uploads: refactor "My Uploads" page for multi-file uploads.

* Make thumbnails on the "My Uploads" page show an icon with an image
  count when an upload contains multiple files.

* Make the "My Uploads" page show each upload, not each individual file.
  If an upload contains multiple files, they're shown grouped together
  under a single upload. This does mean that failed or duplicate uploads
  will show up on this page now. This is because this page shows each
  upload attempt, not each uniquely uploaded file.
This commit is contained in:
evazion
2022-02-13 15:26:10 -06:00
parent 879363b585
commit 53a3beee35
10 changed files with 60 additions and 62 deletions

View File

@@ -5,13 +5,12 @@ class MediaAssetGalleryComponent < ApplicationComponent
attr_reader :inline, :size, :options attr_reader :inline, :size, :options
renders_many :media_assets, MediaAssetPreviewComponent renders_many :media_assets
renders_one :footer renders_one :footer
def initialize(inline: false, size: DEFAULT_SIZE, **options) def initialize(inline: false, size: DEFAULT_SIZE)
super super
@inline = inline @inline = inline
@size = size @size = size
@option = options
end end
end end

View File

@@ -1,4 +1,4 @@
.media-asset-animation-icon { .media-asset-animation-icon, .media-asset-image-count-icon {
color: var(--preview-icon-color); color: var(--preview-icon-color);
background: var(--preview-icon-background); background: var(--preview-icon-background);
} }

View File

@@ -5,7 +5,7 @@ class MediaAssetsController < ApplicationController
def index def index
@media_assets = authorize MediaAsset.visible(CurrentUser.user).paginated_search(params, count_pages: false) @media_assets = authorize MediaAsset.visible(CurrentUser.user).paginated_search(params, count_pages: false)
@media_assets = @media_assets.joins(:media_metadata).includes(:post) @media_assets = @media_assets.includes(:media_metadata, :post)
respond_with(@media_assets) respond_with(@media_assets)
end end

View File

@@ -30,18 +30,11 @@ class UploadsController < ApplicationController
def index def index
@mode = params.fetch(:mode, "table") @mode = params.fetch(:mode, "table")
@uploads = authorize Upload.visible(CurrentUser.user).paginated_search(params, count_pages: true)
@uploads = @uploads.includes(:uploader, upload_media_assets: { media_asset: :post }) if request.format.html?
case @mode @uploads = @uploads.includes(:uploader, media_assets: :post, upload_media_assets: { media_asset: :post }) if request.format.html?
when "table" respond_with(@uploads, include: { upload_media_assets: { include: :media_asset }})
@uploads = authorize Upload.visible(CurrentUser.user).paginated_search(params, count_pages: true)
@uploads = @uploads.includes(:uploader, media_assets: :post, upload_media_assets: { media_asset: :post }) if request.format.html?
respond_with(@uploads, include: { upload_media_assets: { include: :media_asset }})
when "gallery"
@media_assets = authorize MediaAsset.active.visible(CurrentUser.user).includes(:post, uploads: [:uploader]).where(uploads: { uploader: CurrentUser.user }).paginated_search(params, count_pages: true).reorder("uploads.id DESC")
respond_with(@media_assets)
else
raise "Invalid mode '#{@mode}'"
end
end end
def show def show

View File

