From 695462ed87224d563d0ccece4d005aa0eb5bed21 Mon Sep 17 00:00:00 2001 From: Psychotoxical <171614930+Psychotoxical@users.noreply.github.com> Date: Tue, 30 Jun 2026 20:21:15 +0200 Subject: [PATCH] refactor(cover,lib): fold utils/cover into cover/ + utils/media into lib/media (generic infra) --- src/{utils => }/cover/coverArtRegisteredSizes.test.ts | 2 +- src/{utils => }/cover/coverArtRegisteredSizes.ts | 0 src/{utils => }/cover/coverBlobDownscale.ts | 0 src/cover/resolveJs.ts | 2 +- src/features/offline/pages/OfflineLibrary.tsx | 2 +- src/features/offline/store/offlineStore.ts | 2 +- src/features/offline/utils/favoritesOfflineSync.ts | 2 +- src/features/offline/utils/legacyOfflineFileMigration.ts | 2 +- src/features/offline/utils/libraryTierReconcile.ts | 2 +- src/features/offline/utils/pinnedOfflineSync.ts | 2 +- src/features/playback/store/hotCacheStore.ts | 2 +- src/features/playback/store/promoteStreamCache.test.ts | 2 +- src/features/playback/store/promoteStreamCache.ts | 2 +- src/hotCachePrefetch.ts | 2 +- src/{utils => lib}/media/mediaDir.ts | 2 +- src/{utils => lib}/media/mediaLayout.test.ts | 2 +- src/{utils => lib}/media/mediaLayout.ts | 0 src/localPlaybackInvalidation.ts | 4 ++-- src/utils/cache/ephemeralTierReconcile.ts | 2 +- src/utils/imageCache.ts | 2 +- src/utils/imageCache/coverSiblings.ts | 2 +- src/utils/migrations/coverIdbUpgradeMigration.ts | 2 +- 22 files changed, 20 insertions(+), 20 deletions(-) rename src/{utils => }/cover/coverArtRegisteredSizes.test.ts (94%) rename src/{utils => }/cover/coverArtRegisteredSizes.ts (100%) rename src/{utils => }/cover/coverBlobDownscale.ts (100%) rename src/{utils => lib}/media/mediaDir.ts (79%) rename src/{utils => lib}/media/mediaLayout.test.ts (97%) rename src/{utils => lib}/media/mediaLayout.ts (100%) diff --git a/src/utils/cover/coverArtRegisteredSizes.test.ts b/src/cover/coverArtRegisteredSizes.test.ts similarity index 94% rename from src/utils/cover/coverArtRegisteredSizes.test.ts rename to src/cover/coverArtRegisteredSizes.test.ts index f0d9a9fa..151837cc 100644 --- a/src/utils/cover/coverArtRegisteredSizes.test.ts +++ b/src/cover/coverArtRegisteredSizes.test.ts @@ -1,7 +1,7 @@ import { readFileSync, readdirSync } from 'node:fs'; import { join } from 'node:path'; import { describe, it } from 'vitest'; -import { COVER_ART_REGISTERED_SIZES } from './coverArtRegisteredSizes'; +import { COVER_ART_REGISTERED_SIZES } from '@/cover/coverArtRegisteredSizes'; const registry = new Set(COVER_ART_REGISTERED_SIZES); diff --git a/src/utils/cover/coverArtRegisteredSizes.ts b/src/cover/coverArtRegisteredSizes.ts similarity index 100% rename from src/utils/cover/coverArtRegisteredSizes.ts rename to src/cover/coverArtRegisteredSizes.ts diff --git a/src/utils/cover/coverBlobDownscale.ts b/src/cover/coverBlobDownscale.ts similarity index 100% rename from src/utils/cover/coverBlobDownscale.ts rename to src/cover/coverBlobDownscale.ts diff --git a/src/cover/resolveJs.ts b/src/cover/resolveJs.ts index 382cde9f..c0c254e7 100644 --- a/src/cover/resolveJs.ts +++ b/src/cover/resolveJs.ts @@ -8,7 +8,7 @@ import { scheduleSiblingVersusNetworkRace, } from '../utils/imageCache/coverSiblings'; import { blobCache } from '../utils/imageCache/blobCache'; -import { downscaleCoverBlob } from '../utils/cover/coverBlobDownscale'; +import { downscaleCoverBlob } from '@/cover/coverBlobDownscale'; import { rememberBlob } from '../utils/imageCache/blobCache'; import { putBlob } from '../utils/imageCache/idbStore'; import { buildCoverArtFetchUrl } from './fetchUrl'; diff --git a/src/features/offline/pages/OfflineLibrary.tsx b/src/features/offline/pages/OfflineLibrary.tsx index 886206ff..d025daac 100644 --- a/src/features/offline/pages/OfflineLibrary.tsx +++ b/src/features/offline/pages/OfflineLibrary.tsx @@ -34,7 +34,7 @@ import { } from '@/features/offline/utils/offlineLibraryHelpers'; import { showToast } from '@/utils/ui/toast'; import { shuffleArray } from '@/lib/util/shuffleArray'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { canonicalQueueServerKey, resolveIndexKey } from '@/utils/server/serverIndexKey'; import { reconcileAllLibraryTiersFromDisk } from '@/features/offline/utils/libraryTierReconcile'; import { diff --git a/src/features/offline/store/offlineStore.ts b/src/features/offline/store/offlineStore.ts index c53a773b..1c7f5e6a 100644 --- a/src/features/offline/store/offlineStore.ts +++ b/src/features/offline/store/offlineStore.ts @@ -10,7 +10,7 @@ import { useAuthStore } from '@/store/authStore'; import { showToast } from '@/utils/ui/toast'; import { useOfflineJobStore, cancelledDownloads } from '@/features/offline/store/offlineJobStore'; import { useLocalPlaybackStore, type PinSource } from '@/store/localPlaybackStore'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { findLocalPlaybackEntry } from '@/store/localPlaybackResolve'; import { isOfflinePinComplete, diff --git a/src/features/offline/utils/favoritesOfflineSync.ts b/src/features/offline/utils/favoritesOfflineSync.ts index 79b33d1f..828b0dff 100644 --- a/src/features/offline/utils/favoritesOfflineSync.ts +++ b/src/features/offline/utils/favoritesOfflineSync.ts @@ -11,7 +11,7 @@ import { useAuthStore } from '@/store/authStore'; import { cancelledDownloads, useOfflineJobStore } from '@/features/offline/store/offlineJobStore'; import { useFavoritesOfflineSyncStore } from '@/features/offline/store/favoritesOfflineSyncStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { resolveIndexKey, serverIndexKeyForProfile } from '@/utils/server/serverIndexKey'; import { FAVORITES_OFFLINE_JOB_ID } from '@/features/offline/utils/favoritesOfflineConstants'; import { isActiveServerReachable } from '@/utils/network/activeServerReachability'; diff --git a/src/features/offline/utils/legacyOfflineFileMigration.ts b/src/features/offline/utils/legacyOfflineFileMigration.ts index 57fb8f01..7819e2b9 100644 --- a/src/features/offline/utils/legacyOfflineFileMigration.ts +++ b/src/features/offline/utils/legacyOfflineFileMigration.ts @@ -5,7 +5,7 @@ import { useOfflineStore, type OfflineAlbumMeta } from '@/features/offline/store import { useLocalPlaybackStore, type LocalPlaybackEntry, type PinSource } from '@/store/localPlaybackStore'; import { localPlaybackEntryKey } from '@/store/localPlaybackKeys'; import { importLegacyLocalPlayback } from '@/store/localPlaybackMigration'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { resolveServerIdForIndexKey } from '@/utils/server/serverLookup'; import { resolveIndexKey } from '@/utils/server/serverIndexKey'; diff --git a/src/features/offline/utils/libraryTierReconcile.ts b/src/features/offline/utils/libraryTierReconcile.ts index e7361b6f..3b8ba469 100644 --- a/src/features/offline/utils/libraryTierReconcile.ts +++ b/src/features/offline/utils/libraryTierReconcile.ts @@ -5,7 +5,7 @@ import { invoke } from '@tauri-apps/api/core'; import { useAuthStore } from '@/store/authStore'; import type { LocalPlaybackEntry, PinSource } from '@/store/localPlaybackStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { resolveIndexKey, serverIndexKeyForProfile } from '@/utils/server/serverIndexKey'; import { entryBelongsToServer, diff --git a/src/features/offline/utils/pinnedOfflineSync.ts b/src/features/offline/utils/pinnedOfflineSync.ts index bb73c06d..1ec322f1 100644 --- a/src/features/offline/utils/pinnedOfflineSync.ts +++ b/src/features/offline/utils/pinnedOfflineSync.ts @@ -10,7 +10,7 @@ import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; import { useOfflineStore } from '@/features/offline/store/offlineStore'; import { usePlaylistStore } from '@/features/playlist'; import { isSmartPlaylistName } from '@/utils/componentHelpers/playlistDetailHelpers'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { isActiveServerReachable, onActiveServerBecameReachable, diff --git a/src/features/playback/store/hotCacheStore.ts b/src/features/playback/store/hotCacheStore.ts index 05064ebc..475e368b 100644 --- a/src/features/playback/store/hotCacheStore.ts +++ b/src/features/playback/store/hotCacheStore.ts @@ -4,7 +4,7 @@ import type { HotCacheEntry } from '@/features/playback/store/hotCacheStoreTypes import { useLocalPlaybackStore, type LocalPlaybackEntry } from '@/store/localPlaybackStore'; import { entryBelongsToServer } from '@/store/localPlaybackResolve'; import { invoke } from '@tauri-apps/api/core'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; export type { HotCacheEntry } from '@/features/playback/store/hotCacheStoreTypes'; /** @deprecated Use {@link LOCAL_PLAYBACK_PROTECT_AFTER_CURRENT}. */ diff --git a/src/features/playback/store/promoteStreamCache.test.ts b/src/features/playback/store/promoteStreamCache.test.ts index dc2b8371..9b73f90d 100644 --- a/src/features/playback/store/promoteStreamCache.test.ts +++ b/src/features/playback/store/promoteStreamCache.test.ts @@ -14,7 +14,7 @@ vi.mock('@/features/playback/store/hotCacheStore', () => ({ }, })); -vi.mock('@/utils/media/mediaDir', () => ({ +vi.mock('@/lib/media/mediaDir', () => ({ getMediaDir: () => '/media', })); diff --git a/src/features/playback/store/promoteStreamCache.ts b/src/features/playback/store/promoteStreamCache.ts index 64d742cc..d35e2308 100644 --- a/src/features/playback/store/promoteStreamCache.ts +++ b/src/features/playback/store/promoteStreamCache.ts @@ -2,7 +2,7 @@ import { buildStreamUrlForServer } from '@/lib/api/subsonicStreamUrl'; import type { Track } from '@/lib/media/trackTypes'; import { invoke } from '@tauri-apps/api/core'; import { useHotCacheStore } from '@/features/playback/store/hotCacheStore'; -import { getMediaDir } from '@/utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { librarySqlServerId } from '@/api/coverCache'; import { hasLocalPersistentPlaybackBytes } from '@/store/localPlaybackResolve'; diff --git a/src/hotCachePrefetch.ts b/src/hotCachePrefetch.ts index 45e9d7ba..b4ef784b 100644 --- a/src/hotCachePrefetch.ts +++ b/src/hotCachePrefetch.ts @@ -6,7 +6,7 @@ import { invoke } from '@tauri-apps/api/core'; import { useAuthStore } from './store/authStore'; import { selectHotCacheEntries, useHotCacheStore } from '@/features/playback/store/hotCacheStore'; import { useLocalPlaybackStore } from './store/localPlaybackStore'; -import { getMediaDir } from './utils/media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { librarySqlServerId } from './api/coverCache'; import { usePlayerStore } from '@/features/playback/store/playerStore'; import { diff --git a/src/utils/media/mediaDir.ts b/src/lib/media/mediaDir.ts similarity index 79% rename from src/utils/media/mediaDir.ts rename to src/lib/media/mediaDir.ts index eb0ed4b5..8a5d36f9 100644 --- a/src/utils/media/mediaDir.ts +++ b/src/lib/media/mediaDir.ts @@ -1,4 +1,4 @@ -import { useAuthStore } from '../../store/authStore'; +import { useAuthStore } from '@/store/authStore'; /** Resolved user media root `M` (empty → Rust default `{app_data}/media/`). */ export function getMediaDir(): string | null { diff --git a/src/utils/media/mediaLayout.test.ts b/src/lib/media/mediaLayout.test.ts similarity index 97% rename from src/utils/media/mediaLayout.test.ts rename to src/lib/media/mediaLayout.test.ts index 28c667cf..40f39af4 100644 --- a/src/utils/media/mediaLayout.test.ts +++ b/src/lib/media/mediaLayout.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { layoutFingerprintFromLibraryTrack, sanitizeAndTruncateSegment } from './mediaLayout'; +import { layoutFingerprintFromLibraryTrack, sanitizeAndTruncateSegment } from '@/lib/media/mediaLayout'; // Keep in sync with `short_hash` in `src-tauri/crates/psysonic-core/src/media_layout.rs`. function shortHash(s: string): string { diff --git a/src/utils/media/mediaLayout.ts b/src/lib/media/mediaLayout.ts similarity index 100% rename from src/utils/media/mediaLayout.ts rename to src/lib/media/mediaLayout.ts diff --git a/src/localPlaybackInvalidation.ts b/src/localPlaybackInvalidation.ts index 436e30e0..0be6b895 100644 --- a/src/localPlaybackInvalidation.ts +++ b/src/localPlaybackInvalidation.ts @@ -3,8 +3,8 @@ import { invoke } from '@tauri-apps/api/core'; import { libraryGetTrack } from '@/lib/api/library'; import { useAuthStore } from './store/authStore'; import { useLocalPlaybackStore } from './store/localPlaybackStore'; -import { layoutFingerprintFromLibraryTrack } from './utils/media/mediaLayout'; -import { getMediaDir } from './utils/media/mediaDir'; +import { layoutFingerprintFromLibraryTrack } from '@/lib/media/mediaLayout'; +import { getMediaDir } from '@/lib/media/mediaDir'; import { runLegacyOfflineFileMigration } from '@/features/offline'; import { reconcileLibraryTierForServer } from '@/features/offline'; import { resolveServerIdForIndexKey } from './utils/server/serverLookup'; diff --git a/src/utils/cache/ephemeralTierReconcile.ts b/src/utils/cache/ephemeralTierReconcile.ts index d5d60a83..00c6164d 100644 --- a/src/utils/cache/ephemeralTierReconcile.ts +++ b/src/utils/cache/ephemeralTierReconcile.ts @@ -1,7 +1,7 @@ import { invoke } from '@tauri-apps/api/core'; import { useLocalPlaybackStore } from '../../store/localPlaybackStore'; import { parseLocalPlaybackEntryKey } from '../../store/localPlaybackKeys'; -import { getMediaDir } from '../media/mediaDir'; +import { getMediaDir } from '@/lib/media/mediaDir'; export interface EphemeralReconcileResult { removedStaleIndex: number; diff --git a/src/utils/imageCache.ts b/src/utils/imageCache.ts index 92d95a15..7ecc6f9f 100644 --- a/src/utils/imageCache.ts +++ b/src/utils/imageCache.ts @@ -2,7 +2,7 @@ // `imageCache/`; this file keeps the orchestration entry points and re-exports // the public surface so existing call sites import from `imageCache` unchanged. import { useAuthStore } from '../store/authStore'; -import { COVER_ART_REGISTERED_SIZES } from './cover/coverArtRegisteredSizes'; +import { COVER_ART_REGISTERED_SIZES } from '@/cover/coverArtRegisteredSizes'; import { STORE_NAME } from './imageCache/constants'; import { blobCache, inflightBlobGets, rememberBlob } from './imageCache/blobCache'; import { purgeUrlEntry, clearAllUrlEntries } from './imageCache/urlPool'; diff --git a/src/utils/imageCache/coverSiblings.ts b/src/utils/imageCache/coverSiblings.ts index adb9d3e6..7998f203 100644 --- a/src/utils/imageCache/coverSiblings.ts +++ b/src/utils/imageCache/coverSiblings.ts @@ -2,7 +2,7 @@ import { COVER_ART_TIERS } from '../../cover/tiers'; /** Tier ladder for sibling probe (exclude on-demand 2000). */ const COVER_SIBLING_TIERS = COVER_ART_TIERS.filter(t => t !== 2000); -import { downscaleCoverBlob } from '../cover/coverBlobDownscale'; +import { downscaleCoverBlob } from '@/cover/coverBlobDownscale'; import { blobCache, rememberBlob } from './blobCache'; import { purgeUrlEntry } from './urlPool'; import { mapBlobsFromIDB, putBlob } from './idbStore'; diff --git a/src/utils/migrations/coverIdbUpgradeMigration.ts b/src/utils/migrations/coverIdbUpgradeMigration.ts index 907b0e3f..e4948239 100644 --- a/src/utils/migrations/coverIdbUpgradeMigration.ts +++ b/src/utils/migrations/coverIdbUpgradeMigration.ts @@ -1,5 +1,5 @@ import { COVER_ART_TIERS } from '../../cover/tiers'; -import { COVER_ART_REGISTERED_SIZES } from '../cover/coverArtRegisteredSizes'; +import { COVER_ART_REGISTERED_SIZES } from '@/cover/coverArtRegisteredSizes'; import { invalidateCacheKey } from '../imageCache'; import { STORE_NAME } from '../imageCache/constants'; import { openDB } from '../imageCache/idbStore';