summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-25 22:48:38 +0300
committerPaul Buetow <paul@buetow.org>2026-04-25 22:48:38 +0300
commit2a75af9d78b18b33c9b329886464a20c11bd7a65 (patch)
tree2c38836a2af87716b9ce79e1412c377d7c2757ca /internal
parentd926e5f9c7a2de85589047f93626c6348ab94555 (diff)
Add opt-in ambient music control (task o8)
- Change ambient playback hotkey from 'm' to 'p' - Move flash effect hotkey from 'p' to 'f' - Update nav button labels: '<kbd>p</kbd> music' and '<kbd>f</kbd> flash' - Update splash hint to advertise 'p' music alongside 'w' wild - Add 'p' and 'f' hotkey support in splash and modal states - Persist ambient enabled/disabled state in localStorage (snonuxAmbientEnabled) - Default off; restore preference on page load without overwriting via wild mode - Improve accessibility with explicit aria-labels and aria-pressed state sync
Diffstat (limited to 'internal')
-rw-r--r--internal/generator/templates/shared/nav.tmpl4
-rw-r--r--internal/generator/templates/shared/shared.js35
2 files changed, 33 insertions, 6 deletions
diff --git a/internal/generator/templates/shared/nav.tmpl b/internal/generator/templates/shared/nav.tmpl
index b22ae0a..4f620a5 100644
--- a/internal/generator/templates/shared/nav.tmpl
+++ b/internal/generator/templates/shared/nav.tmpl
@@ -58,8 +58,8 @@
<button type="button" class="nav-fx-button" data-sno-fx="wild" aria-pressed="false" aria-label="Toggle wild mode"><kbd>w</kbd> wild</button>
<button type="button" class="nav-fx-button" data-sno-fx="crt" aria-pressed="false" aria-label="Toggle CRT effect"><kbd>c</kbd> crt</button>
<button type="button" class="nav-fx-button" data-sno-fx="ghost" aria-pressed="false" aria-label="Toggle ghost mode"><kbd>g</kbd> ghost</button>
- <button type="button" class="nav-fx-button" data-sno-fx="ambient" aria-pressed="false" aria-label="Toggle ambient sound"><kbd>m</kbd> ambient</button>
- <button type="button" class="nav-fx-button" data-sno-fx="flash" aria-label="Trigger flash effect"><kbd>p</kbd> flash</button>
+ <button type="button" class="nav-fx-button" data-sno-fx="ambient" aria-pressed="false" aria-label="Start or pause ambient music"><kbd>p</kbd> music</button>
+ <button type="button" class="nav-fx-button" data-sno-fx="flash" aria-label="Trigger flash effect"><kbd>f</kbd> flash</button>
<button type="button" class="nav-fx-button" data-sno-fx="scatter" aria-label="Trigger scatter effect"><kbd>x</kbd> scatter</button>
<span class="nav-hints-spacer"><kbd>t</kbd> theme</span>
<select id="sno-theme-select" class="nav-fx-button" aria-label="Theme"></select>
diff --git a/internal/generator/templates/shared/shared.js b/internal/generator/templates/shared/shared.js
index 31c19ed..eb7e8e5 100644
--- a/internal/generator/templates/shared/shared.js
+++ b/internal/generator/templates/shared/shared.js
@@ -1242,10 +1242,18 @@
syncFxButtonStates();
}
+ function snonuxAmbientSavePreference(enabled) {
+ try { localStorage.setItem('snonuxAmbientEnabled', enabled ? '1' : '0'); } catch (_) {}
+ }
+ function snonuxAmbientLoadPreference() {
+ try { return localStorage.getItem('snonuxAmbientEnabled') === '1'; } catch (_) { return false; }
+ }
+
function toggleAmbientMode() {
if (window.snonuxAmbientToggle) window.snonuxAmbientToggle();
pulseFxButton('ambient');
syncFxButtonStates();
+ snonuxAmbientSavePreference(window.snonuxAmbientIsPlaying && window.snonuxAmbientIsPlaying());
}
function triggerFlashEffect() {
@@ -1277,13 +1285,21 @@
syncFxButtonStates();
})();
+ // Restore ambient preference on load (opt-in; default off).
+ (function initAmbientPreference() {
+ if (snonuxAmbientLoadPreference() && window.snonuxAmbientStart) {
+ window.snonuxAmbientStart('restore');
+ }
+ syncFxButtonStates();
+ })();
+
// Inject keyboard controls hint into splash overlay (all themes)
(function enhanceSplashHint() {
var hint = document.querySelector('#splash-overlay .splash-hint');
if (!hint || document.querySelector('#splash-overlay .splash-controls')) return;
var extra = document.createElement('div');
extra.className = 'splash-controls';
- extra.innerHTML = '<kbd>↑</kbd><kbd>↓</kbd><kbd>←</kbd><kbd>→</kbd> drift \u2022 <kbd>w</kbd> wild \u2022 <kbd>m</kbd> ambient \u2022 <kbd>Enter</kbd> open';
+ extra.innerHTML = '<kbd>↑</kbd><kbd>↓</kbd><kbd>←</kbd><kbd>→</kbd> drift \u2022 <kbd>w</kbd> wild \u2022 <kbd>p</kbd> music \u2022 <kbd>Enter</kbd> open';
hint.appendChild(extra);
})();
@@ -1350,9 +1366,12 @@
} else if (e.key === 'w' && !e.repeat) {
e.preventDefault();
toggleWildMode({ splashMode: true, kickSplash: true });
- } else if (e.key === 'm' && !e.repeat) {
+ } else if (e.key === 'p' && !e.repeat) {
e.preventDefault();
toggleAmbientMode();
+ } else if (e.key === 'f' && !e.repeat) {
+ e.preventDefault();
+ triggerFlashEffect();
} else if (e.key === 'c' && !e.repeat) {
e.preventDefault();
toggleCrtMode();
@@ -1370,6 +1389,14 @@
}
if (document.getElementById('post-modal').classList.contains('active')) {
if (e.key === 'Escape') { closeModal(); e.preventDefault(); }
+ else if (e.key === 'p' && !e.repeat) {
+ e.preventDefault();
+ toggleAmbientMode();
+ }
+ else if (e.key === 'f' && !e.repeat) {
+ e.preventDefault();
+ triggerFlashEffect();
+ }
else if (e.key === 't' && !e.repeat) {
e.preventDefault();
var pick = snonuxRandomTheme();
@@ -1416,7 +1443,7 @@
toggleWildMode();
e.preventDefault(); break;
}
- case 'm': {
+ case 'p': {
toggleAmbientMode();
e.preventDefault(); break;
}
@@ -1426,7 +1453,7 @@
case 'g':
toggleGhostMode();
e.preventDefault(); break;
- case 'p':
+ case 'f':
triggerFlashEffect();
e.preventDefault(); break;
case 'x':