Skip to content

Commit

Permalink
Feature: Copy to clipboard
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanDrake committed Dec 17, 2023
1 parent 631cfb5 commit 1c5ad2d
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 0 deletions.
3 changes: 3 additions & 0 deletions resources/icons/copy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/frontend/containers/ContentView/menu-items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,14 @@ export const SlideFileViewerMenuItems = observer(({ file }: { file: ClientFile }
uiStore.openPreviewWindow();
};

const handleCopyToClipboard = () => {
uiStore.selectFile(file, true);
uiStore.copyToClipboard();
};

return (
<>
<MenuItem onClick={handleCopyToClipboard} text="Copy" icon={IconSet.COPY} />
<MenuItem
onClick={handlePreviewWindow}
text="Open In Preview Window"
Expand Down
34 changes: 34 additions & 0 deletions src/frontend/stores/UiStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { action, computed, makeObservable, observable } from 'mobx';

import { maxNumberOfExternalFilesBeforeWarning } from 'common/config';
import { clamp, notEmpty } from 'common/core';
import { encodeFilePath } from 'common/fs';
import { ID } from '../../api/id';
import { SearchCriteria } from '../../api/search-criteria';
import { RendererMessenger } from '../../ipc/renderer';
Expand Down Expand Up @@ -318,6 +319,39 @@ class UiStore {
}
}

@action.bound async copyToClipboard(): Promise<void> {
if (this.fileSelection.size === 0) {
return;
}

const file = Array.from(this.fileSelection)[0];
if (file.isBroken) {
return;
}

try {
const src = await this.rootStore.imageLoader.getImageSrc(file);
if (src !== undefined) {
const image = new Image();
image.src = encodeFilePath(src);
const canvas = new OffscreenCanvas(image.width, image.height);
canvas.width = image.width;
canvas.height = image.height;
const ctx2D = canvas.getContext('2d');
if (!ctx2D) {
throw new Error('Context2D not available!');
}
ctx2D.drawImage(image, 0, 0);
const blob = await canvas.convertToBlob({ type: 'image/png' });
navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]);
} else {
throw new Error('Failed to get image data.');
}
} catch (e) {
console.error('Could not copy image to clipboard', e);
}
}

@action.bound openExternal(warnIfTooManyFiles: boolean = true): void {
// Don't open when no files have been selected
if (this.fileSelection.size === 0) {
Expand Down
2 changes: 2 additions & 0 deletions widgets/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import CHROME_DEVTOOLS from 'resources/icons/chrome-devtools.svg';
import CLEAR_DATABASE from 'resources/icons/clear-database.svg';
import CLOSE from 'resources/icons/close.svg';
import COLOR from 'resources/icons/color.svg';
import COPY from 'resources/icons/copy.svg';
import CHROME_CLOSE from 'resources/icons/chrome-close.svg';
import CHROME_MAXIMIZE from 'resources/icons/chrome-maximize.svg';
import CHROME_MINIMIZE from 'resources/icons/chrome-minimize.svg';
Expand Down Expand Up @@ -130,6 +131,7 @@ const IconSet = {
CLEAR_DATABASE: toSvg(CLEAR_DATABASE),
CLOSE: toSvg(CLOSE),
COLOR: toSvg(COLOR),
COPY: toSvg(COPY),
CHROME_CLOSE: toSvg(CHROME_CLOSE),
CHROME_MAXIMIZE: toSvg(CHROME_MAXIMIZE),
CHROME_MINIMIZE: toSvg(CHROME_MINIMIZE),
Expand Down

0 comments on commit 1c5ad2d

Please sign in to comment.