anvilsign in

collin/mahjong

1import type { Prefs } from '../game/prefs';
2import { play, setSoundEnabled } from '../game/sound';
3
4interface Props {
5 prefs: Prefs;
6 onPrefs: (p: Prefs) => void;
7 /** Icon only, for the cramped row of controls in the middle of the table. */
8 compact?: boolean;
9}
10
11/**
12 * Mute. Turning sound *on* plays the chime straight away — partly so the room
13 * hears how loud it is before a hand starts, partly because the browser will
14 * only start the audio hardware from inside a click like this one.
15 */
16export function SoundToggle({ prefs, onPrefs, compact }: Props) {
17 const on = prefs.sound;
18 return (
19 <button
20 className={`btn ghost pill sound-toggle ${compact ? 'compact' : ''} ${on ? 'on' : ''}`}
21 aria-pressed={on}
22 onClick={() => {
23 // Unlock the audio hardware here, inside the click, rather than
24 // waiting for the effect that persists the preference.
25 setSoundEnabled(!on);
26 onPrefs({ ...prefs, sound: !on });
27 if (!on) play('claimWindow');
28 }}
29 >
30 <span className="spk" aria-hidden>
31 {on ? '🔊' : '🔇'}
32 </span>
33 {!compact && <span>{on ? '音效開 Sound on' : '靜音 Muted'}</span>}
34 </button>
35 );
36}