From fe70e64a40b341b3e21b8c25baacbf5693ef1a75 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Oct 2021 11:01:40 +0100 Subject: [PATCH 1/3] Improve typing --- src/editor/deserialize.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/editor/deserialize.ts b/src/editor/deserialize.ts index 14be9f8a92d..b9043e565a7 100644 --- a/src/editor/deserialize.ts +++ b/src/editor/deserialize.ts @@ -20,7 +20,7 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { walkDOMDepthFirst } from "./dom"; import { checkBlockNode } from "../HtmlUtils"; import { getPrimaryPermalinkEntity } from "../utils/permalinks/Permalinks"; -import { PartCreator, Type } from "./parts"; +import { Part, PartCreator, Type } from "./parts"; import SdkConfig from "../SdkConfig"; function parseAtRoomMentions(text: string, partCreator: PartCreator) { @@ -213,12 +213,12 @@ function prefixQuoteLines(isFirstNode, parts, partCreator) { } } -function parseHtmlMessage(html: string, partCreator: PartCreator, isQuotedMessage: boolean) { +function parseHtmlMessage(html: string, partCreator: PartCreator, isQuotedMessage: boolean): Part[] { // no nodes from parsing here should be inserted in the document, // as scripts in event handlers, etc would be executed then. // we're only taking text, so that is fine const rootNode = new DOMParser().parseFromString(html, "text/html").body; - const parts = []; + const parts: Part[] = []; let lastNode; let inQuote = isQuotedMessage; const state: IState = { @@ -233,7 +233,7 @@ function parseHtmlMessage(html: string, partCreator: PartCreator, isQuotedMessag inQuote = true; } - const newParts = []; + const newParts: Part[] = []; if (lastNode && (checkBlockNode(lastNode) || checkBlockNode(n))) { newParts.push(partCreator.newline()); } @@ -288,7 +288,7 @@ function parseHtmlMessage(html: string, partCreator: PartCreator, isQuotedMessag return parts; } -export function parsePlainTextMessage(body: string, partCreator: PartCreator, isQuotedMessage?: boolean) { +export function parsePlainTextMessage(body: string, partCreator: PartCreator, isQuotedMessage?: boolean): Part[] { const lines = body.split(/\r\n|\r|\n/g); // split on any new-line combination not just \n, collapses \r\n return lines.reduce((parts, line, i) => { if (isQuotedMessage) { @@ -300,7 +300,7 @@ export function parsePlainTextMessage(body: string, partCreator: PartCreator, is parts.push(partCreator.newline()); } return parts; - }, []); + }, [] as Part[]); } export function parseEvent(event: MatrixEvent, partCreator: PartCreator, { isQuotedMessage = false } = {}) { From ddc408690cf0931ca5d640a49a2de5091dc5edd6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Oct 2021 11:02:06 +0100 Subject: [PATCH 2/3] Fix EditorModel clone to actually be useful --- src/editor/model.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/editor/model.ts b/src/editor/model.ts index 212a7d17c04..b9850a7ba77 100644 --- a/src/editor/model.ts +++ b/src/editor/model.ts @@ -91,7 +91,8 @@ export default class EditorModel { } public clone(): EditorModel { - return new EditorModel(this._parts, this._partCreator, this.updateCallback); + const clonedParts = this.parts.map(p => this.partCreator.deserializePart(p.serialize())); + return new EditorModel(clonedParts, this._partCreator, this.updateCallback); } private insertPart(index: number, part: Part): void { From fd6d853bb13d3561622c674722cca6373d2dc462 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Oct 2021 14:02:05 +0100 Subject: [PATCH 3/3] Allow editing of /rainbow and /rainbowme --- src/editor/deserialize.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/editor/deserialize.ts b/src/editor/deserialize.ts index b9043e565a7..1f84c08239b 100644 --- a/src/editor/deserialize.ts +++ b/src/editor/deserialize.ts @@ -22,6 +22,7 @@ import { checkBlockNode } from "../HtmlUtils"; import { getPrimaryPermalinkEntity } from "../utils/permalinks/Permalinks"; import { Part, PartCreator, Type } from "./parts"; import SdkConfig from "../SdkConfig"; +import { textToHtmlRainbow } from "../utils/colour"; function parseAtRoomMentions(text: string, partCreator: PartCreator) { const ATROOM = "@room"; @@ -305,14 +306,26 @@ export function parsePlainTextMessage(body: string, partCreator: PartCreator, is export function parseEvent(event: MatrixEvent, partCreator: PartCreator, { isQuotedMessage = false } = {}) { const content = event.getContent(); - let parts; + let parts: Part[]; + const isEmote = content.msgtype === "m.emote"; + let isRainbow = false; + if (content.format === "org.matrix.custom.html") { parts = parseHtmlMessage(content.formatted_body || "", partCreator, isQuotedMessage); + if (content.body && content.formatted_body && textToHtmlRainbow(content.body) === content.formatted_body) { + isRainbow = true; + } } else { parts = parsePlainTextMessage(content.body || "", partCreator, isQuotedMessage); } - if (content.msgtype === "m.emote") { + + if (isEmote && isRainbow) { + parts.unshift(partCreator.plain("/rainbowme ")); + } else if (isRainbow) { + parts.unshift(partCreator.plain("/rainbow ")); + } else if (isEmote) { parts.unshift(partCreator.plain("/me ")); } + return parts; }