Compare commits

..

7 Commits

Author SHA1 Message Date
1708-huayu a2b278d600 feat:开始最大化 2024-12-07 10:20:24 +08:00
1708-huayu f14e6c0e34 feat:点击元素外部事件后关闭菜单 2024-10-22 16:50:40 +08:00
1708-huayu 8a73b6f5b3 feat:文件夹中打开 2024-09-29 16:38:59 +08:00
1708-huayu 1aba426886 feat:backup 2024-09-28 22:21:21 +08:00
1708-huayu b6b1847b92 feat:wait-on使用ip,使用localhost无法启动 2024-09-25 13:27:25 +08:00
1708-huayu 3b7d8f14c3 feat:carco正常启动 2024-09-24 19:07:06 +08:00
1708-huayu 56418aeea4 feat:backup 2024-09-24 18:53:53 +08:00
20 changed files with 6360 additions and 1767 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
NODE_ENV=development

View File

@ -1,7 +1,4 @@
const CracoLessPlugin = require('craco-less'); const CracoLessPlugin = require('craco-less');
function resolve(dir) {
return path.join(__dirname, dir);
}
const path = require('path'); const path = require('path');
module.exports = { module.exports = {
plugins: [ plugins: [
@ -18,11 +15,17 @@ module.exports = {
}, },
], ],
webpack: { webpack: {
entry: {
main: ['whatwg-fetch', './src/index.js'],
},
configure: (webpackConfig, { env, paths }) => { configure: (webpackConfig, { env, paths }) => {
// 修改output.publicPath为'./' // 修改output.publicPath为'./'
// webpackConfig.output.publicPath = './'; // webpackConfig.output.publicPath = './';
webpackConfig.output.path = path.join(__dirname,"/build"); // webpackConfig.output.path = path.join(__dirname,"/build");
webpackConfig.output.publicPath = "./"; // webpackConfig.output.publicPath = "./";
webpackConfig.output.path = path.join(__dirname,);
webpackConfig.output.publicPath = "";
// webpackConfig.output.module // webpackConfig.output.module
// .rule("icons") // .rule("icons")
// .test(/\.svg$/) // .test(/\.svg$/)
@ -40,7 +43,12 @@ module.exports = {
// 将@/*映射为src目录 // 将@/*映射为src目录
'@': path.resolve(__dirname, 'src/'), '@': path.resolve(__dirname, 'src/'),
}, },
} // 确保入口文件正确
// entry: {
// main: ['whatwg-fetch', './src/index.js'],
// },
},
devServer: {
port: 3008, // 设置端口
},
}; };

View File

@ -20,6 +20,10 @@ class UploadUtils {
UploadUtils.staticStore = store; UploadUtils.staticStore = store;
} }
getActiveFile() { getActiveFile() {
let persist = this.store.get("persist:tableBarItem");
if (persist === undefined){
return undefined
}
let tableBarItem = JSON.parse(this.store.get("persist:tableBarItem")); let tableBarItem = JSON.parse(this.store.get("persist:tableBarItem"));
if (!tableBarItem) { if (!tableBarItem) {
return; return;

19
main.js
View File

@ -1,4 +1,4 @@
const {app, Menu, BrowserWindow,ipcMain,dialog} = require('electron') const {app, Menu, BrowserWindow,ipcMain,dialog,shell } = require('electron')
const path = require('path') const path = require('path')
const {menuRebuild} = require('./elsrc/TopMenu.js') const {menuRebuild} = require('./elsrc/TopMenu.js')
const UploadUtils = require("./elsrc/sync/tencent/UploadUtils") const UploadUtils = require("./elsrc/sync/tencent/UploadUtils")
@ -15,21 +15,24 @@ const createWindow = () => {
nodeIntegration: true, nodeIntegration: true,
// 启用后nodeIntegration会无效 // 启用后nodeIntegration会无效
contextIsolation: false, contextIsolation: false,
// 添加预加载脚本
// __dirname 字符串指向当前正在执行脚本的路径
// path.join API 将多个路径联结在一起,创建一个跨平台的路径字符串。
preload: path.join(__dirname, 'preload.js') preload: path.join(__dirname, 'preload.js')
} }
}) })
console.log("isDev", isDev)
if (isDev){ if (isDev){
// 加载 index.html // 加载 index.html
win.loadURL('http://localhost:3000') win.loadURL('http://localhost:3008')
// 打开开发工具 // 打开开发工具
win.webContents.openDevTools() win.webContents.openDevTools()
}else { }else {
// 加载 index.html // 加载 index.html
win.loadFile('./index.html') win.loadFile('./index.html')
} }
win.maximize()
// let okPush =false // let okPush =false
let devToolPush = 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)
if (input.control && input.key.toLowerCase() === 's' && input.type.toLowerCase() === "keydown" && input.isAutoRepeat === false) { if (input.control && input.key.toLowerCase() === 's' && input.type.toLowerCase() === "keydown" && input.isAutoRepeat === false) {
@ -40,7 +43,7 @@ const createWindow = () => {
event.preventDefault() event.preventDefault()
} }
// console.log('Pressed ',input.key) // console.log('Pressed ',input.key)
if (input.key.toUpperCase() === 'F5' && input.type.toLowerCase() === "keydown" && input.isAutoRepeat === false) { if (input.key.toUpperCase() === 'F5' && input.isAutoRepeat === false) {
win.reload() win.reload()
} }
if (input.key.toUpperCase() === 'F12' && input.type.toLowerCase() === "keydown" && input.isAutoRepeat === false) { if (input.key.toUpperCase() === 'F12' && input.type.toLowerCase() === "keydown" && input.isAutoRepeat === false) {
@ -90,6 +93,12 @@ app.whenReady().then(() => {
console.log("electronStoreDelete") console.log("electronStoreDelete")
return store.delete(args) return store.delete(args)
}) })
ipcMain.handle("showOpenDialog",(listen,args)=>{
console.log("showOpenDialog:"+args)
// return dialog.showOpenDialog({defaultPath:args.filePath,
// properties: ['openFile']} )
return shell.openPath(args)
})
console.log("配置文件地址",app.getPath('userData')+"/config.json") console.log("配置文件地址",app.getPath('userData')+"/config.json")
console.log("操作系统:"+process.platform) console.log("操作系统:"+process.platform)
}) })

