uploads: show videos and ugoiras on upload page.

* On the upload page, show the video when uploading a video or ugoira.
* On the upload page, show the filesize and resolution beneath the
  image, instead of above it.
* On the media asset show page, show the full video or ugoira instead of
  just the thumbnail.
This commit is contained in:
evazion
2022-01-30 22:27:07 -06:00
parent 5d2996d0c2
commit 4ad554e28b
12 changed files with 161 additions and 86 deletions

View File

@@ -0,0 +1,13 @@
# frozen_string_literal: true
# A component for showing a full-sized image or video for a media asset.
class MediaAssetComponent < ApplicationComponent
attr_reader :media_asset
delegate :image_width, :image_height, :variant, :is_image?, :is_video?, :is_ugoira?, :is_flash?, to: :media_asset
def initialize(media_asset:)
super
@media_asset = media_asset
end
end

View File

@@ -0,0 +1,15 @@
<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>
<% 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 %>
</div>

View File

@@ -0,0 +1,56 @@
export default class MediaAssetComponent {
static initialize() {
$(".media-asset-component").toArray().forEach(element => {
new MediaAssetComponent(element);
});
}
constructor(element) {
this.$component = $(element);
if (this.$image.length) {
this.$image.on("click.danbooru", e => this.toggleFit());
new ResizeObserver(() => this.updateZoom()).observe(this.$image.get(0));
this.updateZoom();
}
}
toggleFit() {
this.$component.toggleClass("fit-screen");
this.updateZoom();
}
updateZoom() {
this.$image.removeClass("cursor-zoom-in cursor-zoom-out");
this.$zoomLevel.addClass("hidden").text(`${Math.round(100 * this.zoomLevel)}%`);
if (this.isDownscaled) {
this.$image.addClass("cursor-zoom-out");
this.$zoomLevel.removeClass("hidden");
} else if (this.isTooBig) {
this.$image.addClass("cursor-zoom-in");
}
}
get zoomLevel() {
return this.$image.width() / Number(this.$image.attr("width"));
}
get isDownscaled() {
return this.$image.width() < Number(this.$image.attr("width"));
}
get isTooBig() {
return this.$image.width() > this.$component.width();
}
get $image() {
return this.$component.find(".media-asset-image");
}
get $zoomLevel() {
return this.$component.find(".media-asset-zoom-level");
}
}
$(MediaAssetComponent.initialize);

View File

@@ -0,0 +1,11 @@
.media-asset-component.fit-screen img, .media-asset-component.fit-screen video {
max-width: 100%;
max-height: 90vh;
width: auto;
height: auto;
}
.media-asset-zoom-level {
color: var(--preview-icon-color);
background: var(--preview-icon-background);
}