From a997e1d10de639dc44fedfefea738c68355c5cb0 Mon Sep 17 00:00:00 2001 From: boojack Date: Sun, 12 Feb 2023 16:34:42 +0800 Subject: [PATCH] chore: simplify memo editor component (#1079) --- web/src/components/CreateTagDialog.tsx | 2 +- web/src/components/MemoEditor.tsx | 143 +++++++------------------ web/src/components/MemoResource.tsx | 4 +- web/src/helpers/storage.ts | 2 - web/src/less/memo-editor.less | 8 +- 5 files changed, 45 insertions(+), 114 deletions(-) diff --git a/web/src/components/CreateTagDialog.tsx b/web/src/components/CreateTagDialog.tsx index 04ddd4dd..911ae698 100644 --- a/web/src/components/CreateTagDialog.tsx +++ b/web/src/components/CreateTagDialog.tsx @@ -31,7 +31,7 @@ const CreateTagDialog: React.FC = (props: Props) => { getTagSuggestionList().then(({ data }) => { setSuggestTagNameList(data.data.filter((tag) => validateTagName(tag))); }); - }, []); + }, [tagNameList]); const handleTagNameInputKeyDown = (event: React.KeyboardEvent) => { if (event.key === "Enter") { diff --git a/web/src/components/MemoEditor.tsx b/web/src/components/MemoEditor.tsx index 3e00847e..7378b0f7 100644 --- a/web/src/components/MemoEditor.tsx +++ b/web/src/components/MemoEditor.tsx @@ -17,7 +17,6 @@ import "../less/memo-editor.less"; const listItemSymbolList = ["- [ ] ", "- [x] ", "- [X] ", "* ", "- "]; const emptyOlReg = /^(\d+)\. $/; -const pairSymbols = ["[]", "()", '""', "''", "{}", "``", "”“", "‘‘", "【】", "()", "《》"]; const getEditorContentCache = (): string => { return storage.get(["editorContentCache"]).editorContentCache ?? ""; @@ -29,12 +28,6 @@ const setEditorContentCache = (content: string) => { }); }; -const setEditingMemoVisibilityCache = (visibility: Visibility) => { - storage.set({ - editingMemoVisibilityCache: visibility, - }); -}; - interface State { fullscreen: boolean; isUploadingResource: boolean; @@ -51,8 +44,8 @@ const MemoEditor = () => { const resourceStore = useResourceStore(); const [state, setState] = useState({ - isUploadingResource: false, fullscreen: false, + isUploadingResource: false, isRequesting: false, }); const [allowSave, setAllowSave] = useState(false); @@ -62,7 +55,6 @@ const MemoEditor = () => { const tagSelectorRef = useRef(null); const user = userStore.state.user as User; const setting = user.setting; - const localSetting = user.localSetting; const tags = tagStore.state.tags; const memoVisibilityOptionSelectorItems = VISIBILITY_SELECTOR_ITEMS.map((item) => { return { @@ -72,12 +64,9 @@ const MemoEditor = () => { }); useEffect(() => { - const { editingMemoIdCache, editingMemoVisibilityCache } = storage.get(["editingMemoIdCache", "editingMemoVisibilityCache"]); + const { editingMemoIdCache } = storage.get(["editingMemoIdCache"]); if (editingMemoIdCache) { editorStore.setEditMemoWithId(editingMemoIdCache); - } - if (editingMemoVisibilityCache) { - editorStore.setMemoVisibility(editingMemoVisibilityCache as "PUBLIC" | "PROTECTED" | "PRIVATE"); } else { editorStore.setMemoVisibility(setting.memoVisibility); } @@ -109,8 +98,7 @@ const MemoEditor = () => { } const isMetaKey = event.ctrlKey || event.metaKey; - const isShiftKey = event.shiftKey; - if (!isShiftKey && isMetaKey) { + if (isMetaKey) { if (event.key === "Enter") { handleSaveBtnClick(); return; @@ -141,8 +129,7 @@ const MemoEditor = () => { } } } - - if (!isShiftKey && event.key === "Enter") { + if (event.key === "Enter") { const cursorPosition = editorRef.current.getCursorPosition(); const contentBeforeCursor = editorRef.current.getContent().slice(0, cursorPosition); const rowValue = last(contentBeforeCursor.split("\n")); @@ -179,7 +166,7 @@ const MemoEditor = () => { } return; } - if (!isShiftKey && event.key === "Escape") { + if (event.key === "Escape") { if (state.fullscreen) { handleFullscreenBtnClick(); } @@ -190,57 +177,37 @@ const MemoEditor = () => { const tabSpace = " ".repeat(TAB_SPACE_WIDTH); const cursorPosition = editorRef.current.getCursorPosition(); const selectedContent = editorRef.current.getSelectedContent(); - if (isShiftKey) { - const beforeContent = editorRef.current.getContent().slice(0, cursorPosition); - for (let i = beforeContent.length - 1; i >= 0; i--) { - if (beforeContent[i] !== "\n") { - continue; - } - const rowStart = i + 1; - const isTabSpace = beforeContent.substring(rowStart, i + TAB_SPACE_WIDTH + 1) === tabSpace; - const isSpace = beforeContent.substring(rowStart, i + 2) === " "; - if (!isTabSpace && !isSpace) { - break; - } - const removeLength = isTabSpace ? TAB_SPACE_WIDTH : 1; - editorRef.current.removeText(rowStart, removeLength); - const startPos = cursorPosition - removeLength; - let endPos = startPos; - if (selectedContent) { - endPos += selectedContent.length; - } - editorRef.current.setCursorPosition(startPos, endPos); - } - return; - } else { - editorRef.current.insertText(tabSpace); - if (selectedContent) { - editorRef.current.setCursorPosition(cursorPosition + TAB_SPACE_WIDTH); - } - return; + editorRef.current.insertText(tabSpace); + if (selectedContent) { + editorRef.current.setCursorPosition(cursorPosition + TAB_SPACE_WIDTH); } + return; } + }; - if (localSetting.enablePowerfulEditor) { - for (const symbol of pairSymbols) { - if (event.key === symbol[0]) { - event.preventDefault(); - editorRef.current.insertText("", symbol[0], symbol[1]); - return; - } - } - if (event.key === "Backspace") { - const cursor = editorRef.current.getCursorPosition(); - const content = editorRef.current.getContent(); - const deleteChar = content?.slice(cursor - 1, cursor); - const nextChar = content?.slice(cursor, cursor + 1); - if (pairSymbols.includes(`${deleteChar}${nextChar}`)) { - event.preventDefault(); - editorRef.current.removeText(cursor - 1, 2); - } - return; - } + const handleUploadResource = async (file: File) => { + setState((state) => { + return { + ...state, + isUploadingResource: true, + }; + }); + + let resource = undefined; + try { + resource = await resourceStore.createResourceWithBlob(file); + } catch (error: any) { + console.error(error); + toastHelper.error(error.response.data.message); } + + setState((state) => { + return { + ...state, + isUploadingResource: false, + }; + }); + return resource; }; const uploadMultiFiles = async (files: FileList) => { @@ -274,32 +241,6 @@ const MemoEditor = () => { } }; - const handleUploadResource = async (file: File) => { - setState((state) => { - return { - ...state, - isUploadingResource: true, - }; - }); - - let resource = undefined; - - try { - resource = await resourceStore.createResourceWithBlob(file); - } catch (error: any) { - console.error(error); - toastHelper.error(error.response.data.message); - } - - setState((state) => { - return { - ...state, - isUploadingResource: false, - }; - }); - return resource; - }; - const scrollToEditingMemo = useCallback(() => { if (editorState.editMemoId) { const memoElements = document.getElementsByClassName(`memos-${editorState.editMemoId}`); @@ -369,9 +310,7 @@ const MemoEditor = () => { }); editorStore.clearResourceList(); setEditorContentCache(""); - storage.remove(["editingMemoVisibilityCache"]); editorRef.current?.setContent(""); - scrollToEditingMemo(); }; @@ -381,10 +320,8 @@ const MemoEditor = () => { editorStore.clearResourceList(); editorRef.current?.setContent(""); setEditorContentCache(""); - storage.remove(["editingMemoVisibilityCache"]); + scrollToEditingMemo(); } - - scrollToEditingMemo(); }; const handleContentChange = (content: string) => { @@ -439,11 +376,8 @@ const MemoEditor = () => { }); }; - const handleTagSelectorClick = useCallback((event: React.MouseEvent) => { - if (tagSelectorRef.current !== event.target && tagSelectorRef.current?.contains(event.target as Node)) { - editorRef.current?.insertText(`#${(event.target as HTMLElement).textContent} ` ?? ""); - editorRef.current?.scrollToCursor(); - } + const handleTagSelectorClick = useCallback((tag: string) => { + editorRef.current?.insertText(`#${tag} `); }, []); const handleDeleteResource = async (resourceId: ResourceId) => { @@ -456,7 +390,6 @@ const MemoEditor = () => { const handleMemoVisibilityOptionChanged = async (value: string) => { const visibilityValue = value as Visibility; editorStore.setMemoVisibility(visibilityValue); - setEditingMemoVisibilityCache(visibilityValue); }; const handleEditorFocus = () => { @@ -495,12 +428,12 @@ const MemoEditor = () => {
-
+
{tags.length > 0 ? ( tags.map((tag) => { return ( - - {tag} + handleTagSelectorClick(tag)} key={tag}> + #{tag} ); }) diff --git a/web/src/components/MemoResource.tsx b/web/src/components/MemoResource.tsx index ca7e0d2d..c316ccc5 100644 --- a/web/src/components/MemoResource.tsx +++ b/web/src/components/MemoResource.tsx @@ -16,7 +16,7 @@ const MemoResource: React.FC = (props: Props) => { return ( <> -
+
{resource.type.startsWith("audio") ? ( <> @@ -24,7 +24,7 @@ const MemoResource: React.FC = (props: Props) => { ) : ( <> - + {resource.filename} diff --git a/web/src/helpers/storage.ts b/web/src/helpers/storage.ts index bf615d14..b8713c60 100644 --- a/web/src/helpers/storage.ts +++ b/web/src/helpers/storage.ts @@ -6,8 +6,6 @@ interface StorageData { editorContentCache: string; // Editing memo id cache editingMemoIdCache: MemoId; - // Editing memo visibility - editingMemoVisibilityCache: Visibility; // locale locale: Locale; // appearance diff --git a/web/src/less/memo-editor.less b/web/src/less/memo-editor.less index d0adb9cc..c700337f 100644 --- a/web/src/less/memo-editor.less +++ b/web/src/less/memo-editor.less @@ -37,7 +37,7 @@ @apply flex flex-row justify-start items-center; > .action-btn { - @apply flex flex-row justify-center items-center p-1 w-auto h-auto mr-1 select-none rounded cursor-pointer dark:text-gray-200 opacity-60 hover:opacity-90 hover:bg-gray-300 dark:hover:bg-zinc-800 hover:shadow; + @apply flex flex-row justify-center items-center p-1 w-auto h-auto mr-1 select-none rounded cursor-pointer text-gray-600 dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-zinc-800 hover:shadow; &.tag-action { @apply relative; @@ -49,14 +49,14 @@ } > .tag-list { - @apply hidden flex-col justify-start items-start absolute top-6 left-0 mt-1 p-1 z-1 rounded w-36 max-h-52 overflow-auto font-mono bg-black; + @apply hidden flex-row justify-start items-start flex-wrap absolute top-6 left-0 mt-1 p-1 z-1 rounded w-52 h-auto max-h-48 overflow-y-auto font-mono shadow bg-zinc-200 dark:bg-zinc-600; > .item-container { - @apply w-full text-white cursor-pointer rounded text-sm leading-6 px-2 truncate hover:bg-gray-700 shrink-0; + @apply w-auto max-w-full truncate text-black dark:text-gray-300 cursor-pointer rounded text-sm leading-6 px-2 truncate hover:bg-zinc-300 dark:hover:bg-zinc-700 shrink-0; } > .tip-text { - @apply w-full text-sm text-gray-200 leading-6 px-2 cursor-default; + @apply w-auto text-sm text-gray-200 leading-6 px-2 cursor-default; } } }