summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2020-08-25 09:31:30 +0200
committerYorhel <git@yorhel.nl>2020-08-25 09:33:00 +0200
commitb608999b020fce26fd7dd07078b240d18a312953 (patch)
treef46fd186b2bbfd5dd175ff298cc1819b668855ef
parent00ef4b38f81df579b2eae6fc042ca95c8083d0d5 (diff)
UList.VNPage: Use schema to normalize data + disallow undef schema
Mistyping a namespaced variable results in undef, which was interpreted to mean "don't use a schema", which is rarely what you want. Throwing a hard error makes such typos a lot more visible.
-rw-r--r--elm/UList/VNPage.elm25
-rw-r--r--lib/VNWeb/HTML.pm6
-rw-r--r--lib/VNWeb/Reviews/Page.pm4
-rw-r--r--lib/VNWeb/Reviews/VNTab.pm4
-rw-r--r--lib/VNWeb/ULists/Elm.pm15
-rw-r--r--lib/VNWeb/ULists/List.pm2
-rw-r--r--lib/VNWeb/VN/Page.pm14
7 files changed, 32 insertions, 38 deletions
diff --git a/elm/UList/VNPage.elm b/elm/UList/VNPage.elm
index 64c5f99a..7746e836 100644
--- a/elm/UList/VNPage.elm
+++ b/elm/UList/VNPage.elm
@@ -18,26 +18,7 @@ import Gen.UListDel as GDE
import UList.LabelEdit as LE
import UList.VoteEdit as VE
--- We don't have a Gen.* module for this (yet), so define these manually
-type alias RecvLabels =
- { id : Int
- , label : String
- , private : Bool
- }
-
-type alias Recv =
- { uid : Int
- , vid : Int
- , onlist : Bool
- , canvote : Bool
- , vote : Maybe String
- , labels : List RecvLabels
- , selected : List Int
- , notes : String
- }
-
-
-main : Program Recv Model Msg
+main : Program GVN.VNPage Model Msg
main = Browser.element
{ init = \f -> (init f, Cmd.none)
, subscriptions = \model -> Sub.batch [ Sub.map Labels (DD.sub model.labels.dd), Sub.map Vote (DD.sub model.vote.dd) ]
@@ -46,7 +27,7 @@ main = Browser.element
}
type alias Model =
- { flags : Recv
+ { flags : GVN.VNPage
, onlist : Bool
, del : Bool
, state : Api.State -- For adding/deleting; Vote and label edit widgets have their own state
@@ -58,7 +39,7 @@ type alias Model =
, notesVis : Bool
}
-init : Recv -> Model
+init : GVN.VNPage -> Model
init f =
{ flags = f
, onlist = f.onlist
diff --git a/lib/VNWeb/HTML.pm b/lib/VNWeb/HTML.pm
index 28cfa66a..496427ad 100644
--- a/lib/VNWeb/HTML.pm
+++ b/lib/VNWeb/HTML.pm
@@ -116,10 +116,12 @@ sub spoil_ {
}
-# Instantiate an Elm module
+# Instantiate an Elm module.
+# $schema can be set to the string 'raw' to encode the JSON directly, without a normalizing through a schema.
sub elm_ {
my($mod, $schema, $data, $placeholder) = @_;
- push tuwf->req->{pagevars}{elm}->@*, [ $mod, $data ? ($schema ? $schema->analyze->coerce_for_json($data, unknown => 'remove') : $data) : () ];
+ die "Elm data without a schema" if defined $data && !defined $schema;
+ push tuwf->req->{pagevars}{elm}->@*, [ $mod, $data ? ($schema eq 'raw' ? $data : $schema->analyze->coerce_for_json($data, unknown => 'remove')) : () ];
div_ id => sprintf('elm%d', $#{ tuwf->req->{pagevars}{elm} }), $placeholder//'';
}
diff --git a/lib/VNWeb/Reviews/Page.pm b/lib/VNWeb/Reviews/Page.pm
index 4a8d6b6b..27f10920 100644
--- a/lib/VNWeb/Reviews/Page.pm
+++ b/lib/VNWeb/Reviews/Page.pm
@@ -71,7 +71,7 @@ TUWF::get qr{/$RE{wid}(?:(?<sep>[\./])$RE{num})?}, sub {
return tuwf->resNotFound if !auth->permReview; #XXX:While in beta
my($id, $sep, $num) = (tuwf->capture('id'), tuwf->capture('sep')||'', tuwf->capture('num'));
my $w = tuwf->dbRowi(
- 'SELECT r.id, r.vid, r.rid, r.isfull, r.text, r.spoiler, COALESCE(c.count,0) AS count, r.c_up, r.c_down, uv.vote, r2.id IS NULL AS can
+ 'SELECT r.id, r.vid, r.rid, r.isfull, r.text, r.spoiler, COALESCE(c.count,0) AS count, r.c_up, r.c_down, uv.vote, rm.id IS NULL AS can
, rel.title AS rtitle, rel.original AS roriginal, rel.type AS rtype, rv.vote AS my
, ', sql_user(), ',', sql_totime('r.date'), 'AS date,', sql_totime('r.lastmod'), 'AS lastmod
FROM reviews r
@@ -80,7 +80,7 @@ TUWF::get qr{/$RE{wid}(?:(?<sep>[\./])$RE{num})?}, sub {
LEFT JOIN ulist_vns uv ON uv.uid = r.uid AND uv.vid = r.vid
LEFT JOIN (SELECT id, COUNT(*) FROM reviews_posts GROUP BY id) AS c(id,count) ON c.id = r.id
LEFT JOIN reviews_votes rv ON rv.id = r.id AND rv.uid =', \auth->uid, '
- LEFT JOIN reviews r2 ON r2.vid = r.vid AND r2.uid =', \auth->uid, '
+ LEFT JOIN reviews rm ON rm.vid = r.vid AND rm.uid =', \auth->uid, '
WHERE r.id =', \$id
);
return tuwf->resNotFound if !$w->{id};
diff --git a/lib/VNWeb/Reviews/VNTab.pm b/lib/VNWeb/Reviews/VNTab.pm
index 49850f36..b91cd2ca 100644
--- a/lib/VNWeb/Reviews/VNTab.pm
+++ b/lib/VNWeb/Reviews/VNTab.pm
@@ -9,13 +9,13 @@ sub reviews_ {
# TODO: Order, pagination
my $lst = tuwf->dbAlli(
- 'SELECT r.id, r.rid, r.text, r.spoiler, r.c_up, r.c_down, r.c_count, uv.vote, rv.vote AS my, NOT r.isfull AND r2.id IS NULL AS can
+ 'SELECT r.id, r.rid, r.text, r.spoiler, r.c_up, r.c_down, r.c_count, uv.vote, rv.vote AS my, NOT r.isfull AND rm.id IS NULL AS can
, ', sql_totime('r.date'), 'AS date, ', sql_user(), '
FROM reviews r
LEFT JOIN users u ON r.uid = u.id
LEFT JOIN ulist_vns uv ON uv.uid = r.uid AND uv.vid = r.vid
LEFT JOIN reviews_votes rv ON rv.uid =', \auth->uid, ' AND rv.id = r.id
- LEFT JOIN reviews r2 ON r2.vid = r.vid AND r2.uid =', \auth->uid, '
+ LEFT JOIN reviews rm ON rm.vid = r.vid AND rm.uid =', \auth->uid, '
WhERE r.vid =', \$v->{id}, 'AND', ($mini ? 'NOT' : ''), 'r.isfull'
);
diff --git a/lib/VNWeb/ULists/Elm.pm b/lib/VNWeb/ULists/Elm.pm
index 0dd546c6..33ad9b86 100644
--- a/lib/VNWeb/ULists/Elm.pm
+++ b/lib/VNWeb/ULists/Elm.pm
@@ -165,8 +165,19 @@ our $VNOPT = form_compile any => {
};
+our $VNPAGE = form_compile any => {
+ uid => { id => 1 },
+ vid => { id => 1 },
+ onlist => { anybool => 1 },
+ canvote => { anybool => 1 },
+ vote => { vnvote => 1 },
+ notes => { required => 0, default => '' },
+ labels => { aoh => { id => { int => 1 }, label => {}, private => { anybool => 1 } } },
+ selected => { type => 'array', values => { id => 1 } },
+};
-# UListVNNotes module is abused for the UList.Opts flag definition
+
+# UListVNNotes module is abused for the UList.Opts and UList.VNPage flag definition
elm_api UListVNNotes => $VNOPT, {
uid => { id => 1 },
vid => { id => 1 },
@@ -179,7 +190,7 @@ elm_api UListVNNotes => $VNOPT, {
);
# Doesn't need `updcache()`
elm_Success
-};
+}, VNPage => $VNPAGE;
diff --git a/lib/VNWeb/ULists/List.pm b/lib/VNWeb/ULists/List.pm
index a3716006..3d2bf681 100644
--- a/lib/VNWeb/ULists/List.pm
+++ b/lib/VNWeb/ULists/List.pm
@@ -222,7 +222,7 @@ sub listing_ {
# TODO: Thumbnail view?
paginate_ $url, $opt->{p}, [ $count, 50 ], 't', sub {
- elm_ ColSelect => undef, [ $url->(), [
+ elm_ ColSelect => 'raw', [ $url->(), [
[ voted => 'Vote date' ],
[ vote => 'Vote' ],
[ rating => 'Rating' ],
diff --git a/lib/VNWeb/VN/Page.pm b/lib/VNWeb/VN/Page.pm
index 3e48437d..6dcd3fc9 100644
--- a/lib/VNWeb/VN/Page.pm
+++ b/lib/VNWeb/VN/Page.pm
@@ -310,14 +310,14 @@ sub infobox_useroptions_ {
tr_ class => 'nostripe', sub {
td_ colspan => 2, sub {
- elm_ 'UList.VNPage', undef, { # TODO: Go through a TUWF::Validation schema
- uid => 1*auth->uid,
- vid => 1*$v->{id},
- onlist => $lst->{vid}?\1:\0,
- canvote => canvote($v)?\1:\0,
- vote => fmtvote($lst->{vote}).'',
+ elm_ 'UList.VNPage', $VNWeb::ULists::Elm::VNPAGE, {
+ uid => auth->uid,
+ vid => $v->{id},
+ onlist => $lst->{vid}||0,
+ canvote => canvote($v),
+ vote => fmtvote($lst->{vote}),
notes => $lst->{notes}||'',
- labels => [ map +{ id => 1*$_->{id}, label => $_->{label}, private => $_->{private}?\1:\0 }, @$labels ],
+ labels => $labels,
selected => [ map $_->{id}, grep $_->{assigned}, @$labels ],
};
}