Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 2ba0a80

Browse files
authored
Merge pull request #1449 from matrix-org/luke/groups-store
Factor-out GroupStore and create GroupStoreCache
2 parents 6875005 + cbb36b1 commit 2ba0a80

File tree

4 files changed

+82
-36
lines changed

4 files changed

+82
-36
lines changed

src/GroupAddressPicker.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import sdk from './';
1919
import MultiInviter from './utils/MultiInviter';
2020
import { _t } from './languageHandler';
2121
import MatrixClientPeg from './MatrixClientPeg';
22+
import GroupStoreCache from './stores/GroupStoreCache';
2223

2324
export function showGroupInviteDialog(groupId) {
2425
const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog");
@@ -86,10 +87,11 @@ function _onGroupInviteFinished(groupId, addrs) {
8687
}
8788

8889
function _onGroupAddRoomFinished(groupId, addrs) {
90+
const groupStore = GroupStoreCache.getGroupStore(MatrixClientPeg.get(), groupId);
8991
const errorList = [];
9092
return Promise.all(addrs.map((addr) => {
91-
return MatrixClientPeg.get()
92-
.addRoomToGroup(groupId, addr.address)
93+
return groupStore
94+
.addRoomToGroup(addr.address)
9395
.catch(() => { errorList.push(addr.address); })
9496
.reflect();
9597
})).then(() => {

src/components/structures/GroupView.js

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import AccessibleButton from '../views/elements/AccessibleButton';
2727
import Modal from '../../Modal';
2828
import classnames from 'classnames';
2929

30-
import GroupSummaryStore from '../../stores/GroupSummaryStore';
30+
import GroupStoreCache from '../../stores/GroupStoreCache';
31+
import GroupStore from '../../stores/GroupStore';
3132

3233
const RoomSummaryType = PropTypes.shape({
3334
room_id: PropTypes.string.isRequired,
@@ -78,7 +79,7 @@ const CategoryRoomList = React.createClass({
7879
if (!success) return;
7980
const errorList = [];
8081
Promise.all(addrs.map((addr) => {
81-
return this.context.groupSummaryStore
82+
return this.context.groupStore
8283
.addRoomToGroupSummary(addr.address)
8384
.catch(() => { errorList.push(addr.address); })
8485
.reflect();
@@ -157,7 +158,7 @@ const FeaturedRoom = React.createClass({
157158
onDeleteClicked: function(e) {
158159
e.preventDefault();
159160
e.stopPropagation();
160-
this.context.groupSummaryStore.removeRoomFromGroupSummary(
161+
this.context.groupStore.removeRoomFromGroupSummary(
161162
this.props.summaryInfo.room_id,
162163
).catch((err) => {
163164
console.error('Error whilst removing room from group summary', err);
@@ -252,7 +253,7 @@ const RoleUserList = React.createClass({
252253
if (!success) return;
253254
const errorList = [];
254255
Promise.all(addrs.map((addr) => {
255-
return this.context.groupSummaryStore
256+
return this.context.groupStore
256257
.addUserToGroupSummary(addr.address)
257258
.catch(() => { errorList.push(addr.address); })
258259
.reflect();
@@ -327,7 +328,7 @@ const FeaturedUser = React.createClass({
327328
onDeleteClicked: function(e) {
328329
e.preventDefault();
329330
e.stopPropagation();
330-
this.context.groupSummaryStore.removeUserFromGroupSummary(
331+
this.context.groupStore.removeUserFromGroupSummary(
331332
this.props.summaryInfo.user_id,
332333
).catch((err) => {
333334
console.error('Error whilst removing user from group summary', err);
@@ -373,14 +374,14 @@ const FeaturedUser = React.createClass({
373374
},
374375
});
375376

376-
const GroupSummaryContext = {
377-
groupSummaryStore: React.PropTypes.instanceOf(GroupSummaryStore).isRequired,
377+
const GroupContext = {
378+
groupStore: React.PropTypes.instanceOf(GroupStore).isRequired,
378379
};
379380

380-
CategoryRoomList.contextTypes = GroupSummaryContext;
381-
FeaturedRoom.contextTypes = GroupSummaryContext;
382-
RoleUserList.contextTypes = GroupSummaryContext;
383-
FeaturedUser.contextTypes = GroupSummaryContext;
381+
CategoryRoomList.contextTypes = GroupContext;
382+
FeaturedRoom.contextTypes = GroupContext;
383+
RoleUserList.contextTypes = GroupContext;
384+
FeaturedUser.contextTypes = GroupContext;
384385

385386
export default React.createClass({
386387
displayName: 'GroupView',
@@ -390,12 +391,12 @@ export default React.createClass({
390391
},
391392

392393
childContextTypes: {
393-
groupSummaryStore: React.PropTypes.instanceOf(GroupSummaryStore),
394+
groupStore: React.PropTypes.instanceOf(GroupStore),
394395
},
395396

396397
getChildContext: function() {
397398
return {
398-
groupSummaryStore: this._groupSummaryStore,
399+
groupStore: this._groupStore,
399400
};
400401
},
401402

@@ -413,14 +414,14 @@ export default React.createClass({
413414

414415
componentWillMount: function() {
415416
this._changeAvatarComponent = null;
416-
this._initGroupSummaryStore(this.props.groupId);
417+
this._initGroupStore(this.props.groupId);
417418

418419
MatrixClientPeg.get().on("Group.myMembership", this._onGroupMyMembership);
419420
},
420421

421422
componentWillUnmount: function() {
422423
MatrixClientPeg.get().removeListener("Group.myMembership", this._onGroupMyMembership);
423-
this._groupSummaryStore.removeAllListeners();
424+
this._groupStore.removeAllListeners();
424425
},
425426

426427
componentWillReceiveProps: function(newProps) {
@@ -429,7 +430,7 @@ export default React.createClass({
429430
summary: null,
430431
error: null,
431432
}, () => {
432-
this._initGroupSummaryStore(newProps.groupId);
433+
this._initGroupStore(newProps.groupId);
433434
});
434435
}
435436
},
@@ -440,17 +441,15 @@ export default React.createClass({
440441
this.setState({membershipBusy: false});
441442
},
442443

443-
_initGroupSummaryStore: function(groupId) {
444-
this._groupSummaryStore = new GroupSummaryStore(
445-
MatrixClientPeg.get(), this.props.groupId,
446-
);
447-
this._groupSummaryStore.on('update', () => {
444+
_initGroupStore: function(groupId) {
445+
this._groupStore = GroupStoreCache.getGroupStore(MatrixClientPeg.get(), groupId);
446+
this._groupStore.on('update', () => {
448447
this.setState({
449-
summary: this._groupSummaryStore.getSummary(),
448+
summary: this._groupStore.getSummary(),
450449
error: null,
451450
});
452451
});
453-
this._groupSummaryStore.on('error', (err) => {
452+
this._groupStore.on('error', (err) => {
454453
this.setState({
455454
summary: null,
456455
error: err,
@@ -527,7 +526,7 @@ export default React.createClass({
527526
editing: false,
528527
summary: null,
529528
});
530-
this._initGroupSummaryStore(this.props.groupId);
529+
this._initGroupStore(this.props.groupId);
531530
}).catch((e) => {
532531
this.setState({
533532
saving: false,
@@ -606,7 +605,7 @@ export default React.createClass({
606605
this.setState({
607606
publicityBusy: true,
608607
});
609-
this._groupSummaryStore.setGroupPublicity(publicity).then(() => {
608+
this._groupStore.setGroupPublicity(publicity).then(() => {
610609
this.setState({
611610
publicityBusy: false,
612611
});

src/stores/GroupSummaryStore.js renamed to src/stores/GroupStore.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,20 @@ limitations under the License.
1717
import EventEmitter from 'events';
1818

1919
/**
20-
* Stores the group summary for a room and provides an API to change it
20+
* Stores the group summary for a room and provides an API to change it and
21+
* other useful group APIs that may have an effect on the group summary.
2122
*/
22-
export default class GroupSummaryStore extends EventEmitter {
23+
export default class GroupStore extends EventEmitter {
2324
constructor(matrixClient, groupId) {
2425
super();
25-
this._groupId = groupId;
26+
this.groupId = groupId;
2627
this._matrixClient = matrixClient;
2728
this._summary = {};
2829
this._fetchSummary();
2930
}
3031

3132
_fetchSummary() {
32-
this._matrixClient.getGroupSummary(this._groupId).then((resp) => {
33+
this._matrixClient.getGroupSummary(this.groupId).then((resp) => {
3334
this._summary = resp;
3435
this._notifyListeners();
3536
}).catch((err) => {
@@ -45,33 +46,38 @@ export default class GroupSummaryStore extends EventEmitter {
4546
return this._summary;
4647
}
4748

49+
addRoomToGroup(roomId) {
50+
return this._matrixClient
51+
.addRoomToGroup(this.groupId, roomId);
52+
}
53+
4854
addRoomToGroupSummary(roomId, categoryId) {
4955
return this._matrixClient
50-
.addRoomToGroupSummary(this._groupId, roomId, categoryId)
56+
.addRoomToGroupSummary(this.groupId, roomId, categoryId)
5157
.then(this._fetchSummary.bind(this));
5258
}
5359

5460
addUserToGroupSummary(userId, roleId) {
5561
return this._matrixClient
56-
.addUserToGroupSummary(this._groupId, userId, roleId)
62+
.addUserToGroupSummary(this.groupId, userId, roleId)
5763
.then(this._fetchSummary.bind(this));
5864
}
5965

6066
removeRoomFromGroupSummary(roomId) {
6167
return this._matrixClient
62-
.removeRoomFromGroupSummary(this._groupId, roomId)
68+
.removeRoomFromGroupSummary(this.groupId, roomId)
6369
.then(this._fetchSummary.bind(this));
6470
}
6571

6672
removeUserFromGroupSummary(userId) {
6773
return this._matrixClient
68-
.removeUserFromGroupSummary(this._groupId, userId)
74+
.removeUserFromGroupSummary(this.groupId, userId)
6975
.then(this._fetchSummary.bind(this));
7076
}
7177

7278
setGroupPublicity(isPublished) {
7379
return this._matrixClient
74-
.setGroupPublicity(this._groupId, isPublished)
80+
.setGroupPublicity(this.groupId, isPublished)
7581
.then(this._fetchSummary.bind(this));
7682
}
7783
}

src/stores/GroupStoreCache.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright 2017 New Vector Ltd
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import GroupStore from './GroupStore';
18+
19+
class GroupStoreCache {
20+
constructor() {
21+
this.groupStore = null;
22+
}
23+
24+
getGroupStore(matrixClient, groupId) {
25+
if (!this.groupStore || this.groupStore.groupId !== groupId) {
26+
// This effectively throws away the reference to any previous GroupStore,
27+
// allowing it to be GCd once the components referencing it have stopped
28+
// referencing it.
29+
this.groupStore = new GroupStore(matrixClient, groupId);
30+
}
31+
return this.groupStore;
32+
}
33+
}
34+
35+
let singletonGroupStoreCache = null;
36+
if (!singletonGroupStoreCache) {
37+
singletonGroupStoreCache = new GroupStoreCache();
38+
}
39+
module.exports = singletonGroupStoreCache;

0 commit comments

Comments
 (0)