Add some resource leak protection to new room list badges
Most of the leaks were because we never set `this.rooms` in the notification state, which meant we were constantly triggering the `diff.added` loop.pull/21833/head
parent
d3a3b54a82
commit
d1c2ecb6cc
|
@ -205,7 +205,7 @@ export class RoomNotificationState extends EventEmitter implements IDestroyable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ListNotificationState extends EventEmitter {
|
export class ListNotificationState extends EventEmitter implements IDestroyable {
|
||||||
private _count: number;
|
private _count: number;
|
||||||
private _color: NotificationColor;
|
private _color: NotificationColor;
|
||||||
private rooms: Room[] = [];
|
private rooms: Room[] = [];
|
||||||
|
@ -237,6 +237,7 @@ export class ListNotificationState extends EventEmitter {
|
||||||
|
|
||||||
const oldRooms = this.rooms;
|
const oldRooms = this.rooms;
|
||||||
const diff = arrayDiff(oldRooms, rooms);
|
const diff = arrayDiff(oldRooms, rooms);
|
||||||
|
this.rooms = rooms;
|
||||||
for (const oldRoom of diff.removed) {
|
for (const oldRoom of diff.removed) {
|
||||||
const state = this.states[oldRoom.roomId];
|
const state = this.states[oldRoom.roomId];
|
||||||
delete this.states[oldRoom.roomId];
|
delete this.states[oldRoom.roomId];
|
||||||
|
@ -246,12 +247,24 @@ export class ListNotificationState extends EventEmitter {
|
||||||
for (const newRoom of diff.added) {
|
for (const newRoom of diff.added) {
|
||||||
const state = new RoomNotificationState(newRoom);
|
const state = new RoomNotificationState(newRoom);
|
||||||
state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate);
|
state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate);
|
||||||
|
if (this.states[newRoom.roomId]) {
|
||||||
|
// "Should never happen" disclaimer.
|
||||||
|
console.warn("Overwriting notification state for room:", newRoom.roomId);
|
||||||
|
this.states[newRoom.roomId].destroy();
|
||||||
|
}
|
||||||
this.states[newRoom.roomId] = state;
|
this.states[newRoom.roomId] = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.calculateTotalState();
|
this.calculateTotalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public destroy() {
|
||||||
|
for (const state of Object.values(this.states)) {
|
||||||
|
state.destroy();
|
||||||
|
}
|
||||||
|
this.states = {};
|
||||||
|
}
|
||||||
|
|
||||||
private onRoomNotificationStateUpdate = () => {
|
private onRoomNotificationStateUpdate = () => {
|
||||||
this.calculateTotalState();
|
this.calculateTotalState();
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,6 +84,10 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
this.state.notificationState.setRooms(this.props.rooms);
|
this.state.notificationState.setRooms(this.props.rooms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public componentWillUnmount() {
|
||||||
|
this.state.notificationState.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
private onAddRoom = (e) => {
|
private onAddRoom = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (this.props.onAddRoom) this.props.onAddRoom();
|
if (this.props.onAddRoom) this.props.onAddRoom();
|
||||||
|
|
Loading…
Reference in New Issue