feat(guild): reorderCategories for category position updates

Support sidebar category drag-reorder by reassigning category channel
position indices with P2P CHANNEL_UPDATE gossip.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-22 21:08:22 -04:00
co-authored by Cursor
parent 630f41841a
commit fa0af043c2
2 changed files with 22 additions and 0 deletions
+1
View File
@@ -31,6 +31,7 @@ Create and load guilds in local storage, join peers on `pearcord:guild:{guildId}
| `PearcordGuild#listChannels()` / `#listMembers()` | DB queries with thread meta attached | | `PearcordGuild#listChannels()` / `#listMembers()` | DB queries with thread meta attached |
| `PearcordGuild#createChannel`, `#createCategory`, `#createThread`, `#createForumThread` | Channel tree | | `PearcordGuild#createChannel`, `#createCategory`, `#createThread`, `#createForumThread` | Channel tree |
| `PearcordGuild#reorderChannelsInParent` | Reassign `position` for siblings under one category/root | | `PearcordGuild#reorderChannelsInParent` | Reassign `position` for siblings under one category/root |
| `PearcordGuild#reorderCategories` | Reassign `position` for category rows |
| `PearcordGuild#updateChannel`, `#ingestChannel` | Upsert + thread meta | | `PearcordGuild#updateChannel`, `#ingestChannel` | Upsert + thread meta |
| `PearcordGuild#setMessageHandler(fn)` | Inbound `RPC.MESSAGE_CREATE` persistence hook (platform sets this) | | `PearcordGuild#setMessageHandler(fn)` | Inbound `RPC.MESSAGE_CREATE` persistence hook (platform sets this) |
| `PearcordGuild#gossip*` / `#sendVoiceMedia` / `#sendScreenMedia` | Outbound RPC (see `index.js` for full list) | | `PearcordGuild#gossip*` / `#sendVoiceMedia` / `#sendScreenMedia` | Outbound RPC (see `index.js` for full list) |
+21
View File
@@ -1118,6 +1118,27 @@ class PearcordGuild extends EventEmitter {
return updated return updated
} }
async reorderCategories ({ categoryIds = [] } = {}) {
if (!this.guild) throw new Error('no active guild')
const existing = await this.listChannels()
const categories = existing.filter((c) => c.type === CHANNEL_TYPES.CATEGORY)
if (!categoryIds.length || categoryIds.length !== categories.length) {
throw new Error('category order mismatch')
}
const byId = new Map(categories.map((c) => [c.id, c]))
for (const id of categoryIds) {
if (!byId.has(id)) throw new Error('invalid category id')
}
const updated = []
for (let i = 0; i < categoryIds.length; i++) {
const ch = byId.get(categoryIds[i])
if ((ch.position || 0) === i) continue
const merged = await this.updateChannel({ ...ch, position: i })
updated.push(merged)
}
return updated
}
async listChannels () { async listChannels () {
if (!this.guild) return [] if (!this.guild) return []
const rows = await this.db.find(COLLECTIONS.CHANNELS, { guildId: this.guild.id }) const rows = await this.db.find(COLLECTIONS.CHANNELS, { guildId: this.guild.id })