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:
parent
34c4fbf730
commit
efdf8bbca9
5 changed files with 57 additions and 143 deletions
|
@ -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,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in a new issue