refactor: use shineout tree replace antd tree

This commit is contained in:
duanhongbo committed 2020-11-27 18:06:22 +08:00
1 parent af3f00b3b2
commit 8c6991afb3
6 files changed
+418 -151

No files matched your search

+219 -5
View File
@@ -2451,6 +2451,15 @@
"sha.js": "^2.4.8" "sha.js": "^2.4.8"
} }
}, },
"create-react-context": {
"version": "0.2.3",
"resolved": "https://registry.npm.taobao.org/create-react-context/download/create-react-context-0.2.3.tgz",
"integrity": "sha1-nsFAppFKIu8EuLCbd3HeiVZ8tvM=",
"requires": {
"fbjs": "^0.8.0",
"gud": "^1.0.0"
}
},
"cross-spawn": { "cross-spawn": {
"version": "6.0.5", "version": "6.0.5",
"resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-6.0.5.tgz", "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-6.0.5.tgz",
@@ -2663,6 +2672,14 @@
"mimic-response": "^1.0.0" "mimic-response": "^1.0.0"
} }
}, },
"deep-eql": {
"version": "4.0.0",
"resolved": "https://registry.npm.taobao.org/deep-eql/download/deep-eql-4.0.0.tgz",
"integrity": "sha1-xwrycTpOGNnCwSA/+dEau9Ucj70=",
"requires": {
"type-detect": "^4.0.0"
}
},
"deep-extend": { "deep-extend": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npm.taobao.org/deep-extend/download/deep-extend-0.6.0.tgz", "resolved": "https://registry.npm.taobao.org/deep-extend/download/deep-extend-0.6.0.tgz",
@@ -3506,6 +3523,14 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"encoding": {
"version": "0.1.13",
"resolved": "https://registry.npm.taobao.org/encoding/download/encoding-0.1.13.tgz",
"integrity": "sha1-VldK/deR9UqOmyeFwFgqLSYhD6k=",
"requires": {
"iconv-lite": "^0.6.2"
}
},
"end-of-stream": { "end-of-stream": {
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz", "resolved": "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz",
@@ -3874,6 +3899,35 @@
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
}, },
"fbjs": {
"version": "0.8.17",
"resolved": "https://registry.npm.taobao.org/fbjs/download/fbjs-0.8.17.tgz?cache=0&sync_timestamp=1602048886093&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffbjs%2Fdownload%2Ffbjs-0.8.17.tgz",
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
"requires": {
"core-js": "^1.0.0",
"isomorphic-fetch": "^2.1.1",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
"ua-parser-js": "^0.7.18"
},
"dependencies": {
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npm.taobao.org/core-js/download/core-js-1.2.7.tgz?cache=0&sync_timestamp=1606329319777&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
},
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npm.taobao.org/promise/download/promise-7.3.1.tgz",
"integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=",
"requires": {
"asap": "~2.0.3"
}
}
}
},
"fd-slicer": { "fd-slicer": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "http://registry.npm.taobao.org/fd-slicer/download/fd-slicer-1.1.0.tgz", "resolved": "http://registry.npm.taobao.org/fd-slicer/download/fd-slicer-1.1.0.tgz",
@@ -4384,6 +4438,11 @@
"lodash": "^4.17.15" "lodash": "^4.17.15"
} }
}, },
"gud": {
"version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/gud/download/gud-1.0.0.tgz",
"integrity": "sha1-pIlYGxfmpwvsqavjrlfeekmYUsA="
},
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "http://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz", "resolved": "http://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz",
@@ -4566,7 +4625,6 @@
"version": "0.6.2", "version": "0.6.2",
"resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.6.2.tgz", "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.6.2.tgz",
"integrity": "sha1-zhPRh1sMOmdL1qBLf3awGxtt7QE=", "integrity": "sha1-zhPRh1sMOmdL1qBLf3awGxtt7QE=",
"dev": true,
"requires": { "requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0" "safer-buffer": ">= 2.1.2 < 3.0.0"
} }
@@ -4598,6 +4656,18 @@
"integrity": "sha1-8VCotQo0KJsz4i9YiavU2AFvDlc=", "integrity": "sha1-8VCotQo0KJsz4i9YiavU2AFvDlc=",
"dev": true "dev": true
}, },
"image-size": {
"version": "0.5.5",
"resolved": "https://registry.npm.taobao.org/image-size/download/image-size-0.5.5.tgz?cache=0&sync_timestamp=1603731285656&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimage-size%2Fdownload%2Fimage-size-0.5.5.tgz",
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
"dev": true,
"optional": true
},
"immer": {
"version": "4.0.2",
"resolved": "https://registry.npm.taobao.org/immer/download/immer-4.0.2.tgz",
"integrity": "sha1-n/D834jgb5Jhill4zuy1iE5jNVk="
},
"import-lazy": { "import-lazy": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/import-lazy/download/import-lazy-2.1.0.tgz", "resolved": "https://registry.npm.taobao.org/import-lazy/download/import-lazy-2.1.0.tgz",
@@ -4880,6 +4950,11 @@
"isobject": "^3.0.1" "isobject": "^3.0.1"
} }
}, },
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/is-stream/download/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"is-typedarray": { "is-typedarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz", "resolved": "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz",
@@ -4930,6 +5005,15 @@
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true "dev": true
}, },
"isomorphic-fetch": {
"version": "2.2.1",
"resolved": "https://registry.npm.taobao.org/isomorphic-fetch/download/isomorphic-fetch-2.2.1.tgz?cache=0&sync_timestamp=1600844260369&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisomorphic-fetch%2Fdownload%2Fisomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"requires": {
"node-fetch": "^1.0.1",
"whatwg-fetch": ">=0.10.0"
}
},
"jake": { "jake": {
"version": "10.8.2", "version": "10.8.2",
"resolved": "https://registry.npm.taobao.org/jake/download/jake-10.8.2.tgz", "resolved": "https://registry.npm.taobao.org/jake/download/jake-10.8.2.tgz",
@@ -5041,6 +5125,12 @@
"integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=", "integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=",
"dev": true "dev": true
}, },
"klona": {
"version": "2.0.4",
"resolved": "https://registry.npm.taobao.org/klona/download/klona-2.0.4.tgz",
"integrity": "sha1-e7Hjr/sMuGJFR+9+j2cI6i4538A=",
"dev": true
},
"latest-version": { "latest-version": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npm.taobao.org/latest-version/download/latest-version-5.1.0.tgz", "resolved": "https://registry.npm.taobao.org/latest-version/download/latest-version-5.1.0.tgz",
@@ -5056,6 +5146,82 @@
"integrity": "sha1-iCY2pyRcLP5uCk47psXWihN+XGU=", "integrity": "sha1-iCY2pyRcLP5uCk47psXWihN+XGU=",
"dev": true "dev": true
}, },
"less": {
"version": "3.12.2",
"resolved": "https://registry.npm.taobao.org/less/download/less-3.12.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fless%2Fdownload%2Fless-3.12.2.tgz",
"integrity": "sha1-FX5t0ypohp34hZMUrTjnAhGvOrQ=",
"dev": true,
"requires": {
"errno": "^0.1.1",
"graceful-fs": "^4.1.2",
"image-size": "~0.5.0",
"make-dir": "^2.1.0",
"mime": "^1.4.1",
"native-request": "^1.0.5",
"source-map": "~0.6.0",
"tslib": "^1.10.0"
},
"dependencies": {
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz",
"integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=",
"dev": true,
"optional": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true,
"optional": true
}
}
},
"less-loader": {
"version": "7.1.0",
"resolved": "https://registry.npm.taobao.org/less-loader/download/less-loader-7.1.0.tgz?cache=0&sync_timestamp=1605095927771&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fless-loader%2Fdownload%2Fless-loader-7.1.0.tgz",
"integrity": "sha1-lY1B6G194Ly0kHEe4PI1qp3Flqo=",
"dev": true,
"requires": {
"klona": "^2.0.4",
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"dependencies": {
"json5": {
"version": "2.1.3",
"resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.3.tgz",
"integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
"integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"schema-utils": {
"version": "3.0.0",
"resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-3.0.0.tgz",
"integrity": "sha1-Z1AvaqK2ai1AMrQnmilEl4oJE+8=",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.6",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
}
}
},
"load-json-file": { "load-json-file": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/load-json-file/download/load-json-file-2.0.0.tgz", "resolved": "https://registry.npm.taobao.org/load-json-file/download/load-json-file-2.0.0.tgz",
@@ -5566,6 +5732,13 @@
"to-regex": "^3.0.1" "to-regex": "^3.0.1"
} }
}, },
"native-request": {
"version": "1.0.8",
"resolved": "https://registry.npm.taobao.org/native-request/download/native-request-1.0.8.tgz?cache=0&sync_timestamp=1603412804149&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnative-request%2Fdownload%2Fnative-request-1.0.8.tgz",
"integrity": "sha1-j2a/YG4PfqJ8DlmV6y9dA+M65vs=",
"dev": true,
"optional": true
},
"neo-async": { "neo-async": {
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npm.taobao.org/neo-async/download/neo-async-2.6.2.tgz", "resolved": "https://registry.npm.taobao.org/neo-async/download/neo-async-2.6.2.tgz",
@@ -5578,6 +5751,15 @@
"integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=", "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=",
"dev": true "dev": true
}, },
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npm.taobao.org/node-fetch/download/node-fetch-1.7.3.tgz?cache=0&sync_timestamp=1599309206591&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-fetch%2Fdownload%2Fnode-fetch-1.7.3.tgz",
"integrity": "sha1-mA9vcthSEaU0fGsrwYxbhMPrR+8=",
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
}
},
"node-libs-browser": { "node-libs-browser": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npm.taobao.org/node-libs-browser/download/node-libs-browser-2.2.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-libs-browser%2Fdownload%2Fnode-libs-browser-2.2.1.tgz", "resolved": "https://registry.npm.taobao.org/node-libs-browser/download/node-libs-browser-2.2.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-libs-browser%2Fdownload%2Fnode-libs-browser-2.2.1.tgz",
@@ -7075,8 +7257,7 @@
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "http://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz", "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": { "sanitize-filename": {
"version": "1.6.3", "version": "1.6.3",
@@ -7201,8 +7382,7 @@
"setimmediate": { "setimmediate": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "http://registry.npm.taobao.org/setimmediate/download/setimmediate-1.0.5.tgz", "resolved": "http://registry.npm.taobao.org/setimmediate/download/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
"dev": true
}, },
"sha.js": { "sha.js": {
"version": "2.4.11", "version": "2.4.11",
@@ -7234,6 +7414,25 @@
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
"dev": true "dev": true
}, },
"shineout": {
"version": "1.6.1",
"resolved": "https://registry.npm.taobao.org/shineout/download/shineout-1.6.1.tgz",
"integrity": "sha1-cGf1X6MG4CHHZ5MComI2t+xOfgo=",
"requires": {
"classnames": "^2.2.5",
"create-react-context": "^0.2.3",
"date-fns": "2.0.0-alpha.10",
"deep-eql": "^4.0.0",
"immer": "^4.0.0"
},
"dependencies": {
"date-fns": {
"version": "2.0.0-alpha.10",
"resolved": "https://registry.npm.taobao.org/date-fns/download/date-fns-2.0.0-alpha.10.tgz?cache=0&sync_timestamp=1598884225872&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdate-fns%2Fdownload%2Fdate-fns-2.0.0-alpha.10.tgz",
"integrity": "sha1-0zRFOk2OBkPb7i1wQ2/JJiwV2oA="
}
}
},
"signal-exit": { "signal-exit": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz?cache=0&sync_timestamp=1600349108829&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsignal-exit%2Fdownload%2Fsignal-exit-3.0.3.tgz", "resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz?cache=0&sync_timestamp=1600349108829&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsignal-exit%2Fdownload%2Fsignal-exit-3.0.3.tgz",
@@ -8053,6 +8252,11 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npm.taobao.org/type-detect/download/type-detect-4.0.8.tgz",
"integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw="
},
"type-fest": { "type-fest": {
"version": "0.13.1", "version": "0.13.1",
"resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.13.1.tgz?cache=0&sync_timestamp=1601425309553&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype-fest%2Fdownload%2Ftype-fest-0.13.1.tgz", "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.13.1.tgz?cache=0&sync_timestamp=1601425309553&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype-fest%2Fdownload%2Ftype-fest-0.13.1.tgz",
@@ -8080,6 +8284,11 @@
"integrity": "sha1-FTu9Ro7wdyXB35x36LRT+NNqu6U=", "integrity": "sha1-FTu9Ro7wdyXB35x36LRT+NNqu6U=",
"dev": true "dev": true
}, },
"ua-parser-js": {
"version": "0.7.22",
"resolved": "https://registry.npm.taobao.org/ua-parser-js/download/ua-parser-js-0.7.22.tgz?cache=0&sync_timestamp=1599900430227&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fua-parser-js%2Fdownload%2Fua-parser-js-0.7.22.tgz",
"integrity": "sha1-lg32Cl+RHqjxyBjzdHuZxuF36uM="
},
"unified": { "unified": {
"version": "9.2.0", "version": "9.2.0",
"resolved": "https://registry.npm.taobao.org/unified/download/unified-9.2.0.tgz?cache=0&sync_timestamp=1598034253769&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funified%2Fdownload%2Funified-9.2.0.tgz", "resolved": "https://registry.npm.taobao.org/unified/download/unified-9.2.0.tgz?cache=0&sync_timestamp=1598034253769&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funified%2Fdownload%2Funified-9.2.0.tgz",
@@ -8652,6 +8861,11 @@
} }
} }
}, },
"whatwg-fetch": {
"version": "3.5.0",
"resolved": "https://registry.npm.taobao.org/whatwg-fetch/download/whatwg-fetch-3.5.0.tgz",
"integrity": "sha1-YFos0KcUbl2xQeKdHGKrhMDEyGg="
},
"whatwg-mimetype": { "whatwg-mimetype": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "http://registry.npm.taobao.org/whatwg-mimetype/download/whatwg-mimetype-2.3.0.tgz", "resolved": "http://registry.npm.taobao.org/whatwg-mimetype/download/whatwg-mimetype-2.3.0.tgz",
+3
View File
@@ -36,6 +36,8 @@
"electron-localshortcut": "^3.2.1", "electron-localshortcut": "^3.2.1",
"electron-packager": "^15.1.0", "electron-packager": "^15.1.0",
"file-loader": "^6.1.1", "file-loader": "^6.1.1",
"less": "^3.12.2",
"less-loader": "^7.1.0",
"source-map-loader": "^1.1.0", "source-map-loader": "^1.1.0",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"ts-loader": "^8.0.4", "ts-loader": "^8.0.4",
@@ -56,6 +58,7 @@
"react-markdown": "^5.0.2", "react-markdown": "^5.0.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sanitize-filename": "^1.6.3", "sanitize-filename": "^1.6.3",
"shineout": "^1.6.1",
"sync-request": "^6.1.0" "sync-request": "^6.1.0"
} }
} }
@@ -1,68 +1,55 @@
import React, { ChangeEvent, Component } from "react"; import React, { ChangeEvent, Component } from "react";
import { Input, Tree, Dropdown } from "antd"; import { Input } from "antd";
import { Tree } from "shineout";
import {FolderOutlined ,FileOutlined,FolderOpenOutlined} from "@ant-design/icons";
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import { ipcRenderer } from "electron"; import { ipcRenderer } from "electron";
import MainEventType from "../common/MainEventType"; import MainEventType from "../common/MainEventType";
import { DataNode } from "antd/lib/tree";
import { EventDataNode, IconType } from "rc-tree/lib/interface";
const { Search } = Input; const {Search} = Input;
const { DirectoryTree, TreeNode } = Tree; const DirectoryTree = Tree;
export interface PropertiesProps {
workdir: string;
onOpenTree: (path: string) => void;
onDeleteTree: (path: string) => void;
}
class FileDataNode implements DataNode { class FileDataNode {
checkable?: boolean; name: string; //display name
children?: FileDataNode[]; filepath: string; //file full path
disabled?: boolean; isFolder: boolean;
disableCheckbox?: boolean;
icon?: IconType;
isLeaf?: boolean;
key: React.ReactText;
title?: React.ReactNode;
selectable?: boolean;
switcherIcon?: IconType;
className?: string;
style?: React.CSSProperties;
parent: FileDataNode; parent: FileDataNode;
visible: boolean = true; visible: boolean = true;
children: FileDataNode[];
public constructor(init?: Partial<FileDataNode>) { public constructor(init?: Partial<FileDataNode>) {
Object.assign(this, init); Object.assign(this, init);
} }
get isFolder() { get id() {
return this.isLeaf !== void 0 && !this.isLeaf; return this.filepath;
} }
get name() { get text() {
return this.title as string; return this.name;
} }
get path() { get path() {
return this.key as string; return this.filepath;
} }
public getRenderData() { public getRenderData() {
if(!this.visible){ if (!this.visible) {
return null; return null;
} }
let ret = { let ret = new FileDataNode({
title: this.title, name: this.name,
key: this.key, filepath: this.filepath,
isLeaf: this.isLeaf, isFolder: this.isFolder,
children: new Array() children: new Array(),
}; });
for (const child of this.children) { for (const child of this.children) {
const data = child.getRenderData(); const data = child.getRenderData();
if(data){ if (data) {
ret.children.push(data); ret.children.push(data);
} }
} }
@@ -70,7 +57,7 @@ class FileDataNode implements DataNode {
} }
loadChilds(recursive?: boolean) { loadChilds(recursive?: boolean) {
const folder = this.key as string; const folder = this.path;
if (folder == "" || !fs.existsSync(folder)) { if (folder == "" || !fs.existsSync(folder)) {
return []; return [];
} }
@@ -82,9 +69,9 @@ class FileDataNode implements DataNode {
const isFolder = stat.isDirectory(); const isFolder = stat.isDirectory();
const name = isFolder ? filename : filename.slice(0, -5); const name = isFolder ? filename : filename.slice(0, -5);
const node = new FileDataNode({ const node = new FileDataNode({
title: name, name: name,
key: fullPath, filepath: fullPath,
isLeaf: !isFolder, isFolder: isFolder,
parent: this, parent: this,
}); });
@@ -92,15 +79,60 @@ class FileDataNode implements DataNode {
isFolder && recursive ? (node.loadChilds(recursive) as FileDataNode[]) : []), isFolder && recursive ? (node.loadChilds(recursive) as FileDataNode[]) : []),
list.push(node); list.push(node);
}); });
list.sort((a, b) => {
const av = a.isFolder ? 100 : 0;
const bv = b.isFolder ? 100 : 0;
return bv - av;
});
return list; return list;
} }
// async updateChilds(recursive?: boolean): Promise<FileDataNode[]> {
// 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<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({
// 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) { addChild(filePath: string) {
const isDir = fs.statSync(filePath).isDirectory(); const isDir = fs.statSync(filePath).isDirectory();
const newNode = new FileDataNode({ const newNode = new FileDataNode({
title: path.basename(filePath), name: path.basename(filePath),
key: filePath, filepath: filePath,
isLeaf: !isDir, isFolder: isDir,
parent: this, parent: this,
children: [], children: [],
}); });
@@ -116,15 +148,17 @@ class FileDataNode implements DataNode {
} }
expandSelf(recursive: boolean = true) { expandSelf(recursive: boolean = true) {
if (this.isFolder) this.children = this.loadChilds(recursive); if (this.isFolder) {
this.children = this.loadChilds(recursive);
}
} }
findChild(key: string): FileDataNode { findChild(id: string): FileDataNode {
for (const child of this.children) { for (const child of this.children) {
if (child.key == key) { if (child.id == id) {
return child; return child;
} else { } else {
const ret = child.findChild(key); const ret = child.findChild(id);
if (ret) { if (ret) {
return ret; return ret;
} }
@@ -142,12 +176,12 @@ class FileDataNode implements DataNode {
return ret; return ret;
} }
setVisible(keyWord:string){ setVisible(keyWord: string) {
let ret = false; let ret = false;
for (let i = this.children.length-1;i >= 0;i--) { for (let i = this.children.length - 1; i >= 0; i--) {
const child = this.children[i]; const child = this.children[i];
if (child.isLeaf) { if (!child.isFolder) {
const keyStr = child.title as string; const keyStr = child.id;
child.visible = keyStr.includes(keyWord); child.visible = keyStr.includes(keyWord);
} else { } else {
child.visible = child.setVisible(keyWord); child.visible = child.setVisible(keyWord);
@@ -164,9 +198,17 @@ class FileDataNode implements DataNode {
// children?: NodeData[]; // children?: NodeData[];
} }
interface PropertiesState { export interface ExplorerProps {
workdir: string;
onOpenTree: (path: string) => void;
onDeleteTree: (path: string) => void;
}
interface ExplorerState {
root: FileDataNode; root: FileDataNode;
searchKey: string; searchKey: string;
selectedKey: string;
defaultExpandedKeys: string[]; defaultExpandedKeys: string[];
expandedKeys: string[]; expandedKeys: string[];
autoExpandParent: boolean; autoExpandParent: boolean;
@@ -185,10 +227,11 @@ const NodeActions: { [x: string]: string } = {
["reveal_in_explorer"]: "Reveal In File Explorer", ["reveal_in_explorer"]: "Reveal In File Explorer",
}; };
export default class Properties extends Component<PropertiesProps> { export default class Explorer extends Component<ExplorerProps> {
state: PropertiesState = { state: ExplorerState = {
root: null, root: this.getRootNode(this.props.workdir),
searchKey: "", searchKey: "",
selectedKey: "",
rightClickNode: null, rightClickNode: null,
expandedKeys: [], expandedKeys: [],
defaultExpandedKeys: [], defaultExpandedKeys: [],
@@ -197,7 +240,7 @@ export default class Properties extends Component<PropertiesProps> {
curWorkdir: string = ""; curWorkdir: string = "";
shouldComponentUpdate(nextProps: PropertiesProps) { shouldComponentUpdate(nextProps: ExplorerProps) {
const shouldUpdate = this.curWorkdir != nextProps.workdir; const shouldUpdate = this.curWorkdir != nextProps.workdir;
this.curWorkdir = nextProps.workdir; this.curWorkdir = nextProps.workdir;
return shouldUpdate; return shouldUpdate;
@@ -226,21 +269,23 @@ export default class Properties extends Component<PropertiesProps> {
return; return;
} }
const root = this.getRootNode(workdir); const root = this.getRootNode(workdir);
root.expandSelf(); root.expandSelf()
this.setState({ this.setState({
root: root, root: root,
expandedKeys: [root.key], expandedKeys: [root.id],
defaultExpandedKeys: [root.key] defaultExpandedKeys: [root.id],
}); });
this.forceUpdate();
} }
getRootNode(workdir: string) { getRootNode(workdir: string) {
return new FileDataNode({ return new FileDataNode({
title: path.basename(workdir), name: path.basename(workdir),
key: workdir, filepath: workdir,
isLeaf: false, isFolder: true,
parent: null, parent: null,
children: [], children: []
}); });
} }
@@ -268,28 +313,27 @@ export default class Properties extends Component<PropertiesProps> {
const expandedKeys = this.state.root const expandedKeys = this.state.root
.getList() .getList()
.map((item) => { .map((item) => {
if (!item.isLeaf) if (item.isFolder) return null;
return null; const title = item.text;
const title = item.title as string;
if (title.includes(value) && item.parent) { if (title.includes(value) && item.parent) {
return item.parent.key; return item.parent.id;
} }
return null; return null;
}) })
.filter((item, i, self) => item && self.indexOf(item) === i); .filter((item, i, self) => item && self.indexOf(item) === i);
const root = this.state.root; const root = this.state.root;
root.setVisible(value||""); root.setVisible(value || "");
if (value && value.length > 0) { if (value && value.length > 0) {
this.setState({ this.setState({
root:root, root: root,
searchKey: value, searchKey: value,
expandedKeys: expandedKeys, expandedKeys: expandedKeys,
autoExpandParent: true, autoExpandParent: true,
}); });
} else { } else {
this.setState({ this.setState({
root:root, root: root,
searchKey: "", searchKey: "",
expandedKeys: this.state.defaultExpandedKeys, expandedKeys: this.state.defaultExpandedKeys,
autoExpandParent: false, autoExpandParent: false,
@@ -299,97 +343,86 @@ export default class Properties extends Component<PropertiesProps> {
this.forceUpdate(); this.forceUpdate();
} }
titleRender(node: DataNode): React.ReactNode { renderItem(node: FileDataNode) {
const titleStr = node.title as string; if(!node.visible){
return null;
}
const titleStr = node.text;
const searchKey = this.state.searchKey; const searchKey = this.state.searchKey;
const index = titleStr.indexOf(searchKey); const index = titleStr.indexOf(searchKey);
const beforeStr = titleStr.substr(0, index); const beforeStr = titleStr.substr(0, index);
const afterStr = titleStr.substr(index + searchKey.length); const afterStr = titleStr.substr(index + searchKey.length);
const expended = this.state.expandedKeys.includes(node.id );
//return (<span>{titleStr}</span>) return (
return node.isLeaf && index > -1 ? ( <div
<span> className="explorer-node"
{beforeStr} key={node.id}
<span className="site-tree-search-value">{searchKey}</span> onMouseMove={() => {}}
{afterStr} >
</span> {node.isFolder?(expended?<FolderOpenOutlined />:<FolderOutlined />):<FileOutlined />}
) : ( {!node.isFolder && index > -1 ? (
<span>{titleStr}</span> <span className="explorer-node-title">
); {beforeStr}
} <span className="explorer-node-search-value">{searchKey}</span>
{afterStr}
handleOnLoadData(loadNode: EventDataNode) { </span>
return new Promise((resolve) => { ) : (
const root = this.state.root; <span className="explorer-node-title">{titleStr}</span>
)}
const node = root.findChild(loadNode.key as string); </div>
if (node) { );
node.expandSelf();
this.setState({ root: root });
this.forceUpdate();
}
resolve();
return;
});
} }
render() { render() {
console.log("render Properties"); console.log("render Explorer");
const { onOpenTree, onDeleteTree, workdir } = this.props; const { onOpenTree, onDeleteTree, workdir } = this.props;
const root = this.state.root; const root = this.state.root;
if (!workdir || workdir === "") {
return `请打开workspace.json文件`;
}
const nodes = root ? [root.getRenderData()] : []; const nodes = root ? [root.getRenderData()] : [];
return nodes.length ? (
return (
<div> <div>
<Search <Search
allowClear allowClear
placeholder="Search" placeholder="Search"
// onChange={(e)=>{ // onChange={(e) => {
// const value = e.target.value?.toLowerCase(); // const value = e.target.value?.toLowerCase();
// this.handleOnSearch(value); // this.handleOnSearch(value);
// }} // }}
onSearch={ onSearch={(value, event) => {
(value,event)=>{ this.handleOnSearch(value?.toLowerCase());
this.handleOnSearch(value?.toLowerCase()); }}
}
}
/> />
<DirectoryTree <DirectoryTree
selectable keygen="id"
// showLine data={nodes}
checkStrictly line={true}
expandAction="click" doubleClickExpand
expandedKeys={this.state.expandedKeys} // expandIcons={[<DownOutlined />, <RightOutlined />]}
autoExpandParent={this.state.autoExpandParent} //defaultValue={[root.id]}
titleRender={this.titleRender.bind(this)} defaultExpanded={[root.id]}
treeData={nodes} expanded={this.state.expandedKeys}
defaultExpandedKeys={[root.key]} value={[this.state.selectedKey]}
onSelect={(keys, info) => { onExpand={(expanded)=>{
//console.log("onSelect", keys, info); this.setState({ expandedKeys: expanded })
if (info.node.isLeaf) { }}
onOpenTree(keys[0] as string); renderItem={this.renderItem.bind(this)}
onClick={(node: FileDataNode) => {
if (!node.isFolder) {
onOpenTree(node.path);
this.setState({
selectedKey:node.id
})
} }
}} }}
onExpand={(keys, info) => {
this.setState({
expandedKeys: keys,
autoExpandParent: false
})
// 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();
}}
loadData={this.handleOnLoadData.bind(this)}
></DirectoryTree> ></DirectoryTree>
</div> </div>
) : ( );
`Work Dir (${workdir}) Empty`
);
} }
} }
+19 -3
View File
@@ -42,10 +42,26 @@ body {
background-color: #818181; background-color: #818181;
} }
.site-tree-search-value {
color: #f50;
}
[data-theme="dark"] .site-tree-search-value { [data-theme="dark"] .site-tree-search-value {
color: #d84a1b; color: #d84a1b;
} }
.explorer-node {
margin: 0;
padding: 0;
line-height: 20px;
white-space: nowrap;
list-style: none;
outline: 0;
color: #ffffff;
}
.explorer-node-title {
color: #ffffff;
}
.explorer-node-search-value {
color: #f50;
}
+2 -2
View File
@@ -5,13 +5,13 @@ import { Layout, message, Tabs } from "antd";
import { ipcRenderer, remote } from "electron"; import { ipcRenderer, remote } from "electron";
import * as Utils from "../common/Utils"; import * as Utils from "../common/Utils";
import MainEventType from "../common/MainEventType"; import MainEventType from "../common/MainEventType";
import Properties from "./Properties";
import Settings from "../main-process/Settings"; import Settings from "../main-process/Settings";
import "antd/dist/antd.dark.css"; import "antd/dist/antd.dark.css";
import "./index.css"; import "./index.css";
import RegisterNode from "./RegisterNode"; import RegisterNode from "./RegisterNode";
import TreeTabs from "./TreeTabs"; import TreeTabs from "./TreeTabs";
import Explorer from "./Explorer";
const { Sider, Content } = Layout; const { Sider, Content } = Layout;
@@ -82,7 +82,7 @@ export default class Main extends Component {
<Layout className="body"> <Layout className="body">
<Sider className="sider" width={250}> <Sider className="sider" width={250}>
{workdir !== "" ? ( {workdir !== "" ? (
<Properties <Explorer
workdir={workdir} workdir={workdir}
onOpenTree={(path) => { onOpenTree={(path) => {
this.tabs.openFile(path); this.tabs.openFile(path);
+4 -3
View File
@@ -23,15 +23,16 @@ module.exports = {
{ test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader" }, { test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader" },
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }, { enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
{ {
test: /\.css$/, test: /\.(sass|less|css)$/,
loaders: ['style-loader', 'css-loader'] loaders: ['style-loader', 'css-loader', 'less-loader']
}, },
{//https://github.com/ashtuchkin/iconv-lite/issues/205 {//https://github.com/ashtuchkin/iconv-lite/issues/205
test: /node_modules[\/\\](iconv-lite)[\/\\].+/, test: /node_modules[\/\\](iconv-lite)[\/\\].+/,
resolve: { resolve: {
aliasFields: ['main'] aliasFields: ['main']
} }
} },
] ]
}, },