Skip to content

Commit

Permalink
feat: Added shortcuts, shift-multi select and missing menu options to…
Browse files Browse the repository at this point in the history
… Search (Galleryviewer) (immich-app#14213)

feat: Added shortcuts, shift-multi select and missing menu options to GalleryViewer (Search, Share, Memories)

Co-authored-by: Alex <[email protected]>
  • Loading branch information
2 people authored and yosit committed Nov 21, 2024
1 parent c2c990b commit 53cfac3
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 48 deletions.
21 changes: 10 additions & 11 deletions web/src/lib/components/memory-page/memory-viewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte';
import { cancelMultiselect } from '$lib/utils/asset-utils';
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
import { AppRoute, QueryParameter } from '$lib/constants';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { type Viewport } from '$lib/stores/assets.store';
Expand Down Expand Up @@ -44,7 +46,6 @@
import { tweened } from 'svelte/motion';
import { derived as storeDerived } from 'svelte/store';
import { fade } from 'svelte/transition';
import { SvelteSet } from 'svelte/reactivity';
type MemoryIndex = {
memoryIndex: number;
Expand All @@ -64,13 +65,14 @@
let memoryWrapper: HTMLElement | undefined = $state();
let galleryInView = $state(false);
let paused = $state(false);
let selectedAssets: SvelteSet<AssetResponseDto> = $state(new SvelteSet());
let current: MemoryAsset | undefined = $state(undefined);
// let memories: MemoryAsset[] = [];
let resetPromise = $state(Promise.resolve());
const { isViewing } = assetViewingStore;
const viewport: Viewport = $state({ width: 0, height: 0 });
const assetInteractionStore = createAssetInteractionStore();
const { selectedAssets } = assetInteractionStore;
const progressBarController = tweened<number>(0, {
duration: (from: number, to: number) => (to ? 5000 * (to - from) : 0),
});
Expand Down Expand Up @@ -126,7 +128,7 @@
const handleNextMemory = () => handleNavigate(current?.nextMemory?.assets[0]);
const handlePreviousMemory = () => handleNavigate(current?.previousMemory?.assets[0]);
const handleEscape = async () => goto(AppRoute.PHOTOS);
const handleSelectAll = () => (selectedAssets = new SvelteSet(current?.memory.assets || []));
const handleSelectAll = () => assetInteractionStore.selectAssets(current?.memory.assets || []);
const handleAction = async (action: 'reset' | 'pause' | 'play') => {
switch (action) {
case 'play': {
Expand Down Expand Up @@ -207,13 +209,10 @@
current = loadFromParams($memories, target);
});
$effect(() => {
selectedAssets = galleryInView ? selectedAssets : new SvelteSet();
});
let isMultiSelectionMode = $derived(selectedAssets.size > 0);
let isAllArchived = $derived([...selectedAssets].every((asset) => asset.isArchived));
let isAllFavorite = $derived([...selectedAssets].every((asset) => asset.isFavorite));
let isMultiSelectionMode = $derived($selectedAssets.size > 0);
let isAllArchived = $derived([...$selectedAssets].every((asset) => asset.isArchived));
let isAllFavorite = $derived([...$selectedAssets].every((asset) => asset.isFavorite));
$effect(() => {
handlePromiseError(handleProgress($progressBarController));
Expand All @@ -238,7 +237,7 @@

{#if isMultiSelectionMode}
<div class="sticky top-0 z-[90]">
<AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new SvelteSet())}>
<AssetSelectControlBar assets={$selectedAssets} clearSelect={() => cancelMultiselect(assetInteractionStore)}>
<CreateSharedLink />
<CircleIconButton title={$t('select_all')} icon={mdiSelectAll} onclick={handleSelectAll} />

Expand Down Expand Up @@ -485,7 +484,7 @@
onPrevious={handlePreviousAsset}
assets={current.memory.assets}
{viewport}
bind:selectedAssets
{assetInteractionStore}
/>
</div>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
import { downloadArchive } from '$lib/utils/asset-utils';
import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
import { handleError } from '$lib/utils/handle-error';
import { addSharedLinkAssets, type AssetResponseDto, type SharedLinkResponseDto } from '@immich/sdk';
import { addSharedLinkAssets, type SharedLinkResponseDto } from '@immich/sdk';
import { mdiArrowLeft, mdiFileImagePlusOutline, mdiFolderDownloadOutline, mdiSelectAll } from '@mdi/js';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import DownloadAction from '../photos-page/actions/download-action.svelte';
import RemoveFromSharedLink from '../photos-page/actions/remove-from-shared-link.svelte';
import AssetSelectControlBar from '../photos-page/asset-select-control-bar.svelte';
import ControlAppBar from '../shared-components/control-app-bar.svelte';
import GalleryViewer from '../shared-components/gallery-viewer/gallery-viewer.svelte';
import { cancelMultiselect } from '$lib/utils/asset-utils';
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
import ImmichLogoSmallLink from '$lib/components/shared-components/immich-logo-small-link.svelte';
import { NotificationType, notificationController } from '../shared-components/notification/notification';
import type { Viewport } from '$lib/stores/assets.store';
Expand All @@ -27,11 +29,12 @@
let { sharedLink = $bindable(), isOwned }: Props = $props();
const viewport: Viewport = $state({ width: 0, height: 0 });
let selectedAssets: Set<AssetResponseDto> = $state(new Set());
const assetInteractionStore = createAssetInteractionStore();
const { selectedAssets } = assetInteractionStore;
let innerWidth: number = $state(0);
let assets = $derived(sharedLink.assets);
let isMultiSelectionMode = $derived(selectedAssets.size > 0);
let isMultiSelectionMode = $derived($selectedAssets.size > 0);
dragAndDropFilesStore.subscribe((value) => {
if (value.isDragging && value.files.length > 0) {
Expand Down Expand Up @@ -70,15 +73,15 @@
};
const handleSelectAll = () => {
selectedAssets = new Set(assets);
assetInteractionStore.selectAssets(assets);
};
</script>

<svelte:window bind:innerWidth />

<section class="bg-immich-bg dark:bg-immich-dark-bg">
{#if isMultiSelectionMode}
<AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new Set())}>
<AssetSelectControlBar assets={$selectedAssets} clearSelect={() => cancelMultiselect(assetInteractionStore)}>
<CircleIconButton title={$t('select_all')} icon={mdiSelectAll} onclick={handleSelectAll} />
{#if sharedLink?.allowDownload}
<DownloadAction filename="immich-shared.zip" />
Expand Down Expand Up @@ -109,6 +112,6 @@
</ControlAppBar>
{/if}
<section class="my-[160px] mx-4" bind:clientHeight={viewport.height} bind:clientWidth={viewport.width}>
<GalleryViewer {assets} bind:selectedAssets {viewport} />
<GalleryViewer {assets} {assetInteractionStore} {viewport} />
</section>
</section>
Loading

0 comments on commit 53cfac3

Please sign in to comment.