Files
TasGrid/src/lib/extensions/media-upload.ts
T

80 lines
3.4 KiB
TypeScript

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<ReturnType> {
mediaUpload: {
uploadMedia: () => ReturnType;
};
}
}
export const MediaUpload = Extension.create({
name: 'mediaUpload',
addCommands() {
return {
uploadMedia: () => ({ editor }) => {
const taskId = activeTaskId();
const noteId = activeNoteId();
if (!taskId && !noteId) {
toast.error("Cannot upload media outside of a task or note.");
return false;
}
const input = document.createElement("input");
input.type = "file";
input.onchange = async () => {
if (input.files?.length) {
const originalFile = input.files[0];
const isImage = originalFile.type.startsWith('image/');
const isVideo = originalFile.type.startsWith('video/');
toast.promise(
(async () => {
let fileToUpload = originalFile;
if (isImage && !originalFile.type.includes('svg') && !originalFile.type.includes('gif')) {
fileToUpload = await convertImageToWebpFile(originalFile);
}
if (taskId) {
return uploadTaskAttachment(taskId, fileToUpload);
} else {
return uploadNoteAttachment(noteId!, fileToUpload);
}
})(),
{
loading: "Processing & uploading media...",
success: ({ url, filename }) => {
if (isImage) {
// @ts-ignore
editor.chain().focus().setImage({ src: url, filename }).run();
} else if (isVideo) {
editor.chain().focus().setVideo({ src: url, filename }).run();
} else {
editor.chain().focus().insertFileAttachment({ src: url, filename, filesize: originalFile.size.toString() }).run();
}
// Manually force a new paragraph at the end so the user can keep typing
editor.chain()
.focus('end')
.insertContent('<p></p>')
.run();
return "Media uploaded.";
},
error: "Failed to upload media."
}
);
}
};
input.click();
return true;
},
};
},
});