Fix joinRoom failing when the roomviewstore state changes. (#34180)
* Fix joinRoom failing when the roomviewstore state changes. * drive by type fix * Help debugging failed dispatches * Use proper types and include roomId in RoomViewStore tests * remove focus * Update apps/web/src/stores/RoomViewStore.tsx Co-authored-by: R Midhun Suresh <hi@midhun.dev> * fmt * Add a test for coverage --------- Co-authored-by: R Midhun Suresh <hi@midhun.dev>
This commit is contained in:
co-authored by
R Midhun Suresh
parent
f2cc9353ac
commit
ea38041c87
@@ -148,7 +148,8 @@ export class RoomViewStore extends EventEmitter {
|
||||
// another RVS via INITIAL_STATE as they share the same underlying object. Mostly relevant for tests.
|
||||
private state = utils.deepCopy(INITIAL_STATE);
|
||||
|
||||
private dis?: MatrixDispatcher;
|
||||
// this is defacto always assigned as `resetDispatcher` is called in the constructor.
|
||||
private dis!: MatrixDispatcher;
|
||||
private dispatchToken?: string;
|
||||
|
||||
public constructor(
|
||||
@@ -195,7 +196,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
|
||||
// Fired so we can reduce dependency on event emitters to this store, which is relatively
|
||||
// central to the application and can easily cause import cycles.
|
||||
this.dis?.dispatch<ActiveRoomChangedPayload>({
|
||||
this.dis.dispatch<ActiveRoomChangedPayload>({
|
||||
action: Action.ActiveRoomChanged,
|
||||
oldRoomId: lastRoomId,
|
||||
newRoomId: this.state.roomId,
|
||||
@@ -302,7 +303,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
// if the room is displayed in a module, we don't want to change the room view
|
||||
if (roomId && this.isRoomDisplayedInModule(roomId)) return;
|
||||
|
||||
this.dis?.dispatch<ViewRoomPayload>({
|
||||
this.dis.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: payload.event.getRoomId(),
|
||||
replyingToEvent: payload.event,
|
||||
@@ -415,7 +416,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
await this.stores.slidingSyncManager.setRoomVisible(payload.room_id);
|
||||
|
||||
// Re-fire the payload: we won't re-process it because the prev room ID == payload room ID now
|
||||
this.dis?.dispatch({
|
||||
this.dis.dispatch({
|
||||
...payload,
|
||||
});
|
||||
return;
|
||||
@@ -466,7 +467,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
viaServers: payload.via_servers,
|
||||
};
|
||||
}
|
||||
this.dis?.dispatch<JoinRoomPayload>(joinPayload);
|
||||
this.dis.dispatch<JoinRoomPayload>(joinPayload);
|
||||
}
|
||||
|
||||
if (room) {
|
||||
@@ -505,7 +506,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
viaServers = result.servers;
|
||||
} catch (err) {
|
||||
logger.error("RVS failed to get room id for alias: ", err);
|
||||
this.dis?.dispatch<ViewRoomErrorPayload>({
|
||||
this.dis.dispatch<ViewRoomErrorPayload>({
|
||||
action: Action.ViewRoomError,
|
||||
room_id: null,
|
||||
room_alias: payload.room_alias,
|
||||
@@ -516,7 +517,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
}
|
||||
|
||||
// Re-fire the payload with the newly found room_id
|
||||
this.dis?.dispatch({
|
||||
this.dis.dispatch({
|
||||
...payload,
|
||||
room_id: roomId,
|
||||
via_servers: viaServers,
|
||||
@@ -545,9 +546,24 @@ export class RoomViewStore extends EventEmitter {
|
||||
});
|
||||
|
||||
// take a copy of roomAlias, roomId & viaServers as they may change by the time the join is complete
|
||||
const { roomAlias, roomId = payload.roomId, viaServers = [] } = this.state;
|
||||
const { roomAlias, viaServers = [] } = this.state;
|
||||
// fall back to the payload's roomId explicitly since it is always the room we were asked to join
|
||||
const roomId = this.state.roomId ?? payload.roomId;
|
||||
// prefer the room alias if we have one as it allows joining over federation even with no viaServers
|
||||
const address = roomAlias || roomId!;
|
||||
const address = roomAlias || roomId;
|
||||
|
||||
if (!address) {
|
||||
logger.error("Cannot join room: no room ID or alias to join", payload);
|
||||
this.dis.dispatch<JoinRoomErrorPayload>({
|
||||
action: Action.JoinRoomError,
|
||||
roomId,
|
||||
err: new UserFriendlyError("room|error_join_unknown", {
|
||||
cause: new Error("Cannot join room: no room ID or alias to join"),
|
||||
}),
|
||||
canAskToJoin: payload.canAskToJoin,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const joinOpts: IJoinRoomOpts = {
|
||||
viaServers,
|
||||
@@ -568,14 +584,14 @@ export class RoomViewStore extends EventEmitter {
|
||||
// We do *not* clear the 'joining' flag because the Room object and/or our 'joined' member event may not
|
||||
// have come down the sync stream yet, and that's the point at which we'd consider the user joined to the
|
||||
// room.
|
||||
this.dis?.dispatch<JoinRoomReadyPayload>({
|
||||
this.dis.dispatch<JoinRoomReadyPayload>({
|
||||
action: Action.JoinRoomReady,
|
||||
roomId: roomId!,
|
||||
roomId,
|
||||
metricsTrigger: payload.metricsTrigger,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error("Error thrown while handling joinRoom", err);
|
||||
this.dis?.dispatch<JoinRoomErrorPayload>({
|
||||
this.dis.dispatch<JoinRoomErrorPayload>({
|
||||
action: Action.JoinRoomError,
|
||||
roomId,
|
||||
err: err instanceof Error ? err : new UserFriendlyError("room|error_join_unknown", { cause: err }),
|
||||
@@ -583,7 +599,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
});
|
||||
|
||||
if (payload.canAskToJoin && err instanceof MatrixError && err.httpStatus === 403) {
|
||||
this.dis?.dispatch({ action: Action.PromptAskToJoin });
|
||||
this.dis.dispatch({ action: Action.PromptAskToJoin });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -665,7 +681,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
*/
|
||||
public resetDispatcher(dis: MatrixDispatcher): void {
|
||||
if (this.dispatchToken) {
|
||||
this.dis?.unregister(this.dispatchToken);
|
||||
this.dis.unregister(this.dispatchToken);
|
||||
}
|
||||
this.dis = dis;
|
||||
if (dis) {
|
||||
|
||||
Reference in New Issue
Block a user