diff --git a/web/src/components/ArchivedMemo.tsx b/web/src/components/ArchivedMemo.tsx index addc2ede..a919460e 100644 --- a/web/src/components/ArchivedMemo.tsx +++ b/web/src/components/ArchivedMemo.tsx @@ -51,7 +51,7 @@ const ArchivedMemo: React.FC = (props: Props) => { }; return ( -
+
{t("common.archived-at")} {utils.getDateTimeString(memo.updatedTs)} diff --git a/web/src/components/Editor/Editor.tsx b/web/src/components/Editor/Editor.tsx index f6e8324f..8c27dd27 100644 --- a/web/src/components/Editor/Editor.tsx +++ b/web/src/components/Editor/Editor.tsx @@ -5,6 +5,7 @@ import "../../less/editor.less"; export interface EditorRefActions { focus: FunctionType; insertText: (text: string, prefix?: string, suffix?: string) => void; + removeText: (start: number, length: number) => void; setContent: (text: string) => void; getContent: () => string; getSelectedContent: () => string; @@ -67,6 +68,19 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef< handleContentChangeCallback(editorRef.current.value); refresh(); }, + removeText: (start: number, length: number) => { + if (!editorRef.current) { + return; + } + + const prevValue = editorRef.current.value; + const value = prevValue.slice(0, start) + prevValue.slice(start + length); + editorRef.current.value = value; + editorRef.current.focus(); + editorRef.current.selectionEnd = start; + handleContentChangeCallback(editorRef.current.value); + refresh(); + }, setContent: (text: string) => { if (editorRef.current) { editorRef.current.value = text; diff --git a/web/src/components/MemoEditor.tsx b/web/src/components/MemoEditor.tsx index 3f715571..1fb8900d 100644 --- a/web/src/components/MemoEditor.tsx +++ b/web/src/components/MemoEditor.tsx @@ -1,4 +1,4 @@ -import { toLower } from "lodash"; +import { last, toLower } from "lodash"; import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { deleteMemoResource, upsertMemoResource } from "../helpers/api"; @@ -14,6 +14,8 @@ import ResourceIcon from "./ResourceIcon"; import showResourcesSelectorDialog from "./ResourcesSelectorDialog"; import "../less/memo-editor.less"; +const listItemSymbolList = ["* ", "- ", "- [ ] ", "- [x] ", "- [X] "]; + const getEditorContentCache = (): string => { return storage.get(["editorContentCache"]).editorContentCache ?? ""; }; @@ -48,7 +50,7 @@ const MemoEditor = () => { shouldShowEmojiPicker: false, }); const [allowSave, setAllowSave] = useState(false); - const prevGlobalStateRef = useRef(editorState); + const prevEditorStateRef = useRef(editorState); const editorRef = useRef(null); const tagSelectorRef = useRef(null); const memoVisibilityOptionSelectorItems = VISIBILITY_SELECTOR_ITEMS.map((item) => { @@ -87,10 +89,14 @@ const MemoEditor = () => { storage.remove(["editingMemoIdCache"]); } - prevGlobalStateRef.current = editorState; + prevEditorStateRef.current = editorState; }, [editorState.editMemoId]); const handleKeyDown = (event: React.KeyboardEvent) => { + if (!editorRef.current) { + return; + } + if (event.ctrlKey || event.metaKey) { if (event.key === "Enter") { handleSaveBtnClick(); @@ -98,39 +104,36 @@ const MemoEditor = () => { } if (event.key === "b") { event.preventDefault(); - editorRef.current?.insertText("", "**", "**"); + editorRef.current.insertText("", "**", "**"); return; } if (event.key === "i") { event.preventDefault(); - editorRef.current?.insertText("", "*", "*"); + editorRef.current.insertText("", "*", "*"); return; } if (event.key === "e") { event.preventDefault(); - editorRef.current?.insertText("", "`", "`"); + editorRef.current.insertText("", "`", "`"); return; } } + if (event.key === "Enter") { - if (!editorRef.current) { - return; - } const cursorPosition = editorRef.current.getCursorPosition(); - const prevValue = editorRef.current.getContent().slice(0, cursorPosition); - const prevRows = prevValue.split("\n"); - const prevRowValue = prevRows[prevRows.length - 1]; - if (prevRowValue === "- " || prevRowValue === "- [ ] " || prevRowValue === "- [x] " || prevRowValue === "- [X] ") { - event.preventDefault(); - prevRows[prevRows.length - 1] = ""; - editorRef.current.setContent(prevRows.join("\n")); - } else { - if (prevRowValue.startsWith("- [ ] ") || prevRowValue.startsWith("- [x] ") || prevRowValue.startsWith("- [X] ")) { + const contentBeforeCursor = editorRef.current.getContent().slice(0, cursorPosition); + const rowValue = last(contentBeforeCursor.split("\n")); + if (rowValue) { + if (listItemSymbolList.includes(rowValue)) { event.preventDefault(); - editorRef.current.insertText("", "\n- [ ] "); - } else if (prevRowValue.startsWith("- ")) { - event.preventDefault(); - editorRef.current.insertText("", "\n- "); + editorRef.current.removeText(cursorPosition - rowValue.length, rowValue.length); + } else { + for (const listItemSymbol of listItemSymbolList) { + if (rowValue.startsWith(listItemSymbol)) { + event.preventDefault(); + editorRef.current.insertText("", `\n${listItemSymbol}`); + } + } } } return; @@ -138,14 +141,14 @@ const MemoEditor = () => { if (event.key === "Escape") { if (state.fullscreen) { handleFullscreenBtnClick(); - } else { + } else if (editorState.editMemoId) { handleCancelEdit(); } return; } if (event.key === "Tab") { event.preventDefault(); - editorRef.current?.insertText(" ".repeat(TAB_SPACE_WIDTH)); + editorRef.current.insertText(" ".repeat(TAB_SPACE_WIDTH)); return; } }; @@ -251,11 +254,13 @@ const MemoEditor = () => { }; const handleCancelEdit = () => { - editorStateService.clearEditMemo(); - editorStateService.clearResourceList(); - editorRef.current?.setContent(""); - setEditorContentCache(""); - storage.remove(["editingMemoVisibilityCache"]); + if (editorState.editMemoId) { + editorStateService.clearEditMemo(); + editorStateService.clearResourceList(); + editorRef.current?.setContent(""); + setEditorContentCache(""); + storage.remove(["editingMemoVisibilityCache"]); + } }; const handleContentChange = (content: string) => { diff --git a/web/src/components/Settings/SystemSection.tsx b/web/src/components/Settings/SystemSection.tsx index 94c05053..98d8a215 100644 --- a/web/src/components/Settings/SystemSection.tsx +++ b/web/src/components/Settings/SystemSection.tsx @@ -117,20 +117,16 @@ const SystemSection = () => { {t("setting.system-section.database-file-size")}: {formatBytes(state.dbSize)} - +

{t("sidebar.setting")}

{t("setting.system-section.additional-style")} - +