Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added shortcuts, shift-multi select and missing menu options to Search (Galleryviewer) #14213

Merged
merged 2 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading