feat(04-01): add mute button with CSS, wire audio toggle in main.ts
- Add mute-btn element to index.html outside all screen sections - Add .mute-btn CSS styles (fixed position, bottom-right, circular) - Wire mute button click handler to toggle audioEnabled in Settings - Initialize AudioContext on first user interaction (autoplay policy) - Fix lint issues: import ordering, non-null assertion
This commit is contained in:
+51
-2
@@ -1,5 +1,7 @@
|
||||
import "./styles/main.css";
|
||||
import { initApp } from "./app";
|
||||
import { getDB, initApp } from "./app";
|
||||
import { initAudioOnInteraction } from "./audio/sounds";
|
||||
import { getSettings, saveSettings } from "./storage/db";
|
||||
|
||||
window.addEventListener("error", (event) => {
|
||||
console.error("Global error:", event.error);
|
||||
@@ -13,4 +15,51 @@ window.addEventListener("unhandledrejection", (event) => {
|
||||
if (overlay) overlay.style.display = "flex";
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", initApp);
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await initApp();
|
||||
|
||||
const db = getDB();
|
||||
|
||||
// Wire mute button
|
||||
const muteBtn = document.getElementById("mute-btn");
|
||||
const muteIcon = document.getElementById("mute-icon");
|
||||
if (muteBtn && muteIcon) {
|
||||
// Set initial state from settings
|
||||
const settings = await getSettings(db);
|
||||
const audioEnabled = settings?.audioEnabled !== false;
|
||||
muteIcon.textContent = audioEnabled ? "\u{1F50A}" : "\u{1F507}";
|
||||
if (!audioEnabled) {
|
||||
muteBtn.classList.add("mute-btn--muted");
|
||||
}
|
||||
|
||||
muteBtn.onclick = async () => {
|
||||
// Initialize AudioContext on first click (autoplay policy)
|
||||
initAudioOnInteraction();
|
||||
|
||||
const current = await getSettings(db);
|
||||
const nowEnabled = !(current?.audioEnabled !== false);
|
||||
const updated = current ?? {
|
||||
id: 1 as const,
|
||||
audioEnabled: false,
|
||||
speechEnabled: false,
|
||||
apiKey: "",
|
||||
apiCallsToday: { text: 0, image: 0 },
|
||||
lastApiCallDate: "",
|
||||
};
|
||||
updated.audioEnabled = nowEnabled;
|
||||
await saveSettings(db, updated);
|
||||
|
||||
muteIcon.textContent = nowEnabled ? "\u{1F50A}" : "\u{1F507}";
|
||||
muteBtn.classList.toggle("mute-btn--muted", !nowEnabled);
|
||||
};
|
||||
}
|
||||
|
||||
// Initialize AudioContext on first user interaction (autoplay policy D-02)
|
||||
const initAudioOnce = () => {
|
||||
initAudioOnInteraction();
|
||||
document.removeEventListener("click", initAudioOnce);
|
||||
document.removeEventListener("keydown", initAudioOnce);
|
||||
};
|
||||
document.addEventListener("click", initAudioOnce);
|
||||
document.addEventListener("keydown", initAudioOnce);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user