summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2021-06-19 16:48:35 +0200
committerYorhel <git@yorhel.nl>2021-06-19 16:52:01 +0200
commit19915ad171ed996cf914e2899a4e7643b18c65eb (patch)
tree1f6895394d4a2d1fcfb20303737a6de6e86af3ef
parent4feb1a15aa8ea9e7acce64e4434782ee4202522f (diff)
cssv3/witch: Add some icons and make header menu mostly workcssv3
-rw-r--r--css/docs-page.sass1
-rw-r--r--css/layout-angel.sass2
-rw-r--r--css/layout-witch.sass39
-rw-r--r--css/v3.sass43
-rw-r--r--elm/details-dropdown.js30
-rw-r--r--lib/VNWeb/HTML.pm106
-rw-r--r--static/f/bell.svg4
-rw-r--r--static/f/random.svg4
-rw-r--r--static/f/search.svg5
9 files changed, 217 insertions, 17 deletions
diff --git a/css/docs-page.sass b/css/docs-page.sass
index 383aeee5..56a67690 100644
--- a/css/docs-page.sass
+++ b/css/docs-page.sass
@@ -104,4 +104,3 @@
.docs-page .markdown
padding: 0
flex: 1
- min-width: 0
diff --git a/css/layout-angel.sass b/css/layout-angel.sass
index 2e2f6765..20ebb5b6 100644
--- a/css/layout-angel.sass
+++ b/css/layout-angel.sass
@@ -10,7 +10,7 @@
position: absolute
top: 80px
left: 400px
- font: italic 24px $headerfont
+ font: bold italic 24px $headerfont
color: $maintitle
#bgright
diff --git a/css/layout-witch.sass b/css/layout-witch.sass
index 304e37e2..67d92fa2 100644
--- a/css/layout-witch.sass
+++ b/css/layout-witch.sass
@@ -22,7 +22,6 @@
display: flex
justify-content: flex-start
align-items: center
- font-size: 16px
> h1 // logo
font-size: 18px
@@ -35,14 +34,50 @@
justify-content: space-between
align-items: center
+ .icon
+ height: 14px
+
+ a:hover
+ color: #3f3f3f
+
+ .noti
+ position: relative
+ > span
+ position: absolute
+ top: 3px
+ right: 5px
+ font-size: 8px
+ background: #e63131
+ color: #fff
+ padding: 3px 4px
+ font-weight: 500
+ line-height: 1
+ min-width: 14px
+ border-radius: 100px
+ text-align: center
+
> section
display: flex
align-items: center
&:nth-item(2)
justify-content: flex-end
- > *
+ > a, > details summary
padding: 8px 16px
+ font-size: 16px
+
+ details input[type=submit] // logout button
+ display: block;
+ padding: 4px 16px
+ cursor: pointer
+ width: 100%
+ background-color: #fff
+ color: $maintext
+ text-align: left
+ margin-top: 20px
+ &:hover
+ background-color: #f1f1f1
+ color: #171717
// TODO: The header can also have "row"s
diff --git a/css/v3.sass b/css/v3.sass
index ed95c9bf..4923683a 100644
--- a/css/v3.sass
+++ b/css/v3.sass
@@ -55,6 +55,7 @@ $blendbg: #{if($angel, rgb((red($boxbg) * alpha($boxbg) + red($bodybg) * (1 - al
font: inherit
color: inherit
text-decoration: inherit
+ min-width: 0
@@ -133,6 +134,48 @@ main a
background-color: $noticebg
border: 1px solid $noticeborder
+
+// Generic dropdown, usage:
+// <details class="dropdown">
+// <summary>label</summary>
+//
+// // In the case of a simple dropdown menu:
+// <ul>
+// <li><a href=..>menu item</a></li>
+// <li><div>misc stuff here</div></li>
+// </ul>
+//
+// // Other top-level element types can be added for other types of dropdowns (e.g. forms, info windows, etc)
+// </details>
+details.dropdown
+ position: relative
+
+ > summary
+ cursor: pointer
+ list-style: none
+ &::-webkit-details-marker
+ display: none
+
+ > *:nth-child(2)
+ position: absolute
+ top: 40px // XXX: Depends on height of <summary>
+ right: 0px
+ background-color: #{if($angel, $blendbg, #fff)}
+ box-shadow: 0 15px 35px rgba(50,50,93,.2),0 5px 15px rgba(0,0,0,.2)
+
+ > ul
+ list-style-type: none
+ padding: 6px 0
+ > li
+ > a, > div
+ display: block
+ padding: 4px 16px
+ white-space: nowrap
+ > a:hover
+ background-color: #f1f1f1
+ color: #171717
+
+
@import "css/layout-angel"
@import "css/layout-witch"
@import "css/docs-page"
diff --git a/elm/details-dropdown.js b/elm/details-dropdown.js
new file mode 100644
index 00000000..4ab2e01c
--- /dev/null
+++ b/elm/details-dropdown.js
@@ -0,0 +1,30 @@
+/* JS support code for <details>-based dropdown implementation.
+ * See css/v3.sass for an overview of how to use those.
+ *
+ * They generally work without JS, but can only be closed by clicking on the
+ * <summary> element again. This support code allows closing the dropdown by
+ * clicking anywhere on the page.
+ */
+var active = null;
+function close() {
+ if(active && active.open) active.open = false;
+ set(null);
+}
+function stop(ev) {
+ ev.stopPropagation();
+}
+function set(el) {
+ if(active)
+ active.removeEventListener('click', stop);
+ if(el) {
+ el.addEventListener('click', stop);
+ document.addEventListener('click', close);
+ } else
+ document.removeEventListener('click', close);
+ active = el;
+}
+document.querySelectorAll('details.dropdown').forEach(function(el) {
+ el.addEventListener('toggle', function() {
+ set(el.open ? el : null);
+ });
+});
diff --git a/lib/VNWeb/HTML.pm b/lib/VNWeb/HTML.pm
index 63dafa6d..b1f740ff 100644
--- a/lib/VNWeb/HTML.pm
+++ b/lib/VNWeb/HTML.pm
@@ -102,11 +102,12 @@ sub user_ {
sub user_displayname {
my $obj = shift;
my $prefix = shift||'user_';
+ my $capital = shift;
my sub f($) { $obj->{"${prefix}$_[0]"} }
return 'anonymous' if !f 'id';
my $fancy = !(auth->pref('nodistract_can') && auth->pref('nodistract_nofancy'));
- $fancy && f 'uniname_can' && f 'uniname' ? f 'uniname' : f 'name'
+ $fancy && f 'uniname_can' && f 'uniname' ? f 'uniname' : $capital ? ucfirst f 'name' : f 'name'
}
@@ -240,7 +241,7 @@ sub _menu_angel_ {
section_ sub {
my $uid = '/'.auth->uid;
- my $nc = auth && tuwf->dbVali('SELECT count(*) FROM notifications WHERE uid =', \auth->uid, 'AND read IS NULL');
+ my $nc = tuwf->dbVali('SELECT count(*) FROM notifications WHERE uid =', \auth->uid, 'AND read IS NULL');
h2_ sub { user_ auth->user, 'user_', 1 };
p_ sub {
a_ href => "$uid/edit", 'My Profile'; txt_ '⭐' if auth->pref('nodistract_can') && !auth->pref('nodistract_nofancy'); br_;
@@ -282,9 +283,9 @@ sub _menu_angel_ {
h2_ 'User menu';
p_ sub {
my $ref = uri_escape tuwf->reqPath().tuwf->reqQuery();
- a_ href => "/u/login?ref=$ref", 'Login'; br_;
- a_ href => '/u/newpass', 'Password reset'; br_;
- a_ href => '/u/register', 'Register'; br_;
+ a_ href => "/u/login?ref=$ref", 'Login';
+ lit_ ' - ';
+ a_ href => '/u/register', 'Register';
}
} if !auth;
@@ -308,22 +309,100 @@ sub _menu_angel_ {
sub _menu_witch_ {
my $o = shift;
- # TODO: Support VNDB things
+ # TODO: "Support VNDB" things
# TODO: Responsive hamburger thing
- # TODO: Don't require click to see database links
section_ sub {
- a_ href => '#', sub { txt_ 'Database'; span_ class => 'caret', '' };
+ # TODO: Don't require click to see database links
+ # (But if we're going to keep this menu, witchcapture's two-column layout is better)
+ details_ class => 'dropdown', sub {
+ tag_ 'summary', sub { txt_ 'Database'; span_ class => 'caret', '' };
+ ul_ sub {
+ li_ sub { a_ href => '/v', 'Visual novels' };
+ li_ sub { a_ href => '/g', '> Tags' };
+ li_ sub { a_ href => '/r', 'Releases' };
+ li_ sub { a_ href => '/p/all', 'Producers' };
+ li_ sub { a_ href => '/s', 'Staff' };
+ li_ sub { a_ href => '/c', 'Characters' };
+ li_ sub { a_ href => '/i', '> Traits' };
+ };
+ };
a_ href => '/d6', 'FAQ';
a_ href => '/t', 'Forums';
- a_ href => '#', sub { txt_ 'Contribute'; span_ class => 'caret', '' }; # TODO: Should prolly go to the user menu as a [+] icon
- # TODO: Random VN icon could be placed here, wouldn't take much space
- a_ href => '#', '🔎'; # TODO: svg icon
+ a_ href => '/v/rand', title => 'Random visual novel', sub {
+ img_ src => config->{url_static}.'/f/random.svg', class => 'icon';
+ };
+ a_ href => '/v', title => 'Search visual novels', sub {
+ # TODO: Input box
+ img_ src => config->{url_static}.'/f/search.svg', class => 'icon';
+ };
};
+
section_ sub {
- # TODO: Notifications and user menu
a_ href => '/u/register', 'Register';
a_ href => '/u/login', 'Login';
- };
+ } if !auth;
+
+ section_ sub {
+ my $uid = '/'.auth->uid;
+ my $nc = tuwf->dbVali('SELECT count(*) FROM notifications WHERE uid =', \auth->uid, 'AND read IS NULL');
+ a_ href => "$uid/notifies", class => 'noti', sub {
+ img_ alt => 'Notififications', src => config->{url_static}.'/f/bell.svg', class => 'icon';
+ span_ $nc;
+ } if $nc;
+
+ my $reports = auth->isMod && tuwf->dbRowi("SELECT
+ (SELECT count(*) FROM reports WHERE status = 'new') as new,
+ (SELECT count(*) FROM reports WHERE status = 'new' AND date > (SELECT last_reports FROM users WHERE id =", \auth->uid, ")) AS unseen,
+ (SELECT count(*) FROM reports WHERE lastmod > (SELECT last_reports FROM users WHERE id =", \auth->uid, ")) AS upd
+ ");
+ details_ class => 'dropdown', sub {
+ tag_ 'summary', title => 'Contribute', mkclass(standout => $reports && $reports->{unseen}), sub {
+ strong_ '+';
+ span_ class => 'caret', '';
+ };
+ ul_ sub {
+ li_ sub { a_ href => '/hist', 'Recent changes' };
+ if(auth->permImgvote) {
+ li_ sub { a_ href => '/img/vote', 'Image Flagging' };
+ }
+ if(auth->permEdit) {
+ li_ sub { a_ href => '/v/add', 'Add Visual Novel' };
+ li_ sub { a_ href => '/p/add', 'Add Producer' };
+ li_ sub { a_ href => '/s/new', 'Add Staff' };
+ }
+ li_ sub {
+ div_ sub {
+ a_ $reports->{unseen} ? (class => 'standout') : (), href => '/report/list?status=new', sprintf 'Reports %d/%d', $reports->{unseen}, $reports->{new};
+ small_ ' | ';
+ a_ href => '/report/list?s=lastmod', sprintf '%d upd', $reports->{upd};
+ }
+ } if $reports;
+ };
+ };
+ details_ class => 'dropdown', sub {
+ tag_ 'summary', sub {
+ txt_ user_displayname auth->user, 'user_', 1;
+ span_ class => 'caret', '';
+ };
+ ul_ sub {
+ li_ sub { a_ href => "$uid/edit", sub { txt_ 'My Profile'; txt_ '⭐' if auth->pref('nodistract_can') && !auth->pref('nodistract_nofancy') } };
+ li_ sub { a_ href => "$uid/ulist?vnlist=1", 'My Visual Novel List' };
+ li_ sub { a_ href => "$uid/ulist?votes=1",'My Votes' };
+ li_ sub { a_ href => "$uid/ulist?wishlist=1", 'My Wishlist' };
+ li_ sub { a_ href => "$uid/notifies", 'My Notifications' };
+ li_ sub { a_ href => "$uid/hist", 'My Recent Changes' };
+ li_ sub { a_ href => '/g/links?u='.auth->uid, 'My Tags' };
+ li_ sub {
+ form_ action => "$uid/logout", method => 'post', sub {
+ fieldset_ sub {
+ input_ type => 'hidden', name => 'csrf', value => auth->csrftoken;
+ input_ type => 'submit', value => 'Logout';
+ }
+ }
+ }
+ };
+ };
+ } if auth;
}
@@ -567,6 +646,7 @@ sub framework_ {
$o{skin} = config->{skin_default} if !skins->{$o{skin}};
tuwf->req->{layout} = skins->{$o{skin}}{layout};
tuwf->req->{v3} = $o{v3};
+ tuwf->req->{js} = 1 if tuwf->witch; # Witch layout requires JS for dropdown menus
html_ lang => 'en', sub {
head_ sub { _head_ \%o };
diff --git a/static/f/bell.svg b/static/f/bell.svg
new file mode 100644
index 00000000..125639c7
--- /dev/null
+++ b/static/f/bell.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 448 512" xmlns="http://www.w3.org/2000/svg">
+<path d="M425 331c-17-17-34-34-34-116 0-83-61-152-141-165a32 32 0 0 0 6-18 32 32 0 0 0-64 0 32 32 0 0 0 6 18C118 63 57 132 57 215c0 82-17 99-34 116a67 67 0 0 0 44 117h93a64 64 0 0 0 128 0h93c57 0 92-70 44-117zM224 472c-13 0-24-11-24-24h48c0 13-11 24-24 24zm157-72H67c-17 0-25-20-13-32 28-29 51-56 51-153a119 119 0 0 1 238 0c0 98 23 124 51 153 12 12 4 32-13 32z"/>
+</svg>
diff --git a/static/f/random.svg b/static/f/random.svg
new file mode 100644
index 00000000..07d9b08c
--- /dev/null
+++ b/static/f/random.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
+<path d="M505 359c9 9 9 25 0 34l-80 80c-15 15-41 4-41-17v-40h-59a12 12 0 0 1-9-4l-70-75 53-58 53 57h32v-40c0-21 26-32 41-17l80 80zM12 176h84l53 57 53-58-70-75a12 12 0 0 0-9-4H12c-7 0-12 5-12 12v56c0 7 5 12 12 12zm372 0v40c0 21 26 32 41 17l80-80c9-9 9-25 0-34l-80-80c-15-15-41-4-41 17v40h-59a12 12 0 0 0-9 4L96 336H12c-7 0-12 5-12 12v56c0 7 5 12 12 12h111c3 0 6-1 9-4l220-236h32z"/>
+</svg>
diff --git a/static/f/search.svg b/static/f/search.svg
new file mode 100644
index 00000000..427a6dae
--- /dev/null
+++ b/static/f/search.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m10.442 10.442a1 1 0 0 1 1.415 0l3.85 3.85a1 1 0 0 1-1.414 1.415l-3.85-3.85a1 1 0 0 1 0-1.415z" fill-rule="evenodd"/>
+<path d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z" fill-rule="evenodd"/>
+</svg>