diff --git a/src/pages/Note/Hlexical/index.jsx b/src/pages/Note/Hlexical/index.jsx
index 2e7332b..4b24602 100644
--- a/src/pages/Note/Hlexical/index.jsx
+++ b/src/pages/Note/Hlexical/index.jsx
@@ -15,31 +15,28 @@ import {AutoLinkNode, LinkNode} from "@lexical/link";
import {MarkdownShortcutPlugin} from "@lexical/react/LexicalMarkdownShortcutPlugin";
import {
TRANSFORMERS, $convertFromMarkdownString,
- $convertToMarkdownString,
} from "@lexical/markdown";
import "./index.less"
-import {useEffect, useId, useState} from 'react';
+import {useEffect, useState} from 'react';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
-import {importFile, overWriteFile, saveFileWithName} from "../../../utils/File"
-import {$getRoot, CLEAR_HISTORY_COMMAND, $createTextNode,} from "lexical";
-import md5 from "md5"
+import {importFile} from "../../../utils/File"
+
import {isEmpty} from "../../../utils/ObjectUtils";
-import {useDispatch, useSelector} from "react-redux";
-import {updatedSavedFile} from "../../../redux/tableBarItem_reducer";
import {ListPlugin} from "@lexical/react/LexicalListPlugin";
import {LinkPlugin} from "@lexical/react/LexicalLinkPlugin";
import AutoLinkPlugin from "./plugins/AutoLinkPlugin";
import ListMaxIndentLevelPlugin from "./plugins/ListMaxIndentLevelPlugin";
import CodeHighlightPlugin from "./plugins/CodeHighlightPlugin";
-import {getFileNameByPath} from "../../../utils/PathOperate";
+import ImportFilePlugin from "./plugins/ImportFilePlugin";
+import {TablePlugin} from "@lexical/react/LexicalTablePlugin";
+import SaveFilePlugin from "./plugins/SaveFilePlugin";
-const {ipcRenderer} = window.require('electron')
function Placeholder() {
return
Enter some rich text...
;
}
-const editorConfig = {
+let editorConfig = {
// The editor theme
theme: ExampleTheme,
// Handling of errors during update
@@ -61,133 +58,21 @@ const editorConfig = {
LinkNode
]
};
-
-function OnChangePlugin({onChange}) {
- const [editor] = useLexicalComposerContext();
- console.log('editor', editor)
- useEffect(() => {
- return editor.registerUpdateListener(({editorState}) => {
- onChange(editorState);
- });
- }, [editor, onChange]);
-}
-
-function ImportFilePlugin(props) {
- const [editor] = useLexicalComposerContext();
- useEffect(() => {
- if (props.filePath) {
- importFile(props.filePath).then(value => {
- if (isEmpty(value)) {
- return
- }
- if (props.filePath.endsWith(".md")) {
- const root = $getRoot();
- const firstChild = root.getFirstChild();
- if ($isCodeNode(firstChild) && firstChild.getLanguage() === 'markdown') {
- $convertFromMarkdownString(
- firstChild.getTextContent(),
- PLAYGROUND_TRANSFORMERS,
- );
- } else {
- const markdown = $convertToMarkdownString(PLAYGROUND_TRANSFORMERS);
- root
- .clear()
- .append(
- $createCodeNode('markdown').append($createTextNode(markdown)),
- );
- }
- root.selectEnd();
- } else {
- const editorState = editor.parseEditorState(
- JSON.stringify(JSON.parse(value.toString()).editorState)
- );
- editor.setEditorState(editorState);
- editor.dispatchCommand(CLEAR_HISTORY_COMMAND, undefined);
- }
- }).catch(error =>
- console.error(error)
- )
- }
- }, [])
-}
-
-
// 从字符串化 JSON 设置编辑器状态
// const editorState = editor.parseEditorState(editorStateJSONString);
// editor.setEditorState(editorState);
-
export default function Hlexical(props) {
console.log("Hlexical(props):this.props.filePath:", props.filePath)
- const [editorState, setEditorState] = useState();
- const dispatch = useDispatch();
-
- function onChange(editorState) {
- // Call toJSON on the EditorState object, which produces a serialization safe string
- const editorStateJSON = editorState.toJSON();
- console.log('onChange-editorStateJSON')
- // However, we still have a JavaScript object, so we need to convert it to an actual string with JSON.stringify
- setEditorState(JSON.stringify(editorStateJSON));
- }
-
- let pushHotKey = useSelector(state => state.pushHotkeys.data);
- let activeKey = useSelector(state => state.tableBarItem.activeKey);
- const saveFile = (event, args) => {
- console.log("event,args:", event, args)
- console.log("触发保存pushHotKey:", pushHotKey)
- if (pushHotKey !== "CTRL+S") {
- return
- }
- let filePath = props.filePath;
- if (filePath !== activeKey) {
- console.log("文件不同", filePath, activeKey)
- return;
- }
- console.log("触发保存filePath:", filePath)
- if (isEmpty(editorState)) {
- return
- }
- const editorStateSave = {"editorState": JSON.parse(editorState)};
- let resultSave = JSON.stringify(editorStateSave);
-
- // 如果文件地址为空需要用户选择目录并设置文件。
- if (!filePath) {
- let saveDialogReturnValuePromise = saveFileWithName();
- console.log("saveDialogReturnValuePromise", saveDialogReturnValuePromise)
- saveDialogReturnValuePromise.then(result => {
- if (!result.canceled) {
- let fileKey = getFileNameByPath(result.filePath)
- if (isEmpty(fileKey)){
- fileKey = fileKey+".lexical"
- }
- overWriteFile(fileKey, resultSave)
- // 修改当前文件名
- dispatch(updatedSavedFile({filePath: result.filePath}))
- // 文件目录更新
- dispatch()
- }
- })
- return
- }
- importFile(filePath).then(value => {
- let save = (isEmpty(value)) || md5(resultSave) !== md5(JSON.stringify(JSON.parse(value.toString())));
- if (save) {
- console.log("保存重写" + filePath)
- overWriteFile(filePath, resultSave)
+ if (props.filePath.endsWith(".md")){
+ importFile(props.filePath).then(value => {
+ if (isEmpty(value)) {
+ return
}
+ editorConfig={...editorConfig,editorState: () => $convertFromMarkdownString(value.toString(), TRANSFORMERS)}
}).catch(error =>
console.error(error)
)
}
- useEffect(() => {
- ipcRenderer.on("pushHotkeys", saveFile);
- return () => {
- console.log("销毁取消监听");
- ipcRenderer.removeListener("pushHotkeys", saveFile)
- };
- }
- )
-
-
return (
@@ -202,17 +87,17 @@ export default function Hlexical(props) {
{/*黑窗口动态记录当前操作*/}
{/*
*/}
-
+
{/*markdown 快捷键*/}
-
+
{/*文件操作导入文件*/}
{/**/}
diff --git a/src/pages/Note/Hlexical/index.less b/src/pages/Note/Hlexical/index.less
index 25103b1..d5adae1 100644
--- a/src/pages/Note/Hlexical/index.less
+++ b/src/pages/Note/Hlexical/index.less
@@ -147,8 +147,8 @@ body {
margin-top: 8px;
margin-bottom: 8px;
tab-size: 2;
- /* white-space: pre; */
- overflow-x: auto;
+ white-space: pre;
+ overflow: auto;
position: relative;
}
diff --git a/src/pages/Note/Hlexical/plugins/ImportFilePlugin.js b/src/pages/Note/Hlexical/plugins/ImportFilePlugin.js
new file mode 100644
index 0000000..b1a67b3
--- /dev/null
+++ b/src/pages/Note/Hlexical/plugins/ImportFilePlugin.js
@@ -0,0 +1,37 @@
+import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
+import {useEffect} from "react";
+import {importFile} from "../../../../utils/File";
+import {isEmpty} from "../../../../utils/ObjectUtils";
+import {CLEAR_HISTORY_COMMAND} from "lexical";
+import {TRANSFORMERS, $convertFromMarkdownString, $convertToMarkdownString,} from "@lexical/markdown";
+export default function ImportFilePlugin(props) {
+ const [editor] = useLexicalComposerContext();
+ useEffect(() => {
+ if (props.filePath) {
+ importFile(props.filePath).then(value => {
+ if (isEmpty(value)) {
+ return
+ }
+ if (props.filePath.endsWith(".md")) {
+ console.log("$convertFromMarkdownString(value.toString(), TRANSFORMERS)",editor)
+ // const editorState = editor.parseEditorState($convertFromMarkdownString(value.toString(), TRANSFORMERS))
+ // editor.setEditorState(editorState);
+ // editor.dispatchCommand(CLEAR_HISTORY_COMMAND, undefined);
+
+ editor.update(() => {
+ $convertFromMarkdownString(value.toString(), TRANSFORMERS);
+ })
+
+ } else {
+ const editorState = editor.parseEditorState(
+ JSON.stringify(JSON.parse(value.toString()).editorState)
+ );
+ editor.setEditorState(editorState);
+ editor.dispatchCommand(CLEAR_HISTORY_COMMAND, undefined);
+ }
+ }).catch(error =>
+ console.error(error)
+ )
+ }
+ }, [])
+}
diff --git a/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js b/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js
new file mode 100644
index 0000000..3cad213
--- /dev/null
+++ b/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js
@@ -0,0 +1,111 @@
+import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
+import {Fragment, useEffect, useState} from "react";
+import {importFile, overWriteFile, saveFileWithName} from "../../../../utils/File";
+import {isEmpty} from "../../../../utils/ObjectUtils";
+import {CLEAR_HISTORY_COMMAND} from "lexical";
+import {TRANSFORMERS, $convertFromMarkdownString, $convertToMarkdownString,} from "@lexical/markdown";
+import {getFileNameByPath} from "../../../../utils/PathOperate";
+import {updatedSavedFile} from "../../../../redux/tableBarItem_reducer";
+import {useDispatch, useSelector} from "react-redux";
+import md5 from "md5"
+import {message} from "antd";
+const {ipcRenderer} = window.require('electron')
+export default function SaveFilePlugin(props) {
+ let activeKey = useSelector(state => state.tableBarItem.activeKey);
+ const dispatch = useDispatch();
+ const [messageApi,contextHolder] = message.useMessage();
+ const [editor] = useLexicalComposerContext();
+ const [editorState,setEditorState]=useState();
+
+ function onChange(editorState) {
+ if (props.filePath.endsWith(".md")){
+ let read = editorState.read(() => $convertToMarkdownString(TRANSFORMERS));
+ setEditorState(read)
+ }else {
+ // Call toJSON on the EditorState object, which produces a serialization safe string
+ const editorStateJSON = editorState.toJSON();
+ console.log('onChange-editorStateJSON')
+ // However, we still have a JavaScript object, so we need to convert it to an actual string with JSON.stringify
+ setEditorState(JSON.stringify(editorStateJSON));
+ }
+ }
+
+ const saveFile = (event, args) => {
+ console.log("event,args:", event, args)
+ if (args !== "CTRL+S") {
+ return
+ }
+ let filePath = props.filePath;
+ if (filePath !== activeKey) {
+ console.log("文件不同", filePath, activeKey)
+ return;
+ }
+ console.log("触发保存filePath:", filePath)
+ if (isEmpty(editorState)) {
+ return
+ }
+ let resultSave;
+ if (props.filePath.endsWith(".md")){
+ resultSave=editorState
+ }else {
+ const editorStateSave = {"editorState": JSON.parse(editorState)};
+ resultSave = JSON.stringify(editorStateSave);
+ }
+
+ // 如果文件地址为空需要用户选择目录并设置文件。
+ if (!filePath) {
+ let saveDialogReturnValuePromise = saveFileWithName();
+ console.log("saveDialogReturnValuePromise", saveDialogReturnValuePromise)
+ saveDialogReturnValuePromise.then(result => {
+ if (!result.canceled) {
+ let fileKey = getFileNameByPath(result.filePath)
+ if (isEmpty(fileKey)){
+ fileKey = fileKey+".lexical"
+ }
+ overWriteFile(fileKey, resultSave)
+ // 修改当前文件名
+ dispatch(updatedSavedFile({filePath: result.filePath}))
+ // 文件目录更新
+ dispatch()
+ }
+ })
+ return
+ }
+ importFile(filePath).then(value => {
+ let save
+ if (props.filePath.endsWith(".md")){
+ // editorState
+ save = (isEmpty(value)) || md5(resultSave) !== md5(value.toString());
+ }else {
+ save = (isEmpty(value)) || md5(resultSave) !== md5(JSON.stringify(JSON.parse(value.toString())));
+ }
+
+ if (save) {
+ overWriteFile(filePath, resultSave)
+ console.log("保存成功"+ filePath)
+ messageApi.open({type:"success",content:"保存成功:" + filePath})
+ }
+ }).catch(error =>
+ console.error(error)
+ )
+ }
+
+ useEffect(() => {
+ ipcRenderer.on("pushHotkeys", saveFile);
+ let updateListener = editor.registerUpdateListener(({editorState}) => {
+ console.log("SaveFilePlugin:editorState",editorState)
+ onChange(editorState);
+ })
+ return () => {
+ console.log("销毁取消监听");
+ updateListener()
+ ipcRenderer.removeListener("pushHotkeys", saveFile)
+ };
+ },[editor,onChange]
+ )
+ return (
+
+ {contextHolder}
+
+ )
+}
diff --git a/src/redux/dirMessage_reducer.js b/src/redux/dirMessage_reducer.js
index f64eeff..00a412d 100644
--- a/src/redux/dirMessage_reducer.js
+++ b/src/redux/dirMessage_reducer.js
@@ -19,6 +19,7 @@ export const dirMessageSlice = createSlice({
// selectDirKey:""
},
reducers: {
+ // 一级目录有相同的就要和并,从第一次展开处和并,不需要展示上一级。
dirAdd: (state, action) => {
console.log("dirMessage:dirAdd", state, action)
if (action.payload) {