[Posts] Rework the post search page to be mobile-first (#855)

This commit is contained in:
Cinder 2025-01-26 06:26:11 -08:00 committed by GitHub
parent 85b8aa2309
commit 0dfcb4710d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 248 additions and 68 deletions

View File

@ -8,7 +8,7 @@ class FavoritesController < ApplicationController
def index
if params[:tags]
redirect_to(posts_path(:tags => params[:tags]))
redirect_to(posts_path(tags: params[:tags]))
else
user_id = params[:user_id] || CurrentUser.user.id
@user = User.find(user_id)
@ -17,10 +17,11 @@ class FavoritesController < ApplicationController
raise Favorite::HiddenError
end
@favorite_set = PostSets::Favorites.new(@user, params[:page], limit: params[:limit])
respond_with(@favorite_set.posts) do |fmt|
@post_set = PostSets::Favorites.new(@user, params[:page], limit: params[:limit])
@posts = PostsDecorator.decorate_collection(@post_set.posts)
respond_with(@posts) do |fmt|
fmt.json do
render json: @favorite_set.api_posts, root: 'posts'
render json: @post_set.api_posts, root: "posts"
end
end
end

View File

@ -0,0 +1,34 @@
const PostSearch = {};
PostSearch.init = function () {
$(".post-search").each((index, element) => {
PostSearch.initialize_input($(element));
});
};
PostSearch.initialize_input = function ($form) {
const $textarea = $form.find("textarea[name='tags']").first();
if (!$textarea.length) return;
const element = $textarea[0];
// Adjust the number of rows based on input length
$textarea
.on("input", () => {
$textarea.css("height", 0);
$textarea.css("height", element.scrollHeight + "px");
})
.on("keypress", function (event) {
if (event.which !== 13 || event.shiftKey) return;
event.preventDefault();
$textarea.closest("form").submit();
});
// Reset default height
$textarea.trigger("input");
};
$(() => {
PostSearch.init();
});
export default PostSearch;

View File

@ -29,6 +29,7 @@
@import "common/news.scss";
@import "common/notices.scss";
@import "common/paginator.scss";
@import "common/post_search.scss";
@import "common/scores";
@import "common/simple_form.scss";
@import "common/spoiler.scss";
@ -64,6 +65,7 @@
@import "specific/popular.scss";
@import "specific/post_delete.scss";
@import "specific/post_flags.scss";
@import "specific/post_index.scss";
@import "specific/post_mode_menu.scss";
@import "specific/posts.scss";
@import "specific/post_replacements.scss";

View File

@ -6,6 +6,11 @@ div.paginator {
text-align: center;
clear: both;
menu {
display: flex;
justify-content: center;
}
li {
a {
margin: 0 0.25em;

View File

@ -0,0 +1,55 @@
// Searchbar
.post-search {
display: flex;
flex-wrap: wrap;
.post-search-title { flex: 1; }
.post-search-help { font-size: 90%; }
form.post-search-form {
display: flex;
width: 100%;
textarea {
// Override default texarea styles
font-family: Verdana, sans-serif;
font-size: 1.05em;
// Remove old styles from z_responsive
vertical-align: unset;
border: unset;
width: unset;
max-width: unset;
// Override style from posts.scss
margin-bottom: 0 !important;
// Disable manual resizing
resize: none;
flex: 1;
padding: 0.5em;
border-radius: 3px 0 0 3px;
box-sizing: border-box;
&:focus, &:focus + button[type="submit"] { background: #FFC; }
}
button[type="submit"] {
// Remove old styles from z_responsive
font-size: unset;
max-width: unset;
font-size: 1em;
padding: 0.5em;
border-radius: 0 3px 3px 0;
background: white;
span { display: none; }
}
}
}

View File

@ -30,8 +30,6 @@
}
}
#search-box { display: none; }
.mobile-search {
display: block;
margin: $padding-050 $padding-050 $padding-150;

View File

@ -0,0 +1,61 @@
.post-index {
display: grid;
grid-template-areas:
"search "
"content"
"sidebar";
grid-template-columns: 1fr;
grid-template-rows: min-content 1fr min-content;
gap: 1em;
// 1. Searchbox
.search {
grid-area: search;
h1 {
font-size: $h3-size;
}
}
// 2. Content
.content {
grid-area: content;
// Quick tag edit
#edit-dialog textarea {
margin-bottom: 0.25em;
}
}
// 3. Sidebar
.sidebar {
grid-area: sidebar;
display: flex;
flex-flow: column;
gap: 1em;
// Mode selection
#mode-box-mode, #mode-box #set-id {
width: 100%;
// Match the searchbox
padding: 0.5em;
font-family: Verdana, sans-serif;
font-size: 1.05em;
}
}
}
// Desktop
.post-index {
@include window-larger-than(800px) {
grid-template-areas:
"search content"
"sidebar content";
grid-template-columns: 15em 1fr;
grid-template-rows: min-content 1fr;
}
}

View File

@ -1,11 +1,5 @@
#mode-box-mode, #mode-box #set-id {
width: 15em; // Match width to that of the
}
#edit-dialog textarea {
margin-bottom: 0.25em;
}
#has-parent-relationship-preview, #has-children-relationship-preview {
flex-direction: row;

