Files
Psychotoxical-psysonic/src/features/artist/hooks/useArtistOfflineState.ts
T

57 lines
2.0 KiB
TypeScript

import { useLocalPlaybackStore } from '@/store/localPlaybackStore';
import { useOfflineJobStore } from '@/features/offline';
import { isOfflinePinComplete } from '@/features/offline';
export type ArtistOfflineStatus = 'none' | 'queued' | 'downloading' | 'cached';
interface UseArtistOfflineStateResult {
status: ArtistOfflineStatus;
progress: { done: number; total: number } | null;
}
/**
* Offline discography status for an artist page. Uses persisted library pins
* (not ephemeral bulkProgress) so "Discography cached" survives navigation.
*/
export function useArtistOfflineState(
artistId: string,
serverId: string,
albumIds: string[],
): UseArtistOfflineStateResult {
useLocalPlaybackStore(s => s.entries);
const allPinned = albumIds.length > 0
&& albumIds.every(id => isOfflinePinComplete(id, serverId));
const bulkDone = useOfflineJobStore(s => (artistId ? s.bulkProgress[artistId]?.done : undefined));
const bulkTotal = useOfflineJobStore(s => (artistId ? s.bulkProgress[artistId]?.total : undefined));
const hasQueuedAlbums = useOfflineJobStore(s =>
albumIds.length > 0
&& albumIds.some(id => s.pinQueue.some(p => p.albumId === id && p.status === 'queued')),
);
const hasDownloadingAlbums = useOfflineJobStore(s =>
albumIds.length > 0
&& albumIds.some(id =>
s.pinQueue.some(p => p.albumId === id && p.status === 'downloading')
|| s.jobs.some(j => j.albumId === id && (j.status === 'queued' || j.status === 'downloading')),
),
);
const bulkActive = bulkTotal !== undefined && bulkDone !== undefined && bulkDone < bulkTotal;
const waitingInQueue = bulkActive && hasQueuedAlbums && !hasDownloadingAlbums;
const status: ArtistOfflineStatus = allPinned
? 'cached'
: hasDownloadingAlbums || (bulkActive && !waitingInQueue)
? 'downloading'
: waitingInQueue
? 'queued'
: 'none';
const progress = bulkActive && bulkDone !== undefined && bulkTotal !== undefined
? { done: bulkDone, total: bulkTotal }
: null;
return { status, progress };
}