feat(channels): deleteChannel and CHANNEL_DELETE gossip (v0.8.421)
Ingest channel delete on mesh; block deleting non-empty categories or channels that still have threads. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -31,7 +31,9 @@ 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 |
|
||||||
|
|
||||||
**v0.8.420 (Phase 457):** Platform wraps `createChannel` / `createCategory` / `renameChannel` with `channel.create`, `category.create`, and `channel.update` spans (see [CHANNELS.md](../../docs/CHANNELS.md)). Channel delete API planned for Phase 458.
|
**v0.8.421 (Phase 458):** `deleteChannel` + `gossipChannelDelete` (`RPC.CHANNEL_DELETE`); inbound `_ingestChannelDelete` on mesh.
|
||||||
|
|
||||||
|
**v0.8.420 (Phase 457):** Platform wraps `createChannel` / `createCategory` / `renameChannel` with `channel.create`, `category.create`, and `channel.update` spans (see [CHANNELS.md](../../docs/CHANNELS.md)).
|
||||||
| `PearcordGuild#reorderChannelsInParent` | Reassign `position` for siblings under one category/root |
|
| `PearcordGuild#reorderChannelsInParent` | Reassign `position` for siblings under one category/root |
|
||||||
| `PearcordGuild#moveChannelToParent` | Move channel into category (v0.8.168) |
|
| `PearcordGuild#moveChannelToParent` | Move channel into category (v0.8.168) |
|
||||||
| `PearcordGuild#reorderCategories` | Reassign `position` for category rows |
|
| `PearcordGuild#reorderCategories` | Reassign `position` for category rows |
|
||||||
|
|||||||
@@ -285,6 +285,9 @@ class PearcordGuild extends EventEmitter {
|
|||||||
this.emit('channel', ch)
|
this.emit('channel', ch)
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
if (method === RPC.CHANNEL_DELETE) {
|
||||||
|
this._ingestChannelDelete(payload).catch(() => {})
|
||||||
|
}
|
||||||
if (method === RPC.MESSAGE_PIN) {
|
if (method === RPC.MESSAGE_PIN) {
|
||||||
this.db.insert(COLLECTIONS.PINS, payload).then(() => {
|
this.db.insert(COLLECTIONS.PINS, payload).then(() => {
|
||||||
this.emit('pin', payload)
|
this.emit('pin', payload)
|
||||||
@@ -504,6 +507,10 @@ class PearcordGuild extends EventEmitter {
|
|||||||
await this.ingestChannel(payload).catch(() => {})
|
await this.ingestChannel(payload).catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (method === RPC.CHANNEL_DELETE) {
|
||||||
|
await this._ingestChannelDelete(payload).catch(() => {})
|
||||||
|
return
|
||||||
|
}
|
||||||
if (method === RPC.EMOJI_UPSERT) {
|
if (method === RPC.EMOJI_UPSERT) {
|
||||||
this.emit('guild-emoji', payload)
|
this.emit('guild-emoji', payload)
|
||||||
return
|
return
|
||||||
@@ -635,6 +642,10 @@ class PearcordGuild extends EventEmitter {
|
|||||||
broadcastGossip(this, RPC.CHANNEL_CREATE, channel)
|
broadcastGossip(this, RPC.CHANNEL_CREATE, channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gossipChannelDelete (payload) {
|
||||||
|
broadcastGossip(this, RPC.CHANNEL_DELETE, payload)
|
||||||
|
}
|
||||||
|
|
||||||
gossipPin (payload) {
|
gossipPin (payload) {
|
||||||
broadcastGossip(this, RPC.MESSAGE_PIN, payload)
|
broadcastGossip(this, RPC.MESSAGE_PIN, payload)
|
||||||
}
|
}
|
||||||
@@ -1147,6 +1158,37 @@ class PearcordGuild extends EventEmitter {
|
|||||||
return merged
|
return merged
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _ingestChannelDelete (payload) {
|
||||||
|
const guildId = payload?.guildId
|
||||||
|
const channelId = payload?.channelId || payload?.id
|
||||||
|
if (!guildId || !channelId) return
|
||||||
|
await this.db.delete(COLLECTIONS.CHANNELS, { guildId, id: channelId })
|
||||||
|
await this.db.delete(COLLECTIONS.CHANNEL_SETTINGS, { guildId, channelId }).catch(() => {})
|
||||||
|
this.emit('channel-delete', { guildId, channelId, type: payload?.type || null })
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteChannel (channelId) {
|
||||||
|
if (!this.guild) throw new Error('no active guild')
|
||||||
|
if (!channelId) throw new Error('channelId required')
|
||||||
|
const channels = await this.listChannels()
|
||||||
|
const ch = channels.find((c) => c.id === channelId)
|
||||||
|
if (!ch) throw new Error('channel not found')
|
||||||
|
if (ch.type === CHANNEL_TYPES.CATEGORY) {
|
||||||
|
const children = channels.filter(
|
||||||
|
(c) => c.type !== CHANNEL_TYPES.CATEGORY && (c.parentId || null) === channelId
|
||||||
|
)
|
||||||
|
if (children.length) throw new Error('category not empty')
|
||||||
|
} else if (ch.type !== CHANNEL_TYPES.THREAD) {
|
||||||
|
const threads = channels.filter(
|
||||||
|
(c) => c.type === CHANNEL_TYPES.THREAD && c.parentId === channelId
|
||||||
|
)
|
||||||
|
if (threads.length) throw new Error('channel has threads')
|
||||||
|
}
|
||||||
|
const payload = { guildId: this.guild.id, channelId, type: ch.type }
|
||||||
|
await this._ingestChannelDelete(payload)
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
async createChannel ({ name, type = CHANNEL_TYPES.TEXT, parentId = null } = {}) {
|
async createChannel ({ name, type = CHANNEL_TYPES.TEXT, parentId = null } = {}) {
|
||||||
if (!this.guild) throw new Error('no active guild')
|
if (!this.guild) throw new Error('no active guild')
|
||||||
if (!name) throw new Error('name required')
|
if (!name) throw new Error('name required')
|
||||||
|
|||||||
Reference in New Issue
Block a user