mobilizon/js/src/components/Editor/Image.ts

99 lines
2.8 KiB
TypeScript
Raw Normal View History

import { UPLOAD_MEDIA } from "@/graphql/upload";
import apolloProvider from "@/vue-apollo";
import { ApolloClient } from "@apollo/client/core/ApolloClient";
import { Plugin } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import Image from "@tiptap/extension-image";
import { NormalizedCacheObject } from "@apollo/client/cache";
/* eslint-disable class-methods-use-this */
const CustomImage = Image.extend({
name: "image",
addAttributes() {
return {
src: {
default: null,
},
alt: {
default: null,
},
title: {
default: null,
},
"data-media-id": {
default: null,
},
};
},
addProseMirrorPlugins() {
return [
new Plugin({
props: {
handleDOMEvents: {
drop(view: EditorView<any>, event: Event) {
const realEvent = event as DragEvent;
if (
!(
realEvent.dataTransfer &&
realEvent.dataTransfer.files &&
realEvent.dataTransfer.files.length
)
) {
return false;
}
const images = Array.from(realEvent.dataTransfer.files).filter(
(file: any) =>
/image/i.test(file.type) && !/svg/i.test(file.type)
);
if (images.length === 0) {
return false;
}
realEvent.preventDefault();
const { schema } = view.state;
const coordinates = view.posAtCoords({
left: realEvent.clientX,
top: realEvent.clientY,
});
if (!coordinates) return false;
const client =
apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
try {
images.forEach(async (image) => {
const { data } = await client.mutate({
mutation: UPLOAD_MEDIA,
variables: {
file: image,
name: image.name,
},
});
const node = schema.nodes.image.create({
src: data.uploadMedia.url,
"data-media-id": data.uploadMedia.id,
});
const transaction = view.state.tr.insert(
coordinates.pos,
node
);
view.dispatch(transaction);
});
return true;
} catch (error) {
console.error(error);
return false;
}
},
},
},
}),
];
},
});
export default CustomImage;