diff --git a/src/components/views/groups/GroupRoomInfo.js b/src/components/views/groups/GroupRoomInfo.js index 647651a0d8..3f0b0067d2 100644 --- a/src/components/views/groups/GroupRoomInfo.js +++ b/src/components/views/groups/GroupRoomInfo.js @@ -21,7 +21,6 @@ import dis from '../../../dispatcher'; import Modal from '../../../Modal'; import sdk from '../../../index'; import { _t } from '../../../languageHandler'; -import { GroupRoomType } from '../../../groups'; import GroupStoreCache from '../../../stores/GroupStoreCache'; import GeminiScrollbar from 'react-gemini-scrollbar'; @@ -34,13 +33,15 @@ module.exports = React.createClass({ propTypes: { groupId: PropTypes.string, - groupRoom: GroupRoomType, + groupRoomId: PropTypes.string, }, getInitialState: function() { return { - removingRoom: false, isUserPrivilegedInGroup: null, + groupRoom: null, + groupRoomPublicityLoading: false, + groupRoomRemoveLoading: false, }; }, @@ -55,6 +56,10 @@ module.exports = React.createClass({ } }, + componentWillUnmount() { + this._unregisterGroupStore(); + }, + _initGroupStore(groupId) { this._groupStore = GroupStoreCache.getGroupStore( 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() { this.setState({ isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), }); + this._updateGroupRoom(); }, _onRemove: function(e) { const groupId = this.props.groupId; - const roomName = this.props.groupRoom.displayname; + const roomName = this.state.groupRoom.displayname; e.preventDefault(); e.stopPropagation(); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); @@ -86,9 +100,9 @@ module.exports = React.createClass({ button: _t("Remove"), onFinished: (proceed) => { if (!proceed) return; - this.setState({removingRoom: true}); + this.setState({groupRoomRemoveLoading: true}); const groupId = this.props.groupId; - const roomId = this.props.groupRoom.roomId; + const roomId = this.props.groupRoomId; this._groupStore.removeRoomFromGroup(roomId).then(() => { dis.dispatch({ action: "view_group_room_list", @@ -103,7 +117,7 @@ module.exports = React.createClass({ ), }); }).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() { const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); const EmojiText = sdk.getComponent('elements.EmojiText'); 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"); - return ; + return
+ +
; } let adminTools; @@ -134,20 +176,50 @@ module.exports = React.createClass({ { _t('Remove from community') } +

+ { _t('Visibility in Room List') } + { this.state.groupRoomPublicityLoading ? + :
+ } +

+
+ +
+
+ +
; } const avatarUrl = this.context.matrixClient.mxcUrlToHttp( - this.props.groupRoom.avatarUrl, + this.state.groupRoom.avatarUrl, 36, 36, 'crop', ); - const groupRoomName = this.props.groupRoom.displayname; + const groupRoomName = this.state.groupRoom.displayname; const avatar = ; return (
- +
@@ -158,7 +230,7 @@ module.exports = React.createClass({
- { this.props.groupRoom.canonical_alias } + { this.state.groupRoom.canonical_alias }
diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index e445f06044..907ce93a4a 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -33,7 +33,7 @@ const GroupRoomTile = React.createClass({ dis.dispatch({ action: 'view_group_room', groupId: this.props.groupId, - groupRoom: this.props.groupRoom, + groupRoomId: this.props.groupRoom.roomId, }); }, diff --git a/src/groups.js b/src/groups.js index 3c80677b0c..6c266e0fb6 100644 --- a/src/groups.js +++ b/src/groups.js @@ -50,5 +50,6 @@ export function groupRoomFromApiObject(apiObject) { numJoinedMembers: apiObject.num_joined_members, worldReadable: apiObject.world_readable, guestCanJoin: apiObject.guest_can_join, + isPublic: apiObject.is_public !== false, }; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 4254303b23..bc2f0754a7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -332,8 +332,6 @@ "Rooms": "Rooms", "Low priority": "Low priority", "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.", "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.", @@ -504,6 +502,11 @@ "Remove": "Remove", "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", + "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", "Unknown Address": "Unknown Address", "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...", "ex. @bob:example.com": "ex. @bob:example.com", "Add User": "Add User", - "Something went wrong!": "Something went wrong!", "Matrix ID": "Matrix ID", "Matrix Room ID": "Matrix Room ID", "email address": "email address", diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index 3afac3c049..2578d373a7 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -141,9 +141,15 @@ export default class GroupStore extends EventEmitter { return this._summary.user ? this._summary.user.is_privileged : null; } - addRoomToGroup(roomId) { + addRoomToGroup(roomId, isPublic) { 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)); }