feat:开始最大化

This commit is contained in:
1708-huayu 2024-12-07 10:20:24 +08:00
parent f14e6c0e34
commit a2b278d600
7 changed files with 168 additions and 152 deletions

View File

@ -31,7 +31,7 @@ const createWindow = () => {
// 加载 index.html
win.loadFile('./index.html')
}
win.maximize()
// let okPush =false
win.webContents.on('before-input-event', (event, input) => {
console.log("input.type.toLowerCase()", input)

View File

@ -1,4 +1,4 @@
import React, {useId} from 'react';
import React, {Fragment, useId} from 'react';
import routes from './routes'
import {Outlet, useNavigate, useRoutes} from 'react-router-dom'
import useIpcRenderer from '../src/utils/useIpcRenderer'
@ -31,11 +31,11 @@ function App() {
useIpcRenderer({'openDirectory':addNewDir})
// useIpcRenderer({'pushHotkeys':pushHotkeysAction})
return (
<>
<Fragment>
{/* 注册路由 */}
{/*{element}*/}
<Note/>
</>
</Fragment>
)
}

View File

@ -1,6 +1,6 @@
@import '~antd/dist/reset.css';
.ant-tree{
overflow: auto scroll;
overflow: auto;
height: 95.7%;
}
.ant-tree-node-content-wrapper {

View File

@ -55,12 +55,6 @@ h1 {
border-top-right-radius: 10px;
height: 100%;
}
.toolbar {
height: 4.9%;
margin-bottom: 0.1%
}
.editor-inner {
background: #fff;
position: relative;
@ -187,6 +181,9 @@ pre::-webkit-scrollbar-thumb {
}
.toolbar {
margin-left: 20px;
margin-right: 20px;
height: 46px;
display: flex;
margin-bottom: 1px;
background: #fff;

View File

@ -1,130 +1,133 @@
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import {Fragment, useEffect, useState} from "react";
import {useLexicalComposerContext} from "@lexical/react/LexicalComposerContext";
import {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 {TRANSFORMERS, $convertToMarkdownString,} from "@lexical/markdown";
import {getFileExtByPath, getFileFullNameByPath, 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')
import "./ToobarPlugin.less"
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")){
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));
function onChange(editorState) {
if (!isEmpty(props.filePath) && 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 (!isEmpty(filePath)&&filePath !== activeKey) {
console.log("文件不同", filePath, activeKey)
return;
}
console.log("触发保存filePath:", filePath)
if (isEmpty(editorState)) {
return
}
let resultSave;
const saveFile = (event, args) => {
console.log("event,args:", event, args)
if (args !== "CTRL+S") {
return
}
let filePath = props.filePath;
if (!isEmpty(filePath) && filePath !== activeKey) {
console.log("文件不同", filePath, activeKey)
return;
}
console.log("触发保存filePath:", editorState,filePath)
if (isEmpty(editorState)) {
return
}
let resultSave;
// 如果文件地址为空需要用户选择目录并设置文件。
if (!filePath) {
let saveDialogReturnValuePromise = saveFileWithName();
console.log("saveDialogReturnValuePromise", saveDialogReturnValuePromise)
saveDialogReturnValuePromise.then(result => {
if (!result.canceled) {
let filePath =result.filePath
let fileExt = getFileExtByPath(result.filePath)
if (isEmpty(fileExt)){
filePath = filePath+".lexical"
}
if (filePath.endsWith(".md")){
resultSave=editorState
}else {
// 如果文件地址为空需要用户选择目录并设置文件。
if (!filePath) {
let saveDialogReturnValuePromise = saveFileWithName();
console.log("saveDialogReturnValuePromise", saveDialogReturnValuePromise)
saveDialogReturnValuePromise.then(result => {
if (!result.canceled) {
let filePath = result.filePath
let fileExt = getFileExtByPath(result.filePath)
if (isEmpty(fileExt)) {
filePath = filePath + ".lexical"
}
if (filePath.endsWith(".md")) {
resultSave = editorState
} 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)};
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)};
resultSave = JSON.stringify(editorStateSave);
// 后期不再读取文件直接读取文件MD5
importFile(filePath).then(value => {
let save = true;
let oldFileMd5
let newFileMd5 = md5(resultSave)
if (!isEmpty(value)) {
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
importFile(filePath).then(value => {
let save =true;
let oldFileMd5
let newFileMd5 =md5(resultSave)
if (!isEmpty(value)){
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)
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]
)
}
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

View File

@ -20,9 +20,9 @@ const Note = () => {
const newTabIndex = useRef(0);
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);
console.log("itemList",itemList)
const itemTreeTab=[
{
key: '1',
@ -84,33 +84,42 @@ const Note = () => {
return (
<Layout>
<Sider margin='5' collapsedWidth={0} collapsed="true">
<div>
<Avatar size={60} src='http://localhost/20231114150555.jpg' icon={<UserOutlined/>}/>
</div>
<div>
<p style={{color: colorBgContainer, 'fontSize': 60}}>上善若水</p>
</div>
</Sider>
{/*<Sider margin='5' collapsedWidth={0} collapsed="true">*/}
{/* <div>*/}
{/* <Avatar size={60} src='http://localhost/20231114150555.jpg' icon={<UserOutlined/>}/>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p style={{color: colorBgContainer, 'fontSize': 60}}>上善若水</p>*/}
{/* </div>*/}
{/*</Sider>*/}
<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}
style ={{background:"#fff"}}
style ={{background:"#fff",width:'100%'}}
/>
</Sider>
<Layout>
<Tabs
type="editable-card"
onChange={onChange}
activeKey={activeKey}
onEdit={onEdit}
items={items.map(item=>{
return {label:item.label,children: <div className="HlexicalName"><Hlexical filePath={item.children}/></div>,key:item.key}
})}
/>
</Layout>
<Layout>
<Tabs
id="layout-note"
type="editable-card"
onChange={onChange}
activeKey={activeKey}
onEdit={onEdit}
items={itemList.map(item=>{
return {
label:item.label,
children: <div className="HlexicalName"><Hlexical filePath={item.children}/></div>,
key:item.key
}
})}
/>
</Layout>
</Layout>
);
};

View File

@ -1,3 +1,6 @@
.ant-layout .ant-layout-has-sider .css-dev-only-do-not-override-1okl62o{
overflow: hidden;
}
.HlexicalName {
// 顶上有标题设置100h后下面会多处一部分
height: 100%;
@ -10,11 +13,15 @@
margin: 0;
height: 100%;
}
#itemTreeTabs .ant-tabs-nav{
height: 6%;
#layout-note .ant-tabs-nav{
//width: calc(100% - 300px);
margin: 0px 20px;
}
#itemTreeTabs .ant-tabs-nav {
height: 60px;
}
#itemTreeTabs .ant-tabs-content-holder{
height: 94%;
height: calc (100%-60px);
}
#itemTreeTabs .ant-tabs-tab{
margin: 0;
@ -28,12 +35,12 @@
#itemTreeTabs .ant-tabs-tab-btn{
width: 100%;
}
.ant-tabs-nav .ant-tabs-nav-add,
/* 显示新增标签按钮 */
.ant-tabs-nav-operations {
display: inline-block;
}
//.ant-tabs-nav .ant-tabs-nav-add,
///* 显示新增标签按钮 */
//.ant-tabs-nav-operations {
// display: inline-block;
//}
/* 隐藏触发隐藏操作按钮的样式 */
.ant-tabs-nav-operations-hidden {
display: none !important;
}
//.ant-tabs-nav-operations-hidden {
// display: none !important;
//}