Resync username instead of using Anonymous

This commit is contained in:
2026-03-19 03:57:51 +01:00
parent 9a173792a4
commit 8f960be1e9
4 changed files with 66 additions and 11 deletions

View File

@@ -8,18 +8,24 @@ interface WsMessage {
type: string; type: string;
} }
function normalizeDisplayName(value: unknown, fallback = 'User'): string {
const normalized = typeof value === 'string' ? value.trim() : '';
return normalized || fallback;
}
/** Sends the current user list for a given server to a single connected user. */ /** Sends the current user list for a given server to a single connected user. */
function sendServerUsers(user: ConnectedUser, serverId: string): void { function sendServerUsers(user: ConnectedUser, serverId: string): void {
const users = Array.from(connectedUsers.values()) const users = Array.from(connectedUsers.values())
.filter(cu => cu.serverIds.has(serverId) && cu.oderId !== user.oderId) .filter(cu => cu.serverIds.has(serverId) && cu.oderId !== user.oderId)
.map(cu => ({ oderId: cu.oderId, displayName: cu.displayName ?? 'Anonymous' })); .map(cu => ({ oderId: cu.oderId, displayName: normalizeDisplayName(cu.displayName) }));
user.ws.send(JSON.stringify({ type: 'server_users', serverId, users })); user.ws.send(JSON.stringify({ type: 'server_users', serverId, users }));
} }
function handleIdentify(user: ConnectedUser, message: WsMessage, connectionId: string): void { function handleIdentify(user: ConnectedUser, message: WsMessage, connectionId: string): void {
user.oderId = String(message['oderId'] || connectionId); user.oderId = String(message['oderId'] || connectionId);
user.displayName = String(message['displayName'] || 'Anonymous'); user.displayName = normalizeDisplayName(message['displayName'], normalizeDisplayName(user.displayName));
connectedUsers.set(connectionId, user); connectedUsers.set(connectionId, user);
console.log(`User identified: ${user.displayName} (${user.oderId})`); console.log(`User identified: ${user.displayName} (${user.oderId})`);
} }
@@ -47,7 +53,7 @@ async function handleJoinServer(user: ConnectedUser, message: WsMessage, connect
user.serverIds.add(sid); user.serverIds.add(sid);
user.viewedServerId = sid; user.viewedServerId = sid;
connectedUsers.set(connectionId, user); connectedUsers.set(connectionId, user);
console.log(`User ${user.displayName ?? 'Anonymous'} (${user.oderId}) joined server ${sid} (new=${isNew})`); console.log(`User ${normalizeDisplayName(user.displayName)} (${user.oderId}) joined server ${sid} (new=${isNew})`);
sendServerUsers(user, sid); sendServerUsers(user, sid);
@@ -55,7 +61,7 @@ async function handleJoinServer(user: ConnectedUser, message: WsMessage, connect
broadcastToServer(sid, { broadcastToServer(sid, {
type: 'user_joined', type: 'user_joined',
oderId: user.oderId, oderId: user.oderId,
displayName: user.displayName ?? 'Anonymous', displayName: normalizeDisplayName(user.displayName),
serverId: sid serverId: sid
}, user.oderId); }, user.oderId);
} }
@@ -66,7 +72,7 @@ function handleViewServer(user: ConnectedUser, message: WsMessage, connectionId:
user.viewedServerId = viewSid; user.viewedServerId = viewSid;
connectedUsers.set(connectionId, user); connectedUsers.set(connectionId, user);
console.log(`User ${user.displayName ?? 'Anonymous'} (${user.oderId}) viewing server ${viewSid}`); console.log(`User ${normalizeDisplayName(user.displayName)} (${user.oderId}) viewing server ${viewSid}`);
sendServerUsers(user, viewSid); sendServerUsers(user, viewSid);
} }
@@ -87,7 +93,7 @@ function handleLeaveServer(user: ConnectedUser, message: WsMessage, connectionId
broadcastToServer(leaveSid, { broadcastToServer(leaveSid, {
type: 'user_left', type: 'user_left',
oderId: user.oderId, oderId: user.oderId,
displayName: user.displayName ?? 'Anonymous', displayName: normalizeDisplayName(user.displayName),
serverId: leaveSid, serverId: leaveSid,
serverIds: Array.from(user.serverIds) serverIds: Array.from(user.serverIds)
}, user.oderId); }, user.oderId);

View File

@@ -825,13 +825,15 @@ export class WebRTCService implements OnDestroy {
* @param displayName - The user's display name. * @param displayName - The user's display name.
*/ */
identify(oderId: string, displayName: string, signalUrl?: string): void { identify(oderId: string, displayName: string, signalUrl?: string): void {
const normalizedDisplayName = displayName.trim() || DEFAULT_DISPLAY_NAME;
this.lastIdentifyCredentials = { oderId, this.lastIdentifyCredentials = { oderId,
displayName }; displayName: normalizedDisplayName };
const identifyMessage = { const identifyMessage = {
type: SIGNALING_TYPE_IDENTIFY, type: SIGNALING_TYPE_IDENTIFY,
oderId, oderId,
displayName displayName: normalizedDisplayName
}; };
if (signalUrl) { if (signalUrl) {
@@ -839,7 +841,15 @@ export class WebRTCService implements OnDestroy {
return; return;
} }
this.sendRawMessage(identifyMessage); const connectedManagers = this.getConnectedSignalingManagers();
if (connectedManagers.length === 0) {
return;
}
for (const { manager } of connectedManagers) {
manager.sendRawMessage(identifyMessage);
}
} }
/** /**

View File

@@ -60,7 +60,7 @@ function buildSignalingUser(
data: { oderId: string; displayName?: string }, data: { oderId: string; displayName?: string },
extras: Record<string, unknown> = {} extras: Record<string, unknown> = {}
) { ) {
const displayName = data.displayName || 'User'; const displayName = data.displayName?.trim() || 'User';
return { return {
oderId: data.oderId, oderId: data.oderId,
@@ -98,6 +98,16 @@ function isWrongServer(
return !!(msgServerId && viewedServerId && msgServerId !== viewedServerId); return !!(msgServerId && viewedServerId && msgServerId !== viewedServerId);
} }
function resolveUserDisplayName(user: Pick<User, 'displayName' | 'username'> | null | undefined): string {
const displayName = user?.displayName?.trim();
if (displayName) {
return displayName;
}
return user?.username?.trim() || 'User';
}
interface RoomPresenceSignalingMessage { interface RoomPresenceSignalingMessage {
type: string; type: string;
reason?: string; reason?: string;
@@ -1379,7 +1389,7 @@ export class RoomsEffects {
sourceUrl: room.sourceUrl sourceUrl: room.sourceUrl
}); });
const oderId = resolvedOderId || user?.oderId || this.webrtc.peerId(); const oderId = resolvedOderId || user?.oderId || this.webrtc.peerId();
const displayName = user?.displayName || 'Anonymous'; const displayName = resolveUserDisplayName(user);
const sameSignalRooms = this.getRoomsForSignalingUrl(this.includeRoom(savedRooms, room), wsUrl); const sameSignalRooms = this.getRoomsForSignalingUrl(this.includeRoom(savedRooms, room), wsUrl);
const backgroundRooms = sameSignalRooms.filter((candidate) => candidate.id !== room.id); const backgroundRooms = sameSignalRooms.filter((candidate) => candidate.id !== room.id);
const joinCurrentEndpointRooms = () => { const joinCurrentEndpointRooms = () => {

View File

@@ -438,6 +438,25 @@ export class UsersEffects {
{ dispatch: false } { dispatch: false }
); );
/** Keep signaling identity aligned with the current profile to avoid stale fallback names. */
syncSignalingIdentity$ = createEffect(
() =>
this.actions$.pipe(
ofType(
UsersActions.setCurrentUser,
UsersActions.loadCurrentUserSuccess
),
withLatestFrom(this.store.select(selectCurrentUser)),
tap(([, user]) => {
if (!user)
return;
this.webrtc.identify(user.oderId || user.id, this.resolveDisplayName(user));
})
),
{ dispatch: false }
);
private resolveRoom(roomId: string | undefined, currentRoom: Room | null, savedRooms: Room[]): Room | null { private resolveRoom(roomId: string | undefined, currentRoom: Room | null, savedRooms: Room[]): Room | null {
if (!roomId) if (!roomId)
return currentRoom; return currentRoom;
@@ -448,6 +467,16 @@ export class UsersEffects {
return savedRooms.find((room) => room.id === roomId) ?? null; return savedRooms.find((room) => room.id === roomId) ?? null;
} }
private resolveDisplayName(user: Pick<User, 'displayName' | 'username'>): string {
const displayName = user.displayName?.trim();
if (displayName) {
return displayName;
}
return user.username?.trim() || 'User';
}
private toSourceSelector(room: Room): { sourceId?: string; sourceUrl?: string } { private toSourceSelector(room: Room): { sourceId?: string; sourceUrl?: string } {
return { return {
sourceId: room.sourceId, sourceId: room.sourceId,