Merge remote-tracking branch 'matrix-org/develop' into travis/granular-settings
This commit is contained in:
commit
030633fa90
12 changed files with 134 additions and 75 deletions
|
@ -49,20 +49,26 @@ export function showGroupInviteDialog(groupId) {
|
||||||
|
|
||||||
export function showGroupAddRoomDialog(groupId) {
|
export function showGroupAddRoomDialog(groupId) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
let addRoomsPublicly = false;
|
||||||
|
const onCheckboxClicked = (e) => {
|
||||||
|
addRoomsPublicly = e.target.checked;
|
||||||
|
};
|
||||||
const description = <div>
|
const description = <div>
|
||||||
<div>{ _t("Which rooms would you like to add to this community?") }</div>
|
<div>{ _t("Which rooms would you like to add to this community?") }</div>
|
||||||
<div className="warning">
|
|
||||||
{ _t(
|
|
||||||
"Warning: any room you add to a community will be publicly "+
|
|
||||||
"visible to anyone who knows the community ID",
|
|
||||||
) }
|
|
||||||
</div>
|
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
|
const checkboxContainer = <label className="mx_GroupAddressPicker_checkboxContainer">
|
||||||
|
<input type="checkbox" onClick={onCheckboxClicked} />
|
||||||
|
<div>
|
||||||
|
{ _t("Show these rooms to non-members on the community page and room list?") }
|
||||||
|
</div>
|
||||||
|
</label>;
|
||||||
|
|
||||||
const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog");
|
const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog");
|
||||||
Modal.createTrackedDialog('Add Rooms to Group', '', AddressPickerDialog, {
|
Modal.createTrackedDialog('Add Rooms to Group', '', AddressPickerDialog, {
|
||||||
title: _t("Add rooms to the community"),
|
title: _t("Add rooms to the community"),
|
||||||
description: description,
|
description: description,
|
||||||
|
extraNode: checkboxContainer,
|
||||||
placeholder: _t("Room name or alias"),
|
placeholder: _t("Room name or alias"),
|
||||||
button: _t("Add to community"),
|
button: _t("Add to community"),
|
||||||
pickerType: 'room',
|
pickerType: 'room',
|
||||||
|
@ -70,7 +76,7 @@ export function showGroupAddRoomDialog(groupId) {
|
||||||
onFinished: (success, addrs) => {
|
onFinished: (success, addrs) => {
|
||||||
if (!success) return;
|
if (!success) return;
|
||||||
|
|
||||||
_onGroupAddRoomFinished(groupId, addrs).then(resolve, reject);
|
_onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly).then(resolve, reject);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -106,13 +112,13 @@ function _onGroupInviteFinished(groupId, addrs) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function _onGroupAddRoomFinished(groupId, addrs) {
|
function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) {
|
||||||
const matrixClient = MatrixClientPeg.get();
|
const matrixClient = MatrixClientPeg.get();
|
||||||
const groupStore = GroupStoreCache.getGroupStore(matrixClient, groupId);
|
const groupStore = GroupStoreCache.getGroupStore(matrixClient, groupId);
|
||||||
const errorList = [];
|
const errorList = [];
|
||||||
return Promise.all(addrs.map((addr) => {
|
return Promise.all(addrs.map((addr) => {
|
||||||
return groupStore
|
return groupStore
|
||||||
.addRoomToGroup(addr.address)
|
.addRoomToGroup(addr.address, addRoomsPublicly)
|
||||||
.catch(() => { errorList.push(addr.address); })
|
.catch(() => { errorList.push(addr.address); })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const roomId = addr.address;
|
const roomId = addr.address;
|
||||||
|
|
|
@ -25,6 +25,7 @@ const onAction = function(payload) {
|
||||||
const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog');
|
const UnknownDeviceDialog = sdk.getComponent('dialogs.UnknownDeviceDialog');
|
||||||
isDialogOpen = true;
|
isDialogOpen = true;
|
||||||
Modal.createTrackedDialog('Unknown Device Error', '', UnknownDeviceDialog, {
|
Modal.createTrackedDialog('Unknown Device Error', '', UnknownDeviceDialog, {
|
||||||
|
devices: payload.err.devices,
|
||||||
room: payload.room,
|
room: payload.room,
|
||||||
onFinished: (r) => {
|
onFinished: (r) => {
|
||||||
isDialogOpen = false;
|
isDialogOpen = false;
|
||||||
|
|
|
@ -430,6 +430,7 @@ export default React.createClass({
|
||||||
uploadingAvatar: false,
|
uploadingAvatar: false,
|
||||||
membershipBusy: false,
|
membershipBusy: false,
|
||||||
publicityBusy: false,
|
publicityBusy: false,
|
||||||
|
inviterProfile: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -463,6 +464,10 @@ export default React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_initGroupStore: function(groupId, firstInit) {
|
_initGroupStore: function(groupId, firstInit) {
|
||||||
|
const group = MatrixClientPeg.get().getGroup(groupId);
|
||||||
|
if (group && group.inviter && group.inviter.userId) {
|
||||||
|
this._fetchInviterProfile(group.inviter.userId);
|
||||||
|
}
|
||||||
this._groupStore = GroupStoreCache.getGroupStore(MatrixClientPeg.get(), groupId);
|
this._groupStore = GroupStoreCache.getGroupStore(MatrixClientPeg.get(), groupId);
|
||||||
this._groupStore.registerListener(() => {
|
this._groupStore.registerListener(() => {
|
||||||
const summary = this._groupStore.getSummary();
|
const summary = this._groupStore.getSummary();
|
||||||
|
@ -497,6 +502,26 @@ export default React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_fetchInviterProfile(userId) {
|
||||||
|
this.setState({
|
||||||
|
inviterProfileBusy: true,
|
||||||
|
});
|
||||||
|
MatrixClientPeg.get().getProfileInfo(userId).then((resp) => {
|
||||||
|
this.setState({
|
||||||
|
inviterProfile: {
|
||||||
|
avatarUrl: resp.avatar_url,
|
||||||
|
displayName: resp.displayname,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error('Error getting group inviter profile', e);
|
||||||
|
}).finally(() => {
|
||||||
|
this.setState({
|
||||||
|
inviterProfileBusy: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
_onShowRhsClick: function(ev) {
|
_onShowRhsClick: function(ev) {
|
||||||
dis.dispatch({ action: 'show_right_panel' });
|
dis.dispatch({ action: 'show_right_panel' });
|
||||||
},
|
},
|
||||||
|
@ -591,7 +616,7 @@ export default React.createClass({
|
||||||
|
|
||||||
_onAcceptInviteClick: function() {
|
_onAcceptInviteClick: function() {
|
||||||
this.setState({membershipBusy: true});
|
this.setState({membershipBusy: true});
|
||||||
MatrixClientPeg.get().acceptGroupInvite(this.props.groupId).then(() => {
|
this._groupStore.acceptGroupInvite().then(() => {
|
||||||
// don't reset membershipBusy here: wait for the membership change to come down the sync
|
// don't reset membershipBusy here: wait for the membership change to come down the sync
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
this.setState({membershipBusy: false});
|
this.setState({membershipBusy: false});
|
||||||
|
@ -802,20 +827,37 @@ export default React.createClass({
|
||||||
|
|
||||||
_getMembershipSection: function() {
|
_getMembershipSection: function() {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
|
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||||
|
|
||||||
const group = MatrixClientPeg.get().getGroup(this.props.groupId);
|
const group = MatrixClientPeg.get().getGroup(this.props.groupId);
|
||||||
if (!group) return null;
|
if (!group) return null;
|
||||||
|
|
||||||
if (group.myMembership === 'invite') {
|
if (group.myMembership === 'invite') {
|
||||||
if (this.state.membershipBusy) {
|
if (this.state.membershipBusy || this.state.inviterProfileBusy) {
|
||||||
return <div className="mx_GroupView_membershipSection">
|
return <div className="mx_GroupView_membershipSection">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
const httpInviterAvatar = this.state.inviterProfile ?
|
||||||
|
MatrixClientPeg.get().mxcUrlToHttp(
|
||||||
|
this.state.inviterProfile.avatarUrl, 36, 36,
|
||||||
|
) : null;
|
||||||
|
|
||||||
|
let inviterName = group.inviter.userId;
|
||||||
|
if (this.state.inviterProfile) {
|
||||||
|
inviterName = this.state.inviterProfile.displayName || group.inviter.userId;
|
||||||
|
}
|
||||||
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_invited">
|
return <div className="mx_GroupView_membershipSection mx_GroupView_membershipSection_invited">
|
||||||
<div className="mx_GroupView_membershipSubSection">
|
<div className="mx_GroupView_membershipSubSection">
|
||||||
<div className="mx_GroupView_membershipSection_description">
|
<div className="mx_GroupView_membershipSection_description">
|
||||||
{ _t("%(inviter)s has invited you to join this community", {inviter: group.inviter.userId}) }
|
<BaseAvatar url={httpInviterAvatar}
|
||||||
|
name={inviterName}
|
||||||
|
width={36}
|
||||||
|
height={36}
|
||||||
|
/>
|
||||||
|
{ _t("%(inviter)s has invited you to join this community", {
|
||||||
|
inviter: inviterName,
|
||||||
|
}) }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_GroupView_membership_buttonContainer">
|
<div className="mx_GroupView_membership_buttonContainer">
|
||||||
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
<AccessibleButton className="mx_GroupView_textButton mx_RoomHeader_textButton"
|
||||||
|
|
|
@ -34,6 +34,8 @@ module.exports = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
description: PropTypes.node,
|
description: PropTypes.node,
|
||||||
|
// Extra node inserted after picker input, dropdown and errors
|
||||||
|
extraNode: PropTypes.node,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
roomId: PropTypes.string,
|
roomId: PropTypes.string,
|
||||||
|
@ -268,34 +270,53 @@ module.exports = React.createClass({
|
||||||
const rooms = MatrixClientPeg.get().getRooms();
|
const rooms = MatrixClientPeg.get().getRooms();
|
||||||
const results = [];
|
const results = [];
|
||||||
rooms.forEach((room) => {
|
rooms.forEach((room) => {
|
||||||
|
let rank = Infinity;
|
||||||
const nameEvent = room.currentState.getStateEvents('m.room.name', '');
|
const nameEvent = room.currentState.getStateEvents('m.room.name', '');
|
||||||
const topicEvent = room.currentState.getStateEvents('m.room.topic', '');
|
|
||||||
const name = nameEvent ? nameEvent.getContent().name : '';
|
const name = nameEvent ? nameEvent.getContent().name : '';
|
||||||
const canonicalAlias = room.getCanonicalAlias();
|
const canonicalAlias = room.getCanonicalAlias();
|
||||||
const aliasEvents = room.currentState.getStateEvents('m.room.aliases');
|
const aliasEvents = room.currentState.getStateEvents('m.room.aliases');
|
||||||
const aliases = aliasEvents.map((ev) => ev.getContent().aliases).reduce((a, b) => {
|
const aliases = aliasEvents.map((ev) => ev.getContent().aliases).reduce((a, b) => {
|
||||||
return a.concat(b);
|
return a.concat(b);
|
||||||
}, []);
|
}, []);
|
||||||
const topic = topicEvent ? topicEvent.getContent().topic : '';
|
|
||||||
|
|
||||||
const nameMatch = (name || '').toLowerCase().includes(lowerCaseQuery);
|
const nameMatch = (name || '').toLowerCase().includes(lowerCaseQuery);
|
||||||
const aliasMatch = aliases.some((alias) =>
|
let aliasMatch = false;
|
||||||
(alias || '').toLowerCase().includes(lowerCaseQuery),
|
let shortestMatchingAliasLength = Infinity;
|
||||||
);
|
aliases.forEach((alias) => {
|
||||||
const topicMatch = (topic || '').toLowerCase().includes(lowerCaseQuery);
|
if ((alias || '').toLowerCase().includes(lowerCaseQuery)) {
|
||||||
if (!(nameMatch || topicMatch || aliasMatch)) {
|
aliasMatch = true;
|
||||||
|
if (shortestMatchingAliasLength > alias.length) {
|
||||||
|
shortestMatchingAliasLength = alias.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!(nameMatch || aliasMatch)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aliasMatch) {
|
||||||
|
// A shorter matching alias will give a better rank
|
||||||
|
rank = shortestMatchingAliasLength;
|
||||||
|
}
|
||||||
|
|
||||||
const avatarEvent = room.currentState.getStateEvents('m.room.avatar', '');
|
const avatarEvent = room.currentState.getStateEvents('m.room.avatar', '');
|
||||||
const avatarUrl = avatarEvent ? avatarEvent.getContent().url : undefined;
|
const avatarUrl = avatarEvent ? avatarEvent.getContent().url : undefined;
|
||||||
|
|
||||||
results.push({
|
results.push({
|
||||||
|
rank,
|
||||||
room_id: room.roomId,
|
room_id: room.roomId,
|
||||||
avatar_url: avatarUrl,
|
avatar_url: avatarUrl,
|
||||||
name: name || canonicalAlias || aliases[0] || _t('Unnamed Room'),
|
name: name || canonicalAlias || aliases[0] || _t('Unnamed Room'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this._processResults(results, query);
|
|
||||||
|
// Sort by rank ascending (a high rank being less relevant)
|
||||||
|
const sortedResults = results.sort((a, b) => {
|
||||||
|
return a.rank - b.rank;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._processResults(sortedResults, query);
|
||||||
this.setState({
|
this.setState({
|
||||||
busy: false,
|
busy: false,
|
||||||
});
|
});
|
||||||
|
@ -574,6 +595,7 @@ module.exports = React.createClass({
|
||||||
<div className="mx_ChatInviteDialog_inputContainer">{ query }</div>
|
<div className="mx_ChatInviteDialog_inputContainer">{ query }</div>
|
||||||
{ error }
|
{ error }
|
||||||
{ addressSelector }
|
{ addressSelector }
|
||||||
|
{ this.props.extraNode }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className="mx_Dialog_primary" onClick={this.onButtonClick}>
|
<button className="mx_Dialog_primary" onClick={this.onButtonClick}>
|
||||||
|
|
|
@ -49,9 +49,8 @@ function UserUnknownDeviceList(props) {
|
||||||
const {userId, userDevices} = props;
|
const {userId, userDevices} = props;
|
||||||
|
|
||||||
const deviceListEntries = Object.keys(userDevices).map((deviceId) =>
|
const deviceListEntries = Object.keys(userDevices).map((deviceId) =>
|
||||||
<DeviceListEntry key={deviceId} userId={userId}
|
<DeviceListEntry key={deviceId} userId={userId}
|
||||||
device={userDevices[deviceId]}
|
device={userDevices[deviceId]} />,
|
||||||
/>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -94,52 +93,23 @@ export default React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
room: React.PropTypes.object.isRequired,
|
room: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
|
// map from userid -> deviceid -> deviceinfo
|
||||||
|
devices: React.PropTypes.object.isRequired,
|
||||||
onFinished: React.PropTypes.func.isRequired,
|
onFinished: React.PropTypes.func.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentDidMount: function() {
|
||||||
this._unmounted = false;
|
// Given we've now shown the user the unknown device, it is no longer
|
||||||
|
// unknown to them. Therefore mark it as 'known'.
|
||||||
const roomMembers = this.props.room.getJoinedMembers().map((m) => {
|
Object.keys(this.props.devices).forEach((userId) => {
|
||||||
return m.userId;
|
Object.keys(this.props.devices[userId]).map((deviceId) => {
|
||||||
});
|
MatrixClientPeg.get().setDeviceKnown(userId, deviceId, true);
|
||||||
|
|
||||||
this.setState({
|
|
||||||
// map from userid -> deviceid -> deviceinfo
|
|
||||||
devices: null,
|
|
||||||
});
|
|
||||||
MatrixClientPeg.get().downloadKeys(roomMembers, false).then((devices) => {
|
|
||||||
if (this._unmounted) return;
|
|
||||||
|
|
||||||
const unknownDevices = {};
|
|
||||||
// This is all devices in this room, so find the unknown ones.
|
|
||||||
Object.keys(devices).forEach((userId) => {
|
|
||||||
Object.keys(devices[userId]).map((deviceId) => {
|
|
||||||
const device = devices[userId][deviceId];
|
|
||||||
|
|
||||||
if (device.isUnverified() && !device.isKnown()) {
|
|
||||||
if (unknownDevices[userId] === undefined) {
|
|
||||||
unknownDevices[userId] = {};
|
|
||||||
}
|
|
||||||
unknownDevices[userId][deviceId] = device;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given we've now shown the user the unknown device, it is no longer
|
|
||||||
// unknown to them. Therefore mark it as 'known'.
|
|
||||||
if (!device.isKnown()) {
|
|
||||||
MatrixClientPeg.get().setDeviceKnown(userId, deviceId, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
devices: unknownDevices,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
// XXX: temporary logging to try to diagnose
|
||||||
this._unmounted = true;
|
// https://github.com/vector-im/riot-web/issues/3148
|
||||||
|
console.log('Opening UnknownDeviceDialog');
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
@ -186,7 +156,7 @@ export default React.createClass({
|
||||||
{ warning }
|
{ warning }
|
||||||
{ _t("Unknown devices") }:
|
{ _t("Unknown devices") }:
|
||||||
|
|
||||||
<UnknownDeviceList devices={this.state.devices} />
|
<UnknownDeviceList devices={this.props.devices} />
|
||||||
</GeminiScrollbar>
|
</GeminiScrollbar>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className="mx_Dialog_primary" autoFocus={true}
|
<button className="mx_Dialog_primary" autoFocus={true}
|
||||||
|
|
|
@ -108,14 +108,20 @@ export default withMatrixClient(React.createClass({
|
||||||
if (!uniqueMembers[m.userId]) uniqueMembers[m.userId] = m;
|
if (!uniqueMembers[m.userId]) uniqueMembers[m.userId] = m;
|
||||||
});
|
});
|
||||||
memberList = Object.keys(uniqueMembers).map((userId) => uniqueMembers[userId]);
|
memberList = Object.keys(uniqueMembers).map((userId) => uniqueMembers[userId]);
|
||||||
|
// Descending sort on isPrivileged = true = 1 to isPrivileged = false = 0
|
||||||
memberList.sort((a, b) => {
|
memberList.sort((a, b) => {
|
||||||
// TODO: should put admins at the top: we don't yet have that info
|
if (a.isPrivileged === b.isPrivileged) {
|
||||||
if (a < b) {
|
const aName = a.displayname || a.userId;
|
||||||
return -1;
|
const bName = b.displayname || b.userId;
|
||||||
} else if (a > b) {
|
if (aName < bName) {
|
||||||
return 1;
|
return -1;
|
||||||
|
} else if (aName > bName) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return a.isPrivileged ? -1 : 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ export default withMatrixClient(React.createClass({
|
||||||
return (
|
return (
|
||||||
<EntityTile name={name} avatarJsx={av} onClick={this.onClick}
|
<EntityTile name={name} avatarJsx={av} onClick={this.onClick}
|
||||||
suppressOnHover={true} presenceState="online"
|
suppressOnHover={true} presenceState="online"
|
||||||
powerStatus={this.props.member.isAdmin ? EntityTile.POWER_STATUS_ADMIN : null}
|
powerStatus={this.props.member.isPrivileged ? EntityTile.POWER_STATUS_ADMIN : null}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -94,7 +94,7 @@ export default React.createClass({
|
||||||
let roomList = this.state.rooms;
|
let roomList = this.state.rooms;
|
||||||
if (query) {
|
if (query) {
|
||||||
roomList = roomList.filter((room) => {
|
roomList = roomList.filter((room) => {
|
||||||
const matchesName = (room.name || "").toLowerCase().include(query);
|
const matchesName = (room.name || "").toLowerCase().includes(query);
|
||||||
const matchesAlias = (room.canonicalAlias || "").toLowerCase().includes(query);
|
const matchesAlias = (room.canonicalAlias || "").toLowerCase().includes(query);
|
||||||
return matchesName || matchesAlias;
|
return matchesName || matchesAlias;
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,7 +36,7 @@ export function groupMemberFromApiObject(apiObject) {
|
||||||
userId: apiObject.user_id,
|
userId: apiObject.user_id,
|
||||||
displayname: apiObject.displayname,
|
displayname: apiObject.displayname,
|
||||||
avatarUrl: apiObject.avatar_url,
|
avatarUrl: apiObject.avatar_url,
|
||||||
isAdmin: apiObject.is_admin,
|
isPrivileged: apiObject.is_privileged,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
"Name or matrix ID": "Name or matrix ID",
|
"Name or matrix ID": "Name or matrix ID",
|
||||||
"Invite to Community": "Invite to Community",
|
"Invite to Community": "Invite to Community",
|
||||||
"Which rooms would you like to add to this community?": "Which rooms would you like to add to this community?",
|
"Which rooms would you like to add to this community?": "Which rooms would you like to add to this community?",
|
||||||
"Warning: any room you add to a community will be publicly visible to anyone who knows the community ID": "Warning: any room you add to a community will be publicly visible to anyone who knows the community ID",
|
"Show these rooms to non-members on the community page and room list?": "Show these rooms to non-members on the community page and room list?",
|
||||||
"Add rooms to the community": "Add rooms to the community",
|
"Add rooms to the community": "Add rooms to the community",
|
||||||
"Room name or alias": "Room name or alias",
|
"Room name or alias": "Room name or alias",
|
||||||
"Add to community": "Add to community",
|
"Add to community": "Add to community",
|
||||||
|
|
|
@ -69,9 +69,13 @@ class FlairStore extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bulk lookup ongoing, return promise to resolve/reject
|
// Bulk lookup ongoing, return promise to resolve/reject
|
||||||
if (this._usersPending[userId] || this._usersInFlight[userId]) {
|
if (this._usersPending[userId]) {
|
||||||
return this._usersPending[userId].prom;
|
return this._usersPending[userId].prom;
|
||||||
}
|
}
|
||||||
|
// User has been moved from pending to in-flight
|
||||||
|
if (this._usersInFlight[userId]) {
|
||||||
|
return this._usersInFlight[userId].prom;
|
||||||
|
}
|
||||||
|
|
||||||
this._usersPending[userId] = {};
|
this._usersPending[userId] = {};
|
||||||
this._usersPending[userId].prom = new Promise((resolve, reject) => {
|
this._usersPending[userId].prom = new Promise((resolve, reject) => {
|
||||||
|
|
|
@ -169,6 +169,14 @@ export default class GroupStore extends EventEmitter {
|
||||||
.then(this._fetchMembers.bind(this));
|
.then(this._fetchMembers.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acceptGroupInvite() {
|
||||||
|
return this._matrixClient.acceptGroupInvite(this.groupId)
|
||||||
|
// The user might be able to see more rooms now
|
||||||
|
.then(this._fetchRooms.bind(this))
|
||||||
|
// The user should now appear as a member
|
||||||
|
.then(this._fetchMembers.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
addRoomToGroupSummary(roomId, categoryId) {
|
addRoomToGroupSummary(roomId, categoryId) {
|
||||||
return this._matrixClient
|
return this._matrixClient
|
||||||
.addRoomToGroupSummary(this.groupId, roomId, categoryId)
|
.addRoomToGroupSummary(this.groupId, roomId, categoryId)
|
||||||
|
|
Loading…
Reference in a new issue