Cleanup `MessageContextMenu` code (#8351)

pull/28217/head
Šimon Brandner 2022-04-19 09:59:23 +02:00 committed by GitHub
parent 2f3249793f
commit 511965b840
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 52 deletions

View File

@ -21,7 +21,6 @@ import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
import { EventType, RelationType } from "matrix-js-sdk/src/@types/event";
import { Relations } from 'matrix-js-sdk/src/models/relations';
import { RoomMemberEvent } from "matrix-js-sdk/src/models/room-member";
import { M_LOCATION } from 'matrix-js-sdk/src/@types/location';
import { M_POLL_START } from "matrix-events-sdk";
import { MatrixClientPeg } from '../../../MatrixClientPeg';
@ -31,7 +30,7 @@ import Modal from '../../../Modal';
import Resend from '../../../Resend';
import SettingsStore from '../../../settings/SettingsStore';
import { isUrlPermitted } from '../../../HtmlUtils';
import { canEditContent, editEvent, isContentActionable } from '../../../utils/EventUtils';
import { canEditContent, canForward, editEvent, isContentActionable, isLocationEvent } from '../../../utils/EventUtils';
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from './IconizedContextMenu';
import { ReadPinsEventId } from "../right_panel/types";
import { Action } from "../../../dispatcher/actions";
@ -49,20 +48,11 @@ import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInse
import EndPollDialog from '../dialogs/EndPollDialog';
import { isPollEnded } from '../messages/MPollBody';
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { GetRelationsForEvent } from "../rooms/EventTile";
import { GetRelationsForEvent, IEventTileOps } from "../rooms/EventTile";
import { OpenForwardDialogPayload } from "../../../dispatcher/payloads/OpenForwardDialogPayload";
import { OpenReportEventDialogPayload } from "../../../dispatcher/payloads/OpenReportEventDialogPayload";
import { createMapSiteLink } from '../../../utils/location';
export interface IEventTileOps {
isWidgetHidden(): boolean;
unhideWidget(): void;
}
export interface IOperableEventTile {
getEventTileOps(): IEventTileOps;
}
interface IProps extends IPosition {
chevronFace: ChevronFace;
/* the MatrixEvent associated with the context menu */
@ -343,28 +333,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
const isThreadRootEvent = isThread && mxEvent?.getThread()?.rootEvent === mxEvent;
let openInMapSiteButton: JSX.Element;
let endPollButton: JSX.Element;
let resendReactionsButton: JSX.Element;
let redactButton: JSX.Element;
let forwardButton: JSX.Element;
let pinButton: JSX.Element;
let unhidePreviewButton: JSX.Element;
let externalURLButton: JSX.Element;
let quoteButton: JSX.Element;
let redactItemList: JSX.Element;
let reportEventButton: JSX.Element;
let copyButton: JSX.Element;
let editButton: JSX.Element;
let replyButton: JSX.Element;
let reactButton: JSX.Element;
let reactionPicker: JSX.Element;
let quickItemsList: JSX.Element;
let nativeItemsList: JSX.Element;
let permalinkButton: JSX.Element;
let collapseReplyChainButton: JSX.Element;
let viewInRoomButton: JSX.Element;
if (!mxEvent.isRedacted() && unsentReactionsCount !== 0) {
resendReactionsButton = (
<IconizedContextMenuOption
@ -375,6 +344,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let redactButton: JSX.Element;
if (isSent && this.state.canRedact) {
redactButton = (
<IconizedContextMenuOption
@ -385,6 +355,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let openInMapSiteButton: JSX.Element;
if (this.canOpenInMapSite(mxEvent)) {
const mapSiteLink = createMapSiteLink(mxEvent);
openInMapSiteButton = (
@ -404,6 +375,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let forwardButton: JSX.Element;
if (contentActionable && canForward(mxEvent)) {
forwardButton = (
<IconizedContextMenuOption
@ -414,6 +386,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let pinButton: JSX.Element;
if (contentActionable && this.state.canPin) {
pinButton = (
<IconizedContextMenuOption
@ -435,6 +408,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let unhidePreviewButton: JSX.Element;
if (eventTileOps?.isWidgetHidden()) {
unhidePreviewButton = (
<IconizedContextMenuOption
@ -445,6 +419,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let permalinkButton: JSX.Element;
if (permalink) {
permalinkButton = (
<IconizedContextMenuOption
@ -468,6 +443,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let endPollButton: JSX.Element;
if (this.canEndPoll(mxEvent)) {
endPollButton = (
<IconizedContextMenuOption
@ -478,6 +454,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let quoteButton: JSX.Element;
if (eventTileOps) { // this event is rendered using TextualBody
quoteButton = (
<IconizedContextMenuOption
@ -489,6 +466,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
}
// Bridges can provide a 'external_url' to link back to the source.
let externalURLButton: JSX.Element;
if (
typeof (mxEvent.getContent().external_url) === "string" &&
isUrlPermitted(mxEvent.getContent().external_url)
@ -511,6 +489,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let collapseReplyChainButton: JSX.Element;
if (collapseReplyChain) {
collapseReplyChainButton = (
<IconizedContextMenuOption
@ -521,6 +500,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let reportEventButton: JSX.Element;
if (mxEvent.getSender() !== me) {
reportEventButton = (
<IconizedContextMenuOption
@ -531,6 +511,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let copyButton: JSX.Element;
if (rightClick && getSelectedText()) {
copyButton = (
<IconizedContextMenuOption
@ -542,6 +523,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let editButton: JSX.Element;
if (rightClick && canEditContent(mxEvent)) {
editButton = (
<IconizedContextMenuOption
@ -552,6 +534,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let replyButton: JSX.Element;
if (rightClick && contentActionable && canSendMessages) {
replyButton = (
<IconizedContextMenuOption
@ -562,6 +545,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let reactButton;
if (rightClick && contentActionable && canReact) {
reactButton = (
<IconizedContextMenuOption
@ -573,6 +557,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let viewInRoomButton: JSX.Element;
if (isThreadRootEvent) {
viewInRoomButton = (
<IconizedContextMenuOption
@ -583,6 +568,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let nativeItemsList: JSX.Element;
if (copyButton) {
nativeItemsList = (
<IconizedContextMenuOptionList>
@ -591,6 +577,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let quickItemsList: JSX.Element;
if (editButton || replyButton || reactButton) {
quickItemsList = (
<IconizedContextMenuOptionList>
@ -619,6 +606,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
</IconizedContextMenuOptionList>
);
let redactItemList: JSX.Element;
if (redactButton) {
redactItemList = (
<IconizedContextMenuOptionList red>
@ -627,6 +615,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
let reactionPicker: JSX.Element;
if (this.state.reactionPickerDisplayed) {
const buttonRect = (this.reactButtonRef.current as HTMLElement)?.getBoundingClientRect();
reactionPicker = (
@ -662,20 +651,3 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
}
}
function canForward(event: MatrixEvent): boolean {
return !(
isLocationEvent(event) ||
M_POLL_START.matches(event.getType())
);
}
function isLocationEvent(event: MatrixEvent): boolean {
const eventType = event.getType();
return (
M_LOCATION.matches(eventType) ||
(
eventType === EventType.RoomMessage &&
M_LOCATION.matches(event.getContent().msgtype)
)
);
}

View File

@ -26,7 +26,6 @@ import { Mjolnir } from "../../../mjolnir/Mjolnir";
import RedactedBody from "./RedactedBody";
import UnknownBody from "./UnknownBody";
import { IMediaBody } from "./IMediaBody";
import { IOperableEventTile } from "../context_menus/MessageContextMenu";
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
import { ReactAnyComponent } from "../../../@types/common";
import { IBodyProps } from "./IBodyProps";
@ -41,6 +40,7 @@ import MPollBody from "./MPollBody";
import MLocationBody from "./MLocationBody";
import MjolnirBody from "./MjolnirBody";
import MBeaconBody from "./MBeaconBody";
import { IEventTileOps } from "../rooms/EventTile";
// onMessageAllowed is handled internally
interface IProps extends Omit<IBodyProps, "onMessageAllowed" | "mediaEventHelper"> {
@ -54,6 +54,10 @@ interface IProps extends Omit<IBodyProps, "onMessageAllowed" | "mediaEventHelper
isSeeingThroughMessageHiddenForModeration?: boolean;
}
export interface IOperableEventTile {
getEventTileOps(): IEventTileOps;
}
export default class MessageEvent extends React.Component<IProps> implements IMediaBody, IOperableEventTile {
private body: React.RefObject<React.Component | IOperableEventTile> = createRef();
private mediaHelper: MediaEventHelper;

View File

@ -38,7 +38,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { E2EState } from "./E2EIcon";
import { toRem } from "../../../utils/units";
import RoomAvatar from "../avatars/RoomAvatar";
import MessageContextMenu, { IEventTileOps } from "../context_menus/MessageContextMenu";
import MessageContextMenu from "../context_menus/MessageContextMenu";
import { aboveRightOf } from '../../structures/ContextMenu';
import { objectHasDiff } from "../../../utils/objects";
import Tooltip from "../elements/Tooltip";
@ -99,6 +99,11 @@ export interface IReadReceiptProps {
ts: number;
}
export interface IEventTileOps {
isWidgetHidden(): boolean;
unhideWidget(): void;
}
export interface IEventTileType extends React.Component {
getEventTileOps?(): IEventTileOps;
}

View File

@ -19,6 +19,7 @@ import { EventType, EVENT_VISIBILITY_CHANGE_TYPE, MsgType, RelationType } from "
import { MatrixClient } from 'matrix-js-sdk/src/client';
import { logger } from 'matrix-js-sdk/src/logger';
import { M_POLL_START } from "matrix-events-sdk";
import { M_LOCATION } from "matrix-js-sdk/src/@types/location";
import { MatrixClientPeg } from '../MatrixClientPeg';
import shouldHideEvent from "../shouldHideEvent";
@ -262,3 +263,21 @@ export function editEvent(
export function canCancel(status: EventStatus): boolean {
return status === EventStatus.QUEUED || status === EventStatus.NOT_SENT || status === EventStatus.ENCRYPTING;
}
export const isLocationEvent = (event: MatrixEvent): boolean => {
const eventType = event.getType();
return (
M_LOCATION.matches(eventType) ||
(
eventType === EventType.RoomMessage &&
M_LOCATION.matches(event.getContent().msgtype)
)
);
};
export function canForward(event: MatrixEvent): boolean {
return !(
isLocationEvent(event) ||
M_POLL_START.matches(event.getType())
);
}