diff --git a/res/css/_components.scss b/res/css/_components.scss
index c47222da59..4081e49630 100644
--- a/res/css/_components.scss
+++ b/res/css/_components.scss
@@ -67,6 +67,7 @@
@import "./views/dialogs/_RestoreKeyBackupDialog.scss";
@import "./views/dialogs/_RoomSettingsDialog.scss";
@import "./views/dialogs/_RoomUpgradeDialog.scss";
+@import "./views/dialogs/_RoomUpgradeWarningDialog.scss";
@import "./views/dialogs/_SetEmailDialog.scss";
@import "./views/dialogs/_SetMxIdDialog.scss";
@import "./views/dialogs/_SetPasswordDialog.scss";
diff --git a/res/css/views/dialogs/_RoomUpgradeWarningDialog.scss b/res/css/views/dialogs/_RoomUpgradeWarningDialog.scss
new file mode 100644
index 0000000000..a40c591f6c
--- /dev/null
+++ b/res/css/views/dialogs/_RoomUpgradeWarningDialog.scss
@@ -0,0 +1,29 @@
+/*
+Copyright 2019 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.mx_RoomUpgradeWarningDialog .mx_SettingsFlag {
+ .mx_ToggleSwitch {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 8px;
+ }
+
+ .mx_SettingsFlag_label {
+ display: inline-block;
+ vertical-align: middle;
+ }
+}
+
diff --git a/src/RoomInvite.js b/src/RoomInvite.js
index b2b8689174..48baad5d9f 100644
--- a/src/RoomInvite.js
+++ b/src/RoomInvite.js
@@ -153,13 +153,8 @@ function _onStartDmFinished(shouldInvite, addrs) {
}
}
-function _onRoomInviteFinished(roomId, shouldInvite, addrs) {
- if (!shouldInvite) return;
-
- const addrTexts = addrs.map((addr) => addr.address);
-
- // Invite new users to a room
- inviteMultipleToRoom(roomId, addrTexts).then((result) => {
+export function inviteUsersToRoom(roomId, userIds) {
+ return inviteMultipleToRoom(roomId, userIds).then((result) => {
const room = MatrixClientPeg.get().getRoom(roomId);
return _showAnyInviteErrors(result.states, room, result.inviter);
}).catch((err) => {
@@ -172,6 +167,15 @@ function _onRoomInviteFinished(roomId, shouldInvite, addrs) {
});
}
+function _onRoomInviteFinished(roomId, shouldInvite, addrs) {
+ if (!shouldInvite) return;
+
+ const addrTexts = addrs.map((addr) => addr.address);
+
+ // Invite new users to a room
+ inviteUsersToRoom(roomId, addrTexts);
+}
+
// TODO: Immutable DMs replaces this
function _isDmChat(addrTexts) {
if (addrTexts.length === 1 && getAddressType(addrTexts[0]) === 'mx-user-id') {
diff --git a/src/SlashCommands.js b/src/SlashCommands.js
index 31e7ca4f39..b488fa821b 100644
--- a/src/SlashCommands.js
+++ b/src/SlashCommands.js
@@ -32,6 +32,7 @@ import { getAddressType } from './UserAddress';
import { abbreviateUrl } from './utils/UrlUtils';
import { getDefaultIdentityServerUrl, useDefaultIdentityServer } from './utils/IdentityServerUtils';
import {isPermalinkHost, parsePermalink} from "./utils/permalinks/Permalinks";
+import {inviteUsersToRoom} from "./RoomInvite";
const singleMxcUpload = async () => {
return new Promise((resolve) => {
@@ -154,70 +155,57 @@ export const CommandMap = {
return reject(_t("You do not have the required permissions to use this command."));
}
+ const RoomUpgradeWarningDialog = sdk.getComponent("dialogs.RoomUpgradeWarningDialog");
+
const {finished} = Modal.createTrackedDialog('Slash Commands', 'upgrade room confirmation',
- QuestionDialog, {
- title: _t('Room upgrade confirmation'),
- description: (
-
-
{_t("Upgrading a room can be destructive and isn't always necessary.")}
-
- {_t(
- "Room upgrades are usually recommended when a room version is considered " +
- "unstable. Unstable room versions might have bugs, missing features, or " +
- "security vulnerabilities.",
- {}, {
- "i": (sub) => {sub},
- },
- )}
-
-
- {_t(
- "Room upgrades usually only affect server-side processing of the " +
- "room. If you're having problems with your Riot client, please file an issue " +
- "with .",
- {}, {
- "i": (sub) => {sub},
- "issueLink": () => {
- return
- https://github.com/vector-im/riot-web/issues/new/choose
- ;
- },
- },
- )}
-
-
- {_t(
- "Warning: Upgrading a room will not automatically migrate room " +
- "members to the new version of the room. We'll post a link to the new room " +
- "in the old version of the room - room members will have to click this link to " +
- "join the new room.",
- {}, {
- "b": (sub) => {sub},
- "i": (sub) => {sub},
- },
- )}
-
-
- {_t(
- "Please confirm that you'd like to go forward with upgrading this room " +
- "from to .",
- {},
- {
- oldVersion: () => {room ? room.getVersion() : "1"}
,
- newVersion: () => {args}
,
- },
- )}
-
-
- ),
- button: _t("Upgrade"),
- });
+ RoomUpgradeWarningDialog, {roomId: roomId, targetVersion: args});
- return success(finished.then(([confirm]) => {
- if (!confirm) return;
+ return success(finished.then(async ([resp]) => {
+ if (!resp.continue) return;
- return cli.upgradeRoom(roomId, args);
+ let checkForUpgradeFn;
+ try {
+ const upgradePromise = cli.upgradeRoom(roomId, args);
+
+ // We have to wait for the js-sdk to give us the room back so
+ // we can more effectively abuse the MultiInviter behaviour
+ // which heavily relies on the Room object being available.
+ if (resp.invite) {
+ checkForUpgradeFn = async (newRoom) => {
+ // The upgradePromise should be done by the time we await it here.
+ const {replacement_room: newRoomId} = await upgradePromise;
+ if (newRoom.roomId !== newRoomId) return;
+
+ const toInvite = [
+ ...room.getMembersWithMembership("join"),
+ ...room.getMembersWithMembership("invite"),
+ ].map(m => m.userId).filter(m => m !== cli.getUserId());
+
+ if (toInvite.length > 0) {
+ // Errors are handled internally to this function
+ await inviteUsersToRoom(newRoomId, toInvite);
+ }
+
+ cli.removeListener('Room', checkForUpgradeFn);
+ };
+ cli.on('Room', checkForUpgradeFn);
+ }
+
+ // We have to await after so that the checkForUpgradesFn has a proper reference
+ // to the new room's ID.
+ await upgradePromise;
+ } catch (e) {
+ console.error(e);
+
+ if (checkForUpgradeFn) cli.removeListener('Room', checkForUpgradeFn);
+
+ const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
+ Modal.createTrackedDialog('Slash Commands', 'room upgrade error', ErrorDialog, {
+ title: _t('Error upgrading room'),
+ description: _t(
+ 'Double check that your server supports the room version chosen and try again.'),
+ });
+ }
}));
}
return reject(this.getUsage());
diff --git a/src/components/views/dialogs/RoomUpgradeWarningDialog.js b/src/components/views/dialogs/RoomUpgradeWarningDialog.js
new file mode 100644
index 0000000000..3a243a2d93
--- /dev/null
+++ b/src/components/views/dialogs/RoomUpgradeWarningDialog.js
@@ -0,0 +1,136 @@
+/*
+Copyright 2019 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from 'react';
+import PropTypes from 'prop-types';
+import {_t} from "../../../languageHandler";
+import sdk from "../../../index";
+import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
+import MatrixClientPeg from "../../../MatrixClientPeg";
+
+export default class RoomUpgradeWarningDialog extends React.Component {
+ static propTypes = {
+ onFinished: PropTypes.func.isRequired,
+ roomId: PropTypes.string.isRequired,
+ targetVersion: PropTypes.string.isRequired,
+ };
+
+ constructor(props) {
+ super(props);
+
+ const room = MatrixClientPeg.get().getRoom(this.props.roomId);
+ const joinRules = room ? room.currentState.getStateEvents("m.room.join_rules", "") : null;
+ const isPrivate = joinRules ? joinRules.getContent()['join_rule'] !== 'public' : true;
+ this.state = {
+ currentVersion: room ? room.getVersion() : "1",
+ isPrivate,
+ inviteUsersToNewRoom: true,
+ };
+ }
+
+ _onContinue = () => {
+ this.props.onFinished({continue: true, invite: this.state.isPrivate && this.state.inviteUsersToNewRoom});
+ };
+
+ _onCancel = () => {
+ this.props.onFinished({continue: false, invite: false});
+ };
+
+ _onInviteUsersToggle = (newVal) => {
+ this.setState({inviteUsersToNewRoom: newVal});
+ };
+
+ render() {
+ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
+ const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
+
+ let inviteToggle = null;
+ if (this.state.isPrivate) {
+ inviteToggle = (
+
+ );
+ }
+
+ return (
+
+
+
{_t("Upgrading a room can be destructive and isn't always necessary.")}
+
+ {_t(
+ "Room upgrades are usually recommended when a room version is considered " +
+ "unstable. Unstable room versions might have bugs, missing features, or " +
+ "security vulnerabilities.",
+ {}, {
+ "i": (sub) => {sub},
+ },
+ )}
+
+
+ {_t(
+ "Room upgrades usually only affect server-side processing of the " +
+ "room. If you're having problems with your Riot client, please file an issue " +
+ "with .",
+ {}, {
+ "i": (sub) => {sub},
+ "issueLink": () => {
+ return
+ https://github.com/vector-im/riot-web/issues/new/choose
+ ;
+ },
+ },
+ )}
+
+
+ {_t(
+ "Warning: Upgrading a room will not automatically migrate room " +
+ "members to the new version of the room. We'll post a link to the new room " +
+ "in the old version of the room - room members will have to click this link to " +
+ "join the new room.",
+ {}, {
+ "b": (sub) => {sub},
+ "i": (sub) => {sub},
+ },
+ )}
+
+
+ {_t(
+ "Please confirm that you'd like to go forward with upgrading this room " +
+ "from to .",
+ {},
+ {
+ oldVersion: () => {this.state.currentVersion}
,
+ newVersion: () => {this.props.targetVersion}
,
+ },
+ )}
+
+ {inviteToggle}
+
+
+
+ );
+ }
+}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 4b3feb96ab..bacd15a275 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -154,13 +154,8 @@
"To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.",
"Upgrades a room to a new version": "Upgrades a room to a new version",
"You do not have the required permissions to use this command.": "You do not have the required permissions to use this command.",
- "Room upgrade confirmation": "Room upgrade confirmation",
- "Upgrading a room can be destructive and isn't always necessary.": "Upgrading a room can be destructive and isn't always necessary.",
- "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.",
- "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .": "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .",
- "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.",
- "Please confirm that you'd like to go forward with upgrading this room from to .": "Please confirm that you'd like to go forward with upgrading this room from to .",
- "Upgrade": "Upgrade",
+ "Error upgrading room": "Error upgrading room",
+ "Double check that your server supports the room version chosen and try again.": "Double check that your server supports the room version chosen and try again.",
"Changes your display nickname": "Changes your display nickname",
"Changes your display nickname in the current room only": "Changes your display nickname in the current room only",
"Changes the avatar of the current room": "Changes the avatar of the current room",
@@ -720,6 +715,7 @@
"Camera": "Camera",
"Voice & Video": "Voice & Video",
"This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers",
+ "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.",
"Upgrade this room to the recommended room version": "Upgrade this room to the recommended room version",
"this room": "this room",
"View older messages in %(roomName)s.": "View older messages in %(roomName)s.",
@@ -1435,6 +1431,12 @@
"Update any local room aliases to point to the new room": "Update any local room aliases to point to the new room",
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Stop users from speaking in the old version of the room, and post a message advising users to move to the new room",
"Put a link back to the old room at the start of the new room so people can see old messages": "Put a link back to the old room at the start of the new room so people can see old messages",
+ "Invite joined members to the new room automatically": "Invite joined members to the new room automatically",
+ "Room upgrade confirmation": "Room upgrade confirmation",
+ "Upgrading a room can be destructive and isn't always necessary.": "Upgrading a room can be destructive and isn't always necessary.",
+ "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered unstable. Unstable room versions might have bugs, missing features, or security vulnerabilities.",
+ "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .": "Room upgrades usually only affect server-side processing of the room. If you're having problems with your Riot client, please file an issue with .",
+ "Please confirm that you'd like to go forward with upgrading this room from to .": "Please confirm that you'd like to go forward with upgrading this room from to .",
"Sign out and remove encryption keys?": "Sign out and remove encryption keys?",
"Clear Storage and Sign Out": "Clear Storage and Sign Out",
"Send Logs": "Send Logs",
diff --git a/src/utils/MultiInviter.js b/src/utils/MultiInviter.js
index 8b952a2b5b..887d829d76 100644
--- a/src/utils/MultiInviter.js
+++ b/src/utils/MultiInviter.js
@@ -154,6 +154,8 @@ export default class MultiInviter {
return;
}
+ console.error(err);
+
let errorText;
let fatal = false;
if (err.errcode === 'M_FORBIDDEN') {