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:
parent
100363c7be
commit
369acc7bea
@ -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>
|
||||||
|
@ -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>
|
|
@ -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_++) {
|
||||||
|
@ -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);
|
||||||
|
@ -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} />
|
|
||||||
|
@ -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} />
|
|
||||||
|
@ -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>
|
||||||
|
@ -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} />
|
|
||||||
|
@ -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} />
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user