[#1287] feat(frontend): add audible sound alert toggle and browser push notifications - #1383
Merged
Conversation
…d browser push notifications High and critical alerts (CIRCUIT_BREAKER_TRIPPED, RESERVE_MISMATCH, ...) were only ever rendered in the notifications drawer, so an operator who switched to another window never noticed them. Adds audible and out-of-tab alerting for those two priorities: - `useAlertChime` — plays a chime through the Web Audio API. Critical gets a descending two-tone siren and high gets a single blip so the two are distinguishable without looking. One AudioContext is created lazily and reused (browsers cap how many a page may hold), and each oscillator is disconnected on `ended` so nodes do not accumulate over a long shift. - `useDesktopNotifications` — dispatches native notifications via the Web Notifications API, but only while the document is hidden: if the operator is already looking at the tab, a native popup would duplicate the drawer. - `useAlertNotifier` — watches the notification store and fires either channel for newly arrived high/critical alerts. The store is seeded with existing ids on mount so a page reload does not replay every historical alert. - Drawer switches for both channels, persisted through the existing (previously unused) `soundEnabled` and `notificationsEnabled` user preferences. Browser constraints are surfaced rather than swallowed: the audio switch arms the AudioContext in the same click, because browsers keep it suspended until a user gesture and the first chime would otherwise be silent; permission is only requested on the enabling gesture, since browsers reject prompts that are not user-initiated; and a denied permission explains how to unblock it. Adds 31 tests across the three hooks and the drawer controls. The existing 10 NotificationsDrawer tests still pass.
|
@ToryMic Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
High and critical alerts only ever rendered inside the notifications drawer, so an operator who switched to another window never noticed a tripped circuit breaker or a reserve mismatch. This PR adds audible and out-of-tab alerting for those two priorities.
What was added
useAlertChime— chimes via the Web Audio API. Critical gets a descending two-tone siren, high a single blip, so the two are distinguishable without looking. A singleAudioContextis created lazily and reused (browsers cap how many a page may hold), and each oscillator is disconnected onendedso nodes don't accumulate over a long shift.useDesktopNotifications— native notifications via the Web Notifications API, dispatched only while the document is hidden. If the operator is already looking at the tab, a native popup would duplicate the drawer.useAlertNotifier— watches the notification store and fires either channel for newly arrived high/critical alerts.soundEnabledandnotificationsEnableduser preferences, which were defined but previously unused.Browser constraints, surfaced rather than swallowed
AudioContextin the same click. Browsers keep it suspended until a user gesture, so without this the first chime is silent. Until then the drawer tells the operator to tap once.Avoiding noise
The store is seeded with existing notification ids on mount, so a page reload does not replay every historical alert as a siren. Each id fires at most once, and medium/low priorities stay silent.
Testing
useAlertChime.test.ts(10),useAlertNotifier.test.ts(9),NotificationsDrawer.alerts.test.tsx(12)NotificationsDrawer.test.tsxtests still passeslintandtsc --noEmitclean on every changed filePre-existing baseline failures (not touched here): the frontend suite on
mainalready fails with 76 tests across 15 files. That count is identical before and after this branch, so this adds no new failures..github/workflows/ci.ymlanddocker.ymlalso fail to parse onmain(invalid${{ runner.temp }}in job-levelenvand${{ id.meta.* }}), which is an upstream issue I have left alone.Reviewer notes
critical/high) already exist on the notification store, so the feature needed no new data.NotificationContextthat plays/notification-sound.mp3vianew Audio(). It uses a differentNotificationtype with no priority field and a separate storage key. I did not touch it — consolidating the two notification systems looked out of scope, but it is worth a follow-up issue since it means the two systems can disagree about what has alerted.Closes #1287