mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
feat: fix UI freezes in ZIP and offline cache downloads
ZIP downloads (PlaylistDetail, Albums, NewReleases, RandomAlbums) now use
invoke('download_zip') via Rust streaming instead of fetch+blob+arrayBuffer,
eliminating JS heap saturation on large files. Progress shown in ZipDownloadOverlay.
Offline cache downloads (600+ songs) no longer freeze the UI: transient job
state moved to a separate non-persisted offlineJobStore, reducing localStorage
writes from ~1200 down to 2 for an entire download. Also adds playlist offline
toggle — clicking the cache button when already cached removes it from cache.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
export interface ZipDownload {
|
||||
id: string;
|
||||
filename: string;
|
||||
bytes: number;
|
||||
/** null = Content-Length unbekannt (Navidrome on-the-fly ZIP) */
|
||||
total: number | null;
|
||||
done: boolean;
|
||||
error: boolean;
|
||||
}
|
||||
|
||||
interface ZipDownloadState {
|
||||
downloads: ZipDownload[];
|
||||
start: (id: string, filename: string) => void;
|
||||
updateProgress: (id: string, bytes: number, total: number | null) => void;
|
||||
complete: (id: string) => void;
|
||||
fail: (id: string) => void;
|
||||
dismiss: (id: string) => void;
|
||||
}
|
||||
|
||||
export const useZipDownloadStore = create<ZipDownloadState>((set) => ({
|
||||
downloads: [],
|
||||
|
||||
start: (id, filename) => set(state => ({
|
||||
downloads: [...state.downloads, { id, filename, bytes: 0, total: null, done: false, error: false }],
|
||||
})),
|
||||
|
||||
updateProgress: (id, bytes, total) => set(state => ({
|
||||
downloads: state.downloads.map(d =>
|
||||
d.id === id ? { ...d, bytes, total: total ?? d.total } : d
|
||||
),
|
||||
})),
|
||||
|
||||
complete: (id) => set(state => ({
|
||||
downloads: state.downloads.map(d => d.id === id ? { ...d, done: true } : d),
|
||||
})),
|
||||
|
||||
fail: (id) => set(state => ({
|
||||
downloads: state.downloads.map(d => d.id === id ? { ...d, error: true } : d),
|
||||
})),
|
||||
|
||||
dismiss: (id) => set(state => ({
|
||||
downloads: state.downloads.filter(d => d.id !== id),
|
||||
})),
|
||||
}));
|
||||
Reference in New Issue
Block a user