perf: server navigation

This commit is contained in:
2026-05-18 19:38:08 +02:00
parent 0152ed9dd2
commit afb64520ed
12 changed files with 212 additions and 90 deletions

View File

@@ -340,11 +340,12 @@ export class RoomMembersSyncEffects {
const role = room.hostId === currentUser.id
? 'host'
: (isCurrentRoom ? currentUser.role : existingMember?.role ?? 'member');
const seenAt = existingMember?.lastSeenAt ?? currentUser.joinedAt ?? Date.now();
return {
...roomMemberFromUser(currentUser, Date.now(), role),
...roomMemberFromUser(currentUser, seenAt, role),
id: existingMember?.id ?? currentUser.id,
joinedAt: existingMember?.joinedAt ?? currentUser.joinedAt ?? Date.now(),
joinedAt: existingMember?.joinedAt ?? currentUser.joinedAt ?? seenAt,
avatarUrl: currentUser.avatarUrl ?? existingMember?.avatarUrl,
role
};

View File

@@ -12,7 +12,8 @@ import {
of,
from,
EMPTY,
merge
merge,
timer
} from 'rxjs';
import {
map,
@@ -60,6 +61,8 @@ type BlockedRoomAccessAction =
| ReturnType<typeof RoomsActions.forgetRoom>
| ReturnType<typeof RoomsActions.joinRoomFailure>;
const VIEW_SERVER_LOAD_DELAY_MS = 75;
@Injectable()
export class RoomsEffects {
private actions$ = inject(Actions);
@@ -608,7 +611,12 @@ export class RoomsEffects {
navigationRequestVersion
});
this.router.navigate(['/room', room.id]);
window.setTimeout(() => {
if (this.signalingConnection.isCurrentRoomNavigation(room.id, navigationRequestVersion)) {
void this.router.navigate(['/room', room.id]);
}
}, 0);
return of(RoomsActions.viewServerSuccess({ room }));
};
@@ -634,7 +642,9 @@ export class RoomsEffects {
onViewServerSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(RoomsActions.viewServerSuccess),
mergeMap(({ room }) => [MessagesActions.loadMessages({ roomId: room.id }), UsersActions.loadBans()])
switchMap(({ room }) => timer(VIEW_SERVER_LOAD_DELAY_MS).pipe(
mergeMap(() => [MessagesActions.loadMessages({ roomId: room.id }), UsersActions.loadBans()])
))
)
);

View File

@@ -42,6 +42,20 @@ function getDefaultTextChannelId(room: Room): string {
return resolveActiveTextChannelId(enrichRoom(room).channels, 'general');
}
function activateRoomView(state: RoomsState, room: Room, isConnecting: boolean): RoomsState {
const enriched = enrichRoom(room);
return {
...state,
currentRoom: enriched,
savedRooms: upsertRoom(state.savedRooms, enriched),
isConnecting,
signalServerCompatibilityError: null,
isConnected: true,
activeChannelId: getDefaultTextChannelId(enriched)
};
}
/** Upsert a room into a saved-rooms list (add or replace by id) */
function upsertRoom(savedRooms: Room[], room: Room): Room[] {
const normalizedRoom = enrichRoom(room);
@@ -220,27 +234,24 @@ export const roomsReducer = createReducer(
})),
// View server - just switch the viewed room, stay connected
on(RoomsActions.viewServer, (state) => ({
...state,
isConnecting: true,
signalServerCompatibilityError: null,
error: null
})),
on(RoomsActions.viewServerSuccess, (state, { room }) => {
const enriched = enrichRoom(room);
on(RoomsActions.viewServer, (state, { room, skipBanCheck }) => {
if (skipBanCheck) {
return {
...activateRoomView(state, room, true),
error: null
};
}
return {
...state,
currentRoom: enriched,
savedRooms: upsertRoom(state.savedRooms, enriched),
isConnecting: false,
isConnecting: true,
signalServerCompatibilityError: null,
isConnected: true,
activeChannelId: getDefaultTextChannelId(enriched)
error: null
};
}),
on(RoomsActions.viewServerSuccess, (state, { room }) => activateRoomView(state, room, false)),
// Update room settings
on(RoomsActions.updateRoomSettings, (state) => ({
...state,