2020-02-18 08:57:00 +01:00
|
|
|
import { Node } from "tiptap";
|
|
|
|
import { UPLOAD_PICTURE } from "@/graphql/upload";
|
|
|
|
import apolloProvider from "@/vue-apollo";
|
|
|
|
import ApolloClient from "apollo-client";
|
|
|
|
import { NormalizedCacheObject } from "apollo-cache-inmemory";
|
|
|
|
import { NodeType, NodeSpec } from "prosemirror-model";
|
|
|
|
import { EditorState, Plugin, TextSelection } from "prosemirror-state";
|
|
|
|
import { DispatchFn } from "tiptap-commands";
|
|
|
|
import { EditorView } from "prosemirror-view";
|
2019-05-29 17:47:52 +02:00
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
/* eslint-disable class-methods-use-this */
|
2019-05-29 17:47:52 +02:00
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
export default class Image extends Node {
|
2019-05-29 17:47:52 +02:00
|
|
|
get name() {
|
2020-02-18 08:57:00 +01:00
|
|
|
return "image";
|
2019-05-29 17:47:52 +02:00
|
|
|
}
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
get schema(): NodeSpec {
|
2019-05-29 17:47:52 +02:00
|
|
|
return {
|
|
|
|
inline: true,
|
|
|
|
attrs: {
|
|
|
|
src: {},
|
|
|
|
alt: {
|
|
|
|
default: null,
|
|
|
|
},
|
|
|
|
title: {
|
|
|
|
default: null,
|
|
|
|
},
|
|
|
|
},
|
2020-02-18 08:57:00 +01:00
|
|
|
group: "inline",
|
2019-05-29 17:47:52 +02:00
|
|
|
draggable: true,
|
|
|
|
parseDOM: [
|
|
|
|
{
|
2020-02-18 08:57:00 +01:00
|
|
|
tag: "img[src]",
|
|
|
|
getAttrs: (dom: any) => ({
|
|
|
|
src: dom.getAttribute("src"),
|
|
|
|
title: dom.getAttribute("title"),
|
|
|
|
alt: dom.getAttribute("alt"),
|
2019-05-29 17:47:52 +02:00
|
|
|
}),
|
|
|
|
},
|
|
|
|
],
|
2020-02-18 08:57:00 +01:00
|
|
|
toDOM: (node: any) => ["img", node.attrs],
|
2019-05-29 17:47:52 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
commands({ type }: { type: NodeType }): any {
|
|
|
|
return (attrs: { [key: string]: string }) => (state: EditorState, dispatch: DispatchFn) => {
|
|
|
|
const { selection }: { selection: TextSelection } = state;
|
2019-05-29 17:47:52 +02:00
|
|
|
const position = selection.$cursor ? selection.$cursor.pos : selection.$to.pos;
|
|
|
|
const node = type.create(attrs);
|
|
|
|
const transaction = state.tr.insert(position, node);
|
|
|
|
dispatch(transaction);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
get plugins() {
|
|
|
|
return [
|
|
|
|
new Plugin({
|
|
|
|
props: {
|
|
|
|
handleDOMEvents: {
|
2020-02-18 08:57:00 +01:00
|
|
|
drop(view: EditorView<any>, event: Event) {
|
|
|
|
const realEvent = event as DragEvent;
|
|
|
|
if (
|
|
|
|
!(
|
|
|
|
realEvent.dataTransfer &&
|
|
|
|
realEvent.dataTransfer.files &&
|
|
|
|
realEvent.dataTransfer.files.length
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
return false;
|
2019-05-29 17:47:52 +02:00
|
|
|
}
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
const images = Array.from(realEvent.dataTransfer.files).filter((file: any) =>
|
|
|
|
/image/i.test(file.type)
|
|
|
|
);
|
2019-05-29 17:47:52 +02:00
|
|
|
|
|
|
|
if (images.length === 0) {
|
2020-02-18 08:57:00 +01:00
|
|
|
return false;
|
2019-05-29 17:47:52 +02:00
|
|
|
}
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
realEvent.preventDefault();
|
2019-05-29 17:47:52 +02:00
|
|
|
|
|
|
|
const { schema } = view.state;
|
2020-02-18 08:57:00 +01:00
|
|
|
const coordinates = view.posAtCoords({
|
|
|
|
left: realEvent.clientX,
|
|
|
|
top: realEvent.clientY,
|
|
|
|
});
|
|
|
|
if (!coordinates) return false;
|
|
|
|
const client = apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
|
|
|
|
const editorElem = document.getElementById("tiptab-editor");
|
2019-05-31 17:58:03 +02:00
|
|
|
const actorId = editorElem && editorElem.dataset.actorId;
|
2019-05-29 17:47:52 +02:00
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
images.forEach(async (image) => {
|
2019-05-29 17:47:52 +02:00
|
|
|
const { data } = await client.mutate({
|
|
|
|
mutation: UPLOAD_PICTURE,
|
|
|
|
variables: {
|
2019-05-31 17:58:03 +02:00
|
|
|
actorId,
|
2019-05-29 17:47:52 +02:00
|
|
|
file: image,
|
|
|
|
name: image.name,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const node = schema.nodes.image.create({ src: data.uploadPicture.url });
|
|
|
|
const transaction = view.state.tr.insert(coordinates.pos, node);
|
|
|
|
view.dispatch(transaction);
|
2020-02-18 08:57:00 +01:00
|
|
|
});
|
|
|
|
return true;
|
2019-05-29 17:47:52 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|