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 useIpcRenderer from '../src/utils/useIpcRenderer'
import {dirAdd} from "./redux/dirMessage_reducer"; import {dirAdd} from "./redux/dirMessage_reducer";
import {pushHotkeys} from "./redux/pushHotkeys_reducer"; import {pushHotkeys} from "./redux/pushHotkeys_reducer";
import {store} from "./redux/store"; import {useDispatch} from "react-redux";
function App() { function App() {
let navigateFunction = useNavigate(); let navigateFunction = useNavigate();
let dispatch = useDispatch();
function nativeTo(path){ function nativeTo(path){
navigateFunction(path) navigateFunction(path)
} }
@ -15,11 +17,11 @@ function App() {
nativeTo(args) nativeTo(args)
} }
const addNewDir =(event,args)=> { const addNewDir =(event,args)=> {
store.dispatch(dirAdd(args)) dispatch(dirAdd(args))
} }
const pushHotkeysAction =(event,args)=> { const pushHotkeysAction =(event,args)=> {
console.log("store.dispatch(pushHotkeys(args))",args) console.log("store.dispatch(pushHotkeys(args))",args)
store.dispatch(pushHotkeys(args)) dispatch(pushHotkeys(args))
} }
console.log("routes",routes) console.log("routes",routes)

View File

@ -1,6 +1,32 @@
const {app, Menu, shell, dialog} = require('electron') const {app, Menu, shell, dialog} = require('electron')
const {stat, readdir} = require("fs/promises"); const {stat, readdir} = require("fs/promises");
const isMac = process.platform === 'darwin' 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) => { exports.menuRebuild = (mainWindow) => {
return template = [ return template = [
// { role: 'appMenu' } // { role: 'appMenu' }
@ -34,31 +60,8 @@ exports.menuRebuild = (mainWindow) => {
// 不取消就发送目录 // 不取消就发送目录
if (!result.canceled) { if (!result.canceled) {
console.log('result.filePaths', result.filePaths) console.log('result.filePaths', result.filePaths)
const {readdir, stat} = require('fs/promises')
try { try {
const files = await readdir(result.filePaths[0]); mainWindow.webContents.send('openDirectory', readDirLocal(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)
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }

View File

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

View File

@ -1,30 +1,72 @@
import { createSlice } from '@reduxjs/toolkit' import {createSlice} from '@reduxjs/toolkit'
import {Alert} from "antd"; import {isEmpty} from "../utils/ObjectUtils";
/*
"fileName": filePath,
"filePath": filePath,
"dirFlag": true,
"childList": fileChildList
*/
export const dirMessageSlice = createSlice({ export const dirMessageSlice = createSlice({
name: 'dirMessage', name: 'dirMessage',
initialState: { initialState: {
data: [] data: [],
// selectDirKey:""
}, },
reducers: { reducers: {
dirAdd: (state, action) => { dirAdd: (state, action) => {
console.log("dirMessage:dirAdd", state, action) console.log("dirMessage:dirAdd", state, action)
if(action.payload){ if (action.payload) {
// 新添加进来的目录,要判断是否重复,如果重复则提示 // 新添加进来的目录,要判断是否重复,如果重复则提示
let filter = state.data.filter((fileMessage)=> let filter = state.data.filter((fileMessage) =>
fileMessage.filePath===action.payload[0].filePath fileMessage.filePath === action.payload[0].filePath
); );
if (filter.length>0){ if (filter.length > 0) {
console.log('filter',filter) console.log('filter', filter)
}else { } else {
// 添加进当前目录 // 添加进当前目录
state.data=[...new Set([...state.data,...action.payload])]; state.data = [...new Set([...state.data, ...action.payload])];
console.log('state.data:',state.data) 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 export default dirMessageSlice.reducer

View File

@ -1,5 +1,32 @@
const fs = window.require("fs").promises const fs = window.require("fs").promises
const {ipcRenderer} = window.require('electron') 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) { export async function importFile(pathName) {
return await fs.readFile(pathName) return await fs.readFile(pathName)
} }