Fixes #71: also adds drag & drop support

pull/73/head
Zef Hemel 2022-09-05 13:11:03 +02:00
parent e679820c7d
commit c7545bf350
5 changed files with 75 additions and 46 deletions

View File

@ -1,4 +1,5 @@
export const reservedPageNames = ["page", "attachment", "plug"];
export const maximumAttachmentSize = 100 * 1024 * 1024; // 100 MB
export type PageMeta = {
name: string;

View File

@ -47,7 +47,7 @@ import { systemSyscalls } from "./syscalls/system";
import { Panel } from "./components/panel";
import { CommandHook } from "./hooks/command";
import { SlashCommandHook } from "./hooks/slash_command";
import { pasteAttachmentExtension, pasteLinkExtension } from "./editor_paste";
import { attachmentExtension, pasteLinkExtension } from "./editor_paste";
import { markdownSyscalls } from "@silverbulletmd/common/syscalls/markdown";
import { clientStoreSyscalls } from "./syscalls/clientStore";
import {
@ -518,7 +518,7 @@ export class Editor {
}
),
pasteLinkExtension,
pasteAttachmentExtension(this.space),
attachmentExtension(this),
closeBrackets(),
],
});

View File

@ -1,6 +1,9 @@
import { EditorView, ViewPlugin, ViewUpdate } from "@codemirror/view";
import { safeRun } from "@plugos/plugos/util";
import { Space } from "@silverbulletmd/common/spaces/space";
import { maximumAttachmentSize } from "@silverbulletmd/common/types";
import { createImportSpecifier } from "typescript";
import { Editor } from "./editor";
const urlRegexp =
/^https?:\/\/[-a-zA-Z0-9@:%._\+~#=]{1,256}([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
@ -45,50 +48,73 @@ export const pasteLinkExtension = ViewPlugin.fromClass(
}
);
export function pasteAttachmentExtension(space: Space) {
export function attachmentExtension(editor: Editor) {
return EditorView.domEventHandlers({
paste: (event: ClipboardEvent, editor) => {
dragover: (event) => {
event.preventDefault();
},
drop: (event: DragEvent) => {
// TODO: This doesn't take into account the target cursor position,
// it just drops the attachment wherever the cursor was last.
if (event.dataTransfer) {
let payload = [...event.dataTransfer.items];
safeRun(async () => {
await processFileTransfer(payload);
});
}
},
paste: (event: ClipboardEvent) => {
let payload = [...event.clipboardData!.items];
if (!payload.length || payload.length === 0) {
return false;
}
let file = payload.find((item) => item.kind === "file");
if (!file) {
return false;
}
const fileType = file.type;
Promise.resolve()
.then(async () => {
let data = await file!.getAsFile()?.arrayBuffer();
let ext = fileType.split("/")[1];
let fileName = new Date()
.toISOString()
.split(".")[0]
.replace("T", "_")
.replaceAll(":", "-");
let finalFileName = prompt(
"File name for pasted attachment",
`${fileName}.${ext}`
);
if (!finalFileName) {
return;
}
await space.writeAttachment(finalFileName, data!);
let attachmentMarkdown = `[${finalFileName}](attachment/${finalFileName})`;
if (fileType.startsWith("image/")) {
attachmentMarkdown = `![](attachment/${finalFileName})`;
}
editor.dispatch({
changes: [
{
insert: attachmentMarkdown,
from: editor.state.selection.main.from,
},
],
});
})
.catch(console.error);
safeRun(async () => {
await processFileTransfer(payload);
});
},
});
async function processFileTransfer(payload: DataTransferItem[]) {
if (!payload.length || payload.length === 0) {
return false;
}
let file = payload.find((item) => item.kind === "file");
if (!file) {
return false;
}
const fileType = file.type;
let data = await file!.getAsFile()?.arrayBuffer();
if (data!.byteLength > maximumAttachmentSize) {
editor.flashNotification(
`Attachment is too large, maximum is ${
maximumAttachmentSize / 1024 / 1024
}MB`,
"error"
);
return;
}
let ext = fileType.split("/")[1];
let fileName = new Date()
.toISOString()
.split(".")[0]
.replace("T", "_")
.replaceAll(":", "-");
let finalFileName = prompt(
"File name for pasted attachment",
`${fileName}.${ext}`
);
if (!finalFileName) {
return;
}
await editor.space.writeAttachment(finalFileName, data!);
let attachmentMarkdown = `[${finalFileName}](attachment/${finalFileName})`;
if (fileType.startsWith("image/")) {
attachmentMarkdown = `![](attachment/${finalFileName})`;
}
editor.editorView!.dispatch({
changes: [
{
insert: attachmentMarkdown,
from: editor.editorView!.state.selection.main.from,
},
],
});
}
}

View File

@ -1,4 +1,4 @@
import { AppCommand, CommandDef } from "./hooks/command";
import { AppCommand } from "./hooks/command";
import { FilterOption, PageMeta } from "@silverbulletmd/common/types";
export type Notification = {

View File

@ -1,7 +1,9 @@
An attempt at documenting of the changes/new features introduced in each (pre) release.
An attempt at documenting of the changes/new features introduced in each
---
## 0.0.33
* **Attachments**: you can now copy & paste or drag & drop files (images, PDF, whatever you like) into a page and it will be uploaded and appropriately linked from your page. Attachment size is currently limited to 100mb.
* Changed full-text search page prefix from `@search/` to `🔍` for the {[Search Space]} command.
* `page`, `plug` and `attachment` are now _reserved page names_, you cannot name your pages these (you will get an error when explicitly navigating to them).