diff options
author | Yorhel <git@yorhel.nl> | 2021-06-19 16:48:35 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2021-06-19 16:52:01 +0200 |
commit | 19915ad171ed996cf914e2899a4e7643b18c65eb (patch) | |
tree | 1f6895394d4a2d1fcfb20303737a6de6e86af3ef | |
parent | 4feb1a15aa8ea9e7acce64e4434782ee4202522f (diff) |
cssv3/witch: Add some icons and make header menu mostly workcssv3
-rw-r--r-- | css/docs-page.sass | 1 | ||||
-rw-r--r-- | css/layout-angel.sass | 2 | ||||
-rw-r--r-- | css/layout-witch.sass | 39 | ||||
-rw-r--r-- | css/v3.sass | 43 | ||||
-rw-r--r-- | elm/details-dropdown.js | 30 | ||||
-rw-r--r-- | lib/VNWeb/HTML.pm | 106 | ||||
-rw-r--r-- | static/f/bell.svg | 4 | ||||
-rw-r--r-- | static/f/random.svg | 4 | ||||
-rw-r--r-- | static/f/search.svg | 5 |
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> |