Files
immich/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte

38 lines
1.4 KiB
Svelte
Raw Normal View History

<script lang="ts">
2025-04-28 14:48:33 -04:00
import { authManager } from '$lib/managers/auth-manager.svelte';
import { getAssetOriginalUrl, getAssetThumbnailUrl } from '$lib/utils';
import { isWebCompatibleImage } from '$lib/utils/asset-utils';
import { AssetMediaSize, viewAsset, type AssetResponseDto } from '@immich/sdk';
2025-09-16 16:22:13 -04:00
import { LoadingSpinner } from '@immich/ui';
2025-04-28 14:48:33 -04:00
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
type Props = {
asset: AssetResponseDto;
zoomToggle?: (() => void) | null;
};
let { asset, zoomToggle = $bindable() }: Props = $props();
const loadAssetData = async (id: string) => {
const data = await viewAsset({ ...authManager.params, id, size: AssetMediaSize.Preview });
return URL.createObjectURL(data);
};
</script>
<div transition:fade={{ duration: 150 }} class="flex h-full select-none place-content-center place-items-center">
{#await Promise.all([loadAssetData(asset.id), import('./photo-sphere-viewer-adapter.svelte')])}
<LoadingSpinner />
{:then [data, { default: PhotoSphereViewer }]}
<PhotoSphereViewer
bind:zoomToggle
panorama={data}
originalPanorama={isWebCompatibleImage(asset)
? getAssetOriginalUrl(asset.id)
: getAssetThumbnailUrl({ id: asset.id, size: AssetMediaSize.Fullsize, cacheKey: asset.thumbhash })}
/>
{:catch}
{$t('errors.failed_to_load_asset')}
{/await}
</div>