getting edits closer to working

This commit is contained in:
Cadence Ember 2023-08-16 17:03:05 +12:00
commit b1ca71f37c
10 changed files with 259 additions and 51 deletions

View file

@ -9,7 +9,7 @@ const messageToEvent = sync.require("../converters/message-to-event")
/** @type {import("../../matrix/api")} */
const api = sync.require("../../matrix/api")
/** @type {import("../actions/register-user")} */
const registerUser = sync.require("./register-user")
const registerUser = sync.require("../actions/register-user")
/** @type {import("../actions/create-room")} */
const createRoom = sync.require("../actions/create-room")
@ -22,7 +22,7 @@ const createRoom = sync.require("../actions/create-room")
async function editToChanges(message, guild) {
// Figure out what events we will be replacing
const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").get(message.channel_id)
const roomID = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(message.channel_id)
const senderMxid = await registerUser.ensureSimJoined(message.author, roomID)
/** @type {{event_id: string, event_type: string, event_subtype: string?, part: number}[]} */
const oldEventRows = db.prepare("SELECT event_id, event_type, event_subtype, part FROM event_message WHERE message_id = ?").all(message.id)
@ -37,7 +37,7 @@ async function editToChanges(message, guild) {
Rules:
+ The events must have the same type.
+ The events must have the same subtype.
Events will therefore be divided into three categories:
Events will therefore be divided into four categories:
*/
/** 1. Events that are matched, and should be edited by sending another m.replace event */
let eventsToReplace = []
@ -45,12 +45,12 @@ async function editToChanges(message, guild) {
let eventsToRedact = []
/** 3. Events that are present in the new version only, and should be sent as new, with references back to the context */
let eventsToSend = []
// 4. Events that are matched and have definitely not changed, so they don't need to be edited or replaced at all. This is represented as nothing.
// For each old event...
outer: while (newEvents.length) {
const newe = newEvents[0]
// Find a new event to pair it with...
let handled = false
for (let i = 0; i < oldEventRows.length; i++) {
const olde = oldEventRows[i]
if (olde.event_type === newe.$type && olde.event_subtype === (newe.msgtype || null)) {
@ -76,7 +76,7 @@ async function editToChanges(message, guild) {
// Now, everything in eventsToSend and eventsToRedact is a real change, but everything in eventsToReplace might not have actually changed!
// (Consider a MESSAGE_UPDATE for a text+image message - Discord does not allow the image to be changed, but the text might have been.)
// So we'll remove entries from eventsToReplace that *definitely* cannot have changed. Everything remaining *may* have changed.
// So we'll remove entries from eventsToReplace that *definitely* cannot have changed. (This is category 4 mentioned above.) Everything remaining *may* have changed.
eventsToReplace = eventsToReplace.filter(ev => {
// Discord does not allow files, images, attachments, or videos to be edited.
if (ev.old.event_type === "m.room.message" && ev.old.event_subtype !== "m.text" && ev.old.event_subtype !== "m.emote") {
@ -90,7 +90,42 @@ async function editToChanges(message, guild) {
return true
})
// Removing unnecessary properties before returning
eventsToRedact = eventsToRedact.map(e => e.event_id)
eventsToReplace = eventsToReplace.map(e => ({oldID: e.old.event_id, new: eventToReplacementEvent(e.old.event_id, e.new)}))
return {eventsToReplace, eventsToRedact, eventsToSend}
}
module.exports.editMessage = editMessage
/**
* @template T
* @param {string} oldID
* @param {T} content
* @returns {import("../../types").Event.ReplacementContent<T>} content
*/
function eventToReplacementEvent(oldID, content) {
const newContent = {
...content,
"m.mentions": {},
"m.new_content": {
...content
},
"m.relates_to": {
rel_type: "m.replace",
event_id: oldID
}
}
if (typeof newContent.body === "string") {
newContent.body = "* " + newContent.body
}
if (typeof newContent.formatted_body === "string") {
newContent.formatted_body = "* " + newContent.formatted_body
}
delete newContent["m.new_content"]["$type"]
// Client-Server API spec 11.37.3: Any m.relates_to property within m.new_content is ignored.
delete newContent["m.new_content"]["m.relates_to"]
return newContent
}
module.exports.editToChanges = editToChanges
module.exports.eventToReplacementEvent = eventToReplacementEvent