eloigil6 Claude Opus 4.8 commited on
Commit
ca87834
·
1 Parent(s): 1abd679

Add a café-jazz lobby bed that plays at startup and when idle

Browse files

A looping background track (frontend/lobby.mp3, LFS-tracked, served at /static/lobby.mp3) starts on the user's first gesture (browsers gate audio autoplay) and plays whenever the player is idle - no tape loaded, or paused. It fades out under a playing tape and back in when the tape stops, driven from the one play/pause chokepoint syncPlayState() -> updateLobby(). Track: Alex Morgan, 'Peaceful Cafe Jazz' (Pixabay, royalty-free). Also adds *.mp3 to Git LFS.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

Files changed (3) hide show
  1. .gitattributes +1 -0
  2. frontend/lobby.mp3 +3 -0
  3. frontend/ui.js +52 -0
.gitattributes CHANGED
@@ -35,3 +35,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  *.wav filter=lfs diff=lfs merge=lfs -text
37
  *.png filter=lfs diff=lfs merge=lfs -text
 
 
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  *.wav filter=lfs diff=lfs merge=lfs -text
37
  *.png filter=lfs diff=lfs merge=lfs -text
38
+ *.mp3 filter=lfs diff=lfs merge=lfs -text
frontend/lobby.mp3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7f5abc44caa2c025a3ac37e2c35086e64e24a9a7db209f11ef27a565021b0de2
3
+ size 4245504
frontend/ui.js CHANGED
@@ -99,6 +99,57 @@ export function initUI({
99
  // so tapes are private and a reload starts the shelf empty. Newest first.
100
  const sessionTapes = [];
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  function setStage(stage) {
103
  controlsRow.classList.toggle("hidden", stage !== "prompt");
104
  generating.classList.toggle("hidden", stage !== "generating");
@@ -433,6 +484,7 @@ export function initUI({
433
  cassette.classList.toggle("playing", playing);
434
  deck.classList.toggle("playing", playing);
435
  syncCards();
 
436
  }
437
 
438
  function updateProgress() {
 
99
  // so tapes are private and a reload starts the shelf empty. Newest first.
100
  const sessionTapes = [];
101
 
102
+ // --- lobby music ------------------------------------------------------------
103
+ // A café-jazz bed that plays at startup and whenever the player is idle (no
104
+ // tape loaded, or paused), and ducks out under a playing tape. Browsers block
105
+ // audio autoplay until the user interacts, so it's primed on the first gesture;
106
+ // after that it just follows the player state via syncPlayState() -> updateLobby().
107
+ // Track: Alex Morgan — "Peaceful Cafe Jazz" (Pixabay, royalty-free).
108
+ const LOBBY_VOL = 0.4;
109
+ const lobby = new Audio("/static/lobby.mp3");
110
+ lobby.loop = true;
111
+ lobby.preload = "auto";
112
+ lobby.volume = 0;
113
+ lobby.id = "lobby-audio";
114
+ document.body.appendChild(lobby);
115
+ let lobbyFade = null;
116
+ function fadeLobby(target, durSec = 0.7) {
117
+ if (lobbyFade) clearInterval(lobbyFade);
118
+ const from = lobby.volume;
119
+ const steps = Math.max(1, Math.round(durSec * 30));
120
+ let i = 0;
121
+ lobbyFade = setInterval(() => {
122
+ i += 1;
123
+ lobby.volume = Math.max(0, Math.min(1, from + (target - from) * (i / steps)));
124
+ if (i >= steps) {
125
+ clearInterval(lobbyFade);
126
+ lobbyFade = null;
127
+ if (target === 0) lobby.pause();
128
+ }
129
+ }, 1000 / 30);
130
+ }
131
+ // Play the bed only while nothing else is — fade it out under a live tape.
132
+ function updateLobby() {
133
+ const tapePlaying = !!active.src && !active.paused;
134
+ if (tapePlaying) {
135
+ if (!lobby.paused) fadeLobby(0);
136
+ } else {
137
+ if (lobby.paused) {
138
+ lobby.volume = 0;
139
+ lobby.play().catch(() => {}); // gated on a user gesture (primed below)
140
+ }
141
+ fadeLobby(LOBBY_VOL);
142
+ }
143
+ }
144
+ // Autoplay needs a user gesture; kick the bed off on the first one.
145
+ function primeLobby() {
146
+ window.removeEventListener("pointerdown", primeLobby);
147
+ window.removeEventListener("keydown", primeLobby);
148
+ updateLobby();
149
+ }
150
+ window.addEventListener("pointerdown", primeLobby);
151
+ window.addEventListener("keydown", primeLobby);
152
+
153
  function setStage(stage) {
154
  controlsRow.classList.toggle("hidden", stage !== "prompt");
155
  generating.classList.toggle("hidden", stage !== "generating");
 
484
  cassette.classList.toggle("playing", playing);
485
  deck.classList.toggle("playing", playing);
486
  syncCards();
487
+ updateLobby(); // duck the café-jazz bed under a playing tape, restore it when idle
488
  }
489
 
490
  function updateProgress() {