Promote another event if part = 0 is redacted
This commit is contained in:
parent
f69cf587a2
commit
ef15c850dd
3 changed files with 41 additions and 10 deletions
|
@ -1,7 +1,7 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const passthrough = require("../../passthrough")
|
const passthrough = require("../../passthrough")
|
||||||
const { sync, db } = passthrough
|
const {sync, db, select} = passthrough
|
||||||
/** @type {import("../converters/edit-to-changes")} */
|
/** @type {import("../converters/edit-to-changes")} */
|
||||||
const editToChanges = sync.require("../converters/edit-to-changes")
|
const editToChanges = sync.require("../converters/edit-to-changes")
|
||||||
/** @type {import("../../matrix/api")} */
|
/** @type {import("../../matrix/api")} */
|
||||||
|
@ -12,7 +12,7 @@ const api = sync.require("../../matrix/api")
|
||||||
* @param {import("discord-api-types/v10").APIGuild} guild
|
* @param {import("discord-api-types/v10").APIGuild} guild
|
||||||
*/
|
*/
|
||||||
async function editMessage(message, guild) {
|
async function editMessage(message, guild) {
|
||||||
const {roomID, eventsToRedact, eventsToReplace, eventsToSend, senderMxid} = await editToChanges.editToChanges(message, guild, api)
|
const {roomID, eventsToRedact, eventsToReplace, eventsToSend, senderMxid, promoteEvent, promoteNextEvent} = await editToChanges.editToChanges(message, guild, api)
|
||||||
|
|
||||||
// 1. Replace all the things.
|
// 1. Replace all the things.
|
||||||
for (const {oldID, newContent} of eventsToReplace) {
|
for (const {oldID, newContent} of eventsToReplace) {
|
||||||
|
@ -33,10 +33,17 @@ async function editMessage(message, guild) {
|
||||||
for (const eventID of eventsToRedact) {
|
for (const eventID of eventsToRedact) {
|
||||||
await api.redactEvent(roomID, eventID, senderMxid)
|
await api.redactEvent(roomID, eventID, senderMxid)
|
||||||
db.prepare("DELETE FROM event_message WHERE event_id = ?").run(eventID)
|
db.prepare("DELETE FROM event_message WHERE event_id = ?").run(eventID)
|
||||||
// TODO: If I just redacted part = 0, I should update one of the other events to make it the new part = 0, right?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Send all the things.
|
// 3. Consistency: Ensure there is exactly one part = 0
|
||||||
|
let eventPart = 1
|
||||||
|
if (promoteEvent) {
|
||||||
|
db.prepare("UPDATE event_message SET part = 0 WHERE event_id = ?").run(promoteEvent)
|
||||||
|
} else if (promoteNextEvent) {
|
||||||
|
eventPart = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Send all the things.
|
||||||
for (const content of eventsToSend) {
|
for (const content of eventsToSend) {
|
||||||
const eventType = content.$type
|
const eventType = content.$type
|
||||||
/** @type {Pick<typeof content, Exclude<keyof content, "$type">> & { $type?: string }} */
|
/** @type {Pick<typeof content, Exclude<keyof content, "$type">> & { $type?: string }} */
|
||||||
|
@ -44,7 +51,9 @@ async function editMessage(message, guild) {
|
||||||
delete contentWithoutType.$type
|
delete contentWithoutType.$type
|
||||||
|
|
||||||
const eventID = await api.sendEvent(roomID, eventType, contentWithoutType, senderMxid)
|
const eventID = await api.sendEvent(roomID, eventType, contentWithoutType, senderMxid)
|
||||||
db.prepare("INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, source) VALUES (?, ?, ?, ?, 1, 1)").run(eventID, eventType, content.msgtype || null, message.id) // part 1 = supporting; source 1 = discord
|
db.prepare("INSERT INTO event_message (event_id, event_type, event_subtype, message_id, part, source) VALUES (?, ?, ?, ?, ?, 1)").run(eventID, eventType, content.msgtype || null, message.id, eventPart) // part 1 = supporting; source 1 = discord
|
||||||
|
|
||||||
|
eventPart = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,20 @@ async function editToChanges(message, guild, api) {
|
||||||
// Anything remaining in oldEventRows is present in the old version only and should be redacted.
|
// Anything remaining in oldEventRows is present in the old version only and should be redacted.
|
||||||
eventsToRedact = oldEventRows
|
eventsToRedact = oldEventRows
|
||||||
|
|
||||||
|
// If events are being deleted, we might be deleting the part = 0. But we want to have a part = 0 at all times. In this case we choose an existing event to promote.
|
||||||
|
let promoteEvent = null, promoteNextEvent = false
|
||||||
|
if (eventsToRedact.some(e => e.part === 0)) {
|
||||||
|
if (eventsToReplace.length) {
|
||||||
|
// We can choose an existing event to promote. Bigger order is better.
|
||||||
|
const order = e => 2*+(e.event_type === "m.room.message") + 1*+(e.event_subtype === "m.text")
|
||||||
|
eventsToReplace.sort((a, b) => order(b) - order(a))
|
||||||
|
promoteEvent = eventsToReplace[0].old.event_id
|
||||||
|
} else {
|
||||||
|
// Everything is being deleted. Whatever gets sent in their place will be the new part = 0.
|
||||||
|
promoteNextEvent = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now, everything in eventsToSend and eventsToRedact is a real change, but everything in eventsToReplace might not have actually changed!
|
// Now, everything in eventsToSend and eventsToRedact is a real change, but everything in eventsToReplace might not have actually changed!
|
||||||
// (Example: a MESSAGE_UPDATE for a text+image message - Discord does not allow the image to be changed, but the text might have been.)
|
// (Example: 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. (This is category 4 mentioned above.) 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.
|
||||||
|
@ -103,7 +117,7 @@ async function editToChanges(message, guild, api) {
|
||||||
eventsToRedact = eventsToRedact.map(e => e.event_id)
|
eventsToRedact = eventsToRedact.map(e => e.event_id)
|
||||||
eventsToReplace = eventsToReplace.map(e => ({oldID: e.old.event_id, newContent: makeReplacementEventContent(e.old.event_id, e.newFallbackContent, e.newInnerContent)}))
|
eventsToReplace = eventsToReplace.map(e => ({oldID: e.old.event_id, newContent: makeReplacementEventContent(e.old.event_id, e.newFallbackContent, e.newInnerContent)}))
|
||||||
|
|
||||||
return {roomID, eventsToReplace, eventsToRedact, eventsToSend, senderMxid}
|
return {roomID, eventsToReplace, eventsToRedact, eventsToSend, senderMxid, promoteEvent, promoteNextEvent}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,7 @@ const data = require("../../test/data")
|
||||||
const Ty = require("../../types")
|
const Ty = require("../../types")
|
||||||
|
|
||||||
test("edit2changes: edit by webhook", async t => {
|
test("edit2changes: edit by webhook", async t => {
|
||||||
const {senderMxid, eventsToRedact, eventsToReplace, eventsToSend} = await editToChanges(data.message_update.edit_by_webhook, data.guild.general, {})
|
const {senderMxid, eventsToRedact, eventsToReplace, eventsToSend, promoteEvent, promoteNextEvent} = await editToChanges(data.message_update.edit_by_webhook, data.guild.general, {})
|
||||||
t.deepEqual(eventsToRedact, [])
|
t.deepEqual(eventsToRedact, [])
|
||||||
t.deepEqual(eventsToSend, [])
|
t.deepEqual(eventsToSend, [])
|
||||||
t.deepEqual(eventsToReplace, [{
|
t.deepEqual(eventsToReplace, [{
|
||||||
|
@ -27,10 +27,12 @@ test("edit2changes: edit by webhook", async t => {
|
||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
t.equal(senderMxid, null)
|
t.equal(senderMxid, null)
|
||||||
|
t.equal(promoteEvent, null)
|
||||||
|
t.equal(promoteNextEvent, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("edit2changes: bot response", async t => {
|
test("edit2changes: bot response", async t => {
|
||||||
const {senderMxid, eventsToRedact, eventsToReplace, eventsToSend} = await editToChanges(data.message_update.bot_response, data.guild.general, {
|
const {senderMxid, eventsToRedact, eventsToReplace, eventsToSend, promoteEvent, promoteNextEvent} = await editToChanges(data.message_update.bot_response, data.guild.general, {
|
||||||
async getJoinedMembers(roomID) {
|
async getJoinedMembers(roomID) {
|
||||||
t.equal(roomID, "!hYnGGlPHlbujVVfktC:cadence.moe")
|
t.equal(roomID, "!hYnGGlPHlbujVVfktC:cadence.moe")
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
@ -82,17 +84,21 @@ test("edit2changes: bot response", async t => {
|
||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
t.equal(senderMxid, "@_ooye_bojack_horseman:cadence.moe")
|
t.equal(senderMxid, "@_ooye_bojack_horseman:cadence.moe")
|
||||||
|
t.equal(promoteEvent, null)
|
||||||
|
t.equal(promoteNextEvent, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("edit2changes: remove caption from image", async t => {
|
test("edit2changes: remove caption from image", async t => {
|
||||||
const {eventsToRedact, eventsToReplace, eventsToSend} = await editToChanges(data.message_update.removed_caption_from_image, data.guild.general, {})
|
const {eventsToRedact, eventsToReplace, eventsToSend, promoteEvent, promoteNextEvent} = await editToChanges(data.message_update.removed_caption_from_image, data.guild.general, {})
|
||||||
t.deepEqual(eventsToRedact, ["$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA"])
|
t.deepEqual(eventsToRedact, ["$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA"])
|
||||||
t.deepEqual(eventsToSend, [])
|
t.deepEqual(eventsToSend, [])
|
||||||
t.deepEqual(eventsToReplace, [])
|
t.deepEqual(eventsToReplace, [])
|
||||||
|
t.equal(promoteEvent, "$51f4yqHinwnSbPEQ9dCgoyy4qiIJSX0QYYVUnvwyTCI")
|
||||||
|
t.equal(promoteNextEvent, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("edit2changes: add caption back to that image", async t => {
|
test("edit2changes: add caption back to that image", async t => {
|
||||||
const {eventsToRedact, eventsToReplace, eventsToSend} = await editToChanges(data.message_update.added_caption_to_image, data.guild.general, {})
|
const {eventsToRedact, eventsToReplace, eventsToSend, promoteEvent, promoteNextEvent} = await editToChanges(data.message_update.added_caption_to_image, data.guild.general, {})
|
||||||
t.deepEqual(eventsToRedact, [])
|
t.deepEqual(eventsToRedact, [])
|
||||||
t.deepEqual(eventsToSend, [{
|
t.deepEqual(eventsToSend, [{
|
||||||
$type: "m.room.message",
|
$type: "m.room.message",
|
||||||
|
@ -101,6 +107,8 @@ test("edit2changes: add caption back to that image", async t => {
|
||||||
"m.mentions": {}
|
"m.mentions": {}
|
||||||
}])
|
}])
|
||||||
t.deepEqual(eventsToReplace, [])
|
t.deepEqual(eventsToReplace, [])
|
||||||
|
t.equal(promoteEvent, null)
|
||||||
|
t.equal(promoteNextEvent, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("edit2changes: stickers and attachments are not changed, only the content can be edited", async t => {
|
test("edit2changes: stickers and attachments are not changed, only the content can be edited", async t => {
|
||||||
|
|
Loading…
Reference in a new issue