Implement file node for editor

This commit is contained in:
Hakan Shehu
2024-10-23 23:47:02 +02:00
parent ecbb92baa6
commit 917cb9b5f4
7 changed files with 124 additions and 1 deletions

View File

@@ -15,12 +15,14 @@ import {
TodoCommand,
PageCommand,
FolderCommand,
FileCommand,
} from '@/renderer/editor/commands';
import {
IdExtension,
DocumentNode,
PageNode,
FolderNode,
FileNode,
TextNode,
ParagraphNode,
Heading1Node,
@@ -93,6 +95,7 @@ export const DocumentEditor = ({
DocumentNode,
PageNode,
FolderNode,
FileNode,
TextNode,
ParagraphNode,
Heading1Node,
@@ -128,6 +131,7 @@ export const DocumentEditor = ({
OrderedListCommand,
DividerCommand,
TodoCommand,
FileCommand,
FolderCommand,
],
context: {

View File

@@ -0,0 +1,51 @@
import { EditorCommand } from '@/types/editor';
import { NodeTypes } from '@/lib/constants';
export const FileCommand: EditorCommand = {
key: 'file',
name: 'File',
description: 'Insert a nested file',
keywords: ['file', 'image', 'video', 'audio'],
icon: 'file-text-line',
disabled: false,
async handler({ editor, range, context }) {
if (context == null) {
return;
}
const result = await window.neuron.openFileDialog({
properties: ['openFile'],
buttonLabel: 'Upload',
title: 'Upload files to page',
});
if (result.canceled) {
return;
}
const { userId, documentId } = context;
const output = await window.neuron.executeMutation({
type: 'file_create',
filePath: result.filePaths[0],
userId,
parentId: documentId,
generateIndex: false,
});
if (!output.id) {
return;
}
editor
.chain()
.focus()
.deleteRange(range)
.insertContent({
type: NodeTypes.File,
attrs: {
id: output.id,
},
})
.run();
},
};

View File

@@ -10,6 +10,7 @@ import { ParagraphCommand } from '@/renderer/editor/commands/paragraph';
import { TodoCommand } from '@/renderer/editor/commands/todo';
import { PageCommand } from '@/renderer/editor/commands/page';
import { FolderCommand } from '@/renderer/editor/commands/folder';
import { FileCommand } from '@/renderer/editor/commands/file';
import { EditorCommand, EditorCommandProps } from '@/types/editor';
export type { EditorCommand, EditorCommandProps };
@@ -27,4 +28,5 @@ export {
TodoCommand,
PageCommand,
FolderCommand,
FileCommand,
};

View File

@@ -0,0 +1,26 @@
import { mergeAttributes, Node } from '@tiptap/core';
import { ReactNodeViewRenderer } from '@tiptap/react';
import { FileNodeView } from '@/renderer/editor/views';
export const FileNode = Node.create({
name: 'file',
group: 'block',
atom: true,
defining: true,
draggable: true,
addAttributes() {
return {
id: {
default: null,
},
};
},
renderHTML({ HTMLAttributes }) {
return ['file', mergeAttributes(HTMLAttributes)];
},
addNodeView() {
return ReactNodeViewRenderer(FileNodeView, {
as: 'file',
});
},
});

View File

@@ -32,6 +32,7 @@ import { TaskListNode } from '@/renderer/editor/extensions/task-list';
import { TrailingNode } from '@/renderer/editor/extensions/trailing-node';
import { PageNode } from '@/renderer/editor/extensions/page';
import { FolderNode } from '@/renderer/editor/extensions/folder';
import { FileNode } from '@/renderer/editor/extensions/file';
export {
IdExtension,
@@ -67,4 +68,5 @@ export {
DropcursorExtension,
PageNode,
FolderNode,
FileNode,
};

View File

@@ -0,0 +1,37 @@
import React from 'react';
import { type NodeViewProps } from '@tiptap/core';
import { NodeViewWrapper } from '@tiptap/react';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { useQuery } from '@/renderer/hooks/use-query';
import { FilePreview } from '@/renderer/components/files/file-preview';
export const FileNodeView = ({ node }: NodeViewProps) => {
const workspace = useWorkspace();
const id = node.attrs.id;
const { data } = useQuery({
type: 'file_get',
fileId: id,
userId: workspace.userId,
});
if (!id) {
return null;
}
if (!data) {
return null;
}
return (
<NodeViewWrapper
data-id={node.attrs.id}
className="flex h-72 max-h-72 w-full cursor-pointer overflow-hidden rounded-md p-2 hover:bg-gray-100"
onClick={() => {
workspace.openModal(id);
}}
>
<FilePreview file={data} />
</NodeViewWrapper>
);
};

View File

@@ -1,5 +1,6 @@
import { CodeBlockNodeView } from '@/renderer/editor/views/code-block';
import { PageNodeView } from '@/renderer/editor/views/page';
import { FolderNodeView } from '@/renderer/editor/views/folder';
import { FileNodeView } from '@/renderer/editor/views/file';
export { CodeBlockNodeView, PageNodeView, FolderNodeView };
export { CodeBlockNodeView, PageNodeView, FolderNodeView, FileNodeView };