summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2021-08-04 11:23:54 +0200
committerYorhel <git@yorhel.nl>2021-08-04 11:23:54 +0200
commit801ddce64be0af357967e8346fbc934b8a8d50ed (patch)
tree2bf65cf0b93c5e55f60c19081c5d1ec10bad8eca
parent868a6a609e31ffee1a7f0c91f431cf450795230a (diff)
VN::Page: Aggergate play times per speed + use median
-rw-r--r--css/v2.css13
-rw-r--r--elm/VNLengthVote.elm10
-rw-r--r--lib/VNWeb/VN/Page.pm37
3 files changed, 38 insertions, 22 deletions
diff --git a/css/v2.css b/css/v2.css
index 3a1464ac..4e5d455a 100644
--- a/css/v2.css
+++ b/css/v2.css
@@ -468,14 +468,19 @@ div.vnimg { float: left; width: 250px; margin: 0 10px; }
div.vnimg p { text-align: center; padding: 0px; margin: 0; }
div.vndetails h2 { margin: 5px 0 0 0; }
.vndesc p { padding: 0 0 0 5px; }
-div.vndetails table { float: left; width: 500px; }
-div.vndetails table td.key { width: 90px; }
-div.vndetails table dt { float: left; font-style: italic; }
-div.vndetails table dd { margin-left: 90px; }
+div.vndetails > table { float: left; width: 500px; }
+div.vndetails > table td.key { width: 90px; }
+div.vndetails > table dt { float: left; font-style: italic; }
+div.vndetails > table dd { margin-left: 90px; }
div.vndetails td.title abbr { float: right }
div.vndetails td.relations dt { float: none; font-style: normal; }
div.vndetails td.relations dd { margin-left: 15px; }
div.vndetails td.anime b { font-size: 10px; font-weight: normal; padding-right: 4px; }
+div.vndetails .lengthstats { width: 100% }
+div.vndetails .lengthstats td { padding: 0 5px 0 0 }
+div.vndetails .lengthstats td:last-child { padding-right: 0 }
+div.vndetails .lengthstats td:not(:last-child) { width: 1px; white-space: nowrap; }
+div.vndetails .lengthvotefrm { margin-top: -18px }
.ulistvn { padding: 5px 0 0 0 }
.ulistvn > b { font-size: 14px }
.ulistvn > span { float: right }
diff --git a/elm/VNLengthVote.elm b/elm/VNLengthVote.elm
index 5c1a08ac..0f799854 100644
--- a/elm/VNLengthVote.elm
+++ b/elm/VNLengthVote.elm
@@ -117,12 +117,12 @@ update msg model =
view : Model -> Html Msg
-view model = span [] <|
+view model = div [class "lengthvotefrm"] <|
let
cansubmit = enclen model > 0 && model.speed /= -1 && model.rid /= ""
rels = Maybe.withDefault [] model.rels
frm = [ form_ "" (if cansubmit then Submit else Noop) False
- [ br [] []
+ [ br_ 2
, text "How long did you take to finish this VN?"
, br [] []
, text "- Only vote if you've completed all normal/true endings."
@@ -154,12 +154,12 @@ view model = span [] <|
] ]
in
[ text " "
- , a [ onClickD (Open (not model.open)), href "#" ]
+ , a [ onClickD (Open (not model.open)), href "#", style "float" "right" ]
[ 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
- (_, Api.Error e) -> [ br [] [], b [ class "standout" ] [ text ("Error: " ++ Api.showResponse e) ] ]
- (_, Api.Loading) -> [ span [ class "spinner" ] [] ]
+ (_, Api.Error e) -> [ br_ 2, b [ class "standout" ] [ text ("Error: " ++ Api.showResponse e) ] ]
+ (_, Api.Loading) -> [ span [ style "float" "right", class "spinner" ] [] ]
diff --git a/lib/VNWeb/VN/Page.pm b/lib/VNWeb/VN/Page.pm
index 1bfd6fa8..bed1a45a 100644
--- a/lib/VNWeb/VN/Page.pm
+++ b/lib/VNWeb/VN/Page.pm
@@ -159,27 +159,38 @@ sub infobox_length_ {
my $today = strftime('%Y%m%d', gmtime);
return if !grep $_->{type} ne 'trial' && $_->{released} <= $today, $v->{releases}->@*;
- my $stats = tuwf->dbRowi('
- SELECT count(*) as count, avg(l.length)::int as avg, stddev_pop(l.length::real)::int as stddev
+ my $stats = tuwf->dbAlli('
+ SELECT speed, count(*) as count, stddev_pop(l.length::real)::int as stddev
+ , percentile_cont(0.5) WITHIN GROUP (ORDER BY l.length) AS median
FROM vn_length_votes l
LEFT JOIN users u ON u.id = l.uid
- WHERE u.perm_lengthvote IS DISTINCT FROM false AND l.vid =', \$v->{id});
- return if !$v->{length} && !$stats->{count} && !auth->permLengthvote;
+ WHERE u.perm_lengthvote IS DISTINCT FROM false AND l.vid =', \$v->{id}, '
+ GROUP BY speed ORDER BY speed');
+ return if !$v->{length} && !@$stats && !VNWeb::VN::Length::can_vote();
my $my = VNWeb::VN::Length::can_vote() && tuwf->dbRowi('SELECT rid, length, speed, notes FROM vn_length_votes WHERE vid =', \$v->{id}, 'AND uid =', \auth->uid);
tr_ sub {
td_ 'Play time';
td_ sub {
- if($stats->{count}) {
- vnlength_ $stats->{avg};
- if ($stats->{stddev}) {
- txt_ ' σ ';
- vnlength_ $stats->{stddev};
- }
- txt_ ' (';
- a_ href => "/$v->{id}/lengthvotes", sprintf '%d vote%s', $stats->{count}, $stats->{count}==1?'':'s';
- txt_ ').';
+ if(@$stats) {
+ my $first=0;
+ table_ class => 'lengthstats', sub {
+ tr_ sub {
+ td_ ['Slow', 'Normal', 'Fast']->[$_->{speed}].':';
+ td_ sub { vnlength_ $_->{median} };
+ td_ sub {
+ if ($_->{stddev}) {
+ txt_ 'σ ';
+ vnlength_ $_->{stddev};
+ }
+ };
+ td_ sub {
+ txt_ sprintf ' (%d vote%s).', $_->{count}, $_->{count}==1?'':'s';
+ a_ href => "/$v->{id}/lengthvotes", style => @$stats > 1 ? 'float: right' : undef, ' All votes »' if !$first++;
+ };
+ } for @$stats;
+ };
} elsif($v->{length}) {
txt_ "$VN_LENGTH{$v->{length}}{txt} ($VN_LENGTH{$v->{length}}{time})";
} else {