mirror of
https://github.com/immich-app/immich.git
synced 2026-02-11 11:27:56 +03:00
fix: correctly cancel select all assets (#26067)
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment';
|
||||
|
||||
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiClose } from '@mdi/js';
|
||||
import { onDestroy, onMount, type Snippet } from 'svelte';
|
||||
@@ -46,11 +44,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
$isSelectingAllAssets = false;
|
||||
onClose();
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
if (browser) {
|
||||
document.addEventListener('scroll', onScroll, { passive: true });
|
||||
@@ -82,7 +75,7 @@
|
||||
{#if showBackButton}
|
||||
<IconButton
|
||||
aria-label={$t('close')}
|
||||
onclick={handleClose}
|
||||
onclick={onClose}
|
||||
color="secondary"
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
import { assetsSnapshot } from '$lib/managers/timeline-manager/utils.svelte';
|
||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
||||
import { mediaQueryManager } from '$lib/stores/media-query-manager.svelte';
|
||||
import { isAssetViewerRoute, navigate } from '$lib/utils/navigation';
|
||||
import { getTimes, type ScrubberListener } from '$lib/utils/timeline-util';
|
||||
@@ -411,11 +410,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (timelineManager.assetCount == assetInteraction.selectedAssets.length) {
|
||||
isSelectingAllAssets.set(true);
|
||||
} else {
|
||||
isSelectingAllAssets.set(false);
|
||||
}
|
||||
assetInteraction.selectAll = timelineManager.assetCount === assetInteraction.selectedAssets.length;
|
||||
};
|
||||
|
||||
const onSelectAssets = async (asset: TimelineAsset) => {
|
||||
@@ -559,7 +554,7 @@
|
||||
assetInteraction.removeGroupFromMultiselectGroup(groupTitle);
|
||||
}
|
||||
|
||||
isSelectingAllAssets.set(timelineManager.assetCount === assetInteraction.selectedAssets.length);
|
||||
assetInteraction.selectAll = timelineManager.assetCount === assetInteraction.selectedAssets.length;
|
||||
};
|
||||
|
||||
const _onClick = (
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
||||
import { cancelMultiselect, selectAllAssets } from '$lib/utils/asset-utils';
|
||||
import { Button, IconButton } from '@immich/ui';
|
||||
import { mdiSelectAll, mdiSelectRemove } from '@mdi/js';
|
||||
@@ -14,6 +13,7 @@
|
||||
}
|
||||
|
||||
let { timelineManager, assetInteraction, withText = false }: Props = $props();
|
||||
const allAssetsSelected = $derived(assetInteraction.selectAll);
|
||||
|
||||
const handleSelectAll = async () => {
|
||||
await selectAllAssets(timelineManager, assetInteraction);
|
||||
@@ -26,21 +26,21 @@
|
||||
|
||||
{#if withText}
|
||||
<Button
|
||||
leadingIcon={$isSelectingAllAssets ? mdiSelectRemove : mdiSelectAll}
|
||||
leadingIcon={allAssetsSelected ? mdiSelectRemove : mdiSelectAll}
|
||||
size="medium"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
onclick={$isSelectingAllAssets ? handleCancel : handleSelectAll}
|
||||
onclick={allAssetsSelected ? handleCancel : handleSelectAll}
|
||||
>
|
||||
{$isSelectingAllAssets ? $t('unselect_all') : $t('select_all')}
|
||||
{allAssetsSelected ? $t('unselect_all') : $t('select_all')}
|
||||
</Button>
|
||||
{:else}
|
||||
<IconButton
|
||||
shape="round"
|
||||
color="secondary"
|
||||
variant="ghost"
|
||||
aria-label={$isSelectingAllAssets ? $t('unselect_all') : $t('select_all')}
|
||||
icon={$isSelectingAllAssets ? mdiSelectRemove : mdiSelectAll}
|
||||
onclick={$isSelectingAllAssets ? handleCancel : handleSelectAll}
|
||||
aria-label={allAssetsSelected ? $t('unselect_all') : $t('select_all')}
|
||||
icon={allAssetsSelected ? mdiSelectRemove : mdiSelectAll}
|
||||
onclick={allAssetsSelected ? handleCancel : handleSelectAll}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { fromStore } from 'svelte/store';
|
||||
|
||||
export class AssetInteraction {
|
||||
selectedAssets = $state<TimelineAsset[]>([]);
|
||||
selectAll = $state(false);
|
||||
hasSelectedAsset(assetId: string) {
|
||||
return this.selectedAssets.some((asset) => asset.id === assetId);
|
||||
}
|
||||
@@ -65,6 +66,8 @@ export class AssetInteraction {
|
||||
}
|
||||
|
||||
clearMultiselect() {
|
||||
this.selectAll = false;
|
||||
|
||||
// Multi-selection
|
||||
this.selectedAssets = [];
|
||||
this.selectedGroup.clear();
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export const isSelectingAllAssets = writable(false);
|
||||
@@ -7,7 +7,6 @@ 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 { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
|
||||
import { preferences } from '$lib/stores/user.store';
|
||||
import { downloadRequest, withError } from '$lib/utils';
|
||||
import { getByteUnitString } from '$lib/utils/byte-units';
|
||||
@@ -427,17 +426,17 @@ export const keepThisDeleteOthers = async (keepAsset: AssetResponseDto, stack: S
|
||||
};
|
||||
|
||||
export const selectAllAssets = async (timelineManager: TimelineManager, assetInteraction: AssetInteraction) => {
|
||||
if (get(isSelectingAllAssets)) {
|
||||
if (assetInteraction.selectAll) {
|
||||
// Selection is already ongoing
|
||||
return;
|
||||
}
|
||||
isSelectingAllAssets.set(true);
|
||||
assetInteraction.selectAll = true;
|
||||
|
||||
try {
|
||||
for (const monthGroup of timelineManager.months) {
|
||||
await timelineManager.loadMonthGroup(monthGroup.yearMonth);
|
||||
|
||||
if (!get(isSelectingAllAssets)) {
|
||||
if (!assetInteraction.selectAll) {
|
||||
assetInteraction.clearMultiselect();
|
||||
break; // Cancelled
|
||||
}
|
||||
@@ -450,12 +449,12 @@ export const selectAllAssets = async (timelineManager: TimelineManager, assetInt
|
||||
} catch (error) {
|
||||
const $t = get(t);
|
||||
handleError(error, $t('errors.error_selecting_all_assets'));
|
||||
isSelectingAllAssets.set(false);
|
||||
assetInteraction.selectAll = false;
|
||||
}
|
||||
};
|
||||
|
||||
export const cancelMultiselect = (assetInteraction: AssetInteraction) => {
|
||||
isSelectingAllAssets.set(false);
|
||||
assetInteraction.selectAll = false;
|
||||
assetInteraction.clearMultiselect();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user