media assets: add thumbnail view to /media_assets page.

Add a thumbnail view to the /media_assets page. This page lets you see
all images uploaded to Danbooru by all users (although you can't see who
the uploader is). Also add a link to this page in the subnav bar on the
upload page.
This commit is contained in:
evazion
2022-02-01 23:43:12 -06:00
parent 317d369c6a
commit 92a4d045e2
13 changed files with 140 additions and 35 deletions

View File

@@ -0,0 +1,17 @@
# frozen_string_literal: true
class MediaAssetGalleryComponent < ApplicationComponent
DEFAULT_SIZE = 180
attr_reader :inline, :size, :options
renders_many :media_assets, MediaAssetPreviewComponent
renders_one :footer
def initialize(inline: false, size: DEFAULT_SIZE, **options)
super
@inline = inline
@size = size
@option = options
end
end

View File

@@ -0,0 +1,13 @@
<div class="media-asset-gallery media-asset-gallery-<%= size %>">
<% if media_assets.empty? %>
<p>No results found.</p>
<% else %>
<div class="media-assets-container grid justify-items-center items-end">
<% media_assets.each do |media_asset| -%>
<% %><%= media_asset -%>
<% end -%>
</div>
<% end %>
<%= footer %>
</div>

View File

@@ -0,0 +1,34 @@
.media-asset-gallery {
.media-assets-container {
gap: 0.5rem;
}
@media screen and (min-width: 660px) {
&.media-asset-gallery-150 .post-preview-container { height: 150px; }
&.media-asset-gallery-180 .post-preview-container { height: 180px; }
&.media-asset-gallery-225 .post-preview-container { height: 225px; }
&.media-asset-gallery-270 .post-preview-container { height: 270px; }
&.media-asset-gallery-360 .post-preview-container { height: 360px; }
&.media-asset-gallery-720 .post-preview-container { height: 720px; }
}
&.media-asset-gallery-150 .media-assets-container { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
&.media-asset-gallery-180 .media-assets-container { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
&.media-asset-gallery-225 .media-assets-container { grid-template-columns: repeat(auto-fill, minmax(225px, 1fr)); }
&.media-asset-gallery-270 .media-assets-container { grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); }
&.media-asset-gallery-360 .media-assets-container { grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); }
&.media-asset-gallery-720 .media-assets-container { grid-template-columns: repeat(auto-fill, minmax(720px, 1fr)); }
@media screen and (max-width: 660px) {
.media-assets-container {
gap: 0.25rem;
}
&.media-asset-gallery-150 .media-assets-container { grid-template-columns: repeat(3, minmax(0, 150px)); }
&.media-asset-gallery-180 .media-assets-container { grid-template-columns: repeat(2, auto); }
&.media-asset-gallery-225 .media-assets-container { grid-template-columns: repeat(2, auto); }
&.media-asset-gallery-270 .media-assets-container { grid-template-columns: repeat(2, auto); }
&.media-asset-gallery-360 .media-assets-container { grid-template-columns: repeat(1, auto); }
&.media-asset-gallery-720 .media-assets-container { grid-template-columns: repeat(1, auto); }
}
}

View File

@@ -8,6 +8,8 @@ class MediaAssetPreviewComponent < ApplicationComponent
attr_reader :media_asset, :size, :fit, :link_target, :shrink_to_fit, :save_data
delegate :duration_to_hhmmss, :sound_icon, to: :helpers
renders_one :footer
# @param media_asset [MediaAsset] The media asset to show the thumbnail for.
# @param size [String] The size of the thumbnail. One of 150, 180, 225, 270, or 360.
# @param link_target [ApplicationRecord] What the thumbnail links to (default: the media asset).

View File

@@ -1,5 +1,5 @@
<%= tag.article class: "media-asset-preview media-asset-preview-#{size}" do -%>
<%= link_to link_target, class: "inline-block relative", draggable: "false" do -%>
<%= link_to link_target, class: "inline-block relative flex justify-center", draggable: "false" do -%>
<% if media_asset.is_animated? %>
<div class="media-asset-animation-icon absolute top-0.5 left-0.5 p-0.5 m-0.5 leading-none rounded text-xs font-arial font-bold">
<span class="media-asset-duration align-middle">
@@ -21,4 +21,8 @@
<%= tag.img src: variant.file_url, width: variant.width, height: variant.height, class: "media-asset-preview-image w-auto h-auto max-h-#{size}px #{"max-w-full" if shrink_to_fit}", crossorigin: "anonymous", draggable: "false" -%>
</picture>
<% end %>
<div>
<%= footer %>
</div>
<% end %>

View File

@@ -113,7 +113,9 @@ $spacer: 0.25rem; /* 4px */
.h-auto { height: auto; }
.h-1 { height: 1 * $spacer; }
.h-3 { height: 3 * $spacer; }
.h-8 { height: 8 * $spacer; }
.h-10 { height: 10 * $spacer; }
.h-12 { height: 12 * $spacer; }
.max-h-150px { max-height: 150px; }
.max-h-180px { max-height: 180px; }
@@ -143,7 +145,12 @@ $spacer: 0.25rem; /* 4px */
.flex-initial { flex: 0 1 auto; }
.flex-grow-1 { flex-grow: 1; }
.flex-col { flex-direction: column; }
.items-start { align-items: flex-start; }
.items-center { align-items: center; }
.items-end { align-items: flex-end; }
.justify-items-center { justify-items: center; }
.justify-center { justify-content: center; }
.float-right { float: right; }

View File

