From 0322a8b1d94b815cacee6a3eda6cd27f879d8c09 Mon Sep 17 00:00:00 2001 From: Robin Brisa Date: Thu, 12 Jun 2025 13:13:35 +0200 Subject: [PATCH] fix(web): properly update activityManager when browsing assets (#18909) --- .../asset-viewer/asset-viewer.svelte | 20 +----- .../lib/managers/activity-manager.svelte.ts | 63 ++++++++++++++++++- .../[[assetId=id]]/+page.svelte | 25 +++----- 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index a448f96c32..b6daa4d384 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -138,16 +138,6 @@ } }; - const updateComments = async () => { - if (album) { - try { - await activityManager.refreshActivities(album.id, asset.id); - } catch (error) { - handleError(error, $t('errors.unable_to_get_comments_number')); - } - } - }; - const onAssetUpdate = ({ asset: assetUpdate }: { event: 'upload' | 'update'; asset: AssetResponseDto }) => { if (assetUpdate.id === asset.id) { asset = assetUpdate; @@ -180,10 +170,6 @@ if (!sharedLink) { await handleGetAllAlbums(); } - - if (album) { - activityManager.init(album.id, asset.id); - } }); onDestroy(() => { @@ -370,8 +356,8 @@ } }); $effect(() => { - if (isShared && asset.id) { - handlePromiseError(updateComments()); + if (album && isShared && asset.id) { + handlePromiseError(activityManager.init(album.id, asset.id)); } }); $effect(() => { @@ -510,7 +496,7 @@ onVideoStarted={handleVideoStarted} /> {/if} - {#if $slideshowState === SlideshowState.None && isShared && ((album && album.isActivityEnabled) || activityManager.commentCount > 0)} + {#if $slideshowState === SlideshowState.None && isShared && ((album && album.isActivityEnabled) || activityManager.commentCount > 0) && !activityManager.isLoading}
(); #assetId = $state(); @@ -20,6 +30,14 @@ class ActivityManager { #likeCount = $state(0); #isLiked = $state(null); + #cache = new Map(); + + isLoading = $state(false); + + get assetId() { + return this.#assetId; + } + get activities() { return this.#activities; } @@ -36,9 +54,27 @@ class ActivityManager { return this.#isLiked; } - init(albumId: string, assetId?: string) { + #getCacheKey(albumId: string, assetId?: string) { + return `${albumId}:${assetId ?? ''}`; + } + + async init(albumId: string, assetId?: string) { + if (assetId && assetId === this.#assetId) { + return; + } + this.#albumId = albumId; this.#assetId = assetId; + try { + await activityManager.refreshActivities(albumId, assetId); + } catch (error) { + handleError(error, get(t)('errors.unable_to_get_comments_number')); + } + } + + #invalidateCache(albumId: string, assetId?: string) { + this.#cache.delete(this.#getCacheKey(albumId)); + this.#cache.delete(this.#getCacheKey(albumId, assetId)); } async addActivity(dto: ActivityCreateDto) { @@ -57,6 +93,7 @@ class ActivityManager { this.#likeCount++; } + this.#invalidateCache(this.#albumId, this.#assetId); handlePromiseError(this.refreshActivities(this.#albumId, this.#assetId)); return activity; } @@ -79,6 +116,7 @@ class ActivityManager { : this.#activities.filter(({ id }) => id !== activity.id); await deleteActivity({ id: activity.id }); + this.#invalidateCache(this.#albumId, this.#assetId); handlePromiseError(this.refreshActivities(this.#albumId, this.#assetId)); } @@ -100,6 +138,20 @@ class ActivityManager { } async refreshActivities(albumId: string, assetId?: string) { + this.isLoading = true; + + const cacheKey = this.#getCacheKey(albumId, assetId); + + if (this.#cache.has(cacheKey)) { + const cached = this.#cache.get(cacheKey)!; + this.#activities = cached.activities; + this.#commentCount = cached.commentCount; + this.#likeCount = cached.likeCount; + this.#isLiked = cached.isLiked ?? null; + this.isLoading = false; + return; + } + this.#activities = await getActivities({ albumId, assetId }); const [liked] = await getActivities({ @@ -114,6 +166,15 @@ class ActivityManager { const { comments, likes } = await getActivityStatistics({ albumId, assetId }); this.#commentCount = comments; this.#likeCount = likes; + + this.#cache.set(cacheKey, { + activities: this.#activities, + commentCount: this.#commentCount, + likeCount: this.#likeCount, + isLiked: this.#isLiked, + }); + + this.isLoading = false; } reset() { diff --git a/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte index 669edf8a2a..faaa7f6ff6 100644 --- a/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte +++ b/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte @@ -159,14 +159,6 @@ } }; - const updateComments = async () => { - try { - await activityManager.refreshActivities(album.id); - } catch (error) { - handleError(error, $t('errors.cant_get_number_of_comments')); - } - }; - const handleOpenAndCloseActivityTab = () => { isShowActivity = !isShowActivity; }; @@ -388,9 +380,14 @@ } }); + const isShared = $derived(viewMode === AlbumPageViewMode.SELECT_ASSETS ? false : album.albumUsers.length > 0); + $effect(() => { - activityManager.reset(); - activityManager.init(album.id); + if ($showAssetViewer || !isShared) { + return; + } + + handlePromiseError(activityManager.init(album.id)); }); onDestroy(() => { @@ -409,12 +406,6 @@ ); let albumHasViewers = $derived(album.albumUsers.some(({ role }) => role === AlbumUserRole.Viewer)); - $effect(() => { - if (album.albumUsers.length > 0) { - handlePromiseError(updateComments()); - } - }); - const isShared = $derived(viewMode === AlbumPageViewMode.SELECT_ASSETS ? false : album.albumUsers.length > 0); const isSelectionMode = $derived( viewMode === AlbumPageViewMode.SELECT_ASSETS ? true : viewMode === AlbumPageViewMode.SELECT_THUMBNAIL, ); @@ -570,7 +561,7 @@ {/if} - {#if showActivityStatus} + {#if showActivityStatus && !activityManager.isLoading}