diff --git a/src/App.js b/src/App.js index 8359ab1..fdd83a3 100644 --- a/src/App.js +++ b/src/App.js @@ -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) diff --git a/src/comment/TopMenu.js b/src/comment/TopMenu.js index 172b88a..045793b 100644 --- a/src/comment/TopMenu.js +++ b/src/comment/TopMenu.js @@ -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); } diff --git a/src/components/ItemTree/index.jsx b/src/components/ItemTree/index.jsx index 8106343..f88405a 100644 --- a/src/components/ItemTree/index.jsx +++ b/src/components/ItemTree/index.jsx @@ -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?:fileName.endsWith(".md")?:, "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(() => { diff --git a/src/redux/dirMessage_reducer.js b/src/redux/dirMessage_reducer.js index a5842ab..70bc36c 100644 --- a/src/redux/dirMessage_reducer.js +++ b/src/redux/dirMessage_reducer.js @@ -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 diff --git a/src/utils/File/index.jsx b/src/utils/File/index.jsx index c512aae..94046da 100644 --- a/src/utils/File/index.jsx +++ b/src/utils/File/index.jsx @@ -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) }