diff options
author | Yorhel <git@yorhel.nl> | 2020-01-08 14:09:38 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2020-01-08 14:09:40 +0100 |
commit | 274f42136b35255768fcdc151cda5dca42bb418c (patch) | |
tree | c16b4110394d40a325f06722f395a13d5b924b8c | |
parent | 63f5fc988b86e543fa4d161d10786ce8d9ddbaeb (diff) |
ulist: Add vote dropdown again
As in: Provide some voting guidance again and optimize for the common
case where you vote with a whole number.
-rw-r--r-- | data/style.css | 1 | ||||
-rw-r--r-- | elm/UList/VNPage.elm | 12 | ||||
-rw-r--r-- | elm/UList/VoteEdit.elm | 100 | ||||
-rw-r--r-- | lib/VNWeb/Elm.pm | 2 |
4 files changed, 74 insertions, 41 deletions
diff --git a/data/style.css b/data/style.css index 9f2c1d35..72404bbf 100644 --- a/data/style.css +++ b/data/style.css @@ -104,6 +104,7 @@ div.warning h2, div.notice h2 { font-size: 13px; font-weight: bold; margin: 0; } .elm_dd > div > ul li a:hover { background: $boxbg$ } .elm_dd > div > ul li p { white-space: normal; padding: 3px 5px 3px 3px } .maintabs .elm_dd > a { box-sizing: border-box; height: 21px; padding: 1px 15px 0 7px; border: 1px solid $border$; border-bottom: none; background-color: $tabbg$; color: $maintext$ } +.elm_votedd .elm_dd > div > ul li { text-align: left } diff --git a/elm/UList/VNPage.elm b/elm/UList/VNPage.elm index 05d94ecf..e736bad4 100644 --- a/elm/UList/VNPage.elm +++ b/elm/UList/VNPage.elm @@ -5,6 +5,7 @@ import Html.Attributes exposing (..) import Html.Events exposing (..) import Browser import Lib.Html exposing (..) +import Lib.Util exposing (..) import Lib.Api as Api import Lib.DropDown as DD import Gen.Api as GApi @@ -34,7 +35,7 @@ type alias Recv = main : Program Recv Model Msg main = Browser.element { init = \f -> (init f, Cmd.none) - , subscriptions = \model -> Sub.map Labels (DD.sub model.labels.dd) + , subscriptions = \model -> Sub.batch [ Sub.map Labels (DD.sub model.labels.dd), Sub.map Vote (DD.sub model.vote.dd) ] , view = view , update = update } @@ -87,7 +88,7 @@ update msg model = isPublic : Model -> Bool isPublic model = LE.isPublic model.labels - || (model.vote.text /= "" && model.vote.text /= "-" && List.any (\l -> l.id == 7 && not l.private) model.labels.labels) + || (isJust model.vote.vote && List.any (\l -> l.id == 7 && not l.private) model.labels.labels) view : Model -> Html Msg @@ -110,16 +111,17 @@ view model = table [ style "width" "100%" ] [ tr [ class "nostripe" ] [ td [ style "width" "70px" ] [ text "Labels:" ] - , td [] [ Html.map Labels (LE.view model.labels) ] + , td [ colspan 2 ] [ Html.map Labels (LE.view model.labels) ] ] , if model.flags.canvote || (Maybe.withDefault "-" model.flags.vote /= "-") then tr [ class "nostripe" ] [ td [] [ text "Vote:" ] - , td [ class "compact stealth" ] [ Html.map Vote (VE.view model.vote) ] + , td [ style "width" "80px", class "compact stealth" ] [ Html.map Vote (VE.view model.vote) ] + , td [] [] ] else text "" , tr [ class "nostripe" ] - [ td [ colspan 2 ] + [ td [ colspan 3 ] [ span [ classList [("invisible", not (isPublic model))], title "This visual novel is on your public list" ] [ text "👁 " ] , a [ onClickD (Del True) ] [ text "Remove from list" ] ] diff --git a/elm/UList/VoteEdit.elm b/elm/UList/VoteEdit.elm index adf2cb95..f34b133c 100644 --- a/elm/UList/VoteEdit.elm +++ b/elm/UList/VoteEdit.elm @@ -7,8 +7,11 @@ import Json.Decode as JD import Browser import Task import Lib.Html exposing (..) +import Lib.Util exposing (..) import Lib.Api as Api import Lib.Ffi as Ffi +import Lib.DropDown as DD +import Gen.Types exposing (ratings) import Gen.Api as GApi import Gen.UListVoteEdit as GVE @@ -16,7 +19,7 @@ import Gen.UListVoteEdit as GVE main : Program GVE.Send Model Msg main = Browser.element { init = \f -> (init f, Cmd.none) - , subscriptions = always Sub.none + , subscriptions = \model -> DD.sub model.dd , view = view , update = update } @@ -26,22 +29,32 @@ port ulistVoteChanged : Bool -> Cmd msg type alias Model = { state : Api.State , flags : GVE.Send + , dd : DD.Config Msg , text : String - , valid : Bool + , vote : Maybe String + , ovote : Maybe String + , isvalid : Bool , fieldId : String } init : GVE.Send -> Model init f = + let v = if f.vote == Just "-" || f.vote == Just "" then Nothing else f.vote + in { state = Api.Normal , flags = f - , text = Maybe.withDefault "-" f.vote - , valid = True + , dd = DD.init ("vote_edit_dd_" ++ String.fromInt f.vid) Open + , text = if List.any (\n -> v == Just (String.fromInt n)) (List.indexedMap (\a b -> a+1) ratings) then "" else Maybe.withDefault "" v + , vote = v + , ovote = v + , isvalid = True , fieldId = "vote_edit_" ++ String.fromInt f.vid } type Msg = Input String Bool + | Open Bool + | Set (Maybe String) Bool | Noop | Focus | Save @@ -51,44 +64,59 @@ type Msg update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of - Input s b -> ({ model | text = String.replace "," "." s, valid = b }, Cmd.none) + Input s b -> let t = String.replace "," "." s in ({ model | text = t, isvalid = b, vote = if not b then model.vote else if t == "" || t == "-" then Nothing else Just t }, Cmd.none) + Open b -> ({ model | dd = DD.toggle model.dd b }, if b then selfCmd Focus else Cmd.none) + Set s b -> ({ model | text = "", vote = s, isvalid = True, dd = DD.toggle model.dd False }, selfCmd Save) Noop -> (model, Cmd.none) - Focus -> ( { model | text = if model.text == "-" then "" else model.text } - , Task.attempt (always Noop) <| Ffi.elemCall "select" model.fieldId ) + Focus -> (model, Task.attempt (always Noop) <| Ffi.elemCall "select" model.fieldId) Save -> - let nmodel = { model | text = if model.text == "" then "-" else model.text } - in if nmodel.valid && (Just nmodel.text) /= nmodel.flags.vote - then ( { nmodel | state = Api.Loading } - , GVE.send { uid = model.flags.uid, vid = model.flags.vid, vote = Just model.text } Saved ) - else (nmodel, Task.attempt (always Noop) <| Ffi.elemCall "reportValidity" model.fieldId) + case (model.vote == model.ovote, model.isvalid) of + (True, _) -> (model, Cmd.none) + (_, False) -> (model, Task.attempt (always Noop) <| Ffi.elemCall "reportValidity" model.fieldId) + (_, _) -> ( { model | state = Api.Loading, ovote = model.vote, dd = DD.toggle model.dd False } + , GVE.send { uid = model.flags.uid, vid = model.flags.vid, vote = model.vote } Saved) - Saved GApi.Success -> - let flags = model.flags - nflags = { flags | vote = Just model.text } - in ({ model | flags = nflags, state = Api.Normal }, ulistVoteChanged (model.text /= "" && model.text /= "-")) + Saved GApi.Success -> ({ model | state = Api.Normal }, ulistVoteChanged (isJust (model.vote))) Saved e -> ({ model | state = Api.Error e }, Cmd.none) view : Model -> Html Msg view model = - case model.state of - Api.Loading -> div [ class "spinner" ] [] - Api.Error _ -> b [ class "standout" ] [ text "error" ] -- Need something more informative and actionable, meh... - Api.Normal -> - input ( - [ type_ "text" - , class "text" - , id model.fieldId - , value model.text - , onInputValidation Input - , onBlur Save - , onFocus Focus - , placeholder "7.5" - , style "width" "55px" - , custom "keydown" -- Grab enter key - <| JD.andThen (\c -> if c == "Enter" then JD.succeed { preventDefault = True, stopPropagation = True, message = Save } else JD.fail "") - <| JD.field "key" JD.string - ] - ++ GVE.valVote - ) [] + div [ class "elm_votedd" ] + [ DD.view model.dd model.state + (text <| Maybe.withDefault "-" model.ovote) + <| \_ -> + [ ul [] <| + List.indexedMap (\n s -> + let sn = String.fromInt (10-n) + in li [] [ linkRadio (Just sn == model.ovote) (Set (Just sn)) [ text <| sn ++ " (" ++ s ++ ")" ] ] + ) (List.reverse ratings) + ++ + [ li [] [ p [] + [ text "custom: " + , input ( + [ type_ "text" + , class "text" + , id model.fieldId + , value model.text + , onInputValidation Input + , onBlur Save + , onFocus Focus + , placeholder "7.5" + , style "width" "55px" + , custom "keydown" -- Grab enter key + <| JD.andThen (\c -> if c == "Enter" then JD.succeed { preventDefault = True, stopPropagation = True, message = Save } else JD.fail "") + <| JD.field "key" JD.string + ] + ++ GVE.valVote + ) [] + ] + ] ] + ++ + ( if isJust (model.ovote) + then [ li [] [ a [ href "#", onClickD (Set Nothing True) ] [ text "remove vote" ] ] ] + else [] + ) + ] + ] diff --git a/lib/VNWeb/Elm.pm b/lib/VNWeb/Elm.pm index d9bdd7cc..0c8b42eb 100644 --- a/lib/VNWeb/Elm.pm +++ b/lib/VNWeb/Elm.pm @@ -15,6 +15,7 @@ use Exporter 'import'; use List::Util 'max'; use VNDB::Config; use VNDB::Types; +use VNDB::Func 'fmtrating'; use VNWeb::Auth; our @EXPORT = qw/ @@ -292,6 +293,7 @@ sub write_types { $data .= def releaseTypes => 'List (String, String)' => list map tuple(string $_, string $RELEASE_TYPE{$_}), keys %RELEASE_TYPE; $data .= def rlistStatus => 'List (Int, String)' => list map tuple($_, string $RLIST_STATUS{$_}), keys %RLIST_STATUS; $data .= def boardTypes => 'List (String, String)' => list map tuple(string $_, string $BOARD_TYPE{$_}{txt}), keys %BOARD_TYPE; + $data .= def ratings => 'List String' => list map string(fmtrating $_), 1..10; write_module Types => $data; } |