diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7b6563bcc..928838e57 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -14,6 +14,24 @@ module ApplicationHelper render "diff_list", diff: diff end + def decorated_nav_link_to(text, icon, url, **options) + klass = options.delete(:class) + + if nav_link_match(params[:controller], url) + klass = "#{klass} current" + end + + id = "nav-#{text.downcase.gsub(/[^a-z ]/, '').parameterize}" + + tag.li(id: id, class: klass) do + link_to(url, id: "#{id}-link", **options) do + concat tag.i(class: icon) + concat " " + concat tag.span(text) + end + end + end + def nav_link_to(text, url, **options) klass = options.delete(:class) diff --git a/app/javascript/src/javascripts/navigation.js b/app/javascript/src/javascripts/navigation.js new file mode 100644 index 000000000..d2f2fe5d3 --- /dev/null +++ b/app/javascript/src/javascripts/navigation.js @@ -0,0 +1,17 @@ +const Navigation = {}; + +Navigation.init = function () { + const wrapper = $("body"); + $("#nav-toggle").on("click", (event) => { + event.preventDefault(); + + wrapper.toggleClass("nav-toggled"); + }); +}; + +$(() => { + if (!$("nav.navigation").length) return; + Navigation.init(); +}); + +export default Navigation; diff --git a/app/javascript/src/javascripts/responsive.js b/app/javascript/src/javascripts/responsive.js deleted file mode 100644 index 3f821d3fe..000000000 --- a/app/javascript/src/javascripts/responsive.js +++ /dev/null @@ -1,8 +0,0 @@ -$(function () { - $("#maintoggle").on("click.danbooru", function (e) { - e.preventDefault(); - $("#nav").toggle(); - $("#maintoggle-on").toggle(); - $("#maintoggle-off").toggle(); - }); -}); diff --git a/app/javascript/src/styles/base.scss b/app/javascript/src/styles/base.scss index 07847ae48..68379cbe6 100644 --- a/app/javascript/src/styles/base.scss +++ b/app/javascript/src/styles/base.scss @@ -24,9 +24,9 @@ @import "common/jquery_ui_custom.scss"; @import "common/link_decorator.scss"; @import "common/main_layout.scss"; +@import "common/navigation.scss"; @import "common/news.scss"; @import "common/notices.scss"; -@import "common/page_header.scss"; @import "common/paginator.scss"; @import "common/scores"; @import "common/simple_form.scss"; diff --git a/app/javascript/src/styles/common/navigation.scss b/app/javascript/src/styles/common/navigation.scss new file mode 100644 index 000000000..3c7496d43 --- /dev/null +++ b/app/javascript/src/styles/common/navigation.scss @@ -0,0 +1,328 @@ +nav.navigation { + display: grid; + grid-template-areas: "logo logo controls"; + grid-template-columns: min-content auto; + grid-template-rows: min-content auto min-content min-content; + + width: 100%; // otherwise narrow when fixed + z-index: 10; // otherwise post labels layered above + + pointer-events: none; // allow clicking through offset + & > menu { pointer-events: auto; } + + + /* Top bar, always visible */ + .nav-logo { + grid-area: logo; + + a.nav-logo-link { + display: flex; + + height: 3rem; + width: 3rem; + margin: 0.5rem; + + background-image: url("main-logo.png"); + background-repeat: no-repeat; + background-size: contain; + background-position-y: center; + } + } + + .nav-controls { + grid-area: controls; + + display: flex; + flex-flow: row-reverse; + align-items: center; + gap: 0.5em; + + font-size: 1.15rem; + padding-right: 0.5em; + + & > a { + display: flex; + gap: 0.25em; + + padding: 0.25rem 0.5rem; + background: themed("color-foreground"); + border-radius: 6px; + + & > i { + font-size: 1.5rem; + color: themed("color-link-active"); + } + } + } + + /* Prevent toggled menus from being too wide */ + .nav-offset { + grid-area: offset; + pointer-events: none; + display: none; // flex + } + + /* Toggled menus, hidden by default */ + .nav-primary { + grid-area: primary; + display: none; // flex + flex-flow: column; + + background-color: themed("color-section"); + font-size: 1.5em; + + li { + padding: 0; + a { + display: block; + border-bottom: 1px solid themed("color-foreground"); + padding: 0.5em; + + i { + width: 1.5rem; + color: themed("color-link-active"); + text-align: center; + } + } + + &.current a { background-color: themed("color-foreground"); } + } + } + + .nav-secondary { + grid-area: secondary; + display: none; // flex + flex-flow: column; + + background-color: themed("color-foreground"); + font-size: 1.35em; + + li { + padding: 0; + a { + display: block; + border-bottom: 1px solid themed("color-section"); + padding: 0.5em; + } + + &.divider { + border-bottom: 1px solid themed("color-section"); + height: 0.25em; + } + + form input[type="text"] { width: 100%; } + } + } + + .nav-tools { + grid-area: tools; + + display: none; // grid + grid-template-columns: 1fr 1fr; + grid-template-rows: min-content; + + padding: 1rem; + gap: 1rem; + + background-color: themed("color-section"); + border-top: 1px solid themed("color-foreground"); + + li { + padding: 0; + + &.nav-tools-login { grid-column: 1 / -1; } + + & > a { + display: block; + + background: themed("color-section-lighten-5"); + border-radius: 6px; + + font-size: 125%; + padding: 0.5rem 1rem; + text-align: center; + + i { color: themed("color-link-active"); } + } + } + + &.anonymous li.nav-tools-themes { + grid-column: 1 / -1; + } + } + + .nav-help { + grid-area: help; + + display: none; // grid + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: min-content; + + padding: 1rem; + gap: 1rem; + + background: themed("color-section"); + + li { + padding: 0; + + &.nav-help-discord { grid-column: 1 / -1; } + + & > a { + display: block; + + background: themed("color-section-darken-5"); + border-radius: 6px; + + font-size: 125%; + padding: 0.5rem 1rem; + text-align: center; + + i { color: themed("color-link-active"); } + } + } + } +} + + +// Mobile toggle +body.nav-toggled { + padding-top: 4rem; + + nav.navigation { + grid-template-areas: + "logo logo controls" + "offset primary secondary " + "offset tools tools " + "offset help help "; + grid-template-columns: auto minmax(auto, 180px) minmax(auto, 180px); + position: fixed; + top: 0; + height: 100vh; + max-height: 800px; + max-width: 100vw; // prevent bug when page overflows viewport + + // Allow scrolling when the menu is too long + overflow-y: scroll; + + .nav-logo, .nav-controls { + background-color: themed("color-background"); + } + + .nav-primary, .nav-secondary, .nav-offset { + display: flex; + } + .nav-tools, .nav-help { + display: grid; + } + } +} + + +// Desktop +nav.navigation, body.nav-toggled nav.navigation { + @include window-larger-than(800px) { + grid-template-areas: + "logo primary help tools " + "logo secondary secondary secondary" + ; + grid-template-columns: min-content min-content 1fr min-content; + grid-template-rows: 1fr 1fr; + + padding: 0 1em 1em; + box-sizing: border-box; + height: unset; + + .nav-logo { + a.nav-logo-link { margin: 0.5em 0.25em 0 0; } + } + + .nav-offset, .nav-controls { display: none; } + + .nav-primary { + display: flex; + flex-flow: row; + + background: unset; + font-size: 1.05em; + padding: 0 0.25em; + + li { + display: flex; + + a { + align-content: center; + + border-bottom: 0; + padding: 0 0.75em; + i { display: none; } + } + } + } + + .nav-secondary { + display: flex; + flex-flow: row; + align-items: center; + + padding: 0 0.25em; + font-size: 1.05em; + border-radius: 6px; + + // Silly fix for too many links + overflow: hidden; + + li { + a { + border-bottom: 0; + padding: 0 0.75em; + white-space: nowrap; + } + + &.divider { + display: flex; + align-items: center; + &::after { content: "|"; } + } + } + } + + .nav-tools, .nav-help { + display: flex; + + padding: 0; + background: unset; + border: none; + gap: 0; + + li { + display: flex; + + a { + align-content: center; + + background: unset; + font-size: 1.05em; + padding: 0 0.75em; + text-align: unset; + white-space: nowrap; + border-radius: 0; + } + } + } + + .nav-tools { + li a { + span { display: none; } + i { color: themed("color-link"); } + &:hover i { color: themed("color-link-hover"); } + } + } + .nav-help { + li.current a { + background-color: themed("color-foreground"); + i { display: none; } + } + } + } +} \ No newline at end of file diff --git a/app/javascript/src/styles/common/page_header.scss b/app/javascript/src/styles/common/page_header.scss deleted file mode 100644 index 30556071e..000000000 --- a/app/javascript/src/styles/common/page_header.scss +++ /dev/null @@ -1,92 +0,0 @@ - -#maintoggle { - display: none; -} - -#nav { - display: grid; - grid-template-columns: 3.75em 1fr; - grid-template-areas: "logo main" "logo secondary"; - - .logo { - grid-area: logo; - - margin-top: 6px; - background-image: url("main-logo.png"); - background-repeat: no-repeat; - background-size: contain; - background-position-y: center; - } - - .mobile-logo { - display: none; - } - - .main { - grid-area: main; - } - - .secondary { - grid-area: secondary; - } -} - -header#top { - font-size: 1.05em; - margin: 0 $base-padding 0.8rem; - color: themed("color-text"); - background-color: themed("color-background"); - background-image: themed("image-background"); - - #subnav-height-placeholder { - visibility: hidden; - } - - menu { - margin-top: -2px; - background-color: themed("color-foreground"); - border-radius: $border-radius-full; - padding: 6px; - - form { - display: inline-block; - - input { - width: 9.5em; - vertical-align: baseline; - font-size: revert; - padding-top: 0; - padding-bottom: 0; - } - } - - li { - margin: 0; - padding: 0; - white-space: nowrap; - } - - li a { - padding: 6px 10px; - } - } - - menu.main { - margin-top: 0; - background-color: themed("color-background"); - - li.current a { - background-color: themed("color-foreground"); - font-weight: bold; - } - - li#nav-sign-in a { - font-weight: bold; - color: $page-header-sign-in-link-color; - } - - li.forum-updated a { - font-style: italic; - } - } -} diff --git a/app/javascript/src/styles/common/z_responsive.scss b/app/javascript/src/styles/common/z_responsive.scss index 9c41084d7..df11223a5 100644 --- a/app/javascript/src/styles/common/z_responsive.scss +++ b/app/javascript/src/styles/common/z_responsive.scss @@ -130,12 +130,6 @@ } } - #maintoggle { - display: block; - font-weight: bold; - font-size: 2em; - } - /* Make the quick search box in the navbar full width. */ header#top menu form input { width: auto; @@ -216,47 +210,6 @@ } } - #nav { - font-size: 2em; - line-height: 2em; - display: none; - } - - header#top { - input { - font-size: 18pt; - } - - menu.main { - padding: 5px 10px; - - .mobile-logo { - display: inline-block; - width: 1.5em; - box-sizing: border-box; - - a { - display: inline-block; - padding: 6px 10px; - - background-image: url("main-logo.png"); - background-repeat: no-repeat; - background-size: contain; - - // Gives the link height - &::after { - content: "Placeholder"; - visibility: hidden; - } - } - } - } - - menu.secondary.empty { - display: none; - } - } - header { text-align: center; line-height: 2em; diff --git a/app/views/artists/_secondary_links.html.erb b/app/views/artists/_secondary_links.html.erb index 3b2894b27..6f5400b0c 100644 --- a/app/views/artists/_secondary_links.html.erb +++ b/app/views/artists/_secondary_links.html.erb @@ -8,7 +8,7 @@ <%= subnav_link_to "Recent changes", artist_versions_path %> <%= subnav_link_to "URLs", artist_urls_path %> <% if @artist && !@artist.new_record? %> -
  • |
  • +
  • <%= subnav_link_to "Posts (#{@artist.tag.try(:post_count).to_i})", posts_path(tags: @artist.name) %> <%= subnav_link_to "Show", artist_path(@artist) %> <% if @artist.editable_by?(CurrentUser.user) %> @@ -19,7 +19,7 @@ <%= subnav_link_to "Delete", artist_path(@artist), method: :delete, data: { confirm: "Are you sure you want to delete this artist? This cannot be undone." } %> <% end %> <% if @artist.is_dnp? %> -
  • |
  • +
  • <%= subnav_link_to "DNP", avoid_posting_path(@artist.avoid_posting) %> <% end %> <% else %> diff --git a/app/views/avoid_postings/_secondary_links.html.erb b/app/views/avoid_postings/_secondary_links.html.erb index 536b761e1..f77a68f74 100644 --- a/app/views/avoid_postings/_secondary_links.html.erb +++ b/app/views/avoid_postings/_secondary_links.html.erb @@ -18,6 +18,6 @@ <% else %> <%= subnav_link_to "History", avoid_posting_versions_path %> <% end %> -
  • |
  • +
  • <%= subnav_link_to "Static", avoid_posting_static_path %> <% end %> diff --git a/app/views/blips/_secondary_links.html.erb b/app/views/blips/_secondary_links.html.erb index cfb3f47fd..4066e5bd8 100644 --- a/app/views/blips/_secondary_links.html.erb +++ b/app/views/blips/_secondary_links.html.erb @@ -3,7 +3,7 @@ <%= subnav_link_to "List", blips_path %> <%= subnav_link_to "New", new_blip_path %> <% unless @blip&.response_to.nil? %> -
  • |
  • +
  • <%= subnav_link_to "Parent", blip_path(@blip.response_to) %> <% end %> <% end %> diff --git a/app/views/dmails/_secondary_links.html.erb b/app/views/dmails/_secondary_links.html.erb index b8ee61a8f..8e2b72f8e 100644 --- a/app/views/dmails/_secondary_links.html.erb +++ b/app/views/dmails/_secondary_links.html.erb @@ -3,9 +3,9 @@ <%= subnav_link_to "All", all_dmails_path(set_default_folder: true) %> <%= subnav_link_to "Received", received_dmails_path(set_default_folder: true) %> <%= subnav_link_to "Sent", sent_dmails_path(set_default_folder: true) %> -
  • |
  • +
  • <%= subnav_link_to "New", new_dmail_path %> <%= subnav_link_to "Mark all as read", mark_all_as_read_dmails_path, method: :put %> -
  • |
  • +
  • <%= subnav_link_to "Help", help_page_path(id: "dmail") %> <% end %> diff --git a/app/views/forum_topics/_secondary_links.html.erb b/app/views/forum_topics/_secondary_links.html.erb index 3d552f473..a3b42e653 100644 --- a/app/views/forum_topics/_secondary_links.html.erb +++ b/app/views/forum_topics/_secondary_links.html.erb @@ -13,7 +13,7 @@ <%= subnav_link_to "Search", search_forum_posts_path %> <%= subnav_link_to "Help", help_page_path(id: "forum") %> <% if CurrentUser.is_member? && @forum_topic && !@forum_topic.new_record? %> -
  • |
  • +
  • <%= subnav_link_to "Reply", new_forum_post_path(forum_post: { topic_id: @forum_topic.id }) %> <% if @forum_topic.user_subscription(CurrentUser.user) %> <%= subnav_link_to "Unsubscribe", unsubscribe_forum_topic_path(@forum_topic), method: :post %> diff --git a/app/views/help/_secondary_links.html.erb b/app/views/help/_secondary_links.html.erb index 1cc0c3b57..ee94d61fa 100644 --- a/app/views/help/_secondary_links.html.erb +++ b/app/views/help/_secondary_links.html.erb @@ -15,7 +15,7 @@ <% if (related_array = @help.related_array).any? %> <% help_pages = HelpPage.help_index %> -
  • |
  • +
  • <% related_array.each do |related| %>
  • <%= subnav_link_to HelpPage.pretty_related_title(related, help_pages), help_page_path(related) %>
  • <% end %> diff --git a/app/views/layouts/_main_links.html.erb b/app/views/layouts/_main_links.html.erb index 020b65f16..eea0868fb 100644 --- a/app/views/layouts/_main_links.html.erb +++ b/app/views/layouts/_main_links.html.erb @@ -1,23 +1,7 @@ -<%= nav_link_to("", "/", class: "mobile-logo") %> -<% if CurrentUser.is_anonymous? %> - <%= nav_link_to("Sign in", new_session_path) %> -<% else %> - <%= nav_link_to("Account #{unread_dmails(CurrentUser.user)}", home_users_path) %> -<% end %> -<%= nav_link_to("Posts", posts_path) %> -<%= nav_link_to("Comments", comments_path(group_by: "post")) %> -<%= nav_link_to("Artists", artists_path) %> -<%= nav_link_to("Tags", tags_path) %> -<%= nav_link_to("Blips", blips_path) %> -<%= nav_link_to("Pools", gallery_pools_path) %> -<%= nav_link_to("Sets", post_sets_path) %> -<%= nav_link_to("Wiki", wiki_pages_path(title: "help:home")) %> -<%= nav_link_to("Forum", forum_topics_path, class: (CurrentUser.has_forum_been_updated? ? "forum-updated" : nil)) %> -<% if CurrentUser.is_moderator? %> - <%= nav_link_to("Dashboard", moderator_dashboard_path) %> -<% end %> -<% if !CurrentUser.is_anonymous? %> - <%= nav_link_to("Discord", discord_get_path) %> -<% end %> -<%= nav_link_to("Help", help_pages_path) %> -<%= nav_link_to("More ยป", site_map_path) %> +<%= decorated_nav_link_to("Posts", "fas fa-images", posts_path) %> +<%= decorated_nav_link_to("Pools", "fas fa-book", gallery_pools_path) %> +<%= decorated_nav_link_to("Sets", "fas fa-clone", post_sets_path) %> +<%= decorated_nav_link_to("Tags", "fas fa-tags", tags_path) %> +<%= decorated_nav_link_to("Blips", "fas fa-bullhorn", blips_path) %> +<%= decorated_nav_link_to("Comments", "fas fa-comment-alt", comments_path(group_by: "post")) %> +<%= decorated_nav_link_to("Forum", "fas fa-chalkboard", forum_topics_path, class: (CurrentUser.has_forum_been_updated? ? "forum-updated" : nil)) %> diff --git a/app/views/layouts/_nav.html.erb b/app/views/layouts/_nav.html.erb new file mode 100644 index 000000000..5ec4699fa --- /dev/null +++ b/app/views/layouts/_nav.html.erb @@ -0,0 +1,56 @@ + \ No newline at end of file diff --git a/app/views/layouts/default.html.erb b/app/views/layouts/default.html.erb index 6db37b891..21c2c6963 100644 --- a/app/views/layouts/default.html.erb +++ b/app/views/layouts/default.html.erb @@ -6,26 +6,7 @@ <%= tag.body(**body_attributes(CurrentUser.user)) do %> <%= render "layouts/theme_include" %> -
    -
    - - -
    - - -
    + <%= render "layouts/nav" %>
    <%= render "news_updates/notice", news_update: NewsUpdate.recent %> diff --git a/app/views/pools/_secondary_links.html.erb b/app/views/pools/_secondary_links.html.erb index 5dc13913b..0f36b9321 100644 --- a/app/views/pools/_secondary_links.html.erb +++ b/app/views/pools/_secondary_links.html.erb @@ -5,7 +5,7 @@ <%= subnav_link_to "New", new_pool_path %> <%= subnav_link_to "Help", help_page_path(id: "pools") %> <% if @pool && !@pool.new_record? %> -
  • |
  • +
  • <%= subnav_link_to "Show", pool_path(@pool) %> <%= subnav_link_to "Posts", posts_path(tags: "pool:#{@pool.id}") %> <% if CurrentUser.is_member? %> diff --git a/app/views/post_sets/_secondary_links.html.erb b/app/views/post_sets/_secondary_links.html.erb index 16447b2f1..268d2aaf7 100644 --- a/app/views/post_sets/_secondary_links.html.erb +++ b/app/views/post_sets/_secondary_links.html.erb @@ -7,7 +7,7 @@ <%= subnav_link_to "Invites", post_set_maintainers_path %> <% end %> <% if @post_set&.id %> -
  • |
  • +
  • <%= subnav_link_to "Posts", posts_path(tags: "set:#{@post_set.shortname}") %> <%= subnav_link_to "Maintainers", maintainers_post_set_path(@post_set) %> diff --git a/app/views/posts/partials/common/_secondary_links.html.erb b/app/views/posts/partials/common/_secondary_links.html.erb index d40e105d2..fb70c7911 100644 --- a/app/views/posts/partials/common/_secondary_links.html.erb +++ b/app/views/posts/partials/common/_secondary_links.html.erb @@ -12,7 +12,7 @@
  • Blacklist
  • <%= subnav_link_to "Help", help_page_path(id: "posts") %> <% if CurrentUser.can_approve_posts? %> -
  • |
  • +
  • Approvals: Off
  • <% end %> <% end %> diff --git a/app/views/tags/_secondary_links.html.erb b/app/views/tags/_secondary_links.html.erb index 5330d5038..513798964 100644 --- a/app/views/tags/_secondary_links.html.erb +++ b/app/views/tags/_secondary_links.html.erb @@ -9,7 +9,7 @@ <%= subnav_link_to "Cheatsheet", help_page_path(id: "cheatsheet") %> <%= subnav_link_to "Help", help_page_path(id: "tags") %> <% if @tag %> -
  • |
  • +
  • <%= subnav_link_to "Posts (#{@tag.post_count})", posts_path(tags: @tag.name) %> <%= subnav_link_to "Wiki Page", show_or_new_wiki_pages_path(title: @tag.name) %> <%= subnav_link_to "Edit", edit_tag_path(@tag) %> diff --git a/app/views/user_feedbacks/_secondary_links.html.erb b/app/views/user_feedbacks/_secondary_links.html.erb index 8e997e68e..0a6ca2580 100644 --- a/app/views/user_feedbacks/_secondary_links.html.erb +++ b/app/views/user_feedbacks/_secondary_links.html.erb @@ -11,7 +11,7 @@ <%= subnav_link_to "Listing", user_feedbacks_path %> <%= subnav_link_to "Search", search_user_feedbacks_path %> <% if CurrentUser.is_moderator? %> -
  • |
  • +
  • <% if @user_feedback %> <%= subnav_link_to "Ban", new_ban_path(ban: { user_id: @user_feedback.user_id }) %> <% elsif params.dig(:search, :user_id) %> diff --git a/app/views/users/_secondary_links.html.erb b/app/views/users/_secondary_links.html.erb index 2f2d97cfb..fa62cb0ed 100644 --- a/app/views/users/_secondary_links.html.erb +++ b/app/views/users/_secondary_links.html.erb @@ -8,7 +8,7 @@ <% end %> <% if @user && !@user.new_record? && !CurrentUser.user.is_anonymous? %> -
  • |
  • +
  • <% if @user.id == CurrentUser.user.id %> <%= subnav_link_to "Settings", edit_user_path(CurrentUser.user) %> <%= subnav_link_to "Profile", user_path(CurrentUser.user) %> @@ -33,7 +33,7 @@ <% end %> <% end %> -
  • |
  • +
  • <%= subnav_link_to "Sign out", session_path, method: :delete %> <% end %> <% end %> diff --git a/app/views/wiki_pages/_secondary_links.html.erb b/app/views/wiki_pages/_secondary_links.html.erb index c73360a85..47dc049bd 100644 --- a/app/views/wiki_pages/_secondary_links.html.erb +++ b/app/views/wiki_pages/_secondary_links.html.erb @@ -12,7 +12,7 @@ <%= subnav_link_to "Help", help_page_path(id: "wiki") %> <% if @wiki_page %> -
  • |
  • +
  • <% if @wiki_page.tag.present? %> <%= subnav_link_to "Posts (#{@wiki_page.tag.post_count})", posts_path(tags: @wiki_page.title) %> @@ -41,7 +41,7 @@ <% end %> <% end %> <% elsif @wiki_page_version %> -
  • |
  • +
  • <%= subnav_link_to "Newest", wiki_page_path(@wiki_page_version.wiki_page_id) %> @@ -53,7 +53,7 @@ <%= subnav_link_to "Revert to", revert_wiki_page_path(@wiki_page_version.wiki_page_id, version_id: @wiki_page_version.id), method: :put, data: { confirm: "Are you sure you want to revert to this version?" } %> <% end %> <% elsif @thispage %> -
  • |
  • +
  • <%= subnav_link_to "Newest", wiki_page_path(@thispage.wiki_page_id) %>