perf(web): speed up asset selection (#26216)

This commit is contained in:
Michel Heusschen 2026-02-14 21:31:04 +01:00 committed by GitHub
parent 49ba833e4c
commit ff7dca35f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 15 deletions

View File

@ -1,14 +1,15 @@
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
import { user } from '$lib/stores/user.store';
import { AssetVisibility, type UserAdminResponseDto } from '@immich/sdk';
import { SvelteSet } from 'svelte/reactivity';
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
import { fromStore } from 'svelte/store';
export class AssetInteraction {
selectedAssets = $state<TimelineAsset[]>([]);
private selectedAssetsMap = new SvelteMap<string, TimelineAsset>();
selectedAssets = $derived(Array.from(this.selectedAssetsMap.values()));
selectAll = $state(false);
hasSelectedAsset(assetId: string) {
return this.selectedAssets.some((asset) => asset.id === assetId);
return this.selectedAssetsMap.has(assetId);
}
selectedGroup = new SvelteSet<string>();
assetSelectionCandidates = $state<TimelineAsset[]>([]);
@ -16,7 +17,7 @@ export class AssetInteraction {
return this.assetSelectionCandidates.some((asset) => asset.id === assetId);
}
assetSelectionStart = $state<TimelineAsset | null>(null);
selectionActive = $derived(this.selectedAssets.length > 0);
selectionActive = $derived(this.selectedAssetsMap.size > 0);
private user = fromStore<UserAdminResponseDto | undefined>(user);
private userId = $derived(this.user.current?.id);
@ -27,9 +28,7 @@ export class AssetInteraction {
isAllUserOwned = $derived(this.selectedAssets.every((asset) => asset.ownerId === this.userId));
selectAsset(asset: TimelineAsset) {
if (!this.hasSelectedAsset(asset.id)) {
this.selectedAssets.push(asset);
}
this.selectedAssetsMap.set(asset.id, asset);
}
selectAssets(assets: TimelineAsset[]) {
@ -39,10 +38,7 @@ export class AssetInteraction {
}
removeAssetFromMultiselectGroup(assetId: string) {
const index = this.selectedAssets.findIndex((a) => a.id == assetId);
if (index !== -1) {
this.selectedAssets.splice(index, 1);
}
this.selectedAssetsMap.delete(assetId);
}
addGroupToMultiselectGroup(group: string) {
@ -69,7 +65,7 @@ export class AssetInteraction {
this.selectAll = false;
// Multi-selection
this.selectedAssets = [];
this.selectedAssetsMap.clear();
this.selectedGroup.clear();
// Range selection

View File

@ -4,7 +4,6 @@ import { authManager } from '$lib/managers/auth-manager.svelte';
import { downloadManager } from '$lib/managers/download-manager.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
import { assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte';
import { Route } from '$lib/route';
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { preferences } from '$lib/stores/user.store';
@ -443,13 +442,15 @@ export const selectAllAssets = async (timelineManager: TimelineManager, assetInt
try {
for (const monthGroup of timelineManager.months) {
await timelineManager.loadMonthGroup(monthGroup.yearMonth);
if (!monthGroup.isLoaded) {
await timelineManager.loadMonthGroup(monthGroup.yearMonth);
}
if (!assetInteraction.selectAll) {
assetInteraction.clearMultiselect();
break; // Cancelled
}
assetInteraction.selectAssets(assetsSnapshot([...monthGroup.assetsIterator()]));
assetInteraction.selectAssets([...monthGroup.assetsIterator()]);
for (const dateGroup of monthGroup.dayGroups) {
assetInteraction.addGroupToMultiselectGroup(dateGroup.groupTitle);