feat: update image by paste in editor

This commit is contained in:
boojack 2021-12-16 22:39:45 +08:00
parent cc2af0e449
commit ee3c753c99
4 changed files with 82 additions and 3 deletions
web/src
components/Editor
helpers
services
types

@ -1,6 +1,8 @@
import { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useRef } from "react";
import TinyUndo from "tiny-undo";
import toastHelper from "../Toast";
import appContext from "../../stores/appContext";
import resourceService from "../../services/resourceService";
import { storage } from "../../helpers/storage";
import useRefresh from "../../hooks/useRefresh";
import Only from "../common/OnlyWhen";
@ -46,10 +48,50 @@ const Editor = forwardRef((props: Props, ref: React.ForwardedRef<EditorRefAction
const refresh = useRefresh();
useEffect(() => {
if (initialContent && editorRef.current) {
if (!editorRef.current) {
return;
}
if (initialContent) {
editorRef.current.value = initialContent;
refresh();
}
const handlePasteEvent = async (event: ClipboardEvent) => {
if (event.clipboardData && event.clipboardData.files.length > 0) {
const file = event.clipboardData.files[0];
const { type } = file;
if (!type.startsWith("image")) {
return;
}
event.preventDefault();
try {
if (!editorRef.current) {
return;
}
const resource = await resourceService.upload(file);
const url = `https://memos.justsven.top/r/${resource.id}/${resource.filename}`;
const prevValue = editorRef.current.value;
editorRef.current.value =
prevValue.slice(0, editorRef.current.selectionStart) + url + prevValue.slice(editorRef.current.selectionStart);
handleContentChangeCallback(editorRef.current.value);
refresh();
} catch (error: any) {
toastHelper.error(error);
}
}
};
editorRef.current.addEventListener("paste", handlePasteEvent);
return () => {
editorRef.current?.removeEventListener("paste", handlePasteEvent);
};
}, []);
useEffect(() => {
@ -102,7 +144,8 @@ const Editor = forwardRef((props: Props, ref: React.ForwardedRef<EditorRefAction
}
const prevValue = editorRef.current.value;
editorRef.current.value = prevValue + rawText;
editorRef.current.value =
prevValue.slice(0, editorRef.current.selectionStart) + rawText + prevValue.slice(editorRef.current.selectionStart);
handleContentChangeCallback(editorRef.current.value);
refresh();
},

@ -199,7 +199,7 @@ namespace api {
}
export function uploadFile(formData: FormData) {
return request({
return request<Model.Resource>({
method: "PUT",
url: "/api/resource/",
data: formData,

@ -0,0 +1,28 @@
import api from "../helpers/api";
class ResourceService {
/**
* Upload resource file to server,
* @param file file
* @returns resource: id, filename
*/
public async upload(file: File) {
const { name: filename, size } = file;
if (size > 5 << 20) {
return Promise.reject("超过最大文件大小 5Mb");
}
const formData = new FormData();
formData.append("file", file, filename);
const { data } = await api.uploadFile(formData);
return data;
}
}
const resourceService = new ResourceService();
export default resourceService;

@ -20,4 +20,12 @@ declare namespace Model {
querystring: string;
pinnedAt: string;
}
interface Resource {
id: string;
filename: string;
type: string;
size: string;
createdAt: string;
}
}