summaryrefslogtreecommitdiff
path: root/lib/VNWeb/Chars/List.pm
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2021-01-16 09:39:54 +0100
committerYorhel <git@yorhel.nl>2021-01-16 09:39:56 +0100
commitb82e89d248861bdd5dd4dfd2a793ee94d4a29185 (patch)
tree3953db67f5f083a78aa805b80c9c90c76203bdc6 /lib/VNWeb/Chars/List.pm
parent2a0e9edae898865a44a65135049d74ecf7ee1154 (diff)
Chars::List: Switch to new AdvSearch system
TODO: Add VN subquery and migrate trait pages.
Diffstat (limited to 'lib/VNWeb/Chars/List.pm')
-rw-r--r--lib/VNWeb/Chars/List.pm106
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/VNWeb/Chars/List.pm b/lib/VNWeb/Chars/List.pm
new file mode 100644
index 00000000..62b0d3e9
--- /dev/null
+++ b/lib/VNWeb/Chars/List.pm
@@ -0,0 +1,106 @@
+package VNWeb::Chars::List;
+
+use VNWeb::Prelude;
+use VNWeb::AdvSearch;
+use VNWeb::Filters;
+
+
+sub listing_ {
+ my($opt, $list, $count) = @_;
+ my sub url { '?'.query_encode %$opt, @_ }
+ paginate_ \&url, $opt->{p}, [$count, 50], 't';
+ div_ class => 'mainbox browse charb', sub {
+ table_ class => 'stripe', sub {
+ tr_ sub {
+ td_ class => 'tc1', sub {
+ abbr_ class => "icons gen $_->{gender}", title => $GENDER{$_->{gender}}, '' if $_->{gender} ne 'unknown';
+ };
+ td_ class => 'tc2', sub {
+ a_ href => "/c$_->{id}", title => $_->{original}||$_->{name}, $_->{name};
+ b_ class => 'grayedout', sub {
+ join_ ', ', sub { a_ href => "/v$_->{id}", title => $_->{original}||$_->{title}, $_->{title} }, $_->{vn}->@*;
+ };
+ };
+ } for @$list;
+ }
+ };
+ paginate_ \&url, $opt->{p}, [$count, 50], 'b';
+}
+
+
+TUWF::get qr{/c(?:/(?<char>all|[a-z0]))?}, sub {
+ my $opt = tuwf->validate(get =>
+ q => { onerror => undef },
+ p => { upage => 1 },
+ f => { advsearch_err => 'c' },
+ ch=> { onerror => [], type => 'array', scalar => 1, values => { onerror => undef, enum => ['0', 'a'..'z'] } },
+ fil => { required => 0 },
+ )->data;
+ $opt->{ch} = $opt->{ch}[0];
+
+ # compat with old URLs
+ my $oldch = tuwf->capture('char');
+ $opt->{ch} //= $oldch if defined $oldch && $oldch ne 'all';
+
+ # URL compatibility with old filters
+ if(!$opt->{f}->{query} && $opt->{fil}) {
+ my $q = eval {
+ tuwf->compile({ advsearch => 'c' })->validate(filter_char_adv filter_parse c => $opt->{fil})->data;
+ };
+ if(!$q) {
+ warn "Filter compatibility conversion failed\n$@";
+ } else {
+ return tuwf->resRedirect(tuwf->reqPath().'?'.query_encode(%$opt, fil => undef, f => $q), 'temp');
+ }
+ }
+
+ $opt->{f} = advsearch_default 'c' if !$opt->{f}{query} && !defined tuwf->reqGet('f');
+
+ my @search = map {
+ my $l = '%'.sql_like($_).'%';
+ length $_ > 0 ? sql '(c.name ILIKE', \$l, "OR translate(c.original,' ','') ILIKE", \$l, "OR translate(c.alias,' ','') ILIKE", \$l, ')' : ();
+ } split /[ -,._]/, $opt->{q}||'';
+
+ my $where = sql_and
+ 'NOT c.hidden', $opt->{f}->sql_where(), @search,
+ defined($opt->{ch}) && $opt->{ch} ? sql('LOWER(SUBSTR(c.name, 1, 1)) =', \$opt->{ch}) : (),
+ defined($opt->{ch}) && !$opt->{ch} ? sql('(ASCII(c.name) <', \97, 'OR ASCII(c.name) >', \122, ') AND (ASCII(c.name) <', \65, 'OR ASCII(c.name) >', \90, ')') : ();
+
+ my $time = time;
+ my($count, $list);
+ db_maytimeout {
+ $count = tuwf->dbVali('SELECT count(*) FROM chars c WHERE', $where);
+ $list = $count ? tuwf->dbPagei({results => 50, page => $opt->{p}}, '
+ SELECT c.id, c.name, c.original, c.gender FROM chars c WHERE', $where, 'ORDER BY c.name, c.id'
+ ) : [];
+ } || (($count, $list) = (undef, []));
+
+ enrich vn => id => cid => sub { sql '
+ SELECT cv.id AS cid, v.id, v.title, v.original
+ FROM chars_vns cv
+ JOIN vn v ON v.id = cv.vid
+ WHERE NOT v.hidden AND cv.id IN', $_, '
+ ORDER BY v.title'
+ }, $list;
+
+ $time = time - $time;
+
+ framework_ title => 'Browse characters', sub {
+ div_ class => 'mainbox', sub {
+ h1_ 'Browse characters';
+ form_ action => '/c', method => 'get', sub {
+ searchbox_ c => $opt->{q}//'';
+ p_ class => 'browseopts', sub {
+ button_ type => 'submit', name => 'ch', value => ($_//''), ($_//'') eq ($opt->{ch}//'') ? (class => 'optselected') : (), !defined $_ ? 'ALL' : $_ ? uc $_ : '#'
+ for (undef, 'a'..'z', 0);
+ };
+ input_ type => 'hidden', name => 'ch', value => $opt->{ch}//'';
+ $opt->{f}->elm_;
+ advsearch_msg_ $count, $time;
+ };
+ };
+ listing_ $opt, $list, $count if $count;
+ };
+};
+
+1;