keep cached avatar&c when refresh fails to get new values

when the remote explicitly tells us a user image is gone, we remove
our cached value, but if we fail to get the image, we keep whatever
value we already have

this should minimise the problem of avatars randomly disappearing
This commit is contained in:
dakkar 2024-01-28 14:02:12 +00:00
parent aabf168d05
commit 6a5ff04112
1 changed files with 26 additions and 11 deletions

View File

@ -225,23 +225,38 @@ export class ApPersonService implements OnModuleInit {
return null; return null;
} }
private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any, bgimg: any): Promise<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'backgroundId' | 'avatarUrl' | 'bannerUrl' | 'backgroundUrl' | 'avatarBlurhash' | 'bannerBlurhash' | 'backgroundBlurhash'>> { private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any, bgimg: any): Promise<Partial<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'backgroundId' | 'avatarUrl' | 'bannerUrl' | 'backgroundUrl' | 'avatarBlurhash' | 'bannerBlurhash' | 'backgroundBlurhash'>>> {
const [avatar, banner, background] = await Promise.all([icon, image, bgimg].map(img => { const [avatar, banner, background] = await Promise.all([icon, image, bgimg].map(img => {
if (img == null) return null; // if we have an explicitly missing image, return a special value
if ((img == null) || (typeof img === 'object' && img.url == null)) {
return { id: null, url: null, blurhash: null };
}
if (user == null) throw new Error('failed to create user: user is null'); if (user == null) throw new Error('failed to create user: user is null');
return this.apImageService.resolveImage(user, img).catch(() => null); return this.apImageService.resolveImage(user, img).catch(() => null);
})); }));
/* we don't want to return nulls on errors! if the database fields
are already null, nothing changes; if the database has old
values, we should keep those. The exception is if the remote
has actually removed the images: in that case, the block above
returns the special {id:null}&c value, and we return those
*/
return { return {
avatarId: avatar?.id ?? null, ...( avatar ? {
bannerId: banner?.id ?? null, avatarId: avatar.id,
backgroundId: background?.id ?? null, avatarUrl: avatar.url ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null,
avatarUrl: avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, avatarBlurhash: avatar.blurhash,
bannerUrl: banner ? this.driveFileEntityService.getPublicUrl(banner) : null, } : {}),
backgroundUrl: background ? this.driveFileEntityService.getPublicUrl(background) : null, ...( banner ? {
avatarBlurhash: avatar?.blurhash ?? null, bannerId: banner.id,
bannerBlurhash: banner?.blurhash ?? null, bannerUrl: banner.url ? this.driveFileEntityService.getPublicUrl(banner) : null,
backgroundBlurhash: background?.blurhash ?? null bannerBlurhash: banner.blurhash,
} : {}),
...(background ? {
backgroundId: background.id,
backgroundUrl: background.url ? this.driveFileEntityService.getPublicUrl(background) : null,
backgroundBlurhash: background.blurhash,
} : {} ),
}; };
} }