From 891827b242de00cb272dc37607f7adef56510341 Mon Sep 17 00:00:00 2001 From: Thibault Nocchi <1619359+ThibaultNocchi@users.noreply.github.com> Date: Wed, 4 Nov 2020 11:26:37 +0100 Subject: [PATCH 1/4] Basic fullscreen feature for photos --- src/components/slideshow/slideshow.js | 57 +++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index b27f8af11d..fe385299fe 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -16,6 +16,7 @@ import ServerConnections from '../ServerConnections'; // eslint-disable-next-line import/named, import/namespace import { Swiper } from 'swiper/swiper-bundle.esm'; import 'swiper/swiper-bundle.css'; +import screenfull from 'screenfull'; /** * Name of transition event. @@ -177,6 +178,10 @@ export default function (options) { if (appHost.supports('sharing')) { html += getIcon('share', 'btnShare slideshowButton', true); } + if (screenfull.isEnabled) { + html += getIcon('fullscreen', 'btnFullscreen', true); + html += getIcon('fullscreen_exit', 'btnFullscreenExit hide', true); + } } html += getIcon('close', 'slideshowButton btnSlideshowExit hide-mouse-idle-tv', false); html += ''; @@ -191,6 +196,10 @@ export default function (options) { if (appHost.supports('sharing')) { html += getIcon('share', 'btnShare slideshowButton', true); } + if (screenfull.isEnabled) { + html += getIcon('fullscreen', 'btnFullscreen', true); + html += getIcon('fullscreen_exit', 'btnFullscreenExit hide', true); + } html += ''; } @@ -219,6 +228,22 @@ export default function (options) { if (btnShare) { btnShare.addEventListener('click', share); } + + const btnFullscreen = dialog.querySelector('.btnFullscreen'); + if (btnFullscreen) { + btnFullscreen.addEventListener('click', fullscreen); + } + + const btnFullscreenExit = dialog.querySelector('.btnFullscreenExit'); + if (btnFullscreenExit) { + btnFullscreenExit.addEventListener('click', fullscreenExit); + } + + if (screenfull.isEnabled) { + screenfull.on('change', function () { + toggleFullscreenButtons(screenfull.isFullscreen); + }); + } } setUserScalable(true); @@ -449,6 +474,35 @@ export default function (options) { }); } + /** + * Goes to fullscreen using screenfull plugin + */ + function fullscreen() { + if (!screenfull.isFullscreen) screenfull.request(); + toggleFullscreenButtons(true); + } + + /** + * Exits fullscreen using screenfull plugin + */ + function fullscreenExit() { + if (screenfull.isFullscreen) screenfull.exit(); + toggleFullscreenButtons(false); + } + + /** + * Updates the display of fullscreen buttons + * @param {boolean} isFullscreen - Whether the wanted state of buttons is fullscreen or not + */ + function toggleFullscreenButtons(isFullscreen) { + const btnFullscreen = dialog.querySelector('.btnFullscreen'); + const btnFullscreenExit = dialog.querySelector('.btnFullscreenExit'); + if (btnFullscreen) + btnFullscreen.classList.toggle('hide', isFullscreen); + if (btnFullscreenExit) + btnFullscreenExit.classList.toggle('hide', !isFullscreen); + } + /** * Starts the autoplay feature of the Swiper instance. */ @@ -483,6 +537,9 @@ export default function (options) { * Closes the dialog and destroys the Swiper instance. */ function onDialogClosed() { + // Exits fullscreen + fullscreenExit(); + const swiper = swiperInstance; if (swiper) { swiper.destroy(true, true); From 74fa4e4824c24b8cbf4443b06fe609ebef151b2f Mon Sep 17 00:00:00 2001 From: Thibault Nocchi <1619359+ThibaultNocchi@users.noreply.github.com> Date: Wed, 4 Nov 2020 14:19:46 +0100 Subject: [PATCH 2/4] Hiding exit, left, right buttons with OSD --- src/components/slideshow/slideshow.js | 84 +++++++++++++++++++++------ 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index fe385299fe..8fe73bc88e 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -269,6 +269,12 @@ export default function (options) { if (btnSlideshowPause) { btnSlideshowPause.classList.replace('play_arrow', 'pause'); } + + const left = dialog.querySelector('.btnSlideshowPrevious'); + if (left) slideToHide(left, 'left'); + + const right = dialog.querySelector('.btnSlideshowNext'); + if (right) slideToHide(right, 'right'); } /** @@ -279,6 +285,12 @@ export default function (options) { if (btnSlideshowPause) { btnSlideshowPause.classList.replace('pause', 'play_arrow'); } + + const left = dialog.querySelector('.btnSlideshowPrevious'); + if (left) slideToShow(left, 'left'); + + const right = dialog.querySelector('.btnSlideshowNext'); + if (right) slideToShow(right, 'right'); } /** @@ -560,9 +572,19 @@ export default function (options) { function showOsd() { const bottom = dialog.querySelector('.slideshowBottomBar'); if (bottom) { - slideUpToShow(bottom); - startHideTimer(); + slideToShow(bottom, 'down'); } + + const exit = dialog.querySelector('.btnSlideshowExit'); + if (exit) slideToShow(exit, 'up'); + + const left = dialog.querySelector('.btnSlideshowPrevious'); + if (left) slideToShow(left, 'left'); + + const right = dialog.querySelector('.btnSlideshowNext'); + if (right) slideToShow(right, 'right'); + + startHideTimer(); } /** @@ -571,8 +593,17 @@ export default function (options) { function hideOsd() { const bottom = dialog.querySelector('.slideshowBottomBar'); if (bottom) { - slideDownToHide(bottom); + slideToHide(bottom, 'down'); } + + const exit = dialog.querySelector('.btnSlideshowExit'); + if (exit) slideToHide(exit, 'up'); + + const left = dialog.querySelector('.btnSlideshowPrevious'); + if (left) slideToHide(left, 'left'); + + const right = dialog.querySelector('.btnSlideshowNext'); + if (right) slideToHide(right, 'right'); } /** @@ -594,10 +625,31 @@ export default function (options) { } /** - * Shows the OSD by sliding it into view. - * @param {HTMLElement} element - Element containing the OSD. + * + * @param {string} hiddenPosition - Position of the hidden element compared to when it's visible ('down', 'up', 'left', 'right') + * @param {*} fadingOut - Whether it is fading out or in + * @param {HTMLElement} element - Element to fade. + * @returns {Array} Array of keyframes */ - function slideUpToShow(element) { + function keyframesSlide(hiddenPosition, fadingOut, element) { + const visible = { transform: 'translate(0,0)', opacity: '1' }; + const invisible = { opacity: '.3' }; + + if (hiddenPosition === 'up' || hiddenPosition === 'down') { + invisible['transform'] = 'translate3d(0,' + element.offsetHeight * (hiddenPosition === 'down' ? 1 : -1) + 'px,0)'; + } else if (hiddenPosition === 'left' || hiddenPosition === 'right') { + invisible['transform'] = 'translate3d(' + element.offsetWidth * (hiddenPosition === 'right' ? 1 : -1) + 'px,0,0)'; + } + + return fadingOut ? [visible, invisible] : [invisible, visible]; + } + + /** + * Shows the element by sliding it into view. + * @param {HTMLElement} element - Element to show. + * @param {string} slideFrom - Direction to slide from ('down', 'up', 'left', 'right') + */ + function slideToShow(element, slideFrom) { if (!element.classList.contains('hide')) { return; } @@ -605,7 +657,8 @@ export default function (options) { element.classList.remove('hide'); const onFinish = function () { - focusManager.focus(element.querySelector('.btnSlideshowPause')); + const pause = element.querySelector('.btnSlideshowPause'); + if (pause) focusManager.focus(pause); }; if (!element.animate) { @@ -614,20 +667,18 @@ export default function (options) { } requestAnimationFrame(function () { - const keyframes = [ - { transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 0 }, - { transform: 'translate3d(0,0,0)', opacity: '1', offset: 1 } - ]; + const keyframes = keyframesSlide(slideFrom, false, element); const timing = { duration: 300, iterations: 1, easing: 'ease-out' }; element.animate(keyframes, timing).onfinish = onFinish; }); } /** - * Hides the OSD by sliding it out of view. - * @param {HTMLElement} element - Element containing the OSD. + * Hides the element by sliding it out of view. + * @param {HTMLElement} element - Element to hide. + * @param {string} slideInto - Direction to slide into ('down', 'up', 'left', 'right') */ - function slideDownToHide(element) { + function slideToHide(element, slideInto) { if (element.classList.contains('hide')) { return; } @@ -642,10 +693,7 @@ export default function (options) { } requestAnimationFrame(function () { - const keyframes = [ - { transform: 'translate3d(0,0,0)', opacity: '1', offset: 0 }, - { transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 1 } - ]; + const keyframes = keyframesSlide(slideInto, true, element); const timing = { duration: 300, iterations: 1, easing: 'ease-out' }; element.animate(keyframes, timing).onfinish = onFinish; }); From 0122ef1e038061cb4655f5fc4e1136e415881bbc Mon Sep 17 00:00:00 2001 From: Thibault Nocchi <1619359+ThibaultNocchi@users.noreply.github.com> Date: Mon, 16 Nov 2020 15:15:03 +0100 Subject: [PATCH 3/4] Applied some slideshow fixes --- src/components/slideshow/slideshow.js | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 8fe73bc88e..90ef1e0b38 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -259,6 +259,13 @@ export default function (options) { dialog.addEventListener('close', onDialogClosed); loadSwiper(dialog, options); + + const btnSlideshowExit = dialog.querySelector('.btnSlideshowExit'); + if (btnSlideshowExit) btnSlideshowExit.classList.add('hide'); + const btnSlideshowPrevious = dialog.querySelector('.btnSlideshowPrevious'); + if (btnSlideshowPrevious) btnSlideshowPrevious.classList.add('hide'); + const btnSlideshowNext = dialog.querySelector('.btnSlideshowNext'); + if (btnSlideshowNext) btnSlideshowNext.classList.add('hide'); } /** @@ -269,12 +276,6 @@ export default function (options) { if (btnSlideshowPause) { btnSlideshowPause.classList.replace('play_arrow', 'pause'); } - - const left = dialog.querySelector('.btnSlideshowPrevious'); - if (left) slideToHide(left, 'left'); - - const right = dialog.querySelector('.btnSlideshowNext'); - if (right) slideToHide(right, 'right'); } /** @@ -285,12 +286,6 @@ export default function (options) { if (btnSlideshowPause) { btnSlideshowPause.classList.replace('pause', 'play_arrow'); } - - const left = dialog.querySelector('.btnSlideshowPrevious'); - if (left) slideToShow(left, 'left'); - - const right = dialog.querySelector('.btnSlideshowNext'); - if (right) slideToShow(right, 'right'); } /** @@ -657,8 +652,8 @@ export default function (options) { element.classList.remove('hide'); const onFinish = function () { - const pause = element.querySelector('.btnSlideshowPause'); - if (pause) focusManager.focus(pause); + const btnSlideshowPause = element.querySelector('.btnSlideshowPause'); + if (btnSlideshowPause) focusManager.focus(btnSlideshowPause); }; if (!element.animate) { From bf995e4d6389f9367376773817ba5da002042835 Mon Sep 17 00:00:00 2001 From: Thibault Nocchi <1619359+ThibaultNocchi@users.noreply.github.com> Date: Sat, 21 Nov 2020 19:11:25 +0100 Subject: [PATCH 4/4] Applied fixes for exit button on mobile --- src/components/slideshow/slideshow.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 90ef1e0b38..10a3ae6200 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -260,8 +260,11 @@ export default function (options) { loadSwiper(dialog, options); - const btnSlideshowExit = dialog.querySelector('.btnSlideshowExit'); - if (btnSlideshowExit) btnSlideshowExit.classList.add('hide'); + if (layoutManager.desktop) { + const topActionButtons = dialog.querySelector('.topActionButtons'); + if (topActionButtons) topActionButtons.classList.add('hide'); + } + const btnSlideshowPrevious = dialog.querySelector('.btnSlideshowPrevious'); if (btnSlideshowPrevious) btnSlideshowPrevious.classList.add('hide'); const btnSlideshowNext = dialog.querySelector('.btnSlideshowNext'); @@ -570,8 +573,8 @@ export default function (options) { slideToShow(bottom, 'down'); } - const exit = dialog.querySelector('.btnSlideshowExit'); - if (exit) slideToShow(exit, 'up'); + const topActionButtons = dialog.querySelector('.topActionButtons'); + if (topActionButtons) slideToShow(topActionButtons, 'up'); const left = dialog.querySelector('.btnSlideshowPrevious'); if (left) slideToShow(left, 'left'); @@ -591,8 +594,8 @@ export default function (options) { slideToHide(bottom, 'down'); } - const exit = dialog.querySelector('.btnSlideshowExit'); - if (exit) slideToHide(exit, 'up'); + const topActionButtons = dialog.querySelector('.topActionButtons'); + if (topActionButtons) slideToHide(topActionButtons, 'up'); const left = dialog.querySelector('.btnSlideshowPrevious'); if (left) slideToHide(left, 'left');