Avoid looking up settings during timeline rendering (#8313)

* Avoid showHiddenEventsInTimeline lookups

* Avoid MSC3531 feature lookups

* Test that showHiddenEventsInTimeline doesn't get looked up while
rendering

* Fix code review nits

Co-authored-by: Travis Ralston <travisr@matrix.org>
This commit is contained in:
Robin 2022-04-14 19:23:22 -04:00 committed by GitHub
parent f27386ec37
commit 7335b35fbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 120 additions and 54 deletions

View file

@ -242,7 +242,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
// displayed event in the current render cycle.
private readReceiptsByUserId: Record<string, IReadReceiptForUser> = {};
private readonly showHiddenEventsInTimeline: boolean;
private readonly _showHiddenEvents: boolean;
private readonly threadsEnabled: boolean;
private isMounted = false;
@ -270,7 +270,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
// Cache these settings on mount since Settings is expensive to query,
// and we check this in a hot code path. This is also cached in our
// RoomContext, however we still need a fallback for roomless MessagePanels.
this.showHiddenEventsInTimeline = SettingsStore.getValue("showHiddenEventsInTimeline");
this._showHiddenEvents = SettingsStore.getValue("showHiddenEventsInTimeline");
this.threadsEnabled = SettingsStore.getValue("feature_thread");
this.showTypingNotificationsWatcherRef =
@ -465,7 +465,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
};
public get showHiddenEvents(): boolean {
return this.context?.showHiddenEventsInTimeline ?? this.showHiddenEventsInTimeline;
return this.context?.showHiddenEvents ?? this._showHiddenEvents;
}
// TODO: Implement granular (per-room) hide options
@ -748,7 +748,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
const willWantDateSeparator = this.wantsDateSeparator(mxEv, nextEv.getDate() || new Date());
lastInSection = willWantDateSeparator ||
mxEv.getSender() !== nextEv.getSender() ||
getEventDisplayInfo(nextEv).isInfoMessage ||
getEventDisplayInfo(nextEv, this.showHiddenEvents).isInfoMessage ||
!shouldFormContinuation(
mxEv, nextEv, this.showHiddenEvents, this.threadsEnabled, this.context.timelineRenderingType,
);

View file

