mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
209dd61442
Move domain-agnostic, feature-free helpers out of the flat utils/ and store/ roots into src/lib/ (plan M4, §3 lib/ layer): - lib/format/: formatBytes, formatClockTime, formatDuration, formatHumanDuration, relativeTime (pure format/date/byte/clock helpers) - lib/i18n.ts: i18next bootstrap (global app infra) - lib/util/: sanitizeHtml, platform, dedupeById, safeStorage (pure helpers + the zustand storage adapter) playbackScheduleFormat stays in utils/format (runtime usePlayerStore dep = audio-core coupling, not generic). formatClockTime keeps a type-only @/store/authStoreTypes import (erased, no runtime inversion — accepted per the deviceSync precedent). Pure move via deep @/lib/* specifiers (no barrel → no mock-collapse surface). tsc 0, lint 0/0, full suite 319 files / 2353 tests green. Tooling note: lib_move.py regex extended to also rewrite side-effect imports (import './i18n') and vi.importActual paths — both were silent gaps.
45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
import type { SubsonicAlbum } from '@/lib/api/subsonicTypes';
|
|
import { dedupeById } from '@/lib/util/dedupeById';
|
|
import { isOfflineBrowseActive } from '@/features/offline';
|
|
import { loadOfflineAlbumCatalogChunk } from '@/features/offline';
|
|
import type { AlbumBrowseQuery } from './albumBrowseTypes';
|
|
import { fetchLocalAlbumCatalogChunk } from './albumBrowseLoad';
|
|
|
|
export type AlbumCatalogChunk = {
|
|
albums: SubsonicAlbum[];
|
|
hasMore: boolean;
|
|
};
|
|
|
|
export function mergeAlbumCatalogChunk(
|
|
prev: SubsonicAlbum[],
|
|
chunk: AlbumCatalogChunk,
|
|
append: boolean,
|
|
): { albums: SubsonicAlbum[]; offset: number } {
|
|
if (!append) {
|
|
return { albums: chunk.albums, offset: chunk.albums.length };
|
|
}
|
|
const merged = dedupeById([...prev, ...chunk.albums]);
|
|
return { albums: merged, offset: merged.length };
|
|
}
|
|
|
|
/** Local-index or offline-bytes catalog chunk for the albums grid. */
|
|
export async function fetchAlbumBrowseCatalogChunk(
|
|
serverId: string,
|
|
indexEnabled: boolean,
|
|
query: AlbumBrowseQuery,
|
|
offset: number,
|
|
chunkSize: number,
|
|
starredOverrides: Record<string, boolean>,
|
|
): Promise<AlbumCatalogChunk | null> {
|
|
if (isOfflineBrowseActive()) {
|
|
return loadOfflineAlbumCatalogChunk(
|
|
serverId,
|
|
query,
|
|
offset,
|
|
chunkSize,
|
|
starredOverrides,
|
|
);
|
|
}
|
|
return fetchLocalAlbumCatalogChunk(serverId, indexEnabled, query, offset, chunkSize);
|
|
}
|