diff --git a/src/GroupAddressPicker.js b/src/GroupAddressPicker.js index 0b039074f0..595f0cfe46 100644 --- a/src/GroupAddressPicker.js +++ b/src/GroupAddressPicker.js @@ -96,13 +96,6 @@ function _onGroupInviteFinished(groupId, addrs) { title: _t("Failed to invite the following users to %(groupId)s:", {groupId: groupId}), description: errorList.join(", "), }); - } else { - const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createTrackedDialog('Group invitations sent', '', QuestionDialog, { - title: _t("Invites sent"), - description: _t("Your community invitations have been sent."), - hasCancelButton: false, - }); } }).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index 899543238c..511af37166 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -17,7 +17,7 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -import { groupMemberFromApiObject } from '../../../groups'; +import GroupStoreCache from '../../../stores/GroupStoreCache'; import GeminiScrollbar from 'react-gemini-scrollbar'; import PropTypes from 'prop-types'; import withMatrixClient from '../../../wrappers/withMatrixClient'; @@ -27,15 +27,16 @@ const INITIAL_LOAD_NUM_MEMBERS = 30; export default withMatrixClient(React.createClass({ displayName: 'GroupMemberList', - propTypes: { + contextTypes: { matrixClient: PropTypes.object.isRequired, + }, + + propTypes: { groupId: PropTypes.string.isRequired, }, getInitialState: function() { return { - fetching: false, - fetchingInvitedMembers: false, members: null, invitedMembers: null, truncateAt: INITIAL_LOAD_NUM_MEMBERS, @@ -44,36 +45,23 @@ export default withMatrixClient(React.createClass({ componentWillMount: function() { this._unmounted = false; - this._fetchMembers(); + this._initGroupStore(this.props.groupId); + }, + + _initGroupStore: function(groupId) { + this._groupStore = GroupStoreCache.getGroupStore(this.context.matrixClient, groupId); + this._groupStore.on('update', () => { + this._fetchMembers(); + }); + this._groupStore.on('error', (err) => { + console.error(err); + }); }, _fetchMembers: function() { this.setState({ - fetching: true, - fetchingInvitedMembers: true, - }); - this.props.matrixClient.getGroupUsers(this.props.groupId).then((result) => { - this.setState({ - members: result.chunk.map((apiMember) => { - return groupMemberFromApiObject(apiMember); - }), - fetching: false, - }); - }).catch((e) => { - this.setState({fetching: false}); - console.error("Failed to get group member list: " + e); - }); - - this.props.matrixClient.getGroupInvitedUsers(this.props.groupId).then((result) => { - this.setState({ - invitedMembers: result.chunk.map((apiMember) => { - return groupMemberFromApiObject(apiMember); - }), - fetchingInvitedMembers: false, - }); - }).catch((e) => { - this.setState({fetchingInvitedMembers: false}); - console.error("Failed to get group invited member list: " + e); + members: this._groupStore.getGroupMembers(), + invitedMembers: this._groupStore.getGroupInvitedMembers(), }); }, diff --git a/src/components/views/groups/GroupRoomList.js b/src/components/views/groups/GroupRoomList.js index 5dd4de110e..3fcfedd486 100644 --- a/src/components/views/groups/GroupRoomList.js +++ b/src/components/views/groups/GroupRoomList.js @@ -16,7 +16,6 @@ limitations under the License. import React from 'react'; import { _t } from '../../../languageHandler'; import sdk from '../../../index'; -import { groupRoomFromApiObject } from '../../../groups'; import GroupStoreCache from '../../../stores/GroupStoreCache'; import GeminiScrollbar from 'react-gemini-scrollbar'; import PropTypes from 'prop-types'; @@ -63,9 +62,7 @@ export default React.createClass({ _fetchRooms: function() { if (this._unmounted) return; this.setState({ - rooms: this._groupStore.getGroupRooms().map((apiRoom) => { - return groupRoomFromApiObject(apiRoom); - }), + rooms: this._groupStore.getGroupRooms(), }); }, diff --git a/src/stores/GroupStore.js b/src/stores/GroupStore.js index da27bd10e8..1da1c35a2b 100644 --- a/src/stores/GroupStore.js +++ b/src/stores/GroupStore.js @@ -15,6 +15,7 @@ limitations under the License. */ import EventEmitter from 'events'; +import { groupMemberFromApiObject, groupRoomFromApiObject } from '../groups'; import FlairStore from './FlairStore'; /** @@ -30,6 +31,29 @@ export default class GroupStore extends EventEmitter { this._rooms = []; this._fetchSummary(); this._fetchRooms(); + this._fetchMembers(); + } + + _fetchMembers() { + this._matrixClient.getGroupUsers(this.groupId).then((result) => { + this._members = result.chunk.map((apiMember) => { + return groupMemberFromApiObject(apiMember); + }); + this._notifyListeners(); + }).catch((err) => { + console.error("Failed to get group member list: " + err); + this.emit('error', err); + }); + + this._matrixClient.getGroupInvitedUsers(this.groupId).then((result) => { + this._invitedMembers = result.chunk.map((apiMember) => { + return groupMemberFromApiObject(apiMember); + }); + this._notifyListeners(); + }).catch((err) => { + console.error("Failed to get group invited member list: " + err); + this.emit('error', err); + }); } _fetchSummary() { @@ -43,7 +67,9 @@ export default class GroupStore extends EventEmitter { _fetchRooms() { this._matrixClient.getGroupRooms(this.groupId).then((resp) => { - this._rooms = resp.chunk; + this._rooms = resp.chunk.map((apiRoom) => { + return groupRoomFromApiObject(apiRoom); + }); this._notifyListeners(); }).catch((err) => { this.emit('error', err); @@ -62,6 +88,14 @@ export default class GroupStore extends EventEmitter { return this._rooms; } + getGroupMembers( ) { + return this._members; + } + + getGroupInvitedMembers( ) { + return this._invitedMembers; + } + getGroupPublicity() { return this._summary.user ? this._summary.user.is_publicised : null; } @@ -84,6 +118,11 @@ export default class GroupStore extends EventEmitter { .then(this._fetchRooms.bind(this)); } + inviteUserToGroup(userId) { + return this._matrixClient.inviteUserToGroup(this.groupId, userId) + .then(this._fetchMembers.bind(this)); + } + addRoomToGroupSummary(roomId, categoryId) { return this._matrixClient .addRoomToGroupSummary(this.groupId, roomId, categoryId) diff --git a/src/utils/MultiInviter.js b/src/utils/MultiInviter.js index e090f3d9e2..02c413ac83 100644 --- a/src/utils/MultiInviter.js +++ b/src/utils/MultiInviter.js @@ -18,6 +18,7 @@ limitations under the License. import MatrixClientPeg from '../MatrixClientPeg'; import {getAddressType} from '../UserAddress'; import {inviteToRoom} from '../RoomInvite'; +import GroupStoreCache from '../stores/GroupStoreCache'; import Promise from 'bluebird'; /** @@ -117,7 +118,9 @@ export default class MultiInviter { let doInvite; if (this.groupId !== null) { - doInvite = MatrixClientPeg.get().inviteUserToGroup(this.groupId, addr); + doInvite = GroupStoreCache + .getGroupStore(MatrixClientPeg.get(), this.groupId) + .inviteUserToGroup(addr); } else { doInvite = inviteToRoom(this.roomId, addr); }