From ae9c8dcb4cf53ea0966615e4942322f323ffb3b2 Mon Sep 17 00:00:00 2001 From: prcrst <138210321+prcrst@users.noreply.github.com> Date: Thu, 23 Nov 2023 11:09:48 +0000 Subject: [PATCH] Upload file command with copy/paste logic (#571) Upload: File command Co-authored-by: prcrst Co-authored-by: Zef Hemel --- plug-api/types.ts | 1 + plugs/editor/editor.plug.yaml | 4 +++ plugs/editor/upload.ts | 49 +++++++++++++++++++++++++++++++++++ web/syscalls/editor.ts | 1 + 4 files changed, 55 insertions(+) create mode 100644 plugs/editor/upload.ts diff --git a/plug-api/types.ts b/plug-api/types.ts index 6cf8d27..2b2d439 100644 --- a/plug-api/types.ts +++ b/plug-api/types.ts @@ -143,5 +143,6 @@ export type LintDiagnostic = { export type UploadFile = { name: string; + contentType: string; content: Uint8Array; } \ No newline at end of file diff --git a/plugs/editor/editor.plug.yaml b/plugs/editor/editor.plug.yaml index 640d782..ddd713f 100644 --- a/plugs/editor/editor.plug.yaml +++ b/plugs/editor/editor.plug.yaml @@ -222,3 +222,7 @@ functions: command: name: "Account: Logout" + uploadFileCommand: + path: ./upload.ts:uploadFile + command: + name: "Upload: File" diff --git a/plugs/editor/upload.ts b/plugs/editor/upload.ts new file mode 100644 index 0000000..1fb4838 --- /dev/null +++ b/plugs/editor/upload.ts @@ -0,0 +1,49 @@ +import { editor, space } from "$sb/silverbullet-syscall/mod.ts"; +import { UploadFile } from "$sb/types.ts"; + +const maximumAttachmentSize = 1024 * 1024 * 10; // 10MB + +function folderName(path: string) { + return path.split("/").slice(0, -1).join("/"); +} + +async function saveFile(file: UploadFile) { + if (file.content.length > maximumAttachmentSize) { + editor.flashNotification( + `Attachment is too large, maximum is ${ + maximumAttachmentSize / 1024 / 1024 + }MB`, + "error", + ); + return; + } + + let prefix = folderName(await editor.getCurrentPage()) + "/"; + if (prefix === "/") { + // root folder case + prefix = ""; + } + const suggestedName = prefix + file.name; + + const finalFileName = await editor.prompt( + "File name for pasted attachment", + suggestedName, + ); + if (!finalFileName) { + return; + } + await space.writeAttachment( + finalFileName, + file.content, + ); + let attachmentMarkdown = `[${finalFileName}](${encodeURI(finalFileName)})`; + if (file.contentType.startsWith("image/")) { + attachmentMarkdown = `![](${encodeURI(finalFileName)})`; + } + editor.insertAtCursor(attachmentMarkdown); +} + +export async function uploadFile() { + const uploadFile = await editor.uploadFile(); + await saveFile(uploadFile); +} diff --git a/web/syscalls/editor.ts b/web/syscalls/editor.ts index ae8c312..6dda6b5 100644 --- a/web/syscalls/editor.ts +++ b/web/syscalls/editor.ts @@ -88,6 +88,7 @@ export function editorSyscalls(editor: Client): SysCallMapping { if (evt.target?.readyState == FileReader.DONE) { resolve({ name: file.name, + contentType: file.type, content: new Uint8Array(await file.arrayBuffer()), }); }