diff --git a/src/components/control_panel.jsx b/src/components/control_panel.jsx index 1508a7b..70bb757 100644 --- a/src/components/control_panel.jsx +++ b/src/components/control_panel.jsx @@ -169,6 +169,15 @@ export default function ControlPanel(props) { return n; }) ); + } else if (a.element === ObjectType.NOTE) { + setNotes((prev) => + prev.map((n) => { + if (n.id === a.nid) { + return { ...n, ...a.undo }; + } + return n; + }) + ); } else if (a.element === ObjectType.TABLE) { if (a.component === "field") { updateField(a.data.undo.tid, a.data.undo.fid, a.data.undo.values); @@ -318,6 +327,15 @@ export default function ControlPanel(props) { return n; }) ); + } else if (a.element === ObjectType.NOTE) { + setNotes((prev) => + prev.map((n) => { + if (n.id === a.nid) { + return { ...n, ...a.redo }; + } + return n; + }) + ); } else if (a.element === ObjectType.TABLE) { if (a.component === "field") { updateField(a.data.redo.tid, a.data.redo.fid, a.data.redo.values); diff --git a/src/components/note.jsx b/src/components/note.jsx index 785986c..7d149cf 100644 --- a/src/components/note.jsx +++ b/src/components/note.jsx @@ -1,12 +1,14 @@ -import React, { useContext } from "react"; -import { NoteContext } from "../pages/editor"; +import React, { useContext, useState } from "react"; +import { NoteContext, UndoRedoContext } from "../pages/editor"; +import { Action, ObjectType } from "../data/data"; export default function Note(props) { const { setNotes } = useContext(NoteContext); const w = 180; const r = 3; const fold = 24; - + const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const [editField, setEditField] = useState({}); const handleChange = (e) => { const textarea = document.getElementById(`note_${props.data.id}`); textarea.style.height = "0"; @@ -69,6 +71,31 @@ export default function Note(props) { id={`note_${props.data.id}`} value={props.data.content} onChange={handleChange} + onFocus={(e) => + setEditField({ + content: e.target.value, + height: props.data.height, + }) + } + onBlur={(e) => { + if (e.target.value === editField.name) return; + const textarea = document.getElementById(`note_${props.data.id}`); + textarea.style.height = "0"; + textarea.style.height = textarea.scrollHeight + "px"; + const newHeight = textarea.scrollHeight + 16 + 20 + 4; + setUndoStack((prev) => [ + ...prev, + { + action: Action.EDIT, + element: ObjectType.NOTE, + nid: props.data.id, + undo: editField, + redo: { content: e.target.value, height: newHeight }, + }, + ]); + setRedoStack([]); + setEditField({}); + }} className="w-full resize-none outline-none overflow-y-hidden border-none select-none" style={{ backgroundColor: props.data.color }} > diff --git a/src/components/notes_overview.jsx b/src/components/notes_overview.jsx index 780b94a..bda90df 100644 --- a/src/components/notes_overview.jsx +++ b/src/components/notes_overview.jsx @@ -20,12 +20,14 @@ import { IconSearch, IconCheckboxTick, } from "@douyinfe/semi-icons"; -import { NoteContext } from "../pages/editor"; -import { defaultNoteTheme, noteThemes } from "../data/data"; +import { NoteContext, UndoRedoContext } from "../pages/editor"; +import { noteThemes, Action, ObjectType } from "../data/data"; export default function NotesOverview(props) { const { notes, setNotes, addNote, deleteNote } = useContext(NoteContext); + const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const [value, setValue] = useState(""); + const [editField, setEditField] = useState({}); const [activeKey, setActiveKey] = useState(""); const [filteredResult, setFilteredResult] = useState( notes.map((t) => { @@ -123,24 +125,35 @@ export default function NotesOverview(props) { const newHeight = textarea.scrollHeight + 16 + 20 + 4; updateNote(n.id, { height: newHeight, content: value }); }} + onFocus={(e) => + setEditField({ content: e.target.value, height: n.height }) + } + onBlur={(e) => { + if (e.target.value === editField.name) return; + const textarea = document.getElementById(`note_${n.id}`); + textarea.style.height = "0"; + textarea.style.height = textarea.scrollHeight + "px"; + const newHeight = textarea.scrollHeight + 16 + 20 + 4; + setUndoStack((prev) => [ + ...prev, + { + action: Action.EDIT, + element: ObjectType.NOTE, + nid: i, + undo: editField, + redo: { content: e.target.value, height: newHeight }, + }, + ]); + setRedoStack([]); + setEditField({}); + }} rows={3} />
-
-
Theme
- -
+
Theme

{noteThemes.map((c) => ( @@ -148,7 +161,20 @@ export default function NotesOverview(props) { key={c} style={{ backgroundColor: c }} className="p-3 rounded-full mx-1" - onClick={() => updateNote(i, { color: c })} + onClick={() => { + setUndoStack((prev) => [ + ...prev, + { + action: Action.EDIT, + element: ObjectType.NOTE, + nid: i, + undo: { color: n.color }, + redo: { color: c }, + }, + ]); + setRedoStack([]); + updateNote(i, { color: c }); + }} > {n.color === c ? ( diff --git a/src/data/data.js b/src/data/data.js index 5fba11a..5fe2674 100644 --- a/src/data/data.js +++ b/src/data/data.js @@ -39,7 +39,7 @@ const tableThemes = [ "#ff9159", ]; -const noteThemes = ["#ffdfd9", "#ffffc7", "#cffcb1", "#c7d2ff", "#e7c7ff"]; +const noteThemes = ["#ffdfd9", "#fcf7ac", "#cffcb1", "#c7d2ff", "#e7c7ff"]; const defaultTableTheme = "#175e7a"; const defaultNoteTheme = "#fcf7ac";