fix(web): properly update activityManager when browsing assets (#18909)

This commit is contained in:
Robin Brisa 2025-06-12 13:13:35 +02:00 committed by GitHub
parent 94e9adf625
commit 0322a8b1d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 35 deletions

View File

@ -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}
<div class="absolute bottom-0 end-0 mb-20 me-8">
<ActivityStatus
disabled={!album?.isActivityEnabled}

View File

@ -1,5 +1,6 @@
import { user } from '$lib/stores/user.store';
import { handlePromiseError } from '$lib/utils';
import { handleError } from '$lib/utils/handle-error';
import {
createActivity,
deleteActivity,
@ -10,8 +11,17 @@ import {
type ActivityCreateDto,
type ActivityResponseDto,
} from '@immich/sdk';
import { t } from 'svelte-i18n';
import { get } from 'svelte/store';
type CacheKey = string;
type ActivityCache = {
activities: ActivityResponseDto[];
commentCount: number;
likeCount: number;
isLiked: ActivityResponseDto | null;
};
class ActivityManager {
#albumId = $state<string | undefined>();
#assetId = $state<string | undefined>();
@ -20,6 +30,14 @@ class ActivityManager {
#likeCount = $state(0);
#isLiked = $state<ActivityResponseDto | null>(null);
#cache = new Map<CacheKey, ActivityCache>();
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() {

View File

@ -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}
</AssetGrid>
{#if showActivityStatus}
{#if showActivityStatus && !activityManager.isLoading}
<div class="absolute z-2 bottom-0 end-0 mb-6 me-6 justify-self-end">
<ActivityStatus
disabled={!album.isActivityEnabled}