diff --git a/main-process/Settings.ts b/main-process/Settings.ts index 7b9502b..4a8b94a 100644 --- a/main-process/Settings.ts +++ b/main-process/Settings.ts @@ -11,6 +11,7 @@ export interface SettingsModel { recentFiles?: string[]; serverName?: string; nodeClassify?: BehaviorNodeClassify[]; + treesDesc?: { [name: string]: string }; } const settingPath = "settings.json"; @@ -23,10 +24,18 @@ const sampleNodeClassify: BehaviorNodeClassify[] = [ export default class Settings { private model: SettingsModel; + private dirty: boolean = false; curWorkspace?: Workspace; constructor() { this.load(); + + setInterval(() => { + if (this.dirty) { + fs.writeFileSync(settingPath, JSON.stringify(this.model, null, 2)); + this.dirty = false; + } + }, 1000) } get nodeConfPath() { @@ -66,7 +75,7 @@ export default class Settings { return this.model.serverName; } } - if(servers[0]) { + if (servers[0]) { return servers[0].name; } else { return '' @@ -88,6 +97,10 @@ export default class Settings { if (fs.existsSync(settingPath)) { const str = fs.readFileSync(settingPath, "utf8"); this.model = JSON.parse(str); + if (!this.model.treesDesc) { + this.model.treesDesc = {}; + this.save(); + } } else { this.model = { recentWorkspaces: ["sample/workspace.json"], @@ -101,7 +114,7 @@ export default class Settings { } save() { - fs.writeFileSync(settingPath, JSON.stringify(this.model, null, 2)); + this.dirty = true; } getNodeConf(name: string) { @@ -114,10 +127,28 @@ export default class Settings { list = list.filter((value) => value !== path); } list.unshift(path); - while(list.length > 10) { + while (list.length > 10) { list.pop(); } this.model.recentWorkspaces = list; this.save(); } + + getTreeDesc(name: string) { + const key = this.curWorkspace.getFilepath() + ' ' + name; + var desc = this.model.treesDesc[key]; + if (!desc) { + const str = fs.readFileSync(name, "utf8"); + const tree = JSON.parse(str); + desc = tree.desc ? tree.desc : ''; + this.model.treesDesc[key] = desc; + this.save(); + } + return desc; + } + + setTreeDesc(name: string, desc?: string) { + const key = this.curWorkspace.getFilepath() + ' ' + name; + this.model.treesDesc[key] = desc; + } } diff --git a/package.json b/package.json index 76e5fa7..815a3ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "behavior3editor", - "version": "0.1.7", + "version": "0.1.8", "description": "行为树编辑器", "main": "./dist/main.js", "scripts": { diff --git a/render-process/Explorer.tsx b/render-process/Explorer.tsx index 05f41d3..aa52f48 100644 --- a/render-process/Explorer.tsx +++ b/render-process/Explorer.tsx @@ -1,27 +1,33 @@ import React, { ChangeEvent, Component } from "react"; import { Input } from "antd"; import { Tree } from "shineout"; -import {FolderOutlined ,FileOutlined,FolderOpenOutlined} from "@ant-design/icons"; +import { FolderOutlined, FileOutlined, FolderOpenOutlined } from "@ant-design/icons"; import * as fs from "fs"; import * as path from "path"; import { ipcRenderer } from "electron"; import MainEventType from "../common/MainEventType"; +import Settings from "../main-process/Settings"; +import * as Utils from "../common/Utils"; -const {Search} = Input; +const { Search } = Input; const DirectoryTree = Tree; class FileDataNode { name: string; //display name + desc: string; //describe filepath: string; //file full path isFolder: boolean; + settings: Settings; + parent: FileDataNode; visible: boolean = true; children: FileDataNode[]; - public constructor(init?: Partial) { + public constructor(init?: Partial, settings?: Settings) { Object.assign(this, init); + this.settings = settings; } get id() { @@ -29,7 +35,10 @@ class FileDataNode { } get text() { - return this.name; + if (!this.desc) { + return this.name; + } + return `${this.name}(${this.desc})`; } get path() { @@ -42,10 +51,11 @@ class FileDataNode { } let ret = new FileDataNode({ name: this.name, + desc: this.isFolder ? undefined : this.settings.getTreeDesc(this.filepath), filepath: this.filepath, isFolder: this.isFolder, children: new Array(), - }); + }, this.settings); for (const child of this.children) { const data = child.getRenderData(); @@ -70,10 +80,11 @@ class FileDataNode { const name = isFolder ? filename : filename.slice(0, -5); const node = new FileDataNode({ name: name, + desc: isFolder ? undefined : this.settings.getTreeDesc(fullPath), filepath: fullPath, isFolder: isFolder, parent: this, - }); + }, this.settings); (node.children = isFolder && recursive ? (node.loadChilds(recursive) as FileDataNode[]) : []), @@ -87,46 +98,6 @@ class FileDataNode { return list; } - - // async updateChilds(recursive?: boolean): Promise { - // const folder = this.path; - // if (folder == "" || !fs.existsSync(folder)) { - // return []; - // } - // this.loading = true; - // await fs.promises.readdir(folder).then((files) => { - // this.loading = false; - // let list = new Array(); - // 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({ - // name: name, - // filepath: fullPath, - // isFolder: isFolder, - // parent: this, - // children: [], - // }); - - // if (isFolder && recursive) { - // node.updateChilds(recursive).then((children)=>{ - // node.children = children; - // }); - // } - // list.push(node); - // }); - // list.sort((a, b) => { - // const av = a.isFolder ? 100 : 0; - // const bv = b.isFolder ? 100 : 0; - // return bv - av; - // }); - // this.children = list; - // }); - // return this.children; - // } - addChild(filePath: string) { const isDir = fs.statSync(filePath).isDirectory(); const newNode = new FileDataNode({ @@ -135,7 +106,7 @@ class FileDataNode { isFolder: isDir, parent: this, children: [], - }); + }, this.settings); this.children = [newNode, ...this.children]; } @@ -206,22 +177,22 @@ const NodeActions: { [x: string]: string } = { ["reveal_in_explorer"]: "Reveal In File Explorer", }; -interface ExplorerNodeProps{ - visible:boolean; - title:string; - selected:boolean; - expended:boolean; - isLeaf:boolean; - searchKey:string; +interface ExplorerNodeProps { + visible: boolean; + title: string; + selected: boolean; + expended: boolean; + isLeaf: boolean; + searchKey: string; } class ExplorerNode extends Component { shouldComponentUpdate(nextProps: ExplorerNodeProps) { - return JSON.stringify(this.props)!=JSON.stringify(nextProps); + return JSON.stringify(this.props) != JSON.stringify(nextProps); } render() { - const {title,visible,selected,expended,isLeaf,searchKey} = this.props; - if(!visible){ + const { title, visible, selected, expended, isLeaf, searchKey } = this.props; + if (!visible) { return null; } @@ -231,9 +202,9 @@ class ExplorerNode extends Component { return (
- {!isLeaf?(expended?:):} + {!isLeaf ? (expended ? : ) : } {isLeaf && index > -1 ? ( {beforeStr} @@ -241,8 +212,8 @@ class ExplorerNode extends Component { {afterStr} ) : ( - {title} - )} + {title} + )}
); } @@ -281,6 +252,7 @@ export default class Explorer extends Component { }; curWorkdir: string = ""; + settings: Settings; shouldComponentUpdate(nextProps: ExplorerProps) { const shouldUpdate = this.curWorkdir != nextProps.workdir; @@ -289,6 +261,7 @@ export default class Explorer extends Component { } componentDidMount() { + this.settings = Utils.getRemoteSettings(); ipcRenderer.on(MainEventType.CREATE_TREE, (event: any, path: string) => { console.log("on Create tree", path); this.props.onOpenTree(path); @@ -322,15 +295,15 @@ export default class Explorer extends Component { } getRootNode(workdir: string) { - if(workdir && workdir!==""){ + if (workdir && workdir !== "") { return new FileDataNode({ name: path.basename(workdir), filepath: workdir, isFolder: true, parent: null, children: [] - }); - }else{ + }, this.settings); + } else { return null; } } @@ -389,9 +362,9 @@ export default class Explorer extends Component { this.forceUpdate(); } - selectNode(id:string){ + selectNode(id: string) { this.setState({ - selectedKey:id + selectedKey: id }); this.forceUpdate(); } @@ -400,11 +373,11 @@ export default class Explorer extends Component { return (); + />); } render() { @@ -430,7 +403,7 @@ export default class Explorer extends Component { onSearch={(value, event) => { this.handleOnSearch(value?.toLowerCase()); }} - /> + /> { defaultExpanded={[root.id]} expanded={this.state.expandedKeys} value={[this.state.selectedKey]} - onExpand={(expanded)=>{ + onExpand={(expanded) => { this.setState({ expandedKeys: expanded }) this.forceUpdate(); }}