import type { AssetResponseDto } from '@immich/sdk'; import { derived, writable } from 'svelte/store'; export interface AssetInteractionStore { selectAsset: (asset: AssetResponseDto) => void; selectAssets: (assets: AssetResponseDto[]) => void; removeAssetFromMultiselectGroup: (asset: AssetResponseDto) => void; addGroupToMultiselectGroup: (group: string) => void; removeGroupFromMultiselectGroup: (group: string) => void; setAssetSelectionCandidates: (assets: AssetResponseDto[]) => void; clearAssetSelectionCandidates: () => void; setAssetSelectionStart: (asset: AssetResponseDto | null) => void; clearMultiselect: () => void; isMultiSelectState: { subscribe: (run: (value: boolean) => void, invalidate?: (value?: boolean) => void) => () => void; }; selectedAssets: { subscribe: ( run: (value: Set) => void, invalidate?: (value?: Set) => void, ) => () => void; }; selectedGroup: { subscribe: (run: (value: Set) => void, invalidate?: (value?: Set) => void) => () => void; }; assetSelectionCandidates: { subscribe: ( run: (value: Set) => void, invalidate?: (value?: Set) => void, ) => () => void; }; assetSelectionStart: { subscribe: ( run: (value: AssetResponseDto | null) => void, invalidate?: (value?: AssetResponseDto | null) => void, ) => () => void; }; } export function createAssetInteractionStore(): AssetInteractionStore { let _selectedAssets: Set; let _selectedGroup: Set; let _assetSelectionCandidates: Set; let _assetSelectionStart: AssetResponseDto | null; // Selected assets const selectedAssets = writable>(new Set()); // Selected date groups const selectedGroup = writable>(new Set()); // If any asset selected const isMultiSelectStoreState = derived(selectedAssets, ($selectedAssets) => $selectedAssets.size > 0); // Candidates for the range selection. This set includes only loaded assets, so it improves highlight // performance. From the user's perspective, range is highlighted almost immediately const assetSelectionCandidates = writable>(new Set()); // The beginning of the selection range const assetSelectionStart = writable(null); selectedAssets.subscribe((assets) => { _selectedAssets = assets; }); selectedGroup.subscribe((group) => { _selectedGroup = group; }); assetSelectionCandidates.subscribe((assets) => { _assetSelectionCandidates = assets; }); assetSelectionStart.subscribe((asset) => { _assetSelectionStart = asset; }); const selectAsset = (asset: AssetResponseDto) => { _selectedAssets.add(asset); selectedAssets.set(_selectedAssets); }; const selectAssets = (assets: AssetResponseDto[]) => { for (const asset of assets) { _selectedAssets.add(asset); } selectedAssets.set(_selectedAssets); }; const removeAssetFromMultiselectGroup = (asset: AssetResponseDto) => { _selectedAssets.delete(asset); selectedAssets.set(_selectedAssets); }; const addGroupToMultiselectGroup = (group: string) => { _selectedGroup.add(group); selectedGroup.set(_selectedGroup); }; const removeGroupFromMultiselectGroup = (group: string) => { _selectedGroup.delete(group); selectedGroup.set(_selectedGroup); }; const setAssetSelectionStart = (asset: AssetResponseDto | null) => { _assetSelectionStart = asset; assetSelectionStart.set(_assetSelectionStart); }; const setAssetSelectionCandidates = (assets: AssetResponseDto[]) => { _assetSelectionCandidates = new Set(assets); assetSelectionCandidates.set(_assetSelectionCandidates); }; const clearAssetSelectionCandidates = () => { _assetSelectionCandidates.clear(); assetSelectionCandidates.set(_assetSelectionCandidates); }; const clearMultiselect = () => { // Multi-selection _selectedAssets.clear(); _selectedGroup.clear(); // Range selection _assetSelectionCandidates.clear(); _assetSelectionStart = null; selectedAssets.set(_selectedAssets); selectedGroup.set(_selectedGroup); assetSelectionCandidates.set(_assetSelectionCandidates); assetSelectionStart.set(_assetSelectionStart); }; return { selectAsset, selectAssets, removeAssetFromMultiselectGroup, addGroupToMultiselectGroup, removeGroupFromMultiselectGroup, setAssetSelectionCandidates, clearAssetSelectionCandidates, setAssetSelectionStart, clearMultiselect, isMultiSelectState: { subscribe: isMultiSelectStoreState.subscribe, }, selectedAssets: { subscribe: selectedAssets.subscribe, }, selectedGroup: { subscribe: selectedGroup.subscribe, }, assetSelectionCandidates: { subscribe: assetSelectionCandidates.subscribe, }, assetSelectionStart: { subscribe: assetSelectionStart.subscribe, }, }; }