From ee24f04d76a3e9648554d4234c801de5267da0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Tue, 18 Nov 2025 08:36:49 +0100 Subject: [PATCH] feat: add automatic waveform repaint on theme change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented MutationObserver to detect theme changes: - Added themeKey state that increments on theme change - MutationObserver watches document.documentElement for class changes - Detects when "dark" class is toggled - Added themeKey to waveform effect dependencies - Canvas automatically redraws with new theme colors How it works: 1. Observer listens for class attribute changes on 2. When dark mode is toggled, themeKey increments 3. useEffect dependency triggers canvas redraw 4. getComputedStyle reads fresh --color-waveform-bg value 5. Waveform renders with correct theme background Benefits: - Seamless theme transitions - Waveform colors always match current theme - No manual refresh needed - Automatic cleanup on unmount Now switching between light/dark themes instantly updates all waveform backgrounds with the correct theme colors! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- components/tracks/Track.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/components/tracks/Track.tsx b/components/tracks/Track.tsx index 497c6de..d9c88f9 100644 --- a/components/tracks/Track.tsx +++ b/components/tracks/Track.tsx @@ -58,6 +58,7 @@ export function Track({ const [nameInput, setNameInput] = React.useState(String(track.name || 'Untitled Track')); const [effectBrowserOpen, setEffectBrowserOpen] = React.useState(false); const [showEffects, setShowEffects] = React.useState(false); + const [themeKey, setThemeKey] = React.useState(0); const inputRef = React.useRef(null); const handleNameClick = () => { @@ -90,6 +91,22 @@ export function Track({ } }, [isEditingName]); + // Listen for theme changes + React.useEffect(() => { + const observer = new MutationObserver(() => { + // Increment key to force waveform redraw + setThemeKey((prev) => prev + 1); + }); + + // Watch for class changes on document element (dark mode toggle) + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['class'], + }); + + return () => observer.disconnect(); + }, []); + // Draw waveform React.useEffect(() => { if (!track.audioBuffer || !canvasRef.current) return; @@ -166,7 +183,7 @@ export function Track({ ctx.lineTo(playheadX, height); ctx.stroke(); } - }, [track.audioBuffer, track.color, track.collapsed, track.height, zoom, currentTime, duration]); + }, [track.audioBuffer, track.color, track.collapsed, track.height, zoom, currentTime, duration, themeKey]); const handleCanvasClick = (e: React.MouseEvent) => { if (!onSeek || !duration) return;