feat(web): add zoom toggle icon (#2873)

* feat(web): add zoom toggle icon

* update zoom-image dependency

* fix lint issues

* remove variable testing line

* Simplify code using ternary conditional

Co-authored-by: Thomas <9749173+uhthomas@users.noreply.github.com>

* fix typo

---------

Co-authored-by: Thomas <9749173+uhthomas@users.noreply.github.com>
This commit is contained in:
Manuel Taberna 2023-06-20 16:36:38 +02:00 committed by GitHub
parent f9fbf1a2a5
commit 48e4ea5231
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 3 deletions

1
web/src/app.d.ts vendored
View file

@ -29,5 +29,6 @@ declare namespace svelteHTML {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface HTMLAttributes<T> {
'on:copyImage'?: () => void;
'on:zoomImage'?: () => void;
}
}

View file

@ -11,14 +11,18 @@
import Heart from 'svelte-material-icons/Heart.svelte';
import HeartOutline from 'svelte-material-icons/HeartOutline.svelte';
import InformationOutline from 'svelte-material-icons/InformationOutline.svelte';
import MagnifyPlusOutline from 'svelte-material-icons/MagnifyPlusOutline.svelte';
import MagnifyMinusOutline from 'svelte-material-icons/MagnifyMinusOutline.svelte';
import MotionPauseOutline from 'svelte-material-icons/MotionPauseOutline.svelte';
import MotionPlayOutline from 'svelte-material-icons/MotionPlayOutline.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
import { photoZoomState } from '$lib/stores/zoom-image.store';
export let asset: AssetResponseDto;
export let showCopyButton: boolean;
export let showZoomButton: boolean;
export let showMotionPlayButton: boolean;
export let isMotionPhotoPlaying = false;
export let showDownloadButton: boolean;
@ -65,6 +69,20 @@
/>
{/if}
{/if}
{#if showZoomButton}
<CircleIconButton
isOpacity={true}
hideMobile={true}
logo={$photoZoomState && $photoZoomState.currentZoom > 1
? MagnifyMinusOutline
: MagnifyPlusOutline}
title="Zoom Image"
on:click={() => {
const zoomImage = new CustomEvent('zoomImage');
window.dispatchEvent(zoomImage);
}}
/>
{/if}
{#if showCopyButton}
<CircleIconButton
isOpacity={true}

View file

@ -308,6 +308,7 @@
{asset}
isMotionPhotoPlaying={shouldPlayMotionPhoto}
showCopyButton={canCopyImagesToClipboard && asset.type === AssetTypeEnum.Image}
showZoomButton={asset.type === AssetTypeEnum.Image}
showMotionPlayButton={!!asset.livePhotoVideoId}
showDownloadButton={shouldShowDownloadButton}
on:goBack={closeViewer}

View file

@ -8,6 +8,7 @@
NotificationType
} from '../shared-components/notification/notification';
import { useZoomImageWheel } from '@zoom-image/svelte';
import { photoZoomState } from '$lib/stores/zoom-image.store';
export let asset: AssetResponseDto;
export let publicSharedKey = '';
@ -73,7 +74,22 @@
}
};
const { createZoomImage: createZoomImageWheel } = useZoomImageWheel();
const doZoomImage = async () => {
setZoomImageWheelState({
currentZoom: $zoomImageWheelState.currentZoom === 1 ? 2 : 1
});
};
const {
createZoomImage: createZoomImageWheel,
zoomImageState: zoomImageWheelState,
setZoomImageState: setZoomImageWheelState
} = useZoomImageWheel();
zoomImageWheelState.subscribe((state) => {
photoZoomState.set(state);
});
$: if (imgElement) {
createZoomImageWheel(imgElement, {
wheelZoomRatio: 0.06
@ -81,7 +97,7 @@
}
</script>
<svelte:window on:keydown={handleKeypress} on:copyImage={doCopy} />
<svelte:window on:keydown={handleKeypress} on:copyImage={doCopy} on:zoomImage={doZoomImage} />
<div
transition:fade={{ duration: 150 }}

View file

@ -8,6 +8,7 @@
export let title = '';
export let isOpacity = false;
export let forceDark = false;
export let hideMobile = false;
</script>
<button
@ -17,7 +18,8 @@
class:dark:text-immich-dark-fg={!forceDark}
class="rounded-full p-3 flex place-items-center place-content-center transition-all
{isOpacity ? 'hover:bg-immich-bg/30' : 'immich-circle-icon-button hover:dark:text-immich-dark-gray'}
{forceDark && 'hover:text-black'}"
{forceDark && 'hover:text-black'}
{hideMobile && 'hidden sm:flex'}"
on:click
>
<svelte:component this={logo} {size} />

View file

@ -0,0 +1,4 @@
import { writable } from 'svelte/store';
import type { ZoomImageWheelState } from '@zoom-image/core';
export const photoZoomState = writable<ZoomImageWheelState>();