diff options
author | Yorhel <git@yorhel.nl> | 2020-08-25 09:31:30 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2020-08-25 09:33:00 +0200 |
commit | b608999b020fce26fd7dd07078b240d18a312953 (patch) | |
tree | f46fd186b2bbfd5dd175ff298cc1819b668855ef | |
parent | 00ef4b38f81df579b2eae6fc042ca95c8083d0d5 (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.elm | 25 | ||||
-rw-r--r-- | lib/VNWeb/HTML.pm | 6 | ||||
-rw-r--r-- | lib/VNWeb/Reviews/Page.pm | 4 | ||||
-rw-r--r-- | lib/VNWeb/Reviews/VNTab.pm | 4 | ||||
-rw-r--r-- | lib/VNWeb/ULists/Elm.pm | 15 | ||||
-rw-r--r-- | lib/VNWeb/ULists/List.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/VN/Page.pm | 14 |
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 ], }; } |