feat(roles): add reorderRoles for drag-reorder position updates

Batch-update custom role positions for server settings drag reorder
with P2P ROLE_UPSERT sync.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-22 21:38:00 -04:00
co-authored by Cursor
parent 478bcbbebe
commit 69bcf09c94
2 changed files with 27 additions and 2 deletions
+3 -2
View File
@@ -36,7 +36,7 @@ Let servers define up to 24 named colored roles with Discord-style permission fl
| Method | Role | | Method | Role |
|--------|------| |--------|------|
| `listRoles` / `getRole` / `createRole` / `updateRole` / `deleteRole` | Role CRUD | | `listRoles` / `getRole` / `createRole` / `updateRole` / `deleteRole` / `reorderRoles` | Role CRUD + position reorder |
| `getMemberRoleIds` / `setMemberRoleIds` | Member links | | `getMemberRoleIds` / `setMemberRoleIds` | Member links |
| `attachCustomRolesToMembers` | Enrich member list | | `attachCustomRolesToMembers` | Enrich member list |
| `resolvePermissions(member, customRoles)` | View object for UI | | `resolvePermissions(member, customRoles)` | View object for UI |
@@ -82,7 +82,7 @@ Voice/stage join: `listRoles` + `memberPermissionMask` with channel overwrites.
## UI / IPC ## UI / IPC
Server settings → Roles: create role, color, permission matrix, assign to members. IPC mirrors platform role APIs. Server settings → Roles: create role, color, permission matrix, **drag reorder** (updates `position` + `ROLE_UPSERT` gossip), assign to members. IPC mirrors platform role APIs including `reorder-guild-custom-roles`.
## Related docs ## Related docs
@@ -96,6 +96,7 @@ Server settings → Roles: create role, color, permission matrix, assign to memb
- `npm run test:role-permissions` - `npm run test:role-permissions`
- `npm run test:voice-permissions` - `npm run test:voice-permissions`
- `npm run test:role-reorder` (Phase 202 GUI drag reorder)
## Code example ## Code example
+24
View File
@@ -120,6 +120,30 @@ class PearcordGuildRoles {
return row return row
} }
async reorderRoles (guildId, orderedRoleIds = []) {
const gid = this._guildKey(guildId)
const roles = await this.listRoles(gid)
const want = (orderedRoleIds || []).map(String)
if (want.length !== roles.length) {
throw new Error('role order must include all custom roles')
}
const roleSet = new Set(roles.map((r) => r.id))
for (const id of want) {
if (!roleSet.has(id)) throw new Error('unknown role in order')
}
const updated = []
for (let i = 0; i < want.length; i++) {
const prev = roles.find((r) => r.id === want[i])
if (!prev) continue
if ((prev.position || 0) === i) {
updated.push(prev)
continue
}
updated.push(await this.updateRole(gid, want[i], { position: i }))
}
return updated
}
async deleteRole (guildId, roleId) { async deleteRole (guildId, roleId) {
const gid = this._guildKey(guildId) const gid = this._guildKey(guildId)
const prev = await this.getRole(gid, roleId) const prev = await this.getRole(gid, roleId)