summaryrefslogtreecommitdiff
path: root/lib/VNWeb
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2021-06-28 07:53:27 +0200
committerYorhel <git@yorhel.nl>2021-07-08 16:11:33 +0200
commitf936faa64f4dae3035159dfa454bf044ba05c517 (patch)
treee84448438a6ce07a50245c0c6794438881ca2810 /lib/VNWeb
parent7c08ad43f59ab237d7fd011fb285e26db9dc5c2d (diff)
Ulist.Widget: Experiment with a VN list management widget
Currently only added on VN listings in row view, but the goal is to add this widget to other listings and pages as well. This should make it easy to see whether a VN is on your list and to add/remove/edit your list status. The code is one of the messiest copy-paste jobs I've ever done. I'm totally going to regret having to maintain this crap. But anyway, let's first see how this UI is received.
Diffstat (limited to 'lib/VNWeb')
-rw-r--r--lib/VNWeb/AdvSearch.pm1
-rw-r--r--lib/VNWeb/Elm.pm22
-rw-r--r--lib/VNWeb/ULists/Elm.pm33
-rw-r--r--lib/VNWeb/VN/List.pm23
4 files changed, 64 insertions, 15 deletions
diff --git a/lib/VNWeb/AdvSearch.pm b/lib/VNWeb/AdvSearch.pm
index 6c8474cf..7e610fd6 100644
--- a/lib/VNWeb/AdvSearch.pm
+++ b/lib/VNWeb/AdvSearch.pm
@@ -751,6 +751,7 @@ sub elm_search_query {
sub elm_ {
my($self) = @_;
+ # TODO: labels can be lazily loaded to reduce page weight
state $schema ||= tuwf->compile({ type => 'hash', keys => {
uid => { vndbid => 'u', required => 0 },
labels => { aoh => { id => { uint => 1 }, label => {} } },
diff --git a/lib/VNWeb/Elm.pm b/lib/VNWeb/Elm.pm
index 68b244c7..1c02a5fe 100644
--- a/lib/VNWeb/Elm.pm
+++ b/lib/VNWeb/Elm.pm
@@ -168,7 +168,27 @@ $apis{AdvSearchQuery} = [ { type => 'hash', keys => { # Response to 'AdvSearchLo
tags => $apis{TagResult}[0],
traits => $apis{TraitResult}[0],
anime => $apis{AnimeResult}[0],
-} } ],
+} } ];
+$apis{UListWidget} = [ { type => 'hash', keys => { # Initialization for UList.Widget and response to UListWidget
+ uid => { vndbid => 'u' },
+ vid => { vndbid => 'v' },
+ # Only includes selected labels, null if the VN is not on the list at all.
+ labels => { required => 0, aoh => { id => { int => 1 }, label => {required => 0, default => ''} } },
+ # Can be set to null to lazily load the extra data as needed
+ full => { required => 0, type => 'hash', keys => {
+ title => {},
+ labels => { aoh => { id => { int => 1 }, label => {}, private => { anybool => 1 } } },
+ canvote => { anybool => 1 },
+ canreview => { anybool => 1 },
+ vote => { vnvote => 1 },
+ review => { required => 0, vndbid => 'w' },
+ notes => { required => 0, default => '' },
+ started => { required => 0, default => '' },
+ finished => { required => 0, default => '' },
+ releases => $apis{Releases}[0],
+ rlist => { aoh => { id => { vndbid => 'r' }, status => { uint => 1 } } },
+ } },
+} } ];
# Compile %apis into a %schema and generate the elm_Response() functions
diff --git a/lib/VNWeb/ULists/Elm.pm b/lib/VNWeb/ULists/Elm.pm
index e1a61737..0d9eeb06 100644
--- a/lib/VNWeb/ULists/Elm.pm
+++ b/lib/VNWeb/ULists/Elm.pm
@@ -2,6 +2,7 @@ package VNWeb::ULists::Elm;
use VNWeb::Prelude;
use VNWeb::ULists::Lib;
+use VNWeb::Releases::Lib 'releases_by_vn';
# Should be called after any change to the ulist_* tables.
@@ -235,6 +236,38 @@ elm_api UListRStatus => undef, $RLIST_STATUS, sub {
+our $WIDGET = form_compile out => $VNWeb::Elm::apis{UListWidget}[0]{keys};
+
+elm_api UListWidget => $WIDGET, { uid => { vndbid => 'u' }, vid => { vndbid => 'v' } }, sub {
+ my($data) = @_;
+ return elm_Unauth if !ulists_own $data->{uid};
+ my $v = tuwf->dbRowi('SELECT title, c_released FROM vn WHERE id =', \$data->{vid});
+ return elm_Invalid if !defined $v->{title};
+ my $lst = tuwf->dbRowi('SELECT vid, vote, notes, started, finished FROM ulist_vns WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid});
+ my $review = tuwf->dbVali('SELECT id FROM reviews WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid});
+ my $canvote = sprintf('%08d', $v->{c_released}||0) < strftime '%Y%m%d', gmtime;
+ elm_UListWidget {
+ uid => $data->{uid},
+ vid => $data->{vid},
+ labels => !$lst->{vid} ? undef : tuwf->dbAlli('SELECT lbl AS id, \'\' AS label FROM ulist_vns_labels WHERE uid =', \$data->{uid}, 'AND vid =', \$data->{vid}),
+ full => {
+ title => $v->{title},
+ labels => tuwf->dbAlli('SELECT id, label, private FROM ulist_labels WHERE uid =', \$data->{uid}, 'ORDER BY CASE WHEN id < 10 THEN id ELSE 10 END, label'),
+ canvote => $lst->{vote} || $canvote || 0,
+ canreview => $review || ($canvote && can_edit(w => {})) || 0,
+ vote => fmtvote($lst->{vote}),
+ review => $review,
+ notes => $lst->{notes}||'',
+ started => $lst->{started}||'',
+ finished => $lst->{finished}||'',
+ releases => releases_by_vn($data->{vid}),
+ rlist => tuwf->dbAlli('SELECT rid AS id, status FROM rlists WHERE uid =', \$data->{uid}, 'AND rid IN(SELECT id FROM releases_vn WHERE vid =', \$data->{vid}, ')'),
+ },
+ };
+};
+
+
+
our %SAVED_OPTS = (
# Labels
diff --git a/lib/VNWeb/VN/List.pm b/lib/VNWeb/VN/List.pm
index 670c8358..0c28a1c4 100644
--- a/lib/VNWeb/VN/List.pm
+++ b/lib/VNWeb/VN/List.pm
@@ -97,9 +97,12 @@ sub listing_ {
}, sort { $a->{name} cmp $b->{name} || $a->{id} <=> $b->{id} } $_->{developers}->@*;
} if $opt->{s}->vis('developer');
td_ class => 'tc_ulist', sub {
- b_ class => $_->{userlist_obtained} == $_->{userlist_all} ? 'done' : 'todo', sprintf '%d/%d', $_->{userlist_obtained}, $_->{userlist_all} if $_->{userlist_all};
- abbr_ title => join(', ', $_->{vnlist_labels}->@*), scalar $_->{vnlist_labels}->@* if $_->{vnlist_labels} && $_->{vnlist_labels}->@*;
- abbr_ title => 'No labels', ' ' if $_->{vnlist_labels} && !$_->{vnlist_labels}->@*;
+ elm_ 'UList.Widget', $VNWeb::ULists::Elm::WIDGET, {
+ uid => auth->uid,
+ vid => $_->{id},
+ labels => $_->{on_vnlist} ? $_->{vnlist_labels} : undef,
+ full => undef,
+ } if auth;
};
td_ class => 'tc_plat', sub { join_ '', sub { platform_ $_ if $_ ne 'unk' }, sort $_->{platforms}->@* };
td_ class => 'tc_lang', sub { join_ '', sub { abbr_ class => "icons lang $_", title => $LANGUAGE{$_}, '' }, reverse sort $_->{lang}->@* };
@@ -202,18 +205,10 @@ sub enrich_listing {
enrich_image_obj image => @_ if !$opt->{s}->rows;
- enrich_merge id => sub { sql '
- SELECT irv.vid AS id
- , COUNT(*) AS userlist_all
- , SUM(CASE WHEN irl.status = 1+1 THEN 1 ELSE 0 END) AS userlist_obtained
- FROM rlists irl
- JOIN releases_vn irv ON irv.id = irl.rid
- WHERE irl.uid =', \auth->uid, 'AND irv.vid IN', $_, '
- GROUP BY irv.vid
- ' }, @_ if auth;
+ enrich_merge id => sql('SELECT vid AS id, true AS on_vnlist FROM ulist_vns WHERE uid =', \auth->uid, 'AND vid IN'), @_ if auth;
- enrich_flatten vnlist_labels => id => vid => sub { sql '
- SELECT uvl.vid, ul.label
+ enrich vnlist_labels => id => vid => sub { sql '
+ SELECT uvl.vid, ul.id, ul.label
FROM ulist_vns_labels uvl
JOIN ulist_labels ul ON ul.uid = uvl.uid AND ul.id = uvl.lbl
WHERE uvl.uid =', \auth->uid, 'AND uvl.vid IN', $_[0], '