diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index ed31a4b44f..8e1ec4acf7 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -37,6 +37,7 @@ mdiPlus, } from '@mdi/js'; import { DateTime } from 'luxon'; + import { onDestroy } from 'svelte'; import { t } from 'svelte-i18n'; import { slide } from 'svelte/transition'; import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte'; @@ -52,7 +53,6 @@ let { asset, currentAlbum = null }: Props = $props(); - let showEditFaces = $derived(assetViewerManager.isEditFacesPanelOpen); let isOwner = $derived(authManager.authenticated && authManager.user.id === asset.ownerId); let people = $derived(asset.people || []); let unassignedFaces = $derived(asset.unassignedFaces || []); @@ -118,379 +118,385 @@ // Remove the last part of the path to get the parent path return Route.folders({ path: getParentPath(asset.originalPath) }); }; + + onDestroy(() => { + assetViewerManager.closeEditFacesPanel(); + }); (albums = refreshAlbums())} /> -
-
- assetViewerManager.closeDetailPanel()} - shape="round" - color="secondary" - variant="ghost" - /> -

{$t('info')}

-
+{#if !assetViewerManager.isEditFacesPanelOpen} +
+
+ assetViewerManager.closeDetailPanel()} + shape="round" + color="secondary" + variant="ghost" + /> +

{$t('info')}

