diff --git a/web/plugin.head.html b/web/plugin.head.html index e6cc522..bdaa9d5 100644 --- a/web/plugin.head.html +++ b/web/plugin.head.html @@ -12,6 +12,7 @@ html:not(.politictalk-direct-access-blocked) body { min-height: 100vh; + --politictalk-toolbar-bottom-offset: 12px; } html:not(.politictalk-direct-access-blocked) .conference, @@ -480,9 +481,10 @@ html:not(.politictalk-direct-access-blocked) #new-toolbox, html:not(.politictalk-direct-access-blocked) .toolbox { - bottom: 0 !important; - height: 0 !important; + bottom: var(--politictalk-toolbar-bottom-offset, 12px) !important; + height: auto !important; left: 0 !important; + overflow: visible !important; pointer-events: none !important; position: fixed !important; right: 0 !important; @@ -498,12 +500,10 @@ } html:not(.politictalk-direct-access-blocked) .toolbox-content-wrapper { - align-items: flex-end !important; - bottom: calc(env(safe-area-inset-bottom, 0px) + 10px) !important; - display: flex !important; - justify-content: center !important; + bottom: var(--politictalk-toolbar-bottom-offset, 12px) !important; + display: block !important; left: 50% !important; - min-height: 84px !important; + min-height: 0 !important; position: fixed !important; right: auto !important; top: auto !important; @@ -517,7 +517,7 @@ margin-left: auto !important; margin-right: auto !important; max-width: calc(100vw - 20px) !important; - position: static !important; + position: relative !important; right: auto !important; top: auto !important; transform: none !important; @@ -608,6 +608,75 @@ }); } + function updateMobileToolbarViewportOffset() { + if (!window.matchMedia || !window.matchMedia('(max-width: 640px)').matches) { + document.documentElement.style.removeProperty('--politictalk-toolbar-bottom-offset'); + return; + } + + var viewport = window.visualViewport; + var bottomGap = 0; + + if (viewport) { + bottomGap = Math.max(0, window.innerHeight - viewport.height - viewport.offsetTop); + } + + var baseOffset = Math.round(bottomGap + 12); + + setMobileToolbarBottomOffset(baseOffset); + + window.cancelAnimationFrame(window.politicTalkToolbarOffsetFrame); + window.politicTalkToolbarOffsetFrame = window.requestAnimationFrame(function() { + var toolbar = document.querySelector('.toolbox-content') + || document.querySelector('.toolbox-content-wrapper') + || document.querySelector('#new-toolbox') + || document.querySelector('.toolbox'); + + if (!toolbar) { + return; + } + + var rect = toolbar.getBoundingClientRect(); + var visibleBottom = viewport + ? Math.min(window.innerHeight, viewport.offsetTop + viewport.height) + : window.innerHeight; + var overflow = Math.ceil(rect.bottom - (visibleBottom - 12)); + + if (overflow > 0) { + setMobileToolbarBottomOffset(baseOffset + overflow); + } + }); + } + + function setMobileToolbarBottomOffset(offset) { + document.documentElement.style.setProperty( + '--politictalk-toolbar-bottom-offset', + Math.max(12, offset) + 'px' + ); + } + + function mountMobileToolbarPositioning() { + updateMobileToolbarViewportOffset(); + + window.addEventListener('resize', updateMobileToolbarViewportOffset, { passive: true }); + window.addEventListener('orientationchange', updateMobileToolbarViewportOffset, { passive: true }); + + if (window.visualViewport) { + window.visualViewport.addEventListener('resize', updateMobileToolbarViewportOffset, { passive: true }); + window.visualViewport.addEventListener('scroll', updateMobileToolbarViewportOffset, { passive: true }); + } + + var attempts = 0; + var interval = window.setInterval(function() { + attempts += 1; + updateMobileToolbarViewportOffset(); + + if (attempts >= 40) { + window.clearInterval(interval); + } + }, 250); + } + function isIgnoredJitsiPath(path) { return /^\/(?:static|images|libs|css|sounds|fonts|transcripts)\//.test(path); } @@ -996,12 +1065,14 @@ mountPoliticTalkLogo(); mountDirectAccessMessage(); mountHostHangupPolicy(); + mountMobileToolbarPositioning(); }); } else { mountPoliticTalkDocumentTitle(); mountPoliticTalkLogo(); mountDirectAccessMessage(); mountHostHangupPolicy(); + mountMobileToolbarPositioning(); } }());