mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 14:55:43 +00:00
fix(waveform): repaint on Vite HMR so theme CSS var edits show live (#1005)
* fix(waveform): repaint on Vite HMR so theme CSS var edits show live The seekbar caches its colours and repaints the canvas on a data-theme MutationObserver, so a manual theme switch picks up new waveform colours. Editing a theme's CSS variables via Vite HMR changes the stylesheet but not data-theme, so the observer never fires and the canvas keeps the old palette until a theme switch — annoying during theme dev. Add a dev-only effect that drops the colour cache and repaints on every HMR update (vite:afterUpdate). import.meta.hot is undefined in production builds, so the effect is stripped there — no runtime cost. * fix(waveform): guard HMR effect against partial import.meta.hot in tests vitest's SSR env exposes a partial import.meta.hot (has .on, no .off), so the cleanup threw and failed all WaveformSeek/PlayerBar tests. Feature-detect both .on and .off before wiring the vite:afterUpdate listener.
This commit is contained in:
committed by
GitHub
parent
1c23305887
commit
f706336e58
@@ -219,6 +219,27 @@ export default function WaveformSeek({ trackId }: Props) {
|
||||
return () => observer.disconnect();
|
||||
}, [seekbarStyle]);
|
||||
|
||||
// Dev-only: a theme's CSS variables can change via Vite HMR without the
|
||||
// `data-theme` attribute changing, so the observer above never fires and the
|
||||
// cached colours + canvas keep the old palette until a manual theme switch
|
||||
// (annoying during theme dev — issue: waveform doesn't reflect CSS var edits).
|
||||
// On every HMR update, drop the colour cache and repaint. `import.meta.hot` is
|
||||
// undefined in production builds, so this whole effect is stripped there.
|
||||
useEffect(() => {
|
||||
// `import.meta.hot` is undefined in prod builds and only a partial stub in
|
||||
// the test/SSR env (has `.on` but not `.off`), so feature-detect both before
|
||||
// wiring — otherwise the cleanup throws under vitest.
|
||||
const hot = import.meta.hot;
|
||||
if (!hot || typeof hot.on !== 'function' || typeof hot.off !== 'function') return;
|
||||
const repaint = () => {
|
||||
invalidateColorCache();
|
||||
const canvas = canvasRef.current;
|
||||
if (canvas) drawSeekbar(canvas, seekbarStyle, heightsRef.current, progressRef.current, bufferedRef.current, animStateRef.current);
|
||||
};
|
||||
hot.on('vite:afterUpdate', repaint);
|
||||
return () => { hot.off('vite:afterUpdate', repaint); };
|
||||
}, [seekbarStyle]);
|
||||
|
||||
const trackIdRef = useRef(trackId);
|
||||
trackIdRef.current = trackId;
|
||||
const seekRef = useRef(seek);
|
||||
|
||||
Reference in New Issue
Block a user