Merge pull request #1566 from matrix-org/luke/groups-room-publicity
Add toggle to alter visibility of a room-group association
This commit is contained in:
commit
7c17ad8509
5 changed files with 100 additions and 19 deletions
|
@ -21,7 +21,6 @@ import dis from '../../../dispatcher';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { GroupRoomType } from '../../../groups';
|
|
||||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||||
import GeminiScrollbar from 'react-gemini-scrollbar';
|
import GeminiScrollbar from 'react-gemini-scrollbar';
|
||||||
|
|
||||||
|
@ -34,13 +33,15 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
groupId: PropTypes.string,
|
groupId: PropTypes.string,
|
||||||
groupRoom: GroupRoomType,
|
groupRoomId: PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
removingRoom: false,
|
|
||||||
isUserPrivilegedInGroup: null,
|
isUserPrivilegedInGroup: null,
|
||||||
|
groupRoom: null,
|
||||||
|
groupRoomPublicityLoading: false,
|
||||||
|
groupRoomRemoveLoading: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -55,6 +56,10 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this._unregisterGroupStore();
|
||||||
|
},
|
||||||
|
|
||||||
_initGroupStore(groupId) {
|
_initGroupStore(groupId) {
|
||||||
this._groupStore = GroupStoreCache.getGroupStore(
|
this._groupStore = GroupStoreCache.getGroupStore(
|
||||||
this.context.matrixClient, this.props.groupId,
|
this.context.matrixClient, this.props.groupId,
|
||||||
|
@ -68,15 +73,24 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateGroupRoom() {
|
||||||
|
this.setState({
|
||||||
|
groupRoom: this._groupStore.getGroupRooms().find(
|
||||||
|
(r) => r.roomId === this.props.groupRoomId,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
onGroupStoreUpdated: function() {
|
onGroupStoreUpdated: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(),
|
isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(),
|
||||||
});
|
});
|
||||||
|
this._updateGroupRoom();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRemove: function(e) {
|
_onRemove: function(e) {
|
||||||
const groupId = this.props.groupId;
|
const groupId = this.props.groupId;
|
||||||
const roomName = this.props.groupRoom.displayname;
|
const roomName = this.state.groupRoom.displayname;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
|
@ -86,9 +100,9 @@ module.exports = React.createClass({
|
||||||
button: _t("Remove"),
|
button: _t("Remove"),
|
||||||
onFinished: (proceed) => {
|
onFinished: (proceed) => {
|
||||||
if (!proceed) return;
|
if (!proceed) return;
|
||||||
this.setState({removingRoom: true});
|
this.setState({groupRoomRemoveLoading: true});
|
||||||
const groupId = this.props.groupId;
|
const groupId = this.props.groupId;
|
||||||
const roomId = this.props.groupRoom.roomId;
|
const roomId = this.props.groupRoomId;
|
||||||
this._groupStore.removeRoomFromGroup(roomId).then(() => {
|
this._groupStore.removeRoomFromGroup(roomId).then(() => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: "view_group_room_list",
|
action: "view_group_room_list",
|
||||||
|
@ -103,7 +117,7 @@ module.exports = React.createClass({
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.setState({removingRoom: false});
|
this.setState({groupRoomRemoveLoading: false});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -115,13 +129,41 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_changeGroupRoomPublicity(e) {
|
||||||
|
const isPublic = e.target.value === "public";
|
||||||
|
this.setState({
|
||||||
|
groupRoomPublicityLoading: true,
|
||||||
|
});
|
||||||
|
const groupId = this.props.groupId;
|
||||||
|
const roomId = this.props.groupRoomId;
|
||||||
|
const roomName = this.state.groupRoom.displayname;
|
||||||
|
this._groupStore.updateGroupRoomAssociation(roomId, isPublic).catch((err) => {
|
||||||
|
console.error(`Error whilst changing visibility of ${roomId} in ${groupId} to ${isPublic}`, err);
|
||||||
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, {
|
||||||
|
title: _t("Something went wrong!"),
|
||||||
|
description: _t(
|
||||||
|
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.",
|
||||||
|
{roomName, groupId},
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}).finally(() => {
|
||||||
|
this.setState({
|
||||||
|
groupRoomPublicityLoading: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
if (this.state.removingRoom) {
|
const InlineSpinner = sdk.getComponent('elements.InlineSpinner');
|
||||||
|
if (this.state.groupRoomRemoveLoading || !this.state.groupRoom) {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
return <Spinner />;
|
return <div className="mx_MemberInfo">
|
||||||
|
<Spinner />
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let adminTools;
|
let adminTools;
|
||||||
|
@ -134,20 +176,50 @@ module.exports = React.createClass({
|
||||||
{ _t('Remove from community') }
|
{ _t('Remove from community') }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
|
<h3>
|
||||||
|
{ _t('Visibility in Room List') }
|
||||||
|
{ this.state.groupRoomPublicityLoading ?
|
||||||
|
<InlineSpinner /> : <div />
|
||||||
|
}
|
||||||
|
</h3>
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
<input type="radio"
|
||||||
|
value="public"
|
||||||
|
checked={this.state.groupRoom.isPublic}
|
||||||
|
onClick={this._changeGroupRoomPublicity}
|
||||||
|
/>
|
||||||
|
<div className="mx_MemberInfo_label_text">
|
||||||
|
{ _t('Visible to everyone') }
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
<input type="radio"
|
||||||
|
value="private"
|
||||||
|
checked={!this.state.groupRoom.isPublic}
|
||||||
|
onClick={this._changeGroupRoomPublicity}
|
||||||
|
/>
|
||||||
|
<div className="mx_MemberInfo_label_text">
|
||||||
|
{ _t('Only visible to community members') }
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const avatarUrl = this.context.matrixClient.mxcUrlToHttp(
|
const avatarUrl = this.context.matrixClient.mxcUrlToHttp(
|
||||||
this.props.groupRoom.avatarUrl,
|
this.state.groupRoom.avatarUrl,
|
||||||
36, 36, 'crop',
|
36, 36, 'crop',
|
||||||
);
|
);
|
||||||
|
|
||||||
const groupRoomName = this.props.groupRoom.displayname;
|
const groupRoomName = this.state.groupRoom.displayname;
|
||||||
const avatar = <BaseAvatar name={groupRoomName} width={36} height={36} url={avatarUrl} />;
|
const avatar = <BaseAvatar name={groupRoomName} width={36} height={36} url={avatarUrl} />;
|
||||||
return (
|
return (
|
||||||
<div className="mx_MemberInfo">
|
<div className="mx_MemberInfo">
|
||||||
<GeminiScrollbar autoshow={true}>
|
<GeminiScrollbar autoshow={true}>
|
||||||
<AccessibleButton className="mx_MemberInfo_cancel"onClick={this._onCancel}>
|
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
||||||
<img src="img/cancel.svg" width="18" height="18" className="mx_filterFlipColor" />
|
<img src="img/cancel.svg" width="18" height="18" className="mx_filterFlipColor" />
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<div className="mx_MemberInfo_avatar">
|
<div className="mx_MemberInfo_avatar">
|
||||||
|
@ -158,7 +230,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
<div className="mx_MemberInfo_profile">
|
<div className="mx_MemberInfo_profile">
|
||||||
<div className="mx_MemberInfo_profileField">
|
<div className="mx_MemberInfo_profileField">
|
||||||
{ this.props.groupRoom.canonical_alias }
|
{ this.state.groupRoom.canonical_alias }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ const GroupRoomTile = React.createClass({
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_group_room',
|
action: 'view_group_room',
|
||||||
groupId: this.props.groupId,
|
groupId: this.props.groupId,
|
||||||
groupRoom: this.props.groupRoom,
|
groupRoomId: this.props.groupRoom.roomId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -50,5 +50,6 @@ export function groupRoomFromApiObject(apiObject) {
|
||||||
numJoinedMembers: apiObject.num_joined_members,
|
numJoinedMembers: apiObject.num_joined_members,
|
||||||
worldReadable: apiObject.world_readable,
|
worldReadable: apiObject.world_readable,
|
||||||
guestCanJoin: apiObject.guest_can_join,
|
guestCanJoin: apiObject.guest_can_join,
|
||||||
|
isPublic: apiObject.is_public !== false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,8 +332,6 @@
|
||||||
"Rooms": "Rooms",
|
"Rooms": "Rooms",
|
||||||
"Low priority": "Low priority",
|
"Low priority": "Low priority",
|
||||||
"Historical": "Historical",
|
"Historical": "Historical",
|
||||||
"a room": "a room",
|
|
||||||
"Unnamed Room": "Unnamed Room",
|
|
||||||
"Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Unable to ascertain that the address this invite was sent to matches one associated with your account.",
|
"Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Unable to ascertain that the address this invite was sent to matches one associated with your account.",
|
||||||
"This invitation was sent to an email address which is not associated with this account:": "This invitation was sent to an email address which is not associated with this account:",
|
"This invitation was sent to an email address which is not associated with this account:": "This invitation was sent to an email address which is not associated with this account:",
|
||||||
"You may wish to login with a different account, or add this email to this account.": "You may wish to login with a different account, or add this email to this account.",
|
"You may wish to login with a different account, or add this email to this account.": "You may wish to login with a different account, or add this email to this account.",
|
||||||
|
@ -504,6 +502,11 @@
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
"Failed to remove room from community": "Failed to remove room from community",
|
"Failed to remove room from community": "Failed to remove room from community",
|
||||||
"Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s",
|
"Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s",
|
||||||
|
"Something went wrong!": "Something went wrong!",
|
||||||
|
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "The visibility of '%(roomName)s' in %(groupId)s could not be updated.",
|
||||||
|
"Visibility in Room List": "Visibility in Room List",
|
||||||
|
"Visible to everyone": "Visible to everyone",
|
||||||
|
"Only visible to community members": "Only visible to community members",
|
||||||
"Filter community rooms": "Filter community rooms",
|
"Filter community rooms": "Filter community rooms",
|
||||||
"Unknown Address": "Unknown Address",
|
"Unknown Address": "Unknown Address",
|
||||||
"NOTE: Apps are not end-to-end encrypted": "NOTE: Apps are not end-to-end encrypted",
|
"NOTE: Apps are not end-to-end encrypted": "NOTE: Apps are not end-to-end encrypted",
|
||||||
|
@ -582,7 +585,6 @@
|
||||||
"And %(count)s more...|other": "And %(count)s more...",
|
"And %(count)s more...|other": "And %(count)s more...",
|
||||||
"ex. @bob:example.com": "ex. @bob:example.com",
|
"ex. @bob:example.com": "ex. @bob:example.com",
|
||||||
"Add User": "Add User",
|
"Add User": "Add User",
|
||||||
"Something went wrong!": "Something went wrong!",
|
|
||||||
"Matrix ID": "Matrix ID",
|
"Matrix ID": "Matrix ID",
|
||||||
"Matrix Room ID": "Matrix Room ID",
|
"Matrix Room ID": "Matrix Room ID",
|
||||||
"email address": "email address",
|
"email address": "email address",
|
||||||
|
|
|
@ -141,9 +141,15 @@ export default class GroupStore extends EventEmitter {
|
||||||
return this._summary.user ? this._summary.user.is_privileged : null;
|
return this._summary.user ? this._summary.user.is_privileged : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
addRoomToGroup(roomId) {
|
addRoomToGroup(roomId, isPublic) {
|
||||||
return this._matrixClient
|
return this._matrixClient
|
||||||
.addRoomToGroup(this.groupId, roomId)
|
.addRoomToGroup(this.groupId, roomId, isPublic)
|
||||||
|
.then(this._fetchRooms.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGroupRoomAssociation(roomId, isPublic) {
|
||||||
|
return this._matrixClient
|
||||||
|
.updateGroupRoomAssociation(this.groupId, roomId, isPublic)
|
||||||
.then(this._fetchRooms.bind(this));
|
.then(this._fetchRooms.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue