mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 03:36:07 +03:00
Move editEvent()
to EventUtils
(#7836)
This commit is contained in:
parent
34567b9aab
commit
fe7f1688dd
5 changed files with 71 additions and 63 deletions
|
@ -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;
|
||||||
|
|
|
@ -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 = [
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue