diff options
author | Yorhel <git@yorhel.nl> | 2021-01-16 09:39:54 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2021-01-16 09:39:56 +0100 |
commit | b82e89d248861bdd5dd4dfd2a793ee94d4a29185 (patch) | |
tree | 3953db67f5f083a78aa805b80c9c90c76203bdc6 /lib/VNWeb/Chars/List.pm | |
parent | 2a0e9edae898865a44a65135049d74ecf7ee1154 (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.pm | 106 |
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; |