diff options
| author | 2025-03-31 15:51:17 +0200 | |
|---|---|---|
| committer | 2025-03-31 15:51:17 +0200 | |
| commit | 3949117be01ac8aca7e41a7179506f27627654e5 (patch) | |
| tree | ce5c30ca299a57af69284d58021cc9380cdc553f /web/source/frontend | |
| parent | [docs] Fix Swagger URL for the "edit status" operation (#3932) (diff) | |
| download | gotosocial-3949117be01ac8aca7e41a7179506f27627654e5.tar.xz | |
[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
Diffstat (limited to 'web/source/frontend')
| -rw-r--r-- | web/source/frontend/index.js | 116 |
1 files changed, 74 insertions, 42 deletions
diff --git a/web/source/frontend/index.js b/web/source/frontend/index.js index d45420255..5a6224994 100644 --- a/web/source/frontend/index.js +++ b/web/source/frontend/index.js @@ -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(); |
