From 67dfd7ec08fd66ef69d484c347c74f41251e3e73 Mon Sep 17 00:00:00 2001 From: Eddy G Date: Tue, 1 Jul 2025 21:49:36 -0400 Subject: [PATCH] Add "Sticky Kiosk" setting that stores "Kiosk" mode when activate - This setting is important to allow creation ofa Home Screen app on iOS/iPadOS - If kiosk mode is accidentally made sticky, it can be cleared by adding '&kiosk=false` to the URL - Ctrl-K will now also exit kiosk mode This adds a `stickyRead` parameter to settings, that means "read it if it's there, but don't write it" --- server/scripts/index.mjs | 14 ++++++++++++-- server/scripts/modules/settings.mjs | 13 +++++++++++++ server/scripts/modules/utils/setting.mjs | 18 +++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/server/scripts/index.mjs b/server/scripts/index.mjs index 946e79a..62ac57e 100644 --- a/server/scripts/index.mjs +++ b/server/scripts/index.mjs @@ -349,10 +349,20 @@ const updateFullScreenNavigate = () => { }; const documentKeydown = (e) => { - // don't trigger on ctrl/alt/shift modified key - if (e.altKey || e.ctrlKey || e.shiftKey) return false; const { key } = e; + // Handle Ctrl+K to exit kiosk mode (even when other modifiers would normally be ignored) + if (e.ctrlKey && (key === 'k' || key === 'K')) { + e.preventDefault(); + if (settings.kiosk?.value) { + settings.kiosk.value = false; + } + return false; + } + + // don't trigger on ctrl/alt/shift modified key for other shortcuts + if (e.altKey || e.ctrlKey || e.shiftKey) return false; + if (document.fullscreenElement || document.activeElement === document.body) { switch (key) { case ' ': // Space diff --git a/server/scripts/modules/settings.mjs b/server/scripts/modules/settings.mjs index 2011f30..cd9b116 100644 --- a/server/scripts/modules/settings.mjs +++ b/server/scripts/modules/settings.mjs @@ -26,6 +26,13 @@ const kioskChange = (value) => { window.dispatchEvent(new Event('resize')); } else { body.classList.remove('kiosk'); + window.dispatchEvent(new Event('resize')); + } + + // Conditionally store the kiosk setting based on the "Sticky Kiosk" setting + // (Need to check if the method exists to handle initialization race condition) + if (settings.kiosk?.conditionalStoreToLocalStorage) { + settings.kiosk.conditionalStoreToLocalStorage(value, settings.stickyKiosk?.value); } }; @@ -95,6 +102,12 @@ const init = () => { defaultValue: false, changeAction: kioskChange, sticky: false, + stickyRead: true, + }); + settings.stickyKiosk = new Setting('stickyKiosk', { + name: 'Sticky Kiosk', + defaultValue: false, + sticky: true, }); settings.speed = new Setting('speed', { name: 'Speed', diff --git a/server/scripts/modules/utils/setting.mjs b/server/scripts/modules/utils/setting.mjs index 4ac0862..4369df4 100644 --- a/server/scripts/modules/utils/setting.mjs +++ b/server/scripts/modules/utils/setting.mjs @@ -9,6 +9,7 @@ const DEFAULTS = { defaultValue: undefined, changeAction: () => { }, sticky: true, + stickyRead: false, values: [], visible: true, }; @@ -28,6 +29,7 @@ class Setting { this.myValue = this.defaultValue; this.type = options?.type; this.sticky = options.sticky; + this.stickyRead = options.stickyRead; this.values = options.values; this.visible = options.visible; this.changeAction = options.changeAction; @@ -51,7 +53,7 @@ class Setting { // get existing value if present const storedValue = urlState ?? this.getFromLocalStorage(); - if ((this.sticky || urlValue !== undefined) && storedValue !== null) { + if ((this.sticky || this.stickyRead || urlValue !== undefined) && storedValue !== null) { this.myValue = storedValue; } @@ -154,6 +156,20 @@ class Setting { localStorage?.setItem(SETTINGS_KEY, JSON.stringify(allSettings)); } + // Conditional storage method for stickyRead settings + conditionalStoreToLocalStorage(value, shouldStore) { + if (!this.stickyRead) return; + const allSettingsString = localStorage?.getItem(SETTINGS_KEY) ?? '{}'; + const allSettings = JSON.parse(allSettingsString); + + if (shouldStore) { + allSettings[this.shortName] = value; + } else { + delete allSettings[this.shortName]; + } + localStorage?.setItem(SETTINGS_KEY, JSON.stringify(allSettings)); + } + getFromLocalStorage() { const allSettings = localStorage?.getItem(SETTINGS_KEY); try {