From f54f03b8b8703a186ca483fe0b08d90232e084c8 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 20 Mar 2022 12:58:24 +0000 Subject: [PATCH] don't restore MemberInfo from RightPanel history when viewing a room As bringing up a specific MemberInfo when you view a room is freaky, even if it happened to be the last thing you were doing in that room. Fixes https://github.com/vector-im/element-web/issues/21487 --- src/components/structures/RightPanel.tsx | 22 +++++++++++++++++++ src/stores/right-panel/RightPanelStore.ts | 6 ++++- .../right-panel/RightPanelStoreIPanelState.ts | 6 +++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 65cddbd2253..d129d2ff53a 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -84,6 +84,14 @@ export default class RightPanel extends React.Component { public componentDidMount(): void { this.context.on(RoomStateEvent.Members, this.onRoomStateMember); RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate); + + if (this.props.room?.roomId) { + // skip cards which are not to be restored from history + // (i.e. memberinfo cards which have already been viewed) + while (RightPanelStore.instance.currentCardForRoom(this.props.room.roomId)?.state.skipFromHistory) { + RightPanelStore.instance.popCard(); + } + } } public componentWillUnmount(): void { @@ -91,6 +99,15 @@ export default class RightPanel extends React.Component { RightPanelStore.instance.off(UPDATE_EVENT, this.onRightPanelStoreUpdate); } + private static skipHistory(card: IRightPanelCard): boolean { + // determines phases whose history should not be persisted per-room + // so we don't find ourselves being teleported into random old MemberInfo + // views when viewing a given room. + // See https://github.com/vector-im/element-web/issues/21487 + return (card.phase === RightPanelPhases.RoomMemberInfo || + card.phase === RightPanelPhases.Room3pidMemberInfo); + } + public static getDerivedStateFromProps(props: IProps): Partial { let currentCard: IRightPanelCard; if (props.room) { @@ -100,6 +117,11 @@ export default class RightPanel extends React.Component { currentCard = RightPanelStore.instance.currentGroup; } + if (RightPanel.skipHistory(currentCard)) { + // having displayed this card, don't restore this card from history in future + RightPanelStore.instance.skipHistoryForCard(currentCard); + } + if (currentCard?.phase && !RightPanelStore.instance.isPhaseValid(currentCard.phase, !!props.room)) { // XXX: We can probably get rid of this workaround once GroupView is dead, it's unmounting happens weirdly // late causing the app to soft-crash due to lack of a room object being passed to a RightPanel diff --git a/src/stores/right-panel/RightPanelStore.ts b/src/stores/right-panel/RightPanelStore.ts index 3ea50ec0bb3..4adc15b2553 100644 --- a/src/stores/right-panel/RightPanelStore.ts +++ b/src/stores/right-panel/RightPanelStore.ts @@ -159,7 +159,7 @@ export default class RightPanelStore extends ReadyWatchingStore { if (!this.isPhaseValid(targetPhase)) return; if ((targetPhase === this.currentCardForRoom(rId)?.phase && !!cardState)) { - // Update state: set right panel with a new state but keep the phase (dont know it this is ever needed...) + // Update state: set right panel with a new state but keep the phase (don't know it this is ever needed...) const hist = this.byRoom[rId]?.history ?? []; hist[hist.length - 1].state = cardState; this.emitAndUpdateSettings(); @@ -214,6 +214,10 @@ export default class RightPanelStore extends ReadyWatchingStore { this.emitAndUpdateSettings(); } + public skipHistoryForCard(card: IRightPanelCard) { + card.state.skipFromHistory = true; + } + public popCard(roomId: string = null) { const rId = roomId ?? this.viewedRoomId; if (!this.byRoom[rId]) return; diff --git a/src/stores/right-panel/RightPanelStoreIPanelState.ts b/src/stores/right-panel/RightPanelStoreIPanelState.ts index 34fecf018d3..877cf1e3f44 100644 --- a/src/stores/right-panel/RightPanelStoreIPanelState.ts +++ b/src/stores/right-panel/RightPanelStoreIPanelState.ts @@ -38,6 +38,8 @@ export interface IRightPanelCardState { threadHeadEvent?: MatrixEvent; initialEvent?: MatrixEvent; isInitialEventHighlighted?: boolean; + // should this card be skipped when switching to a room? + skipFromHistory?: boolean; } export interface IRightPanelCardStateStored { @@ -54,6 +56,8 @@ export interface IRightPanelCardStateStored { threadHeadEventId?: string; initialEventId?: string; isInitialEventHighlighted?: boolean; + // should this card be skipped when switching to a room? + skipFromHistory?: boolean; } export interface IRightPanelCard { @@ -104,6 +108,7 @@ export function convertCardToStore(panelState: IRightPanelCard): IRightPanelCard panelState.state.initialEvent.getId() : undefined, memberId: !!state?.member?.userId ? panelState.state.member.userId : undefined, + skipFromHistory: state.skipFromHistory, }; return { state: stateStored, phase: panelState.phase }; @@ -125,6 +130,7 @@ function convertStoreToCard(panelStateStore: IRightPanelCardStored, room: Room): room.findEventById(stateStored.initialEventId) : undefined, member: !!stateStored?.memberId ? room.getMember(stateStored.memberId) : undefined, + skipFromHistory: stateStored.skipFromHistory, }; return { state: state, phase: panelStateStore.phase };