mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	feat(web): avoid duplicate call + small refactor (#1731)
This commit is contained in:
		
							parent
							
								
									6b3892987a
								
							
						
					
					
						commit
						53fb3a36f7
					
				
							
								
								
									
										14
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							@ -17,7 +17,6 @@
 | 
			
		||||
				"lodash-es": "^4.17.21",
 | 
			
		||||
				"luxon": "^3.1.1",
 | 
			
		||||
				"socket.io-client": "^4.5.1",
 | 
			
		||||
				"svelte-keydown": "^0.5.0",
 | 
			
		||||
				"svelte-material-icons": "^2.0.2"
 | 
			
		||||
			},
 | 
			
		||||
			"devDependencies": {
 | 
			
		||||
@ -54,7 +53,6 @@
 | 
			
		||||
				"svelte": "^3.44.0",
 | 
			
		||||
				"svelte-check": "^2.7.1",
 | 
			
		||||
				"svelte-jester": "^2.3.2",
 | 
			
		||||
				"svelte-keydown": "^0.5.0",
 | 
			
		||||
				"svelte-preprocess": "^4.10.7",
 | 
			
		||||
				"tailwindcss": "^3.0.24",
 | 
			
		||||
				"tslib": "^2.3.1",
 | 
			
		||||
@ -10592,12 +10590,6 @@
 | 
			
		||||
				"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==",
 | 
			
		||||
			"dev": true
 | 
			
		||||
		},
 | 
			
		||||
		"node_modules/svelte-material-icons": {
 | 
			
		||||
			"version": "2.0.4",
 | 
			
		||||
			"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-2.0.4.tgz",
 | 
			
		||||
@ -19031,12 +19023,6 @@
 | 
			
		||||
			"dev": true,
 | 
			
		||||
			"requires": {}
 | 
			
		||||
		},
 | 
			
		||||
		"svelte-keydown": {
 | 
			
		||||
			"version": "0.5.0",
 | 
			
		||||
			"resolved": "https://registry.npmjs.org/svelte-keydown/-/svelte-keydown-0.5.0.tgz",
 | 
			
		||||
			"integrity": "sha512-DgY6AYlKbBocSvjC3kUeNPcStJQOTOCxAGG9ymVHzJdsQ1hRJuB8pcnB4UFH8uH3bAPdYyXXa3LwenLDL41eqQ==",
 | 
			
		||||
			"dev": true
 | 
			
		||||
		},
 | 
			
		||||
		"svelte-material-icons": {
 | 
			
		||||
			"version": "2.0.4",
 | 
			
		||||
			"resolved": "https://registry.npmjs.org/svelte-material-icons/-/svelte-material-icons-2.0.4.tgz",
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,6 @@
 | 
			
		||||
		"svelte": "^3.44.0",
 | 
			
		||||
		"svelte-check": "^2.7.1",
 | 
			
		||||
		"svelte-jester": "^2.3.2",
 | 
			
		||||
		"svelte-keydown": "^0.5.0",
 | 
			
		||||
		"svelte-preprocess": "^4.10.7",
 | 
			
		||||
		"tailwindcss": "^3.0.24",
 | 
			
		||||
		"tslib": "^2.3.1",
 | 
			
		||||
@ -70,7 +69,6 @@
 | 
			
		||||
		"lodash-es": "^4.17.21",
 | 
			
		||||
		"luxon": "^3.1.1",
 | 
			
		||||
		"socket.io-client": "^4.5.1",
 | 
			
		||||
		"svelte-keydown": "^0.5.0",
 | 
			
		||||
		"svelte-material-icons": "^2.0.2"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -304,7 +304,7 @@
 | 
			
		||||
						on:onVideoEnded={() => (shouldPlayMotionPhoto = false)}
 | 
			
		||||
					/>
 | 
			
		||||
				{:else}
 | 
			
		||||
					<PhotoViewer {publicSharedKey} assetId={asset.id} on:close={closeViewer} />
 | 
			
		||||
					<PhotoViewer {publicSharedKey} {asset} on:close={closeViewer} />
 | 
			
		||||
				{/if}
 | 
			
		||||
			{:else}
 | 
			
		||||
				<VideoViewer {publicSharedKey} assetId={asset.id} on:close={closeViewer} />
 | 
			
		||||
 | 
			
		||||
@ -1,39 +1,21 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { fade } from 'svelte/transition';
 | 
			
		||||
 | 
			
		||||
	import { onMount } from 'svelte';
 | 
			
		||||
	import LoadingSpinner from '../shared-components/loading-spinner.svelte';
 | 
			
		||||
	import { api, AssetResponseDto } from '@api';
 | 
			
		||||
	import Keydown from 'svelte-keydown';
 | 
			
		||||
	import { copyImageToClipboard } from 'copy-image-clipboard';
 | 
			
		||||
	import {
 | 
			
		||||
		notificationController,
 | 
			
		||||
		NotificationType
 | 
			
		||||
	} from '../shared-components/notification/notification';
 | 
			
		||||
 | 
			
		||||
	export let assetId: string;
 | 
			
		||||
	export let asset: AssetResponseDto;
 | 
			
		||||
	export let publicSharedKey = '';
 | 
			
		||||
 | 
			
		||||
	let assetInfo: AssetResponseDto;
 | 
			
		||||
	let assetData: string;
 | 
			
		||||
 | 
			
		||||
	let copyImageToClipboard: (src: string) => Promise<Blob>;
 | 
			
		||||
 | 
			
		||||
	onMount(async () => {
 | 
			
		||||
		const { data } = await api.assetApi.getAssetById(assetId, {
 | 
			
		||||
			params: {
 | 
			
		||||
				key: publicSharedKey
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		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 () => {
 | 
			
		||||
		try {
 | 
			
		||||
			const { data } = await api.assetApi.serveFile(assetInfo.id, false, true, {
 | 
			
		||||
			const { data } = await api.assetApi.serveFile(asset.id, false, true, {
 | 
			
		||||
				params: {
 | 
			
		||||
					key: publicSharedKey
 | 
			
		||||
				},
 | 
			
		||||
@ -51,42 +33,51 @@
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const handleKeypress = async (keyEvent: CustomEvent<string>) => {
 | 
			
		||||
		if (keyEvent.detail == 'Control-c' || keyEvent.detail == 'Meta-c') {
 | 
			
		||||
	const handleKeypress = async ({ metaKey, ctrlKey, key }: KeyboardEvent) => {
 | 
			
		||||
		if ((metaKey || ctrlKey) && key === 'c') {
 | 
			
		||||
			await doCopy();
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	export const doCopy = async () => {
 | 
			
		||||
		try {
 | 
			
		||||
			await copyImageToClipboard(assetData);
 | 
			
		||||
			notificationController.show({
 | 
			
		||||
				type: NotificationType.Info,
 | 
			
		||||
				message: 'Copied image to clipboard.',
 | 
			
		||||
				timeout: 3000
 | 
			
		||||
			});
 | 
			
		||||
		} catch (err) {
 | 
			
		||||
			console.error(err);
 | 
			
		||||
			notificationController.show({
 | 
			
		||||
				type: NotificationType.Error,
 | 
			
		||||
				message: 'Copying image to clipboard failed. Click here to learn more.',
 | 
			
		||||
				timeout: 5000,
 | 
			
		||||
				action: {
 | 
			
		||||
					type: 'link',
 | 
			
		||||
					target:
 | 
			
		||||
						'https://github.com/LuanEdCosta/copy-image-clipboard#enable-clipboard-api-features-in-firefox'
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<Keydown on:combo={handleKeypress} />
 | 
			
		||||
 | 
			
		||||
<svelte:window on:copyImage={async () => await doCopy()} />
 | 
			
		||||
<svelte:window on:keydown={handleKeypress} on:copyImage={doCopy} />
 | 
			
		||||
 | 
			
		||||
<div
 | 
			
		||||
	transition:fade={{ duration: 150 }}
 | 
			
		||||
	class="flex place-items-center place-content-center h-full select-none"
 | 
			
		||||
>
 | 
			
		||||
	{#if assetInfo}
 | 
			
		||||
	{#await loadAssetData()}
 | 
			
		||||
		<LoadingSpinner />
 | 
			
		||||
	{:then assetData}
 | 
			
		||||
		<img
 | 
			
		||||
			transition:fade={{ duration: 150 }}
 | 
			
		||||
			src={assetData}
 | 
			
		||||
				alt={assetId}
 | 
			
		||||
			alt={asset.id}
 | 
			
		||||
			class="object-contain h-full transition-all"
 | 
			
		||||
				loading="lazy"
 | 
			
		||||
			draggable="false"
 | 
			
		||||
		/>
 | 
			
		||||
	{/await}
 | 
			
		||||
	{/if}
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@ -1,40 +1,17 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import { fade } from 'svelte/transition';
 | 
			
		||||
 | 
			
		||||
	import { createEventDispatcher, onMount } from 'svelte';
 | 
			
		||||
	import { createEventDispatcher } from 'svelte';
 | 
			
		||||
	import LoadingSpinner from '../shared-components/loading-spinner.svelte';
 | 
			
		||||
	import { api, AssetResponseDto, getFileUrl } from '@api';
 | 
			
		||||
	import { getFileUrl } from '@api';
 | 
			
		||||
 | 
			
		||||
	export let assetId: string;
 | 
			
		||||
	export let publicSharedKey = '';
 | 
			
		||||
	let asset: AssetResponseDto;
 | 
			
		||||
 | 
			
		||||
	let isVideoLoading = true;
 | 
			
		||||
	let videoUrl: string;
 | 
			
		||||
	const dispatch = createEventDispatcher();
 | 
			
		||||
 | 
			
		||||
	onMount(async () => {
 | 
			
		||||
		const { data: assetInfo } = await api.assetApi.getAssetById(assetId, {
 | 
			
		||||
			params: {
 | 
			
		||||
				key: publicSharedKey
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		await loadVideoData(assetInfo);
 | 
			
		||||
 | 
			
		||||
		asset = assetInfo;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const loadVideoData = async (assetInfo: AssetResponseDto) => {
 | 
			
		||||
		isVideoLoading = true;
 | 
			
		||||
 | 
			
		||||
		videoUrl = getFileUrl(assetInfo.id, false, true, publicSharedKey);
 | 
			
		||||
 | 
			
		||||
		return assetInfo;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const handleCanPlay = (ev: Event) => {
 | 
			
		||||
		const playerNode = ev.target as HTMLVideoElement;
 | 
			
		||||
	const handleCanPlay = (ev: Event & { currentTarget: HTMLVideoElement }) => {
 | 
			
		||||
		const playerNode = ev.currentTarget;
 | 
			
		||||
 | 
			
		||||
		playerNode.muted = true;
 | 
			
		||||
		playerNode.play();
 | 
			
		||||
@ -48,14 +25,13 @@
 | 
			
		||||
	transition:fade={{ duration: 150 }}
 | 
			
		||||
	class="flex place-items-center place-content-center h-full select-none"
 | 
			
		||||
>
 | 
			
		||||
	{#if asset}
 | 
			
		||||
	<video
 | 
			
		||||
		controls
 | 
			
		||||
		class="h-full object-contain"
 | 
			
		||||
		src={getFileUrl(assetId, false, true, publicSharedKey)}
 | 
			
		||||
		on:canplay={handleCanPlay}
 | 
			
		||||
		on:ended={() => dispatch('onVideoEnded')}
 | 
			
		||||
	>
 | 
			
		||||
			<source src={videoUrl} type="video/mp4" />
 | 
			
		||||
		<track kind="captions" />
 | 
			
		||||
	</video>
 | 
			
		||||
 | 
			
		||||
@ -64,5 +40,4 @@
 | 
			
		||||
			<LoadingSpinner />
 | 
			
		||||
		</div>
 | 
			
		||||
	{/if}
 | 
			
		||||
	{/if}
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user