6787
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
{ {
"name": "my-electron-app", "name": "assistant-note",
"version": "1.0.0", "version": "1.0.0",
"description": "Hello World!", "description": "note",
"main": "main.js", "main": "main.js",
"author": "hua", "author": "hua",
"license": "MIT", "license": "MIT",
"dependencies": { "devDependencies": {
"@ant-design/icons": "^5.3.7", "@ant-design/icons": "^5.3.7",
"@ant-design/pro-components": "^2.3.57", "@ant-design/pro-components": "^2.3.57",
"@craco/craco": "^6.0.0", "@craco/craco": "^6.4.5",
"@electron-forge/cli": "^6.0.4", "@electron-forge/cli": "^6.0.4",
"@electron-forge/maker-deb": "^6.0.4", "@electron-forge/maker-deb": "^6.0.4",
"@electron-forge/maker-rpm": "^6.0.4", "@electron-forge/maker-rpm": "^6.0.4",
@ -54,10 +54,10 @@
"yjs": ">=13.5.42" "yjs": ">=13.5.42"
}, },
"scripts": { "scripts": {
"dev": "concurrently \"wait-on http://localhost:3000 && electron .\" \"cross-env BROWSER=none npm start\"", "dev": "concurrently \"wait-on --log http://127.0.0.1:3008 && electron .\" \"cross-env BROWSER=none npm start\"",
"start": "craco start --verbose", "start": "craco start --verbose",
"build": "craco build", "build": "craco build",
"startel": "electron .", "startel": "set NODE_ENV=development&&electron .",
"package": "electron-forge package", "package": "electron-forge package",
"make": "electron-forge make" "make": "electron-forge make"
}, },

View File

@ -1,3 +1,4 @@
// 通过预加载脚本从渲染器访问Node.js
// 预加载脚本 在上下文隔离渲染器进程中导入 Node.js 和 Electron 模块的概念 // 预加载脚本 在上下文隔离渲染器进程中导入 Node.js 和 Electron 模块的概念
// 所有的 Node.js API接口 都可以在 preload 进程中被调用. // 所有的 Node.js API接口 都可以在 preload 进程中被调用.
// 它拥有与Chrome扩展一样的沙盒。 // 它拥有与Chrome扩展一样的沙盒。

View File

@ -4,7 +4,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<!-- %PUBLIC_URL% public 文件夹 --> <!-- %PUBLIC_URL% public 文件夹 -->
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="favicon.ico" />
<!-- 移动端网页适配 --> <!-- 移动端网页适配 -->
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- 配置浏览器页签+地址颜色,仅适用于android --> <!-- 配置浏览器页签+地址颜色,仅适用于android -->
@ -15,11 +15,7 @@
<!-- 应用加壳 --> <!-- 应用加壳 -->
<!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> --> <!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> -->
<title>Note</title> <title>Note</title>
<!--[if IE]> <!-- <script src="index.jsx"></script>-->
<script src="js/html5.js"></script>
<![endif]-->
<script src="index.jsx"></script>
</head> </head>
<body> <body>

View File

@ -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>
) )
} }

