diff --git a/src/app/migrations/coverIdbUpgradeMigration.ts b/src/app/migrations/coverIdbUpgradeMigration.ts index a08b1eb3..fa7f7c0a 100644 --- a/src/app/migrations/coverIdbUpgradeMigration.ts +++ b/src/app/migrations/coverIdbUpgradeMigration.ts @@ -1,8 +1,6 @@ import { COVER_ART_TIERS } from '@/cover/tiers'; import { COVER_ART_REGISTERED_SIZES } from '@/cover/coverArtRegisteredSizes'; -import { invalidateCacheKey } from '@/utils/imageCache'; -import { STORE_NAME } from '@/utils/imageCache/constants'; -import { openDB } from '@/utils/imageCache/idbStore'; +import { invalidateCacheKey, STORE_NAME, openDB } from '@/cover'; const MIGRATION_FLAG = 'psysonic_cover_tier_idb_cleared_v1'; diff --git a/src/app/tauriBridge/useCoverArtBridge.ts b/src/app/tauriBridge/useCoverArtBridge.ts index dc188afe..ba6ca666 100644 --- a/src/app/tauriBridge/useCoverArtBridge.ts +++ b/src/app/tauriBridge/useCoverArtBridge.ts @@ -7,7 +7,7 @@ import { } from '@/cover/diskSrcCache'; import { rememberDiskSrcLadder } from '@/cover/diskSrcLookup'; import { notifyCoverDiskReady } from '@/cover/diskHandoff'; -import { invalidateCacheKey } from '@/utils/imageCache'; +import { invalidateCacheKey } from '@/cover'; import { COVER_ART_TIERS } from '@/cover/tiers'; import type { CoverArtTier, CoverCacheKind } from '@/cover/types'; diff --git a/src/utils/imageCache.ts b/src/cover/imageCache.ts similarity index 100% rename from src/utils/imageCache.ts rename to src/cover/imageCache.ts diff --git a/src/utils/imageCache/blobCache.ts b/src/cover/imageCache/blobCache.ts similarity index 100% rename from src/utils/imageCache/blobCache.ts rename to src/cover/imageCache/blobCache.ts diff --git a/src/utils/imageCache/constants.ts b/src/cover/imageCache/constants.ts similarity index 100% rename from src/utils/imageCache/constants.ts rename to src/cover/imageCache/constants.ts diff --git a/src/utils/imageCache/coverSiblings.ts b/src/cover/imageCache/coverSiblings.ts similarity index 100% rename from src/utils/imageCache/coverSiblings.ts rename to src/cover/imageCache/coverSiblings.ts diff --git a/src/utils/imageCache/idbStore.ts b/src/cover/imageCache/idbStore.ts similarity index 100% rename from src/utils/imageCache/idbStore.ts rename to src/cover/imageCache/idbStore.ts diff --git a/src/utils/imageCache/netFetchScheduler.ts b/src/cover/imageCache/netFetchScheduler.ts similarity index 100% rename from src/utils/imageCache/netFetchScheduler.ts rename to src/cover/imageCache/netFetchScheduler.ts diff --git a/src/utils/imageCache/urlPool.ts b/src/cover/imageCache/urlPool.ts similarity index 100% rename from src/utils/imageCache/urlPool.ts rename to src/cover/imageCache/urlPool.ts diff --git a/src/cover/index.ts b/src/cover/index.ts index 3b810f89..1f3b5639 100644 --- a/src/cover/index.ts +++ b/src/cover/index.ts @@ -57,3 +57,15 @@ export { coverIndexKeyFromScope, coverIndexKeyFromRef, } from './storageKeys'; +export { + acquireUrl, + releaseUrl, + getCachedBlob, + getImageCacheSize, + subscribeCoverUpgraded, + invalidateCacheKey, + invalidateCoverArt, + clearImageCache, +} from './imageCache'; +export { STORE_NAME } from './imageCache/constants'; +export { openDB } from './imageCache/idbStore'; diff --git a/src/cover/resolveDisk.test.ts b/src/cover/resolveDisk.test.ts index c0843f35..0326ea2c 100644 --- a/src/cover/resolveDisk.test.ts +++ b/src/cover/resolveDisk.test.ts @@ -3,7 +3,7 @@ import { albumCoverRef } from './ref'; vi.mock('@tauri-apps/api/core', () => ({ isTauri: () => true })); vi.mock('../api/coverCache', () => ({ coverCacheEnsure: vi.fn() })); -vi.mock('../utils/imageCache', () => ({ invalidateCacheKey: vi.fn() })); +vi.mock('./imageCache', () => ({ invalidateCacheKey: vi.fn() })); vi.mock('./diskSrcCache', () => ({ getDiskSrc: vi.fn(() => ''), rememberDiskSrc: vi.fn((_key: string, path: string) => `asset://${path}`), diff --git a/src/cover/resolveDisk.ts b/src/cover/resolveDisk.ts index 822fcf08..7944fa90 100644 --- a/src/cover/resolveDisk.ts +++ b/src/cover/resolveDisk.ts @@ -1,6 +1,6 @@ import { isTauri } from '@tauri-apps/api/core'; import { coverCacheEnsure } from '../api/coverCache'; -import { invalidateCacheKey } from '../utils/imageCache'; +import { invalidateCacheKey } from './imageCache'; import { getDiskSrc, rememberDiskSrc } from './diskSrcCache'; import { coverStorageKeyFromRef } from './storageKeys'; import type { CoverArtRef, CoverArtTier } from './types'; diff --git a/src/cover/resolveJs.test.ts b/src/cover/resolveJs.test.ts index 041633f6..170a7e11 100644 --- a/src/cover/resolveJs.test.ts +++ b/src/cover/resolveJs.test.ts @@ -2,11 +2,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { ensureCoverTierJs } from './resolveJs'; import type { CoverArtRef } from './types'; -vi.mock('../utils/imageCache', () => ({ +vi.mock('./imageCache', () => ({ getCachedBlob: vi.fn(async () => new Blob(['x'], { type: 'image/jpeg' })), })); -vi.mock('../utils/imageCache/coverSiblings', () => ({ +vi.mock('./imageCache/coverSiblings', () => ({ parseCoverCacheKey: (key: string) => { const m = key.match(/^(.+):cover:(.+):(.+):(\d+)$/); if (!m) return null; @@ -18,14 +18,14 @@ vi.mock('../utils/imageCache/coverSiblings', () => ({ })); const { blobMap } = vi.hoisted(() => ({ blobMap: new Map() })); -vi.mock('../utils/imageCache/blobCache', () => ({ +vi.mock('./imageCache/blobCache', () => ({ blobCache: blobMap, rememberBlob: (key: string, blob: Blob) => { blobMap.set(key, blob); }, })); -vi.mock('../utils/imageCache/idbStore', () => ({ +vi.mock('./imageCache/idbStore', () => ({ putBlob: vi.fn(), })); @@ -54,7 +54,7 @@ describe('ensureCoverTierJs', () => { }); it('fetches via getCachedBlob on cold path', async () => { - const { getCachedBlob } = await import('../utils/imageCache'); + const { getCachedBlob } = await import('./imageCache'); vi.mocked(getCachedBlob).mockImplementation(async (_url, key) => { const b = new Blob(['x'], { type: 'image/jpeg' }); blobMap.set(key, b); diff --git a/src/cover/resolveJs.ts b/src/cover/resolveJs.ts index c0c254e7..ca9d5392 100644 --- a/src/cover/resolveJs.ts +++ b/src/cover/resolveJs.ts @@ -1,16 +1,16 @@ import { isTauri } from '@tauri-apps/api/core'; -import { getCachedBlob } from '../utils/imageCache'; +import { getCachedBlob } from './imageCache'; import { ensureCoverTierDiskBlob } from './resolveDisk'; import { parseCoverCacheKey, probeSiblingCoverBlobFromIDB, probeSiblingCoverBlobInMemory, scheduleSiblingVersusNetworkRace, -} from '../utils/imageCache/coverSiblings'; -import { blobCache } from '../utils/imageCache/blobCache'; +} from './imageCache/coverSiblings'; +import { blobCache } from './imageCache/blobCache'; import { downscaleCoverBlob } from '@/cover/coverBlobDownscale'; -import { rememberBlob } from '../utils/imageCache/blobCache'; -import { putBlob } from '../utils/imageCache/idbStore'; +import { rememberBlob } from './imageCache/blobCache'; +import { putBlob } from './imageCache/idbStore'; import { buildCoverArtFetchUrl } from './fetchUrl'; import { coverServerReachable } from './reachability'; import { coverStorageKeyFromRef } from './storageKeys'; diff --git a/src/features/album/components/AlbumCard.tsx b/src/features/album/components/AlbumCard.tsx index 34eb3ee4..db944df0 100644 --- a/src/features/album/components/AlbumCard.tsx +++ b/src/features/album/components/AlbumCard.tsx @@ -14,7 +14,7 @@ import { coverStorageKeyFromRef } from '@/cover/storageKeys'; import type { CoverPrefetchPriority } from '@/cover/types'; import { COVER_DENSE_GRID_MIN_CELL_CSS_PX } from '@/cover/layoutSizes'; import { resolveCoverDisplayTier } from '@/cover/tiers'; -import { acquireUrl } from '@/utils/imageCache/urlPool'; +import { acquireUrl } from '@/cover'; import { OpenArtistRefInline } from '@/features/artist'; import { fetchAlbumTracks, playAlbum, playAlbumShuffled } from '@/features/playback/utils/playback/playAlbum'; import { useLongPressAction } from '@/lib/hooks/useLongPressAction'; diff --git a/src/features/artist/utils/runArtistDetailActions.ts b/src/features/artist/utils/runArtistDetailActions.ts index 63ef4324..61450860 100644 --- a/src/features/artist/utils/runArtistDetailActions.ts +++ b/src/features/artist/utils/runArtistDetailActions.ts @@ -5,7 +5,7 @@ import { setRating, star, unstar } from '@/lib/api/subsonicStarRating'; import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { copyEntityShareLink } from '@/lib/share/copyEntityShareLink'; -import { invalidateCoverArt } from '@/utils/imageCache'; +import { invalidateCoverArt } from '@/cover'; import { showToast } from '@/lib/dom/toast'; export interface RunArtistEntityRatingDeps { diff --git a/src/features/radio/pages/InternetRadio.tsx b/src/features/radio/pages/InternetRadio.tsx index b2e9b56e..ba7b98aa 100644 --- a/src/features/radio/pages/InternetRadio.tsx +++ b/src/features/radio/pages/InternetRadio.tsx @@ -5,7 +5,7 @@ import { Plus, Search } from 'lucide-react'; import { usePlayerStore } from '@/features/playback/store/playerStore'; import { setRadioVolume } from '@/features/playback/store/radioPlayer'; import { fadeOut } from '@/features/playback/utils/playback/fadeOut'; -import { invalidateCoverArt } from '@/utils/imageCache'; +import { invalidateCoverArt } from '@/cover'; import { useTranslation } from 'react-i18next'; import { showToast } from '@/lib/dom/toast'; import RadioToolbar from '@/features/radio/components/RadioToolbar'; diff --git a/src/features/settings/components/CoverCacheStrategySection.tsx b/src/features/settings/components/CoverCacheStrategySection.tsx index ae0c0d91..f82451fa 100644 --- a/src/features/settings/components/CoverCacheStrategySection.tsx +++ b/src/features/settings/components/CoverCacheStrategySection.tsx @@ -18,7 +18,7 @@ import { serverListDisplayLabel } from '@/lib/server/serverDisplayName'; import { serverIndexKeyForProfile } from '@/lib/server/serverIndexKey'; import { showToast } from '@/lib/dom/toast'; import { formatBytes } from '@/lib/format/formatBytes'; -import { clearImageCache, getImageCacheSize } from '@/utils/imageCache'; +import { clearImageCache, getImageCacheSize } from '@/cover'; import { wakeLibraryCoverBackfill } from '@/lib/library/coverBackfillWake'; import { COVER_CACHE_STRATEGIES, diff --git a/src/ui/CachedImage.tsx b/src/ui/CachedImage.tsx index 23ccea06..8942a8dd 100644 --- a/src/ui/CachedImage.tsx +++ b/src/ui/CachedImage.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; -import { acquireUrl, getCachedBlob, releaseUrl, subscribeCoverUpgraded } from '@/utils/imageCache'; +import { acquireUrl, getCachedBlob, releaseUrl, subscribeCoverUpgraded } from '@/cover'; import { resolveIntersectionScrollRoot } from '@/lib/dom/resolveIntersectionScrollRoot'; interface CachedImageProps extends React.ImgHTMLAttributes {