fix(media): keep self-host media loading after restarts (#3283)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-08 17:28:18 +02:00
1 parent bd56174870
commit 46a356cc40
59 files changed
+1238 -499

No files matched your search

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {runtimeInstanceKey} from '@app/features/app/state/InstanceSnapshotStore';
import type {Account} from '@app/features/platform/state/AuthSession';
import * as AvatarUtils from '@app/features/user/utils/AvatarUtils';
import {getDefaultAvatarAssetURL} from '@app/features/user/utils/DefaultAvatars';
@@ -16,12 +17,25 @@ function defaultAccountAvatarURL(account: Account, size?: MediaProxyImageSize):
function resolveAccountAvatarURL(account: Account, size?: MediaProxyImageSize): string {
const avatar = account.userData?.avatar ?? null;
const mediaEndpoint = account.instance?.mediaEndpoint ?? null;
if (avatar == null || avatar.length === 0 || mediaEndpoint == null || mediaEndpoint.length === 0) {
const instance = account.instance ?? null;
const mediaEndpoint = instance?.mediaEndpoint ?? null;
const instanceKey = instance == null ? null : runtimeInstanceKey(instance);
if (
avatar == null ||
avatar.length === 0 ||
mediaEndpoint == null ||
mediaEndpoint.length === 0 ||
instanceKey == null
) {
return defaultAccountAvatarURL(account, size);
}
try {
return AvatarUtils.getUserAvatarURLWithProxy({id: account.userId, avatar}, mediaEndpoint, false, size);
return AvatarUtils.getUserAvatarURLForInstance(
{id: account.userId, avatar},
{mediaEndpoint, instanceKey},
false,
size,
);
} catch {
return defaultAccountAvatarURL(account, size);
}
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import accountStorage from '@app/features/auth/state/AccountStorage';
import type {UserData} from '@app/features/auth/state/AccountStorageContract';
import Accounts from '@app/features/auth/state/Accounts';
import {Logger} from '@app/features/platform/utils/AppLogger';
const logger = new Logger('AccountUserDataSync');
export interface AccountUserIdentity {
readonly username: string;
readonly discriminator: string;
readonly global_name?: string | null;
readonly email?: string | null;
readonly avatar?: string | null;
}
export function syncAccountUserData(accountKey: string, user: AccountUserIdentity): void {
const previous = Accounts.getAccount(accountKey)?.userData;
const userData: UserData = {
username: user.username,
discriminator: user.discriminator,
globalName: user.global_name === undefined ? previous?.globalName : user.global_name,
email: user.email === undefined ? previous?.email : (user.email ?? undefined),
avatar: user.avatar ?? undefined,
};
void accountStorage.updateAccountUserData(accountKey, userData).catch((error) => {
logger.warn(`Failed to persist account user data for ${accountKey}`, error);
});
Accounts.updateAccountUserData(accountKey, userData);
}