diff options
author | Yorhel <git@yorhel.nl> | 2020-07-13 11:32:52 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2020-07-13 11:32:54 +0200 |
commit | f23f9a67e17c6678bcf7ff7a32b867ba0ee80962 (patch) | |
tree | 94cd398b1efd0d6b3737b99ef85413f39c61abde /lib | |
parent | 4a3daf884119a57cd5c8bb4acda2a2c502a372ae (diff) |
Refactor: Split VNWeb::User::Lists into its own VNWeb::ULists::*
It's not exactly a tiny feature, after all. ULists::Elm should really
be split up further, too, and the sharing of structures between
ULists::Elm and ULists::List is kind of ugly at the moment, but I may
get to that later.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VNWeb/Releases/Lib.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/Releases/Page.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/ULists/Elm.pm | 252 | ||||
-rw-r--r-- | lib/VNWeb/ULists/Lib.pm | 13 | ||||
-rw-r--r-- | lib/VNWeb/ULists/List.pm (renamed from lib/VNWeb/User/Lists.pm) | 275 |
5 files changed, 278 insertions, 266 deletions
diff --git a/lib/VNWeb/Releases/Lib.pm b/lib/VNWeb/Releases/Lib.pm index 7b36a290..234de176 100644 --- a/lib/VNWeb/Releases/Lib.pm +++ b/lib/VNWeb/Releases/Lib.pm @@ -96,7 +96,7 @@ sub release_row_ { td_ class => 'tc_icons', sub { icons_ $r }; td_ class => 'tc_prod', join ' & ', $r->{publisher} ? 'Pub' : (), $r->{developer} ? 'Dev' : () if $prodpage; td_ class => 'tc5 elm_dd_left', sub { - elm_ 'UList.ReleaseEdit', $VNWeb::User::Lists::RLIST_STATUS, { rid => $r->{id}, uid => auth->uid, status => $r->{rlist_status}, empty => '--' } if auth; + elm_ 'UList.ReleaseEdit', $VNWeb::ULists::Elm::RLIST_STATUS, { rid => $r->{id}, uid => auth->uid, status => $r->{rlist_status}, empty => '--' } if auth; }; td_ class => 'tc6', sub { release_extlinks_ $r, "${id}_$r->{id}" }; } diff --git a/lib/VNWeb/Releases/Page.pm b/lib/VNWeb/Releases/Page.pm index ccf4b6fb..d7cbb745 100644 --- a/lib/VNWeb/Releases/Page.pm +++ b/lib/VNWeb/Releases/Page.pm @@ -195,7 +195,7 @@ sub _infotable_ { td_ sub { div_ class => 'elm_dd_input', style => 'width: 150px', sub { my $d = tuwf->dbVali('SELECT status FROM rlists WHERE', { rid => $r->{id}, uid => auth->uid }); - elm_ 'UList.ReleaseEdit', $VNWeb::User::Lists::RLIST_STATUS, { rid => $r->{id}, uid => auth->uid, status => $d, empty => 'not on your list' }; + elm_ 'UList.ReleaseEdit', $VNWeb::ULists::Elm::RLIST_STATUS, { rid => $r->{id}, uid => auth->uid, status => $d, empty => 'not on your list' }; } }; } if auth; diff --git a/lib/VNWeb/ULists/Elm.pm b/lib/VNWeb/ULists/Elm.pm new file mode 100644 index 00000000..0dd546c6 --- /dev/null +++ b/lib/VNWeb/ULists/Elm.pm @@ -0,0 +1,252 @@ +package VNWeb::ULists::Elm; + +use VNWeb::Prelude; +use VNWeb::ULists::Lib; + + +# Should be called after any change to the ulist_* tables. +# (Normally I'd do this with triggers, but that seemed like a more complex and less efficient solution in this case) +sub updcache { + tuwf->dbExeci(SELECT => sql_func update_users_ulist_stats => \shift); +} + + +our $LABELS = form_compile any => { + uid => { id => 1 }, + labels => { aoh => { + id => { int => 1 }, + label => { maxlength => 50 }, + private => { anybool => 1 }, + count => { uint => 1 }, + delete => { required => 0, default => undef, uint => 1, range => [1, 3] }, # 1=keep vns, 2=delete when no other label, 3=delete all + } } +}; + +elm_api UListManageLabels => undef, $LABELS, sub { + my($uid, $labels) = ($_[0]{uid}, $_[0]{labels}); + return elm_Unauth if !ulists_own $uid; + + # Insert new labels + my @new = grep $_->{id} < 0 && !$_->{delete}, @$labels; + # Subquery to get the lowest unused id + my $newid = sql '( + SELECT min(x.n) + FROM generate_series(10, + greatest((SELECT max(id)+1 from ulist_labels ul WHERE ul.uid =', \$uid, '), 10) + ) x(n) + WHERE NOT EXISTS(SELECT 1 FROM ulist_labels ul WHERE ul.uid =', \$uid, 'AND ul.id = x.n) + )'; + tuwf->dbExeci('INSERT INTO ulist_labels', { id => $newid, uid => $uid, label => $_->{label}, private => $_->{private} }) for @new; + + # Update private flag + tuwf->dbExeci( + 'UPDATE ulist_labels SET private =', \$_->{private}, + 'WHERE uid =', \$uid, 'AND id =', \$_->{id}, 'AND private <>', \$_->{private} + ) for grep $_->{id} > 0 && !$_->{delete}, @$labels; + + # Update label + tuwf->dbExeci( + 'UPDATE ulist_labels SET label =', \$_->{label}, + 'WHERE uid =', \$uid, 'AND id =', \$_->{id}, 'AND label <>', \$_->{label} + ) for grep $_->{id} >= 10 && !$_->{delete}, @$labels; + + # Delete labels + my @delete = grep $_->{id} >= 10 && $_->{delete}, @$labels; + my @delete_lblonly = map $_->{id}, grep $_->{delete} == 1, @delete; + my @delete_empty = map $_->{id}, grep $_->{delete} == 2, @delete; + my @delete_all = map $_->{id}, grep $_->{delete} == 3, @delete; + + # delete vns with: (a label in option 3) OR ((a label in option 2) AND (no labels other than in option 1 or 2)) + my @where = + @delete_all ? sql('vid IN(SELECT vid FROM ulist_vns_labels WHERE uid =', \$uid, 'AND lbl IN', \@delete_all, ')') : (), + @delete_empty ? sql( + 'vid IN(SELECT vid FROM ulist_vns_labels WHERE uid =', \$uid, 'AND lbl IN', \@delete_empty, ')', + 'AND NOT EXISTS(SELECT 1 FROM ulist_vns_labels WHERE uid =', \$uid, 'AND lbl NOT IN(', [ @delete_lblonly, @delete_empty ], '))' + ) : (); + tuwf->dbExeci('DELETE FROM ulist_vns WHERE uid =', \$uid, 'AND (', sql_or(@where), ')') if @where; + + # (This will also delete all relevant vn<->label rows from ulist_vns_labels) + tuwf->dbExeci('DELETE FROM ulist_labels WHERE uid =', \$uid, 'AND id IN', [ map $_->{id}, @delete ]) if @delete; + + updcache $uid; + elm_Success +}; + + + + +our $VNVOTE = form_compile any => { + uid => { id => 1 }, + vid => { id => 1 }, + vote => { vnvote => 1 }, +}; + +elm_api UListVoteEdit => undef, $VNVOTE, sub { + my($data) = @_; + return elm_Unauth if !ulists_own $data->{uid}; + tuwf->dbExeci( + 'INSERT INTO ulist_vns', { %$data, vote_date => sql $data->{vote} ? 'NOW()' : 'NULL' }, + 'ON CONFLICT (uid, vid) DO UPDATE + SET', { %$data, + lastmod => sql('NOW()'), + vote_date => sql $data->{vote} ? 'CASE WHEN ulist_vns.vote IS NULL THEN NOW() ELSE ulist_vns.vote_date END' : 'NULL' + } + ); + updcache $data->{uid}; + elm_Success +}; + + + + +my $VNLABELS = { + uid => { id => 1 }, + vid => { id => 1 }, + label => { _when => 'in', id => 1 }, + applied => { _when => 'in', anybool => 1 }, + labels => { _when => 'out', aoh => { id => { int => 1 }, label => {}, private => { anybool => 1 } } }, + selected => { _when => 'out', type => 'array', values => { id => 1 } }, +}; + +our $VNLABELS_OUT = form_compile out => $VNLABELS; +my $VNLABELS_IN = form_compile in => $VNLABELS; + +elm_api UListLabelEdit => $VNLABELS_OUT, $VNLABELS_IN, sub { + my($data) = @_; + return elm_Unauth if !ulists_own $data->{uid}; + die "Attempt to set vote label" if $data->{label} == 7; + + tuwf->dbExeci('INSERT INTO ulist_vns', {uid => $data->{uid}, vid => $data->{vid}}, 'ON CONFLICT (uid, vid) DO NOTHING'); + tuwf->dbExeci( + 'DELETE FROM ulist_vns_labels + WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}, 'AND lbl =', \$data->{label} + ) if !$data->{applied}; + tuwf->dbExeci( + 'INSERT INTO ulist_vns_labels', { uid => $data->{uid}, vid => $data->{vid}, lbl => $data->{label} }, + 'ON CONFLICT (uid, vid, lbl) DO NOTHING' + ) if $data->{applied}; + tuwf->dbExeci('UPDATE ulist_vns SET lastmod = NOW() WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}); + + updcache $data->{uid}; + elm_Success +}; + + + + +our $VNDATE = form_compile any => { + uid => { id => 1 }, + vid => { id => 1 }, + date => { required => 0, default => '', regex => qr/^(?:19[7-9][0-9]|20[0-9][0-9])-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$/ }, # 1970 - 2099 for sanity + start => { anybool => 1 }, # Field selection, started/finished +}; + +elm_api UListDateEdit => undef, $VNDATE, sub { + my($data) = @_; + return elm_Unauth if !ulists_own $data->{uid}; + tuwf->dbExeci( + 'UPDATE ulist_vns SET lastmod = NOW(), ', $data->{start} ? 'started' : 'finished', '=', \($data->{date}||undef), + 'WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid} + ); + updcache $data->{uid}; + elm_Success +}; + + + + +our $VNOPT = form_compile any => { + own => { anybool => 1 }, + uid => { id => 1 }, + vid => { id => 1 }, + notes => {}, + rels => $VNWeb::Elm::apis{Releases}[0], + relstatus => { type => 'array', values => { uint => 1 } }, # List of release statuses, same order as rels +}; + + + +# UListVNNotes module is abused for the UList.Opts flag definition +elm_api UListVNNotes => $VNOPT, { + uid => { id => 1 }, + vid => { id => 1 }, + notes => { required => 0, default => '', maxlength => 2000 }, +}, sub { + my($data) = @_; + return elm_Unauth if !ulists_own $data->{uid}; + tuwf->dbExeci( + 'INSERT INTO ulist_vns', \%$data, 'ON CONFLICT (uid, vid) DO UPDATE SET', { %$data, lastmod => sql('NOW()') } + ); + # Doesn't need `updcache()` + elm_Success +}; + + + + +elm_api UListDel => undef, { + uid => { id => 1 }, + vid => { id => 1 }, +}, sub { + my($data) = @_; + return elm_Unauth if !ulists_own $data->{uid}; + tuwf->dbExeci('DELETE FROM ulist_vns WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}); + updcache $data->{uid}; + elm_Success +}; + + + + +# Adds the release when not in the list. +# $RLIST_STATUS is also referenced from VNWeb::Releases::Page. +our $RLIST_STATUS = form_compile any => { + uid => { id => 1 }, + rid => { id => 1 }, + status => { required => 0, uint => 1, enum => \%RLIST_STATUS }, # undef meaning delete + empty => { required => 0, default => '' }, # An 'out' field +}; +elm_api UListRStatus => undef, $RLIST_STATUS, sub { + my($data) = @_; + delete $data->{empty}; + return elm_Unauth if !ulists_own $data->{uid}; + if(!defined $data->{status}) { + tuwf->dbExeci('DELETE FROM rlists WHERE uid =', \$data->{uid}, 'AND rid =', \$data->{rid}) + } else { + tuwf->dbExeci('INSERT INTO rlists', $data, 'ON CONFLICT (uid, rid) DO UPDATE SET status =', \$data->{status}) + } + # Doesn't need `updcache()` + elm_Success +}; + + + + +our %SAVED_OPTS = ( + # Labels + l => { onerror => [], type => 'array', scalar => 1, values => { int => 1 } }, + mul => { anybool => 1 }, + # Sort column & order + s => { onerror => 'title', enum => [qw[ title label vote voted added modified started finished rel rating ]] }, + o => { onerror => 'a', enum => ['a', 'd'] }, + # Visible columns + c => { onerror => [], type => 'array', scalar => 1, values => { enum => [qw[ label vote voted added modified started finished rel rating ]] } }, +); + +my $SAVED_OPTS = { + uid => { id => 1 }, + opts => { type => 'hash', keys => \%SAVED_OPTS }, + field => { _when => 'in', enum => [qw/ vnlist votes wish /] }, +}; + +my $SAVED_OPTS_IN = form_compile in => $SAVED_OPTS; +our $SAVED_OPTS_OUT = form_compile out => $SAVED_OPTS; + +elm_api UListSaveDefault => $SAVED_OPTS_OUT, $SAVED_OPTS_IN, sub { + my($data) = @_; + return elm_Unauth if !ulists_own $data->{uid}; + tuwf->dbExeci('UPDATE users SET ulist_'.$data->{field}, '=', \JSON::XS->new->encode($data->{opts}), 'WHERE id =', \$data->{uid}); + elm_Success +}; + +1; diff --git a/lib/VNWeb/ULists/Lib.pm b/lib/VNWeb/ULists/Lib.pm new file mode 100644 index 00000000..d831692a --- /dev/null +++ b/lib/VNWeb/ULists/Lib.pm @@ -0,0 +1,13 @@ +package VNWeb::ULists::Lib; + +use VNWeb::Prelude; +use Exporter 'import'; + +our @EXPORT = qw/ulists_own/; + +# Do we have "ownership" access to this users' list (i.e. can we edit and see private stuff)? +sub ulists_own { + auth->permUsermod || (auth && auth->uid == shift) +} + +1; diff --git a/lib/VNWeb/User/Lists.pm b/lib/VNWeb/ULists/List.pm index ff287c5e..a451e73c 100644 --- a/lib/VNWeb/User/Lists.pm +++ b/lib/VNWeb/ULists/List.pm @@ -1,263 +1,10 @@ -package VNWeb::User::Lists; +package VNWeb::ULists::Main; use VNWeb::Prelude; +use VNWeb::ULists::Lib; use POSIX 'strftime'; -# Do we have "ownership" access to this users' list (i.e. can we edit and see private stuff)? -sub own { - auth->permUsermod || (auth && auth->uid == shift) -} - - -# Should be called after any change to the ulist_* tables. -# (Normally I'd do this with triggers, but that seemed like a more complex and less efficient solution in this case) -sub updcache { - tuwf->dbExeci(SELECT => sql_func update_users_ulist_stats => \shift); -} - - -my $LABELS = form_compile any => { - uid => { id => 1 }, - labels => { aoh => { - id => { int => 1 }, - label => { maxlength => 50 }, - private => { anybool => 1 }, - count => { uint => 1 }, - delete => { required => 0, default => undef, uint => 1, range => [1, 3] }, # 1=keep vns, 2=delete when no other label, 3=delete all - } } -}; - -elm_api UListManageLabels => undef, $LABELS, sub { - my($uid, $labels) = ($_[0]{uid}, $_[0]{labels}); - return elm_Unauth if !own $uid; - - # Insert new labels - my @new = grep $_->{id} < 0 && !$_->{delete}, @$labels; - # Subquery to get the lowest unused id - my $newid = sql '( - SELECT min(x.n) - FROM generate_series(10, - greatest((SELECT max(id)+1 from ulist_labels ul WHERE ul.uid =', \$uid, '), 10) - ) x(n) - WHERE NOT EXISTS(SELECT 1 FROM ulist_labels ul WHERE ul.uid =', \$uid, 'AND ul.id = x.n) - )'; - tuwf->dbExeci('INSERT INTO ulist_labels', { id => $newid, uid => $uid, label => $_->{label}, private => $_->{private} }) for @new; - - # Update private flag - tuwf->dbExeci( - 'UPDATE ulist_labels SET private =', \$_->{private}, - 'WHERE uid =', \$uid, 'AND id =', \$_->{id}, 'AND private <>', \$_->{private} - ) for grep $_->{id} > 0 && !$_->{delete}, @$labels; - - # Update label - tuwf->dbExeci( - 'UPDATE ulist_labels SET label =', \$_->{label}, - 'WHERE uid =', \$uid, 'AND id =', \$_->{id}, 'AND label <>', \$_->{label} - ) for grep $_->{id} >= 10 && !$_->{delete}, @$labels; - - # Delete labels - my @delete = grep $_->{id} >= 10 && $_->{delete}, @$labels; - my @delete_lblonly = map $_->{id}, grep $_->{delete} == 1, @delete; - my @delete_empty = map $_->{id}, grep $_->{delete} == 2, @delete; - my @delete_all = map $_->{id}, grep $_->{delete} == 3, @delete; - - # delete vns with: (a label in option 3) OR ((a label in option 2) AND (no labels other than in option 1 or 2)) - my @where = - @delete_all ? sql('vid IN(SELECT vid FROM ulist_vns_labels WHERE uid =', \$uid, 'AND lbl IN', \@delete_all, ')') : (), - @delete_empty ? sql( - 'vid IN(SELECT vid FROM ulist_vns_labels WHERE uid =', \$uid, 'AND lbl IN', \@delete_empty, ')', - 'AND NOT EXISTS(SELECT 1 FROM ulist_vns_labels WHERE uid =', \$uid, 'AND lbl NOT IN(', [ @delete_lblonly, @delete_empty ], '))' - ) : (); - tuwf->dbExeci('DELETE FROM ulist_vns WHERE uid =', \$uid, 'AND (', sql_or(@where), ')') if @where; - - # (This will also delete all relevant vn<->label rows from ulist_vns_labels) - tuwf->dbExeci('DELETE FROM ulist_labels WHERE uid =', \$uid, 'AND id IN', [ map $_->{id}, @delete ]) if @delete; - - updcache $uid; - elm_Success -}; - - - - -my $VNVOTE = form_compile any => { - uid => { id => 1 }, - vid => { id => 1 }, - vote => { vnvote => 1 }, -}; - -elm_api UListVoteEdit => undef, $VNVOTE, sub { - my($data) = @_; - return elm_Unauth if !own $data->{uid}; - tuwf->dbExeci( - 'INSERT INTO ulist_vns', { %$data, vote_date => sql $data->{vote} ? 'NOW()' : 'NULL' }, - 'ON CONFLICT (uid, vid) DO UPDATE - SET', { %$data, - lastmod => sql('NOW()'), - vote_date => sql $data->{vote} ? 'CASE WHEN ulist_vns.vote IS NULL THEN NOW() ELSE ulist_vns.vote_date END' : 'NULL' - } - ); - updcache $data->{uid}; - elm_Success -}; - - - - -my $VNLABELS = { - uid => { id => 1 }, - vid => { id => 1 }, - label => { _when => 'in', id => 1 }, - applied => { _when => 'in', anybool => 1 }, - labels => { _when => 'out', aoh => { id => { int => 1 }, label => {}, private => { anybool => 1 } } }, - selected => { _when => 'out', type => 'array', values => { id => 1 } }, -}; - -my $VNLABELS_OUT = form_compile out => $VNLABELS; -my $VNLABELS_IN = form_compile in => $VNLABELS; - -elm_api UListLabelEdit => $VNLABELS_OUT, $VNLABELS_IN, sub { - my($data) = @_; - return elm_Unauth if !own $data->{uid}; - die "Attempt to set vote label" if $data->{label} == 7; - - tuwf->dbExeci('INSERT INTO ulist_vns', {uid => $data->{uid}, vid => $data->{vid}}, 'ON CONFLICT (uid, vid) DO NOTHING'); - tuwf->dbExeci( - 'DELETE FROM ulist_vns_labels - WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}, 'AND lbl =', \$data->{label} - ) if !$data->{applied}; - tuwf->dbExeci( - 'INSERT INTO ulist_vns_labels', { uid => $data->{uid}, vid => $data->{vid}, lbl => $data->{label} }, - 'ON CONFLICT (uid, vid, lbl) DO NOTHING' - ) if $data->{applied}; - tuwf->dbExeci('UPDATE ulist_vns SET lastmod = NOW() WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}); - - updcache $data->{uid}; - elm_Success -}; - - - - -my $VNDATE = form_compile any => { - uid => { id => 1 }, - vid => { id => 1 }, - date => { required => 0, default => '', regex => qr/^(?:19[7-9][0-9]|20[0-9][0-9])-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$/ }, # 1970 - 2099 for sanity - start => { anybool => 1 }, # Field selection, started/finished -}; - -elm_api UListDateEdit => undef, $VNDATE, sub { - my($data) = @_; - return elm_Unauth if !own $data->{uid}; - tuwf->dbExeci( - 'UPDATE ulist_vns SET lastmod = NOW(), ', $data->{start} ? 'started' : 'finished', '=', \($data->{date}||undef), - 'WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid} - ); - updcache $data->{uid}; - elm_Success -}; - - - - -my $VNOPT = form_compile any => { - own => { anybool => 1 }, - uid => { id => 1 }, - vid => { id => 1 }, - notes => {}, - rels => $VNWeb::Elm::apis{Releases}[0], - relstatus => { type => 'array', values => { uint => 1 } }, # List of release statuses, same order as rels -}; - - - -# UListVNNotes module is abused for the UList.Opts flag definition -elm_api UListVNNotes => $VNOPT, { - uid => { id => 1 }, - vid => { id => 1 }, - notes => { required => 0, default => '', maxlength => 2000 }, -}, sub { - my($data) = @_; - return elm_Unauth if !own $data->{uid}; - tuwf->dbExeci( - 'INSERT INTO ulist_vns', \%$data, 'ON CONFLICT (uid, vid) DO UPDATE SET', { %$data, lastmod => sql('NOW()') } - ); - # Doesn't need `updcache()` - elm_Success -}; - - - - -elm_api UListDel => undef, { - uid => { id => 1 }, - vid => { id => 1 }, -}, sub { - my($data) = @_; - return elm_Unauth if !own $data->{uid}; - tuwf->dbExeci('DELETE FROM ulist_vns WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}); - updcache $data->{uid}; - elm_Success -}; - - - - -# Adds the release when not in the list. -# $RLIST_STATUS is also referenced from VNWeb::Releases::Page. -our $RLIST_STATUS = form_compile any => { - uid => { id => 1 }, - rid => { id => 1 }, - status => { required => 0, uint => 1, enum => \%RLIST_STATUS }, # undef meaning delete - empty => { required => 0, default => '' }, # An 'out' field -}; -elm_api UListRStatus => undef, $RLIST_STATUS, sub { - my($data) = @_; - delete $data->{empty}; - return elm_Unauth if !own $data->{uid}; - if(!defined $data->{status}) { - tuwf->dbExeci('DELETE FROM rlists WHERE uid =', \$data->{uid}, 'AND rid =', \$data->{rid}) - } else { - tuwf->dbExeci('INSERT INTO rlists', $data, 'ON CONFLICT (uid, rid) DO UPDATE SET status =', \$data->{status}) - } - # Doesn't need `updcache()` - elm_Success -}; - - - - -my %SAVED_OPTS = ( - # Labels - l => { onerror => [], type => 'array', scalar => 1, values => { int => 1 } }, - mul => { anybool => 1 }, - # Sort column & order - s => { onerror => 'title', enum => [qw[ title label vote voted added modified started finished rel rating ]] }, - o => { onerror => 'a', enum => ['a', 'd'] }, - # Visible columns - c => { onerror => [], type => 'array', scalar => 1, values => { enum => [qw[ label vote voted added modified started finished rel rating ]] } }, -); - -my $SAVED_OPTS = { - uid => { id => 1 }, - opts => { type => 'hash', keys => \%SAVED_OPTS }, - field => { _when => 'in', enum => [qw/ vnlist votes wish /] }, -}; - -my $SAVED_OPTS_IN = form_compile in => $SAVED_OPTS; -my $SAVED_OPTS_OUT = form_compile out => $SAVED_OPTS; - -elm_api UListSaveDefault => $SAVED_OPTS_OUT, $SAVED_OPTS_IN, sub { - my($data) = @_; - return elm_Unauth if !own $data->{uid}; - tuwf->dbExeci('UPDATE users SET ulist_'.$data->{field}, '=', \JSON::XS->new->encode($data->{opts}), 'WHERE id =', \$data->{uid}); - elm_Success -}; - - - - sub opt { my($u, $filtlabels) = @_; @@ -273,7 +20,7 @@ sub opt { p => { upage => 1 }, ch=> { onerror => undef, enum => [ 'a'..'z', 0 ] }, q => { onerror => undef }, - %SAVED_OPTS + %VNWeb::ULists::Elm::SAVED_OPTS )->data; # $labels only includes labels we are allowed to see, getting rid of any labels in 'l' that aren't in $labels ensures we only filter on visible labels @@ -364,7 +111,7 @@ sub vn_ { td_ mkclass(tc_vote => 1, compact => $own, stealth => $own), sub { txt_ fmtvote $v->{vote} if !$own; - elm_ 'UList.VoteEdit' => $VNVOTE, { uid => $uid, vid => $v->{id}, vote => fmtvote($v->{vote}) }, fmtvote $v->{vote} + elm_ 'UList.VoteEdit' => $VNWeb::ULists::Elm::VNVOTE, { uid => $uid, vid => $v->{id}, vote => fmtvote($v->{vote}) }, fmtvote $v->{vote} if $own && ($v->{vote} || sprintf('%08d', $v->{c_released}||0) < strftime '%Y%m%d', gmtime); } if in vote => $opt->{c}; @@ -377,7 +124,7 @@ sub vn_ { my @l = grep $labels{$_->{id}} && $_->{id} != 7, @$labels; my $txt = @l ? join ', ', map $_->{label}, @l : '-'; if($own) { - elm_ 'UList.LabelEdit' => $VNLABELS_OUT, { vid => $v->{id}, selected => [ grep $_ != 7, $v->{labels}->@* ] }, $txt; + elm_ 'UList.LabelEdit' => $VNWeb::ULists::Elm::VNLABELS_OUT, { vid => $v->{id}, selected => [ grep $_ != 7, $v->{labels}->@* ] }, $txt; } else { txt_ $txt; } @@ -393,12 +140,12 @@ sub vn_ { td_ class => 'tc_started', sub { txt_ $v->{started}||'' if !$own; - elm_ 'UList.DateEdit' => $VNDATE, { uid => $uid, vid => $v->{id}, date => $v->{started}||'', start => 1 }, $v->{started}||'' if $own; + elm_ 'UList.DateEdit' => $VNWeb::ULists::Elm::VNDATE, { uid => $uid, vid => $v->{id}, date => $v->{started}||'', start => 1 }, $v->{started}||'' if $own; } if in started => $opt->{c}; td_ class => 'tc_finished', sub { txt_ $v->{finished}||'' if !$own; - elm_ 'UList.DateEdit' => $VNDATE, { uid => $uid, vid => $v->{id}, date => $v->{finished}||'', start => 0 }, $v->{finished}||'' if $own; + elm_ 'UList.DateEdit' => $VNWeb::ULists::Elm::VNDATE, { uid => $uid, vid => $v->{id}, date => $v->{finished}||'', start => 0 }, $v->{finished}||'' if $own; } if in finished => $opt->{c}; td_ class => 'tc_rel', sub { rdate_ $v->{c_released} } if in rel => $opt->{c}; @@ -407,7 +154,7 @@ sub vn_ { tr_ mkclass(hidden => 1, 'collapsed_vid'.$v->{id} => 1, odd => $n % 2 == 0), sub { td_ colspan => 7, class => 'tc_opt', sub { my $relstatus = [ map $_->{status}, $v->{rels}->@* ]; - elm_ 'UList.Opt' => $VNOPT, { own => $own, uid => $uid, vid => $v->{id}, notes => $v->{notes}, rels => $v->{rels}, relstatus => $relstatus }; + elm_ 'UList.Opt' => $VNWeb::ULists::Elm::VNOPT, { own => $own, uid => $uid, vid => $v->{id}, notes => $v->{notes}, rels => $v->{rels}, relstatus => $relstatus }; }; }; } @@ -517,7 +264,7 @@ TUWF::get qr{/$RE{uid}/ulist}, sub { my $u = tuwf->dbRowi('SELECT id,', sql_user(), ', ulist_votes, ulist_vnlist, ulist_wish FROM users u WHERE id =', \tuwf->capture('id')); return tuwf->resNotFound if !$u->{id}; - my $own = own $u->{id}; + my $own = ulists_own $u->{id}; # Visible and selectable labels my $labels = tuwf->dbAlli( @@ -562,7 +309,7 @@ TUWF::get qr{/$RE{uid}/ulist}, sub { framework_ title => $title, type => 'u', dbobj => $u, tab => $tab, js => 1, $own ? ( pagevars => { uid => $u->{id}*1, - labels => $LABELS->analyze->{keys}{labels}->coerce_for_json($labels), + labels => $VNWeb::ULists::Elm::LABELS->analyze->{keys}{labels}->coerce_for_json($labels), voteprivate => (map \($_->{private}?1:0), grep $_->{id} == 7, @$labels), } ) : (), sub { @@ -576,7 +323,7 @@ TUWF::get qr{/$RE{uid}/ulist}, sub { } else { filters_ $own, $filtlabels, $opt, $opt_labels, \&url; elm_ 'UList.ManageLabels' if $own; - elm_ 'UList.SaveDefault', $SAVED_OPTS_OUT, { uid => $u->{id}, opts => $opt } if $own; + elm_ 'UList.SaveDefault', $VNWeb::ULists::Elm::SAVED_OPTS_OUT, { uid => $u->{id}, opts => $opt } if $own; } }; listing_ $u->{id}, $own, $opt, $labels, \&url if !$empty; |