Skip to content

fix(audio-mixer): make volume faders drag with the pointer#859

Open
LegionaryLeader wants to merge 2 commits into
got-feedBack:mainfrom
LegionaryLeader:fix/mixer-fader-vertical-drag
Open

fix(audio-mixer): make volume faders drag with the pointer#859
LegionaryLeader wants to merge 2 commits into
got-feedBack:mainfrom
LegionaryLeader:fix/mixer-fader-vertical-drag

Conversation

@LegionaryLeader

@LegionaryLeader LegionaryLeader commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

What & why

The in-player audio mixer's volume faders only jumped to where you clicked and never followed the mouse on drag. Dragging the Song fader also stuttered playback.

Root cause

Two stacked, engine-specific problems:

  1. Vertical native sliders don't drag in this Electron/Chromium build. The faders were vertical <input type="range"> elements. This engine renders a writing-mode: vertical-lr range but neither tracks the pointer on drag nor reflects programmatic .value changes. (The original transform: rotate(-90deg) fallback failed for the same underlying reason — hit-testing ran on the un-rotated geometry.) Horizontal native ranges work fine here; only vertical ones are broken.
  2. The popover rebuilt itself mid-drag. Each committed value emits audio-mix:fader-value-changed, whose handler re-renders the entire popover — destroying the slider under the pointer after one step. The Song fader additionally re-registers itself on every change (_applySongVolumeparticipant-registered), so it broke even after the value-changed guard.

Fix

  • Replace the native range with a custom div fader (track / fill / thumb) driven directly from the pointer's Y position, backed by a hidden <input type="range"> so the existing set-fader-value commit path is reused unchanged.
  • Guard re-renders while interacting (fader-value-changed, fader-unavailable, participant-registered, participant-removed) so a drag isn't torn down by its own commits.
  • Throttle commits to ~20/sec while painting the thumb every move, so dragging Song no longer stutters playback (each commit re-runs the full _applySongVolume path incl. native gain IPC).
  • Defensive numeric coercion of fader min/max/step, and a guard so a late value-sync can't yank the thumb back mid-drag.
  • Cache-bust the audio-mixer.js include (?v=2) so clients load the new script instead of a stale cached copy.

Files

  • static/audio-mixer.js — custom fader, throttle, re-render guards
  • static/style.css — fader visuals (track / fill / thumb)
  • static/index.html, static/v3/index.html?v=2 cache-bust

Testing

  • npm run test:js955/955 pass
  • Manual: dragged every fader top↔bottom, click-to-position, Song fader during playback (no stutter), negative-dB and decimal faders, keyboard (arrows / Home / End).
image

Summary by CodeRabbit

  • Enhancements
    • Improved audio mixer fader controls with smoother dragging and keyboard adjustments.
    • Added clearer visual feedback for fader position, focus, disabled controls, and unavailable channels.
    • Prevented mixer updates from interrupting active adjustments.
    • Improved synchronization when volume changes are made elsewhere.
    • Updated the mixer resources to ensure the latest interface is loaded.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1bd3232b-21e0-47f3-ae8b-536b1a5f3a5b

📥 Commits

Reviewing files that changed from the base of the PR and between 508829c and d9475c0.

📒 Files selected for processing (4)
  • static/audio-mixer.js
  • static/index.html
  • static/style.css
  • static/v3/index.html

📝 Walkthrough

Walkthrough

The audio mixer now uses a custom vertical fader with throttled drag commits, interaction-aware rendering, committed-value synchronization, updated visual states, and cache-busted script URLs.

Changes

Mixer fader interaction

Layer / File(s) Summary
Custom vertical fader control
static/audio-mixer.js, static/style.css
Adds pointer- and keyboard-driven fader visuals, throttled drag commits, committed-value application, focus styling, and disabled/failed states.
Popover synchronization and loading
static/audio-mixer.js, static/index.html, static/v3/index.html
Prevents event-driven re-renders during interaction, resets interaction state when opening or closing, and loads the mixer script with ?v=2.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CustomFader
  participant setFaderValue
  User->>CustomFader: Adjust fader
  CustomFader->>setFaderValue: Commit value
  setFaderValue-->>CustomFader: Return commit outcome
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main user-facing change: audio mixer faders now drag with the pointer.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

The in-player mixer faders only jumped to the clicked spot and never
tracked the mouse on drag; dragging the Song fader also stuttered playback.
Root causes were engine-specific and stacked:

- The faders were vertical <input type=range> elements. This app's Electron/
  Chromium build renders a writing-mode vertical range but neither drags it
  with the pointer nor reflects programmatic .value changes (the older
  transform: rotate(-90deg) fallback broke hit-testing for the same reason).
  Horizontal native ranges work; vertical ones do not.
- Every committed value re-rendered the whole popover (fader-value-changed,
  and for Song also participant-registered via _applySongVolume re-
  registration), tearing down the slider mid-drag after a single step.

Replace the native range with a custom div fader (track/fill/thumb) driven
from the pointer's Y position, backed by a hidden <input> so the existing
set-fader-value commit path is unchanged. Guard the self-inflicted re-render
while interacting, and throttle commits to ~20/sec (painting every move) so
dragging Song no longer stutters playback. Harden fader min/max/step against
non-numeric bounds and stop a late value-sync from yanking the thumb mid-drag.

Cache-bust the audio-mixer.js include (?v=2) so clients pick up the new
script instead of a stale cached copy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: LegionaryLeader <legionaryleader@gmail.com>
@LegionaryLeader
LegionaryLeader force-pushed the fix/mixer-fader-vertical-drag branch from 51d488b to bf11320 Compare July 11, 2026 00:44
Calling preventDefault() in the fader's pointerdown handler cancels the
default focus, so a click left the fader unfocused and the arrow/Home/End
keys did nothing until the user Tabbed to it. Focus the fader explicitly
after preventDefault so keyboard adjustment works immediately after a click.

Also set aria-valuetext alongside aria-valuenow so screen readers announce
the formatted value with units (e.g. "-6 dB") instead of a bare number.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LegionaryLeader
LegionaryLeader marked this pull request as ready for review July 11, 2026 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant