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
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 - 2021 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019 - 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -23,12 +23,13 @@ import { M_POLL_START } from "matrix-events-sdk";
|
|||
|
||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||
import shouldHideEvent from "../shouldHideEvent";
|
||||
import { getHandlerTile, GetRelationsForEvent, haveTileForEvent } from "../components/views/rooms/EventTile";
|
||||
import { GetRelationsForEvent } from "../components/views/rooms/EventTile";
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
import defaultDispatcher from "../dispatcher/dispatcher";
|
||||
import { TimelineRenderingType } from "../contexts/RoomContext";
|
||||
import { launchPollEditor } from "../components/views/messages/MPollBody";
|
||||
import { Action } from "../dispatcher/actions";
|
||||
import { haveRendererForEvent, JitsiEventFactory, JSONEventFactory, pickFactory } from "../events/EventTileFactory";
|
||||
|
||||
/**
|
||||
* Returns whether an event should allow actions like reply, reactions, edit, etc.
|
||||
|
@ -134,7 +135,7 @@ export function findEditableEvent({
|
|||
/**
|
||||
* How we should render a message depending on its moderation state.
|
||||
*/
|
||||
enum MessageModerationState {
|
||||
export enum MessageModerationState {
|
||||
/**
|
||||
* The message is visible to all.
|
||||
*/
|
||||
|
@ -158,7 +159,9 @@ enum MessageModerationState {
|
|||
* If MSC3531 is deactivated in settings, all messages are considered visible
|
||||
* to all.
|
||||
*/
|
||||
export function getMessageModerationState(mxEvent: MatrixEvent): MessageModerationState {
|
||||
export function getMessageModerationState(mxEvent: MatrixEvent, client?: MatrixClient): MessageModerationState {
|
||||
client = client ?? MatrixClientPeg.get(); // because param defaults don't do the correct thing
|
||||
|
||||
if (!SettingsStore.getValue("feature_msc3531_hide_messages_pending_moderation")) {
|
||||
return MessageModerationState.VISIBLE_FOR_ALL;
|
||||
}
|
||||
|
@ -171,7 +174,6 @@ export function getMessageModerationState(mxEvent: MatrixEvent): MessageModerati
|
|||
// pending moderation. However, if we're the author or a moderator,
|
||||
// we still need to display it.
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
if (mxEvent.sender?.userId === client.getUserId()) {
|
||||
// We're the author, show the message.
|
||||
return MessageModerationState.SEE_THROUGH_FOR_CURRENT_USER;
|
||||
|
@ -196,7 +198,7 @@ export function getMessageModerationState(mxEvent: MatrixEvent): MessageModerati
|
|||
|
||||
export function getEventDisplayInfo(mxEvent: MatrixEvent, hideEvent?: boolean): {
|
||||
isInfoMessage: boolean;
|
||||
tileHandler: string;
|
||||
hasRenderer: boolean;
|
||||
isBubbleMessage: boolean;
|
||||
isLeftAlignedBubbleMessage: boolean;
|
||||
noBubbleEvent: boolean;
|
||||
|
@ -207,15 +209,11 @@ export function getEventDisplayInfo(mxEvent: MatrixEvent, hideEvent?: boolean):
|
|||
const eventType = mxEvent.getType();
|
||||
|
||||
let isSeeingThroughMessageHiddenForModeration = false;
|
||||
let tileHandler;
|
||||
if (SettingsStore.getValue("feature_msc3531_hide_messages_pending_moderation")) {
|
||||
switch (getMessageModerationState(mxEvent)) {
|
||||
case MessageModerationState.VISIBLE_FOR_ALL:
|
||||
// Default behavior, nothing to do.
|
||||
break;
|
||||
case MessageModerationState.HIDDEN_TO_CURRENT_USER:
|
||||
// Hide message.
|
||||
tileHandler = "messages.HiddenBody";
|
||||
// Nothing specific to do here
|
||||
break;
|
||||
case MessageModerationState.SEE_THROUGH_FOR_CURRENT_USER:
|
||||
// Show message with a marker.
|
||||
|
@ -223,9 +221,9 @@ export function getEventDisplayInfo(mxEvent: MatrixEvent, hideEvent?: boolean):
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!tileHandler) {
|
||||
tileHandler = getHandlerTile(mxEvent);
|
||||
}
|
||||
|
||||
// TODO: Thread a MatrixClient through to here
|
||||
let factory = pickFactory(mxEvent, MatrixClientPeg.get());
|
||||
|
||||
// Info messages are basically information about commands processed on a room
|
||||
let isBubbleMessage = (
|
||||
|
@ -233,7 +231,7 @@ export function getEventDisplayInfo(mxEvent: MatrixEvent, hideEvent?: boolean):
|
|||
(eventType === EventType.RoomMessage && msgtype?.startsWith("m.key.verification")) ||
|
||||
(eventType === EventType.RoomCreate) ||
|
||||
(eventType === EventType.RoomEncryption) ||
|
||||
(tileHandler === "messages.MJitsiWidgetEvent")
|
||||
(factory === JitsiEventFactory)
|
||||
);
|
||||
const isLeftAlignedBubbleMessage = (
|
||||
!isBubbleMessage &&
|
||||
|
@ -263,15 +261,20 @@ export function getEventDisplayInfo(mxEvent: MatrixEvent, hideEvent?: boolean):
|
|||
// source tile when there's no regular tile for an event and also for
|
||||
// replace relations (which otherwise would display as a confusing
|
||||
// duplicate of the thing they are replacing).
|
||||
if ((hideEvent || !haveTileForEvent(mxEvent)) && SettingsStore.getValue("showHiddenEventsInTimeline")) {
|
||||
tileHandler = "messages.ViewSourceEvent";
|
||||
isBubbleMessage = false;
|
||||
// Reuse info message avatar and sender profile styling
|
||||
isInfoMessage = true;
|
||||
if (hideEvent || !haveRendererForEvent(mxEvent)) {
|
||||
// forcefully ask for a factory for a hidden event (hidden event
|
||||
// setting is checked internally)
|
||||
// TODO: Thread a MatrixClient through to here
|
||||
factory = pickFactory(mxEvent, MatrixClientPeg.get(), true);
|
||||
if (factory === JSONEventFactory) {
|
||||
isBubbleMessage = false;
|
||||
// Reuse info message avatar and sender profile styling
|
||||
isInfoMessage = true;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
tileHandler,
|
||||
hasRenderer: !!factory,
|
||||
isInfoMessage,
|
||||
isBubbleMessage,
|
||||
isLeftAlignedBubbleMessage,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue