mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 11:47:23 +03:00
Fix codepath which can wrongly cause automatic space switch from all rooms (#8560)
* Fix codepath which can wrongly cause automatic space switch from all rooms * Improve typing
This commit is contained in:
parent
13aa610cd2
commit
f9c85ac7c2
2 changed files with 37 additions and 36 deletions
|
@ -25,6 +25,8 @@ import { JoinedRoom as JoinedRoomEvent } from "matrix-analytics-events/types/typ
|
||||||
import { JoinRule } from "matrix-js-sdk/src/@types/partials";
|
import { JoinRule } from "matrix-js-sdk/src/@types/partials";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { ClientEvent } from "matrix-js-sdk/src/client";
|
import { ClientEvent } from "matrix-js-sdk/src/client";
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
import { Optional } from "matrix-events-sdk";
|
||||||
|
|
||||||
import dis from '../dispatcher/dispatcher';
|
import dis from '../dispatcher/dispatcher';
|
||||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||||
|
@ -53,30 +55,30 @@ const INITIAL_STATE = {
|
||||||
// Whether we're joining the currently viewed room (see isJoining())
|
// Whether we're joining the currently viewed room (see isJoining())
|
||||||
joining: false,
|
joining: false,
|
||||||
// Any error that has occurred during joining
|
// Any error that has occurred during joining
|
||||||
joinError: null,
|
joinError: null as Error,
|
||||||
// The room ID of the room currently being viewed
|
// The room ID of the room currently being viewed
|
||||||
roomId: null,
|
roomId: null as string,
|
||||||
|
|
||||||
// The event to scroll to when the room is first viewed
|
// The event to scroll to when the room is first viewed
|
||||||
initialEventId: null,
|
initialEventId: null as string,
|
||||||
initialEventPixelOffset: null,
|
initialEventPixelOffset: null as number,
|
||||||
// Whether to highlight the initial event
|
// Whether to highlight the initial event
|
||||||
isInitialEventHighlighted: false,
|
isInitialEventHighlighted: false,
|
||||||
// whether to scroll `event_id` into view
|
// whether to scroll `event_id` into view
|
||||||
initialEventScrollIntoView: true,
|
initialEventScrollIntoView: true,
|
||||||
|
|
||||||
// The room alias of the room (or null if not originally specified in view_room)
|
// The room alias of the room (or null if not originally specified in view_room)
|
||||||
roomAlias: null,
|
roomAlias: null as string,
|
||||||
// Whether the current room is loading
|
// Whether the current room is loading
|
||||||
roomLoading: false,
|
roomLoading: false,
|
||||||
// Any error that has occurred during loading
|
// Any error that has occurred during loading
|
||||||
roomLoadError: null,
|
roomLoadError: null as MatrixError,
|
||||||
|
|
||||||
replyingToEvent: null,
|
replyingToEvent: null as MatrixEvent,
|
||||||
|
|
||||||
shouldPeek: false,
|
shouldPeek: false,
|
||||||
|
|
||||||
viaServers: [],
|
viaServers: [] as string[],
|
||||||
|
|
||||||
wasContextSwitch: false,
|
wasContextSwitch: false,
|
||||||
};
|
};
|
||||||
|
@ -103,12 +105,12 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
super(dis);
|
super(dis);
|
||||||
}
|
}
|
||||||
|
|
||||||
public addRoomListener(roomId: string, fn: Listener) {
|
public addRoomListener(roomId: string, fn: Listener): void {
|
||||||
if (!this.roomIdActivityListeners[roomId]) this.roomIdActivityListeners[roomId] = [];
|
if (!this.roomIdActivityListeners[roomId]) this.roomIdActivityListeners[roomId] = [];
|
||||||
this.roomIdActivityListeners[roomId].push(fn);
|
this.roomIdActivityListeners[roomId].push(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeRoomListener(roomId: string, fn: Listener) {
|
public removeRoomListener(roomId: string, fn: Listener): void {
|
||||||
if (this.roomIdActivityListeners[roomId]) {
|
if (this.roomIdActivityListeners[roomId]) {
|
||||||
const i = this.roomIdActivityListeners[roomId].indexOf(fn);
|
const i = this.roomIdActivityListeners[roomId].indexOf(fn);
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
|
@ -119,7 +121,7 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitForRoom(roomId: string, isActive: boolean) {
|
private emitForRoom(roomId: string, isActive: boolean): void {
|
||||||
if (!this.roomIdActivityListeners[roomId]) return;
|
if (!this.roomIdActivityListeners[roomId]) return;
|
||||||
|
|
||||||
for (const fn of this.roomIdActivityListeners[roomId]) {
|
for (const fn of this.roomIdActivityListeners[roomId]) {
|
||||||
|
@ -127,7 +129,7 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setState(newState: Partial<typeof INITIAL_STATE>) {
|
private setState(newState: Partial<typeof INITIAL_STATE>): void {
|
||||||
// If values haven't changed, there's nothing to do.
|
// If values haven't changed, there's nothing to do.
|
||||||
// This only tries a shallow comparison, so unchanged objects will slip
|
// This only tries a shallow comparison, so unchanged objects will slip
|
||||||
// through, but that's probably okay for now.
|
// through, but that's probably okay for now.
|
||||||
|
@ -160,7 +162,7 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
this.__emitChange();
|
this.__emitChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __onDispatch(payload) { // eslint-disable-line @typescript-eslint/naming-convention
|
protected __onDispatch(payload): void { // eslint-disable-line @typescript-eslint/naming-convention
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
// view_room:
|
// view_room:
|
||||||
// - room_alias: '#somealias:matrix.org'
|
// - room_alias: '#somealias:matrix.org'
|
||||||
|
@ -367,7 +369,7 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private viewRoomError(payload: ViewRoomErrorPayload) {
|
private viewRoomError(payload: ViewRoomErrorPayload): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
roomId: payload.room_id,
|
roomId: payload.room_id,
|
||||||
roomAlias: payload.room_alias,
|
roomAlias: payload.room_alias,
|
||||||
|
@ -376,7 +378,7 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async joinRoom(payload: JoinRoomPayload) {
|
private async joinRoom(payload: JoinRoomPayload): Promise<void> {
|
||||||
this.setState({
|
this.setState({
|
||||||
joining: true,
|
joining: true,
|
||||||
});
|
});
|
||||||
|
@ -415,14 +417,14 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
private getInvitingUserId(roomId: string): string {
|
private getInvitingUserId(roomId: string): string {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const room = cli.getRoom(roomId);
|
const room = cli.getRoom(roomId);
|
||||||
if (room && room.getMyMembership() === "invite") {
|
if (room?.getMyMembership() === "invite") {
|
||||||
const myMember = room.getMember(cli.getUserId());
|
const myMember = room.getMember(cli.getUserId());
|
||||||
const inviteEvent = myMember ? myMember.events.member : null;
|
const inviteEvent = myMember ? myMember.events.member : null;
|
||||||
return inviteEvent && inviteEvent.getSender();
|
return inviteEvent && inviteEvent.getSender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public showJoinRoomError(err: MatrixError, roomId: string) {
|
public showJoinRoomError(err: MatrixError, roomId: string): void {
|
||||||
let description: ReactNode = err.message ? err.message : JSON.stringify(err);
|
let description: ReactNode = err.message ? err.message : JSON.stringify(err);
|
||||||
logger.log("Failed to join room:", description);
|
logger.log("Failed to join room:", description);
|
||||||
|
|
||||||
|
@ -452,7 +454,7 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private joinRoomError(payload: JoinRoomErrorPayload) {
|
private joinRoomError(payload: JoinRoomErrorPayload): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
joining: false,
|
joining: false,
|
||||||
joinError: payload.err,
|
joinError: payload.err,
|
||||||
|
@ -460,42 +462,42 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
this.showJoinRoomError(payload.err, payload.roomId);
|
this.showJoinRoomError(payload.err, payload.roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public reset() {
|
public reset(): void {
|
||||||
this.state = Object.assign({}, INITIAL_STATE);
|
this.state = Object.assign({}, INITIAL_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The room ID of the room currently being viewed
|
// The room ID of the room currently being viewed
|
||||||
public getRoomId() {
|
public getRoomId(): Optional<string> {
|
||||||
return this.state.roomId;
|
return this.state.roomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The event to scroll to when the room is first viewed
|
// The event to scroll to when the room is first viewed
|
||||||
public getInitialEventId() {
|
public getInitialEventId(): Optional<string> {
|
||||||
return this.state.initialEventId;
|
return this.state.initialEventId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether to highlight the initial event
|
// Whether to highlight the initial event
|
||||||
public isInitialEventHighlighted() {
|
public isInitialEventHighlighted(): boolean {
|
||||||
return this.state.isInitialEventHighlighted;
|
return this.state.isInitialEventHighlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether to avoid jumping to the initial event
|
// Whether to avoid jumping to the initial event
|
||||||
public initialEventScrollIntoView() {
|
public initialEventScrollIntoView(): boolean {
|
||||||
return this.state.initialEventScrollIntoView;
|
return this.state.initialEventScrollIntoView;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The room alias of the room (or null if not originally specified in view_room)
|
// The room alias of the room (or null if not originally specified in view_room)
|
||||||
public getRoomAlias() {
|
public getRoomAlias(): Optional<string> {
|
||||||
return this.state.roomAlias;
|
return this.state.roomAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether the current room is loading (true whilst resolving an alias)
|
// Whether the current room is loading (true whilst resolving an alias)
|
||||||
public isRoomLoading() {
|
public isRoomLoading(): boolean {
|
||||||
return this.state.roomLoading;
|
return this.state.roomLoading;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any error that has occurred during loading
|
// Any error that has occurred during loading
|
||||||
public getRoomLoadError() {
|
public getRoomLoadError(): Optional<MatrixError> {
|
||||||
return this.state.roomLoadError;
|
return this.state.roomLoadError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,25 +524,25 @@ export class RoomViewStore extends Store<ActionPayload> {
|
||||||
// // show join prompt
|
// // show join prompt
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
public isJoining() {
|
public isJoining(): boolean {
|
||||||
return this.state.joining;
|
return this.state.joining;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any error that has occurred during joining
|
// Any error that has occurred during joining
|
||||||
public getJoinError() {
|
public getJoinError(): Optional<Error> {
|
||||||
return this.state.joinError;
|
return this.state.joinError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The mxEvent if one is currently being replied to/quoted
|
// The mxEvent if one is currently being replied to/quoted
|
||||||
public getQuotingEvent() {
|
public getQuotingEvent(): Optional<MatrixEvent> {
|
||||||
return this.state.replyingToEvent;
|
return this.state.replyingToEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public shouldPeek() {
|
public shouldPeek(): boolean {
|
||||||
return this.state.shouldPeek;
|
return this.state.shouldPeek;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getWasContextSwitch() {
|
public getWasContextSwitch(): boolean {
|
||||||
return this.state.wasContextSwitch;
|
return this.state.wasContextSwitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -803,8 +803,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
this.updateNotificationStates(notificationStatesToUpdate);
|
this.updateNotificationStates(notificationStatesToUpdate);
|
||||||
};
|
};
|
||||||
|
|
||||||
private switchSpaceIfNeeded = () => {
|
private switchSpaceIfNeeded = (roomId = RoomViewStore.instance.getRoomId()) => {
|
||||||
const roomId = RoomViewStore.instance.getRoomId();
|
|
||||||
if (!this.isRoomInSpace(this.activeSpace, roomId) && !this.matrixClient.getRoom(roomId)?.isSpaceRoom()) {
|
if (!this.isRoomInSpace(this.activeSpace, roomId) && !this.matrixClient.getRoom(roomId)?.isSpaceRoom()) {
|
||||||
this.switchToRelatedSpace(roomId);
|
this.switchToRelatedSpace(roomId);
|
||||||
}
|
}
|
||||||
|
@ -856,7 +855,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
|
|
||||||
// if the room currently being viewed was just joined then switch to its related space
|
// if the room currently being viewed was just joined then switch to its related space
|
||||||
if (newMembership === "join" && room.roomId === RoomViewStore.instance.getRoomId()) {
|
if (newMembership === "join" && room.roomId === RoomViewStore.instance.getRoomId()) {
|
||||||
this.switchToRelatedSpace(room.roomId);
|
this.switchSpaceIfNeeded(room.roomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -1131,8 +1130,8 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
// Don't context switch when navigating to the space room
|
// Don't context switch when navigating to the space room
|
||||||
// as it will cause you to end up in the wrong room
|
// as it will cause you to end up in the wrong room
|
||||||
this.setActiveSpace(room.roomId, false);
|
this.setActiveSpace(room.roomId, false);
|
||||||
} else if (!this.isRoomInSpace(this.activeSpace, roomId)) {
|
} else {
|
||||||
this.switchToRelatedSpace(roomId);
|
this.switchSpaceIfNeeded(roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Persist last viewed room from a space
|
// Persist last viewed room from a space
|
||||||
|
|
Loading…
Reference in a new issue