Skip to content

Commit 761ac07

Browse files
authored
fix(web): asset refresh (#21788)
1 parent 7e377d3 commit 761ac07

File tree

4 files changed

+55
-81
lines changed

4 files changed

+55
-81
lines changed

web/src/lib/components/asset-viewer/detail-panel-tags.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
2222
const handleAddTag = async () => {
2323
const success = await modalManager.show(AssetTagModal, { assetIds: [asset.id] });
24-
2524
if (success) {
2625
asset = await getAssetInfo({ id: asset.id });
2726
}

web/src/lib/components/asset-viewer/detail-panel.svelte

Lines changed: 23 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,14 @@
1616
import { locale } from '$lib/stores/preferences.store';
1717
import { featureFlags } from '$lib/stores/server-config.store';
1818
import { preferences, user } from '$lib/stores/user.store';
19-
import { getAssetThumbnailUrl, getPeopleThumbnailUrl, handlePromiseError } from '$lib/utils';
20-
import { delay, isFlipped } from '$lib/utils/asset-utils';
19+
import { getAssetThumbnailUrl, getPeopleThumbnailUrl } from '$lib/utils';
20+
import { delay, getDimensions } from '$lib/utils/asset-utils';
2121
import { getByteUnitString } from '$lib/utils/byte-units';
2222
import { handleError } from '$lib/utils/handle-error';
2323
import { getMetadataSearchQuery } from '$lib/utils/metadata-search';
2424
import { fromISODateTime, fromISODateTimeUTC } from '$lib/utils/timeline-util';
2525
import { getParentPath } from '$lib/utils/tree-utils';
26-
import {
27-
AssetMediaSize,
28-
getAssetInfo,
29-
updateAsset,
30-
type AlbumResponseDto,
31-
type AssetResponseDto,
32-
type ExifResponseDto,
33-
} from '@immich/sdk';
26+
import { AssetMediaSize, getAssetInfo, updateAsset, type AlbumResponseDto, type AssetResponseDto } from '@immich/sdk';
3427
import { IconButton } from '@immich/ui';
3528
import {
3629
mdiCalendar,
@@ -61,44 +54,18 @@
6154
6255
let { asset, albums = [], currentAlbum = null, onClose }: Props = $props();
6356
64-
const getDimensions = (exifInfo: ExifResponseDto) => {
65-
const { exifImageWidth: width, exifImageHeight: height } = exifInfo;
66-
if (isFlipped(exifInfo.orientation)) {
67-
return { width: height, height: width };
68-
}
69-
70-
return { width, height };
71-
};
72-
7357
let showAssetPath = $state(false);
7458
let showEditFaces = $state(false);
75-
let previousId: string | undefined = $state();
76-
77-
$effect(() => {
78-
if (!previousId) {
79-
previousId = asset.id;
80-
}
81-
if (asset.id !== previousId) {
82-
showEditFaces = false;
83-
previousId = asset.id;
84-
}
85-
});
86-
8759
let isOwner = $derived($user?.id === asset.ownerId);
88-
89-
const handleNewAsset = async (newAsset: AssetResponseDto) => {
90-
// TODO: check if reloading asset data is necessary
91-
if (newAsset.id && !authManager.isSharedLink) {
92-
const data = await getAssetInfo({ id: asset.id });
93-
people = data?.people || [];
94-
unassignedFaces = data?.unassignedFaces || [];
95-
}
96-
};
97-
98-
$effect(() => {
99-
handlePromiseError(handleNewAsset(asset));
100-
});
101-
60+
let people = $derived(asset.people || []);
61+
let unassignedFaces = $derived(asset.unassignedFaces || []);
62+
let showingHiddenPeople = $state(false);
63+
let timeZone = $derived(asset.exifInfo?.timeZone);
64+
let dateTime = $derived(
65+
timeZone && asset.exifInfo?.dateTimeOriginal
66+
? fromISODateTime(asset.exifInfo.dateTimeOriginal, timeZone)
67+
: fromISODateTimeUTC(asset.localDateTime),
68+
);
10269
let latlng = $derived(
10370
(() => {
10471
const lat = asset.exifInfo?.latitude;
@@ -109,16 +76,17 @@
10976
}
11077
})(),
11178
);
79+
let previousId: string | undefined = $state();
11280
113-
let people = $state(asset.people || []);
114-
let unassignedFaces = $state(asset.unassignedFaces || []);
115-
let showingHiddenPeople = $state(false);
116-
let timeZone = $derived(asset.exifInfo?.timeZone);
117-
let dateTime = $derived(
118-
timeZone && asset.exifInfo?.dateTimeOriginal
119-
? fromISODateTime(asset.exifInfo.dateTimeOriginal, timeZone)
120-
: fromISODateTimeUTC(asset.localDateTime),
121-
);
81+
$effect(() => {
82+
if (!previousId) {
83+
previousId = asset.id;
84+
}
85+
if (asset.id !== previousId) {
86+
showEditFaces = false;
87+
previousId = asset.id;
88+
}
89+
});
12290
12391
const getMegapixel = (width: number, height: number): number | undefined => {
12492
const megapixel = Math.round((height * width) / 1_000_000);
@@ -131,10 +99,7 @@
13199
};
132100
133101
const handleRefreshPeople = async () => {
134-
await getAssetInfo({ id: asset.id }).then((data) => {
135-
people = data?.people || [];
136-
unassignedFaces = data?.unassignedFaces || [];
137-
});
102+
asset = await getAssetInfo({ id: asset.id });
138103
showEditFaces = false;
139104
};
140105

web/src/lib/components/utilities-page/duplicates/duplicates-compare-control.svelte

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
import { shortcuts } from '$lib/actions/shortcut';
33
import Portal from '$lib/components/shared-components/portal/portal.svelte';
44
import DuplicateAsset from '$lib/components/utilities-page/duplicates/duplicate-asset.svelte';
5+
import { authManager } from '$lib/managers/auth-manager.svelte';
56
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
67
import { handlePromiseError } from '$lib/utils';
78
import { suggestDuplicate } from '$lib/utils/duplicate-utils';
89
import { navigate } from '$lib/utils/navigation';
9-
import { type AssetResponseDto } from '@immich/sdk';
10+
import { getAssetInfo, type AssetResponseDto } from '@immich/sdk';
1011
import { Button } from '@immich/ui';
1112
import { mdiCheck, mdiImageMultipleOutline, mdiTrashCanOutline } from '@mdi/js';
1213
import { onDestroy, onMount } from 'svelte';
@@ -42,32 +43,32 @@
4243
assetViewingStore.showAssetViewer(false);
4344
});
4445
45-
const onNext = () => {
46+
const onNext = async () => {
4647
const index = getAssetIndex($viewingAsset.id) + 1;
4748
if (index >= assets.length) {
48-
return Promise.resolve(false);
49+
return false;
4950
}
50-
setAsset(assets[index]);
51-
return Promise.resolve(true);
51+
await onViewAsset(assets[index]);
52+
return true;
5253
};
5354
54-
const onPrevious = () => {
55+
const onPrevious = async () => {
5556
const index = getAssetIndex($viewingAsset.id) - 1;
5657
if (index < 0) {
57-
return Promise.resolve(false);
58+
return false;
5859
}
59-
setAsset(assets[index]);
60-
return Promise.resolve(true);
60+
await onViewAsset(assets[index]);
61+
return true;
6162
};
6263
63-
const onRandom = () => {
64+
const onRandom = async () => {
6465
if (assets.length <= 0) {
65-
return Promise.resolve(undefined);
66+
return;
6667
}
6768
const index = Math.floor(Math.random() * assets.length);
6869
const asset = assets[index];
69-
setAsset(asset);
70-
return Promise.resolve(asset);
70+
await onViewAsset(asset);
71+
return { id: asset.id };
7172
};
7273
7374
const onSelectAsset = (asset: AssetResponseDto) => {
@@ -86,6 +87,12 @@
8687
selectedAssetIds = new SvelteSet(assets.map((asset) => asset.id));
8788
};
8889
90+
const onViewAsset = async ({ id }: AssetResponseDto) => {
91+
const asset = await getAssetInfo({ ...authManager.params, id });
92+
setAsset(asset);
93+
await navigate({ targetRoute: 'current', assetId: asset.id });
94+
};
95+
8996
const handleResolve = () => {
9097
const trashIds = assets.map((asset) => asset.id).filter((id) => !selectedAssetIds.has(id));
9198
const duplicateAssetIds = assets.map((asset) => asset.id);
@@ -102,9 +109,7 @@
102109
{ shortcut: { key: 'a' }, onShortcut: onSelectAll },
103110
{
104111
shortcut: { key: 's' },
105-
onShortcut: () => {
106-
setAsset(assets[0]);
107-
},
112+
onShortcut: () => onViewAsset(assets[0]),
108113
},
109114
{ shortcut: { key: 'd' }, onShortcut: onSelectNone },
110115
{ shortcut: { key: 'c', shift: true }, onShortcut: handleResolve },
@@ -166,12 +171,7 @@
166171

167172
<div class="flex flex-wrap gap-1 mb-4 place-items-center place-content-center px-4 pt-4">
168173
{#each assets as asset (asset.id)}
169-
<DuplicateAsset
170-
{asset}
171-
{onSelectAsset}
172-
isSelected={selectedAssetIds.has(asset.id)}
173-
onViewAsset={(asset) => setAsset(asset)}
174-
/>
174+
<DuplicateAsset {asset} {onSelectAsset} isSelected={selectedAssetIds.has(asset.id)} {onViewAsset} />
175175
{/each}
176176
</div>
177177
</div>

web/src/lib/utils/asset-utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
type AssetResponseDto,
3535
type AssetTypeEnum,
3636
type DownloadInfoDto,
37+
type ExifResponseDto,
3738
type StackResponseDto,
3839
type UserPreferencesResponseDto,
3940
type UserResponseDto,
@@ -328,6 +329,15 @@ export function isFlipped(orientation?: string | null) {
328329
return value && (isRotated270CW(value) || isRotated90CW(value));
329330
}
330331

332+
export const getDimensions = (exifInfo: ExifResponseDto) => {
333+
const { exifImageWidth: width, exifImageHeight: height } = exifInfo;
334+
if (isFlipped(exifInfo.orientation)) {
335+
return { width: height, height: width };
336+
}
337+
338+
return { width, height };
339+
};
340+
331341
export function getFileSize(asset: AssetResponseDto, maxPrecision = 4): string {
332342
const size = asset.exifInfo?.fileSizeInByte || 0;
333343
return size > 0 ? getByteUnitString(size, undefined, maxPrecision) : 'Invalid Data';

0 commit comments

Comments
 (0)