View File

@ -28,11 +28,15 @@ module PostSets
end
end
def hidden_posts
@hidden_posts ||= posts.reject(&:visible?)
end
def api_posts
_posts = posts
fill_children(_posts)
fill_tag_types(_posts)
_posts
result = posts
fill_children(result)
fill_tag_types(result)
result
end
def tag_array
@ -42,5 +46,9 @@ module PostSets
def presenter
::PostSetPresenters::Post.new(self)
end
def is_random?
false
end
end
end

View File

@ -0,0 +1,26 @@
<div id="posts" class="user-disable-cropped-<%= Danbooru.config.enable_image_cropping? && CurrentUser.user.disable_cropped_thumbnails? %>">
<section class="posts-container">
<% if @posts.empty? %>
<%= render "posts/blank" %>
<% else %>
<% @posts.each do |post| %>
<%= post.preview_html(self, { tags: @post_set.public_tag_string, show_cropped: true, stats: CurrentUser.show_post_statistics? }) %>
<% end %>
<% end %>
</section>
<% if post_set.hidden_posts.present? %>
<div class="info hidden-posts-notice">
<% if post_set.safe_posts.present? %>
<%= post_set.safe_posts.size %> post(s) on this page were hidden by safe mode (<%= Danbooru.config.app_name %>). Go to <%= link_to "e621", "https://e621.net/" %> or disable safe mode to view (<%= link_to "learn more", help_page_path(id: "user_settings") %>).<br>
<% end %>
<% if post_set.login_blocked_posts.present? %>
<%= post_set.login_blocked_posts.size %> post(s) on this page were hidden because you need to be logged in to view them. <%= link_to "(learn more)", help_page_path(id: "global_blacklist") %>
<% end %>
</div>
<% end %>
<% unless post_set.is_random? %>
<%= numbered_paginator(post_set.posts) %>
<% end %>
</div>

View File

@ -1,34 +1,39 @@
<div id="c-favorites">
<div id="a-index">
<aside id="sidebar">
<%= render "posts/partials/common/search", :path => posts_path, :tags => "fav:#{@user.name} ", :tags_dom_id => "tags" %>
<div style="color:darkorange;margin-bottom:0.5rem;">*Searching favorites does not preserve the order they were added in.<br/></div>
<div id="c-favorites"><div id="a-index">
<div class="post-index">
<div class="search">
<%= render "posts/partials/common/search", title: "Favorites", :tags => "fav:#{@user.name} " %>
<div style="color: darkorange;">Searching favorites does not preserve the order in which they were added.<br/></div>
</div>
<div class="sidebar">
<% if CurrentUser.is_member? %>
<%= render "posts/partials/index/mode_menu" %>
<% end %>
<%= render "posts/partials/index/blacklist" %>
<section id="tag-box">
<h3>Tags</h3>
<!-- TODO: Lock off these extra items? -->
<%= @post_set.presenter.post_index_sidebar_tag_list_html(current_query: params[:tags]) %>
</section>
<section id="related-box">
<h1>Related</h1>
<h3>Related</h3>
<ul id="related-list">
<li><%= link_to "Random post", random_posts_path(:tags => @favorite_set.public_tag_string), :id => "random-post", :rel => "nofollow", :"data-shortcut" => "r" %></li>
<li><%= link_to "Random post", random_posts_path(:tags => @post_set.public_tag_string), :id => "random-post", :rel => "nofollow", :"data-shortcut" => "r" %></li>
</ul>
</section>
</aside>
</div>
<section id="content">
<div class="content">
<%= render "ads/leaderboard", tag_string: @post_set.ad_tag_string %>
<%= render "posts/partials/index/edit" %>
<%= render "posts/partials/index/posts", :post_set => @post_set %>
</div>
<div id="posts" class="user-disable-cropped-<%= Danbooru.config.enable_image_cropping? && CurrentUser.user.disable_cropped_thumbnails? %>">
<section class="posts-container">
<%= @favorite_set.presenter.post_previews_html(self) %>
</section>
<%= numbered_paginator(@favorite_set.posts) %>
</div>
</section>
</div>
</div>
</div></div>
<%= render "posts/partials/common/secondary_links" %>

