media assets: redesign show page.
Redesign the media assets show page to: * Include sidebar with AI tags and image metadata. * Include next and previous image buttons. * Make the image use 100% of the available screen space and to scroll with the window.
This commit is contained in:
@@ -2,12 +2,19 @@
|
||||
|
||||
# A component for showing a full-sized image or video for a media asset.
|
||||
class MediaAssetComponent < ApplicationComponent
|
||||
attr_reader :media_asset
|
||||
attr_reader :media_asset, :current_user, :outer_classes, :inner_classes, :dynamic_height
|
||||
|
||||
delegate :image_width, :image_height, :variant, :is_image?, :is_video?, :is_ugoira?, :is_flash?, to: :media_asset
|
||||
|
||||
def initialize(media_asset:)
|
||||
renders_one :header
|
||||
renders_one :footer
|
||||
|
||||
def initialize(media_asset:, current_user:, outer_classes: "", inner_classes: "", dynamic_height: false)
|
||||
super
|
||||
@media_asset = media_asset
|
||||
@current_user = current_user
|
||||
@outer_classes = outer_classes
|
||||
@inner_classes = inner_classes
|
||||
@dynamic_height = dynamic_height
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
<div class="media-asset-component relative fit-screen">
|
||||
<div class="media-asset-zoom-level hidden absolute top-0.5 left-0.5 p-1 m-0.5 leading-none rounded text-xs font-arial font-bold pointer-events-none">
|
||||
100%
|
||||
<div class="media-asset-container media-asset-container-fit-height flex flex-col <%= outer_classes %>" data-dynamic-height="<%= dynamic_height %>" style="--header-visible-height: 0px">
|
||||
<%= header %>
|
||||
|
||||
<div class="media-asset-component relative max-h-inherit overflow-hidden <%= inner_classes %>">
|
||||
<div class="media-asset-zoom-level hidden absolute top-0.5 left-0.5 p-1 m-0.5 leading-none rounded text-xs font-arial font-bold pointer-events-none transition-opacity">
|
||||
100%
|
||||
</div>
|
||||
|
||||
<% if !policy(media_asset).can_see_image? %>
|
||||
<p>Image unavailable.</p>
|
||||
<% elsif is_image? %>
|
||||
<%= tag.img src: variant(:original).file_url, width: image_width, height: image_height, draggable: "false", class: "media-asset-image max-h-inherit max-w-full h-full w-auto select-none" -%>
|
||||
<% elsif is_video? %>
|
||||
<%= tag.video src: variant(:original).file_url, width: image_width, height: image_height, autoplay: true, loop: true, controls: "controls" %>
|
||||
<% elsif is_ugoira? %>
|
||||
<%= tag.video src: variant(:sample).file_url, width: image_width, height: image_height, autoplay: true, loop: true, controls: "controls" %>
|
||||
<% elsif is_flash? %>
|
||||
<%= tag.div class: "ruffle-container", "data-swf": variant(:original).file_url %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if is_image? %>
|
||||
<%= tag.img src: variant(:original).file_url, width: image_width, height: image_height, draggable: "false", class: "media-asset-image select-none" -%>
|
||||
<% elsif is_video? %>
|
||||
<%= tag.video src: variant(:original).file_url, width: image_width, height: image_height, autoplay: true, loop: true, controls: "controls" %>
|
||||
<% elsif is_ugoira? %>
|
||||
<%= tag.video src: variant(:sample).file_url, width: image_width, height: image_height, autoplay: true, loop: true, controls: "controls" %>
|
||||
<% elsif is_flash? %>
|
||||
<%= tag.div class: "ruffle-container", "data-swf": variant(:original).file_url %>
|
||||
<% end %>
|
||||
<%= footer %>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,41 @@
|
||||
.media-asset-component.fit-screen img, .media-asset-component.fit-screen video {
|
||||
max-width: 100%;
|
||||
max-height: 90vh;
|
||||
width: auto;
|
||||
height: auto;
|
||||
.media-asset-component:not(:hover) .media-asset-zoom-level {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.media-asset-zoom-level {
|
||||
color: var(--preview-icon-color);
|
||||
background: var(--preview-icon-background);
|
||||
}
|
||||
|
||||
.media-asset-container {
|
||||
&:not(.media-asset-container-fit-height) .paginator {
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.paginator-prev, .paginator-next {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.paginator-prev, .paginator-next {
|
||||
opacity: 0;
|
||||
width: 48px;
|
||||
height: 96px;
|
||||
top: calc((100vh - var(--header-visible-height) - 96px) / 2);
|
||||
transition: opacity 0.125s, background-color 0.125s;
|
||||
|
||||
color: var(--asset-paginator-link-color);
|
||||
background-color: var(--asset-paginator-background-color);
|
||||
|
||||
&:hover {
|
||||
color: var(--asset-paginator-link-hover-color);
|
||||
background-color: var(--asset-paginator-background-hover-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.media-asset-container-fit-height {
|
||||
max-height: calc(100vh - var(--header-visible-height));
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,72 @@
|
||||
export default class MediaAssetComponent {
|
||||
static initialize() {
|
||||
$(".media-asset-component").toArray().forEach(element => {
|
||||
$(".media-asset-container").toArray().forEach(element => {
|
||||
new MediaAssetComponent(element);
|
||||
});
|
||||
}
|
||||
|
||||
constructor(element) {
|
||||
this.$component = $(element);
|
||||
this.$container = $(element);
|
||||
this.$component = this.$container.find(".media-asset-component");
|
||||
|
||||
if (this.$container.attr("data-dynamic-height") === "true") {
|
||||
this.updateHeight();
|
||||
$(window).on("scroll.danbooru", element => {
|
||||
this.updateHeight();
|
||||
});
|
||||
}
|
||||
|
||||
if (this.$image.length) {
|
||||
this.$image.on("click.danbooru", e => this.toggleFit());
|
||||
this.$image.on("load.danbooru", e => this.updateZoom());
|
||||
this.$image.on("load.danbooru", e => this.updateHeight());
|
||||
new ResizeObserver(() => this.updateZoom()).observe(this.$image.get(0));
|
||||
this.updateZoom();
|
||||
}
|
||||
}
|
||||
|
||||
toggleFit() {
|
||||
this.$component.toggleClass("fit-screen");
|
||||
if (this.canZoom) {
|
||||
this.$container.toggleClass("media-asset-container-fit-height");
|
||||
}
|
||||
|
||||
this.updateZoom();
|
||||
}
|
||||
|
||||
updateZoom() {
|
||||
this.$image.removeClass("cursor-zoom-in cursor-zoom-out");
|
||||
this.$zoomLevel.addClass("hidden").text(`${Math.round(100 * this.zoomLevel)}%`);
|
||||
this.$zoomLevel.removeClass("hidden").text(`${Math.round(100 * this.zoomLevel)}%`);
|
||||
|
||||
if (this.isDownscaled) {
|
||||
this.$image.addClass("cursor-zoom-out");
|
||||
this.$zoomLevel.removeClass("hidden");
|
||||
} else if (this.isTooBig) {
|
||||
if (this.canZoomIn) {
|
||||
this.$image.addClass("cursor-zoom-in");
|
||||
} else if (this.canZoomOut) {
|
||||
this.$image.addClass("cursor-zoom-out");
|
||||
}
|
||||
}
|
||||
|
||||
updateHeight() {
|
||||
// XXX 115 = header height (hardcoded to prevent height glitches as page loads)
|
||||
this.$container.css("--header-visible-height", Math.min(115, Math.max(0, this.$container.offset().top - $(window).scrollTop())) + "px");
|
||||
}
|
||||
|
||||
get zoomLevel() {
|
||||
return this.$image.width() / Number(this.$image.attr("width"));
|
||||
}
|
||||
|
||||
get isDownscaled() {
|
||||
return this.$image.width() < Number(this.$image.attr("width"));
|
||||
get canZoom() {
|
||||
return this.canZoomIn || this.canZoomOut;
|
||||
}
|
||||
|
||||
get isTooBig() {
|
||||
return this.$image.width() > this.$component.width();
|
||||
get canZoomIn() {
|
||||
return !this.isZoomed && this.$image.height() < this.$image.get(0).naturalHeight && Math.round(this.$image.width()) < Math.round(this.$container.width());
|
||||
}
|
||||
|
||||
get canZoomOut() {
|
||||
return this.isZoomed;
|
||||
}
|
||||
|
||||
get isZoomed() {
|
||||
return !this.$container.is(".media-asset-container-fit-height");
|
||||
}
|
||||
|
||||
get $image() {
|
||||
|
||||
@@ -116,6 +116,9 @@ html, body[data-current-user-theme="light"] {
|
||||
|
||||
--default-border-color: var(--grey-1);
|
||||
|
||||
--success-color: var(--green-5);
|
||||
--error-color: var(--red-5);
|
||||
|
||||
--error-background-color: var(--red-1);
|
||||
--success-background-color: var(--green-0);
|
||||
--target-background: var(--yellow-0);
|
||||
@@ -287,6 +290,11 @@ html, body[data-current-user-theme="light"] {
|
||||
--paginator-arrow-background-color: var(--inverse-text-color);
|
||||
--paginator-arrow-color: var(--link-color);
|
||||
|
||||
--asset-paginator-link-color: var(--link-color);
|
||||
--asset-paginator-link-hover-color: var(--link-color);
|
||||
--asset-paginator-background-color: var(--white);
|
||||
--asset-paginator-background-hover-color: var(--blue-0);
|
||||
|
||||
--artist-tag-color: var(--red-6);
|
||||
--artist-tag-hover-color: var(--red-5);
|
||||
--copyright-tag-color: var(--magenta-6);
|
||||
@@ -334,6 +342,9 @@ html, body[data-current-user-theme="light"] {
|
||||
--link-color: var(--azure-4);
|
||||
--link-hover-color: var(--azure-3);
|
||||
|
||||
--success-color: var(--green-3);
|
||||
--error-color: var(--red-3);
|
||||
|
||||
--default-border-color: var(--grey-7);
|
||||
|
||||
--error-background-color: var(--red-9);
|
||||
@@ -494,6 +505,11 @@ html, body[data-current-user-theme="light"] {
|
||||
--paginator-arrow-background-color: var(--grey-0);
|
||||
--paginator-arrow-color: var(--link-color);
|
||||
|
||||
--asset-paginator-link-color: var(--white);
|
||||
--asset-paginator-link-hover-color: var(--white);
|
||||
--asset-paginator-background-color: var(--grey-9);
|
||||
--asset-paginator-background-hover-color: var(--grey-8);
|
||||
|
||||
--artist-tag-color: var(--red-3);
|
||||
--artist-tag-hover-color: var(--red-2);
|
||||
--copyright-tag-color: var(--purple-3);
|
||||
|
||||
@@ -46,6 +46,7 @@ $spacer: 0.25rem; /* 4px */
|
||||
}
|
||||
|
||||
.overflow-auto { overflow: auto; }
|
||||
.overflow-hidden { overflow: hidden; }
|
||||
|
||||
.break-all { word-break: break-all; }
|
||||
.whitespace-nowrap { white-space: nowrap; }
|
||||
@@ -62,11 +63,21 @@ $spacer: 0.25rem; /* 4px */
|
||||
.relative { position: relative; }
|
||||
.sticky { position: sticky; }
|
||||
|
||||
.top-0 { top: 0; }
|
||||
.bottom-0 { bottom: 0; }
|
||||
.left-0 { left: 0; }
|
||||
.right-0 { right: 0; }
|
||||
|
||||
.top-0\.5 { top: 0.5 * $spacer; }
|
||||
.bottom-0\.5 { bottom: 0.5 * $spacer; }
|
||||
.left-0\.5 { left: 0.5 * $spacer; }
|
||||
.right-0\.5 { right: 0.5 * $spacer; }
|
||||
|
||||
.top-4 { top: 4 * $spacer; }
|
||||
.bottom-4 { bottom: 4 * $spacer; }
|
||||
.left-4 { left: 4 * $spacer; }
|
||||
.right-4 { right: 4 * $spacer; }
|
||||
|
||||
.inset-0 { top: 0; right: 0; bottom: 0; left: 0 }
|
||||
|
||||
.border, %border { border-width: 1px; }
|
||||
@@ -138,6 +149,7 @@ $spacer: 0.25rem; /* 4px */
|
||||
.w-auto { width: auto; }
|
||||
.w-min { width: min-content; }
|
||||
.w-max { width: max-content; }
|
||||
.w-fit { width: fit-content; }
|
||||
.w-sm { width: 24rem; }
|
||||
.w-md { width: 28rem; }
|
||||
.w-1\/4 { width: 25%; }
|
||||
@@ -149,15 +161,20 @@ $spacer: 0.25rem; /* 4px */
|
||||
.w-225px { width: 225px; }
|
||||
.w-270px { width: 270px; }
|
||||
.w-360px { width: 360px; }
|
||||
.w-600px { width: 600px; }
|
||||
|
||||
.min-w-0 { min-width: 0; }
|
||||
|
||||
.max-w-full { max-width: 100%; }
|
||||
.max-h-full { max-height: 100%; }
|
||||
|
||||
.h-auto { height: auto; }
|
||||
.h-inherit { height: inherit; }
|
||||
.h-fit { height: fit-content; }
|
||||
.h-1 { height: 1 * $spacer; }
|
||||
.h-3 { height: 3 * $spacer; }
|
||||
.h-4 { height: 4 * $spacer; }
|
||||
.h-6 { height: 6 * $spacer; }
|
||||
.h-8 { height: 8 * $spacer; }
|
||||
.h-10 { height: 10 * $spacer; }
|
||||
.h-12 { height: 12 * $spacer; }
|
||||
@@ -176,6 +193,7 @@ $spacer: 0.25rem; /* 4px */
|
||||
.max-h-360px { max-height: 360px; }
|
||||
.max-h-720px { max-height: 720px; }
|
||||
.max-h-screen { max-height: 100vh; }
|
||||
.max-h-inherit { max-height: inherit; }
|
||||
|
||||
.space-x-1 > * + * { margin-left: 1 * $spacer; }
|
||||
.space-x-2 > * + * { margin-left: 2 * $spacer; }
|
||||
@@ -195,6 +213,7 @@ $spacer: 0.25rem; /* 4px */
|
||||
.flex-1 { flex: 1 1 0%; }
|
||||
.flex-auto { flex: 1 1 auto; }
|
||||
.flex-initial { flex: 0 1 auto; }
|
||||
.flex-none { flex: none; }
|
||||
.flex-grow-1 { flex-grow: 1; }
|
||||
.flex-col { flex-direction: column; }
|
||||
.flex-wrap { flex-wrap: wrap; }
|
||||
@@ -212,6 +231,7 @@ $spacer: 0.25rem; /* 4px */
|
||||
.self-start { align-self: flex-start; }
|
||||
.self-center { align-self: center; }
|
||||
.self-stretch { align-self: stretch; }
|
||||
.self-end { align-self: flex-end; }
|
||||
|
||||
.float-right { float: right; }
|
||||
|
||||
@@ -223,8 +243,19 @@ $spacer: 0.25rem; /* 4px */
|
||||
.grid-cols-8 { grid-template-columns: repeat(8, minmax(0, 1fr)); }
|
||||
.grid-cols-12 { grid-template-columns: repeat(12, minmax(0, 1fr)); }
|
||||
|
||||
.z-0 { z-index: 0; }
|
||||
.z-10 { z-index: 10; }
|
||||
.z-20 { z-index: 20; }
|
||||
|
||||
.link-color { color: var(--link-color); }
|
||||
|
||||
.text-success { color: var(--success-color); }
|
||||
.text-error { color: var(--error-color); }
|
||||
|
||||
.transition-opacity {
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
.card {
|
||||
@extend %border;
|
||||
@extend %rounded-lg;
|
||||
@@ -232,10 +263,9 @@ $spacer: 0.25rem; /* 4px */
|
||||
}
|
||||
|
||||
.thin-scrollbar {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overflow: auto;
|
||||
padding-right: 2 * $spacer;
|
||||
overscroll-behavior: contain; // https://caniuse.com/css-overscroll-behavior
|
||||
overscroll-behavior-x: contain; // https://caniuse.com/css-overscroll-behavior
|
||||
|
||||
// Firefox only
|
||||
// https://caniuse.com/?search=scrollbar-width
|
||||
@@ -304,8 +334,11 @@ $spacer: 0.25rem; /* 4px */
|
||||
.md\:block { display: block; }
|
||||
.md\:flex { display: flex; }
|
||||
.md\:grid { display: grid; }
|
||||
.md\:sticky { position: sticky; }
|
||||
|
||||
.md\:space-x-4 > * + * { margin-left: 4 * $spacer; }
|
||||
.md\:space-x-8 > * + * { margin-left: 8 * $spacer; }
|
||||
.md\:space-y-0 > * + * { margin-top: 0; }
|
||||
|
||||
.md\:w-360px { width: 360px; }
|
||||
}
|
||||
|
||||
@@ -1,33 +1,112 @@
|
||||
<div id="c-media-assets">
|
||||
<div id="a-show" class="fixed-width-container">
|
||||
<h1 class="mb-4">Media Asset</h1>
|
||||
<div id="a-show">
|
||||
<div class="md:flex flex-row gap-4">
|
||||
<div class="flex-1 w-full">
|
||||
<%= render MediaAssetComponent.new(media_asset: @media_asset, current_user: CurrentUser.user, outer_classes: "sticky h-full relative top-0", inner_classes: "mx-auto", dynamic_height: true) do |component| %>
|
||||
<% component.with_header do %>
|
||||
<div class="paginator top-0 w-full z-10">
|
||||
<%= link_to chevron_left_icon, media_assets_path(search: { id: ">#{@media_asset.id}", order: "id_asc" }, limit: 1, redirect: true), class: "paginator-prev flex items-center justify-center text-xl absolute left-0 z-10", "data-shortcut": "a left" %>
|
||||
<%= link_to chevron_right_icon, media_assets_path(search: { id: "<#{@media_asset.id}", order: "id_desc" }, limit: 1, redirect: true), class: "paginator-next flex items-center justify-center text-xl absolute right-0 z-10", "data-shortcut": "d right" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if policy(@media_asset).can_see_image? %>
|
||||
<%= render MediaAssetComponent.new(media_asset: @media_asset) %>
|
||||
<% end %>
|
||||
<% if policy(@media_asset).can_see_image? %>
|
||||
<% component.with_footer do %>
|
||||
<div class="flex flex-none h-6 items-center justify-center text-xs">
|
||||
<%= link_to @media_asset.original.file_url do %>
|
||||
<%= number_to_human_size(@media_asset.file_size) %> .<%= @media_asset.file_ext %>,
|
||||
<%= @media_asset.image_width %>x<%= @media_asset.image_height %>
|
||||
|
||||
<table class="striped aligned-vertical">
|
||||
<% if @post.present? %>
|
||||
<tr>
|
||||
<th>Post</th>
|
||||
<td><%= link_to "##{@post.id}", @post %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% if @media_asset.duration.present? %>
|
||||
(<%= duration_to_hhmmss(@media_asset.duration) %>)
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if policy(@media_asset).can_see_image? %>
|
||||
<tr>
|
||||
<th>MD5</th>
|
||||
<td><%= @media_asset.md5 %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<div class="media-asset-sidebar md:w-360px">
|
||||
<div>
|
||||
<h3>Tags</h3>
|
||||
|
||||
<% @media_asset.metadata.sort.each do |key, value| %>
|
||||
<tr>
|
||||
<th><%= key %></th>
|
||||
<td><%= link_to value, media_assets_path(search: { metadata: { key => value }}) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<ul class="tag-list categorized-tag-list">
|
||||
<% @media_asset.ai_tags.undeprecated.sort_by { |tag| [TagCategory.split_header_list.index(tag.category_name.downcase), tag.name.starts_with?("rating:") ? 0 : 1, tag.name] }.each do |ai_tag| %>
|
||||
<%= tag.li class: "tag-type-#{ai_tag.category} space-x-1 text-sm", "data-tag-name": ai_tag.name do %>
|
||||
<% if ai_tag.tag.artist? %>
|
||||
<%= link_to "?", show_or_new_artists_path(name: ai_tag.name) %>
|
||||
<% elsif ai_tag.name =~ /\A\d+\z/ %>
|
||||
<%= link_to "?", wiki_page_path("~#{ai_tag.name}") %>
|
||||
<% else %>
|
||||
<%= link_to "?", wiki_page_path(ai_tag.name) %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to ai_tag.pretty_name, media_assets_path(search: { ai_tags_match: ai_tag.name }), class: "break-word" %>
|
||||
<%= tag.span "#{ai_tag.score}%", class: ["text-muted text-xs"] %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<table class="striped text-sm w-full">
|
||||
<tr>
|
||||
<th colspan="2" class="text-center">Metadata</th>
|
||||
</tr>
|
||||
|
||||
<% if @post.present? %>
|
||||
<tr>
|
||||
<th class="text-left">Post</th>
|
||||
<td class="break-all"><%= link_to "##{@post.id}", @post %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
|
||||
<% if policy(@media_asset).can_see_image? %>
|
||||
<tr>
|
||||
<th class="text-left">MD5</th>
|
||||
<td class="break-all"><%= @media_asset.md5 %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
|
||||
<tr>
|
||||
<th class="text-left">File Type</th>
|
||||
<td class="break-all"><%= @media_asset.mime_type %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="text-left">File Size</th>
|
||||
<td class="break-all"><%= number_to_human_size(@media_asset.file_size) %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="text-left">Resolution</th>
|
||||
<td class="break-all"><%= @media_asset.image_width %>x<%= @media_asset.image_height %></td>
|
||||
</tr>
|
||||
|
||||
<% if @media_asset.duration.present? %>
|
||||
<tr>
|
||||
<th class="text-left">Duration</th>
|
||||
<td class="break-all"><%= duration_to_hhmmss(@media_asset.duration) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
|
||||
<% @media_asset.metadata.group_by { |key, value| key.split(":").first }.sort.each do |group, pairs| %>
|
||||
<tr>
|
||||
<th colspan="2" class="text-center"><%= group.split(/[ _-]/).map(&:upcase_first).join(" ") %></th>
|
||||
</tr>
|
||||
|
||||
<% pairs.sort.each do |key, value| %>
|
||||
<tr>
|
||||
<th class="text-left w-1/4"><%= key.split(":").second.scan(/(?:[A-Z][a-z]+|[A-Z]+(?![a-z]))/).join(" ") %></th>
|
||||
<td class="break-all"><%= link_to value, media_assets_path(search: { metadata: { key => value }}) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div id="client-errors" class="error-messages ui-state-error ui-corner-all" style="display:none"></div>
|
||||
|
||||
<div id="upload-image">
|
||||
<%= render MediaAssetComponent.new(media_asset: media_asset) %>
|
||||
<%= render MediaAssetComponent.new(media_asset: media_asset, current_user: CurrentUser.user) %>
|
||||
|
||||
<p>
|
||||
<strong>Size</strong>
|
||||
|
||||
Reference in New Issue
Block a user