@@ -173,6 +173,10 @@ module IconHelper
svg_icon_tag("hashtag-icon", "M416 127.1h-58.23l9.789-58.74c2.906-17.44-8.875-33.92-26.3-36.83c-17.53-2.875-33.92 8.891-36.83 26.3L292.9 127.1H197.8l9.789-58.74c2.906-17.44-8.875-33.92-26.3-36.83c-17.53-2.875-33.92 8.891-36.83 26.3L132.9 127.1H64c-17.67 0-32 14.33-32 32C32 177.7 46.33 191.1 64 191.1h58.23l-21.33 128H32c-17.67 0-32 14.33-32 32c0 17.67 14.33 31.1 32 31.1h58.23l-9.789 58.74c-2.906 17.44 8.875 33.92 26.3 36.83C108.5 479.9 110.3 480 112 480c15.36 0 28.92-11.09 31.53-26.73l11.54-69.27h95.12l-9.789 58.74c-2.906 17.44 8.875 33.92 26.3 36.83C268.5 479.9 270.3 480 272 480c15.36 0 28.92-11.09 31.53-26.73l11.54-69.27H384c17.67 0 32-14.33 32-31.1c0-17.67-14.33-32-32-32h-58.23l21.33-128H416c17.67 0 32-14.32 32-31.1C448 142.3 433.7 127.1 416 127.1zM260.9 319.1H165.8L187.1 191.1h95.12L260.9 319.1z", viewbox: "0 0 448 512", **options) svg_icon_tag("hashtag-icon", "M416 127.1h-58.23l9.789-58.74c2.906-17.44-8.875-33.92-26.3-36.83c-17.53-2.875-33.92 8.891-36.83 26.3L292.9 127.1H197.8l9.789-58.74c2.906-17.44-8.875-33.92-26.3-36.83c-17.53-2.875-33.92 8.891-36.83 26.3L132.9 127.1H64c-17.67 0-32 14.33-32 32C32 177.7 46.33 191.1 64 191.1h58.23l-21.33 128H32c-17.67 0-32 14.33-32 32c0 17.67 14.33 31.1 32 31.1h58.23l-9.789 58.74c-2.906 17.44 8.875 33.92 26.3 36.83C108.5 479.9 110.3 480 112 480c15.36 0 28.92-11.09 31.53-26.73l11.54-69.27h95.12l-9.789 58.74c-2.906 17.44 8.875 33.92 26.3 36.83C268.5 479.9 270.3 480 272 480c15.36 0 28.92-11.09 31.53-26.73l11.54-69.27H384c17.67 0 32-14.33 32-31.1c0-17.67-14.33-32-32-32h-58.23l21.33-128H416c17.67 0 32-14.32 32-31.1C448 142.3 433.7 127.1 416 127.1zM260.9 319.1H165.8L187.1 191.1h95.12L260.9 319.1z", viewbox: "0 0 448 512", **options)
end end
def multiple_images_icon(**options)
svg_icon_tag("multiple-images-icon", "M8,3 C8.55228475,3 9,3.44771525 9,4 L9,9 C9,9.55228475 8.55228475,10 8,10 L3,10 C2.44771525,10 2,9.55228475 2,9 L6,9 C7.1045695,9 8,8.1045695 8,7 L8,3 Z M1,1 L6,1 C6.55228475,1 7,1.44771525 7,2 L7,7 C7,7.55228475 6.55228475,8 6,8 L1,8 C0.44771525,8 0,7.55228475 0,7 L0,2 C0,1.44771525 0.44771525,1 1,1 Z", viewbox: "0 0 9 10", **options)
end
def globe_icon(**options) def globe_icon(**options)
icon_tag("fas fa-globe", **options) icon_tag("fas fa-globe", **options)
end end

View File

@@ -1,14 +1,8 @@
<%= render(MediaAssetGalleryComponent.new) do |gallery| %> <%= render(MediaAssetGalleryComponent.new) do |gallery| %>
<% @media_assets.each do |media_asset| %> <% @media_assets.each do |media_asset| %>
<% if policy(media_asset).can_see_image? %> <% if policy(media_asset).can_see_image? %>
<% gallery.media_asset(media_asset: media_asset, size: gallery.size, link_target: media_asset) do |preview| %> <% gallery.media_asset do %>
<% preview.footer do %> <%= render "media_assets/preview", media_asset: media_asset, size: gallery.size %>
<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 %>
<% end %> <% end %>

View File

