fix: multiple bug fixes
isolated users, db backup, weird disconnect issues for long voice sessions,
This commit is contained in:
@@ -48,6 +48,7 @@ import {
|
||||
buildKnownUserExtras,
|
||||
isWrongServer,
|
||||
resolveRoom,
|
||||
reconcileRoomSnapshotChannels,
|
||||
sanitizeRoomSnapshot,
|
||||
normalizeIncomingBans,
|
||||
getPersistedCurrentUserId
|
||||
@@ -122,7 +123,8 @@ export class RoomStateSyncEffects {
|
||||
const actions: Action[] = [
|
||||
UsersActions.syncServerPresence({
|
||||
roomId: signalingMessage.serverId,
|
||||
users: syncedUsers
|
||||
users: syncedUsers,
|
||||
connectedPeerIds: this.webrtc.getConnectedPeers()
|
||||
})
|
||||
];
|
||||
|
||||
@@ -641,7 +643,10 @@ export class RoomStateSyncEffects {
|
||||
if (!room || !incomingRoom)
|
||||
return EMPTY;
|
||||
|
||||
const roomChanges = sanitizeRoomSnapshot(incomingRoom);
|
||||
const roomChanges = {
|
||||
...sanitizeRoomSnapshot(incomingRoom),
|
||||
channels: reconcileRoomSnapshotChannels(room.channels, incomingRoom.channels)
|
||||
};
|
||||
const bans = normalizeIncomingBans(room.id, event.bans);
|
||||
|
||||
return this.syncBansToLocalRoom(room.id, bans).pipe(
|
||||
|
||||
45
toju-app/src/app/store/rooms/rooms-helpers-snapshot.spec.ts
Normal file
45
toju-app/src/app/store/rooms/rooms-helpers-snapshot.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import {
|
||||
reconcileRoomSnapshotChannels,
|
||||
sanitizeRoomSnapshot
|
||||
} from './rooms.helpers';
|
||||
|
||||
describe('room snapshot helpers', () => {
|
||||
it('drops empty channel arrays from outgoing snapshots', () => {
|
||||
expect(sanitizeRoomSnapshot({ channels: [] }).channels).toBeUndefined();
|
||||
});
|
||||
|
||||
it('keeps cached channels when incoming snapshot has none', () => {
|
||||
const cachedChannels = [
|
||||
{ id: 'general', name: 'general', type: 'text', position: 0 },
|
||||
{ id: 'updates', name: 'updates', type: 'text', position: 1 }
|
||||
] as const;
|
||||
|
||||
expect(reconcileRoomSnapshotChannels(cachedChannels as never, undefined)).toEqual(cachedChannels);
|
||||
expect(reconcileRoomSnapshotChannels(cachedChannels as never, [] as never)).toEqual(cachedChannels);
|
||||
});
|
||||
|
||||
it('keeps richer cached channels when incoming snapshot is smaller', () => {
|
||||
const cachedChannels = [
|
||||
{ id: 'general', name: 'general', type: 'text', position: 0 },
|
||||
{ id: 'updates', name: 'updates', type: 'text', position: 1 },
|
||||
{ id: 'voice', name: 'General', type: 'voice', position: 0 }
|
||||
] as const;
|
||||
const incomingChannels = [
|
||||
{ id: 'general', name: 'general', type: 'text', position: 0 }
|
||||
] as const;
|
||||
|
||||
expect(reconcileRoomSnapshotChannels(cachedChannels as never, incomingChannels as never)).toEqual(cachedChannels);
|
||||
});
|
||||
|
||||
it('accepts incoming channels when snapshot is at least as complete', () => {
|
||||
const cachedChannels = [
|
||||
{ id: 'general', name: 'general', type: 'text', position: 0 }
|
||||
] as const;
|
||||
const incomingChannels = [
|
||||
{ id: 'general', name: 'general', type: 'text', position: 0 },
|
||||
{ id: 'updates', name: 'updates', type: 'text', position: 1 }
|
||||
] as const;
|
||||
|
||||
expect(reconcileRoomSnapshotChannels(cachedChannels as never, incomingChannels as never)).toEqual(incomingChannels);
|
||||
});
|
||||
});
|
||||
@@ -57,6 +57,8 @@ export const RoomsActions = createActionGroup({
|
||||
'Forget Room': props<{ roomId: string; nextOwnerKey?: string }>(),
|
||||
'Forget Room Success': props<{ roomId: string }>(),
|
||||
|
||||
'Reset Rooms State': emptyProps(),
|
||||
|
||||
'Update Room Settings': props<{ roomId: string; settings: Partial<RoomSettings> }>(),
|
||||
'Update Room Settings Success': props<{ roomId: string; settings: RoomSettings }>(),
|
||||
'Update Room Settings Failure': props<{ error: string }>(),
|
||||
|
||||
@@ -97,6 +97,31 @@ export function resolveRoomChannels(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Peer room-state snapshots can lag behind cached room metadata.
|
||||
* Keep richer cached channels until an equally rich or richer snapshot arrives.
|
||||
*/
|
||||
export function reconcileRoomSnapshotChannels(
|
||||
cachedChannels: Room['channels'] | undefined,
|
||||
incomingChannels: Room['channels'] | undefined
|
||||
): Room['channels'] | undefined {
|
||||
if (hasPersistedChannels(cachedChannels) && !hasPersistedChannels(incomingChannels)) {
|
||||
return cachedChannels;
|
||||
}
|
||||
|
||||
if (hasPersistedChannels(cachedChannels) && hasPersistedChannels(incomingChannels)) {
|
||||
return incomingChannels.length >= cachedChannels.length
|
||||
? incomingChannels
|
||||
: cachedChannels;
|
||||
}
|
||||
|
||||
if (hasPersistedChannels(incomingChannels)) {
|
||||
return incomingChannels;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function resolveTextChannelId(
|
||||
channels: Room['channels'] | undefined,
|
||||
preferredChannelId?: string | null
|
||||
@@ -136,7 +161,7 @@ export function sanitizeRoomSnapshot(room: Partial<Room>): Partial<Room> {
|
||||
iconUpdatedAt: typeof room.iconUpdatedAt === 'number' ? room.iconUpdatedAt : undefined,
|
||||
slowModeInterval: typeof room.slowModeInterval === 'number' ? room.slowModeInterval : undefined,
|
||||
permissions: room.permissions ? { ...room.permissions } : undefined,
|
||||
channels: Array.isArray(room.channels) ? room.channels : undefined,
|
||||
channels: hasPersistedChannels(room.channels) ? room.channels : undefined,
|
||||
members: Array.isArray(room.members) ? room.members : undefined,
|
||||
roles: Array.isArray(room.roles) ? room.roles : undefined,
|
||||
roleAssignments: Array.isArray(room.roleAssignments) ? room.roleAssignments : undefined,
|
||||
|
||||
@@ -105,6 +105,10 @@ export const initialState: RoomsState = {
|
||||
export const roomsReducer = createReducer(
|
||||
initialState,
|
||||
|
||||
on(RoomsActions.resetRoomsState, () => ({
|
||||
...initialState
|
||||
})),
|
||||
|
||||
// Load rooms
|
||||
on(RoomsActions.loadRooms, (state) => ({
|
||||
...state,
|
||||
|
||||
Reference in New Issue
Block a user