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:
@@ -42,6 +42,14 @@ export const spaceMembers = sqliteTable('space_members', {
|
||||
pk: primaryKey({ columns: [table.spaceId, table.userId] }),
|
||||
}));
|
||||
|
||||
export const channelCategories = sqliteTable('channel_categories', {
|
||||
id: text('id').primaryKey(),
|
||||
spaceId: text('space_id').notNull().references(() => spaces.id, { onDelete: 'cascade' }),
|
||||
name: text('name').notNull(),
|
||||
position: integer('position').default(0),
|
||||
createdAt: integer('created_at').notNull(),
|
||||
});
|
||||
|
||||
export const channels = sqliteTable('channels', {
|
||||
id: text('id').primaryKey(),
|
||||
spaceId: text('space_id').notNull().references(() => spaces.id, { onDelete: 'cascade' }),
|
||||
@@ -49,6 +57,7 @@ export const channels = sqliteTable('channels', {
|
||||
type: text('type').notNull(),
|
||||
topic: text('topic'),
|
||||
position: integer('position').default(0),
|
||||
categoryId: text('category_id'),
|
||||
createdAt: integer('created_at').notNull(),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user