fix(ui): propagate photo tag edits to grid and viewer

Add a shared photo-updates signal the panel publishes on rename or tag
add/remove; the album grid and viewer subscribe and patch the changed
photo into their lists, so the 360 badge and panorama mode update without
a reload.
This commit is contained in:
iu
2026-10-12 12:14:48 +03:00
parent eef7c6c5d0
commit e4975aafb5
9 changed files with 190 additions and 1 deletions
@@ -1,7 +1,7 @@
<script lang="ts">
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { tick } from 'svelte';
import { tick, untrack } from 'svelte';
import { api, photosApi } from '$lib/api';
import PhotoGrid from '$lib/components/PhotoGrid.svelte';
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
@@ -12,6 +12,7 @@
import { albums } from '$lib/stores/albums.svelte';
import { density } from '$lib/stores/density.svelte';
import { selection } from '$lib/stores/selection.svelte';
import { photoUpdates } from '$lib/stores/photo-updates.svelte';
import { viewerReturn } from '$lib/stores/viewer-return';
import { transfer } from '$lib/stores/transfer.svelte';
import { contextMenu, type ContextMenuItem } from '$lib/stores/context-menu.svelte';
@@ -80,6 +81,18 @@
});
});
$effect(() => {
// Patch a photo edited in the panel (e.g. tags) into the grid list so
// derived UI like the 360 badge updates without a reload. Read the list
// untracked so writing it cannot re-trigger this effect.
const updated = photoUpdates.latest;
if (!updated) return;
const list = untrack(() => photos);
if (list.some((p) => p.id === updated.id)) {
photos = list.map((p) => (p.id === updated.id ? updated : p));
}
});
let client: SSEClient | null = null;
$effect(() => {
@@ -1,10 +1,12 @@
<script lang="ts">
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { untrack } from 'svelte';
import { api } from '$lib/api';
import Viewer from '$lib/components/Viewer.svelte';
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
import { viewerActions } from '$lib/stores/viewer-actions.svelte';
import { photoUpdates } from '$lib/stores/photo-updates.svelte';
import { viewerReturn } from '$lib/stores/viewer-return';
import type { Album, Photo } from '$lib/types';
@@ -40,6 +42,18 @@
.finally(() => (loading = false));
});
$effect(() => {
// Patch a photo edited in the panel (e.g. tags) so the viewer reflects
// changes such as panorama mode without reopening. Read the list
// untracked so writing it cannot re-trigger this effect.
const updated = photoUpdates.latest;
if (!updated) return;
const list = untrack(() => photos);
if (list.some((p) => p.id === updated.id)) {
photos = list.map((p) => (p.id === updated.id ? updated : p));
}
});
function close() {
goto(`/albums/${albumId}`);
}