Fix various races that prevented the right panel being in the right state for verifications

Fixes https://github.com/vector-im/riot-web/issues/11989
pull/21833/head
David Baker 2020-01-29 16:56:12 +00:00
parent d8ca9d0f13
commit e403169e13
2 changed files with 22 additions and 2 deletions

View File

@ -48,6 +48,7 @@ export default class RightPanel extends React.Component {
phase: this._getPhaseFromProps(), phase: this._getPhaseFromProps(),
isUserPrivilegedInGroup: null, isUserPrivilegedInGroup: null,
member: this._getUserForPanel(), member: this._getUserForPanel(),
verificationRequest: RightPanelStore.getSharedInstance().roomPanelPhaseParams.verificationRequest,
}; };
this.onAction = this.onAction.bind(this); this.onAction = this.onAction.bind(this);
this.onRoomStateMember = this.onRoomStateMember.bind(this); this.onRoomStateMember = this.onRoomStateMember.bind(this);
@ -68,15 +69,34 @@ export default class RightPanel extends React.Component {
return this.props.user || lastParams['member']; return this.props.user || lastParams['member'];
} }
// gets the current phase from the props and also maybe the store
_getPhaseFromProps() { _getPhaseFromProps() {
const rps = RightPanelStore.getSharedInstance(); const rps = RightPanelStore.getSharedInstance();
const userForPanel = this._getUserForPanel();
if (this.props.groupId) { if (this.props.groupId) {
if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.groupPanelPhase)) { if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.groupPanelPhase)) {
dis.dispatch({action: "set_right_panel_phase", phase: RIGHT_PANEL_PHASES.GroupMemberList}); dis.dispatch({action: "set_right_panel_phase", phase: RIGHT_PANEL_PHASES.GroupMemberList});
return RIGHT_PANEL_PHASES.GroupMemberList; return RIGHT_PANEL_PHASES.GroupMemberList;
} }
return rps.groupPanelPhase; return rps.groupPanelPhase;
} else if (this._getUserForPanel()) { } else if (userForPanel) {
// XXX FIXME AAAAAARGH: What is going on with this class!? It takes some of its state
// from its props and some from a store, expect if the contents of the store changes
// while it's mounted in which case it replaces all of its state with that of the store,
// expect it uses a dispatch instead of a normal store listener?
// Unfortunately rewriting this would almost certainly break showing the right panel
// in some of the many cases, and I don't have time to re-architect it and test all
// the flows now, so adding yet another special case so if the store thinks there is
// a verification going on for the member we're displaying, we show that, otherwise
// we race if a verification is started while the panel isn't displayed because we're
// not mounted in time to get the dispatch.
// Until then, let this code serve as a warning from history.
if (
userForPanel.userId === rps.roomPanelPhaseParams.member.userId &&
rps.roomPanelPhaseParams.verificationRequest
) {
return rps.roomPanelPhase;
}
return RIGHT_PANEL_PHASES.RoomMemberInfo; return RIGHT_PANEL_PHASES.RoomMemberInfo;
} else { } else {
if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.roomPanelPhase)) { if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.roomPanelPhase)) {

View File

@ -36,7 +36,7 @@ const EncryptionPanel = ({verificationRequest, member, onClose}) => {
setRequest(verificationRequest); setRequest(verificationRequest);
}, [verificationRequest]); }, [verificationRequest]);
const [phase, setPhase] = useState(undefined); const [phase, setPhase] = useState(request.phase);
const changeHandler = useCallback(() => { const changeHandler = useCallback(() => {
// handle transitions -> cancelled for mismatches which fire a modal instead of showing a card // handle transitions -> cancelled for mismatches which fire a modal instead of showing a card
if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) { if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) {