import { open } from '@tauri-apps/api/dialog'; import { listen } from '@tauri-apps/api/event'; import { Body, fetch } from '@tauri-apps/api/http'; import { useCallback, useEffect, useState } from 'react'; import { Transforms } from 'slate'; import { useSlateStatic } from 'slate-react'; import { PlusCircleIcon } from '@shared/icons'; import { createBlobFromFile } from '@utils/createBlobFromFile'; export function ImageUploader() { const editor = useSlateStatic(); const [loading, setLoading] = useState(false); const insertImage = (editor, url) => { const image = { type: 'image', url, children: [{ text: url }] }; Transforms.insertNodes(editor, image); }; const uploadToVoidCat = useCallback( async (filepath) => { const filename = filepath.split('/').pop(); const file = await createBlobFromFile(filepath); const buf = await file.arrayBuffer(); try { const res: { data: { file: { id: string } } } = await fetch( 'https://void.cat/upload?cli=false', { method: 'POST', timeout: 5, headers: { accept: '*/*', 'Content-Type': 'application/octet-stream', 'V-Filename': filename, 'V-Description': 'Uploaded from https://lume.nu', 'V-Strip-Metadata': 'true', }, body: Body.bytes(buf), } ); const image = `https://void.cat/d/${res.data.file.id}.webp`; // update parent state insertImage(editor, image); // reset loading state setLoading(false); } catch (error) { // reset loading state setLoading(false); // handle error if (error instanceof SyntaxError) { // Unexpected token < in JSON console.log('There was a SyntaxError', error); } else { console.log('There was an error', error); } } }, [editor] ); const openFileDialog = async () => { const selected: any = await open({ multiple: false, filters: [ { name: 'Image', extensions: ['png', 'jpeg', 'jpg', 'gif'], }, ], }); if (Array.isArray(selected)) { // user selected multiple files } else if (selected === null) { // user cancelled the selection } else { setLoading(true); // upload file uploadToVoidCat(selected); } }; useEffect(() => { async function initFileDrop() { const unlisten = await listen('tauri://file-drop', (event) => { // set loading state setLoading(true); // upload file uploadToVoidCat(event.payload[0]); }); return () => { unlisten(); }; } initFileDrop(); }, [uploadToVoidCat]); return ( ); }