diff --git a/src/components/WaveformSeek.tsx b/src/components/WaveformSeek.tsx index f0c44668..ab6eae9f 100644 --- a/src/components/WaveformSeek.tsx +++ b/src/components/WaveformSeek.tsx @@ -785,6 +785,10 @@ export function drawSeekbar( case 'particletrail': drawParticleTrail(canvas, progress, buffered, anim); break; case 'liquidfill': drawLiquidFill(canvas, progress, buffered, anim); break; case 'retrotape': drawRetroTape(canvas, progress, buffered, anim); break; + // Safety net: if a legacy or tampered persisted style sneaks past the + // authStore migration, fall back to the truewave renderer instead of + // leaving a blank canvas. + default: drawWaveform(canvas, heights, progress, buffered); break; } } diff --git a/src/store/authStore.ts b/src/store/authStore.ts index decfe04a..f178c564 100644 --- a/src/store/authStore.ts +++ b/src/store/authStore.ts @@ -800,12 +800,18 @@ export const useAuthStore = create()( } catch { /* ignore */ } } - // One-time: 'waveform' style was renamed to 'truewave' (with 'pseudowave' - // added as the deterministic legacy variant). Existing persisted value - // 'waveform' should land on the new bins-based default. - const seekbarStyleMigrated = (state.seekbarStyle as string) === 'waveform' - ? { seekbarStyle: 'truewave' as SeekbarStyle } - : {}; + // 'waveform' style was renamed to 'truewave' (with 'pseudowave' added + // as the deterministic legacy variant). Any persisted value that is + // not a valid SeekbarStyle (legacy 'waveform', undefined, tampered + // strings) lands on the new bins-based default — otherwise the + // dispatcher's switch finds no match and the seekbar renders blank. + const VALID_SEEKBAR_STYLES = new Set([ + 'truewave', 'pseudowave', 'linedot', 'bar', 'thick', + 'segmented', 'neon', 'pulsewave', 'particletrail', 'liquidfill', 'retrotape', + ]); + const seekbarStyleMigrated = VALID_SEEKBAR_STYLES.has(state.seekbarStyle as string) + ? {} + : { seekbarStyle: 'truewave' as SeekbarStyle }; const st = state as { loudnessTargetLufs?: unknown;