Files
outline/shared/editor/commands/createAndInsertLink.ts
Tom Moor 631d600920 feat: File attachments (#3031)
* stash

* refactor, working in non-collab + collab editor

* attachment styling

* Avoid crypto require in browser

* AttachmentIcon, handling unknown types

* Do not allow attachment creation for file sizes over limit

* Allow image as file attachment

* Upload placeholder styling

* lint

* Refactor: Do not use placeholder for file attachmentuploads

* Add loading spinner

* fix: Extra paragraphs around attachments on insert

* Bump editor

* fix build error

* Remove attachment placeholder when upload fails

* Remove unused styles

* fix: Attachments on shared pages

* Merge fixes
2022-03-06 13:58:58 -08:00

90 lines
2.0 KiB
TypeScript

import { Node } from "prosemirror-model";
import { EditorView } from "prosemirror-view";
import { ToastType } from "../types";
function findPlaceholderLink(doc: Node, href: string) {
let result: { pos: number; node: Node } | undefined;
function findLinks(node: Node, pos = 0) {
// get text nodes
if (node.type.name === "text") {
// get marks for text nodes
node.marks.forEach((mark) => {
// any of the marks links?
if (mark.type.name === "link") {
// any of the links to other docs?
if (mark.attrs.href === href) {
result = { node, pos };
}
}
});
}
if (!node.content.size) {
return;
}
node.descendants(findLinks);
}
findLinks(doc);
return result;
}
const createAndInsertLink = async function (
view: EditorView,
title: string,
href: string,
options: {
dictionary: any;
onCreateLink: (title: string) => Promise<string>;
onShowToast: (message: string, code: string) => void;
}
) {
const { dispatch, state } = view;
const { onCreateLink, onShowToast } = options;
try {
const url = await onCreateLink(title);
const result = findPlaceholderLink(view.state.doc, href);
if (!result) {
return;
}
dispatch(
view.state.tr
.removeMark(
result.pos,
result.pos + result.node.nodeSize,
state.schema.marks.link
)
.addMark(
result.pos,
result.pos + result.node.nodeSize,
state.schema.marks.link.create({ href: url })
)
);
} catch (err) {
const result = findPlaceholderLink(view.state.doc, href);
if (!result) {
return;
}
dispatch(
view.state.tr.removeMark(
result.pos,
result.pos + result.node.nodeSize,
state.schema.marks.link
)
);
// let the user know
if (onShowToast) {
onShowToast(options.dictionary.createLinkError, ToastType.Error);
}
}
};
export default createAndInsertLink;