feat(platform): forum tags module, palette, filter, and createForumPost tags
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -21,6 +21,7 @@ const { BotEventFanout, BOT_EVENTS } = require('pearcord-bot-events')
|
||||
const { INTENTS } = require('pearcord-bot-sdk')
|
||||
const { BotRateLimits } = require('pearcord-bot-limits')
|
||||
const { PearcordStepUp } = require('pearcord-step-up')
|
||||
const { PearcordForum } = require('pearcord-forum')
|
||||
const {
|
||||
createInstallToken,
|
||||
verifyInstallToken,
|
||||
@@ -204,6 +205,9 @@ class PearcordPlatform extends EventEmitter {
|
||||
userId: user.id
|
||||
})
|
||||
await this.stepUp.ready()
|
||||
this.forum = new PearcordForum({ storagePath: this.storagePath })
|
||||
await this.forum.ready()
|
||||
this._forumTagFilter = null
|
||||
this.guilds = await this.listGuilds()
|
||||
await this._joinDiscoveryMesh()
|
||||
await this._joinContactsMesh()
|
||||
@@ -707,6 +711,7 @@ class PearcordPlatform extends EventEmitter {
|
||||
this.emit('link-embed', p)
|
||||
})
|
||||
guildInstance.on('channel-update', (ch) => this.emit('channel-update', ch))
|
||||
guildInstance.on('forum-post-tags', (p) => this._onForumPostTagsGossip(p))
|
||||
guildInstance.setAttachmentProvider(async (attachmentId) => {
|
||||
const row = await this.attachments?.get(attachmentId)
|
||||
if (!row) throw new Error('attachment not found')
|
||||
@@ -715,6 +720,51 @@ class PearcordPlatform extends EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
async _onForumPostTagsGossip (payload) {
|
||||
if (!payload?.guildId || !payload?.threadId || !this.forum) return
|
||||
const tags = await this.forum.setPostTags(
|
||||
payload.guildId,
|
||||
payload.threadId,
|
||||
payload.tags || []
|
||||
)
|
||||
this.emit('forum-tags', { guildId: payload.guildId, threadId: payload.threadId, tags })
|
||||
}
|
||||
|
||||
setForumTagFilter (tag) {
|
||||
const t = String(tag || '').trim().toLowerCase()
|
||||
this._forumTagFilter = t || null
|
||||
}
|
||||
|
||||
async setForumChannelPalette (channelId, tags) {
|
||||
if (!this.guild?.guild || !this.forum) throw new Error('no guild')
|
||||
const roles = await this._memberRoles()
|
||||
if (!roleHasPermission(roles, PERMISSION.MANAGE_CHANNELS)) {
|
||||
throw new Error('no permission to edit forum tags')
|
||||
}
|
||||
const ch = await this.db.get(COLLECTIONS.CHANNELS, {
|
||||
guildId: this.guild.guild.id,
|
||||
id: channelId
|
||||
})
|
||||
if (!ch || !isForumChannel(ch)) throw new Error('not a forum channel')
|
||||
const topic = this.forum.formatPaletteTopic(tags)
|
||||
const updated = await this.guild.updateChannel({ ...ch, topic })
|
||||
this.guild.gossipChannelUpdate(updated)
|
||||
this.emit('channel-update', updated)
|
||||
return { channelId, palette: this.forum.parsePaletteFromTopic(topic) }
|
||||
}
|
||||
|
||||
async _enrichForumPosts (posts, guildId, forumChannel) {
|
||||
if (!this.forum || !posts?.length) return posts
|
||||
const out = []
|
||||
for (const p of posts) {
|
||||
const tags = await this.forum.getPostTags(guildId, p.id)
|
||||
out.push({ ...p, tags })
|
||||
}
|
||||
const filter = this._forumTagFilter
|
||||
if (!filter) return out
|
||||
return out.filter((p) => (p.tags || []).includes(filter))
|
||||
}
|
||||
|
||||
async _onKickGossip (payload) {
|
||||
const user = this.identity.user
|
||||
if (user && payload.userId === user.id) {
|
||||
@@ -1975,7 +2025,7 @@ class PearcordPlatform extends EventEmitter {
|
||||
return channel
|
||||
}
|
||||
|
||||
async createForumPost ({ title, content }) {
|
||||
async createForumPost ({ title, content, tags }) {
|
||||
if (!this.guild?.guild || !this.activeChannelId) throw new Error('no active forum channel')
|
||||
const forum = await this.db.get(COLLECTIONS.CHANNELS, {
|
||||
guildId: this.guild.guild.id,
|
||||
@@ -1996,12 +2046,25 @@ class PearcordPlatform extends EventEmitter {
|
||||
const message = await this.sendMessage(body)
|
||||
const merged = await this.guild.setThreadRootMessage(thread.id, message.id)
|
||||
this.guild.gossipChannelUpdate(merged)
|
||||
const guildId = this.guild.guild.id
|
||||
const palette = this.forum.parsePaletteFromTopic(forum.topic)
|
||||
const postTags = this.forum.normalizePostTags(
|
||||
(tags || []).filter((t) => !palette.length || palette.includes(t))
|
||||
)
|
||||
if (postTags.length) {
|
||||
await this.forum.setPostTags(guildId, thread.id, postTags)
|
||||
this.guild.gossipForumPostTags({
|
||||
guildId,
|
||||
threadId: thread.id,
|
||||
tags: postTags
|
||||
})
|
||||
}
|
||||
await this._audit('forum.post.create', {
|
||||
guildId: this.guild.guild.id,
|
||||
guildId,
|
||||
targetId: thread.id
|
||||
})
|
||||
this.emit('channel', merged)
|
||||
return { thread: merged, message }
|
||||
return { thread: { ...merged, tags: postTags }, message }
|
||||
}
|
||||
|
||||
async createThread ({ messageId, name }) {
|
||||
@@ -2372,10 +2435,23 @@ class PearcordPlatform extends EventEmitter {
|
||||
threadMessageCounts[ch.id] = rows.length
|
||||
}
|
||||
const activeChannel = channels.find((c) => c.id === this.activeChannelId) || null
|
||||
const forumPosts =
|
||||
let forumPosts =
|
||||
activeChannel && isForumChannel(activeChannel)
|
||||
? sortForumPosts(threadsByParent[activeChannel.id] || [])
|
||||
: []
|
||||
let forumPaletteTags = []
|
||||
let forumUsedTags = []
|
||||
if (activeChannel && isForumChannel(activeChannel) && guild) {
|
||||
forumPaletteTags = this.forum
|
||||
? this.forum.parsePaletteFromTopic(activeChannel.topic)
|
||||
: []
|
||||
forumPosts = await this._enrichForumPosts(
|
||||
forumPosts,
|
||||
guild.id,
|
||||
activeChannel
|
||||
)
|
||||
forumUsedTags = this.forum ? this.forum.collectUsedTags(forumPosts) : []
|
||||
}
|
||||
const channelMeta = {}
|
||||
if (user) {
|
||||
const alertRows = await this.db.find(COLLECTIONS.MENTION_ALERTS, { userId: user.id })
|
||||
@@ -2509,6 +2585,9 @@ class PearcordPlatform extends EventEmitter {
|
||||
threadMessageCounts,
|
||||
threadTypingByParent,
|
||||
forumPosts,
|
||||
forumPaletteTags,
|
||||
forumUsedTags,
|
||||
forumTagFilter: this._forumTagFilter || null,
|
||||
activeChannel,
|
||||
needsGuild: this.onboarded && !this.guilds.length && this.mode !== 'dm',
|
||||
guildUnread,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"pearcord-settings": "git+https://git.ssh.surf/pearcord/pearcord-settings.git#main",
|
||||
"pearcord-device-sync": "git+https://git.ssh.surf/pearcord/pearcord-device-sync.git#main",
|
||||
"pearcord-step-up": "git+https://git.ssh.surf/pearcord/pearcord-step-up.git#main",
|
||||
"pearcord-forum": "git+https://git.ssh.surf/pearcord/pearcord-forum.git#main",
|
||||
"hyperswarm": "^4.11.6",
|
||||
"pearcord-shared": "git+https://git.ssh.surf/pearcord/pearcord-shared.git#main"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user