Fix issues with server navigation

This commit is contained in:
2026-04-01 18:18:31 +02:00
parent 8b6578da3c
commit fed270d28d
2 changed files with 140 additions and 94 deletions

View File

@@ -167,6 +167,8 @@ export class RoomsEffects {
* and prevents false join/leave sounds during state re-syncs.
*/
private knownVoiceUsers = new Set<string>();
private roomNavigationRequestVersion = 0;
private latestNavigatedRoomId: string | null = null;
/** Loads all saved rooms from the local database. */
loadRooms$ = createEffect(() =>
@@ -416,8 +418,11 @@ export class RoomsEffects {
user,
savedRooms
]) => {
const navigationRequestVersion = this.beginRoomNavigation(room.id);
void this.connectToRoomSignaling(room, user ?? null, undefined, savedRooms, {
showCompatibilityError: true
showCompatibilityError: true,
navigationRequestVersion
});
this.router.navigate(['/room', room.id]);
@@ -478,9 +483,11 @@ export class RoomsEffects {
const activateViewedRoom = () => {
const oderId = user.oderId || this.webrtc.peerId();
const navigationRequestVersion = this.beginRoomNavigation(room.id);
void this.connectToRoomSignaling(room, user, oderId, savedRooms, {
showCompatibilityError: true
showCompatibilityError: true,
navigationRequestVersion
});
this.router.navigate(['/room', room.id]);
@@ -1621,14 +1628,19 @@ export class RoomsEffects {
user: User | null,
resolvedOderId?: string,
savedRooms: Room[] = [],
options: { showCompatibilityError?: boolean } = {}
options: { showCompatibilityError?: boolean; navigationRequestVersion?: number } = {}
): Promise<void> {
const shouldShowCompatibilityError = options.showCompatibilityError ?? false;
const navigationRequestVersion = options.navigationRequestVersion;
const compatibilitySelector = this.resolveCompatibilitySelector(room);
const isCompatible = compatibilitySelector === null
? true
: await this.serverDirectory.ensureEndpointVersionCompatibility(compatibilitySelector);
if (!this.isCurrentRoomNavigation(room.id, navigationRequestVersion)) {
return;
}
if (!isCompatible) {
if (shouldShowCompatibilityError) {
this.store.dispatch(
@@ -1653,6 +1665,10 @@ export class RoomsEffects {
const sameSignalRooms = this.getRoomsForSignalingUrl(this.includeRoom(savedRooms, room), wsUrl);
const backgroundRooms = sameSignalRooms.filter((candidate) => candidate.id !== room.id);
const joinCurrentEndpointRooms = () => {
if (!this.isCurrentRoomNavigation(room.id, navigationRequestVersion)) {
return;
}
this.webrtc.setCurrentServer(room.id);
this.webrtc.identify(oderId, displayName, wsUrl);
@@ -1676,7 +1692,7 @@ export class RoomsEffects {
this.webrtc.connectToSignalingServer(wsUrl).subscribe({
next: (connected) => {
if (!connected)
if (!connected || !this.isCurrentRoomNavigation(room.id, navigationRequestVersion))
return;
joinCurrentEndpointRooms();
@@ -1788,6 +1804,22 @@ export class RoomsEffects {
return roomMatch ? roomMatch[1] : null;
}
private beginRoomNavigation(roomId: string): number {
this.roomNavigationRequestVersion += 1;
this.latestNavigatedRoomId = roomId;
return this.roomNavigationRequestVersion;
}
private isCurrentRoomNavigation(roomId: string, navigationRequestVersion?: number): boolean {
if (typeof navigationRequestVersion !== 'number') {
return true;
}
return navigationRequestVersion === this.roomNavigationRequestVersion
&& roomId === this.latestNavigatedRoomId;
}
private getUserRoleForRoom(room: Room, currentUser: User, currentRoom: Room | null): User['role'] | null {
if (room.hostId === currentUser.id || room.hostId === currentUser.oderId)
return 'host';