Move editEvent() to EventUtils (#7836)

This commit is contained in:
Šimon Brandner 2022-02-18 16:01:32 +01:00 committed by GitHub
parent 34567b9aab
commit fe7f1688dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 63 deletions

View file

@ -38,6 +38,9 @@ import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
import StyledRadioButton from '../elements/StyledRadioButton'; import StyledRadioButton from '../elements/StyledRadioButton';
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";
import ErrorDialog from '../dialogs/ErrorDialog'; import ErrorDialog from '../dialogs/ErrorDialog';
import { GetRelationsForEvent } from "../rooms/EventTile";
import PollCreateDialog from "../elements/PollCreateDialog";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
interface IState { interface IState {
selected?: string; // Which option was clicked by the local user selected?: string; // Which option was clicked by the local user
@ -169,6 +172,43 @@ export function isPollEnded(
return authorisedRelations.length > 0; return authorisedRelations.length > 0;
} }
export function pollAlreadyHasVotes(mxEvent: MatrixEvent, getRelationsForEvent?: GetRelationsForEvent): boolean {
if (!getRelationsForEvent) return false;
const voteRelations = createVoteRelations(getRelationsForEvent, mxEvent.getId());
return voteRelations.getRelations().length > 0;
}
export function launchPollEditor(mxEvent: MatrixEvent, getRelationsForEvent?: GetRelationsForEvent): void {
if (pollAlreadyHasVotes(mxEvent, getRelationsForEvent)) {
Modal.createTrackedDialog(
'Not allowed to edit poll',
'',
ErrorDialog,
{
title: _t("Can't edit poll"),
description: _t(
"Sorry, you can't edit a poll after votes have been cast.",
),
},
);
} else {
Modal.createTrackedDialog(
'Polls',
'create',
PollCreateDialog,
{
room: MatrixClientPeg.get().getRoom(mxEvent.getRoomId()),
threadId: mxEvent.getThread()?.id ?? null,
editingMxEvent: mxEvent,
},
'mx_CompoundDialog',
false, // isPriorityModal
true, // isStaticModal
);
}
}
@replaceableComponent("views.messages.MPollBody") @replaceableComponent("views.messages.MPollBody")
export default class MPollBody extends React.Component<IBodyProps, IState> { export default class MPollBody extends React.Component<IBodyProps, IState> {
public static contextType = MatrixClientContext; public static contextType = MatrixClientContext;

View file

@ -20,14 +20,13 @@ import React, { ReactElement, useEffect } from 'react';
import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event'; import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
import classNames from 'classnames'; import classNames from 'classnames';
import { MsgType } from 'matrix-js-sdk/src/@types/event'; import { MsgType } from 'matrix-js-sdk/src/@types/event';
import { M_POLL_START } from 'matrix-events-sdk';
import type { Relations } from 'matrix-js-sdk/src/models/relations'; import type { Relations } from 'matrix-js-sdk/src/models/relations';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import dis from '../../../dispatcher/dispatcher'; import dis from '../../../dispatcher/dispatcher';
import { Action } from '../../../dispatcher/actions'; import { Action } from '../../../dispatcher/actions';
import ContextMenu, { aboveLeftOf, ContextMenuTooltipButton, useContextMenu } from '../../structures/ContextMenu'; import ContextMenu, { aboveLeftOf, ContextMenuTooltipButton, useContextMenu } from '../../structures/ContextMenu';
import { isContentActionable, canEditContent } from '../../../utils/EventUtils'; import { isContentActionable, canEditContent, editEvent } from '../../../utils/EventUtils';
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext"; import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
import Toolbar from "../../../accessibility/Toolbar"; import Toolbar from "../../../accessibility/Toolbar";
import { RovingAccessibleTooltipButton, useRovingTabIndex } from "../../../accessibility/RovingTabIndex"; import { RovingAccessibleTooltipButton, useRovingTabIndex } from "../../../accessibility/RovingTabIndex";
@ -40,13 +39,9 @@ import DownloadActionButton from "./DownloadActionButton";
import SettingsStore from '../../../settings/SettingsStore'; import SettingsStore from '../../../settings/SettingsStore';
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks'; import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
import ReplyChain from '../elements/ReplyChain'; import ReplyChain from '../elements/ReplyChain';
import { showThread } from '../../../dispatcher/dispatch-actions/threads';
import ReactionPicker from "../emojipicker/ReactionPicker"; import ReactionPicker from "../emojipicker/ReactionPicker";
import { CardContext } from '../right_panel/BaseCard'; import { CardContext } from '../right_panel/BaseCard';
import Modal from '../../../Modal'; import { showThread } from "../../../dispatcher/dispatch-actions/threads";
import PollCreateDialog from '../elements/PollCreateDialog';
import ErrorDialog from '../dialogs/ErrorDialog';
import { createVoteRelations } from './MPollBody';
interface IOptionsButtonProps { interface IOptionsButtonProps {
mxEvent: MatrixEvent; mxEvent: MatrixEvent;
@ -233,59 +228,8 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
}); });
}; };
private pollAlreadyHasVotes = (): boolean => {
if (!this.props.getRelationsForEvent) {
return false;
}
const voteRelations = createVoteRelations(
this.props.getRelationsForEvent,
this.props.mxEvent.getId(),
);
return voteRelations.getRelations().length > 0;
};
private launchPollEditor = (): void => {
if (this.pollAlreadyHasVotes()) {
Modal.createTrackedDialog(
'Not allowed to edit poll',
'',
ErrorDialog,
{
title: _t("Can't edit poll"),
description: _t(
"Sorry, you can't edit a poll after votes have been cast.",
),
},
);
} else {
Modal.createTrackedDialog(
'Polls',
'create',
PollCreateDialog,
{
room: this.context.room,
threadId: this.context.threadId ?? null,
editingMxEvent: this.props.mxEvent,
},
'mx_CompoundDialog',
false, // isPriorityModal
true, // isStaticModal
);
}
};
private onEditClick = (): void => { private onEditClick = (): void => {
if (M_POLL_START.matches(this.props.mxEvent.getType())) { editEvent(this.props.mxEvent, this.context.timelineRenderingType);
this.launchPollEditor();
} else {
dis.dispatch({
action: Action.EditEvent,
event: this.props.mxEvent,
timelineRenderingType: this.context.timelineRenderingType,
});
}
}; };
private readonly forbiddenThreadHeadMsgType = [ private readonly forbiddenThreadHeadMsgType = [

View file

@ -79,6 +79,8 @@ import { DecryptionFailureTracker } from '../../../DecryptionFailureTracker';
import RedactedBody from '../messages/RedactedBody'; import RedactedBody from '../messages/RedactedBody';
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
export type GetRelationsForEvent = (eventId: string, relationType: string, eventType: string) => Relations;
const eventTileTypes = { const eventTileTypes = {
[EventType.RoomMessage]: 'messages.MessageEvent', [EventType.RoomMessage]: 'messages.MessageEvent',
[EventType.Sticker]: 'messages.MessageEvent', [EventType.Sticker]: 'messages.MessageEvent',
@ -293,7 +295,7 @@ interface IProps {
isTwelveHour?: boolean; isTwelveHour?: boolean;
// helper function to access relations for this event // helper function to access relations for this event
getRelationsForEvent?: (eventId: string, relationType: string, eventType: string) => Relations; getRelationsForEvent?: GetRelationsForEvent;
// whether to show reactions for this event // whether to show reactions for this event
showReactions?: boolean; showReactions?: boolean;

View file

@ -2093,8 +2093,6 @@
"Go": "Go", "Go": "Go",
"Error processing audio message": "Error processing audio message", "Error processing audio message": "Error processing audio message",
"React": "React", "React": "React",
"Can't edit poll": "Can't edit poll",
"Sorry, you can't edit a poll after votes have been cast.": "Sorry, you can't edit a poll after votes have been cast.",
"Edit": "Edit", "Edit": "Edit",
"Reply in thread": "Reply in thread", "Reply in thread": "Reply in thread",
"Reply": "Reply", "Reply": "Reply",
@ -2130,6 +2128,8 @@
"Failed to load map": "Failed to load map", "Failed to load map": "Failed to load map",
"Zoom in": "Zoom in", "Zoom in": "Zoom in",
"Zoom out": "Zoom out", "Zoom out": "Zoom out",
"Can't edit poll": "Can't edit poll",
"Sorry, you can't edit a poll after votes have been cast.": "Sorry, you can't edit a poll after votes have been cast.",
"Vote not registered": "Vote not registered", "Vote not registered": "Vote not registered",
"Sorry, your vote was not registered. Please try again.": "Sorry, your vote was not registered. Please try again.", "Sorry, your vote was not registered. Please try again.": "Sorry, your vote was not registered. Please try again.",
"Final result based on %(count)s votes|other": "Final result based on %(count)s votes", "Final result based on %(count)s votes|other": "Final result based on %(count)s votes",

View file

@ -23,8 +23,12 @@ import { M_POLL_START } from "matrix-events-sdk";
import { MatrixClientPeg } from '../MatrixClientPeg'; import { MatrixClientPeg } from '../MatrixClientPeg';
import shouldHideEvent from "../shouldHideEvent"; import shouldHideEvent from "../shouldHideEvent";
import { getHandlerTile, haveTileForEvent } from "../components/views/rooms/EventTile"; import { getHandlerTile, GetRelationsForEvent, haveTileForEvent } from "../components/views/rooms/EventTile";
import SettingsStore from "../settings/SettingsStore"; 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";
/** /**
* Returns whether an event should allow actions like reply, reactions, edit, etc. * Returns whether an event should allow actions like reply, reactions, edit, etc.
@ -312,3 +316,21 @@ export async function fetchInitialEvent(
return initialEvent; return initialEvent;
} }
export function editEvent(
mxEvent: MatrixEvent,
timelineRenderingType: TimelineRenderingType,
getRelationsForEvent?: GetRelationsForEvent,
): void {
if (!canEditContent(mxEvent)) return;
if (M_POLL_START.matches(mxEvent.getType())) {
launchPollEditor(mxEvent, getRelationsForEvent);
} else {
defaultDispatcher.dispatch({
action: Action.EditEvent,
event: mxEvent,
timelineRenderingType: timelineRenderingType,
});
}
}