summaryrefslogtreecommitdiff
path: root/lib/VNWeb/User/Lists.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VNWeb/User/Lists.pm')
-rw-r--r--lib/VNWeb/User/Lists.pm249
1 files changed, 136 insertions, 113 deletions
diff --git a/lib/VNWeb/User/Lists.pm b/lib/VNWeb/User/Lists.pm
index fb09a8e4..7c8237c5 100644
--- a/lib/VNWeb/User/Lists.pm
+++ b/lib/VNWeb/User/Lists.pm
@@ -2,6 +2,8 @@ package VNWeb::User::Lists;
use VNWeb::Prelude;
+
+
my $LABELS = form_compile any => {
uid => { id => 1 },
labels => { aoh => {
@@ -13,7 +15,60 @@ my $LABELS = form_compile any => {
} }
};
-elm_form 'ManageLabels', undef, $LABELS;
+elm_form 'UListManageLabels', undef, $LABELS;
+
+json_api qr{/u/ulist/labels.json}, $LABELS, sub {
+ my($uid, $labels) = ($_[0]{uid}, $_[0]{labels});
+ return elm_Unauth if !auth || auth->uid != $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, uid, label, private)
+ VALUES (', sql_comma($newid, \$uid, \$_->{label}, \$_->{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;
+
+ elm_Success
+};
+
@@ -23,7 +78,20 @@ my $VNVOTE = form_compile any => {
vote => { vnvote => 1 },
};
-elm_form 'VoteEdit', undef, $VNVOTE;
+elm_form 'UListVoteEdit', undef, $VNVOTE;
+
+json_api qr{/u/ulist/setvote.json}, $VNVOTE, sub {
+ my($data) = @_;
+ return elm_Unauth if !auth || auth->uid != $data->{uid};
+ tuwf->dbExeci(
+ 'UPDATE ulist_vns
+ SET vote =', \$data->{vote},
+ ', vote_date = CASE WHEN', \$data->{vote}, '::smallint IS NULL THEN NULL WHEN vote IS NULL THEN NOW() ELSE vote_date END
+ WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}
+ );
+ elm_Success
+};
+
@@ -39,7 +107,26 @@ my $VNLABELS = {
my $VNLABELS_OUT = form_compile out => $VNLABELS;
my $VNLABELS_IN = form_compile in => $VNLABELS;
-elm_form 'LabelEdit', $VNLABELS_OUT, $VNLABELS_IN;
+elm_form 'UListLabelEdit', $VNLABELS_OUT, $VNLABELS_IN;
+
+json_api qr{/u/ulist/setlabel.json}, $VNLABELS_IN, sub {
+ my($data) = @_;
+ return elm_Unauth if !auth || auth->uid != $data->{uid};
+ die "Attempt to set vote label" if $data->{label} == 7;
+
+ 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, vid, lbl)
+ VALUES (', sql_comma(\$data->{uid}, \$data->{vid}, \$data->{label}), ')
+ ON CONFLICT (uid, vid, lbl) DO NOTHING'
+ ) if $data->{applied};
+
+ elm_Success
+};
+
@@ -50,7 +137,18 @@ my $VNDATE = form_compile any => {
start => { anybool => 1 }, # Field selection, started/finished
};
-elm_form 'DateEdit', undef, $VNDATE;
+elm_form 'UListDateEdit', undef, $VNDATE;
+
+json_api qr{/u/ulist/setdate.json}, $VNDATE, sub {
+ my($data) = @_;
+ return elm_Unauth if !auth || auth->uid != $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}
+ );
+ elm_Success
+};
+
@@ -58,7 +156,7 @@ my $VNOPT = form_compile any => {
own => { anybool => 1 },
uid => { id => 1 },
vid => { id => 1 },
- notes => { required => 0, default => '', maxlength => 2000 },
+ notes => {},
rels => { aoh => {
id => { id => 1 },
title => {},
@@ -70,7 +168,29 @@ my $VNOPT = form_compile any => {
} },
};
-elm_form 'UListVNOpt', undef, $VNOPT;
+elm_form 'UListVNOpt', $VNOPT, undef;
+
+
+
+
+my $VNNOTES = form_compile any => {
+ uid => { id => 1 },
+ vid => { id => 1 },
+ notes => { required => 0, default => '', maxlength => 2000 },
+};
+
+elm_form 'UListVNNotes', undef, $VNNOTES;
+
+json_api qr{/u/ulist/setnote.json}, $VNNOTES, sub {
+ my($data) = @_;
+ return elm_Unauth if !auth || auth->uid != $data->{uid};
+ tuwf->dbExeci(
+ 'UPDATE ulist_vns SET lastmod = NOW(), notes = ', \$data->{notes},
+ 'WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}
+ );
+ elm_Success
+};
+
@@ -81,6 +201,14 @@ my $VNDEL = form_compile any => {
elm_form 'UListDel', undef, $VNDEL;
+json_api qr{/u/ulist/del.json}, $VNDEL, sub {
+ my($data) = @_;
+ return elm_Unauth if !auth || auth->uid != $data->{uid};
+ tuwf->dbExeci('DELETE FROM ulist_vns WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid});
+ elm_Success
+};
+
+
# TODO: Filters to find unlabeled VNs or VNs with/without notes?
@@ -147,7 +275,7 @@ sub vn_ {
if($total && $obtained == $total) { b_ class => 'done', $txt }
elsif($obtained < $total) { b_ class => 'todo', $txt }
else { txt_ $txt }
- span_ $v->{notes} ? () : (style => 'opacity: 0.5'), ' 💬';
+ span_ id => 'ulist_noteflag_'.$v->{id}, mkclass(blurred => !$v->{notes}), ' 💬';
if($own) {
my $public = List::Util::any { $labels{$_->{id}} && !$_->{private} } @$labels;
my $publicLabel = List::Util::any { $_->{id} != 7 && $labels{$_->{id}} && !$_->{private} } @$labels;
@@ -161,7 +289,7 @@ sub vn_ {
};
td_ class => 'tc2', sub {
a_ href => "/v$v->{id}", title => $v->{original}||$v->{title}, shorten $v->{title}, 70;
- b_ class => 'grayedout', $v->{notes} if $v->{notes};
+ b_ class => 'grayedout', id => 'ulist_notes_'.$v->{id}, $v->{notes} if $v->{notes} || $own;
};
td_ class => 'tc3', sub {
my @l = grep $labels{$_->{id}} && $_->{id} != 7, @$labels;
@@ -294,109 +422,4 @@ TUWF::get qr{/$RE{uid}/ulist}, sub {
};
};
-
-json_api qr{/u/ulist/labels.json}, $LABELS, sub {
- my($uid, $labels) = ($_[0]{uid}, $_[0]{labels});
- return elm_Unauth if !auth || auth->uid != $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, uid, label, private)
- VALUES (', sql_comma($newid, \$uid, \$_->{label}, \$_->{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;
-
- elm_Success
-};
-
-
-# XXX: Doesn't add the VN to the list if it isn't in there, yet.
-json_api qr{/u/ulist/setvote.json}, $VNVOTE, sub {
- my($data) = @_;
- return elm_Unauth if !auth || auth->uid != $data->{uid};
- tuwf->dbExeci(
- 'UPDATE ulist_vns
- SET vote =', \$data->{vote},
- ', vote_date = CASE WHEN', \$data->{vote}, '::smallint IS NULL THEN NULL WHEN vote IS NULL THEN NOW() ELSE vote_date END
- WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}
- );
- elm_Success
-};
-
-
-json_api qr{/u/ulist/setlabel.json}, $VNLABELS_IN, sub {
- my($data) = @_;
- return elm_Unauth if !auth || auth->uid != $data->{uid};
- die "Attempt to set vote label" if $data->{label} == 7;
-
- 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, vid, lbl)
- VALUES (', sql_comma(\$data->{uid}, \$data->{vid}, \$data->{label}), ')
- ON CONFLICT (uid, vid, lbl) DO NOTHING'
- ) if $data->{applied};
-
- elm_Success
-};
-
-
-json_api qr{/u/ulist/setdate.json}, $VNDATE, sub {
- my($data) = @_;
- return elm_Unauth if !auth || auth->uid != $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}
- );
- elm_Success
-};
-
-
-json_api qr{/u/ulist/del.json}, $VNDEL, sub {
- my($data) = @_;
- return elm_Unauth if !auth || auth->uid != $data->{uid};
- tuwf->dbExeci('DELETE FROM ulist_vns WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid});
- elm_Success
-};
-
1;