From 6d7464fddf2453e39ad78a196c4ab477446c01e9 Mon Sep 17 00:00:00 2001 From: Psychotoxical <171614930+Psychotoxical@users.noreply.github.com> Date: Mon, 29 Jun 2026 22:30:53 +0200 Subject: [PATCH] refactor(waveform): co-locate seekbar feature into features/waveform --- .../fullscreenPlayer/FullscreenPlayerStatic.tsx | 2 +- .../playerBar/PlayerSeekbarSection.tsx | 2 +- src/components/settings/AppearanceTab.tsx | 2 +- .../waveform}/components/WaveformSeek.test.tsx | 2 +- .../waveform}/components/WaveformSeek.tsx | 16 ++++++++-------- .../waveform}/components/WaveformSeekPreview.tsx | 6 +++--- .../waveform}/hooks/useWaveformHeights.ts | 8 ++++---- .../waveform}/hooks/useWaveformInterpolation.ts | 8 ++++---- src/features/waveform/index.ts | 11 +++++++++++ .../waveform}/store/waveformRefresh.test.ts | 8 ++++---- .../waveform}/store/waveformRefresh.ts | 8 ++++---- .../waveform}/store/waveformRefreshGen.test.ts | 2 +- .../waveform}/store/waveformRefreshGen.ts | 0 .../waveform/utils}/waveformParse.test.ts | 2 +- .../waveform/utils}/waveformParse.ts | 0 .../waveform/utils}/waveformSeekHelpers.ts | 2 +- .../waveform/utils}/waveformSeekRenderers.ts | 10 +++++----- .../utils}/waveformSeekRenderersAnimated.ts | 2 +- .../utils}/waveformSeekRenderersStatic.ts | 2 +- src/store/applyQueueHistorySnapshot.ts | 2 +- src/store/applyServerPlayQueue.idle.test.ts | 2 +- src/store/applyServerPlayQueue.ts | 2 +- src/store/audioEventHandlers.ts | 2 +- .../audioListenerSetup/audioEngineListeners.ts | 4 ++-- src/store/audioListenerSetup/authSyncListener.ts | 4 ++-- src/store/audioListenerSetup/initialAudioSync.ts | 2 +- src/store/crossfadePreload.ts | 2 +- src/store/loudnessReseed.test.ts | 2 +- src/store/loudnessReseed.ts | 2 +- src/store/playTrackAction.ts | 2 +- src/store/transportLightActions.ts | 2 +- 31 files changed, 66 insertions(+), 55 deletions(-) rename src/{ => features/waveform}/components/WaveformSeek.test.tsx (98%) rename src/{ => features/waveform}/components/WaveformSeek.tsx (97%) rename src/{ => features/waveform}/components/WaveformSeekPreview.tsx (91%) rename src/{ => features/waveform}/hooks/useWaveformHeights.ts (93%) rename src/{ => features/waveform}/hooks/useWaveformInterpolation.ts (95%) create mode 100644 src/features/waveform/index.ts rename src/{ => features/waveform}/store/waveformRefresh.test.ts (92%) rename src/{ => features/waveform}/store/waveformRefresh.ts (89%) rename src/{ => features/waveform}/store/waveformRefreshGen.test.ts (95%) rename src/{ => features/waveform}/store/waveformRefreshGen.ts (100%) rename src/{utils/waveform => features/waveform/utils}/waveformParse.test.ts (96%) rename src/{utils/waveform => features/waveform/utils}/waveformParse.ts (100%) rename src/{utils/waveform => features/waveform/utils}/waveformSeekHelpers.ts (98%) rename src/{utils/waveform => features/waveform/utils}/waveformSeekRenderers.ts (82%) rename src/{utils/waveform => features/waveform/utils}/waveformSeekRenderersAnimated.ts (99%) rename src/{utils/waveform => features/waveform/utils}/waveformSeekRenderersStatic.ts (99%) diff --git a/src/components/fullscreenPlayer/FullscreenPlayerStatic.tsx b/src/components/fullscreenPlayer/FullscreenPlayerStatic.tsx index a168fc78..152ab305 100644 --- a/src/components/fullscreenPlayer/FullscreenPlayerStatic.tsx +++ b/src/components/fullscreenPlayer/FullscreenPlayerStatic.tsx @@ -14,7 +14,7 @@ import { backdropFromConfig } from '../../cover/artistBackdrop'; import { useThemeStore } from '../../store/themeStore'; import { useFsIdleFade } from '../../hooks/useFsIdleFade'; import { useQueueTrackAt } from '../../hooks/useQueueTracks'; -import WaveformSeek from '../WaveformSeek'; +import { WaveformSeek } from '@/features/waveform'; import { FsQueueModal } from './FsQueueModal'; import { FsLyricsApple } from './FsLyricsApple'; import { FsPlayBtn } from './FsPlayBtn'; diff --git a/src/components/playerBar/PlayerSeekbarSection.tsx b/src/components/playerBar/PlayerSeekbarSection.tsx index 3dee3679..004c5cdd 100644 --- a/src/components/playerBar/PlayerSeekbarSection.tsx +++ b/src/components/playerBar/PlayerSeekbarSection.tsx @@ -3,7 +3,7 @@ import type { TFunction } from 'i18next'; import type { RadioMetadata } from '../../hooks/useRadioMetadata'; import { useThemeStore } from '../../store/themeStore'; import { formatTrackTime, playbarMinuteFieldWidth } from '../../utils/format/formatDuration'; -import WaveformSeek from '../WaveformSeek'; +import { WaveformSeek } from '@/features/waveform'; import { PlaybackTime, ToggleClock } from './PlaybackClock'; interface Props { diff --git a/src/components/settings/AppearanceTab.tsx b/src/components/settings/AppearanceTab.tsx index 2bebecb5..0c81da2f 100644 --- a/src/components/settings/AppearanceTab.tsx +++ b/src/components/settings/AppearanceTab.tsx @@ -16,7 +16,7 @@ import { SettingsGroup } from './SettingsGroup'; import { SettingsToggle } from './SettingsToggle'; import { SettingsSubCard, SettingsField, SettingsValue } from './SettingsSubCard'; import { SettingsSegmented, type SegmentedOption } from './SettingsSegmented'; -import { SeekbarPreview } from '../WaveformSeekPreview'; +import { SeekbarPreview } from '@/features/waveform'; import WindowButtonPreview from '../WindowButtonPreview'; export function AppearanceTab() { diff --git a/src/components/WaveformSeek.test.tsx b/src/features/waveform/components/WaveformSeek.test.tsx similarity index 98% rename from src/components/WaveformSeek.test.tsx rename to src/features/waveform/components/WaveformSeek.test.tsx index 993c3632..df563cc1 100644 --- a/src/components/WaveformSeek.test.tsx +++ b/src/features/waveform/components/WaveformSeek.test.tsx @@ -25,7 +25,7 @@ vi.mock('@/api/subsonic', () => ({ })); -import WaveformSeek from './WaveformSeek'; +import WaveformSeek from '@/features/waveform/components/WaveformSeek'; import { renderWithProviders } from '@/test/helpers/renderWithProviders'; import { usePlayerStore } from '@/store/playerStore'; import { useAuthStore } from '@/store/authStore'; diff --git a/src/components/WaveformSeek.tsx b/src/features/waveform/components/WaveformSeek.tsx similarity index 97% rename from src/components/WaveformSeek.tsx rename to src/features/waveform/components/WaveformSeek.tsx index 8ef2e057..c62b16cf 100644 --- a/src/components/WaveformSeek.tsx +++ b/src/features/waveform/components/WaveformSeek.tsx @@ -1,17 +1,17 @@ -import { getPlaybackProgressSnapshot, subscribePlaybackProgress } from '../store/playbackProgress'; +import { getPlaybackProgressSnapshot, subscribePlaybackProgress } from '@/store/playbackProgress'; import { useEffect, useRef, useState } from 'react'; -import { usePlayerStore } from '../store/playerStore'; -import { usePreviewStore } from '../store/previewStore'; -import { useAuthStore } from '../store/authStore'; +import { usePlayerStore } from '@/store/playerStore'; +import { usePreviewStore } from '@/store/previewStore'; +import { useAuthStore } from '@/store/authStore'; import { ANIMATED_STYLES, AnimState, STATIC_REDRAW_FORCE_MS, STATIC_REDRAW_MIN_MS, fmt, invalidateColorCache, isBarQuantizedSeekStyle, makeAnimState, quantizeProgressByBars, -} from '../utils/waveform/waveformSeekHelpers'; -import { drawSeekbar } from '../utils/waveform/waveformSeekRenderers'; -import { useWaveformHeights } from '../hooks/useWaveformHeights'; -import { useWaveformInterpolation } from '../hooks/useWaveformInterpolation'; +} from '@/features/waveform/utils/waveformSeekHelpers'; +import { drawSeekbar } from '@/features/waveform/utils/waveformSeekRenderers'; +import { useWaveformHeights } from '@/features/waveform/hooks/useWaveformHeights'; +import { useWaveformInterpolation } from '@/features/waveform/hooks/useWaveformInterpolation'; // ── main component ──────────────────────────────────────────────────────────── // diff --git a/src/components/WaveformSeekPreview.tsx b/src/features/waveform/components/WaveformSeekPreview.tsx similarity index 91% rename from src/components/WaveformSeekPreview.tsx rename to src/features/waveform/components/WaveformSeekPreview.tsx index 58d5680a..aa49af22 100644 --- a/src/components/WaveformSeekPreview.tsx +++ b/src/features/waveform/components/WaveformSeekPreview.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef } from 'react'; -import type { SeekbarStyle } from '../store/authStoreTypes'; -import { makeAnimState, makeHeights } from '../utils/waveform/waveformSeekHelpers'; -import { drawSeekbar } from '../utils/waveform/waveformSeekRenderers'; +import type { SeekbarStyle } from '@/store/authStoreTypes'; +import { makeAnimState, makeHeights } from '@/features/waveform/utils/waveformSeekHelpers'; +import { drawSeekbar } from '@/features/waveform/utils/waveformSeekRenderers'; interface Props { style: SeekbarStyle; diff --git a/src/hooks/useWaveformHeights.ts b/src/features/waveform/hooks/useWaveformHeights.ts similarity index 93% rename from src/hooks/useWaveformHeights.ts rename to src/features/waveform/hooks/useWaveformHeights.ts index c76989da..a26b53ef 100644 --- a/src/hooks/useWaveformHeights.ts +++ b/src/features/waveform/hooks/useWaveformHeights.ts @@ -1,12 +1,12 @@ import React, { useEffect } from 'react'; -import type { SeekbarStyle } from '../store/authStoreTypes'; -import type { AnimState } from '../utils/waveform/waveformSeekHelpers'; +import type { SeekbarStyle } from '@/store/authStoreTypes'; +import type { AnimState } from '@/features/waveform/utils/waveformSeekHelpers'; import { ANIMATED_STYLES, BAR_COUNT, FLAT_WAVE_NORM, WAVE_MORPH_MS, binsToHeights, easeOutCubic, heightsNearlyEqual, makeFlatWaveHeights, makeHeights, -} from '../utils/waveform/waveformSeekHelpers'; -import { drawSeekbar } from '../utils/waveform/waveformSeekRenderers'; +} from '@/features/waveform/utils/waveformSeekHelpers'; +import { drawSeekbar } from '@/features/waveform/utils/waveformSeekRenderers'; interface Args { trackId: string | undefined; diff --git a/src/hooks/useWaveformInterpolation.ts b/src/features/waveform/hooks/useWaveformInterpolation.ts similarity index 95% rename from src/hooks/useWaveformInterpolation.ts rename to src/features/waveform/hooks/useWaveformInterpolation.ts index ffe4556a..d360eb09 100644 --- a/src/hooks/useWaveformInterpolation.ts +++ b/src/features/waveform/hooks/useWaveformInterpolation.ts @@ -1,11 +1,11 @@ import React, { useEffect } from 'react'; -import type { SeekbarStyle } from '../store/authStoreTypes'; -import { getPlaybackProgressSnapshot } from '../store/playbackProgress'; +import type { SeekbarStyle } from '@/store/authStoreTypes'; +import { getPlaybackProgressSnapshot } from '@/store/playbackProgress'; import { ANIMATED_STYLES, AnimState, INTERPOLATION_PAINT_MIN_MS, isBarQuantizedSeekStyle, quantizeProgressByBars, -} from '../utils/waveform/waveformSeekHelpers'; -import { drawSeekbar } from '../utils/waveform/waveformSeekRenderers'; +} from '@/features/waveform/utils/waveformSeekHelpers'; +import { drawSeekbar } from '@/features/waveform/utils/waveformSeekRenderers'; interface Args { duration: number; diff --git a/src/features/waveform/index.ts b/src/features/waveform/index.ts new file mode 100644 index 00000000..11d5032d --- /dev/null +++ b/src/features/waveform/index.ts @@ -0,0 +1,11 @@ +/** + * Waveform seekbar feature — the canvas seekbar, its waveform-bin loading, and + * the per-track refresh generation guard. Co-located mirror of `cover/` / + * `music-network/`. `waveformSilence` stays in `utils/waveform/` (crossfade / + * auto-dj concern, not seekbar rendering). + */ +export { default as WaveformSeek } from './components/WaveformSeek'; +export { SeekbarPreview } from './components/WaveformSeekPreview'; +export { fetchWaveformBins, refreshWaveformForTrack } from './store/waveformRefresh'; +export type { WaveformCachePayload } from './store/waveformRefresh'; +export { bumpWaveformRefreshGen, getWaveformRefreshGen } from './store/waveformRefreshGen'; diff --git a/src/store/waveformRefresh.test.ts b/src/features/waveform/store/waveformRefresh.test.ts similarity index 92% rename from src/store/waveformRefresh.test.ts rename to src/features/waveform/store/waveformRefresh.test.ts index 5579d882..53761c3b 100644 --- a/src/store/waveformRefresh.test.ts +++ b/src/features/waveform/store/waveformRefresh.test.ts @@ -22,18 +22,18 @@ const hoisted = vi.hoisted(() => ({ })); vi.mock('@tauri-apps/api/core', () => ({ invoke: hoisted.invokeMock })); -vi.mock('../utils/waveform/waveformParse', () => ({ coerceWaveformBins: hoisted.coerceWaveformBinsMock })); -vi.mock('./playerStore', () => ({ +vi.mock('@/features/waveform/utils/waveformParse', () => ({ coerceWaveformBins: hoisted.coerceWaveformBinsMock })); +vi.mock('@/store/playerStore', () => ({ usePlayerStore: { getState: () => hoisted.playerSnapshot, setState: hoisted.playerSetStateMock, }, })); -vi.mock('./waveformRefreshGen', () => ({ +vi.mock('@/features/waveform/store/waveformRefreshGen', () => ({ getWaveformRefreshGen: hoisted.getGenMock, })); -import { refreshWaveformForTrack } from './waveformRefresh'; +import { refreshWaveformForTrack } from '@/features/waveform/store/waveformRefresh'; beforeEach(() => { hoisted.invokeMock.mockReset(); diff --git a/src/store/waveformRefresh.ts b/src/features/waveform/store/waveformRefresh.ts similarity index 89% rename from src/store/waveformRefresh.ts rename to src/features/waveform/store/waveformRefresh.ts index d53f4a59..0830ee2e 100644 --- a/src/store/waveformRefresh.ts +++ b/src/features/waveform/store/waveformRefresh.ts @@ -1,8 +1,8 @@ import { invoke } from '@tauri-apps/api/core'; -import { coerceWaveformBins } from '../utils/waveform/waveformParse'; -import { getPlaybackIndexKey } from '../utils/playback/playbackServer'; -import { usePlayerStore } from './playerStore'; -import { getWaveformRefreshGen } from './waveformRefreshGen'; +import { coerceWaveformBins } from '@/features/waveform/utils/waveformParse'; +import { getPlaybackIndexKey } from '@/utils/playback/playbackServer'; +import { usePlayerStore } from '@/store/playerStore'; +import { getWaveformRefreshGen } from '@/features/waveform/store/waveformRefreshGen'; /** Subsonic-server waveform-cache row as Rust hands it back. */ export type WaveformCachePayload = { diff --git a/src/store/waveformRefreshGen.test.ts b/src/features/waveform/store/waveformRefreshGen.test.ts similarity index 95% rename from src/store/waveformRefreshGen.test.ts rename to src/features/waveform/store/waveformRefreshGen.test.ts index 2d864ccf..c246c3d5 100644 --- a/src/store/waveformRefreshGen.test.ts +++ b/src/features/waveform/store/waveformRefreshGen.test.ts @@ -3,7 +3,7 @@ import { _resetWaveformRefreshGenForTest, bumpWaveformRefreshGen, getWaveformRefreshGen, -} from './waveformRefreshGen'; +} from '@/features/waveform/store/waveformRefreshGen'; afterEach(() => { _resetWaveformRefreshGenForTest(); diff --git a/src/store/waveformRefreshGen.ts b/src/features/waveform/store/waveformRefreshGen.ts similarity index 100% rename from src/store/waveformRefreshGen.ts rename to src/features/waveform/store/waveformRefreshGen.ts diff --git a/src/utils/waveform/waveformParse.test.ts b/src/features/waveform/utils/waveformParse.test.ts similarity index 96% rename from src/utils/waveform/waveformParse.test.ts rename to src/features/waveform/utils/waveformParse.test.ts index 87234477..ce78be39 100644 --- a/src/utils/waveform/waveformParse.test.ts +++ b/src/features/waveform/utils/waveformParse.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { coerceWaveformBins, waveformBlobLenOk } from './waveformParse'; +import { coerceWaveformBins, waveformBlobLenOk } from '@/features/waveform/utils/waveformParse'; describe('waveformBlobLenOk', () => { it('accepts the legacy single-curve length (500)', () => { diff --git a/src/utils/waveform/waveformParse.ts b/src/features/waveform/utils/waveformParse.ts similarity index 100% rename from src/utils/waveform/waveformParse.ts rename to src/features/waveform/utils/waveformParse.ts diff --git a/src/utils/waveform/waveformSeekHelpers.ts b/src/features/waveform/utils/waveformSeekHelpers.ts similarity index 98% rename from src/utils/waveform/waveformSeekHelpers.ts rename to src/features/waveform/utils/waveformSeekHelpers.ts index 86efd7b2..0664452f 100644 --- a/src/utils/waveform/waveformSeekHelpers.ts +++ b/src/features/waveform/utils/waveformSeekHelpers.ts @@ -1,4 +1,4 @@ -import type { SeekbarStyle } from '../../store/authStoreTypes'; +import type { SeekbarStyle } from '@/store/authStoreTypes'; export function fmt(s: number): string { if (!s || isNaN(s)) return '0:00'; diff --git a/src/utils/waveform/waveformSeekRenderers.ts b/src/features/waveform/utils/waveformSeekRenderers.ts similarity index 82% rename from src/utils/waveform/waveformSeekRenderers.ts rename to src/features/waveform/utils/waveformSeekRenderers.ts index 019fed39..98a380f9 100644 --- a/src/utils/waveform/waveformSeekRenderers.ts +++ b/src/features/waveform/utils/waveformSeekRenderers.ts @@ -1,12 +1,12 @@ -import type { SeekbarStyle } from '../../store/authStoreTypes'; -import { bumpPerfCounter } from '../perf/perfTelemetry'; -import { AnimState, makeAnimState } from './waveformSeekHelpers'; +import type { SeekbarStyle } from '@/store/authStoreTypes'; +import { bumpPerfCounter } from '@/utils/perf/perfTelemetry'; +import { AnimState, makeAnimState } from '@/features/waveform/utils/waveformSeekHelpers'; import { drawBar, drawLineDot, drawNeon, drawSegmented, drawThick, drawWaveform, -} from './waveformSeekRenderersStatic'; +} from '@/features/waveform/utils/waveformSeekRenderersStatic'; import { drawLiquidFill, drawParticleTrail, drawPulseWave, drawRetroTape, -} from './waveformSeekRenderersAnimated'; +} from '@/features/waveform/utils/waveformSeekRenderersAnimated'; export function drawSeekbar( canvas: HTMLCanvasElement, diff --git a/src/utils/waveform/waveformSeekRenderersAnimated.ts b/src/features/waveform/utils/waveformSeekRenderersAnimated.ts similarity index 99% rename from src/utils/waveform/waveformSeekRenderersAnimated.ts rename to src/features/waveform/utils/waveformSeekRenderersAnimated.ts index 2e80ee2d..8b91b0fb 100644 --- a/src/utils/waveform/waveformSeekRenderersAnimated.ts +++ b/src/features/waveform/utils/waveformSeekRenderersAnimated.ts @@ -1,4 +1,4 @@ -import { AnimState, getColors, setShadowBlur, setupCanvas } from './waveformSeekHelpers'; +import { AnimState, getColors, setShadowBlur, setupCanvas } from '@/features/waveform/utils/waveformSeekHelpers'; export function drawPulseWave( canvas: HTMLCanvasElement, diff --git a/src/utils/waveform/waveformSeekRenderersStatic.ts b/src/features/waveform/utils/waveformSeekRenderersStatic.ts similarity index 99% rename from src/utils/waveform/waveformSeekRenderersStatic.ts rename to src/features/waveform/utils/waveformSeekRenderersStatic.ts index 63bde758..a0c0ae1b 100644 --- a/src/utils/waveform/waveformSeekRenderersStatic.ts +++ b/src/features/waveform/utils/waveformSeekRenderersStatic.ts @@ -1,7 +1,7 @@ import { BAR_COUNT, SEG_COUNT, getColors, setShadowBlur, setupCanvas, waveformBarThickness, -} from './waveformSeekHelpers'; +} from '@/features/waveform/utils/waveformSeekHelpers'; export function drawWaveform( canvas: HTMLCanvasElement, diff --git a/src/store/applyQueueHistorySnapshot.ts b/src/store/applyQueueHistorySnapshot.ts index c8dc7cc1..33e69c0b 100644 --- a/src/store/applyQueueHistorySnapshot.ts +++ b/src/store/applyQueueHistorySnapshot.ts @@ -20,7 +20,7 @@ import { type QueueUndoSnapshot, } from './queueUndo'; import { refreshLoudnessForTrack } from './loudnessRefresh'; -import { refreshWaveformForTrack } from './waveformRefresh'; +import { refreshWaveformForTrack } from '@/features/waveform'; import { stopRadio } from './radioPlayer'; import { clearAllPlaybackScheduleTimers } from './scheduleTimers'; import { syncUserQueueMutationToServer } from './queueSync'; diff --git a/src/store/applyServerPlayQueue.idle.test.ts b/src/store/applyServerPlayQueue.idle.test.ts index 776cdb4c..0e947ec8 100644 --- a/src/store/applyServerPlayQueue.idle.test.ts +++ b/src/store/applyServerPlayQueue.idle.test.ts @@ -27,7 +27,7 @@ vi.mock('./pausedRestorePrepare', () => ({ preparePausedRestoreOnStartup: vi.fn(), })); -vi.mock('./waveformRefresh', () => ({ +vi.mock('@/features/waveform', () => ({ refreshWaveformForTrack: vi.fn(), })); diff --git a/src/store/applyServerPlayQueue.ts b/src/store/applyServerPlayQueue.ts index d3f9e7a9..c57da047 100644 --- a/src/store/applyServerPlayQueue.ts +++ b/src/store/applyServerPlayQueue.ts @@ -9,7 +9,7 @@ import { useAuthStore } from './authStore'; import { usePlayerStore } from './playerStore'; import { preparePausedRestoreOnStartup } from './pausedRestorePrepare'; import { pushQueueUndoFromGetter } from './queueUndo'; -import { refreshWaveformForTrack } from './waveformRefresh'; +import { refreshWaveformForTrack } from '@/features/waveform'; import { getIdlePullGeneration, isIdleQueuePullSuspended, diff --git a/src/store/audioEventHandlers.ts b/src/store/audioEventHandlers.ts index f85bf46b..104e2964 100644 --- a/src/store/audioEventHandlers.ts +++ b/src/store/audioEventHandlers.ts @@ -87,7 +87,7 @@ import { getSeekTarget, getSeekTargetSetAt, } from './seekTargetState'; -import { refreshWaveformForTrack } from './waveformRefresh'; +import { refreshWaveformForTrack } from '@/features/waveform'; import { analyzeBoundary, computeWaveformSilence } from '../utils/waveform/waveformSilence'; import { autodjMaxOverlapCapSec } from '../utils/playback/autodjOverlapCap'; import { diff --git a/src/store/audioListenerSetup/audioEngineListeners.ts b/src/store/audioListenerSetup/audioEngineListeners.ts index b096b3af..ca14ebc5 100644 --- a/src/store/audioListenerSetup/audioEngineListeners.ts +++ b/src/store/audioListenerSetup/audioEngineListeners.ts @@ -24,8 +24,8 @@ import { markNormalizationUiUpdate, } from '../playbackThrottles'; import { usePlayerStore } from '../playerStore'; -import { refreshWaveformForTrack } from '../waveformRefresh'; -import { bumpWaveformRefreshGen } from '../waveformRefreshGen'; +import { refreshWaveformForTrack } from '@/features/waveform'; +import { bumpWaveformRefreshGen } from '@/features/waveform'; import { setBytePreloadingId } from '../gaplessPreloadState'; type PreloadEventPayload = { diff --git a/src/store/audioListenerSetup/authSyncListener.ts b/src/store/audioListenerSetup/authSyncListener.ts index fad46663..e5145df7 100644 --- a/src/store/audioListenerSetup/authSyncListener.ts +++ b/src/store/audioListenerSetup/authSyncListener.ts @@ -7,8 +7,8 @@ import { invokeAudioSetNormalizationDeduped } from '../normalizationIpcDedupe'; import { usePlayerStore } from '../playerStore'; import { clearLoudnessCacheStateForTrackId } from '../loudnessGainCache'; import { refreshLoudnessForTrack } from '../loudnessRefresh'; -import { refreshWaveformForTrack } from '../waveformRefresh'; -import { bumpWaveformRefreshGen } from '../waveformRefreshGen'; +import { refreshWaveformForTrack } from '@/features/waveform'; +import { bumpWaveformRefreshGen } from '@/features/waveform'; /** * Keeps the Rust audio engine in sync whenever the auth store changes diff --git a/src/store/audioListenerSetup/initialAudioSync.ts b/src/store/audioListenerSetup/initialAudioSync.ts index 497187ec..55758d43 100644 --- a/src/store/audioListenerSetup/initialAudioSync.ts +++ b/src/store/audioListenerSetup/initialAudioSync.ts @@ -5,7 +5,7 @@ import { emitNormalizationDebug } from '../normalizationDebug'; import { invokeAudioSetNormalizationDeduped } from '../normalizationIpcDedupe'; import { usePlayerStore } from '../playerStore'; import { refreshLoudnessForTrack } from '../loudnessRefresh'; -import { refreshWaveformForTrack } from '../waveformRefresh'; +import { refreshWaveformForTrack } from '@/features/waveform'; /** * One-shot startup sync: pushes the persisted audio settings to the Rust engine diff --git a/src/store/crossfadePreload.ts b/src/store/crossfadePreload.ts index 6e2ee6db..045b42ad 100644 --- a/src/store/crossfadePreload.ts +++ b/src/store/crossfadePreload.ts @@ -15,7 +15,7 @@ import { import { getBytePreloadingId, setBytePreloadingId } from './gaplessPreloadState'; import { refreshLoudnessForTrack } from './loudnessRefresh'; import { usePlayerStore } from './playerStore'; -import { fetchWaveformBins } from './waveformRefresh'; +import { fetchWaveformBins } from '@/features/waveform'; // Crossfade pre-buffer budget: begin downloading the next track this many // seconds before it needs to play (the crossfade start), so a large lossless diff --git a/src/store/loudnessReseed.test.ts b/src/store/loudnessReseed.test.ts index b95f4c34..a93d5692 100644 --- a/src/store/loudnessReseed.test.ts +++ b/src/store/loudnessReseed.test.ts @@ -39,7 +39,7 @@ vi.mock('./playerStore', () => ({ setState: hoisted.playerSetStateMock, }, })); -vi.mock('./waveformRefreshGen', () => ({ +vi.mock('@/features/waveform', () => ({ bumpWaveformRefreshGen: hoisted.bumpWaveformRefreshGenMock, })); vi.mock('./loudnessGainCache', () => ({ diff --git a/src/store/loudnessReseed.ts b/src/store/loudnessReseed.ts index a62022fa..9444bf9a 100644 --- a/src/store/loudnessReseed.ts +++ b/src/store/loudnessReseed.ts @@ -3,7 +3,7 @@ import { invoke } from '@tauri-apps/api/core'; import { getPlaybackIndexKey } from '../utils/playback/playbackServer'; import { useAuthStore } from './authStore'; import { usePlayerStore } from './playerStore'; -import { bumpWaveformRefreshGen } from './waveformRefreshGen'; +import { bumpWaveformRefreshGen } from '@/features/waveform'; import { clearLoudnessCacheStateForTrackId } from './loudnessGainCache'; import { resetLoudnessBackfillStateForTrackId } from './loudnessBackfillState'; diff --git a/src/store/playTrackAction.ts b/src/store/playTrackAction.ts index f1bef9e9..3a0adc95 100644 --- a/src/store/playTrackAction.ts +++ b/src/store/playTrackAction.ts @@ -51,7 +51,7 @@ import { loudnessGainDbForEngineBind, } from './loudnessGainCache'; import { refreshLoudnessForTrack } from './loudnessRefresh'; -import { fetchWaveformBins, refreshWaveformForTrack } from './waveformRefresh'; +import { fetchWaveformBins, refreshWaveformForTrack } from '@/features/waveform'; import { deriveNormalizationSnapshot } from './normalizationSnapshot'; import { useOrbitStore } from './orbitStore'; import { diff --git a/src/store/transportLightActions.ts b/src/store/transportLightActions.ts index 0472c4a9..16c02cea 100644 --- a/src/store/transportLightActions.ts +++ b/src/store/transportLightActions.ts @@ -11,7 +11,7 @@ import { clearSeekDebounce } from './seekDebounce'; import { clearSeekFallbackRetry } from './seekFallbackState'; import { clearSeekTarget } from './seekTargetState'; import { tryAcquireTogglePlayLock } from './togglePlayLock'; -import { refreshWaveformForTrack } from './waveformRefresh'; +import { refreshWaveformForTrack } from '@/features/waveform'; import { clearAutodjTransitionUi } from './autodjTransitionUi'; type SetState = (