1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

Add navbar button to copy image (#961)

* Add navbar button to copy image

* Use global event for copy image

* merge upstream

* Fixed missing required props

* feat(web): Show notification after copying image to clipboard

* chore(web): Fix typescript error

* chore(web): Formatting

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
bo0tzz 2022-11-16 22:04:37 +01:00 committed by GitHub
parent e799f35dd2
commit 70cd313082
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 5 deletions

8
web/src/app.d.ts vendored
View File

@ -9,3 +9,11 @@ declare namespace App {
// interface Platform {}
}
// Source: https://stackoverflow.com/questions/63814432/typescript-typing-of-non-standard-window-event-in-svelte
// To fix the <svelte:window... in components/asset-viewer/photo-viewer.svelte
declare namespace svelte.JSX {
interface HTMLAttributes<T> {
oncopyImage?: () => void;
}
}

View File

@ -11,10 +11,13 @@
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
import Star from 'svelte-material-icons/Star.svelte';
import StarOutline from 'svelte-material-icons/StarOutline.svelte';
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
import { page } from '$app/stores';
import { AssetResponseDto } from '../../../api';
export let asset: AssetResponseDto;
export let showCopyButton: boolean;
const isOwner = asset.ownerId === $page.data.user.id;
@ -45,6 +48,15 @@
<CircleIconButton logo={ArrowLeft} on:click={() => dispatch('goBack')} />
</div>
<div class="text-white flex gap-2">
{#if showCopyButton}
<CircleIconButton
logo={ContentCopy}
on:click={() => {
const copyEvent = new CustomEvent('copyImage');
window.dispatchEvent(copyEvent);
}}
/>
{/if}
<CircleIconButton logo={CloudDownloadOutline} on:click={() => dispatch('download')} />
<CircleIconButton logo={InformationOutline} on:click={() => dispatch('showDetail')} />
{#if isOwner}

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { createEventDispatcher, onMount, onDestroy } from 'svelte';
import { fly } from 'svelte/transition';
import AsserViewerNavBar from './asset-viewer-nav-bar.svelte';
import AssetViewerNavBar from './asset-viewer-nav-bar.svelte';
import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
import PhotoViewer from './photo-viewer.svelte';
@ -219,11 +219,12 @@
class="fixed h-screen w-screen top-0 overflow-y-hidden bg-black z-[999] grid grid-rows-[64px_1fr] grid-cols-4"
>
<div class="col-start-1 col-span-4 row-start-1 row-span-1 z-[1000] transition-transform">
<AsserViewerNavBar
<AssetViewerNavBar
{asset}
on:goBack={closeViewer}
on:showDetail={showDetailInfoHandler}
on:download={downloadFile}
showCopyButton={asset.type === AssetTypeEnum.Image}
on:delete={deleteAsset}
on:favorite={toggleFavorite}
on:addToAlbum={() => openAlbumPicker(false)}

View File

@ -5,6 +5,10 @@
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
import { api, AssetResponseDto } from '@api';
import Keydown from 'svelte-keydown';
import {
notificationController,
NotificationType
} from '../shared-components/notification/notification';
export let assetId: string;
@ -39,14 +43,25 @@
}
};
const handleCopy = async (keyEvent: CustomEvent<string>) => {
const handleKeypress = async (keyEvent: CustomEvent<string>) => {
if (keyEvent.detail == 'Control-c' || keyEvent.detail == 'Meta-c') {
await copyImageToClipboard(assetData);
await doCopy();
}
};
export const doCopy = async () => {
await copyImageToClipboard(assetData);
notificationController.show({
type: NotificationType.Info,
message: 'Copied image to clipboard.',
timeout: 3000
});
};
</script>
<Keydown on:combo={handleCopy} />
<Keydown on:combo={handleKeypress} />
<svelte:window on:copyImage={async () => await doCopy()} />
<div
transition:fade={{ duration: 150 }}