mirror of
https://github.com/colanode/colanode.git
synced 2025-12-16 11:47:47 +01:00
Use tanstackdb for file nodes
This commit is contained in:
@@ -1,105 +0,0 @@
|
||||
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 { FileListQueryInput } from '@colanode/client/queries/files/file-list';
|
||||
import { Event } from '@colanode/client/types/events';
|
||||
import { LocalFileNode } from '@colanode/client/types/nodes';
|
||||
|
||||
export class FileListQueryHandler
|
||||
extends WorkspaceQueryHandlerBase
|
||||
implements QueryHandler<FileListQueryInput>
|
||||
{
|
||||
public async handleQuery(
|
||||
input: FileListQueryInput
|
||||
): Promise<LocalFileNode[]> {
|
||||
return await this.fetchFiles(input);
|
||||
}
|
||||
|
||||
public async checkForChanges(
|
||||
event: Event,
|
||||
input: FileListQueryInput,
|
||||
output: LocalFileNode[]
|
||||
): Promise<ChangeCheckResult<FileListQueryInput>> {
|
||||
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.parentId === input.parentId
|
||||
) {
|
||||
const output = await this.handleQuery(input);
|
||||
return {
|
||||
hasChanges: true,
|
||||
result: output,
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
event.type === 'node.updated' &&
|
||||
event.workspace.userId === input.userId &&
|
||||
event.node.parentId === input.parentId
|
||||
) {
|
||||
const file = output.find((file) => file.id === event.node.id);
|
||||
if (file) {
|
||||
const newResult = output.map((file) => {
|
||||
if (file.id === event.node.id && event.node.type === 'file') {
|
||||
return event.node;
|
||||
}
|
||||
|
||||
return file;
|
||||
});
|
||||
|
||||
return {
|
||||
hasChanges: true,
|
||||
result: newResult,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
event.type === 'node.deleted' &&
|
||||
event.workspace.userId === input.userId &&
|
||||
event.node.parentId === input.parentId
|
||||
) {
|
||||
const file = output.find((file) => file.id === event.node.id);
|
||||
if (file) {
|
||||
const output = await this.handleQuery(input);
|
||||
return {
|
||||
hasChanges: true,
|
||||
result: output,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
hasChanges: false,
|
||||
};
|
||||
}
|
||||
|
||||
private async fetchFiles(
|
||||
input: FileListQueryInput
|
||||
): Promise<LocalFileNode[]> {
|
||||
const workspace = this.getWorkspace(input.userId);
|
||||
|
||||
const offset = (input.page - 1) * input.count;
|
||||
const files = await workspace.database
|
||||
.selectFrom('nodes')
|
||||
.selectAll()
|
||||
.where('type', '=', 'file')
|
||||
.where('parent_id', '=', input.parentId)
|
||||
.orderBy('id', 'asc')
|
||||
.limit(input.count)
|
||||
.offset(offset)
|
||||
.execute();
|
||||
|
||||
return files.map(mapNode) as LocalFileNode[];
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ import { EmojiSearchQueryHandler } from './emojis/emoji-search';
|
||||
import { EmojiSvgGetQueryHandler } from './emojis/emoji-svg-get';
|
||||
import { DownloadListQueryHandler } from './files/download-list';
|
||||
import { FileDownloadRequestGetQueryHandler } from './files/file-download-request-get';
|
||||
import { FileListQueryHandler } from './files/file-list';
|
||||
import { LocalFileGetQueryHandler } from './files/local-file-get';
|
||||
import { TempFileListQueryHandler } from './files/temp-file-list';
|
||||
import { UploadListQueryHandler } from './files/upload-list';
|
||||
@@ -63,7 +62,6 @@ export const buildQueryHandlerMap = (app: AppService): QueryHandlerMap => {
|
||||
'user.search': new UserSearchQueryHandler(app),
|
||||
'workspace.list': new WorkspaceListQueryHandler(app),
|
||||
'user.list': new UserListQueryHandler(app),
|
||||
'file.list': new FileListQueryHandler(app),
|
||||
'emoji.list': new EmojiListQueryHandler(app),
|
||||
'emoji.get': new EmojiGetQueryHandler(app),
|
||||
'emoji.get.by.skin.id': new EmojiGetBySkinIdQueryHandler(app),
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { LocalFileNode } from '@colanode/client/types/nodes';
|
||||
|
||||
export type FileListQueryInput = {
|
||||
type: 'file.list';
|
||||
parentId: string;
|
||||
page: number;
|
||||
count: number;
|
||||
userId: string;
|
||||
};
|
||||
|
||||
declare module '@colanode/client/queries' {
|
||||
interface QueryMap {
|
||||
'file.list': {
|
||||
input: FileListQueryInput;
|
||||
output: LocalFileNode[];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ export * from './emojis/emoji-get-by-skin-id';
|
||||
export * from './emojis/emoji-get';
|
||||
export * from './emojis/emoji-list';
|
||||
export * from './emojis/emoji-search';
|
||||
export * from './files/file-list';
|
||||
export * from './files/local-file-get';
|
||||
export * from './files/file-download-request-get';
|
||||
export * from './icons/icon-category-list';
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import { eq, useLiveQuery } from '@tanstack/react-db';
|
||||
import { useNavigate } from '@tanstack/react-router';
|
||||
import { useState } from 'react';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { FileListQueryInput } from '@colanode/client/queries';
|
||||
import { FolderLayoutType } from '@colanode/client/types';
|
||||
import { FolderLayoutType, LocalFileNode } from '@colanode/client/types';
|
||||
import { GalleryLayout } from '@colanode/ui/components/folders/galleries/gallery-layout';
|
||||
import { GridLayout } from '@colanode/ui/components/folders/grids/grid-layout';
|
||||
import { ListLayout } from '@colanode/ui/components/folders/lists/list-layout';
|
||||
import { FolderContext } from '@colanode/ui/contexts/folder';
|
||||
import { useWorkspace } from '@colanode/ui/contexts/workspace';
|
||||
import { useLiveQueries } from '@colanode/ui/hooks/use-live-queries';
|
||||
|
||||
const FILES_PER_PAGE = 100;
|
||||
import { database } from '@colanode/ui/data';
|
||||
|
||||
interface FolderFilesProps {
|
||||
id: string;
|
||||
@@ -27,19 +24,15 @@ export const FolderFiles = ({
|
||||
const workspace = useWorkspace();
|
||||
const navigate = useNavigate({ from: '/workspace/$userId' });
|
||||
|
||||
const [lastPage] = useState<number>(1);
|
||||
const inputs: FileListQueryInput[] = Array.from({
|
||||
length: lastPage,
|
||||
}).map((_, i) => ({
|
||||
type: 'file.list',
|
||||
userId: workspace.userId,
|
||||
parentId: id,
|
||||
count: FILES_PER_PAGE,
|
||||
page: i + 1,
|
||||
}));
|
||||
const viewListQuery = useLiveQuery((q) =>
|
||||
q
|
||||
.from({ nodes: database.workspace(workspace.userId).nodes })
|
||||
.where(({ nodes }) => eq(nodes.type, 'file'))
|
||||
.where(({ nodes }) => eq(nodes.parentId, id))
|
||||
.orderBy(({ nodes }) => nodes.id, 'asc')
|
||||
);
|
||||
|
||||
const result = useLiveQueries(inputs);
|
||||
const files = result.flatMap((data) => data.data ?? []);
|
||||
const files = viewListQuery.data.map((node) => node as LocalFileNode) ?? [];
|
||||
|
||||
return (
|
||||
<FolderContext.Provider
|
||||
|
||||
Reference in New Issue
Block a user