mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
perf: move album fetching into detail panel (#26632)
This commit is contained in:
@@ -30,7 +30,6 @@
|
|||||||
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
import { toTimelineAsset } from '$lib/utils/timeline-util';
|
||||||
import {
|
import {
|
||||||
AssetTypeEnum,
|
AssetTypeEnum,
|
||||||
getAllAlbums,
|
|
||||||
getAssetInfo,
|
getAssetInfo,
|
||||||
getStack,
|
getStack,
|
||||||
type AlbumResponseDto,
|
type AlbumResponseDto,
|
||||||
@@ -105,7 +104,6 @@
|
|||||||
const asset = $derived(cursor.current);
|
const asset = $derived(cursor.current);
|
||||||
const nextAsset = $derived(cursor.nextAsset);
|
const nextAsset = $derived(cursor.nextAsset);
|
||||||
const previousAsset = $derived(cursor.previousAsset);
|
const previousAsset = $derived(cursor.previousAsset);
|
||||||
let appearsInAlbums: AlbumResponseDto[] = $state([]);
|
|
||||||
let sharedLink = getSharedLink();
|
let sharedLink = getSharedLink();
|
||||||
let previewStackedAsset: AssetResponseDto | undefined = $state();
|
let previewStackedAsset: AssetResponseDto | undefined = $state();
|
||||||
let fullscreenElement = $state<Element>();
|
let fullscreenElement = $state<Element>();
|
||||||
@@ -147,7 +145,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(() => {
|
||||||
syncAssetViewerOpenClass(true);
|
syncAssetViewerOpenClass(true);
|
||||||
unsubscribes.push(
|
unsubscribes.push(
|
||||||
slideshowState.subscribe((value) => {
|
slideshowState.subscribe((value) => {
|
||||||
@@ -166,8 +164,6 @@
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await onAlbumAddAssets();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
@@ -180,18 +176,6 @@
|
|||||||
syncAssetViewerOpenClass(false);
|
syncAssetViewerOpenClass(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
const onAlbumAddAssets = async () => {
|
|
||||||
if (authManager.isSharedLink) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
appearsInAlbums = await getAllAlbums({ assetId: asset.id });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error getting album that asset belong to', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeViewer = () => {
|
const closeViewer = () => {
|
||||||
onClose?.(asset);
|
onClose?.(asset);
|
||||||
};
|
};
|
||||||
@@ -363,7 +347,6 @@
|
|||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
await refreshStack();
|
await refreshStack();
|
||||||
await onAlbumAddAssets();
|
|
||||||
ocrManager.clear();
|
ocrManager.clear();
|
||||||
if (!sharedLink) {
|
if (!sharedLink) {
|
||||||
if (previewStackedAsset) {
|
if (previewStackedAsset) {
|
||||||
@@ -441,7 +424,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CommandPaletteDefaultProvider name={$t('assets')} actions={[Tag]} />
|
<CommandPaletteDefaultProvider name={$t('assets')} actions={[Tag]} />
|
||||||
<OnEvents {onAssetReplace} {onAssetUpdate} {onAlbumAddAssets} />
|
<OnEvents {onAssetReplace} {onAssetUpdate} />
|
||||||
|
|
||||||
<svelte:document bind:fullscreenElement />
|
<svelte:document bind:fullscreenElement />
|
||||||
|
|
||||||
@@ -586,7 +569,7 @@
|
|||||||
>
|
>
|
||||||
{#if showDetailPanel}
|
{#if showDetailPanel}
|
||||||
<div class="w-90 h-full">
|
<div class="w-90 h-full">
|
||||||
<DetailPanel {asset} currentAlbum={album} albums={appearsInAlbums} />
|
<DetailPanel {asset} currentAlbum={album} />
|
||||||
</div>
|
</div>
|
||||||
{:else if assetViewerManager.isShowEditor}
|
{:else if assetViewerManager.isShowEditor}
|
||||||
<div class="w-100 h-full">
|
<div class="w-100 h-full">
|
||||||
|
|||||||
@@ -17,9 +17,16 @@
|
|||||||
import { getAssetMediaUrl, getPeopleThumbnailUrl } from '$lib/utils';
|
import { getAssetMediaUrl, getPeopleThumbnailUrl } from '$lib/utils';
|
||||||
import { delay, getDimensions } from '$lib/utils/asset-utils';
|
import { delay, getDimensions } from '$lib/utils/asset-utils';
|
||||||
import { getByteUnitString } from '$lib/utils/byte-units';
|
import { getByteUnitString } from '$lib/utils/byte-units';
|
||||||
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { fromISODateTime, fromISODateTimeUTC, toTimelineAsset } from '$lib/utils/timeline-util';
|
import { fromISODateTime, fromISODateTimeUTC, toTimelineAsset } from '$lib/utils/timeline-util';
|
||||||
import { getParentPath } from '$lib/utils/tree-utils';
|
import { getParentPath } from '$lib/utils/tree-utils';
|
||||||
import { AssetMediaSize, getAssetInfo, type AlbumResponseDto, type AssetResponseDto } from '@immich/sdk';
|
import {
|
||||||
|
AssetMediaSize,
|
||||||
|
getAllAlbums,
|
||||||
|
getAssetInfo,
|
||||||
|
type AlbumResponseDto,
|
||||||
|
type AssetResponseDto,
|
||||||
|
} from '@immich/sdk';
|
||||||
import { Icon, IconButton, LoadingSpinner, modalManager, Text } from '@immich/ui';
|
import { Icon, IconButton, LoadingSpinner, modalManager, Text } from '@immich/ui';
|
||||||
import {
|
import {
|
||||||
mdiCalendar,
|
mdiCalendar,
|
||||||
@@ -38,16 +45,16 @@
|
|||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
|
||||||
import PersonSidePanel from '../faces-page/person-side-panel.svelte';
|
import PersonSidePanel from '../faces-page/person-side-panel.svelte';
|
||||||
|
import OnEvents from '../OnEvents.svelte';
|
||||||
import UserAvatar from '../shared-components/user-avatar.svelte';
|
import UserAvatar from '../shared-components/user-avatar.svelte';
|
||||||
import AlbumListItemDetails from './album-list-item-details.svelte';
|
import AlbumListItemDetails from './album-list-item-details.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
asset: AssetResponseDto;
|
asset: AssetResponseDto;
|
||||||
albums?: AlbumResponseDto[];
|
|
||||||
currentAlbum?: AlbumResponseDto | null;
|
currentAlbum?: AlbumResponseDto | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { asset, albums = [], currentAlbum = null }: Props = $props();
|
let { asset, currentAlbum = null }: Props = $props();
|
||||||
|
|
||||||
let showAssetPath = $state(false);
|
let showAssetPath = $state(false);
|
||||||
let showEditFaces = $state(false);
|
let showEditFaces = $state(false);
|
||||||
@@ -74,14 +81,33 @@
|
|||||||
let previousId: string | undefined = $state();
|
let previousId: string | undefined = $state();
|
||||||
let previousRoute = $derived(currentAlbum?.id ? Route.viewAlbum(currentAlbum) : Route.photos());
|
let previousRoute = $derived(currentAlbum?.id ? Route.viewAlbum(currentAlbum) : Route.photos());
|
||||||
|
|
||||||
|
const refreshAlbums = async () => {
|
||||||
|
if (authManager.isSharedLink) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await getAllAlbums({ assetId: asset.id });
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error, 'Error getting asset album membership');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let albums = $derived(refreshAlbums());
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!previousId) {
|
if (!previousId) {
|
||||||
previousId = asset.id;
|
previousId = asset.id;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (asset.id !== previousId) {
|
|
||||||
showEditFaces = false;
|
if (asset.id === previousId) {
|
||||||
previousId = asset.id;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showEditFaces = false;
|
||||||
|
previousId = asset.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const getMegapixel = (width: number, height: number): number | undefined => {
|
const getMegapixel = (width: number, height: number): number | undefined => {
|
||||||
@@ -119,6 +145,8 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<OnEvents onAlbumAddAssets={() => (albums = refreshAlbums())} />
|
||||||
|
|
||||||
<section class="relative p-2">
|
<section class="relative p-2">
|
||||||
<div class="flex place-items-center gap-2">
|
<div class="flex place-items-center gap-2">
|
||||||
<IconButton
|
<IconButton
|
||||||
@@ -502,37 +530,39 @@
|
|||||||
</section>
|
</section>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if albums.length > 0}
|
{#await albums then albums}
|
||||||
<section class="px-6 py-6 dark:text-immich-dark-fg">
|
{#if albums.length > 0}
|
||||||
<div class="pb-4">
|
<section class="px-6 py-6 dark:text-immich-dark-fg">
|
||||||
<Text size="small" color="muted">{$t('appears_in')}</Text>
|
<div class="pb-4">
|
||||||
</div>
|
<Text size="small" color="muted">{$t('appears_in')}</Text>
|
||||||
{#each albums as album (album.id)}
|
</div>
|
||||||
<a href={Route.viewAlbum(album)}>
|
{#each albums as album (album.id)}
|
||||||
<div class="flex gap-4 pt-2 hover:cursor-pointer items-center">
|
<a href={Route.viewAlbum(album)}>
|
||||||
<div>
|
<div class="flex gap-4 pt-2 hover:cursor-pointer items-center">
|
||||||
<img
|
<div>
|
||||||
alt={album.albumName}
|
<img
|
||||||
class="h-12.5 w-12.5 rounded object-cover"
|
alt={album.albumName}
|
||||||
src={album.albumThumbnailAssetId &&
|
class="h-12.5 w-12.5 rounded object-cover"
|
||||||
getAssetMediaUrl({ id: album.albumThumbnailAssetId, size: AssetMediaSize.Preview })}
|
src={album.albumThumbnailAssetId &&
|
||||||
draggable="false"
|
getAssetMediaUrl({ id: album.albumThumbnailAssetId, size: AssetMediaSize.Preview })}
|
||||||
/>
|
draggable="false"
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-auto mt-auto">
|
<div class="mb-auto mt-auto">
|
||||||
<p class="dark:text-immich-dark-primary">{album.albumName}</p>
|
<p class="dark:text-immich-dark-primary">{album.albumName}</p>
|
||||||
<div class="flex flex-col gap-0 text-sm">
|
<div class="flex flex-col gap-0 text-sm">
|
||||||
<div>
|
<div>
|
||||||
<AlbumListItemDetails {album} />
|
<AlbumListItemDetails {album} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</a>
|
{/each}
|
||||||
{/each}
|
</section>
|
||||||
</section>
|
{/if}
|
||||||
{/if}
|
{/await}
|
||||||
|
|
||||||
{#if $preferences?.tags?.enabled}
|
{#if $preferences?.tags?.enabled}
|
||||||
<section class="relative px-2 pb-12 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
|
<section class="relative px-2 pb-12 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
|
||||||
|
|||||||
Reference in New Issue
Block a user