1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-01 08:31:59 +00:00

refactor(web): simplify some stores (#11695)

* refactor(web): simplify some stores

* make writable
This commit is contained in:
Michel Heusschen 2024-08-11 14:01:16 +02:00 committed by GitHub
parent 34c4fbf730
commit efdf8bbca9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 57 additions and 143 deletions

View file

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

View file

@ -1,6 +1,6 @@
import { getKey } from '$lib/utils'; import { getKey } from '$lib/utils';
import { getAssetInfo, type AssetResponseDto } from '@immich/sdk'; import { getAssetInfo, type AssetResponseDto } from '@immich/sdk';
import { writable } from 'svelte/store'; import { readonly, writable } from 'svelte/store';
function createAssetViewingStore() { function createAssetViewingStore() {
const viewingAssetStoreState = writable<AssetResponseDto>(); const viewingAssetStoreState = writable<AssetResponseDto>();
@ -23,16 +23,9 @@ function createAssetViewingStore() {
}; };
return { return {
asset: { asset: readonly(viewingAssetStoreState),
subscribe: viewingAssetStoreState.subscribe, preloadAssets: readonly(preloadAssets),
}, isViewing: viewState,
preloadAssets: {
subscribe: preloadAssets.subscribe,
},
isViewing: {
subscribe: viewState.subscribe,
set: viewState.set,
},
setAsset, setAsset,
setAssetId, setAssetId,
showAssetViewer, showAssetViewer,

View file

@ -10,11 +10,7 @@ export interface DownloadProgress {
export const downloadAssets = writable<Record<string, DownloadProgress>>({}); export const downloadAssets = writable<Record<string, DownloadProgress>>({});
export const isDownloading = derived(downloadAssets, ($downloadAssets) => { export const isDownloading = derived(downloadAssets, ($downloadAssets) => {
if (Object.keys($downloadAssets).length === 0) { return Object.keys($downloadAssets).length > 0;
return false;
}
return true;
}); });
const update = (key: string, value: Partial<DownloadProgress> | null) => { const update = (key: string, value: Partial<DownloadProgress> | null) => {

View file

@ -1,4 +1,4 @@
import { writable } from 'svelte/store'; import { readonly, writable } from 'svelte/store';
function createPurchaseStore() { function createPurchaseStore() {
const isPurcharsed = writable(false); const isPurcharsed = writable(false);
@ -8,9 +8,7 @@ function createPurchaseStore() {
} }
return { return {
isPurchased: { isPurchased: readonly(isPurcharsed),
subscribe: isPurcharsed.subscribe,
},
setPurchaseStatus, setPurchaseStatus,
}; };
} }

View file

@ -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'; import { UploadState, type UploadAsset } from '../models/upload-asset';
function createUploadStore() { function createUploadStore() {
@ -22,23 +22,22 @@ function createUploadStore() {
); );
const addNewUploadAsset = (newAsset: UploadAsset) => { const addNewUploadAsset = (newAsset: UploadAsset) => {
const assets = get(uploadAssets); uploadAssets.update(($assets) => {
const duplicate = assets.find((asset) => asset.id === newAsset.id); const duplicate = $assets.find((asset) => asset.id === newAsset.id);
if (duplicate) { if (duplicate) {
uploadAssets.update((assets) => assets.map((asset) => (asset.id === newAsset.id ? newAsset : asset))); return $assets.map((asset) => (asset.id === newAsset.id ? newAsset : asset));
} else { }
totalUploadCounter.update((c) => c + 1); totalUploadCounter.update((c) => c + 1);
uploadAssets.update((assets) => [ $assets.push({
...assets,
{
...newAsset, ...newAsset,
speed: 0, speed: 0,
state: UploadState.PENDING, state: UploadState.PENDING,
progress: 0, progress: 0,
eta: 0, eta: 0,
}, });
]); return $assets;
} });
}; };
const updateProgress = (id: string, loaded: number, total: number) => { const updateProgress = (id: string, loaded: number, total: number) => {