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:
parent
f9fbf1a2a5
commit
48e4ea5231
6 changed files with 45 additions and 3 deletions
1
web/src/app.d.ts
vendored
1
web/src/app.d.ts
vendored
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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 }}
|
||||
|
|
|
@ -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} />
|
||||
|
|
4
web/src/lib/stores/zoom-image.store.ts
Normal file
4
web/src/lib/stores/zoom-image.store.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { writable } from 'svelte/store';
|
||||
import type { ZoomImageWheelState } from '@zoom-image/core';
|
||||
|
||||
export const photoZoomState = writable<ZoomImageWheelState>();
|
Loading…
Reference in a new issue