1
0
mirror of https://github.com/immich-app/immich.git synced 2025-01-25 17:15:28 +02:00

fix(web): asset disappears from album after metadata edit (#7520)

This commit is contained in:
Michel Heusschen 2024-02-29 18:44:30 +01:00 committed by GitHub
parent 100363c7be
commit 369acc7bea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 30 additions and 37 deletions

View File

@ -20,7 +20,6 @@
import ThemeButton from '../shared-components/theme-button.svelte'; import ThemeButton from '../shared-components/theme-button.svelte';
import { shouldIgnoreShortcut } from '$lib/utils/shortcut'; import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
import { mdiFileImagePlusOutline, mdiFolderDownloadOutline } from '@mdi/js'; import { mdiFileImagePlusOutline, mdiFolderDownloadOutline } from '@mdi/js';
import UpdatePanel from '../shared-components/update-panel.svelte';
import { handlePromiseError } from '$lib/utils'; import { handlePromiseError } from '$lib/utils';
export let sharedLink: SharedLinkResponseDto; export let sharedLink: SharedLinkResponseDto;
@ -168,5 +167,4 @@
{/if} {/if}
</section> </section>
</AssetGrid> </AssetGrid>
<UpdatePanel {assetStore} />
</main> </main>

View File

@ -1,18 +0,0 @@
<script lang="ts">
import { websocketEvents } from '$lib/stores/websocket';
import type { AssetStore } from '$lib/stores/assets.store';
import { onMount } from 'svelte';
export let assetStore: AssetStore | null;
onMount(() => {
return websocketEvents.on('on_asset_update', (asset) => {
if (asset.originalFileName && assetStore) {
assetStore.updateAsset(asset, true);
assetStore.removeAsset(asset.id); // Update timeline
assetStore.addAsset(asset);
}
});
});
</script>

View File

@ -49,6 +49,11 @@ interface AddAsset {
value: AssetResponseDto; value: AssetResponseDto;
} }
interface UpdateAsset {
type: 'update';
value: AssetResponseDto;
}
interface DeleteAsset { interface DeleteAsset {
type: 'delete'; type: 'delete';
value: string; value: string;
@ -61,7 +66,7 @@ interface TrashAsset {
export const photoViewer = writable<HTMLImageElement | null>(null); export const photoViewer = writable<HTMLImageElement | null>(null);
type PendingChange = AddAsset | DeleteAsset | TrashAsset; type PendingChange = AddAsset | UpdateAsset | DeleteAsset | TrashAsset;
export class AssetStore { export class AssetStore {
private store$ = writable(this); private store$ = writable(this);
@ -102,6 +107,9 @@ export class AssetStore {
websocketEvents.on('on_asset_trash', (ids) => { websocketEvents.on('on_asset_trash', (ids) => {
this.addPendingChanges(...ids.map((id): TrashAsset => ({ type: 'trash', value: id }))); this.addPendingChanges(...ids.map((id): TrashAsset => ({ type: 'trash', value: id })));
}), }),
websocketEvents.on('on_asset_update', (asset) => {
this.addPendingChanges({ type: 'update', value: asset });
}),
websocketEvents.on('on_asset_delete', (id: string) => { websocketEvents.on('on_asset_delete', (id: string) => {
this.addPendingChanges({ type: 'delete', value: id }); this.addPendingChanges({ type: 'delete', value: id });
}), }),
@ -122,6 +130,11 @@ export class AssetStore {
break; break;
} }
case 'update': {
this.updateAsset(value);
break;
}
case 'trash': { case 'trash': {
if (!this.options.isTrashed) { if (!this.options.isTrashed) {
this.removeAsset(value); this.removeAsset(value);
@ -276,6 +289,10 @@ export class AssetStore {
return; return;
} }
this.addAssetToBucket(asset);
}
private addAssetToBucket(asset: AssetResponseDto) {
const timeBucket = DateTime.fromISO(asset.fileCreatedAt).toUTC().startOf('month').toString(); const timeBucket = DateTime.fromISO(asset.fileCreatedAt).toUTC().startOf('month').toString();
let bucket = this.getBucketByDate(timeBucket); let bucket = this.getBucketByDate(timeBucket);
@ -307,7 +324,7 @@ export class AssetStore {
// If we added an asset to the store, we need to recalculate // If we added an asset to the store, we need to recalculate
// asset store containers // asset store containers
this.assets.push(asset); this.assets.push(asset);
this.updateAsset(asset, true); this.emit(true);
} }
getBucketByDate(bucketDate: string): AssetBucket | null { getBucketByDate(bucketDate: string): AssetBucket | null {
@ -338,14 +355,20 @@ export class AssetStore {
return null; return null;
} }
updateAsset(_asset: AssetResponseDto, recalculate = false) { updateAsset(_asset: AssetResponseDto) {
const asset = this.assets.find((asset) => asset.id === _asset.id); const asset = this.assets.find((asset) => asset.id === _asset.id);
if (!asset) { if (!asset) {
return; return;
} }
Object.assign(asset, _asset); const recalculate = asset.fileCreatedAt !== _asset.fileCreatedAt;
if (recalculate) {
this.removeAsset(asset.id);
this.addAssetToBucket(_asset);
return;
}
Object.assign(asset, _asset);
this.emit(recalculate); this.emit(recalculate);
} }
@ -357,6 +380,9 @@ export class AssetStore {
} }
removeAsset(id: string) { removeAsset(id: string) {
this.assets = this.assets.filter((asset) => asset.id !== id);
delete this.assetToBucket[id];
for (let index = 0; index < this.buckets.length; index++) { for (let index = 0; index < this.buckets.length; index++) {
const bucket = this.buckets[index]; const bucket = this.buckets[index];
for (let index_ = 0; index_ < bucket.assets.length; index_++) { for (let index_ = 0; index_ < bucket.assets.length; index_++) {

View File

@ -30,7 +30,6 @@
NotificationType, NotificationType,
notificationController, notificationController,
} from '$lib/components/shared-components/notification/notification'; } from '$lib/components/shared-components/notification/notification';
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte'; import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
import { AppRoute, dateFormats } from '$lib/constants'; import { AppRoute, dateFormats } from '$lib/constants';
import { numberOfComments, setNumberOfComments, updateNumberOfComments } from '$lib/stores/activity.store'; import { numberOfComments, setNumberOfComments, updateNumberOfComments } from '$lib/stores/activity.store';
@ -718,8 +717,6 @@
/> />
{/if} {/if}
<UpdatePanel {assetStore} />
<style> <style>
::placeholder { ::placeholder {
color: rgb(60, 60, 60); color: rgb(60, 60, 60);

View File

@ -16,7 +16,6 @@
import { AssetStore } from '$lib/stores/assets.store'; import { AssetStore } from '$lib/stores/assets.store';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { mdiPlus, mdiDotsVertical } from '@mdi/js'; import { mdiPlus, mdiDotsVertical } from '@mdi/js';
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
export let data: PageData; export let data: PageData;
@ -53,4 +52,3 @@
/> />
</AssetGrid> </AssetGrid>
</UserPageLayout> </UserPageLayout>
<UpdatePanel {assetStore} />

View File

@ -18,7 +18,6 @@
import { AssetStore } from '$lib/stores/assets.store'; import { AssetStore } from '$lib/stores/assets.store';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { mdiDotsVertical, mdiPlus } from '@mdi/js'; import { mdiDotsVertical, mdiPlus } from '@mdi/js';
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
export let data: PageData; export let data: PageData;
@ -58,4 +57,3 @@
/> />
</AssetGrid> </AssetGrid>
</UserPageLayout> </UserPageLayout>
<UpdatePanel {assetStore} />

View File

@ -13,7 +13,6 @@
import { onDestroy } from 'svelte'; import { onDestroy } from 'svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { mdiPlus, mdiArrowLeft } from '@mdi/js'; import { mdiPlus, mdiArrowLeft } from '@mdi/js';
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
export let data: PageData; export let data: PageData;
@ -46,5 +45,4 @@
</ControlAppBar> </ControlAppBar>
{/if} {/if}
<AssetGrid {assetStore} {assetInteractionStore} /> <AssetGrid {assetStore} {assetInteractionStore} />
<UpdatePanel {assetStore} />
</main> </main>

View File

@ -22,7 +22,6 @@
import { openFileUploadDialog } from '$lib/utils/file-uploader'; import { openFileUploadDialog } from '$lib/utils/file-uploader';
import { assetViewingStore } from '$lib/stores/asset-viewing.store'; import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { mdiDotsVertical, mdiPlus } from '@mdi/js'; import { mdiDotsVertical, mdiPlus } from '@mdi/js';
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
import { user } from '$lib/stores/user.store'; import { user } from '$lib/stores/user.store';
let { isViewing: showAssetViewer } = assetViewingStore; let { isViewing: showAssetViewer } = assetViewingStore;
@ -96,4 +95,3 @@
/> />
</AssetGrid> </AssetGrid>
</UserPageLayout> </UserPageLayout>
<UpdatePanel {assetStore} />

View File

@ -15,7 +15,6 @@
NotificationType, NotificationType,
notificationController, notificationController,
} from '$lib/components/shared-components/notification/notification'; } from '$lib/components/shared-components/notification/notification';
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
import { AppRoute } from '$lib/constants'; import { AppRoute } from '$lib/constants';
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store'; import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
import { AssetStore } from '$lib/stores/assets.store'; import { AssetStore } from '$lib/stores/assets.store';
@ -115,4 +114,3 @@
</svelte:fragment> </svelte:fragment>
</ConfirmDialogue> </ConfirmDialogue>
{/if} {/if}
<UpdatePanel {assetStore} />