diff options
-rw-r--r-- | data/tpl/defs.pl | 25 | ||||
-rw-r--r-- | data/tpl/main | 22 | ||||
-rw-r--r-- | data/tpl/myvotes | 31 | ||||
-rw-r--r-- | data/tpl/rpage | 9 | ||||
-rw-r--r-- | data/tpl/useredit | 1 | ||||
-rw-r--r-- | data/tpl/userlist | 8 | ||||
-rw-r--r-- | data/tpl/userpage | 5 | ||||
-rw-r--r-- | data/tpl/vnpage | 7 | ||||
-rw-r--r-- | data/tpl/vnpage_rel | 9 | ||||
-rw-r--r-- | data/tpl/vnpage_stats | 30 | ||||
-rw-r--r-- | lib/ChangeLog | 6 | ||||
-rw-r--r-- | lib/VNDB.pm | 10 | ||||
-rw-r--r-- | lib/VNDB/Releases.pm | 3 | ||||
-rw-r--r-- | lib/VNDB/Users.pm | 9 | ||||
-rw-r--r-- | lib/VNDB/Util/DB.pm | 128 | ||||
-rw-r--r-- | lib/VNDB/VN.pm | 20 | ||||
-rw-r--r-- | lib/VNDB/VNLists.pm | 101 | ||||
-rw-r--r-- | lib/VNDB/Votes.pm | 62 | ||||
-rw-r--r-- | lib/global.pl | 18 | ||||
-rw-r--r-- | static/files/def.js | 96 | ||||
-rw-r--r-- | static/files/style.css | 35 | ||||
-rw-r--r-- | util/dump.sql | 12 | ||||
-rw-r--r-- | util/updates/update_1.20.sql | 13 |
23 files changed, 444 insertions, 216 deletions
diff --git a/data/tpl/defs.pl b/data/tpl/defs.pl index ef5b3a67..27d1443d 100644 --- a/data/tpl/defs.pl +++ b/data/tpl/defs.pl @@ -215,7 +215,6 @@ sub ttabs { # [vrpu], obj, sel ($s eq 'edit' ? 'edit' : '<a href="'.($p{Authedit}?'/%s/edit':'/u/register?n=1').'" '.($t eq 'v' || $t eq 'r' ? 'class="dropdown" rel="nofollow editDD"':'').'>edit</a>') : (), $t eq 'u' ? ( - $o->{flags} & $VNDB::UFLAGS->{votes} ? ( $s eq 'vote' ? 'votes' : '<a href="/%s/votes">votes</a>', ) : (), $o->{flags} & $VNDB::UFLAGS->{list} ? ( $s eq 'list' ? 'list' : '<a href="/%s/list">list</a>', ) : (), ) : (), @@ -258,6 +257,26 @@ sub ttabs { # [vrpu], obj, sel } +# Uwaaaa~ ugly function! +sub rlist_dd { + my $r = shift; + return + qq|<div class="dropdown rlistdd" id="rlistDD$$r{id}"><ul><li><b>Release status</b></li>|. + join('', map { + $r->{rlist} && $_ == $r->{rlist}{rstat} ? "<li><b> $$VNDB::RSTAT[$_]</b></li>" + : qq|<li><a href="/r$$r{id}/list?r=$_"> $$VNDB::RSTAT[$_]</a></li>| + } 0..$#$VNDB::RSTAT). + qq|</ul><ul><li><b>Play status</b></li>|. + join('', map { + $r->{rlist} && $_ == $r->{rlist}{vstat} ? "<li><b> $$VNDB::VSTAT[$_]</b></li>" + : qq|<li><a href="/r$$r{id}/list?v=$_"> $$VNDB::VSTAT[$_]</a></li>| + } 0..$#$VNDB::VSTAT). + qq|</ul><ul class="full">|. + ($r->{rlist} ? qq|<li class="center"><a href="/r$$r{id}/list?d=1">remove from my list</a></li>| + : qq|<li class="center"><b>not in your list</b></li>|). + qq|</ul></div>|; +} + my %pagetitles = ( faq => 'Frequently Asked Questions', @@ -275,12 +294,12 @@ my %pagetitles = ( tedit => sub { return $p{tedit}{p} ? 'Edit post' : $p{tedit}{t} ? 'Reply to thread' : 'Start a new thread' }, - myvotes => sub { - return $p{myvotes}{user}{username} eq $p{AuthUsername} ? 'My votes' : ('Votes by '.$p{myvotes}{user}{username}); }, userpage => sub { return 'User: '.$p{userpage}{user}{username} }, vnlist => sub { return $p{vnlist}{user}{username} eq $p{AuthUsername} ? 'My visual novel list' : ($p{vnlist}{user}{username}.'\'s visual novel list'); }, + rlist => sub { + return $p{rlist}{user}{username} eq $p{AuthUsername} ? 'My visual novel list' : ($p{rlist}{user}{username}.'\'s visual novel list'); }, useredit => sub { return !$p{useredit}{adm} ? 'My account' : 'Edit '.$p{useredit}{form}{username}.'\'s account'; }, ppage => sub { diff --git a/data/tpl/main b/data/tpl/main index 799a1ee8..d0739537 100644 --- a/data/tpl/main +++ b/data/tpl/main @@ -14,12 +14,15 @@ <script src="[[: $p{st} ]]/files/dyna.js?[[= $VNDB::VERSION ]]" type="text/javascript"></script> [[ } ]]- <script src="[[: $p{st} ]]/files/def.js?[[= $VNDB::VERSION ]]" type="text/javascript"></script> -[[ if($p{devshit}) { ]]- +[[ if(0 && $p{devshit}) { ]]- <link rel="icon" href="/favicon.gif" type="image/gif" /> <meta name="robots" content="noindex, nofollow" /> -[[ } elsif($p{userlist} || $p{userpage} || $p{userlogin} || $p{userreg} || $p{userpass} || $p{myvotes} - || $p{vnlist} || $p{hist} || ($p{vnpage} && $p{vnpage}{page} eq 'stats') - || grep { $p{$_} && $p{$_}{change} } qw|vnpage ppage rpage|) { ]]- +[[ } elsif( + grep($p{$_}, qw| userlist userpage userlogin userreg userpass vnlist rlist hist |) + || ($p{ttag} && $p{ttag}{iid}) + || ($p{vnpage} && $p{vnpage}{page} eq 'stats') + || grep { $p{$_} && $p{$_}{change} } qw|vnpage ppage rpage| + ) { ]]- <meta name="robots" content="noindex, follow" /> [[ }]]- @@ -61,13 +64,13 @@ [[ if($p{pbrowse}) { %d = %{$p{pbrowse}}; ]] [[+ pbrowse ]][[ } ]] [[ if($p{pedit}) { %d = %{$p{pedit}}; ]] [[+ pedit ]][[ } ]] [[ if($p{ppage}) { %d = %{$p{ppage}}; ]] [[+ ppage ]][[ } ]] -[[ if($p{myvotes}) { %d = %{$p{myvotes}}; ]] [[+ myvotes ]][[ }# ]] [[ if($p{vnlist}) { %d = %{$p{vnlist}}; ]] [[+ vnlist ]][[ }# ]] +[[ if($p{rlist}) { %d = %{$p{rlist}}; ]] [[+ rlist ]][[ }# ]] [[ if($p{hist}) { %d = %{$p{hist}}; ]] [[+ hist ]][[ }# ]] [[ if($p{rpage}) { %d = %{$p{rpage}}; ]] [[+ rpage ]][[ } ]] [[ if($p{docs}) { %d = %{$p{docs}}; ]] [[+ docs ]][[ } ]] [[ if($p{tindex}) { %d = %{$p{tindex}}; ]] [[+ tindex ]][[ } ]] -[[ if($p{ttag}) { %d = %{$p{ttag}}; ]] [[+ ttag ]][[ } ]] +[[ if($p{ttag}) { %d = %{$p{ttag}}; ]] [[+ ttag ]][[ }# ]] [[ if($p{tthread}) { %d = %{$p{tthread}}; ]] [[+ tthread ]][[ } ]] [[ if($p{tedit}) { %d = %{$p{tedit}}; ]] [[+ tedit ]][[ } ]] [[ if($p{error}) { %d = %{$p{error}}; ]] [[+ error ]][[ } ]] @@ -103,12 +106,11 @@ [[ } else { ]]- <h2>User menu</h2> <ul> - <li>[[: $p{AuthUsername} ]]- ([[: $p{AuthRankname} ]])</li> - <li><a href="/u[[= $p{AuthId} ]]/edit">My profile</a></li> - <li><a href="/u[[= $p{AuthId} ]]/votes">My votes</a></li> + <li><a href="/u[[= $p{AuthId} ]]">[[: $p{AuthUsername} ]]</a> ([[: $p{AuthRankname} ]])</li> + <!--<li><a href="/u[[= $p{AuthId} ]]/edit">My profile</a></li>--> <li><a href="/u[[= $p{AuthId} ]]/list">My visual novel list</a></li> - <li><a href="/u[[= $p{AuthId} ]]/hist">My recent changes</a></li> <li><a href="/t/u[[= $p{AuthId} ]]">My messages</a></li> + <li><a href="/u[[= $p{AuthId} ]]/hist">My recent changes</a></li> [[ if($p{Authedit}) { ]]- <li> </li> <li><a href="/v/new">Add visual novel</a></li> diff --git a/data/tpl/myvotes b/data/tpl/myvotes deleted file mode 100644 index 231eaf25..00000000 --- a/data/tpl/myvotes +++ /dev/null @@ -1,31 +0,0 @@ -[[= ttabs('u', $d{user}, 'vote') ]] -<h2>[[: $p{PageTitle} ]]</h2> -[[ if($#{$d{votes}} < 0) { ]]- -<p> -[[ if($d{user}{username} eq $p{AuthUsername}) { ]] - You haven't voted on anything yet... -[[ } else { ]] - [[: $d{user}{username} ]]- hasn't voted on anything yet... -[[ } ]] -</p> -[[ } else { - my $url = sprintf '/u%d/votes', $d{user}{id}; - my $surl = sprintf '%s?s=%s&o=%s', $url, $d{order}[0], $d{order}[1]; -]] -[[= pagebut($surl) ]]- -<table id="tmv"> - <thead><tr> - <td class="tc1">Title [[= sortbut($url, 'title') ]]</td> - <td class="tc2">Vote [[= sortbut($url, 'vote') ]]</td> - <td class="tc3">Date [[= sortbut($url, 'date') ]]</td> - </tr></thead> - [[ for (@{$d{votes}}) { ]]- - <tr> - <td class="tc1"><a href="/v[[= $_->{vid} ]]">[[: $_->{title} ]]</a></td> - <td class="tc2">[[: $_->{vote} ]]</td> - <td class="tc3">[[= formatdate('%Y-%m-%d', $_->{date}, 'dh') ]]</td> - </tr> - [[ } ]]- -</table> --[[= pagebut($surl) ]] -[[ } ]] diff --git a/data/tpl/rpage b/data/tpl/rpage index 54267204..1652ec47 100644 --- a/data/tpl/rpage +++ b/data/tpl/rpage @@ -9,9 +9,16 @@ [[ } ]] [[ if(!$d{rel}{hidden} || $p{Authdel}) { ]]- +-[[ if($p{AuthLoggedin}) { ]] +<p class="mod">< +<a href="/u[[= $p{AuthId} ]]/list" rel="rlistDD[[= $d{rel}{id} ]]" class="dropdown"> +[[= !$d{rel}{rlist} ? 'not in your list' : "$$VNDB::RSTAT[$d{rel}{rlist}{rstat}] / $$VNDB::VSTAT[$d{rel}{rlist}{vstat}]" ]] +</a> ></p> +[[= rlist_dd($d{rel}) ]] +[[ } ]]- -[[ if($d{change}) { ]] +-[[ if($d{change}) { ]] [[= cdiff($d{prev}, $d{rel}, [ vn => 'Relations', sub { join("<br />\n", map { $_->{title} } @{$_[0]}) } ], [ type => 'Type', sub { $VNDB::RTYP->[$_[0] ] } ], diff --git a/data/tpl/useredit b/data/tpl/useredit index 0e152f80..f9db7c61 100644 --- a/data/tpl/useredit +++ b/data/tpl/useredit @@ -20,7 +20,6 @@ { type => 'pass', name => 'Confirm', short => 'pass2' }, { type => 'sub', title => 'Miscellaneous options', short => 'misc' }, - { type => 'check', short => 'pvotes', name => sprintf 'Allow other people to see my votes (<a href="/u%d/votes">/u%1$d/votes</a>)', $d{user} }, { type => 'check', short => 'plist', name => sprintf 'Allow other people to see my visual novel list (<a href="/u%d/list">/u%1$d/list</a>)', $d{user} }, { type => 'check', short => 'pign_nsfw', name => 'Disable warnings for images that are not safe for work.' }, diff --git a/data/tpl/userlist b/data/tpl/userlist index d83249e1..578d320e 100644 --- a/data/tpl/userlist +++ b/data/tpl/userlist @@ -23,7 +23,6 @@ <td class="tc2">Mail [[= sortbut($url, 'mail') ]]</td> <td class="tc3">Rank [[= sortbut($url, 'rank') ]]</td>[[ } ]]- <td class="tc4">Registered [[= sortbut($url, 'registered') ]]</td> - <td class="tc5">VN list</td> <td class="tc6">Votes</td> <td class="tc7">Changes</td> [[ if($p{Authusermod}) { ]]- @@ -36,12 +35,9 @@ <td class="tc2">[[: $_->{mail} ]]</td> <td class="tc3">[[: $VNDB::VNDBopts{ranks}[0][0][$_->{rank}] ]]</td>[[ } ]]- <td class="tc4">[[= formatdate('%Y-%m-%d', $_->{registered}, 'wd') ]]</td> - <td class="tc5">[[ if($_->{flags} & $VNDB::UFLAGS->{list} && $_->{vnlist}) { ]] - <a href="/u[[= $_->{id} ]]/list" title="[[: $_->{username} ]]'s visual novel list">[[= $_->{vnlist} ]]</a> + <td class="tc6">[[ if($_->{flags} & $VNDB::UFLAGS->{list} && $_->{votes}) { ]] + <a href="/u[[= $_->{id} ]]/list" title="[[: $_->{username} ]]'s votes">[[= $_->{votes} ]]</a> [[ } else { ]][[= $_->{flags} & $VNDB::UFLAGS->{list} ? 0 : '-' ]][[ } ]]</td> - <td class="tc6">[[ if($_->{flags} & $VNDB::UFLAGS->{votes} && $_->{votes}) { ]] - <a href="/u[[= $_->{id} ]]/votes" title="[[: $_->{username} ]]'s votes">[[= $_->{votes} ]]</a> - [[ } else { ]][[= $_->{flags} & $VNDB::UFLAGS->{votes} ? 0 : '-' ]][[ } ]]</td> <td class="tc7">[[ if($_->{changes}) { ]] <a href="/u[[= $_->{id} ]]/hist" title="Recent changes by -[[: $_->{username} ]]">[[= $_->{changes} ]]</a> [[ } else { ]]0[[ } ]]</td> diff --git a/data/tpl/userpage b/data/tpl/userpage index ef5fc55c..a45fc8af 100644 --- a/data/tpl/userpage +++ b/data/tpl/userpage @@ -1,13 +1,12 @@ [[= ttabs('u', $d{user}) ]] [[ - ($d{pv}, $d{pl}) = ($d{user}{flags} & $VNDB::UFLAGS->{votes}, $d{user}{flags} & $VNDB::UFLAGS->{list}); + $d{pl} = $d{user}{flags} & $VNDB::UFLAGS->{list}; ]] <h2>[[: $p{PageTitle} ]]</h2> <dl> <dt>Username</dt><dd>[[: $d{user}{username} ]]- (<a href="/u[[= $d{user}{id} ]]">u[[= $d{user}{id} ]]</a>)</dd> <dt>Registered</dt><dd>[[= formatdate('%Y-%m-%d', $d{user}{registered}) ]]</dd> - <dt>Votes</dt><dd>[[= $d{pv} ? $d{user}{votes}.' (<a href="/u'.$d{user}{id}.'/votes">view all</a>)' : '(hidden)' ]]</dd> - <dt>VN List</dt><dd>[[= $d{pl} ? $d{user}{vnlist}.' (<a href="/u'.$d{user}{id}.'/list">view all</a>)' : '(hidden)' ]]</dd> + <dt>Votes</dt><dd>[[= $d{pl} ? $d{user}{list}.' (<a href="/u'.$d{user}{id}.'/list">view all</a>)' : '(hidden)' ]]</dd> <dt>Changes</dt><dd>[[= $d{user}{changes}.($d{user}{changes}>0?' (<a href="/u'.$d{user}{id}.'/hist">recent changes</a>)':'') ]]</dd> </dl> diff --git a/data/tpl/vnpage b/data/tpl/vnpage index 220b6c9f..f59c0a1c 100644 --- a/data/tpl/vnpage +++ b/data/tpl/vnpage @@ -12,9 +12,8 @@ [[ if(!$d{vn}{hidden} || $p{Authdel}) { ]]- -[[ if($p{AuthLoggedin}) { ]] -<p class="mod">< user options - - <a href="/u[[= $p{AuthId} ]]/votes" rel="voteDD" class="dropdown">[[= $d{vote}{vid} ? 'your vote: '.$d{vote}{vote} : 'vote' ]]</a> -- <a href="/u[[= $p{AuthId} ]]/list" rel="listDD" class="dropdown">[[= !$d{list}{vid} ? 'add to vn list' : 'status: '.lc $VNDB::LSTAT->[$d{list}{status}] ]]</a> +<p class="mod">< + <a href="/u[[= $p{AuthId} ]]/list" rel="voteDD" class="dropdown">[[= $d{vote}{vid} ? 'your vote: '.$d{vote}{vote} : 'vote' ]]</a> ></p> [[ } ]]- @@ -179,6 +178,7 @@ if($d{vn}{length} || $d{vn}{alias} || @links || $prod) { ]] </ul> </div> +[[ if(0) { ]] <div class="dropdown" id="listDD"> <ul> [[ for (0..$#$VNDB::LSTAT) { ]]- @@ -188,6 +188,7 @@ if($d{vn}{length} || $d{vn}{alias} || @links || $prod) { ]] [[ } ]]- </ul> </div> +[[ } ]] [[ } ]] diff --git a/data/tpl/vnpage_rel b/data/tpl/vnpage_rel index e213c12f..ed39477f 100644 --- a/data/tpl/vnpage_rel +++ b/data/tpl/vnpage_rel @@ -34,7 +34,10 @@ <acronym title="[[= $VNDB::RTYP->[$_->{type}] ]]- release" class="icons -[[= lc substr($VNDB::RTYP->[$_->{type}],0,3) ]]"> </acronym> </td> <td class="tc4"><a href="/r[[= $_->{id} ]]" title="[[: $_->{original} || $_->{title} ]]">[[: shorten $_->{title},60 ]]</a></td> - <td class="tc5">[[ if($_->{website}) { ]]<a href="[[: $_->{website} ]]" class="icons ext" title="WWW"> </a>[[ } ]]</td> + <td class="tc5">[[ if($p{AuthId}) { ]] + [[= sprintf '<a href="/r%d/list?s=%d" class="dropdown above" rel="rlistDD%1$d">%s</a>', $_->{id}, $_->{rlist} ? (-1, 'x') : (1, '-') ]] + [[ } else { ]] [[ } ]]</td> + <td class="tc6">[[ if($_->{website}) { ]]<a href="[[: $_->{website} ]]" class="icons ext" title="WWW"> </a>[[ } ]]</td> </tr> [[ } ]]- [[ } ]]- @@ -47,3 +50,7 @@ [[ } ]] +[[ if($p{AuthId}) { ]] +[[ for my $r (@{$d{rel}}) { ]]- +-[[= rlist_dd($r) ]] +[[ } } ]] diff --git a/data/tpl/vnpage_stats b/data/tpl/vnpage_stats index 653987a1..b4a3b018 100644 --- a/data/tpl/vnpage_stats +++ b/data/tpl/vnpage_stats @@ -36,34 +36,4 @@ [[ } ]]- </table></li> [[ } } ]]- - --[[ $max = 1; $total = 0; - for (@{$d{lists}{graph}}) { $total += $_; $max = $_ if $_ > $max; } ]] -[[ if(!$d{user} || ($d{pl} && $d{user}{vnlist})) { ]]- -<li class="break"><h3>VN List stats <p class="actions">[[= $total ]]- -[[= $d{user}?'visual novel':'user' ]][[= $total==1?'':'s' ]]- total</p></h3> -<table id="tus"> - [[ for (0..$#$VNDB::LSTAT) { ]]- - <tr> - <td class="tc1">[[= $VNDB::LSTAT->[$_] ]]</td> - <td class="tc2"><div style="width: -[[= ($d{lists}{graph}[$_]/$max)*235 + 5 ]]px"> </div>[[= $d{lists}{graph}[$_] ]]</td> - </tr> - [[ } ]]- -</table></li> - -[[ if($#{$d{lists}{latest}} >= 0) { ]] -<li><h3>Recent VN list additions</h3> -<table id="tur"> -[[ for (@{$d{lists}{latest}}) { ]]- - <tr> - [[ if(!$d{user}) { ]]- - <td class="tc1">[[= userstr $_ ]]</td> - [[ } else { ]]- - <td class="tc1"><a href="/v[[= $_->{vid} ]]">[[: length($_->{title})>25?substr($_->{title},0,23).'...':$_->{title} ]]</a></td> - [[ } ]]- - <td class="tc2">[[= $VNDB::LSTAT->[$_->{status}] ]]</td> - <td class="tc3">[[= formatdate('%Y-%m-%d %R', $_->{date}, 'dh') ]]</td> - </tr> -[[ } ]]- -</table></li> -[[ } } ]]- </ul> diff --git a/lib/ChangeLog b/lib/ChangeLog index dc4d5b9f..f14c0edd 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -15,6 +15,12 @@ TODO: - Place/time category order on VN pages is now consistent - Admins can delete users from the DB - Added small NSFW indication for users who have disabled the warning + - Added noindex tag to iid-ttag browser + - Replaced last poster with age of last post on home page + - Added release list feature and removed the old VNList + - Merged user vote list into the new release list (and removed 'hide my + votes' option) + - Merged Votes.pm into VNLists.pm 1.19 - 2008-07-08 (r62) - Integrated discussion board diff --git a/lib/VNDB.pm b/lib/VNDB.pm index dff63bc7..be5bc542 100644 --- a/lib/VNDB.pm +++ b/lib/VNDB.pm @@ -20,7 +20,6 @@ use VNDB::Producers; use VNDB::Releases; use VNDB::VNLists; use VNDB::Users; -use VNDB::Votes; use VNDB::VN; @@ -43,10 +42,11 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+) }, 'u+' => { '/' => sub { shift->UsrPage(shift) }, - votes => sub { shift->VNVotes(shift) }, edit => sub { shift->UsrEdit(shift) }, del => sub { shift->UsrDel(shift) }, - list => sub { shift->VNMyList(shift) }, + list => sub { shift->RList(shift) }, + #vlist => sub { shift->VNMyList(shift) }, + #votes => sub { shift->VNVotes(shift) }, hist => {'*'=> sub { shift->History('u', shift, $_[1]) } }, }, # visual novels @@ -61,7 +61,7 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+) rg => sub { shift->VNPage(shift, shift) }, edit => sub { shift->VNEdit(shift) }, vote => sub { shift->VNVote(shift) }, - list => sub { shift->VNListMod(shift) }, + #list => sub { shift->VNListMod(shift) }, add => sub { shift->REdit('v', shift) }, lock => sub { shift->VNLock(shift) }, hide => sub { shift->VNHide(shift) }, @@ -74,6 +74,7 @@ my %VNDBuris = ( # wildcards: * -> (.+), + -> ([0-9]+) edit => sub { shift->REdit('r', shift) }, lock => sub { shift->RLock(shift) }, hide => sub { shift->RHide(shift) }, + list => sub { shift->RListMod(shift) }, hist => {'*'=> sub { shift->History('r', shift, $_[1]) } }, }, 'r+.+' => sub { shift->RPage($_[0][0], $_[0][1]) }, @@ -160,6 +161,7 @@ my %OLDuris = ( } }, 'u+' => { + votes => sub { shift->ResRedirect('/u'.(shift).'/list', 'perm') }, hist=>{rss => sub { shift->ResRedirect('/u'.(shift).'/hist/rss.xml', 'perm') } }, }, 'p+' => { diff --git a/lib/VNDB/Releases.pm b/lib/VNDB/Releases.pm index 3dcf4153..de598276 100644 --- a/lib/VNDB/Releases.pm +++ b/lib/VNDB/Releases.pm @@ -31,6 +31,9 @@ sub RPage { $self->ResRedirect('/v'.$v->{vn}[0]{vid}) if ($self->ReqHeader('Referer')||'') =~ m{^http://[^/]*(yahoo|google)} && @{$v->{vn}} == 1; + $v->{rlist} = $self->DBGetRList(rids => [ $id ], uid => $self->AuthInfo->{id})->[0] + if $self->AuthInfo->{id}; + return $self->ResAddTpl(rpage => { rel => $v, prev => $c, diff --git a/lib/VNDB/Users.pm b/lib/VNDB/Users.pm index 4b953d17..e2021627 100644 --- a/lib/VNDB/Users.pm +++ b/lib/VNDB/Users.pm @@ -141,7 +141,6 @@ sub UsrEdit { { name => 'username',required => 1, template => 'pname', minlength => 2, maxlength => 15 }, { name => 'rank', required => 1, enum => [ '1'..($#{$self->{ranks}}-1) ] }, ) : (), - { name => 'pvotes',required => 0 }, { name => 'plist', required => 0 }, { name => 'pign_nsfw', required => 0 }, ); @@ -157,8 +156,7 @@ sub UsrEdit { mail => $frm->{mail}, ); $opts{passwd} = $pass if $pass; - $opts{flags} = $frm->{pvotes} ? $VNDB::UFLAGS->{votes} : 0; - $opts{flags} += $VNDB::UFLAGS->{list} if $frm->{plist}; + $opts{flags} = $frm->{plist} ? $VNDB::UFLAGS->{list} : 0; $opts{flags} += $VNDB::UFLAGS->{nsfw} if $frm->{pign_nsfw}; $self->DBUpdateUser($u->{id}, %opts); return $adm ? $self->ResRedirect('/u'.$user.'/edit?d=1', 'post') : @@ -169,7 +167,6 @@ sub UsrEdit { $frm->{$_} ||= $u->{$_} for (qw| username mail rank |); - $frm->{pvotes} ||= $u->{flags} & $VNDB::UFLAGS->{votes}; $frm->{plist} ||= $u->{flags} & $VNDB::UFLAGS->{list}; $frm->{pign_nsfw} ||= $u->{flags} & $VNDB::UFLAGS->{nsfw}; $self->ResAddTpl(useredit => { @@ -221,10 +218,6 @@ sub UsrPage { $self->ResAddTpl(userpage => { user => $u, - lists => { - latest => scalar $self->DBGetVNList(uid => $id, results => 7), - graph => $self->DBVNListStats(uid => $id), - }, votes => { latest => scalar $self->DBGetVotes(uid => $id, results => 10), graph => $self->DBVoteStats(uid => $id), diff --git a/lib/VNDB/Util/DB.pm b/lib/VNDB/Util/DB.pm index 46a17fb1..fdefa6e6 100644 --- a/lib/VNDB/Util/DB.pm +++ b/lib/VNDB/Util/DB.pm @@ -16,6 +16,7 @@ $VERSION = $VNDB::VERSION; DBGetUser DBAddUser DBUpdateUser DBDelUser DBGetVotes DBVoteStats DBAddVote DBDelVote DBGetVNList DBVNListStats DBAddVNList DBEditVNList DBDelVNList + DBGetRList DBGetRLists DBEditRList DBDelRList DBGetVN DBAddVN DBEditVN DBHideVN DBUndefRG DBVNCache DBGetRelease DBAddRelease DBEditRelease DBHideRelease DBGetProducer DBGetProducerVN DBAddProducer DBEditProducer DBHideProducer @@ -141,7 +142,7 @@ sub DBTableCount { # table (users, producers, vn, releases, votes) %s|, $_[1], $_[1] =~ /producers|vn|releases/ ? 'WHERE hidden = 0' : '', - )->{cnt}; + )->{cnt} - ($_[1] eq 'users' ? 1 : 0); } @@ -304,14 +305,6 @@ sub DBGetUser { # %options->{ username mail passwd order firstchar uid results p [ keys %r ] )}); - $r->[$r{$_->{uid}}]{vnlist} = $_->{cnt} for (@{$s->DBAll(q| - SELECT uid, COUNT(vid) AS cnt - FROM vnlists - WHERE uid IN(!l) - GROUP BY uid|, - [ keys %r ] - )}); - $r->[$r{$_->{requester}}]{changes} = $_->{cnt} for (@{$s->DBAll(q| SELECT requester, COUNT(id) AS cnt FROM changes @@ -390,7 +383,7 @@ sub DBGetVotes { # %options->{ uid vid hide order results page } my %where = ( $o{uid} ? ( 'n.uid = %d' => $o{uid} ) : (), $o{vid} ? ( 'n.vid = %d' => $o{vid} ) : (), - $o{hide} ? ( 'u.flags & %d = %1$d' => $VNDB::UFLAGS->{votes} ) : (), + $o{hide} ? ( 'u.flags & %d = %1$d' => $VNDB::UFLAGS->{list} ) : (), ); my $where = scalar keys %where ? 'WHERE !W' : ''; @@ -553,6 +546,119 @@ sub DBDelVNList { # uid, @vid # uid = 0 to delete all #-----------------------------------------------------------------------------# +# U S E R R E L E A S E L I S T S # +#-----------------------------------------------------------------------------# + + +sub DBGetRList { # %options->{ uid rids } + my($s, %o) = @_; + + my %where = ( + 'uid = %d' => $o{uid}, + $o{rids} ? ( + 'rid IN(!l)' => $o{rids} ) : (), + ); + + return $s->DBAll(q| + SELECT uid, rid, rstat, vstat + FROM rlists + WHERE !W|, + \%where); +} + + +# separate function, which also fetches VN info and votes +sub DBGetRLists { # %options->{ uid order char rstat vstat voted page results } + my($s, %o) = @_; + + $o{results} ||= 50; + $o{page} ||= 1; + + # bit ugly... + my $where = !$o{rstat} && !$o{vstat} ? 'vo.vote IS NOT NULL' : ''; + $where .= ($where?' OR ':'').q|v.id IN( + SELECT irv.vid + FROM rlists irl + JOIN releases ir ON ir.id = irl.rid + JOIN releases_vn irv ON irv.rid = ir.latest + WHERE !W + )| if !$o{voted}; + $where = '('.$where.') AND LOWER(SUBSTR(vr.title, 1, 1)) = \''.$o{char}.'\'' if $o{char}; + $where = '('.$where.') AND (ASCII(vr.title) < 97 OR ASCII(vr.title) > 122) AND (ASCII(vr.title) < 65 OR ASCII(vr.title) > 90)' if defined $o{char} && !$o{char}; + + # WHERE clause for the rlists subquery + my %where = ( + 'uid = %d' => $o{uid}, + defined $o{rstat} ? ( 'rstat = %d' => $o{rstat} ) : (), + defined $o{vstat} ? ( 'vstat = %d' => $o{vstat} ) : (), + ); + + my $r = $s->DBAll(qq| + SELECT vr.vid, vr.title, v.c_released, v.c_languages, v.c_platforms, COALESCE(vo.vote, 0) AS vote + FROM vn v + JOIN vn_rev vr ON vr.id = v.latest + %s JOIN votes vo ON vo.vid = v.id AND vo.uid = %d + WHERE $where + ORDER BY %s + LIMIT %d OFFSET %d|, + $o{voted} ? '' : 'LEFT', $o{uid}, # JOIN if we only want votes, LEFT JOIN if we also want rlist items + $o{voted} ? () : \%where, + $o{order}, + $o{results}+(wantarray?1:0), $o{results}*($o{page}-1) + ); + + # now fetch the releases and link them to VNs + if(@$r) { + my %vns = map { $_->{rels}=[]; $_->{vid}, $_->{rels} } @$r; + push @{$vns{$_->{vid}}}, $_ for (@{$s->DBAll(q| + SELECT rv.vid, rr.rid, rr.title, rr.original, rr.released, rr.type, rr.language, rr.minage, rl.rstat, rl.vstat + FROM rlists rl + JOIN releases r ON rl.rid = r.id + JOIN releases_rev rr ON rr.id = r.latest + JOIN releases_vn rv ON rv.rid = r.latest + WHERE rl.uid = %d + AND rv.vid IN(!l) + ORDER BY rr.released ASC|, + $o{uid}, [ keys %vns ] + )}); + } + + return $r if !wantarray; + return ($r, 0) if $#$r < $o{results}; + pop @$r; + return ($r, 1); +} + + +sub DBEditRList { # %options->{ uid rid rstat vstat } + # rid can only be a arrayref with UPDATE + my($s, %o) = @_; + my %s = ( + defined $o{rstat} ? ( 'rstat = %d', $o{rstat} ) : (), + defined $o{vstat} ? ( 'vstat = %d', $o{vstat} ) : (), + ); + $o{rstat}||=0; + $o{vstat}||=0; + + $s->DBExec(q|UPDATE rlists SET !H WHERE uid = %d AND rid IN(!l)|, + \%s, $o{uid}, ref($o{rid}) eq 'ARRAY' ? $o{rid} : [ $o{rid} ]) + || + $s->DBExec(q|INSERT INTO rlists (uid, rid, rstat, vstat) + VALUES(%d, %d, %d, %d)|, + @o{qw| uid rid rstat vstat |}); +} + + +sub DBDelRList { # uid, \@rids + my($s, $uid, $rid) = @_; + $s->DBExec(q|DELETE FROM rlists WHERE uid = %d AND rid IN(!l)|, $uid, ref($rid) eq 'ARRAY' ? $rid : [ $rid ]); +} + + + + + +#-----------------------------------------------------------------------------# # V I S U A L N O V E L S # #-----------------------------------------------------------------------------# @@ -1374,7 +1480,7 @@ sub sqlhelper { # type, query, @list $sqlq =~ s/\r?\n/ /g; $sqlq =~ s/ +/ /g; $sqlq = sqlprint($sqlq, @_) if exists $_[0]; -# warn "$sqlq\n"; + #warn "$sqlq\n"; my $q = $s->prepare($sqlq); $q->execute(); diff --git a/lib/VNDB/VN.pm b/lib/VNDB/VN.pm index fadba900..c94705cc 100644 --- a/lib/VNDB/VN.pm +++ b/lib/VNDB/VN.pm @@ -30,7 +30,19 @@ sub VNPage { my $c = $rev && $rev > 1 && $self->DBGetVN(id => $id, rev => $rev-1, what => 'extended changes relations categories anime')->[0]; $v->{next} = $rev && $v->{latest} > $v->{cid} ? $rev+1 : 0; - if($page eq 'rg' && $v->{rgraph}) { + my $rel = $self->DBGetRelease(vid => $id, what => 'producers platforms'); + + if(!$page && @$rel && $self->AuthInfo->{id}) { + my $rl = $self->DBGetRList( + rids => [ map $_->{id}, @$rel ], + uid => $self->AuthInfo->{id} + ); + for my $i (@$rl) { + my $r = (grep $i->{rid} == $_->{id}, @$rel)[0]; + $r->{rlist} = $i; + } + + } elsif($page eq 'rg' && $v->{rgraph}) { open(my $F, '<:utf8', sprintf '%s/%02d/%d.cmap', $self->{mappath}, $v->{rgraph}%100, $v->{rgraph}) || die $!; $v->{rmap} = join('', (<$F>)); close($F); @@ -39,16 +51,12 @@ sub VNPage { $self->ResAddTpl(vnpage => { vote => $self->AuthInfo->{id} ? $self->DBGetVotes(uid => $self->AuthInfo->{id}, vid => $id)->[0] : {}, list => $self->AuthInfo->{id} ? $self->DBGetVNList(uid => $self->AuthInfo->{id}, vid => $id)->[0] : {}, - rel => scalar $self->DBGetRelease(vid => $id, what => 'producers platforms'), vn => $v, + rel => $rel, prev => $c, page => $page, change => $rev, $page eq 'stats' ? ( - lists => { - latest => scalar $self->DBGetVNList(vid => $id, results => 7, hide => 1), - graph => $self->DBVNListStats(vid => $id), - }, votes => { latest => scalar $self->DBGetVotes(vid => $id, results => 10, hide => 1), graph => $self->DBVoteStats(vid => $id), diff --git a/lib/VNDB/VNLists.pm b/lib/VNDB/VNLists.pm index 2a8be0a8..f2ad5d50 100644 --- a/lib/VNDB/VNLists.pm +++ b/lib/VNDB/VNLists.pm @@ -7,7 +7,7 @@ use Exporter 'import'; use vars ('$VERSION', '@EXPORT'); $VERSION = $VNDB::VERSION; -@EXPORT = qw| VNListMod VNMyList |; +@EXPORT = qw| VNListMod VNMyList VNVote RListMod RList |; sub VNListMod { @@ -93,5 +93,104 @@ sub VNMyList { } +sub VNVote { + my $self = shift; + my $id = shift; + + my $uid = $self->AuthInfo()->{id}; + return $self->ResDenied() if !$uid; + + my $f = $self->FormCheck( + { name => 'v', required => 0, default => 0, enum => [ '-1','1'..'10'] } + ); + return $self->ResNotFound() if !$f->{v}; + + + $self->DBDelVote($uid, $id) if $f->{v} == -1 || $self->DBGetVotes(uid => $uid, vid => $id)->[0]{vid}; + $self->DBAddVote($id, $uid, $f->{v}) if $f->{v} > 0; + + $self->ResRedirect('/v'.$id, 'temp'); +} + + +sub RListMod { + my $self = shift; + my $rid = shift; + + my $f = $self->FormCheck( + { name => 'd', required => 0 }, + { name => 'r', required => 0, enum => [ 0..$#$VNDB::RSTAT ] }, + { name => 'v', required => 0, enum => [ 0..$#$VNDB::VSTAT ] }, + ); + + return $self->ResNotFound if $f->{_err}; + return $self->ResDenied if !$self->AuthInfo->{id}; + + if($f->{d}) { + $self->DBDelRList($self->AuthInfo->{id}, $rid); + } else { + $self->DBEditRList( + uid => $self->AuthInfo->{id}, + rid => $rid, + rstat => $f->{r}, + vstat => $f->{v}, + ); + } + + my $r = $self->ReqHeader('Referer'); + $r = $r && $r =~ /([vr][0-9]+)$/ ? $1 : 'r'.$rid; + return $self->ResRedirect('/'.$r, 'temp'); +} + + +sub RList { + my $self = shift; + my $uid = shift; + + my $u = $self->DBGetUser(uid => $uid)->[0]; + return $self->ResNotFound if !$uid || !$u || (($self->AuthInfo->{id}||0) != $uid && !($u->{flags} & $VNDB::UFLAGS->{list})); + + my $f = $self->FormCheck( + { name => 's', required => 0, default => 'title', enum => [ qw|title vote| ] }, + { name => 'o', required => 0, default => 'a', enum => [ 'a','d' ] }, + { name => 'p', required => 0, template => 'int', default => 1 }, + { name => 'c', required => 0, default => 'all', enum => [ 'a'..'z', '0', 'all' ] }, + ); + return $self->ResNotFound if $f->{_err}; + + if($self->ReqMethod eq 'POST') { + my $frm = $self->FormCheck( + { name => 'vnlistchange', required => 1, enum => [ 'd', 'r0'..('r'.$#$VNDB::RSTAT), 'v0'..('v'.$#$VNDB::VSTAT) ] }, + { name => 'rsel', required => 1, multi => 1, template => 'int' }, + ); + if(!$frm->{_err} && @{$frm->{rsel}}) { + $self->DBDelRList($uid, $frm->{rsel}) if $frm->{vnlistchange} eq 'd'; + $self->DBEditRList( + uid => $uid, + rid => $frm->{rsel}, + substr($frm->{vnlistchange},0,1).'stat', substr($frm->{vnlistchange},1) + ) if $frm->{vnlistchange} ne 'd'; + } + } + + my $order = $f->{s} . ($f->{o} eq 'a' ? ' ASC' : ' DESC'); + my($list, $np) = $self->DBGetRLists( + uid => $uid, + results => 50, + page => $f->{p}, + order => $order, + char => $f->{c} eq 'all' ? undef : $f->{c}, + ); + + $self->ResAddTpl(rlist => { + user => $u, + list => $list, + char => $f->{c}, + order => [ $f->{s}, $f->{o} ], + page => $f->{p}, + npage => $np, + }); +} + 1; diff --git a/lib/VNDB/Votes.pm b/lib/VNDB/Votes.pm deleted file mode 100644 index 99b28465..00000000 --- a/lib/VNDB/Votes.pm +++ /dev/null @@ -1,62 +0,0 @@ - -package VNDB::Votes; - -use strict; -use warnings; -use Exporter 'import'; - -use vars ('$VERSION', '@EXPORT'); -$VERSION = $VNDB::VERSION; -@EXPORT = qw| VNVote VNVotes |; - - -sub VNVote { - my $self = shift; - my $id = shift; - - my $uid = $self->AuthInfo()->{id}; - return $self->ResDenied() if !$uid; - - my $f = $self->FormCheck( - { name => 'v', required => 1, default => 0, enum => [ '-1','1'..'10'] } - ); - return $self->ResNotFound() if $f->{_err}; - - - $self->DBDelVote($uid, $id) if $f->{v} == -1 || $self->DBGetVotes(uid => $uid, vid => $id)->[0]{vid}; - $self->DBAddVote($id, $uid, $f->{v}) if $f->{v} > 0; - - $self->ResRedirect('/v'.$id, 'temp'); -} - - -sub VNVotes { - my $self = shift; - my $user = shift; - - my $u = $self->DBGetUser(uid => $user)->[0]; - return $self->ResNotFound if !$user || !$u || (($self->AuthInfo->{id}||0) != $user && !($u->{flags} & $VNDB::UFLAGS->{votes})); - - my $f = $self->FormCheck( - { name => 's', required => 0, default => 'date', enum => [ qw|date title vote| ] }, - { name => 'o', required => 0, default => 'd', enum => [ 'a','d' ] }, - { name => 'p', required => 0, default => 1, template => 'int' }, - ); - return $self->ResNotFound if $f->{_err}; - - my $order = $f->{s} . ($f->{o} eq 'a' ? ' ASC' : ' DESC'); - my ($votes, $np) = $self->DBGetVotes( - uid => $u->{id}, - order => $order, - results => 50, - page => $f->{p} - ); - - $self->ResAddTpl(myvotes => { - user => $u, - votes => $votes, - page => $f->{p}, - npage => $np, - order => [ $f->{s}, $f->{o} ], - }); -} diff --git a/lib/global.pl b/lib/global.pl index 353ffb6d..c1ee12ab 100644 --- a/lib/global.pl +++ b/lib/global.pl @@ -157,6 +157,23 @@ our $CAT = { }; +our $RSTAT = [ + '[blank]', + 'Pending', + 'Obtained', # hardcoded + 'On loan', + 'Deleted', +]; +our $VSTAT = [ + '[blank]', + 'Playing', + 'Finished', # hardcoded + 'Stalled', + 'Dropped', +]; + + +# OLD our $LSTAT = [ 'Wishlist', 'Blacklist', @@ -187,7 +204,6 @@ our $VRELW = {map{$_=>1}qw| 1 7 9 |}; # users.flags our $UFLAGS = { - votes => 1, list => 4, nsfw => 8, }; diff --git a/static/files/def.js b/static/files/def.js index 3c13402b..fea41239 100644 --- a/static/files/def.js +++ b/static/files/def.js @@ -96,7 +96,12 @@ function dropDown(e) { ddx += obj.offsetLeft; ddy += obj.offsetTop; } while(obj = obj.offsetParent); - ddy += 16; + if(tg.className.indexOf('above') >= 0) { + ddx += 16; + ddy -= x(tg.rel).offsetHeight - 20; + } + else + ddy += 16; obj = x(tg.rel); obj.style.left = ddx+'px'; obj.style.top = ddy+'px'; @@ -107,8 +112,8 @@ function dropDown(e) { var mouseX = e.pageX || (e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft); var mouseY = e.pageY || (e.clientY + document.body.scrollTop + document.documentElement.scrollTop); var obj = x(dds.rel); - if((mouseX < ddx-5 || mouseX > ddx+obj.offsetWidth+5 || mouseY < ddy-20 || mouseY > ddy + obj.offsetHeight) - || (mouseY < ddy && tg.nodeName.toLowerCase() == 'a' && tg != dds)) { + if((mouseX < ddx-15 || mouseX > ddx+obj.offsetWidth+5 || mouseY < ddy-20 || mouseY > ddy + obj.offsetHeight) + || (tg.nodeName.toLowerCase() == 'a' && tg.className.indexOf('dropdown') >= 0 && tg != dds)) { obj.style.left = '-500px'; dds = null; } @@ -226,33 +231,6 @@ DOMLoad(function() { if(x('adsearch')) adsearch(); - // vnlist - cl('askcomment', function() { - this.href = this.href + ';c=' + encodeURIComponent(prompt("Enter personal note (optional)", '')||''); - return true; - }); - - // mass-change vnlist status - if(x('vnlistchange')) { - x('vnlistchange').onchange = function() { - var val = this.options[this.selectedIndex].value; - if(val == '-3') - return; - var l = document.getElementsByTagName('input'); - var y; var ch=0; - for(y=0;y<l.length;y++) - if(l[y].type == 'checkbox' && l[y].checked) - ch++; - if(!ch) - return alert('Nothing selected...'); - if(val == '-1' && !confirm('Are you sure you want to remove the selected items from your visual novel list?')) - return; - if(val == '-2') - x('comments').value = prompt('Enter personal note (leave blank to delete note)','')||''; - document.forms[1].submit(); - } - } - // userdel cl('userdel', function() { return confirm("Completely remove this account from the site?") }); @@ -273,6 +251,59 @@ DOMLoad(function() { this.id = ''; }); + // rlists + i = x('rli'); + if(i) { + var l=i.getElementsByTagName('td'); + for(i=0;i<l.length;i++) + if(l[i].className.indexOf('relhid')>=0) + l[i].onclick = function() { + var id=this.id.substr(2); + var j=0;var o; + var op=x('rr'+id+'-1').style.display == 'none' ? 1 : 0; + while((o=x('rr'+id+'-'+(++j))) != null) + o.style.display = op ? '' : 'none'; + x('rhd'+id).innerHTML = op ? '▾' : '▸'; + }; + var l=x('rli').getElementsByTagName('tr'); + for(i=0;i<l.length;i++) + if(l[i].className.indexOf('relhid')>=0) + l[i].style.display = 'none'; + var allhid=1; + cl('relhidpar', function() { + allhid=!allhid; + l=x('rli').getElementsByTagName('tr'); + for(i=0;i<l.length;i++) + if(l[i].className.indexOf('relhid')>=0) + l[i].style.display = allhid ? 'none' : ''; + l=x('rli').getElementsByTagName('b'); + for(i=0;i<l.length;i++) + if(l[i].id.substr(0,3) == 'rhd') + l[i].innerHTML = !allhid ? '▾' : '▸'; + x('relhidparb').innerHTML = !allhid ? '▾' : '▸'; + }); + } + + // mass-change rlist status + if(x('vnlistchange')) { + x('vnlistchange').onchange = function() { + var val = this.options[this.selectedIndex].value; + if(val == 'n') + return; + var l = x('rli').getElementsByTagName('input'); + var y; var ch=0; + for(y=0;y<l.length;y++) + if(l[y].type == 'checkbox' && l[y].checked) + ch++; + if(!ch) + return alert('Nothing selected...'); + if(val == 'd' && !confirm('Are you sure you want to remove the selected items from your visual novel list?')) + return; + document.forms[1].submit(); + } + } + + // spam protection on all forms if(document.forms.length > 1) for(i=1; i<document.forms.length; i++) @@ -308,7 +339,8 @@ DOMLoad(function() { // zebra-striped tables (client side!? yes... client side :3) var sub = document.getElementsByTagName('tr'); for(i=1; i<sub.length; i+=2) - sub[i].style.backgroundColor = '#f5f5f5'; + if(!sub[i].style.backgroundColor) + sub[i].style.backgroundColor = '#f5f5f5'; }); @@ -316,7 +348,7 @@ DOMLoad(function() { // small hack because the mozilla -moz-inline-stack display hack sucks // (so we're counter-hacking a CSS hack using JS... right) -if(navigator.userAgent.indexOf('Gecko') >= 0 && navigator.userAgent.indexOf('like Gecko') < 0 && navigator.userAgent.indexOf('fox/3') < 0) +if(navigator.userAgent.indexOf('Gecko') >= 0 && navigator.userAgent.indexOf('like Gecko') < 0 && navigator.userAgent.indexOf('3.0') < 0) document.write('<style type="text/css">.icons.lang { width: 15px; height: 13px; }</style>'); diff --git a/static/files/style.css b/static/files/style.css index 6047f517..b383369a 100644 --- a/static/files/style.css +++ b/static/files/style.css @@ -479,12 +479,28 @@ div.dropdown b { font-style: italic; color: #666; } -div.dropdown li.center a { +div.dropdown li.center a, div.dropdown li.center b { text-align: center; } div.dropdown a:hover { background-color: #e0e0e0; } +div.rlistdd { + width: 200px; +} +div.rlistdd ul, div.rlistdd ul li { + float: left; +} +div.rlistdd a, div.rlistdd b { + padding: 1px 5px; +} +div.dropdown ul.full a, div.dropdown ul.full b { + width: 190px; +} +div.dropdown ul.full, div.dropdown ul.full li { + clear: left; + width: 200px; +} /* paragraph markups... */ @@ -748,13 +764,28 @@ b.diff_del { font-weight: normal; background-color: #fcc; } #thi .tc1 { width: 10px } #thi .tc2 { width: 110px; } +#rli tr.relhid { background-color: #fff!important; } +#rli td.relhid, #relhidpar { cursor: pointer; } +#rli td.relnone { color: #aaa }; +#rli .tc1 { width: 560px; } +#rli .tc2 { width: 80px; } +#rli .tc3 { width: 50px; } +#rli .tc1_1 { width: 70px; padding-left: 20px } +#rli .tc1_2 { width: 40px; padding:0; text-align: right; } +#rli .tc1_3 { width: 370px; } +#rli .tc1_4 { width: 60px } +#rli .tc1_3 a { color: #203c36; } +#rli .tc1_6 { text-align: right } + #tre tr { background-color: #fff!important; } #tre tr.lang { background-color: #f5f5f5!important; font-style: italic; } #tre .tc1 { width: 75px; padding-left: 10px; } #tre .tc2 { width: 50px; text-align: center; white-space: nowrap; } -#tre .tc3, #tre .tc5 { width: 16px; margin: 0; padding: 0; white-space: nowrap; text-align: right } +#tre .tc3, #tre .tc6 { width: 16px; margin: 0; padding: 0; white-space: nowrap; text-align: right } #tre .tc3 { width: 70px; } +#tre .tc5 { width: 15px; text-align: right; padding-right: 10px; } +#tre .tc5 a { display: block; width: 15px; text-decoration: none; color: #333; } #tbv .tc2 acronym, #tbv .tc3 acronym { zoom: 1; diff --git a/util/dump.sql b/util/dump.sql index ce0f8be4..54dd9f6b 100644 --- a/util/dump.sql +++ b/util/dump.sql @@ -113,6 +113,16 @@ CREATE TABLE releases_vn ( PRIMARY KEY(rid, vid) ); +-- rlists +CREATE TABLE rlists ( + uid integer NOT NULL DEFAULT 0, + rid integer NOT NULL DEFAULT 0, + vstat smallint NOT NULL DEFAULT 0, + rstat smallint NOT NULL DEFAULT 0, + added bigint NOT NULL DEFAULT DATE_PART('epoch', NOW()), + PRIMARY KEY(uid, rid) +); + -- threads CREATE TABLE threads ( id SERIAL NOT NULL PRIMARY KEY, @@ -247,6 +257,8 @@ ALTER TABLE releases_rev ADD FOREIGN KEY (id) REFERENCES changes ALTER TABLE releases_rev ADD FOREIGN KEY (rid) REFERENCES releases (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE releases_vn ADD FOREIGN KEY (rid) REFERENCES releases_rev (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE releases_vn ADD FOREIGN KEY (vid) REFERENCES vn (id) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE rlists ADD FOREIGN KEY (uid) REFERENCES users (id) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE rlists ADD FOREIGN KEY (rid) REFERENCES releases (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE threads_posts ADD FOREIGN KEY (tid) REFERENCES threads (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE threads_posts ADD FOREIGN KEY (uid) REFERENCES users (id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE threads_tags ADD FOREIGN KEY (tid) REFERENCES threads (id) DEFERRABLE INITIALLY DEFERRED; diff --git a/util/updates/update_1.20.sql b/util/updates/update_1.20.sql index 9c02e184..4abd2211 100644 --- a/util/updates/update_1.20.sql +++ b/util/updates/update_1.20.sql @@ -2,3 +2,16 @@ -- deleted user INSERT INTO users (id, username, mail, rank) VALUES (0, 'deleted', 'del@vndb.org', 0); + + + +-- release lists +CREATE TABLE rlists ( + uid integer NOT NULL DEFAULT 0 REFERENCES users (id) DEFERRABLE INITIALLY DEFERRED, + rid integer NOT NULL DEFAULT 0 REFERENCES releases (id) DEFERRABLE INITIALLY DEFERRED, + vstat smallint NOT NULL DEFAULT 0, + rstat smallint NOT NULL DEFAULT 0, + added bigint NOT NULL DEFAULT DATE_PART('epoch', NOW()), + PRIMARY KEY(uid, rid) +) WITHOUT OIDS; + |