Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 8d73ea2

Browse files
t3chguydbkr
authored andcommitted
Fix right panel soft crashes due to missing room prop (#7923)
1 parent bf2bb26 commit 8d73ea2

File tree

6 files changed

+29
-39
lines changed

6 files changed

+29
-39
lines changed

res/css/structures/_GroupView.scss

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
display: flex;
1919
flex-direction: column;
2020
overflow: hidden;
21+
flex-grow: 1;
2122
}
2223

2324
.mx_GroupView_error {

src/components/structures/MatrixChat.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
975975
this.viewWelcome();
976976
return;
977977
}
978-
if (!this.state.currentGroupId && !this.state.currentRoomId) {
978+
if (!this.state.currentGroupId && !this.state.currentRoomId && !this.state.currentUserId) {
979979
this.viewHome();
980980
}
981981
}

src/components/structures/RightPanel.tsx

+19-10
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,23 @@ export default class RightPanel extends React.Component<IProps, IState> {
9494
}
9595

9696
public static getDerivedStateFromProps(props: IProps): Partial<IState> {
97-
const currentCard = RightPanelStore.instance.currentCardForRoom(props.room.roomId);
97+
let currentCard: IRightPanelCard;
98+
if (props.room) {
99+
currentCard = RightPanelStore.instance.currentCardForRoom(props.room.roomId);
100+
}
101+
if (props.groupId) {
102+
currentCard = RightPanelStore.instance.currentGroup;
103+
}
104+
105+
if (currentCard?.phase && !RightPanelStore.instance.isPhaseValid(currentCard.phase, !!props.room)) {
106+
// XXX: We can probably get rid of this workaround once GroupView is dead, it's unmounting happens weirdly
107+
// late causing the app to soft-crash due to lack of a room object being passed to a RightPanel
108+
return null; // skip this update, we're about to be unmounted and don't have the appropriate props
109+
}
110+
98111
return {
99-
cardState: currentCard.state,
100-
phase: currentCard.phase,
112+
cardState: currentCard?.state,
113+
phase: currentCard?.phase,
101114
};
102115
}
103116

@@ -118,11 +131,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
118131
};
119132

120133
private onRightPanelStoreUpdate = () => {
121-
const currentCard = RightPanelStore.instance.currentCardForRoom(this.props.room.roomId);
122-
this.setState({
123-
cardState: currentCard.state,
124-
phase: currentCard.phase,
125-
});
134+
this.setState({ ...RightPanel.getDerivedStateFromProps(this.props) as IState });
126135
};
127136