View File

@ -166,6 +166,7 @@ const ItemTree = (prop) => {
const [defaultValueState, setDefaultValueState] = useState(flushTree(prop.filePath)); const [defaultValueState, setDefaultValueState] = useState(flushTree(prop.filePath));
generateList(defaultValueState); generateList(defaultValueState);
const [state, setState] = useState(); const [state, setState] = useState();
const [inFrame, setInFrame] = useState(true);
useEffect(() => { useEffect(() => {
setDefaultValueState(flushTree(prop.filePath)) setDefaultValueState(flushTree(prop.filePath))
}, [prop]); }, [prop]);
@ -294,7 +295,18 @@ const ItemTree = (prop) => {
}); });
} }
const getNodeTreeRightClickMenu = () => { const getNodeTreeRightClickMenu = () => {
console.log("state", state, isEmpty(state)) useEffect(() => {
const handleKeyDown = (event) => {
if (!inFrame) {
event.preventDefault(); //
setState("");
}
};
document.addEventListener('click', handleKeyDown);
return () => {
document.removeEventListener('click', handleKeyDown);
};
});
if (isEmpty(state)) { if (isEmpty(state)) {
return return
} }
@ -321,6 +333,7 @@ const ItemTree = (prop) => {
menuItem.push(getMenuItem('6',<DirDeleteFile filePath={key} />)) menuItem.push(getMenuItem('6',<DirDeleteFile filePath={key} />))
} }
menuItem.push(getMenuItem('7',<OpenInDir filePath={key} />)) menuItem.push(getMenuItem('7',<OpenInDir filePath={key} />))
return <Fragment> return <Fragment>
{createPortal( {createPortal(
<Menu style={tmpStyle} onClick={e => <Menu style={tmpStyle} onClick={e =>
@ -328,7 +341,18 @@ const ItemTree = (prop) => {
console.log('onClick',e) console.log('onClick',e)
} }
} }
onMouseLeave={e => {setState("");}} //
onMouseLeave={e => {
console.log('onMouseLeave',e)
// setState("");
setInFrame(false)
}}
//
onMouseEnter={e => {
console.log('onMouseEnter',e)
// setState("");
setInFrame(true)
}}
items={menuItem}> items={menuItem}>
</Menu>, </Menu>,
document.body document.body

View File

@ -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 {

View File

@ -8,7 +8,7 @@ import { BrowserRouter } from 'react-router-dom';
import {PersistGate} from "redux-persist/integration/react"; import {PersistGate} from "redux-persist/integration/react";
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( root.render(
// <React.StrictMode> <React.StrictMode>
<Provider store={store}> <Provider store={store}>
<PersistGate loading={null} persistor={persistor}> <PersistGate loading={null} persistor={persistor}>
<BrowserRouter> <BrowserRouter>
@ -16,5 +16,5 @@ root.render(
</BrowserRouter> </BrowserRouter>
</PersistGate> </PersistGate>
</Provider> </Provider>
// </React.StrictMode> </React.StrictMode>
); );

View File

@ -11,6 +11,7 @@ import {
TRANSFORMERS, $convertFromMarkdownString, TRANSFORMERS, $convertFromMarkdownString,
} from "@lexical/markdown"; } from "@lexical/markdown";
import "@/pages/Note/Hlexical/index.less" import "@/pages/Note/Hlexical/index.less"
import "@/pages/Note/Hlexical/theme.less"
import {importFile} from "@/utils/File" import {importFile} from "@/utils/File"
import {isEmpty} from "@/utils/ObjectUtils"; import {isEmpty} from "@/utils/ObjectUtils";
@ -31,11 +32,12 @@ import TableCellActionMenuPlugin from '@/pages/Note/Hlexical/plugins/TableAction
import ExcalidrawPlugin from "@/pages/Note/Hlexical/plugins/ExcalidrawPlugin"; import ExcalidrawPlugin from "@/pages/Note/Hlexical/plugins/ExcalidrawPlugin";
import TableOfContentsPlugin from "@/pages/Note/Hlexical/plugins/TableOfContentsPlugin"; import TableOfContentsPlugin from "@/pages/Note/Hlexical/plugins/TableOfContentsPlugin";
import ContextMenuPlugin from "@/pages/Note/Hlexical/plugins/ContextMenuPlugin" import ContextMenuPlugin from "@/pages/Note/Hlexical/plugins/ContextMenuPlugin"
import {Spin,FloatButton } from "antd"; import {Spin, FloatButton} from "antd";
import { CommentOutlined, CustomerServiceOutlined } from '@ant-design/icons'; import {CommentOutlined, CustomerServiceOutlined} from '@ant-design/icons';
import {useState} from "react"; import {useState} from "react";
import DragDropPaste from "@/pages/Note/Hlexical/plugins/DragDropPastePlugin"; import DragDropPaste from "@/pages/Note/Hlexical/plugins/DragDropPastePlugin";
import TreeViewPlugin from "@/pages/Note/Hlexical/plugins/TreeViewPlugin"; import TreeViewPlugin from "@/pages/Note/Hlexical/plugins/TreeViewPlugin";
function Placeholder() { function Placeholder() {
return <div className="editor-placeholder">记录一些灵感吧</div>; return <div className="editor-placeholder">记录一些灵感吧</div>;
} }
@ -48,88 +50,90 @@ export default function Hlexical(props) {
}, },
nodes: UsefulNodes nodes: UsefulNodes
}; };
const [spinningState,setSpinningState]=useState(!isEmpty(props.filePath)) const [spinningState, setSpinningState] = useState(!isEmpty(props.filePath))
console.log("Hlexical(props):this.props.filePath:", props.filePath) console.log("Hlexical(props):this.props.filePath:", props.filePath)
if (!isEmpty(props.filePath)&&props.filePath.endsWith(".md")){ if (!isEmpty(props.filePath) && props.filePath.endsWith(".md")) {
let promise = importFile(props.filePath); let promise = importFile(props.filePath);
promise.then(value => { promise.then(value => {
if (isEmpty(value)) { if (isEmpty(value)) {
setSpinningState(false) setSpinningState(false)
return return
} }
editorConfig={...editorConfig,editorState: () => $convertFromMarkdownString(value.toString(), TRANSFORMERS)} editorConfig = {
...editorConfig,
editorState: () => $convertFromMarkdownString(value.toString(), TRANSFORMERS)
}
setSpinningState(false) setSpinningState(false)
}).catch(error => }).catch(error =>
console.error(error) console.error(error)
) )
} }
return ( return (
// <Spin size="large" fullscreen="ture" spinning={spinningState}>
<LexicalComposer initialConfig={editorConfig}>
<div className="editor-container">
{/* 富文本插件 */}
<ToolbarPlugin/>
<div className="editor-inner">
<LexicalComposer initialConfig={editorConfig}> <RichTextPlugin
<div className="editor-container"> contentEditable={<ContentEditable className="editor-input"/>}
{/* 富文本插件 */} placeholder={<Placeholder/>}
<ToolbarPlugin/> ErrorBoundary={LexicalErrorBoundary}
<div className="editor-inner"> />
<Spin size="large" fullscreen="ture" spinning={spinningState}>
<RichTextPlugin
contentEditable={<ContentEditable className="editor-input"/>}
placeholder={<Placeholder/>}
ErrorBoundary={LexicalErrorBoundary}
/> </Spin>
<HistoryPlugin/>
{/*黑窗口动态记录当前操作*/}
{/*<TreeViewPlugin/>*/}
<AutoFocusPlugin/>
<CodeHighlightPlugin/>
<ListPlugin/>
<LinkPlugin/>
<AutoLinkPlugin/>
<ListMaxIndentLevelPlugin maxDepth={7}/>
{/* 表格操作 */}
<TablePlugin
hasCellMerge={true}
hasCellBackgroundColor={true}
/>
{/* 表格单元格操作 */}
<TableCellActionMenuPlugin/>
<TabIndentationPlugin/>
{/*markdown 快捷键*/}
<MarkdownShortcutPlugin transformers={TRANSFORMERS}/>
{/*图片加载*/}
<ImagesPlugin captionsEnabled={true}/>
<InlineImagePlugin/>
{/*分割线 */} <HistoryPlugin/>
<HorizontalRulePlugin/> {/*黑窗口动态记录当前操作*/}
{/*页分割线*/} {/*<TreeViewPlugin/>*/}
<AutoFocusPlugin/>
<CodeHighlightPlugin/>
<ListPlugin/>
<LinkPlugin/>
<AutoLinkPlugin/>
<ListMaxIndentLevelPlugin maxDepth={7}/>
{/* 表格操作 */}
<TablePlugin
hasCellMerge={true}
hasCellBackgroundColor={true}
/>
{/* 表格单元格操作 */}
<TableCellActionMenuPlugin/>
<TabIndentationPlugin/>
{/*markdown 快捷键*/}
<MarkdownShortcutPlugin transformers={TRANSFORMERS}/>
{/*图片加载*/}
<ImagesPlugin captionsEnabled={true}/>
<InlineImagePlugin/>
{/*目录加载*/} {/*分割线 */}
<TableOfContentsPlugin filePath={props.filePath}/> <HorizontalRulePlugin/>
{/*右键菜单*/} {/*页分割线*/}
<ContextMenuPlugin/>
{/* 画图 */} {/*目录加载*/}
<ExcalidrawPlugin/> <TableOfContentsPlugin filePath={props.filePath}/>
{/* 拖拽复制*/} {/*右键菜单*/}
<DragDropPaste /> <ContextMenuPlugin/>
<ImportFilePlugin filePath={props.filePath} setSpinningState={setSpinningState}/> {/* 画图 */}
<SaveFilePlugin filePath={props.filePath}/> <ExcalidrawPlugin/>
{/*文件操作导入文件*/} {/* 拖拽复制*/}
{/*<ActionPlugin/>*/} <DragDropPaste/>
<FloatButton.Group <ImportFilePlugin filePath={props.filePath} setSpinningState={setSpinningState}/>
trigger="hover" <SaveFilePlugin filePath={props.filePath}/>
type="primary" {/*文件操作导入文件*/}
style={{ {/*<ActionPlugin/>*/}
right: 94, <FloatButton.Group
}} trigger="hover"
icon={<CustomerServiceOutlined />} type="primary"
> style={{
<FloatButton /> right: 94,
<FloatButton icon={<CommentOutlined />} /> }}
</FloatButton.Group> icon={<CustomerServiceOutlined/>}>
<FloatButton/>
<FloatButton icon={<CommentOutlined/>}/>
</FloatButton.Group>
</div>
</div> </div>
</div> </LexicalComposer>
// </Spin>
</LexicalComposer>
); );
} }

