Compare commits
No commits in common. "56f959e9f3d84f8482293afacf2764fdaacd0e09" and "fd11e3fd10a69ad00ff82491b667a2ea7902b48a" have entirely different histories.
56f959e9f3
...
fd11e3fd10
3 changed files with 3 additions and 160 deletions
|
@ -33,12 +33,6 @@ const markdownEscapes = [
|
||||||
[/^>/g, '\\>'],
|
[/^>/g, '\\>'],
|
||||||
[/_/g, '\\_'],
|
[/_/g, '\\_'],
|
||||||
[/^(\d+)\. /g, '$1\\. ']
|
[/^(\d+)\. /g, '$1\\. ']
|
||||||
/*
|
|
||||||
Strikethrough is deliberately not escaped. Usually when Matrix users type ~~ it's not because they wanted to send ~~,
|
|
||||||
it's because they wanted strikethrough and it didn't work because their client doesn't support it.
|
|
||||||
As bridge developers, we can choose between "messages should look as similar as possible" vs "it was most likely intended to be strikethrough".
|
|
||||||
I went with the latter. Even though the appearance doesn't match, I'd rather it displayed as originally intended for 80% of the readers than for 0%.
|
|
||||||
*/
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const turndownService = new TurndownService({
|
const turndownService = new TurndownService({
|
||||||
|
@ -93,15 +87,11 @@ turndownService.addRule("blockquote", {
|
||||||
|
|
||||||
turndownService.addRule("spoiler", {
|
turndownService.addRule("spoiler", {
|
||||||
filter: function (node, options) {
|
filter: function (node, options) {
|
||||||
return node.tagName === "SPAN" && node.hasAttribute("data-mx-spoiler")
|
return node.hasAttribute("data-mx-spoiler")
|
||||||
},
|
},
|
||||||
|
|
||||||
replacement: function (content, node) {
|
replacement: function (content, node) {
|
||||||
if (node.getAttribute("data-mx-spoiler")) {
|
return "||" + content + "||"
|
||||||
// escape parentheses so it can't become a link
|
|
||||||
return `\\(${node.getAttribute("data-mx-spoiler")}\\) ||${content}||`
|
|
||||||
}
|
|
||||||
return `||${content}||`
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -519,8 +509,6 @@ async function eventToMessage(event, guild, di) {
|
||||||
const fileReplyContentAlternative = attachmentEmojis.get(repliedToEvent.content.msgtype)
|
const fileReplyContentAlternative = attachmentEmojis.get(repliedToEvent.content.msgtype)
|
||||||
if (fileReplyContentAlternative) {
|
if (fileReplyContentAlternative) {
|
||||||
contentPreview = " " + fileReplyContentAlternative
|
contentPreview = " " + fileReplyContentAlternative
|
||||||
} else if (repliedToEvent.unsigned?.redacted_because) {
|
|
||||||
contentPreview = " (in reply to a deleted message)"
|
|
||||||
} else {
|
} else {
|
||||||
const repliedToContent = repliedToEvent.content.formatted_body || repliedToEvent.content.body
|
const repliedToContent = repliedToEvent.content.formatted_body || repliedToEvent.content.body
|
||||||
const contentPreviewChunks = chunk(
|
const contentPreviewChunks = chunk(
|
||||||
|
@ -640,9 +628,6 @@ async function eventToMessage(event, guild, di) {
|
||||||
// It's designed for commonmark, we need to replace the space-space-newline with just newline
|
// It's designed for commonmark, we need to replace the space-space-newline with just newline
|
||||||
content = content.replace(/ \n/g, "\n")
|
content = content.replace(/ \n/g, "\n")
|
||||||
|
|
||||||
// If there's a blockquote at the start of the message body and this message is a reply, they should be visually separated
|
|
||||||
if (replyLine && content.startsWith("> ")) content = "\n" + content
|
|
||||||
|
|
||||||
// SPRITE SHEET EMOJIS FEATURE:
|
// SPRITE SHEET EMOJIS FEATURE:
|
||||||
content = await uploadEndOfMessageSpriteSheet(content, attachments, pendingFiles)
|
content = await uploadEndOfMessageSpriteSheet(content, attachments, pendingFiles)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -234,37 +234,6 @@ test("event2message: spoilers work", async t => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("event2message: spoiler reasons work", async t => {
|
|
||||||
t.deepEqual(
|
|
||||||
await eventToMessage({
|
|
||||||
content: {
|
|
||||||
msgtype: "m.text",
|
|
||||||
body: "wrong body",
|
|
||||||
format: "org.matrix.custom.html",
|
|
||||||
formatted_body: `<span data-mx-spoiler="cw crossword spoilers you'll never believe. don't tell anybody">zoe kills a 5 letter noun at the end</span>`
|
|
||||||
},
|
|
||||||
event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
|
|
||||||
origin_server_ts: 1688301929913,
|
|
||||||
room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
|
|
||||||
sender: "@cadence:cadence.moe",
|
|
||||||
type: "m.room.message",
|
|
||||||
unsigned: {
|
|
||||||
age: 405299
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
ensureJoined: [],
|
|
||||||
messagesToDelete: [],
|
|
||||||
messagesToEdit: [],
|
|
||||||
messagesToSend: [{
|
|
||||||
username: "cadence [they]",
|
|
||||||
content: "\\(cw crossword spoilers you'll never believe. don't tell anybody\\) ||zoe kills a 5 letter noun at the end||",
|
|
||||||
avatar_url: undefined
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("event2message: markdown syntax is escaped", async t => {
|
test("event2message: markdown syntax is escaped", async t => {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
await eventToMessage({
|
await eventToMessage({
|
||||||
|
@ -1809,115 +1778,6 @@ test("event2message: with layered rich replies, the preview should only be the r
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("event2message: if event is a reply and starts with a quote, they should be separated by a blank line, so that they don't visually merge together", async t => {
|
|
||||||
t.deepEqual(
|
|
||||||
await eventToMessage({
|
|
||||||
type: "m.room.message",
|
|
||||||
sender: "@aflower:syndicated.gay",
|
|
||||||
content: {
|
|
||||||
body: "> <@aflower:syndicated.gay> i have a feeling that clients are *meant to* strip these reply fallbacks too, just that none of them, in reality, do\n\n>To strip the fallback on the <code>body</code>, the client should iterate over each line of the string, removing any lines that start with the fallback prefix ("> “, including the space, without quotes) and stopping when a line is encountered without the prefix. This prefix is known as the “fallback prefix sequence”.",
|
|
||||||
format: "org.matrix.custom.html",
|
|
||||||
formatted_body: "<mx-reply><blockquote><a href=\"https://matrix.to/#/!TqlyQmifxGUggEmdBN:cadence.moe/$tTYQcke93fwocsc1K6itwUq85EG0RZ0ksCuIglKioks\">In reply to</a> <a href=\"https://matrix.to/#/@aflower:syndicated.gay\">@aflower:syndicated.gay</a><br/>i have a feeling that clients are <em>meant to</em> strip these reply fallbacks too, just that none of them, in reality, do</blockquote></mx-reply><blockquote>\n<p>To strip the fallback on the <code>body</code>, the client should iterate over each line of the string, removing any lines that start with the fallback prefix ("> “, including the space, without quotes) and stopping when a line is encountered without the prefix. This prefix is known as the “fallback prefix sequence”.</p>\n</blockquote>",
|
|
||||||
"im.nheko.relations.v1.relations": [
|
|
||||||
{
|
|
||||||
event_id: "$tTYQcke93fwocsc1K6itwUq85EG0RZ0ksCuIglKioks",
|
|
||||||
rel_type: "im.nheko.relations.v1.in_reply_to"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"m.relates_to": {
|
|
||||||
"m.in_reply_to": {
|
|
||||||
event_id: "$tTYQcke93fwocsc1K6itwUq85EG0RZ0ksCuIglKioks"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
msgtype: "m.text"
|
|
||||||
},
|
|
||||||
room_id: "!TqlyQmifxGUggEmdBN:cadence.moe",
|
|
||||||
event_id: "$nCvtZeBFedYuEavt4OftloCHc0kaFW2ktHCfIOklhjU",
|
|
||||||
}, data.guild.general, {
|
|
||||||
api: {
|
|
||||||
getEvent: mockGetEvent(t, "!TqlyQmifxGUggEmdBN:cadence.moe", "$tTYQcke93fwocsc1K6itwUq85EG0RZ0ksCuIglKioks", {
|
|
||||||
sender: "@aflower:syndicated.gay",
|
|
||||||
type: "m.room.message",
|
|
||||||
content: {
|
|
||||||
body: "i have a feeling that clients are *meant to* strip these reply fallbacks too, just that none of them, in reality, do",
|
|
||||||
format: "org.matrix.custom.html",
|
|
||||||
formatted_body: "i have a feeling that clients are <em>meant to</em> strip these reply fallbacks too, just that none of them, in reality, do",
|
|
||||||
msgtype: "m.text"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
ensureJoined: [],
|
|
||||||
messagesToDelete: [],
|
|
||||||
messagesToEdit: [],
|
|
||||||
messagesToSend: [{
|
|
||||||
username: "Rose",
|
|
||||||
content: "> <:L1:1144820033948762203><:L2:1144820084079087647>Ⓜ️**Rose**:"
|
|
||||||
+ "\n> i have a feeling that clients are meant to strip..."
|
|
||||||
+ "\n"
|
|
||||||
+ "\n> To strip the fallback on the `body`, the client should iterate over each line of the string, removing any lines that start with the fallback prefix (\"> “, including the space, without quotes) and stopping when a line is encountered without the prefix. This prefix is known as the “fallback prefix sequence”.",
|
|
||||||
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/syndicated.gay/ZkBUPXCiXTjdJvONpLJmcbKP"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("event2message: rich reply to a deleted event", async t => {
|
|
||||||
t.deepEqual(
|
|
||||||
await eventToMessage({
|
|
||||||
type: "m.room.message",
|
|
||||||
sender: "@ampflower:matrix.org",
|
|
||||||
content: {
|
|
||||||
msgtype: "m.text",
|
|
||||||
body: "> <@ampflower:matrix.org> \n\nHuh it did the same thing here too",
|
|
||||||
format: "org.matrix.custom.html",
|
|
||||||
formatted_body: "<mx-reply><blockquote><a href=\"https://matrix.to/#/!TqlyQmifxGUggEmdBN:cadence.moe/$f-noT-d-Eo_Xgpc05Ww89ErUXku4NwKWYGHLzWKo1kU?via=cadence.moe\">In reply to</a> <a href=\"https://matrix.to/#/@ampflower:matrix.org\">@ampflower:matrix.org</a><br></blockquote></mx-reply>Huh it did the same thing here too",
|
|
||||||
"m.relates_to": {
|
|
||||||
"m.in_reply_to": {
|
|
||||||
event_id: "$f-noT-d-Eo_Xgpc05Ww89ErUXku4NwKWYGHLzWKo1kU"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event_id: "$v_Gtr-bzv9IVlSLBO5DstzwmiDd-GSFaNfHX66IupV8",
|
|
||||||
room_id: "!TqlyQmifxGUggEmdBN:cadence.moe"
|
|
||||||
}, data.guild.general, {
|
|
||||||
api: {
|
|
||||||
getEvent: mockGetEvent(t, "!TqlyQmifxGUggEmdBN:cadence.moe", "$f-noT-d-Eo_Xgpc05Ww89ErUXku4NwKWYGHLzWKo1kU", {
|
|
||||||
type: "m.room.message",
|
|
||||||
sender: "@ampflower:matrix.org",
|
|
||||||
content: {},
|
|
||||||
origin_server_ts: 1707798292953,
|
|
||||||
unsigned: {
|
|
||||||
redacted_because: {
|
|
||||||
type: "m.room.redaction",
|
|
||||||
room_id: "!TqlyQmifxGUggEmdBN:cadence.moe",
|
|
||||||
sender: "@_ooye_bot:cadence.moe",
|
|
||||||
content: {},
|
|
||||||
redacts: "$uyOzmYhqcgF5i0bZb4MrAIEKEvzDOLgXdlRr1zfvWo0",
|
|
||||||
origin_server_ts: 1707798294565,
|
|
||||||
event_id: "$enCV-40Sut8llwALAV0T3qjwK7MvO9jgY9C4DHbxKXA",
|
|
||||||
user_id: "@_ooye_bot:cadence.moe",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
user_id: "@ampflower:matrix.org"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
ensureJoined: [],
|
|
||||||
messagesToDelete: [],
|
|
||||||
messagesToEdit: [],
|
|
||||||
messagesToSend: [{
|
|
||||||
username: "Ampflower 🌺",
|
|
||||||
content: "> <:L1:1144820033948762203><:L2:1144820084079087647>Ⓜ️**Ampflower 🌺** (in reply to a deleted message)"
|
|
||||||
+ "\nHuh it did the same thing here too",
|
|
||||||
avatar_url: "https://matrix.cadence.moe/_matrix/media/r0/download/cadence.moe/PRfhXYBTOalvgQYtmCLeUXko"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("event2message: raw mentioning discord users in plaintext body works", async t => {
|
test("event2message: raw mentioning discord users in plaintext body works", async t => {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
await eventToMessage({
|
await eventToMessage({
|
||||||
|
|
|
@ -115,9 +115,7 @@ INSERT INTO member_cache (room_id, mxid, displayname, avatar_url) VALUES
|
||||||
('!BnKuBPCvyfOkhcUjEu:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', 'mxc://cadence.moe/azCAhThKTojXSZJRoWwZmhvU'),
|
('!BnKuBPCvyfOkhcUjEu:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', 'mxc://cadence.moe/azCAhThKTojXSZJRoWwZmhvU'),
|
||||||
('!maggESguZBqGBZtSnr:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', 'mxc://cadence.moe/azCAhThKTojXSZJRoWwZmhvU'),
|
('!maggESguZBqGBZtSnr:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', 'mxc://cadence.moe/azCAhThKTojXSZJRoWwZmhvU'),
|
||||||
('!CzvdIdUQXgUjDVKxeU:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', 'mxc://cadence.moe/azCAhThKTojXSZJRoWwZmhvU'),
|
('!CzvdIdUQXgUjDVKxeU:cadence.moe', '@cadence:cadence.moe', 'cadence [they]', 'mxc://cadence.moe/azCAhThKTojXSZJRoWwZmhvU'),
|
||||||
('!cBxtVRxDlZvSVhJXVK:cadence.moe', '@Milan:tchncs.de', 'Milan', NULL),
|
('!cBxtVRxDlZvSVhJXVK:cadence.moe', '@Milan:tchncs.de', 'Milan', NULL);
|
||||||
('!TqlyQmifxGUggEmdBN:cadence.moe', '@ampflower:matrix.org', 'Ampflower 🌺', 'mxc://cadence.moe/PRfhXYBTOalvgQYtmCLeUXko'),
|
|
||||||
('!TqlyQmifxGUggEmdBN:cadence.moe', '@aflower:syndicated.gay', 'Rose', 'mxc://syndicated.gay/ZkBUPXCiXTjdJvONpLJmcbKP');
|
|
||||||
|
|
||||||
INSERT INTO lottie (sticker_id, mxc_url) VALUES
|
INSERT INTO lottie (sticker_id, mxc_url) VALUES
|
||||||
('860171525772279849', 'mxc://cadence.moe/ZtvvVbwMIdUZeovWVyGVFCeR');
|
('860171525772279849', 'mxc://cadence.moe/ZtvvVbwMIdUZeovWVyGVFCeR');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue