Step 6: Refactor event rendering to stop using getComponent
We move all of the event tile rendering into a factory manager for a couple reasons: 1. `EventTile` is uncomfortably large for a file 2. A simple map isn't possible anymore (can't convert the existing maps like `eventTileTypes` to `Record<string, typeof React.Component>` because the types are actually incompatible) So, by having a factory manager place we can more easily render components without having to use `getComponent()` all over the place, and without lying to ourselves about how simple the event rendering path is. This change also moves quite a bit of the rendering path into the new `EventTileFactory` file so it can be easily seen by future developers.
This commit is contained in:
parent
115ae198c8
commit
9350c50f87
14 changed files with 523 additions and 283 deletions
|
@ -27,11 +27,11 @@ import { Action } from '../../../dispatcher/actions';
|
|||
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
|
||||
import SenderProfile from "../messages/SenderProfile";
|
||||
import MImageReplyBody from "../messages/MImageReplyBody";
|
||||
import * as sdk from '../../../index';
|
||||
import { getEventDisplayInfo, isVoiceMessage } from '../../../utils/EventUtils';
|
||||
import MFileBody from "../messages/MFileBody";
|
||||
import MVoiceMessageBody from "../messages/MVoiceMessageBody";
|
||||
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { renderReplyTile } from "../../../events/EventTileFactory";
|
||||
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
|
@ -109,10 +109,10 @@ export default class ReplyTile extends React.PureComponent<IProps> {
|
|||
const msgType = mxEvent.getContent().msgtype;
|
||||
const evType = mxEvent.getType() as EventType;
|
||||
|
||||
const { tileHandler, isInfoMessage, isSeeingThroughMessageHiddenForModeration } = getEventDisplayInfo(mxEvent);
|
||||
const { hasRenderer, isInfoMessage, isSeeingThroughMessageHiddenForModeration } = getEventDisplayInfo(mxEvent);
|
||||
// This shouldn't happen: the caller should check we support this type
|
||||
// before trying to instantiate us
|
||||
if (!tileHandler) {
|
||||
if (!hasRenderer) {
|
||||
const { mxEvent } = this.props;
|
||||
logger.warn(`Event type not supported: type:${mxEvent.getType()} isState:${mxEvent.isState()}`);
|
||||
return <div className="mx_ReplyTile mx_ReplyTile_info mx_MNoticeBody">
|
||||
|
@ -120,8 +120,6 @@ export default class ReplyTile extends React.PureComponent<IProps> {
|
|||
</div>;
|
||||
}
|
||||
|
||||
const EventTileType = sdk.getComponent(tileHandler);
|
||||
|
||||
const classes = classNames("mx_ReplyTile", {
|
||||
mx_ReplyTile_info: isInfoMessage && !mxEvent.isRedacted(),
|
||||
mx_ReplyTile_audio: msgType === MsgType.Audio,
|
||||
|
@ -135,10 +133,10 @@ export default class ReplyTile extends React.PureComponent<IProps> {
|
|||
|
||||
let sender;
|
||||
const needsSenderProfile = (
|
||||
!isInfoMessage &&
|
||||
msgType !== MsgType.Image &&
|
||||
tileHandler !== EventType.RoomCreate &&
|
||||
evType !== EventType.Sticker
|
||||
!isInfoMessage
|
||||
&& msgType !== MsgType.Image
|
||||
&& evType !== EventType.Sticker
|
||||
&& evType !== EventType.RoomCreate
|
||||
);
|
||||
|
||||
if (needsSenderProfile) {
|
||||
|
@ -147,13 +145,13 @@ export default class ReplyTile extends React.PureComponent<IProps> {
|
|||
/>;
|
||||
}
|
||||
|
||||
const msgtypeOverrides = {
|
||||
const msgtypeOverrides: Record<string, typeof React.Component> = {
|
||||
[MsgType.Image]: MImageReplyBody,
|
||||
// Override audio and video body with file body. We also hide the download/decrypt button using CSS
|
||||
[MsgType.Audio]: isVoiceMessage(mxEvent) ? MVoiceMessageBody : MFileBody,
|
||||
[MsgType.Video]: MFileBody,
|
||||
};
|
||||
const evOverrides = {
|
||||
const evOverrides: Record<string, typeof React.Component> = {
|
||||
// Use MImageReplyBody so that the sticker isn't taking up a lot of space
|
||||
[EventType.Sticker]: MImageReplyBody,
|
||||
};
|
||||
|
@ -162,20 +160,23 @@ export default class ReplyTile extends React.PureComponent<IProps> {
|
|||
<div className={classes}>
|
||||
<a href={permalink} onClick={this.onClick} ref={this.anchorElement}>
|
||||
{ sender }
|
||||
<EventTileType
|
||||
ref="tile"
|
||||
mxEvent={mxEvent}
|
||||
highlights={this.props.highlights}
|
||||
highlightLink={this.props.highlightLink}
|
||||
onHeightChanged={this.props.onHeightChanged}
|
||||
showUrlPreview={false}
|
||||
overrideBodyTypes={msgtypeOverrides}
|
||||
overrideEventTypes={evOverrides}
|
||||
replacingEventId={mxEvent.replacingEventId()}
|
||||
maxImageHeight={96}
|
||||
getRelationsForEvent={this.props.getRelationsForEvent}
|
||||
isSeeingThroughMessageHiddenForModeration={isSeeingThroughMessageHiddenForModeration}
|
||||
/>
|
||||
{ renderReplyTile({
|
||||
...this.props,
|
||||
|
||||
// overrides
|
||||
ref: null,
|
||||
showUrlPreview: false,
|
||||
overrideBodyTypes: msgtypeOverrides,
|
||||
overrideEventTypes: evOverrides,
|
||||
maxImageHeight: 96,
|
||||
isSeeingThroughMessageHiddenForModeration,
|
||||
|
||||
// appease TS
|
||||
highlights: this.props.highlights,
|
||||
highlightLink: this.props.highlightLink,
|
||||
onHeightChanged: this.props.onHeightChanged,
|
||||
permalinkCreator: this.props.permalinkCreator,
|
||||
}) }
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue