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

This commit is contained in:
2026-04-17 22:04:18 +02:00
parent 3ba8a2c9eb
commit bd21568726
41 changed files with 1176 additions and 191 deletions

View File

@@ -232,7 +232,7 @@ A single ordered data channel carries all peer-to-peer messages: chat events, at
Back-pressure is handled with a high-water mark (4 MB) and low-water mark (1 MB). `sendToPeerBuffered()` waits for the buffer to drain before sending, which matters during file transfers.
Profile avatar sync follows attachment-style chunk transport plus server-icon-style version handshakes: sender announces `avatarUpdatedAt`, receiver requests only when remote version is newer, then sender streams ordered base64 chunks over buffered sends.
Profile avatar sync follows attachment-style chunk transport plus server-icon-style version handshakes: sender announces avatar/profile versions, receiver requests only when either remote version is newer, then sender streams ordered base64 chunks when avatar bytes are needed and still uses the same full-event path for profile-only updates.
Every 5 seconds a PING message is sent to each peer. The peer responds with PONG carrying the original timestamp, and the round-trip latency is stored in a signal.

View File

@@ -328,8 +328,13 @@ export class WebRTCService implements OnDestroy {
* @param oderId - The user's unique order/peer ID.
* @param displayName - The user's display name.
*/
identify(oderId: string, displayName: string, signalUrl?: string): void {
this.signalingTransportHandler.identify(oderId, displayName, signalUrl);
identify(
oderId: string,
displayName: string,
signalUrl?: string,
profile?: { description?: string; profileUpdatedAt?: number }
): void {
this.signalingTransportHandler.identify(oderId, displayName, signalUrl, profile);
}
/**

View File

@@ -36,6 +36,10 @@ export interface IdentifyCredentials {
oderId: string;
/** The user's display name shown to other peers. */
displayName: string;
/** Optional profile description advertised via signaling identity. */
description?: string;
/** Monotonic profile version for late-join reconciliation. */
profileUpdatedAt?: number;
}
/** Last-joined server info, used for reconnection. */

View File

@@ -30,6 +30,10 @@ export class SignalingTransportHandler<TMessage> {
return this.lastIdentifyCredentials?.displayName || DEFAULT_DISPLAY_NAME;
}
getIdentifyDescription(): string | undefined {
return this.lastIdentifyCredentials?.description;
}
getConnectedSignalingManagers(): ConnectedSignalingManager[] {
return this.dependencies.signalingCoordinator.getConnectedSignalingManagers();
}
@@ -160,12 +164,27 @@ export class SignalingTransportHandler<TMessage> {
return true;
}
identify(oderId: string, displayName: string, signalUrl?: string): void {
identify(
oderId: string,
displayName: string,
signalUrl?: string,
profile?: Pick<IdentifyCredentials, 'description' | 'profileUpdatedAt'>
): void {
const normalizedDisplayName = displayName.trim() || DEFAULT_DISPLAY_NAME;
const normalizedDescription = typeof profile?.description === 'string'
? (profile.description.trim() || undefined)
: undefined;
const normalizedProfileUpdatedAt = typeof profile?.profileUpdatedAt === 'number'
&& Number.isFinite(profile.profileUpdatedAt)
&& profile.profileUpdatedAt > 0
? profile.profileUpdatedAt
: undefined;
this.lastIdentifyCredentials = {
oderId,
displayName: normalizedDisplayName
displayName: normalizedDisplayName,
description: normalizedDescription,
profileUpdatedAt: normalizedProfileUpdatedAt
};
if (signalUrl) {
@@ -173,6 +192,8 @@ export class SignalingTransportHandler<TMessage> {
type: SIGNALING_TYPE_IDENTIFY,
oderId,
displayName: normalizedDisplayName,
description: normalizedDescription,
profileUpdatedAt: normalizedProfileUpdatedAt,
connectionScope: signalUrl
});
@@ -190,6 +211,8 @@ export class SignalingTransportHandler<TMessage> {
type: SIGNALING_TYPE_IDENTIFY,
oderId,
displayName: normalizedDisplayName,
description: normalizedDescription,
profileUpdatedAt: normalizedProfileUpdatedAt,
connectionScope: managerSignalUrl
});
}