feat: Add profile images
This commit is contained in:
@@ -30,6 +30,37 @@ function normalizeRoleIds(roleIds: readonly string[] | undefined): string[] | un
|
||||
return normalized.length > 0 ? normalized : undefined;
|
||||
}
|
||||
|
||||
function normalizeAvatarUpdatedAt(value: unknown): number | undefined {
|
||||
return typeof value === 'number' && Number.isFinite(value) && value > 0
|
||||
? value
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function mergeAvatarFields(
|
||||
existingMember: Pick<RoomMember, 'avatarUrl' | 'avatarHash' | 'avatarMime' | 'avatarUpdatedAt'>,
|
||||
incomingMember: Pick<RoomMember, 'avatarUrl' | 'avatarHash' | 'avatarMime' | 'avatarUpdatedAt'>,
|
||||
preferIncomingFallback: boolean
|
||||
): Pick<RoomMember, 'avatarUrl' | 'avatarHash' | 'avatarMime' | 'avatarUpdatedAt'> {
|
||||
const existingUpdatedAt = existingMember.avatarUpdatedAt ?? 0;
|
||||
const incomingUpdatedAt = incomingMember.avatarUpdatedAt ?? 0;
|
||||
const preferIncoming = incomingUpdatedAt === existingUpdatedAt
|
||||
? preferIncomingFallback
|
||||
: incomingUpdatedAt > existingUpdatedAt;
|
||||
|
||||
return {
|
||||
avatarUrl: preferIncoming
|
||||
? (incomingMember.avatarUrl || existingMember.avatarUrl)
|
||||
: (existingMember.avatarUrl || incomingMember.avatarUrl),
|
||||
avatarHash: preferIncoming
|
||||
? (incomingMember.avatarHash || existingMember.avatarHash)
|
||||
: (existingMember.avatarHash || incomingMember.avatarHash),
|
||||
avatarMime: preferIncoming
|
||||
? (incomingMember.avatarMime || existingMember.avatarMime)
|
||||
: (existingMember.avatarMime || incomingMember.avatarMime),
|
||||
avatarUpdatedAt: Math.max(existingUpdatedAt, incomingUpdatedAt) || undefined
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeMember(member: RoomMember, now = Date.now()): RoomMember {
|
||||
const key = getRoomMemberKey(member);
|
||||
const lastSeenAt =
|
||||
@@ -49,6 +80,9 @@ function normalizeMember(member: RoomMember, now = Date.now()): RoomMember {
|
||||
username: member.username || fallbackUsername(member),
|
||||
displayName: fallbackDisplayName(member),
|
||||
avatarUrl: member.avatarUrl || undefined,
|
||||
avatarHash: member.avatarHash || undefined,
|
||||
avatarMime: member.avatarMime || undefined,
|
||||
avatarUpdatedAt: normalizeAvatarUpdatedAt(member.avatarUpdatedAt),
|
||||
role: member.role || 'member',
|
||||
roleIds: normalizeRoleIds(member.roleIds),
|
||||
joinedAt,
|
||||
@@ -94,6 +128,7 @@ function mergeMembers(
|
||||
|
||||
const normalizedExisting = normalizeMember(existingMember, now);
|
||||
const preferIncoming = normalizedIncoming.lastSeenAt >= normalizedExisting.lastSeenAt;
|
||||
const avatarFields = mergeAvatarFields(normalizedExisting, normalizedIncoming, preferIncoming);
|
||||
|
||||
return {
|
||||
id: normalizedExisting.id || normalizedIncoming.id,
|
||||
@@ -104,9 +139,7 @@ function mergeMembers(
|
||||
displayName: preferIncoming
|
||||
? (normalizedIncoming.displayName || normalizedExisting.displayName)
|
||||
: (normalizedExisting.displayName || normalizedIncoming.displayName),
|
||||
avatarUrl: preferIncoming
|
||||
? (normalizedIncoming.avatarUrl || normalizedExisting.avatarUrl)
|
||||
: (normalizedExisting.avatarUrl || normalizedIncoming.avatarUrl),
|
||||
...avatarFields,
|
||||
role: mergeRole(normalizedExisting.role, normalizedIncoming.role, preferIncoming),
|
||||
roleIds: preferIncoming
|
||||
? (normalizedIncoming.roleIds || normalizedExisting.roleIds)
|
||||
@@ -145,6 +178,9 @@ export function roomMemberFromUser(
|
||||
username: user.username || '',
|
||||
displayName: user.displayName || user.username || 'User',
|
||||
avatarUrl: user.avatarUrl,
|
||||
avatarHash: user.avatarHash,
|
||||
avatarMime: user.avatarMime,
|
||||
avatarUpdatedAt: user.avatarUpdatedAt,
|
||||
role: roleOverride || user.role || 'member',
|
||||
joinedAt: user.joinedAt || seenAt,
|
||||
lastSeenAt: seenAt
|
||||
@@ -290,6 +326,9 @@ export function transferRoomOwnership(
|
||||
username: existingNextOwner?.username || nextOwner.username || '',
|
||||
displayName: existingNextOwner?.displayName || nextOwner.displayName || 'User',
|
||||
avatarUrl: existingNextOwner?.avatarUrl || nextOwner.avatarUrl || undefined,
|
||||
avatarHash: existingNextOwner?.avatarHash || nextOwner.avatarHash || undefined,
|
||||
avatarMime: existingNextOwner?.avatarMime || nextOwner.avatarMime || undefined,
|
||||
avatarUpdatedAt: existingNextOwner?.avatarUpdatedAt || nextOwner.avatarUpdatedAt || undefined,
|
||||
role: 'host',
|
||||
joinedAt: existingNextOwner?.joinedAt || nextOwner.joinedAt || now,
|
||||
lastSeenAt: existingNextOwner?.lastSeenAt || nextOwner.lastSeenAt || now
|
||||
|
||||
Reference in New Issue
Block a user