WIP: feature: threads'n'forums #74

Draft
Guzio wants to merge 109 commits from Guzio/out-of-your-element:mergable-fr-fr into main
Showing only changes of commit b924de2357 - Show all commits

View file

@ -211,8 +211,11 @@ sync.addTemporaryListener(as, "type:m.room.message", guard("m.room.message",
async event => {
if (utils.eventSenderIsFromDiscord(event.sender)) return
let processCommands = true
if (event.content["m.relates_to"]?.rel_type === "m.thread") {
processCommands = false
const bridgedTo = utils.getThreadRoomFromThreadEvent(event.content["m.relates_to"].event_id)
if (bridgedTo) event.room_id = bridgedTo;
else await bridgeThread(event);
}
@ -222,7 +225,7 @@ async event => {
/** @type {string|undefined} */
let executedCommand
if (event.type === "m.room.message" && event.content.msgtype === "m.text") {
if (event.type === "m.room.message" && event.content.msgtype === "m.text" && processCommands) {
executedCommand = await matrixCommandHandler.parseAndExecute(
// @ts-ignore - TypeScript doesn't know that the event.content.msgtype === "m.text" check ensures that event isn't of type Ty.Event.Outer_M_Room_Message_File (which, indeed, wouldn't fit here)
event
@ -238,17 +241,22 @@ async event => {
*/
async function bridgeThread(event) {
/** @type {string} */ // @ts-ignore
const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get();
const channelID = select("channel_room", "channel_id", {room_id: event.room_id}).pluck().get()
const channel = discord.channels.get(channelID)
const guildID = channel?.["guild_id"]
if (!guildID) return; //Room not bridged? We don't care. It's a Matrix-naive room, let Matrix users have standard Matrix-native threads there.
if (!guildID) return; //Room not bridged? We don't care. It's a Matrix-native room, let Matrix users have standard Matrix-native threads there.
const eventID = event.content["m.relates_to"]?.event_id
if (!eventID) throw new Error("There was an event sent inside SOME Matrix thread, but it lacked any information as to what thread it actually was!"); //An „ugly error” is justified because if something like this DOES happen, then that means that it should be reported to us, as there is some broken client out there that we should account for.
const messageID = select("event_message", "message_id", {event_id: eventID}).pluck().get()
if (!messageID) return; //Message not bridged? Too bad! Discord users will just see normal replies, and Matrix uses won't get a thread-room.We COULD technically create a "headless" thread on Discord side and bridge it to a new thread-room, but that comes with a whole host of complications on its own (notably: what do we do if the message gets bridged later (by reaction emoji), and maybe gets its own thread; and: getThreadRoomFromThreadEvent will have to be much more complex than a simple DB call (probably a whole new DB table would have to be created, just to hold these Matrix-branched-but-headless-on-Discord threads) because the simple „MX event --(db)--> Discord Message --(Discord spec)--> Discord thread” relation would no longer hold true), which may not be worth it, as an unbridged message in a bridged channel is already an edge-case and it seems somewhat pointless to introduce and account for a whole bunch of edgier-cases that handling this edge-case "properly" would bring.
event.room_id = await createRoom.ensureRoom((await discord.snow.channel.createThreadWithMessage(channelID, messageID, {name: "TODO: name-gen"})).id)
if (!messageID) return; //Message not bridged? Too bad! Discord users will just see normal replies, and Matrix uses won't get a thread-room. We COULD technically create a "headless" thread on Discord side and bridge it to a new thread-room, but that comes with a whole host of complications on its own (notably: what do we do if the message gets bridged later (by reaction emoji), and maybe gets its own thread; and: getThreadRoomFromThreadEvent will have to be much more complex than a simple DB call (probably a whole new DB table would have to be created, just to hold these Matrix-branched-but-headless-on-Discord threads) because the simple „MX event --(db)--> Discord Message --(Discord spec)--> Discord thread” relation would no longer hold true), which may not be worth it, as an unbridged message in a bridged channel is already an edge-case and it seems somewhat pointless to introduce and account for a whole bunch of edgier-cases that handling this edge-case "properly" would bring.
let name = event.content.body
if (name.startsWith("/thread ")) name = name.substring(8);
else name = (await api.getEvent(event.room_id, eventID)).content.body;
name = name.length < 100 ? name.replaceAll("\n", " ") : name.slice(0, 96).replaceAll("\n", " ") + "..."
event.room_id = await createRoom.ensureRoom((await discord.snow.channel.createThreadWithMessage(channelID, messageID, {name})).id)
}
sync.addTemporaryListener(as, "type:m.sticker", guard("m.sticker",