Repository navigation
π dashboard: keep tracker sounds working after reloads and in Safari - #14959
Conversation
Every reload β including the dashboard's automatic reload on a new hive version β starts a document without user activation, so the AudioContext created for the first automatic zap/buzz is suspended by the browser's autoplay policy and each play was dropped silently while the key was still marked as played and the chip kept showing π. - Show a one-time 'Enable sounds' toast and turn the chip amber when the engine is held back (at init when there is no user activation, and when an automatic play is skipped); any click/key/pointer/touch primes it. - Schedule gesture plays (βΆ Play, toggling sound on) synchronously inside the gesture so WebKit unlocks the context; wait for 'statechange' when resume() settles before the state flips; close and drop a refused context instead of leaving voices queued to burst out later. - Node fixtures cover the held notice, synchronous gesture scheduling, stale-resume wait and discard-on-refusal; docs and changelog updated. Signed-off-by: Andrew Anderson <andy@clubanderson.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Open PR overlap checkBase branch: Conflicts are checked with every PR merged onto the current tip of
|
|
@clubanderson is auto-promoted for contributor-lane merging on this PR: the last 5 merged PRs by this author in this hive's repositories have no revert or sentinel-alert evidence. CI, reviewer verdict, diff fences, soak, holds and branch protection still apply. |
There was a problem hiding this comment.
Read src/pkg/dashboard/static/index.html at v5 bcd44e7 around the stage-tracker sound block (16625β17160) and showToast (36996). This looks correct to me; one low-severity note below.
What I verified:
showToast(msg, type, persistent, autoDismissMs)atindex.html:36997-37005already treats an object third argument as options and rendersactionLabel/onActionas a.toast-actionbutton (same call shaperesetDashboardLayoutuses at:9783), so the Enable sounds action will render and run inside its own click β the gesture the resume needs.stageTrackerSoundHeldClearβstageTrackerSoundSyncButton(:17058-17067) rewritestitle/aria-label, so the amber title set bystageTrackerSoundHeldNoticedoes not linger after the engine is released.stageTrackerSoundPrimeis guarded by_stageTrackerSoundPrimed(:16664), so the extra call fromstageTrackerSoundHeldNoticeon every blocked play is a no-op while listeners are already armed.stageTrackerDiscardContextnulls_stageTrackerAudioCtxbeforeclose(), andstageTrackerAudioContext()(:16628) recreates lazily, so a refused gesture play cannot leave a closed context behind for the next zap.- The
statechangelistener instageTrackerResumeContextis removed infinishon every path, including timeout.
Low β chip can stay amber on a browser that actually permits autoplay. stageTrackerHasUserActivation is consulted only at init (diff: stageTrackerSoundInit), and stageTrackerPlayVoices's ctx.state === 'running' branch and its resume-success branch never call stageTrackerSoundHeldClear(). On Chrome with a high media-engagement score for the dashboard origin, or Firefox with the site's autoplay permission set to Allow, the first automatic zap plays fine while the chip reads "held back by the browser" and the 60 s toast says the same, until any click/keydown fires the prime listener. Cosmetic and self-healing on the next gesture; a one-line stageTrackerSoundHeldClear() in the two success paths of stageTrackerPlayVoices would make the chip truthful. Not blocking.
Docs and changelog fragment match the behaviour.
β hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88
|
merged by Hive trusted-author auto-merge: author @clubanderson holds role owner and GitHub permission admin on repo; CI green at 68e2b90. |
|
Thank you for your contribution! Your PR has been merged. We'd love to hear how your experience was: share feedback |
Fixes #14958
Root cause
Every reload β including the dashboard's automatic reload on each new hive version β starts a document without user activation, so the
AudioContextcreated for the first automatic zap/buzz is suspended by the browser's autoplay policy; each play was dropped silently while the item was still marked as played and the chip kept showing π. In Safari the gesture path scheduled voices only afterresume()resolved and treated a latestateflip as "blocked", so even the toggle chime could be silent.(Live inspection of the hive's own tab also showed the master toggle is currently off there β
hive.tracker.sound = '0'β and the detection/poll path is intact; see the issue for the probe log.)Changes
index.html: when sound is on but the engine is held back (no user activation at init, or an automatic play skipped) the chip turns amber with a title and a one-time toast offers Enable sounds; priming listens for pointerdown/keydown/click/touchend.stageTrackerPlayOnGestureschedules voices synchronously inside the gesture (WebKit unlock),stageTrackerResumeContextwaits forstatechangewhenresume()settles before the state flips, and a refused context is closed and dropped (stageTrackerDiscardContext) rather than leaving voices queued to burst out later.stage_tracker_sound_resume_test.go/stage_tracker_merge_sound_test.go: node fixtures cover the held notice (once per load, action clears the chip, listener primes), synchronous gesture scheduling, stale-resume wait, discard-on-refusal, andstageTrackerSoundInitbehaviour with/without user activation.src/docs/dashboard-sections.mdSounds / Sound settings paragraphs;changelog.d/fixed-dashboard-tracker-sounds-held-by-autoplay.md.Operator action
Click the π chip once to turn sounds on in the Chrome tab; after any reload, click or press a key once (or the toast's Enable sounds).