+
- {#if asset.isOffline} -
-
-
- {$t('asset_offline')} + {#if asset.isOffline} +
+
+
+ {$t('asset_offline')} +
+
+

+ {#if authManager.authenticated && authManager.user.isAdmin} + {$t('admin.asset_offline_description')} + {:else} + {$t('asset_offline_description')} + {/if} +

+
+
+

{asset.originalPath}

+
-
-

- {#if authManager.authenticated && authManager.user.isAdmin} - {$t('admin.asset_offline_description')} - {:else} - {$t('asset_offline_description')} +

+ {/if} + + + + + {#if !authManager.isSharedLink && isOwner} +
+
+ {$t('people')} +
+ {#if people.some((person) => person.isHidden)} + (showingHiddenPeople = !showingHiddenPeople)} + /> + {/if} + assetViewerManager.toggleFaceEditMode()} + /> + + {#if people.length > 0 || unassignedFaces.length > 0} + assetViewerManager.openEditFacesPanel()} + /> + {/if} +
+
+ + +
+ {/if} + +
+ {#if asset.exifInfo} +
+ {$t('details')} +
+ {:else} + {$t('no_exif_info_available')} + {/if} + + + +
+
+ +
+

+ {asset.originalFileName} + {#if isOwner} + assetViewerManager.toggleAssetPath()} + /> {/if}

-
-
-

{asset.originalPath}

-
-
-
- {/if} - - - - - {#if !authManager.isSharedLink && isOwner} -
-
- {$t('people')} -
- {#if people.some((person) => person.isHidden)} - (showingHiddenPeople = !showingHiddenPeople)} - /> + {#if assetViewerManager.isShowAssetPath} +

+ + + {asset.originalPath} + +

{/if} - assetViewerManager.toggleFaceEditMode()} - /> - - {#if people.length > 0 || unassignedFaces.length > 0} - assetViewerManager.openEditFacesPanel()} - /> - {/if} -
-
- -
- {#each people as person, index (person.id)} - {#if showingHiddenPeople || !person.isHidden} - {@const isHighlighted = people[index].faces.some((f) => $boundingBoxesArray.some((b) => b.id === f.id))} - ($boundingBoxesArray = people[index].faces)} - onblur={() => ($boundingBoxesArray = [])} - onmouseover={() => ($boundingBoxesArray = people[index].faces)} - onmouseleave={() => ($boundingBoxesArray = [])} - > -
-
-

{person.name}

- {#if person.birthDate} - {@const personBirthDate = DateTime.fromISO(person.birthDate)} - {@const age = Math.floor(DateTime.fromISO(asset.localDateTime).diff(personBirthDate, 'years').years)} - {@const ageInMonths = Math.floor( - DateTime.fromISO(asset.localDateTime).diff(personBirthDate, 'months').months, - )} - {#if age >= 0} -

- {#if ageInMonths <= 11} - {$t('age_months', { values: { months: ageInMonths } })} - {:else if ageInMonths > 12 && ageInMonths <= 23} - {$t('age_year_months', { values: { months: ageInMonths - 12 } })} - {:else} - {$t('age_years', { values: { years: age } })} - {/if} + {#if (asset.exifInfo?.exifImageHeight && asset.exifInfo?.exifImageWidth) || asset.exifInfo?.fileSizeInByte} +

{/if} - {/each} +
+ + + {#if asset.exifInfo?.make || asset.exifInfo?.model || asset.exifInfo?.exposureTime || asset.exifInfo?.iso} +
+
+ +
+ {#if asset.exifInfo?.make || asset.exifInfo?.model} +

+ + {asset.exifInfo.make || ''} + {asset.exifInfo.model || ''} + +

+ {/if} + +
+ {#if asset.exifInfo.exposureTime} +

{`${asset.exifInfo.exposureTime} s`}

+ {/if} + + {#if asset.exifInfo.iso} +

{`ISO ${asset.exifInfo.iso}`}

+ {/if} +
+
+
+ {/if} + + {#if asset.exifInfo?.lensModel || asset.exifInfo?.fNumber || asset.exifInfo?.focalLength} +
+
+ +
+ {#if asset.exifInfo?.lensModel} +

+ + {asset.exifInfo.lensModel} + +

+ {/if} + +
+ {#if asset.exifInfo?.fNumber} +

ƒ/{asset.exifInfo.fNumber.toLocaleString($locale)}

+ {/if} + + {#if asset.exifInfo.focalLength} +

{`${asset.exifInfo.focalLength.toLocaleString($locale)} mm`}

+ {/if} +
+
+
+ {/if} + + + +
+ + {#if latlng && featureFlagsManager.value.map} +
+ {#await import('$lib/components/shared-components/map/map.svelte')} + {#await delay(timeToLoadTheMap) then} + +
+ +
+ {/await} + {:then { default: Map }} + goto(Route.map({ ...latlng, zoom: 12.5 }))} + > + {#snippet popup({ marker })} + {@const { lat, lon } = marker} +
+

{lat.toPrecision(6)}, {lon.toPrecision(6)}

+ + {$t('open_in_openstreetmap')} + +
+ {/snippet} +
+ {/await} +
+ {/if} + + {#if currentAlbum && currentAlbum.albumUsers.length > 0 && asset.owner} +
+ {$t('shared_by')} +
+
+ +
+ +
+

+ {asset.owner.name} +

+
{/if} -
- {#if asset.exifInfo} -
- {$t('details')} -
- {:else} - {$t('no_exif_info_available')} - {/if} - - - -
-
- -
-

- {asset.originalFileName} - {#if isOwner} - assetViewerManager.toggleAssetPath()} - /> - {/if} -

- {#if assetViewerManager.isShowAssetPath} -

- - - {asset.originalPath} - -

- {/if} - {#if (asset.exifInfo?.exifImageHeight && asset.exifInfo?.exifImageWidth) || asset.exifInfo?.fileSizeInByte} -
- {#if asset.exifInfo?.exifImageHeight && asset.exifInfo?.exifImageWidth} - {#if getMegapixel(asset.exifInfo.exifImageHeight, asset.exifInfo.exifImageWidth)} -

- {getMegapixel(asset.exifInfo.exifImageHeight, asset.exifInfo.exifImageWidth)} MP -

- {/if} - {@const { width, height } = getDimensions(asset.exifInfo)} -

{width} x {height}

- {/if} - {#if asset.exifInfo?.fileSizeInByte} -

{getByteUnitString(asset.exifInfo.fileSizeInByte, $locale)}

- {/if} -
- {/if} -
-
- - {#if asset.exifInfo?.make || asset.exifInfo?.model || asset.exifInfo?.exposureTime || asset.exifInfo?.iso} -
-
- -
- {#if asset.exifInfo?.make || asset.exifInfo?.model} -

- - {asset.exifInfo.make || ''} - {asset.exifInfo.model || ''} - -

- {/if} - -
- {#if asset.exifInfo.exposureTime} -

{`${asset.exifInfo.exposureTime} s`}

- {/if} - - {#if asset.exifInfo.iso} -

{`ISO ${asset.exifInfo.iso}`}

- {/if} -
+ {#await albums then albums} + {#if albums.length > 0} +
+
+ {$t('appears_in')}
-
- {/if} + {#each albums as album (album.id)} + +
+
+ {album.albumName} +
- {#if asset.exifInfo?.lensModel || asset.exifInfo?.fNumber || asset.exifInfo?.focalLength} -
-
- -
- {#if asset.exifInfo?.lensModel} -

- - {asset.exifInfo.lensModel} - -

- {/if} - -
- {#if asset.exifInfo?.fNumber} -

ƒ/{asset.exifInfo.fNumber.toLocaleString($locale)}

- {/if} - - {#if asset.exifInfo.focalLength} -

{`${asset.exifInfo.focalLength.toLocaleString($locale)} mm`}

- {/if} -
-
-
- {/if} - - -
-
- -{#if latlng && featureFlagsManager.value.map} -
- {#await import('$lib/components/shared-components/map/map.svelte')} - {#await delay(timeToLoadTheMap) then} - -
- -
- {/await} - {:then { default: Map }} - goto(Route.map({ ...latlng, zoom: 12.5 }))} - > - {#snippet popup({ marker })} - {@const { lat, lon } = marker} -
-

{lat.toPrecision(6)}, {lon.toPrecision(6)}

- - {$t('open_in_openstreetmap')} - -
- {/snippet} -
- {/await} -
-{/if} - -{#if currentAlbum && currentAlbum.albumUsers.length > 0 && asset.owner} -
- {$t('shared_by')} -
-
- -
- -
-

- {asset.owner.name} -

-
-
-
-{/if} - -{#await albums then albums} - {#if albums.length > 0} -
-
- {$t('appears_in')} -
- {#each albums as album (album.id)} - -
+ {/if} + {/await} + + {#if authManager.authenticated && authManager.preferences.tags.enabled} +
+
{/if} -{/await} - -{#if authManager.authenticated && authManager.preferences.tags.enabled} -
- -
{/if} -{#if showEditFaces} +{#if assetViewerManager.isEditFacesPanelOpen} { this.closeFaceEditMode(); this.closeEditFacesPanel(); } - setAsset(asset: AssetResponseDto) { this.#viewingAssetStoreState = asset; this.#viewState = true;