import { Extension } from '@tiptap/core'; import { activeTaskId, uploadTaskAttachment, activeNoteId, uploadNoteAttachment } from "@/store"; import { convertImageToWebpFile } from "@/lib/utils"; import { toast } from "solid-sonner"; declare module '@tiptap/core' { interface Commands { imageUpload: { uploadImage: () => ReturnType; }; } } export const ImageUpload = Extension.create({ name: 'imageUpload', addCommands() { return { uploadImage: () => ({ editor }) => { const taskId = activeTaskId(); const noteId = activeNoteId(); if (!taskId && !noteId) { toast.error("Cannot upload image outside of a task or note."); return false; } const input = document.createElement("input"); input.type = "file"; input.accept = "image/*,.heic,.heif"; input.onchange = async () => { if (input.files?.length) { const originalFile = input.files[0]; toast.promise( (async () => { const webpFile = await convertImageToWebpFile(originalFile); if (taskId) { return uploadTaskAttachment(taskId, webpFile); } else { return uploadNoteAttachment(noteId!, webpFile); } })(), { loading: "Processing & uploading image...", success: ({ url, filename }) => { // Insert image editor.chain() .focus() // @ts-ignore .setImage({ src: url, filename }) .run(); // Manually force a new paragraph at the end so the user can keep typing editor.chain() .focus('end') .insertContent('

') .run(); return "Image uploaded."; }, error: "Failed to upload image." } ); } }; input.click(); return true; }, }; }, });