diff --git a/src/api/coverCache.ts b/src/api/coverCache.ts index 345f34a0..7d2d21db 100644 --- a/src/api/coverCache.ts +++ b/src/api/coverCache.ts @@ -5,7 +5,7 @@ import { coverIndexKeyFromRef, coverStorageKeyFromRef } from '../cover/storageKe import { connectBaseUrlForServer } from '../utils/server/serverEndpoint'; import { serverIndexKeyForProfile } from '../utils/server/serverIndexKey'; import { getPlaybackServerId } from '../utils/playback/playbackServer'; -import { restBaseFromUrl } from './subsonicClient'; +import { restBaseFromUrl } from '@/lib/api/subsonicClient'; import type { CoverArtRef, CoverArtTier } from '../cover/types'; /** Library SQLite `track.server_id` uses host index keys, not auth profile UUIDs. */ diff --git a/src/components/BecauseYouLikeRail.tsx b/src/components/BecauseYouLikeRail.tsx index f6d4f989..59dc5a1c 100644 --- a/src/components/BecauseYouLikeRail.tsx +++ b/src/components/BecauseYouLikeRail.tsx @@ -1,7 +1,7 @@ import { getArtist, getArtistInfo } from '@/features/artist'; -import { filterAlbumsToActiveLibrary } from '../api/subsonicLibrary'; +import { filterAlbumsToActiveLibrary } from '@/lib/api/subsonicLibrary'; import { resolveAlbum, resolveMediaServerId } from '@/features/offline'; -import type { SubsonicAlbum } from '../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../utils/playback/songToTrack'; import { shuffleArray } from '../utils/playback/shuffleArray'; import React, { memo, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; diff --git a/src/components/ContextMenu.test.tsx b/src/components/ContextMenu.test.tsx index 524d0680..71bbaa4a 100644 --- a/src/components/ContextMenu.test.tsx +++ b/src/components/ContextMenu.test.tsx @@ -9,7 +9,7 @@ import type { ServerProfile } from '@/store/authStoreTypes'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), diff --git a/src/components/GenreFilterBar.tsx b/src/components/GenreFilterBar.tsx index 876382b3..dbf567c9 100644 --- a/src/components/GenreFilterBar.tsx +++ b/src/components/GenreFilterBar.tsx @@ -1,4 +1,4 @@ -import { getGenres } from '../api/subsonicGenres'; +import { getGenres } from '@/lib/api/subsonicGenres'; import type { GenreFilterOption } from '../utils/library/albumBrowseLoad'; import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx index 0760ea57..060667fe 100644 --- a/src/components/Hero.tsx +++ b/src/components/Hero.tsx @@ -1,6 +1,6 @@ -import { getRandomAlbums } from '../api/subsonicLibrary'; +import { getRandomAlbums } from '@/lib/api/subsonicLibrary'; import { resolveAlbum, resolveMediaServerId } from '@/features/offline'; -import type { SubsonicAlbum } from '../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../utils/playback/songToTrack'; import React, { useEffect, useState, useRef, useCallback, useMemo } from 'react'; import { useNavigateToAlbum } from '@/features/album'; diff --git a/src/components/HostApprovalQueue.tsx b/src/components/HostApprovalQueue.tsx index d1c26efa..11d639fa 100644 --- a/src/components/HostApprovalQueue.tsx +++ b/src/components/HostApprovalQueue.tsx @@ -1,5 +1,5 @@ -import { getSong } from '../api/subsonicLibrary'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import { getSong } from '@/lib/api/subsonicLibrary'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useEffect, useMemo, useState } from 'react'; import { Check, X, Inbox } from 'lucide-react'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/PagedSongList.tsx b/src/components/PagedSongList.tsx index 1f9cf8c4..d4984581 100644 --- a/src/components/PagedSongList.tsx +++ b/src/components/PagedSongList.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useRef } from 'react'; import SongRow, { SongListHeader } from './SongRow'; import { useInpageScrollSentinel } from '../hooks/useInpageScrollSentinel'; diff --git a/src/components/PlayerBar.test.tsx b/src/components/PlayerBar.test.tsx index 6b3c020b..1d516636 100644 --- a/src/components/PlayerBar.test.tsx +++ b/src/components/PlayerBar.test.tsx @@ -7,7 +7,7 @@ */ import { beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), pingWithCredentials: vi.fn(async () => ({ diff --git a/src/components/QueuePanel.test.tsx b/src/components/QueuePanel.test.tsx index 45e88ec3..2d7badda 100644 --- a/src/components/QueuePanel.test.tsx +++ b/src/components/QueuePanel.test.tsx @@ -9,7 +9,7 @@ */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), diff --git a/src/components/SongCard.test.tsx b/src/components/SongCard.test.tsx index 1c40dd69..9178ef9c 100644 --- a/src/components/SongCard.test.tsx +++ b/src/components/SongCard.test.tsx @@ -3,7 +3,7 @@ import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { renderWithProviders } from '../test/helpers/renderWithProviders'; import SongCard from './SongCard'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; const navigateToArtist = vi.fn(); diff --git a/src/components/SongCard.tsx b/src/components/SongCard.tsx index 8e9f0579..59dc1609 100644 --- a/src/components/SongCard.tsx +++ b/src/components/SongCard.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../utils/playback/songToTrack'; import React, { memo, useMemo } from 'react'; import { Play, ListPlus, Star, Disc3 } from 'lucide-react'; diff --git a/src/components/SongInfoModal.tsx b/src/components/SongInfoModal.tsx index d2e2ce4a..5d8b3624 100644 --- a/src/components/SongInfoModal.tsx +++ b/src/components/SongInfoModal.tsx @@ -1,12 +1,12 @@ -import { getSong } from '../api/subsonicLibrary'; -import { libraryGetFacts } from '../api/library'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import { getSong } from '@/lib/api/subsonicLibrary'; +import { libraryGetFacts } from '@/lib/api/library'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import { X } from 'lucide-react'; import { usePlayerStore } from '../store/playerStore'; import { useShallow } from 'zustand/react/shallow'; -import { ndGetSongPath } from '../api/navidromeAdmin'; +import { ndGetSongPath } from '@/lib/api/navidromeAdmin'; import { useAuthStore } from '../store/authStore'; import { useLibraryIndexStore } from '../store/libraryIndexStore'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/SongRail.tsx b/src/components/SongRail.tsx index 9171747c..f74ef929 100644 --- a/src/components/SongRail.tsx +++ b/src/components/SongRail.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useRef, useState, useEffect, useMemo } from 'react'; import { ChevronLeft, ChevronRight, RefreshCw } from 'lucide-react'; import SongCard from './SongCard'; diff --git a/src/components/SongRow.tsx b/src/components/SongRow.tsx index b23b2c52..45919f8d 100644 --- a/src/components/SongRow.tsx +++ b/src/components/SongRow.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../utils/playback/songToTrack'; import React, { memo } from 'react'; import { useNavigateToAlbum } from '@/features/album'; diff --git a/src/components/contextMenu/AddToPlaylistSubmenu.tsx b/src/components/contextMenu/AddToPlaylistSubmenu.tsx index a20cf97b..b8a2b7a6 100644 --- a/src/components/contextMenu/AddToPlaylistSubmenu.tsx +++ b/src/components/contextMenu/AddToPlaylistSubmenu.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 're import { useTranslation } from 'react-i18next'; import { ListMusic, Plus } from 'lucide-react'; import { getPlaylist, updatePlaylist } from '@/features/playlist'; -import type { SubsonicPlaylist } from '../../api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistStore } from '@/features/playlist'; import { showToast } from '../../utils/ui/toast'; import { diff --git a/src/components/contextMenu/AlbumContextItems.tsx b/src/components/contextMenu/AlbumContextItems.tsx index dc87d804..cb6fd32d 100644 --- a/src/components/contextMenu/AlbumContextItems.tsx +++ b/src/components/contextMenu/AlbumContextItems.tsx @@ -2,8 +2,8 @@ import { useTranslation } from 'react-i18next'; import { Play, ListPlus, Heart, Download, ChevronRight, ChevronsRight, User, ListMusic, Star, Share2 } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { resolveAlbum, resolveMediaServerId } from '@/features/offline'; -import { star, unstar } from '../../api/subsonicStarRating'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import { star, unstar } from '@/lib/api/subsonicStarRating'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../../utils/playback/songToTrack'; import StarRating from '../StarRating'; import { AlbumToPlaylistSubmenu } from './AlbumArtistToPlaylistSubmenu'; diff --git a/src/components/contextMenu/ArtistContextItems.tsx b/src/components/contextMenu/ArtistContextItems.tsx index cf0f8de6..0143e5b7 100644 --- a/src/components/contextMenu/ArtistContextItems.tsx +++ b/src/components/contextMenu/ArtistContextItems.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next'; import { Radio, Heart, ChevronRight, ListMusic, Star, Share2 } from 'lucide-react'; -import { star, unstar } from '../../api/subsonicStarRating'; -import type { SubsonicArtist } from '../../api/subsonicTypes'; +import { star, unstar } from '@/lib/api/subsonicStarRating'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import StarRating from '../StarRating'; import { ArtistToPlaylistSubmenu } from './AlbumArtistToPlaylistSubmenu'; import { MultiArtistToPlaylistSubmenu } from './MultiArtistToPlaylistSubmenu'; diff --git a/src/components/contextMenu/MultiAlbumToPlaylistSubmenu.tsx b/src/components/contextMenu/MultiAlbumToPlaylistSubmenu.tsx index 223d8b0b..a1acb3ec 100644 --- a/src/components/contextMenu/MultiAlbumToPlaylistSubmenu.tsx +++ b/src/components/contextMenu/MultiAlbumToPlaylistSubmenu.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 're import { useTranslation } from 'react-i18next'; import { ListMusic, Plus } from 'lucide-react'; import { resolveAlbum, resolveMediaServerId, resolvePlaylist } from '@/features/offline'; -import type { SubsonicPlaylist } from '../../api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistStore } from '@/features/playlist'; import { showToast } from '../../utils/ui/toast'; import { diff --git a/src/components/contextMenu/MultiArtistToPlaylistSubmenu.tsx b/src/components/contextMenu/MultiArtistToPlaylistSubmenu.tsx index a578ccb1..90d1820e 100644 --- a/src/components/contextMenu/MultiArtistToPlaylistSubmenu.tsx +++ b/src/components/contextMenu/MultiArtistToPlaylistSubmenu.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { ListMusic, Plus } from 'lucide-react'; import { resolveAlbum, resolveArtist, resolveMediaServerId, resolvePlaylist } from '@/features/offline'; import { getPlaylists } from '@/features/playlist'; -import type { SubsonicPlaylist } from '../../api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistStore } from '@/features/playlist'; import { showToast } from '../../utils/ui/toast'; import { diff --git a/src/components/contextMenu/PlaylistContextItems.tsx b/src/components/contextMenu/PlaylistContextItems.tsx index 78313fd4..aa259015 100644 --- a/src/components/contextMenu/PlaylistContextItems.tsx +++ b/src/components/contextMenu/PlaylistContextItems.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next'; import { Play, ChevronRight, FolderTree, ListMusic, Trash2 } from 'lucide-react'; -import type { SubsonicPlaylist } from '../../api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistStore } from '@/features/playlist'; import { MultiPlaylistToPlaylistSubmenu, SinglePlaylistToPlaylistSubmenu } from './PlaylistToPlaylistSubmenus'; import MoveToFolderSubmenu from './MoveToFolderSubmenu'; diff --git a/src/components/contextMenu/contextMenuItemTypes.ts b/src/components/contextMenu/contextMenuItemTypes.ts index 7fc1991d..7ead8a13 100644 --- a/src/components/contextMenu/contextMenuItemTypes.ts +++ b/src/components/contextMenu/contextMenuItemTypes.ts @@ -1,5 +1,5 @@ import type React from 'react'; -import type { SubsonicAlbum, SubsonicArtist } from '../../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist } from '@/lib/api/subsonicTypes'; import type { QueueItemRef, Track } from '../../store/playerStoreTypes'; import type { EntityShareKind } from '../../utils/share/shareLink'; import type { OfflineActionPolicy } from '@/features/offline'; diff --git a/src/components/folderBrowser/FolderBrowserColumn.tsx b/src/components/folderBrowser/FolderBrowserColumn.tsx index 1c5b6a85..9fbc3f8d 100644 --- a/src/components/folderBrowser/FolderBrowserColumn.tsx +++ b/src/components/folderBrowser/FolderBrowserColumn.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { ChevronRight, Folder, FolderOpen, Music } from 'lucide-react'; -import type { SubsonicDirectoryEntry } from '../../api/subsonicTypes'; +import type { SubsonicDirectoryEntry } from '@/lib/api/subsonicTypes'; import type { Track } from '../../store/playerStoreTypes'; import { folderBrowserHasKeyModifiers, isFolderBrowserArrowKey, diff --git a/src/components/playerBar/PlayerTrackInfo.tsx b/src/components/playerBar/PlayerTrackInfo.tsx index 4de84b51..c1a82047 100644 --- a/src/components/playerBar/PlayerTrackInfo.tsx +++ b/src/components/playerBar/PlayerTrackInfo.tsx @@ -1,7 +1,7 @@ import { Cast, Heart, Maximize2, Music } from 'lucide-react'; import type { TFunction } from 'i18next'; import { queueSongRating } from '../../store/pendingStarSync'; -import type { InternetRadioStation, SubsonicOpenArtistRef } from '../../api/subsonicTypes'; +import type { InternetRadioStation, SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; import type { PlayerState, Track } from '../../store/playerStoreTypes'; import type { RadioMetadata } from '@/features/radio'; import type { PreviewingTrack } from '../../store/previewStore'; diff --git a/src/components/queuePanel/LoadPlaylistModal.tsx b/src/components/queuePanel/LoadPlaylistModal.tsx index bf4c61fb..9929ffb1 100644 --- a/src/components/queuePanel/LoadPlaylistModal.tsx +++ b/src/components/queuePanel/LoadPlaylistModal.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { Play, X, Trash2, ListPlus } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { getPlaylists, deletePlaylist } from '@/features/playlist'; -import type { SubsonicPlaylist } from '../../api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; interface Props { onClose: () => void; diff --git a/src/components/randomMix/RandomMixTrackRow.tsx b/src/components/randomMix/RandomMixTrackRow.tsx index 13b60aa5..8a6f36de 100644 --- a/src/components/randomMix/RandomMixTrackRow.tsx +++ b/src/components/randomMix/RandomMixTrackRow.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { AudioLines, ChevronRight, Heart, Play, Square } from 'lucide-react'; -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '../../store/playerStoreTypes'; import { previewInputFromSong, usePreviewStore } from '../../store/previewStore'; import { useDragDrop } from '../../contexts/DragDropContext'; diff --git a/src/components/tracks/SongBrowseSection.tsx b/src/components/tracks/SongBrowseSection.tsx index f9c5f77c..6aedd24a 100644 --- a/src/components/tracks/SongBrowseSection.tsx +++ b/src/components/tracks/SongBrowseSection.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import React from 'react'; import { useTranslation } from 'react-i18next'; import PagedSongList from '../PagedSongList'; diff --git a/src/components/tracks/TracksPageChrome.tsx b/src/components/tracks/TracksPageChrome.tsx index ffb45801..95e731d4 100644 --- a/src/components/tracks/TracksPageChrome.tsx +++ b/src/components/tracks/TracksPageChrome.tsx @@ -1,6 +1,6 @@ import { AlbumCoverArtImage } from '../../cover/AlbumCoverArtImage'; -import { getRandomSongs } from '../../api/subsonicLibrary'; -import type { SubsonicSong } from '../../api/subsonicTypes'; +import { getRandomSongs } from '@/lib/api/subsonicLibrary'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../../utils/playback/songToTrack'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Play, ListPlus, RefreshCw, Sparkles } from 'lucide-react'; @@ -9,7 +9,7 @@ import { useAuthStore } from '../../store/authStore'; import { usePlayerStore } from '../../store/playerStore'; import SongRail from '../SongRail'; import { playSongNow } from '../../utils/playback/playSong'; -import { ndListSongs, ndInvalidateSongsCache } from '../../api/navidromeBrowse'; +import { ndListSongs, ndInvalidateSongsCache } from '@/lib/api/navidromeBrowse'; import { usePerfProbeFlags } from '../../utils/perf/perfFlags'; import { useNavigateToAlbum } from '@/features/album'; import { useNavigateToArtist } from '@/features/artist'; diff --git a/src/config/shortcutActionRegistry.ts b/src/config/shortcutActionRegistry.ts index 4610f8e6..cf999f52 100644 --- a/src/config/shortcutActionRegistry.ts +++ b/src/config/shortcutActionRegistry.ts @@ -1,5 +1,5 @@ import { queueSongStar } from '../store/pendingStarSync'; -import { getSong } from '../api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { songToTrack } from '../utils/playback/songToTrack'; import { invoke } from '@tauri-apps/api/core'; import { getCurrentWindow } from '@tauri-apps/api/window'; diff --git a/src/cover/TrackCoverArtImage.tsx b/src/cover/TrackCoverArtImage.tsx index 52e327de..39335803 100644 --- a/src/cover/TrackCoverArtImage.tsx +++ b/src/cover/TrackCoverArtImage.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { CoverArtImage, type CoverArtImageProps } from './CoverArtImage'; import { useTrackCoverRef } from './useLibraryCoverRef'; import { COVER_SCOPE_ACTIVE, type CoverServerScope } from './types'; diff --git a/src/cover/artistHero.tsx b/src/cover/artistHero.tsx index 440ac221..56a0cdc0 100644 --- a/src/cover/artistHero.tsx +++ b/src/cover/artistHero.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState, type CSSProperties, type ImgHTMLAttributes } from 'react'; -import type { SubsonicArtistInfo } from '../api/subsonicTypes'; +import type { SubsonicArtistInfo } from '@/lib/api/subsonicTypes'; import { isRealArtistImage } from '../utils/componentHelpers/nowPlayingHelpers'; import { CoverArtImage } from './CoverArtImage'; import type { CoverArtRef, CoverSurfaceKind } from './types'; diff --git a/src/cover/fetchUrl.ts b/src/cover/fetchUrl.ts index 5ab587dd..35c0ed36 100644 --- a/src/cover/fetchUrl.ts +++ b/src/cover/fetchUrl.ts @@ -1,7 +1,7 @@ import { buildCoverArtUrl, buildCoverArtUrlForServer, -} from '../api/subsonicStreamUrl'; +} from '@/lib/api/subsonicStreamUrl'; import { getPlaybackServerId } from '../utils/playback/playbackServer'; import { useAuthStore } from '../store/authStore'; import { connectBaseUrlForServer } from '../utils/server/serverEndpoint'; diff --git a/src/cover/integrations/discord.ts b/src/cover/integrations/discord.ts index d52bd24c..58661cdc 100644 --- a/src/cover/integrations/discord.ts +++ b/src/cover/integrations/discord.ts @@ -1,4 +1,4 @@ -import { buildCoverArtUrlForServer } from '../../api/subsonicStreamUrl'; +import { buildCoverArtUrlForServer } from '@/lib/api/subsonicStreamUrl'; import { serverShareBaseUrl } from '../../utils/server/serverEndpoint'; import { useAuthStore } from '../../store/authStore'; import type { CoverArtRef } from '../types'; diff --git a/src/cover/ref.ts b/src/cover/ref.ts index b6f6d0f7..d9c6ea1e 100644 --- a/src/cover/ref.ts +++ b/src/cover/ref.ts @@ -1,7 +1,7 @@ import { getPlaybackServerId } from '../utils/playback/playbackServer'; import { useAuthStore } from '../store/authStore'; import { coverServerScopeForServerId } from './serverScope'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { CoverArtId, CoverArtRef, CoverCacheKind, CoverServerScope } from './types'; import { albumHasDistinctDiscCovers, diff --git a/src/cover/resolveEntry.ts b/src/cover/resolveEntry.ts index 6a50d69c..08ad7a97 100644 --- a/src/cover/resolveEntry.ts +++ b/src/cover/resolveEntry.ts @@ -8,7 +8,7 @@ * stay in sync with `resolve_album_cover` / `resolve_artist_cover` there. */ -import type { SubsonicAlbum, SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import type { CoverArtRef, CoverCacheKind, CoverServerScope } from './types'; /** Resolved cover identity — maps 1:1 to Rust `CoverEntry`. */ diff --git a/src/cover/useLibraryCoverPrefetch.ts b/src/cover/useLibraryCoverPrefetch.ts index 378612ca..8d844a15 100644 --- a/src/cover/useLibraryCoverPrefetch.ts +++ b/src/cover/useLibraryCoverPrefetch.ts @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { coverPrefetchRegister } from './prefetchRegistry'; import { resolveAlbumCoverRefsFromLibrary, diff --git a/src/cover/useLibraryCoverRef.ts b/src/cover/useLibraryCoverRef.ts index bf5aaca2..a5877dc3 100644 --- a/src/cover/useLibraryCoverRef.ts +++ b/src/cover/useLibraryCoverRef.ts @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState, type Dispatch, type SetStateAction } from 'react'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '../store/authStore'; import { usePlayerStore } from '../store/playerStore'; import { diff --git a/src/cover/warmDiskPeek.ts b/src/cover/warmDiskPeek.ts index 93097c4d..797875cf 100644 --- a/src/cover/warmDiskPeek.ts +++ b/src/cover/warmDiskPeek.ts @@ -1,5 +1,5 @@ import { coverCachePeekBatch } from '../api/coverCache'; -import type { SubsonicAlbum } from '../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { coverEnsureQueued, ensureArtistBackdropQueued } from './ensureQueue'; import { getDiskSrcForGrid, rememberGridDiskSrc } from './diskSrcLookup'; import { albumCoverRef, artistCoverRef } from './ref'; diff --git a/src/features/album/api/subsonicAlbumInfo.ts b/src/features/album/api/subsonicAlbumInfo.ts index 0fae46ab..30637eea 100644 --- a/src/features/album/api/subsonicAlbumInfo.ts +++ b/src/features/album/api/subsonicAlbumInfo.ts @@ -1,5 +1,5 @@ -import { api } from '@/api/subsonicClient'; -import type { AlbumInfo } from '@/api/subsonicTypes'; +import { api } from '@/lib/api/subsonicClient'; +import type { AlbumInfo } from '@/lib/api/subsonicTypes'; export async function getAlbumInfo2(albumId: string): Promise { try { diff --git a/src/features/album/components/AlbumCard.tsx b/src/features/album/components/AlbumCard.tsx index 18d92a35..82fba0a0 100644 --- a/src/features/album/components/AlbumCard.tsx +++ b/src/features/album/components/AlbumCard.tsx @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import React, { memo, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { useNavigateToAlbum } from '@/features/album/hooks/useNavigateToAlbum'; diff --git a/src/features/album/components/AlbumHeader.test.tsx b/src/features/album/components/AlbumHeader.test.tsx index 8dea49ab..170472ab 100644 --- a/src/features/album/components/AlbumHeader.test.tsx +++ b/src/features/album/components/AlbumHeader.test.tsx @@ -3,7 +3,7 @@ import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { renderWithProviders } from '@/test/helpers/renderWithProviders'; import AlbumHeader from '@/features/album/components/AlbumHeader'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; const navigate = vi.fn(); diff --git a/src/features/album/components/AlbumHeader.tsx b/src/features/album/components/AlbumHeader.tsx index 60db1e87..91256bbe 100644 --- a/src/features/album/components/AlbumHeader.tsx +++ b/src/features/album/components/AlbumHeader.tsx @@ -1,4 +1,4 @@ -import type { EntityRatingSupportLevel, SubsonicItemGenre, SubsonicOpenArtistRef, SubsonicSong } from '@/api/subsonicTypes'; +import type { EntityRatingSupportLevel, SubsonicItemGenre, SubsonicOpenArtistRef, SubsonicSong } from '@/lib/api/subsonicTypes'; import { type CSSProperties, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { useNavigate } from 'react-router-dom'; diff --git a/src/features/album/components/AlbumRow.tsx b/src/features/album/components/AlbumRow.tsx index 142f5588..77727796 100644 --- a/src/features/album/components/AlbumRow.tsx +++ b/src/features/album/components/AlbumRow.tsx @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import React, { useRef, useState, useEffect, useLayoutEffect, useMemo } from 'react'; import AlbumCard from '@/features/album/components/AlbumCard'; import { ChevronLeft, ChevronRight, ArrowRight } from 'lucide-react'; diff --git a/src/features/album/components/AlbumTrackList.tsx b/src/features/album/components/AlbumTrackList.tsx index 46364176..1055a645 100644 --- a/src/features/album/components/AlbumTrackList.tsx +++ b/src/features/album/components/AlbumTrackList.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; import React, { useMemo, useState, useEffect } from 'react'; import { useTracklistColumns } from '@/utils/useTracklistColumns'; diff --git a/src/features/album/components/AlbumTrackListMobile.tsx b/src/features/album/components/AlbumTrackListMobile.tsx index b67f5ce4..b76df24d 100644 --- a/src/features/album/components/AlbumTrackListMobile.tsx +++ b/src/features/album/components/AlbumTrackListMobile.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { AudioLines } from 'lucide-react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { formatLongDuration } from '@/utils/format/formatDuration'; diff --git a/src/features/album/components/LosslessAlbumsRail.tsx b/src/features/album/components/LosslessAlbumsRail.tsx index 2f147585..5d9813b1 100644 --- a/src/features/album/components/LosslessAlbumsRail.tsx +++ b/src/features/album/components/LosslessAlbumsRail.tsx @@ -1,7 +1,7 @@ -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { ndListLosslessAlbumsPage } from '@/api/navidromeBrowse'; +import { ndListLosslessAlbumsPage } from '@/lib/api/navidromeBrowse'; import AlbumRow from '@/features/album/components/AlbumRow'; import { useAuthStore } from '@/store/authStore'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; diff --git a/src/features/album/components/TrackRow.tsx b/src/features/album/components/TrackRow.tsx index b1c6dc35..99cd55e0 100644 --- a/src/features/album/components/TrackRow.tsx +++ b/src/features/album/components/TrackRow.tsx @@ -3,7 +3,7 @@ import { AudioLines, ChevronRight, Heart, Play, Square } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import type { ColDef } from '@/utils/useTracklistColumns'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useSelectionStore } from '@/store/selectionStore'; diff --git a/src/features/album/hooks/useAlbumBrowseData.test.ts b/src/features/album/hooks/useAlbumBrowseData.test.ts index a76412d4..19e80f10 100644 --- a/src/features/album/hooks/useAlbumBrowseData.test.ts +++ b/src/features/album/hooks/useAlbumBrowseData.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; // Keep pagination termination rules aligned with the hook implementation. function resolveHasMoreAfterPage( diff --git a/src/features/album/hooks/useAlbumBrowseData.ts b/src/features/album/hooks/useAlbumBrowseData.ts index 64261f51..8a00d468 100644 --- a/src/features/album/hooks/useAlbumBrowseData.ts +++ b/src/features/album/hooks/useAlbumBrowseData.ts @@ -5,7 +5,7 @@ import { useRef, useState, } from 'react'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { coverTrafficBeginGridPagination, coverTrafficEndGridPagination, @@ -25,7 +25,7 @@ import { type AlbumBrowseQuery, type GenreFilterOption, } from '@/utils/library/albumBrowseLoad'; -import { libraryScopeForServer } from '@/api/subsonicClient'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { ALBUM_YEAR_FILTER_DEBOUNCE_MS, resolveAlbumYearBounds, diff --git a/src/features/album/hooks/useAlbumDetailData.ts b/src/features/album/hooks/useAlbumDetailData.ts index 9c6c1e20..9398ac04 100644 --- a/src/features/album/hooks/useAlbumDetailData.ts +++ b/src/features/album/hooks/useAlbumDetailData.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { loadAlbumFromLibraryIndex, diff --git a/src/features/album/hooks/useAlbumDetailSort.ts b/src/features/album/hooks/useAlbumDetailSort.ts index 6b475464..f11de8bf 100644 --- a/src/features/album/hooks/useAlbumDetailSort.ts +++ b/src/features/album/hooks/useAlbumDetailSort.ts @@ -1,5 +1,5 @@ import { useMemo, useState } from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export type AlbumSortKey = 'natural' | 'title' | 'artist' | 'album' | 'favorite' | 'rating' | 'duration' | 'playCount' | 'lastPlayed' | 'bpm'; diff --git a/src/features/album/hooks/useAlbumGridBrowseFilters.ts b/src/features/album/hooks/useAlbumGridBrowseFilters.ts index 720daad8..23d9e714 100644 --- a/src/features/album/hooks/useAlbumGridBrowseFilters.ts +++ b/src/features/album/hooks/useAlbumGridBrowseFilters.ts @@ -1,6 +1,6 @@ import { useEffect, useRef, useState, type RefObject } from 'react'; import { useLocation, useNavigationType, type NavigationType } from 'react-router-dom'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { DEFAULT_ALBUM_BROWSE_RETURN_FILTERS, type AlbumBrowseReturnFilters, diff --git a/src/features/album/hooks/useAlbumTrackListSelection.ts b/src/features/album/hooks/useAlbumTrackListSelection.ts index bde46042..991b49ee 100644 --- a/src/features/album/hooks/useAlbumTrackListSelection.ts +++ b/src/features/album/hooks/useAlbumTrackListSelection.ts @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useRef } from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useSelectionStore } from '@/store/selectionStore'; import { useDragDrop } from '@/contexts/DragDropContext'; import { songToTrack } from '@/utils/playback/songToTrack'; diff --git a/src/features/album/hooks/useBrowseAlbumTextSearch.ts b/src/features/album/hooks/useBrowseAlbumTextSearch.ts index 7842dd0f..98e8d6b7 100644 --- a/src/features/album/hooks/useBrowseAlbumTextSearch.ts +++ b/src/features/album/hooks/useBrowseAlbumTextSearch.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { useEffect, useRef, useState } from 'react'; import { BROWSE_TEXT_DEBOUNCE_NETWORK_MS, diff --git a/src/features/album/hooks/useGenreAlbumBrowse.ts b/src/features/album/hooks/useGenreAlbumBrowse.ts index 9dd15fe6..d305b0ae 100644 --- a/src/features/album/hooks/useGenreAlbumBrowse.ts +++ b/src/features/album/hooks/useGenreAlbumBrowse.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { dedupeById } from '@/utils/dedupeById'; import type { AlbumBrowseSort } from '@/utils/library/albumBrowseSort'; import { diff --git a/src/features/album/pages/AlbumDetail.tsx b/src/features/album/pages/AlbumDetail.tsx index 0e5d3ec6..efed065f 100644 --- a/src/features/album/pages/AlbumDetail.tsx +++ b/src/features/album/pages/AlbumDetail.tsx @@ -1,9 +1,9 @@ -import { buildDownloadUrl } from '@/api/subsonicStreamUrl'; -import { setRating, star, unstar } from '@/api/subsonicStarRating'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; +import { setRating, star, unstar } from '@/lib/api/subsonicStarRating'; import { queueSongStar, queueSongRating } from '@/store/pendingStarSync'; -import { getAlbumForServer } from '@/api/subsonicLibrary'; +import { getAlbumForServer } from '@/lib/api/subsonicLibrary'; import { getArtistInfo } from '@/features/artist'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { shuffleArray } from '@/utils/playback/shuffleArray'; import React, { useEffect, useState, useCallback, useMemo } from 'react'; diff --git a/src/features/album/pages/Albums.tsx b/src/features/album/pages/Albums.tsx index 6650677c..52fc2f59 100644 --- a/src/features/album/pages/Albums.tsx +++ b/src/features/album/pages/Albums.tsx @@ -1,4 +1,4 @@ -import { buildDownloadUrl } from '@/api/subsonicStreamUrl'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; import { resolveAlbum } from '@/features/offline'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useState, useEffect, useLayoutEffect, useRef, useMemo } from 'react'; diff --git a/src/features/album/pages/LabelAlbums.tsx b/src/features/album/pages/LabelAlbums.tsx index b08aae0c..cf62b5cd 100644 --- a/src/features/album/pages/LabelAlbums.tsx +++ b/src/features/album/pages/LabelAlbums.tsx @@ -1,5 +1,5 @@ -import { search } from '@/api/subsonicSearch'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import { search } from '@/lib/api/subsonicSearch'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import React, { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { ChevronLeft } from 'lucide-react'; diff --git a/src/features/album/pages/LosslessAlbums.tsx b/src/features/album/pages/LosslessAlbums.tsx index 4a205278..372f05c0 100644 --- a/src/features/album/pages/LosslessAlbums.tsx +++ b/src/features/album/pages/LosslessAlbums.tsx @@ -1,11 +1,11 @@ -import { buildDownloadUrl } from '@/api/subsonicStreamUrl'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; import { resolveAlbum } from '@/features/offline'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import AlbumCard from '@/features/album/components/AlbumCard'; import { LOSSLESS_MODE_QUERY } from '@/utils/library/losslessMode'; -import { ndListLosslessAlbumsPage } from '@/api/navidromeBrowse'; +import { ndListLosslessAlbumsPage } from '@/lib/api/navidromeBrowse'; import { useTranslation } from 'react-i18next'; import { useAuthStore } from '@/store/authStore'; import { useOfflineStore } from '@/features/offline'; diff --git a/src/features/album/pages/RandomAlbums.tsx b/src/features/album/pages/RandomAlbums.tsx index b4e5df75..f7fef95a 100644 --- a/src/features/album/pages/RandomAlbums.tsx +++ b/src/features/album/pages/RandomAlbums.tsx @@ -1,8 +1,8 @@ -import { buildDownloadUrl } from '@/api/subsonicStreamUrl'; -import { getAlbumsByGenre } from '@/api/subsonicGenres'; -import { getAlbumList } from '@/api/subsonicLibrary'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; +import { getAlbumsByGenre } from '@/lib/api/subsonicGenres'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; import { resolveAlbum } from '@/features/offline'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { dedupeById } from '@/utils/dedupeById'; import { shuffleArray } from '@/utils/playback/shuffleArray'; import React, { useEffect, useLayoutEffect, useState, useCallback, useRef } from 'react'; diff --git a/src/features/album/store/albumBrowseSessionStore.test.ts b/src/features/album/store/albumBrowseSessionStore.test.ts index 7252aad9..bc58e761 100644 --- a/src/features/album/store/albumBrowseSessionStore.test.ts +++ b/src/features/album/store/albumBrowseSessionStore.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, beforeEach } from 'vitest'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { DEFAULT_ALBUM_BROWSE_RETURN_FILTERS, DEFAULT_ALBUM_BROWSE_SORT, diff --git a/src/features/album/store/albumBrowseSessionStore.ts b/src/features/album/store/albumBrowseSessionStore.ts index a7cbd0b5..4110f31d 100644 --- a/src/features/album/store/albumBrowseSessionStore.ts +++ b/src/features/album/store/albumBrowseSessionStore.ts @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import type { AlbumBrowseSort } from '@/utils/library/browseTextSearch'; export const DEFAULT_ALBUM_BROWSE_SORT: AlbumBrowseSort = 'alphabeticalByName'; diff --git a/src/features/album/utils/deriveAlbumHeaderArtistRefs.test.ts b/src/features/album/utils/deriveAlbumHeaderArtistRefs.test.ts index f4d900a9..6389397a 100644 --- a/src/features/album/utils/deriveAlbumHeaderArtistRefs.test.ts +++ b/src/features/album/utils/deriveAlbumHeaderArtistRefs.test.ts @@ -4,7 +4,7 @@ import { deriveAlbumArtistRefs, deriveAlbumHeaderArtistRefs, } from '@/features/album/utils/deriveAlbumHeaderArtistRefs'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { makeSubsonicSong } from '@/test/helpers/factories'; const baseAlbum = (): SubsonicAlbum => ({ diff --git a/src/features/album/utils/deriveAlbumHeaderArtistRefs.ts b/src/features/album/utils/deriveAlbumHeaderArtistRefs.ts index acd9c56c..bb5bec4c 100644 --- a/src/features/album/utils/deriveAlbumHeaderArtistRefs.ts +++ b/src/features/album/utils/deriveAlbumHeaderArtistRefs.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum, SubsonicOpenArtistRef, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicOpenArtistRef, SubsonicSong } from '@/lib/api/subsonicTypes'; import { coerceOpenArtistRefs } from '@/features/artist'; function nonEmpty(refs: SubsonicOpenArtistRef[]): refs is SubsonicOpenArtistRef[] { diff --git a/src/features/album/utils/exportAlbumCard.ts b/src/features/album/utils/exportAlbumCard.ts index 6b031643..87ca9661 100644 --- a/src/features/album/utils/exportAlbumCard.ts +++ b/src/features/album/utils/exportAlbumCard.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { coverArtRef } from '@/cover/ref'; diff --git a/src/features/album/utils/exportNewAlbums.ts b/src/features/album/utils/exportNewAlbums.ts index 3a7df326..0527db98 100644 --- a/src/features/album/utils/exportNewAlbums.ts +++ b/src/features/album/utils/exportNewAlbums.ts @@ -1,7 +1,7 @@ -import { getAlbumList } from '@/api/subsonicLibrary'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; import { coverArtRef } from '@/cover/ref'; import { loadCoverBlobForExport } from '@/cover/integrations/export'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { albumArtistDisplayName } from '@/features/album/utils/deriveAlbumHeaderArtistRefs'; import { writeFile } from '@tauri-apps/plugin-fs'; import { downloadDir, join } from '@tauri-apps/api/path'; diff --git a/src/features/artist/api/subsonicArtists.router.test.ts b/src/features/artist/api/subsonicArtists.router.test.ts index 32cbc1fe..76b53c51 100644 --- a/src/features/artist/api/subsonicArtists.router.test.ts +++ b/src/features/artist/api/subsonicArtists.router.test.ts @@ -1,19 +1,19 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonicClient', () => ({ +vi.mock('@/lib/api/subsonicClient', () => ({ api: vi.fn(), apiForServer: vi.fn(), libraryFilterParams: () => ({}), libraryFilterParamsForServer: () => ({}), })); -vi.mock('@/api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ filterSongsToActiveLibrary: async (songs: unknown[]) => songs, filterSongsToServerLibrary: async (songs: unknown[]) => songs, similarSongsRequestCount: (count: number) => count, })); -import { api } from '@/api/subsonicClient'; +import { api } from '@/lib/api/subsonicClient'; import { fetchSimilarTracksRouted } from '@/features/artist/api/subsonicArtists'; import { useAuthStore } from '@/store/authStore'; diff --git a/src/features/artist/api/subsonicArtists.ts b/src/features/artist/api/subsonicArtists.ts index 2a91ccf8..6db84df9 100644 --- a/src/features/artist/api/subsonicArtists.ts +++ b/src/features/artist/api/subsonicArtists.ts @@ -1,7 +1,7 @@ import { useAuthStore } from '@/store/authStore'; -import { api, apiForServer, libraryFilterParams, libraryFilterParamsForServer } from '@/api/subsonicClient'; -import { filterSongsToServerLibrary } from '@/api/subsonicLibrary'; -import { filterSongsToActiveLibrary, similarSongsRequestCount } from '@/api/subsonicLibrary'; +import { api, apiForServer, libraryFilterParams, libraryFilterParamsForServer } from '@/lib/api/subsonicClient'; +import { filterSongsToServerLibrary } from '@/lib/api/subsonicLibrary'; +import { filterSongsToActiveLibrary, similarSongsRequestCount } from '@/lib/api/subsonicLibrary'; import { FEATURE_AUDIOMUSE_SIMILAR_TRACKS, OP_SIMILAR_TRACKS, @@ -12,7 +12,7 @@ import type { SubsonicArtist, SubsonicArtistInfo, SubsonicSong, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; export async function getArtists(): Promise { type ArtistIndexEntry = { artist?: SubsonicArtist | SubsonicArtist[] }; diff --git a/src/features/artist/components/ArtistAvatars.tsx b/src/features/artist/components/ArtistAvatars.tsx index b169180f..d1d57de0 100644 --- a/src/features/artist/components/ArtistAvatars.tsx +++ b/src/features/artist/components/ArtistAvatars.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { ArtistCoverArtImage } from '@/cover/ArtistCoverArtImage'; import { COVER_DENSE_ARTIST_LIST_CSS_PX, diff --git a/src/features/artist/components/ArtistCardLocal.tsx b/src/features/artist/components/ArtistCardLocal.tsx index e007d131..62a1389c 100644 --- a/src/features/artist/components/ArtistCardLocal.tsx +++ b/src/features/artist/components/ArtistCardLocal.tsx @@ -1,4 +1,4 @@ -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import React, { useMemo } from 'react'; import { Users } from 'lucide-react'; import { useTranslation } from 'react-i18next'; diff --git a/src/features/artist/components/ArtistDetailHero.tsx b/src/features/artist/components/ArtistDetailHero.tsx index 01d4736d..e68a385d 100644 --- a/src/features/artist/components/ArtistDetailHero.tsx +++ b/src/features/artist/components/ArtistDetailHero.tsx @@ -5,7 +5,7 @@ import { ArrowLeft, Camera, Check, HardDriveDownload, Heart, Loader2, Play, Radio, Share2, Shuffle, Users, } from 'lucide-react'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicArtistInfo } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicArtistInfo } from '@/lib/api/subsonicTypes'; import { useOfflineStore } from '@/features/offline'; import { useAuthStore } from '@/store/authStore'; import { useThemeStore } from '@/store/themeStore'; diff --git a/src/features/artist/components/ArtistDetailSimilarArtists.tsx b/src/features/artist/components/ArtistDetailSimilarArtists.tsx index 33354438..7df6a550 100644 --- a/src/features/artist/components/ArtistDetailSimilarArtists.tsx +++ b/src/features/artist/components/ArtistDetailSimilarArtists.tsx @@ -2,7 +2,7 @@ import React, { Fragment } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { ChevronDown, ChevronUp } from 'lucide-react'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { useIsMobile } from '@/hooks/useIsMobile'; interface Props { diff --git a/src/features/artist/components/ArtistDetailTopTracks.tsx b/src/features/artist/components/ArtistDetailTopTracks.tsx index 36f2daff..cdd6e8ac 100644 --- a/src/features/artist/components/ArtistDetailTopTracks.tsx +++ b/src/features/artist/components/ArtistDetailTopTracks.tsx @@ -1,7 +1,7 @@ import React, { Fragment } from 'react'; import { useTranslation } from 'react-i18next'; import { AudioLines, ChevronRight, Play, Square } from 'lucide-react'; -import type { SubsonicAlbum, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; import { previewInputFromSong, usePreviewStore } from '@/store/previewStore'; import { useOrbitSongRowBehavior } from '@/features/orbit'; diff --git a/src/features/artist/components/ArtistRow.tsx b/src/features/artist/components/ArtistRow.tsx index 9a98baad..62635659 100644 --- a/src/features/artist/components/ArtistRow.tsx +++ b/src/features/artist/components/ArtistRow.tsx @@ -1,4 +1,4 @@ -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import React, { useRef, useState, useEffect, useLayoutEffect } from 'react'; import ArtistCardLocal from '@/features/artist/components/ArtistCardLocal'; import { ChevronLeft, ChevronRight, ArrowRight } from 'lucide-react'; diff --git a/src/features/artist/components/ArtistsGridView.tsx b/src/features/artist/components/ArtistsGridView.tsx index 0cb94f00..49885d86 100644 --- a/src/features/artist/components/ArtistsGridView.tsx +++ b/src/features/artist/components/ArtistsGridView.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Check } from 'lucide-react'; import type { TFunction } from 'i18next'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import type { PlayerState } from '@/store/playerStoreTypes'; import { ARTISTS_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll'; import { VirtualCardGrid } from '@/components/VirtualCardGrid'; diff --git a/src/features/artist/components/ArtistsListView.tsx b/src/features/artist/components/ArtistsListView.tsx index 2d07453a..2f9d80bd 100644 --- a/src/features/artist/components/ArtistsListView.tsx +++ b/src/features/artist/components/ArtistsListView.tsx @@ -1,7 +1,7 @@ import React from 'react'; import type { Virtualizer } from '@tanstack/react-virtual'; import type { TFunction } from 'i18next'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import type { PlayerState } from '@/store/playerStoreTypes'; import { OTHER_BUCKET, type ArtistListFlatRow } from '@/features/artist/utils/artistsHelpers'; import { ArtistRowAvatar } from '@/features/artist/components/ArtistAvatars'; diff --git a/src/features/artist/components/OpenArtistRefInline.tsx b/src/features/artist/components/OpenArtistRefInline.tsx index f314b3e0..cebcb175 100644 --- a/src/features/artist/components/OpenArtistRefInline.tsx +++ b/src/features/artist/components/OpenArtistRefInline.tsx @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import type { SubsonicOpenArtistRef } from '@/api/subsonicTypes'; +import type { SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; interface Props { refs: SubsonicOpenArtistRef[]; diff --git a/src/features/artist/components/topSongAlbumForCover.ts b/src/features/artist/components/topSongAlbumForCover.ts index 6f492f7c..6908e9db 100644 --- a/src/features/artist/components/topSongAlbumForCover.ts +++ b/src/features/artist/components/topSongAlbumForCover.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; export type TopSongAlbumCoverSource = Pick; diff --git a/src/features/artist/hooks/useArtistDetailData.test.ts b/src/features/artist/hooks/useArtistDetailData.test.ts index acf9e28c..7b1179db 100644 --- a/src/features/artist/hooks/useArtistDetailData.test.ts +++ b/src/features/artist/hooks/useArtistDetailData.test.ts @@ -13,13 +13,13 @@ import { renderHook, act, waitFor } from '@testing-library/react'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import type { SubsonicArtistInfo } from '@/api/subsonicTypes'; +import type { SubsonicArtistInfo } from '@/lib/api/subsonicTypes'; vi.mock('@/features/artist/api/subsonicArtists'); -vi.mock('@/api/subsonicSearch'); +vi.mock('@/lib/api/subsonicSearch'); import { getArtist, getArtistInfo, getTopSongs } from '@/features/artist/api/subsonicArtists'; -import { search } from '@/api/subsonicSearch'; +import { search } from '@/lib/api/subsonicSearch'; import { useArtistDetailData } from '@/features/artist/hooks/useArtistDetailData'; const mockArtistInfo = vi.mocked(getArtistInfo) as unknown as { diff --git a/src/features/artist/hooks/useArtistDetailData.ts b/src/features/artist/hooks/useArtistDetailData.ts index ee4c241c..dc0f054c 100644 --- a/src/features/artist/hooks/useArtistDetailData.ts +++ b/src/features/artist/hooks/useArtistDetailData.ts @@ -1,10 +1,10 @@ import { useEffect, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; -import { search } from '@/api/subsonicSearch'; +import { search } from '@/lib/api/subsonicSearch'; import { getArtist, getArtistForServer, getArtistInfo, getTopSongs } from '@/features/artist/api/subsonicArtists'; import type { SubsonicAlbum, SubsonicArtist, SubsonicArtistInfo, SubsonicSong, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { useConnectionStatus } from '@/hooks/useConnectionStatus'; import { loadArtistFromLibraryIndex } from '@/features/offline'; diff --git a/src/features/artist/hooks/useArtistInfoBatch.ts b/src/features/artist/hooks/useArtistInfoBatch.ts index 6ea0d85b..33d1cc16 100644 --- a/src/features/artist/hooks/useArtistInfoBatch.ts +++ b/src/features/artist/hooks/useArtistInfoBatch.ts @@ -1,6 +1,6 @@ import { useEffect, useMemo, useState } from 'react'; import { getArtistInfoForServer } from '@/features/artist/api/subsonicArtists'; -import type { SubsonicArtistInfo, SubsonicOpenArtistRef } from '@/api/subsonicTypes'; +import type { SubsonicArtistInfo, SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; import { makeCache } from '@/utils/cache/nowPlayingCache'; const artistInfoCache = makeCache(); diff --git a/src/features/artist/hooks/useArtistSimilarArtists.ts b/src/features/artist/hooks/useArtistSimilarArtists.ts index 81fba5d4..99b23d2d 100644 --- a/src/features/artist/hooks/useArtistSimilarArtists.ts +++ b/src/features/artist/hooks/useArtistSimilarArtists.ts @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { getMusicNetworkRuntime } from '@/music-network'; -import { search } from '@/api/subsonicSearch'; -import type { SubsonicArtist, SubsonicArtistInfo } from '@/api/subsonicTypes'; +import { search } from '@/lib/api/subsonicSearch'; +import type { SubsonicArtist, SubsonicArtistInfo } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; export interface ArtistSimilarArtistsResult { diff --git a/src/features/artist/hooks/useArtistsBrowseCatalog.ts b/src/features/artist/hooks/useArtistsBrowseCatalog.ts index 436bce89..3276b66a 100644 --- a/src/features/artist/hooks/useArtistsBrowseCatalog.ts +++ b/src/features/artist/hooks/useArtistsBrowseCatalog.ts @@ -1,5 +1,5 @@ import { getArtists } from '@/features/artist/api/subsonicArtists'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { useCallback, useEffect, useRef, useState } from 'react'; import { dedupeById } from '@/utils/dedupeById'; import { diff --git a/src/features/artist/hooks/useArtistsFiltering.ts b/src/features/artist/hooks/useArtistsFiltering.ts index 046f6a45..a407a0d2 100644 --- a/src/features/artist/hooks/useArtistsFiltering.ts +++ b/src/features/artist/hooks/useArtistsFiltering.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; import { ALL_SENTINEL, artistLetterBucket, compareBuckets, type ArtistListFlatRow } from '@/features/artist/utils/artistsHelpers'; diff --git a/src/features/artist/hooks/useBrowseArtistTextSearch.ts b/src/features/artist/hooks/useBrowseArtistTextSearch.ts index 517ed461..da9e2a50 100644 --- a/src/features/artist/hooks/useBrowseArtistTextSearch.ts +++ b/src/features/artist/hooks/useBrowseArtistTextSearch.ts @@ -1,4 +1,4 @@ -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { useEffect, useRef, useState } from 'react'; import { BROWSE_TEXT_DEBOUNCE_NETWORK_MS, diff --git a/src/features/artist/pages/ArtistDetail.tsx b/src/features/artist/pages/ArtistDetail.tsx index 14083b10..95110a92 100644 --- a/src/features/artist/pages/ArtistDetail.tsx +++ b/src/features/artist/pages/ArtistDetail.tsx @@ -1,6 +1,6 @@ import { useCoverArt } from '@/cover/useCoverArt'; import { useArtistCoverRef } from '@/cover/useLibraryCoverRef'; -import type { SubsonicArtist, SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicArtist, SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { useEffect, useState, Fragment, useMemo } from 'react'; import { useParams, useSearchParams } from 'react-router-dom'; import { AlbumCard } from '@/features/album'; diff --git a/src/features/artist/utils/artistsHelpers.ts b/src/features/artist/utils/artistsHelpers.ts index bf6f1033..aeb02a72 100644 --- a/src/features/artist/utils/artistsHelpers.ts +++ b/src/features/artist/utils/artistsHelpers.ts @@ -1,4 +1,4 @@ -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; export const ALL_SENTINEL = 'ALL'; /** Catch-all bucket for names that start with neither an A–Z letter nor a digit diff --git a/src/features/artist/utils/openArtistRefs.ts b/src/features/artist/utils/openArtistRefs.ts index 52f46a64..3b03ae8e 100644 --- a/src/features/artist/utils/openArtistRefs.ts +++ b/src/features/artist/utils/openArtistRefs.ts @@ -1,4 +1,4 @@ -import type { SubsonicOpenArtistRef } from '@/api/subsonicTypes'; +import type { SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; /** Subsonic JSON may return one ref object instead of a one-element array. */ export function coerceOpenArtistRefs( diff --git a/src/features/artist/utils/runArtistDetailActions.ts b/src/features/artist/utils/runArtistDetailActions.ts index bf3948c3..2fba18d4 100644 --- a/src/features/artist/utils/runArtistDetailActions.ts +++ b/src/features/artist/utils/runArtistDetailActions.ts @@ -1,8 +1,8 @@ import type React from 'react'; import type { TFunction } from 'i18next'; import { uploadArtistImage } from '@/features/playlist'; -import { setRating, star, unstar } from '@/api/subsonicStarRating'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import { setRating, star, unstar } from '@/lib/api/subsonicStarRating'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { copyEntityShareLink } from '@/utils/share/copyEntityShareLink'; import { invalidateCoverArt } from '@/utils/imageCache'; diff --git a/src/features/artist/utils/runArtistDetailPlay.test.ts b/src/features/artist/utils/runArtistDetailPlay.test.ts index 6e0c161f..4937466e 100644 --- a/src/features/artist/utils/runArtistDetailPlay.test.ts +++ b/src/features/artist/utils/runArtistDetailPlay.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import * as offlineMediaResolve from '@/features/offline'; import { fetchArtistDetailTracks, runArtistDetailPlayTopSong } from '@/features/artist/utils/runArtistDetailPlay'; diff --git a/src/features/artist/utils/runArtistDetailPlay.ts b/src/features/artist/utils/runArtistDetailPlay.ts index 9c23d412..3f79f1d5 100644 --- a/src/features/artist/utils/runArtistDetailPlay.ts +++ b/src/features/artist/utils/runArtistDetailPlay.ts @@ -1,6 +1,6 @@ import type { TFunction } from 'i18next'; import { getSimilarSongs2, getTopSongs } from '@/features/artist/api/subsonicArtists'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { runBulkPlayAll, runBulkShuffle } from '@/utils/playback/runBulkPlay'; diff --git a/src/features/artist/utils/sortArtistAlbums.test.ts b/src/features/artist/utils/sortArtistAlbums.test.ts index c7d43bee..fe21b2c1 100644 --- a/src/features/artist/utils/sortArtistAlbums.test.ts +++ b/src/features/artist/utils/sortArtistAlbums.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { sortArtistAlbumsByYear } from '@/features/artist/utils/sortArtistAlbums'; const album = (id: string, name: string, year?: number): SubsonicAlbum => ({ diff --git a/src/features/artist/utils/sortArtistAlbums.ts b/src/features/artist/utils/sortArtistAlbums.ts index 133711c1..2fb4b22a 100644 --- a/src/features/artist/utils/sortArtistAlbums.ts +++ b/src/features/artist/utils/sortArtistAlbums.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; export type ArtistAlbumYearOrder = 'yearDesc' | 'yearAsc'; diff --git a/src/features/deviceSync/components/DeviceSyncBrowserPanel.tsx b/src/features/deviceSync/components/DeviceSyncBrowserPanel.tsx index c5d15b2e..4b4e32f4 100644 --- a/src/features/deviceSync/components/DeviceSyncBrowserPanel.tsx +++ b/src/features/deviceSync/components/DeviceSyncBrowserPanel.tsx @@ -6,7 +6,7 @@ import { } from 'lucide-react'; import type { SubsonicAlbum, SubsonicArtist, SubsonicPlaylist, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import type { DeviceSyncSource } from '@/features/deviceSync/store/deviceSyncStore'; import type { SourceTab } from '@/features/deviceSync/utils/deviceSyncHelpers'; import BrowserRow from '@/features/deviceSync/components/BrowserRow'; diff --git a/src/features/deviceSync/hooks/useDeviceSyncBrowser.ts b/src/features/deviceSync/hooks/useDeviceSyncBrowser.ts index 22774741..ead13a41 100644 --- a/src/features/deviceSync/hooks/useDeviceSyncBrowser.ts +++ b/src/features/deviceSync/hooks/useDeviceSyncBrowser.ts @@ -1,11 +1,11 @@ import { useCallback, useEffect, useState } from 'react'; import { getPlaylists } from '@/features/playlist'; import { getArtists, getArtist } from '@/features/artist'; -import { getAlbumList } from '@/api/subsonicLibrary'; -import { search as searchSubsonic } from '@/api/subsonicSearch'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; +import { search as searchSubsonic } from '@/lib/api/subsonicSearch'; import type { SubsonicAlbum, SubsonicArtist, SubsonicPlaylist, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import type { SourceTab } from '@/features/deviceSync/utils/deviceSyncHelpers'; export interface DeviceSyncBrowserResult { diff --git a/src/features/deviceSync/pages/DeviceSync.tsx b/src/features/deviceSync/pages/DeviceSync.tsx index 45b611e9..f4e2f29f 100644 --- a/src/features/deviceSync/pages/DeviceSync.tsx +++ b/src/features/deviceSync/pages/DeviceSync.tsx @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useState, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useDeviceSyncStore, DeviceSyncSource } from '@/features/deviceSync/store/deviceSyncStore'; diff --git a/src/features/deviceSync/utils/deviceSyncHelpers.ts b/src/features/deviceSync/utils/deviceSyncHelpers.ts index fa43efa9..e352931f 100644 --- a/src/features/deviceSync/utils/deviceSyncHelpers.ts +++ b/src/features/deviceSync/utils/deviceSyncHelpers.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export type SourceTab = 'playlists' | 'albums' | 'artists'; diff --git a/src/features/deviceSync/utils/runDeviceSyncExecution.ts b/src/features/deviceSync/utils/runDeviceSyncExecution.ts index 6e8070e7..1eaa9d69 100644 --- a/src/features/deviceSync/utils/runDeviceSyncExecution.ts +++ b/src/features/deviceSync/utils/runDeviceSyncExecution.ts @@ -1,7 +1,7 @@ import type { TFunction } from 'i18next'; import { invoke } from '@tauri-apps/api/core'; -import { buildDownloadUrl } from '@/api/subsonicStreamUrl'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useDeviceSyncStore, type DeviceSyncSource } from '@/features/deviceSync/store/deviceSyncStore'; import { useDeviceSyncJobStore } from '@/features/deviceSync/store/deviceSyncJobStore'; import { showToast } from '@/utils/ui/toast'; @@ -37,7 +37,7 @@ export async function runDeviceSyncSummaryPrompt(deps: RunDeviceSyncSummaryDeps) setPreSyncOpen(true); try { - const { getClient } = await import('@/api/subsonicClient'); + const { getClient } = await import('@/lib/api/subsonicClient'); const { baseUrl, params } = getClient(); const payload = await invoke('calculate_sync_payload', { sources, diff --git a/src/features/deviceSync/utils/runDeviceSyncMigration.ts b/src/features/deviceSync/utils/runDeviceSyncMigration.ts index 7d00b3b2..7652445e 100644 --- a/src/features/deviceSync/utils/runDeviceSyncMigration.ts +++ b/src/features/deviceSync/utils/runDeviceSyncMigration.ts @@ -1,7 +1,7 @@ import type React from 'react'; import { invoke } from '@tauri-apps/api/core'; import type { DeviceSyncSource } from '@/features/deviceSync/store/deviceSyncStore'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { applyLegacyTemplate } from '@/features/deviceSync/utils/deviceSyncLegacyTemplate'; import { trackToSyncInfo } from '@/features/deviceSync/utils/deviceSyncHelpers'; import { fetchTracksForSource } from '@/utils/playback/fetchTracksForSource'; diff --git a/src/features/favorites/components/FavoriteSongRow.tsx b/src/features/favorites/components/FavoriteSongRow.tsx index cb193f4f..8ed192aa 100644 --- a/src/features/favorites/components/FavoriteSongRow.tsx +++ b/src/features/favorites/components/FavoriteSongRow.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { AudioLines, ChevronRight, Play, Square, X } from 'lucide-react'; import type { ColDef } from '@/utils/useTracklistColumns'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { codecLabel } from '@/utils/componentHelpers/playlistDetailHelpers'; import { formatLastSeen } from '@/utils/componentHelpers/userMgmtHelpers'; import i18n from '@/i18n'; diff --git a/src/features/favorites/components/FavoritesSongsSectionHeader.tsx b/src/features/favorites/components/FavoritesSongsSectionHeader.tsx index 87e0ffe7..da7db3b3 100644 --- a/src/features/favorites/components/FavoritesSongsSectionHeader.tsx +++ b/src/features/favorites/components/FavoritesSongsSectionHeader.tsx @@ -1,7 +1,7 @@ import React, { useMemo, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { ListPlus, Play, SlidersHorizontal, X } from 'lucide-react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; import { useSelectionStore } from '@/store/selectionStore'; import { songToTrack } from '@/utils/playback/songToTrack'; diff --git a/src/features/favorites/components/FavoritesSongsTracklist.tsx b/src/features/favorites/components/FavoritesSongsTracklist.tsx index 11b4adc5..dfed81c4 100644 --- a/src/features/favorites/components/FavoritesSongsTracklist.tsx +++ b/src/features/favorites/components/FavoritesSongsTracklist.tsx @@ -5,7 +5,7 @@ import { TracklistColumnPicker } from '@/components/albumTrackList/TracklistColu import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import type { ColDef } from '@/utils/useTracklistColumns'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; import { previewInputFromSong, usePreviewStore } from '@/store/previewStore'; import { useSelectionStore } from '@/store/selectionStore'; diff --git a/src/features/favorites/components/RadioFavorites.tsx b/src/features/favorites/components/RadioFavorites.tsx index abbb40e8..e5c89561 100644 --- a/src/features/favorites/components/RadioFavorites.tsx +++ b/src/features/favorites/components/RadioFavorites.tsx @@ -1,7 +1,7 @@ import React, { useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Cast, ChevronLeft, ChevronRight, Heart, X } from 'lucide-react'; -import type { InternetRadioStation } from '@/api/subsonicTypes'; +import type { InternetRadioStation } from '@/lib/api/subsonicTypes'; import { CoverArtImage } from '@/cover/CoverArtImage'; import { albumCoverRef } from '@/cover/ref'; import { coverArtIdFromRadio } from '@/cover/ids'; diff --git a/src/features/favorites/hooks/useFavoritesData.ts b/src/features/favorites/hooks/useFavoritesData.ts index b67aa528..d04ca2bc 100644 --- a/src/features/favorites/hooks/useFavoritesData.ts +++ b/src/features/favorites/hooks/useFavoritesData.ts @@ -1,9 +1,9 @@ import { useEffect, useMemo, useState } from 'react'; import { getInternetRadioStations } from '@/features/radio'; -import { getStarred } from '@/api/subsonicStarRating'; +import { getStarred } from '@/lib/api/subsonicStarRating'; import type { InternetRadioStation, SubsonicAlbum, SubsonicArtist, SubsonicSong, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { usePlayerStore } from '@/store/playerStore'; import type { TopFavoriteArtist } from '@/features/favorites/components/TopFavoriteArtists'; diff --git a/src/features/favorites/hooks/useFavoritesSelection.ts b/src/features/favorites/hooks/useFavoritesSelection.ts index b209730d..50d0484d 100644 --- a/src/features/favorites/hooks/useFavoritesSelection.ts +++ b/src/features/favorites/hooks/useFavoritesSelection.ts @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useRef } from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useSelectionStore } from '@/store/selectionStore'; export interface FavoritesSelectionResult { diff --git a/src/features/favorites/hooks/useFavoritesSongFiltering.tsx b/src/features/favorites/hooks/useFavoritesSongFiltering.tsx index 5556480b..ac19bb0e 100644 --- a/src/features/favorites/hooks/useFavoritesSongFiltering.tsx +++ b/src/features/favorites/hooks/useFavoritesSongFiltering.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; import { ArrowDown, ArrowUp } from 'lucide-react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; const CURRENT_YEAR = new Date().getFullYear(); diff --git a/src/features/miniPlayer/components/MiniContextMenu.tsx b/src/features/miniPlayer/components/MiniContextMenu.tsx index f3b480aa..5e70060d 100644 --- a/src/features/miniPlayer/components/MiniContextMenu.tsx +++ b/src/features/miniPlayer/components/MiniContextMenu.tsx @@ -1,4 +1,4 @@ -import { star, unstar } from '@/api/subsonicStarRating'; +import { star, unstar } from '@/lib/api/subsonicStarRating'; import { useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { emit } from '@tauri-apps/api/event'; diff --git a/src/features/miniPlayer/components/MiniPlayer.test.tsx b/src/features/miniPlayer/components/MiniPlayer.test.tsx index 42649672..3cbcd885 100644 --- a/src/features/miniPlayer/components/MiniPlayer.test.tsx +++ b/src/features/miniPlayer/components/MiniPlayer.test.tsx @@ -9,7 +9,7 @@ */ import { beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), diff --git a/src/features/miniPlayer/utils/miniPlayerBridge.ts b/src/features/miniPlayer/utils/miniPlayerBridge.ts index 21e7294a..f3245972 100644 --- a/src/features/miniPlayer/utils/miniPlayerBridge.ts +++ b/src/features/miniPlayer/utils/miniPlayerBridge.ts @@ -4,7 +4,7 @@ import { usePlayerStore } from '@/store/playerStore'; import { useAuthStore } from '@/store/authStore'; import { setTransitionMode, type TransitionMode } from '@/utils/playback/playbackTransition'; import { resolveQueueTrack } from '@/utils/library/queueTrackView'; -import type { SubsonicOpenArtistRef } from '@/api/subsonicTypes'; +import type { SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; export const MINI_WINDOW_LABEL = 'mini'; diff --git a/src/features/nowPlaying/api/nowPlayingPresence.test.ts b/src/features/nowPlaying/api/nowPlayingPresence.test.ts index ec756007..dd5bbc0d 100644 --- a/src/features/nowPlaying/api/nowPlayingPresence.test.ts +++ b/src/features/nowPlaying/api/nowPlayingPresence.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; import { nowPlayingPresence, NOW_PLAYING_IDLE_MINUTES } from '@/features/nowPlaying/api/nowPlayingPresence'; -import type { SubsonicNowPlaying, PlaybackReportState } from '@/api/subsonicTypes'; +import type { SubsonicNowPlaying, PlaybackReportState } from '@/lib/api/subsonicTypes'; // The function only reads `state` and `minutesAgo`; cast a minimal fixture. function entry(partial: { state?: PlaybackReportState; minutesAgo?: number }): SubsonicNowPlaying { diff --git a/src/features/nowPlaying/api/nowPlayingPresence.ts b/src/features/nowPlaying/api/nowPlayingPresence.ts index d7854acb..e838468c 100644 --- a/src/features/nowPlaying/api/nowPlayingPresence.ts +++ b/src/features/nowPlaying/api/nowPlayingPresence.ts @@ -1,4 +1,4 @@ -import type { SubsonicNowPlaying } from '@/api/subsonicTypes'; +import type { SubsonicNowPlaying } from '@/lib/api/subsonicTypes'; /** * Derived liveness of a now-playing entry, surfaced as the indicator dot in the diff --git a/src/features/nowPlaying/components/AlbumCard.tsx b/src/features/nowPlaying/components/AlbumCard.tsx index 40bf21a0..f0b60279 100644 --- a/src/features/nowPlaying/components/AlbumCard.tsx +++ b/src/features/nowPlaying/components/AlbumCard.tsx @@ -1,7 +1,7 @@ import React, { memo, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Disc3, ExternalLink, Star } from 'lucide-react'; -import type { SubsonicAlbum, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import { formatTotalDuration } from '@/utils/componentHelpers/nowPlayingHelpers'; import { formatTrackTime } from '@/utils/format/formatDuration'; diff --git a/src/features/nowPlaying/components/ArtistCard.test.tsx b/src/features/nowPlaying/components/ArtistCard.test.tsx index 4ddd8469..a4a35468 100644 --- a/src/features/nowPlaying/components/ArtistCard.test.tsx +++ b/src/features/nowPlaying/components/ArtistCard.test.tsx @@ -8,7 +8,7 @@ import { describe, it, expect, vi } from 'vitest'; import { fireEvent } from '@testing-library/react'; import { renderWithProviders } from '@/test/helpers/renderWithProviders'; import ArtistCard from '@/features/nowPlaying/components/ArtistCard'; -import type { SubsonicArtistInfo } from '@/api/subsonicTypes'; +import type { SubsonicArtistInfo } from '@/lib/api/subsonicTypes'; const infoWithImage: SubsonicArtistInfo = { biography: 'Some bio text here.', diff --git a/src/features/nowPlaying/components/ArtistCard.tsx b/src/features/nowPlaying/components/ArtistCard.tsx index 52aa9dd5..48fd0662 100644 --- a/src/features/nowPlaying/components/ArtistCard.tsx +++ b/src/features/nowPlaying/components/ArtistCard.tsx @@ -1,7 +1,7 @@ import React, { memo, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ExternalLink } from 'lucide-react'; -import type { SubsonicArtistInfo } from '@/api/subsonicTypes'; +import type { SubsonicArtistInfo } from '@/lib/api/subsonicTypes'; import { isRealArtistImage, sanitizeHtml } from '@/utils/componentHelpers/nowPlayingHelpers'; import CachedImage from '@/ui/CachedImage'; diff --git a/src/features/nowPlaying/components/DiscographyCard.tsx b/src/features/nowPlaying/components/DiscographyCard.tsx index e0dbd3fb..fff80ff3 100644 --- a/src/features/nowPlaying/components/DiscographyCard.tsx +++ b/src/features/nowPlaying/components/DiscographyCard.tsx @@ -1,7 +1,7 @@ import React, { memo, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Disc3, ExternalLink, Music } from 'lucide-react'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { AlbumCoverArtImage } from '@/cover/AlbumCoverArtImage'; import { COVER_DENSE_RAIL_CELL_CSS_PX } from '@/cover/layoutSizes'; diff --git a/src/features/nowPlaying/components/Hero.tsx b/src/features/nowPlaying/components/Hero.tsx index 7dbb1ab5..36995327 100644 --- a/src/features/nowPlaying/components/Hero.tsx +++ b/src/features/nowPlaying/components/Hero.tsx @@ -4,7 +4,7 @@ import { Headphones, Heart, MicVocal, Music, Star } from 'lucide-react'; import { CoverArtImage } from '@/cover/CoverArtImage'; import type { CoverArtRef } from '@/cover/types'; import type { ArtistStats, TrackStats } from '@/music-network'; -import type { SubsonicOpenArtistRef } from '@/api/subsonicTypes'; +import type { SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; import { OpenArtistRefInline } from '@/features/artist'; import { formatTrackTime } from '@/utils/format/formatDuration'; import { useEnrichmentPrimaryLabel } from '@/hooks/useEnrichmentPrimaryLabel'; diff --git a/src/features/nowPlaying/components/NowPlayingDropdown.tsx b/src/features/nowPlaying/components/NowPlayingDropdown.tsx index f0971418..8957fb2f 100644 --- a/src/features/nowPlaying/components/NowPlayingDropdown.tsx +++ b/src/features/nowPlaying/components/NowPlayingDropdown.tsx @@ -1,6 +1,6 @@ import { TrackCoverArtImage } from '@/cover/TrackCoverArtImage'; -import { getNowPlaying } from '@/api/subsonicScrobble'; -import type { SubsonicNowPlaying } from '@/api/subsonicTypes'; +import { getNowPlaying } from '@/lib/api/subsonicScrobble'; +import type { SubsonicNowPlaying } from '@/lib/api/subsonicTypes'; import React, { useState, useEffect, useRef, useCallback, useLayoutEffect } from 'react'; import { createPortal } from 'react-dom'; import { PlayCircle, Pause, User, Radio, RefreshCw } from 'lucide-react'; diff --git a/src/features/nowPlaying/components/NowPlayingInfo.tsx b/src/features/nowPlaying/components/NowPlayingInfo.tsx index f5cdb3c1..e2458e3a 100644 --- a/src/features/nowPlaying/components/NowPlayingInfo.tsx +++ b/src/features/nowPlaying/components/NowPlayingInfo.tsx @@ -1,6 +1,6 @@ -import { getSongForServer } from '@/api/subsonicLibrary'; +import { getSongForServer } from '@/lib/api/subsonicLibrary'; import { getArtistInfoForServer } from '@/features/artist'; -import type { SubsonicArtistInfo, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicArtistInfo, SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Info } from 'lucide-react'; diff --git a/src/features/nowPlaying/components/TopSongsCard.tsx b/src/features/nowPlaying/components/TopSongsCard.tsx index aa6344d6..fbb45bfd 100644 --- a/src/features/nowPlaying/components/TopSongsCard.tsx +++ b/src/features/nowPlaying/components/TopSongsCard.tsx @@ -1,7 +1,7 @@ import React, { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { ExternalLink, Play, TrendingUp } from 'lucide-react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { formatTrackTime } from '@/utils/format/formatDuration'; interface TopSongsCardProps { diff --git a/src/features/nowPlaying/hooks/useNowPlayingFetchers.test.ts b/src/features/nowPlaying/hooks/useNowPlayingFetchers.test.ts index cf1a4a5e..78ba3959 100644 --- a/src/features/nowPlaying/hooks/useNowPlayingFetchers.test.ts +++ b/src/features/nowPlaying/hooks/useNowPlayingFetchers.test.ts @@ -11,10 +11,10 @@ */ import { renderHook, act, waitFor } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import type { SubsonicArtistInfo, SubsonicSong, SubsonicAlbum, SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtistInfo, SubsonicSong, SubsonicAlbum, SubsonicArtist } from '@/lib/api/subsonicTypes'; vi.mock('@/features/artist'); -vi.mock('@/api/subsonicLibrary'); +vi.mock('@/lib/api/subsonicLibrary'); vi.mock('@/api/bandsintown'); vi.mock('@/utils/network/subsonicNetworkGuard', () => ({ shouldAttemptSubsonicForServer: vi.fn(() => true), @@ -22,7 +22,7 @@ vi.mock('@/utils/network/subsonicNetworkGuard', () => ({ import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; import { getArtistForServer, getArtistInfoForServer, getTopSongsForServer } from '@/features/artist'; -import { getAlbumForServer, getSongForServer } from '@/api/subsonicLibrary'; +import { getAlbumForServer, getSongForServer } from '@/lib/api/subsonicLibrary'; import { fetchBandsintownEvents } from '@/api/bandsintown'; import { useNowPlayingFetchers, type NowPlayingFetchersDeps } from '@/features/nowPlaying/hooks/useNowPlayingFetchers'; diff --git a/src/features/nowPlaying/hooks/useNowPlayingFetchers.ts b/src/features/nowPlaying/hooks/useNowPlayingFetchers.ts index 5ae0dea0..6e392c08 100644 --- a/src/features/nowPlaying/hooks/useNowPlayingFetchers.ts +++ b/src/features/nowPlaying/hooks/useNowPlayingFetchers.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { getArtistInfoForServer } from '@/features/artist'; -import type { SubsonicAlbum, SubsonicArtistInfo, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtistInfo, SubsonicSong } from '@/lib/api/subsonicTypes'; import { resolveNpAlbum, resolveNpDiscography, resolveNpSongMeta, resolveNpTopSongs } from '@/features/nowPlaying/utils/nowPlayingMetadataResolve'; import { fetchBandsintownEvents, type BandsintownEvent } from '@/api/bandsintown'; import type { ArtistStats, TrackStats } from '@/music-network'; diff --git a/src/features/nowPlaying/hooks/useNowPlayingStarLove.ts b/src/features/nowPlaying/hooks/useNowPlayingStarLove.ts index 63578bda..8fa38d35 100644 --- a/src/features/nowPlaying/hooks/useNowPlayingStarLove.ts +++ b/src/features/nowPlaying/hooks/useNowPlayingStarLove.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from 'react'; import { queueSongStar } from '@/store/pendingStarSync'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; import type { TrackStats } from '@/music-network'; import { getMusicNetworkRuntime } from '@/music-network'; diff --git a/src/features/nowPlaying/pages/NowPlaying.tsx b/src/features/nowPlaying/pages/NowPlaying.tsx index e2864036..5f0e682d 100644 --- a/src/features/nowPlaying/pages/NowPlaying.tsx +++ b/src/features/nowPlaying/pages/NowPlaying.tsx @@ -2,7 +2,7 @@ import { useCoverArt } from '@/cover/useCoverArt'; import { albumCoverRef } from '@/cover/ref'; import { usePlaybackTrackCoverRef } from '@/cover/useLibraryCoverRef'; import { coverArtIdFromRadio } from '@/cover/ids'; -import type { SubsonicArtistInfo, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicArtistInfo, SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react'; import { usePlaybackLibraryNavigate } from '@/hooks/usePlaybackLibraryNavigate'; import { usePlaybackServerId } from '@/hooks/usePlaybackServerId'; diff --git a/src/features/nowPlaying/utils/nowPlayingMetadataResolve.test.ts b/src/features/nowPlaying/utils/nowPlayingMetadataResolve.test.ts index 5a138c07..7e435d73 100644 --- a/src/features/nowPlaying/utils/nowPlayingMetadataResolve.test.ts +++ b/src/features/nowPlaying/utils/nowPlayingMetadataResolve.test.ts @@ -8,9 +8,9 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { onInvoke } from '@/test/mocks/tauri'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; -import type { LibraryAdvancedSearchResponse } from '@/api/library'; +import type { LibraryAdvancedSearchResponse } from '@/lib/api/library'; import * as subsonicArtists from '@/features/artist'; -import * as subsonicLibrary from '@/api/subsonicLibrary'; +import * as subsonicLibrary from '@/lib/api/subsonicLibrary'; // Network reachability is decided by the guard; mock it so we can test both arms. vi.mock('@/utils/network/subsonicNetworkGuard', () => ({ diff --git a/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts b/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts index 89281b3a..48fa3d1c 100644 --- a/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts +++ b/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts @@ -16,10 +16,10 @@ * `artistInfo` (bio / similar) has no index source and stays network-only — it * is intentionally absent here. */ -import { libraryGetTrack, libraryGetTracksByAlbum } from '@/api/library'; +import { libraryGetTrack, libraryGetTracksByAlbum } from '@/lib/api/library'; import { getArtistForServer, getTopSongsForServer } from '@/features/artist'; -import { getAlbumForServer, getSongForServer } from '@/api/subsonicLibrary'; -import type { SubsonicAlbum, SubsonicSong } from '@/api/subsonicTypes'; +import { getAlbumForServer, getSongForServer } from '@/lib/api/subsonicLibrary'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; import { loadAlbumFromLibraryIndex, loadArtistFromLibraryIndex } from '@/features/offline'; import { trackToSong } from '@/utils/library/advancedSearchLocal'; diff --git a/src/features/offline/store/offlineStore.ts b/src/features/offline/store/offlineStore.ts index cf26103b..eda3a61c 100644 --- a/src/features/offline/store/offlineStore.ts +++ b/src/features/offline/store/offlineStore.ts @@ -1,8 +1,8 @@ -import { libraryUpsertSongsFromApi } from '@/api/library'; -import { buildStreamUrl } from '@/api/subsonicStreamUrl'; -import { getAlbum } from '@/api/subsonicLibrary'; +import { libraryUpsertSongsFromApi } from '@/lib/api/library'; +import { buildStreamUrl } from '@/lib/api/subsonicStreamUrl'; +import { getAlbum } from '@/lib/api/subsonicLibrary'; import { getArtist } from '@/features/artist'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { create } from 'zustand'; import { persist, createJSONStorage } from 'zustand/middleware'; import { invoke } from '@tauri-apps/api/core'; diff --git a/src/features/offline/utils/favoritesOfflineBrowse.test.ts b/src/features/offline/utils/favoritesOfflineBrowse.test.ts index 6d86e538..74f33bc7 100644 --- a/src/features/offline/utils/favoritesOfflineBrowse.test.ts +++ b/src/features/offline/utils/favoritesOfflineBrowse.test.ts @@ -32,11 +32,11 @@ const libraryAdvancedSearchMock = vi.fn(); const libraryGetTracksByAlbumMock = vi.fn(); const libraryGetTracksBatchChunkedMock = vi.fn(); -vi.mock('@/api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getAlbumForServer: (...args: unknown[]) => getAlbumForServerMock(...args), })); -vi.mock('@/api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryAdvancedSearch: (...args: unknown[]) => libraryAdvancedSearchMock(...args), libraryGetTracksByAlbum: (...args: unknown[]) => libraryGetTracksByAlbumMock(...args), libraryGetTracksBatchChunked: (...args: unknown[]) => libraryGetTracksBatchChunkedMock(...args), diff --git a/src/features/offline/utils/favoritesOfflineSync.test.ts b/src/features/offline/utils/favoritesOfflineSync.test.ts index 40ff1cbb..55003e88 100644 --- a/src/features/offline/utils/favoritesOfflineSync.test.ts +++ b/src/features/offline/utils/favoritesOfflineSync.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { useOfflineJobStore } from '@/features/offline/store/offlineJobStore'; import { FAVORITES_OFFLINE_JOB_ID } from '@/features/offline/utils/favoritesOfflineConstants'; @@ -20,11 +20,11 @@ vi.mock('@/utils/network/activeServerReachability', () => ({ isActiveServerReachable: () => isActiveServerReachableMock(), })); -vi.mock('@/api/subsonicStarRating', () => ({ +vi.mock('@/lib/api/subsonicStarRating', () => ({ getStarredForServer: (serverId: string) => getStarredForServerMock(serverId), })); -vi.mock('@/api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getAlbumForServer: vi.fn(async () => ({ songs: [] })), })); diff --git a/src/features/offline/utils/favoritesOfflineSync.ts b/src/features/offline/utils/favoritesOfflineSync.ts index 8b1e310e..7f42c95c 100644 --- a/src/features/offline/utils/favoritesOfflineSync.ts +++ b/src/features/offline/utils/favoritesOfflineSync.ts @@ -1,10 +1,10 @@ -import { libraryUpsertSongsFromApi } from '@/api/library'; +import { libraryUpsertSongsFromApi } from '@/lib/api/library'; import { librarySqlServerId } from '@/api/coverCache'; -import { getAlbumForServer } from '@/api/subsonicLibrary'; +import { getAlbumForServer } from '@/lib/api/subsonicLibrary'; import { getArtistForServer } from '@/features/artist'; -import { getStarredForServer } from '@/api/subsonicStarRating'; -import { buildStreamUrlForServer } from '@/api/subsonicStreamUrl'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import { getStarredForServer } from '@/lib/api/subsonicStarRating'; +import { buildStreamUrlForServer } from '@/lib/api/subsonicStreamUrl'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { invoke } from '@tauri-apps/api/core'; import i18n from '@/i18n'; import { useAuthStore } from '@/store/authStore'; diff --git a/src/features/offline/utils/legacyOfflineFileMigration.ts b/src/features/offline/utils/legacyOfflineFileMigration.ts index fca156e6..57fb8f01 100644 --- a/src/features/offline/utils/legacyOfflineFileMigration.ts +++ b/src/features/offline/utils/legacyOfflineFileMigration.ts @@ -1,5 +1,5 @@ import { invoke } from '@tauri-apps/api/core'; -import { libraryGetTracksBatch } from '@/api/library'; +import { libraryGetTracksBatch } from '@/lib/api/library'; import { useAuthStore } from '@/store/authStore'; import { useOfflineStore, type OfflineAlbumMeta } from '@/features/offline/store/offlineStore'; import { useLocalPlaybackStore, type LocalPlaybackEntry, type PinSource } from '@/store/localPlaybackStore'; diff --git a/src/features/offline/utils/libraryTierReconcile.ts b/src/features/offline/utils/libraryTierReconcile.ts index 3d319278..2eeb70f9 100644 --- a/src/features/offline/utils/libraryTierReconcile.ts +++ b/src/features/offline/utils/libraryTierReconcile.ts @@ -1,6 +1,6 @@ -import { libraryUpsertSongsFromApi } from '@/api/library'; +import { libraryUpsertSongsFromApi } from '@/lib/api/library'; import { librarySqlServerId } from '@/api/coverCache'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { invoke } from '@tauri-apps/api/core'; import { useAuthStore } from '@/store/authStore'; import type { LocalPlaybackEntry, PinSource } from '@/store/localPlaybackStore'; diff --git a/src/features/offline/utils/offlineAlbumBrowseCatalog.ts b/src/features/offline/utils/offlineAlbumBrowseCatalog.ts index d265aa79..bb1f53b3 100644 --- a/src/features/offline/utils/offlineAlbumBrowseCatalog.ts +++ b/src/features/offline/utils/offlineAlbumBrowseCatalog.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import type { AlbumBrowseQuery } from '@/utils/library/albumBrowseTypes'; import { isOfflineBrowseActive } from '@/features/offline/utils/offlineBrowseMode'; import { diff --git a/src/features/offline/utils/offlineLibraryHelpers.test.ts b/src/features/offline/utils/offlineLibraryHelpers.test.ts index 01a768d7..730c47be 100644 --- a/src/features/offline/utils/offlineLibraryHelpers.test.ts +++ b/src/features/offline/utils/offlineLibraryHelpers.test.ts @@ -16,7 +16,7 @@ import { offlineTrackCount, type OfflineLibraryCard, } from '@/features/offline/utils/offlineLibraryHelpers'; -import * as libraryApi from '@/api/library'; +import * as libraryApi from '@/lib/api/library'; import { coverStorageKey } from '@/cover/storageKeys'; import { resolveCoverDisplayTier } from '@/cover/tiers'; @@ -24,8 +24,8 @@ vi.mock('@/utils/server/switchActiveServer', () => ({ switchActiveServer: vi.fn(async () => true), })); -vi.mock('@/api/library', async importOriginal => { - const actual = await importOriginal(); +vi.mock('@/lib/api/library', async importOriginal => { + const actual = await importOriginal(); const libraryGetTracksBatch = vi.fn(); return { ...actual, diff --git a/src/features/offline/utils/offlineLibraryHelpers.ts b/src/features/offline/utils/offlineLibraryHelpers.ts index bfca9012..07a9f39d 100644 --- a/src/features/offline/utils/offlineLibraryHelpers.ts +++ b/src/features/offline/utils/offlineLibraryHelpers.ts @@ -1,6 +1,6 @@ -import type { LibraryTrackDto } from '@/api/library'; -import { libraryGetTrack, libraryGetTracksBatchChunked } from '@/api/library'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { LibraryTrackDto } from '@/lib/api/library'; +import { libraryGetTrack, libraryGetTracksBatchChunked } from '@/lib/api/library'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { CoverServerScope } from '@/cover/types'; import { useAuthStore } from '@/store/authStore'; import type { LocalPlaybackEntry, PinnedGroup, PinSource } from '@/store/localPlaybackStore'; diff --git a/src/features/offline/utils/offlineLibraryIndexLoad.ts b/src/features/offline/utils/offlineLibraryIndexLoad.ts index 0079a5cb..7aa1f55c 100644 --- a/src/features/offline/utils/offlineLibraryIndexLoad.ts +++ b/src/features/offline/utils/offlineLibraryIndexLoad.ts @@ -1,9 +1,9 @@ -import { libraryAdvancedSearch, libraryGetTracksByAlbum } from '@/api/library'; +import { libraryAdvancedSearch, libraryGetTracksByAlbum } from '@/lib/api/library'; import type { SubsonicAlbum, SubsonicArtist, SubsonicSong, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import { albumToAlbum, artistToArtist, diff --git a/src/features/offline/utils/offlineLocalBrowse.test.ts b/src/features/offline/utils/offlineLocalBrowse.test.ts index 4b6e6555..b99dd360 100644 --- a/src/features/offline/utils/offlineLocalBrowse.test.ts +++ b/src/features/offline/utils/offlineLocalBrowse.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { LibraryTrackDto } from '@/api/library'; +import type { LibraryTrackDto } from '@/lib/api/library'; import { useAuthStore } from '@/store/authStore'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; @@ -13,7 +13,7 @@ const { libraryGetTracksBatchChunkedMock } = vi.hoisted(() => ({ libraryGetTracksBatchChunkedMock: vi.fn(async (): Promise => []), })); -vi.mock('@/api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryGetTracksBatchChunked: libraryGetTracksBatchChunkedMock, libraryGetTracksByAlbum: vi.fn(async () => []), libraryAdvancedSearch: vi.fn(async () => ({ albums: [], artists: [], tracks: [] })), diff --git a/src/features/offline/utils/offlineLocalBrowse.ts b/src/features/offline/utils/offlineLocalBrowse.ts index 47557e9f..155caaf5 100644 --- a/src/features/offline/utils/offlineLocalBrowse.ts +++ b/src/features/offline/utils/offlineLocalBrowse.ts @@ -1,6 +1,6 @@ -import type { LibraryTrackDto } from '@/api/library'; -import { libraryAdvancedSearch, libraryGetTracksBatchChunked, libraryGetTracksByAlbum } from '@/api/library'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/api/subsonicTypes'; +import type { LibraryTrackDto } from '@/lib/api/library'; +import { libraryAdvancedSearch, libraryGetTracksBatchChunked, libraryGetTracksByAlbum } from '@/lib/api/library'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import type { LocalPlaybackEntry } from '@/store/localPlaybackStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; diff --git a/src/features/offline/utils/offlineMediaResolve.test.ts b/src/features/offline/utils/offlineMediaResolve.test.ts index 0f6ce5ca..c619257b 100644 --- a/src/features/offline/utils/offlineMediaResolve.test.ts +++ b/src/features/offline/utils/offlineMediaResolve.test.ts @@ -49,7 +49,7 @@ vi.mock('@/utils/network/subsonicNetworkGuard', () => ({ shouldAttemptSubsonicForServerMock(serverId, trackId), })); -vi.mock('@/api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getAlbumForServer: (serverId: string, albumId: string) => getAlbumForServerMock(serverId, albumId), })); diff --git a/src/features/offline/utils/offlineMediaResolve.ts b/src/features/offline/utils/offlineMediaResolve.ts index a2cdebf7..0e05172c 100644 --- a/src/features/offline/utils/offlineMediaResolve.ts +++ b/src/features/offline/utils/offlineMediaResolve.ts @@ -1,4 +1,4 @@ -import { getAlbumForServer } from '@/api/subsonicLibrary'; +import { getAlbumForServer } from '@/lib/api/subsonicLibrary'; import { getArtistForServer } from '@/features/artist'; import { getPlaylistForServer } from '@/features/playlist'; import type { @@ -6,7 +6,7 @@ import type { SubsonicArtist, SubsonicPlaylist, SubsonicSong, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; import { isOfflineBrowseActive } from '@/features/offline/utils/offlineBrowseMode'; diff --git a/src/features/offline/utils/offlinePinQueue.ts b/src/features/offline/utils/offlinePinQueue.ts index 8394c7f1..49283f23 100644 --- a/src/features/offline/utils/offlinePinQueue.ts +++ b/src/features/offline/utils/offlinePinQueue.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { PinSource } from '@/store/localPlaybackStore'; import { cancelledDownloads, diff --git a/src/features/offline/utils/offlinePlaylistBrowse.test.ts b/src/features/offline/utils/offlinePlaylistBrowse.test.ts index 8a57cd7c..04e616a3 100644 --- a/src/features/offline/utils/offlinePlaylistBrowse.test.ts +++ b/src/features/offline/utils/offlinePlaylistBrowse.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import * as libraryApi from '@/api/library'; +import * as libraryApi from '@/lib/api/library'; import { useAuthStore } from '@/store/authStore'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; @@ -10,7 +10,7 @@ import { playlistsOfflineBrowseEnabled, } from '@/features/offline/utils/offlinePlaylistBrowse'; -vi.mock('@/api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryGetTracksBatchChunked: vi.fn(), })); diff --git a/src/features/offline/utils/offlinePlaylistBrowse.ts b/src/features/offline/utils/offlinePlaylistBrowse.ts index 77af2675..2af15f3d 100644 --- a/src/features/offline/utils/offlinePlaylistBrowse.ts +++ b/src/features/offline/utils/offlinePlaylistBrowse.ts @@ -1,5 +1,5 @@ -import { libraryGetTracksBatchChunked } from '@/api/library'; -import type { SubsonicPlaylist, SubsonicSong } from '@/api/subsonicTypes'; +import { libraryGetTracksBatchChunked } from '@/lib/api/library'; +import type { SubsonicPlaylist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import type { PinnedGroup } from '@/store/localPlaybackStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; diff --git a/src/features/offline/utils/offlineStarredLoad.ts b/src/features/offline/utils/offlineStarredLoad.ts index 9be9ed44..dedcaa00 100644 --- a/src/features/offline/utils/offlineStarredLoad.ts +++ b/src/features/offline/utils/offlineStarredLoad.ts @@ -1,11 +1,11 @@ -import { getStarredForServer } from '@/api/subsonicStarRating'; -import { libraryAdvancedSearch } from '@/api/library'; +import { getStarredForServer } from '@/lib/api/subsonicStarRating'; +import { libraryAdvancedSearch } from '@/lib/api/library'; import type { StarredResults, SubsonicAlbum, SubsonicArtist, SubsonicSong, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import { isActiveServerReachable } from '@/utils/network/activeServerReachability'; import { albumToAlbum, diff --git a/src/features/offline/utils/pinnedOfflineSync.test.ts b/src/features/offline/utils/pinnedOfflineSync.test.ts index 426d6f0c..db6c1303 100644 --- a/src/features/offline/utils/pinnedOfflineSync.test.ts +++ b/src/features/offline/utils/pinnedOfflineSync.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; import { useOfflineJobStore } from '@/features/offline/store/offlineJobStore'; @@ -33,7 +33,7 @@ vi.mock('@/features/playlist/api/subsonicPlaylists', () => ({ getPlaylistForServer: (serverId: string, id: string) => getPlaylistMock(serverId, id), })); -vi.mock('@/api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getAlbumForServer: (serverId: string, id: string) => getAlbumForServerMock(serverId, id), filterSongsToServerLibrary: (songs: SubsonicSong[]) => filterSongsMock(songs), })); @@ -42,7 +42,7 @@ vi.mock('@/features/artist', () => ({ getArtistForServer: (serverId: string, artistId: string) => getArtistForServerMock(serverId, artistId), })); -vi.mock('@/api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryGetTracksByAlbum: vi.fn(async () => []), subscribeLibrarySyncIdle: vi.fn(async () => () => {}), })); diff --git a/src/features/offline/utils/pinnedOfflineSync.ts b/src/features/offline/utils/pinnedOfflineSync.ts index 69758e40..8cc93573 100644 --- a/src/features/offline/utils/pinnedOfflineSync.ts +++ b/src/features/offline/utils/pinnedOfflineSync.ts @@ -1,8 +1,8 @@ -import { libraryGetTracksByAlbum, subscribeLibrarySyncIdle } from '@/api/library'; -import { getAlbumForServer, filterSongsToServerLibrary } from '@/api/subsonicLibrary'; +import { libraryGetTracksByAlbum, subscribeLibrarySyncIdle } from '@/lib/api/library'; +import { getAlbumForServer, filterSongsToServerLibrary } from '@/lib/api/subsonicLibrary'; import { getPlaylistForServer } from '@/features/playlist'; import { getArtistForServer } from '@/features/artist'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { invoke } from '@tauri-apps/api/core'; import { useAuthStore } from '@/store/authStore'; import type { PinSource } from '@/store/localPlaybackStore'; diff --git a/src/features/offline/utils/resumeIncompleteOfflinePins.test.ts b/src/features/offline/utils/resumeIncompleteOfflinePins.test.ts index 7497bb3b..7e3aaa25 100644 --- a/src/features/offline/utils/resumeIncompleteOfflinePins.test.ts +++ b/src/features/offline/utils/resumeIncompleteOfflinePins.test.ts @@ -23,7 +23,7 @@ vi.mock('@/features/offline/utils/offlineMediaResolve', () => ({ resolveAlbumForServerMock(serverId, albumId), })); -vi.mock('@/api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryGetTracksBatchChunked: vi.fn(async () => []), LIBRARY_TRACKS_BATCH_LIMIT: 100, })); diff --git a/src/features/offline/utils/resumeIncompleteOfflinePins.ts b/src/features/offline/utils/resumeIncompleteOfflinePins.ts index e7e8155a..c2ace389 100644 --- a/src/features/offline/utils/resumeIncompleteOfflinePins.ts +++ b/src/features/offline/utils/resumeIncompleteOfflinePins.ts @@ -1,6 +1,6 @@ -import { libraryGetTracksBatchChunked } from '@/api/library'; +import { libraryGetTracksBatchChunked } from '@/lib/api/library'; import { getPlaylist } from '@/features/playlist'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import type { OfflineAlbumMeta } from '@/features/offline/store/offlineStore'; import { useOfflineStore } from '@/features/offline/store/offlineStore'; diff --git a/src/features/orbit/components/OrbitGuestQueue.tsx b/src/features/orbit/components/OrbitGuestQueue.tsx index 421e25e5..107dcd0b 100644 --- a/src/features/orbit/components/OrbitGuestQueue.tsx +++ b/src/features/orbit/components/OrbitGuestQueue.tsx @@ -1,5 +1,5 @@ -import { getSong } from '@/api/subsonicLibrary'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import { getSong } from '@/lib/api/subsonicLibrary'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useEffect, useMemo, useState } from 'react'; import { Radio, Clock } from 'lucide-react'; import { useTranslation } from 'react-i18next'; diff --git a/src/features/orbit/components/OrbitSessionBar.tsx b/src/features/orbit/components/OrbitSessionBar.tsx index f36e2be8..c138866f 100644 --- a/src/features/orbit/components/OrbitSessionBar.tsx +++ b/src/features/orbit/components/OrbitSessionBar.tsx @@ -1,4 +1,4 @@ -import { getSong } from '@/api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useEffect, useRef, useState } from 'react'; import { X, RefreshCw, Shuffle, Settings2, Share2, HelpCircle, Activity } from 'lucide-react'; diff --git a/src/features/orbit/hooks/useOrbitGuest.ts b/src/features/orbit/hooks/useOrbitGuest.ts index 126f53b7..61531106 100644 --- a/src/features/orbit/hooks/useOrbitGuest.ts +++ b/src/features/orbit/hooks/useOrbitGuest.ts @@ -1,4 +1,4 @@ -import { getSong } from '@/api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useEffect, useRef } from 'react'; import { useOrbitStore } from '@/features/orbit/store/orbitStore'; diff --git a/src/features/orbit/hooks/useOrbitHost.ts b/src/features/orbit/hooks/useOrbitHost.ts index d28cdaaa..f4bb4195 100644 --- a/src/features/orbit/hooks/useOrbitHost.ts +++ b/src/features/orbit/hooks/useOrbitHost.ts @@ -1,4 +1,4 @@ -import { getSong } from '@/api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useEffect } from 'react'; import { useOrbitStore } from '@/features/orbit/store/orbitStore'; diff --git a/src/features/orbit/utils/guest.ts b/src/features/orbit/utils/guest.ts index b2acc6c3..8b1a4e7a 100644 --- a/src/features/orbit/utils/guest.ts +++ b/src/features/orbit/utils/guest.ts @@ -1,5 +1,5 @@ import { createPlaylist, deletePlaylist, getPlaylist, getPlaylists, updatePlaylist } from '@/features/playlist'; -import { getSong } from '@/api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useAuthStore } from '@/store/authStore'; import { useOrbitStore } from '@/features/orbit/store/orbitStore'; diff --git a/src/features/orbit/utils/host.test.ts b/src/features/orbit/utils/host.test.ts index 7441e819..291048e8 100644 --- a/src/features/orbit/utils/host.test.ts +++ b/src/features/orbit/utils/host.test.ts @@ -25,7 +25,7 @@ vi.mock('@/features/orbit/store/orbitStore', () => ({ useOrbitStore: { getState: vi.mock('@/store/authStore', () => ({ useAuthStore: { getState: () => ({}) } })); vi.mock('@/store/playerStore', () => ({ usePlayerStore: { getState: () => ({ enqueue: vi.fn() }) } })); vi.mock('@/features/playlist', () => ({ createPlaylist: vi.fn(), deletePlaylist: vi.fn() })); -vi.mock('@/api/subsonicLibrary', () => ({ getSong: vi.fn() })); +vi.mock('@/lib/api/subsonicLibrary', () => ({ getSong: vi.fn() })); vi.mock('@/utils/playback/songToTrack', () => ({ songToTrack: vi.fn() })); import { updateOrbitSettings } from '@/features/orbit/utils/host'; diff --git a/src/features/orbit/utils/host.ts b/src/features/orbit/utils/host.ts index cc8d3d0e..d987b7b6 100644 --- a/src/features/orbit/utils/host.ts +++ b/src/features/orbit/utils/host.ts @@ -1,5 +1,5 @@ import { createPlaylist, deletePlaylist } from '@/features/playlist'; -import { getSong } from '@/api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useAuthStore } from '@/store/authStore'; import { useOrbitStore } from '@/features/orbit/store/orbitStore'; diff --git a/src/features/playlist/api/subsonicPlaylists.ts b/src/features/playlist/api/subsonicPlaylists.ts index 80d55015..c155d344 100644 --- a/src/features/playlist/api/subsonicPlaylists.ts +++ b/src/features/playlist/api/subsonicPlaylists.ts @@ -1,8 +1,8 @@ import { invoke } from '@tauri-apps/api/core'; import { useAuthStore } from '@/store/authStore'; import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; -import { api, apiForServer } from '@/api/subsonicClient'; -import type { SubsonicPlaylist, SubsonicSong } from '@/api/subsonicTypes'; +import { api, apiForServer } from '@/lib/api/subsonicClient'; +import type { SubsonicPlaylist, SubsonicSong } from '@/lib/api/subsonicTypes'; export async function getPlaylists(includeOrbit = false): Promise { const data = await api<{ playlists: { playlist: SubsonicPlaylist[] } }>('getPlaylists.view', { _t: Date.now() }); diff --git a/src/features/playlist/components/PlaylistArtistCell.test.tsx b/src/features/playlist/components/PlaylistArtistCell.test.tsx index 6e2832dc..f1067e60 100644 --- a/src/features/playlist/components/PlaylistArtistCell.test.tsx +++ b/src/features/playlist/components/PlaylistArtistCell.test.tsx @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'; import { screen } from '@testing-library/react'; import { renderWithProviders } from '@/test/helpers/renderWithProviders'; import { PlaylistArtistCell } from '@/features/playlist/components/PlaylistArtistCell'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; function song(overrides: Partial): SubsonicSong { return { diff --git a/src/features/playlist/components/PlaylistArtistCell.tsx b/src/features/playlist/components/PlaylistArtistCell.tsx index c6f529f7..50ecbe56 100644 --- a/src/features/playlist/components/PlaylistArtistCell.tsx +++ b/src/features/playlist/components/PlaylistArtistCell.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { resolveTrackArtistRefs } from '@/utils/playback/trackArtistRefs'; /** diff --git a/src/features/playlist/components/PlaylistCard.tsx b/src/features/playlist/components/PlaylistCard.tsx index 0202c19d..8475c22a 100644 --- a/src/features/playlist/components/PlaylistCard.tsx +++ b/src/features/playlist/components/PlaylistCard.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { Check, Clock3, ListMusic, Pencil, Play, Sparkles, Trash2 } from 'lucide-react'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; import { displayPlaylistName, isSmartPlaylistName, type PendingSmartPlaylist, diff --git a/src/features/playlist/components/PlaylistEditModal.tsx b/src/features/playlist/components/PlaylistEditModal.tsx index 3494bc85..79a80c2c 100644 --- a/src/features/playlist/components/PlaylistEditModal.tsx +++ b/src/features/playlist/components/PlaylistEditModal.tsx @@ -1,7 +1,7 @@ import React, { useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Camera, Loader2, X } from 'lucide-react'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import type { CoverArtId } from '@/cover/types'; import { AlbumCoverArtImage } from '@/cover/AlbumCoverArtImage'; import { PLAYLIST_MAIN_COVER_CSS_PX } from '@/features/playlist/hooks/usePlaylistCovers'; diff --git a/src/features/playlist/components/PlaylistFolderSection.tsx b/src/features/playlist/components/PlaylistFolderSection.tsx index 387e336b..799d4866 100644 --- a/src/features/playlist/components/PlaylistFolderSection.tsx +++ b/src/features/playlist/components/PlaylistFolderSection.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ChevronRight, Folder, Pencil, Trash2 } from 'lucide-react'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistFolderStore } from '@/features/playlist/store/playlistFolderStore'; import type { PlaylistFolder } from '@/features/playlist/utils/playlistFolders'; import { useDragDrop } from '@/contexts/DragDropContext'; diff --git a/src/features/playlist/components/PlaylistHero.tsx b/src/features/playlist/components/PlaylistHero.tsx index 07d47858..697ed448 100644 --- a/src/features/playlist/components/PlaylistHero.tsx +++ b/src/features/playlist/components/PlaylistHero.tsx @@ -5,7 +5,7 @@ import { Camera, ChevronLeft, Download, FileUp, Globe, HardDriveDownload, ListPlus, Loader2, Lock, Pencil, Play, Search, Shuffle, Sparkles, Trash2, } from 'lucide-react'; -import type { SubsonicPlaylist, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist, SubsonicSong } from '@/lib/api/subsonicTypes'; import type { ZipDownload } from '@/features/offline'; import type { AlbumOfflineStatus } from '@/features/album'; import { dequeueOfflinePin } from '@/features/offline'; diff --git a/src/features/playlist/components/PlaylistRow.tsx b/src/features/playlist/components/PlaylistRow.tsx index e9542aca..c96bb48b 100644 --- a/src/features/playlist/components/PlaylistRow.tsx +++ b/src/features/playlist/components/PlaylistRow.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { AudioLines, ChevronRight, Heart, Play, Square, Trash2 } from 'lucide-react'; import type { ColDef } from '@/utils/useTracklistColumns'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { codecLabel } from '@/utils/componentHelpers/playlistDetailHelpers'; import { formatLastSeen } from '@/utils/componentHelpers/userMgmtHelpers'; import i18n from '@/i18n'; diff --git a/src/features/playlist/components/PlaylistSongSearchPanel.tsx b/src/features/playlist/components/PlaylistSongSearchPanel.tsx index abe82a9f..33533c3d 100644 --- a/src/features/playlist/components/PlaylistSongSearchPanel.tsx +++ b/src/features/playlist/components/PlaylistSongSearchPanel.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { Check, ListPlus, X } from 'lucide-react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; import { songToTrack } from '@/utils/playback/songToTrack'; import { formatTrackTime } from '@/utils/format/formatDuration'; diff --git a/src/features/playlist/components/PlaylistSuggestions.tsx b/src/features/playlist/components/PlaylistSuggestions.tsx index 29688e41..4e26f4c9 100644 --- a/src/features/playlist/components/PlaylistSuggestions.tsx +++ b/src/features/playlist/components/PlaylistSuggestions.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { ChevronRight, Heart, Play, Plus, RefreshCw, Square } from 'lucide-react'; import type { ColDef } from '@/utils/useTracklistColumns'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; import { usePreviewStore } from '@/store/previewStore'; import StarRating from '@/components/StarRating'; diff --git a/src/features/playlist/components/PlaylistTracklist.tsx b/src/features/playlist/components/PlaylistTracklist.tsx index 94f24efd..fbbebb8a 100644 --- a/src/features/playlist/components/PlaylistTracklist.tsx +++ b/src/features/playlist/components/PlaylistTracklist.tsx @@ -10,7 +10,7 @@ import { ListPlus, Search, Trash2, X, } from 'lucide-react'; import type { ColDef } from '@/utils/useTracklistColumns'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; import { usePlayerStore } from '@/store/playerStore'; import { previewInputFromSong, usePreviewStore } from '@/store/previewStore'; diff --git a/src/features/playlist/components/PlaylistsFolderView.tsx b/src/features/playlist/components/PlaylistsFolderView.tsx index 9aa6ac6d..b4174803 100644 --- a/src/features/playlist/components/PlaylistsFolderView.tsx +++ b/src/features/playlist/components/PlaylistsFolderView.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { EMPTY_SERVER_FOLDERS, usePlaylistFolderStore } from '@/features/playlist/store/playlistFolderStore'; import { groupPlaylistsByFolder } from '@/features/playlist/utils/playlistFolders'; import { useDragDrop } from '@/contexts/DragDropContext'; diff --git a/src/features/playlist/components/PlaylistsHeader.tsx b/src/features/playlist/components/PlaylistsHeader.tsx index f67c739f..e0954f75 100644 --- a/src/features/playlist/components/PlaylistsHeader.tsx +++ b/src/features/playlist/components/PlaylistsHeader.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { CheckSquare2, Plus, Sparkles, Trash2 } from 'lucide-react'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { defaultSmartFilters, type SmartFilters, } from '@/features/playlist/utils/playlistsSmart'; diff --git a/src/features/playlist/hooks/usePlaylistCovers.ts b/src/features/playlist/hooks/usePlaylistCovers.ts index 2a89b89e..12d6618c 100644 --- a/src/features/playlist/hooks/usePlaylistCovers.ts +++ b/src/features/playlist/hooks/usePlaylistCovers.ts @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState } from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { CoverArtId, CoverArtRef } from '@/cover/types'; import { coverPrefetchRegister } from '@/cover/prefetchRegistry'; import { resolveAlbumCoverRefFromLibrary } from '@/cover/resolveEntryLibrary'; diff --git a/src/features/playlist/hooks/usePlaylistDerived.ts b/src/features/playlist/hooks/usePlaylistDerived.ts index d986257e..989457e3 100644 --- a/src/features/playlist/hooks/usePlaylistDerived.ts +++ b/src/features/playlist/hooks/usePlaylistDerived.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '@/store/playerStoreTypes'; import { usePlayerStore } from '@/store/playerStore'; import { songToTrack } from '@/utils/playback/songToTrack'; diff --git a/src/features/playlist/hooks/usePlaylistDnDReorder.ts b/src/features/playlist/hooks/usePlaylistDnDReorder.ts index 008668e1..66ffda99 100644 --- a/src/features/playlist/hooks/usePlaylistDnDReorder.ts +++ b/src/features/playlist/hooks/usePlaylistDnDReorder.ts @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useDragDrop } from '@/contexts/DragDropContext'; import { runPlaylistReorderDrop } from '@/features/playlist/utils/runPlaylistReorderDrop'; diff --git a/src/features/playlist/hooks/usePlaylistPreview.ts b/src/features/playlist/hooks/usePlaylistPreview.ts index c81e7bd5..17f3e67a 100644 --- a/src/features/playlist/hooks/usePlaylistPreview.ts +++ b/src/features/playlist/hooks/usePlaylistPreview.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect } from 'react'; import { previewInputFromSong, usePreviewStore } from '@/store/previewStore'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export function usePlaylistPreview(): { startPreview: (song: SubsonicSong) => void; diff --git a/src/features/playlist/hooks/usePlaylistSelection.ts b/src/features/playlist/hooks/usePlaylistSelection.ts index d2e167d8..a8a83017 100644 --- a/src/features/playlist/hooks/usePlaylistSelection.ts +++ b/src/features/playlist/hooks/usePlaylistSelection.ts @@ -1,6 +1,6 @@ import { useState } from 'react'; import type React from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export interface PlaylistSelection { selectedIds: Set; diff --git a/src/features/playlist/hooks/usePlaylistSongMutations.ts b/src/features/playlist/hooks/usePlaylistSongMutations.ts index c1fa475e..bc52457b 100644 --- a/src/features/playlist/hooks/usePlaylistSongMutations.ts +++ b/src/features/playlist/hooks/usePlaylistSongMutations.ts @@ -1,6 +1,6 @@ import type React from 'react'; import type { TFunction } from 'i18next'; -import type { SubsonicPlaylist, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { showToast } from '@/utils/ui/toast'; export interface PlaylistSongMutationsDeps { diff --git a/src/features/playlist/hooks/usePlaylistSongSearch.ts b/src/features/playlist/hooks/usePlaylistSongSearch.ts index ebd1c15c..ad60807a 100644 --- a/src/features/playlist/hooks/usePlaylistSongSearch.ts +++ b/src/features/playlist/hooks/usePlaylistSongSearch.ts @@ -1,7 +1,7 @@ import { useEffect, useRef, useState } from 'react'; import type React from 'react'; -import { search } from '@/api/subsonicSearch'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import { search } from '@/lib/api/subsonicSearch'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export interface PlaylistSongSearchResult { searchResults: SubsonicSong[]; diff --git a/src/features/playlist/hooks/usePlaylistStarRating.ts b/src/features/playlist/hooks/usePlaylistStarRating.ts index 877cbe73..f945ac78 100644 --- a/src/features/playlist/hooks/usePlaylistStarRating.ts +++ b/src/features/playlist/hooks/usePlaylistStarRating.ts @@ -1,6 +1,6 @@ import React from 'react'; import { queueSongStar, queueSongRating } from '@/store/pendingStarSync'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '@/store/playerStore'; export interface PlaylistStarRatingDeps { diff --git a/src/features/playlist/hooks/usePlaylistSuggestions.ts b/src/features/playlist/hooks/usePlaylistSuggestions.ts index f5269f38..0546c254 100644 --- a/src/features/playlist/hooks/usePlaylistSuggestions.ts +++ b/src/features/playlist/hooks/usePlaylistSuggestions.ts @@ -1,7 +1,7 @@ import { useCallback, useEffect, useState } from 'react'; import type React from 'react'; -import { getRandomSongs } from '@/api/subsonicLibrary'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import { getRandomSongs } from '@/lib/api/subsonicLibrary'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export interface PlaylistSuggestionsResult { suggestions: SubsonicSong[]; diff --git a/src/features/playlist/hooks/usePlaylistsLibraryScopeCounts.ts b/src/features/playlist/hooks/usePlaylistsLibraryScopeCounts.ts index 574a4f3f..3fe51bb9 100644 --- a/src/features/playlist/hooks/usePlaylistsLibraryScopeCounts.ts +++ b/src/features/playlist/hooks/usePlaylistsLibraryScopeCounts.ts @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; -import { filterSongsToActiveLibrary } from '@/api/subsonicLibrary'; +import { filterSongsToActiveLibrary } from '@/lib/api/subsonicLibrary'; import { getPlaylist } from '@/features/playlist/api/subsonicPlaylists'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { useOfflineBrowseContext } from '@/features/offline'; export interface PlaylistsLibraryScopeCountsResult { diff --git a/src/features/playlist/pages/PlaylistDetail.tsx b/src/features/playlist/pages/PlaylistDetail.tsx index 67df8a19..1cb840fb 100644 --- a/src/features/playlist/pages/PlaylistDetail.tsx +++ b/src/features/playlist/pages/PlaylistDetail.tsx @@ -1,5 +1,5 @@ import { updatePlaylist } from '@/features/playlist/api/subsonicPlaylists'; -import type { SubsonicPlaylist, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist, SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useEffect, useState, useCallback, useMemo } from 'react'; import { useParams, useNavigate, useLocation } from 'react-router-dom'; import { useTracklistColumns, type ColDef } from '@/utils/useTracklistColumns'; diff --git a/src/features/playlist/pages/Playlists.tsx b/src/features/playlist/pages/Playlists.tsx index 8e5b3d3d..ad303aa1 100644 --- a/src/features/playlist/pages/Playlists.tsx +++ b/src/features/playlist/pages/Playlists.tsx @@ -1,7 +1,7 @@ import { resolveMediaServerId, resolvePlaylist } from '@/features/offline'; -import { getGenres } from '@/api/subsonicGenres'; -import { filterSongsToActiveLibrary } from '@/api/subsonicLibrary'; -import type { SubsonicPlaylist, SubsonicGenre } from '@/api/subsonicTypes'; +import { getGenres } from '@/lib/api/subsonicGenres'; +import { filterSongsToActiveLibrary } from '@/lib/api/subsonicLibrary'; +import type { SubsonicPlaylist, SubsonicGenre } from '@/lib/api/subsonicTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import React, { useEffect, useState, useRef, useCallback } from 'react'; import { usePlayerStore } from '@/store/playerStore'; diff --git a/src/features/playlist/store/playlistStore.ts b/src/features/playlist/store/playlistStore.ts index f4c758d9..78f2e618 100644 --- a/src/features/playlist/store/playlistStore.ts +++ b/src/features/playlist/store/playlistStore.ts @@ -1,5 +1,5 @@ import { getPlaylists } from '@/features/playlist/api/subsonicPlaylists'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import { createPlaylist as apiCreatePlaylist } from '@/features/playlist/api/subsonicPlaylists'; diff --git a/src/features/playlist/utils/playlistDisplayedSongs.test.ts b/src/features/playlist/utils/playlistDisplayedSongs.test.ts index 3a049580..cd2bac63 100644 --- a/src/features/playlist/utils/playlistDisplayedSongs.test.ts +++ b/src/features/playlist/utils/playlistDisplayedSongs.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { getDisplayedSongs, type DisplayedSongsOptions, diff --git a/src/features/playlist/utils/playlistDisplayedSongs.ts b/src/features/playlist/utils/playlistDisplayedSongs.ts index 2bc5eedf..7857ba87 100644 --- a/src/features/playlist/utils/playlistDisplayedSongs.ts +++ b/src/features/playlist/utils/playlistDisplayedSongs.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export type PlaylistSortKey = 'natural' | 'position' | 'title' | 'artist' | 'album' | 'favorite' | 'rating' | 'duration' | 'playCount' | 'lastPlayed' | 'bpm'; export type PlaylistSortDir = 'asc' | 'desc'; diff --git a/src/features/playlist/utils/runPlaylistCsvImport.ts b/src/features/playlist/utils/runPlaylistCsvImport.ts index 8114ba12..87244f5d 100644 --- a/src/features/playlist/utils/runPlaylistCsvImport.ts +++ b/src/features/playlist/utils/runPlaylistCsvImport.ts @@ -1,8 +1,8 @@ import type { TFunction } from 'i18next'; import { open as openDialog } from '@tauri-apps/plugin-dialog'; import { readTextFile } from '@tauri-apps/plugin-fs'; -import { search } from '@/api/subsonicSearch'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import { search } from '@/lib/api/subsonicSearch'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { showToast } from '@/utils/ui/toast'; import { parseSpotifyCsv, type SpotifyCsvTrack } from '@/features/playlist/utils/spotifyCsvImport'; import { diff --git a/src/features/playlist/utils/runPlaylistLoad.ts b/src/features/playlist/utils/runPlaylistLoad.ts index 9ab0fb44..37927548 100644 --- a/src/features/playlist/utils/runPlaylistLoad.ts +++ b/src/features/playlist/utils/runPlaylistLoad.ts @@ -1,7 +1,7 @@ import type React from 'react'; import { getPlaylist } from '@/features/playlist/api/subsonicPlaylists'; -import { filterSongsToActiveLibrary } from '@/api/subsonicLibrary'; -import type { SubsonicPlaylist, SubsonicSong } from '@/api/subsonicTypes'; +import { filterSongsToActiveLibrary } from '@/lib/api/subsonicLibrary'; +import type { SubsonicPlaylist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { usePlaylistStore } from '@/features/playlist/store/playlistStore'; import { isOfflineBrowseActive } from '@/features/offline'; diff --git a/src/features/playlist/utils/runPlaylistReorderDrop.ts b/src/features/playlist/utils/runPlaylistReorderDrop.ts index 790b2306..04eb00a2 100644 --- a/src/features/playlist/utils/runPlaylistReorderDrop.ts +++ b/src/features/playlist/utils/runPlaylistReorderDrop.ts @@ -1,5 +1,5 @@ import type React from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export interface RunPlaylistReorderDropDeps { e: Event; diff --git a/src/features/playlist/utils/runPlaylistSaveMeta.ts b/src/features/playlist/utils/runPlaylistSaveMeta.ts index 16633d47..e846a375 100644 --- a/src/features/playlist/utils/runPlaylistSaveMeta.ts +++ b/src/features/playlist/utils/runPlaylistSaveMeta.ts @@ -1,6 +1,6 @@ import type { TFunction } from 'i18next'; import { getPlaylist, updatePlaylistMeta, uploadPlaylistCoverArt } from '@/features/playlist/api/subsonicPlaylists'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { showToast } from '@/utils/ui/toast'; export interface RunPlaylistSaveMetaDeps { diff --git a/src/features/playlist/utils/runPlaylistZipDownload.ts b/src/features/playlist/utils/runPlaylistZipDownload.ts index b175f4c0..5b6930a1 100644 --- a/src/features/playlist/utils/runPlaylistZipDownload.ts +++ b/src/features/playlist/utils/runPlaylistZipDownload.ts @@ -1,7 +1,7 @@ import { invoke } from '@tauri-apps/api/core'; import { join } from '@tauri-apps/api/path'; -import { buildDownloadUrl } from '@/api/subsonicStreamUrl'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { useZipDownloadStore } from '@/features/offline'; import { sanitizeFilename } from '@/utils/componentHelpers/playlistDetailHelpers'; diff --git a/src/features/playlist/utils/runPlaylistsActions.ts b/src/features/playlist/utils/runPlaylistsActions.ts index 44b93da1..af453611 100644 --- a/src/features/playlist/utils/runPlaylistsActions.ts +++ b/src/features/playlist/utils/runPlaylistsActions.ts @@ -1,7 +1,7 @@ import type React from 'react'; import type { TFunction } from 'i18next'; import { deletePlaylist, getPlaylist, updatePlaylist } from '@/features/playlist/api/subsonicPlaylists'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistStore } from '@/features/playlist/store/playlistStore'; import { showToast } from '@/utils/ui/toast'; diff --git a/src/features/playlist/utils/runPlaylistsOpenSmartEditor.ts b/src/features/playlist/utils/runPlaylistsOpenSmartEditor.ts index 05341362..7f7422d1 100644 --- a/src/features/playlist/utils/runPlaylistsOpenSmartEditor.ts +++ b/src/features/playlist/utils/runPlaylistsOpenSmartEditor.ts @@ -1,7 +1,7 @@ import type React from 'react'; import type { TFunction } from 'i18next'; -import { ndGetSmartPlaylist, ndListSmartPlaylists } from '@/api/navidromeSmart'; -import type { SubsonicGenre, SubsonicPlaylist } from '@/api/subsonicTypes'; +import { ndGetSmartPlaylist, ndListSmartPlaylists } from '@/lib/api/navidromeSmart'; +import type { SubsonicGenre, SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { defaultSmartFilters, displayPlaylistName, isSmartPlaylistName, parseSmartRulesToFilters, type SmartFilters, diff --git a/src/features/playlist/utils/runPlaylistsSaveSmart.ts b/src/features/playlist/utils/runPlaylistsSaveSmart.ts index 44be8391..988dd4c7 100644 --- a/src/features/playlist/utils/runPlaylistsSaveSmart.ts +++ b/src/features/playlist/utils/runPlaylistsSaveSmart.ts @@ -1,7 +1,7 @@ import type React from 'react'; import type { TFunction } from 'i18next'; -import { ndCreateSmartPlaylist, ndUpdateSmartPlaylist } from '@/api/navidromeSmart'; -import type { SubsonicPlaylist } from '@/api/subsonicTypes'; +import { ndCreateSmartPlaylist, ndUpdateSmartPlaylist } from '@/lib/api/navidromeSmart'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistStore } from '@/features/playlist/store/playlistStore'; import { buildSmartRulesPayload, defaultSmartFilters, SMART_PREFIX, diff --git a/src/features/playlist/utils/startPlaylistRowDrag.ts b/src/features/playlist/utils/startPlaylistRowDrag.ts index 107baf7a..ed8e9fec 100644 --- a/src/features/playlist/utils/startPlaylistRowDrag.ts +++ b/src/features/playlist/utils/startPlaylistRowDrag.ts @@ -1,5 +1,5 @@ import type React from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; export interface StartPlaylistRowDragDeps { diff --git a/src/features/radio/api/subsonicRadio.ts b/src/features/radio/api/subsonicRadio.ts index f3f27e5a..40212a97 100644 --- a/src/features/radio/api/subsonicRadio.ts +++ b/src/features/radio/api/subsonicRadio.ts @@ -1,7 +1,7 @@ import { invoke } from '@tauri-apps/api/core'; import { useAuthStore } from '@/store/authStore'; -import { api } from '@/api/subsonicClient'; -import type { InternetRadioStation, RadioBrowserStation } from '@/api/subsonicTypes'; +import { api } from '@/lib/api/subsonicClient'; +import type { InternetRadioStation, RadioBrowserStation } from '@/lib/api/subsonicTypes'; export async function getInternetRadioStations(): Promise { try { diff --git a/src/features/radio/components/RadioCard.tsx b/src/features/radio/components/RadioCard.tsx index a4ec5374..d5938e32 100644 --- a/src/features/radio/components/RadioCard.tsx +++ b/src/features/radio/components/RadioCard.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { Cast, Globe, Heart, Square, Trash2, X } from 'lucide-react'; import { open } from '@tauri-apps/plugin-shell'; -import type { InternetRadioStation } from '@/api/subsonicTypes'; +import type { InternetRadioStation } from '@/lib/api/subsonicTypes'; import { useDragDrop, useDragSource } from '@/contexts/DragDropContext'; import { CoverArtImage } from '@/cover/CoverArtImage'; import { albumCoverRef } from '@/cover/ref'; diff --git a/src/features/radio/components/RadioDirectoryModal.tsx b/src/features/radio/components/RadioDirectoryModal.tsx index 97b8f67f..da925f0b 100644 --- a/src/features/radio/components/RadioDirectoryModal.tsx +++ b/src/features/radio/components/RadioDirectoryModal.tsx @@ -8,7 +8,7 @@ import { } from '@/features/radio/api/subsonicRadio'; import { type InternetRadioStation, type RadioBrowserStation, RADIO_PAGE_SIZE, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; import { showToast } from '@/utils/ui/toast'; interface RadioDirectoryModalProps { diff --git a/src/features/radio/components/RadioEditModal.tsx b/src/features/radio/components/RadioEditModal.tsx index 8169776f..2a61e070 100644 --- a/src/features/radio/components/RadioEditModal.tsx +++ b/src/features/radio/components/RadioEditModal.tsx @@ -2,7 +2,7 @@ import React, { useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; import { Camera, Cast, Loader2, X } from 'lucide-react'; -import type { InternetRadioStation } from '@/api/subsonicTypes'; +import type { InternetRadioStation } from '@/lib/api/subsonicTypes'; import { CoverArtImage } from '@/cover/CoverArtImage'; import { albumCoverRef } from '@/cover/ref'; import { coverArtIdFromRadio } from '@/cover/ids'; diff --git a/src/features/radio/hooks/useRadioMetadata.ts b/src/features/radio/hooks/useRadioMetadata.ts index c530d82b..5d94ea29 100644 --- a/src/features/radio/hooks/useRadioMetadata.ts +++ b/src/features/radio/hooks/useRadioMetadata.ts @@ -1,4 +1,4 @@ -import type { InternetRadioStation } from '@/api/subsonicTypes'; +import type { InternetRadioStation } from '@/lib/api/subsonicTypes'; import { useEffect, useRef, useState } from 'react'; import { invoke } from '@tauri-apps/api/core'; import { usePerfProbeFlags } from '@/utils/perf/perfFlags'; diff --git a/src/features/radio/hooks/useRadioMprisSync.test.ts b/src/features/radio/hooks/useRadioMprisSync.test.ts index 863ef1cf..363a5f4e 100644 --- a/src/features/radio/hooks/useRadioMprisSync.test.ts +++ b/src/features/radio/hooks/useRadioMprisSync.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { invoke } from '@tauri-apps/api/core'; import { useRadioMprisSync } from '@/features/radio/hooks/useRadioMprisSync'; import type { RadioMetadata } from '@/features/radio/hooks/useRadioMetadata'; -import type { InternetRadioStation } from '@/api/subsonicTypes'; +import type { InternetRadioStation } from '@/lib/api/subsonicTypes'; vi.mock('@tauri-apps/api/core', () => ({ invoke: vi.fn(async () => undefined) })); const invokeMock = vi.mocked(invoke); diff --git a/src/features/radio/hooks/useRadioMprisSync.ts b/src/features/radio/hooks/useRadioMprisSync.ts index 20f4bf0f..0095cc43 100644 --- a/src/features/radio/hooks/useRadioMprisSync.ts +++ b/src/features/radio/hooks/useRadioMprisSync.ts @@ -1,6 +1,6 @@ import { useEffect, useRef } from 'react'; import { invoke } from '@tauri-apps/api/core'; -import type { InternetRadioStation } from '@/api/subsonicTypes'; +import type { InternetRadioStation } from '@/lib/api/subsonicTypes'; import type { RadioMetadata } from '@/features/radio/hooks/useRadioMetadata'; /** diff --git a/src/features/radio/pages/InternetRadio.tsx b/src/features/radio/pages/InternetRadio.tsx index b0da101e..828c7644 100644 --- a/src/features/radio/pages/InternetRadio.tsx +++ b/src/features/radio/pages/InternetRadio.tsx @@ -1,5 +1,5 @@ import { getInternetRadioStations, createInternetRadioStation, updateInternetRadioStation, deleteInternetRadioStation, uploadRadioCoverArt, deleteRadioCoverArt } from '@/features/radio/api/subsonicRadio'; -import { type InternetRadioStation } from '@/api/subsonicTypes'; +import { type InternetRadioStation } from '@/lib/api/subsonicTypes'; import React, { useEffect, useState, useMemo, useCallback } from 'react'; import { Plus, Search } from 'lucide-react'; import { usePlayerStore } from '@/store/playerStore'; diff --git a/src/features/search/components/LiveSearch.tsx b/src/features/search/components/LiveSearch.tsx index faac41f0..72612082 100644 --- a/src/features/search/components/LiveSearch.tsx +++ b/src/features/search/components/LiveSearch.tsx @@ -1,5 +1,5 @@ -import { subscribeLibrarySyncIdle, subscribeLibrarySyncProgress } from '@/api/library'; -import type { SearchResults, SubsonicArtist } from '@/api/subsonicTypes'; +import { subscribeLibrarySyncIdle, subscribeLibrarySyncProgress } from '@/lib/api/library'; +import type { SearchResults, SubsonicArtist } from '@/lib/api/subsonicTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { LIVE_SEARCH_DEBOUNCE_NETWORK_MS, @@ -30,7 +30,7 @@ import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { useTranslation } from 'react-i18next'; import { albumArtistDisplayName } from '@/features/album'; import { FETCH_QUEUE_BIAS_SEARCH_ARTIST_OVER_ALBUM } from '@/ui/CachedImage'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { AlbumCoverArtImage } from '@/cover/AlbumCoverArtImage'; import { ArtistCoverArtImage } from '@/cover/ArtistCoverArtImage'; import { CoverArtImage } from '@/cover/CoverArtImage'; diff --git a/src/features/search/components/MobileSearchOverlay.test.tsx b/src/features/search/components/MobileSearchOverlay.test.tsx index 97855bf0..9eb1570c 100644 --- a/src/features/search/components/MobileSearchOverlay.test.tsx +++ b/src/features/search/components/MobileSearchOverlay.test.tsx @@ -10,7 +10,7 @@ import { useLiveSearchScopeStore } from '@/store/liveSearchScopeStore'; // function mis-flagged as a hook). Smoke-test that the recent-search path still // applies the term to the live-search store. Heavy collaborators are stubbed. vi.mock('@/features/search/hooks/useShareSearch', () => ({ useShareSearch: () => ({ shareMatch: null }) })); -vi.mock('@/api/subsonicSearch', () => ({ +vi.mock('@/lib/api/subsonicSearch', () => ({ search: vi.fn(() => Promise.resolve({ artists: [], albums: [], songs: [] })), })); vi.mock('@/cover/AlbumCoverArtImage', () => ({ AlbumCoverArtImage: () => null })); diff --git a/src/features/search/components/MobileSearchOverlay.tsx b/src/features/search/components/MobileSearchOverlay.tsx index 6186b6d8..22f4f2be 100644 --- a/src/features/search/components/MobileSearchOverlay.tsx +++ b/src/features/search/components/MobileSearchOverlay.tsx @@ -1,5 +1,5 @@ -import { search } from '@/api/subsonicSearch'; -import type { SearchResults, SubsonicArtist } from '@/api/subsonicTypes'; +import { search } from '@/lib/api/subsonicSearch'; +import type { SearchResults, SubsonicArtist } from '@/lib/api/subsonicTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { useLiveSearchScopeStore } from '@/store/liveSearchScopeStore'; import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'; diff --git a/src/features/search/components/ShareQueuePreviewModal.tsx b/src/features/search/components/ShareQueuePreviewModal.tsx index 176135b9..ab2f2019 100644 --- a/src/features/search/components/ShareQueuePreviewModal.tsx +++ b/src/features/search/components/ShareQueuePreviewModal.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from 'react'; import { createPortal } from 'react-dom'; import { Music, X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { ServerProfile } from '@/store/authStoreTypes'; import { formatTrackTime } from '@/utils/format/formatDuration'; import type { ShareQueuePreviewState } from '@/features/search/hooks/useShareQueuePreview'; diff --git a/src/features/search/components/ShareSearchResults.tsx b/src/features/search/components/ShareSearchResults.tsx index 87bf11dd..58b91074 100644 --- a/src/features/search/components/ShareSearchResults.tsx +++ b/src/features/search/components/ShareSearchResults.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { Disc3, Eye, Link2, ListPlus, Music, Users } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import type { TFunction } from 'i18next'; -import type { SubsonicArtist } from '@/api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import type { ServerProfile } from '@/store/authStoreTypes'; import { songToTrack } from '@/utils/playback/songToTrack'; import { activateShareSearchServer } from '@/utils/share/enqueueShareSearchPayload'; diff --git a/src/features/search/hooks/useShareQueuePreview.ts b/src/features/search/hooks/useShareQueuePreview.ts index f366e5e5..03c5be0d 100644 --- a/src/features/search/hooks/useShareQueuePreview.ts +++ b/src/features/search/hooks/useShareQueuePreview.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { resolveShareSearchPayload, type ShareSearchResolveResult, diff --git a/src/features/search/hooks/useShareSearchPreview.ts b/src/features/search/hooks/useShareSearchPreview.ts index da02f660..761abdae 100644 --- a/src/features/search/hooks/useShareSearchPreview.ts +++ b/src/features/search/hooks/useShareSearchPreview.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { resolveShareSearchAlbum, resolveShareSearchArtist, diff --git a/src/features/search/pages/SearchBrowsePage.tsx b/src/features/search/pages/SearchBrowsePage.tsx index 2638df04..112a0f68 100644 --- a/src/features/search/pages/SearchBrowsePage.tsx +++ b/src/features/search/pages/SearchBrowsePage.tsx @@ -1,7 +1,7 @@ -import { getGenres, getAlbumsByGenre } from '@/api/subsonicGenres'; -import { search, searchSongsPaged } from '@/api/subsonicSearch'; -import { getRandomSongs } from '@/api/subsonicLibrary'; -import type { SubsonicGenre, SubsonicArtist, SubsonicAlbum, SubsonicSong } from '@/api/subsonicTypes'; +import { getGenres, getAlbumsByGenre } from '@/lib/api/subsonicGenres'; +import { search, searchSongsPaged } from '@/lib/api/subsonicSearch'; +import { getRandomSongs } from '@/lib/api/subsonicLibrary'; +import type { SubsonicGenre, SubsonicArtist, SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useLocation, useNavigate, useNavigationType, useSearchParams } from 'react-router-dom'; import { SlidersVertical, Search, X } from 'lucide-react'; diff --git a/src/features/settings/components/AnalyticsStrategySection.tsx b/src/features/settings/components/AnalyticsStrategySection.tsx index 646bb26f..d80ef28d 100644 --- a/src/features/settings/components/AnalyticsStrategySection.tsx +++ b/src/features/settings/components/AnalyticsStrategySection.tsx @@ -19,8 +19,8 @@ import { libraryAnalysisProgress, type LibraryAnalysisProgressDto, } from '@/api/analysis'; -import { libraryGetTracksBatch, type LibraryTrackDto, type TrackRefDto } from '@/api/library'; -import { buildStreamUrlForServer } from '@/api/subsonicStreamUrl'; +import { libraryGetTracksBatch, type LibraryTrackDto, type TrackRefDto } from '@/lib/api/library'; +import { buildStreamUrlForServer } from '@/lib/api/subsonicStreamUrl'; import { serverListDisplayLabel } from '@/utils/server/serverDisplayName'; import { serverIndexKeyForProfile } from '@/utils/server/serverIndexKey'; import { showToast } from '@/utils/ui/toast'; diff --git a/src/features/settings/components/ServerLibraryIndexControls.tsx b/src/features/settings/components/ServerLibraryIndexControls.tsx index a48079ce..81495e01 100644 --- a/src/features/settings/components/ServerLibraryIndexControls.tsx +++ b/src/features/settings/components/ServerLibraryIndexControls.tsx @@ -1,6 +1,6 @@ import { RefreshCw, ShieldCheck, WifiOff, Zap } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import type { SyncStateDto } from '@/api/library'; +import type { SyncStateDto } from '@/lib/api/library'; import { libraryStatusDisplayTrackCount, libraryStatusIsReady, diff --git a/src/features/settings/components/ServersTab.tsx b/src/features/settings/components/ServersTab.tsx index eaad76a5..2b8005fb 100644 --- a/src/features/settings/components/ServersTab.tsx +++ b/src/features/settings/components/ServersTab.tsx @@ -7,12 +7,12 @@ import { useAuthStore } from '@/store/authStore'; import { formatServerSoftware, isNavidromeAudiomuseSoftwareEligible, type InstantMixProbeResult, type SubsonicServerIdentity } from '@/utils/server/subsonicServerIdentity'; import { buildCapabilityContext } from '@/serverCapabilities/context'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; -import { libraryDeleteServerData, librarySyncClearSession } from '@/api/library'; +import { libraryDeleteServerData, librarySyncClearSession } from '@/lib/api/library'; import { bootstrapIndexedServer } from '@/utils/library/librarySession'; import { useLibraryIndexSync } from '@/hooks/useLibraryIndexSync'; import ServerLibraryIndexControls from '@/features/settings/components/ServerLibraryIndexControls'; import type { ServerProfile } from '@/store/authStoreTypes'; -import { pingWithCredentialsForProfile, scheduleInstantMixProbeForServer } from '@/api/subsonic'; +import { pingWithCredentialsForProfile, scheduleInstantMixProbeForServer } from '@/lib/api/subsonic'; import { clearServerHttpContext, syncServerHttpContextForProfile, diff --git a/src/features/settings/components/UserForm.tsx b/src/features/settings/components/UserForm.tsx index 37d838d3..4e329d6d 100644 --- a/src/features/settings/components/UserForm.tsx +++ b/src/features/settings/components/UserForm.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Shield, Wand2 } from 'lucide-react'; -import { ndUpdateUser, type NdLibrary, type NdUser } from '@/api/navidromeAdmin'; +import { ndUpdateUser, type NdLibrary, type NdUser } from '@/lib/api/navidromeAdmin'; import { showToast } from '@/utils/ui/toast'; import { copyTextToClipboard, diff --git a/src/features/settings/components/UserManagementSection.tsx b/src/features/settings/components/UserManagementSection.tsx index 2af34102..9ab539ff 100644 --- a/src/features/settings/components/UserManagementSection.tsx +++ b/src/features/settings/components/UserManagementSection.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { RotateCcw, UserPlus, Users } from 'lucide-react'; -import type { NdUser } from '@/api/navidromeAdmin'; +import type { NdUser } from '@/lib/api/navidromeAdmin'; import ConfirmModal from '@/components/ConfirmModal'; import { useUserMgmtData } from '@/features/settings/hooks/useUserMgmtData'; import { useUserMgmtActions } from '@/features/settings/hooks/useUserMgmtActions'; diff --git a/src/features/settings/components/userMgmt/MagicStringModal.tsx b/src/features/settings/components/userMgmt/MagicStringModal.tsx index 8c54afaf..53bd1276 100644 --- a/src/features/settings/components/userMgmt/MagicStringModal.tsx +++ b/src/features/settings/components/userMgmt/MagicStringModal.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { createPortal } from 'react-dom'; import { X } from 'lucide-react'; import type { TFunction } from 'i18next'; -import { ndUpdateUser, type NdUser } from '@/api/navidromeAdmin'; +import { ndUpdateUser, type NdUser } from '@/lib/api/navidromeAdmin'; import { showToast } from '@/utils/ui/toast'; import { copyTextToClipboard, diff --git a/src/features/settings/components/userMgmt/UserMgmtRow.tsx b/src/features/settings/components/userMgmt/UserMgmtRow.tsx index 6d451034..d4542ec7 100644 --- a/src/features/settings/components/userMgmt/UserMgmtRow.tsx +++ b/src/features/settings/components/userMgmt/UserMgmtRow.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Shield, Trash2, User, Wand2 } from 'lucide-react'; import type { i18n as I18nType, TFunction } from 'i18next'; -import type { NdLibrary, NdUser } from '@/api/navidromeAdmin'; +import type { NdLibrary, NdUser } from '@/lib/api/navidromeAdmin'; import { formatLastSeen } from '@/utils/componentHelpers/userMgmtHelpers'; interface Props { diff --git a/src/features/settings/hooks/useUserMgmtActions.ts b/src/features/settings/hooks/useUserMgmtActions.ts index 3883f32e..9e333729 100644 --- a/src/features/settings/hooks/useUserMgmtActions.ts +++ b/src/features/settings/hooks/useUserMgmtActions.ts @@ -7,7 +7,7 @@ import { ndUpdateUser, type NdLibrary, type NdUser, -} from '@/api/navidromeAdmin'; +} from '@/lib/api/navidromeAdmin'; import { showToast } from '@/utils/ui/toast'; import { copyTextToClipboard, diff --git a/src/features/settings/hooks/useUserMgmtData.ts b/src/features/settings/hooks/useUserMgmtData.ts index a12100a7..14fcc12b 100644 --- a/src/features/settings/hooks/useUserMgmtData.ts +++ b/src/features/settings/hooks/useUserMgmtData.ts @@ -5,7 +5,7 @@ import { ndListUsers, type NdLibrary, type NdUser, -} from '@/api/navidromeAdmin'; +} from '@/lib/api/navidromeAdmin'; interface UseUserMgmtDataResult { users: NdUser[]; diff --git a/src/features/settings/pages/Settings.tsx b/src/features/settings/pages/Settings.tsx index 8bed021f..781376fe 100644 --- a/src/features/settings/pages/Settings.tsx +++ b/src/features/settings/pages/Settings.tsx @@ -20,7 +20,7 @@ import { SystemTab } from '@/features/settings/components/SystemTab'; import { searchSettings, type SettingsSearchHit } from '@/features/settings/components/settingsSearch'; import { type Tab, resolveTab } from '@/features/settings/components/settingsTabs'; import { UserManagementSection } from '@/features/settings/components/UserManagementSection'; -import { ndLogin } from '@/api/navidromeAdmin'; +import { ndLogin } from '@/lib/api/navidromeAdmin'; import { type ServerMagicPayload } from '@/utils/server/serverMagicString'; diff --git a/src/features/sidebar/hooks/useSidebarNewReleasesUnread.ts b/src/features/sidebar/hooks/useSidebarNewReleasesUnread.ts index 3467ae67..1ef19360 100644 --- a/src/features/sidebar/hooks/useSidebarNewReleasesUnread.ts +++ b/src/features/sidebar/hooks/useSidebarNewReleasesUnread.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { getAlbumList } from '@/api/subsonicLibrary'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; import { isActiveServerReachable } from '@/utils/network/activeServerReachability'; import { NEW_RELEASES_RESET_DELAY_MS, diff --git a/src/features/stats/api/subsonicStatistics.ts b/src/features/stats/api/subsonicStatistics.ts index fc3e97b0..1b0b351a 100644 --- a/src/features/stats/api/subsonicStatistics.ts +++ b/src/features/stats/api/subsonicStatistics.ts @@ -1,7 +1,7 @@ import { useAuthStore } from '@/store/authStore'; import { genreTagsFor } from '@/utils/library/genreTags'; import { getArtists } from '@/features/artist'; -import { getAlbumList, getRandomSongs } from '@/api/subsonicLibrary'; +import { getAlbumList, getRandomSongs } from '@/lib/api/subsonicLibrary'; import type { StatisticsFormatSample, StatisticsLibraryAggregates, @@ -10,7 +10,7 @@ import type { SubsonicArtist, SubsonicGenre, SubsonicSong, -} from '@/api/subsonicTypes'; +} from '@/lib/api/subsonicTypes'; /** Cache TTL for statistics page aggregates — same 7-minute window as * the rating prefetch cache in subsonicRatings.ts. */ diff --git a/src/features/stats/components/PlayerStatisticsPanel.tsx b/src/features/stats/components/PlayerStatisticsPanel.tsx index 85949486..f793f4cc 100644 --- a/src/features/stats/components/PlayerStatisticsPanel.tsx +++ b/src/features/stats/components/PlayerStatisticsPanel.tsx @@ -7,7 +7,7 @@ import { libraryGetPlayerStatsYearSummary, type PlaySessionYearBounds, type PlaySessionYearSummary, -} from '@/api/library'; +} from '@/lib/api/library'; import { usePlayerStatsLiveRefresh } from '@/features/stats/hooks/usePlayerStatsLiveRefresh'; import { usePlayerStatsRecordingEnabled } from '@/features/stats/hooks/usePlayerStatsRecordingEnabled'; import PlayerStatsHeatmap from '@/features/stats/components/PlayerStatsHeatmap'; diff --git a/src/features/stats/components/PlayerStatsDayTracks.tsx b/src/features/stats/components/PlayerStatsDayTracks.tsx index 4d4a0527..e8b2a879 100644 --- a/src/features/stats/components/PlayerStatsDayTracks.tsx +++ b/src/features/stats/components/PlayerStatsDayTracks.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next'; -import type { PlaySessionDayDetail } from '@/api/library'; +import type { PlaySessionDayDetail } from '@/lib/api/library'; import { formatPlayerStatsListenedSec } from '@/utils/format/formatHumanDuration'; type Props = { diff --git a/src/features/stats/components/PlayerStatsRecentDays.tsx b/src/features/stats/components/PlayerStatsRecentDays.tsx index afba9106..550ec774 100644 --- a/src/features/stats/components/PlayerStatsRecentDays.tsx +++ b/src/features/stats/components/PlayerStatsRecentDays.tsx @@ -6,7 +6,7 @@ import { libraryGetPlayerStatsRecentDays, type PlaySessionDayDetail, type PlaySessionRecentDay, -} from '@/api/library'; +} from '@/lib/api/library'; import { formatPlayerStatsListeningTotal } from '@/utils/format/formatHumanDuration'; import { formatPlayerStatsDayLabel, diff --git a/src/features/stats/components/StatsExportModal.tsx b/src/features/stats/components/StatsExportModal.tsx index e13b0fd8..7a5b2336 100644 --- a/src/features/stats/components/StatsExportModal.tsx +++ b/src/features/stats/components/StatsExportModal.tsx @@ -1,5 +1,5 @@ -import { getAlbumList } from '@/api/subsonicLibrary'; -import type { SubsonicAlbum } from '@/api/subsonicTypes'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { useEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; diff --git a/src/features/stats/pages/Statistics.tsx b/src/features/stats/pages/Statistics.tsx index 88990219..d65ce88d 100644 --- a/src/features/stats/pages/Statistics.tsx +++ b/src/features/stats/pages/Statistics.tsx @@ -1,6 +1,6 @@ import { fetchStatisticsFormatSample, fetchStatisticsLibraryAggregates, fetchStatisticsOverview } from '@/features/stats/api/subsonicStatistics'; -import { getAlbumList } from '@/api/subsonicLibrary'; -import type { SubsonicAlbum, SubsonicGenre } from '@/api/subsonicTypes'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; +import type { SubsonicAlbum, SubsonicGenre } from '@/lib/api/subsonicTypes'; import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Share2 } from 'lucide-react'; diff --git a/src/features/waveform/components/WaveformSeek.test.tsx b/src/features/waveform/components/WaveformSeek.test.tsx index df563cc1..ca7ebb7d 100644 --- a/src/features/waveform/components/WaveformSeek.test.tsx +++ b/src/features/waveform/components/WaveformSeek.test.tsx @@ -8,7 +8,7 @@ */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), diff --git a/src/hooks/tauriBridge/useCliBridge.ts b/src/hooks/tauriBridge/useCliBridge.ts index 4d9a0dd4..32ff20e5 100644 --- a/src/hooks/tauriBridge/useCliBridge.ts +++ b/src/hooks/tauriBridge/useCliBridge.ts @@ -3,8 +3,8 @@ import { listen } from '@tauri-apps/api/event'; import { invoke } from '@tauri-apps/api/core'; import type { NavigateFunction } from 'react-router-dom'; import { getSimilarSongs } from '@/features/artist'; -import { getMusicFolders } from '../../api/subsonicLibrary'; -import { search as subsonicSearch } from '../../api/subsonicSearch'; +import { getMusicFolders } from '@/lib/api/subsonicLibrary'; +import { search as subsonicSearch } from '@/lib/api/subsonicSearch'; import { filterSongsForLuckyMixRatings, getMixMinRatingsConfigFromAuth } from '../../utils/mix/mixRatingFilter'; import { shuffleArray } from '../../utils/playback/shuffleArray'; import { songToTrack } from '../../utils/playback/songToTrack'; diff --git a/src/hooks/tauriBridge/useLibraryDevSyncLog.ts b/src/hooks/tauriBridge/useLibraryDevSyncLog.ts index 96deadd3..33906a6f 100644 --- a/src/hooks/tauriBridge/useLibraryDevSyncLog.ts +++ b/src/hooks/tauriBridge/useLibraryDevSyncLog.ts @@ -5,7 +5,7 @@ import { libraryGetPlaybackHint, subscribeLibrarySyncIdle, subscribeLibrarySyncProgress, -} from '../../api/library'; +} from '@/lib/api/library'; import { activeIngestStrategy, ingestParallelismNote, diff --git a/src/hooks/useConnectionStatus.test.ts b/src/hooks/useConnectionStatus.test.ts index f0e4f978..c8495f86 100644 --- a/src/hooks/useConnectionStatus.test.ts +++ b/src/hooks/useConnectionStatus.test.ts @@ -7,7 +7,7 @@ import { type PickReachableResult, } from '@/utils/server/serverEndpoint'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ pingWithCredentials: vi.fn(), pingWithCredentialsForProfile: vi.fn(), scheduleInstantMixProbeForServer: vi.fn(), @@ -17,7 +17,7 @@ vi.mock('@/utils/perf/perfFlags', () => ({ usePerfProbeFlags: () => ({ disableBackgroundPolling: false }), })); -import { pingWithCredentialsForProfile } from '@/api/subsonic'; +import { pingWithCredentialsForProfile } from '@/lib/api/subsonic'; import { useDevOfflineBrowseStore } from '@/features/offline'; import { resetActiveServerConnectionSnapshot, setConnectionStatus } from '@/utils/network/activeServerReachability'; import { useConnectionStatus } from './useConnectionStatus'; diff --git a/src/hooks/useConnectionStatus.ts b/src/hooks/useConnectionStatus.ts index 5c7b49dd..dba00c8d 100644 --- a/src/hooks/useConnectionStatus.ts +++ b/src/hooks/useConnectionStatus.ts @@ -1,6 +1,6 @@ import { useState, useEffect, useCallback, useRef, useMemo, useSyncExternalStore } from 'react'; import { useAuthStore } from '../store/authStore'; -import { scheduleInstantMixProbeForServer } from '../api/subsonic'; +import { scheduleInstantMixProbeForServer } from '@/lib/api/subsonic'; import { serverListDisplayLabel } from '../utils/server/serverDisplayName'; import { ensureConnectUrlResolved, diff --git a/src/hooks/useContextMenuRating.ts b/src/hooks/useContextMenuRating.ts index 91fe21c5..eb5d15bc 100644 --- a/src/hooks/useContextMenuRating.ts +++ b/src/hooks/useContextMenuRating.ts @@ -1,7 +1,7 @@ import { useCallback } from 'react'; -import { setRating } from '../api/subsonicStarRating'; +import { setRating } from '@/lib/api/subsonicStarRating'; import { queueSongRating } from '../store/pendingStarSync'; -import type { SubsonicAlbum, SubsonicArtist } from '../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist } from '@/lib/api/subsonicTypes'; import type { Track } from '../store/playerStoreTypes'; import { useAuthStore } from '../store/authStore'; import { showToast } from '../utils/ui/toast'; diff --git a/src/hooks/useFolderBrowserKeyboardNav.ts b/src/hooks/useFolderBrowserKeyboardNav.ts index ec70c9ac..b0d12351 100644 --- a/src/hooks/useFolderBrowserKeyboardNav.ts +++ b/src/hooks/useFolderBrowserKeyboardNav.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import type { SubsonicDirectoryEntry } from '../api/subsonicTypes'; +import type { SubsonicDirectoryEntry } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '../store/playerStore'; import { entryToTrack, folderBrowserHasKeyModifiers, isFolderBrowserArrowKey, diff --git a/src/hooks/useFolderBrowserNowPlayingPath.ts b/src/hooks/useFolderBrowserNowPlayingPath.ts index 0289e3b1..e9708e77 100644 --- a/src/hooks/useFolderBrowserNowPlayingPath.ts +++ b/src/hooks/useFolderBrowserNowPlayingPath.ts @@ -1,7 +1,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { useLocation } from 'react-router-dom'; -import { getMusicDirectory, getMusicIndexes } from '../api/subsonicLibrary'; -import type { SubsonicDirectoryEntry } from '../api/subsonicTypes'; +import { getMusicDirectory, getMusicIndexes } from '@/lib/api/subsonicLibrary'; +import type { SubsonicDirectoryEntry } from '@/lib/api/subsonicTypes'; import type { Track } from '../store/playerStoreTypes'; import type { Column, NavPos } from '../utils/componentHelpers/folderBrowserHelpers'; diff --git a/src/hooks/useLibraryIgnoredArticles.ts b/src/hooks/useLibraryIgnoredArticles.ts index be0208db..1d698f9c 100644 --- a/src/hooks/useLibraryIgnoredArticles.ts +++ b/src/hooks/useLibraryIgnoredArticles.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { libraryGetStatus } from '../api/library'; +import { libraryGetStatus } from '@/lib/api/library'; /** * Server `ignoredArticles` (Navidrome `getArtists` watermark) for the active diff --git a/src/hooks/useLibraryIndexSync.ts b/src/hooks/useLibraryIndexSync.ts index 1b221400..e519a6ef 100644 --- a/src/hooks/useLibraryIndexSync.ts +++ b/src/hooks/useLibraryIndexSync.ts @@ -10,7 +10,7 @@ import { subscribeLibrarySyncIdle, subscribeLibrarySyncProgress, type SyncStateDto, -} from '../api/library'; +} from '@/lib/api/library'; import { bootstrapAllIndexedServers, bootstrapIndexedServer, diff --git a/src/hooks/useLyrics.ts b/src/hooks/useLyrics.ts index 1634b2a1..af76bbe0 100644 --- a/src/hooks/useLyrics.ts +++ b/src/hooks/useLyrics.ts @@ -1,5 +1,5 @@ -import { getLyricsBySongId } from '../api/subsonicLyrics'; -import type { SubsonicStructuredLyrics } from '../api/subsonicTypes'; +import { getLyricsBySongId } from '@/lib/api/subsonicLyrics'; +import type { SubsonicStructuredLyrics } from '@/lib/api/subsonicTypes'; import type { Track } from '../store/playerStoreTypes'; import { useEffect, useState } from 'react'; import { useShallow } from 'zustand/react/shallow'; diff --git a/src/hooks/useMigrationOrchestrator.test.ts b/src/hooks/useMigrationOrchestrator.test.ts index 3081e68c..53dc49c8 100644 --- a/src/hooks/useMigrationOrchestrator.test.ts +++ b/src/hooks/useMigrationOrchestrator.test.ts @@ -18,7 +18,7 @@ vi.mock('../api/migration', () => ({ migrationRun: (mappings: unknown) => migrationRunMock(mappings), })); -vi.mock('../api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryGenreTagsInspect: () => libraryGenreTagsInspectMock(), libraryGenreTagsRun: () => libraryGenreTagsRunMock(), })); diff --git a/src/hooks/useMigrationOrchestrator.ts b/src/hooks/useMigrationOrchestrator.ts index c9c09f00..7898d5c7 100644 --- a/src/hooks/useMigrationOrchestrator.ts +++ b/src/hooks/useMigrationOrchestrator.ts @@ -1,6 +1,6 @@ import { useEffect } from 'react'; import { listen } from '@tauri-apps/api/event'; -import { libraryGenreTagsInspect, libraryGenreTagsRun } from '../api/library'; +import { libraryGenreTagsInspect, libraryGenreTagsRun } from '@/lib/api/library'; import { migrationInspect, migrationRun, type ServerIndexMapping } from '../api/migration'; import { useAuthStore } from '../store/authStore'; import { useMigrationStore } from '../store/migrationStore'; diff --git a/src/hooks/useNavidromeAdminRole.test.ts b/src/hooks/useNavidromeAdminRole.test.ts index de0b954a..355a9cfc 100644 --- a/src/hooks/useNavidromeAdminRole.test.ts +++ b/src/hooks/useNavidromeAdminRole.test.ts @@ -3,11 +3,11 @@ import { renderHook, waitFor } from '@testing-library/react'; import { resetAuthStore } from '@/test/helpers/storeReset'; import { useAuthStore } from '@/store/authStore'; -vi.mock('@/api/navidromeAdmin', () => ({ +vi.mock('@/lib/api/navidromeAdmin', () => ({ ndLogin: vi.fn(), })); -import { ndLogin } from '@/api/navidromeAdmin'; +import { ndLogin } from '@/lib/api/navidromeAdmin'; import { useNavidromeAdminRole, canManageNavidromeRadio } from './useNavidromeAdminRole'; beforeEach(() => { diff --git a/src/hooks/useNavidromeAdminRole.ts b/src/hooks/useNavidromeAdminRole.ts index 5637f039..fe55e36d 100644 --- a/src/hooks/useNavidromeAdminRole.ts +++ b/src/hooks/useNavidromeAdminRole.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { ndLogin } from '../api/navidromeAdmin'; +import { ndLogin } from '@/lib/api/navidromeAdmin'; import { useAuthStore } from '../store/authStore'; import { isNavidromeServer } from '../utils/server/subsonicServerIdentity'; diff --git a/src/hooks/usePendingSmartPolling.ts b/src/hooks/usePendingSmartPolling.ts index 6a923a95..6421310d 100644 --- a/src/hooks/usePendingSmartPolling.ts +++ b/src/hooks/usePendingSmartPolling.ts @@ -1,7 +1,7 @@ import { useEffect } from 'react'; import type React from 'react'; import { getPlaylist } from '@/features/playlist'; -import type { SubsonicPlaylist } from '../api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { usePlaylistStore } from '@/features/playlist'; import type { PendingSmartPlaylist } from '@/features/playlist'; diff --git a/src/hooks/useQueueTrackEnrichment.ts b/src/hooks/useQueueTrackEnrichment.ts index e0592d68..48cf02c2 100644 --- a/src/hooks/useQueueTrackEnrichment.ts +++ b/src/hooks/useQueueTrackEnrichment.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { listen } from '@tauri-apps/api/event'; -import { libraryGetFacts, libraryGetTrack } from '../api/library'; +import { libraryGetFacts, libraryGetTrack } from '@/lib/api/library'; import { usePlaybackServerId } from './usePlaybackServerId'; import { useLibraryIndexStore } from '../store/libraryIndexStore'; import { diff --git a/src/hooks/useServerCapabilitiesProbe.ts b/src/hooks/useServerCapabilitiesProbe.ts index c662fbd5..986b5795 100644 --- a/src/hooks/useServerCapabilitiesProbe.ts +++ b/src/hooks/useServerCapabilitiesProbe.ts @@ -1,6 +1,6 @@ import { useEffect } from 'react'; -import { getMusicFolders } from '../api/subsonicLibrary'; -import { probeEntityRatingSupport } from '../api/subsonicStarRating'; +import { getMusicFolders } from '@/lib/api/subsonicLibrary'; +import { probeEntityRatingSupport } from '@/lib/api/subsonicStarRating'; import { useAuthStore } from '../store/authStore'; import { cleanupOrphanedOrbitPlaylists } from '@/features/orbit'; diff --git a/src/hooks/useSmartCoverCollage.ts b/src/hooks/useSmartCoverCollage.ts index 9321cec2..978d3155 100644 --- a/src/hooks/useSmartCoverCollage.ts +++ b/src/hooks/useSmartCoverCollage.ts @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; -import { filterSongsToActiveLibrary } from '../api/subsonicLibrary'; +import { filterSongsToActiveLibrary } from '@/lib/api/subsonicLibrary'; import { getPlaylist } from '@/features/playlist'; -import type { SubsonicPlaylist } from '../api/subsonicTypes'; +import type { SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { isSmartPlaylistName } from '@/features/playlist'; /** diff --git a/src/hooks/useSongBrowseList.test.ts b/src/hooks/useSongBrowseList.test.ts index 06e62204..04e6e01d 100644 --- a/src/hooks/useSongBrowseList.test.ts +++ b/src/hooks/useSongBrowseList.test.ts @@ -1,16 +1,16 @@ // @vitest-environment jsdom import { renderHook, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useSongBrowseList } from './useSongBrowseList'; import { useAuthStore } from '../store/authStore'; import { useLibraryIndexStore } from '../store/libraryIndexStore'; -vi.mock('../api/subsonicSearch', () => ({ +vi.mock('@/lib/api/subsonicSearch', () => ({ searchSongsPaged: vi.fn(async () => []), })); -vi.mock('../api/navidromeBrowse', () => ({ +vi.mock('@/lib/api/navidromeBrowse', () => ({ ndListSongs: vi.fn(async () => []), })); diff --git a/src/hooks/useSongBrowseList.ts b/src/hooks/useSongBrowseList.ts index 4eeb8d5a..ca4cc9ae 100644 --- a/src/hooks/useSongBrowseList.ts +++ b/src/hooks/useSongBrowseList.ts @@ -1,7 +1,7 @@ -import { searchSongsPaged } from '../api/subsonicSearch'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import { searchSongsPaged } from '@/lib/api/subsonicSearch'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { ndListSongs } from '../api/navidromeBrowse'; +import { ndListSongs } from '@/lib/api/navidromeBrowse'; import { runLocalSongBrowse } from '../utils/library/advancedSearchLocal'; import { BROWSE_TEXT_DEBOUNCE_NETWORK_MS, diff --git a/src/hooks/useTimelinePlayHistory.test.ts b/src/hooks/useTimelinePlayHistory.test.ts index 91178237..f66c3b86 100644 --- a/src/hooks/useTimelinePlayHistory.test.ts +++ b/src/hooks/useTimelinePlayHistory.test.ts @@ -8,7 +8,7 @@ import { ensureTimelineBootstrap, } from './useTimelinePlayHistory'; -vi.mock('../api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryGetRecentPlaySessions: vi.fn(async () => []), TIMELINE_HISTORY_BOOTSTRAP_LIMIT: 50, })); @@ -22,7 +22,7 @@ vi.mock('../utils/library/queueTrackResolver', async importOriginal => { return { ...actual, seedQueueResolver: vi.fn() }; }); -import { libraryGetRecentPlaySessions } from '../api/library'; +import { libraryGetRecentPlaySessions } from '@/lib/api/library'; import { timelineBootstrapIndexReady } from '../utils/queue/timelineBootstrapReady'; describe('ensureTimelineBootstrap', () => { diff --git a/src/hooks/useTimelinePlayHistory.ts b/src/hooks/useTimelinePlayHistory.ts index d8d964cf..da4a5560 100644 --- a/src/hooks/useTimelinePlayHistory.ts +++ b/src/hooks/useTimelinePlayHistory.ts @@ -1,5 +1,5 @@ import { useEffect, useMemo, useSyncExternalStore } from 'react'; -import { libraryGetRecentPlaySessions, type PlaySessionRecentTrack } from '../api/library'; +import { libraryGetRecentPlaySessions, type PlaySessionRecentTrack } from '@/lib/api/library'; import { seedQueueResolver, resolveBatch } from '../utils/library/queueTrackResolver'; import { applyTimelineBootstrap, diff --git a/src/hotCachePrefetch.ts b/src/hotCachePrefetch.ts index be81f696..df22ba09 100644 --- a/src/hotCachePrefetch.ts +++ b/src/hotCachePrefetch.ts @@ -1,4 +1,4 @@ -import { buildStreamUrlForServer } from './api/subsonicStreamUrl'; +import { buildStreamUrlForServer } from '@/lib/api/subsonicStreamUrl'; import { getPlaybackCacheServerKey } from './utils/playback/playbackServer'; import type { QueueItemRef } from './store/playerStoreTypes'; import { resolveQueueTrack } from './utils/library/queueTrackView'; diff --git a/src/api/library.ts b/src/lib/api/library.ts similarity index 99% rename from src/api/library.ts rename to src/lib/api/library.ts index 8d1ea909..7333fffa 100644 --- a/src/api/library.ts +++ b/src/lib/api/library.ts @@ -8,9 +8,9 @@ import { invoke } from '@tauri-apps/api/core'; import { listen, type UnlistenFn } from '@tauri-apps/api/event'; -import { useAuthStore } from '../store/authStore'; -import { serverIndexKeyFromUrl } from '../utils/server/serverIndexKey'; -import { resolveServerIdForIndexKey } from '../utils/server/serverLookup'; +import { useAuthStore } from '@/store/authStore'; +import { serverIndexKeyFromUrl } from '@/utils/server/serverIndexKey'; +import { resolveServerIdForIndexKey } from '@/utils/server/serverLookup'; // ── DTO mirrors (camelCase, matching the Rust `#[serde(rename_all = "camelCase")]`) ─ diff --git a/src/api/navidromeAdmin.ts b/src/lib/api/navidromeAdmin.ts similarity index 100% rename from src/api/navidromeAdmin.ts rename to src/lib/api/navidromeAdmin.ts diff --git a/src/api/navidromeBrowse.ts b/src/lib/api/navidromeBrowse.ts similarity index 98% rename from src/api/navidromeBrowse.ts rename to src/lib/api/navidromeBrowse.ts index c504f28b..897c64ae 100644 --- a/src/api/navidromeBrowse.ts +++ b/src/lib/api/navidromeBrowse.ts @@ -1,8 +1,8 @@ -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from './subsonicTypes'; -import { parseItemGenres } from '../utils/library/genreTags'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; +import { parseItemGenres } from '@/utils/library/genreTags'; import { invoke } from '@tauri-apps/api/core'; -import { useAuthStore } from '../store/authStore'; -import { ndLogin } from './navidromeAdmin'; +import { useAuthStore } from '@/store/authStore'; +import { ndLogin } from '@/lib/api/navidromeAdmin'; /** Server-keyed Bearer token cache. Cheap to keep — Navidrome tokens are long-lived. */ let cachedToken: { serverUrl: string; token: string } | null = null; diff --git a/src/api/navidromeSmart.ts b/src/lib/api/navidromeSmart.ts similarity index 97% rename from src/api/navidromeSmart.ts rename to src/lib/api/navidromeSmart.ts index 23ecc6c0..c135bac7 100644 --- a/src/api/navidromeSmart.ts +++ b/src/lib/api/navidromeSmart.ts @@ -1,6 +1,6 @@ import { invoke } from '@tauri-apps/api/core'; -import { useAuthStore } from '../store/authStore'; -import { ndLogin } from './navidromeAdmin'; +import { useAuthStore } from '@/store/authStore'; +import { ndLogin } from '@/lib/api/navidromeAdmin'; export type SmartRuleOperator = | 'is' diff --git a/src/api/subsonic.async.test.ts b/src/lib/api/subsonic.async.test.ts similarity index 98% rename from src/api/subsonic.async.test.ts rename to src/lib/api/subsonic.async.test.ts index 3680f3bd..6c168c41 100644 --- a/src/api/subsonic.async.test.ts +++ b/src/lib/api/subsonic.async.test.ts @@ -20,17 +20,17 @@ vi.mock('axios', () => ({ default: { get: vi.fn() }, })); -vi.mock('../utils/network/subsonicNetworkGuard', () => ({ +vi.mock('@/utils/network/subsonicNetworkGuard', () => ({ shouldAttemptSubsonicForActiveServer: () => true, shouldAttemptSubsonicForServer: () => true, })); import axios from 'axios'; -import { pingWithCredentials, pingWithCredentialsForProfile, ping } from './subsonic'; +import { pingWithCredentials, pingWithCredentialsForProfile, ping } from '@/lib/api/subsonic'; import { getAlbumInfo2 } from '@/features/album'; -import { getStarred } from './subsonicStarRating'; -import { search } from './subsonicSearch'; -import { getAlbum, getMusicDirectory, getMusicFolders, getMusicIndexes, getRandomSongs, getSong } from './subsonicLibrary'; +import { getStarred } from '@/lib/api/subsonicStarRating'; +import { search } from '@/lib/api/subsonicSearch'; +import { getAlbum, getMusicDirectory, getMusicFolders, getMusicIndexes, getRandomSongs, getSong } from '@/lib/api/subsonicLibrary'; import { getArtists, getTopSongs } from '@/features/artist'; import { useAuthStore } from '@/store/authStore'; import { resetAuthStore } from '@/test/helpers/storeReset'; diff --git a/src/api/subsonic.contract.test.ts b/src/lib/api/subsonic.contract.test.ts similarity index 98% rename from src/api/subsonic.contract.test.ts rename to src/lib/api/subsonic.contract.test.ts index f3e9cb2e..bbc8b11c 100644 --- a/src/api/subsonic.contract.test.ts +++ b/src/lib/api/subsonic.contract.test.ts @@ -17,10 +17,10 @@ import { buildStreamUrl, coverArtCacheKey, coverArtCacheKeyForServer, -} from './subsonicStreamUrl'; +} from '@/lib/api/subsonicStreamUrl'; import { beforeEach, describe, expect, it } from 'vitest'; -import { parseSubsonicEntityStarRating } from './subsonicRatings'; -import { getClient, libraryFilterParams, libraryScopeForServer } from './subsonicClient'; +import { parseSubsonicEntityStarRating } from '@/lib/api/subsonicRatings'; +import { getClient, libraryFilterParams, libraryScopeForServer } from '@/lib/api/subsonicClient'; import { useAuthStore } from '@/store/authStore'; import { resetAuthStore } from '@/test/helpers/storeReset'; diff --git a/src/api/subsonic.scheduleProbe.test.ts b/src/lib/api/subsonic.scheduleProbe.test.ts similarity index 93% rename from src/api/subsonic.scheduleProbe.test.ts rename to src/lib/api/subsonic.scheduleProbe.test.ts index c93a59dd..18e173ea 100644 --- a/src/api/subsonic.scheduleProbe.test.ts +++ b/src/lib/api/subsonic.scheduleProbe.test.ts @@ -1,13 +1,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('./subsonicOpenSubsonic', () => ({ +vi.mock('@/lib/api/subsonicOpenSubsonic', () => ({ fetchOpenSubsonicExtensionsWithCredentials: vi.fn(), })); -import { fetchOpenSubsonicExtensionsWithCredentials } from './subsonicOpenSubsonic'; -import { scheduleInstantMixProbeForServer } from './subsonic'; -import { useAuthStore } from '../store/authStore'; -import type { SubsonicServerIdentity } from '../utils/server/subsonicServerIdentity'; +import { fetchOpenSubsonicExtensionsWithCredentials } from '@/lib/api/subsonicOpenSubsonic'; +import { scheduleInstantMixProbeForServer } from '@/lib/api/subsonic'; +import { useAuthStore } from '@/store/authStore'; +import type { SubsonicServerIdentity } from '@/utils/server/subsonicServerIdentity'; const fetchMock = vi.mocked(fetchOpenSubsonicExtensionsWithCredentials); const SID = 'srv-probe'; diff --git a/src/api/subsonic.ts b/src/lib/api/subsonic.ts similarity index 92% rename from src/api/subsonic.ts rename to src/lib/api/subsonic.ts index bbb4bcbf..da45c2b0 100644 --- a/src/api/subsonic.ts +++ b/src/lib/api/subsonic.ts @@ -1,30 +1,30 @@ import axios from 'axios'; import md5 from 'md5'; -import { useAuthStore } from '../store/authStore'; -import type { ServerProfile } from '../store/authStoreTypes'; -import { headersForServerRequest } from '../utils/server/serverHttpHeaders'; -import { findServerByIdOrIndexKey } from '../utils/server/serverLookup'; +import { useAuthStore } from '@/store/authStore'; +import type { ServerProfile } from '@/store/authStoreTypes'; +import { headersForServerRequest } from '@/utils/server/serverHttpHeaders'; +import { findServerByIdOrIndexKey } from '@/utils/server/serverLookup'; import { type InstantMixProbeResult, type SubsonicServerIdentity, -} from '../utils/server/subsonicServerIdentity'; -import { fetchOpenSubsonicExtensionsWithCredentials } from './subsonicOpenSubsonic'; -import { buildCapabilityContext } from '../serverCapabilities/context'; +} from '@/utils/server/subsonicServerIdentity'; +import { fetchOpenSubsonicExtensionsWithCredentials } from '@/lib/api/subsonicOpenSubsonic'; +import { buildCapabilityContext } from '@/serverCapabilities/context'; import { PROBE_LEGACY_INSTANT_MIX, PROBE_OPENSUBSONIC_EXTENSIONS, SERVER_CAPABILITY_CATALOG, SONIC_SIMILARITY_EXTENSION, -} from '../serverCapabilities/catalog'; -import { neededProbeIds } from '../serverCapabilities/resolve'; +} from '@/serverCapabilities/catalog'; +import { neededProbeIds } from '@/serverCapabilities/resolve'; import { SUBSONIC_CLIENT, api, apiWithCredentials, secureRandomSalt, type ServerHttpHeaderProfile, -} from './subsonicClient'; -import type { PingWithCredentialsResult, SubsonicSong } from './subsonicTypes'; +} from '@/lib/api/subsonicClient'; +import type { PingWithCredentialsResult, SubsonicSong } from '@/lib/api/subsonicTypes'; export async function ping(): Promise { try { diff --git a/src/api/subsonicClient.ts b/src/lib/api/subsonicClient.ts similarity index 93% rename from src/api/subsonicClient.ts rename to src/lib/api/subsonicClient.ts index d3dd6a1c..1d91e9a3 100644 --- a/src/api/subsonicClient.ts +++ b/src/lib/api/subsonicClient.ts @@ -1,11 +1,11 @@ import axios from 'axios'; import md5 from 'md5'; -import { version } from '../../package.json'; -import { useAuthStore } from '../store/authStore'; -import type { ServerProfile } from '../store/authStoreTypes'; -import { connectBaseUrlForServer } from '../utils/server/serverEndpoint'; -import { headersForServerRequest } from '../utils/server/serverHttpHeaders'; -import { findServerByIdOrIndexKey, resolveServerIdForIndexKey } from '../utils/server/serverLookup'; +import { version } from '@/../package.json'; +import { useAuthStore } from '@/store/authStore'; +import type { ServerProfile } from '@/store/authStoreTypes'; +import { connectBaseUrlForServer } from '@/utils/server/serverEndpoint'; +import { headersForServerRequest } from '@/utils/server/serverHttpHeaders'; +import { findServerByIdOrIndexKey, resolveServerIdForIndexKey } from '@/utils/server/serverLookup'; export const SUBSONIC_CLIENT = `psysonic/${version}`; diff --git a/src/api/subsonicEntityWithCredentials.ts b/src/lib/api/subsonicEntityWithCredentials.ts similarity index 96% rename from src/api/subsonicEntityWithCredentials.ts rename to src/lib/api/subsonicEntityWithCredentials.ts index dc96aaf5..b55ff5de 100644 --- a/src/api/subsonicEntityWithCredentials.ts +++ b/src/lib/api/subsonicEntityWithCredentials.ts @@ -1,5 +1,5 @@ -import { apiWithCredentials, type ServerHttpHeaderProfile } from './subsonicClient'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from './subsonicTypes'; +import { apiWithCredentials, type ServerHttpHeaderProfile } from '@/lib/api/subsonicClient'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; export async function getSongWithCredentials( serverUrl: string, diff --git a/src/api/subsonicGenres.test.ts b/src/lib/api/subsonicGenres.test.ts similarity index 90% rename from src/api/subsonicGenres.test.ts rename to src/lib/api/subsonicGenres.test.ts index 72f78c86..ef7779b0 100644 --- a/src/api/subsonicGenres.test.ts +++ b/src/lib/api/subsonicGenres.test.ts @@ -1,10 +1,10 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { fetchAllSongsByGenre, getSongsByGenre } from './subsonicGenres'; -import type { SubsonicSong } from './subsonicTypes'; +import { fetchAllSongsByGenre, getSongsByGenre } from '@/lib/api/subsonicGenres'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; const { apiMock } = vi.hoisted(() => ({ apiMock: vi.fn() })); -vi.mock('./subsonicClient', () => ({ +vi.mock('@/lib/api/subsonicClient', () => ({ api: apiMock, libraryFilterParams: () => ({}), })); diff --git a/src/api/subsonicGenres.ts b/src/lib/api/subsonicGenres.ts similarity index 95% rename from src/api/subsonicGenres.ts rename to src/lib/api/subsonicGenres.ts index 3f10fc8f..85abcceb 100644 --- a/src/api/subsonicGenres.ts +++ b/src/lib/api/subsonicGenres.ts @@ -1,5 +1,5 @@ -import { api, libraryFilterParams } from './subsonicClient'; -import type { SubsonicAlbum, SubsonicGenre, SubsonicSong } from './subsonicTypes'; +import { api, libraryFilterParams } from '@/lib/api/subsonicClient'; +import type { SubsonicAlbum, SubsonicGenre, SubsonicSong } from '@/lib/api/subsonicTypes'; export async function getGenres(): Promise { const data = await api<{ genres: { genre: SubsonicGenre | SubsonicGenre[] } }>('getGenres.view', { diff --git a/src/api/subsonicLibrary.ts b/src/lib/api/subsonicLibrary.ts similarity index 98% rename from src/api/subsonicLibrary.ts rename to src/lib/api/subsonicLibrary.ts index f4313275..3b594a3c 100644 --- a/src/api/subsonicLibrary.ts +++ b/src/lib/api/subsonicLibrary.ts @@ -1,9 +1,9 @@ -import { useAuthStore } from '../store/authStore'; +import { useAuthStore } from '@/store/authStore'; import { shouldAttemptSubsonicForActiveServer, shouldAttemptSubsonicForServer, -} from '../utils/network/subsonicNetworkGuard'; -import { api, apiForServer, libraryFilterParams, libraryFilterParamsForServer } from './subsonicClient'; +} from '@/utils/network/subsonicNetworkGuard'; +import { api, apiForServer, libraryFilterParams, libraryFilterParamsForServer } from '@/lib/api/subsonicClient'; import type { RandomSongsFilters, SubsonicAlbum, @@ -11,7 +11,7 @@ import type { SubsonicDirectoryEntry, SubsonicMusicFolder, SubsonicSong, -} from './subsonicTypes'; +} from '@/lib/api/subsonicTypes'; export async function getMusicDirectory(id: string): Promise { const data = await api<{ directory: { id: string; parent?: string; name: string; child?: SubsonicDirectoryEntry | SubsonicDirectoryEntry[] } }>( diff --git a/src/api/subsonicLibraryAlbumScope.test.ts b/src/lib/api/subsonicLibraryAlbumScope.test.ts similarity index 82% rename from src/api/subsonicLibraryAlbumScope.test.ts rename to src/lib/api/subsonicLibraryAlbumScope.test.ts index 01cd9511..8c678fda 100644 --- a/src/api/subsonicLibraryAlbumScope.test.ts +++ b/src/lib/api/subsonicLibraryAlbumScope.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import type { SubsonicAlbum } from './subsonicTypes'; -import { filterAlbumsByScopedAlbumIds } from './subsonicLibrary'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; +import { filterAlbumsByScopedAlbumIds } from '@/lib/api/subsonicLibrary'; const album = (id: string): SubsonicAlbum => ({ id, diff --git a/src/api/subsonicLyrics.ts b/src/lib/api/subsonicLyrics.ts similarity index 86% rename from src/api/subsonicLyrics.ts rename to src/lib/api/subsonicLyrics.ts index 7a3f2b51..dbf47fd4 100644 --- a/src/api/subsonicLyrics.ts +++ b/src/lib/api/subsonicLyrics.ts @@ -1,5 +1,5 @@ -import { api } from './subsonicClient'; -import type { SubsonicStructuredLyrics } from './subsonicTypes'; +import { api } from '@/lib/api/subsonicClient'; +import type { SubsonicStructuredLyrics } from '@/lib/api/subsonicTypes'; /** * Fetches structured lyrics from the server's embedded tags via the diff --git a/src/api/subsonicOpenSubsonic.test.ts b/src/lib/api/subsonicOpenSubsonic.test.ts similarity index 98% rename from src/api/subsonicOpenSubsonic.test.ts rename to src/lib/api/subsonicOpenSubsonic.test.ts index 3c02f8a1..9b0c4134 100644 --- a/src/api/subsonicOpenSubsonic.test.ts +++ b/src/lib/api/subsonicOpenSubsonic.test.ts @@ -4,7 +4,7 @@ import { fetchOpenSubsonicExtensionsWithCredentials, hasOpenSubsonicExtension, parseOpenSubsonicExtensions, -} from './subsonicOpenSubsonic'; +} from '@/lib/api/subsonicOpenSubsonic'; vi.mock('axios'); diff --git a/src/api/subsonicOpenSubsonic.ts b/src/lib/api/subsonicOpenSubsonic.ts similarity index 98% rename from src/api/subsonicOpenSubsonic.ts rename to src/lib/api/subsonicOpenSubsonic.ts index beb51385..5cf700a6 100644 --- a/src/api/subsonicOpenSubsonic.ts +++ b/src/lib/api/subsonicOpenSubsonic.ts @@ -1,4 +1,4 @@ -import { apiWithCredentials, type ServerHttpHeaderProfile } from './subsonicClient'; +import { apiWithCredentials, type ServerHttpHeaderProfile } from '@/lib/api/subsonicClient'; export interface OpenSubsonicExtension { name: string; diff --git a/src/api/subsonicPlayQueue.ts b/src/lib/api/subsonicPlayQueue.ts similarity index 92% rename from src/api/subsonicPlayQueue.ts rename to src/lib/api/subsonicPlayQueue.ts index b93a6d3a..1bfaaa71 100644 --- a/src/api/subsonicPlayQueue.ts +++ b/src/lib/api/subsonicPlayQueue.ts @@ -1,5 +1,5 @@ -import { api, apiForServer } from './subsonicClient'; -import type { SubsonicSong } from './subsonicTypes'; +import { api, apiForServer } from '@/lib/api/subsonicClient'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; export type PlayQueueResult = { current?: string; position?: number; songs: SubsonicSong[] }; diff --git a/src/api/subsonicRatings.test.ts b/src/lib/api/subsonicRatings.test.ts similarity index 91% rename from src/api/subsonicRatings.test.ts rename to src/lib/api/subsonicRatings.test.ts index 295d6e77..f47074c2 100644 --- a/src/api/subsonicRatings.test.ts +++ b/src/lib/api/subsonicRatings.test.ts @@ -1,13 +1,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; vi.mock('@/features/artist', () => ({ getArtist: vi.fn() })); -vi.mock('./subsonicLibrary', () => ({ getAlbum: vi.fn() })); -vi.mock('../utils/network/subsonicNetworkGuard', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getAlbum: vi.fn() })); +vi.mock('@/utils/network/subsonicNetworkGuard', () => ({ shouldAttemptSubsonicForActiveServer: vi.fn(() => true), })); import { getArtist } from '@/features/artist'; -import { invalidateEntityUserRatingCaches, prefetchArtistUserRatings } from './subsonicRatings'; +import { invalidateEntityUserRatingCaches, prefetchArtistUserRatings } from '@/lib/api/subsonicRatings'; beforeEach(() => { vi.mocked(getArtist).mockReset(); diff --git a/src/api/subsonicRatings.ts b/src/lib/api/subsonicRatings.ts similarity index 96% rename from src/api/subsonicRatings.ts rename to src/lib/api/subsonicRatings.ts index 710b7442..885cac56 100644 --- a/src/api/subsonicRatings.ts +++ b/src/lib/api/subsonicRatings.ts @@ -1,6 +1,6 @@ import { getArtist } from '@/features/artist'; -import { getAlbum } from './subsonicLibrary'; -import { shouldAttemptSubsonicForActiveServer } from '../utils/network/subsonicNetworkGuard'; +import { getAlbum } from '@/lib/api/subsonicLibrary'; +import { shouldAttemptSubsonicForActiveServer } from '@/utils/network/subsonicNetworkGuard'; const MIX_RATING_PREFETCH_CONCURRENCY = 8; const RATING_CACHE_TTL = 7 * 60 * 1000; // 7 minutes diff --git a/src/api/subsonicScrobble.test.ts b/src/lib/api/subsonicScrobble.test.ts similarity index 85% rename from src/api/subsonicScrobble.test.ts rename to src/lib/api/subsonicScrobble.test.ts index ca81017b..b4989297 100644 --- a/src/api/subsonicScrobble.test.ts +++ b/src/lib/api/subsonicScrobble.test.ts @@ -1,18 +1,18 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { useAuthStore } from '../store/authStore'; -import { usePlayerStore } from '../store/playerStore'; -import { reportNowPlaying, scrobbleSong } from './subsonicScrobble'; -import { shouldAttemptSubsonicForServer } from '../utils/network/subsonicNetworkGuard'; +import { useAuthStore } from '@/store/authStore'; +import { usePlayerStore } from '@/store/playerStore'; +import { reportNowPlaying, scrobbleSong } from '@/lib/api/subsonicScrobble'; +import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; const { apiForServerMock } = vi.hoisted(() => ({ apiForServerMock: vi.fn(async () => ({})), })); -vi.mock('./subsonicClient', () => ({ +vi.mock('@/lib/api/subsonicClient', () => ({ api: vi.fn(), apiForServer: apiForServerMock, })); -vi.mock('../utils/network/subsonicNetworkGuard', () => ({ +vi.mock('@/utils/network/subsonicNetworkGuard', () => ({ shouldAttemptSubsonicForServer: vi.fn(() => true), })); diff --git a/src/api/subsonicScrobble.ts b/src/lib/api/subsonicScrobble.ts similarity index 91% rename from src/api/subsonicScrobble.ts rename to src/lib/api/subsonicScrobble.ts index 9b2336cc..7b7c7b29 100644 --- a/src/api/subsonicScrobble.ts +++ b/src/lib/api/subsonicScrobble.ts @@ -1,7 +1,7 @@ -import { api, apiForServer } from './subsonicClient'; -import type { PlaybackReportState, SubsonicNowPlaying } from './subsonicTypes'; -import { patchLibraryTrackOnUse } from '../utils/library/patchOnUse'; -import { shouldAttemptSubsonicForServer } from '../utils/network/subsonicNetworkGuard'; +import { api, apiForServer } from '@/lib/api/subsonicClient'; +import type { PlaybackReportState, SubsonicNowPlaying } from '@/lib/api/subsonicTypes'; +import { patchLibraryTrackOnUse } from '@/utils/library/patchOnUse'; +import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; async function scrobbleOnServer( serverId: string, diff --git a/src/api/subsonicSearch.test.ts b/src/lib/api/subsonicSearch.test.ts similarity index 80% rename from src/api/subsonicSearch.test.ts rename to src/lib/api/subsonicSearch.test.ts index c826344e..e45b506c 100644 --- a/src/api/subsonicSearch.test.ts +++ b/src/lib/api/subsonicSearch.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { filterSearchArtistsWithNoAlbums } from './subsonicSearch'; -import type { SubsonicArtist } from './subsonicTypes'; +import { filterSearchArtistsWithNoAlbums } from '@/lib/api/subsonicSearch'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; describe('filterSearchArtistsWithNoAlbums', () => { it('removes artists with albumCount 0', () => { diff --git a/src/api/subsonicSearch.ts b/src/lib/api/subsonicSearch.ts similarity index 92% rename from src/api/subsonicSearch.ts rename to src/lib/api/subsonicSearch.ts index 75c506d4..44d1dc97 100644 --- a/src/api/subsonicSearch.ts +++ b/src/lib/api/subsonicSearch.ts @@ -1,11 +1,11 @@ -import { api, libraryFilterParams } from './subsonicClient'; -import { searchQueryIsFtsSafe } from '../utils/library/searchQueryFtsSafe'; +import { api, libraryFilterParams } from '@/lib/api/subsonicClient'; +import { searchQueryIsFtsSafe } from '@/utils/library/searchQueryFtsSafe'; import type { SearchResults, SubsonicAlbum, SubsonicArtist, SubsonicSong, -} from './subsonicTypes'; +} from '@/lib/api/subsonicTypes'; /** * search3 sometimes returns duplicate or junk artist rows with **zero** albums (e.g. Navidrome indexing). diff --git a/src/api/subsonicStarRating.ts b/src/lib/api/subsonicStarRating.ts similarity index 90% rename from src/api/subsonicStarRating.ts rename to src/lib/api/subsonicStarRating.ts index 5d769046..5fa25152 100644 --- a/src/api/subsonicStarRating.ts +++ b/src/lib/api/subsonicStarRating.ts @@ -1,19 +1,19 @@ -import { api, apiForServer, libraryFilterParams, libraryFilterParamsForServer } from './subsonicClient'; -import { invalidateEntityUserRatingCaches } from './subsonicRatings'; -import { useAuthStore } from '../store/authStore'; -import { patchLibraryTrackOnUse, type StarPatchMeta } from '../utils/library/patchOnUse'; -import { useLibraryIndexStore } from '../store/libraryIndexStore'; +import { api, apiForServer, libraryFilterParams, libraryFilterParamsForServer } from '@/lib/api/subsonicClient'; +import { invalidateEntityUserRatingCaches } from '@/lib/api/subsonicRatings'; +import { useAuthStore } from '@/store/authStore'; +import { patchLibraryTrackOnUse, type StarPatchMeta } from '@/utils/library/patchOnUse'; +import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { invalidateStarredAlbumBrowse, refreshStarredAlbumIndexFromServer, -} from '../utils/library/starredAlbumIndexSync'; +} from '@/utils/library/starredAlbumIndexSync'; import type { EntityRatingSupportLevel, StarredResults, SubsonicAlbum, SubsonicArtist, SubsonicSong, -} from './subsonicTypes'; +} from '@/lib/api/subsonicTypes'; function parseStarred2Response(data: { starred2?: { @@ -122,7 +122,7 @@ export async function setRating(id: string, rating: number): Promise { // mix paths already pull `subsonicRatings` (e.g. mixRatingFilter), so a // dynamic import would not split chunks and only triggered INEFFECTIVE_DYNAMIC_IMPORT. // Navidrome browse stays lazy to keep this module free of that dependency when unused. - void import('./navidromeBrowse').then(m => m.ndInvalidateSongsCache()).catch(() => {}); + void import('@/lib/api/navidromeBrowse').then(m => m.ndInvalidateSongsCache()).catch(() => {}); invalidateEntityUserRatingCaches(id); } diff --git a/src/api/subsonicStreamUrl.ts b/src/lib/api/subsonicStreamUrl.ts similarity index 90% rename from src/api/subsonicStreamUrl.ts rename to src/lib/api/subsonicStreamUrl.ts index a95e9c48..5a467f13 100644 --- a/src/api/subsonicStreamUrl.ts +++ b/src/lib/api/subsonicStreamUrl.ts @@ -1,11 +1,11 @@ import md5 from 'md5'; -import { coverStorageKeyFromRef } from '../cover/storageKeys'; -import { coverEntryToRef, resolveAlbumCoverEntry } from '../cover/resolveEntry'; -import type { CoverArtTier } from '../cover/types'; -import { useAuthStore } from '../store/authStore'; -import { connectBaseUrlForServer } from '../utils/server/serverEndpoint'; -import { findServerByIdOrIndexKey } from '../utils/server/serverLookup'; -import { restBaseFromUrl, SUBSONIC_CLIENT, secureRandomSalt } from './subsonicClient'; +import { coverStorageKeyFromRef } from '@/cover/storageKeys'; +import { coverEntryToRef, resolveAlbumCoverEntry } from '@/cover/resolveEntry'; +import type { CoverArtTier } from '@/cover/types'; +import { useAuthStore } from '@/store/authStore'; +import { connectBaseUrlForServer } from '@/utils/server/serverEndpoint'; +import { findServerByIdOrIndexKey } from '@/utils/server/serverLookup'; +import { restBaseFromUrl, SUBSONIC_CLIENT, secureRandomSalt } from '@/lib/api/subsonicClient'; function coverArtQueryParams(username: string, password: string, id: string, size: number): URLSearchParams { const salt = secureRandomSalt(); diff --git a/src/api/subsonicTypes.ts b/src/lib/api/subsonicTypes.ts similarity index 98% rename from src/api/subsonicTypes.ts rename to src/lib/api/subsonicTypes.ts index 3671644d..58cf0cbf 100644 --- a/src/api/subsonicTypes.ts +++ b/src/lib/api/subsonicTypes.ts @@ -1,4 +1,4 @@ -import type { SubsonicServerIdentity } from '../utils/server/subsonicServerIdentity'; +import type { SubsonicServerIdentity } from '@/utils/server/subsonicServerIdentity'; /** OpenSubsonic `ItemGenre` on songs/albums (atomic genres from the server). */ export interface SubsonicItemGenre { diff --git a/src/localPlaybackInvalidation.ts b/src/localPlaybackInvalidation.ts index 415ade52..436e30e0 100644 --- a/src/localPlaybackInvalidation.ts +++ b/src/localPlaybackInvalidation.ts @@ -1,6 +1,6 @@ import { listen } from '@tauri-apps/api/event'; import { invoke } from '@tauri-apps/api/core'; -import { libraryGetTrack } from './api/library'; +import { libraryGetTrack } from '@/lib/api/library'; import { useAuthStore } from './store/authStore'; import { useLocalPlaybackStore } from './store/localPlaybackStore'; import { layoutFingerprintFromLibraryTrack } from './utils/media/mediaLayout'; diff --git a/src/pages/ComposerDetail.tsx b/src/pages/ComposerDetail.tsx index 1dd7d6c7..16234bb4 100644 --- a/src/pages/ComposerDetail.tsx +++ b/src/pages/ComposerDetail.tsx @@ -1,9 +1,9 @@ -import { star, unstar } from '../api/subsonicStarRating'; +import { star, unstar } from '@/lib/api/subsonicStarRating'; import { getArtist, getArtistInfo } from '@/features/artist'; -import type { SubsonicArtist, SubsonicAlbum, SubsonicArtistInfo } from '../api/subsonicTypes'; +import type { SubsonicArtist, SubsonicAlbum, SubsonicArtistInfo } from '@/lib/api/subsonicTypes'; import { useEffect, useState, useMemo } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; -import { ndListAlbumsByArtistRole } from '../api/navidromeBrowse'; +import { ndListAlbumsByArtistRole } from '@/lib/api/navidromeBrowse'; import { AlbumCard } from '@/features/album'; import { ArtistHeroCover } from '../cover/artistHero'; import { coverArtRef } from '../cover/ref'; diff --git a/src/pages/Composers.tsx b/src/pages/Composers.tsx index 4dfffdf4..f3347ea0 100644 --- a/src/pages/Composers.tsx +++ b/src/pages/Composers.tsx @@ -1,7 +1,7 @@ -import type { SubsonicArtist } from '../api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; import { useEffect, useState, useCallback, useRef, useMemo } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; -import { ndListArtistsByRole } from '../api/navidromeBrowse'; +import { ndListArtistsByRole } from '@/lib/api/navidromeBrowse'; import { LayoutGrid, List } from 'lucide-react'; import StarFilterButton from '../components/StarFilterButton'; import { usePlayerStore } from '../store/playerStore'; diff --git a/src/pages/FolderBrowser.tsx b/src/pages/FolderBrowser.tsx index 88819cc5..b912c365 100644 --- a/src/pages/FolderBrowser.tsx +++ b/src/pages/FolderBrowser.tsx @@ -1,5 +1,5 @@ -import { getMusicFolders, getMusicDirectory, getMusicIndexes } from '../api/subsonicLibrary'; -import type { SubsonicDirectoryEntry, SubsonicArtist } from '../api/subsonicTypes'; +import { getMusicFolders, getMusicDirectory, getMusicIndexes } from '@/lib/api/subsonicLibrary'; +import type { SubsonicDirectoryEntry, SubsonicArtist } from '@/lib/api/subsonicTypes'; import React, { useEffect, useRef, useState, useCallback, useMemo } from 'react'; import { usePlayerStore } from '../store/playerStore'; import { useTranslation } from 'react-i18next'; diff --git a/src/pages/GenreDetail.tsx b/src/pages/GenreDetail.tsx index bcbcf47b..bbc51922 100644 --- a/src/pages/GenreDetail.tsx +++ b/src/pages/GenreDetail.tsx @@ -24,7 +24,7 @@ import { fetchGenreTracksForPlayback, } from '../utils/library/genreBrowsePlayback'; import { lookupGenreAlbumCount } from '../utils/library/genreCatalogCountsCache'; -import { libraryScopeForServer } from '../api/subsonicClient'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { readAlbumBrowseRestore, readAlbumDetailReturnTo, diff --git a/src/pages/Genres.tsx b/src/pages/Genres.tsx index d39cbe4a..944a00b4 100644 --- a/src/pages/Genres.tsx +++ b/src/pages/Genres.tsx @@ -1,14 +1,14 @@ -import type { SubsonicGenre } from '../api/subsonicTypes'; +import type { SubsonicGenre } from '@/lib/api/subsonicTypes'; import { useEffect, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Tags } from 'lucide-react'; import { APP_MAIN_SCROLL_VIEWPORT_ID } from '../constants/appScroll'; -import { subscribeLibrarySyncIdle } from '../api/library'; +import { subscribeLibrarySyncIdle } from '@/lib/api/library'; import { useAuthStore } from '../store/authStore'; import { useLibraryIndexStore } from '../store/libraryIndexStore'; import { fetchGenreCatalog, filterGenresWithContent } from '../utils/library/genreBrowsePlayback'; -import { libraryScopeForServer } from '../api/subsonicClient'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { peekGenreCatalogCache } from '../utils/library/genreCatalogCountsCache'; import { resolveIndexKey } from '../utils/server/serverIndexKey'; import { genreColor } from '../utils/library/genreColor'; diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index ce80f31d..15acd962 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,6 +1,6 @@ import { getArtists } from '@/features/artist'; -import { getAlbumList, getRandomSongs } from '../api/subsonicLibrary'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '../api/subsonicTypes'; +import { getAlbumList, getRandomSongs } from '@/lib/api/subsonicLibrary'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { runLocalRandomSongs } from '../utils/library/browseTextSearch'; import React, { useEffect, useState } from 'react'; import Hero from '../components/Hero'; diff --git a/src/pages/Login.test.tsx b/src/pages/Login.test.tsx index 60bc8016..e2db91f0 100644 --- a/src/pages/Login.test.tsx +++ b/src/pages/Login.test.tsx @@ -6,7 +6,7 @@ import { resetAuthStore } from '@/test/helpers/storeReset'; import { useAuthStore } from '@/store/authStore'; import { encodeServerMagicString } from '@/utils/server/serverMagicString'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ pingWithCredentialsForProfile: vi.fn(async () => ({ ok: true, type: 'navidrome', @@ -20,7 +20,7 @@ vi.mock('@/utils/server/syncServerHttpContext', () => ({ syncServerHttpContextForProfile: vi.fn(async () => undefined), })); -import { pingWithCredentialsForProfile } from '@/api/subsonic'; +import { pingWithCredentialsForProfile } from '@/lib/api/subsonic'; beforeEach(() => { resetAuthStore(); diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 7a4f79ac..72ef970b 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -3,7 +3,7 @@ import { useNavigate, useLocation } from 'react-router-dom'; import { Wifi, WifiOff, Eye, EyeOff, Server, Globe } from 'lucide-react'; import { useAuthStore } from '../store/authStore'; import type { CustomHeaderEntry, CustomHeadersApplyTo, ServerProfile } from '../store/authStoreTypes'; -import { pingWithCredentialsForProfile, scheduleInstantMixProbeForServer } from '../api/subsonic'; +import { pingWithCredentialsForProfile, scheduleInstantMixProbeForServer } from '@/lib/api/subsonic'; import { CustomHttpHeadersEditor } from '@/features/settings'; import { DEFAULT_CUSTOM_HEADERS_APPLY_TO, diff --git a/src/pages/MostPlayed.tsx b/src/pages/MostPlayed.tsx index 2d6be71a..1cd90b39 100644 --- a/src/pages/MostPlayed.tsx +++ b/src/pages/MostPlayed.tsx @@ -1,6 +1,6 @@ -import { getAlbumList } from '../api/subsonicLibrary'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; import { resolveAlbum } from '@/features/offline'; -import type { SubsonicAlbum } from '../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../utils/playback/songToTrack'; import React, { useEffect, useState, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; diff --git a/src/pages/NewReleases.tsx b/src/pages/NewReleases.tsx index 7be78bf3..aa43ec31 100644 --- a/src/pages/NewReleases.tsx +++ b/src/pages/NewReleases.tsx @@ -1,8 +1,8 @@ -import { buildDownloadUrl } from '../api/subsonicStreamUrl'; -import { getAlbumsByGenre } from '../api/subsonicGenres'; -import { getAlbumList } from '../api/subsonicLibrary'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; +import { getAlbumsByGenre } from '@/lib/api/subsonicGenres'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; import { resolveAlbum } from '@/features/offline'; -import type { SubsonicAlbum } from '../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { dedupeById } from '../utils/dedupeById'; import { useEffect, useLayoutEffect, useState, useCallback, useRef, useMemo } from 'react'; import { Download, HardDriveDownload } from 'lucide-react'; diff --git a/src/pages/RandomMix.tsx b/src/pages/RandomMix.tsx index b1eb01c6..383930d9 100644 --- a/src/pages/RandomMix.tsx +++ b/src/pages/RandomMix.tsx @@ -1,5 +1,5 @@ import { queueSongStar } from '../store/pendingStarSync'; -import type { SubsonicSong, SubsonicGenre } from '../api/subsonicTypes'; +import type { SubsonicSong, SubsonicGenre } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../utils/playback/songToTrack'; import React, { useEffect, useMemo, useState } from 'react'; import { usePlayerStore } from '../store/playerStore'; diff --git a/src/store/advancedSearchSessionStore.ts b/src/store/advancedSearchSessionStore.ts index 82fa78c8..f155359a 100644 --- a/src/store/advancedSearchSessionStore.ts +++ b/src/store/advancedSearchSessionStore.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { create } from 'zustand'; import type { AdvancedSearchLeaveSnapshot } from '../utils/navigation/advancedSearchScrollSnapshot'; diff --git a/src/store/applyServerPlayQueue.idle.test.ts b/src/store/applyServerPlayQueue.idle.test.ts index e162f8a6..ff69f7b2 100644 --- a/src/store/applyServerPlayQueue.idle.test.ts +++ b/src/store/applyServerPlayQueue.idle.test.ts @@ -3,7 +3,7 @@ import type { QueueItemRef } from './playerStoreTypes'; const getPlayQueueForServerMock = vi.fn(); -vi.mock('../api/subsonicPlayQueue', () => ({ +vi.mock('@/lib/api/subsonicPlayQueue', () => ({ getPlayQueueForServer: (...args: unknown[]) => getPlayQueueForServerMock(...args), })); diff --git a/src/store/applyServerPlayQueue.ts b/src/store/applyServerPlayQueue.ts index efcebaea..df329337 100644 --- a/src/store/applyServerPlayQueue.ts +++ b/src/store/applyServerPlayQueue.ts @@ -1,4 +1,4 @@ -import { getPlayQueueForServer, type PlayQueueResult } from '../api/subsonicPlayQueue'; +import { getPlayQueueForServer, type PlayQueueResult } from '@/lib/api/subsonicPlayQueue'; import { songToTrack } from '../utils/playback/songToTrack'; import { bindQueueServerId } from '../utils/playback/playbackServer'; import { resolveServerIdForIndexKey } from '../utils/server/serverLookup'; diff --git a/src/store/audioEventHandlers.ts b/src/store/audioEventHandlers.ts index e4913d70..cb94fd6b 100644 --- a/src/store/audioEventHandlers.ts +++ b/src/store/audioEventHandlers.ts @@ -1,4 +1,4 @@ -import { scrobbleSong } from '../api/subsonicScrobble'; +import { scrobbleSong } from '@/lib/api/subsonicScrobble'; import type { Track } from './playerStoreTypes'; import { playbackReportPlaying, diff --git a/src/store/authStore.settings.test.ts b/src/store/authStore.settings.test.ts index 04cc7806..3cda5dd2 100644 --- a/src/store/authStore.settings.test.ts +++ b/src/store/authStore.settings.test.ts @@ -10,7 +10,7 @@ */ import { beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), diff --git a/src/store/authStoreTypes.ts b/src/store/authStoreTypes.ts index 534ecc9b..c5466549 100644 --- a/src/store/authStoreTypes.ts +++ b/src/store/authStoreTypes.ts @@ -1,5 +1,5 @@ import type { HiResCrossfadeResampleHz } from '../utils/audio/hiResCrossfadeResample'; -import type { EntityRatingSupportLevel } from '../api/subsonicTypes'; +import type { EntityRatingSupportLevel } from '@/lib/api/subsonicTypes'; import type { AudiomusePluginProbeResult, InstantMixProbeResult, diff --git a/src/store/b1QueueServerIdentity.test.ts b/src/store/b1QueueServerIdentity.test.ts index c9a3f1e6..f90b7ef0 100644 --- a/src/store/b1QueueServerIdentity.test.ts +++ b/src/store/b1QueueServerIdentity.test.ts @@ -29,10 +29,10 @@ import { type QueueUndoSnapshot, } from '@/store/queueUndo'; import type { PlayerState, QueueItemRef, Track } from '@/store/playerStoreTypes'; -import { savePlayQueue } from '@/api/subsonicPlayQueue'; +import { savePlayQueue } from '@/lib/api/subsonicPlayQueue'; import { _resetQueueSyncForTest, flushPlayQueuePosition } from '@/store/queueSync'; -vi.mock('@/api/subsonicPlayQueue', () => ({ +vi.mock('@/lib/api/subsonicPlayQueue', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), })); diff --git a/src/store/becauseYouLikeCache.ts b/src/store/becauseYouLikeCache.ts index 543a8176..7dfa4dc9 100644 --- a/src/store/becauseYouLikeCache.ts +++ b/src/store/becauseYouLikeCache.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; export type BecauseYouLikeAnchor = { id: string; name: string }; diff --git a/src/store/homeFeedCache.ts b/src/store/homeFeedCache.ts index 73d8d708..6a3fe7e8 100644 --- a/src/store/homeFeedCache.ts +++ b/src/store/homeFeedCache.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; /** Session cache so leaving Mainstage and returning does not refetch + reshuffle everything. */ export type HomeFeedSnapshot = { diff --git a/src/store/libraryPlaybackHint.ts b/src/store/libraryPlaybackHint.ts index cd6dad1b..49d29c23 100644 --- a/src/store/libraryPlaybackHint.ts +++ b/src/store/libraryPlaybackHint.ts @@ -1,4 +1,4 @@ -import { librarySetPlaybackHint, type PlaybackHint } from '../api/library'; +import { librarySetPlaybackHint, type PlaybackHint } from '@/lib/api/library'; import { useAuthStore } from './authStore'; import { useLibraryIndexStore } from './libraryIndexStore'; diff --git a/src/store/loudnessRefresh.test.ts b/src/store/loudnessRefresh.test.ts index 540c04b5..e3035155 100644 --- a/src/store/loudnessRefresh.test.ts +++ b/src/store/loudnessRefresh.test.ts @@ -38,7 +38,7 @@ const hoisted = vi.hoisted(() => { }); vi.mock('@tauri-apps/api/core', () => ({ invoke: hoisted.invokeMock })); -vi.mock('../api/subsonicStreamUrl', () => ({ buildStreamUrl: hoisted.buildStreamUrlMock })); +vi.mock('@/lib/api/subsonicStreamUrl', () => ({ buildStreamUrl: hoisted.buildStreamUrlMock })); vi.mock('../utils/server/redactSubsonicUrl', () => ({ redactSubsonicUrlForLog: hoisted.redactMock })); vi.mock('./authStore', () => ({ useAuthStore: { getState: () => hoisted.auth } })); vi.mock('./playerStore', () => ({ diff --git a/src/store/loudnessRefresh.ts b/src/store/loudnessRefresh.ts index 31bd49a1..5ed75e2b 100644 --- a/src/store/loudnessRefresh.ts +++ b/src/store/loudnessRefresh.ts @@ -1,4 +1,4 @@ -import { buildStreamUrl } from '../api/subsonicStreamUrl'; +import { buildStreamUrl } from '@/lib/api/subsonicStreamUrl'; import { invoke } from '@tauri-apps/api/core'; import { getPlaybackIndexKey } from '../utils/playback/playbackServer'; import { redactSubsonicUrlForLog } from '../utils/server/redactSubsonicUrl'; diff --git a/src/store/loudnessReseed.test.ts b/src/store/loudnessReseed.test.ts index 48da88c9..83ec07f9 100644 --- a/src/store/loudnessReseed.test.ts +++ b/src/store/loudnessReseed.test.ts @@ -31,7 +31,7 @@ const hoisted = vi.hoisted(() => { }); vi.mock('@tauri-apps/api/core', () => ({ invoke: hoisted.invokeMock })); -vi.mock('../api/subsonicStreamUrl', () => ({ buildStreamUrl: hoisted.buildStreamUrlMock })); +vi.mock('@/lib/api/subsonicStreamUrl', () => ({ buildStreamUrl: hoisted.buildStreamUrlMock })); vi.mock('./authStore', () => ({ useAuthStore: { getState: () => hoisted.authState } })); vi.mock('./playerStore', () => ({ usePlayerStore: { diff --git a/src/store/loudnessReseed.ts b/src/store/loudnessReseed.ts index 2121e0af..1a4d86a8 100644 --- a/src/store/loudnessReseed.ts +++ b/src/store/loudnessReseed.ts @@ -1,4 +1,4 @@ -import { buildStreamUrl } from '../api/subsonicStreamUrl'; +import { buildStreamUrl } from '@/lib/api/subsonicStreamUrl'; import { invoke } from '@tauri-apps/api/core'; import { getPlaybackIndexKey } from '../utils/playback/playbackServer'; import { useAuthStore } from './authStore'; diff --git a/src/store/migrationStore.ts b/src/store/migrationStore.ts index 02674acd..a9380270 100644 --- a/src/store/migrationStore.ts +++ b/src/store/migrationStore.ts @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import type { GenreTagsInspectDto } from '../api/library'; +import type { GenreTagsInspectDto } from '@/lib/api/library'; import type { MigrationInspectReport, MigrationProgressEvent } from '../api/migration'; export type MigrationPhase = 'idle' | 'inspecting' | 'running' | 'completed' | 'error'; diff --git a/src/store/pendingStarSync.test.ts b/src/store/pendingStarSync.test.ts index 6642bf1c..c705cf41 100644 --- a/src/store/pendingStarSync.test.ts +++ b/src/store/pendingStarSync.test.ts @@ -3,7 +3,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; const starMock = vi.fn(); const unstarMock = vi.fn(); const setRatingMock = vi.fn(); -vi.mock('../api/subsonicStarRating', () => ({ +vi.mock('@/lib/api/subsonicStarRating', () => ({ star: (...a: unknown[]) => starMock(...a), unstar: (...a: unknown[]) => unstarMock(...a), setRating: (...a: unknown[]) => setRatingMock(...a), diff --git a/src/store/pendingStarSync.ts b/src/store/pendingStarSync.ts index de63c9a5..7b0444be 100644 --- a/src/store/pendingStarSync.ts +++ b/src/store/pendingStarSync.ts @@ -1,4 +1,4 @@ -import { setRating, star, unstar } from '../api/subsonicStarRating'; +import { setRating, star, unstar } from '@/lib/api/subsonicStarRating'; import { usePlayerStore } from './playerStore'; import { patchCachedTrack } from '../utils/library/queueTrackResolver'; diff --git a/src/store/playListenSession.ts b/src/store/playListenSession.ts index 0309ed67..2e802bd1 100644 --- a/src/store/playListenSession.ts +++ b/src/store/playListenSession.ts @@ -4,7 +4,7 @@ import { usePreviewStore } from './previewStore'; import { libraryRecordPlaySession, type PlaySessionEndReason, -} from '../api/library'; +} from '@/lib/api/library'; import { libraryIsReady } from '../utils/library/libraryReady'; import { getPlaybackServerId } from '../utils/playback/playbackServer'; import { emitPlaySessionRecorded } from './playSessionRecorded'; diff --git a/src/store/playbackReportSession.test.ts b/src/store/playbackReportSession.test.ts index 4eea5869..7b2f3e08 100644 --- a/src/store/playbackReportSession.test.ts +++ b/src/store/playbackReportSession.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('../api/subsonicScrobble', () => ({ +vi.mock('@/lib/api/subsonicScrobble', () => ({ reportPlayback: vi.fn(() => Promise.resolve()), reportNowPlaying: vi.fn(() => Promise.resolve()), })); @@ -21,7 +21,7 @@ vi.mock('./playbackRateStore', () => ({ vi.mock('../utils/audio/playbackRateHelpers', () => ({ isPlaybackRateApplied: () => false })); vi.mock('@/features/orbit', () => ({ isOrbitPlaybackSyncActive: () => false })); -import { reportNowPlaying, reportPlayback } from '../api/subsonicScrobble'; +import { reportNowPlaying, reportPlayback } from '@/lib/api/subsonicScrobble'; import { isFeatureActiveForServer } from '../serverCapabilities/storeView'; import { useAuthStore } from './authStore'; import { diff --git a/src/store/playbackReportSession.ts b/src/store/playbackReportSession.ts index 139d962e..b20a803a 100644 --- a/src/store/playbackReportSession.ts +++ b/src/store/playbackReportSession.ts @@ -1,5 +1,5 @@ -import { reportNowPlaying, reportPlayback } from '../api/subsonicScrobble'; -import type { PlaybackReportState } from '../api/subsonicTypes'; +import { reportNowPlaying, reportPlayback } from '@/lib/api/subsonicScrobble'; +import type { PlaybackReportState } from '@/lib/api/subsonicTypes'; import { FEATURE_PLAYBACK_REPORT } from '../serverCapabilities/catalog'; import { isFeatureActiveForServer } from '../serverCapabilities/storeView'; import { isPlaybackRateApplied } from '../utils/audio/playbackRateHelpers'; diff --git a/src/store/playerStore.events.test.ts b/src/store/playerStore.events.test.ts index 4fe0be5c..d934d75c 100644 --- a/src/store/playerStore.events.test.ts +++ b/src/store/playerStore.events.test.ts @@ -10,8 +10,8 @@ import { initAudioListeners } from './initAudioListeners'; import { armInterruptHandoff, clearInterruptHandoff } from '../utils/playback/autodjInterruptPrep'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', async () => { - const actual = await vi.importActual('@/api/subsonic'); +vi.mock('@/lib/api/subsonic', async () => { + const actual = await vi.importActual('@/lib/api/subsonic'); return { ...actual, savePlayQueue: vi.fn(async () => undefined), diff --git a/src/store/playerStore.misc.test.ts b/src/store/playerStore.misc.test.ts index 2bce5a96..c3a79a4e 100644 --- a/src/store/playerStore.misc.test.ts +++ b/src/store/playerStore.misc.test.ts @@ -18,7 +18,7 @@ const runtimeMock = { syncLovedTracks: vi.fn(async () => ({})), }; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), diff --git a/src/store/playerStore.persistence.test.ts b/src/store/playerStore.persistence.test.ts index a0a3dd98..bb44f8e9 100644 --- a/src/store/playerStore.persistence.test.ts +++ b/src/store/playerStore.persistence.test.ts @@ -13,7 +13,7 @@ * Mocks `savePlayQueue` at the module boundary so we can assert the exact * args passed to the Subsonic API call. */ -import { savePlayQueue } from '@/api/subsonicPlayQueue'; +import { savePlayQueue } from '@/lib/api/subsonicPlayQueue'; import { initAudioListeners } from './initAudioListeners'; import { flushPlayQueuePosition } from './queueSync'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; @@ -21,25 +21,25 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; // Explicit (non-spread) mock map — the `...actual` spread pattern lets the // real `savePlayQueue` leak through to `playerStore.ts`'s relative import. // Listing every export the store uses keeps the override stable. -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ pingWithCredentials: vi.fn(async () => ({ ok: true })), pingWithCredentialsForProfile: vi.fn(async () => ({ ok: true })), scheduleInstantMixProbeForServer: vi.fn(), })); -vi.mock('@/api/subsonicPlayQueue', () => ({ +vi.mock('@/lib/api/subsonicPlayQueue', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), })); vi.mock('@/utils/network/activeServerReachability', () => ({ isActiveServerReachable: () => true, })); -vi.mock('@/api/subsonicStreamUrl', () => ({ +vi.mock('@/lib/api/subsonicStreamUrl', () => ({ buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), buildCoverArtUrl: vi.fn((id: string) => `https://mock/cover/${id}`), buildDownloadUrl: vi.fn((id: string) => `https://mock/download/${id}`), coverArtCacheKey: vi.fn((id: string, size = 256) => `mock:cover:${id}:${size}`), })); -vi.mock('@/api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getSong: vi.fn(async () => null), getRandomSongs: vi.fn(async () => []), })); @@ -50,7 +50,7 @@ vi.mock('@/features/artist', () => ({ vi.mock('@/features/album', () => ({ getAlbumInfo2: vi.fn(async () => null), })); -vi.mock('@/api/subsonicScrobble', () => ({ +vi.mock('@/lib/api/subsonicScrobble', () => ({ reportNowPlaying: vi.fn(async () => undefined), scrobbleSong: vi.fn(async () => undefined), })); @@ -66,7 +66,7 @@ vi.mock('@/utils/playback/playbackServer', () => ({ cacheKey: `mock:cover:${id}:${size}`, }), })); -vi.mock('@/api/subsonicStarRating', () => ({ +vi.mock('@/lib/api/subsonicStarRating', () => ({ setRating: vi.fn(async () => undefined), probeEntityRatingSupport: vi.fn(async () => 'track_only'), })); diff --git a/src/store/playerStore.playbackActions.test.ts b/src/store/playerStore.playbackActions.test.ts index 3a64bccd..723482dd 100644 --- a/src/store/playerStore.playbackActions.test.ts +++ b/src/store/playerStore.playbackActions.test.ts @@ -13,8 +13,8 @@ */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', async () => { - const actual = await vi.importActual('@/api/subsonic'); +vi.mock('@/lib/api/subsonic', async () => { + const actual = await vi.importActual('@/lib/api/subsonic'); return { ...actual, savePlayQueue: vi.fn(async () => undefined), diff --git a/src/store/playerStore.progress.test.ts b/src/store/playerStore.progress.test.ts index 7494e832..628ca498 100644 --- a/src/store/playerStore.progress.test.ts +++ b/src/store/playerStore.progress.test.ts @@ -14,8 +14,8 @@ import { initAudioListeners } from './initAudioListeners'; import { getPlaybackProgressSnapshot, subscribePlaybackProgress, type PlaybackProgressSnapshot } from './playbackProgress'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('@/api/subsonic', async () => { - const actual = await vi.importActual('@/api/subsonic'); +vi.mock('@/lib/api/subsonic', async () => { + const actual = await vi.importActual('@/lib/api/subsonic'); return { ...actual, savePlayQueue: vi.fn(async () => undefined), diff --git a/src/store/playerStore.queue.test.ts b/src/store/playerStore.queue.test.ts index 0f91e910..8526aaed 100644 --- a/src/store/playerStore.queue.test.ts +++ b/src/store/playerStore.queue.test.ts @@ -11,11 +11,11 @@ */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -// `playerStore` pulls `savePlayQueue` from `@/api/subsonic`, which talks to a +// `playerStore` pulls `savePlayQueue` from `@/lib/api/subsonic`, which talks to a // real server. Override only what the queue path touches; everything else // stays as the actual module so unrelated imports don't break. -vi.mock('@/api/subsonic', async () => { - const actual = await vi.importActual('@/api/subsonic'); +vi.mock('@/lib/api/subsonic', async () => { + const actual = await vi.importActual('@/lib/api/subsonic'); return { ...actual, savePlayQueue: vi.fn(async () => undefined), diff --git a/src/store/playerStoreTypes.ts b/src/store/playerStoreTypes.ts index 3ae7e867..82091837 100644 --- a/src/store/playerStoreTypes.ts +++ b/src/store/playerStoreTypes.ts @@ -1,4 +1,4 @@ -import type { InternetRadioStation, SubsonicOpenArtistRef } from '../api/subsonicTypes'; +import type { InternetRadioStation, SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; import type { PlaybackSourceKind } from '../utils/playback/resolvePlaybackUrl'; export interface Track { diff --git a/src/store/previewStore.test.ts b/src/store/previewStore.test.ts index 4a552dd8..a6f895d5 100644 --- a/src/store/previewStore.test.ts +++ b/src/store/previewStore.test.ts @@ -6,11 +6,11 @@ * * Drives the store through its public action surface with the real * Zustand instance, stubs the Tauri commands via `onInvoke`, and uses - * `vi.mock('@/api/subsonic')` because `startPreview` calls `buildStreamUrl`. + * `vi.mock('@/lib/api/subsonic')` because `startPreview` calls `buildStreamUrl`. */ import { describe, it, expect, beforeEach, vi } from 'vitest'; -vi.mock('@/api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ savePlayQueue: vi.fn(async () => undefined), getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })), buildStreamUrl: vi.fn((id: string) => `https://mock/stream/${id}`), diff --git a/src/store/previewStore.ts b/src/store/previewStore.ts index 96e8b472..2d724c3e 100644 --- a/src/store/previewStore.ts +++ b/src/store/previewStore.ts @@ -1,5 +1,5 @@ -import { buildStreamUrl } from '../api/subsonicStreamUrl'; -import type { SubsonicSong } from '../api/subsonicTypes'; +import { buildStreamUrl } from '@/lib/api/subsonicStreamUrl'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { TrackPreviewLocation } from './authStoreTypes'; import { create } from 'zustand'; import { invoke } from '@tauri-apps/api/core'; diff --git a/src/store/promoteStreamCache.test.ts b/src/store/promoteStreamCache.test.ts index c7a86623..11edb0e0 100644 --- a/src/store/promoteStreamCache.test.ts +++ b/src/store/promoteStreamCache.test.ts @@ -18,7 +18,7 @@ vi.mock('../utils/media/mediaDir', () => ({ getMediaDir: () => '/media', })); -vi.mock('../api/subsonicStreamUrl', () => ({ +vi.mock('@/lib/api/subsonicStreamUrl', () => ({ buildStreamUrlForServer: (_sid: string, id: string) => `https://mock/stream/${id}`, })); diff --git a/src/store/promoteStreamCache.ts b/src/store/promoteStreamCache.ts index 178a7153..46cd7738 100644 --- a/src/store/promoteStreamCache.ts +++ b/src/store/promoteStreamCache.ts @@ -1,4 +1,4 @@ -import { buildStreamUrlForServer } from '../api/subsonicStreamUrl'; +import { buildStreamUrlForServer } from '@/lib/api/subsonicStreamUrl'; import type { Track } from './playerStoreTypes'; import { invoke } from '@tauri-apps/api/core'; import { useHotCacheStore } from './hotCacheStore'; diff --git a/src/store/queueSync.test.ts b/src/store/queueSync.test.ts index fcbf5c50..ef15976e 100644 --- a/src/store/queueSync.test.ts +++ b/src/store/queueSync.test.ts @@ -12,7 +12,7 @@ const { savePlayQueueMock, playerState, progressSnapshot, isSubsonicServerReacha progressSnapshot: { currentTime: 0, progress: 0, buffered: 0 }, })); -vi.mock('../api/subsonicPlayQueue', () => ({ savePlayQueue: savePlayQueueMock })); +vi.mock('@/lib/api/subsonicPlayQueue', () => ({ savePlayQueue: savePlayQueueMock })); vi.mock('../utils/network/subsonicNetworkGuard', () => ({ isSubsonicServerReachable: (serverId: string) => isSubsonicServerReachableMock(serverId), })); diff --git a/src/store/queueSync.ts b/src/store/queueSync.ts index 90421a61..28d238a9 100644 --- a/src/store/queueSync.ts +++ b/src/store/queueSync.ts @@ -1,4 +1,4 @@ -import { savePlayQueue } from '../api/subsonicPlayQueue'; +import { savePlayQueue } from '@/lib/api/subsonicPlayQueue'; import type { QueueItemRef, Track } from './playerStoreTypes'; import { isSubsonicServerReachable } from '../utils/network/subsonicNetworkGuard'; import { diff --git a/src/store/resumeAction.ts b/src/store/resumeAction.ts index 509c8561..7a5e8c2e 100644 --- a/src/store/resumeAction.ts +++ b/src/store/resumeAction.ts @@ -1,4 +1,4 @@ -import { getSong } from '../api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { invoke } from '@tauri-apps/api/core'; import { estimateLivePosition } from '@/features/orbit'; import { setDeferHotCachePrefetch } from '../utils/cache/hotCacheGate'; diff --git a/src/test/helpers/factories.ts b/src/test/helpers/factories.ts index d0deb4b7..05f04975 100644 --- a/src/test/helpers/factories.ts +++ b/src/test/helpers/factories.ts @@ -5,7 +5,7 @@ * the fields the test cares about. Keeps tests focused on behaviour rather * than on assembling boilerplate. */ -import type { SubsonicSong } from '@/api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { ServerProfile } from '@/store/authStoreTypes'; import type { Track } from '@/store/playerStoreTypes'; import { usePlayerStore } from '@/store/playerStore'; diff --git a/src/test/mocks/subsonic.ts b/src/test/mocks/subsonic.ts index d9abc285..2b5b84f2 100644 --- a/src/test/mocks/subsonic.ts +++ b/src/test/mocks/subsonic.ts @@ -1,12 +1,12 @@ /** * Subsonic API mock fixtures. * - * `vi.mock('@/api/subsonic')` is hoisted in the test file itself (vitest + * `vi.mock('@/lib/api/subsonic')` is hoisted in the test file itself (vitest * limitation — factory functions can't reach helper modules at hoist time). * This module supplies the *data* the test injects into those mocks: * * // In the test: - * vi.mock('@/api/subsonic'); + * vi.mock('@/lib/api/subsonic'); * * import { sampleAlbumWithSongs, mockStreamUrl } from '@/test/mocks/subsonic'; * * beforeEach(() => { @@ -17,7 +17,7 @@ * Realistic shape matters more than perfect coverage — these fixtures * mirror what Navidrome actually returns for common queries. */ -import type { SubsonicSong, SubsonicAlbum, SubsonicPlaylist } from '@/api/subsonicTypes'; +import type { SubsonicSong, SubsonicAlbum, SubsonicPlaylist } from '@/lib/api/subsonicTypes'; import { makeSubsonicSong } from '@/test/helpers/factories'; export const sampleSubsonicSong: SubsonicSong = makeSubsonicSong({ diff --git a/src/utils/componentHelpers/contextMenuActions.ts b/src/utils/componentHelpers/contextMenuActions.ts index 76a5b484..6271036b 100644 --- a/src/utils/componentHelpers/contextMenuActions.ts +++ b/src/utils/componentHelpers/contextMenuActions.ts @@ -2,7 +2,7 @@ import { join } from '@tauri-apps/api/path'; import { invoke } from '@tauri-apps/api/core'; import { getSimilarSongs2, fetchSimilarTracksRouted, getTopSongs } from '@/features/artist'; import { filterSongsForLuckyMixRatings, getMixMinRatingsConfigFromAuth } from '../mix/mixRatingFilter'; -import { buildDownloadUrl } from '../../api/subsonicStreamUrl'; +import { buildDownloadUrl } from '@/lib/api/subsonicStreamUrl'; import { useAuthStore } from '../../store/authStore'; import { usePlayerStore } from '../../store/playerStore'; import type { Track } from '../../store/playerStoreTypes'; diff --git a/src/utils/componentHelpers/folderBrowserHelpers.ts b/src/utils/componentHelpers/folderBrowserHelpers.ts index 76a37b57..b6bb5d9e 100644 --- a/src/utils/componentHelpers/folderBrowserHelpers.ts +++ b/src/utils/componentHelpers/folderBrowserHelpers.ts @@ -1,5 +1,5 @@ import type React from 'react'; -import type { SubsonicAlbum, SubsonicDirectoryEntry } from '../../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicDirectoryEntry } from '@/lib/api/subsonicTypes'; import type { Track } from '../../store/playerStoreTypes'; export type ColumnKind = 'roots' | 'indexes' | 'directory'; diff --git a/src/utils/componentHelpers/nowPlayingHelpers.ts b/src/utils/componentHelpers/nowPlayingHelpers.ts index 7947f2e0..46e1311d 100644 --- a/src/utils/componentHelpers/nowPlayingHelpers.ts +++ b/src/utils/componentHelpers/nowPlayingHelpers.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { sanitizeHtml as sanitizeHtmlBase } from '../sanitizeHtml'; export function formatTime(s: number): string { diff --git a/src/utils/componentHelpers/playlistDetailHelpers.ts b/src/utils/componentHelpers/playlistDetailHelpers.ts index 7e86a3b6..76cdb546 100644 --- a/src/utils/componentHelpers/playlistDetailHelpers.ts +++ b/src/utils/componentHelpers/playlistDetailHelpers.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { formatHumanHoursMinutes } from '../format/formatHumanDuration'; import { formatMb } from '../format/formatBytes'; diff --git a/src/utils/componentHelpers/randomMixHelpers.test.ts b/src/utils/componentHelpers/randomMixHelpers.test.ts index 62b66162..53636fb0 100644 --- a/src/utils/componentHelpers/randomMixHelpers.test.ts +++ b/src/utils/componentHelpers/randomMixHelpers.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { filterRandomMixSongs } from './randomMixHelpers'; function song(id: string): SubsonicSong { diff --git a/src/utils/componentHelpers/randomMixHelpers.ts b/src/utils/componentHelpers/randomMixHelpers.ts index 2ad0c5d7..70d64395 100644 --- a/src/utils/componentHelpers/randomMixHelpers.ts +++ b/src/utils/componentHelpers/randomMixHelpers.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { passesMixMinRatings, type MixMinRatingsConfig } from '../mix/mixRatingFilter'; export const AUDIOBOOK_GENRES = [ diff --git a/src/utils/library/advancedSearchLocal.ts b/src/utils/library/advancedSearchLocal.ts index 44c4d689..8d645b16 100644 --- a/src/utils/library/advancedSearchLocal.ts +++ b/src/utils/library/advancedSearchLocal.ts @@ -19,10 +19,10 @@ import { type LibraryEntityType, type LibraryFilterClause, type LibraryTrackDto, -} from '../../api/library'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '../../api/subsonicTypes'; -import { search } from '../../api/subsonicSearch'; -import { libraryScopeForServer } from '../../api/subsonicClient'; +} from '@/lib/api/library'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; +import { search } from '@/lib/api/subsonicSearch'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { fetchAlbumBrowseNetwork } from './albumBrowseNetwork'; import type { AlbumBrowseQuery } from './albumBrowseTypes'; import { resolveAlbumYearBounds } from './albumYearFilter'; diff --git a/src/utils/library/albumBrowseCatalogChunk.ts b/src/utils/library/albumBrowseCatalogChunk.ts index 7aa5a85e..6105c394 100644 --- a/src/utils/library/albumBrowseCatalogChunk.ts +++ b/src/utils/library/albumBrowseCatalogChunk.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { dedupeById } from '../dedupeById'; import { isOfflineBrowseActive } from '@/features/offline'; import { loadOfflineAlbumCatalogChunk } from '@/features/offline'; diff --git a/src/utils/library/albumBrowseFilters.ts b/src/utils/library/albumBrowseFilters.ts index bcba8796..66fe9fe8 100644 --- a/src/utils/library/albumBrowseFilters.ts +++ b/src/utils/library/albumBrowseFilters.ts @@ -1,5 +1,5 @@ -import type { SubsonicAlbum } from '../../api/subsonicTypes'; -import type { LibraryFilterClause } from '../../api/library'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; +import type { LibraryFilterClause } from '@/lib/api/library'; import { albumIsCompilation, type AlbumCompFilter } from './albumCompilation'; import { albumYearFilterClauses, type AlbumYearBounds } from './albumYearFilter'; import type { AlbumBrowseQuery, GenreFilterOption } from './albumBrowseTypes'; diff --git a/src/utils/library/albumBrowseGenreOptions.test.ts b/src/utils/library/albumBrowseGenreOptions.test.ts index 29e95481..8e06be3d 100644 --- a/src/utils/library/albumBrowseGenreOptions.test.ts +++ b/src/utils/library/albumBrowseGenreOptions.test.ts @@ -6,7 +6,7 @@ const libraryIsReady = vi.fn(); const libraryScopeForServer = vi.fn(); const runLocalAlbumBrowse = vi.fn(); -vi.mock('../../api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryGetGenreAlbumCounts: (...args: unknown[]) => libraryGetGenreAlbumCounts(...args), })); @@ -14,7 +14,7 @@ vi.mock('./libraryReady', () => ({ libraryIsReady: (...args: unknown[]) => libraryIsReady(...args), })); -vi.mock('../../api/subsonicClient', () => ({ +vi.mock('@/lib/api/subsonicClient', () => ({ libraryScopeForServer: (...args: unknown[]) => libraryScopeForServer(...args), })); diff --git a/src/utils/library/albumBrowseLoad.test.ts b/src/utils/library/albumBrowseLoad.test.ts index a530d405..da515c23 100644 --- a/src/utils/library/albumBrowseLoad.test.ts +++ b/src/utils/library/albumBrowseLoad.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { albumBrowseHasGenreFilter, albumBrowseHasServerFilters, diff --git a/src/utils/library/albumBrowseLoad.ts b/src/utils/library/albumBrowseLoad.ts index c01da923..cb94a4eb 100644 --- a/src/utils/library/albumBrowseLoad.ts +++ b/src/utils/library/albumBrowseLoad.ts @@ -22,8 +22,8 @@ import { albumBrowseHasServerFilters, countGenresFromAlbums, filterAlbumsByCompi import { runLocalAlbumBrowse } from './albumBrowseLocal'; import { fetchAlbumBrowseNetwork } from './albumBrowseNetwork'; import { fetchStarredAlbumBrowse } from './albumBrowseStarredFetch'; -import { libraryGetGenreAlbumCounts } from '../../api/library'; -import { libraryScopeForServer } from '../../api/subsonicClient'; +import { libraryGetGenreAlbumCounts } from '@/lib/api/library'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { libraryIsReady } from './libraryReady'; import type { AlbumBrowseFetchCallbacks, diff --git a/src/utils/library/albumBrowseLocal.ts b/src/utils/library/albumBrowseLocal.ts index 6e99bbfc..6d77713e 100644 --- a/src/utils/library/albumBrowseLocal.ts +++ b/src/utils/library/albumBrowseLocal.ts @@ -1,6 +1,6 @@ -import { libraryAdvancedSearch, libraryListAlbumsByGenre } from '../../api/library'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; -import { libraryScopeForServer } from '../../api/subsonicClient'; +import { libraryAdvancedSearch, libraryListAlbumsByGenre } from '@/lib/api/library'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { dedupeById } from '../dedupeById'; import { albumToAlbum } from './advancedSearchLocal'; import { sharedServerFilters } from './albumBrowseFilters'; diff --git a/src/utils/library/albumBrowseNetwork.ts b/src/utils/library/albumBrowseNetwork.ts index 06e9ac3d..8870dee5 100644 --- a/src/utils/library/albumBrowseNetwork.ts +++ b/src/utils/library/albumBrowseNetwork.ts @@ -1,6 +1,6 @@ -import { getAlbumList } from '../../api/subsonicLibrary'; -import { getAlbumsByGenre } from '../../api/subsonicGenres'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import { getAlbumList } from '@/lib/api/subsonicLibrary'; +import { getAlbumsByGenre } from '@/lib/api/subsonicGenres'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { dedupeById } from '../dedupeById'; import { filterAlbumsByCompilation, diff --git a/src/utils/library/albumBrowseSort.test.ts b/src/utils/library/albumBrowseSort.test.ts index 5f25d88d..2bdf8ca2 100644 --- a/src/utils/library/albumBrowseSort.test.ts +++ b/src/utils/library/albumBrowseSort.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { albumSortClauses, sortSubsonicAlbums } from './albumBrowseSort'; const album = (artist: string, name: string, year?: number): SubsonicAlbum => diff --git a/src/utils/library/albumBrowseSort.ts b/src/utils/library/albumBrowseSort.ts index f18530fb..d89cddec 100644 --- a/src/utils/library/albumBrowseSort.ts +++ b/src/utils/library/albumBrowseSort.ts @@ -1,5 +1,5 @@ -import type { SubsonicAlbum } from '../../api/subsonicTypes'; -import type { LibrarySortClause } from '../../api/library'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; +import type { LibrarySortClause } from '@/lib/api/library'; export type AlbumBrowseSort = 'alphabeticalByName' | 'alphabeticalByArtist' | 'byArtistThenYear'; diff --git a/src/utils/library/albumBrowseStarredCache.ts b/src/utils/library/albumBrowseStarredCache.ts index 82d86e1b..4b2a774b 100644 --- a/src/utils/library/albumBrowseStarredCache.ts +++ b/src/utils/library/albumBrowseStarredCache.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; type StarredCacheEntry = { albums: SubsonicAlbum[]; diff --git a/src/utils/library/albumBrowseStarredFetch.ts b/src/utils/library/albumBrowseStarredFetch.ts index e633039f..b5c9bc63 100644 --- a/src/utils/library/albumBrowseStarredFetch.ts +++ b/src/utils/library/albumBrowseStarredFetch.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { peekStarredAlbumBrowseCache } from './albumBrowseStarredCache'; import { refreshStarredAlbumIndexFromServer } from './starredAlbumIndexSync'; import { diff --git a/src/utils/library/albumBrowseTypes.ts b/src/utils/library/albumBrowseTypes.ts index b3ea1986..45d13f8e 100644 --- a/src/utils/library/albumBrowseTypes.ts +++ b/src/utils/library/albumBrowseTypes.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import type { AlbumYearBounds } from './albumYearFilter'; import type { AlbumCompFilter } from './albumCompilation'; import type { AlbumBrowseSort } from './albumBrowseSort'; diff --git a/src/utils/library/albumCatalogYearBounds.ts b/src/utils/library/albumCatalogYearBounds.ts index 77f569dd..34d51f57 100644 --- a/src/utils/library/albumCatalogYearBounds.ts +++ b/src/utils/library/albumCatalogYearBounds.ts @@ -1,4 +1,4 @@ -import { libraryGetCatalogYearBounds } from '../../api/library'; +import { libraryGetCatalogYearBounds } from '@/lib/api/library'; import { ALBUM_YEAR_MAX, ALBUM_YEAR_MIN, type AlbumCatalogYearRange } from './albumYearFilter'; import { libraryIsReady } from './libraryReady'; diff --git a/src/utils/library/albumCompilation.test.ts b/src/utils/library/albumCompilation.test.ts index 1835257e..8b71d6b3 100644 --- a/src/utils/library/albumCompilation.test.ts +++ b/src/utils/library/albumCompilation.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { albumBrowseCompFilterClientOnly, albumBrowseCompScanComplete, diff --git a/src/utils/library/albumCompilation.ts b/src/utils/library/albumCompilation.ts index 6335508a..2b561cf0 100644 --- a/src/utils/library/albumCompilation.ts +++ b/src/utils/library/albumCompilation.ts @@ -1,5 +1,5 @@ -import type { LibraryTrackDto } from '../../api/library'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import type { LibraryTrackDto } from '@/lib/api/library'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; export type AlbumCompFilter = 'all' | 'only' | 'hide'; diff --git a/src/utils/library/albumYearFilter.ts b/src/utils/library/albumYearFilter.ts index fa17cb5e..e8a8c9e3 100644 --- a/src/utils/library/albumYearFilter.ts +++ b/src/utils/library/albumYearFilter.ts @@ -1,4 +1,4 @@ -import type { LibraryFilterClause } from '../../api/library'; +import type { LibraryFilterClause } from '@/lib/api/library'; export const ALBUM_YEAR_MIN = 1900; export const ALBUM_YEAR_MAX = new Date().getFullYear(); diff --git a/src/utils/library/browseTextSearch.ts b/src/utils/library/browseTextSearch.ts index dac77bdc..6734b105 100644 --- a/src/utils/library/browseTextSearch.ts +++ b/src/utils/library/browseTextSearch.ts @@ -1,11 +1,11 @@ /** * Browse-page text search — local index vs network race (LiveSearch / SearchBrowsePage pattern). */ -import { getStarred } from '../../api/subsonicStarRating'; -import { search, searchSongsPaged } from '../../api/subsonicSearch'; -import type { SearchResults, SubsonicAlbum, SubsonicArtist, SubsonicSong } from '../../api/subsonicTypes'; -import { libraryAdvancedSearch, libraryGetArtistLosslessBrowse, libraryListLosslessAlbums } from '../../api/library'; -import { libraryScopeForServer } from '../../api/subsonicClient'; +import { getStarred } from '@/lib/api/subsonicStarRating'; +import { search, searchSongsPaged } from '@/lib/api/subsonicSearch'; +import type { SearchResults, SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; +import { libraryAdvancedSearch, libraryGetArtistLosslessBrowse, libraryListLosslessAlbums } from '@/lib/api/library'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { LIVE_SEARCH_DEBOUNCE_NETWORK_MS, LIVE_SEARCH_DEBOUNCE_RACE_MS, diff --git a/src/utils/library/composerBrowse.ts b/src/utils/library/composerBrowse.ts index 8e34a344..11ad8f4f 100644 --- a/src/utils/library/composerBrowse.ts +++ b/src/utils/library/composerBrowse.ts @@ -1,4 +1,4 @@ -import type { SubsonicArtist } from '../../api/subsonicTypes'; +import type { SubsonicArtist } from '@/lib/api/subsonicTypes'; /** * Navidrome's `/api/artist?role=composer` can include artists whose diff --git a/src/utils/library/genreAlbumBrowse.test.ts b/src/utils/library/genreAlbumBrowse.test.ts index d6d711f7..36940cf5 100644 --- a/src/utils/library/genreAlbumBrowse.test.ts +++ b/src/utils/library/genreAlbumBrowse.test.ts @@ -1,15 +1,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { fetchGenreAlbumPage, fetchGenreAlbumTotal } from './genreAlbumBrowse'; -vi.mock('../../api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryListAlbumsByGenre: vi.fn(), })); -vi.mock('../../api/subsonicGenres', () => ({ +vi.mock('@/lib/api/subsonicGenres', () => ({ getAlbumsByGenre: vi.fn(), })); -vi.mock('../../api/subsonicClient', () => ({ +vi.mock('@/lib/api/subsonicClient', () => ({ libraryScopeForServer: vi.fn(() => 'lib-a'), })); @@ -17,8 +17,8 @@ vi.mock('./libraryReady', () => ({ libraryIsReady: vi.fn(), })); -import { libraryListAlbumsByGenre } from '../../api/library'; -import { getAlbumsByGenre } from '../../api/subsonicGenres'; +import { libraryListAlbumsByGenre } from '@/lib/api/library'; +import { getAlbumsByGenre } from '@/lib/api/subsonicGenres'; import { libraryIsReady } from './libraryReady'; describe('genreAlbumBrowse', () => { diff --git a/src/utils/library/genreAlbumBrowse.ts b/src/utils/library/genreAlbumBrowse.ts index a247ad23..a260df8b 100644 --- a/src/utils/library/genreAlbumBrowse.ts +++ b/src/utils/library/genreAlbumBrowse.ts @@ -1,6 +1,6 @@ -import { getAlbumsByGenre } from '../../api/subsonicGenres'; -import { libraryListAlbumsByGenre } from '../../api/library'; -import { libraryScopeForServer } from '../../api/subsonicClient'; +import { getAlbumsByGenre } from '@/lib/api/subsonicGenres'; +import { libraryListAlbumsByGenre } from '@/lib/api/library'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { albumToAlbum } from './advancedSearchLocal'; import { albumSortClauses, sortSubsonicAlbums, type AlbumBrowseSort } from './albumBrowseSort'; import type { AlbumBrowsePageResult } from './albumBrowseTypes'; diff --git a/src/utils/library/genreBrowsePlayback.test.ts b/src/utils/library/genreBrowsePlayback.test.ts index f3eec564..8b925c9b 100644 --- a/src/utils/library/genreBrowsePlayback.test.ts +++ b/src/utils/library/genreBrowsePlayback.test.ts @@ -8,17 +8,17 @@ import { GENRE_PLAYBACK_QUEUE_CAP, } from './genreBrowsePlayback'; -vi.mock('../../api/library', () => ({ +vi.mock('@/lib/api/library', () => ({ libraryAdvancedSearch: vi.fn(), libraryGetGenreAlbumCounts: vi.fn(), })); -vi.mock('../../api/subsonicGenres', () => ({ +vi.mock('@/lib/api/subsonicGenres', () => ({ fetchAllSongsByGenre: vi.fn(), getGenres: vi.fn(), })); -vi.mock('../../api/subsonicClient', () => ({ +vi.mock('@/lib/api/subsonicClient', () => ({ libraryScopeForServer: vi.fn(() => 'music'), })); @@ -34,8 +34,8 @@ vi.mock('./genreAlbumBrowse', async (importOriginal) => ({ fetchGenreAlbumTotal: vi.fn(), })); -import { libraryAdvancedSearch, libraryGetGenreAlbumCounts } from '../../api/library'; -import { fetchAllSongsByGenre, getGenres } from '../../api/subsonicGenres'; +import { libraryAdvancedSearch, libraryGetGenreAlbumCounts } from '@/lib/api/library'; +import { fetchAllSongsByGenre, getGenres } from '@/lib/api/subsonicGenres'; import { fetchGenreAlbumTotal } from './genreAlbumBrowse'; import { resetGenreCatalogCountsCacheForTests } from './genreCatalogCountsCache'; import { libraryIsReady } from './libraryReady'; diff --git a/src/utils/library/genreBrowsePlayback.ts b/src/utils/library/genreBrowsePlayback.ts index 8954fedb..6d006965 100644 --- a/src/utils/library/genreBrowsePlayback.ts +++ b/src/utils/library/genreBrowsePlayback.ts @@ -1,10 +1,10 @@ /** * Genre-detail bulk play/shuffle against the local library index. */ -import { libraryAdvancedSearch, libraryGetGenreAlbumCounts, type LibrarySortClause } from '../../api/library'; -import { fetchAllSongsByGenre, getGenres } from '../../api/subsonicGenres'; -import type { SubsonicGenre } from '../../api/subsonicTypes'; -import { libraryScopeForServer } from '../../api/subsonicClient'; +import { libraryAdvancedSearch, libraryGetGenreAlbumCounts, type LibrarySortClause } from '@/lib/api/library'; +import { fetchAllSongsByGenre, getGenres } from '@/lib/api/subsonicGenres'; +import type { SubsonicGenre } from '@/lib/api/subsonicTypes'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import type { Track } from '../../store/playerStoreTypes'; import { songToTrack } from '../playback/songToTrack'; import { shuffleArray } from '../playback/shuffleArray'; diff --git a/src/utils/library/genreCatalogCountsCache.ts b/src/utils/library/genreCatalogCountsCache.ts index 25e4849e..8b486567 100644 --- a/src/utils/library/genreCatalogCountsCache.ts +++ b/src/utils/library/genreCatalogCountsCache.ts @@ -1,4 +1,4 @@ -import type { SubsonicGenre } from '../../api/subsonicTypes'; +import type { SubsonicGenre } from '@/lib/api/subsonicTypes'; import { resolveServerIdForIndexKey } from '../server/serverLookup'; /** Fresh hits skip SQLite entirely. */ diff --git a/src/utils/library/genreTags.ts b/src/utils/library/genreTags.ts index 3383d3df..9981834b 100644 --- a/src/utils/library/genreTags.ts +++ b/src/utils/library/genreTags.ts @@ -1,4 +1,4 @@ -import type { SubsonicAlbum, SubsonicItemGenre, SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicItemGenre, SubsonicSong } from '@/lib/api/subsonicTypes'; const GENRE_SEPARATORS = [';', '/', ','] as const; diff --git a/src/utils/library/libraryDevLog.test.ts b/src/utils/library/libraryDevLog.test.ts index 8925887b..f835f4fb 100644 --- a/src/utils/library/libraryDevLog.test.ts +++ b/src/utils/library/libraryDevLog.test.ts @@ -6,7 +6,7 @@ import { ingestStallHint, normalizeIngestMetrics, } from './libraryDevLog'; -import type { SyncStateDto } from '../../api/library'; +import type { SyncStateDto } from '@/lib/api/library'; describe('libraryDevLog', () => { it('decodeCapabilityFlags maps known bits', () => { diff --git a/src/utils/library/libraryDevLog.ts b/src/utils/library/libraryDevLog.ts index 5d65651d..ab7c8411 100644 --- a/src/utils/library/libraryDevLog.ts +++ b/src/utils/library/libraryDevLog.ts @@ -3,7 +3,7 @@ * Search one-liner: `search [surface] path=… winner=…` or `source=…` * Ring buffer: `window.__PSYSONIC_LIBRARY_DEBUG__` */ -import type { SyncStateDto } from '../../api/library'; +import type { SyncStateDto } from '@/lib/api/library'; import { syncIngestDisplayCount } from './libraryReady'; const PREFIX = '[psysonic][library]'; diff --git a/src/utils/library/libraryReady.test.ts b/src/utils/library/libraryReady.test.ts index 93a2499b..2dbf228f 100644 --- a/src/utils/library/libraryReady.test.ts +++ b/src/utils/library/libraryReady.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SyncStateDto } from '../../api/library'; +import type { SyncStateDto } from '@/lib/api/library'; import { libraryStatusIsReady, syncIngestDisplayCount } from './libraryReady'; const status = (over: Partial): SyncStateDto => ({ diff --git a/src/utils/library/libraryReady.ts b/src/utils/library/libraryReady.ts index d5717d66..a3cae8af 100644 --- a/src/utils/library/libraryReady.ts +++ b/src/utils/library/libraryReady.ts @@ -4,7 +4,7 @@ * Spec §5.13.6 / §9.3 (`isReady()`): consumers only read from the local * index when it's enabled and synced enough for trustworthy results. */ -import { libraryGetStatus, type SyncStateDto } from '../../api/library'; +import { libraryGetStatus, type SyncStateDto } from '@/lib/api/library'; import { useLibraryIndexStore } from '../../store/libraryIndexStore'; /** Spec §9.3 — shared by Live Search, Advanced Search, browse, … */ diff --git a/src/utils/library/librarySession.ts b/src/utils/library/librarySession.ts index eb55ff75..73defc14 100644 --- a/src/utils/library/librarySession.ts +++ b/src/utils/library/librarySession.ts @@ -1,7 +1,7 @@ import { libraryGetStatus, librarySyncBindSession, -} from '../../api/library'; +} from '@/lib/api/library'; import { enqueueLibrarySync, queueInitialSyncIfNeeded } from './librarySyncQueue'; import type { ServerProfile } from '../../store/authStoreTypes'; import { useAuthStore } from '../../store/authStore'; diff --git a/src/utils/library/librarySyncQueue.ts b/src/utils/library/librarySyncQueue.ts index cf50d1b3..71135c40 100644 --- a/src/utils/library/librarySyncQueue.ts +++ b/src/utils/library/librarySyncQueue.ts @@ -4,7 +4,7 @@ import { librarySyncVerifyIntegrity, subscribeLibrarySyncIdle, type LibrarySyncIdlePayload, -} from '../../api/library'; +} from '@/lib/api/library'; import type { UnlistenFn } from '@tauri-apps/api/event'; import { libraryDevEnabled, logLibrarySync } from './libraryDevLog'; import { invalidateGenreCatalogCache } from './genreCatalogCountsCache'; diff --git a/src/utils/library/liveSearchDebug.ts b/src/utils/library/liveSearchDebug.ts index f8e777a8..4ba9a932 100644 --- a/src/utils/library/liveSearchDebug.ts +++ b/src/utils/library/liveSearchDebug.ts @@ -1,5 +1,5 @@ import { invoke } from '@tauri-apps/api/core'; -import type { SearchResults } from '../../api/subsonicTypes'; +import type { SearchResults } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '../../store/authStore'; export function searchHitCounts(result: SearchResults): string { diff --git a/src/utils/library/liveSearchLocal.test.ts b/src/utils/library/liveSearchLocal.test.ts index a848d604..178a386f 100644 --- a/src/utils/library/liveSearchLocal.test.ts +++ b/src/utils/library/liveSearchLocal.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; import { onInvoke } from '@/test/mocks/tauri'; -import type { SearchResults } from '../../api/subsonicTypes'; +import type { SearchResults } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import { liveSearchQueryRejected, diff --git a/src/utils/library/liveSearchLocal.ts b/src/utils/library/liveSearchLocal.ts index 9e3e845e..0d9209d4 100644 --- a/src/utils/library/liveSearchLocal.ts +++ b/src/utils/library/liveSearchLocal.ts @@ -3,11 +3,11 @@ * Uses column-scoped `library_live_search` FTS — not Advanced Search. * Falls back to search3 when the index isn't ready (caller orchestrates). */ -import type { SearchResults } from '../../api/subsonicTypes'; -import { search } from '../../api/subsonicSearch'; -import { libraryScopeForServer } from '../../api/subsonicClient'; -import { libraryLiveSearch } from '../../api/library'; -import { filterSearchArtistsWithNoAlbums } from '../../api/subsonicSearch'; +import type { SearchResults } from '@/lib/api/subsonicTypes'; +import { search } from '@/lib/api/subsonicSearch'; +import { libraryScopeForServer } from '@/lib/api/subsonicClient'; +import { libraryLiveSearch } from '@/lib/api/library'; +import { filterSearchArtistsWithNoAlbums } from '@/lib/api/subsonicSearch'; import { albumToAlbum, artistToArtist, diff --git a/src/utils/library/patchOnUse.ts b/src/utils/library/patchOnUse.ts index 16e3b69b..375b613b 100644 --- a/src/utils/library/patchOnUse.ts +++ b/src/utils/library/patchOnUse.ts @@ -1,4 +1,4 @@ -import { libraryPatchTrack } from '../../api/library'; +import { libraryPatchTrack } from '@/lib/api/library'; import { useLibraryIndexStore } from '../../store/libraryIndexStore'; type TrackPatch = { diff --git a/src/utils/library/queueRestore.test.ts b/src/utils/library/queueRestore.test.ts index 1dba1275..4e0a90c3 100644 --- a/src/utils/library/queueRestore.test.ts +++ b/src/utils/library/queueRestore.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { onInvoke } from '@/test/mocks/tauri'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { usePlayerStore } from '@/store/playerStore'; -import type { TrackRefDto } from '@/api/library'; +import type { TrackRefDto } from '@/lib/api/library'; import type { Track } from '@/store/playerStoreTypes'; import { getCachedTrack, diff --git a/src/utils/library/queueTrackResolver.test.ts b/src/utils/library/queueTrackResolver.test.ts index 1ea91fed..216fad33 100644 --- a/src/utils/library/queueTrackResolver.test.ts +++ b/src/utils/library/queueTrackResolver.test.ts @@ -2,9 +2,9 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { onInvoke } from '@/test/mocks/tauri'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { usePlayerStore } from '@/store/playerStore'; -import type { TrackRefDto } from '@/api/library'; +import type { TrackRefDto } from '@/lib/api/library'; import type { QueueItemRef } from '@/store/playerStoreTypes'; -import * as subsonic from '@/api/subsonicLibrary'; +import * as subsonic from '@/lib/api/subsonicLibrary'; import { resolveBatch, resolveVisibleRange, diff --git a/src/utils/library/queueTrackResolver.ts b/src/utils/library/queueTrackResolver.ts index 54cc1e45..1c0e8a3c 100644 --- a/src/utils/library/queueTrackResolver.ts +++ b/src/utils/library/queueTrackResolver.ts @@ -1,5 +1,5 @@ -import { libraryGetTracksBatch, type TrackRefDto } from '../../api/library'; -import { getSongForServer } from '../../api/subsonicLibrary'; +import { libraryGetTracksBatch, type TrackRefDto } from '@/lib/api/library'; +import { getSongForServer } from '@/lib/api/subsonicLibrary'; import { usePlayerStore } from '../../store/playerStore'; import type { QueueItemRef, Track } from '../../store/playerStoreTypes'; import { songToTrack } from '../playback/songToTrack'; diff --git a/src/utils/library/searchRace.live.test.ts b/src/utils/library/searchRace.live.test.ts index 7b6774b7..9402d4fb 100644 --- a/src/utils/library/searchRace.live.test.ts +++ b/src/utils/library/searchRace.live.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { SearchResults } from '../../api/subsonicTypes'; +import type { SearchResults } from '@/lib/api/subsonicTypes'; import { raceLiveSearch, type LiveSearchRaceSettled } from './searchRace'; const empty: SearchResults = { artists: [], albums: [], songs: [] }; diff --git a/src/utils/library/searchRace.ts b/src/utils/library/searchRace.ts index f8a4eee2..c756d850 100644 --- a/src/utils/library/searchRace.ts +++ b/src/utils/library/searchRace.ts @@ -2,7 +2,7 @@ * Parallel local vs network search — first successful backend wins. */ -import type { SearchResults } from '../../api/subsonicTypes'; +import type { SearchResults } from '@/lib/api/subsonicTypes'; export type SearchRaceSource = 'local' | 'network'; diff --git a/src/utils/library/starredAlbumIndexSync.ts b/src/utils/library/starredAlbumIndexSync.ts index a692355c..b26c3d26 100644 --- a/src/utils/library/starredAlbumIndexSync.ts +++ b/src/utils/library/starredAlbumIndexSync.ts @@ -1,6 +1,6 @@ -import { libraryReconcileAlbumStars } from '../../api/library'; -import { getStarred } from '../../api/subsonicStarRating'; -import type { SubsonicAlbum } from '../../api/subsonicTypes'; +import { libraryReconcileAlbumStars } from '@/lib/api/library'; +import { getStarred } from '@/lib/api/subsonicStarRating'; +import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { invalidateStarredAlbumBrowseCache, setStarredAlbumBrowseCache, diff --git a/src/utils/library/trackEnrichment.ts b/src/utils/library/trackEnrichment.ts index d2cf4d3b..c8a3a938 100644 --- a/src/utils/library/trackEnrichment.ts +++ b/src/utils/library/trackEnrichment.ts @@ -1,5 +1,5 @@ import type { TFunction } from 'i18next'; -import type { TrackFactDto } from '../../api/library'; +import type { TrackFactDto } from '@/lib/api/library'; import { distinctOximediaMoodTagIds, topDistinctOximediaMoodTagIds, diff --git a/src/utils/media/mediaLayout.ts b/src/utils/media/mediaLayout.ts index 5ab5d18f..ef3a73a1 100644 --- a/src/utils/media/mediaLayout.ts +++ b/src/utils/media/mediaLayout.ts @@ -1,4 +1,4 @@ -import type { LibraryTrackDto } from '../../api/library'; +import type { LibraryTrackDto } from '@/lib/api/library'; const MAX_SEGMENT_LEN = 120; // eslint-disable-next-line no-control-regex -- intentional: strip C0/DEL control chars from path segments (mirrors Rust sanitize_path_segment) diff --git a/src/utils/mix/luckyMix.ts b/src/utils/mix/luckyMix.ts index 89c3554e..adcb18fa 100644 --- a/src/utils/mix/luckyMix.ts +++ b/src/utils/mix/luckyMix.ts @@ -1,6 +1,6 @@ import { fetchSimilarTracksRouted } from '@/features/artist'; -import { filterSongsToActiveLibrary, getRandomSongs } from '../../api/subsonicLibrary'; -import type { SubsonicAlbum, SubsonicSong } from '../../api/subsonicTypes'; +import { filterSongsToActiveLibrary, getRandomSongs } from '@/lib/api/subsonicLibrary'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import type { QueueItemRef } from '../../store/playerStoreTypes'; import { songToTrack } from '../playback/songToTrack'; import { invoke } from '@tauri-apps/api/core'; diff --git a/src/utils/mix/luckyMixHelpers.ts b/src/utils/mix/luckyMixHelpers.ts index 3d1f7e32..5a41d136 100644 --- a/src/utils/mix/luckyMixHelpers.ts +++ b/src/utils/mix/luckyMixHelpers.ts @@ -1,7 +1,7 @@ import { getTopSongs } from '@/features/artist'; -import { filterSongsToActiveLibrary, getAlbumList, getRandomSongs } from '../../api/subsonicLibrary'; +import { filterSongsToActiveLibrary, getAlbumList, getRandomSongs } from '@/lib/api/subsonicLibrary'; import { resolveAlbumForActiveServer } from '@/features/offline'; -import type { SubsonicAlbum, SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import { filterSongsForLuckyMixRatings, type MixMinRatingsConfig, diff --git a/src/utils/mix/mixRatingFilter.test.ts b/src/utils/mix/mixRatingFilter.test.ts index c3e11c87..ce0276f6 100644 --- a/src/utils/mix/mixRatingFilter.test.ts +++ b/src/utils/mix/mixRatingFilter.test.ts @@ -1,15 +1,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { usePlayerStore } from '../../store/playerStore'; import { resetPlayerStore } from '../../test/helpers/storeReset'; -vi.mock('../../api/subsonicRatings', () => ({ +vi.mock('@/lib/api/subsonicRatings', () => ({ prefetchArtistUserRatings: vi.fn(), prefetchAlbumUserRatings: vi.fn(), parseSubsonicEntityStarRating: vi.fn(), })); -import { prefetchArtistUserRatings, prefetchAlbumUserRatings } from '../../api/subsonicRatings'; +import { prefetchArtistUserRatings, prefetchAlbumUserRatings } from '@/lib/api/subsonicRatings'; import { enrichSongsForMixRatingFilter, filterTopArtistsForMixRatings, diff --git a/src/utils/mix/mixRatingFilter.ts b/src/utils/mix/mixRatingFilter.ts index 54637b52..822faf90 100644 --- a/src/utils/mix/mixRatingFilter.ts +++ b/src/utils/mix/mixRatingFilter.ts @@ -1,6 +1,6 @@ -import { parseSubsonicEntityStarRating, prefetchAlbumUserRatings, prefetchArtistUserRatings } from '../../api/subsonicRatings'; -import { getRandomSongs } from '../../api/subsonicLibrary'; -import type { SubsonicAlbum, SubsonicSong } from '../../api/subsonicTypes'; +import { parseSubsonicEntityStarRating, prefetchAlbumUserRatings, prefetchArtistUserRatings } from '@/lib/api/subsonicRatings'; +import { getRandomSongs } from '@/lib/api/subsonicLibrary'; +import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '../../store/authStore'; import { usePlayerStore } from '../../store/playerStore'; diff --git a/src/utils/playback/buildInfiniteQueueCandidates.test.ts b/src/utils/playback/buildInfiniteQueueCandidates.test.ts index a5734c78..bed28bb9 100644 --- a/src/utils/playback/buildInfiniteQueueCandidates.test.ts +++ b/src/utils/playback/buildInfiniteQueueCandidates.test.ts @@ -7,7 +7,7 @@ * order, the dedup contract against existingIds, and the autoAdded flag. */ import { getSimilarSongs2, getTopSongs } from '@/features/artist'; -import { getRandomSongs } from '../../api/subsonicLibrary'; +import { getRandomSongs } from '@/lib/api/subsonicLibrary'; import type { Track } from '../../store/playerStoreTypes'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; @@ -19,7 +19,7 @@ vi.mock('@/features/artist/api/subsonicArtists', () => ({ getTopSongs: vi.fn(), })); -vi.mock('../../api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getRandomSongs: vi.fn(), })); diff --git a/src/utils/playback/buildInfiniteQueueCandidates.ts b/src/utils/playback/buildInfiniteQueueCandidates.ts index 5ca8778b..cce683f0 100644 --- a/src/utils/playback/buildInfiniteQueueCandidates.ts +++ b/src/utils/playback/buildInfiniteQueueCandidates.ts @@ -1,5 +1,5 @@ import { getSimilarSongs2, getTopSongs } from '@/features/artist'; -import { getRandomSongs } from '../../api/subsonicLibrary'; +import { getRandomSongs } from '@/lib/api/subsonicLibrary'; import type { Track } from '../../store/playerStoreTypes'; import { enrichSongsForMixRatingFilter, diff --git a/src/utils/playback/fetchTracksForSource.ts b/src/utils/playback/fetchTracksForSource.ts index aa0cf01e..ad82b5c3 100644 --- a/src/utils/playback/fetchTracksForSource.ts +++ b/src/utils/playback/fetchTracksForSource.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { DeviceSyncSource } from '@/features/deviceSync'; import { resolveAlbum, diff --git a/src/utils/playback/playByOpaqueId.ts b/src/utils/playback/playByOpaqueId.ts index a4099193..a85c66c6 100644 --- a/src/utils/playback/playByOpaqueId.ts +++ b/src/utils/playback/playByOpaqueId.ts @@ -1,4 +1,4 @@ -import { getSong } from '../../api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { resolveAlbumForActiveServer } from '@/features/offline'; import { songToTrack } from './songToTrack'; import { playAlbum } from './playAlbum'; diff --git a/src/utils/playback/playSong.ts b/src/utils/playback/playSong.ts index baa94b27..b276a143 100644 --- a/src/utils/playback/playSong.ts +++ b/src/utils/playback/playSong.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { songToTrack } from './songToTrack'; import { usePlayerStore } from '../../store/playerStore'; import { fadeOut } from './fadeOut'; diff --git a/src/utils/playback/resolvePlaybackUrl.ts b/src/utils/playback/resolvePlaybackUrl.ts index 72f34a71..84cd99da 100644 --- a/src/utils/playback/resolvePlaybackUrl.ts +++ b/src/utils/playback/resolvePlaybackUrl.ts @@ -1,4 +1,4 @@ -import { buildStreamUrlForServer } from '../../api/subsonicStreamUrl'; +import { buildStreamUrlForServer } from '@/lib/api/subsonicStreamUrl'; import { findLocalPlaybackUrl } from '@/features/offline'; import { resolveServerIdForIndexKey } from '../server/serverLookup'; import { getPlaybackCacheServerKey, getPlaybackServerId } from './playbackServer'; diff --git a/src/utils/playback/songToTrack.ts b/src/utils/playback/songToTrack.ts index 7d992afe..f1de11c2 100644 --- a/src/utils/playback/songToTrack.ts +++ b/src/utils/playback/songToTrack.ts @@ -1,4 +1,4 @@ -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import type { Track } from '../../store/playerStoreTypes'; import { coerceOpenArtistRefs } from '@/features/artist'; import { activeServerProfileId } from './trackServerScope'; diff --git a/src/utils/playback/trackArtistRefs.ts b/src/utils/playback/trackArtistRefs.ts index 3acf91ba..b49898a4 100644 --- a/src/utils/playback/trackArtistRefs.ts +++ b/src/utils/playback/trackArtistRefs.ts @@ -1,4 +1,4 @@ -import type { SubsonicOpenArtistRef } from '../../api/subsonicTypes'; +import type { SubsonicOpenArtistRef } from '@/lib/api/subsonicTypes'; import type { Track } from '../../store/playerStoreTypes'; import { coerceOpenArtistRefs } from '@/features/artist'; diff --git a/src/utils/queue/timelineHistoryRefs.ts b/src/utils/queue/timelineHistoryRefs.ts index aad58834..27922a36 100644 --- a/src/utils/queue/timelineHistoryRefs.ts +++ b/src/utils/queue/timelineHistoryRefs.ts @@ -1,5 +1,5 @@ import type { QueueItemRef } from '../../store/playerStoreTypes'; -import type { PlaySessionRecentTrack } from '../../api/library'; +import type { PlaySessionRecentTrack } from '@/lib/api/library'; import type { TimelinePlayedRef } from '../../store/timelineSessionHistory'; import type { Track } from '../../store/playerStoreTypes'; diff --git a/src/utils/server/serverEndpoint.test.ts b/src/utils/server/serverEndpoint.test.ts index 146f9027..426afb70 100644 --- a/src/utils/server/serverEndpoint.test.ts +++ b/src/utils/server/serverEndpoint.test.ts @@ -1,11 +1,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -vi.mock('../../api/subsonic', () => ({ +vi.mock('@/lib/api/subsonic', () => ({ pingWithCredentials: vi.fn(), pingWithCredentialsForProfile: vi.fn(), })); -import { pingWithCredentialsForProfile } from '../../api/subsonic'; +import { pingWithCredentialsForProfile } from '@/lib/api/subsonic'; import { allNormalizedAddresses, ensureConnectUrlResolved, diff --git a/src/utils/server/serverEndpoint.ts b/src/utils/server/serverEndpoint.ts index 5ac5012f..384e23b6 100644 --- a/src/utils/server/serverEndpoint.ts +++ b/src/utils/server/serverEndpoint.ts @@ -1,5 +1,5 @@ -import { pingWithCredentialsForProfile } from '../../api/subsonic'; -import type { PingWithCredentialsResult } from '../../api/subsonicTypes'; +import { pingWithCredentialsForProfile } from '@/lib/api/subsonic'; +import type { PingWithCredentialsResult } from '@/lib/api/subsonicTypes'; import type { ServerProfile } from '../../store/authStoreTypes'; import { serverProfileBaseUrl } from './serverBaseUrl'; diff --git a/src/utils/server/serverFingerprint.test.ts b/src/utils/server/serverFingerprint.test.ts index 765cb517..a9d3ff5e 100644 --- a/src/utils/server/serverFingerprint.test.ts +++ b/src/utils/server/serverFingerprint.test.ts @@ -2,15 +2,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; // Mock the apiWithCredentials surface — fetchServerFingerprint pulls // folders / user / license / indexes through it. -vi.mock('../../api/subsonicClient', async importOriginal => { - const original = await importOriginal(); +vi.mock('@/lib/api/subsonicClient', async importOriginal => { + const original = await importOriginal(); return { ...original, apiWithCredentials: vi.fn(), }; }); -import { apiWithCredentials } from '../../api/subsonicClient'; +import { apiWithCredentials } from '@/lib/api/subsonicClient'; import { compareFingerprints, fetchServerFingerprint, diff --git a/src/utils/server/serverFingerprint.ts b/src/utils/server/serverFingerprint.ts index a06f0889..66888a7b 100644 --- a/src/utils/server/serverFingerprint.ts +++ b/src/utils/server/serverFingerprint.ts @@ -21,7 +21,7 @@ import { secureRandomSalt, SUBSONIC_CLIENT, type ServerHttpHeaderProfile, -} from '../../api/subsonicClient'; +} from '@/lib/api/subsonicClient'; import type { ServerProfile } from '../../store/authStoreTypes'; import { allNormalizedAddresses } from './serverEndpoint'; import { headersForServerRequest } from './serverHttpHeaders'; diff --git a/src/utils/server/switchActiveServer.ts b/src/utils/server/switchActiveServer.ts index 1a404c0b..530bd47c 100644 --- a/src/utils/server/switchActiveServer.ts +++ b/src/utils/server/switchActiveServer.ts @@ -1,5 +1,5 @@ import type { ServerProfile } from '../../store/authStoreTypes'; -import { scheduleInstantMixProbeForServer } from '../../api/subsonic'; +import { scheduleInstantMixProbeForServer } from '@/lib/api/subsonic'; import { coverTrafficBeginServerSwitch, coverTrafficEndServerSwitch, diff --git a/src/utils/share/applySharePaste.ts b/src/utils/share/applySharePaste.ts index e4c20f23..59516c48 100644 --- a/src/utils/share/applySharePaste.ts +++ b/src/utils/share/applySharePaste.ts @@ -1,6 +1,6 @@ -import { getSong } from '../../api/subsonicLibrary'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { resolveAlbum, resolveArtist } from '@/features/offline'; -import type { SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { songToTrack } from '../playback/songToTrack'; import type { Location, NavigateFunction } from 'react-router-dom'; import type { TFunction } from 'i18next'; diff --git a/src/utils/share/enqueueShareSearchPayload.test.ts b/src/utils/share/enqueueShareSearchPayload.test.ts index ba299b8a..8300308c 100644 --- a/src/utils/share/enqueueShareSearchPayload.test.ts +++ b/src/utils/share/enqueueShareSearchPayload.test.ts @@ -22,7 +22,7 @@ const mocks = vi.hoisted(() => ({ songToTrack: vi.fn(), })); -vi.mock('../../api/subsonicLibrary', () => ({ +vi.mock('@/lib/api/subsonicLibrary', () => ({ getAlbum: mocks.getAlbum, getSong: mocks.getSong, })); @@ -31,7 +31,7 @@ vi.mock('@/features/artist', () => ({ getArtist: mocks.getArtist, })); -vi.mock('../../api/subsonicEntityWithCredentials', () => ({ +vi.mock('@/lib/api/subsonicEntityWithCredentials', () => ({ getAlbumWithCredentials: mocks.getAlbumWithCredentials, getArtistWithCredentials: mocks.getArtistWithCredentials, getSongWithCredentials: mocks.getSongWithCredentials, diff --git a/src/utils/share/enqueueShareSearchPayload.ts b/src/utils/share/enqueueShareSearchPayload.ts index bc2ced0c..34384f66 100644 --- a/src/utils/share/enqueueShareSearchPayload.ts +++ b/src/utils/share/enqueueShareSearchPayload.ts @@ -3,10 +3,10 @@ import { getAlbumWithCredentials, getArtistWithCredentials, getSongWithCredentials, -} from '../../api/subsonicEntityWithCredentials'; -import { getSong } from '../../api/subsonicLibrary'; +} from '@/lib/api/subsonicEntityWithCredentials'; +import { getSong } from '@/lib/api/subsonicLibrary'; import { resolveAlbum, resolveArtist } from '@/features/offline'; -import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '../../api/subsonicTypes'; +import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '../../store/authStore'; import type { ServerProfile } from '../../store/authStoreTypes'; import { usePlayerStore } from '../../store/playerStore';