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.
134 lines
4.5 KiB
Ruby
134 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class PostPreviewComponent < ApplicationComponent
|
|
DEFAULT_SIZE = "150"
|
|
|
|
SIZES = %w[150 180 225 225w 270 270w 360]
|
|
|
|
with_collection_parameter :post
|
|
|
|
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 :image_width, :image_height, :file_ext, :file_size, :duration, :is_animated?, to: :media_asset
|
|
delegate :media_asset, to: :post
|
|
|
|
# @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
|
|
@post = post
|
|
@tags = tags.presence
|
|
@size = size.presence || DEFAULT_SIZE
|
|
@show_deleted = show_deleted
|
|
@show_votes = show_votes
|
|
@link_target = link_target
|
|
@pool = pool
|
|
@similarity = similarity.round(1) if similarity.present?
|
|
@recommended = recommended.round(1) if recommended.present?
|
|
@compact = compact
|
|
@show_size = show_size
|
|
@current_user = current_user
|
|
@options = options
|
|
end
|
|
|
|
def render?
|
|
post.present? && post.visible?(current_user) && (!post.is_deleted? || show_deleted)
|
|
end
|
|
|
|
def article_attrs(classes = nil)
|
|
{ class: [classes, *preview_class].compact.join(" "), **data_attributes }
|
|
end
|
|
|
|
def variant
|
|
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
|
|
|
|
def tooltip
|
|
"#{post.tag_string} rating:#{post.rating} score:#{post.score}"
|
|
end
|
|
|
|
def preview_class
|
|
klass = ["post-preview"]
|
|
klass << "captioned" if pool || show_size || similarity || recommended
|
|
klass << "post-status-pending" if post.is_pending?
|
|
klass << "post-status-flagged" if post.is_flagged?
|
|
klass << "post-status-deleted" if post.is_deleted?
|
|
klass << "post-status-has-parent" if post.parent_id
|
|
klass << "post-status-has-children" if post.has_visible_children?
|
|
klass << "post-preview-compact" if compact
|
|
klass << "post-preview-#{size}"
|
|
klass
|
|
end
|
|
|
|
def data_attributes
|
|
attributes = {
|
|
"data-id" => post.id,
|
|
"data-has-sound" => has_sound?,
|
|
"data-tags" => post.tag_string,
|
|
"data-approver-id" => post.approver_id,
|
|
"data-rating" => post.rating,
|
|
"data-large-width" => post.large_image_width,
|
|
"data-large-height" => post.large_image_height,
|
|
"data-width" => post.image_width,
|
|
"data-height" => post.image_height,
|
|
"data-flags" => post.status_flags,
|
|
"data-parent-id" => post.parent_id,
|
|
"data-has-children" => post.has_children?,
|
|
"data-score" => post.score,
|
|
"data-fav-count" => post.fav_count,
|
|
"data-pixiv-id" => post.pixiv_id,
|
|
"data-file-ext" => post.file_ext,
|
|
"data-source" => post.source,
|
|
"data-uploader-id" => post.uploader_id,
|
|
"data-normalized-source" => post.normalized_source,
|
|
}
|
|
|
|
if post.visible?(current_user)
|
|
attributes["data-md5"] = post.md5
|
|
attributes["data-file-url"] = post.file_url
|
|
attributes["data-large-file-url"] = post.large_file_url
|
|
attributes["data-preview-file-url"] = post.preview_file_url
|
|
end
|
|
|
|
attributes
|
|
end
|
|
|
|
def has_sound?
|
|
post.has_tag?("sound")
|
|
end
|
|
end
|