@@ -0,0 +1,9 @@
<%= render(MediaAssetPreviewComponent.new(media_asset: media_asset, size: 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 %>

View File

@@ -8,27 +8,11 @@
</div> </div>
<%= render(MediaAssetGalleryComponent.new) do |gallery| %> <%= render(MediaAssetGalleryComponent.new) do |gallery| %>
<% @media_assets.each do |media_asset| %> <% @uploads.each do |upload| %>
<% upload = media_asset.uploads.order(id: :desc).select { |upload| upload.uploader == CurrentUser.user }.first %> <% gallery.media_asset do %>
<%= render "uploads/preview", upload: upload, size: gallery.size %>
<% gallery.media_asset(media_asset: media_asset, size: gallery.size, link_target: media_asset.post || upload) do |preview| %>
<% preview.footer do %>
<div class="text-center text-muted text-xs h-12">
<% if media_asset.post.present? %>
<div class="leading-none">
<%= link_to "post ##{media_asset.post.id}", media_asset.post, class: "leading-none" %>
</div>
<% end %>
<% if upload.source.present? %>
<%= external_link_to upload.source, Addressable::URI.parse(upload.source).domain %>
<% else %>
<em>No source</em>
<% end %>
</div>
<% end %>
<% end %> <% end %>
<% end %> <% end %>
<% end %> <% end %>
<%= numbered_paginator(@media_assets) %> <%= numbered_paginator(@uploads) %>

View File

@@ -0,0 +1,30 @@
<% media_asset = upload.upload_media_assets.sort_by(&:id).first&.media_asset %>
<%= render(MediaAssetPreviewComponent.new(media_asset: media_asset, size: size, link_target: upload, save_data: CurrentUser.save_data)) do |preview| %>
<% if upload.media_asset_count > 1 %>
<% preview.header do %>
<div class="media-asset-image-count-icon absolute top-0.5 right-0.5 p-1 m-0.5 leading-none rounded text-xs font-arial font-bold">
<%= multiple_images_icon %>
<span class="align-middle"><%= upload.media_asset_count %></span>
</div>
<% end %>
<% end %>
<% preview.footer do %>
<div class="text-center text-muted text-xs">
<div class="leading-none">
<% if upload.media_asset_count == 1 && media_asset&.post.present? %>
<%= link_to "post ##{media_asset.post.id}", media_asset.post, class: "leading-none" %>
<% else %>
<%= link_to "upload ##{upload.id}", upload, class: "leading-none" %>
<% end %>
</div>
<% if upload.source.present? %>
<%= external_link_to upload.source, Addressable::URI.parse(upload.source).domain %>
<% else %>
<em>No source</em>
<% end %>
</div>
<% end %>
<% end %>

View File

@@ -9,28 +9,13 @@
<%= table_for @uploads, class: "striped", width: "100%" do |t| %> <%= table_for @uploads, class: "striped", width: "100%" do |t| %>
<% t.column "Upload", td: { class: "text-center" } do |upload| %> <% t.column "Upload", td: { class: "text-center" } do |upload| %>
<% upload.media_assets.first.tap do |media_asset| %> <%= render "uploads/preview", upload: upload, size: "180" %>
<% if media_asset.present? %>
<% if media_asset.post.present? %>
<%= render MediaAssetPreviewComponent.new(media_asset: media_asset, link_target: media_asset.post, save_data: CurrentUser.save_data) %>
<% else %>
<%= render MediaAssetPreviewComponent.new(media_asset: media_asset, link_target: upload, save_data: CurrentUser.save_data) %>
<% end %>
<% end %>
<% end %>
<% end %> <% end %>
<% t.column "Info", td: { class: "col-expand" } do |upload| %> <% t.column "Info", td: { class: "col-expand" } do |upload| %>
<div> <div>
<% upload.media_assets.first.tap do |media_asset| %> <strong>Upload</strong>
<% if media_asset&.post.present? %> <span><%= link_to "##{upload.id}", upload %></span>
<strong>Post</strong>
<span><%= link_to "##{media_asset.post.id}", media_asset.post %></span>
<% else %>
<strong>Upload</strong>
<span><%= link_to "##{upload.id}", upload %></span>
<% end %>
<% end %>
</div> </div>
<div> <div>