128137
private onClose = () => {
@@ -139,7 +148,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
139148
});
140149
} else if (
141150
this.state.phase === RightPanelPhases.EncryptionPanel &&
142-
this.state.cardState.verificationRequest && this.state.cardState.verificationRequest.pending
151+
this.state.cardState.verificationRequest?.pending
143152
) {
144153
// When the user clicks close on the encryption panel cancel the pending request first if any
145154
this.state.cardState.verificationRequest.cancel();
@@ -154,7 +163,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
154163

155164
public render(): JSX.Element {
156165
let card = <div />;
157-
const roomId = this.props.room ? this.props.room.roomId : undefined;
166+
const roomId = this.props.room?.roomId;
158167
const phase = this.props.overwriteCard?.phase ?? this.state.phase;
159168
const cardState = this.props.overwriteCard?.state ?? this.state.cardState;
160169
switch (phase) {

src/components/structures/ThreadView.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
9494

9595
public componentWillUnmount(): void {
9696
this.teardownThread();
97-
dis.unregister(this.dispatcherRef);
97+
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
9898
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
9999
room.removeListener(ThreadEvent.New, this.onNewThread);
100100
SettingsStore.unwatchSetting(this.layoutWatcherRef);

src/stores/right-panel/RightPanelStore.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export default class RightPanelStore extends ReadyWatchingStore {
155155
const cardState = redirect?.state ?? (Object.keys(card.state ?? {}).length === 0 ? null : card.state);
156156

157157
// Checks for wrong SetRightPanelPhase requests
158-
if (!this.isPhaseActionValid(targetPhase)) return;
158+
if (!this.isPhaseValid(targetPhase)) return;
159159

160160
if ((targetPhase === this.currentCardForRoom(rId)?.phase && !!cardState)) {
161161
// Update state: set right panel with a new state but keep the phase (dont know it this is ever needed...)
@@ -194,16 +194,16 @@ export default class RightPanelStore extends ReadyWatchingStore {
194194
const pState = redirect?.state ?? (Object.keys(card.state ?? {}).length === 0 ? null : card.state);
195195

196196
// Checks for wrong SetRightPanelPhase requests
197-
if (!this.isPhaseActionValid(targetPhase)) return;
197+
if (!this.isPhaseValid(targetPhase)) return;
198198

199-
let roomCache = this.byRoom[rId];
199+
const roomCache = this.byRoom[rId];
200200
if (!!roomCache) {
201201
// append new phase
202202
roomCache.history.push({ state: pState, phase: targetPhase });
203203
roomCache.isOpen = allowClose ? roomCache.isOpen : true;
204204
} else {
205205
// setup room panel cache with the new card
206-
roomCache = {
206+
this.byRoom[rId] = {
207207
history: [{ phase: targetPhase, state: pState ?? {} }],
208208
// if there was no right panel store object the the panel was closed -> keep it closed, except if allowClose==false
209209
isOpen: !allowClose,
@@ -344,18 +344,18 @@ export default class RightPanelStore extends ReadyWatchingStore {
344344
return null;
345345
}
346346

347-
private isPhaseActionValid(targetPhase) {
347+
public isPhaseValid(targetPhase: RightPanelPhases, isViewingRoom = this.isViewingRoom): boolean {
348348
if (!RightPanelPhases[targetPhase]) {
349349
logger.warn(`Tried to switch right panel to unknown phase: ${targetPhase}`);
350350
return false;
351351
}
352-
if (GROUP_PHASES.includes(targetPhase) && this.isViewingRoom) {
352+
if (GROUP_PHASES.includes(targetPhase) && isViewingRoom) {
353353
logger.warn(
354354
`Tried to switch right panel to a group phase: ${targetPhase}, ` +
355355
`but we are currently not viewing a group`,
356356
);
357357
return false;
358-
} else if (!GROUP_PHASES.includes(targetPhase) && !this.isViewingRoom) {
358+
} else if (!GROUP_PHASES.includes(targetPhase) && !isViewingRoom) {
359359
logger.warn(
360360
`Tried to switch right panel to a room phase: ${targetPhase}, ` +
361361
`but we are currently not viewing a room`,

src/stores/right-panel/RightPanelStorePhases.ts

-20
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,3 @@ export function backLabelForPhase(phase: RightPanelPhases) {
5656
}
5757
return null;
5858
}
59-
60-
// These are the phases that are safe to persist (the ones that don't require additional
61-
// arguments).
62-
export const RIGHT_PANEL_PHASES_NO_ARGS = [
63-
RightPanelPhases.RoomSummary,
64-
RightPanelPhases.NotificationPanel,
65-
RightPanelPhases.PinnedMessages,
66-
RightPanelPhases.FilePanel,
67-
RightPanelPhases.RoomMemberList,
68-
RightPanelPhases.GroupMemberList,
69-
RightPanelPhases.GroupRoomList,
70-
RightPanelPhases.Timeline,
71-
];
72-
73-
// Subset of phases visible in the Space View
74-
export const RIGHT_PANEL_SPACE_PHASES = [
75-
RightPanelPhases.SpaceMemberList,
76-
RightPanelPhases.Space3pidMemberInfo,
77-
RightPanelPhases.SpaceMemberInfo,
78-
];

0 commit comments

Comments
 (0)