All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m4s
- Replaced placeholder audio with the requested high-quality sound file. - Removed deprecated audio files from the public directory.
28 lines
1.4 KiB
Plaintext
28 lines
1.4 KiB
Plaintext
Look at `playNotificationSound`:
|
|
```javascript
|
|
const playNotificationSound = () => {
|
|
if (currentUser?.sound_enabled !== false && audioRef.current) {
|
|
// Reset time to 0 to allow rapid replays
|
|
audioRef.current.currentTime = 0;
|
|
const playPromise = audioRef.current.play();
|
|
```
|
|
Is `currentUser` loaded when `loadNotifications` fires for the first time after `isInitialLoadRef` is false?
|
|
Yes, `useEffect` calls `fetchCurrentUser()`, which sets `currentUser`.
|
|
|
|
Wait. `setInterval` uses a closure over the state!
|
|
```javascript
|
|
useEffect(() => {
|
|
fetchCurrentUser();
|
|
loadNotifications();
|
|
const interval = setInterval(loadNotifications, 10000);
|
|
return () => clearInterval(interval);
|
|
}, [navigate]);
|
|
```
|
|
Oh my god. The `setInterval` callback `loadNotifications` captures the *initial* state variables, including `currentUser`, which is `null` on the first render!
|
|
If `currentUser` is `null` inside the closure, `currentUser?.sound_enabled !== false` evaluates to `true !== false` which is `true`. So that's not blocking it.
|
|
BUT `audioRef.current` might not have been rendered yet? No, `audioRef` is a ref, so it mutates in place. The closure always sees the latest `audioRef.current`.
|
|
|
|
So why does it fail or not play?
|
|
Is the browser policy blocking it silently without logging?
|
|
Let's add a robust, standalone Audio approach that doesn't rely on the DOM tag if it fails, or maybe just force a click handler to "unlock" the audio context.
|