@@ -15,6 +15,9 @@ class MediaAsset < ApplicationRecord
has_one :post, foreign_key: :md5, primary_key: :md5
has_one :media_metadata, dependent: :destroy
has_one :pixiv_ugoira_frame_data, class_name: "PixivUgoiraFrameData", foreign_key: :md5, primary_key: :md5
has_many :upload_media_assets, dependent: :destroy
has_many :uploads, through: :upload_media_assets
has_many :uploaders, through: :uploads, class_name: "User", foreign_key: :uploader_id
delegate :metadata, to: :media_metadata
delegate :is_non_repeating_animation?, :is_greyscale?, :is_rotated?, to: :metadata

View File

@@ -3,7 +3,7 @@
<div id="c-iqdb-queries">
<div id="a-check">
<h1>Similar Images Search</h1>
<h1>Reverse Images Search</h1>
<section>
<p>Paste a URL or upload a file to perform a reverse image search on <%= Danbooru.config.app_name %>.</p>
@@ -19,3 +19,5 @@
<%= render "iqdb_queries/matches" %>
</div>
</div>
<%= render "uploads/secondary_links" %>

View File

@@ -0,0 +1,15 @@
<%= render(MediaAssetGalleryComponent.new) do |gallery| %>
<% @media_assets.each do |media_asset| %>
<% if policy(media_asset).can_see_image? %>
<% gallery.media_asset(media_asset: media_asset, size: gallery.size, link_target: media_asset) do |preview| %>
<% preview.footer do %>
<div class="text-center text-xs h-8">
<% if media_asset.post.present? %>
<%= link_to "post ##{media_asset.post.id}", media_asset.post %>
<% end %>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>

View File

@@ -0,0 +1,20 @@
<%= table_for @media_assets, class: "striped autofit" do |t| %>
<% t.column "File", td: { class: "text-center" } do |media_asset| %>
<% if policy(media_asset).can_see_image? %>
<%= render MediaAssetPreviewComponent.new(media_asset: media_asset, save_data: CurrentUser.save_data, shrink_to_fit: false) %>
<% end %>
<% end %>
<% t.column :image_width %>
<% t.column :image_height %>
<% t.column :file_size %>
<% t.column :file_ext %>
<% t.column "Metadata" do |media_asset| %>
<%= link_to pluralize(media_asset.metadata.size, "tags"), media_asset %>
<% end %>
<% t.column "Created" do |media_asset| %>
<%= time_ago_in_words_tagged(media_asset.created_at) %>
<% end %>
<% end %>

View File

@@ -1,42 +1,27 @@
<div id="c-media-assets">
<div id="a-index">
<%= search_form_for(media_assets_path) do |f| %>
<%= f.input :md5, input_html: { value: params[:search][:md5] } %>
<%= f.input :image_width, input_html: { value: params[:search][:image_width] } %>
<%= f.input :image_height, input_html: { value: params[:search][:image_height] } %>
<%= f.input :file_size, input_html: { value: params[:search][:file_size] } %>
<%= f.input :file_ext, input_html: { value: params[:search][:file_ext] } %>
<h1>All Uploads</h1>
<%= f.simple_fields_for :metadata do |meta| %>
<% params.dig(:search, :metadata).to_h.each do |key, value| %>
<%= meta.input key, label: key, input_html: { value: value } %>
<% if params[:search].present? %>
<%= search_form_for(media_assets_path) do |f| %>
<%= f.simple_fields_for :metadata do |meta| %>
<% params.dig(:search, :metadata).to_h.each do |key, value| %>
<%= meta.input key, label: key, input_html: { value: value } %>
<% end %>
<% end %>
<% end %>
<%= f.submit "Search" %>
<%= f.submit "Search" %>
<% end %>
<% end %>
<%= table_for @media_assets, class: "striped autofit" do |t| %>
<% t.column "File", td: { class: "text-center" } do |media_asset| %>
<% if policy(media_asset).can_see_image? %>
<%= render MediaAssetPreviewComponent.new(media_asset: media_asset, save_data: CurrentUser.save_data, shrink_to_fit: false) %>
<% end %>
<% end %>
<% t.column :image_width %>
<% t.column :image_height %>
<% t.column :file_size %>
<% t.column :file_ext %>
<% t.column "Metadata" do |media_asset| %>
<%= link_to pluralize(media_asset.metadata.size, "tags"), media_asset %>
<% end %>
<% t.column "Created" do |media_asset| %>
<%= time_ago_in_words_tagged(media_asset.created_at) %>
<% end %>
<% if params[:mode] == "table" %>
<%= render "media_assets/table" %>
<% else %>
<%= render "media_assets/gallery" %>
<% end %>
<%= numbered_paginator(@media_assets) %>
</div>
</div>
<%= render "uploads/secondary_links" %>

View File

@@ -30,3 +30,5 @@
</table>
</div>
</div>
<%= render "uploads/secondary_links" %>

View File

@@ -1,7 +1,8 @@
<% content_for(:secondary_links) do %>
<%= subnav_link_to "My Uploads", uploads_path %>
<%= subnav_link_to "New Upload", new_upload_path %>
<%= subnav_link_to "Batch Upload", batch_uploads_path %>
<%= subnav_link_to "Reverse Image Search", iqdb_queries_path %>
<%= subnav_link_to "Batch Upload", batch_uploads_path %> |
<%= subnav_link_to "My Uploads", uploads_path %>
<%= subnav_link_to "All Uploads", media_assets_path %>
<%= subnav_link_to "Reverse Image Search", iqdb_queries_path %> |
<%= subnav_link_to "Help", wiki_page_path("help:upload") %>
<% end %>