feat: channel categories with drag-and-drop reordering

Add channel categories (named groups) with full CRUD, collapsible headers
with unread indicators, and native HTML5 drag-and-drop for reordering
channels within/between categories and reordering categories themselves.

- Schema: channel_categories table, category_id column on channels
- Server: category CRUD endpoints, batch channel-layout reorder endpoint
- WebSocket: categories in ready payload, category_created/updated/deleted
  and channel_layout_updated events with per-user VIEW_CHANNEL filtering
- Frontend: dynamic category-based sidebar layout replacing hardcoded
  Text/Voice sections, collapse state persisted to localStorage,
  category selector in CreateChannel modal, federation-aware store
This commit is contained in:
Jannis Braun
2026-03-12 01:19:06 +01:00
parent b6d44f1568
commit c51d6b1a0e
11 changed files with 1045 additions and 121 deletions
+17
View File
@@ -111,6 +111,12 @@ export function runMigrations(db: Database.Database): void {
columns: [
{ name: 'avatar_color', type: 'TEXT' },
]
},
{
name: 'channels',
columns: [
{ name: 'category_id', type: 'TEXT' },
]
}
];
@@ -168,6 +174,17 @@ export function runMigrations(db: Database.Database): void {
);
`);
// Ensure channel_categories table exists (idempotent)
db.exec(`
CREATE TABLE IF NOT EXISTS channel_categories (
id TEXT PRIMARY KEY,
space_id TEXT NOT NULL REFERENCES spaces(id) ON DELETE CASCADE,
name TEXT NOT NULL,
position INTEGER DEFAULT 0,
created_at INTEGER NOT NULL
);
`);
// Ensure voice_restrictions table exists (idempotent)
db.exec(`
CREATE TABLE IF NOT EXISTS voice_restrictions (