From 0f5026cd2092c0a0c94dfc139011d608012b5f0d Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 15 Jul 2021 00:04:33 +0200 Subject: [PATCH] gallery: option to autoplay next video on end --- copyparty/web/baguettebox.js | 150 ++++++++++++++++++++++------------- copyparty/web/browser.css | 87 ++++++++++---------- copyparty/web/util.js | 10 +-- 3 files changed, 146 insertions(+), 101 deletions(-) diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js index a94b09b2..d52d1acf 100644 --- a/copyparty/web/baguettebox.js +++ b/copyparty/web/baguettebox.js @@ -13,7 +13,7 @@ window.baguetteBox = (function () { captions: true, buttons: 'auto', noScrollbars: false, - bodyClass: 'baguetteBox-open', + bodyClass: 'bbox-open', titleTag: false, async: false, preload: 2, @@ -22,7 +22,7 @@ window.baguetteBox = (function () { afterHide: null, onChange: null, }, - overlay, slider, previousButton, nextButton, closeButton, + overlay, slider, previousButton, nextButton, vmodeButton, closeButton, currentGallery = [], currentIndex = 0, isOverlayVisible = false, @@ -36,6 +36,7 @@ window.baguetteBox = (function () { isFullscreen = false, vmute = false, vloop = false, + vnext = false, resume_mp = false; var onFSC = function (e) { @@ -171,46 +172,28 @@ window.baguetteBox = (function () { } function buildOverlay() { - overlay = ebi('baguetteBox-overlay'); - if (overlay) { - slider = ebi('baguetteBox-slider'); - previousButton = ebi('previous-button'); - nextButton = ebi('next-button'); - closeButton = ebi('close-button'); - return; + overlay = ebi('bbox-overlay'); + if (!overlay) { + var ctr = mknod('div'); + ctr.innerHTML = ( + '' + ); + overlay = ctr.firstChild; + QS('body').appendChild(overlay); + tt.init(); } - overlay = mknod('div'); - overlay.setAttribute('role', 'dialog'); - overlay.id = 'baguetteBox-overlay'; - document.getElementsByTagName('body')[0].appendChild(overlay); - - slider = mknod('div'); - slider.id = 'baguetteBox-slider'; - overlay.appendChild(slider); - - previousButton = mknod('button'); - previousButton.setAttribute('type', 'button'); - previousButton.id = 'previous-button'; - previousButton.setAttribute('aria-label', 'Previous'); - previousButton.innerHTML = '<'; - overlay.appendChild(previousButton); - - nextButton = mknod('button'); - nextButton.setAttribute('type', 'button'); - nextButton.id = 'next-button'; - nextButton.setAttribute('aria-label', 'Next'); - nextButton.innerHTML = '>'; - overlay.appendChild(nextButton); - - closeButton = mknod('button'); - closeButton.setAttribute('type', 'button'); - closeButton.id = 'close-button'; - closeButton.setAttribute('aria-label', 'Close'); - closeButton.innerHTML = '×'; - overlay.appendChild(closeButton); - - previousButton.className = nextButton.className = closeButton.className = 'baguetteBox-button'; - + slider = ebi('bbox-slider'); + previousButton = ebi('bbox-prev'); + nextButton = ebi('bbox-next'); + vmodeButton = ebi('bbox-vmode'); + closeButton = ebi('bbox-close'); bindEvents(); } @@ -239,9 +222,14 @@ window.baguetteBox = (function () { mp_ctl(); } else if (k == "KeyR" && v) { - v.loop = vloop = !vloop; - if (vloop && v.paused) - v.play(); + vloop = !vloop; + vnext = vnext && !vloop; + setVmode(); + } + else if (k == "KeyC" && v) { + vnext = !vnext; + vloop = vloop && !vnext; + setVmode(); } else if (k == "KeyF") try { @@ -253,6 +241,49 @@ window.baguetteBox = (function () { catch (ex) { } } + function setVmode() { + var v = vid(); + ebi('bbox-vmode').style.display = v ? '' : 'none'; + if (!v) + return; + + var msg = 'When video ends, ', lbl; + if (vloop) { + lbl = 'Loop'; + msg += 'repeat it'; + } + else if (vnext) { + lbl = 'Cont'; + msg += 'continue to next'; + } + else { + lbl = 'Stop'; + msg += 'just stop' + } + vmodeButton.setAttribute('aria-label', msg); + vmodeButton.setAttribute('tt', msg); + vmodeButton.textContent = lbl; + + v.loop = vloop + if (vloop && v.paused) + v.play(); + } + + function tglVmode() { + if (vloop) { + vnext = true; + vloop = false; + } + else if (vnext) + vnext = false; + else + vloop = true; + + setVmode(); + if (tt.en) + tt.show.bind(this)(); + } + function keyUpHandler(e) { if (e.ctrlKey || e.altKey || e.metaKey || e.isComposing) return; @@ -285,6 +316,7 @@ window.baguetteBox = (function () { bind(previousButton, 'click', showPreviousImage); bind(nextButton, 'click', showNextImage); bind(closeButton, 'click', hideOverlay); + bind(vmodeButton, 'click', tglVmode); bind(slider, 'contextmenu', contextmenuHandler); bind(overlay, 'touchstart', touchstartHandler, nonPassiveEvent); bind(overlay, 'touchmove', touchmoveHandler, passiveEvent); @@ -297,6 +329,7 @@ window.baguetteBox = (function () { unbind(previousButton, 'click', showPreviousImage); unbind(nextButton, 'click', showNextImage); unbind(closeButton, 'click', hideOverlay); + unbind(vmodeButton, 'click', tglVmode); unbind(slider, 'contextmenu', contextmenuHandler); unbind(overlay, 'touchstart', touchstartHandler, nonPassiveEvent); unbind(overlay, 'touchmove', touchmoveHandler, passiveEvent); @@ -321,8 +354,8 @@ window.baguetteBox = (function () { fullImage.id = 'baguette-img-' + i; imagesElements.push(fullImage); - imagesFiguresIds.push('baguetteBox-figure-' + i); - imagesCaptionsIds.push('baguetteBox-figcaption-' + i); + imagesFiguresIds.push('bbox-figure-' + i); + imagesCaptionsIds.push('bbox-figcaption-' + i); slider.appendChild(imagesElements[i]); } overlay.setAttribute('aria-labelledby', imagesFiguresIds.join(' ')); @@ -445,15 +478,15 @@ window.baguetteBox = (function () { imageElement.getAttribute('data-caption') || imageElement.title; var figure = mknod('figure'); - figure.id = 'baguetteBox-figure-' + index; - figure.innerHTML = '
' + - '
' + - '
' + + figure.id = 'bbox-figure-' + index; + figure.innerHTML = '
' + + '
' + + '
' + '
'; if (options.captions && imageCaption) { var figcaption = mknod('figcaption'); - figcaption.id = 'baguetteBox-figcaption-' + index; + figcaption.id = 'bbox-figcaption-' + index; figcaption.innerHTML = imageCaption; figure.appendChild(figcaption); } @@ -466,13 +499,16 @@ window.baguetteBox = (function () { image.addEventListener(is_vid ? 'loadedmetadata' : 'load', function () { // Remove loader element - var spinner = document.querySelector('#baguette-img-' + index + ' .baguetteBox-spinner'); + var spinner = document.querySelector('#baguette-img-' + index + ' .bbox-spinner'); figure.removeChild(spinner); if (!options.async && callback) callback(); }); image.setAttribute('src', imageSrc); - image.setAttribute('controls', 'controls'); + if (is_vid) { + image.setAttribute('controls', 'controls'); + image.onended = vidEnd; + } image.alt = thumbnailElement ? thumbnailElement.alt || '' : ''; if (options.titleTag && imageCaption) { image.title = imageCaption; @@ -568,6 +604,11 @@ window.baguetteBox = (function () { vid().currentTime += sec; } + function vidEnd() { + if (this == vid() && vnext) + showNextImage(); + } + function mp_ctl() { var v = vid(); if (!vmute && v && mp.au && !mp.au.paused) { @@ -610,6 +651,7 @@ window.baguetteBox = (function () { v.loop = vloop; } mp_ctl(); + setVmode(); } function preloadNext(index) { @@ -643,7 +685,7 @@ window.baguetteBox = (function () { clearCachedData(); unbind(document, 'keydown', keyDownHandler); unbind(document, 'keyup', keyUpHandler); - document.getElementsByTagName('body')[0].removeChild(ebi('baguetteBox-overlay')); + document.getElementsByTagName('body')[0].removeChild(ebi('bbox-overlay')); data = {}; currentGallery = []; currentIndex = 0; diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 0ed2ba87..fc64644f 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1145,7 +1145,7 @@ html.light #tree::-webkit-scrollbar { -#baguetteBox-overlay { +#bbox-overlay { display: none; opacity: 0; position: fixed; @@ -1155,27 +1155,27 @@ html.light #tree::-webkit-scrollbar { left: 0; width: 100%; height: 100%; - z-index: 1000000; + z-index: 10; background: rgba(0, 0, 0, 0.8); transition: opacity .3s ease; } -#baguetteBox-overlay.visible { +#bbox-overlay.visible { opacity: 1; } -#baguetteBox-overlay .full-image { +.full-image { display: inline-block; position: relative; width: 100%; height: 100%; text-align: center; } -#baguetteBox-overlay .full-image figure { +.full-image figure { display: inline; margin: 0; height: 100%; } -#baguetteBox-overlay .full-image img, -#baguetteBox-overlay .full-image video { +.full-image img, +.full-image video { display: inline-block; width: auto; height: auto; @@ -1186,10 +1186,10 @@ html.light #tree::-webkit-scrollbar { vertical-align: middle; box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); } -#baguetteBox-overlay .full-image video { +.full-image video { background: #333; } -#baguetteBox-overlay .full-image figcaption { +.full-image figcaption { display: block; position: fixed; bottom: .1em; @@ -1198,20 +1198,20 @@ html.light #tree::-webkit-scrollbar { white-space: normal; color: #ccc; } -#baguetteBox-overlay figcaption a { +#bbox-overlay figcaption a { background: rgba(0, 0, 0, 0.6); border-radius: .4em; padding: .3em .6em; } -#baguetteBox-overlay .full-image:before { +.full-image:before { content: ""; display: inline-block; height: 50%; width: 1px; margin-right: -1px; } -#baguetteBox-slider { - position: absolute; +#bbox-slider { + position: fixed; left: 0; top: 0; height: 100%; @@ -1219,10 +1219,10 @@ html.light #tree::-webkit-scrollbar { white-space: nowrap; transition: left .2s ease, transform .2s ease; } -#baguetteBox-slider.bounce-from-right { +.bounce-from-right { animation: bounceFromRight .4s ease-out; } -#baguetteBox-slider.bounce-from-left { +.bounce-from-left { animation: bounceFromLeft .4s ease-out; } @keyframes bounceFromRight { @@ -1235,48 +1235,51 @@ html.light #tree::-webkit-scrollbar { 50% {margin-left: 30px} 100% {margin-left: 0} } -.baguetteBox-button#next-button, -.baguetteBox-button#previous-button { +#bbox-next, +#bbox-prev { top: 50%; top: calc(50% - 30px); width: 44px; height: 60px; } -.baguetteBox-button { - position: absolute; +.bbox-btn { + position: fixed; +} +.bbox-btn, +#bbox-btns>button { cursor: pointer; outline: none; - padding: 0; - margin: 0; + padding: 0 .3em; + margin: 0 .4em; border: 0; border-radius: 15%; background: rgba(50, 50, 50, 0.5); color: #ddd; font: 1.6em sans-serif; transition: background-color .3s ease; + line-height: 1em; + vertical-align: top; } -.baguetteBox-button:focus, -.baguetteBox-button:hover { +.bbox-btn:focus, +.bbox-btn:hover { background: rgba(50, 50, 50, 0.9); } -#next-button { +button#bbox-vmode { + font-size: 1em; + line-height: 1.6em; +} +#bbox-next { + right: 1%; +} +#bbox-prev { + left: 1%; +} +#bbox-btns { + top: .5em; right: 2%; + position: fixed; } -#previous-button { - left: 2%; -} -#close-button { - top: 20px; - right: 2%; - width: 30px; - height: 30px; -} -.baguetteBox-button svg { - position: absolute; - left: 0; - top: 0; -} -.baguetteBox-spinner { +.bbox-spinner { width: 40px; height: 40px; display: inline-block; @@ -1286,8 +1289,8 @@ html.light #tree::-webkit-scrollbar { margin-top: -20px; margin-left: -20px; } -.baguetteBox-double-bounce1, -.baguetteBox-double-bounce2 { +.bbox-double-bounce1, +.bbox-double-bounce2 { width: 100%; height: 100%; border-radius: 50%; @@ -1298,7 +1301,7 @@ html.light #tree::-webkit-scrollbar { left: 0; animation: bounce 2s infinite ease-in-out; } -.baguetteBox-double-bounce2 { +.bbox-double-bounce2 { animation-delay: -1s; } @keyframes bounce { diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 4c90f959..684d423c 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -503,7 +503,7 @@ var tt = (function () { r.tt.setAttribute('id', 'tt'); document.body.appendChild(r.tt); - function show() { + r.show = function () { var cfg = sread('tooltips'); if (cfg !== null && cfg != '1') return; @@ -527,7 +527,7 @@ var tt = (function () { clmod(r.tt, 'show', 1); } - function hide() { + r.hide = function () { clmod(r.tt, 'show'); } @@ -543,8 +543,8 @@ var tt = (function () { r.en = bcfg_get('tooltips', true) } - var _show = r.en ? show : null, - _hide = r.en ? hide : null; + var _show = r.en ? r.show : null, + _hide = r.en ? r.hide : null; var o = QSA('*[tt]'); for (var a = o.length - 1; a >= 0; a--) { @@ -553,7 +553,7 @@ var tt = (function () { o[a].onmouseenter = _show; o[a].onmouseleave = _hide; } - hide(); + r.hide(); }; return r;