summaryrefslogtreecommitdiff
path: root/elm/AdvSearch/Tags.elm
blob: dee6621a9b7aa3d22cdc8a8e01fc1dd565040013 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
module AdvSearch.Tags exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)
import Set
import Dict
import Lib.Autocomplete as A
import Lib.Html exposing (..)
import Lib.Util exposing (..)
import Gen.Api as GApi
import AdvSearch.Query exposing (..)
import AdvSearch.Set as S



type alias Model =
  { sel     : S.Model (Int,Int) -- Tag, Level
  , conf    : A.Config Msg GApi.ApiTagResult
  , search  : A.Model GApi.ApiTagResult
  , spoiler : Int
  }

type Msg
  = Sel (S.Msg (Int,Int))
  | Level (Int,Int) Int
  | Spoiler
  | Search (A.Msg GApi.ApiTagResult)


init : Data -> (Data, Model)
init dat =
  let (ndat, sel) = S.init dat
  in  ( { ndat | objid = ndat.objid + 1 }
      , { sel     = { sel | single = False, and = True }
        , conf    = { wrap = Search, id = "advsearch_tag" ++ String.fromInt ndat.objid, source = A.tagSource }
        , search  = A.init ""
        , spoiler = dat.defaultSpoil
        }
      )


update : Data -> Msg -> Model -> (Data, Model, Cmd Msg)
update dat msg model =
  case msg of
    Sel m -> (dat, { model | sel = S.update m model.sel }, Cmd.none)
    Level (t,ol) nl -> (dat, { model | sel = S.update (S.Sel (t,ol) False) model.sel |> S.update (S.Sel (t,nl) True) }, Cmd.none)
    Spoiler -> (dat, { model | spoiler = if model.spoiler < 2 then model.spoiler + 1 else 0 }, Cmd.none)
    Search m ->
      let (nm, c, res) = A.update model.conf m model.search
      in case res of
          Nothing -> (dat, { model | search = nm }, c)
          Just t ->
            ( { dat | tags = Dict.insert t.id t dat.tags }
            , { model | search = A.clear nm "", sel = S.update (S.Sel (t.id,0) True) model.sel }
            , c )


toQuery m = S.toQuery (\o (t,l) -> if m.spoiler == 0 && l == 0 then QInt 8 o t else QTuple 8 o t (l*3+m.spoiler)) m.sel

fromQuery spoil dat q =
  let f qr = case qr of
              QInt 8 op t -> if spoil == 0 then Just (op, (t,0)) else Nothing
              QTuple 8 op t v -> if modBy 3 v == spoil then Just (op, (t,v//3)) else Nothing
              _ -> Nothing
  in
  S.fromQuery f dat q |> Maybe.map (\(ndat,sel) ->
    ( { ndat | objid = ndat.objid+1 }
    , { sel     = { sel | single = False }
      , conf    = { wrap = Search, id = "advsearch_tag" ++ String.fromInt ndat.objid, source = A.tagSource }
      , search  = A.init ""
      , spoiler = spoil
      }
    ))


view : Data -> Model -> (Html Msg, () -> List (Html Msg))
view dat model =
  ( case Set.toList model.sel.sel of
      []  -> b [ class "grayedout" ] [ text "Tags" ]
      [(s,_)] -> span [ class "nowrap" ]
             [ S.lblPrefix model.sel
             , b [ class "grayedout" ] [ text <| "g" ++ String.fromInt s ++ ":" ]
             , Dict.get s dat.tags |> Maybe.map (\t -> t.name) |> Maybe.withDefault "" |> text
             ]
      l   -> span [] [ S.lblPrefix model.sel, text <| "Tags (" ++ String.fromInt (List.length l) ++ ")" ]
  , \() ->
    [ div [ class "advheader" ]
      [ h3 [] [ text "Tags" ]
      , div [ class "opts" ]
        [ Html.map Sel (S.optsMode model.sel True False)
        , a [ href "#", onClickD Spoiler ]
          [ text <| if model.spoiler == 0 then "no spoilers" else if model.spoiler == 1 then "minor spoilers" else "major spoilers" ]
        , linkRadio model.sel.neg (Sel << S.Neg) [ text "invert" ]
        ]
      ]
    , ul [] <| List.map (\(t,l) ->
        li []
        [ inputButton "X" (Sel (S.Sel (t,l) False)) []
        , inputSelect "" l (Level (t,l)) [style "width" "60px"] <|
          (0, "any")
          :: List.map (\i -> (i, String.fromInt (i//5) ++ "." ++ String.fromInt (2*(modBy 5 i)) ++ "+")) (List.range 1 14)
          ++ [(15, "3.0")]
        , b [ class "grayedout" ] [ text <| " g" ++ String.fromInt t ++ ": " ]
        , Dict.get t dat.tags |> Maybe.map (\e -> e.name) |> Maybe.withDefault "" |> text
        ]
      ) (Set.toList model.sel.sel)
    , A.view model.conf model.search [ placeholder "Search..." ]
    ]
  )