Run all room leaving behaviour through a single function

Fixes https://github.com/vector-im/element-web/issues/14999
Fixes https://github.com/vector-im/element-web/issues/10380

We were failing to handle errors when `/part`ing a room, though the leave room button was fine. This runs both the button and command through the same function for handling, including the 'view next room' behaviour.
This commit is contained in:
Travis Ralston 2020-08-19 19:21:40 -06:00
parent c9d98a1d19
commit e0b8343088
4 changed files with 78 additions and 49 deletions

View file

@ -15,6 +15,13 @@ limitations under the License.
*/
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { _t } from "../languageHandler";
import Modal from "../Modal";
import ErrorDialog from "../components/views/dialogs/ErrorDialog";
import React from "react";
import dis from "../dispatcher/dispatcher";
import RoomViewStore from "../stores/RoomViewStore";
/**
* Approximation of a membership status for a given room.
@ -70,3 +77,64 @@ export function getEffectiveMembership(membership: string): EffectiveMembership
return EffectiveMembership.Leave;
}
}
export async function leaveRoomBehaviour(roomId: string): Promise<boolean> {
let leavingAllVersions = true;
const history = await MatrixClientPeg.get().getRoomUpgradeHistory(roomId);
if (history && history.length > 0) {
const currentRoom = history[history.length - 1];
if (currentRoom.roomId !== roomId) {
// The user is trying to leave an older version of the room. Let them through
// without making them leave the current version of the room.
leavingAllVersions = false;
}
}
let results: { [roomId: string]: Error & { errcode: string, message: string } } = {};
if (!leavingAllVersions || true) {
try {
await MatrixClientPeg.get().leave(roomId);
} catch (e) {
if (e && e.data && e.data.errcode) {
const message = e.data.error || _t("Unexpected server error trying to leave the room");
results[roomId] = Object.assign(new Error(message), {errcode: e.data.errcode});
} else {
results[roomId] = e || new Error("Failed to leave room for unknown causes");
}
}
} else {
results = await MatrixClientPeg.get().leaveRoomChain(roomId);
}
const errors = Object.entries(results).filter(r => !!r[1]);
if (errors.length > 0) {
let messages = [];
for (const err of errors) {
let message = _t("Unexpected server error trying to leave the room");
if (results[roomId].errcode && results[roomId].message) {
if (results[roomId].errcode === 'M_CANNOT_LEAVE_SERVER_NOTICE_ROOM') {
Modal.createTrackedDialog('Error Leaving Room', '', ErrorDialog, {
title: _t("Can't leave Server Notices room"),
description: _t(
"This room is used for important messages from the Homeserver, " +
"so you cannot leave it.",
),
});
return false;
}
message = results[roomId].message;
}
messages.push(message, React.createElement('BR')); // createElement to avoid using a tsx file in utils
}
Modal.createTrackedDialog('Error Leaving Room', '', ErrorDialog, {
title: _t("Error leaving room"),
description: messages,
});
return false;
}
if (RoomViewStore.getRoomId() === roomId) {
dis.dispatch({action: 'view_next_room'});
}
return true;
}