-
-
Notifications
You must be signed in to change notification settings - Fork 833
Handle command completions in RTE #10521
Changes from 33 commits
02939fe
d4cadad
4fe0077
6b623d0
e056d5d
c0668f4
212a998
c65a1b7
f4c272d
6f46bf8
0db94cb
f8bddc0
735e8a8
b0c62a3
86347a4
0282c14
377e191
66f8380
8cddb25
000d744
a1a5917
b1ca999
4abd905
fa13702
01fa6a7
cd4ce1b
63579d0
45cc670
b77025b
91ba491
2863b3d
61946a1
a72b837
276f4f7
425d946
eb4e1a8
c08290f
b523ef7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,7 @@ export function useWysiwygSendActionHandler( | |
|
||
switch (payload.action) { | ||
case "reply_to_event": | ||
case Action.FocusAComposer: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the action that is fired when a user enters a bad command and then makes a decision from the dialog they're presented with - it ensures that we put the cursor back in the composer when the dialog closes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that documented in the actions file? Would be good to if not |
||
case Action.FocusSendMessageComposer: | ||
focusComposer(composerElement, context, roomContext, timeoutId); | ||
break; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ limitations under the License. | |
*/ | ||
|
||
import { Composer as ComposerEvent } from "@matrix-org/analytics-events/types/typescript/Composer"; | ||
import { IEventRelation, MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||
import { IContent, IEventRelation, MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||
import { ISendEventResponse, MatrixClient } from "matrix-js-sdk/src/matrix"; | ||
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread"; | ||
|
||
|
@@ -33,6 +33,11 @@ import { endEditing, cancelPreviousPendingEdit } from "./editing"; | |
import EditorStateTransfer from "../../../../../utils/EditorStateTransfer"; | ||
import { createMessageContent } from "./createMessageContent"; | ||
import { isContentModified } from "./isContentModified"; | ||
import { CommandCategories, getCommand } from "../../../../../SlashCommands"; | ||
import { runSlashCommand, shouldSendAnyway } from "../../../../../editor/commands"; | ||
import { Action } from "../../../../../dispatcher/actions"; | ||
import { addReplyToMessageContent } from "../../../../../utils/Reply"; | ||
import { attachRelation } from "../../SendMessageComposer"; | ||
|
||
export interface SendMessageParams { | ||
mxClient: MatrixClient; | ||
|
@@ -47,8 +52,8 @@ export async function sendMessage( | |
message: string, | ||
isHTML: boolean, | ||
{ roomContext, mxClient, ...params }: SendMessageParams, | ||
): Promise<ISendEventResponse> { | ||
const { relation, replyToEvent } = params; | ||
): Promise<ISendEventResponse | undefined> { | ||
const { relation, replyToEvent, permalinkCreator } = params; | ||
const { room } = roomContext; | ||
const roomId = room?.roomId; | ||
|
||
|
@@ -71,9 +76,51 @@ export async function sendMessage( | |
}*/ | ||
PosthogAnalytics.instance.trackEvent<ComposerEvent>(posthogEvent); | ||
|
||
const content = await createMessageContent(message, isHTML, params); | ||
let content: IContent | null = null; | ||
|
||
// TODO slash comment | ||
// Functionality here approximates what can be found in SendMessageComposer.sendMessage() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic in this block is not really new, it has been taken from the current composer's code that is run when a message is sent (can be seen in |
||
if (message.startsWith("/") && !message.startsWith("//")) { | ||
const { cmd, args } = getCommand(message); | ||
if (cmd) { | ||
// we will need to handle /me separately, see SlashCommands.tsx:1387 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems a little brittle to refer to a line number like this, is it possible to just describe the location? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep the action is already documented as it's what is used by the current composer. Fair point on the comment, I couldn't figure out a way to make it a useful link so I've just described the location more generally. |
||
const threadId = relation?.rel_type === THREAD_RELATION_TYPE.name ? relation?.event_id : null; | ||
let commandSuccessful: boolean; | ||
[content, commandSuccessful] = await runSlashCommand(cmd, args, roomId, threadId ?? null); | ||
|
||
if (!commandSuccessful) { | ||
return; // errored | ||
} | ||
|
||
if ( | ||
content && | ||
(cmd.category === CommandCategories.messages || cmd.category === CommandCategories.effects) | ||
) { | ||
attachRelation(content, relation); | ||
if (replyToEvent) { | ||
addReplyToMessageContent(content, replyToEvent, { | ||
permalinkCreator, | ||
// Exclude the legacy fallback for custom event types such as those used by /fireworks | ||
includeLegacyFallback: content.msgtype?.startsWith("m.") ?? true, | ||
}); | ||
} | ||
} else { | ||
// instead of setting shouldSend to false as in SendMessageComposer, just return | ||
return; | ||
} | ||
} else { | ||
const sendAnyway = await shouldSendAnyway(message); | ||
// re-focus the composer after QuestionDialog is closed | ||
dis.dispatch({ | ||
action: Action.FocusAComposer, | ||
context: roomContext.timelineRenderingType, | ||
}); | ||
// if !sendAnyway bail to let the user edit the composer and try again | ||
if (!sendAnyway) return; | ||
} | ||
} | ||
|
||
// if content is null, we haven't done any slash command processing, so generate some content | ||
content ??= await createMessageContent(message, isHTML, params); | ||
|
||
// TODO replace emotion end of message ? | ||
|
||
|
@@ -92,7 +139,7 @@ export async function sendMessage( | |
|
||
const prom = doMaybeLocalRoomAction( | ||
roomId, | ||
(actualRoomId: string) => mxClient.sendMessage(actualRoomId, threadId, content), | ||
(actualRoomId: string) => mxClient.sendMessage(actualRoomId, threadId, content as IContent), | ||
mxClient, | ||
); | ||
|
||
|
@@ -108,7 +155,7 @@ export async function sendMessage( | |
|
||
dis.dispatch({ action: "message_sent" }); | ||
CHAT_EFFECTS.forEach((effect) => { | ||
if (containsEmoji(content, effect.emojis)) { | ||
if (content && containsEmoji(content, effect.emojis)) { | ||
// For initial threads launch, chat effects are disabled | ||
// see #19731 | ||
const isNotThread = relation?.rel_type !== THREAD_RELATION_TYPE.name; | ||
|
@@ -146,7 +193,7 @@ interface EditMessageParams { | |
export async function editMessage( | ||
html: string, | ||
{ roomContext, mxClient, editorStateTransfer }: EditMessageParams, | ||
): Promise<ISendEventResponse> { | ||
): Promise<ISendEventResponse | undefined> { | ||
const editedEvent = editorStateTransfer.getEvent(); | ||
|
||
PosthogAnalytics.instance.trackEvent<ComposerEvent>({ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was previously returning
false | Promise<...>
which I don't think is what we were aiming for here.