diff --git a/src/components/views/groups/GroupRoomInfo.js b/src/components/views/groups/GroupRoomInfo.js index 647651a0d8..bc1fc51853 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,46 @@ 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 +226,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 bffe3b3264..70e1af4834 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -158,6 +158,7 @@ "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing", "Failure to create room": "Failure to create room", "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", + "Unnamed Room": "Unnamed Room", "Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions", "Not a valid Riot keyfile": "Not a valid Riot keyfile", "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", @@ -328,7 +329,6 @@ "Rooms": "Rooms", "Low priority": "Low priority", "Historical": "Historical", - "Unnamed Room": "Unnamed Room", "a room": "a 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:", @@ -491,13 +491,15 @@ "Failed to withdraw invitation": "Failed to withdraw invitation", "Failed to remove user from community": "Failed to remove user from community", "Filter community members": "Filter community members", - "Filter community rooms": "Filter community rooms", - "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", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Are you sure you want to remove '%(roomName)s' from %(groupId)s?", "Removing a room from the community will also remove it from the community page.": "Removing a room from the community will also remove it from the community page.", "Remove": "Remove", - "Remove this room from the community": "Remove this room from the 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", + "Visibility in Room List": "Visibility in Room List", + "Visible to everyone": "Visible to everyone", + "Only visible to group members": "Only visible to group 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", "Do you want to load widget from URL:": "Do you want to load widget from URL:", 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)); }