View File

@ -55,16 +55,11 @@ 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;
height: 95%; margin:20px;
height: 90%;
overflow: hidden auto; overflow: hidden auto;
} }
@ -93,38 +88,6 @@ h1 {
pointer-events: none; pointer-events: none;
} }
.editor-text-bold {
font-weight: bold;
}
.editor-text-italic {
font-style: italic;
}
.editor-text-underline {
text-decoration: underline;
}
.editor-text-strikethrough {
text-decoration: line-through;
}
.editor-text-underlineStrikethrough {
text-decoration: underline line-through;
}
.editor-text-code {
background-color: rgb(240, 242, 245);
padding: 1px 0.25rem;
font-family: Menlo, Consolas, Monaco, monospace;
font-size: 94%;
}
.editor-link {
color: rgb(33, 111, 219);
text-decoration: none;
}
.tree-view-output { .tree-view-output {
display: block; display: block;
background: #222; background: #222;
@ -141,177 +104,6 @@ h1 {
line-height: 14px; line-height: 14px;
} }
.editor-code {
background-color: rgb(240, 242, 245);
font-family: Menlo, Consolas, Monaco, monospace;
display: block;
padding: 8px 8px 8px 52px;
line-height: 1.53;
font-size: 13px;
margin: 0;
margin-top: 8px;
margin-bottom: 8px;
tab-size: 2;
white-space: pre;
overflow: auto;
position: relative;
}
.editor-code:before {
content: attr(data-gutter);
position: absolute;
background-color: #eee;
left: 0;
top: 0;
border-right: 1px solid #ccc;
padding: 8px;
color: #777;
white-space: pre-wrap;
text-align: right;
min-width: 25px;
}
.editor-code:after {
content: attr(data-highlight-language);
top: 0;
right: 3px;
padding: 3px;
font-size: 10px;
text-transform: uppercase;
position: absolute;
color: rgba(0, 0, 0, 0.5);
}
.editor-tokenComment {
color: slategray;
}
.editor-tokenPunctuation {
color: #999;
}
.editor-tokenProperty {
color: #905;
}
.editor-tokenSelector {
color: #690;
}
.editor-tokenOperator {
color: #9a6e3a;
}
.editor-tokenAttr {
color: #07a;
}
.editor-tokenVariable {
color: #e90;
}
.editor-tokenFunction {
color: #dd4a68;
}
.editor-paragraph {
margin: 0;
margin-bottom: 8px;
position: relative;
}
.editor-paragraph:last-child {
margin-bottom: 0;
}
.editor-heading-h1 {
font-size: 50px;
color: rgb(5, 5, 5);
font-weight: 400;
margin: 0;
margin-bottom: 25px;
padding: 0;
}
.editor-heading-h2 {
font-size: 45px;
//color: rgb(101, 103, 107);
//font-weight: 400;
color: rgb(5, 5, 5);
font-weight: 400;
margin: 0;
margin-top: 25px;
padding: 0;
//text-transform: uppercase;
}
.editor-heading-h3 {
font-size: 40px;
color: rgb(5, 5, 5);
font-weight: 400;
margin: 0;
margin-top: 20px;
padding: 0;
//text-transform: uppercase;
}
.editor-heading-h4 {
font-size: 35px;
color: rgb(5, 5, 5);
font-weight: 400;
margin: 0;
margin-top: 20px;
padding: 0;
//text-transform: uppercase;
}
.editor-heading-h5 {
font-size: 30px;
color: rgb(5, 5, 5);
font-weight: 400;
margin: 0;
margin-top: 15px;
padding: 0;
//text-transform: uppercase;
}
.editor-heading-h6 {
font-size: 25px;
color: rgb(5, 5, 5);
font-weight: 400;
margin: 0;
margin-top: 15px;
padding: 0;
//text-transform: uppercase;
}
.editor-quote {
margin: 0;
margin-left: 20px;
font-size: 15px;
color: rgb(101, 103, 107);
border-left-color: rgb(206, 208, 212);
border-left-width: 4px;
border-left-style: solid;
padding-left: 16px;
}
.editor-list-ol {
padding: 0;
margin: 0;
margin-left: 16px;
}
.editor-list-ul {
padding: 0;
margin: 0;
margin-left: 16px;
}
.editor-listitem {
margin: 8px 32px 8px 32px;
}
.editor-nested-listitem {
list-style-type: none;
}
pre::-webkit-scrollbar { pre::-webkit-scrollbar {
background: transparent; background: transparent;
width: 10px; width: 10px;
@ -389,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;
@ -814,143 +609,6 @@ i.justify-align {
background-image: url(images/icons/justify.svg); background-image: url(images/icons/justify.svg);
} }
.editor-table {
border-collapse: collapse;
border-spacing: 0;
overflow-y: scroll;
overflow-x: scroll;
table-layout: fixed;
width: max-content;
margin: 30px 0;
}
.editor-tableSelection *::selection {
background-color: transparent;
}
.editor-tableSelected {
outline: 2px solid rgb(60, 132, 244);
}
.editor-tableCell {
border: 1px solid #bbb;
width: 75px;
min-width: 75px;
vertical-align: top;
text-align: start;
padding: 6px 8px;
position: relative;
outline: none;
}
.editor-tableCellSortedIndicator {
display: block;
opacity: 0.5;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 4px;
background-color: #999;
}
.editor-tableCellResizer {
position: absolute;
right: -4px;
height: 100%;
width: 8px;
cursor: ew-resize;
z-index: 10;
top: 0;
}
.editor-tableCellHeader {
background-color: #f2f3f5;
text-align: start;
}
.editor-tableCellSelected {
background-color: #c9dbf0;
}
.editor-tableCellPrimarySelected {
border: 2px solid rgb(60, 132, 244);
display: block;
height: calc(100% - 2px);
position: absolute;
width: calc(100% - 2px);
left: -1px;
top: -1px;
z-index: 2;
}
.editor-tableCellEditing {
box-shadow: 0 0 5px rgba(0, 0, 0, 0.4);
border-radius: 3px;
}
.editor-tableAddColumns {
position: absolute;
top: 0;
width: 20px;
background-color: #eee;
height: 100%;
right: -25px;
animation: table-controls 0.2s ease;
border: 0;
cursor: pointer;
}
.editor-tableAddColumns:after {
background-image: url(images/icons/plus.svg);
background-size: contain;
background-position: center;
background-repeat: no-repeat;
display: block;
content: ' ';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.4;
}
.editor-tableAddColumns:hover {
background-color: #c9dbf0;
}
.editor-tableAddRows {
position: absolute;
bottom: -25px;
width: calc(100% - 25px);
background-color: #eee;
height: 20px;
left: 0;
animation: table-controls 0.2s ease;
border: 0;
cursor: pointer;
}
.editor-tableAddRows:after {
background-image: url(images/icons/plus.svg);
background-size: contain;
background-position: center;
background-repeat: no-repeat;
display: block;
content: ' ';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.4;
}
.editor-tableAddRows:hover {
background-color: #c9dbf0;
}
@keyframes table-controls { @keyframes table-controls {
0% { 0% {
opacity: 0; opacity: 0;
@ -960,37 +618,4 @@ i.justify-align {
} }
} }
.editor-tableCellResizeRuler {
display: block;
position: absolute;
width: 1px;
background-color: rgb(60, 132, 244);
height: 100%;
top: 0;
}
.editor-tableCellActionButtonContainer {
display: block;
right: 5px;
top: 6px;
position: absolute;
z-index: 4;
width: 20px;
height: 20px;
}
.editor-tableCellActionButton {
background-color: #eee;
display: block;
border: 0;
border-radius: 20px;
width: 20px;
height: 20px;
color: #222;
cursor: pointer;
}
.editor-tableCellActionButton:hover {
background-color: #ddd;
}

View File

@ -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

View File

@ -0,0 +1,371 @@
.editor-text-bold {
font-weight: bold;
}
.editor-text-italic {
font-style: italic;
}
.editor-text-underline {
text-decoration: underline;
}
.editor-text-strikethrough {
text-decoration: line-through;
}
.editor-text-underlineStrikethrough {
text-decoration: underline line-through;
}
.editor-text-code {
background-color: rgb(240, 242, 245);
padding: 1px 0.25rem;
font-family: Menlo, Consolas, Monaco, monospace;
font-size: 94%;
}
.editor-link {
color: rgb(33, 111, 219);
text-decoration: none;
}
.editor-code {
background-color: rgb(240, 242, 245);
font-family: Menlo, Consolas, Monaco, monospace;
display: block;
padding: 8px 8px 8px 52px;
line-height: 1.53;
font-size: 13px;
margin: 0;
margin-top: 8px;
margin-bottom: 8px;
tab-size: 2;
white-space: pre;
overflow: auto;
position: relative;
}
.editor-code:before {
content: attr(data-gutter);
position: absolute;
background-color: #eee;
left: 0;
top: 0;
border-right: 1px solid #ccc;
padding: 8px;
color: #777;
white-space: pre-wrap;
text-align: right;
min-width: 25px;
}
.editor-code:after {
content: attr(data-highlight-language);
top: 0;
right: 3px;
padding: 3px;
font-size: 10px;
text-transform: uppercase;
position: absolute;
color: rgba(0, 0, 0, 0.5);
}
.editor-tokenComment {
color: slategray;
}
.editor-tokenPunctuation {
color: #999;
}
.editor-tokenProperty {
color: #905;
}
.editor-tokenSelector {
color: #690;
}
.editor-tokenOperator {
color: #9a6e3a;
}
.editor-tokenAttr {
color: #07a;
}
.editor-tokenVariable {
color: #e90;
}
.editor-tokenFunction {
color: #dd4a68;
}
.editor-paragraph {
margin: 0;
margin-bottom: 8px;
position: relative;
}
.editor-paragraph:last-child {
margin-bottom: 0;
}
.editor-heading-h1 {
//font-size: 50px;
//color: rgb(5, 5, 5);
//font-weight: 400;
//margin: 0;
//margin-bottom: 25px;
//padding: 0;
}
.editor-heading-h2 {
//font-size: 45px;
//color: rgb(101, 103, 107);
//font-weight: 400;
//color: rgb(5, 5, 5);
//font-weight: 400;
//margin: 0;
//margin-top: 25px;
//padding: 0;
//text-transform: uppercase;
}
.editor-heading-h3 {
//font-size: 40px;
//color: rgb(5, 5, 5);
//font-weight: 400;
//margin: 0;
//margin-top: 20px;
//padding: 0;
//text-transform: uppercase;
}
.editor-heading-h4 {
//font-size: 35px;
//color: rgb(5, 5, 5);
//font-weight: 400;
//margin: 0;
//margin-top: 20px;
//padding: 0;
//text-transform: uppercase;
}
.editor-heading-h5 {
//font-size: 30px;
//color: rgb(5, 5, 5);
//font-weight: 400;
//margin: 0;
//margin-top: 15px;
//padding: 0;
//text-transform: uppercase;
}
.editor-heading-h6 {
//font-size: 25px;
//color: rgb(5, 5, 5);
//font-weight: 400;
//margin: 0;
//margin-top: 15px;
//padding: 0;
//text-transform: uppercase;
}
.editor-quote {
margin: 0;
margin-left: 20px;
font-size: 15px;
color: rgb(101, 103, 107);
border-left-color: rgb(206, 208, 212);
border-left-width: 4px;
border-left-style: solid;
padding-left: 16px;
}
.editor-list-ol {
padding: 0;
margin: 0;
margin-left: 16px;
}
.editor-list-ul {
padding: 0;
margin: 0;
margin-left: 16px;
}
.editor-listitem {
margin: 8px 32px 8px 32px;
}
.editor-nested-listitem {
list-style-type: none;
}
.editor-table {
border-collapse: collapse;
border-spacing: 0;
overflow-y: scroll;
overflow-x: scroll;
table-layout: fixed;
width: max-content;
margin: 30px 0;
}
.editor-tableSelection *::selection {
background-color: transparent;
}
.editor-tableSelected {
outline: 2px solid rgb(60, 132, 244);
}
.editor-tableCell {
border: 1px solid #bbb;
width: 75px;
min-width: 75px;
vertical-align: top;
text-align: start;
padding: 6px 8px;
position: relative;
outline: none;
}
.editor-tableCellSortedIndicator {
display: block;
opacity: 0.5;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 4px;
background-color: #999;
}
.editor-tableCellResizer {
position: absolute;
right: -4px;
height: 100%;
width: 8px;
cursor: ew-resize;
z-index: 10;
top: 0;
}
.editor-tableCellHeader {
background-color: #f2f3f5;
text-align: start;
}
.editor-tableCellSelected {
background-color: #c9dbf0;
}
.editor-tableCellPrimarySelected {
border: 2px solid rgb(60, 132, 244);
display: block;
height: calc(100% - 2px);
position: absolute;
width: calc(100% - 2px);
left: -1px;
top: -1px;
z-index: 2;
}
.editor-tableCellEditing {
box-shadow: 0 0 5px rgba(0, 0, 0, 0.4);
border-radius: 3px;
}
.editor-tableAddColumns {
position: absolute;
top: 0;
width: 20px;
background-color: #eee;
height: 100%;
right: -25px;
animation: table-controls 0.2s ease;
border: 0;
cursor: pointer;
}
.editor-tableAddColumns:after {
background-image: url(images/icons/plus.svg);
background-size: contain;
background-position: center;
background-repeat: no-repeat;
display: block;
content: ' ';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.4;
}
.editor-tableAddColumns:hover {
background-color: #c9dbf0;
}
.editor-tableAddRows {
position: absolute;
bottom: -25px;
width: calc(100% - 25px);
background-color: #eee;
height: 20px;
left: 0;
animation: table-controls 0.2s ease;
border: 0;
cursor: pointer;
}
.editor-tableAddRows:after {
background-image: url(images/icons/plus.svg);
background-size: contain;
background-position: center;
background-repeat: no-repeat;
display: block;
content: ' ';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.4;
}
.editor-tableAddRows:hover {
background-color: #c9dbf0;
}
.editor-tableCellResizeRuler {
display: block;
position: absolute;
width: 1px;
background-color: rgb(60, 132, 244);
height: 100%;
top: 0;
}
.editor-tableCellActionButtonContainer {
display: block;
right: 5px;
top: 6px;
position: absolute;
z-index: 4;
width: 20px;
height: 20px;
}
.editor-tableCellActionButton {
background-color: #eee;
display: block;
border: 0;
border-radius: 20px;
width: 20px;
height: 20px;
color: #222;
cursor: pointer;
}
.editor-tableCellActionButton:hover {
background-color: #ddd;
}

View File

@ -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>
); );
}; };

