summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2022-08-09 10:47:42 +0200
committerYorhel <git@yorhel.nl>2022-08-09 10:47:42 +0200
commitefbed0eb912801f5cc618ea384362f11518cde65 (patch)
tree24cbac40f29d0073d903389f684fbca7016b6533
parentb2190a32a4c4fe967ac226df23c8692184f35132 (diff)
Tagmod: allow setting spoiler level independent of the lie flag
-rw-r--r--css/v2.css14
-rw-r--r--elm/Tagmod.elm71
-rw-r--r--lib/VNWeb/TT/TagLinks.pm14
-rw-r--r--lib/VNWeb/VN/Tagmod.pm15
4 files changed, 73 insertions, 41 deletions
diff --git a/css/v2.css b/css/v2.css
index dc75a3e0..08407c5f 100644
--- a/css/v2.css
+++ b/css/v2.css
@@ -1103,7 +1103,8 @@ table.tgl .tc_you { border-right: 1px solid $border; border-left: 1px
table.tgl .tc_others { border-left: 1px solid $border; text-align: center }
table.tgl .tc_tagname { min-width: 200px; border-right: 1px solid $border }
table.tgl tbody .tc_tagname { padding-left: 15px }
-table.tgl .tc_myvote { padding: 0 0 0 30px; min-width: 100px }
+table.tgl .tc_myvote { padding: 0 0 0 10px; min-width: 80px }
+table.tgl .tc_mynote { min-width: 15px }
table.tgl .tc_mynote span { cursor: pointer }
table.tgl .noteview { position: absolute; max-width: 400px; padding: 0 5px 5px 5px; background: $blendbg }
table.tgl .buts a { box-sizing: border-box; display: block; width: 15px; height: 14px; border: 1px solid $border; margin: 0; float: left }
@@ -1112,16 +1113,21 @@ table.tgl .buts a.l1 { border: none; background-color: #cf0 }
table.tgl .buts a.l2 { border: none; background-color: #8f0 }
table.tgl .buts a.l3 { border: none; background-color: #0f0 }
table.tgl .buts a.ld { border: none; background-color: #f00 }
-table.tgl tbody .tc_myover { padding: 0 5px }
-table.tgl .tc_myspoil { padding: 0 30px; min-width: 60px }
+table.tgl tbody .tc_myover { padding: 0 }
+table.tgl .buts a.ov { border: none; background-color: #f00 }
+table.tgl .tc_myspoil { padding: 0; min-width: 75px }
table.tgl .buts a.sn { border: none; background-color: $border }
table.tgl .buts a.s0 { border: none; background-color: #0f0 }
table.tgl .buts a.s1 { border: none; background-color: #f80 }
table.tgl .buts a.s2 { border: none; background-color: #f40 }
table.tgl .buts a.s3 { border: none; background-color: #cf0 }
+table.tgl .tc_mylie { padding: 0; min-width: 53px }
+table.tgl .buts a.fn { border: none; background-color: $border }
+table.tgl .buts a.f0 { border: none; background-color: #0f0 }
+table.tgl .buts a.f1 { border: none; background-color: #f00 }
table.tgl .tc_allvote { border-left: 1px solid $border; padding: 1px 0 0 30px; }
table.tgl .tc_allvote i { font-style: normal; font-size: 10px }
-table.tgl .tc_allspoil { text-align: right; padding-right: 15px }
+table.tgl .tc_allspoil { text-align: right; padding-right: 5px }
table.tgl .tagmod_cat td { font-weight: bold; padding-top: 10px }
diff --git a/elm/Tagmod.elm b/elm/Tagmod.elm
index e7d3b4d6..fe4b5850 100644
--- a/elm/Tagmod.elm
+++ b/elm/Tagmod.elm
@@ -29,7 +29,9 @@ type alias Tag = GT.RecvTags
type Sel
= NoSel
| Vote Int
+ | Over
| Spoil (Maybe Int)
+ | Lie (Maybe Bool)
| Note
| NoteSet
@@ -77,6 +79,7 @@ type Msg
| SetVote String Int
| SetOver String Bool
| SetSpoil String (Maybe Int)
+ | SetLie String (Maybe Bool)
| SetNote String String
| NegShow Bool
| TagSearch (A.Msg GApi.ApiTagResult)
@@ -99,6 +102,7 @@ update msg model =
SetVote id v -> (modtag id (\t -> { t | vote = v }), Cmd.none)
SetOver id b -> (modtag id (\t -> { t | overrule = b }), Cmd.none)
SetSpoil id s -> (modtag id (\t -> { t | spoil = s }), Cmd.none)
+ SetLie id s -> (modtag id (\t -> { t | lie = s }), Cmd.none)
SetNote id s -> (modtag id (\t -> { t | notes = s }), Cmd.none)
NegShow b -> ({ model | negShow = b }, Cmd.none)
@@ -111,13 +115,13 @@ update msg model =
if t.hidden && t.locked then ([], "Can't add deleted tags")
else if not t.applicable then ([], "Tag is not applicable")
else if List.any (\it -> it.id == t.id) model.tags then ([], "Tag is already in the list")
- else ([{ id = t.id, vote = 0, spoil = Nothing, overrule = False, notes = "", cat = "new", name = t.name
- , rating = 0, count = 0, spoiler = 0, overruled = False, othnotes = "", hidden = t.hidden, locked = t.locked, applicable = t.applicable }], "")
+ else ([{ id = t.id, vote = 0, spoil = Nothing, lie = Nothing, overrule = False, notes = "", cat = "new", name = t.name
+ , rating = 0, count = 0, spoiler = 0, islie = False, overruled = False, othnotes = "", hidden = t.hidden, locked = t.locked, applicable = t.applicable }], "")
in (changed { model | add = if ms == "" then A.clear nm "" else nm, tags = model.tags ++ nl, addMsg = ms }, c)
Submit ->
( { model | state = Api.Loading, addMsg = "" }
- , GT.send { id = model.id, tags = List.map (\t -> { id = t.id, vote = t.vote, spoil = t.spoil, overrule = t.overrule, notes = t.notes }) model.tags } Submitted)
+ , GT.send { id = model.id, tags = List.map (\t -> { id = t.id, vote = t.vote, spoil = t.spoil, lie = t.lie, overrule = t.overrule, notes = t.notes }) model.tags } Submitted)
Submitted GApi.Success -> (model, reload)
Submitted r -> ({ model | state = Api.Error r }, Cmd.none)
@@ -132,11 +136,13 @@ viewTag t sel vid mod =
[ span [] [ text <| Ffi.fmtFloat s 1 ]
, div [ style "width" <| String.fromFloat (abs (s/3*30)) ++ "px" ] []
]
-
+ msg s = [ td [ colspan 4 ] [ text s ] ]
vote = case sel of Vote v -> v
_ -> t.vote
spoil = case sel of Spoil s -> s
_ -> t.spoil
+ lie = case sel of Lie l -> l
+ _ -> t.lie
in
tr [] <|
[ td [ class "tc_tagname" ]
@@ -155,17 +161,24 @@ viewTag t sel vid mod =
, a [ href "#", onMouseOver (SetSel t.id (Vote 3)), onMouseOut (SetSel "" NoSel), onClickD (SetVote t.id 3), classList [("l3", vote == 3)], title "+3" ] []
]
] ++ (if t.vote == 0 && t.count == 0 then
- [ td [ colspan 3 ] [ text "<- don't forget to rate" ]
+ [ td [ colspan 4 ] [ text "<- don't forget to rate" ]
] else
- [ td [ class "tc_myover" ] [ if mod && t.vote /= 0 then inputCheck "" t.overrule (SetOver t.id) else text "" ]
+ [ td [ class "tc_myover buts" ] <|
+ if t.vote <= 0 || not mod then [] else
+ [ a [ href "#", onMouseOver (SetSel t.id Over), onMouseOut (SetSel "" NoSel), onClickD (SetOver t.id (not t.overrule)), classList [("ov", t.overrule || sel == Over)], title "Overrule" ] [] ]
, td [ class "tc_myspoil buts" ] <|
if t.vote <= 0 then [] else
- [ a [ href "#", onMouseOver (SetSel t.id (Spoil (Just 3))), onMouseOut (SetSel "" NoSel), onClickD (SetSpoil t.id (Just 3)), classList [("s3", spoil == Just 3 )], title "False" ] []
- , a [ href "#", onMouseOver (SetSel t.id (Spoil Nothing)), onMouseOut (SetSel "" NoSel), onClickD (SetSpoil t.id Nothing), classList [("sn", spoil == Nothing)], title "Unknown" ] []
+ [ a [ href "#", onMouseOver (SetSel t.id (Spoil Nothing)), onMouseOut (SetSel "" NoSel), onClickD (SetSpoil t.id Nothing), classList [("sn", spoil == Nothing)], title "Unknown" ] []
, a [ href "#", onMouseOver (SetSel t.id (Spoil (Just 0))), onMouseOut (SetSel "" NoSel), onClickD (SetSpoil t.id (Just 0)), classList [("s0", spoil == Just 0 )], title "Not a spoiler" ] []
, a [ href "#", onMouseOver (SetSel t.id (Spoil (Just 1))), onMouseOut (SetSel "" NoSel), onClickD (SetSpoil t.id (Just 1)), classList [("s1", spoil == Just 1 )], title "Minor spoiler" ] []
, a [ href "#", onMouseOver (SetSel t.id (Spoil (Just 2))), onMouseOut (SetSel "" NoSel), onClickD (SetSpoil t.id (Just 2)), classList [("s2", spoil == Just 2 )], title "Major spoiler" ] []
]
+ , td [ class "tc_mylie buts" ] <|
+ if t.vote <= 0 then [] else
+ [ a [ href "#", onMouseOver (SetSel t.id (Lie Nothing)), onMouseOut (SetSel "" NoSel), onClickD (SetLie t.id Nothing ), classList [("fn", lie == Nothing )], title "Unknown" ] []
+ , a [ href "#", onMouseOver (SetSel t.id (Lie (Just False))), onMouseOut (SetSel "" NoSel), onClickD (SetLie t.id (Just False)), classList [("f0", lie == Just False)], title "This tag is not a lie" ] []
+ , a [ href "#", onMouseOver (SetSel t.id (Lie (Just True))), onMouseOut (SetSel "" NoSel), onClickD (SetLie t.id (Just True )), classList [("f1", lie == Just True )], title "This tag is a lie"] []
+ ]
, td [ class "tc_mynote" ] <|
if t.vote == 0 then [] else
[ span
@@ -177,25 +190,28 @@ viewTag t sel vid mod =
]
]) ++
case sel of
- Vote 0 -> [ td [ colspan 3 ] [ text "Remove vote" ] ]
- Vote 1 -> [ td [ colspan 3 ] [ text "Vote +1" ] ]
- Vote 2 -> [ td [ colspan 3 ] [ text "Vote +2" ] ]
- Vote 3 -> [ td [ colspan 3 ] [ text "Vote +3" ] ]
- Vote _ -> [ td [ colspan 3 ] [ text "Downvote (-3)" ] ]
- Spoil (Just 3) -> [ td [ colspan 3 ] [ text "This eventually turns out to be false" ] ]
- Spoil Nothing -> [ td [ colspan 3 ] [ text "Spoiler status not known" ] ]
- Spoil (Just 0) -> [ td [ colspan 3 ] [ text "This is not a spoiler" ] ]
- Spoil (Just 1) -> [ td [ colspan 3 ] [ text "This is a minor spoiler" ] ]
- Spoil (Just 2) -> [ td [ colspan 3 ] [ text "This is a major spoiler" ] ]
- Note -> [ td [ colspan 3 ] [ if t.notes == "" then text "Set note" else div [ class "noteview" ] [ text t.notes ] ] ]
+ Vote 0 -> msg "Remove vote"
+ Vote 1 -> msg "Vote +1"
+ Vote 2 -> msg "Vote +2"
+ Vote 3 -> msg "Vote +3"
+ Vote _ -> msg "Downvote (-3)"
+ Over -> msg "Mod overrule (only your vote counts)"
+ Spoil Nothing -> msg "Spoiler status not known"
+ Spoil (Just 0) -> msg "This is not a spoiler"
+ Spoil (Just 1) -> msg "This is a minor spoiler"
+ Spoil (Just 2) -> msg "This is a major spoiler"
+ Lie Nothing -> msg "Truth status not known"
+ Lie (Just True)-> msg "This tag turns out to be false"
+ Lie (Just False)->msg "This tag is not a lie"
+ Note -> [ td [ colspan 4 ] [ if t.notes == "" then text "Set note" else div [ class "noteview" ] [ text t.notes ] ] ]
NoteSet ->
- [ td [ colspan 3, class "compact" ]
+ [ td [ colspan 4, class "compact" ]
[ Html.form [ onSubmit (SetSel t.id NoSel) ]
[ inputText "tag_note" t.notes (SetNote t.id) (onBlur (SetSel t.id NoSel) :: style "width" "400px" :: style "position" "absolute" :: placeholder "Set note..." :: GT.valTagsNotes) ]
]
]
_ ->
- if t.count == 0 then [ td [ colspan 3 ] [] ]
+ if t.count == 0 then [ td [ colspan 4 ] [] ]
else
[ td [ class "tc_allvote" ]
[ tagscore t.rating
@@ -203,7 +219,8 @@ viewTag t sel vid mod =
, if not t.overruled then text ""
else b [ class "standout", style "font-weight" "bold", title "Tag overruled. All votes other than that of the moderator who overruled it will be ignored." ] [ text "!" ]
]
- , td [ class "tc_allspoil"] [ text <| if t.spoiler < 0 then "False" else Ffi.fmtFloat t.spoiler 2 ]
+ , td [ class "tc_allspoil"] [ text <| Ffi.fmtFloat t.spoiler 2 ]
+ , td [ class "tc_alllie"] [ text <| if t.islie then "lie" else "" ]
, td [ class "tc_allwho" ]
[ span [ style "opacity" <| if t.othnotes == "" then "0" else "1", style "cursor" "default", title t.othnotes ] [ text "💬 " ]
, a [ href <| "/g/links?v="++vid++"&t="++t.id ] [ text "Who?" ]
@@ -217,24 +234,26 @@ viewHead mod negCount negShow =
[ td [ style "font-weight" "normal", style "text-align" "right" ] <|
if negCount == 0 then []
else [ linkRadio negShow NegShow [ text "Show downvoted tags " ], i [] [ text <| " (" ++ String.fromInt negCount ++ ")" ] ]
- , td [ colspan 4, class "tc_you" ] [ text "You" ]
- , td [ colspan 3, class "tc_others" ] [ text "Others" ]
+ , td [ colspan 5, class "tc_you" ] [ text "You" ]
+ , td [ colspan 4, class "tc_others" ] [ text "Others" ]
]
, tr []
[ td [ class "tc_tagname" ] [ text "Tag" ]
, td [ class "tc_myvote" ] [ text "Rating" ]
, td [ class "tc_myover" ] [ text (if mod then "O" else "") ]
, td [ class "tc_myspoil" ] [ text "Spoiler" ]
+ , td [ class "tc_mylie" ] [ text "Lie" ]
, td [ class "tc_mynote" ] []
, td [ class "tc_allvote" ] [ text "Rating" ]
, td [ class "tc_allspoil"] [ text "Spoiler" ]
+ , td [ class "tc_alllie" ] []
, td [ class "tc_allwho" ] []
]
]
viewFoot : Api.State -> Bool -> A.Model GApi.ApiTagResult -> String -> Html Msg
viewFoot state changed add addMsg =
- tfoot [] [ tr [] [ td [ colspan 8 ]
+ tfoot [] [ tr [] [ td [ colspan 10 ]
[ div [ style "display" "flex", style "justify-content" "space-between" ]
[ A.view searchConfig add [placeholder "Add tags..."]
, if addMsg /= ""
@@ -272,7 +291,7 @@ view model =
in
if List.length lst == 0
then []
- else tr [class "tagmod_cat"] [ td [] [text nam], td [ class "tc_you", colspan 4 ] [], td [ class "tc_others", colspan 3 ] [] ]
+ else tr [class "tagmod_cat"] [ td [] [text nam], td [ class "tc_you", colspan 5 ] [], td [ class "tc_others", colspan 4 ] [] ]
:: List.map (\t -> Html.Lazy.lazy4 viewTag t (if t.id == model.selId then model.selType else NoSel) model.id model.mod) lst)
[ ("cont", "Content")
, ("ero", "Sexual content")
diff --git a/lib/VNWeb/TT/TagLinks.pm b/lib/VNWeb/TT/TagLinks.pm
index efe3e8b2..6674d383 100644
--- a/lib/VNWeb/TT/TagLinks.pm
+++ b/lib/VNWeb/TT/TagLinks.pm
@@ -16,8 +16,9 @@ sub listing_ {
td_ class => 'tc3', 'Rating';
td_ class => 'tc4', sub { txt_ 'Tag'; sortable_ 'tag', $opt, $url };
td_ class => 'tc5', 'Spoiler';
- td_ class => 'tc6', 'Visual novel';
- td_ class => 'tc7', 'Note';
+ td_ class => 'tc6', 'Lie';
+ td_ class => 'tc7', 'Visual novel';
+ td_ class => 'tc8', 'Note';
}};
tr_ sub {
my $i = $_;
@@ -32,15 +33,20 @@ sub listing_ {
a_ href => "/$i->{tag}", $i->{name};
};
td_ class => 'tc5', sub {
- my $s = !defined $i->{spoiler} ? '' : $i->{lie} ? 'False' : fmtspoil $i->{spoiler};
+ my $s = !defined $i->{spoiler} ? '' : fmtspoil $i->{spoiler};
b_ class => 'grayedout', $s if $i->{ignore};
txt_ $s if !$i->{ignore};
};
td_ class => 'tc6', sub {
+ my $s = !defined $i->{lie} ? '' : $i->{lie} ? '+' : '-';
+ b_ class => 'grayedout', $s if $i->{ignore};
+ txt_ $s if !$i->{ignore};
+ };
+ td_ class => 'tc7', sub {
a_ href => $url->(v => $i->{vid}, p=>undef), title => $i->{alttitle}||$i->{title}, class => 'setfil', '> ' if !defined $opt->{v};
a_ href => "/$i->{vid}", title => $i->{alttitle}||$i->{title}, shorten $i->{title}, 50;
};
- td_ class => 'tc7', sub { lit_ bb_format $i->{notes}, inline => 1 };
+ td_ class => 'tc8', sub { lit_ bb_format $i->{notes}, inline => 1 };
} for @$lst;
};
};
diff --git a/lib/VNWeb/VN/Tagmod.pm b/lib/VNWeb/VN/Tagmod.pm
index a20d96ad..2555fa08 100644
--- a/lib/VNWeb/VN/Tagmod.pm
+++ b/lib/VNWeb/VN/Tagmod.pm
@@ -9,7 +9,8 @@ my $FORM = {
tags => { sort_keys => 'id', aoh => {
id => { vndbid => 'g' },
vote => { int => 1, enum => [ -3..3 ] },
- spoil => { required => 0, uint => 1, enum => [ 0..3 ] },
+ spoil => { required => 0, uint => 1, enum => [ 0..2 ] },
+ lie => { undefbool => 1 },
overrule => { anybool => 1 },
notes => { required => 0, default => '', maxlength => 1000 },
cat => { _when => 'out' },
@@ -17,6 +18,7 @@ my $FORM = {
rating => { _when => 'out', num => 1 },
count => { _when => 'out', uint => 1 },
spoiler => { _when => 'out', num => 1 },
+ islie => { _when => 'out', anybool => 1 },
overruled => { _when => 'out', anybool => 1 },
othnotes => { _when => 'out' },
hidden => { _when => 'out', anybool => 1 },
@@ -58,9 +60,7 @@ elm_api Tagmod => $FORM_OUT, $FORM_IN, sub {
# Add & update tags
for(@$tags) {
my $row = { uid => auth->uid, vid => $id, tag => $_->{id}, vote => $_->{vote}, notes => $_->{notes}
- , spoiler => !defined $_->{spoil} ? undef : $_->{spoil} == 3 ? 0 : $_->{spoil}
- , lie => !defined $_->{spoil} ? undef : $_->{spoil} == 3 ? 1 : 0
- , ignore => ($_->{overruled} && !$_->{overrule})?1:0
+ , spoiler => $_->{spoil}, lie => $_->{lie}, ignore => ($_->{overruled} && !$_->{overrule})?1:0
};
tuwf->dbExeci('INSERT INTO tags_vn', $row, 'ON CONFLICT (uid, tag, vid) DO UPDATE SET', $row);
tuwf->dbExeci('UPDATE tags_vn SET ignore = TRUE WHERE uid IS DISTINCT FROM (', \auth->uid, ') AND vid =', \$id, 'AND tag =', \$_->{id}) if $_->{overrule};
@@ -83,8 +83,8 @@ TUWF::get qr{/$RE{vid}/tagmod}, sub {
my $tags = tuwf->dbAlli('
SELECT t.id, t.name, t.cat, count(*) as count, t.hidden, t.locked, t.applicable
, coalesce(avg(CASE WHEN tv.ignore OR (u.id IS NOT NULL AND NOT u.perm_tag) THEN NULL ELSE tv.vote END), 0) as rating
- , CASE WHEN count(lie) filter(where lie) > 0 and count(lie) filter (where lie) >= count(lie)>>1 THEN -1
- ELSE coalesce(avg(CASE WHEN tv.ignore OR (u.id IS NOT NULL AND NOT u.perm_tag) THEN NULL ELSE tv.spoiler END), t.defaultspoil) END as spoiler
+ , coalesce(avg(CASE WHEN tv.ignore OR (u.id IS NOT NULL AND NOT u.perm_tag) THEN NULL ELSE tv.spoiler END), t.defaultspoil) as spoiler
+ , count(lie) filter(where not tv.ignore and lie) > 0 and count(lie) filter (where not tv.ignore and lie) >= count(lie) filter (where not tv.ignore)>>1 as islie
, bool_or(tv.ignore) as overruled
FROM tags t
JOIN tags_vn tv ON tv.tag = t.id
@@ -93,7 +93,7 @@ TUWF::get qr{/$RE{vid}/tagmod}, sub {
GROUP BY t.id, t.name, t.cat
ORDER BY t.name'
);
- enrich_merge id => sub { sql 'SELECT tag AS id, vote, CASE WHEN lie THEN', \3, 'ELSE spoiler END AS spoil, ignore, notes FROM tags_vn WHERE', { uid => auth->uid, vid => $v->{id} } }, $tags;
+ enrich_merge id => sub { sql 'SELECT tag AS id, vote, spoiler AS spoil, lie, ignore, notes FROM tags_vn WHERE', { uid => auth->uid, vid => $v->{id} } }, $tags;
enrich othnotes => id => tag => sub {
sql('SELECT tv.tag, ', sql_user(), ', tv.notes FROM tags_vn tv JOIN users u ON u.id = tv.uid WHERE tv.notes <> \'\' AND uid IS DISTINCT FROM (', \auth->uid, ') AND vid=', \$v->{id})
}, $tags;
@@ -101,6 +101,7 @@ TUWF::get qr{/$RE{vid}/tagmod}, sub {
for(@$tags) {
$_->{vote} //= 0;
$_->{spoil} //= undef;
+ $_->{lie} //= undef;
$_->{notes} //= '';
$_->{overrule} = $_->{vote} && !$_->{ignore} && $_->{overruled};
$_->{othnotes} = join "\n", map user_displayname($_).': '.$_->{notes}, $_->{othnotes}->@*;