diff --git a/app/components/post_navbar_component.rb b/app/components/post_navbar_component.rb new file mode 100644 index 000000000..9f02dfee0 --- /dev/null +++ b/app/components/post_navbar_component.rb @@ -0,0 +1,39 @@ +class PostNavbarComponent < ApplicationComponent + extend Memoist + + attr_reader :post, :current_user, :search, :pool_id, :favgroup_id + + def initialize(post:, current_user:, search: nil, pool_id: nil, favgroup_id: nil) + @post = post + @current_user = current_user + @search = search.presence || "status:any" + @pool_id = pool_id&.to_i + @favgroup_id = favgroup_id&.to_i + end + + def render? + has_search_navbar? || pools.any? || favgroups.any? + end + + def pools + post.pools.undeleted.sort_by do |pool| + [pool.id == pool_id ? 0 : 1, pool.is_series? ? 0 : 1, pool.name] + end + end + + def favgroups + current_user.favorite_groups.for_post(post.id).sort_by do |favgroup| + [favgroup.id == favgroup_id ? 0 : 1, favgroup.name] + end + end + + def has_search_navbar? + !has_order_metatag? && pool_id.blank? && favgroup_id.blank? + end + + def has_order_metatag? + PostQueryBuilder.new(search).has_metatag?(:order, :ordfav, :ordpool) + end + + memoize :pools, :favgroups +end diff --git a/app/components/post_navbar_component/post_navbar_component.html.erb b/app/components/post_navbar_component/post_navbar_component.html.erb new file mode 100644 index 000000000..0d290dc24 --- /dev/null +++ b/app/components/post_navbar_component/post_navbar_component.html.erb @@ -0,0 +1,69 @@ + diff --git a/app/components/post_navbar_component/post_navbar_component.scss b/app/components/post_navbar_component/post_navbar_component.scss new file mode 100644 index 000000000..127b81c4c --- /dev/null +++ b/app/components/post_navbar_component/post_navbar_component.scss @@ -0,0 +1,31 @@ +.post-notice-search { + li { + display: flex; + + &[data-selected="true"] { + font-weight: bold; + } + + .first, .prev, .next, .last { + flex: 0; + margin: 0 0.25em; + white-space: nowrap; + } + + .first, .last { + flex-basis: 1em; + } + + &.search-navbar .prev, &.search-navbar .next { + margin: 0 1.75em; + } + + .pool-name, .favgroup-name, .search-name { + flex: 1; + text-align: center; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } +} diff --git a/app/helpers/components_helper.rb b/app/helpers/components_helper.rb index c3538dd3e..b12be2897 100644 --- a/app/helpers/components_helper.rb +++ b/app/helpers/components_helper.rb @@ -18,4 +18,8 @@ module ComponentsHelper def render_post_votes(post, **options) render PostVotesComponent.new(post: post, **options) end + + def render_post_navbar(post, **options) + render PostNavbarComponent.new(post: post, **options) + end end diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb index d43948dd8..4c099c7bc 100644 --- a/app/helpers/posts_helper.rb +++ b/app/helpers/posts_helper.rb @@ -41,11 +41,4 @@ module PostsHelper source end end - - def is_pool_selected?(pool) - return false if params.key?(:q) - return false if params.key?(:favgroup_id) - return false if !params.key?(:pool_id) - return params[:pool_id].to_i == pool.id - end end diff --git a/app/javascript/src/javascripts/posts.js.erb b/app/javascript/src/javascripts/posts.js.erb index 8963aa31b..a6587e8a9 100644 --- a/app/javascript/src/javascripts/posts.js.erb +++ b/app/javascript/src/javascripts/posts.js.erb @@ -178,18 +178,8 @@ Post.swipe_prev = function(e) { Post.nav_prev = function(e) { var href = ""; - if ($("#search-seq-nav").length) { - href = $("#search-seq-nav a[rel~=prev]").attr("href"); - if (href) { - location.href = href; - } - } else if ($(".paginator a[rel~=prev]").length) { + if ($(".paginator a[rel~=prev], .post-notice-search a[rel~=prev]").length) { location.href = $("a[rel~=prev]").attr("href"); - } else { - href = $("#pool-nav li[data-selected=true] a[rel=prev], #favgroup-nav li[data-selected=true] a[rel=prev]").attr("href"); - if (href) { - location.href = href; - } } e.preventDefault(); @@ -198,16 +188,8 @@ Post.nav_prev = function(e) { Post.nav_next = function(e) { var href = ""; - if ($("#search-seq-nav").length) { - href = $("#search-seq-nav a[rel~=next]").attr("href"); - location.href = href; - } else if ($(".paginator a[rel~=next]").length) { - location.href = $(".paginator a[rel~=next]").attr("href"); - } else { - href = $("#pool-nav li[data-selected=true] a[rel=next], #favgroup-nav li[data-selected=true] a[rel=next]").attr("href"); - if (href) { - location.href = href; - } + if ($(".paginator a[rel~=next], .post-notice-search a[rel~=next]").length) { + location.href = $("a[rel~=next]").attr("href"); } e.preventDefault(); diff --git a/app/javascript/src/styles/specific/posts.scss b/app/javascript/src/styles/specific/posts.scss index b0f70c642..99cae7de3 100644 --- a/app/javascript/src/styles/specific/posts.scss +++ b/app/javascript/src/styles/specific/posts.scss @@ -208,10 +208,6 @@ div#c-posts { margin: 1em 0 0.5em; } - .pool-name, .search-name { - word-wrap: break-word; - } - textarea { margin-bottom: 0.25em; } @@ -225,51 +221,11 @@ div#c-posts { word-wrap: break-word; } - #search-seq-nav + #pool-nav, #search-seq-nav + #favgroup-nav, #pool-nav + #favgroup-nav { - margin-top: 0.5em; - } - #recommended.loading-recommended-posts { pointer-events: none; opacity: 0.5; } - #pool-nav, #search-seq-nav, #favgroup-nav { - li { - position: relative; - text-align: center; - padding: 0 5.5em; - - &[data-selected="true"] { - font-weight: bold; - } - - .prev { - position: absolute; - left: 2em; - top: 0; - } - - .next { - position: absolute; - right: 2em; - top: 0; - } - - .first { - position: absolute; - left: 0.5em; - top: 0; - } - - .last { - position: absolute; - right: 0.5em; - top: 0; - } - } - } - span.close-button { position: absolute; top: 5px; diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb index 9c098859e..5b308d150 100644 --- a/app/presenters/post_presenter.rb +++ b/app/presenters/post_presenter.rb @@ -17,14 +17,4 @@ class PostPresenter def filename_for_download "#{humanized_essential_tag_string} - #{@post.md5}.#{@post.file_ext}" end - - def has_nav_links?(template) - has_sequential_navigation?(template.params) || @post.pools.undeleted.any? || CurrentUser.favorite_groups.for_post(@post.id).any? - end - - def has_sequential_navigation?(params) - return false if PostQueryBuilder.new(params[:q]).has_metatag?(:order, :ordfav, :ordpool) - return false if params[:pool_id].present? || params[:favgroup_id].present? - true - end end diff --git a/app/views/posts/partials/show/_favorite_groups.html.erb b/app/views/posts/partials/show/_favorite_groups.html.erb deleted file mode 100644 index fe20599bb..000000000 --- a/app/views/posts/partials/show/_favorite_groups.html.erb +++ /dev/null @@ -1,34 +0,0 @@ -
- -
diff --git a/app/views/posts/partials/show/_nav_links.html.erb b/app/views/posts/partials/show/_nav_links.html.erb deleted file mode 100644 index 8a3cfc367..000000000 --- a/app/views/posts/partials/show/_nav_links.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -<% if (position == "bottom" && CurrentUser.user.new_post_navigation_layout) || (position == "top" && !CurrentUser.user.new_post_navigation_layout) %> -
- <% if post.presenter.has_sequential_navigation?(params) %> - <%= render "posts/partials/show/search_seq", :post => post %> - <% end %> - - <% if post.pools.undeleted.present? %> - <%= render "posts/partials/show/pool_list", post: post, pools: post.pools.undeleted %> - <% end %> - - <% if CurrentUser.user.favorite_groups.for_post(post.id).present? %> - <%= render "posts/partials/show/favorite_groups", post: post, favgroups: CurrentUser.user.favorite_groups.for_post(post.id).order(name: :asc) %> - <% end %> -
-<% end %> diff --git a/app/views/posts/partials/show/_pool_list.html.erb b/app/views/posts/partials/show/_pool_list.html.erb deleted file mode 100644 index 20e6dca7a..000000000 --- a/app/views/posts/partials/show/_pool_list.html.erb +++ /dev/null @@ -1,8 +0,0 @@ -
- -
diff --git a/app/views/posts/partials/show/_pool_list_item.html.erb b/app/views/posts/partials/show/_pool_list_item.html.erb deleted file mode 100644 index d9eb82a8e..000000000 --- a/app/views/posts/partials/show/_pool_list_item.html.erb +++ /dev/null @@ -1,33 +0,0 @@ -<%= tag.li id: "nav-link-for-pool-#{pool.id}", class: "pool-category-#{pool.category}", "data-selected": selected do -%> - <% if !pool.first_post?(post.id) && pool.post_ids.first -%> - <%= link_to("«".html_safe, post_path(pool.post_ids.first, pool_id: pool.id), class: "first", title: "to page 1") %> - <% else -%> - « - <% end -%> - - <% pool.previous_post_id(post.id).tap do |previous_post_id| -%> - <% if previous_post_id %> - <%= link_to "‹ prev".html_safe, post_path(previous_post_id, pool_id: pool.id), rel: selected ? "prev" : nil, class: "prev", title: "to page #{pool.page_number(previous_post_id)}" -%> - <% else -%> - ‹ prev - <% end %> - <% end -%> - - - <%= link_to("Pool: #{pool.pretty_name}", pool_path(pool), title: "page #{pool.page_number(post.id)}/#{pool.post_count}") -%> - - - <% pool.next_post_id(post.id).tap do |next_post_id| -%> - <% if next_post_id %> - <%= link_to("next ›".html_safe, post_path(next_post_id, pool_id: pool.id), rel: selected ? "next" : nil, class: "next", title: "to page #{pool.page_number(next_post_id)}") -%> - <% else -%> - next › - <% end -%> - <% end -%> - - <% if !pool.last_post?(post.id) && pool.post_ids.last -%> - <%= link_to("»".html_safe, post_path(pool.post_ids.last, pool_id: pool.id), class: "last", title: "to page #{pool.post_count}") -%> - <% else -%> - » - <% end -%> -<% end -%> diff --git a/app/views/posts/partials/show/_search_seq.html.erb b/app/views/posts/partials/show/_search_seq.html.erb deleted file mode 100644 index 85339ebbc..000000000 --- a/app/views/posts/partials/show/_search_seq.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -
- -
diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb index 183b4f33d..974c3ccac 100644 --- a/app/views/posts/show.html.erb +++ b/app/views/posts/show.html.erb @@ -38,8 +38,8 @@ <% end %> <% content_for(:content) do %> - <% if @post.presenter.has_nav_links?(self) %> - <%= render "posts/partials/show/nav_links", :post => @post, :position => "top" %> + <% if !CurrentUser.user.new_post_navigation_layout %> + <%= render_post_navbar(@post, current_user: CurrentUser.user, search: params[:q], pool_id: params[:pool_id], favgroup_id: params[:favgroup_id]) %> <% end %> <%= render "posts/partials/show/notices", :post => @post %> @@ -82,8 +82,8 @@ <% end %> - <% if @post.presenter.has_nav_links?(self) %> - <%= render "posts/partials/show/nav_links", :post => @post, :position => "bottom" %> + <% if CurrentUser.user.new_post_navigation_layout %> + <%= render_post_navbar(@post, current_user: CurrentUser.user, search: params[:q], pool_id: params[:pool_id], favgroup_id: params[:favgroup_id]) %> <% end %> diff --git a/test/components/post_navbar_component_test.rb b/test/components/post_navbar_component_test.rb new file mode 100644 index 000000000..5bd58e410 --- /dev/null +++ b/test/components/post_navbar_component_test.rb @@ -0,0 +1,52 @@ +require "test_helper" + +class PostNavbarComponentTest < ViewComponent::TestCase + def render_post_navbar(post, **options) + render_inline(PostNavbarComponent.new(post: post, **options)) + end + + setup do + @post = create(:post) + @user = create(:user) + end + + context "The PostNavbarComponent" do + context "for a post with a search" do + should "render" do + render_post_navbar(@post, current_user: @user, search: "touhou") + + assert_css(".search-navbar", text: "Search: touhou") + end + end + + context "for a post with pools" do + should "render" do + as(@user) do + @pool1 = create(:pool, category: "series") + @pool2 = create(:pool, category: "collection") + @post.update(tag_string: "pool:#{@pool1.id} pool:#{@pool2.id}") + end + + render_post_navbar(@post, current_user: @user, pool_id: @pool1.id) + + assert_css(".pool-name", text: "Pool: #{@pool1.pretty_name}") + assert_css(".pool-name", text: "Pool: #{@pool2.pretty_name}") + end + end + + context "for a post with favgroups" do + should "render" do + as(@user) do + @favgroup1 = create(:favorite_group, creator: @user) + @favgroup2 = create(:favorite_group, creator: @user) + @post.update(tag_string: "favgroup:#{@favgroup1.id} favgroup:#{@favgroup2.id}") + end + + render_post_navbar(@post, current_user: @user, favgroup_id: @favgroup1.id) + + assert_css(".favgroup-name", text: "Favgroup: #{@favgroup1.pretty_name}") + assert_css(".favgroup-name", text: "Favgroup: #{@favgroup2.pretty_name}") + end + end + end +end diff --git a/test/functional/posts_controller_test.rb b/test/functional/posts_controller_test.rb index b844d7b7e..bcae0e069 100644 --- a/test/functional/posts_controller_test.rb +++ b/test/functional/posts_controller_test.rb @@ -556,7 +556,7 @@ class PostsControllerTest < ActionDispatch::IntegrationTest get post_path(@post) assert_response :success - assert_select "#pool-nav .pool-name", /Pool: comic/ + assert_select ".pool-navbar .pool-name", /Pool: comic/ end end