From fcb27ff1563a59c838fbbb3218d274dd2ac27346 Mon Sep 17 00:00:00 2001 From: duanhongbo <6860300@qq.com> Date: Fri, 20 Nov 2020 18:20:43 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=88=A0=E9=99=A4fs-tree-view?= =?UTF-8?q?=E7=BB=84=E4=BB=B6,=E7=94=A8antd=20Tree=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fs-tree-view/App.css | 71 --- fs-tree-view/components/Search/index.tsx | 157 ------- fs-tree-view/components/Search/search.css | 53 --- fs-tree-view/components/Tree/TreeNode.tsx | 127 ----- fs-tree-view/components/Tree/index.tsx | 539 ---------------------- fs-tree-view/components/icon.tsx | 34 -- fs-tree-view/index.tsx | 3 - fs-tree-view/server/server.js | 157 ------- fs-tree-view/services/request.ts | 53 --- main-process/MainProcess.tsx | 3 - package-lock.json | 514 +-------------------- package.json | 8 +- render-process/Properties.tsx | 245 +++++++--- render-process/index.tsx | 22 +- 14 files changed, 224 insertions(+), 1762 deletions(-) delete mode 100644 fs-tree-view/App.css delete mode 100644 fs-tree-view/components/Search/index.tsx delete mode 100644 fs-tree-view/components/Search/search.css delete mode 100644 fs-tree-view/components/Tree/TreeNode.tsx delete mode 100644 fs-tree-view/components/Tree/index.tsx delete mode 100644 fs-tree-view/components/icon.tsx delete mode 100644 fs-tree-view/index.tsx delete mode 100644 fs-tree-view/server/server.js delete mode 100644 fs-tree-view/services/request.ts diff --git a/fs-tree-view/App.css b/fs-tree-view/App.css deleted file mode 100644 index 164bfc0..0000000 --- a/fs-tree-view/App.css +++ /dev/null @@ -1,71 +0,0 @@ -.container { - width: 250px; - height: 100vh; - overflow: hidden; - resize: inline; -} - -.indent-root { - padding-left: 5px; -} - -.indent { - padding-left: 25px; -} - -.mb { - padding-bottom: 10px; -} - -.item-wrapper { - cursor: pointer; - width: 100%; - white-space: nowrap; -} - -.icon { - padding-right: 5px; -} - -.icon.folder { - color: #fab019; -} - -.tomato { - color: #e73934; -} -.red { - color: red; -} -.orange { - color: #dd5b26; -} -.blue { - color: #2372ba; -} -.green { - color: #08743b; -} -.purple { - color: #5b2d8d; -} -.grey { - color: #303c42; -} -.brown { - color: #574038; -} -.yellow { - color: #fab019; -} - -.dragthis { - border: 1px solid blue; - width: 100px; - height: 100px; -} -.drophere { - border: 1px dashed #000; - width: 200px; - height: 200px; -} diff --git a/fs-tree-view/components/Search/index.tsx b/fs-tree-view/components/Search/index.tsx deleted file mode 100644 index 5beb7c8..0000000 --- a/fs-tree-view/components/Search/index.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import React from "react"; -import icon from "../icon"; -import request from "../../services/request"; -import "./search.css"; - -interface SearchProp { - basePath: string; - onItemSelected?: Function; -} - -interface SearchState { - query: string; - result: { name: string; path: string }[]; - showSearchLoader: boolean; - showSearchBox: boolean; -} - -class Search extends React.Component { - state: SearchState = { - query: "", - result: [], - showSearchLoader: false, - showSearchBox: false, - }; - - constructor(props: SearchProp) { - super(props); - } - - runDebounce = this.debounce(this.doSearch, 1000); - - debounce(fn: Function, delay: number) { - let timer: NodeJS.Timeout; - return function () { - clearTimeout(timer); - timer = setTimeout(() => { - fn.apply(this, arguments); - }, delay); - }; - } - - async doSearch(query: string) { - if (!query) { - this.setState({ - query: "", - result: [], - showSearchBox: false, - showSearchLoader: false, - }); - return; - } - - const dirPath = this.props.basePath; - const result = await request.search(dirPath, query); - - this.setState({ - query, - result, - showSearchBox: true, - showSearchLoader: false, - }); - } - - handleChange = (query: string) => { - if (!query) { - this.setState({ - query: "", - }); - return; - } - - this.setState({ - query, - showSearchBox: true, - showSearchLoader: true, - }); - }; - - clearSearch = (event: React.KeyboardEvent) => { - const keyCode = event.which || event.keyCode; - if (keyCode === 27) { - // Clear search - this.setState({ - query: "", - result: [], - showSearchBox: false, - }); - } - }; - - showResults = () => { - return ( -
- {this.state.result.map((item) => ( -
this.props.onItemSelected(item)} - key={item.path} - className="indent mb search-item" - > -
- {icon.file(item)} {item.name} -
-
{item.path}
-
- ))} -
- ); - }; - - emptyResults = () => { - return ( -
- {icon.close()} No Matching Results -
- ); - }; - - loadingResults = () => { - return
{icon.loading()}
; - }; - - results = () => { - if (this.state.showSearchLoader) { - return this.loadingResults(); - } - - if (this.state.result.length > 0) { - return this.showResults(); - } - - return this.emptyResults(); - }; - - render() { - return ( -
- {icon.search()} - { - this.handleChange(event.target.value); - this.runDebounce(); - }} - onKeyDown={this.clearSearch} - value={this.state.query} - /> -
- {this.results()} -
-
- ); - } -} - -export default Search; diff --git a/fs-tree-view/components/Search/search.css b/fs-tree-view/components/Search/search.css deleted file mode 100644 index b6bbe4e..0000000 --- a/fs-tree-view/components/Search/search.css +++ /dev/null @@ -1,53 +0,0 @@ -/* Search Styles */ -.search-wrapper { - height: 35px; - width: 100%; - padding-bottom: 10px; - position: relative; -} - -.search { - width: 100%; - height: 100%; - border: 1px solid rgb(180, 179, 179); - border-radius: 0; - padding-left: 30px; - color: grey; - font-size: 0.85em; - font-weight: 500; - /* border: 1px solid purple; */ -} - -.search-icon { - position: absolute; - padding-left: 8px; - padding-top: 12px; - color: grey; - font-size: 0.85em; - font-weight: 200; -} - -.search-results { - background: #ffffff; - padding-top: 10px; - width: 100%; - min-height: 100vh; - height: auto; -} - -.empty-results { - padding-top: 20px; - text-align: center; - font-size: 0.8em; -} - -.search-item:hover > div { - background: rgba(0, 0, 0, 0.15); -} - -.search-path { - font-size: 10px; - color: #6e6e6e; - padding: 5px 0; - padding-left: 20px; -} diff --git a/fs-tree-view/components/Tree/TreeNode.tsx b/fs-tree-view/components/Tree/TreeNode.tsx deleted file mode 100644 index 8bc7a94..0000000 --- a/fs-tree-view/components/Tree/TreeNode.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { Menu, Dropdown, Input } from "antd"; -import React from "react"; -import icon from "../icon"; - -export interface Node { - name: string; - path: string; - extension?: string; - type?: "directory" | "file"; - //size?: number; - isOpen?: boolean; - isEditing?: boolean; - children?: NodeDict; -} - -export type NodeDict = { [key: string]: Node }; - -export type NodeAction = "create" | "create_folder" | "rename" | "delete" | "reveal_in_explorer"; - -export interface TreeNodeProp { - node: Node; - currentFile: { - name: string; - path: string; - }; - contextMenu: (node: Node) => JSX.Element; - handleClick?: (event: React.MouseEvent, selectedNode: Node) => void; - draggable?: boolean; - onDragStart?: (event: React.DragEvent, data: Node) => void; - onDrag?: (event: React.DragEvent) => void; - onDragOver?: (event: React.DragEvent) => void; - onDrop?: (event: React.DragEvent, data: Node) => void; - onRenameNode?:(node:Node,newFileName:string) => void; - disableContextMenu?: boolean; -} - -let EditingText = ""; - -export default function TreeNode(props: TreeNodeProp) { - const { - node, - currentFile, - contextMenu, - handleClick, - onDragStart, - onDrag, - onDragOver, - onDrop, - onRenameNode, - disableContextMenu, - } = props; - - return ( -
- {node.children && - Object.keys(node.children).map((path) => { - const child = node.children[path]; - - return ( -
handleClick(event, child)} - draggable={true} - onDragStart={(event) => onDragStart(event, child)} - onDrag={onDrag} - onDragOver={onDragOver} - onDrop={(event) => onDrop(event, child)} - > - {child.isEditing ? ( - { - EditingText = e.currentTarget.value; - }} - onFocus={(e)=>{ - EditingText=child.name; - //e.currentTarget.select(); - e.currentTarget.setSelectionRange(0,EditingText.lastIndexOf("."),"forward"); - }} - onPressEnter={(e) => { - if(child.isEditing){ - child.isEditing = false; - onRenameNode(child,EditingText); - } - }} - - onBlur={(e)=>{ - console.log("onBlur ", EditingText); - if(child.isEditing){ - child.isEditing = false; - onRenameNode(child,EditingText); - } - }} - autoFocus={true} - /> - - ) : ( - -
- {icon.file(child)} {child.name} -
-
- )} - -
- ); - })} -
- ); -} diff --git a/fs-tree-view/components/Tree/index.tsx b/fs-tree-view/components/Tree/index.tsx deleted file mode 100644 index f0cd686..0000000 --- a/fs-tree-view/components/Tree/index.tsx +++ /dev/null @@ -1,539 +0,0 @@ -import React, { ChangeEvent, Component } from "react"; -import path from "path"; -import request from "../../services/request"; -import TreeNode, { Node, NodeAction, NodeDict } from "./TreeNode"; -import icon from "../icon"; -import Search from "../Search"; -import { Modal, Menu, Dropdown } from "antd"; -import { shell } from "electron"; - -export interface TreeProps { - className: string; - basePath: string; - disableContextMenu?: boolean; - filter: (path: string) => boolean; - onItemSelected?: (node: Node) => void; - onItemDeleted?: (node: Node) => void; -} - -interface TreeState { - nodes?: NodeDict; - currentFile?: { name: string; path: string }; - overwrite?: boolean; - dragdrop?: { - sourceNode: Node; - destinationNode?: Node; - }; -} - -export default class Tree extends Component { - state: TreeState = { - dragdrop: { - sourceNode: null, - destinationNode: null, - }, - }; - - constructor(props: TreeProps) { - super(props); - } - - _getRootNode() { - return { - [this.props.basePath]: { - name: path.basename(this.props.basePath), - path: this.props.basePath, - type: "directory", - isOpen: false, - children: null, - } as Node, - }; - } - - componentDidMount() { - this.setState({ - nodes: this._getRootNode(), - }); - - // Open first level folders - this.openFolders(); - - console.log("componentDidMount", this.state); - } - - openFolders = async () => { - let nodes = this._getRootNode(); - const rootNode = nodes[this.props.basePath]; - const children = await this.getChildNodes(rootNode, this.props.filter); - - rootNode.children = children; - rootNode.isOpen = true; - - for (const path in children) { - if (children.hasOwnProperty(path)) { - const node = children[path]; - - if (node.type === "directory") { - const subChildren = await this.getChildNodes(node, this.props.filter); - node.children = { ...subChildren }; - node.isOpen = true; - } - } - } - - this.setState({ - nodes: nodes, - }); - }; - - getChildNodes = async (node: Node, filter: (path: string) => boolean) => { - // if (!node.children) { - // return null; - // } - let children = (await request.tree(node.path)) as NodeDict; - let result: NodeDict = {}; - for (const path in children) { - if (children.hasOwnProperty(path)) { - const node = children[path]; - if (node.type == "directory" || filter(node.path)) { - result[node.path] = node; - } - } - } - return result; - }; - - handleClick = async (event: React.MouseEvent, selectedNode: Node) => { - event.stopPropagation(); - - // If folder is clicked and the folder is already open, we will close it - if (selectedNode.isOpen === true) { - this.emptyChildren(this.state.nodes, selectedNode); - selectedNode.isOpen = false; - return; - } - - if (selectedNode.type === "file") { - this.setState({ - currentFile: { - name: selectedNode.name, - path: selectedNode.path, - }, - }); - } - - selectedNode.isOpen = !selectedNode.isOpen; - - if(selectedNode.type === "directory"){ - // Get children of a selected node - const newChildren = await this.getChildNodes(selectedNode, this.props.filter); - - // Add the new children to the selected folder - this.addToChildren(this.state.nodes, selectedNode, newChildren); - } - - // Propagate the selected item to the parent component - this.props.onItemSelected(selectedNode); - }; - - handleOnMove = async () => { - try { - const response = await request.dragDrop({ - source: this.state.dragdrop.sourceNode.path, - destination: this.state.dragdrop.destinationNode.path, - overwrite: this.state.overwrite, - }); - if (response.status === 201) { - this.removeItem(this.state.nodes, this.state.dragdrop.sourceNode); - this.emptyChildren(this.state.nodes, this.state.dragdrop.destinationNode); - } - } catch (error) { - Modal.error({ - title: "Error", - content: "Item already exists in the destination", - centered: true, - }); - } - - this.setState({ - overwrite: false, - }); - }; - - renameNode = async (selectedNode: Node,newFileName:string) => { - try { - const response = await request.renameNode({ - oldPath: selectedNode.path, - newFileName: newFileName, - }); - if (response.status === 200) { - // Add the Item to state - let newNode = selectedNode; - newNode.name = newFileName; - newNode.path = response.data.newFilePath; - this.addItem(this.state.nodes, newNode); - } - } catch (error) { - Modal.error({ - title: "Error", - content: `A ${ - selectedNode.type === "file" ? "file" : "folder" - } with that name already exists`, - centered: true, - }); - } - }; - - handleOnDelete = async (selectedNode: Node) => { - const response = await request.deleteNode(selectedNode.path); - if (response.status === 200) { - this.props.onItemDeleted && this.props.onItemDeleted(selectedNode); - this.removeItem(this.state.nodes, selectedNode); - }else{ - Modal.error({ - title: "Delete File/Folder Error", - content: `${response.statusText}`, - centered: true, - }); - } - }; - - handleContextMenu = (data: { node: Node; action: NodeAction }) => { - - const { node, action } = data; - - switch (action) { - case "create":{ - //TODO new file - const baseDir = path.dirname(node.path) ; - const defaultNewName="NewTree.json"; - const newFilePath = `${baseDir}${path.sep}${defaultNewName}`; - this.addToChildren(this.state.nodes, node, { - [newFilePath]:{ - name:defaultNewName, - path:newFilePath, - type:"file", - isEditing:true, - isOpen: false, - children: null, - } - }); - } - break; - case "create_folder":{ - //TODO: new folder - const baseDir = path.dirname(node.path) ; - const defaultNewName="NewTree.json"; - const newFilePath = `${baseDir}${path.sep}${defaultNewName}`; - this.addToChildren(this.state.nodes, node, { - [newFilePath]:{ - name:defaultNewName, - path:newFilePath, - type:"directory", - isEditing:true, - isOpen: false, - children: null, - } - }); - } - break; - case "reveal_in_explorer":{ - shell.showItemInFolder(node.path); - } - break; - case "rename":{ - node.isEditing = true; - const nodes = this.state.nodes; - this.setState({nodes:nodes}); - } - break; - case "delete":{ - Modal.confirm({ - title: "Delete Confirmation", - content: `You are about to delete ${node.path}`, - centered: true, - okText: "Delete", - onOk: () => this.handleOnDelete(node), - }); - } - break; - } - }; - - // Adds children to a selected folder - addToChildren = (nodes: NodeDict, selectedNode: Node, newChildren: NodeDict) => { - for (const path in nodes) { - const iterator = nodes[path]; - - if (iterator.type === "file") { - continue; - } - - if (selectedNode.path.includes(iterator.path)) { - // If its exactly the same path append the new node in its children array - if (selectedNode.path === iterator.path) { - iterator.children = { ...newChildren, ...iterator.children }; - - // Prepare a new version of the current state - const newNodes = this.state.nodes; - - // Set the new state - this.setState({ - nodes: newNodes, - }); - break; - } else { - // If its a partial match, then get inside its children and perform iteration until exact match is not found - this.addToChildren(iterator.children, selectedNode, newChildren); - } - } - } - }; - - // Removes children from a selected folder - emptyChildren = (nodes: NodeDict, selectedNode: Node) => { - for (let path in nodes) { - const iterator = nodes[path]; - - if (iterator.type === "file") { - continue; - } - - if (selectedNode.path.includes(iterator.path)) { - // If its exactly the same path append the new node in its children array - if (selectedNode.path === iterator.path) { - iterator.children = {}; - iterator.isOpen = false; - - // Prepare a new version of the current state - const newNodes = this.state.nodes; - - // Set the new state - this.setState({ - nodes: newNodes, - }); - break; - } else { - // If its a partial match, then get inside its children and perform iteration until exact match is not found - this.emptyChildren(iterator.children, selectedNode); - } - } - } - }; - - // Add an item (file or folder) to the nodes array - addItem = (nodes: NodeDict, selectedNode: Node) => { - for (const path in nodes) { - const iterator = nodes[path]; - - if (selectedNode.path.includes(iterator.path)) { - // If its exactly the same path append the new node in its children object - if (selectedNode.path === iterator.path) { - // Add the element to the nodes object - nodes[path] = selectedNode; - - // Prepare a new version of the current state - const newNodes = this.state.nodes; - - // Set the new state - this.setState({ - nodes: newNodes, - }); - break; - } else { - // If its a partial match, then get inside its children and perform iteration until exact match is not found - this.addItem(iterator.children, selectedNode); - } - } - } - }; - - // Removes an item (file or folder) from the nodes array - removeItem = (nodes: NodeDict, selectedNode: Node) => { - for (const path in nodes) { - const iterator = nodes[path]; - - if (selectedNode.path.includes(iterator.path)) { - // If its exactly the same path append the new node in its children array - if (selectedNode.path === iterator.path) { - // Remove the element from the nodes array - // nodes.splice(path, 1); - delete nodes[path]; - - // Prepare a new version of the current state - const newNodes = this.state.nodes; - - // Set the new state - this.setState({ - nodes: newNodes, - }); - break; - } else { - // If its a partial match, then get inside its children and perform iteration until exact match is not found - this.removeItem(iterator.children, selectedNode); - } - } - } - }; - - // Toggles the overwrite checkbox - toggleOverwrite = () => { - this.setState({ - overwrite: !this.state.overwrite, - }); - }; - - // Drag & Drop handlers - onDrop = (event: React.DragEvent, selectedNode: Node) => { - event.preventDefault(); - event.stopPropagation(); - - if (selectedNode.type === "file") { - Modal.error({ - title: "Error", - content: "Destination is not a directory", - centered: true, - }); - return; - } - - this.setState( - { - dragdrop: { - sourceNode: this.state.dragdrop.sourceNode, - destinationNode: selectedNode, - }, - }, - async () => { - Modal.confirm({ - title: "Confirm Move", - content: ` -

- You are about to move ${this.state.dragdrop.sourceNode.name} -

-

to

-

- ${selectedNode.path} -

`, - centered: true, - okText: "Delete", - onOk: () => this.handleOnMove(), - }); - } - ); - }; - - onDrag = (event: React.DragEvent) => { - event.preventDefault(); - event.stopPropagation(); - }; - - onDragOver = (event: React.DragEvent) => event.preventDefault(); - - onDragStart = (event: React.DragEvent, selectedNode: Node) => { - event.stopPropagation(); - - this.setState({ - dragdrop: { - sourceNode: selectedNode, - destinationNode: this.state.dragdrop.destinationNode, - }, - }); - const id = (event.target as HTMLDivElement).id; - event.dataTransfer.setData("text/plain", id); - }; - - renderContextMeun(node: Node) { - return ( - - { - this.handleContextMenu({ node: node, action: "create" }); - }} - > - New Tree - - { - this.handleContextMenu({ node: node, action: "create_folder" }); - }} - > - New Folder - - { - this.handleContextMenu({ node: node, action: "reveal_in_explorer" }); - }} - > - Reveal In File Explorer - - - { - this.handleContextMenu({ node: node, action: "rename" }); - }} - > - Rename - - { - this.handleContextMenu({ node: node, action: "delete" }); - }} - > - Delete - - - ); - } - - render() { - if (!this.state.nodes) { - return

Loading...

; - } - return ( -
- -
- {Object.keys(this.state.nodes).map((path) => { - const node = this.state.nodes[path]; - return ( -
- -
{ - this.handleClick(event, node); - }} - className="item-wrapper mb" - > - {icon.file(node)}{" "}{node.name} -
-
- - -
- ); - })} -
-
- ); - } -} diff --git a/fs-tree-view/components/icon.tsx b/fs-tree-view/components/icon.tsx deleted file mode 100644 index a4ea85d..0000000 --- a/fs-tree-view/components/icon.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { FolderOutlined,FolderOpenOutlined,FileTextOutlined,SearchOutlined,CloseOutlined,LoadingOutlined} from '@ant-design/icons'; - -import { Node,NodeDict } from "./Tree/TreeNode"; - -const FileIcon = (node:Node) => { - if (node.type === "file") { - return ( - - ); - } - return node.isOpen ?():() -}; - -const SearchIcon = () => { - return ; -}; - - -const CloseIcon = () => { - return ; -}; - -const LoadingIcon = ()=>{ - return -} - -export default { - file: FileIcon, - search: SearchIcon, - close: CloseIcon, - loading: LoadingIcon -}; diff --git a/fs-tree-view/index.tsx b/fs-tree-view/index.tsx deleted file mode 100644 index b7fb889..0000000 --- a/fs-tree-view/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import "./App.css"; -import Tree from "./components/Tree/index"; -export default Tree; diff --git a/fs-tree-view/server/server.js b/fs-tree-view/server/server.js deleted file mode 100644 index 319ed4d..0000000 --- a/fs-tree-view/server/server.js +++ /dev/null @@ -1,157 +0,0 @@ -const express = require("express"); -const bodyParser = require("body-parser"); -const cors = require("cors"); -const app = express(); -const fs = require("fs"); -const fsx = require("fs-extra"); -const path = require("path"); -const rimraf = require("rimraf"); -const glob = require("glob"); -const sanitize = require("sanitize-filename"); - -function decodeUrlParam(s) { - return decodeURIComponent(s); -} - -app.use(cors()); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); - -// Tree -app.get("/", (req, res) => { - const dirPath = decodeUrlParam(req.query.path) || ""; - - fs.readdir(dirPath, (err, files) => { - if (!files) { - console.log("No Files", dirPath); - return res.json({}); - } - - let finalList = {}; - files.forEach((file) => { - try { - const fullPath = path.join(dirPath, file); - const isDirectory = fs.lstatSync(fullPath).isDirectory(); - let fileProperties = { - [fullPath]: { - name: file, - path: fullPath, - size: fs.statSync(fullPath).size, - extension: path.extname(file), - type: isDirectory ? "directory" : "file", - isOpen: false, - }, - }; - - if (isDirectory) { - delete fileProperties[fullPath].extension; - fileProperties[fullPath].children = {}; - // Directories should appear on top - finalList = { ...fileProperties, ...finalList }; - } else { - // Files should appear at the end - finalList = { ...finalList, ...fileProperties }; - } - } catch (error) { - console.log("Error:", error); - return res.json({}); - } - }); - - return res.json(finalList); - }); -}); - -// Search -app.get("/search", (req, res) => { - const dirPath = decodeUrlParam(req.query.path) || ""; - let query = decodeUrlParam(req.query.query) || ""; - query = sanitize(query); - const maxResults = 20; - - glob(`${dirPath}/**/*.*`, {}, function (er, files) { - const final = []; - let counter = 0; - - for (const file of files) { - // Dont show more than maxResults - if (counter >= maxResults) { - break; - } - - let pattern; - try { - pattern = new RegExp(query, "gi"); - } catch (error) { - query = query.replace(/[|&;$%@"<>()+,*]/g, ""); - pattern = new RegExp(query, "gi"); - } - - if (pattern.test(path.basename(file))) { - final.push({ - name: path.basename(file), - path: file, - type: "file", - extension: path.extname(file), - }); - counter++; - } - } - - return res.json(final); - }); -}); - -// For Drag and Drop -app.post("/dragdrop", (req, res) => { - const { source, destination, overwrite } = req.body; - const filename = path.basename(source); - const destinationPath = `${destination}${path.sep}${filename}`; - - fsx.move(source, destinationPath, { overwrite }, (error) => { - if (error) { - return res.status(400).send("NOT_OK"); - } - - return res.status(201).send("OK"); - }); -}); - -// Rename a file/folder -app.put("/rename", (req, res) => { - const oldPath = decodeUrlParam(req.body.oldPath); - const newFileName = decodeUrlParam(req.body.newFileName); - const newFilePath = `${path.dirname(oldPath)}${path.sep}${sanitize(newFileName)}`; - - if (oldPath == newFilePath) { - return res.json({ - newFilePath, - }); - } else { - fsx.move(oldPath, newFilePath, { overwrite: false }, (error) => { - if (error) { - console.log("Error", error); - return res.status(400).send("NOT_OK"); - } - - return res.json({ - newFilePath, - }); - }); - } -}); - -// Delete file/folder -app.delete("/", (req, res) => { - rimraf(decodeUrlParam(req.query.fullPath), (error) => { - if (error) { - return res.status(400).send(error); - } else { - return res.status(200).send("OK"); - } - }); -}); - -app.listen(5000, () => { - console.log("Server running on port 5000"); -}); diff --git a/fs-tree-view/services/request.ts b/fs-tree-view/services/request.ts deleted file mode 100644 index df3ec9d..0000000 --- a/fs-tree-view/services/request.ts +++ /dev/null @@ -1,53 +0,0 @@ -import * as axios from "axios"; - - -function encodeUrlParam(s: string) { - return encodeURIComponent(s); -} - -const BASE_URL = process.env.fsTreeViewUrl || "http://localhost:5000"; - -const tree = async (dirPath: string) => { - const response = await axios.default.get(`${BASE_URL}/?path=${encodeUrlParam(dirPath)}`); - return response.data; -}; - -const search = async (dirPath: string, query: string) => { - const response = await axios.default.get( - `${BASE_URL}/search?query=${encodeUrlParam(query)}&path=${encodeUrlParam(dirPath)}` - ); - return response.data; -}; - -const dragDrop = async (args: { source: string; destination: string; overwrite: boolean }) => { - const response = await axios.default.post(`${BASE_URL}/dragdrop`, { - source : encodeUrlParam(args.source), - destination : encodeUrlParam(args.destination), - overwrite:args.overwrite - }); - return response; -}; - -const renameNode = async (args: { oldPath: string; newFileName: string }) => { - const response = await axios.default.put(`${BASE_URL}/rename`, { - oldPath : encodeUrlParam(args.oldPath), - newFileName : encodeUrlParam(args.newFileName), - }); - return response; -}; - -const deleteNode = async (fullPath : string) => { - const encodeFullPath = encodeUrlParam(fullPath); - const response = await axios.default.delete(`${BASE_URL}`, { - params: { fullPath:encodeFullPath }, - }); - return response; -}; - -export default { - tree, - search, - dragDrop, - renameNode, - deleteNode, -}; diff --git a/main-process/MainProcess.tsx b/main-process/MainProcess.tsx index 2afe8cb..12a1a0b 100644 --- a/main-process/MainProcess.tsx +++ b/main-process/MainProcess.tsx @@ -5,9 +5,6 @@ import MainEventType from "../common/MainEventType"; import electronLocalshortcut from "electron-localshortcut"; -//launch fs server listen port 5000 -require("../fs-tree-view/server/server"); - // 一些暴露给render-process的全局变量 export interface Global { settings: Settings; diff --git a/package-lock.json b/package-lock.json index 256a375..76c92b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -365,16 +365,6 @@ "defer-to-connect": "^1.0.1" } }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npm.taobao.org/@types/body-parser/download/@types/body-parser-1.19.0.tgz", - "integrity": "sha1-BoWzxH6zAG/+0RfN1VFkth+AU48=", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, "@types/concat-stream": { "version": "1.6.0", "resolved": "https://registry.npm.taobao.org/@types/concat-stream/download/@types/concat-stream-1.6.0.tgz", @@ -383,24 +373,6 @@ "@types/node": "*" } }, - "@types/connect": { - "version": "3.4.33", - "resolved": "https://registry.npm.taobao.org/@types/connect/download/@types/connect-3.4.33.tgz?cache=0&sync_timestamp=1605052812480&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fconnect%2Fdownload%2F%40types%2Fconnect-3.4.33.tgz", - "integrity": "sha1-MWEMkB7KVzuHE8MzCrxua59YhUY=", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/cors": { - "version": "2.8.8", - "resolved": "https://registry.npm.taobao.org/@types/cors/download/@types/cors-2.8.8.tgz?cache=0&sync_timestamp=1605053910398&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcors%2Fdownload%2F%40types%2Fcors-2.8.8.tgz", - "integrity": "sha1-MXqNhWGZXGDjW54PyqjTZmDJgJI=", - "dev": true, - "requires": { - "@types/express": "*" - } - }, "@types/d3-timer": { "version": "1.0.10", "resolved": "https://registry.npm.taobao.org/@types/d3-timer/download/@types/d3-timer-1.0.10.tgz?cache=0&sync_timestamp=1601417425052&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fd3-timer%2Fdownload%2F%40types%2Fd3-timer-1.0.10.tgz", @@ -426,29 +398,6 @@ "resolved": "https://registry.npm.taobao.org/@types/estree/download/@types/estree-0.0.45.tgz", "integrity": "sha1-6Th1cpmOXs2sIhlQ2rPow7Fq+IQ=" }, - "@types/express": { - "version": "4.17.9", - "resolved": "https://registry.npm.taobao.org/@types/express/download/@types/express-4.17.9.tgz?cache=0&sync_timestamp=1605057477768&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fexpress%2Fdownload%2F%40types%2Fexpress-4.17.9.tgz", - "integrity": "sha1-9fLfat1wP/KEKK3VK97IoQkbCng=", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.13", - "resolved": "https://registry.npm.taobao.org/@types/express-serve-static-core/download/@types/express-serve-static-core-4.17.13.tgz", - "integrity": "sha1-2a8CXpJfyLCJvjdCO40erHgb4IQ=", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, "@types/form-data": { "version": "0.0.33", "resolved": "https://registry.npm.taobao.org/@types/form-data/download/@types/form-data-0.0.33.tgz", @@ -490,12 +439,6 @@ "@types/unist": "*" } }, - "@types/mime": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/@types/mime/download/@types/mime-2.0.3.tgz", - "integrity": "sha1-yJO3NyHbc2mZQ7/DZTsd63+qSjo=", - "dev": true - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz?cache=0&sync_timestamp=1596839141589&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fminimatch%2Fdownload%2F%40types%2Fminimatch-3.0.3.tgz", @@ -517,12 +460,6 @@ "resolved": "https://registry.npm.taobao.org/@types/qs/download/@types/qs-6.9.5.tgz?cache=0&sync_timestamp=1605055106687&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fqs%2Fdownload%2F%40types%2Fqs-6.9.5.tgz", "integrity": "sha1-Q0cRvdSete5p2QwdZ8NUqajssYs=" }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz", - "integrity": "sha1-fuMwunyq+5gJC+zoal7kQRWQTCw=", - "dev": true - }, "@types/react": { "version": "16.9.51", "resolved": "https://registry.npm.taobao.org/@types/react/download/@types/react-16.9.51.tgz", @@ -550,16 +487,6 @@ "@types/node": "*" } }, - "@types/serve-static": { - "version": "1.13.8", - "resolved": "https://registry.npm.taobao.org/@types/serve-static/download/@types/serve-static-1.13.8.tgz?cache=0&sync_timestamp=1605657862811&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fserve-static%2Fdownload%2F%40types%2Fserve-static-1.13.8.tgz", - "integrity": "sha1-hREp1DRDPHCCFIV0/+wmPVgwnEY=", - "dev": true, - "requires": { - "@types/mime": "*", - "@types/node": "*" - } - }, "@types/unist": { "version": "2.0.3", "resolved": "https://registry.npm.taobao.org/@types/unist/download/@types/unist-2.0.3.tgz", @@ -783,15 +710,6 @@ "integrity": "sha1-wLZ4+zLWD8EhnHhNaoJv44Wut5o=", "dev": true }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz", - "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, "acorn": { "version": "6.4.2", "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-6.4.2.tgz?cache=0&sync_timestamp=1601885779818&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn%2Fdownload%2Facorn-6.4.2.tgz", @@ -1094,11 +1012,6 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, "array-tree-filter": { "version": "2.1.0", "resolved": "http://registry.npm.taobao.org/array-tree-filter/download/array-tree-filter-2.1.0.tgz", @@ -1227,7 +1140,8 @@ "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npm.taobao.org/at-least-node/download/at-least-node-1.0.0.tgz", - "integrity": "sha1-YCzUtG6EStTv/JKoARo8RuAjjcI=" + "integrity": "sha1-YCzUtG6EStTv/JKoARo8RuAjjcI=", + "dev": true }, "atob": { "version": "2.1.2", @@ -1241,22 +1155,6 @@ "integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=", "dev": true }, - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.19.0.tgz?cache=0&sync_timestamp=1603468783865&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.0.tgz", - "integrity": "sha1-jgm/89kSLhM/e4EByPvdAO09Krg=", - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npm.taobao.org/is-buffer/download/is-buffer-2.0.5.tgz?cache=0&sync_timestamp=1604429388528&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-buffer%2Fdownload%2Fis-buffer-2.0.5.tgz", - "integrity": "sha1-68JS5ADSL/jXf6CYiIIaJKZYwZE=" - } - } - }, "bail": { "version": "1.0.5", "resolved": "https://registry.npm.taobao.org/bail/download/bail-1.0.5.tgz", @@ -1372,38 +1270,12 @@ "integrity": "sha1-vsoAVAj2Quvr6oCwQrTRjSrA7ms=", "dev": true }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz", - "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz", - "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, "boolean": { "version": "3.0.1", "resolved": "https://registry.npm.taobao.org/boolean/download/boolean-3.0.1.tgz", "integrity": "sha1-NezytKLuGRsLRJhvFOtfBSpcu08=", - "dev": true + "dev": true, + "optional": true }, "boxen": { "version": "4.2.0", @@ -1867,11 +1739,6 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz", - "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY=" - }, "cacache": { "version": "12.0.4", "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-12.0.4.tgz", @@ -2277,29 +2144,6 @@ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz", - "integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz", - "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz", - "integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, "copy-concurrently": { "version": "1.0.5", "resolved": "http://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz", @@ -2562,15 +2406,6 @@ "resolved": "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npm.taobao.org/cors/download/cors-2.8.5.tgz", - "integrity": "sha1-6sEdpRWS3Ya58G9uesKTs9+HXSk=", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, "create-ecdh": { "version": "4.0.4", "resolved": "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.4.tgz", @@ -2802,6 +2637,7 @@ "version": "2.6.9", "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz", "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, "requires": { "ms": "2.0.0" } @@ -2892,14 +2728,9 @@ }, "delayed-stream": { "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz", + "resolved": "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, "des.js": { "version": "1.0.1", "resolved": "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz", @@ -2910,11 +2741,6 @@ "minimalistic-assert": "^1.0.0" } }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, "detect-browser": { "version": "5.2.0", "resolved": "https://registry.npm.taobao.org/detect-browser/download/detect-browser-5.2.0.tgz?cache=0&sync_timestamp=1602161052538&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdetect-browser%2Fdownload%2Fdetect-browser-5.2.0.tgz", @@ -3104,11 +2930,6 @@ "stream-shift": "^1.0.0" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, "ejs": { "version": "3.1.5", "resolved": "https://registry.npm.taobao.org/ejs/download/ejs-3.1.5.tgz", @@ -3681,7 +3502,9 @@ "encodeurl": { "version": "1.0.2", "resolved": "http://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "optional": true }, "end-of-stream": { "version": "1.4.4", @@ -3763,11 +3586,6 @@ "integrity": "sha1-Gy3HcANnbEV+x2Cy3GjttkgYhnU=", "dev": true }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", @@ -3813,11 +3631,6 @@ "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=", "dev": true }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, "events": { "version": "3.2.0", "resolved": "https://registry.npm.taobao.org/events/download/events-3.2.0.tgz?cache=0&sync_timestamp=1595422595227&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fevents%2Fdownload%2Fevents-3.2.0.tgz", @@ -3878,43 +3691,6 @@ "homedir-polyfill": "^1.0.1" } }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz", - "integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, "extend": { "version": "3.0.2", "resolved": "http://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz", @@ -4217,20 +3993,6 @@ } } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz", - "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-2.1.0.tgz", @@ -4311,24 +4073,6 @@ "readable-stream": "^2.3.6" } }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz", - "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=", - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz?cache=0&sync_timestamp=1600502826356&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "requires": { - "ms": "2.0.0" - } - } - } - }, "for-in": { "version": "1.0.2", "resolved": "http://registry.npm.taobao.org/for-in/download/for-in-1.0.2.tgz", @@ -4345,11 +4089,6 @@ "mime-types": "^2.1.12" } }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, "fragment-cache": { "version": "0.2.1", "resolved": "http://registry.npm.taobao.org/fragment-cache/download/fragment-cache-0.2.1.tgz", @@ -4359,11 +4098,6 @@ "map-cache": "^0.2.2" } }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, "from2": { "version": "2.3.0", "resolved": "http://registry.npm.taobao.org/from2/download/from2-2.3.0.tgz", @@ -4374,40 +4108,6 @@ "readable-stream": "^2.0.0" } }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npm.taobao.org/fs-extra/download/fs-extra-9.0.1.tgz", - "integrity": "sha1-kQ2gBiQ3ukw5/t2GPxZ1zP78ufw=", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-6.1.0.tgz", - "integrity": "sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4=", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-2.0.0.tgz", - "integrity": "sha1-daSYTv7cSwiXXFrrc/Uw0C3yVxc=" - } - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-1.0.0.tgz", - "integrity": "sha1-thodoXPoQ1sv48Z9Kbmt+FlL0W0=" - } - } - }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-2.1.0.tgz", @@ -4673,7 +4373,8 @@ "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.4.tgz", - "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs=" + "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs=", + "dev": true }, "graphlib": { "version": "2.1.8", @@ -4840,25 +4541,6 @@ "integrity": "sha1-SekcXL82yblLz81xwj1SSex045A=", "dev": true }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz", - "integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, "http-response-object": { "version": "3.0.2", "resolved": "https://registry.npm.taobao.org/http-response-object/download/http-response-object-3.0.2.tgz", @@ -4987,11 +4669,6 @@ "integrity": "sha1-Zlq4vE2iendKQFhOgS4+D6RbGh4=", "dev": true }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz", - "integrity": "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM=" - }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "http://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-0.1.6.tgz", @@ -5428,7 +5105,7 @@ }, "lodash": { "version": "4.17.20", - "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.20.tgz?cache=0&sync_timestamp=1597335994883&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz", + "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.20.tgz", "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=" }, "lodash.camelcase": { @@ -5544,11 +5221,6 @@ "resolved": "https://registry.npm.taobao.org/mdast-util-to-string/download/mdast-util-to-string-1.1.0.tgz", "integrity": "sha1-JwVVABA/UWN70H0B2gHrGWekNSc=" }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.4.1.tgz", @@ -5559,22 +5231,12 @@ "readable-stream": "^2.0.1" } }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npm.taobao.org/merge2/download/merge2-1.4.1.tgz", "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=", "dev": true }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, "micromark": { "version": "2.10.1", "resolved": "https://registry.npm.taobao.org/micromark/download/micromark-2.10.1.tgz", @@ -5875,7 +5537,8 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true }, "nan": { "version": "2.14.1", @@ -5903,11 +5566,6 @@ "to-regex": "^3.0.1" } }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz", - "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs=" - }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npm.taobao.org/neo-async/download/neo-async-2.6.2.tgz", @@ -6069,14 +5727,6 @@ "resolved": "https://registry.npm.taobao.org/omit.js/download/omit.js-2.0.2.tgz", "integrity": "sha1-3ZuENvq5R6Xz/yFMslOGMeMT7C8=" }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, "once": { "version": "1.4.0", "resolved": "http://registry.npm.taobao.org/once/download/once-1.4.0.tgz", @@ -6222,11 +5872,6 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz", - "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=" - }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz", @@ -6269,11 +5914,6 @@ "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", "dev": true }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, "path-type": { "version": "2.0.0", "resolved": "http://registry.npm.taobao.org/path-type/download/path-type-2.0.0.tgz", @@ -6494,15 +6134,6 @@ "dev": true, "optional": true }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.6.tgz", - "integrity": "sha1-/cIzZQVEfT8vLGOO0nLK9hS7sr8=", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, "prr": { "version": "1.0.1", "resolved": "http://registry.npm.taobao.org/prr/download/prr-1.0.1.tgz", @@ -6580,9 +6211,9 @@ } }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz", - "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=" + "version": "6.9.4", + "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.9.4.tgz", + "integrity": "sha1-kJCykNH5FyjTwi5UhDykSupatoc=" }, "querystring": { "version": "0.2.0", @@ -6628,32 +6259,6 @@ "safe-buffer": "^5.1.0" } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz", - "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE=" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz", - "integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz", - "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, "rc": { "version": "1.2.8", "resolved": "https://registry.npm.taobao.org/rc/download/rc-1.2.8.tgz", @@ -7470,7 +7075,8 @@ "safer-buffer": { "version": "2.1.2", "resolved": "http://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", + "dev": true }, "sanitize-filename": { "version": "1.6.3", @@ -7544,38 +7150,6 @@ } } }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz", - "integrity": "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg=", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz", - "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=" - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz", - "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=" - } - } - }, "serialize-error": { "version": "7.0.1", "resolved": "https://registry.npm.taobao.org/serialize-error/download/serialize-error-7.0.1.tgz", @@ -7595,17 +7169,6 @@ "randombytes": "^2.1.0" } }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz", - "integrity": "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk=", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, "set-blocking": { "version": "2.0.0", "resolved": "http://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz", @@ -7641,11 +7204,6 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz", - "integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM=" - }, "sha.js": { "version": "2.4.11", "resolved": "http://registry.npm.taobao.org/sha.js/download/sha.js-2.4.11.tgz", @@ -7981,11 +7539,6 @@ } } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npm.taobao.org/stream-browserify/download/stream-browserify-2.0.2.tgz", @@ -8396,11 +7949,6 @@ "resolved": "http://registry.npm.taobao.org/toggle-selection/download/toggle-selection-1.0.6.tgz", "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz", - "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=" - }, "trim-repeated": { "version": "1.0.0", "resolved": "http://registry.npm.taobao.org/trim-repeated/download/trim-repeated-1.0.0.tgz", @@ -8512,15 +8060,6 @@ "dev": true, "optional": true }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz", - "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, "typedarray": { "version": "0.0.6", "resolved": "http://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz", @@ -8651,11 +8190,6 @@ "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=", "dev": true }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, "unset-value": { "version": "1.0.0", "resolved": "http://registry.npm.taobao.org/unset-value/download/unset-value-1.0.0.tgz", @@ -8850,11 +8384,6 @@ "resolved": "http://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, "v8-compile-cache": { "version": "2.1.1", "resolved": "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.1.1.tgz", @@ -8871,11 +8400,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, "vfile": { "version": "4.2.0", "resolved": "https://registry.npm.taobao.org/vfile/download/vfile-4.2.0.tgz?cache=0&sync_timestamp=1596111366966&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvfile%2Fdownload%2Fvfile-4.2.0.tgz", diff --git a/package.json b/package.json index 73d2e1c..9b70686 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,7 @@ }, "homepage": "https://github.com/zhandouxiaojiji/behavior3editor#readme", "devDependencies": { - "@types/cors": "^2.8.8", "@types/electron-localshortcut": "^3.1.0", - "@types/express": "^4.17.9", "@types/node": "^14.14.8", "@types/rimraf": "^3.0.0", "copy-webpack-plugin": "^6.3.1", @@ -51,11 +49,7 @@ "@types/react": "^16.9.51", "@types/react-dom": "^16.9.8", "antd": "^4.6.6", - "axios": "^0.19.0", - "body-parser": "^1.19.0", - "cors": "^2.8.5", - "express": "^4.17.1", - "fs-extra": "^9.0.1", + "lodash": "^4.17.20", "react": "^16.13.1", "react-confirm-alert": "^2.6.2", "react-dom": "^16.13.1", diff --git a/render-process/Properties.tsx b/render-process/Properties.tsx index 49f2378..f58416a 100644 --- a/render-process/Properties.tsx +++ b/render-process/Properties.tsx @@ -1,17 +1,14 @@ import React, { Component } from "react"; -import { Menu, Input } from "antd"; +import { Menu, Input, Tree ,Dropdown} from "antd"; import * as fs from "fs"; import * as path from "path"; import { ipcRenderer } from "electron"; import MainEventType from "../common/MainEventType"; -import Tree from "../fs-tree-view"; +import { DataNode } from "antd/lib/tree"; +import { IconType } from "rc-tree/lib/interface"; const { Search } = Input; - -export interface TreeFile { - name: string; - path: string; -} +const { DirectoryTree } = Tree; export interface PropertiesProps { workdir: string; @@ -19,13 +16,124 @@ export interface PropertiesProps { onDeleteTree: (path: string) => void; } -interface PropertiesState { - treeList: TreeFile[]; +class FileDataNode implements DataNode { + checkable?: boolean; + children?: FileDataNode[]; + disabled?: boolean; + disableCheckbox?: boolean; + icon?: IconType; + isLeaf?: boolean; + key: React.ReactText; + title?: React.ReactNode; + selectable?: boolean; + switcherIcon?: IconType; + className?: string; + style?: React.CSSProperties; + + parent: FileDataNode; + + public constructor(init?: Partial) { + Object.assign(this, init); + } + + get isFolder() { + return this.isLeaf !== void 0 && !this.isLeaf; + } + + get name() { + return this.title as string; + } + + get path() { + return this.key as string; + } + + loadChilds(recursive?: boolean) { + const folder = this.key as string; + if (folder == "" || !fs.existsSync(folder)) { + return []; + } + const files = fs.readdirSync(folder); + const list: FileDataNode[] = []; + files.forEach((filename) => { + const fullPath = path.join(folder, filename); + const stat = fs.statSync(fullPath); + const isFolder = stat.isDirectory(); + const name = isFolder ? filename : filename.slice(0, -5); + const node = new FileDataNode({ + title: name, + key: fullPath, + isLeaf: !isFolder, + parent: this, + }); + + node.children = isFolder&&recursive ? (node.loadChilds(recursive) as FileDataNode[]) : [], + + list.push(node); + }); + return list; + } + + addChild(filePath: string) { + const isDir = fs.statSync(filePath).isDirectory(); + const newNode = new FileDataNode({ + title: path.basename(filePath), + key: filePath, + isLeaf: !isDir, + parent: this, + children: [], + }); + this.children = [newNode, ...this.children]; + } + + removeFromParent() { + const parent = this.parent; + if (parent) { + const index = parent.children.indexOf(this); + parent.children.splice(index, 1); + } + } + + expandSelf(recursive?: boolean) { + if (this.isFolder) this.children = this.loadChilds(recursive); + } + + findChild(key: string): FileDataNode { + for (const child of this.children) { + if (child.key == key) { + return child; + } else { + const ret = child.findChild(key); + if (ret) { + return ret; + } + } + } + return null; + } + + // name:string; + // path: string; + // isFolder : boolean; + // isEditing?: boolean; + // children?: NodeData[]; } +interface PropertiesState { + root: FileDataNode; +} + +const NodeActions: { [x: string]: string } = { + ["create"]: "New Tree", + ["createFolder"]: "New Folder", + ["rename"]: "Rename", + ["delete"]: "Delete", + ["reveal_in_explorer"]: "Reveal In File Explorer", +}; + export default class Properties extends Component { state: PropertiesState = { - treeList: [], + root: null, }; curWorkdir: string = ""; @@ -40,6 +148,7 @@ export default class Properties extends Component { ipcRenderer.on(MainEventType.CREATE_TREE, (event: any, path: string) => { console.log("on Create tree", path); this.props.onOpenTree(path); + this.state.root.expandSelf(); this.forceUpdate(); }); @@ -47,58 +156,86 @@ export default class Properties extends Component { if (workdir == "") { return; } - this.setState({ treeList: this.getTreeList(workdir) }); + const root = this.getRootNode(workdir); + root.expandSelf(); + this.setState({ root: root }); } - getTreeList(workdir: string) { - if (workdir == "" || !fs.existsSync(workdir)) { - console.log("workdir not exist", workdir); - return []; - } - - const files = fs.readdirSync(workdir); - const list: TreeFile[] = []; - files.forEach((filename) => { - const stat = fs.statSync(path.join(workdir, filename)); - if (stat.isFile()) { - var name = filename.slice(0, -5); - list.push({ - name, - path: workdir + "/" + name + ".json", - }); - } + getRootNode(workdir: string) { + return new FileDataNode({ + title: path.basename(workdir), + key: workdir, + isLeaf: false, + parent: null, + children: [], }); - return list; } + // renderContextMeun(selectedNode: FileDataNode) { + // const actions = Object.keys(NodeActions); + // return ( + // + // {actions.map((action) => { + // const displayName: string = NodeActions[action]; + // return ( + // { + // //this.handleContextMenu({ node: selectedNode, action:{action} }); + // }} + // >{displayName} + // + // ); + // })} + // + // ); + // } + + // renderNode(node:FileDataNode){ + // return ( + //
{node.title}
+ //
) + // } + render() { console.log("render Properties"); const { onOpenTree, onDeleteTree, workdir } = this.props; - //const treeList = this.getTreeList(workdir); - - if (!fs.existsSync(workdir)) { - return
; - } else { - return ( - { - return path.endsWith(".json"); - }} - onItemSelected={(item) => { - if (item.type == "file") { - onOpenTree(item.path); + const root = this.state.root; + const nodes = root ? [root] : []; + return nodes.length ? ( + console.log("onCheck")} + onSelect={(keys, info) => { + console.log("onSelect", keys, info); + if (info.node.isLeaf) { + onOpenTree(keys[0] as string); + } + }} + onExpand={(keys, info) => { + console.log("onExpand", info); + if (info.expanded && !info.node.expanded) { + //let newRoot = _.cloneDeep(root); + const node = root.findChild(info.node.key as string); + if (node) { + node.expandSelf(); + this.setState({ root: root }); + this.forceUpdate(); } - }} - onItemDeleted={(item) => { - if (item.type == "file") { - onDeleteTree(item.path); - } - }} - > - ); - } + } + }} + onLoad={(keys, info) => console.log("onLoad", keys, info)} + onRightClick={(event) => console.log("onRightClick", event)} + > + ) : ( + `Work Dir (${workdir}) Empty` + ); } } diff --git a/render-process/index.tsx b/render-process/index.tsx index fb0bc81..590f99c 100644 --- a/render-process/index.tsx +++ b/render-process/index.tsx @@ -81,15 +81,19 @@ export default class Main extends Component { return ( - { - this.tabs.openFile(path); - }} - onDeleteTree={(path) => { - this.tabs.closeFile(path); - }} - /> + {workdir !== "" ? ( + { + this.tabs.openFile(path); + }} + onDeleteTree={(path) => { + this.tabs.closeFile(path); + }} + /> + ) : ( + "Please Open Workspace" + )}