From ddf10177994d6c27cd6ff27351c1570b34e2f8ae Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 16 Aug 2017 14:58:30 +0100 Subject: [PATCH] Make group invites work --- src/GroupInvite.js | 69 +++++++++++++++++++++++++ src/{Invite.js => RoomInvite.js} | 0 src/components/structures/MatrixChat.js | 2 +- src/i18n/strings/en_EN.json | 6 ++- src/utils/MultiInviter.js | 28 ++++++++-- 5 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 src/GroupInvite.js rename src/{Invite.js => RoomInvite.js} (100%) diff --git a/src/GroupInvite.js b/src/GroupInvite.js new file mode 100644 index 0000000000..e977d2fba0 --- /dev/null +++ b/src/GroupInvite.js @@ -0,0 +1,69 @@ +/* +Copyright 2017 New Vector Ltd + +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 MatrixClientPeg from './MatrixClientPeg'; +import Modal from './Modal'; +import sdk from './'; +import MultiInviter from './utils/MultiInviter'; +import { _t } from './languageHandler'; +import Promise from 'bluebird'; + +export function showGroupInviteDialog(groupId) { + const UserPickerDialog = sdk.getComponent("dialogs.UserPickerDialog"); + Modal.createTrackedDialog('Group Invite', '', UserPickerDialog, { + title: _t('Invite new group members'), + description: _t("Who would you like to add to this group?"), + placeholder: _t("Name or matrix ID"), + button: _t("Invite to Group"), + validAddressTypes: ['mx'], + onFinished: (shouldInvite, addrs) => { + if (!shouldInvite) return; + + _onGroupInviteFinished(groupId, addrs); + }, + }); +} + +function _onGroupInviteFinished(groupId, addrs) { + const multiInviter = new MultiInviter(groupId); + + const addrTexts = addrs.map((addr) => addr.address); + + multiInviter.invite(addrTexts).then((completionStates) => { + // Show user any errors + const errorList = []; + for (const addr of Object.keys(completionStates)) { + if (addrs[addr] === "error") { + errorList.push(addr); + } + } + + if (errorList.length > 0) { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to invite the following users to the group', '', ErrorDialog, { + title: _t("Failed to invite the following users to %(groupId)s:", {groupId: groupId}), + description: errorList.join(", "), + }); + } + }).catch((err) => { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createTrackedDialog('Failed to invite users to group', '', ErrorDialog, { + title: _t("Failed to invite users group"), + description: _t("Failed to invite users to %(groupId)s", {groupId: groupId}), + }); + }); +} + diff --git a/src/Invite.js b/src/RoomInvite.js similarity index 100% rename from src/Invite.js rename to src/RoomInvite.js diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 4d671d9cad..e8ac1a7f65 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -32,7 +32,7 @@ import dis from "../../dispatcher"; import Modal from "../../Modal"; import Tinter from "../../Tinter"; import sdk from '../../index'; -import { showStartChatInviteDialog, showRoomInviteDialog } from '../../Invite'; +import { showStartChatInviteDialog, showRoomInviteDialog } from '../../RoomInvite'; import * as Rooms from '../../Rooms'; import linkifyMatrix from "../../linkify-matrix"; import * as Lifecycle from '../../Lifecycle'; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3baee40a84..87ca75057c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -972,5 +972,9 @@ "Hide avatars in user and room mentions": "Hide avatars in user and room mentions", "Description": "Description", "Filter group members": "Filter group members", - "Remove from group": "Remove from group" + "Remove from group": "Remove from group", + "Invite new group members": "Invite new group members", + "Who would you like to add to this group?": "Who would you like to add to this group?", + "Name or matrix ID": "Name or matrix ID", + "Invite to Group": "Invite to Group" } diff --git a/src/utils/MultiInviter.js b/src/utils/MultiInviter.js index 1d5eac073a..e090f3d9e2 100644 --- a/src/utils/MultiInviter.js +++ b/src/utils/MultiInviter.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,16 +15,26 @@ See the License for the specific language governing permissions and limitations under the License. */ +import MatrixClientPeg from '../MatrixClientPeg'; import {getAddressType} from '../UserAddress'; -import {inviteToRoom} from '../Invite'; +import {inviteToRoom} from '../RoomInvite'; import Promise from 'bluebird'; /** - * Invites multiple addresses to a room, handling rate limiting from the server + * Invites multiple addresses to a room or group, handling rate limiting from the server */ export default class MultiInviter { - constructor(roomId) { - this.roomId = roomId; + /** + * @param {string} targetId The ID of the room or group to invite to + */ + constructor(targetId) { + if (targetId[0] === '+') { + this.roomId = null; + this.groupId = targetId; + } else { + this.roomId = targetId; + this.groupId = null; + } this.canceled = false; this.addrs = []; @@ -104,7 +115,14 @@ export default class MultiInviter { return; } - inviteToRoom(this.roomId, addr).then(() => { + let doInvite; + if (this.groupId !== null) { + doInvite = MatrixClientPeg.get().inviteUserToGroup(this.groupId, addr); + } else { + doInvite = inviteToRoom(this.roomId, addr); + } + + doInvite.then(() => { if (this._canceled) { return; } this.completionStates[addr] = 'invited';