mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	feat(web) add handler for ctrl-c copying images from viewer (#881)
This commit is contained in:
		
							
								
								
									
										22
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										22
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -10,12 +10,14 @@ | |||||||
| 			"dependencies": { | 			"dependencies": { | ||||||
| 				"axios": "^0.27.2", | 				"axios": "^0.27.2", | ||||||
| 				"cookie": "^0.4.2", | 				"cookie": "^0.4.2", | ||||||
|  | 				"copy-image-clipboard": "^2.1.2", | ||||||
| 				"exifr": "^7.1.3", | 				"exifr": "^7.1.3", | ||||||
| 				"leaflet": "^1.8.0", | 				"leaflet": "^1.8.0", | ||||||
| 				"lodash": "^4.17.21", | 				"lodash": "^4.17.21", | ||||||
| 				"lodash-es": "^4.17.21", | 				"lodash-es": "^4.17.21", | ||||||
| 				"moment": "^2.29.3", | 				"moment": "^2.29.3", | ||||||
| 				"socket.io-client": "^4.5.1", | 				"socket.io-client": "^4.5.1", | ||||||
|  | 				"svelte-keydown": "^0.5.0", | ||||||
| 				"svelte-material-icons": "^2.0.2" | 				"svelte-material-icons": "^2.0.2" | ||||||
| 			}, | 			}, | ||||||
| 			"devDependencies": { | 			"devDependencies": { | ||||||
| @@ -4455,6 +4457,11 @@ | |||||||
| 				"node": ">= 0.6" | 				"node": ">= 0.6" | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
|  | 		"node_modules/copy-image-clipboard": { | ||||||
|  | 			"version": "2.1.2", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/copy-image-clipboard/-/copy-image-clipboard-2.1.2.tgz", | ||||||
|  | 			"integrity": "sha512-3VCXVl2IpFfOyD8drv9DozcNlwmqBqxOlsgkEGyVAzadjlPk1go8YNZyy8QmTnwHPxSFpeCR9OdsStEdVK7qDA==" | ||||||
|  | 		}, | ||||||
| 		"node_modules/core-js-compat": { | 		"node_modules/core-js-compat": { | ||||||
| 			"version": "3.25.1", | 			"version": "3.25.1", | ||||||
| 			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.1.tgz", | 			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.1.tgz", | ||||||
| @@ -10334,6 +10341,11 @@ | |||||||
| 				"svelte": ">= 3" | 				"svelte": ">= 3" | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
|  | 		"node_modules/svelte-keydown": { | ||||||
|  | 			"version": "0.5.0", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/svelte-keydown/-/svelte-keydown-0.5.0.tgz", | ||||||
|  | 			"integrity": "sha512-DgY6AYlKbBocSvjC3kUeNPcStJQOTOCxAGG9ymVHzJdsQ1hRJuB8pcnB4UFH8uH3bAPdYyXXa3LwenLDL41eqQ==" | ||||||
|  | 		}, | ||||||
| 		"node_modules/svelte-material-icons": { | 		"node_modules/svelte-material-icons": { | ||||||
| 			"version": "2.0.4", | 			"version": "2.0.4", | ||||||
| 			"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-2.0.4.tgz", | 			"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-2.0.4.tgz", | ||||||
| @@ -14401,6 +14413,11 @@ | |||||||
| 			"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", | 			"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", | ||||||
| 			"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" | 			"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" | ||||||
| 		}, | 		}, | ||||||
|  | 		"copy-image-clipboard": { | ||||||
|  | 			"version": "2.1.2", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/copy-image-clipboard/-/copy-image-clipboard-2.1.2.tgz", | ||||||
|  | 			"integrity": "sha512-3VCXVl2IpFfOyD8drv9DozcNlwmqBqxOlsgkEGyVAzadjlPk1go8YNZyy8QmTnwHPxSFpeCR9OdsStEdVK7qDA==" | ||||||
|  | 		}, | ||||||
| 		"core-js-compat": { | 		"core-js-compat": { | ||||||
| 			"version": "3.25.1", | 			"version": "3.25.1", | ||||||
| 			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.1.tgz", | 			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.1.tgz", | ||||||
| @@ -18619,6 +18636,11 @@ | |||||||
| 			"dev": true, | 			"dev": true, | ||||||
| 			"requires": {} | 			"requires": {} | ||||||
| 		}, | 		}, | ||||||
|  | 		"svelte-keydown": { | ||||||
|  | 			"version": "0.5.0", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/svelte-keydown/-/svelte-keydown-0.5.0.tgz", | ||||||
|  | 			"integrity": "sha512-DgY6AYlKbBocSvjC3kUeNPcStJQOTOCxAGG9ymVHzJdsQ1hRJuB8pcnB4UFH8uH3bAPdYyXXa3LwenLDL41eqQ==" | ||||||
|  | 		}, | ||||||
| 		"svelte-material-icons": { | 		"svelte-material-icons": { | ||||||
| 			"version": "2.0.4", | 			"version": "2.0.4", | ||||||
| 			"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-2.0.4.tgz", | 			"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-2.0.4.tgz", | ||||||
|   | |||||||
| @@ -59,12 +59,14 @@ | |||||||
| 	"dependencies": { | 	"dependencies": { | ||||||
| 		"axios": "^0.27.2", | 		"axios": "^0.27.2", | ||||||
| 		"cookie": "^0.4.2", | 		"cookie": "^0.4.2", | ||||||
|  | 		"copy-image-clipboard": "^2.1.2", | ||||||
| 		"exifr": "^7.1.3", | 		"exifr": "^7.1.3", | ||||||
| 		"leaflet": "^1.8.0", | 		"leaflet": "^1.8.0", | ||||||
| 		"lodash": "^4.17.21", | 		"lodash": "^4.17.21", | ||||||
| 		"lodash-es": "^4.17.21", | 		"lodash-es": "^4.17.21", | ||||||
| 		"moment": "^2.29.3", | 		"moment": "^2.29.3", | ||||||
| 		"socket.io-client": "^4.5.1", | 		"socket.io-client": "^4.5.1", | ||||||
|  | 		"svelte-keydown": "^0.5.0", | ||||||
| 		"svelte-material-icons": "^2.0.2" | 		"svelte-material-icons": "^2.0.2" | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,15 +4,23 @@ | |||||||
| 	import { onMount } from 'svelte'; | 	import { onMount } from 'svelte'; | ||||||
| 	import LoadingSpinner from '../shared-components/loading-spinner.svelte'; | 	import LoadingSpinner from '../shared-components/loading-spinner.svelte'; | ||||||
| 	import { api, AssetResponseDto } from '@api'; | 	import { api, AssetResponseDto } from '@api'; | ||||||
|  | 	import Keydown from 'svelte-keydown'; | ||||||
|  |  | ||||||
| 	export let assetId: string; | 	export let assetId: string; | ||||||
| 	export let deviceId: string; | 	export let deviceId: string; | ||||||
|  |  | ||||||
| 	let assetInfo: AssetResponseDto; | 	let assetInfo: AssetResponseDto; | ||||||
|  | 	let assetData: string; | ||||||
|  |  | ||||||
|  | 	let copyImageToClipboard : (src: string) => Promise<Blob>; | ||||||
|  |  | ||||||
| 	onMount(async () => { | 	onMount(async () => { | ||||||
| 		const { data } = await api.assetApi.getAssetById(assetId); | 		const { data } = await api.assetApi.getAssetById(assetId); | ||||||
| 		assetInfo = data; | 		assetInfo = data; | ||||||
|  |  | ||||||
|  | 		//Import hack :( see https://github.com/vadimkorr/svelte-carousel/issues/27#issuecomment-851022295 | ||||||
|  | 		const module = await import('copy-image-clipboard') | ||||||
|  | 		copyImageToClipboard = module.copyImageToClipboard; | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	const loadAssetData = async () => { | 	const loadAssetData = async () => { | ||||||
| @@ -31,14 +39,22 @@ | |||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			const assetData = URL.createObjectURL(data); | 			assetData = URL.createObjectURL(data); | ||||||
| 			return assetData; | 			return assetData; | ||||||
| 		} catch { | 		} catch { | ||||||
| 			// Do nothing | 			// Do nothing | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	const handleCopy = async (keyEvent: CustomEvent<string>) => { | ||||||
|  | 		if (keyEvent.detail == 'Control-c' || keyEvent.detail == 'Meta-c') { | ||||||
|  | 			await copyImageToClipboard(assetData); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | <Keydown on:combo={handleCopy} /> | ||||||
|  |  | ||||||
| <div | <div | ||||||
| 	transition:fade={{ duration: 150 }} | 	transition:fade={{ duration: 150 }} | ||||||
| 	class="flex place-items-center place-content-center h-full select-none" | 	class="flex place-items-center place-content-center h-full select-none" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user