import type { TrackRef } from '$lib/api/types'; // Global multi-select state for track lists (album, library/liked, // search results, etc.). Reset on route change by the layout effect. // // The store keeps both a Set of ids (for O(1) isSelected) and a Map of // id->TrackRef (so the bulk-action bar can act on the full TrackRef // payload without re-querying the source list). Shift-range uses the // most recent toggle as the anchor. let _selectedIds = $state(new Set()); let _selectedTrackMap = $state(new Map()); let _anchorIndex = $state(null); export const selection = { get count(): number { return _selectedIds.size; }, get active(): boolean { return _selectedIds.size > 0; }, get tracks(): TrackRef[] { return Array.from(_selectedTrackMap.values()); }, get ids(): string[] { return Array.from(_selectedIds); }, isSelected(id: string): boolean { return _selectedIds.has(id); } }; export function toggleOne(track: TrackRef, index: number): void { const ids = new Set(_selectedIds); const map = new Map(_selectedTrackMap); if (ids.has(track.id)) { ids.delete(track.id); map.delete(track.id); } else { ids.add(track.id); map.set(track.id, track); } _selectedIds = ids; _selectedTrackMap = map; _anchorIndex = index; } // Shift-click range: select every track from the anchor to `toIndex` // inclusive. If no anchor is set (first click ever in this list), the // range collapses to a single toggle. export function selectRange(toIndex: number, tracks: TrackRef[]): void { if (_anchorIndex === null) { toggleOne(tracks[toIndex], toIndex); return; } const from = _anchorIndex; const [a, b] = from <= toIndex ? [from, toIndex] : [toIndex, from]; const ids = new Set(_selectedIds); const map = new Map(_selectedTrackMap); for (let i = a; i <= b; i++) { const t = tracks[i]; if (!t) continue; ids.add(t.id); map.set(t.id, t); } _selectedIds = ids; _selectedTrackMap = map; _anchorIndex = toIndex; } export function clearSelection(): void { if (_selectedIds.size === 0 && _anchorIndex === null) return; _selectedIds = new Set(); _selectedTrackMap = new Map(); _anchorIndex = null; }