feat: add background music support and static files mount

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 03:42:34 +00:00
co-authored by Claude Sonnet 4.6
parent fb6a280e85
commit ffbf75e60d
3 changed files with 23 additions and 0 deletions
+1
View File
@@ -9,6 +9,7 @@ services:
- DB_PATH=/data/rr.db - DB_PATH=/data/rr.db
volumes: volumes:
- route_rush_data:/data - route_rush_data:/data
- ./static:/app/static
networks: networks:
- web-net - web-net
+2
View File
@@ -1,4 +1,5 @@
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse, JSONResponse from fastapi.responses import HTMLResponse, JSONResponse
import json, time, random, sqlite3, os import json, time, random, sqlite3, os
@@ -6,6 +7,7 @@ from datetime import datetime
DB_PATH = os.environ.get("DB_PATH", "/data/rr.db") DB_PATH = os.environ.get("DB_PATH", "/data/rr.db")
app = FastAPI() app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")
# ── SCORING CONSTANTS ───────────────────────────────────────────────────────── # ── SCORING CONSTANTS ─────────────────────────────────────────────────────────
+20
View File
@@ -660,6 +660,7 @@ function handle(msg) {
else showRoundResults(msg); else showRoundResults(msg);
} }
else if (msg.type === 'podium') { else if (msg.type === 'podium') {
stopBGM();
showPodium(msg.leaderboard); showPodium(msg.leaderboard);
} }
} }
@@ -685,6 +686,7 @@ document.getElementById('join-btn').addEventListener('click', () => {
} }
const display = `${fn} ${ln}`; const display = `${fn} ${ln}`;
startBGM();
ws.send(JSON.stringify({type: 'join', name: display, dept, display})); ws.send(JSON.stringify({type: 'join', name: display, dept, display}));
}); });
@@ -787,6 +789,23 @@ function showPodium(lb) {
// ── INIT ────────────────────────────────────────────────────────────────────── // ── INIT ──────────────────────────────────────────────────────────────────────
// ── BACKGROUND MUSIC ─────────────────────────────────────────────────────────
let bgmStarted = false;
function startBGM() {
const bgm = document.getElementById('bgm');
if (bgmStarted) return;
bgmStarted = true;
bgm.volume = 0.20;
bgm.play().catch(() => {});
}
function stopBGM() {
const bgm = document.getElementById('bgm');
bgm.pause();
bgm.currentTime = 0;
bgmStarted = false;
}
window.addEventListener('resize', () => { if (grid) { setupCanvas(); drawGrid(); }}); window.addEventListener('resize', () => { if (grid) { setupCanvas(); drawGrid(); }});
connectWS(); connectWS();
</script> </script>
@@ -800,5 +819,6 @@ connectWS();
</div> </div>
</div> </div>
<audio id="bgm" src="/static/music.mp3" loop preload="auto"></audio>
</body> </body>
</html> </html>