mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
refactor(api): F.51 — extract playlists + play queue + radio + statistics (#616)
Four more domain-eng modules out of `api/subsonic.ts`:
- `subsonicPlaylists.ts` — `getPlaylists`/`getPlaylist`/`createPlaylist`
/`updatePlaylist`/`updatePlaylistMeta`/`uploadPlaylistCoverArt`/
`uploadArtistImage`/`deletePlaylist`. The two upload helpers use
the Tauri-side CORS bypass (`upload_playlist_cover` /
`upload_artist_image`).
- `subsonicPlayQueue.ts` — `getPlayQueue`/`savePlayQueue`.
- `subsonicRadio.ts` — Internet Radio CRUD (4 fns), Tauri-side cover
art ops (3 fns), RadioBrowser search/top + `fetchUrlBytes`.
- `subsonicStatistics.ts` — `fetchStatisticsLibraryAggregates`/
`fetchStatisticsOverview`/`fetchStatisticsFormatSample` with their
three per-server-folder caches and the `statisticsPageCacheKey`
helper. `STATS_CACHE_TTL` renamed from the misleadingly-shared
`RATING_CACHE_TTL` constant.
Also: drop ~20 now-unused type/value imports from `subsonic.ts`, trim
three orphan jsdoc comments left behind by earlier slices, fix four
`vi.mock` targets (`queueSync`, `playerStore.persistence`) plus the
dynamic `await import('../api/subsonic')` calls in `ContextMenu.tsx`
to point at the new module paths.
Pure code-move. subsonic.ts: 561 → 144 LOC (−417). What's left:
ping/pingWithCredentials/probeInstantMix/scheduleInstantMixProbe +
internal `apiWithCredentials`/`restBaseFromUrl`.
This commit is contained in:
committed by
GitHub
parent
9606a99efb
commit
f7b2799d39
@@ -1,6 +1,6 @@
|
||||
import { getPlayQueue } from '../api/subsonicPlayQueue';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import i18n from '../i18n';
|
||||
import { getPlayQueue } from '../api/subsonic';
|
||||
import { songToTrack } from '../utils/songToTrack';
|
||||
import { showToast } from '../utils/toast';
|
||||
import { useAuthStore } from './authStore';
|
||||
|
||||
@@ -8,6 +8,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 { initAudioListeners } from './initAudioListeners';
|
||||
import { flushPlayQueuePosition } from './queueSync';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
@@ -16,22 +17,36 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
// real `savePlayQueue` leak through to `playerStore.ts`'s relative import.
|
||||
// Listing every export the store uses keeps the override stable.
|
||||
vi.mock('@/api/subsonic', () => ({
|
||||
pingWithCredentials: vi.fn(async () => ({ ok: true })),
|
||||
}));
|
||||
vi.mock('@/api/subsonicPlayQueue', () => ({
|
||||
savePlayQueue: vi.fn(async () => undefined),
|
||||
getPlayQueue: vi.fn(async () => ({ songs: [], current: undefined, position: 0 })),
|
||||
}));
|
||||
vi.mock('@/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', () => ({
|
||||
getSong: vi.fn(async () => null),
|
||||
getRandomSongs: vi.fn(async () => []),
|
||||
}));
|
||||
vi.mock('@/api/subsonicArtists', () => ({
|
||||
getSimilarSongs2: vi.fn(async () => []),
|
||||
getTopSongs: vi.fn(async () => []),
|
||||
}));
|
||||
vi.mock('@/api/subsonicAlbumInfo', () => ({
|
||||
getAlbumInfo2: vi.fn(async () => null),
|
||||
}));
|
||||
vi.mock('@/api/subsonicScrobble', () => ({
|
||||
reportNowPlaying: vi.fn(async () => undefined),
|
||||
scrobbleSong: vi.fn(async () => undefined),
|
||||
}));
|
||||
vi.mock('@/api/subsonicStarRating', () => ({
|
||||
setRating: vi.fn(async () => undefined),
|
||||
probeEntityRatingSupport: vi.fn(async () => 'track_only'),
|
||||
pingWithCredentials: vi.fn(async () => ({ ok: true })),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/lastfm', () => ({
|
||||
@@ -41,7 +56,6 @@ vi.mock('@/api/lastfm', () => ({
|
||||
lastfmGetAllLovedTracks: vi.fn(async () => []),
|
||||
}));
|
||||
|
||||
import { savePlayQueue } from '@/api/subsonic';
|
||||
import { usePlayerStore } from './playerStore';
|
||||
import { emitTauriEvent, onInvoke } from '@/test/mocks/tauri';
|
||||
import { resetPlayerStore, resetAuthStore } from '@/test/helpers/storeReset';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getPlaylists } from '../api/subsonicPlaylists';
|
||||
import type { SubsonicPlaylist } from '../api/subsonicTypes';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { getPlaylists, createPlaylist as apiCreatePlaylist } from '../api/subsonic';
|
||||
import { createPlaylist as apiCreatePlaylist } from '../api/subsonicPlaylists';
|
||||
interface PlaylistStore {
|
||||
recentIds: string[];
|
||||
playlists: SubsonicPlaylist[];
|
||||
|
||||
@@ -17,7 +17,7 @@ const { savePlayQueueMock, playerState, progressSnapshot } = vi.hoisted(() => ({
|
||||
progressSnapshot: { currentTime: 0, progress: 0, buffered: 0 },
|
||||
}));
|
||||
|
||||
vi.mock('../api/subsonic', () => ({ savePlayQueue: savePlayQueueMock }));
|
||||
vi.mock('../api/subsonicPlayQueue', () => ({ savePlayQueue: savePlayQueueMock }));
|
||||
vi.mock('./playerStore', () => ({
|
||||
usePlayerStore: { getState: () => playerState },
|
||||
}));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { savePlayQueue } from '../api/subsonicPlayQueue';
|
||||
import type { Track } from './playerStoreTypes';
|
||||
import { savePlayQueue } from '../api/subsonic';
|
||||
import { getPlaybackProgressSnapshot } from './playbackProgress';
|
||||
import { usePlayerStore } from './playerStore';
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user