feat:树文件夹保存
This commit is contained in:
parent
15408649d0
commit
93bf0deb5f
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,16 +110,24 @@ 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)
|
||||||
dispatch(addTableBarItem(
|
if (e.node.dirFlag){
|
||||||
{
|
// 加载目录下一级文件信息
|
||||||
label: e.node.title,
|
readDir(e.node.key).then(fileStateList=>{
|
||||||
children: e.node.key,
|
dispatch(nextDirAdd({selectDirKey:e.node.key,fileStateList}))
|
||||||
key: e.node.key,
|
})
|
||||||
activeKey:e.node.key
|
}else {
|
||||||
}
|
// 打开文件
|
||||||
))
|
dispatch(addTableBarItem(
|
||||||
|
{
|
||||||
|
label: e.node.title,
|
||||||
|
children: e.node.key,
|
||||||
|
key: e.node.key,
|
||||||
|
activeKey:e.node.key
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// const treeData = useMemo(() => {
|
// const treeData = useMemo(() => {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue