Task #390: Always play notification sounds (foreground + background)

Removed the `document.visibilityState === "visible"` early-return from
two playback paths so notification sounds fire even when the Tx OS tab
is the active foreground tab:

- `use-notifications-socket.ts` — order + meeting socket events.
- `upcoming-meeting-alert.tsx` — 5-min upcoming-meeting alert chime.

All other gates remain unchanged: global mute, per-channel sound and
vibration toggles, the ~600ms throttle in the audio player, and the
per-meeting `playedRef` dedupe by `meetingId`.

Verified `pnpm --filter @workspace/tx-os typecheck` passes.
This commit is contained in:
Riyadh
2026-05-05 08:31:27 +00:00
parent e9c094f029
commit c8ab4165ba
2 changed files with 6 additions and 8 deletions
@@ -460,15 +460,14 @@ export function UpcomingMeetingAlert() {
// Play the meeting reminder sound exactly once per *new* eligible
// meeting (deduped by id) so polling refetches don't replay the chime
// every 30s. Skipped when the tab is currently visible — sound is meant
// to grab attention from a backgrounded tab. Honors mute and the
// every 30s. Plays whether the tab is foreground or background — the
// user wants to hear the reminder either way. Honors mute and the
// per-channel meeting toggle.
const playedRef = useRef<Set<number>>(new Set());
useEffect(() => {
if (!eligibleId || !user) return;
if (playedRef.current.has(eligibleId)) return;
playedRef.current.add(eligibleId);
if (typeof document !== "undefined" && document.visibilityState === "visible") return;
if (user.notificationsMuted) return;
if (!user.notifyMeetingsEnabled) return;
notificationPlayer.play(user.notificationSoundMeeting, {
@@ -42,11 +42,10 @@ export function useNotificationsSocket() {
});
}
// Per-user sound + vibration. Stay silent when the tab is in the
// foreground (the visible UI already conveys the change), when the
// user has globally muted notifications, or when this event type
// is opted-out.
if (typeof document !== "undefined" && document.visibilityState === "visible") return;
// Per-user sound + vibration. Plays whether the tab is in the
// foreground or background — users want to hear the chime even
// while looking at the app. Still silenced by global mute and
// per-channel opt-outs below.
if (user.notificationsMuted) return;
const isOrder = payload?.type === "order";
const isMeeting = payload?.type === "executive_meeting";