From 791bc5e7ac5c33f6fa72202055cb18f6533c251c Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 22 Sep 2017 18:52:06 +0100 Subject: [PATCH] Create GroupSummaryStore for storing group summary stuff - Acts as a layer between GroupView and the group APIs that modify the summary individually. This allows for abstraction of getting the new summary once a successful API hit has been done. - The plan is to also control the avatar, topic, body of the summary via the same class --- src/components/structures/GroupView.js | 43 ++++++++++++---- src/i18n/strings/en_EN.json | 1 + src/stores/GroupSummaryStore.js | 71 ++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 src/stores/GroupSummaryStore.js diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 4f61bc4647..d3eb97180a 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -27,6 +27,8 @@ import AccessibleButton from '../views/elements/AccessibleButton'; import Modal from '../../Modal'; import classnames from 'classnames'; +import GroupSummaryStore from '../../stores/GroupSummaryStore'; + const RoomSummaryType = PropTypes.shape({ room_id: PropTypes.string.isRequired, profile: PropTypes.shape({ @@ -76,8 +78,8 @@ const CategoryRoomList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return MatrixClientPeg.get() - .addRoomToGroupSummary(this.props.groupId, addr.address) + return this.context.groupSummaryStore + .addRoomToGroupSummary(addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); })).then(() => { @@ -153,8 +155,7 @@ const FeaturedRoom = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - MatrixClientPeg.get().removeRoomFromGroupSummary( - this.props.groupId, + this.context.groupSummaryStore.removeRoomFromGroupSummary( this.props.summaryInfo.room_id, ).catch((err) => { console.error('Error whilst removing room from group summary', err); @@ -242,8 +243,8 @@ const RoleUserList = React.createClass({ if (!success) return; const errorList = []; Promise.all(addrs.map((addr) => { - return MatrixClientPeg.get() - .addUserToGroupSummary(this.props.groupId, addr.address) + return this.context.groupSummaryStore + .addUserToGroupSummary(addr.address) .catch(() => { errorList.push(addr.address); }) .reflect(); })).then(() => { @@ -317,8 +318,7 @@ const FeaturedUser = React.createClass({ onDeleteClicked: function(e) { e.preventDefault(); e.stopPropagation(); - MatrixClientPeg.get().removeUserFromGroupSummary( - this.props.groupId, + this.context.groupSummaryStore.removeUserFromGroupSummary( this.props.summaryInfo.user_id, ).catch((err) => { console.error('Error whilst removing user from group summary', err); @@ -364,6 +364,15 @@ const FeaturedUser = React.createClass({ }, }); +const GroupSummaryContext = { + groupSummaryStore: React.PropTypes.instanceOf(GroupSummaryStore).isRequired, +}; + +CategoryRoomList.contextTypes = GroupSummaryContext; +FeaturedRoom.contextTypes = GroupSummaryContext; +RoleUserList.contextTypes = GroupSummaryContext; +FeaturedUser.contextTypes = GroupSummaryContext; + export default React.createClass({ displayName: 'GroupView', @@ -371,6 +380,16 @@ export default React.createClass({ groupId: PropTypes.string.isRequired, }, + childContextTypes: { + groupSummaryStore: React.PropTypes.instanceOf(GroupSummaryStore), + }, + + getChildContext: function() { + return { + groupSummaryStore: this._groupSummaryStore, + }; + }, + getInitialState: function() { return { summary: null, @@ -411,12 +430,14 @@ export default React.createClass({ }, _loadGroupFromServer: function(groupId) { - MatrixClientPeg.get().getGroupSummary(groupId).done((res) => { + this._groupSummaryStore = new GroupSummaryStore(this.props.groupId); + this._groupSummaryStore.on('update', () => { this.setState({ - summary: res, + summary: this._groupSummaryStore.getSummary(), error: null, }); - }, (err) => { + }); + this._groupSummaryStore.on('error', (err) => { this.setState({ summary: null, error: err, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a0945d7f50..038d26ba4c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -876,6 +876,7 @@ "Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?", "Room name or alias": "Room name or alias", "You are an administrator of this group": "You are an administrator of this group", + "Failed to add the following rooms to the summary of %(groupId)s:": "Failed to add the following rooms to the summary of %(groupId)s:", "Failed to remove the room from the summary of %(groupId)s": "Failed to remove the room from the summary of %(groupId)s", "The room '%(roomName)' could not be removed from the summary.": "The room '%(roomName)' could not be removed from the summary.", "Failed to remove a user from the summary of %(groupId)s": "Failed to remove a user from the summary of %(groupId)s", diff --git a/src/stores/GroupSummaryStore.js b/src/stores/GroupSummaryStore.js new file mode 100644 index 0000000000..a26f0f2d61 --- /dev/null +++ b/src/stores/GroupSummaryStore.js @@ -0,0 +1,71 @@ +/* +Copyright 2017 New Vector Ltd + +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 EventEmitter from 'events'; +import MatrixClientPeg from '../MatrixClientPeg'; + +/** + * Stores the group summary for a room and provides an API to change it + */ +export default class GroupSummaryStore extends EventEmitter { + constructor(groupId) { + super(); + this._groupId = groupId; + this._summary = {}; + this._fetchSummary(); + } + + _fetchSummary() { + MatrixClientPeg.get().getGroupSummary(this._groupId).then((resp) => { + this._summary = resp; + this._notifyListeners(); + }).catch((err) => { + this.emit('error', err); + }); + } + + _notifyListeners() { + this.emit('update'); + } + + getSummary() { + return this._summary; + } + + addRoomToGroupSummary(roomId, categoryId) { + return MatrixClientPeg.get() + .addRoomToGroupSummary(this._groupId, roomId, categoryId) + .then(this._fetchSummary.bind(this)); + } + + addUserToGroupSummary(userId, roleId) { + return MatrixClientPeg.get() + .addUserToGroupSummary(this._groupId, userId, roleId) + .then(this._fetchSummary.bind(this)); + } + + removeRoomFromGroupSummary(roomId) { + return MatrixClientPeg.get() + .removeRoomFromGroupSummary(this._groupId, roomId) + .then(this._fetchSummary.bind(this)); + } + + removeUserFromGroupSummary(userId) { + return MatrixClientPeg.get() + .removeUserFromGroupSummary(this._groupId, userId) + .then(this._fetchSummary.bind(this)); + } +}