feat:树文件夹保存

This commit is contained in:
shixiaohua 2024-02-05 10:59:35 +08:00
parent 15408649d0
commit 93bf0deb5f
5 changed files with 139 additions and 54 deletions

View File

@ -4,10 +4,12 @@ import {Outlet, useNavigate, useRoutes} from 'react-router-dom'
import useIpcRenderer from '../src/utils/useIpcRenderer'
import {dirAdd} from "./redux/dirMessage_reducer";
import {pushHotkeys} from "./redux/pushHotkeys_reducer";
import {store} from "./redux/store";
import {useDispatch} from "react-redux";
function App() {
let navigateFunction = useNavigate();
let dispatch = useDispatch();
function nativeTo(path){
navigateFunction(path)
}
@ -15,11 +17,11 @@ function App() {
nativeTo(args)
}
const addNewDir =(event,args)=> {
store.dispatch(dirAdd(args))
dispatch(dirAdd(args))
}
const pushHotkeysAction =(event,args)=> {
console.log("store.dispatch(pushHotkeys(args))",args)
store.dispatch(pushHotkeys(args))
dispatch(pushHotkeys(args))
}
console.log("routes",routes)

View File

@ -1,6 +1,32 @@
const {app, Menu, shell, dialog} = require('electron')
const {stat, readdir} = require("fs/promises");
const isMac = process.platform === 'darwin'
const readDirLocal=async (filePath) => {
const files = await readdir(filePath);
const fileStateList = []
const fileChildList = []
fileStateList.push({
"fileName": filePath,
"filePath": filePath,
"dirFlag": true,
"childList": fileChildList
})
for (let i = 0; i < files.length; i++) {
const state = await stat(filePath + '/' + files[i]);
if (state.isDirectory()
|| files[i].endsWith(".md")
|| files[i].endsWith(".html")
|| files[i].endsWith(".lexical")) {
fileChildList.push({
'fileName': files[i],
"filePath": filePath + '/' + files[i],
'dirFlag': state.isDirectory(),
"childList":[]
})
}
}
return fileStateList
}
exports.menuRebuild = (mainWindow) => {
return template = [
// { role: 'appMenu' }
@ -34,31 +60,8 @@ exports.menuRebuild = (mainWindow) => {
// 不取消就发送目录
if (!result.canceled) {
console.log('result.filePaths', result.filePaths)
const {readdir, stat} = require('fs/promises')
try {
const files = await readdir(result.filePaths[0]);
const fileStateList = []
const fileChildList = []
fileStateList.push({
"fileName": result.filePaths[0],
"filePath": result.filePaths[0],
"dirFlag": true,
"childList": fileChildList
})
for (let i = 0; i < files.length; i++) {
const state = await stat(result.filePaths[0] + '/' + files[i]);
if (state.isDirectory()
||files[i].endsWith(".md")
||files[i].endsWith(".html")
||files[i].endsWith(".lexical")){
fileChildList.push({
'fileName': files[i],
"filePath": result.filePaths[0]+ '/' +files[i],
'dirFlag': state.isDirectory()
})
}
}
mainWindow.webContents.send('openDirectory', fileStateList)
mainWindow.webContents.send('openDirectory', readDirLocal(result.filePaths[0]))
} catch (err) {
console.error(err);
}

View File

@ -3,10 +3,10 @@ import {Input, Tree} from 'antd';
import {FolderOutlined, FileMarkdownOutlined,FileOutlined} from '@ant-design/icons';
import "./index.less"
const {Search} = Input;
import {store} from "../../redux/store";
import {useSelector,useDispatch} from "react-redux";
import {addTableBarItem} from "../../redux/tableBarItem_reducer";
import {readDir} from "../../utils/File";
import {nextDirAdd} from "../../redux/dirMessage_reducer";
const defaultData = [];
//
const dataList = [];
@ -43,14 +43,17 @@ const getParentKey = (key, tree) => {
function generateChildList(fileList) {
const result = []
for (let i = 0; i < fileList.length; i++) {
const {fileName, filePath, dirFlag} = fileList[i];
const {fileName, filePath, dirFlag,childList} = fileList[i];
const childListM = []
if (Array.isArray(childList)&&childList.length > 0) {
childListM.push(...generateChildList(childList));
}
result.push({
"key": filePath,
"title": fileName,
"icon": dirFlag?<FolderOutlined/>:fileName.endsWith(".md")?<FileMarkdownOutlined/>:<FileOutlined />,
"dirFlag": dirFlag,
"children": []
"children": childListM
});
}
return result;
@ -107,16 +110,24 @@ const ItemTree = () => {
setAutoExpandParent(true);
};
const onSelect = (selectedKeys, e) => {
if (e.selected && !e.node.dirFlag) {
if (e.selected) {
console.log('onSelect.selectedKeys', selectedKeys, e)
dispatch(addTableBarItem(
{
label: e.node.title,
children: e.node.key,
key: e.node.key,
activeKey:e.node.key
}
))
if (e.node.dirFlag){
//
readDir(e.node.key).then(fileStateList=>{
dispatch(nextDirAdd({selectDirKey:e.node.key,fileStateList}))
})
}else {
//
dispatch(addTableBarItem(
{
label: e.node.title,
children: e.node.key,
key: e.node.key,
activeKey:e.node.key
}
))
}
}
}
// const treeData = useMemo(() => {

View File

@ -1,30 +1,72 @@
import { createSlice } from '@reduxjs/toolkit'
import {Alert} from "antd";
import {createSlice} from '@reduxjs/toolkit'
import {isEmpty} from "../utils/ObjectUtils";
/*
"fileName": filePath,
"filePath": filePath,
"dirFlag": true,
"childList": fileChildList
*/
export const dirMessageSlice = createSlice({
name: 'dirMessage',
initialState: {
data: []
data: [],
// selectDirKey:""
},
reducers: {
dirAdd: (state, action) => {
console.log("dirMessage:dirAdd", state, action)
if(action.payload){
if (action.payload) {
// 新添加进来的目录,要判断是否重复,如果重复则提示
let filter = state.data.filter((fileMessage)=>
fileMessage.filePath===action.payload[0].filePath
let filter = state.data.filter((fileMessage) =>
fileMessage.filePath === action.payload[0].filePath
);
if (filter.length>0){
console.log('filter',filter)
}else {
if (filter.length > 0) {
console.log('filter', filter)
} else {
// 添加进当前目录
state.data=[...new Set([...state.data,...action.payload])];
console.log('state.data:',state.data)
state.data = [...new Set([...state.data, ...action.payload])];
console.log('state.data:', state.data)
}
}
},
nextDirAdd: (state, action) => {
console.log("dirMessage:nextDirAdd", state, action)
// 获取当前选中的key
let selectDirKey = action.payload.selectDirKey;
// 便利文件树找到对应的key并加入其中
// 如果包含下级目录则不更新,在刷新中更新。
state.data.forEach(file => {
console.log("file.filePath===selectDirKey && file.dirFlag && file.childList.length===0",
file.filePath,
file.dirFlag,
file.childList.length,
selectDirKey)
if (file.filePath === selectDirKey && file.dirFlag && file.childList.length === 0) {
file.childList.push(action.payload.fileStateList[0].childList)
} else if (file.childList.length > 0) {
findChild(file.childList, action, selectDirKey)
}
})
}
}
})
export const { dirAdd } = dirMessageSlice.actions
function findChild(fileList, action, selectDirKey) {
fileList.forEach(file => {
if (file.filePath === selectDirKey && file.dirFlag &&
(isEmpty(file.childList) || (Array.isArray(file.childList) && file.childList.length === 0))) {
file.childList = action.payload.fileStateList[0].childList
return
}
if (file.dirFlag && Array.isArray(file.childList) && file.childList.length > 0) {
findChild(file.childList, action, selectDirKey)
}
})
}
export const {
dirAdd,
nextDirAdd
} = dirMessageSlice.actions
export default dirMessageSlice.reducer

View File

@ -1,5 +1,32 @@
const fs = window.require("fs").promises
const {ipcRenderer} = window.require('electron')
export async function readDir(filePath){
const files = await fs.readdir(filePath);
const fileStateList = []
const fileChildList = []
fileStateList.push({
"fileName": filePath,
"filePath": filePath,
"dirFlag": true,
"childList": fileChildList
})
for (let i = 0; i < files.length; i++) {
const state = await fs.stat(filePath + '/' + files[i]);
if (state.isDirectory()
|| files[i].endsWith(".md")
|| files[i].endsWith(".html")
|| files[i].endsWith(".lexical")) {
fileChildList.push({
'fileName': files[i],
"filePath": filePath + '/' + files[i],
'dirFlag': state.isDirectory(),
"childList":[]
})
}
}
return fileStateList
}
export async function importFile(pathName) {
return await fs.readFile(pathName)
}