Refactor GroupStores into one global GroupStore
Take a step closer to a flux-like architecture for group data, for the purposes of providing features that require it. Now the app has a single GroupStore that can be poked to fetch updates for a particular group.
This commit is contained in:
parent
fba8a7d7d6
commit
023daef4b7
13 changed files with 245 additions and 281 deletions
|
@ -19,7 +19,7 @@ import sdk from './';
|
|||
import MultiInviter from './utils/MultiInviter';
|
||||
import { _t } from './languageHandler';
|
||||
import MatrixClientPeg from './MatrixClientPeg';
|
||||
import GroupStoreCache from './stores/GroupStoreCache';
|
||||
import GroupStore from './stores/GroupStore';
|
||||
|
||||
export function showGroupInviteDialog(groupId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -116,11 +116,10 @@ function _onGroupInviteFinished(groupId, addrs) {
|
|||
|
||||
function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) {
|
||||
const matrixClient = MatrixClientPeg.get();
|
||||
const groupStore = GroupStoreCache.getGroupStore(groupId);
|
||||
const errorList = [];
|
||||
return Promise.all(addrs.map((addr) => {
|
||||
return groupStore
|
||||
.addRoomToGroup(addr.address, addRoomsPublicly)
|
||||
return GroupStore
|
||||
.addRoomToGroup(groupId, addr.address, addRoomsPublicly)
|
||||
.catch(() => { errorList.push(addr.address); })
|
||||
.then(() => {
|
||||
const roomId = addr.address;
|
||||
|
|
|
@ -27,7 +27,6 @@ import AccessibleButton from '../views/elements/AccessibleButton';
|
|||
import Modal from '../../Modal';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import GroupStoreCache from '../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../stores/GroupStore';
|
||||
import FlairStore from '../../stores/FlairStore';
|
||||
import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||
|
@ -93,8 +92,8 @@ const CategoryRoomList = React.createClass({
|
|||
if (!success) return;
|
||||
const errorList = [];
|
||||
Promise.all(addrs.map((addr) => {
|
||||
return this.context.groupStore
|
||||
.addRoomToGroupSummary(addr.address)
|
||||
return GroupStore
|
||||
.addRoomToGroupSummary(this.props.groupId, addr.address)
|
||||
.catch(() => { errorList.push(addr.address); })
|
||||
.reflect();
|
||||
})).then(() => {
|
||||
|
@ -174,7 +173,8 @@ const FeaturedRoom = React.createClass({
|
|||
onDeleteClicked: function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.context.groupStore.removeRoomFromGroupSummary(
|
||||
GroupStore.removeRoomFromGroupSummary(
|
||||
this.props.groupId,
|
||||
this.props.summaryInfo.room_id,
|
||||
).catch((err) => {
|
||||
console.error('Error whilst removing room from group summary', err);
|
||||
|
@ -269,7 +269,7 @@ const RoleUserList = React.createClass({
|
|||
if (!success) return;
|
||||
const errorList = [];
|
||||
Promise.all(addrs.map((addr) => {
|
||||
return this.context.groupStore
|
||||
return GroupStore
|
||||
.addUserToGroupSummary(addr.address)
|
||||
.catch(() => { errorList.push(addr.address); })
|
||||
.reflect();
|
||||
|
@ -344,7 +344,8 @@ const FeaturedUser = React.createClass({
|
|||
onDeleteClicked: function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.context.groupStore.removeUserFromGroupSummary(
|
||||
GroupStore.removeUserFromGroupSummary(
|
||||
this.props.groupId,
|
||||
this.props.summaryInfo.user_id,
|
||||
).catch((err) => {
|
||||
console.error('Error whilst removing user from group summary', err);
|
||||
|
@ -390,15 +391,6 @@ const FeaturedUser = React.createClass({
|
|||
},
|
||||
});
|
||||
|
||||
const GroupContext = {
|
||||
groupStore: PropTypes.instanceOf(GroupStore).isRequired,
|
||||
};
|
||||
|
||||
CategoryRoomList.contextTypes = GroupContext;
|
||||
FeaturedRoom.contextTypes = GroupContext;
|
||||
RoleUserList.contextTypes = GroupContext;
|
||||
FeaturedUser.contextTypes = GroupContext;
|
||||
|
||||
const GROUP_JOINPOLICY_OPEN = "open";
|
||||
const GROUP_JOINPOLICY_INVITE = "invite";
|
||||
|
||||
|
@ -415,12 +407,6 @@ export default React.createClass({
|
|||
groupStore: PropTypes.instanceOf(GroupStore),
|
||||
},
|
||||
|
||||
getChildContext: function() {
|
||||
return {
|
||||
groupStore: this._groupStore,
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
summary: null,
|
||||
|
@ -440,6 +426,7 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._unmounted = false;
|
||||
this._matrixClient = MatrixClientPeg.get();
|
||||
this._matrixClient.on("Group.myMembership", this._onGroupMyMembership);
|
||||
|
||||
|
@ -448,8 +435,8 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._unmounted = true;
|
||||
this._matrixClient.removeListener("Group.myMembership", this._onGroupMyMembership);
|
||||
this._groupStore.removeAllListeners();
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
|
@ -464,8 +451,7 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
_onGroupMyMembership: function(group) {
|
||||
if (group.groupId !== this.props.groupId) return;
|
||||
|
||||
if (this._unmounted || group.groupId !== this.props.groupId) return;
|
||||
if (group.myMembership === 'leave') {
|
||||
// Leave settings - the user might have clicked the "Leave" button
|
||||
this._closeSettings();
|
||||
|
@ -478,34 +464,11 @@ export default React.createClass({
|
|||
if (group && group.inviter && group.inviter.userId) {
|
||||
this._fetchInviterProfile(group.inviter.userId);
|
||||
}
|
||||
this._groupStore = GroupStoreCache.getGroupStore(groupId);
|
||||
this._groupStore.registerListener(() => {
|
||||
const summary = this._groupStore.getSummary();
|
||||
if (summary.profile) {
|
||||
// Default profile fields should be "" for later sending to the server (which
|
||||
// requires that the fields are strings, not null)
|
||||
["avatar_url", "long_description", "name", "short_description"].forEach((k) => {
|
||||
summary.profile[k] = summary.profile[k] || "";
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
summary,
|
||||
summaryLoading: !this._groupStore.isStateReady(GroupStore.STATE_KEY.Summary),
|
||||
isGroupPublicised: this._groupStore.getGroupPublicity(),
|
||||
isUserPrivileged: this._groupStore.isUserPrivileged(),
|
||||
groupRooms: this._groupStore.getGroupRooms(),
|
||||
groupRoomsLoading: !this._groupStore.isStateReady(GroupStore.STATE_KEY.GroupRooms),
|
||||
isUserMember: this._groupStore.getGroupMembers().some(
|
||||
(m) => m.userId === this._matrixClient.credentials.userId,
|
||||
),
|
||||
error: null,
|
||||
});
|
||||
if (this.props.groupIsNew && firstInit) {
|
||||
this._onEditClick();
|
||||
}
|
||||
});
|
||||
GroupStore.registerListener(groupId, this.onGroupStoreUpdated.bind(this, firstInit));
|
||||
let willDoOnboarding = false;
|
||||
this._groupStore.on('error', (err) => {
|
||||
// XXX: This should be more fluxy - let's get the error from GroupStore .getError or something
|
||||
GroupStore.on('error', (err, errorGroupId) => {
|
||||
if (this._unmounted || groupId !== errorGroupId) return;
|
||||
if (err.errcode === 'M_GUEST_ACCESS_FORBIDDEN' && !willDoOnboarding) {
|
||||
dis.dispatch({
|
||||
action: 'do_after_sync_prepared',
|
||||
|
@ -524,11 +487,40 @@ export default React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
onGroupStoreUpdated(firstInit) {
|
||||
if (this._unmounted) return;
|
||||
const summary = GroupStore.getSummary(this.props.groupId);
|
||||
if (summary.profile) {
|
||||
// Default profile fields should be "" for later sending to the server (which
|
||||
// requires that the fields are strings, not null)
|
||||
["avatar_url", "long_description", "name", "short_description"].forEach((k) => {
|
||||
summary.profile[k] = summary.profile[k] || "";
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
summary,
|
||||
summaryLoading: !GroupStore.isStateReady(this.props.groupId, GroupStore.STATE_KEY.Summary),
|
||||
isGroupPublicised: GroupStore.getGroupPublicity(this.props.groupId),
|
||||
isUserPrivileged: GroupStore.isUserPrivileged(this.props.groupId),
|
||||
groupRooms: GroupStore.getGroupRooms(this.props.groupId),
|
||||
groupRoomsLoading: !GroupStore.isStateReady(this.props.groupId, GroupStore.STATE_KEY.GroupRooms),
|
||||
isUserMember: GroupStore.getGroupMembers(this.props.groupId).some(
|
||||
(m) => m.userId === this._matrixClient.credentials.userId,
|
||||
),
|
||||
error: null,
|
||||
});
|
||||
// XXX: This might not work but this.props.groupIsNew unused anyway
|
||||
if (this.props.groupIsNew && firstInit) {
|
||||
this._onEditClick();
|
||||
}
|
||||
},
|
||||
|
||||
_fetchInviterProfile(userId) {
|
||||
this.setState({
|
||||
inviterProfileBusy: true,
|
||||
});
|
||||
this._matrixClient.getProfileInfo(userId).then((resp) => {
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
inviterProfile: {
|
||||
avatarUrl: resp.avatar_url,
|
||||
|
@ -538,6 +530,7 @@ export default React.createClass({
|
|||
}).catch((e) => {
|
||||
console.error('Error getting group inviter profile', e);
|
||||
}).finally(() => {
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
inviterProfileBusy: false,
|
||||
});
|
||||
|
@ -677,7 +670,7 @@ export default React.createClass({
|
|||
// spinner disappearing after we have fetched new group data.
|
||||
await Promise.delay(500);
|
||||
|
||||
this._groupStore.acceptGroupInvite().then(() => {
|
||||
GroupStore.acceptGroupInvite(this.props.groupId).then(() => {
|
||||
// don't reset membershipBusy here: wait for the membership change to come down the sync
|
||||
}).catch((e) => {
|
||||
this.setState({membershipBusy: false});
|
||||
|
@ -696,7 +689,7 @@ export default React.createClass({
|
|||
// spinner disappearing after we have fetched new group data.
|
||||
await Promise.delay(500);
|
||||
|
||||
this._groupStore.leaveGroup().then(() => {
|
||||
GroupStore.leaveGroup(this.props.groupId).then(() => {
|
||||
// don't reset membershipBusy here: wait for the membership change to come down the sync
|
||||
}).catch((e) => {
|
||||
this.setState({membershipBusy: false});
|
||||
|
@ -715,7 +708,7 @@ export default React.createClass({
|
|||
// spinner disappearing after we have fetched new group data.
|
||||
await Promise.delay(500);
|
||||
|
||||
this._groupStore.joinGroup().then(() => {
|
||||
GroupStore.joinGroup(this.props.groupId).then(() => {
|
||||
// don't reset membershipBusy here: wait for the membership change to come down the sync
|
||||
}).catch((e) => {
|
||||
this.setState({membershipBusy: false});
|
||||
|
@ -743,7 +736,7 @@ export default React.createClass({
|
|||
// spinner disappearing after we have fetched new group data.
|
||||
await Promise.delay(500);
|
||||
|
||||
this._groupStore.leaveGroup().then(() => {
|
||||
GroupStore.leaveGroup(this.props.groupId).then(() => {
|
||||
// don't reset membershipBusy here: wait for the membership change to come down the sync
|
||||
}).catch((e) => {
|
||||
this.setState({membershipBusy: false});
|
||||
|
|
|
@ -27,7 +27,7 @@ import Analytics from '../../Analytics';
|
|||
import RateLimitedFunc from '../../ratelimitedfunc';
|
||||
import AccessibleButton from '../../components/views/elements/AccessibleButton';
|
||||
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||
import GroupStoreCache from '../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../stores/GroupStore';
|
||||
|
||||
import { formatCount } from '../../utils/FormattingUtils';
|
||||
|
||||
|
@ -120,7 +120,7 @@ module.exports = React.createClass({
|
|||
if (this.context.matrixClient) {
|
||||
this.context.matrixClient.removeListener("RoomState.members", this.onRoomStateMember);
|
||||
}
|
||||
this._unregisterGroupStore();
|
||||
this._unregisterGroupStore(this.props.groupId);
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -132,26 +132,23 @@ module.exports = React.createClass({
|
|||
|
||||
componentWillReceiveProps(newProps) {
|
||||
if (newProps.groupId !== this.props.groupId) {
|
||||
this._unregisterGroupStore();
|
||||
this._unregisterGroupStore(this.props.groupId);
|
||||
this._initGroupStore(newProps.groupId);
|
||||
}
|
||||
},
|
||||
|
||||
_initGroupStore(groupId) {
|
||||
if (!groupId) return;
|
||||
this._groupStore = GroupStoreCache.getGroupStore(groupId);
|
||||
this._groupStore.registerListener(this.onGroupStoreUpdated);
|
||||
GroupStore.registerListener(groupId, this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
_unregisterGroupStore() {
|
||||
if (this._groupStore) {
|
||||
this._groupStore.unregisterListener(this.onGroupStoreUpdated);
|
||||
}
|
||||
GroupStore.unregisterListener(this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
onGroupStoreUpdated: function() {
|
||||
this.setState({
|
||||
isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(),
|
||||
isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import sdk from '../../../index';
|
|||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import Promise from 'bluebird';
|
||||
import { addressTypes, getAddressType } from '../../../UserAddress.js';
|
||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../../stores/GroupStore';
|
||||
|
||||
const TRUNCATE_QUERY_LIST = 40;
|
||||
const QUERY_USER_DIRECTORY_DEBOUNCE_MS = 200;
|
||||
|
@ -243,9 +243,8 @@ module.exports = React.createClass({
|
|||
|
||||
_doNaiveGroupRoomSearch: function(query) {
|
||||
const lowerCaseQuery = query.toLowerCase();
|
||||
const groupStore = GroupStoreCache.getGroupStore(this.props.groupId);
|
||||
const results = [];
|
||||
groupStore.getGroupRooms().forEach((r) => {
|
||||
GroupStore.getGroupRooms(this.props.groupId).forEach((r) => {
|
||||
const nameMatch = (r.name || '').toLowerCase().includes(lowerCaseQuery);
|
||||
const topicMatch = (r.topic || '').toLowerCase().includes(lowerCaseQuery);
|
||||
const aliasMatch = (r.canonical_alias || '').toLowerCase().includes(lowerCaseQuery);
|
||||
|
|
|
@ -23,7 +23,7 @@ import Modal from '../../../Modal';
|
|||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { GroupMemberType } from '../../../groups';
|
||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../../stores/GroupStore';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -47,33 +47,37 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._unmounted = false;
|
||||
this._initGroupStore(this.props.groupId);
|
||||
},
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
if (newProps.groupId !== this.props.groupId) {
|
||||
this._unregisterGroupStore();
|
||||
this._unregisterGroupStore(this.props.groupId);
|
||||
this._initGroupStore(newProps.groupId);
|
||||
}
|
||||
},
|
||||
|
||||
_initGroupStore(groupId) {
|
||||
this._groupStore = GroupStoreCache.getGroupStore(this.props.groupId);
|
||||
this._groupStore.registerListener(this.onGroupStoreUpdated);
|
||||
componentWillUnmount() {
|
||||
this._unmounted = true;
|
||||
this._unregisterGroupStore(this.props.groupId);
|
||||
},
|
||||
|
||||
_unregisterGroupStore() {
|
||||
if (this._groupStore) {
|
||||
this._groupStore.unregisterListener(this.onGroupStoreUpdated);
|
||||
}
|
||||
_initGroupStore(groupId) {
|
||||
GroupStore.registerListener(groupId, this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
_unregisterGroupStore(groupId) {
|
||||
GroupStore.unregisterListener(this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
onGroupStoreUpdated: function() {
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
isUserInvited: this._groupStore.getGroupInvitedMembers().some(
|
||||
isUserInvited: GroupStore.getGroupInvitedMembers(this.props.groupId).some(
|
||||
(m) => m.userId === this.props.groupMember.userId,
|
||||
),
|
||||
isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(),
|
||||
isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import sdk from '../../../index';
|
||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../../stores/GroupStore';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||
|
@ -42,9 +42,12 @@ export default React.createClass({
|
|||
this._initGroupStore(this.props.groupId);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._unmounted = true;
|
||||
},
|
||||
|
||||
_initGroupStore: function(groupId) {
|
||||
this._groupStore = GroupStoreCache.getGroupStore(groupId);
|
||||
this._groupStore.registerListener(() => {
|
||||
GroupStore.registerListener(groupId, () => {
|
||||
this._fetchMembers();
|
||||
});
|
||||
},
|
||||
|
@ -52,8 +55,8 @@ export default React.createClass({
|
|||
_fetchMembers: function() {
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
members: this._groupStore.getGroupMembers(),
|
||||
invitedMembers: this._groupStore.getGroupInvitedMembers(),
|
||||
members: GroupStore.getGroupMembers(this.props.groupId),
|
||||
invitedMembers: GroupStore.getGroupInvitedMembers(this.props.groupId),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import sdk from '../../../index';
|
||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../../stores/GroupStore';
|
||||
import { _t } from '../../../languageHandler.js';
|
||||
|
||||
|
@ -41,11 +40,10 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
_initGroupStore: function(groupId) {
|
||||
this._groupStore = GroupStoreCache.getGroupStore(groupId);
|
||||
this._groupStore.registerListener(() => {
|
||||
GroupStore.registerListener(groupId, () => {
|
||||
this.setState({
|
||||
isGroupPublicised: this._groupStore.getGroupPublicity(),
|
||||
ready: this._groupStore.isStateReady(GroupStore.STATE_KEY.Summary),
|
||||
isGroupPublicised: GroupStore.getGroupPublicity(groupId),
|
||||
ready: GroupStore.isStateReady(groupId, GroupStore.STATE_KEY.Summary),
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -57,7 +55,7 @@ export default React.createClass({
|
|||
// Optimistic early update
|
||||
isGroupPublicised: !this.state.isGroupPublicised,
|
||||
});
|
||||
this._groupStore.setGroupPublicity(!this.state.isGroupPublicised).then(() => {
|
||||
GroupStore.setGroupPublicity(this.props.groupId, !this.state.isGroupPublicised).then(() => {
|
||||
this.setState({
|
||||
busy: false,
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ import dis from '../../../dispatcher';
|
|||
import Modal from '../../../Modal';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../../stores/GroupStore';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'GroupRoomInfo',
|
||||
|
@ -50,29 +50,26 @@ module.exports = React.createClass({
|
|||
|
||||
componentWillReceiveProps(newProps) {
|
||||
if (newProps.groupId !== this.props.groupId) {
|
||||
this._unregisterGroupStore();
|
||||
this._unregisterGroupStore(this.props.groupId);
|
||||
this._initGroupStore(newProps.groupId);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
this._unregisterGroupStore();
|
||||
this._unregisterGroupStore(this.props.groupId);
|
||||
},
|
||||
|
||||
_initGroupStore(groupId) {
|
||||
this._groupStore = GroupStoreCache.getGroupStore(this.props.groupId);
|
||||
this._groupStore.registerListener(this.onGroupStoreUpdated);
|
||||
GroupStore.registerListener(groupId, this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
_unregisterGroupStore() {
|
||||
if (this._groupStore) {
|
||||
this._groupStore.unregisterListener(this.onGroupStoreUpdated);
|
||||
}
|
||||
_unregisterGroupStore(groupId) {
|
||||
GroupStore.unregisterListener(this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
_updateGroupRoom() {
|
||||
this.setState({
|
||||
groupRoom: this._groupStore.getGroupRooms().find(
|
||||
groupRoom: GroupStore.getGroupRooms(this.props.groupId).find(
|
||||
(r) => r.roomId === this.props.groupRoomId,
|
||||
),
|
||||
});
|
||||
|
@ -80,7 +77,7 @@ module.exports = React.createClass({
|
|||
|
||||
onGroupStoreUpdated: function() {
|
||||
this.setState({
|
||||
isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(),
|
||||
isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId),
|
||||
});
|
||||
this._updateGroupRoom();
|
||||
},
|
||||
|
@ -100,7 +97,7 @@ module.exports = React.createClass({
|
|||
this.setState({groupRoomRemoveLoading: true});
|
||||
const groupId = this.props.groupId;
|
||||
const roomId = this.props.groupRoomId;
|
||||
this._groupStore.removeRoomFromGroup(roomId).then(() => {
|
||||
GroupStore.removeRoomFromGroup(this.props.groupId, roomId).then(() => {
|
||||
dis.dispatch({
|
||||
action: "view_group_room_list",
|
||||
});
|
||||
|
@ -134,7 +131,7 @@ module.exports = React.createClass({
|
|||
const groupId = this.props.groupId;
|
||||
const roomId = this.props.groupRoomId;
|
||||
const roomName = this.state.groupRoom.displayname;
|
||||
this._groupStore.updateGroupRoomVisibility(roomId, isPublic).catch((err) => {
|
||||
GroupStore.updateGroupRoomVisibility(this.props.groupId, 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, {
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import sdk from '../../../index';
|
||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../../stores/GroupStore';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const INITIAL_LOAD_NUM_ROOMS = 30;
|
||||
|
@ -39,22 +39,31 @@ export default React.createClass({
|
|||
this._initGroupStore(this.props.groupId);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
this._unmounted = true;
|
||||
this._unregisterGroupStore();
|
||||
},
|
||||
|
||||
_unregisterGroupStore() {
|
||||
GroupStore.unregisterListener(this.onGroupStoreUpdated);
|
||||
},
|
||||
|
||||
_initGroupStore: function(groupId) {
|
||||
this._groupStore = GroupStoreCache.getGroupStore(groupId);
|
||||
this._groupStore.registerListener(() => {
|
||||
this._fetchRooms();
|
||||
});
|
||||
this._groupStore.on('error', (err) => {
|
||||
GroupStore.registerListener(groupId, this.onGroupStoreUpdated);
|
||||
// XXX: This should be more fluxy - let's get the error from GroupStore .getError or something
|
||||
// XXX: This is also leaked - we should remove it when unmounting
|
||||
GroupStore.on('error', (err, errorGroupId) => {
|
||||
if (errorGroupId !== groupId) return;
|
||||
this.setState({
|
||||
rooms: null,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_fetchRooms: function() {
|
||||
onGroupStoreUpdated: function() {
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
rooms: this._groupStore.getGroupRooms(),
|
||||
rooms: GroupStore.getGroupRooms(this.props.groupId),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import DMRoomMap from '../../../utils/DMRoomMap';
|
|||
const Receipt = require('../../../utils/Receipt');
|
||||
import TagOrderStore from '../../../stores/TagOrderStore';
|
||||
import RoomListStore from '../../../stores/RoomListStore';
|
||||
import GroupStoreCache from '../../../stores/GroupStoreCache';
|
||||
import GroupStore from '../../../stores/GroupStore';
|
||||
|
||||
const HIDE_CONFERENCE_CHANS = true;
|
||||
const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/;
|
||||
|
@ -83,8 +83,6 @@ module.exports = React.createClass({
|
|||
cli.on("Group.myMembership", this._onGroupMyMembership);
|
||||
|
||||
const dmRoomMap = DMRoomMap.shared();
|
||||
this._groupStores = {};
|
||||
this._groupStoreTokens = [];
|
||||
// A map between tags which are group IDs and the room IDs of rooms that should be kept
|
||||
// in the room list when filtering by that tag.
|
||||
this._visibleRoomsForGroup = {
|
||||
|
@ -96,17 +94,14 @@ module.exports = React.createClass({
|
|||
// When the selected tags are changed, initialise a group store if necessary
|
||||
this._tagStoreToken = TagOrderStore.addListener(() => {
|
||||
(TagOrderStore.getOrderedTags() || []).forEach((tag) => {
|
||||
if (tag[0] !== '+' || this._groupStores[tag]) {
|
||||
if (tag[0] !== '+') {
|
||||
return;
|
||||
}
|
||||
this._groupStores[tag] = GroupStoreCache.getGroupStore(tag);
|
||||
this._groupStoreTokens.push(
|
||||
this._groupStores[tag].registerListener(() => {
|
||||
// This group's rooms or members may have updated, update rooms for its tag
|
||||
this.updateVisibleRoomsForTag(dmRoomMap, tag);
|
||||
this.updateVisibleRooms();
|
||||
}),
|
||||
);
|
||||
this.groupStoreToken = GroupStore.registerListener(tag, () => {
|
||||
// This group's rooms or members may have updated, update rooms for its tag
|
||||
this.updateVisibleRoomsForTag(dmRoomMap, tag);
|
||||
this.updateVisibleRooms();
|
||||
});
|
||||
});
|
||||
// Filters themselves have changed, refresh the selected tags
|
||||
this.updateVisibleRooms();
|
||||
|
@ -183,10 +178,8 @@ module.exports = React.createClass({
|
|||
this._roomListStoreToken.remove();
|
||||
}
|
||||
|
||||
if (this._groupStoreTokens.length > 0) {
|
||||
// NB: GroupStore is not a Flux.Store
|
||||
this._groupStoreTokens.forEach((token) => token.unregister());
|
||||
}
|
||||
// NB: GroupStore is not a Flux.Store
|
||||
this._groupStoreToken.unregister();
|
||||
|
||||
// cancel any pending calls to the rate_limited_funcs
|
||||
this._delayedRefreshRoomList.cancelPendingCall();
|
||||
|
@ -259,12 +252,11 @@ module.exports = React.createClass({
|
|||
updateVisibleRoomsForTag: function(dmRoomMap, tag) {
|
||||
if (!this.mounted) return;
|
||||
// For now, only handle group tags
|
||||
const store = this._groupStores[tag];
|
||||
if (!store) return;
|
||||
if (tag[0] !== '+') return;
|
||||
|
||||
this._visibleRoomsForGroup[tag] = [];
|
||||
store.getGroupRooms().forEach((room) => this._visibleRoomsForGroup[tag].push(room.roomId));
|
||||
store.getGroupMembers().forEach((member) => {
|
||||
GroupStore.getGroupRooms(tag).forEach((room) => this._visibleRoomsForGroup[tag].push(room.roomId));
|
||||
GroupStore.getGroupMembers(tag).forEach((member) => {
|
||||
if (member.userId === MatrixClientPeg.get().credentials.userId) return;
|
||||
dmRoomMap.getDMRoomsForUserId(member.userId).forEach(
|
||||
(roomId) => this._visibleRoomsForGroup[tag].push(roomId),
|
||||
|
|
|
@ -70,84 +70,90 @@ function limitConcurrency(fn) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores the group summary for a room and provides an API to change it and
|
||||
* other useful group APIs that may have an effect on the group summary.
|
||||
* Global store for tracking group summary, members, invited members and rooms.
|
||||
*/
|
||||
export default class GroupStore extends EventEmitter {
|
||||
|
||||
static STATE_KEY = {
|
||||
class GroupStore extends EventEmitter {
|
||||
STATE_KEY = {
|
||||
GroupMembers: 'GroupMembers',
|
||||
GroupInvitedMembers: 'GroupInvitedMembers',
|
||||
Summary: 'Summary',
|
||||
GroupRooms: 'GroupRooms',
|
||||
};
|
||||
|
||||
constructor(groupId) {
|
||||
constructor() {
|
||||
super();
|
||||
if (!groupId) {
|
||||
throw new Error('GroupStore needs a valid groupId to be created');
|
||||
}
|
||||
this.groupId = groupId;
|
||||
this._state = {};
|
||||
this._state[GroupStore.STATE_KEY.Summary] = {};
|
||||
this._state[GroupStore.STATE_KEY.GroupRooms] = [];
|
||||
this._state[GroupStore.STATE_KEY.GroupMembers] = [];
|
||||
this._state[GroupStore.STATE_KEY.GroupInvitedMembers] = [];
|
||||
this._ready = {};
|
||||
this._state[this.STATE_KEY.Summary] = {};
|
||||
this._state[this.STATE_KEY.GroupRooms] = {};
|
||||
this._state[this.STATE_KEY.GroupMembers] = {};
|
||||
this._state[this.STATE_KEY.GroupInvitedMembers] = {};
|
||||
|
||||
this._ready = {};
|
||||
this._ready[this.STATE_KEY.Summary] = {};
|
||||
this._ready[this.STATE_KEY.GroupRooms] = {};
|
||||
this._ready[this.STATE_KEY.GroupMembers] = {};
|
||||
this._ready[this.STATE_KEY.GroupInvitedMembers] = {};
|
||||
|
||||
this._fetchResourcePromise = {
|
||||
[this.STATE_KEY.Summary]: {},
|
||||
[this.STATE_KEY.GroupRooms]: {},
|
||||
[this.STATE_KEY.GroupMembers]: {},
|
||||
[this.STATE_KEY.GroupInvitedMembers]: {},
|
||||
};
|
||||
|
||||
this._fetchResourcePromise = {};
|
||||
this._resourceFetcher = {
|
||||
[GroupStore.STATE_KEY.Summary]: () => {
|
||||
[this.STATE_KEY.Summary]: (groupId) => {
|
||||
return limitConcurrency(
|
||||
() => MatrixClientPeg.get().getGroupSummary(this.groupId),
|
||||
() => MatrixClientPeg.get().getGroupSummary(groupId),
|
||||
);
|
||||
},
|
||||
[GroupStore.STATE_KEY.GroupRooms]: () => {
|
||||
[this.STATE_KEY.GroupRooms]: (groupId) => {
|
||||
return limitConcurrency(
|
||||
() => MatrixClientPeg.get().getGroupRooms(this.groupId).then(parseRoomsResponse),
|
||||
() => MatrixClientPeg.get().getGroupRooms(groupId).then(parseRoomsResponse),
|
||||
);
|
||||
},
|
||||
[GroupStore.STATE_KEY.GroupMembers]: () => {
|
||||
[this.STATE_KEY.GroupMembers]: (groupId) => {
|
||||
return limitConcurrency(
|
||||
() => MatrixClientPeg.get().getGroupUsers(this.groupId).then(parseMembersResponse),
|
||||
() => MatrixClientPeg.get().getGroupUsers(groupId).then(parseMembersResponse),
|
||||
);
|
||||
},
|
||||
[GroupStore.STATE_KEY.GroupInvitedMembers]: () => {
|
||||
[this.STATE_KEY.GroupInvitedMembers]: (groupId) => {
|
||||
return limitConcurrency(
|
||||
() => MatrixClientPeg.get().getGroupInvitedUsers(this.groupId).then(parseMembersResponse),
|
||||
() => MatrixClientPeg.get().getGroupInvitedUsers(groupId).then(parseMembersResponse),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
this.on('error', (err) => {
|
||||
console.error(`GroupStore for ${this.groupId} encountered error`, err);
|
||||
this.on('error', (err, groupId) => {
|
||||
console.error(`GroupStore encountered error whilst fetching data for ${groupId}`, err);
|
||||
});
|
||||
}
|
||||
|
||||
_fetchResource(stateKey) {
|
||||
_fetchResource(stateKey, groupId) {
|
||||
// Ongoing request, ignore
|
||||
if (this._fetchResourcePromise[stateKey]) return;
|
||||
if (this._fetchResourcePromise[stateKey][groupId]) return;
|
||||
|
||||
const clientPromise = this._resourceFetcher[stateKey]();
|
||||
const clientPromise = this._resourceFetcher[stateKey](groupId);
|
||||
|
||||
// Indicate ongoing request
|
||||
this._fetchResourcePromise[stateKey] = clientPromise;
|
||||
this._fetchResourcePromise[stateKey][groupId] = clientPromise;
|
||||
|
||||
clientPromise.then((result) => {
|
||||
this._state[stateKey] = result;
|
||||
this._ready[stateKey] = true;
|
||||
this._state[stateKey][groupId] = result;
|
||||
console.info(this._state);
|
||||
this._ready[stateKey][groupId] = true;
|
||||
this._notifyListeners();
|
||||
}).catch((err) => {
|
||||
// Invited users not visible to non-members
|
||||
if (stateKey === GroupStore.STATE_KEY.GroupInvitedMembers && err.httpStatus === 403) {
|
||||
if (stateKey === this.STATE_KEY.GroupInvitedMembers && err.httpStatus === 403) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error("Failed to get resource " + stateKey + ":" + err);
|
||||
this.emit('error', err);
|
||||
console.error(`Failed to get resource ${stateKey} for ${groupId}`, err);
|
||||
this.emit('error', err, groupId);
|
||||
}).finally(() => {
|
||||
// Indicate finished request, allow for future fetches
|
||||
delete this._fetchResourcePromise[stateKey];
|
||||
delete this._fetchResourcePromise[stateKey][groupId];
|
||||
});
|
||||
|
||||
return clientPromise;
|
||||
|
@ -162,25 +168,26 @@ export default class GroupStore extends EventEmitter {
|
|||
* immediately triggers an update to send the current state of the
|
||||
* store (which could be the initial state).
|
||||
*
|
||||
* This also causes a fetch of all group data, which might cause
|
||||
* 4 separate HTTP requests, but only said requests aren't already
|
||||
* ongoing.
|
||||
* This also causes a fetch of all data of the specified group,
|
||||
* which might cause 4 separate HTTP requests, but only if said
|
||||
* requests aren't already ongoing.
|
||||
*
|
||||
* @param {string} groupId the ID of the group to fetch data for.
|
||||
* @param {function} fn the function to call when the store updates.
|
||||
* @return {Object} tok a registration "token" with a single
|
||||
* property `unregister`, a function that can
|
||||
* be called to unregister the listener such
|
||||
* that it won't be called any more.
|
||||
*/
|
||||
registerListener(fn) {
|
||||
registerListener(groupId, fn) {
|
||||
this.on('update', fn);
|
||||
// Call to set initial state (before fetching starts)
|
||||
this.emit('update');
|
||||
|
||||
this._fetchResource(GroupStore.STATE_KEY.Summary);
|
||||
this._fetchResource(GroupStore.STATE_KEY.GroupRooms);
|
||||
this._fetchResource(GroupStore.STATE_KEY.GroupMembers);
|
||||
this._fetchResource(GroupStore.STATE_KEY.GroupInvitedMembers);
|
||||
this._fetchResource(this.STATE_KEY.Summary, groupId);
|
||||
this._fetchResource(this.STATE_KEY.GroupRooms, groupId);
|
||||
this._fetchResource(this.STATE_KEY.GroupMembers, groupId);
|
||||
this._fetchResource(this.STATE_KEY.GroupInvitedMembers, groupId);
|
||||
|
||||
// Similar to the Store of flux/utils, we return a "token" that
|
||||
// can be used to unregister the listener.
|
||||
|
@ -195,123 +202,129 @@ export default class GroupStore extends EventEmitter {
|
|||
this.removeListener('update', fn);
|
||||
}
|
||||
|
||||
isStateReady(id) {
|
||||
return this._ready[id];
|
||||
isStateReady(groupId, id) {
|
||||
return this._ready[id][groupId];
|
||||
}
|
||||
|
||||
getSummary() {
|
||||
return this._state[GroupStore.STATE_KEY.Summary];
|
||||
getSummary(groupId) {
|
||||
return this._state[this.STATE_KEY.Summary][groupId] || {};
|
||||
}
|
||||
|
||||
getGroupRooms() {
|
||||
return this._state[GroupStore.STATE_KEY.GroupRooms];
|
||||
getGroupRooms(groupId) {
|
||||
return this._state[this.STATE_KEY.GroupRooms][groupId] || [];
|
||||
}
|
||||
|
||||
getGroupMembers() {
|
||||
return this._state[GroupStore.STATE_KEY.GroupMembers];
|
||||
getGroupMembers(groupId) {
|
||||
return this._state[this.STATE_KEY.GroupMembers][groupId] || [];
|
||||
}
|
||||
|
||||
getGroupInvitedMembers() {
|
||||
return this._state[GroupStore.STATE_KEY.GroupInvitedMembers];
|
||||
getGroupInvitedMembers(groupId) {
|
||||
return this._state[this.STATE_KEY.GroupInvitedMembers][groupId] || [];
|
||||
}
|
||||
|
||||
getGroupPublicity() {
|
||||
return this._state[GroupStore.STATE_KEY.Summary].user ?
|
||||
this._state[GroupStore.STATE_KEY.Summary].user.is_publicised : null;
|
||||
getGroupPublicity(groupId) {
|
||||
return (this._state[this.STATE_KEY.Summary][groupId] || {}).user ?
|
||||
(this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_publicised : null;
|
||||
}
|
||||
|
||||
isUserPrivileged() {
|
||||
return this._state[GroupStore.STATE_KEY.Summary].user ?
|
||||
this._state[GroupStore.STATE_KEY.Summary].user.is_privileged : null;
|
||||
isUserPrivileged(groupId) {
|
||||
return (this._state[this.STATE_KEY.Summary][groupId] || {}).user ?
|
||||
(this._state[this.STATE_KEY.Summary][groupId] || {}).user.is_privileged : null;
|
||||
}
|
||||
|
||||
addRoomToGroup(roomId, isPublic) {
|
||||
addRoomToGroup(groupId, roomId, isPublic) {
|
||||
return MatrixClientPeg.get()
|
||||
.addRoomToGroup(this.groupId, roomId, isPublic)
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms));
|
||||
.addRoomToGroup(groupId, roomId, isPublic)
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId));
|
||||
}
|
||||
|
||||
updateGroupRoomVisibility(roomId, isPublic) {
|
||||
updateGroupRoomVisibility(groupId, roomId, isPublic) {
|
||||
return MatrixClientPeg.get()
|
||||
.updateGroupRoomVisibility(this.groupId, roomId, isPublic)
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms));
|
||||
.updateGroupRoomVisibility(groupId, roomId, isPublic)
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId));
|
||||
}
|
||||
|
||||
removeRoomFromGroup(roomId) {
|
||||
removeRoomFromGroup(groupId, roomId) {
|
||||
return MatrixClientPeg.get()
|
||||
.removeRoomFromGroup(this.groupId, roomId)
|
||||
.removeRoomFromGroup(groupId, roomId)
|
||||
// Room might be in the summary, refresh just in case
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary))
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms));
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId));
|
||||
}
|
||||
|
||||
inviteUserToGroup(userId) {
|
||||
return MatrixClientPeg.get().inviteUserToGroup(this.groupId, userId)
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers));
|
||||
inviteUserToGroup(groupId, userId) {
|
||||
return MatrixClientPeg.get().inviteUserToGroup(groupId, userId)
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId));
|
||||
}
|
||||
|
||||
acceptGroupInvite() {
|
||||
return MatrixClientPeg.get().acceptGroupInvite(this.groupId)
|
||||
acceptGroupInvite(groupId) {
|
||||
return MatrixClientPeg.get().acceptGroupInvite(groupId)
|
||||
// The user should now be able to access (personal) group settings
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId))
|
||||
// The user might be able to see more rooms now
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId))
|
||||
// The user should now appear as a member
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId))
|
||||
// The user should now not appear as an invited member
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers));
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId));
|
||||
}
|
||||
|
||||
joinGroup() {
|
||||
return MatrixClientPeg.get().joinGroup(this.groupId)
|
||||
joinGroup(groupId) {
|
||||
return MatrixClientPeg.get().joinGroup(groupId)
|
||||
// The user should now be able to access (personal) group settings
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId))
|
||||
// The user might be able to see more rooms now
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId))
|
||||
// The user should now appear as a member
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId))
|
||||
// The user should now not appear as an invited member
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupInvitedMembers));
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupInvitedMembers, groupId));
|
||||
}
|
||||
|
||||
leaveGroup() {
|
||||
return MatrixClientPeg.get().leaveGroup(this.groupId)
|
||||
leaveGroup(groupId) {
|
||||
return MatrixClientPeg.get().leaveGroup(groupId)
|
||||
// The user should now not be able to access group settings
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId))
|
||||
// The user might only be able to see a subset of rooms now
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupRooms))
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupRooms, groupId))
|
||||
// The user should now not appear as a member
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.GroupMembers));
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.GroupMembers, groupId));
|
||||
}
|
||||
|
||||
addRoomToGroupSummary(roomId, categoryId) {
|
||||
addRoomToGroupSummary(groupId, roomId, categoryId) {
|
||||
return MatrixClientPeg.get()
|
||||
.addRoomToGroupSummary(this.groupId, roomId, categoryId)
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary));
|
||||
.addRoomToGroupSummary(groupId, roomId, categoryId)
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId));
|
||||
}
|
||||
|
||||
addUserToGroupSummary(userId, roleId) {
|
||||
addUserToGroupSummary(groupId, userId, roleId) {
|
||||
return MatrixClientPeg.get()
|
||||
.addUserToGroupSummary(this.groupId, userId, roleId)
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary));
|
||||
.addUserToGroupSummary(groupId, userId, roleId)
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId));
|
||||
}
|
||||
|
||||
removeRoomFromGroupSummary(roomId) {
|
||||
removeRoomFromGroupSummary(groupId, roomId) {
|
||||
return MatrixClientPeg.get()
|
||||
.removeRoomFromGroupSummary(this.groupId, roomId)
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary));
|
||||
.removeRoomFromGroupSummary(groupId, roomId)
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId));
|
||||
}
|
||||
|
||||
removeUserFromGroupSummary(userId) {
|
||||
removeUserFromGroupSummary(groupId, userId) {
|
||||
return MatrixClientPeg.get()
|
||||
.removeUserFromGroupSummary(this.groupId, userId)
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary));
|
||||
.removeUserFromGroupSummary(groupId, userId)
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId));
|
||||
}
|
||||
|
||||
setGroupPublicity(isPublished) {
|
||||
setGroupPublicity(groupId, isPublished) {
|
||||
return MatrixClientPeg.get()
|
||||
.setGroupPublicity(this.groupId, isPublished)
|
||||
.setGroupPublicity(groupId, isPublished)
|
||||
.then(() => { FlairStore.invalidatePublicisedGroups(MatrixClientPeg.get().credentials.userId); })
|
||||
.then(this._fetchResource.bind(this, GroupStore.STATE_KEY.Summary));
|
||||
.then(this._fetchResource.bind(this, this.STATE_KEY.Summary, groupId));
|
||||
}
|
||||
}
|
||||
|
||||
let singletonGroupStore = null;
|
||||
if (!singletonGroupStore) {
|
||||
singletonGroupStore = new GroupStore();
|
||||
}
|
||||
module.exports = singletonGroupStore;
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
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 GroupStore from './GroupStore';
|
||||
|
||||
class GroupStoreCache {
|
||||
constructor() {
|
||||
this.groupStore = null;
|
||||
}
|
||||
|
||||
getGroupStore(groupId) {
|
||||
if (!this.groupStore || this.groupStore.groupId !== groupId) {
|
||||
// This effectively throws away the reference to any previous GroupStore,
|
||||
// allowing it to be GCd once the components referencing it have stopped
|
||||
// referencing it.
|
||||
this.groupStore = new GroupStore(groupId);
|
||||
}
|
||||
return this.groupStore;
|
||||
}
|
||||
}
|
||||
|
||||
if (global.singletonGroupStoreCache === undefined) {
|
||||
global.singletonGroupStoreCache = new GroupStoreCache();
|
||||
}
|
||||
export default global.singletonGroupStoreCache;
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import MatrixClientPeg from '../MatrixClientPeg';
|
||||
import {getAddressType} from '../UserAddress';
|
||||
import {inviteToRoom} from '../RoomInvite';
|
||||
import GroupStoreCache from '../stores/GroupStoreCache';
|
||||
import GroupStore from '../stores/GroupStore';
|
||||
import Promise from 'bluebird';
|
||||
|
||||
/**
|
||||
|
@ -118,9 +118,7 @@ export default class MultiInviter {
|
|||
|
||||
let doInvite;
|
||||
if (this.groupId !== null) {
|
||||
doInvite = GroupStoreCache
|
||||
.getGroupStore(this.groupId)
|
||||
.inviteUserToGroup(addr);
|
||||
doInvite = GroupStore.inviteUserToGroup(this.groupId, addr);
|
||||
} else {
|
||||
doInvite = inviteToRoom(this.roomId, addr);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue