summaryrefslogtreecommitdiff
path: root/elm/AdvSearch/Tags.elm
diff options
context:
space:
mode:
Diffstat (limited to 'elm/AdvSearch/Tags.elm')
-rw-r--r--elm/AdvSearch/Tags.elm127
1 files changed, 127 insertions, 0 deletions
diff --git a/elm/AdvSearch/Tags.elm b/elm/AdvSearch/Tags.elm
new file mode 100644
index 00000000..001890ee
--- /dev/null
+++ b/elm/AdvSearch/Tags.elm
@@ -0,0 +1,127 @@
+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.Lib 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
+ , inherit : Bool
+ , exclie : Bool
+ }
+
+type Msg
+ = Sel (S.Msg (Int,Int))
+ | Level (Int,Int) Int
+ | Spoiler
+ | Inherit Bool
+ | ExcLie Bool
+ | 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 = "xsearch_tag" ++ String.fromInt ndat.objid, source = A.tagSource }
+ , search = A.init ""
+ , spoiler = dat.defaultSpoil
+ , inherit = True
+ , exclie = False
+ }
+ )
+
+
+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, exclie = False }, Cmd.none)
+ Inherit b -> (dat, { model | inherit = b }, Cmd.none)
+ ExcLie b -> (dat, { model | exclie = b }, 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 (vndbidNum t.id,0) True) model.sel }
+ , c )
+
+
+toQuery m = S.toQuery (\o (t,l) ->
+ let id = if m.inherit then 8 else 14
+ in if m.spoiler == 0 && not m.exclie && l == 0 then QInt id o t else QTuple id o t ((if m.exclie then 16*3 else 0) + l*3 + m.spoiler)) m.sel
+
+fromQuery spoil inherit exclie dat q =
+ let id = if inherit then 8 else 14
+ f qr = case qr of
+ QInt x op t -> if id == x && spoil == 0 && not exclie then Just (op, (t,0)) else Nothing
+ QTuple x op t v -> if id == x && modBy 3 v == spoil && exclie == ((v // (16*3)) == 1) then Just (op, (t, modBy 16 (v//3))) else Nothing
+ _ -> Nothing
+ in
+ S.fromQuery f dat q |> Maybe.map (\(ndat,sel) ->
+ ( { ndat | objid = ndat.objid+1 }
+ , { sel = { sel | single = False, and = sel.and || Set.size sel.sel == 1 }
+ , conf = { wrap = Search, id = "xsearch_tag" ++ String.fromInt ndat.objid, source = A.tagSource }
+ , search = A.init ""
+ , spoiler = spoil
+ , inherit = inherit
+ , exclie = exclie
+ }
+ ))
+
+
+view : Data -> Model -> (Html Msg, () -> List (Html Msg))
+view dat model =
+ ( case Set.toList model.sel.sel of
+ [] -> small [] [ text "Tags" ]
+ [(s,_)] -> span [ class "nowrap" ]
+ [ S.lblPrefix model.sel
+ , small [] [ text <| "g" ++ String.fromInt s ++ ":" ]
+ , Dict.get (vndbid 'g' 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" ]
+ ]
+ , div [ class "opts" ]
+ [ if model.spoiler < 2 then span [] [] else
+ linkRadio model.exclie ExcLie [ text "exclude lies" ]
+ , linkRadio model.inherit Inherit [ text "child tags" ]
+ ]
+ ]
+ , ul [] <| List.map (\(t,l) ->
+ li [ style "overflow" "hidden", style "text-overflow" "ellipsis" ]
+ [ 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")]
+ , small [] [ text <| " g" ++ String.fromInt t ++ ": " ]
+ , Dict.get (vndbid 'g' t) dat.tags |> Maybe.map (\e -> a [ href ("/" ++ e.id), target "_blank", style "display" "inline" ] [ text e.name ]) |> Maybe.withDefault (text "")
+ ]
+ ) (Set.toList model.sel.sel)
+ , A.view model.conf model.search [ placeholder "Search..." ]
+ ]
+ )