From efdf8bbca94525068fa38745aea1c1d98229ebf6 Mon Sep 17 00:00:00 2001 From: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Date: Sun, 11 Aug 2024 14:01:16 +0200 Subject: [PATCH] refactor(web): simplify some stores (#11695) * refactor(web): simplify some stores * make writable --- web/src/lib/stores/asset-interaction.store.ts | 140 +++++------------- web/src/lib/stores/asset-viewing.store.ts | 15 +- web/src/lib/stores/download.ts | 6 +- web/src/lib/stores/purchase.store.ts | 6 +- web/src/lib/stores/upload.ts | 33 ++--- 5 files changed, 57 insertions(+), 143 deletions(-) diff --git a/web/src/lib/stores/asset-interaction.store.ts b/web/src/lib/stores/asset-interaction.store.ts index 9dd0ab9b8c..f7db5382b0 100644 --- a/web/src/lib/stores/asset-interaction.store.ts +++ b/web/src/lib/stores/asset-interaction.store.ts @@ -1,132 +1,70 @@ import type { AssetResponseDto } from '@immich/sdk'; -import { derived, writable } from 'svelte/store'; +import { derived, readonly, 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 type AssetInteractionStore = ReturnType; -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 +export function createAssetInteractionStore() { + const selectedAssets = writable(new Set()); + const selectedGroup = writable(new Set()); 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()); + 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); + selectedAssets.update(($selectedAssets) => $selectedAssets.add(asset)); }; const selectAssets = (assets: AssetResponseDto[]) => { - for (const asset of assets) { - _selectedAssets.add(asset); - } - selectedAssets.set(_selectedAssets); + selectedAssets.update(($selectedAssets) => { + for (const asset of assets) { + $selectedAssets.add(asset); + } + return $selectedAssets; + }); }; const removeAssetFromMultiselectGroup = (asset: AssetResponseDto) => { - _selectedAssets.delete(asset); - selectedAssets.set(_selectedAssets); + selectedAssets.update(($selectedAssets) => { + $selectedAssets.delete(asset); + return $selectedAssets; + }); }; const addGroupToMultiselectGroup = (group: string) => { - _selectedGroup.add(group); - selectedGroup.set(_selectedGroup); + selectedGroup.update(($selectedGroup) => $selectedGroup.add(group)); }; const removeGroupFromMultiselectGroup = (group: string) => { - _selectedGroup.delete(group); - selectedGroup.set(_selectedGroup); + selectedGroup.update(($selectedGroup) => { + $selectedGroup.delete(group); + return $selectedGroup; + }); }; const setAssetSelectionStart = (asset: AssetResponseDto | null) => { - _assetSelectionStart = asset; - assetSelectionStart.set(_assetSelectionStart); + assetSelectionStart.set(asset); }; const setAssetSelectionCandidates = (assets: AssetResponseDto[]) => { - _assetSelectionCandidates = new Set(assets); - assetSelectionCandidates.set(_assetSelectionCandidates); + assetSelectionCandidates.set(new Set(assets)); }; const clearAssetSelectionCandidates = () => { - _assetSelectionCandidates.clear(); - assetSelectionCandidates.set(_assetSelectionCandidates); + assetSelectionCandidates.set(new Set()); }; const clearMultiselect = () => { // Multi-selection - _selectedAssets.clear(); - _selectedGroup.clear(); + selectedAssets.set(new Set()); + selectedGroup.set(new Set()); // Range selection - _assetSelectionCandidates.clear(); - _assetSelectionStart = null; - - selectedAssets.set(_selectedAssets); - selectedGroup.set(_selectedGroup); - assetSelectionCandidates.set(_assetSelectionCandidates); - assetSelectionStart.set(_assetSelectionStart); + assetSelectionCandidates.set(new Set()); + assetSelectionStart.set(null); }; return { @@ -139,20 +77,10 @@ export function createAssetInteractionStore(): AssetInteractionStore { clearAssetSelectionCandidates, setAssetSelectionStart, clearMultiselect, - isMultiSelectState: { - subscribe: isMultiSelectStoreState.subscribe, - }, - selectedAssets: { - subscribe: selectedAssets.subscribe, - }, - selectedGroup: { - subscribe: selectedGroup.subscribe, - }, - assetSelectionCandidates: { - subscribe: assetSelectionCandidates.subscribe, - }, - assetSelectionStart: { - subscribe: assetSelectionStart.subscribe, - }, + isMultiSelectState: readonly(isMultiSelectStoreState), + selectedAssets: readonly(selectedAssets), + selectedGroup: readonly(selectedGroup), + assetSelectionCandidates: readonly(assetSelectionCandidates), + assetSelectionStart: readonly(assetSelectionStart), }; } diff --git a/web/src/lib/stores/asset-viewing.store.ts b/web/src/lib/stores/asset-viewing.store.ts index bb32149953..cabe2e85a1 100644 --- a/web/src/lib/stores/asset-viewing.store.ts +++ b/web/src/lib/stores/asset-viewing.store.ts @@ -1,6 +1,6 @@ import { getKey } from '$lib/utils'; import { getAssetInfo, type AssetResponseDto } from '@immich/sdk'; -import { writable } from 'svelte/store'; +import { readonly, writable } from 'svelte/store'; function createAssetViewingStore() { const viewingAssetStoreState = writable(); @@ -23,16 +23,9 @@ function createAssetViewingStore() { }; return { - asset: { - subscribe: viewingAssetStoreState.subscribe, - }, - preloadAssets: { - subscribe: preloadAssets.subscribe, - }, - isViewing: { - subscribe: viewState.subscribe, - set: viewState.set, - }, + asset: readonly(viewingAssetStoreState), + preloadAssets: readonly(preloadAssets), + isViewing: viewState, setAsset, setAssetId, showAssetViewer, diff --git a/web/src/lib/stores/download.ts b/web/src/lib/stores/download.ts index a37b351b44..ac57c76153 100644 --- a/web/src/lib/stores/download.ts +++ b/web/src/lib/stores/download.ts @@ -10,11 +10,7 @@ export interface DownloadProgress { export const downloadAssets = writable>({}); export const isDownloading = derived(downloadAssets, ($downloadAssets) => { - if (Object.keys($downloadAssets).length === 0) { - return false; - } - - return true; + return Object.keys($downloadAssets).length > 0; }); const update = (key: string, value: Partial | null) => { diff --git a/web/src/lib/stores/purchase.store.ts b/web/src/lib/stores/purchase.store.ts index e21a4b804b..4b9c61eed7 100644 --- a/web/src/lib/stores/purchase.store.ts +++ b/web/src/lib/stores/purchase.store.ts @@ -1,4 +1,4 @@ -import { writable } from 'svelte/store'; +import { readonly, writable } from 'svelte/store'; function createPurchaseStore() { const isPurcharsed = writable(false); @@ -8,9 +8,7 @@ function createPurchaseStore() { } return { - isPurchased: { - subscribe: isPurcharsed.subscribe, - }, + isPurchased: readonly(isPurcharsed), setPurchaseStatus, }; } diff --git a/web/src/lib/stores/upload.ts b/web/src/lib/stores/upload.ts index 93a1464b02..16f967edb6 100644 --- a/web/src/lib/stores/upload.ts +++ b/web/src/lib/stores/upload.ts @@ -1,4 +1,4 @@ -import { derived, get, writable } from 'svelte/store'; +import { derived, writable } from 'svelte/store'; import { UploadState, type UploadAsset } from '../models/upload-asset'; function createUploadStore() { @@ -22,23 +22,22 @@ function createUploadStore() { ); const addNewUploadAsset = (newAsset: UploadAsset) => { - const assets = get(uploadAssets); - const duplicate = assets.find((asset) => asset.id === newAsset.id); - if (duplicate) { - uploadAssets.update((assets) => assets.map((asset) => (asset.id === newAsset.id ? newAsset : asset))); - } else { + uploadAssets.update(($assets) => { + const duplicate = $assets.find((asset) => asset.id === newAsset.id); + if (duplicate) { + return $assets.map((asset) => (asset.id === newAsset.id ? newAsset : asset)); + } + totalUploadCounter.update((c) => c + 1); - uploadAssets.update((assets) => [ - ...assets, - { - ...newAsset, - speed: 0, - state: UploadState.PENDING, - progress: 0, - eta: 0, - }, - ]); - } + $assets.push({ + ...newAsset, + speed: 0, + state: UploadState.PENDING, + progress: 0, + eta: 0, + }); + return $assets; + }); }; const updateProgress = (id: string, loaded: number, total: number) => {