mirror of
				https://github.com/usememos/memos.git
				synced 2025-06-05 22:09:59 +02:00 
			
		
		
		
	feat: upload files by dropping (#292)
This commit is contained in:
		| @@ -13,6 +13,7 @@ import MemoContent from "./MemoContent"; | |||||||
| import MemoResources from "./MemoResources"; | import MemoResources from "./MemoResources"; | ||||||
| import showMemoCardDialog from "./MemoCardDialog"; | import showMemoCardDialog from "./MemoCardDialog"; | ||||||
| import showShareMemoImageDialog from "./ShareMemoImageDialog"; | import showShareMemoImageDialog from "./ShareMemoImageDialog"; | ||||||
|  | import showPreviewImageDialog from "./PreviewImageDialog"; | ||||||
| import "../less/memo.less"; | import "../less/memo.less"; | ||||||
|  |  | ||||||
| dayjs.extend(relativeTime); | dayjs.extend(relativeTime); | ||||||
| @@ -159,6 +160,11 @@ const Memo: React.FC<Props> = (props: Props) => { | |||||||
|           }); |           }); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |     } else if (targetEl.tagName === "IMG") { | ||||||
|  |       const imgUrl = targetEl.getAttribute("src"); | ||||||
|  |       if (imgUrl) { | ||||||
|  |         showPreviewImageDialog(imgUrl); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -76,6 +76,36 @@ const MemoEditor: React.FC = () => { | |||||||
|     prevGlobalStateRef.current = editorState; |     prevGlobalStateRef.current = editorState; | ||||||
|   }, [state, editorState.editMemoId]); |   }, [state, editorState.editMemoId]); | ||||||
|  |  | ||||||
|  |   const handleKeyDown = (event: React.KeyboardEvent) => { | ||||||
|  |     if (event.key === "Escape") { | ||||||
|  |       if (state.fullscreen) { | ||||||
|  |         handleFullscreenBtnClick(); | ||||||
|  |       } | ||||||
|  |     } else if (event.key === "Enter" && (event.ctrlKey || event.metaKey)) { | ||||||
|  |       handleSaveBtnClick(); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   const handleDropEvent = async (event: React.DragEvent) => { | ||||||
|  |     if (event.dataTransfer && event.dataTransfer.files.length > 0) { | ||||||
|  |       event.preventDefault(); | ||||||
|  |       const resourceList: Resource[] = []; | ||||||
|  |       for (const file of event.dataTransfer.files) { | ||||||
|  |         const resource = await handleUploadResource(file); | ||||||
|  |         if (resource) { | ||||||
|  |           resourceList.push(resource); | ||||||
|  |           if (editorState.editMemoId) { | ||||||
|  |             await upsertMemoResource(editorState.editMemoId, resource.id); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       setState({ | ||||||
|  |         ...state, | ||||||
|  |         resourceList: [...state.resourceList, ...resourceList], | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
|   const handlePasteEvent = async (event: React.ClipboardEvent) => { |   const handlePasteEvent = async (event: React.ClipboardEvent) => { | ||||||
|     if (event.clipboardData && event.clipboardData.files.length > 0) { |     if (event.clipboardData && event.clipboardData.files.length > 0) { | ||||||
|       event.preventDefault(); |       event.preventDefault(); | ||||||
| @@ -239,12 +269,6 @@ const MemoEditor: React.FC = () => { | |||||||
|     }); |     }); | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   const handleKeyDown = (event: React.KeyboardEvent) => { |  | ||||||
|     if (event.key === "Escape") { |  | ||||||
|       state.fullscreen && handleFullscreenBtnClick(); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   const handleTagSeletorClick = useCallback((event: React.MouseEvent) => { |   const handleTagSeletorClick = useCallback((event: React.MouseEvent) => { | ||||||
|     if (tagSeletorRef.current !== event.target && tagSeletorRef.current?.contains(event.target as Node)) { |     if (tagSeletorRef.current !== event.target && tagSeletorRef.current?.contains(event.target as Node)) { | ||||||
|       editorRef.current?.insertText(`#${(event.target as HTMLElement).textContent} ` ?? ""); |       editorRef.current?.insertText(`#${(event.target as HTMLElement).textContent} ` ?? ""); | ||||||
| @@ -296,6 +320,7 @@ const MemoEditor: React.FC = () => { | |||||||
|     <div |     <div | ||||||
|       className={`memo-editor-container ${mobileEditorStyle} ${isEditing ? "edit-ing" : ""} ${state.fullscreen ? "fullscreen" : ""}`} |       className={`memo-editor-container ${mobileEditorStyle} ${isEditing ? "edit-ing" : ""} ${state.fullscreen ? "fullscreen" : ""}`} | ||||||
|       onKeyDown={handleKeyDown} |       onKeyDown={handleKeyDown} | ||||||
|  |       onDrop={handleDropEvent} | ||||||
|     > |     > | ||||||
|       <div className={`tip-container ${isEditing ? "" : "!hidden"}`}> |       <div className={`tip-container ${isEditing ? "" : "!hidden"}`}> | ||||||
|         <span className="tip-text">{t("editor.editing")}</span> |         <span className="tip-text">{t("editor.editing")}</span> | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { escape } from "lodash-es"; | import { escape } from "lodash-es"; | ||||||
|  |  | ||||||
| export const TAG_REG = /[^\s]?#([^\s#]+?) /; | export const TAG_REG = /#([^\s#]+?) /; | ||||||
|  |  | ||||||
| const renderer = (rawStr: string): string => { | const renderer = (rawStr: string): string => { | ||||||
|   const matchResult = rawStr.match(TAG_REG); |   const matchResult = rawStr.match(TAG_REG); | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|       .hide-scroll-bar(); |       .hide-scroll-bar(); | ||||||
|  |  | ||||||
|       > img { |       > img { | ||||||
|         @apply w-auto max-h-40 rounded-lg; |         @apply w-auto max-h-40 rounded; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| .mask { | .mask { | ||||||
|   @apply fixed top-0 right-0 w-screen h-screen bg-transparent transition-all duration-300 z-0; |   @apply fixed top-0 right-0 w-screen h-screen bg-transparent transition-all duration-300 z-0 sm:hidden; | ||||||
|  |  | ||||||
|   &.show { |   &.show { | ||||||
|     @apply z-20 bg-black opacity-60; |     @apply z-20 bg-black opacity-60; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user