@ -199,7 +199,7 @@ export interface IRoomState {
showTwelveHourTimestamps: boolean;
readMarkerInViewThresholdMs: number;
readMarkerOutOfViewThresholdMs: number;
showHiddenEventsInTimeline: boolean;
showHiddenEvents: boolean;
showReadReceipts: boolean;
showRedactions: boolean;
showJoinLeaves: boolean;
@ -271,7 +271,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
showTwelveHourTimestamps: SettingsStore.getValue("showTwelveHourTimestamps"),
readMarkerInViewThresholdMs: SettingsStore.getValue("readMarkerInViewThresholdMs"),
readMarkerOutOfViewThresholdMs: SettingsStore.getValue("readMarkerOutOfViewThresholdMs"),
showHiddenEventsInTimeline: SettingsStore.getValue("showHiddenEventsInTimeline"),
showHiddenEvents: SettingsStore.getValue("showHiddenEventsInTimeline"),
showReadReceipts: true,
showRedactions: true,
showJoinLeaves: true,
@ -328,7 +328,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.setState({ readMarkerOutOfViewThresholdMs: value as number }),
),
SettingsStore.watchSetting("showHiddenEventsInTimeline", null, (...[,,, value]) =>
this.setState({ showHiddenEventsInTimeline: value as boolean }),
this.setState({ showHiddenEvents: value as boolean }),
),
];
}
@ -1480,7 +1480,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
continue;
}
if (!haveRendererForEvent(mxEv, this.state.showHiddenEventsInTimeline)) {
if (!haveRendererForEvent(mxEv, this.state.showHiddenEvents)) {
// XXX: can this ever happen? It will make the result count
// not match the displayed count.
continue;

View file

@ -250,7 +250,7 @@ const ThreadPanel: React.FC<IProps> = ({
<RoomContext.Provider value={{
...roomContext,
timelineRenderingType: TimelineRenderingType.ThreadsList,
showHiddenEventsInTimeline: true,
showHiddenEvents: true,
narrow,
}}>
<BaseCard

View file

@ -1511,7 +1511,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
const shouldIgnore = !!ev.status || // local echo
(ignoreOwn && ev.getSender() === myUserId); // own message
const isWithoutTile = !haveRendererForEvent(ev, this.context?.showHiddenEventsInTimeline) ||
const isWithoutTile = !haveRendererForEvent(ev, this.context?.showHiddenEvents) ||
shouldHideEvent(ev, this.context);
if (isWithoutTile || !node) {

View file

@ -28,7 +28,7 @@ export default class TextualEvent extends React.Component<IProps> {
static contextType = RoomContext;
public render() {
const text = TextForEvent.textForEvent(this.props.mxEvent, true, this.context?.showHiddenEventsInTimeline);
const text = TextForEvent.textForEvent(this.props.mxEvent, true, this.context?.showHiddenEvents);
if (!text) return null;
return <div className="mx_TextualEvent">{ text }</div>;
}

View file

@ -1214,21 +1214,24 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
msgOption = readAvatars;
}
const replyChain =
(haveRendererForEvent(this.props.mxEvent) && shouldDisplayReply(this.props.mxEvent))
? <ReplyChain
parentEv={this.props.mxEvent}
onHeightChanged={this.props.onHeightChanged}
ref={this.replyChain}
forExport={this.props.forExport}
permalinkCreator={this.props.permalinkCreator}
layout={this.props.layout}
alwaysShowTimestamps={this.props.alwaysShowTimestamps || this.state.hover}
isQuoteExpanded={isQuoteExpanded}
setQuoteExpanded={this.setQuoteExpanded}
getRelationsForEvent={this.props.getRelationsForEvent}
/>
: null;
let replyChain;
if (
haveRendererForEvent(this.props.mxEvent, this.context.showHiddenEvents) &&
shouldDisplayReply(this.props.mxEvent)
) {
replyChain = <ReplyChain
parentEv={this.props.mxEvent}
onHeightChanged={this.props.onHeightChanged}
ref={this.replyChain}
forExport={this.props.forExport}
permalinkCreator={this.props.permalinkCreator}
layout={this.props.layout}
alwaysShowTimestamps={this.props.alwaysShowTimestamps || this.state.hover}
isQuoteExpanded={isQuoteExpanded}
setQuoteExpanded={this.setQuoteExpanded}
getRelationsForEvent={this.props.getRelationsForEvent}
/>;
}
const isOwnEvent = this.props.mxEvent?.sender?.userId === MatrixClientPeg.get().getUserId();
@ -1267,7 +1270,7 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
}) }
}, this.context.showHiddenEvents) }
</div>,
]);
}
@ -1309,7 +1312,7 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
}) }
}, this.context.showHiddenEvents) }
{ actionBar }
<a href={permalink} onClick={this.onPermalinkClicked}>
{ timestamp }
@ -1395,7 +1398,7 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
}) }
}, this.context.showHiddenEvents) }
</div>,
<a
className="mx_EventTile_senderDetailsLink"
@ -1448,7 +1451,7 @@ export class UnwrappedEventTile extends React.Component<IProps, IState> {
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
}) }
}, this.context.showHiddenEvents) }
{ keyRequestInfo }
{ actionBar }
{ this.props.layout === Layout.IRC && <>

View file

@ -110,7 +110,9 @@ export default class ReplyTile extends React.PureComponent<IProps> {
const msgType = mxEvent.getContent().msgtype;
const evType = mxEvent.getType() as EventType;
const { hasRenderer, isInfoMessage, isSeeingThroughMessageHiddenForModeration } = getEventDisplayInfo(mxEvent);
const {
hasRenderer, isInfoMessage, isSeeingThroughMessageHiddenForModeration,
} = getEventDisplayInfo(mxEvent, false /* Replies are never hidden, so this should be fine */);
// This shouldn't happen: the caller should check we support this type
// before trying to instantiate us
if (!hasRenderer) {
@ -177,7 +179,7 @@ export default class ReplyTile extends React.PureComponent<IProps> {
highlightLink: this.props.highlightLink,
onHeightChanged: this.props.onHeightChanged,
permalinkCreator: this.props.permalinkCreator,
}) }
}, false /* showHiddenEvents shouldn't be relevant */) }
</a>
</div>
);

View file

@ -78,7 +78,7 @@ export default class SearchResultTile extends React.Component<IProps> {
highlights = this.props.searchHighlights;
}
if (haveRendererForEvent(mxEv, this.context?.showHiddenEventsInTimeline)) {
if (haveRendererForEvent(mxEv, this.context?.showHiddenEvents)) {
// do we need a date separator since the last event?
const prevEv = timeline[j - 1];
// is this a continuation of the previous message?
@ -87,7 +87,7 @@ export default class SearchResultTile extends React.Component<IProps> {
shouldFormContinuation(
prevEv,
mxEv,
this.context?.showHiddenEventsInTimeline,
this.context?.showHiddenEvents,
threadsEnabled,
TimelineRenderingType.Search,
);
@ -102,7 +102,7 @@ export default class SearchResultTile extends React.Component<IProps> {
!shouldFormContinuation(
mxEv,
nextEv,
this.context?.showHiddenEventsInTimeline,
this.context?.showHiddenEvents,
threadsEnabled,
TimelineRenderingType.Search,
)