Merge pull request #3684 from matrix-org/travis/auto-invite-upgrades

Add an option to invite users to upgraded private rooms
pull/21833/head
Travis Ralston 2019-12-02 17:03:25 -07:00 committed by GitHub
commit 4d5f133b17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 237 additions and 75 deletions

View File

@ -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";

View File

@ -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;
}
}

View File

@ -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') {

View File

@ -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: (
<div>
<p>{_t("Upgrading a room can be destructive and isn't always necessary.")}</p>
<p>
{_t(
"Room upgrades are usually recommended when a room version is considered " +
"<i>unstable</i>. Unstable room versions might have bugs, missing features, or " +
"security vulnerabilities.",
{}, {
"i": (sub) => <i>{sub}</i>,
},
)}
</p>
<p>
{_t(
"Room upgrades usually only affect <i>server-side</i> processing of the " +
"room. If you're having problems with your Riot client, please file an issue " +
"with <issueLink />.",
{}, {
"i": (sub) => <i>{sub}</i>,
"issueLink": () => {
return <a href="https://github.com/vector-im/riot-web/issues/new/choose"
target="_blank" rel="noopener">
https://github.com/vector-im/riot-web/issues/new/choose
</a>;
},
},
)}
</p>
<p>
{_t(
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room " +
"members to the new version of the room.</i> 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) => <b>{sub}</b>,
"i": (sub) => <i>{sub}</i>,
},
)}
</p>
<p>
{_t(
"Please confirm that you'd like to go forward with upgrading this room " +
"from <oldVersion /> to <newVersion />.",
{},
{
oldVersion: () => <code>{room ? room.getVersion() : "1"}</code>,
newVersion: () => <code>{args}</code>,
},
)}
</p>
</div>
),
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());

View File

@ -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 = (
<LabelledToggleSwitch
value={this.state.inviteUsersToNewRoom} toggleInFront={true}
onChange={this._onInviteUsersToggle}
label={_t("Invite joined members to the new room automatically")} />
);
}
return (
<BaseDialog className='mx_RoomUpgradeWarningDialog' hasCancel={true}
onFinished={this.props.onFinished}
title={_t("Room upgrade confirmation")}>
<div>
<p>{_t("Upgrading a room can be destructive and isn't always necessary.")}</p>
<p>
{_t(
"Room upgrades are usually recommended when a room version is considered " +
"<i>unstable</i>. Unstable room versions might have bugs, missing features, or " +
"security vulnerabilities.",
{}, {
"i": (sub) => <i>{sub}</i>,
},
)}
</p>
<p>
{_t(
"Room upgrades usually only affect <i>server-side</i> processing of the " +
"room. If you're having problems with your Riot client, please file an issue " +
"with <issueLink />.",
{}, {
"i": (sub) => <i>{sub}</i>,
"issueLink": () => {
return <a href="https://github.com/vector-im/riot-web/issues/new/choose"
target="_blank" rel="noopener">
https://github.com/vector-im/riot-web/issues/new/choose
</a>;
},
},
)}
</p>
<p>
{_t(
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room " +
"members to the new version of the room.</i> 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) => <b>{sub}</b>,
"i": (sub) => <i>{sub}</i>,
},
)}
</p>
<p>
{_t(
"Please confirm that you'd like to go forward with upgrading this room " +
"from <oldVersion /> to <newVersion />.",
{},
{
oldVersion: () => <code>{this.state.currentVersion}</code>,
newVersion: () => <code>{this.props.targetVersion}</code>,
},
)}
</p>
{inviteToggle}
</div>
<DialogButtons
primaryButton={_t("Continue")}
onPrimaryButtonClick={this._onContinue}
cancelButton={_t("Cancel")}
onCancel={this._onCancel}
/>
</BaseDialog>
);
}
}

View File

@ -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 <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.",
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.",
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> 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>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> 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 <oldVersion /> to <newVersion />.": "Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.",
"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",
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> 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>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> 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 <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.",
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.",
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.",
"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",

View File

@ -154,6 +154,8 @@ export default class MultiInviter {
return;
}
console.error(err);
let errorText;
let fatal = false;
if (err.errcode === 'M_FORBIDDEN') {