fix fulscreen between btns
This commit is contained in:
parent
6e2cf09ce5
commit
ea9bdddef4
2
main.go
2
main.go
|
|
@ -36,7 +36,7 @@ import (
|
||||||
//go:embed static
|
//go:embed static
|
||||||
var embeddedStaticFiles embed.FS
|
var embeddedStaticFiles embed.FS
|
||||||
|
|
||||||
const version = "1.0.5"
|
const version = "1.0.6"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Config structs
|
// Config structs
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,17 @@
|
||||||
|
|
||||||
(function(){
|
(function(){
|
||||||
const THEME_KEY = 'force-monitor-theme';
|
const THEME_KEY = 'force-monitor-theme';
|
||||||
|
const FULLSCREEN_INTENT_KEY = 'force-monitor-fullscreen-intent';
|
||||||
|
|
||||||
function byId(id){ return id ? document.getElementById(id) : null; }
|
function byId(id){ return id ? document.getElementById(id) : null; }
|
||||||
|
|
||||||
|
function getFullscreenIntent(){
|
||||||
|
try { return sessionStorage.getItem(FULLSCREEN_INTENT_KEY) === '1'; } catch (_) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFullscreenIntent(enabled){
|
||||||
|
try { sessionStorage.setItem(FULLSCREEN_INTENT_KEY, enabled ? '1' : '0'); } catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
function setTheme(theme, opts){
|
function setTheme(theme, opts){
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
const t = theme === 'light' ? 'light' : 'dark';
|
const t = theme === 'light' ? 'light' : 'dark';
|
||||||
|
|
@ -12,6 +22,7 @@
|
||||||
if (typeof opts.onChange === 'function') opts.onChange(t);
|
if (typeof opts.onChange === 'function') opts.onChange(t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initTheme(opts){
|
function initTheme(opts){
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
let theme = 'dark';
|
let theme = 'dark';
|
||||||
|
|
@ -30,21 +41,74 @@
|
||||||
}
|
}
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFullscreenButton(buttonId){
|
function updateFullscreenButton(buttonId){
|
||||||
const btn = byId(buttonId || 'fullscreen-toggle');
|
const btn = byId(buttonId || 'fullscreen-toggle');
|
||||||
if (btn) btn.textContent = document.fullscreenElement ? 'Exit fullscreen' : 'Enter fullscreen';
|
if (!btn) return;
|
||||||
|
if (document.fullscreenElement) {
|
||||||
|
btn.textContent = 'Exit fullscreen';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
btn.textContent = getFullscreenIntent() ? 'Restore fullscreen' : 'Enter fullscreen';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function requestFullscreenSafe(){
|
||||||
|
if (document.fullscreenElement) return true;
|
||||||
|
if (!document.fullscreenEnabled) return false;
|
||||||
|
try {
|
||||||
|
await document.documentElement.requestFullscreen();
|
||||||
|
setFullscreenIntent(true);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Fullscreen restore/request blocked:', err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function toggleFullscreen(buttonId){
|
async function toggleFullscreen(buttonId){
|
||||||
try {
|
try {
|
||||||
if (!document.fullscreenElement) await document.documentElement.requestFullscreen();
|
if (!document.fullscreenElement) {
|
||||||
else await document.exitFullscreen();
|
await requestFullscreenSafe();
|
||||||
|
} else {
|
||||||
|
setFullscreenIntent(false);
|
||||||
|
await document.exitFullscreen();
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Fullscreen error:', err);
|
console.warn('Fullscreen error:', err);
|
||||||
} finally {
|
} finally {
|
||||||
updateFullscreenButton(buttonId || 'fullscreen-toggle');
|
updateFullscreenButton(buttonId || 'fullscreen-toggle');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function initFullscreen(opts){
|
|
||||||
|
function bindFullscreenNavPersistence(){
|
||||||
|
if (document.documentElement.dataset.fsNavBound) return;
|
||||||
|
document.documentElement.dataset.fsNavBound = '1';
|
||||||
|
|
||||||
|
document.addEventListener('click', function(ev){
|
||||||
|
const link = ev.target && ev.target.closest ? ev.target.closest('a[href]') : null;
|
||||||
|
if (!link) return;
|
||||||
|
const href = link.getAttribute('href') || '';
|
||||||
|
const target = link.getAttribute('target') || '';
|
||||||
|
if (!href || href.startsWith('#') || target === '_blank' || link.hasAttribute('download')) return;
|
||||||
|
try {
|
||||||
|
const url = new URL(link.href, window.location.href);
|
||||||
|
if (url.origin !== window.location.origin) return;
|
||||||
|
} catch (_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (document.fullscreenElement || getFullscreenIntent()) {
|
||||||
|
setFullscreenIntent(true);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
window.addEventListener('pageshow', function(){
|
||||||
|
document.querySelectorAll('#fullscreen-toggle, #fullscreen-btn').forEach(function(el){
|
||||||
|
updateFullscreenButton(el.id);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initFullscreen(opts){
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
const buttonId = opts.buttonId || 'fullscreen-toggle';
|
const buttonId = opts.buttonId || 'fullscreen-toggle';
|
||||||
const btn = byId(buttonId);
|
const btn = byId(buttonId);
|
||||||
|
|
@ -55,13 +119,23 @@
|
||||||
if (!document.documentElement.dataset.fsListenerBound) {
|
if (!document.documentElement.dataset.fsListenerBound) {
|
||||||
document.documentElement.dataset.fsListenerBound = '1';
|
document.documentElement.dataset.fsListenerBound = '1';
|
||||||
document.addEventListener('fullscreenchange', function(){
|
document.addEventListener('fullscreenchange', function(){
|
||||||
|
setFullscreenIntent(!!document.fullscreenElement);
|
||||||
document.querySelectorAll('#fullscreen-toggle, #fullscreen-btn').forEach(function(el){
|
document.querySelectorAll('#fullscreen-toggle, #fullscreen-btn').forEach(function(el){
|
||||||
el.textContent = document.fullscreenElement ? 'Exit fullscreen' : 'Enter fullscreen';
|
updateFullscreenButton(el.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
bindFullscreenNavPersistence();
|
||||||
updateFullscreenButton(buttonId);
|
updateFullscreenButton(buttonId);
|
||||||
|
|
||||||
|
if (getFullscreenIntent() && !document.fullscreenElement) {
|
||||||
|
// Best effort only: some browsers require a fresh user gesture after navigation.
|
||||||
|
requestAnimationFrame(function(){
|
||||||
|
requestFullscreenSafe().finally(function(){ updateFullscreenButton(buttonId); });
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchJson(url, opts){
|
async function fetchJson(url, opts){
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
|
@ -88,5 +162,15 @@
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.AppUI = { setTheme, initTheme, updateFullscreenButton, toggleFullscreen, initFullscreen, fetchJson };
|
|
||||||
|
window.AppUI = {
|
||||||
|
setTheme,
|
||||||
|
initTheme,
|
||||||
|
updateFullscreenButton,
|
||||||
|
toggleFullscreen,
|
||||||
|
initFullscreen,
|
||||||
|
fetchJson,
|
||||||
|
getFullscreenIntent,
|
||||||
|
setFullscreenIntent
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue