sound effects

This commit is contained in:
2025-12-27 20:59:48 +02:00
parent 542b3eb6b3
commit 2a977ddec4
2 changed files with 140 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
import { useEffect, useRef } from 'react'
import { useStore } from '../store'
import { playKeyClick, playDelete, playComplete, playHint, playWordComplete } from '../sounds'
export function useSounds() {
const prevEntries = useRef<string[][] | null>(null)
const prevSolved = useRef(false)
const prevHints = useRef(0)
useEffect(() => {
const unsub = useStore.subscribe((state) => {
if (!state.puzzle) return
// letter entry or deletion
if (prevEntries.current && state.entries !== prevEntries.current) {
for (let r = 0; r < state.entries.length; r++) {
for (let c = 0; c < state.entries[r].length; c++) {
const cur = state.entries[r][c]
const old = prevEntries.current[r]?.[c] || ''
if (cur && !old) {
playKeyClick()
// word completion check
const span = state.wordSpans.find(s =>
s.cells.some(([sr, sc]) => sr === r && sc === c)
)
if (span) {
const allFilled = span.cells.every(([wr, wc]) => state.entries[wr]?.[wc])
if (allFilled) {
const wasFilled = span.cells.every(([wr, wc]) => prevEntries.current?.[wr]?.[wc])
if (!wasFilled) setTimeout(() => playWordComplete(), 50)
}
}
break
}
if (!cur && old) {
playDelete()
break
}
}
}
}
prevEntries.current = state.entries
// solved
if (state.solved && !prevSolved.current) {
playComplete()
}
prevSolved.current = state.solved
// hints
if (state.hintsUsed > prevHints.current) {
playHint()
}
prevHints.current = state.hintsUsed
})
return unsub
}, [])
}