feat: Add user metadata changing display name and description with sync
All checks were successful
Queue Release Build / prepare (push) Successful in 28s
Deploy Web Apps / deploy (push) Successful in 5m2s
Queue Release Build / build-windows (push) Successful in 16m44s
Queue Release Build / build-linux (push) Successful in 27m12s
Queue Release Build / finalize (push) Successful in 22s
All checks were successful
Queue Release Build / prepare (push) Successful in 28s
Deploy Web Apps / deploy (push) Successful in 5m2s
Queue Release Build / build-windows (push) Successful in 16m44s
Queue Release Build / build-linux (push) Successful in 27m12s
Queue Release Build / finalize (push) Successful in 22s
This commit is contained in:
@@ -36,6 +36,51 @@ function normalizeAvatarUpdatedAt(value: unknown): number | undefined {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function normalizeProfileUpdatedAt(value: unknown): number | undefined {
|
||||
return typeof value === 'number' && Number.isFinite(value) && value > 0
|
||||
? value
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function normalizeDescription(value: unknown): string | undefined {
|
||||
if (typeof value !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const normalized = value.trim();
|
||||
|
||||
return normalized || undefined;
|
||||
}
|
||||
|
||||
function hasOwnProperty(object: object, key: string): boolean {
|
||||
return Object.prototype.hasOwnProperty.call(object, key);
|
||||
}
|
||||
|
||||
function mergeProfileFields(
|
||||
existingMember: Pick<RoomMember, 'displayName' | 'description' | 'profileUpdatedAt'>,
|
||||
incomingMember: Pick<RoomMember, 'displayName' | 'description' | 'profileUpdatedAt'>,
|
||||
preferIncomingFallback: boolean
|
||||
): Pick<RoomMember, 'displayName' | 'description' | 'profileUpdatedAt'> {
|
||||
const existingUpdatedAt = existingMember.profileUpdatedAt ?? 0;
|
||||
const incomingUpdatedAt = incomingMember.profileUpdatedAt ?? 0;
|
||||
const preferIncoming = incomingUpdatedAt === existingUpdatedAt
|
||||
? preferIncomingFallback
|
||||
: incomingUpdatedAt > existingUpdatedAt;
|
||||
const incomingHasDescription = hasOwnProperty(incomingMember, 'description');
|
||||
const incomingDescription = normalizeDescription(incomingMember.description);
|
||||
const existingDescription = normalizeDescription(existingMember.description);
|
||||
|
||||
return {
|
||||
displayName: preferIncoming
|
||||
? (incomingMember.displayName || existingMember.displayName)
|
||||
: (existingMember.displayName || incomingMember.displayName),
|
||||
description: preferIncoming
|
||||
? (incomingHasDescription ? incomingDescription : existingDescription)
|
||||
: existingDescription,
|
||||
profileUpdatedAt: Math.max(existingUpdatedAt, incomingUpdatedAt) || undefined
|
||||
};
|
||||
}
|
||||
|
||||
function mergeAvatarFields(
|
||||
existingMember: Pick<RoomMember, 'avatarUrl' | 'avatarHash' | 'avatarMime' | 'avatarUpdatedAt'>,
|
||||
incomingMember: Pick<RoomMember, 'avatarUrl' | 'avatarHash' | 'avatarMime' | 'avatarUpdatedAt'>,
|
||||
@@ -73,12 +118,12 @@ function normalizeMember(member: RoomMember, now = Date.now()): RoomMember {
|
||||
typeof member.joinedAt === 'number' && Number.isFinite(member.joinedAt)
|
||||
? member.joinedAt
|
||||
: lastSeenAt;
|
||||
|
||||
return {
|
||||
const nextMember: RoomMember = {
|
||||
id: member.id || key,
|
||||
oderId: member.oderId || undefined,
|
||||
username: member.username || fallbackUsername(member),
|
||||
displayName: fallbackDisplayName(member),
|
||||
profileUpdatedAt: normalizeProfileUpdatedAt(member.profileUpdatedAt),
|
||||
avatarUrl: member.avatarUrl || undefined,
|
||||
avatarHash: member.avatarHash || undefined,
|
||||
avatarMime: member.avatarMime || undefined,
|
||||
@@ -88,6 +133,12 @@ function normalizeMember(member: RoomMember, now = Date.now()): RoomMember {
|
||||
joinedAt,
|
||||
lastSeenAt
|
||||
};
|
||||
|
||||
if (hasOwnProperty(member, 'description')) {
|
||||
nextMember.description = normalizeDescription(member.description);
|
||||
}
|
||||
|
||||
return nextMember;
|
||||
}
|
||||
|
||||
function compareMembers(firstMember: RoomMember, secondMember: RoomMember): number {
|
||||
@@ -128,6 +179,7 @@ function mergeMembers(
|
||||
|
||||
const normalizedExisting = normalizeMember(existingMember, now);
|
||||
const preferIncoming = normalizedIncoming.lastSeenAt >= normalizedExisting.lastSeenAt;
|
||||
const profileFields = mergeProfileFields(normalizedExisting, normalizedIncoming, preferIncoming);
|
||||
const avatarFields = mergeAvatarFields(normalizedExisting, normalizedIncoming, preferIncoming);
|
||||
|
||||
return {
|
||||
@@ -136,9 +188,7 @@ function mergeMembers(
|
||||
username: preferIncoming
|
||||
? (normalizedIncoming.username || normalizedExisting.username)
|
||||
: (normalizedExisting.username || normalizedIncoming.username),
|
||||
displayName: preferIncoming
|
||||
? (normalizedIncoming.displayName || normalizedExisting.displayName)
|
||||
: (normalizedExisting.displayName || normalizedIncoming.displayName),
|
||||
...profileFields,
|
||||
...avatarFields,
|
||||
role: mergeRole(normalizedExisting.role, normalizedIncoming.role, preferIncoming),
|
||||
roleIds: preferIncoming
|
||||
@@ -177,6 +227,8 @@ export function roomMemberFromUser(
|
||||
oderId: user.oderId || undefined,
|
||||
username: user.username || '',
|
||||
displayName: user.displayName || user.username || 'User',
|
||||
description: user.description,
|
||||
profileUpdatedAt: user.profileUpdatedAt,
|
||||
avatarUrl: user.avatarUrl,
|
||||
avatarHash: user.avatarHash,
|
||||
avatarMime: user.avatarMime,
|
||||
|
||||
Reference in New Issue
Block a user