[feature] Use blurhashes in frontend, tidy up gallery view a bit (#3948)

* [feature] Use blurhashes in frontend, tidy up gallery view a bit

* weeeeeeeeeeeeeeeee

* beep boop
This commit is contained in:
tobi
2025-03-31 15:51:17 +02:00
committed by GitHub
parent 85fb63f46f
commit 3949117be0
17 changed files with 508 additions and 124 deletions

View File

@@ -60,28 +60,39 @@ lightbox.addFilter('itemData', (item) => {
el._plyrContainer !== undefined
) {
const parentNode = el._plyrContainer.parentNode;
const loopingAuto = el.classList.contains("gifv");
return {
alt: el.getAttribute("alt"),
_video: {
open(c) {
c.appendChild(el._plyrContainer);
if (loopingAuto) {
// Start playing
// when opened.
el._player.play();
}
},
close() {
parentNode.appendChild(el._plyrContainer);
},
pause() {
el._player.pause();
},
play() {
el._player.play();
}
},
width: parseInt(el.dataset.pswpWidth),
height: parseInt(el.dataset.pswpHeight),
parentStatus: el.dataset.pswpParentStatus,
attachmentId: el.dataset.pswpAttachmentId,
loopingAuto: loopingAuto,
};
}
return item;
});
// Open video when user moves to its slide.
lightbox.on("contentActivate", (e) => {
const { content } = e;
if (content.data._video != undefined) {
@@ -89,6 +100,8 @@ lightbox.on("contentActivate", (e) => {
}
});
// Pause + close video when user
// moves away from its slide.
lightbox.on("contentDeactivate", (e) => {
const { content } = e;
if (content.data._video != undefined) {
@@ -97,12 +110,27 @@ lightbox.on("contentDeactivate", (e) => {
}
});
lightbox.on("close", function () {
// Pause video when lightbox is closed.
lightbox.on("closingAnimationStart", function () {
if (lightbox.pswp.currSlide.data._video != undefined) {
lightbox.pswp.currSlide.data._video.close();
}
});
lightbox.on("close", function () {
if (lightbox.pswp.currSlide.data._video != undefined &&
!lightbox.pswp.currSlide.data.loopingAuto) {
lightbox.pswp.currSlide.data._video.pause();
}
});
// Open video when lightbox is opened.
lightbox.on("openingAnimationEnd", function () {
if (lightbox.pswp.currSlide.data._video != undefined) {
lightbox.pswp.currSlide.data._video.play();
}
});
// Add "open this post" link to lightbox UI.
lightbox.on('uiRegister', function() {
lightbox.pswp.ui.registerElement({
name: 'open-post-link',
@@ -164,59 +192,48 @@ dynamicSpoiler("media-spoiler", (spoiler) => {
Array.from(document.getElementsByClassName("plyr-video")).forEach((video) => {
const loopingAuto = !reduceMotion.matches && video.classList.contains("gifv");
if (loopingAuto) {
// If we're able to play this as a
// looping gifv, then do so, else fall
// back to user-controllable video player.
video.draggable = false;
video.autoplay = true;
video.loop = true;
video.classList.remove("photoswipe-slide");
video.classList.remove("plry-video");
video.load();
video.play();
return;
}
let player = new Plyr(video, {
title: video.title,
settings: [],
controls: ['play-large', 'play', 'progress', 'current-time', 'volume', 'mute', 'fullscreen'],
disableContextMenu: false,
hideControls: false,
// Only show controls for video and audio,
// not looping soundless gifv. Don't show
// volume slider as it's unusable anyway
// when the video is inside a lightbox,
// mute toggle will have to be enough.
controls: loopingAuto
? []
: [
'play-large', // The large play button in the center
'restart', // Restart playback
'rewind', // Rewind by the seek time (default 10 seconds)
'play', // Play/pause playback
'fast-forward', // Fast forward by the seek time (default 10 seconds)
'current-time', // The current time of playback
'duration', // The full duration of the media
'mute', // Toggle mute
'fullscreen', // Toggle fullscreen
],
tooltips: { controls: true, seek: true },
iconUrl: "/assets/plyr.svg",
invertTime: false,
hideControls: false,
listeners: {
fullscreen: () => {
// Check if the photoswipe lightbox is
// open with this as the current slide.
const alreadyInLightbox = (
lightbox.pswp !== undefined &&
video.dataset.pswpAttachmentId === lightbox.pswp.currSlide.data.attachmentId
);
if (alreadyInLightbox) {
// If this video is already open as the
// current photoswipe slide, the fullscreen
// button toggles proper fullscreen.
player.fullscreen.toggle();
} else {
// Otherwise the fullscreen button opens
// the video as current photoswipe slide.
//
// (Don't pause the video while it's
// being transitioned to a slide.)
if (player.playing) {
setTimeout(() => player.play(), 1);
}
play: (_) => {
if (!inLightbox(video)) {
// If the video isn't open in the lightbox
// as the current photoswipe slide, clicking
// on it to play it opens it in the lightbox.
lightbox.loadAndOpen(parseInt(video.dataset.pswpIndex), {
gallery: video.closest(".photoswipe-gallery")
});
} else if (!loopingAuto) {
// If the video *is* open in the lightbox,
// and it's not a looping gifv, clicking
// play just plays or pauses the video.
player.togglePlay();
}
return false;
}
},
}
});
@@ -225,6 +242,21 @@ Array.from(document.getElementsByClassName("plyr-video")).forEach((video) => {
video._plyrContainer = player.elements.container;
});
// Return true if the photoswipe lightbox is
// open with this element as the current slide.
function inLightbox(element) {
if (lightbox.pswp === undefined) {
return false;
}
if (lightbox.pswp.currSlide === undefined) {
return false;
}
return element.dataset.pswpAttachmentId ===
lightbox.pswp.currSlide.data.attachmentId;
}
Array.from(document.getElementsByTagName('time')).forEach(timeTag => {
const datetime = timeTag.getAttribute('datetime');
const currentText = timeTag.textContent.trim();