View File

@ -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;
} //}

View File

@ -1,15 +1,15 @@
// const {createProxyMiddleware} = require('http-proxy-middleware') const {createProxyMiddleware} = require('http-proxy-middleware')
// module.exports=function(app){ module.exports=function(app){
// app.use( app.use(
// createProxyMiddleware('/ticai',{ createProxyMiddleware('/ticai',{
// target:'http://localhost:8090/', target:'http://localhost:8090/',
// changeOrigin:false, changeOrigin:false,
// pathRewrite:{'^/ticai':''} pathRewrite:{'^/ticai':''}
// }), }),
// createProxyMiddleware('/oauth',{ createProxyMiddleware('/oauth',{
// target:'http://localhost:1112', target:'http://localhost:1112',
// changeOrigin:true, changeOrigin:true,
// pathRewrite:{'^/oauth':''} pathRewrite:{'^/oauth':''}
// }) })
// ) )
// } }

View File

@ -54,5 +54,7 @@ export async function saveFileWithName(){
} }
export async function openInDir(filePath){ export async function openInDir(filePath){
return dialog.showOpenDialog({defaultPath:"filePath",properties: ['openDirectory']} ) // return dialog.showOpenDialog({defaultPath:filePath,properties: ['openDirectory']} )
console.log("pathOp.dirname(filePath.filePath)"+pathOp.dirname(filePath.filePath))
return ipcRenderer.invoke("showOpenDialog",pathOp.dirname(filePath.filePath))
} }