posts: add adjustable thumbnail sizes (#4932).
Add a menu in the top right of the post index page that lets you select the thumbnail size. This menu is currently hidden until the new thumbnails have been generated. On desktop, there are five thumbnail sizes: * Small: 150x150 (https://danbooru.donmai.us/posts?size=150) * Medium: 180x180 (https://danbooru.donmai.us/posts?size=180) * Large: 225x225 (https://danbooru.donmai.us/posts?size=225) * Huge: 270x270 (https://danbooru.donmai.us/posts?size=270) * Gigantic: 360x360 (https://danbooru.donmai.us/posts?size=360) On mobile, there are four sizes: * Small: 150x150 / 3 posts per row (https://danbooru.donmai.us/posts?size=150) * Medium: 180x180 / 2 posts per row (https://danbooru.donmai.us/posts?size=180) * Large: 225x225 / 2 posts per row (https://danbooru.donmai.us/posts?size=225) * Huge: 360x360 / 1 posts per row (https://danbooru.donmai.us/posts?size=360) There are two extra sizes that aren't listed in the menu: * 225x360 (https://danbooru.donmai.us/posts?size=225w) * 270x360 (https://danbooru.donmai.us/posts?size=270w) These sizes are good for tall thumbnails, but not so much for wide thumbnails. They aren't listed because in practice they're a bit too big. The 225x225 and 270x270 sizes are really just 360x360 thumbnails scaled down in HTML. This means 225x225 and 360x360 thumbnails both use the same amount of bandwidth. Thumbnail size is currently a per-search option, not a persistent account-level setting. This changes the HTML structure of thumbnails somewhat, so this may break userscripts and custom CSS.
This commit is contained in:
@@ -2,7 +2,14 @@
|
|||||||
|
|
||||||
class PopupMenuComponent < ApplicationComponent
|
class PopupMenuComponent < ApplicationComponent
|
||||||
include ViewComponent::SlotableV2
|
include ViewComponent::SlotableV2
|
||||||
delegate :ellipsis_icon, to: :helpers
|
|
||||||
|
|
||||||
|
attr_reader :classes
|
||||||
|
|
||||||
|
renders_one :button
|
||||||
renders_many :items
|
renders_many :items
|
||||||
|
|
||||||
|
# @param classes [String] A list of CSS classes for the root element.
|
||||||
|
def initialize(classes: nil)
|
||||||
|
@classes = classes
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<div class="popup-menu">
|
<div class="popup-menu <%= classes %>">
|
||||||
<a class="popup-menu-button" href="javascript:void(0)">
|
<a class="popup-menu-button" href="javascript:void(0)">
|
||||||
<%= ellipsis_icon %>
|
<% if button.present? %>
|
||||||
|
<%= button %>
|
||||||
|
<% else %>
|
||||||
|
<%= helpers.ellipsis_icon %>
|
||||||
|
<% end %>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<ul class="popup-menu-content">
|
<ul class="popup-menu-content">
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ div.popup-menu {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 50%;
|
border-radius: 4px;
|
||||||
|
padding: 4px 8px;
|
||||||
color: var(--muted-text-color);
|
color: var(--muted-text-color);
|
||||||
|
|
||||||
// the popup menu is open
|
// the popup menu is open
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
# * Inline galleries that fit on a single row, as seen in parent/child post sets.
|
# * Inline galleries that fit on a single row, as seen in parent/child post sets.
|
||||||
#
|
#
|
||||||
class PostGalleryComponent < ApplicationComponent
|
class PostGalleryComponent < ApplicationComponent
|
||||||
attr_reader :posts, :current_user, :inline, :options
|
attr_reader :posts, :current_user, :inline, :size, :options
|
||||||
|
|
||||||
delegate :post_preview, :numbered_paginator, to: :helpers
|
delegate :post_preview, :numbered_paginator, to: :helpers
|
||||||
|
|
||||||
@@ -18,14 +18,22 @@ class PostGalleryComponent < ApplicationComponent
|
|||||||
# @param current_user [User] The current user.
|
# @param current_user [User] The current user.
|
||||||
# @param inline [Boolean] If true, the gallery is rendered as a single row with a
|
# @param inline [Boolean] If true, the gallery is rendered as a single row with a
|
||||||
# horizontal scrollbar. If false, the gallery is rendered as a grid of thumbnails.
|
# horizontal scrollbar. If false, the gallery is rendered as a grid of thumbnails.
|
||||||
|
# @param size [String] The size of thumbnails in the gallery. Can be "150",
|
||||||
|
# "180", "225", "225w", "270", "270w", or "360".
|
||||||
# @param options [Hash] A set of options given to the thumbnail in `post_preview`.
|
# @param options [Hash] A set of options given to the thumbnail in `post_preview`.
|
||||||
def initialize(posts:, current_user:, inline: false, **options)
|
def initialize(posts:, current_user:, inline: false, size: PostPreviewComponent::DEFAULT_SIZE, **options)
|
||||||
super
|
super
|
||||||
@posts = posts
|
@posts = posts
|
||||||
@posts = @posts.includes(:media_asset) if posts.is_a?(ActiveRecord::Relation)
|
@posts = @posts.includes(:media_asset) if posts.is_a?(ActiveRecord::Relation)
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
@inline = inline
|
@inline = inline
|
||||||
@options = options
|
@options = options
|
||||||
|
|
||||||
|
if size.to_s.in?(PostPreviewComponent::SIZES)
|
||||||
|
@size = size
|
||||||
|
else
|
||||||
|
@size = PostPreviewComponent::DEFAULT_SIZE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def gallery_type
|
def gallery_type
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<div class="post-gallery post-gallery-<%= gallery_type %>">
|
<div class="post-gallery post-gallery-<%= gallery_type %> post-gallery-<%= size %>">
|
||||||
<% if empty? %>
|
<% if empty? %>
|
||||||
<p>No posts found.</p>
|
<p>No posts found.</p>
|
||||||
<% else %>
|
<% else %>
|
||||||
<div class="posts-container grid gap-1 grid-cols-2 md:block">
|
<div class="posts-container grid gap-2">
|
||||||
<% posts.each do |post| -%>
|
<% posts.each do |post| -%>
|
||||||
<% %><%= post_preview(post, **options) -%>
|
<% %><%= post_preview(post, **options) -%>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|||||||
@@ -12,12 +12,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 660px) {
|
.post-gallery {
|
||||||
.post-gallery-full {
|
.posts-container {
|
||||||
.posts-container {
|
place-items: center;
|
||||||
&.user-disable-cropped-false article.post-preview img.has-cropped-true {
|
}
|
||||||
object-fit: none;
|
|
||||||
}
|
.post-preview-image {
|
||||||
}
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.post-gallery-150 .posts-container { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
|
||||||
|
&.post-gallery-180 .posts-container { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
|
||||||
|
&.post-gallery-225 .posts-container { grid-template-columns: repeat(auto-fill, minmax(225px, 1fr)); }
|
||||||
|
&.post-gallery-225w .posts-container { grid-template-columns: repeat(auto-fill, minmax(225px, 1fr)); }
|
||||||
|
&.post-gallery-270 .posts-container { grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); }
|
||||||
|
&.post-gallery-270w .posts-container { grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); }
|
||||||
|
&.post-gallery-360 .posts-container { grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); }
|
||||||
|
|
||||||
|
@media screen and (max-width: 660px) {
|
||||||
|
&.post-gallery-150 .posts-container { grid-template-columns: repeat(3, auto); }
|
||||||
|
&.post-gallery-180 .posts-container { grid-template-columns: repeat(2, auto); }
|
||||||
|
&.post-gallery-225 .posts-container { grid-template-columns: repeat(2, auto); }
|
||||||
|
&.post-gallery-225w .posts-container { grid-template-columns: repeat(2, auto); }
|
||||||
|
&.post-gallery-270 .posts-container { grid-template-columns: repeat(2, auto); }
|
||||||
|
&.post-gallery-270w .posts-container { grid-template-columns: repeat(2, auto); }
|
||||||
|
&.post-gallery-360 .posts-container { grid-template-columns: repeat(1, auto); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,33 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class PostPreviewComponent < ApplicationComponent
|
class PostPreviewComponent < ApplicationComponent
|
||||||
|
DEFAULT_SIZE = "150"
|
||||||
|
|
||||||
|
SIZES = %w[150 180 225 225w 270 270w 360]
|
||||||
|
|
||||||
with_collection_parameter :post
|
with_collection_parameter :post
|
||||||
|
|
||||||
attr_reader :post, :tags, :show_deleted, :link_target, :pool, :similarity, :recommended, :show_votes, :compact, :size, :current_user, :options
|
attr_reader :post, :tags, :size, :show_deleted, :link_target, :pool, :similarity, :recommended, :show_votes, :compact, :show_size, :current_user, :options
|
||||||
|
|
||||||
delegate :external_link_to, :time_ago_in_words_tagged, :duration_to_hhmmss, :render_post_votes, :empty_heart_icon, :sound_icon, to: :helpers
|
delegate :external_link_to, :time_ago_in_words_tagged, :duration_to_hhmmss, :render_post_votes, :empty_heart_icon, :sound_icon, to: :helpers
|
||||||
delegate :image_width, :image_height, :file_ext, :file_size, :duration, :is_animated?, to: :media_asset
|
delegate :image_width, :image_height, :file_ext, :file_size, :duration, :is_animated?, to: :media_asset
|
||||||
delegate :media_asset, to: :post
|
delegate :media_asset, to: :post
|
||||||
|
|
||||||
def initialize(post:, tags: "", show_deleted: false, show_votes: false, link_target: post, pool: nil, similarity: nil, recommended: nil, compact: nil, size: nil, current_user: CurrentUser.user, **options)
|
# @param post [Post] The post to show the thumbnail for.
|
||||||
|
# @param tags [String] The current tag search, if any.
|
||||||
|
# @param size [String] The size of the thumbnail. One of "150", "180", "225",
|
||||||
|
# "225w", "270", "270w", or "360".
|
||||||
|
# @param show_deleted [Boolean] If true, show thumbnails for deleted posts.
|
||||||
|
# If false, hide thumbnails of deleted posts.
|
||||||
|
# @param show_votes [Boolean] If true, show scores and vote buttons beneath the thumbnail.
|
||||||
|
# @param show_size [Boolean] If true, show filesize and resolution beneath the thumbnail.
|
||||||
|
# @param link_target [ApplicationRecord] What the thumbnail links to (default: the post).
|
||||||
|
# @param current_user [User] The current user.
|
||||||
|
def initialize(post:, tags: "", size: DEFAULT_SIZE, show_deleted: false, show_votes: false, link_target: post, pool: nil, similarity: nil, recommended: nil, compact: nil, show_size: nil, current_user: CurrentUser.user, **options)
|
||||||
super
|
super
|
||||||
@post = post
|
@post = post
|
||||||
@tags = tags.presence
|
@tags = tags.presence
|
||||||
|
@size = size.presence || DEFAULT_SIZE
|
||||||
@show_deleted = show_deleted
|
@show_deleted = show_deleted
|
||||||
@show_votes = show_votes
|
@show_votes = show_votes
|
||||||
@link_target = link_target
|
@link_target = link_target
|
||||||
@@ -20,7 +35,7 @@ class PostPreviewComponent < ApplicationComponent
|
|||||||
@similarity = similarity.round(1) if similarity.present?
|
@similarity = similarity.round(1) if similarity.present?
|
||||||
@recommended = recommended.round(1) if recommended.present?
|
@recommended = recommended.round(1) if recommended.present?
|
||||||
@compact = compact
|
@compact = compact
|
||||||
@size = post.file_size if size.present?
|
@show_size = show_size
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
@options = options
|
@options = options
|
||||||
end
|
end
|
||||||
@@ -33,16 +48,33 @@ class PostPreviewComponent < ApplicationComponent
|
|||||||
{ class: [classes, *preview_class].compact.join(" "), **data_attributes }
|
{ class: [classes, *preview_class].compact.join(" "), **data_attributes }
|
||||||
end
|
end
|
||||||
|
|
||||||
def preview_width
|
|
||||||
variant.width
|
|
||||||
end
|
|
||||||
|
|
||||||
def preview_height
|
|
||||||
variant.height
|
|
||||||
end
|
|
||||||
|
|
||||||
def variant
|
def variant
|
||||||
@variant ||= media_asset.variant(:preview)
|
case size
|
||||||
|
when "150"
|
||||||
|
media_asset.variant("preview")
|
||||||
|
when "180"
|
||||||
|
media_asset.variant("180x180")
|
||||||
|
when "225", "225w"
|
||||||
|
media_asset.variant("360x360")
|
||||||
|
when "270", "270w"
|
||||||
|
media_asset.variant("360x360")
|
||||||
|
when "360"
|
||||||
|
media_asset.variant("360x360")
|
||||||
|
else
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def preview_srcset
|
||||||
|
if size == "180"
|
||||||
|
"#{media_asset.variant("180x180").file_url} 1x, #{media_asset.variant("360x360").file_url} 2x"
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def preview_url
|
||||||
|
variant.file_url
|
||||||
end
|
end
|
||||||
|
|
||||||
def tooltip
|
def tooltip
|
||||||
@@ -51,13 +83,14 @@ class PostPreviewComponent < ApplicationComponent
|
|||||||
|
|
||||||
def preview_class
|
def preview_class
|
||||||
klass = ["post-preview"]
|
klass = ["post-preview"]
|
||||||
klass << "captioned" if pool || size || similarity || recommended
|
klass << "captioned" if pool || show_size || similarity || recommended
|
||||||
klass << "post-status-pending" if post.is_pending?
|
klass << "post-status-pending" if post.is_pending?
|
||||||
klass << "post-status-flagged" if post.is_flagged?
|
klass << "post-status-flagged" if post.is_flagged?
|
||||||
klass << "post-status-deleted" if post.is_deleted?
|
klass << "post-status-deleted" if post.is_deleted?
|
||||||
klass << "post-status-has-parent" if post.parent_id
|
klass << "post-status-has-parent" if post.parent_id
|
||||||
klass << "post-status-has-children" if post.has_visible_children?
|
klass << "post-status-has-children" if post.has_visible_children?
|
||||||
klass << "post-preview-compact" if compact
|
klass << "post-preview-compact" if compact
|
||||||
|
klass << "post-preview-#{size}"
|
||||||
klass
|
klass
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<%= tag.article id: "post_#{post.id}", **article_attrs do -%>
|
<%= tag.article id: "post_#{post.id}", **article_attrs do -%>
|
||||||
<%= link_to polymorphic_path(link_target, q: tags) do -%>
|
<%= link_to polymorphic_path(link_target, q: tags), class: "post-preview-link" do -%>
|
||||||
<% if is_animated? || has_sound? %>
|
<% if is_animated? || has_sound? %>
|
||||||
<div class="post-animation-icon absolute top-0.5 left-0.5 p-0.5 m-0.5 leading-none rounded text-xs font-arial font-bold">
|
<div class="post-animation-icon absolute top-0.5 left-0.5 p-0.5 m-0.5 leading-none rounded text-xs font-arial font-bold">
|
||||||
<% if is_animated? %>
|
<% if is_animated? %>
|
||||||
@@ -13,9 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= tag.picture do -%>
|
<%= tag.img srcset: preview_srcset, src: preview_url, width: variant.width, height: variant.height, class: "post-preview-image", title: tooltip, alt: "post ##{post.id}", crossorigin: "anonymous" -%>
|
||||||
<%= tag.img src: post.preview_file_url, style: "min-width: #{preview_width}px; min-height: #{preview_height}px;", title: tooltip, alt: "post ##{post.id}", crossorigin: "anonymous" -%>
|
|
||||||
<% end -%>
|
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% if pool -%>
|
<% if pool -%>
|
||||||
<p class="desc">
|
<p class="desc">
|
||||||
@@ -37,9 +35,9 @@
|
|||||||
<p class="desc">
|
<p class="desc">
|
||||||
<%= link_to "#{similarity}%", iqdb_queries_path(post_id: post.id) %> similarity
|
<%= link_to "#{similarity}%", iqdb_queries_path(post_id: post.id) %> similarity
|
||||||
</p>
|
</p>
|
||||||
<% elsif size -%>
|
<% elsif show_size -%>
|
||||||
<p class="desc">
|
<p class="desc">
|
||||||
<%= link_to number_to_human_size(size), post.file_url %>
|
<%= link_to number_to_human_size(file_size), post.file_url %>
|
||||||
(<%= post.image_width %>x<%= post.image_height %>)
|
(<%= post.image_width %>x<%= post.image_height %>)
|
||||||
</p>
|
</p>
|
||||||
<% elsif recommended -%>
|
<% elsif recommended -%>
|
||||||
@@ -53,7 +51,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
<% elsif show_votes -%>
|
<% elsif show_votes -%>
|
||||||
<div class="post-preview-score text-sm mt-1">
|
<div class="post-preview-score text-sm text-center mt-1">
|
||||||
<%= render_post_votes post, current_user: current_user %>
|
<%= render_post_votes post, current_user: current_user %>
|
||||||
</div>
|
</div>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
@import "../../javascript/src/styles/base/000_vars.scss";
|
@import "../../javascript/src/styles/base/000_vars.scss";
|
||||||
|
|
||||||
article.post-preview {
|
article.post-preview {
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
a {
|
.post-preview-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@@ -30,17 +29,16 @@ article.post-preview {
|
|||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avoid dead space around thumbnails in tables. */
|
.post-preview-image {
|
||||||
table article.post-preview {
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
width: auto;
|
||||||
margin: 0;
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 660px) {
|
||||||
|
.post-preview-225 .post-preview-image { max-height: 225px; }
|
||||||
|
.post-preview-270 .post-preview-image { max-height: 270px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-preview {
|
.post-preview {
|
||||||
@@ -117,16 +115,8 @@ body[data-current-user-can-approve-posts="true"] .post-preview {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 660px) {
|
|
||||||
article.post-preview {
|
|
||||||
width: 154px;
|
|
||||||
margin: 0 10px 10px 0;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 660px) {
|
@media screen and (max-width: 660px) {
|
||||||
article.post-preview img {
|
.post-preview-image {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class PostsController < ApplicationController
|
|||||||
elsif params[:random].to_s.truthy?
|
elsif params[:random].to_s.truthy?
|
||||||
post_set = PostSets::Post.new(params[:tags], params[:page], params[:limit], format: request.format.symbol, view: params[:view])
|
post_set = PostSets::Post.new(params[:tags], params[:page], params[:limit], format: request.format.symbol, view: params[:view])
|
||||||
query = "#{post_set.normalized_query.to_s} random:#{post_set.per_page}".strip
|
query = "#{post_set.normalized_query.to_s} random:#{post_set.per_page}".strip
|
||||||
redirect_to posts_path(tags: query, page: params[:page], limit: params[:limit], format: request.format.symbol, view: params[:view])
|
redirect_to posts_path(tags: query, page: params[:page], limit: params[:limit], format: request.format.symbol, view: params[:view], size: params[:size])
|
||||||
else
|
else
|
||||||
tag_query = params[:tags] || params.dig(:post, :tags)
|
tag_query = params[:tags] || params.dig(:post, :tags)
|
||||||
@post_set = PostSets::Post.new(tag_query, params[:page], params[:limit], format: request.format.symbol, view: params[:view])
|
@post_set = PostSets::Post.new(tag_query, params[:page], params[:limit], format: request.format.symbol, view: params[:view])
|
||||||
|
|||||||
@@ -158,6 +158,10 @@ module IconHelper
|
|||||||
icon_tag("fas fa-plus", **options)
|
icon_tag("fas fa-plus", **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def caret_down_icon(**options)
|
||||||
|
svg_icon_tag("caret-down-icon", "M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z", viewbox: "0 0 320 512", **options)
|
||||||
|
end
|
||||||
|
|
||||||
# https://fontawesome.com/v6.0/icons/volume-high
|
# https://fontawesome.com/v6.0/icons/volume-high
|
||||||
def sound_icon(**options)
|
def sound_icon(**options)
|
||||||
svg_icon_tag("sound-icon", "M412.6 182c-10.28-8.334-25.41-6.867-33.75 3.402c-8.406 10.24-6.906 25.35 3.375 33.74C393.5 228.4 400 241.8 400 255.1c0 14.17-6.5 27.59-17.81 36.83c-10.28 8.396-11.78 23.5-3.375 33.74c4.719 5.806 11.62 8.802 18.56 8.802c5.344 0 10.75-1.779 15.19-5.399C435.1 311.5 448 284.6 448 255.1S435.1 200.4 412.6 182zM473.1 108.2c-10.22-8.334-25.34-6.898-33.78 3.34c-8.406 10.24-6.906 25.35 3.344 33.74C476.6 172.1 496 213.3 496 255.1s-19.44 82.1-53.31 110.7c-10.25 8.396-11.75 23.5-3.344 33.74c4.75 5.775 11.62 8.771 18.56 8.771c5.375 0 10.75-1.779 15.22-5.431C518.2 366.9 544 313 544 255.1S518.2 145 473.1 108.2zM534.4 33.4c-10.22-8.334-25.34-6.867-33.78 3.34c-8.406 10.24-6.906 25.35 3.344 33.74C559.9 116.3 592 183.9 592 255.1s-32.09 139.7-88.06 185.5c-10.25 8.396-11.75 23.5-3.344 33.74C505.3 481 512.2 484 519.2 484c5.375 0 10.75-1.779 15.22-5.431C601.5 423.6 640 342.5 640 255.1S601.5 88.34 534.4 33.4zM301.2 34.98c-11.5-5.181-25.01-3.076-34.43 5.29L131.8 160.1H48c-26.51 0-48 21.48-48 47.96v95.92c0 26.48 21.49 47.96 48 47.96h83.84l134.9 119.8C272.7 477 280.3 479.8 288 479.8c4.438 0 8.959-.9314 13.16-2.835C312.7 471.8 320 460.4 320 447.9V64.12C320 51.55 312.7 40.13 301.2 34.98z", viewbox: "0 0 640 512", **options)
|
svg_icon_tag("sound-icon", "M412.6 182c-10.28-8.334-25.41-6.867-33.75 3.402c-8.406 10.24-6.906 25.35 3.375 33.74C393.5 228.4 400 241.8 400 255.1c0 14.17-6.5 27.59-17.81 36.83c-10.28 8.396-11.78 23.5-3.375 33.74c4.719 5.806 11.62 8.802 18.56 8.802c5.344 0 10.75-1.779 15.19-5.399C435.1 311.5 448 284.6 448 255.1S435.1 200.4 412.6 182zM473.1 108.2c-10.22-8.334-25.34-6.898-33.78 3.34c-8.406 10.24-6.906 25.35 3.344 33.74C476.6 172.1 496 213.3 496 255.1s-19.44 82.1-53.31 110.7c-10.25 8.396-11.75 23.5-3.344 33.74c4.75 5.775 11.62 8.771 18.56 8.771c5.375 0 10.75-1.779 15.22-5.431C518.2 366.9 544 313 544 255.1S518.2 145 473.1 108.2zM534.4 33.4c-10.22-8.334-25.34-6.867-33.78 3.34c-8.406 10.24-6.906 25.35 3.344 33.74C559.9 116.3 592 183.9 592 255.1s-32.09 139.7-88.06 185.5c-10.25 8.396-11.75 23.5-3.344 33.74C505.3 481 512.2 484 519.2 484c5.375 0 10.75-1.779 15.22-5.431C601.5 423.6 640 342.5 640 255.1S601.5 88.34 534.4 33.4zM301.2 34.98c-11.5-5.181-25.01-3.076-34.43 5.29L131.8 160.1H48c-26.51 0-48 21.48-48 47.96v95.92c0 26.48 21.49 47.96 48 47.96h83.84l134.9 119.8C272.7 477 280.3 479.8 288 479.8c4.438 0 8.959-.9314 13.16-2.835C312.7 471.8 320 460.4 320 447.9V64.12C320 51.55 312.7 40.13 301.2 34.98z", viewbox: "0 0 640 512", **options)
|
||||||
|
|||||||
@@ -308,19 +308,19 @@ Post.initialize_excerpt = function() {
|
|||||||
$("#excerpt").hide();
|
$("#excerpt").hide();
|
||||||
|
|
||||||
$("#show-posts-link").on("click.danbooru", function(e) {
|
$("#show-posts-link").on("click.danbooru", function(e) {
|
||||||
$("#show-posts-link").parent("li").addClass("active");
|
$("#show-posts-link").addClass("active");
|
||||||
$("#show-excerpt-link").parent("li").removeClass("active");
|
$("#show-excerpt-link").removeClass("active");
|
||||||
$("#posts").show();
|
$("#posts").show();
|
||||||
$("#excerpt").hide();
|
$("#excerpt").hide();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#show-excerpt-link").on("click.danbooru", function(e) {
|
$("#show-excerpt-link").on("click.danbooru", function(e) {
|
||||||
if ($(this).parent("li").hasClass("active")) {
|
if ($(this).hasClass("active")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$("#show-posts-link").parent("li").removeClass("active");
|
$("#show-posts-link").removeClass("active");
|
||||||
$("#show-excerpt-link").parent("li").addClass("active");
|
$("#show-excerpt-link").addClass("active");
|
||||||
$("#posts").hide();
|
$("#posts").hide();
|
||||||
$("#excerpt").show();
|
$("#excerpt").show();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -411,8 +411,9 @@ Post.update = async function(post_id, mode, params) {
|
|||||||
|
|
||||||
let urlParams = new URLSearchParams(window.location.search);
|
let urlParams = new URLSearchParams(window.location.search);
|
||||||
let view = urlParams.get("view");
|
let view = urlParams.get("view");
|
||||||
|
let size = urlParams.get("size");
|
||||||
|
|
||||||
await $.ajax({ type: "PUT", url: `/posts/${post_id}.js?mode=${mode}&view=${view}`, data: params });
|
await $.ajax({ type: "PUT", url: `/posts/${post_id}.js?mode=${mode}&view=${view}&size=${size}`, data: params });
|
||||||
|
|
||||||
Post.pending_update_count -= 1;
|
Post.pending_update_count -= 1;
|
||||||
Post.show_pending_update_notice();
|
Post.show_pending_update_notice();
|
||||||
|
|||||||
@@ -171,10 +171,10 @@ ul.list-inline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mobile-only {
|
.mobile-only {
|
||||||
display: none;
|
display: none !important;
|
||||||
@media (max-width: 660px) { display: initial; }
|
@media (max-width: 660px) { display: initial !important; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.desktop-only {
|
.desktop-only {
|
||||||
@media (max-width: 660px) { display: none; }
|
@media (max-width: 660px) { display: none !important; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
.font-monospace { font: var(--monospace-font); }
|
.font-monospace { font: var(--monospace-font); }
|
||||||
.font-bold { font-weight: bold; }
|
.font-bold { font-weight: bold; }
|
||||||
|
|
||||||
|
.hidden { display: none !important; }
|
||||||
.inline-block { display: inline-block; }
|
.inline-block { display: inline-block; }
|
||||||
.block { display: block; }
|
.block { display: block; }
|
||||||
.flex { display: flex; }
|
.flex { display: flex; }
|
||||||
@@ -44,6 +45,7 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
.rounded-sm { border-radius: 0.5 * $spacer; }
|
.rounded-sm { border-radius: 0.5 * $spacer; }
|
||||||
.rounded { border-radius: 1.0 * $spacer; }
|
.rounded { border-radius: 1.0 * $spacer; }
|
||||||
|
|
||||||
|
.m-0 { margin: 0; }
|
||||||
.m-px { margin: 1px; }
|
.m-px { margin: 1px; }
|
||||||
.m-0\.5 { margin: 0.5 * $spacer; }
|
.m-0\.5 { margin: 0.5 * $spacer; }
|
||||||
|
|
||||||
@@ -62,6 +64,8 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
|
|
||||||
.ml-4 { margin-left: 4 * $spacer; }
|
.ml-4 { margin-left: 4 * $spacer; }
|
||||||
|
|
||||||
|
.p-0 { padding: 0; }
|
||||||
|
.p-px { padding: 1px; }
|
||||||
.p-0\.5 { padding: 0.5 * $spacer; }
|
.p-0\.5 { padding: 0.5 * $spacer; }
|
||||||
.p-4 { padding: 4 * $spacer; }
|
.p-4 { padding: 4 * $spacer; }
|
||||||
|
|
||||||
@@ -80,6 +84,9 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
.space-y-4 > * + * { margin-top: 4 * $spacer; }
|
.space-y-4 > * + * { margin-top: 4 * $spacer; }
|
||||||
|
|
||||||
.gap-1 { gap: 1 * $spacer; }
|
.gap-1 { gap: 1 * $spacer; }
|
||||||
|
.gap-2 { gap: 2 * $spacer; }
|
||||||
|
.gap-3 { gap: 3 * $spacer; }
|
||||||
|
.gap-4 { gap: 4 * $spacer; }
|
||||||
|
|
||||||
.divide-y-1 > * + * { border-top: 1px solid var(--divider-border-color); }
|
.divide-y-1 > * + * { border-top: 1px solid var(--divider-border-color); }
|
||||||
|
|
||||||
@@ -88,6 +95,7 @@ $spacer: 0.25rem; /* 4px */
|
|||||||
|
|
||||||
.flex-1 { flex: 1 1 0%; }
|
.flex-1 { flex: 1 1 0%; }
|
||||||
.flex-auto { flex: 1 1 auto; }
|
.flex-auto { flex: 1 1 auto; }
|
||||||
|
.flex-grow-1 { flex-grow: 1; }
|
||||||
.items-center { align-items: center; }
|
.items-center { align-items: center; }
|
||||||
.justify-center { justify-content: center; }
|
.justify-center { justify-content: center; }
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
<span class="iqdb-posts-high-similarity">
|
<span class="iqdb-posts-high-similarity">
|
||||||
<% @high_similarity_matches.each do |match| %>
|
<% @high_similarity_matches.each do |match| %>
|
||||||
<%= post_preview(match["post"], show_deleted: true, similarity: match["score"], size: true) %>
|
<%= post_preview(match["post"], show_deleted: true, similarity: match["score"], show_size: true) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="iqdb-posts-low-similarity" style="display: none">
|
<span class="iqdb-posts-low-similarity" style="display: none">
|
||||||
<% @low_similarity_matches.each do |match| %>
|
<% @low_similarity_matches.each do |match| %>
|
||||||
<%= post_preview(match["post"], show_deleted: true, similarity: match["score"], size: true) %>
|
<%= post_preview(match["post"], show_deleted: true, similarity: match["score"], show_size: true) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<%= tag.div id: "post-#{post.id}", **PostPreviewComponent.new(post: post).article_attrs("post mod-queue-preview column-container") do %>
|
<%= tag.div id: "post-#{post.id}", **PostPreviewComponent.new(post: post).article_attrs("post mod-queue-preview column-container") do %>
|
||||||
<aside class="column column-shrink">
|
<aside class="column column-shrink">
|
||||||
<%= post_preview(post, size: true, show_deleted: true) %>
|
<%= post_preview(post, show_size: true, show_deleted: true) %>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<section class="column column-expand">
|
<section class="column column-expand">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<section id="tag-box">
|
<section id="tag-box">
|
||||||
<h2>Tags</h2>
|
<h2>Tags</h2>
|
||||||
<%= render_search_tag_list(@post_set.related_tags, current_query: params[:tags], show_extra_links: policy(Post).show_extra_links?, search_params: { view: params[:view] }) %>
|
<%= render_search_tag_list(@post_set.related_tags, current_query: params[:tags], show_extra_links: policy(Post).show_extra_links?, search_params: { view: params[:view], size: params[:size] }) %>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<%= render "posts/partials/index/options" %>
|
<%= render "posts/partials/index/options" %>
|
||||||
@@ -16,34 +16,91 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% content_for(:content) do %>
|
<% content_for(:content) do %>
|
||||||
<menu id="post-sections" class="mb-4 space-x-2">
|
<menu id="post-sections" class="flex">
|
||||||
<li class="active"><a href="#" id="show-posts-link">Posts</a></li>
|
<li class="flex-grow-1 space-x-2">
|
||||||
|
<a href="#" id="show-posts-link" class="active">Posts</a>
|
||||||
|
|
||||||
<% if @post_set.artist.present? %>
|
<% if @post_set.artist.present? %>
|
||||||
<li class="artist-excerpt-link"><%= link_to "Artist", artist_path(@post_set.artist), :id => "show-excerpt-link" %></li>
|
<%= link_to "Artist", artist_path(@post_set.artist), id: "show-excerpt-link", class: "artist-excerpt-link" %>
|
||||||
<% elsif @post_set.wiki_page.present? %>
|
<% elsif @post_set.wiki_page.present? %>
|
||||||
<li class="wiki-excerpt-link"><%= link_to "Wiki", wiki_page_path(@post_set.wiki_page), :id => "show-excerpt-link" %></li>
|
<%= link_to "Wiki", wiki_page_path(@post_set.wiki_page), id: "show-excerpt-link", class: "wiki-excerpt-link" %>
|
||||||
<% elsif @post_set.pool.present? %>
|
<% elsif @post_set.pool.present? %>
|
||||||
<li class="pool-excerpt-link"><%= link_to "Pool", pool_path(@post_set.pool), :id => "show-excerpt-link" %></li>
|
<%= link_to "Pool", pool_path(@post_set.pool), id: "show-excerpt-link", class: "pool-excerpt-link" %>
|
||||||
<% elsif @post_set.favgroup.present? %>
|
<% elsif @post_set.favgroup.present? %>
|
||||||
<li class="favgroup-excerpt-link"><%= link_to "Favorite Group", favorite_group_path(@post_set.favgroup), :id => "show-excerpt-link" %></li>
|
<%= link_to "Favorite Group", favorite_group_path(@post_set.favgroup), id: "show-excerpt-link", class: "favgroup-excerpt-link" %>
|
||||||
<% elsif @post_set.has_blank_wiki? %>
|
<% elsif @post_set.has_blank_wiki? %>
|
||||||
<li class="blank-wiki-excerpt-link"><%= link_to "Wiki", new_wiki_page_path(wiki_page: { title: @post_set.tag.name }), id: "show-excerpt-link" %></li>
|
<%= link_to "Wiki", new_wiki_page_path(wiki_page: { title: @post_set.tag.name }), id: "show-excerpt-link", class: "blank-wiki-excerpt-link" %>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<li class="float-right">
|
|
||||||
<%= render PopupMenuComponent.new do |menu| %>
|
|
||||||
<% menu.item do %>
|
|
||||||
<% if params[:view] == "score" %>
|
|
||||||
<%= link_to "Hide scores", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: nil), rel: "nofollow" %>
|
|
||||||
<% else %>
|
|
||||||
<%= link_to "Show scores", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: "score"), rel: "nofollow" %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<a class="mobile-only" href="#search-box">Search »</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li id="searchbox-redirect-link" class="mobile-only"><a href="#search-box">Search »</a></li>
|
<%= render PopupMenuComponent.new(classes: "hidden") do |menu| %>
|
||||||
|
<% menu.button do %>
|
||||||
|
<span class="text-sm">Size <%= caret_down_icon %></span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% menu.item do %>
|
||||||
|
<% if params.fetch(:size, PostPreviewComponent::DEFAULT_SIZE) == "150" %>
|
||||||
|
<%= link_to "Small", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "150"), class: "font-bold", rel: "nofollow" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Small", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "150"), rel: "nofollow" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% menu.item do %>
|
||||||
|
<% if params.fetch(:size, PostPreviewComponent::DEFAULT_SIZE) == "180" %>
|
||||||
|
<%= link_to "Medium", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "180"), class: "font-bold", rel: "nofollow" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Medium", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "180"), rel: "nofollow" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% menu.item do %>
|
||||||
|
<% if params.fetch(:size, PostPreviewComponent::DEFAULT_SIZE) == "225" %>
|
||||||
|
<%= link_to "Large", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "225"), class: "font-bold", rel: "nofollow" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Large", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "225"), rel: "nofollow" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%# Mobile only %>
|
||||||
|
<% menu.item do %>
|
||||||
|
<% if params.fetch(:size, PostPreviewComponent::DEFAULT_SIZE) == "360" %>
|
||||||
|
<%= link_to "Huge", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "360"), class: "mobile-only font-bold", rel: "nofollow" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Huge", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "360"), class: "mobile-only", rel: "nofollow" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%# Desktop only %>
|
||||||
|
<% menu.item do %>
|
||||||
|
<% if params.fetch(:size, PostPreviewComponent::DEFAULT_SIZE) == "270" %>
|
||||||
|
<%= link_to "Huge", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "270"), class: "desktop-only font-bold", rel: "nofollow" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Huge", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "270"), class: "desktop-only", rel: "nofollow" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%# Desktop only %>
|
||||||
|
<% menu.item do %>
|
||||||
|
<% if params.fetch(:size, PostPreviewComponent::DEFAULT_SIZE) == "360" %>
|
||||||
|
<%= link_to "Gigantic", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "360"), class: "desktop-only font-bold", rel: "nofollow" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Gigantic", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: params[:view], size: "360"), class: "desktop-only", rel: "nofollow" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render PopupMenuComponent.new do |menu| %>
|
||||||
|
<% menu.item do %>
|
||||||
|
<% if params[:view] == "score" %>
|
||||||
|
<%= link_to "Hide scores", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: nil, size: params[:size]), rel: "nofollow" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Show scores", posts_path(tags: params[:tags], page: params[:page], limit: params[:limit], view: "score", size: params[:size]), rel: "nofollow" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<%= render "posts/partials/index/edit" %>
|
<%= render "posts/partials/index/edit" %>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<% if post_set.shown_posts.empty? %>
|
<% if post_set.shown_posts.empty? %>
|
||||||
<%= render "post_sets/blank" %>
|
<%= render "post_sets/blank" %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= render_post_gallery(post_set.posts, show_deleted: post_set.show_deleted?, tags: post_set.tag_string, show_votes: post_set.show_votes?) do |gallery| %>
|
<%= render_post_gallery(post_set.posts, show_deleted: post_set.show_deleted?, tags: post_set.tag_string, show_votes: post_set.show_votes?, size: params[:size]) do |gallery| %>
|
||||||
<% gallery.footer do %>
|
<% gallery.footer do %>
|
||||||
<% if post_set.hidden_posts.present? %>
|
<% if post_set.hidden_posts.present? %>
|
||||||
<div class="fineprint hidden-posts-notice">
|
<div class="fineprint hidden-posts-notice">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<% if @post.valid? %>
|
<% if @post.valid? %>
|
||||||
var $post = $("#post_<%= @post.id %>");
|
var $post = $("#post_<%= @post.id %>");
|
||||||
var $new_post = $("<%= j post_preview(@post, show_deleted: true, show_votes: params[:view] == "score") %>");
|
var $new_post = $("<%= j post_preview(@post, show_deleted: true, show_votes: params[:view] == "score", size: params[:size]) %>");
|
||||||
Danbooru.Blacklist.apply_post($new_post.get(0));
|
Danbooru.Blacklist.apply_post($new_post.get(0));
|
||||||
$("#post_<%= @post.id %>").replaceWith($new_post);
|
$("#post_<%= @post.id %>").replaceWith($new_post);
|
||||||
<% if params[:mode] == "quick-edit" %>
|
<% if params[:mode] == "quick-edit" %>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<% source.related_posts.each do |post| %>
|
<% source.related_posts.each do |post| %>
|
||||||
<%= post_preview(post, show_deleted: true, size: true) %>
|
<%= post_preview(post, show_deleted: true, show_size: true) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user