View File

@ -1,46 +1,33 @@
<div id="c-posts">
<div id="a-index">
<aside id="sidebar">
<%= render "posts/partials/common/search", :path => posts_path, :tags => params[:tags], :tags_dom_id => "tags" %>
<div id="c-posts"><div id="a-index">
<div class="post-index">
<div class="search">
<%= render "posts/partials/common/search", title: "Posts", tags: params[:tags] %>
</div>
<div class="sidebar">
<% if CurrentUser.is_member? %>
<%= render "posts/partials/index/mode_menu" %>
<% end %>
<%= render "posts/partials/index/blacklist" %>
<section id="tag-box">
<h1>Tags</h1>
<h3>Tags</h3>
<!-- TODO: Lock off these extra items? -->
<%= @post_set.presenter.post_index_sidebar_tag_list_html(current_query: params[:tags]) %>
</section>
<%= render "posts/partials/index/related" %>
</aside>
</div>
<section id="content">
<div class="content">
<%= render "ads/leaderboard", tag_string: @post_set.ad_tag_string %>
<!-- TODO: Fix tag array with forced -status:deleted -->
<div class="mobile-search">
<%= link_to "(search help)", help_page_path(id: "cheatsheet"), class: 'search-help' %>
<div class="search-form">
<%= form_tag(posts_path, :method => "get") do %>
<% if params[:random] %>
<%= hidden_field_tag :random, params[:random] %>
<% end %>
<div class="search-input"><%= text_field_tag("tags", params[:tags], :id => "mobile-search-input", :"data-autocomplete" => "tag-query") %></div>
<div class="search-button"><%= tag.button(tag.i(class: "fa-solid fa-magnifying-glass"), type: "submit") %></div>
<% end %>
</div>
</div>
<%= render "posts/partials/index/edit" %>
<%= render "posts/partials/index/posts", :post_set => @post_set %>
</section>
</div>
</div>
</div>
</div></div>
<%= render "posts/partials/common/secondary_links" %>

View File

@ -1,11 +1,15 @@
<%# path, tags %>
<%# locals: (title: "Search", tags: "") %>
<section id="search-box">
<h1>Search <span class="search-help"><%= link_to "(search help)", help_page_path(id: "cheatsheet") %></span></h1>
<%= form_tag(path, :method => "get") do %>
<section class="post-search">
<h3 class="post-search-title"><%= title %></h3>
<span class="post-search-help"><%= link_to "[search help]", help_page_path(id: "cheatsheet") %></span>
<%= form_tag(posts_path, method: "get", class: "post-search-form") do %>
<% if params[:random] %>
<%= hidden_field_tag :random, params[:random] %>
<% end %>
<%= text_field_tag("tags", tags, id: tags_dom_id, data: { shortcut: "q", autocomplete: "tag-query" }) %><%= tag.button(tag.i(class: "fa-solid fa-magnifying-glass"), type: "submit") %>
<%= text_area_tag("tags", tags, placeholder: "Search posts by tag", rows: 1, data: { shortcut: "q", autocomplete: "tag-query" }) %>
<%= tag.button(tag.i(class: "fa-solid fa-magnifying-glass"), type: "submit", title: "Search") %>
<% end %>
</section>

View File

@ -1,5 +1,5 @@
<section id="mode-box">
<h1>Mode</h1>
<h3>Mode</h3>
<form action="/">
<select name="mode" id="mode-box-mode">
<option value="view">View</option>

View File

@ -1,5 +1,5 @@
<section id="related-box">
<h1>Related</h1>
<h3>Related</h3>
<ul id="related-list">
<% if discover_mode? %>
<li id="secondary-links-posts-hot"><%= link_to "Hot", posts_path(:tags => "order:rank") %></li>

View File

@ -1,7 +1,7 @@
<div id="c-posts">
<div id="a-show">
<aside id="sidebar">
<%= render "posts/partials/common/search", :path => posts_path, :tags => params[:q], :tags_dom_id => "tags" %>
<%= render "posts/partials/common/search", title: "Posts", :tags => params[:q] %>
<%= render "posts/partials/index/blacklist", post_id: @post.id %>