feat: unread indicators + DM bug fixes + data-driven isDmChannel
- Fix stale message cache: add force param to loadMessages, clearAllMessages action - Fix reload race condition: URL-based isDmChannel fallback before WS ready - Add read_states DB table for persistent unread tracking - Add channel_ack WS event (client→server→echo) with BigInt comparison - Wire up unread state in chatStore (readStates, unreadChannels, ackChannel) - Auto-ack channels on MessageList view (200ms debounced) - Unread pill indicators on server icons in ServerSidebar - Bold text + white dot on unread channels/DMs in ChannelSidebar - Replace all showDms reads with data-driven isDmChannel() across 8 files - Design system, UI polish, and component fixes from previous sessions
This commit is contained in:
@@ -138,6 +138,15 @@ export const memberRoles = sqliteTable('member_roles', {
|
||||
pk: primaryKey({ columns: [table.serverId, table.userId, table.roleId] }),
|
||||
}));
|
||||
|
||||
export const readStates = sqliteTable('read_states', {
|
||||
userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
channelId: text('channel_id').notNull(),
|
||||
lastReadMessageId: text('last_read_message_id').notNull(),
|
||||
updatedAt: integer('updated_at').notNull(),
|
||||
}, (table) => ({
|
||||
pk: primaryKey({ columns: [table.userId, table.channelId] }),
|
||||
}));
|
||||
|
||||
export const serverFolders = sqliteTable('server_folders', {
|
||||
id: text('id').primaryKey(),
|
||||
userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
|
||||
Reference in New Issue
Block a user