diff --git a/packages/client/src/handlers/queries/chats/chat-list.ts b/packages/client/src/handlers/queries/chats/chat-list.ts deleted file mode 100644 index 28d59dcc..00000000 --- a/packages/client/src/handlers/queries/chats/chat-list.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { SelectNode } from '@colanode/client/databases/workspace'; -import { WorkspaceQueryHandlerBase } from '@colanode/client/handlers/queries/workspace-query-handler-base'; -import { mapNode } from '@colanode/client/lib/mappers'; -import { ChangeCheckResult, QueryHandler } from '@colanode/client/lib/types'; -import { ChatListQueryInput } from '@colanode/client/queries/chats/chat-list'; -import { Event } from '@colanode/client/types/events'; -import { LocalChatNode } from '@colanode/client/types/nodes'; - -export class ChatListQueryHandler - extends WorkspaceQueryHandlerBase - implements QueryHandler -{ - public async handleQuery( - input: ChatListQueryInput - ): Promise { - const rows = await this.fetchChildren(input); - return rows.map(mapNode) as LocalChatNode[]; - } - - public async checkForChanges( - event: Event, - input: ChatListQueryInput, - output: LocalChatNode[] - ): Promise> { - if ( - event.type === 'workspace.deleted' && - event.workspace.userId === input.userId - ) { - return { - hasChanges: true, - result: [], - }; - } - - if ( - event.type === 'node.created' && - event.workspace.userId === input.userId && - event.node.type === 'chat' - ) { - const newChildren = [...output, event.node]; - return { - hasChanges: true, - result: newChildren, - }; - } - - if ( - event.type === 'node.updated' && - event.workspace.userId === input.userId && - event.node.type === 'chat' - ) { - const node = output.find((node) => node.id === event.node.id); - if (node) { - const newChildren = output.map((node) => - node.id === event.node.id ? (event.node as LocalChatNode) : node - ); - - return { - hasChanges: true, - result: newChildren, - }; - } - } - - if ( - event.type === 'node.deleted' && - event.workspace.userId === input.userId && - event.node.type === 'chat' - ) { - const node = output.find((node) => node.id === event.node.id); - if (node) { - const newChildren = output.filter((node) => node.id !== event.node.id); - return { - hasChanges: true, - result: newChildren, - }; - } - } - - return { - hasChanges: false, - }; - } - - private async fetchChildren( - input: ChatListQueryInput - ): Promise { - const workspace = this.getWorkspace(input.userId); - - const rows = await workspace.database - .selectFrom('nodes') - .selectAll() - .where('parent_id', 'is', null) - .where('type', '=', 'chat') - .execute(); - - return rows; - } -} diff --git a/packages/client/src/handlers/queries/index.ts b/packages/client/src/handlers/queries/index.ts index 07126c5b..a29f98dc 100644 --- a/packages/client/src/handlers/queries/index.ts +++ b/packages/client/src/handlers/queries/index.ts @@ -6,7 +6,6 @@ import { AccountListQueryHandler } from './accounts/accounts-list'; import { MetadataListQueryHandler } from './apps/metadata-list'; import { TabsListQueryHandler } from './apps/tabs-list'; import { AvatarGetQueryHandler } from './avatars/avatar-get'; -import { ChatListQueryHandler } from './chats/chat-list'; import { DatabaseListQueryHandler } from './databases/database-list'; import { DatabaseViewListQueryHandler } from './databases/database-view-list'; import { DocumentGetQueryHandler } from './documents/document-get'; @@ -89,7 +88,6 @@ export const buildQueryHandlerMap = (app: AppService): QueryHandlerMap => { 'user.storage.get': new UserStorageGetQueryHandler(app), 'local.file.get': new LocalFileGetQueryHandler(app), 'file.download.request.get': new FileDownloadRequestGetQueryHandler(app), - 'chat.list': new ChatListQueryHandler(app), 'space.list': new SpaceListQueryHandler(app), 'document.get': new DocumentGetQueryHandler(app), 'document.state.get': new DocumentStateGetQueryHandler(app), diff --git a/packages/client/src/queries/chats/chat-list.ts b/packages/client/src/queries/chats/chat-list.ts deleted file mode 100644 index dcd5866e..00000000 --- a/packages/client/src/queries/chats/chat-list.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { LocalChatNode } from '@colanode/client/types/nodes'; - -export type ChatListQueryInput = { - type: 'chat.list'; - page: number; - count: number; - userId: string; -}; - -declare module '@colanode/client/queries' { - interface QueryMap { - 'chat.list': { - input: ChatListQueryInput; - output: LocalChatNode[]; - }; - } -} diff --git a/packages/client/src/queries/index.ts b/packages/client/src/queries/index.ts index 83a4a7de..91ab4031 100644 --- a/packages/client/src/queries/index.ts +++ b/packages/client/src/queries/index.ts @@ -2,7 +2,6 @@ import { sha256 } from 'js-sha256'; export * from './accounts/account-list'; export * from './apps/metadata-list'; -export * from './chats/chat-list'; export * from './databases/database-list'; export * from './databases/database-view-list'; export * from './documents/document-get'; diff --git a/packages/ui/src/collections/index.ts b/packages/ui/src/collections/index.ts index 1198ec43..42facf7a 100644 --- a/packages/ui/src/collections/index.ts +++ b/packages/ui/src/collections/index.ts @@ -2,6 +2,7 @@ import { Collection, createLiveQueryCollection, eq } from '@tanstack/react-db'; import { Download, + LocalChatNode, LocalNode, LocalRecordNode, Upload, @@ -26,6 +27,7 @@ class WorkspaceCollections { public readonly uploads: Collection; public readonly nodes: Collection; public readonly records: Collection; + public readonly chats: Collection; constructor(userId: string) { this.userId = userId; @@ -34,8 +36,14 @@ class WorkspaceCollections { this.uploads = createUploadsCollection(userId); this.nodes = createNodesCollection(userId); + this.chats = createLiveQueryCollection((q) => + q.from({ nodes: this.nodes }).where(({ nodes }) => eq(nodes.type, 'chat')) + ); + this.records = createLiveQueryCollection((q) => - q.from({ node: this.nodes }).where(({ node }) => eq(node.type, 'record')) + q + .from({ nodes: this.nodes }) + .where(({ nodes }) => eq(nodes.type, 'record')) ); } } diff --git a/packages/ui/src/components/layouts/sidebars/sidebar-chats.tsx b/packages/ui/src/components/layouts/sidebars/sidebar-chats.tsx index 3805789f..b625a1b8 100644 --- a/packages/ui/src/components/layouts/sidebars/sidebar-chats.tsx +++ b/packages/ui/src/components/layouts/sidebars/sidebar-chats.tsx @@ -1,21 +1,22 @@ +import { useLiveQuery } from '@tanstack/react-db'; + +import { collections } from '@colanode/ui/collections'; import { ChatCreatePopover } from '@colanode/ui/components/chats/chat-create-popover'; import { ChatSidebarItem } from '@colanode/ui/components/chats/chat-sidebar-item'; import { SidebarHeader } from '@colanode/ui/components/layouts/sidebars/sidebar-header'; import { Link } from '@colanode/ui/components/ui/link'; import { useWorkspace } from '@colanode/ui/contexts/workspace'; -import { useLiveQuery } from '@colanode/ui/hooks/use-live-query'; export const SidebarChats = () => { const workspace = useWorkspace(); - const chatListQuery = useLiveQuery({ - type: 'chat.list', - userId: workspace.userId, - page: 0, - count: 100, - }); + const chatListQuery = useLiveQuery((q) => + q + .from({ chats: collections.workspace(workspace.userId).chats }) + .orderBy(({ chats }) => chats.id, 'asc') + ); - const chats = chatListQuery.data ?? []; + const chats = chatListQuery.data; return (