diff options
author | Yorhel <git@yorhel.nl> | 2021-08-02 13:08:32 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2021-08-02 13:08:32 +0200 |
commit | 2511c1d6231d8d6467caecf2ff970bc8a8546c54 (patch) | |
tree | 62bf8ad2d65b943d5d23471ddfff7ef56d0a86ae | |
parent | 05f2c0127f65bdcad0cd04af4570016288d797f1 (diff) |
VNLenthVote: Improve form with minute field + release filter + some info
-rw-r--r-- | elm/VNLengthVote.elm | 73 | ||||
-rw-r--r-- | lib/VNWeb/VN/Page.pm | 41 |
2 files changed, 76 insertions, 38 deletions
diff --git a/elm/VNLengthVote.elm b/elm/VNLengthVote.elm index 0c7bc0d7..aa5eb0fc 100644 --- a/elm/VNLengthVote.elm +++ b/elm/VNLengthVote.elm @@ -4,6 +4,8 @@ import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) import Browser +import Task +import Date import Lib.Html exposing (..) import Lib.Api as Api import Lib.RDate as RDate @@ -14,7 +16,7 @@ import Gen.Release as GR main : Program GV.Send Model Msg main = Browser.element - { init = \e -> (init e, Cmd.none) + { init = \e -> (init e, Date.today |> Task.perform Today) , view = view , update = update , subscriptions = always Sub.none @@ -23,12 +25,14 @@ main = Browser.element type alias Model = { state : Api.State , open : Bool + , today : Int , uid : String , vid : String , rid : String , defrid : String - , length : Int - , slength : Int + , hours : Maybe Int + , minutes : Maybe Int + , length : Int -- last saved length , notes : String , rels : Maybe (List (String, String)) } @@ -36,13 +40,15 @@ type alias Model = init : GV.Send -> Model init f = { state = Api.Normal + , today = 0 , open = False , uid = f.uid , vid = f.vid - , rid = Maybe.map (\v -> v.rid) f.vote |> Maybe.withDefault "" + , rid = Maybe.map (\v -> v.rid) f.vote |> Maybe.withDefault "" , defrid = "" + , hours = Maybe.map (\v -> v.length // 60 ) f.vote + , minutes = Maybe.map (\v -> modBy 60 v.length) f.vote , length = Maybe.map (\v -> v.length) f.vote |> Maybe.withDefault 0 - , slength = Maybe.map (\v -> v.length) f.vote |> Maybe.withDefault 0 , notes = Maybe.map (\v -> v.notes) f.vote |> Maybe.withDefault "" , rels = Nothing } @@ -51,12 +57,14 @@ encode : Model -> GV.Send encode m = { uid = m.uid , vid = m.vid - , vote = if m.length == 0 then Nothing else Just { rid = m.rid, length = m.length, notes = m.notes } + , vote = Maybe.map (\h -> { rid = m.rid, notes = m.notes, length = h * 60 + Maybe.withDefault 0 m.minutes }) m.hours } type Msg = Open Bool - | Length (Maybe Int) + | Today Date.Date + | Hours (Maybe Int) + | Minutes (Maybe Int) | Release String | Notes String | RelLoaded GApi.Response @@ -72,21 +80,29 @@ update msg model = if b && model.rels == Nothing then ({ model | open = b, state = Api.Loading }, GR.send { vid = model.vid } RelLoaded) else ({ model | open = b }, Cmd.none) - Length n -> ({ model | length = 60 * Maybe.withDefault 0 n }, Cmd.none) + Today d -> ({ model | today = RDate.fromDate d |> RDate.compact }, Cmd.none) + Hours n -> ({ model | hours = n }, Cmd.none) + Minutes n -> ({ model | minutes = n }, Cmd.none) Release s -> ({ model | rid = s }, Cmd.none) Notes s -> ({ model | notes = s }, Cmd.none) RelLoaded (GApi.Releases rels) -> - let def = case rels of - [r] -> r.id + let rel r = if r.rtype /= "trial" && r.released <= model.today then Just (r.id, RDate.showrel r) else Nothing + frels = List.filterMap rel rels + def = case frels of + [(r,_)] -> r _ -> "" in ({ model | state = Api.Normal - , rels = Just <| List.map (\r -> (r.id, RDate.showrel r)) rels + , rels = Just frels + , defrid = def , rid = if model.rid == "" then def else model.rid }, Cmd.none) RelLoaded e -> ({ model | state = Api.Error e }, Cmd.none) - Delete -> let m = { model | length = 0, rid = model.defrid, notes = "", state = Api.Loading } in (m, GV.send (encode m) Submitted) + Delete -> let m = { model | hours = Nothing, minutes = Nothing, rid = model.defrid, notes = "", state = Api.Loading } in (m, GV.send (encode m) Submitted) Submit -> ({ model | state = Api.Loading }, GV.send (encode model) Submitted) - Submitted (GApi.Success) -> ({ model | open = False, state = Api.Normal, slength = model.length }, Cmd.none) + Submitted (GApi.Success) -> + ({ model | open = False, state = Api.Normal + , length = (Maybe.withDefault 0 model.hours) * 60 + Maybe.withDefault 0 model.minutes + }, Cmd.none) Submitted r -> ({ model | state = Api.Error r }, Cmd.none) @@ -94,25 +110,34 @@ view : Model -> Html Msg view model = span [] <| let frm = [ form_ "" (if model.rid == "" then Open True else Submit) False - [ text "My play time: " - , inputNumber "" (if model.length == 0 then Nothing else Just (model.length//60)) Length <| - [ Html.Attributes.min "1", Html.Attributes.max "500", required True ] - , text " hours" + [ br [] [] + , text "How long did you take to finish this VN?" , br [] [] - , if model.defrid /= "" then text "" else - inputSelect "" model.rid Release [style "width" "100%"] <| - ("", "-- select release --") :: (Maybe.withDefault [] model.rels) + , text "- Only vote if you've completed all normal/true endings." + , br [] [] + , text "- Exact measurements preferred, but rough estimates are accepted too." + , br [] [] + , text "Play time: " + , inputNumber "" model.hours Hours [ Html.Attributes.min "1", Html.Attributes.max "500", required True ] + , text " hours " + , inputNumber "" model.minutes Minutes [ Html.Attributes.min "0", Html.Attributes.max "59" ] + , text " minutes" + , br [] [] + , if model.defrid /= "" then text "" else -- TODO: Handle missing model.rid + inputSelect "" model.rid Release [style "width" "100%"] <| ("", "-- select release --") :: (Maybe.withDefault [] model.rels) , inputTextArea "" model.notes Notes [rows 2, cols 30, style "width" "100%", placeholder "(Optional) comments that may be helpful. For example, did you complete all routes, did you use auto mode? etc." ] - , if model.slength == 0 then text "" else inputButton "Delete my vote" Delete [style "float" "right"] - , if model.length == 0 || model.rid == "" then text "" else submitButton "Save" model.state True + , if model.length == 0 then text "" else inputButton "Delete my vote" Delete [style "float" "right"] + , if model.hours == Nothing || model.rid == "" then text "" else submitButton "Save" model.state True , inputButton "Cancel" (Open False) [] + , br_ 2 ] ] in [ text " " , a [ onClickD (Open (not model.open)), href "#" ] - [ text <| if model.slength == 0 then "Vote »" - else "My vote: " ++ String.fromInt (model.slength // 60) ++ "h" ] -- TODO minute + [ text <| if model.length == 0 then "Vote »" + else "My vote: " ++ String.fromInt (model.length // 60) ++ "h" + ++ if modBy 60 model.length /= 0 then String.fromInt (modBy 60 model.length) ++ "m" else "" ] ] ++ case (model.open, model.state) of (False, _) -> [] (_, Api.Normal) -> frm diff --git a/lib/VNWeb/VN/Page.pm b/lib/VNWeb/VN/Page.pm index 10ac10ba..b272c2e8 100644 --- a/lib/VNWeb/VN/Page.pm +++ b/lib/VNWeb/VN/Page.pm @@ -153,6 +153,32 @@ sub infobox_relations_ { } +sub infobox_length_ { + my($v) = @_; + + my $today = strftime('%Y%m%d', gmtime); + my $canvote = auth->permLengthvote && grep $_->{type} ne 'trial' && $_->{released} <= $today, $v->{releases}->@*; + return if !$v->{length} && !$canvote; + + my $vote = tuwf->dbRowi('SELECT rid, length, notes FROM vn_length_votes WHERE vid =', \$v->{id}, 'AND uid =', \auth->uid); + + # TODO: Display aggregated vote stats + + tr_ sub { + td_ 'Length'; + td_ sub { + txt_ $v->{length} ? "$VN_LENGTH{$v->{length}}{txt} ($VN_LENGTH{$v->{length}}{time})" : 'Unknown'; + if ($canvote) { + elm_ VNLengthVote => $VNWeb::VN::Elm::LENGTHVOTE, { + uid => auth->uid, vid => $v->{id}, + vote => $vote->{rid}?$vote:undef, + }, sub { span_ @_, ''}; + } + }; + }; +} + + sub infobox_producers_ { my($v) = @_; @@ -353,20 +379,7 @@ sub infobox_ { td_ $v->{alias} =~ s/\n/, /gr; } if $v->{alias}; - tr_ sub { - td_ 'Length'; - td_ sub { - txt_ "$VN_LENGTH{$v->{length}}{txt} ($VN_LENGTH{$v->{length}}{time})"; - if (auth->permLengthvote && canvote $v) { - my $vote = tuwf->dbRowi('SELECT rid, length, notes FROM vn_length_votes WHERE vid =', \$v->{id}, 'AND uid =', \auth->uid); - elm_ VNLengthVote => $VNWeb::VN::Elm::LENGTHVOTE, { - uid => auth->uid, vid => $v->{id}, - vote => $vote->{rid}?$vote:undef, - }, sub { span_ @_, ''}; - } - }; - } if $v->{length}; - + infobox_length_ $v; infobox_producers_ $v; infobox_relations_ $v; |