5196.js.map (39243B)
1 {"version":3,"file":"bundles/12c8185ea2689492c07b/5196.js","mappings":"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","sources":["webpack://element-web/./src/components/views/rooms/wysiwyg_composer/components/EditionButtons.tsx","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/useInitialContent.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/EditWysiwygComposer.tsx","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/useWysiwygEditActionHandler.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/hooks/useEditing.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/utils/createMessageContent.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/utils/message.ts","webpack://element-web/./src/components/views/rooms/wysiwyg_composer/utils/isContentModified.ts"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type JSX } from \"react\";\n\nimport { _t } from \"../../../../../languageHandler\";\nimport AccessibleButton, { type ButtonEvent } from \"../../../elements/AccessibleButton\";\n\ninterface EditionButtonsProps {\n onCancelClick: (e: ButtonEvent) => void;\n onSaveClick: (e: ButtonEvent) => void;\n isSaveDisabled?: boolean;\n}\n\nexport function EditionButtons({\n onCancelClick,\n onSaveClick,\n isSaveDisabled = false,\n}: EditionButtonsProps): JSX.Element {\n return (\n <div className=\"mx_EditWysiwygComposer_buttons\">\n <AccessibleButton kind=\"secondary\" onClick={onCancelClick}>\n {_t(\"action|cancel\")}\n </AccessibleButton>\n <AccessibleButton kind=\"primary\" onClick={onSaveClick} disabled={isSaveDisabled}>\n {_t(\"action|save\")}\n </AccessibleButton>\n </div>\n );\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type MatrixClient, type Room } from \"matrix-js-sdk/src/matrix\";\nimport { useMemo } from \"react\";\n\nimport { useMatrixClientContext } from \"../../../../../contexts/MatrixClientContext\";\nimport { parseEvent } from \"../../../../../editor/deserialize\";\nimport { CommandPartCreator, type Part } from \"../../../../../editor/parts\";\nimport SettingsStore from \"../../../../../settings/SettingsStore\";\nimport type EditorStateTransfer from \"../../../../../utils/EditorStateTransfer\";\nimport { useScopedRoomContext } from \"../../../../../contexts/ScopedRoomContext.tsx\";\n\nfunction getFormattedContent(editorStateTransfer: EditorStateTransfer): string {\n return (\n editorStateTransfer\n .getEvent()\n .getContent()\n .formatted_body?.replace(/<mx-reply>.*<\\/mx-reply>/, \"\") || \"\"\n );\n}\n\nexport function parseEditorStateTransfer(\n editorStateTransfer: EditorStateTransfer,\n room: Room,\n mxClient: MatrixClient,\n): string {\n const partCreator = new CommandPartCreator(room, mxClient);\n\n let parts: (Part | undefined)[] = [];\n if (editorStateTransfer.hasEditorState()) {\n // if restoring state from a previous editor,\n // restore serialized parts from the state\n const serializedParts = editorStateTransfer.getSerializedParts();\n if (serializedParts !== null) {\n parts = serializedParts.map((p) => partCreator.deserializePart(p));\n }\n } else {\n // otherwise, either restore serialized parts from localStorage or parse the body of the event\n // TODO local storage\n // const restoredParts = this.restoreStoredEditorState(partCreator);\n\n if (editorStateTransfer.getEvent().getContent().format === \"org.matrix.custom.html\") {\n return getFormattedContent(editorStateTransfer);\n }\n\n parts = parseEvent(editorStateTransfer.getEvent(), partCreator, {\n shouldEscape: SettingsStore.getValue(\"MessageComposerInput.useMarkdown\"),\n });\n }\n\n return parts.reduce((content, part) => content + part?.text, \"\");\n // Todo local storage\n // this.saveStoredEditorState();\n}\n\nexport function useInitialContent(editorStateTransfer: EditorStateTransfer): string | undefined {\n const { room } = useScopedRoomContext(\"room\");\n const mxClient = useMatrixClientContext();\n\n return useMemo<string | undefined>(() => {\n if (editorStateTransfer && room && mxClient) {\n return parseEditorStateTransfer(editorStateTransfer, room, mxClient);\n }\n }, [editorStateTransfer, room, mxClient]);\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type JSX, type RefObject, useMemo, type ReactNode } from \"react\";\nimport classNames from \"classnames\";\n\nimport type EditorStateTransfer from \"../../../../utils/EditorStateTransfer\";\nimport { WysiwygComposer } from \"./components/WysiwygComposer\";\nimport { EditionButtons } from \"./components/EditionButtons\";\nimport { useWysiwygEditActionHandler } from \"./hooks/useWysiwygEditActionHandler\";\nimport { useEditing } from \"./hooks/useEditing\";\nimport { useInitialContent } from \"./hooks/useInitialContent\";\nimport { ComposerContext, getDefaultContextValue } from \"./ComposerContext\";\nimport { type ComposerFunctions } from \"./types\";\n\ninterface ContentProps {\n disabled?: boolean;\n composerFunctions: ComposerFunctions;\n ref?: RefObject<HTMLElement | null>;\n}\n\nconst Content = function Content({ disabled = false, composerFunctions, ref }: ContentProps): ReactNode {\n useWysiwygEditActionHandler(disabled, ref, composerFunctions);\n return null;\n};\n\ninterface EditWysiwygComposerProps {\n disabled?: boolean;\n onChange?: (content: string) => void;\n editorStateTransfer: EditorStateTransfer;\n className?: string;\n}\n\n// Default needed for React.lazy\nexport default function EditWysiwygComposer({\n editorStateTransfer,\n className,\n ...props\n}: EditWysiwygComposerProps): JSX.Element {\n const defaultContextValue = useMemo(() => getDefaultContextValue({ editorStateTransfer }), [editorStateTransfer]);\n const initialContent = useInitialContent(editorStateTransfer);\n const isReady = !editorStateTransfer || initialContent !== undefined;\n\n const { editMessage, endEditing, onChange, isSaveDisabled } = useEditing(editorStateTransfer, initialContent);\n\n if (!isReady) {\n return <></>;\n }\n\n return (\n <ComposerContext.Provider value={defaultContextValue}>\n <WysiwygComposer\n className={classNames(\"mx_EditWysiwygComposer\", className)}\n initialContent={initialContent}\n onChange={onChange}\n onSend={editMessage}\n {...props}\n >\n {(ref, composerFunctions) => (\n <>\n <Content disabled={props.disabled} ref={ref} composerFunctions={composerFunctions} />\n <EditionButtons\n onCancelClick={endEditing}\n onSaveClick={editMessage}\n isSaveDisabled={isSaveDisabled}\n />\n </>\n )}\n </WysiwygComposer>\n </ComposerContext.Provider>\n );\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type RefObject, useCallback, useRef } from \"react\";\n\nimport defaultDispatcher from \"../../../../../dispatcher/dispatcher\";\nimport { Action } from \"../../../../../dispatcher/actions\";\nimport { type ActionPayload } from \"../../../../../dispatcher/payloads\";\nimport { TimelineRenderingType } from \"../../../../../contexts/RoomContext\";\nimport { useDispatcher } from \"../../../../../hooks/useDispatcher\";\nimport { focusComposer } from \"./utils\";\nimport { ComposerType } from \"../../../../../dispatcher/payloads/ComposerInsertPayload\";\nimport { type ComposerFunctions } from \"../types\";\nimport { setSelection } from \"../utils/selection\";\nimport { useComposerContext } from \"../ComposerContext\";\nimport { useScopedRoomContext } from \"../../../../../contexts/ScopedRoomContext.tsx\";\n\nexport function useWysiwygEditActionHandler(\n disabled: boolean,\n composerElement: RefObject<HTMLElement | null> | undefined,\n composerFunctions: ComposerFunctions,\n): void {\n const roomContext = useScopedRoomContext(\"timelineRenderingType\");\n const composerContext = useComposerContext();\n const timeoutId = useRef<number | null>(null);\n\n const handler = useCallback(\n (payload: ActionPayload) => {\n // don't let the user into the composer if it is disabled - all of these branches lead\n // to the cursor being in the composer\n if (disabled || !composerElement?.current) return;\n\n const context = payload.context ?? TimelineRenderingType.Room;\n\n switch (payload.action) {\n case Action.FocusEditMessageComposer:\n focusComposer(composerElement, context, roomContext, timeoutId);\n break;\n case Action.ComposerInsert:\n if (payload.timelineRenderingType !== roomContext.timelineRenderingType) break;\n if (payload.composerType !== ComposerType.Edit) break;\n\n if (payload.text) {\n setSelection(composerContext.selection).then(() => composerFunctions.insertText(payload.text));\n }\n break;\n }\n },\n [disabled, composerElement, composerFunctions, timeoutId, roomContext, composerContext],\n );\n\n useDispatcher(defaultDispatcher, handler);\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type ISendEventResponse } from \"matrix-js-sdk/src/matrix\";\nimport { useCallback, useState } from \"react\";\n\nimport { useMatrixClientContext } from \"../../../../../contexts/MatrixClientContext\";\nimport type EditorStateTransfer from \"../../../../../utils/EditorStateTransfer\";\nimport { endEditing } from \"../utils/editing\";\nimport { editMessage } from \"../utils/message\";\nimport { useScopedRoomContext } from \"../../../../../contexts/ScopedRoomContext.tsx\";\n\nexport function useEditing(\n editorStateTransfer: EditorStateTransfer,\n initialContent?: string,\n): {\n isSaveDisabled: boolean;\n onChange(this: void, content: string): void;\n editMessage(this: void): Promise<ISendEventResponse | undefined>;\n endEditing(this: void): void;\n} {\n const roomContext = useScopedRoomContext(\"timelineRenderingType\");\n const mxClient = useMatrixClientContext();\n\n const [isSaveDisabled, setIsSaveDisabled] = useState(true);\n const [content, setContent] = useState(initialContent);\n const onChange = useCallback(\n (_content: string) => {\n setContent(_content);\n setIsSaveDisabled((_isSaveDisabled) => _isSaveDisabled && _content === initialContent);\n },\n [initialContent],\n );\n\n const editMessageMemoized = useCallback(async () => {\n if (mxClient === undefined || content === undefined) {\n return;\n }\n return editMessage(content, { roomContext, mxClient, editorStateTransfer });\n }, [content, roomContext, mxClient, editorStateTransfer]);\n\n const endEditingMemoized = useCallback(() => endEditing(roomContext), [roomContext]);\n return { onChange, editMessage: editMessageMemoized, endEditing: endEditingMemoized, isSaveDisabled };\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { richToPlain, plainToRich } from \"@vector-im/matrix-wysiwyg\";\nimport { type IContent, type IEventRelation, MatrixEvent, MsgType } from \"matrix-js-sdk/src/matrix\";\nimport {\n type ReplacementEvent,\n type RoomMessageEventContent,\n type RoomMessageTextEventContent,\n} from \"matrix-js-sdk/src/types\";\n\nimport SettingsStore from \"../../../../../settings/SettingsStore\";\nimport { parsePermalink } from \"../../../../../utils/permalinks/Permalinks\";\nimport { addReplyToMessageContent } from \"../../../../../utils/Reply\";\nimport { isNotNull } from \"../../../../../Typeguards\";\n\nexport const EMOTE_PREFIX = \"/me \";\n\n// Merges favouring the given relation\nfunction attachRelation(content: IContent, relation?: IEventRelation): void {\n if (relation) {\n content[\"m.relates_to\"] = {\n ...content[\"m.relates_to\"],\n ...relation,\n };\n }\n}\n\ninterface CreateMessageContentParams {\n relation?: IEventRelation;\n replyToEvent?: MatrixEvent;\n editedEvent?: MatrixEvent;\n}\n\nconst isMatrixEvent = (e: MatrixEvent | undefined): e is MatrixEvent => e instanceof MatrixEvent;\n\nexport async function createMessageContent(\n message: string,\n isHTML: boolean,\n { relation, replyToEvent, editedEvent }: CreateMessageContentParams,\n): Promise<RoomMessageEventContent> {\n const isEditing = isMatrixEvent(editedEvent);\n\n const isEmote = message.startsWith(EMOTE_PREFIX);\n if (isEmote) {\n // if we are dealing with an emote we want to remove the prefix so that `/me` does not\n // appear after the `* <userName>` text in the timeline\n message = message.slice(EMOTE_PREFIX.length);\n }\n if (message.startsWith(\"//\")) {\n // if user wants to enter a single slash at the start of a message, this\n // is how they have to do it (due to it clashing with commands), so here we\n // remove the first character to make sure //word displays as /word\n message = message.slice(1);\n }\n\n // if we're editing rich text, the message content is pure html\n // BUT if we're not, the message content will be plain text where we need to convert the mentions\n const body = isHTML ? await richToPlain(message, false) : convertPlainTextToBody(message);\n\n const content = {\n msgtype: isEmote ? MsgType.Emote : MsgType.Text,\n body: isEditing ? `* ${body}` : body,\n } as RoomMessageTextEventContent & ReplacementEvent<RoomMessageTextEventContent>;\n\n // TODO markdown support\n\n const isMarkdownEnabled = SettingsStore.getValue(\"MessageComposerInput.useMarkdown\");\n const formattedBody = isHTML ? message : isMarkdownEnabled ? await plainToRich(message, true) : null;\n\n if (formattedBody) {\n content.format = \"org.matrix.custom.html\";\n content.formatted_body = isEditing ? `* ${formattedBody}` : formattedBody;\n }\n\n if (isEditing) {\n content[\"m.new_content\"] = {\n msgtype: content.msgtype,\n body: body,\n };\n\n if (formattedBody) {\n content[\"m.new_content\"].format = \"org.matrix.custom.html\";\n content[\"m.new_content\"][\"formatted_body\"] = formattedBody;\n }\n }\n\n const newRelation = isEditing ? { ...relation, rel_type: \"m.replace\", event_id: editedEvent.getId() } : relation;\n\n // TODO Do we need to attach mentions here?\n // TODO Handle editing?\n attachRelation(content, newRelation);\n\n if (!isEditing && replyToEvent) {\n addReplyToMessageContent(content, replyToEvent);\n }\n\n return content;\n}\n\n/**\n * Without a model, we need to manually amend mentions in uncontrolled message content\n * to make sure that mentions meet the matrix specification.\n *\n * @param content - the output from the `MessageComposer` state when in plain text mode\n * @returns - a string formatted with the mentions replaced as required\n */\nfunction convertPlainTextToBody(content: string): string {\n const document = new DOMParser().parseFromString(content, \"text/html\");\n const mentions = Array.from(document.querySelectorAll(\"a[data-mention-type]\"));\n\n mentions.forEach((mention) => {\n const mentionType = mention.getAttribute(\"data-mention-type\");\n switch (mentionType) {\n case \"at-room\": {\n mention.replaceWith(\"@room\");\n break;\n }\n case \"user\": {\n const innerText = mention.innerHTML;\n mention.replaceWith(innerText);\n break;\n }\n case \"room\": {\n // for this case we use parsePermalink to try and get the mx id\n const href = mention.getAttribute(\"href\");\n\n // if the mention has no href attribute, leave it alone\n if (href === null) break;\n\n // otherwise, attempt to parse the room alias or id from the href\n const permalinkParts = parsePermalink(href);\n\n // then if we have permalink parts with a valid roomIdOrAlias, replace the\n // room mention with that text\n if (isNotNull(permalinkParts) && isNotNull(permalinkParts.roomIdOrAlias)) {\n mention.replaceWith(permalinkParts.roomIdOrAlias);\n }\n break;\n }\n default:\n break;\n }\n });\n\n return document.body.innerHTML;\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022, 2023 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type Composer as ComposerEvent } from \"@matrix-org/analytics-events/types/typescript/Composer\";\nimport {\n type IEventRelation,\n type MatrixEvent,\n type ISendEventResponse,\n type MatrixClient,\n THREAD_RELATION_TYPE,\n} from \"matrix-js-sdk/src/matrix\";\nimport { type RoomMessageEventContent } from \"matrix-js-sdk/src/types\";\nimport { type MessageComposerUrlPreviewSnapshot } from \"@element-hq/web-shared-components\";\n\nimport { PosthogAnalytics } from \"../../../../../PosthogAnalytics\";\nimport SettingsStore from \"../../../../../settings/SettingsStore\";\nimport { decorateStartSendingTime, sendRoundTripMetric } from \"../../../../../sendTimePerformanceMetrics\";\nimport { doMaybeLocalRoomAction } from \"../../../../../utils/local-room\";\nimport { CHAT_EFFECTS } from \"../../../../../effects\";\nimport { containsEmoji } from \"../../../../../effects/utils\";\nimport { type IRoomState } from \"../../../../structures/RoomView\";\nimport dis from \"../../../../../dispatcher/dispatcher\";\nimport { createRedactEventDialog } from \"../../../dialogs/ConfirmRedactDialog\";\nimport { endEditing, cancelPreviousPendingEdit } from \"./editing\";\nimport type EditorStateTransfer from \"../../../../../utils/EditorStateTransfer\";\nimport { createMessageContent, EMOTE_PREFIX } from \"./createMessageContent\";\nimport { isContentModified } from \"./isContentModified\";\nimport { CommandCategories, getCommand } from \"../../../../../slash-commands/SlashCommands\";\nimport { runSlashCommand, shouldSendAnyway } from \"../../../../../editor/commands\";\nimport { Action } from \"../../../../../dispatcher/actions\";\nimport { addReplyToMessageContent } from \"../../../../../utils/Reply\";\nimport { attachRelation, attachUrlPreviews } from \"../../../../../utils/messages\";\n\nexport interface SendMessageParams {\n mxClient: MatrixClient;\n relation?: IEventRelation;\n replyToEvent?: MatrixEvent;\n roomContext: Pick<IRoomState, \"timelineRenderingType\" | \"room\">;\n urlPreviewSnapshot: MessageComposerUrlPreviewSnapshot;\n}\n\nexport async function sendMessage(\n message: string,\n isHTML: boolean,\n { roomContext, mxClient, urlPreviewSnapshot, ...params }: SendMessageParams,\n): Promise<ISendEventResponse | undefined> {\n const { relation, replyToEvent } = params;\n const { room } = roomContext;\n const roomId = room?.roomId;\n\n if (!roomId) {\n return;\n }\n\n const posthogEvent: ComposerEvent = {\n eventName: \"Composer\",\n isEditing: false,\n messageType: \"Text\",\n isReply: Boolean(replyToEvent),\n // TODO thread\n inThread: relation?.rel_type === THREAD_RELATION_TYPE.name,\n };\n\n // TODO thread\n /*if (posthogEvent.inThread) {\n const threadRoot = room.findEventById(relation?.event_id);\n posthogEvent.startsThread = threadRoot?.getThread()?.events.length === 1;\n }*/\n PosthogAnalytics.instance.trackEvent<ComposerEvent>(posthogEvent);\n\n let content: RoomMessageEventContent | null = null;\n\n // Slash command handling here approximates what can be found in SendMessageComposer.sendMessage()\n // but note that the /me and // special cases are handled by the call to createMessageContent\n if (message.startsWith(\"/\") && !message.startsWith(\"//\") && !message.startsWith(EMOTE_PREFIX)) {\n const { cmd, args } = getCommand(roomId, message);\n if (cmd) {\n const threadId = relation?.rel_type === THREAD_RELATION_TYPE.name ? relation?.event_id : null;\n let commandSuccessful: boolean;\n [content, commandSuccessful] = await runSlashCommand(mxClient, cmd, args, roomId, threadId ?? null);\n\n if (!commandSuccessful) {\n return; // errored\n }\n\n if (\n content &&\n (cmd.category === CommandCategories.messages || cmd.category === CommandCategories.effects)\n ) {\n attachRelation(content, relation);\n if (replyToEvent) {\n addReplyToMessageContent(content, replyToEvent);\n }\n } else {\n // instead of setting shouldSend to false as in SendMessageComposer, just return\n return;\n }\n } else {\n const sendAnyway = await shouldSendAnyway(message);\n // re-focus the composer after QuestionDialog is closed\n dis.dispatch({\n action: Action.FocusAComposer,\n context: roomContext.timelineRenderingType,\n });\n // if !sendAnyway bail to let the user edit the composer and try again\n if (!sendAnyway) return;\n }\n }\n\n // if content is null, we haven't done any slash command processing, so generate some content\n content ??= await createMessageContent(message, isHTML, params);\n attachUrlPreviews(urlPreviewSnapshot, content);\n\n // TODO replace emotion end of message ?\n\n // TODO quick reaction\n\n // don't bother sending an empty message\n if (!content.body.trim()) {\n return;\n }\n\n if (SettingsStore.getValue(\"Performance.addSendMessageTimingMetadata\")) {\n decorateStartSendingTime(content);\n }\n\n const threadId = relation?.event_id && relation?.rel_type === THREAD_RELATION_TYPE.name ? relation.event_id : null;\n\n const prom = doMaybeLocalRoomAction(\n roomId,\n (actualRoomId: string) => mxClient.sendMessage(actualRoomId, threadId, content!),\n mxClient,\n );\n\n if (replyToEvent) {\n // Clear reply_to_event as we put the message into the queue\n // if the send fails, retry will handle resending.\n dis.dispatch({\n action: \"reply_to_event\",\n event: null,\n context: roomContext.timelineRenderingType,\n });\n }\n\n dis.dispatch({ action: \"message_sent\" });\n CHAT_EFFECTS.forEach((effect) => {\n if (content && containsEmoji(content, effect.emojis)) {\n // For initial threads launch, chat effects are disabled\n // see #19731\n const isNotThread = relation?.rel_type !== THREAD_RELATION_TYPE.name;\n if (isNotThread) {\n dis.dispatch({ action: `effects.${effect.command}` });\n }\n }\n });\n if (SettingsStore.getValue(\"Performance.addSendMessageTimingMetadata\")) {\n prom.then((resp) => {\n sendRoundTripMetric(mxClient, roomId, resp.event_id);\n });\n }\n\n // TODO save history\n // TODO save local state\n\n //if (shouldSend && SettingsStore.getValue(\"scrollToBottomOnMessageSent\")) {\n if (SettingsStore.getValue(\"scrollToBottomOnMessageSent\")) {\n dis.dispatch({\n action: \"scroll_to_bottom\",\n timelineRenderingType: roomContext.timelineRenderingType,\n });\n }\n\n return prom;\n}\n\ninterface EditMessageParams {\n mxClient: MatrixClient;\n roomContext: Pick<IRoomState, \"timelineRenderingType\">;\n editorStateTransfer: EditorStateTransfer;\n}\n\nexport async function editMessage(\n html: string,\n { roomContext, mxClient, editorStateTransfer }: EditMessageParams,\n): Promise<ISendEventResponse | undefined> {\n const editedEvent = editorStateTransfer.getEvent();\n\n PosthogAnalytics.instance.trackEvent<ComposerEvent>({\n eventName: \"Composer\",\n isEditing: true,\n messageType: \"Text\",\n inThread: Boolean(editedEvent?.getThread()),\n isReply: Boolean(editedEvent.replyEventId),\n });\n\n // TODO emoji\n // Replace emoticon at the end of the message\n /* if (SettingsStore.getValue('MessageComposerInput.autoReplaceEmoji')) {\n const caret = this.editorRef.current?.getCaret();\n const position = this.model.positionForOffset(caret.offset, caret.atNodeEnd);\n this.editorRef.current?.replaceEmoticon(position, REGEX_EMOTICON);\n }*/\n const editContent = await createMessageContent(html, true, { editedEvent });\n const newContent = editContent[\"m.new_content\"]!;\n\n const shouldSend = true;\n\n if (newContent?.body === \"\") {\n cancelPreviousPendingEdit(mxClient, editorStateTransfer);\n createRedactEventDialog({\n mxEvent: editedEvent,\n onCloseDialog: () => {\n endEditing(roomContext);\n },\n });\n return;\n }\n\n let response: Promise<ISendEventResponse> | undefined;\n\n const roomId = editedEvent.getRoomId();\n\n // If content is modified then send an updated event into the room\n if (isContentModified(newContent, editorStateTransfer) && roomId) {\n // TODO Slash Commands\n\n if (shouldSend) {\n cancelPreviousPendingEdit(mxClient, editorStateTransfer);\n\n const event = editorStateTransfer.getEvent();\n const threadId = event.threadRootId || null;\n\n response = mxClient.sendMessage(roomId, threadId, editContent);\n dis.dispatch({ action: \"message_sent\" });\n }\n }\n\n endEditing(roomContext);\n return response;\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { type RoomMessageEventContent, type RoomMessageTextEventContent } from \"matrix-js-sdk/src/types\";\n\nimport type EditorStateTransfer from \"../../../../../utils/EditorStateTransfer\";\n\nexport function isContentModified(\n newContent: RoomMessageEventContent,\n editorStateTransfer: EditorStateTransfer,\n): boolean {\n // if nothing has changed then bail\n const oldContent = editorStateTransfer.getEvent().getContent<RoomMessageEventContent>();\n if (\n oldContent[\"msgtype\"] === newContent[\"msgtype\"] &&\n oldContent[\"body\"] === newContent[\"body\"] &&\n (<RoomMessageTextEventContent>oldContent)[\"format\"] === (<RoomMessageTextEventContent>newContent)[\"format\"] &&\n (<RoomMessageTextEventContent>oldContent)[\"formatted_body\"] ===\n (<RoomMessageTextEventContent>newContent)[\"formatted_body\"]\n ) {\n return false;\n }\n return true;\n}\n"],"names":["EditionButtons","onCancelClick","onSaveClick","isSaveDisabled","React","className","AccessibleButton","kind","onClick","_t","disabled","useInitialContent","editorStateTransfer","room","useScopedRoomContext","mxClient","useMatrixClientContext","useMemo","partCreator","CommandPartCreator","parts","hasEditorState","serializedParts","getSerializedParts","map","p","deserializePart","getEvent","getContent","format","_editorStateTransfer$","formatted_body","replace","getFormattedContent","parseEvent","shouldEscape","SettingsStore","getValue","reduce","content","part","text","parseEditorStateTransfer","Content","composerFunctions","ref","composerElement","roomContext","composerContext","useComposerContext","timeoutId","useRef","handler","useCallback","payload","_payload$context","current","context","TimelineRenderingType","Room","action","Action","FocusEditMessageComposer","focusComposer","ComposerInsert","timelineRenderingType","composerType","ComposerType","Edit","setSelection","selection","then","insertText","useDispatcher","defaultDispatcher","useWysiwygEditActionHandler","EditWysiwygComposer","_ref","props","_objectWithoutProperties","_excluded","defaultContextValue","getDefaultContextValue","initialContent","isReady","undefined","editMessage","endEditing","onChange","setIsSaveDisabled","useState","setContent","_content","_isSaveDisabled","async","useEditing","ComposerContext","Provider","value","WysiwygComposer","_extends","classNames","onSend","EMOTE_PREFIX","createMessageContent","message","isHTML","relation","replyToEvent","editedEvent","isEditing","MatrixEvent","isEmote","startsWith","slice","body","richToPlain","document","DOMParser","parseFromString","Array","from","querySelectorAll","forEach","mention","getAttribute","replaceWith","innerText","innerHTML","href","permalinkParts","parsePermalink","isNotNull","roomIdOrAlias","convertPlainTextToBody","msgtype","MsgType","Emote","Text","isMarkdownEnabled","formattedBody","plainToRich","_objectSpread","attachRelation","rel_type","event_id","getId","addReplyToMessageContent","sendMessage","urlPreviewSnapshot","params","roomId","posthogEvent","eventName","messageType","isReply","Boolean","inThread","THREAD_RELATION_TYPE","name","PosthogAnalytics","instance","trackEvent","cmd","args","getCommand","threadId","commandSuccessful","runSlashCommand","category","CommandCategories","messages","effects","sendAnyway","shouldSendAnyway","dis","dispatch","FocusAComposer","attachUrlPreviews","trim","decorateStartSendingTime","prom","doMaybeLocalRoomAction","actualRoomId","event","CHAT_EFFECTS","effect","containsEmoji","emojis","command","resp","sendRoundTripMetric","html","getThread","replyEventId","editContent","newContent","cancelPreviousPendingEdit","createRedactEventDialog","mxEvent","onCloseDialog","response","getRoomId","oldContent","isContentModified","threadRootId"],"sourceRoot":""}