Add basic plain text editor
This commit is contained in:
parent
6e73a853a8
commit
50279c8870
18 changed files with 316 additions and 62 deletions
|
@ -16,6 +16,8 @@ limitations under the License.
|
|||
|
||||
import { IContent, IEventRelation, MatrixEvent, MsgType } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { htmlSerializeFromMdIfNeeded } from "../../../../../editor/serialize";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import { RoomPermalinkCreator } from "../../../../../utils/permalinks/Permalinks";
|
||||
import { addReplyToMessageContent } from "../../../../../utils/Reply";
|
||||
|
||||
|
@ -39,6 +41,19 @@ function getHtmlReplyFallback(mxEvent: MatrixEvent): string {
|
|||
return (mxReply && mxReply.outerHTML) || "";
|
||||
}
|
||||
|
||||
function getTextReplyFallback(mxEvent: MatrixEvent): string {
|
||||
const body = mxEvent.getContent().body;
|
||||
const lines = body.split("\n").map(l => l.trim());
|
||||
if (lines.length > 2 && lines[0].startsWith("> ") && lines[1].length === 0) {
|
||||
return `${lines[0]}\n\n`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function htmlToPlainText(html: string) {
|
||||
return new DOMParser().parseFromString(html, 'text/html').documentElement.textContent;
|
||||
}
|
||||
|
||||
interface CreateMessageContentParams {
|
||||
relation?: IEventRelation;
|
||||
replyToEvent?: MatrixEvent;
|
||||
|
@ -49,6 +64,7 @@ interface CreateMessageContentParams {
|
|||
|
||||
export function createMessageContent(
|
||||
message: string,
|
||||
isHTML: boolean,
|
||||
{ relation, replyToEvent, permalinkCreator, includeReplyLegacyFallback = true, editedEvent }:
|
||||
CreateMessageContentParams,
|
||||
): IContent {
|
||||
|
@ -56,6 +72,7 @@ export function createMessageContent(
|
|||
|
||||
const isEditing = Boolean(editedEvent);
|
||||
const isReply = isEditing ? Boolean(editedEvent?.replyEventId) : Boolean(replyToEvent);
|
||||
const isReplyAndEditing = isEditing && isReply;
|
||||
|
||||
/*const isEmote = containsEmote(model);
|
||||
if (isEmote) {
|
||||
|
@ -67,37 +84,43 @@ export function createMessageContent(
|
|||
model = unescapeMessage(model);*/
|
||||
|
||||
// const body = textSerialize(model);
|
||||
const body = message;
|
||||
|
||||
const body = isHTML && htmlToPlainText(message) || message;
|
||||
const bodyPrefix = isReplyAndEditing && getTextReplyFallback(editedEvent) || '';
|
||||
const formattedBodyPrefix = isReplyAndEditing && getHtmlReplyFallback(editedEvent) || '';
|
||||
|
||||
const content: IContent = {
|
||||
// TODO emote
|
||||
// msgtype: isEmote ? "m.emote" : "m.text",
|
||||
msgtype: MsgType.Text,
|
||||
body: body,
|
||||
// TODO when available, use HTML --> Plain text conversion from wysiwyg rust model
|
||||
body: isEditing ? `${bodyPrefix} * ${body}` : body,
|
||||
};
|
||||
|
||||
// TODO markdown support
|
||||
|
||||
/*const formattedBody = htmlSerializeIfNeeded(model, {
|
||||
forceHTML: !!replyToEvent,
|
||||
useMarkdown: SettingsStore.getValue("MessageComposerInput.useMarkdown"),
|
||||
});*/
|
||||
const formattedBody = message;
|
||||
const isMarkdownEnabled = SettingsStore.getValue<boolean>("MessageComposerInput.useMarkdown");
|
||||
const formattedBody =
|
||||
isHTML ?
|
||||
message :
|
||||
isMarkdownEnabled ?
|
||||
htmlSerializeFromMdIfNeeded(message, { forceHTML: isReply }) :
|
||||
null;
|
||||
|
||||
if (formattedBody) {
|
||||
content.format = "org.matrix.custom.html";
|
||||
|
||||
const htmlPrefix = isReply && isEditing ? getHtmlReplyFallback(editedEvent) : '';
|
||||
content.formatted_body = isEditing ? `${htmlPrefix} * ${formattedBody}` : formattedBody;
|
||||
content.formatted_body = isEditing ? `${formattedBodyPrefix} * ${formattedBody}` : formattedBody;
|
||||
}
|
||||
|
||||
if (isEditing) {
|
||||
content['m.new_content'] = {
|
||||
"msgtype": content.msgtype,
|
||||
"body": body,
|
||||
"format": "org.matrix.custom.html",
|
||||
'formatted_body': formattedBody,
|
||||
};
|
||||
|
||||
if (formattedBody) {
|
||||
content['m.new_content'].format = "org.matrix.custom.html";
|
||||
content['m.new_content']['formatted_body'] = formattedBody;
|
||||
}
|
||||
}
|
||||
|
||||
const newRelation = isEditing ?
|
||||
|
|
|
@ -44,7 +44,8 @@ interface SendMessageParams {
|
|||
}
|
||||
|
||||
export function sendMessage(
|
||||
html: string,
|
||||
message: string,
|
||||
isHTML: boolean,
|
||||
{ roomContext, mxClient, ...params }: SendMessageParams,
|
||||
) {
|
||||
const { relation, replyToEvent } = params;
|
||||
|
@ -76,7 +77,8 @@ export function sendMessage(
|
|||
|
||||
if (!content) {
|
||||
content = createMessageContent(
|
||||
html,
|
||||
message,
|
||||
isHTML,
|
||||
params,
|
||||
);
|
||||
}
|
||||
|
@ -167,7 +169,7 @@ export function editMessage(
|
|||
const position = this.model.positionForOffset(caret.offset, caret.atNodeEnd);
|
||||
this.editorRef.current?.replaceEmoticon(position, REGEX_EMOTICON);
|
||||
}*/
|
||||
const editContent = createMessageContent(html, { editedEvent });
|
||||
const editContent = createMessageContent(html, true, { editedEvent });
|
||||
const newContent = editContent["m.new_content"];
|
||||
|
||||
const shouldSend = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue