summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2021-08-02 13:08:32 +0200
committerYorhel <git@yorhel.nl>2021-08-02 13:08:32 +0200
commit2511c1d6231d8d6467caecf2ff970bc8a8546c54 (patch)
tree62bf8ad2d65b943d5d23471ddfff7ef56d0a86ae
parent05f2c0127f65bdcad0cd04af4570016288d797f1 (diff)
VNLenthVote: Improve form with minute field + release filter + some info
-rw-r--r--elm/VNLengthVote.elm73
-rw-r--r--lib/VNWeb/VN/Page.pm41
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;