Use room-specific listeners for message previews

This should be a bit faster (since we now only notify one tile instead of all
for each update). It also resolves the max listener warning.

Fixes https://github.com/vector-im/element-web/issues/15121
This commit is contained in:
J. Ryan Stinnett 2021-01-15 13:54:38 +00:00
parent 266162fa32
commit 729356394e
2 changed files with 26 additions and 6 deletions

View file

@ -29,7 +29,7 @@ import ActiveRoomObserver from "../../../ActiveRoomObserver";
import { _t } from "../../../languageHandler";
import { ChevronFace, ContextMenuTooltipButton } from "../../structures/ContextMenu";
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
import { MessagePreviewStore, ROOM_PREVIEW_CHANGED } from "../../../stores/room-list/MessagePreviewStore";
import { MessagePreviewStore } from "../../../stores/room-list/MessagePreviewStore";
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
import { ALL_MESSAGES, ALL_MESSAGES_LOUD, MENTIONS_ONLY, MUTE } from "../../../RoomNotifs";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
@ -99,7 +99,10 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate);
this.dispatcherRef = defaultDispatcher.register(this.onAction);
MessagePreviewStore.instance.on(ROOM_PREVIEW_CHANGED, this.onRoomPreviewChanged);
MessagePreviewStore.instance.on(
MessagePreviewStore.getPreviewChangedEventName(this.props.room),
this.onRoomPreviewChanged,
);
this.notificationState = RoomNotificationStateStore.instance.getRoomState(this.props.room);
this.notificationState.on(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate);
this.roomProps = EchoChamber.forRoom(this.props.room);
@ -128,6 +131,16 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
if (prevProps.showMessagePreview !== this.props.showMessagePreview && this.showMessagePreview) {
this.setState({messagePreview: this.generatePreview()});
}
if (prevProps.room?.roomId !== this.props.room?.roomId) {
MessagePreviewStore.instance.off(
MessagePreviewStore.getPreviewChangedEventName(prevProps.room),
this.onRoomPreviewChanged,
);
MessagePreviewStore.instance.on(
MessagePreviewStore.getPreviewChangedEventName(this.props.room),
this.onRoomPreviewChanged,
);
}
}
public componentDidMount() {
@ -140,9 +153,12 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
public componentWillUnmount() {
if (this.props.room) {
ActiveRoomObserver.removeListener(this.props.room.roomId, this.onActiveRoomUpdate);
MessagePreviewStore.instance.off(
MessagePreviewStore.getPreviewChangedEventName(this.props.room),
this.onRoomPreviewChanged,
);
}
defaultDispatcher.unregister(this.dispatcherRef);
MessagePreviewStore.instance.off(ROOM_PREVIEW_CHANGED, this.onRoomPreviewChanged);
this.notificationState.off(NOTIFICATION_STATE_UPDATE, this.onNotificationUpdate);
CommunityPrototypeStore.instance.off(UPDATE_EVENT, this.onCommunityUpdate);
}

View file

@ -30,7 +30,7 @@ import { UPDATE_EVENT } from "../AsyncStore";
// Emitted event for when a room's preview has changed. First argument will the room for which
// the change happened.
export const ROOM_PREVIEW_CHANGED = "room_preview_changed";
const ROOM_PREVIEW_CHANGED = "room_preview_changed";
const PREVIEWS = {
'm.room.message': {
@ -84,6 +84,10 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
return MessagePreviewStore.internalInstance;
}
public static getPreviewChangedEventName(room: Room): string {
return `${ROOM_PREVIEW_CHANGED}:${room?.roomId}`;
}
/**
* Gets the pre-translated preview for a given room
* @param room The room to get the preview for.
@ -150,7 +154,7 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
// We've muted the underlying Map, so just emit that we've changed.
this.previews.set(room.roomId, map);
this.emit(UPDATE_EVENT, this);
this.emit(ROOM_PREVIEW_CHANGED, room);
this.emit(MessagePreviewStore.getPreviewChangedEventName(room), room);
}
return; // we're done
}
@ -158,7 +162,7 @@ export class MessagePreviewStore extends AsyncStoreWithClient<IState> {
// At this point, we didn't generate a preview so clear it
this.previews.set(room.roomId, new Map<TagID|TAG_ANY, string|null>());
this.emit(UPDATE_EVENT, this);
this.emit(ROOM_PREVIEW_CHANGED, room);
this.emit(MessagePreviewStore.getPreviewChangedEventName(room), room);
}
protected async onAction(payload: ActionPayload) {