Bridge forums as spaces
This commit is contained in:
parent
642be26313
commit
5f0e765934
1 changed files with 31 additions and 9 deletions
|
@ -59,13 +59,16 @@ function applyKStateDiffToRoom(roomID, kstate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {{id: string, name: string, topic?: string?, type: number}} channel
|
* @param {{id: string, name: string, topic?: string?, type: number, parent_id?: string?}} channel
|
||||||
* @param {{id: string}} guild
|
* @param {{id: string}} guild
|
||||||
* @param {string | null | undefined} customName
|
* @param {string | null | undefined} customName
|
||||||
*/
|
*/
|
||||||
function convertNameAndTopic(channel, guild, customName) {
|
function convertNameAndTopic(channel, guild, customName) {
|
||||||
|
// @ts-ignore
|
||||||
|
const parentChannel = discord.channels.get(channel.parent_id)
|
||||||
let channelPrefix =
|
let channelPrefix =
|
||||||
( channel.type === DiscordTypes.ChannelType.PublicThread ? "[⛓️] "
|
( parentChannel?.type === DiscordTypes.ChannelType.GuildForum ? ""
|
||||||
|
: channel.type === DiscordTypes.ChannelType.PublicThread ? "[⛓️] "
|
||||||
: channel.type === DiscordTypes.ChannelType.PrivateThread ? "[🔒⛓️] "
|
: channel.type === DiscordTypes.ChannelType.PrivateThread ? "[🔒⛓️] "
|
||||||
: channel.type === DiscordTypes.ChannelType.GuildVoice ? "[🔊] "
|
: channel.type === DiscordTypes.ChannelType.GuildVoice ? "[🔊] "
|
||||||
: "")
|
: "")
|
||||||
|
@ -88,9 +91,24 @@ function convertNameAndTopic(channel, guild, customName) {
|
||||||
* @param {DiscordTypes.APIGuild} guild
|
* @param {DiscordTypes.APIGuild} guild
|
||||||
*/
|
*/
|
||||||
async function channelToKState(channel, guild) {
|
async function channelToKState(channel, guild) {
|
||||||
const spaceID = await createSpace.ensureSpace(guild)
|
// @ts-ignore
|
||||||
assert(typeof spaceID === "string")
|
const parentChannel = discord.channels.get(channel.parent_id)
|
||||||
const privacyLevel = select("guild_space", "privacy_level", {space_id: spaceID}).pluck().get()
|
/** Used for membership/permission checks. */
|
||||||
|
let guildSpaceID
|
||||||
|
/** Used as the literal parent on Matrix, for categorisation. Will be the same as `guildSpaceID` unless it's a forum channel's thread, in which case a different space is used to group those threads. */
|
||||||
|
let parentSpaceID
|
||||||
|
let privacyLevel
|
||||||
|
if (parentChannel?.type === DiscordTypes.ChannelType.GuildForum) { // it's a forum channel's thread, so use a different space to group those threads
|
||||||
|
guildSpaceID = await createSpace.ensureSpace(guild)
|
||||||
|
parentSpaceID = await ensureRoom(channel.parent_id)
|
||||||
|
privacyLevel = select("guild_space", "privacy_level", {space_id: guildSpaceID}).pluck().get()
|
||||||
|
} else { // otherwise use the guild's space like usual
|
||||||
|
parentSpaceID = await createSpace.ensureSpace(guild)
|
||||||
|
guildSpaceID = parentSpaceID
|
||||||
|
privacyLevel = select("guild_space", "privacy_level", {space_id: parentSpaceID}).pluck().get()
|
||||||
|
}
|
||||||
|
assert(typeof parentSpaceID === "string")
|
||||||
|
assert(typeof guildSpaceID === "string")
|
||||||
assert(typeof privacyLevel === "number")
|
assert(typeof privacyLevel === "number")
|
||||||
|
|
||||||
const row = select("channel_room", ["nick", "custom_avatar"], {channel_id: channel.id}).get()
|
const row = select("channel_room", ["nick", "custom_avatar"], {channel_id: channel.id}).get()
|
||||||
|
@ -114,7 +132,7 @@ async function channelToKState(channel, guild) {
|
||||||
join_rule: "restricted",
|
join_rule: "restricted",
|
||||||
allow: [{
|
allow: [{
|
||||||
type: "m.room_membership",
|
type: "m.room_membership",
|
||||||
room_id: spaceID
|
room_id: guildSpaceID
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
if (PRIVACY_ENUMS.ROOM_JOIN_RULES[privacyLevel] !== "restricted") {
|
if (PRIVACY_ENUMS.ROOM_JOIN_RULES[privacyLevel] !== "restricted") {
|
||||||
|
@ -130,7 +148,7 @@ async function channelToKState(channel, guild) {
|
||||||
"m.room.avatar/": avatarEventContent,
|
"m.room.avatar/": avatarEventContent,
|
||||||
"m.room.guest_access/": {guest_access: PRIVACY_ENUMS.GUEST_ACCESS[privacyLevel]},
|
"m.room.guest_access/": {guest_access: PRIVACY_ENUMS.GUEST_ACCESS[privacyLevel]},
|
||||||
"m.room.history_visibility/": {history_visibility},
|
"m.room.history_visibility/": {history_visibility},
|
||||||
[`m.space.parent/${spaceID}`]: {
|
[`m.space.parent/${parentSpaceID}`]: {
|
||||||
via: [reg.ooye.server_name],
|
via: [reg.ooye.server_name],
|
||||||
canonical: true
|
canonical: true
|
||||||
},
|
},
|
||||||
|
@ -167,7 +185,7 @@ async function channelToKState(channel, guild) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {spaceID, privacyLevel, channelKState}
|
return {spaceID: parentSpaceID, privacyLevel, channelKState}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,6 +201,9 @@ async function createRoom(channel, guild, spaceID, kstate, privacyLevel) {
|
||||||
let threadParent = null
|
let threadParent = null
|
||||||
if (channel.type === DiscordTypes.ChannelType.PublicThread) threadParent = channel.parent_id
|
if (channel.type === DiscordTypes.ChannelType.PublicThread) threadParent = channel.parent_id
|
||||||
|
|
||||||
|
let spaceCreationContent = {}
|
||||||
|
if (channel.type === DiscordTypes.ChannelType.GuildForum) spaceCreationContent = {creation_content: {type: "m.space"}}
|
||||||
|
|
||||||
// Name and topic can be done earlier in room creation rather than in initial_state
|
// Name and topic can be done earlier in room creation rather than in initial_state
|
||||||
// https://spec.matrix.org/latest/client-server-api/#creation
|
// https://spec.matrix.org/latest/client-server-api/#creation
|
||||||
const name = kstate["m.room.name/"].name
|
const name = kstate["m.room.name/"].name
|
||||||
|
@ -199,7 +220,8 @@ async function createRoom(channel, guild, spaceID, kstate, privacyLevel) {
|
||||||
preset: PRIVACY_ENUMS.PRESET[privacyLevel], // This is closest to what we want, but properties from kstate override it anyway
|
preset: PRIVACY_ENUMS.PRESET[privacyLevel], // This is closest to what we want, but properties from kstate override it anyway
|
||||||
visibility: PRIVACY_ENUMS.VISIBILITY[privacyLevel],
|
visibility: PRIVACY_ENUMS.VISIBILITY[privacyLevel],
|
||||||
invite: [],
|
invite: [],
|
||||||
initial_state: ks.kstateToState(kstate)
|
initial_state: ks.kstateToState(kstate),
|
||||||
|
...spaceCreationContent
|
||||||
})
|
})
|
||||||
|
|
||||||
db.prepare("INSERT INTO channel_room (channel_id, room_id, name, nick, thread_parent) VALUES (?, ?, ?, NULL, ?)").run(channel.id, roomID, channel.name, threadParent)
|
db.prepare("INSERT INTO channel_room (channel_id, room_id, name, nick, thread_parent) VALUES (?, ?, ?, NULL, ?)").run(channel.id, roomID, channel.name, threadParent)
|
||||||
|
|
Loading…
Reference in a new issue