feat:开始最大化
This commit is contained in:
parent
f14e6c0e34
commit
a2b278d600
2
main.js
2
main.js
|
@ -31,7 +31,7 @@ const createWindow = () => {
|
||||||
// 加载 index.html
|
// 加载 index.html
|
||||||
win.loadFile('./index.html')
|
win.loadFile('./index.html')
|
||||||
}
|
}
|
||||||
|
win.maximize()
|
||||||
// let okPush =false
|
// let okPush =false
|
||||||
win.webContents.on('before-input-event', (event, input) => {
|
win.webContents.on('before-input-event', (event, input) => {
|
||||||
console.log("input.type.toLowerCase()", input)
|
console.log("input.type.toLowerCase()", input)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, {useId} from 'react';
|
import React, {Fragment, useId} from 'react';
|
||||||
import routes from './routes'
|
import routes from './routes'
|
||||||
import {Outlet, useNavigate, useRoutes} from 'react-router-dom'
|
import {Outlet, useNavigate, useRoutes} from 'react-router-dom'
|
||||||
import useIpcRenderer from '../src/utils/useIpcRenderer'
|
import useIpcRenderer from '../src/utils/useIpcRenderer'
|
||||||
|
@ -31,11 +31,11 @@ function App() {
|
||||||
useIpcRenderer({'openDirectory':addNewDir})
|
useIpcRenderer({'openDirectory':addNewDir})
|
||||||
// useIpcRenderer({'pushHotkeys':pushHotkeysAction})
|
// useIpcRenderer({'pushHotkeys':pushHotkeysAction})
|
||||||
return (
|
return (
|
||||||
<>
|
<Fragment>
|
||||||
{/* 注册路由 */}
|
{/* 注册路由 */}
|
||||||
{/*{element}*/}
|
{/*{element}*/}
|
||||||
<Note/>
|
<Note/>
|
||||||
</>
|
</Fragment>
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@import '~antd/dist/reset.css';
|
@import '~antd/dist/reset.css';
|
||||||
.ant-tree{
|
.ant-tree{
|
||||||
overflow: auto scroll;
|
overflow: auto;
|
||||||
height: 95.7%;
|
height: 95.7%;
|
||||||
}
|
}
|
||||||
.ant-tree-node-content-wrapper {
|
.ant-tree-node-content-wrapper {
|
||||||
|
|
|
@ -55,12 +55,6 @@ h1 {
|
||||||
border-top-right-radius: 10px;
|
border-top-right-radius: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar {
|
|
||||||
height: 4.9%;
|
|
||||||
margin-bottom: 0.1%
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-inner {
|
.editor-inner {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -187,6 +181,9 @@ pre::-webkit-scrollbar-thumb {
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
height: 46px;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
|
@ -1,130 +1,133 @@
|
||||||
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
import {useLexicalComposerContext} from "@lexical/react/LexicalComposerContext";
|
||||||
import {Fragment, useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {importFile, overWriteFile, saveFileWithName} from "../../../../utils/File";
|
import {importFile, overWriteFile, saveFileWithName} from "../../../../utils/File";
|
||||||
import {isEmpty} from "../../../../utils/ObjectUtils";
|
import {isEmpty} from "../../../../utils/ObjectUtils";
|
||||||
import {CLEAR_HISTORY_COMMAND} from "lexical";
|
import {TRANSFORMERS, $convertToMarkdownString,} from "@lexical/markdown";
|
||||||
import {TRANSFORMERS, $convertFromMarkdownString, $convertToMarkdownString,} from "@lexical/markdown";
|
|
||||||
import {getFileExtByPath, getFileFullNameByPath, getFileNameByPath} from "../../../../utils/PathOperate";
|
import {getFileExtByPath, getFileFullNameByPath, getFileNameByPath} from "../../../../utils/PathOperate";
|
||||||
import {updatedSavedFile} from "../../../../redux/tableBarItem_reducer";
|
import {updatedSavedFile} from "../../../../redux/tableBarItem_reducer";
|
||||||
import {useDispatch, useSelector} from "react-redux";
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
import md5 from "md5"
|
import md5 from "md5"
|
||||||
import {message} from "antd";
|
import {message} from "antd";
|
||||||
|
|
||||||
const {ipcRenderer} = window.require('electron')
|
const {ipcRenderer} = window.require('electron')
|
||||||
import "./ToobarPlugin.less"
|
import "./ToobarPlugin.less"
|
||||||
import {newFileAdd, updateFileMd5} from "../../../../redux/dirMessage_reducer";
|
import {newFileAdd, updateFileMd5} from "../../../../redux/dirMessage_reducer";
|
||||||
const 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) {
|
const SaveFilePlugin = (props) => {
|
||||||
|
let activeKey = useSelector(state => state.tableBarItem.activeKey);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
// const [messageApi,contextHolder] = message.useMessage();
|
||||||
|
const [editor] = useLexicalComposerContext();
|
||||||
|
const [editorState, setEditorState] = useState();
|
||||||
|
|
||||||
if (!isEmpty(props.filePath)&&props.filePath.endsWith(".md")){
|
function onChange(editorState) {
|
||||||
let read = editorState.read(() => $convertToMarkdownString(TRANSFORMERS));
|
|
||||||
setEditorState(read)
|
if (!isEmpty(props.filePath) && props.filePath.endsWith(".md")) {
|
||||||
}else {
|
let read = editorState.read(() => $convertToMarkdownString(TRANSFORMERS));
|
||||||
// Call toJSON on the EditorState object, which produces a serialization safe string
|
setEditorState(read)
|
||||||
const editorStateJSON = editorState.toJSON();
|
} else {
|
||||||
console.log('onChange-editorStateJSON')
|
// Call toJSON on the EditorState object, which produces a serialization safe string
|
||||||
// However, we still have a JavaScript object, so we need to convert it to an actual string with JSON.stringify
|
const editorStateJSON = editorState.toJSON();
|
||||||
setEditorState(JSON.stringify(editorStateJSON));
|
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) => {
|
const saveFile = (event, args) => {
|
||||||
console.log("event,args:", event, args)
|
console.log("event,args:", event, args)
|
||||||
if (args !== "CTRL+S") {
|
if (args !== "CTRL+S") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let filePath = props.filePath;
|
let filePath = props.filePath;
|
||||||
if (!isEmpty(filePath)&&filePath !== activeKey) {
|
if (!isEmpty(filePath) && filePath !== activeKey) {
|
||||||
console.log("文件不同", filePath, activeKey)
|
console.log("文件不同", filePath, activeKey)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("触发保存filePath:", filePath)
|
console.log("触发保存filePath:", editorState,filePath)
|
||||||
if (isEmpty(editorState)) {
|
if (isEmpty(editorState)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let resultSave;
|
let resultSave;
|
||||||
|
|
||||||
|
|
||||||
// 如果文件地址为空需要用户选择目录并设置文件。
|
// 如果文件地址为空需要用户选择目录并设置文件。
|
||||||
if (!filePath) {
|
if (!filePath) {
|
||||||
let saveDialogReturnValuePromise = saveFileWithName();
|
let saveDialogReturnValuePromise = saveFileWithName();
|
||||||
console.log("saveDialogReturnValuePromise", saveDialogReturnValuePromise)
|
console.log("saveDialogReturnValuePromise", saveDialogReturnValuePromise)
|
||||||
saveDialogReturnValuePromise.then(result => {
|
saveDialogReturnValuePromise.then(result => {
|
||||||
if (!result.canceled) {
|
if (!result.canceled) {
|
||||||
let filePath =result.filePath
|
let filePath = result.filePath
|
||||||
let fileExt = getFileExtByPath(result.filePath)
|
let fileExt = getFileExtByPath(result.filePath)
|
||||||
if (isEmpty(fileExt)){
|
if (isEmpty(fileExt)) {
|
||||||
filePath = filePath+".lexical"
|
filePath = filePath + ".lexical"
|
||||||
}
|
}
|
||||||
if (filePath.endsWith(".md")){
|
if (filePath.endsWith(".md")) {
|
||||||
resultSave=editorState
|
resultSave = editorState
|
||||||
}else {
|
} else {
|
||||||
|
const editorStateSave = {"editorState": JSON.parse(editorState)};
|
||||||
|
resultSave = JSON.stringify(editorStateSave);
|
||||||
|
}
|
||||||
|
overWriteFile(filePath, resultSave)
|
||||||
|
// 修改当前文件名
|
||||||
|
dispatch(updatedSavedFile({filePath: filePath}))
|
||||||
|
// 文件目录更新
|
||||||
|
dispatch(newFileAdd({
|
||||||
|
fileName: getFileFullNameByPath(filePath), dirFlag: false, children: [], filePath: filePath,
|
||||||
|
fileId: filePath, fileMd5: md5(resultSave)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (props.filePath.endsWith(".md")) {
|
||||||
|
resultSave = editorState
|
||||||
|
} else {
|
||||||
const editorStateSave = {"editorState": JSON.parse(editorState)};
|
const editorStateSave = {"editorState": JSON.parse(editorState)};
|
||||||
resultSave = JSON.stringify(editorStateSave);
|
resultSave = JSON.stringify(editorStateSave);
|
||||||
}
|
|
||||||
overWriteFile(filePath, resultSave)
|
|
||||||
// 修改当前文件名
|
|
||||||
dispatch(updatedSavedFile({filePath: filePath}))
|
|
||||||
// 文件目录更新
|
|
||||||
dispatch(newFileAdd({fileName:getFileFullNameByPath(filePath),dirFlag:false,children:[],filePath: filePath,
|
|
||||||
fileId:filePath,fileMd5:md5(resultSave)}))
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
return
|
// 后期不再读取文件,直接读取文件MD5
|
||||||
}
|
importFile(filePath).then(value => {
|
||||||
if (props.filePath.endsWith(".md")){
|
let save = true;
|
||||||
resultSave=editorState
|
let oldFileMd5
|
||||||
}else {
|
let newFileMd5 = md5(resultSave)
|
||||||
const editorStateSave = {"editorState": JSON.parse(editorState)};
|
if (!isEmpty(value)) {
|
||||||
resultSave = JSON.stringify(editorStateSave);
|
if (props.filePath.endsWith(".md")) {
|
||||||
|
// editorState
|
||||||
|
oldFileMd5 = md5(value.toString());
|
||||||
|
save = (isEmpty(value)) || newFileMd5 !== oldFileMd5;
|
||||||
|
} else {
|
||||||
|
oldFileMd5 = md5(JSON.stringify(JSON.parse(value.toString())));
|
||||||
|
save = (isEmpty(value)) || newFileMd5 !== oldFileMd5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (save) {
|
||||||
|
overWriteFile(filePath, resultSave).then(() => {
|
||||||
|
console.log("保存成功" + filePath)
|
||||||
|
// 修改文件Md5
|
||||||
|
dispatch(updateFileMd5({filePath, "fileMd5": newFileMd5}))
|
||||||
|
// messageApi.open({type:"success",content:"保存成功:" + filePath,duration:1})
|
||||||
|
message.success("保存成功:" + filePath)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(error =>
|
||||||
|
console.error(error)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 后期不再读取文件,直接读取文件MD5
|
useEffect(() => {
|
||||||
importFile(filePath).then(value => {
|
ipcRenderer.on("pushHotkeys", saveFile);
|
||||||
let save =true;
|
let updateListener = editor.registerUpdateListener(({editorState}) => {
|
||||||
let oldFileMd5
|
console.log("SaveFilePlugin:editorState", editorState)
|
||||||
let newFileMd5 =md5(resultSave)
|
onChange(editorState);
|
||||||
if (!isEmpty(value)){
|
})
|
||||||
if (props.filePath.endsWith(".md")){
|
return () => {
|
||||||
// editorState
|
console.log("销毁取消监听");
|
||||||
oldFileMd5 = md5(value.toString());
|
updateListener()
|
||||||
save = (isEmpty(value)) || newFileMd5 !== oldFileMd5;
|
ipcRenderer.removeListener("pushHotkeys", saveFile)
|
||||||
}else {
|
};
|
||||||
oldFileMd5 = md5(JSON.stringify(JSON.parse(value.toString())));
|
}, [editor, onChange]
|
||||||
save = (isEmpty(value)) || newFileMd5 !== oldFileMd5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (save) {
|
|
||||||
overWriteFile(filePath, resultSave).then(()=>{
|
|
||||||
console.log("保存成功"+ filePath)
|
|
||||||
// 修改文件Md5
|
|
||||||
dispatch(updateFileMd5({filePath,"fileMd5":newFileMd5}))
|
|
||||||
// messageApi.open({type:"success",content:"保存成功:" + filePath,duration:1})
|
|
||||||
message.success("保存成功:" + 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]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
export default SaveFilePlugin
|
export default SaveFilePlugin
|
||||||
|
|
|
@ -20,9 +20,9 @@ const Note = () => {
|
||||||
const newTabIndex = useRef(0);
|
const newTabIndex = useRef(0);
|
||||||
|
|
||||||
const activeKey=useSelector(state => state.tableBarItem.activeKey);
|
const activeKey=useSelector(state => state.tableBarItem.activeKey);
|
||||||
const items = useSelector(state => state.tableBarItem.data)
|
const itemList = useSelector(state => state.tableBarItem.data)
|
||||||
let filePath = useSelector(state => state.dirMessage.dirTree);
|
let filePath = useSelector(state => state.dirMessage.dirTree);
|
||||||
|
console.log("itemList",itemList)
|
||||||
const itemTreeTab=[
|
const itemTreeTab=[
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
|
@ -84,33 +84,42 @@ const Note = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Sider margin='5' collapsedWidth={0} collapsed="true">
|
{/*<Sider margin='5' collapsedWidth={0} collapsed="true">*/}
|
||||||
<div>
|
{/* <div>*/}
|
||||||
<Avatar size={60} src='http://localhost/20231114150555.jpg' icon={<UserOutlined/>}/>
|
{/* <Avatar size={60} src='http://localhost/20231114150555.jpg' icon={<UserOutlined/>}/>*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
<div>
|
{/* <div>*/}
|
||||||
<p style={{color: colorBgContainer, 'fontSize': 60}}>上善若水</p>
|
{/* <p style={{color: colorBgContainer, 'fontSize': 60}}>上善若水</p>*/}
|
||||||
</div>
|
{/* </div>*/}
|
||||||
</Sider>
|
{/*</Sider>*/}
|
||||||
<Sider trigger={null} collapsedWidth={0} width="300px" collapsible collapsed={collapsed}
|
<Sider trigger={null} collapsedWidth={0} width="300px" collapsible collapsed={collapsed}
|
||||||
// style={{overflow:"auto"}}
|
style={{overflow:"hidden"}}
|
||||||
>
|
>
|
||||||
<Tabs id="itemTreeTabs" defaultActiveKey={useSelector(state => state.tableBarItem.leftTableOfContents)} items={itemTreeTab}
|
{/* 文件 标题 */}
|
||||||
|
<Tabs id="itemTreeTabs"
|
||||||
|
defaultActiveKey={useSelector(state => state.tableBarItem.leftTableOfContents)}
|
||||||
|
items={itemTreeTab}
|
||||||
onChange={onChangeLeftTableOfContents}
|
onChange={onChangeLeftTableOfContents}
|
||||||
style ={{background:"#fff"}}
|
style ={{background:"#fff",width:'100%'}}
|
||||||
/>
|
/>
|
||||||
</Sider>
|
</Sider>
|
||||||
<Layout>
|
|
||||||
<Tabs
|
<Layout>
|
||||||
type="editable-card"
|
<Tabs
|
||||||
onChange={onChange}
|
id="layout-note"
|
||||||
activeKey={activeKey}
|
type="editable-card"
|
||||||
onEdit={onEdit}
|
onChange={onChange}
|
||||||
items={items.map(item=>{
|
activeKey={activeKey}
|
||||||
return {label:item.label,children: <div className="HlexicalName"><Hlexical filePath={item.children}/></div>,key:item.key}
|
onEdit={onEdit}
|
||||||
})}
|
items={itemList.map(item=>{
|
||||||
/>
|
return {
|
||||||
</Layout>
|
label:item.label,
|
||||||
|
children: <div className="HlexicalName"><Hlexical filePath={item.children}/></div>,
|
||||||
|
key:item.key
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
.ant-layout .ant-layout-has-sider .css-dev-only-do-not-override-1okl62o{
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
.HlexicalName {
|
.HlexicalName {
|
||||||
// 顶上有标题设置100h后下面会多处一部分
|
// 顶上有标题设置100h后下面会多处一部分
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -10,11 +13,15 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
#itemTreeTabs .ant-tabs-nav{
|
#layout-note .ant-tabs-nav{
|
||||||
height: 6%;
|
//width: calc(100% - 300px);
|
||||||
|
margin: 0px 20px;
|
||||||
|
}
|
||||||
|
#itemTreeTabs .ant-tabs-nav {
|
||||||
|
height: 60px;
|
||||||
}
|
}
|
||||||
#itemTreeTabs .ant-tabs-content-holder{
|
#itemTreeTabs .ant-tabs-content-holder{
|
||||||
height: 94%;
|
height: calc (100%-60px);
|
||||||
}
|
}
|
||||||
#itemTreeTabs .ant-tabs-tab{
|
#itemTreeTabs .ant-tabs-tab{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -28,12 +35,12 @@
|
||||||
#itemTreeTabs .ant-tabs-tab-btn{
|
#itemTreeTabs .ant-tabs-tab-btn{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.ant-tabs-nav .ant-tabs-nav-add,
|
//.ant-tabs-nav .ant-tabs-nav-add,
|
||||||
/* 显示新增标签按钮 */
|
///* 显示新增标签按钮 */
|
||||||
.ant-tabs-nav-operations {
|
//.ant-tabs-nav-operations {
|
||||||
display: inline-block;
|
// display: inline-block;
|
||||||
}
|
//}
|
||||||
/* 隐藏触发隐藏操作按钮的样式 */
|
/* 隐藏触发隐藏操作按钮的样式 */
|
||||||
.ant-tabs-nav-operations-hidden {
|
//.ant-tabs-nav-operations-hidden {
|
||||||
display: none !important;
|
// display: none !important;
|
||||||
}
|
//}
|
||||||
|
|
Loading…
Reference in New Issue