Add an invite users to community step to dialog flow
This commit is contained in:
parent
7c1a9993e3
commit
56c7f86983
7 changed files with 371 additions and 11 deletions
|
@ -72,6 +72,7 @@
|
||||||
@import "./views/dialogs/_KeyboardShortcutsDialog.scss";
|
@import "./views/dialogs/_KeyboardShortcutsDialog.scss";
|
||||||
@import "./views/dialogs/_MessageEditHistoryDialog.scss";
|
@import "./views/dialogs/_MessageEditHistoryDialog.scss";
|
||||||
@import "./views/dialogs/_NewSessionReviewDialog.scss";
|
@import "./views/dialogs/_NewSessionReviewDialog.scss";
|
||||||
|
@import "./views/dialogs/_PrototypeCommunityInviteDialog.scss";
|
||||||
@import "./views/dialogs/_PrototypeCreateGroupDialog.scss";
|
@import "./views/dialogs/_PrototypeCreateGroupDialog.scss";
|
||||||
@import "./views/dialogs/_RoomSettingsDialog.scss";
|
@import "./views/dialogs/_RoomSettingsDialog.scss";
|
||||||
@import "./views/dialogs/_RoomSettingsDialogBridges.scss";
|
@import "./views/dialogs/_RoomSettingsDialogBridges.scss";
|
||||||
|
|
88
res/css/views/dialogs/_PrototypeCommunityInviteDialog.scss
Normal file
88
res/css/views/dialogs/_PrototypeCommunityInviteDialog.scss
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 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_PrototypeCommunityInviteDialog {
|
||||||
|
&.mx_Dialog_fixedWidth {
|
||||||
|
width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_Dialog_content {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
.mx_PrototypeCommunityInviteDialog_people {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
|
||||||
|
.mx_AccessibleButton {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: $focus-bg-color; // XXX: Abuse of variables
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 3px 5px;
|
||||||
|
font-size: $font-12px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_PrototypeCommunityInviteDialog_morePeople {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_PrototypeCommunityInviteDialog_person {
|
||||||
|
position: relative;
|
||||||
|
margin-top: 4px;
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_Checkbox {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: calc(50% - 8px); // checkbox is 16px high
|
||||||
|
width: 16px; // to force a square
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_PrototypeCommunityInviteDialog_personIdentifiers {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_PrototypeCommunityInviteDialog_personName {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: $font-14px;
|
||||||
|
color: $primary-fg-color;
|
||||||
|
margin-left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_PrototypeCommunityInviteDialog_personId {
|
||||||
|
font-size: $font-12px;
|
||||||
|
color: $muted-fg-color;
|
||||||
|
margin-left: 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_PrototypeCommunityInviteDialog_primaryButton {
|
||||||
|
display: block;
|
||||||
|
font-size: $font-13px;
|
||||||
|
line-height: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import Modal from './Modal';
|
||||||
import * as sdk from './';
|
import * as sdk from './';
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
import {KIND_DM, KIND_INVITE} from "./components/views/dialogs/InviteDialog";
|
import {KIND_DM, KIND_INVITE} from "./components/views/dialogs/InviteDialog";
|
||||||
|
import PrototypeCommunityInviteDialog from "./components/views/dialogs/PrototypeCommunityInviteDialog";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invites multiple addresses to a room
|
* Invites multiple addresses to a room
|
||||||
|
@ -56,6 +57,13 @@ export function showRoomInviteDialog(roomId) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showCommunityRoomInviteDialog(roomId, communityName) {
|
||||||
|
Modal.createTrackedDialog(
|
||||||
|
'Invite Users to Community', '', PrototypeCommunityInviteDialog, {communityName, roomId},
|
||||||
|
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the given MatrixEvent is a valid 3rd party user invite.
|
* Checks if the given MatrixEvent is a valid 3rd party user invite.
|
||||||
* @param {MatrixEvent} event The event to check
|
* @param {MatrixEvent} event The event to check
|
||||||
|
@ -77,7 +85,7 @@ export function isValid3pidInvite(event) {
|
||||||
export function inviteUsersToRoom(roomId, userIds) {
|
export function inviteUsersToRoom(roomId, userIds) {
|
||||||
return inviteMultipleToRoom(roomId, userIds).then((result) => {
|
return inviteMultipleToRoom(roomId, userIds).then((result) => {
|
||||||
const room = MatrixClientPeg.get().getRoom(roomId);
|
const room = MatrixClientPeg.get().getRoom(roomId);
|
||||||
return _showAnyInviteErrors(result.states, room, result.inviter);
|
showAnyInviteErrors(result.states, room, result.inviter);
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.error(err.stack);
|
console.error(err.stack);
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
@ -88,7 +96,7 @@ export function inviteUsersToRoom(roomId, userIds) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function _showAnyInviteErrors(addrs, room, inviter) {
|
export function showAnyInviteErrors(addrs, room, inviter) {
|
||||||
// Show user any errors
|
// Show user any errors
|
||||||
const failedUsers = Object.keys(addrs).filter(a => addrs[a] === 'error');
|
const failedUsers = Object.keys(addrs).filter(a => addrs[a] === 'error');
|
||||||
if (failedUsers.length === 1 && inviter.fatal) {
|
if (failedUsers.length === 1 && inviter.fatal) {
|
||||||
|
@ -100,6 +108,7 @@ function _showAnyInviteErrors(addrs, room, inviter) {
|
||||||
title: _t("Failed to invite users to the room:", {roomName: room.name}),
|
title: _t("Failed to invite users to the room:", {roomName: room.name}),
|
||||||
description: inviter.getErrorText(failedUsers[0]),
|
description: inviter.getErrorText(failedUsers[0]),
|
||||||
});
|
});
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
const errorList = [];
|
const errorList = [];
|
||||||
for (const addr of failedUsers) {
|
for (const addr of failedUsers) {
|
||||||
|
@ -118,8 +127,9 @@ function _showAnyInviteErrors(addrs, room, inviter) {
|
||||||
title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}),
|
title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}),
|
||||||
description,
|
description,
|
||||||
});
|
});
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return addrs;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ export default class InviteDialog extends React.PureComponent {
|
||||||
this.state = {
|
this.state = {
|
||||||
targets: [], // array of Member objects (see interface above)
|
targets: [], // array of Member objects (see interface above)
|
||||||
filterText: "",
|
filterText: "",
|
||||||
recents: this._buildRecents(alreadyInvited),
|
recents: InviteDialog.buildRecents(alreadyInvited),
|
||||||
numRecentsShown: INITIAL_ROOMS_SHOWN,
|
numRecentsShown: INITIAL_ROOMS_SHOWN,
|
||||||
suggestions: this._buildSuggestions(alreadyInvited),
|
suggestions: this._buildSuggestions(alreadyInvited),
|
||||||
numSuggestionsShown: INITIAL_ROOMS_SHOWN,
|
numSuggestionsShown: INITIAL_ROOMS_SHOWN,
|
||||||
|
@ -344,7 +344,7 @@ export default class InviteDialog extends React.PureComponent {
|
||||||
this._editorRef = createRef();
|
this._editorRef = createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildRecents(excludedTargetIds: Set<string>): {userId: string, user: RoomMember, lastActive: number} {
|
static buildRecents(excludedTargetIds: Set<string>): {userId: string, user: RoomMember, lastActive: number} {
|
||||||
const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals(); // map of userId => js-sdk Room
|
const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals(); // map of userId => js-sdk Room
|
||||||
|
|
||||||
// Also pull in all the rooms tagged as DefaultTagID.DM so we don't miss anything. Sometimes the
|
// Also pull in all the rooms tagged as DefaultTagID.DM so we don't miss anything. Sometimes the
|
||||||
|
|
252
src/components/views/dialogs/PrototypeCommunityInviteDialog.tsx
Normal file
252
src/components/views/dialogs/PrototypeCommunityInviteDialog.tsx
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 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, { ChangeEvent, FormEvent } from 'react';
|
||||||
|
import BaseDialog from "./BaseDialog";
|
||||||
|
import { _t } from "../../../languageHandler";
|
||||||
|
import { IDialogProps } from "./IDialogProps";
|
||||||
|
import Field from "../elements/Field";
|
||||||
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
|
import InfoTooltip from "../elements/InfoTooltip";
|
||||||
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
|
import {showCommunityRoomInviteDialog} from "../../../RoomInvite";
|
||||||
|
import { arrayFastClone } from "../../../utils/arrays";
|
||||||
|
import SdkConfig from "../../../SdkConfig";
|
||||||
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
|
import InviteDialog from "./InviteDialog";
|
||||||
|
import BaseAvatar from "../avatars/BaseAvatar";
|
||||||
|
import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo";
|
||||||
|
import {inviteMultipleToRoom, showAnyInviteErrors} from "../../../RoomInvite";
|
||||||
|
import {humanizeTime} from "../../../utils/humanize";
|
||||||
|
import StyledCheckbox from "../elements/StyledCheckbox";
|
||||||
|
import Modal from "../../../Modal";
|
||||||
|
import ErrorDialog from "./ErrorDialog";
|
||||||
|
|
||||||
|
interface IProps extends IDialogProps {
|
||||||
|
roomId: string;
|
||||||
|
communityName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IPerson {
|
||||||
|
userId: string;
|
||||||
|
user: RoomMember;
|
||||||
|
lastActive: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
emailTargets: string[];
|
||||||
|
userTargets: string[];
|
||||||
|
showPeople: boolean;
|
||||||
|
people: IPerson[];
|
||||||
|
numPeople: number;
|
||||||
|
busy: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class PrototypeCommunityInviteDialog extends React.PureComponent<IProps, IState> {
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
emailTargets: [],
|
||||||
|
userTargets: [],
|
||||||
|
showPeople: false,
|
||||||
|
people: this.buildSuggestions(),
|
||||||
|
numPeople: 5, // arbitrary default
|
||||||
|
busy: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildSuggestions(): IPerson[] {
|
||||||
|
const alreadyInvited = new Set([MatrixClientPeg.get().getUserId(), SdkConfig.get()['welcomeUserId']]);
|
||||||
|
if (this.props.roomId) {
|
||||||
|
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||||
|
if (!room) throw new Error("Room ID given to InviteDialog does not look like a room");
|
||||||
|
room.getMembersWithMembership('invite').forEach(m => alreadyInvited.add(m.userId));
|
||||||
|
room.getMembersWithMembership('join').forEach(m => alreadyInvited.add(m.userId));
|
||||||
|
// add banned users, so we don't try to invite them
|
||||||
|
room.getMembersWithMembership('ban').forEach(m => alreadyInvited.add(m.userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
return InviteDialog.buildRecents(alreadyInvited);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onSubmit = async (ev: FormEvent) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
|
||||||
|
this.setState({busy: true});
|
||||||
|
try {
|
||||||
|
const targets = [...this.state.emailTargets, ...this.state.userTargets];
|
||||||
|
const result = await inviteMultipleToRoom(this.props.roomId, targets);
|
||||||
|
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||||
|
const success = showAnyInviteErrors(result.states, room, result.inviter);
|
||||||
|
if (success) {
|
||||||
|
this.props.onFinished(true);
|
||||||
|
} else {
|
||||||
|
this.setState({busy: false});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.setState({busy: false});
|
||||||
|
console.error(e);
|
||||||
|
Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, {
|
||||||
|
title: _t("Failed to invite"),
|
||||||
|
description: ((e && e.message) ? e.message : _t("Operation failed")),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private onAddressChange = (ev: ChangeEvent<HTMLInputElement>, index: number) => {
|
||||||
|
const targets = arrayFastClone(this.state.emailTargets);
|
||||||
|
if (index >= targets.length) {
|
||||||
|
targets.push(ev.target.value);
|
||||||
|
} else {
|
||||||
|
targets[index] = ev.target.value;
|
||||||
|
}
|
||||||
|
this.setState({emailTargets: targets});
|
||||||
|
};
|
||||||
|
|
||||||
|
private onAddressBlur = (index: number) => {
|
||||||
|
const targets = arrayFastClone(this.state.emailTargets);
|
||||||
|
if (index >= targets.length) return; // not important
|
||||||
|
if (targets[index].trim() === "") {
|
||||||
|
targets.splice(index, 1);
|
||||||
|
this.setState({emailTargets: targets});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private onShowPeopleClick = () => {
|
||||||
|
this.setState({showPeople: !this.state.showPeople});
|
||||||
|
};
|
||||||
|
|
||||||
|
private setPersonToggle = (person: IPerson, selected: boolean) => {
|
||||||
|
const targets = arrayFastClone(this.state.userTargets);
|
||||||
|
if (selected && !targets.includes(person.userId)) {
|
||||||
|
targets.push(person.userId);
|
||||||
|
} else if (!selected && targets.includes(person.userId)) {
|
||||||
|
targets.splice(targets.indexOf(person.userId), 1);
|
||||||
|
}
|
||||||
|
this.setState({userTargets: targets});
|
||||||
|
};
|
||||||
|
|
||||||
|
private renderPerson(person: IPerson, key: any) {
|
||||||
|
const avatarSize = 36;
|
||||||
|
return (
|
||||||
|
<div className="mx_PrototypeCommunityInviteDialog_person" key={key}>
|
||||||
|
<BaseAvatar
|
||||||
|
url={getHttpUriForMxc(
|
||||||
|
MatrixClientPeg.get().getHomeserverUrl(), person.user.getMxcAvatarUrl(),
|
||||||
|
avatarSize, avatarSize, "crop")}
|
||||||
|
name={person.user.name}
|
||||||
|
idName={person.user.userId}
|
||||||
|
width={avatarSize}
|
||||||
|
height={avatarSize}
|
||||||
|
/>
|
||||||
|
<div className="mx_PrototypeCommunityInviteDialog_personIdentifiers">
|
||||||
|
<span className="mx_PrototypeCommunityInviteDialog_personName">{person.user.name}</span>
|
||||||
|
<span className="mx_PrototypeCommunityInviteDialog_personId">{person.userId}</span>
|
||||||
|
</div>
|
||||||
|
<StyledCheckbox onChange={(e) => this.setPersonToggle(person, e.target.checked)} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onShowMorePeople = () => {
|
||||||
|
this.setState({numPeople: this.state.numPeople + 5}); // arbitrary increase
|
||||||
|
};
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const emailAddresses = [];
|
||||||
|
this.state.emailTargets.forEach((address, i) => {
|
||||||
|
emailAddresses.push(
|
||||||
|
<Field
|
||||||
|
key={i}
|
||||||
|
value={address}
|
||||||
|
onChange={(e) => this.onAddressChange(e, i)}
|
||||||
|
label={_t("Email address")}
|
||||||
|
placeholder={_t("Email address")}
|
||||||
|
onBlur={() => this.onAddressBlur(i)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Push a clean input
|
||||||
|
emailAddresses.push(
|
||||||
|
<Field
|
||||||
|
key={emailAddresses.length}
|
||||||
|
value={""}
|
||||||
|
onChange={(e) => this.onAddressChange(e, emailAddresses.length)}
|
||||||
|
label={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
|
||||||
|
placeholder={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
let peopleIntro = null;
|
||||||
|
let people = [];
|
||||||
|
if (this.state.showPeople) {
|
||||||
|
const humansToPresent = this.state.people.slice(0, this.state.numPeople);
|
||||||
|
humansToPresent.forEach((person, i) => {
|
||||||
|
people.push(this.renderPerson(person, i));
|
||||||
|
});
|
||||||
|
if (humansToPresent.length < this.state.people.length) {
|
||||||
|
people.push(
|
||||||
|
<AccessibleButton
|
||||||
|
onClick={this.onShowMorePeople}
|
||||||
|
kind="link" key="more"
|
||||||
|
className="mx_PrototypeCommunityInviteDialog_morePeople"
|
||||||
|
>{_t("Show more")}</AccessibleButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.state.people.length > 0) {
|
||||||
|
peopleIntro = (
|
||||||
|
<div className="mx_PrototypeCommunityInviteDialog_people">
|
||||||
|
<span>{_t("People you know on %(brand)s", {brand: SdkConfig.get().brand})}</span>
|
||||||
|
<AccessibleButton onClick={this.onShowPeopleClick}>
|
||||||
|
{this.state.showPeople ? _t("Hide") : _t("Show")}
|
||||||
|
</AccessibleButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let buttonText = _t("Skip");
|
||||||
|
const targetCount = this.state.userTargets.length + this.state.emailTargets.length;
|
||||||
|
if (targetCount > 0) {
|
||||||
|
buttonText = _t("Send %(count)s invites", {count: targetCount});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseDialog
|
||||||
|
className="mx_PrototypeCommunityInviteDialog"
|
||||||
|
onFinished={this.props.onFinished}
|
||||||
|
title={_t("Invite people to join %(communityName)s", {communityName: this.props.communityName})}
|
||||||
|
>
|
||||||
|
<form onSubmit={this.onSubmit}>
|
||||||
|
<div className="mx_Dialog_content">
|
||||||
|
{emailAddresses}
|
||||||
|
{peopleIntro}
|
||||||
|
{people}
|
||||||
|
<AccessibleButton
|
||||||
|
kind="primary" onClick={this.onSubmit}
|
||||||
|
disabled={this.state.busy}
|
||||||
|
className="mx_PrototypeCommunityInviteDialog_primaryButton"
|
||||||
|
>{buttonText}</AccessibleButton>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</BaseDialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
import InfoTooltip from "../elements/InfoTooltip";
|
import InfoTooltip from "../elements/InfoTooltip";
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
|
import {showCommunityRoomInviteDialog} from "../../../RoomInvite";
|
||||||
|
|
||||||
interface IProps extends IDialogProps {
|
interface IProps extends IDialogProps {
|
||||||
}
|
}
|
||||||
|
@ -67,7 +68,7 @@ export default class PrototypeCreateGroupDialog extends React.PureComponent<IPro
|
||||||
// the background for the user to look at while they invite people.
|
// the background for the user to look at while they invite people.
|
||||||
this.setState({busy: true});
|
this.setState({busy: true});
|
||||||
try {
|
try {
|
||||||
let avatarUrl = null;
|
let avatarUrl = ''; // must be a string for synapse to accept it
|
||||||
if (this.state.avatarFile) {
|
if (this.state.avatarFile) {
|
||||||
avatarUrl = await MatrixClientPeg.get().uploadContent(this.state.avatarFile);
|
avatarUrl = await MatrixClientPeg.get().uploadContent(this.state.avatarFile);
|
||||||
}
|
}
|
||||||
|
@ -87,11 +88,15 @@ export default class PrototypeCreateGroupDialog extends React.PureComponent<IPro
|
||||||
tag: result.group_id,
|
tag: result.group_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Close our own dialog before moving much further
|
||||||
|
this.props.onFinished(true);
|
||||||
|
|
||||||
if (result.room_id) {
|
if (result.room_id) {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
room_id: result.room_id,
|
room_id: result.room_id,
|
||||||
});
|
});
|
||||||
|
showCommunityRoomInviteDialog(result.room_id, this.state.name);
|
||||||
} else {
|
} else {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_group',
|
action: 'view_group',
|
||||||
|
@ -99,8 +104,6 @@ export default class PrototypeCreateGroupDialog extends React.PureComponent<IPro
|
||||||
group_is_new: true,
|
group_is_new: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Show invite dialog
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
this.setState({
|
this.setState({
|
||||||
|
|
|
@ -1729,6 +1729,15 @@
|
||||||
"Use this session to verify your new one, granting it access to encrypted messages:": "Use this session to verify your new one, granting it access to encrypted messages:",
|
"Use this session to verify your new one, granting it access to encrypted messages:": "Use this session to verify your new one, granting it access to encrypted messages:",
|
||||||
"If you didn’t sign in to this session, your account may be compromised.": "If you didn’t sign in to this session, your account may be compromised.",
|
"If you didn’t sign in to this session, your account may be compromised.": "If you didn’t sign in to this session, your account may be compromised.",
|
||||||
"This wasn't me": "This wasn't me",
|
"This wasn't me": "This wasn't me",
|
||||||
|
"Email address": "Email address",
|
||||||
|
"Add another email": "Add another email",
|
||||||
|
"People you know on %(brand)s": "People you know on %(brand)s",
|
||||||
|
"Hide": "Hide",
|
||||||
|
"Show": "Show",
|
||||||
|
"Skip": "Skip",
|
||||||
|
"Send %(count)s invites|other": "Send %(count)s invites",
|
||||||
|
"Send %(count)s invites|one": "Send %(count)s invite",
|
||||||
|
"Invite people to join %(communityName)s": "Invite people to join %(communityName)s",
|
||||||
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "There was an error creating your community. The name may be taken or the server is unable to process your request.",
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "There was an error creating your community. The name may be taken or the server is unable to process your request.",
|
||||||
"Community ID: +<localpart />:%(domain)s": "Community ID: +<localpart />:%(domain)s",
|
"Community ID: +<localpart />:%(domain)s": "Community ID: +<localpart />:%(domain)s",
|
||||||
"Use this when referencing your community to others. The community ID cannot be changed.": "Use this when referencing your community to others. The community ID cannot be changed.",
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Use this when referencing your community to others. The community ID cannot be changed.",
|
||||||
|
@ -1783,9 +1792,7 @@
|
||||||
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.",
|
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.",
|
||||||
"Verification Pending": "Verification Pending",
|
"Verification Pending": "Verification Pending",
|
||||||
"Please check your email and click on the link it contains. Once this is done, click continue.": "Please check your email and click on the link it contains. Once this is done, click continue.",
|
"Please check your email and click on the link it contains. Once this is done, click continue.": "Please check your email and click on the link it contains. Once this is done, click continue.",
|
||||||
"Email address": "Email address",
|
|
||||||
"This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.",
|
"This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.",
|
||||||
"Skip": "Skip",
|
|
||||||
"A username can only contain lower case letters, numbers and '=_-./'": "A username can only contain lower case letters, numbers and '=_-./'",
|
"A username can only contain lower case letters, numbers and '=_-./'": "A username can only contain lower case letters, numbers and '=_-./'",
|
||||||
"Username not available": "Username not available",
|
"Username not available": "Username not available",
|
||||||
"Username invalid: %(errMessage)s": "Username invalid: %(errMessage)s",
|
"Username invalid: %(errMessage)s": "Username invalid: %(errMessage)s",
|
||||||
|
@ -1898,7 +1905,6 @@
|
||||||
"Set status": "Set status",
|
"Set status": "Set status",
|
||||||
"Set a new status...": "Set a new status...",
|
"Set a new status...": "Set a new status...",
|
||||||
"View Community": "View Community",
|
"View Community": "View Community",
|
||||||
"Hide": "Hide",
|
|
||||||
"Reload": "Reload",
|
"Reload": "Reload",
|
||||||
"Take picture": "Take picture",
|
"Take picture": "Take picture",
|
||||||
"Remove for everyone": "Remove for everyone",
|
"Remove for everyone": "Remove for everyone",
|
||||||
|
|
Loading…
Reference in a new issue