Add file load UI
This commit is contained in:
parent
8a272a9626
commit
0ab53c1800
@ -123,6 +123,10 @@ const resolve = (plugins = []) => {
|
|||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
extensions: [ ".tsx", '.ts', '.js' ],
|
extensions: [ ".tsx", '.ts', '.js' ],
|
||||||
|
fallback: {
|
||||||
|
'react/jsx-runtime': 'react/jsx-runtime.js',
|
||||||
|
'react/jsx-dev-runtime': 'react/jsx-dev-runtime.js',
|
||||||
|
},
|
||||||
plugins: plugins
|
plugins: plugins
|
||||||
};
|
};
|
||||||
|
|
||||||
|
190
package-lock.json
generated
190
package-lock.json
generated
@ -16,6 +16,8 @@
|
|||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"gl-matrix": "^3.4.3",
|
"gl-matrix": "^3.4.3",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
"react-dnd": "^16.0.1",
|
||||||
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
@ -726,6 +728,17 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime": {
|
||||||
|
"version": "7.17.9",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.17.9.tgz",
|
||||||
|
"integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==",
|
||||||
|
"dependencies": {
|
||||||
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@discoveryjs/json-ext": {
|
"node_modules/@discoveryjs/json-ext": {
|
||||||
"version": "0.5.6",
|
"version": "0.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz",
|
||||||
@ -1023,6 +1036,21 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-dnd/asap": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-dnd/asap/-/asap-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
|
||||||
|
},
|
||||||
|
"node_modules/@react-dnd/invariant": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-dnd/invariant/-/invariant-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
|
||||||
|
},
|
||||||
|
"node_modules/@react-dnd/shallowequal": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
|
||||||
|
},
|
||||||
"node_modules/@sindresorhus/is": {
|
"node_modules/@sindresorhus/is": {
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-0.14.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||||
@ -1195,7 +1223,7 @@
|
|||||||
"version": "17.0.21",
|
"version": "17.0.21",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
|
||||||
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
|
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/normalize-package-data": {
|
"node_modules/@types/normalize-package-data": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
@ -2817,6 +2845,16 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dnd-core": {
|
||||||
|
"version": "16.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/dnd-core/-/dnd-core-16.0.1.tgz",
|
||||||
|
"integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-dnd/asap": "^5.0.1",
|
||||||
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
|
"redux": "^4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dns-equal": {
|
"node_modules/dns-equal": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
||||||
@ -3317,8 +3355,7 @@
|
|||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.2.11",
|
"version": "3.2.11",
|
||||||
@ -3945,6 +3982,14 @@
|
|||||||
"he": "bin/he"
|
"he": "bin/he"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hoist-non-react-statics": {
|
||||||
|
"version": "3.3.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||||
|
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||||
|
"dependencies": {
|
||||||
|
"react-is": "^16.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hosted-git-info": {
|
"node_modules/hosted-git-info": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
||||||
@ -6164,6 +6209,43 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-dnd": {
|
||||||
|
"version": "16.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-dnd/-/react-dnd-16.0.1.tgz",
|
||||||
|
"integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
|
"@react-dnd/shallowequal": "^4.0.1",
|
||||||
|
"dnd-core": "^16.0.1",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"hoist-non-react-statics": "^3.3.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/hoist-non-react-statics": ">= 3.3.1",
|
||||||
|
"@types/node": ">= 12",
|
||||||
|
"@types/react": ">= 16",
|
||||||
|
"react": ">= 16.14"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/hoist-non-react-statics": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-dnd-html5-backend": {
|
||||||
|
"version": "16.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
|
||||||
|
"integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
|
||||||
|
"dependencies": {
|
||||||
|
"dnd-core": "^16.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
||||||
@ -6177,6 +6259,11 @@
|
|||||||
"react": "17.0.2"
|
"react": "17.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-is": {
|
||||||
|
"version": "16.13.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
|
},
|
||||||
"node_modules/read-pkg": {
|
"node_modules/read-pkg": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
||||||
@ -6305,6 +6392,19 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/redux": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/regenerator-runtime": {
|
||||||
|
"version": "0.13.9",
|
||||||
|
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||||
|
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||||
|
},
|
||||||
"node_modules/regexp.prototype.flags": {
|
"node_modules/regexp.prototype.flags": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
|
||||||
@ -8767,6 +8867,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@babel/runtime": {
|
||||||
|
"version": "7.17.9",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.17.9.tgz",
|
||||||
|
"integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==",
|
||||||
|
"requires": {
|
||||||
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@discoveryjs/json-ext": {
|
"@discoveryjs/json-ext": {
|
||||||
"version": "0.5.6",
|
"version": "0.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz",
|
||||||
@ -9013,6 +9121,21 @@
|
|||||||
"rimraf": "^3.0.2"
|
"rimraf": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@react-dnd/asap": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-dnd/asap/-/asap-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
|
||||||
|
},
|
||||||
|
"@react-dnd/invariant": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-dnd/invariant/-/invariant-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
|
||||||
|
},
|
||||||
|
"@react-dnd/shallowequal": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
|
||||||
|
},
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-0.14.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||||
@ -9176,7 +9299,7 @@
|
|||||||
"version": "17.0.21",
|
"version": "17.0.21",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
|
||||||
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
|
"integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"@types/normalize-package-data": {
|
"@types/normalize-package-data": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
@ -10488,6 +10611,16 @@
|
|||||||
"path-type": "^4.0.0"
|
"path-type": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dnd-core": {
|
||||||
|
"version": "16.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/dnd-core/-/dnd-core-16.0.1.tgz",
|
||||||
|
"integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
|
||||||
|
"requires": {
|
||||||
|
"@react-dnd/asap": "^5.0.1",
|
||||||
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
|
"redux": "^4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dns-equal": {
|
"dns-equal": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
||||||
@ -10905,8 +11038,7 @@
|
|||||||
"fast-deep-equal": {
|
"fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"fast-glob": {
|
"fast-glob": {
|
||||||
"version": "3.2.11",
|
"version": "3.2.11",
|
||||||
@ -11384,6 +11516,14 @@
|
|||||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"hoist-non-react-statics": {
|
||||||
|
"version": "3.3.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||||
|
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||||
|
"requires": {
|
||||||
|
"react-is": "^16.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hosted-git-info": {
|
"hosted-git-info": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
||||||
@ -13051,6 +13191,26 @@
|
|||||||
"object-assign": "^4.1.1"
|
"object-assign": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-dnd": {
|
||||||
|
"version": "16.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-dnd/-/react-dnd-16.0.1.tgz",
|
||||||
|
"integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
|
||||||
|
"requires": {
|
||||||
|
"@react-dnd/invariant": "^4.0.1",
|
||||||
|
"@react-dnd/shallowequal": "^4.0.1",
|
||||||
|
"dnd-core": "^16.0.1",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"hoist-non-react-statics": "^3.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react-dnd-html5-backend": {
|
||||||
|
"version": "16.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
|
||||||
|
"integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
|
||||||
|
"requires": {
|
||||||
|
"dnd-core": "^16.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
||||||
@ -13061,6 +13221,11 @@
|
|||||||
"scheduler": "^0.20.2"
|
"scheduler": "^0.20.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-is": {
|
||||||
|
"version": "16.13.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
|
},
|
||||||
"read-pkg": {
|
"read-pkg": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
||||||
@ -13163,6 +13328,19 @@
|
|||||||
"strip-indent": "^3.0.0"
|
"strip-indent": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"redux": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"regenerator-runtime": {
|
||||||
|
"version": "0.13.9",
|
||||||
|
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||||
|
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||||
|
},
|
||||||
"regexp.prototype.flags": {
|
"regexp.prototype.flags": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
|
||||||
|
@ -75,6 +75,8 @@
|
|||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"gl-matrix": "^3.4.3",
|
"gl-matrix": "^3.4.3",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
"react-dnd": "^16.0.1",
|
||||||
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ interface IConfirmPopupProps {
|
|||||||
titleI18N?: AllI18nKeys;
|
titleI18N?: AllI18nKeys;
|
||||||
titleI18NOption?: Record<string, string>;
|
titleI18NOption?: Record<string, string>;
|
||||||
infoI18n?: AllI18nKeys;
|
infoI18n?: AllI18nKeys;
|
||||||
|
infoI18nOption?: Record<string, string>;
|
||||||
yesI18n?: AllI18nKeys;
|
yesI18n?: AllI18nKeys;
|
||||||
noI18n?: AllI18nKeys;
|
noI18n?: AllI18nKeys;
|
||||||
renderInfo?: () => ReactNode;
|
renderInfo?: () => ReactNode;
|
||||||
@ -64,8 +65,10 @@ class ConfirmPopup extends Popup<IConfirmPopupProps> {
|
|||||||
this.props.renderInfo ?
|
this.props.renderInfo ?
|
||||||
this.props.renderInfo() :
|
this.props.renderInfo() :
|
||||||
this.props.infoI18n ?
|
this.props.infoI18n ?
|
||||||
<Message i18nKey={this.props.infoI18n}/> :
|
<Message
|
||||||
null
|
i18nKey={this.props.infoI18n}
|
||||||
|
options={this.props.infoI18nOption}
|
||||||
|
/> : null
|
||||||
}
|
}
|
||||||
</ConfirmContent>
|
</ConfirmContent>
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
@import "../Theme/Theme.scss";
|
@import "../Theme/Theme.scss";
|
||||||
|
|
||||||
|
div.load-file-app-root {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
div.load-file-layer-root {
|
div.load-file-layer-root {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
|
||||||
@ -19,7 +25,6 @@ div.load-file-layer-root {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
pointer-events: none;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1,25 +1,18 @@
|
|||||||
|
import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup";
|
||||||
import { Localization } from "@Component/Localization/Localization";
|
import { Localization } from "@Component/Localization/Localization";
|
||||||
import { FontLevel, Theme } from "@Component/Theme/Theme";
|
import { FontLevel, Theme } from "@Component/Theme/Theme";
|
||||||
|
import { Status, useStatus, IMixinStatusProps } from "@Context/Status";
|
||||||
import { Icon } from "@fluentui/react";
|
import { Icon } from "@fluentui/react";
|
||||||
import { Component, ReactNode } from "react";
|
import { FunctionComponent } from "react";
|
||||||
|
import { useDrop } from 'react-dnd'
|
||||||
|
import { NativeTypes } from "react-dnd-html5-backend"
|
||||||
import "./LoadFile.scss";
|
import "./LoadFile.scss";
|
||||||
|
|
||||||
interface ILoadFileState {
|
const DragFileMask: FunctionComponent = () => {
|
||||||
show: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoadFile extends Component<{}, ILoadFileState> {
|
|
||||||
|
|
||||||
public state: Readonly<ILoadFileState> = {
|
|
||||||
show: false
|
|
||||||
};
|
|
||||||
|
|
||||||
private renderMask() {
|
|
||||||
return <Theme
|
return <Theme
|
||||||
className="load-file-layer-root"
|
className="load-file-layer-root"
|
||||||
fontLevel={FontLevel.normal}
|
fontLevel={FontLevel.normal}
|
||||||
onDragEnter={this.handleWindowsDragOnFiles}
|
|
||||||
onDragLeave={this.handleWindowsDragOffFiles}
|
|
||||||
>
|
>
|
||||||
<div className="load-file-layer">
|
<div className="load-file-layer">
|
||||||
<div className="drag-icon">
|
<div className="drag-icon">
|
||||||
@ -33,37 +26,117 @@ class LoadFile extends Component<{}, ILoadFileState> {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Theme>;
|
</Theme>;
|
||||||
}
|
|
||||||
|
|
||||||
private offDragTimer: NodeJS.Timeout | undefined;
|
|
||||||
|
|
||||||
private handleWindowsDragOnFiles = () => {
|
|
||||||
clearTimeout(this.offDragTimer as number | undefined);
|
|
||||||
this.setState({
|
|
||||||
show: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleWindowsDragOffFiles = () => {
|
|
||||||
clearTimeout(this.offDragTimer as number | undefined);
|
|
||||||
this.offDragTimer = setTimeout(() => {
|
|
||||||
this.setState({
|
|
||||||
show: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentDidMount() {
|
|
||||||
window.addEventListener("dragenter", this.handleWindowsDragOnFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentWillUnmount() {
|
|
||||||
window.removeEventListener("dragenter", this.handleWindowsDragOnFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): ReactNode {
|
|
||||||
return this.state.show ? this.renderMask() : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fileChecker(status: Status, file?: File) {
|
||||||
|
|
||||||
|
if (!status) return undefined;
|
||||||
|
|
||||||
|
return new Promise((r, j) => {
|
||||||
|
|
||||||
|
// 检查文件存在性
|
||||||
|
if (!file) {
|
||||||
|
status.popup.showPopup(ConfirmPopup, {
|
||||||
|
infoI18n: "Popup.Load.Save.Error.Empty",
|
||||||
|
titleI18N: "Popup.Load.Save.Title",
|
||||||
|
yesI18n: "Popup.Load.Save.confirm"
|
||||||
|
});
|
||||||
|
return j();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测拓展名
|
||||||
|
let extendName = (file.name.match(/\.(\w+)$/) ?? [])[1];
|
||||||
|
if (extendName !== "ltss") {
|
||||||
|
status.popup.showPopup(ConfirmPopup, {
|
||||||
|
infoI18n: "Popup.Load.Save.Error.Type",
|
||||||
|
infoI18nOption: { ext: extendName },
|
||||||
|
titleI18N: "Popup.Load.Save.Title",
|
||||||
|
yesI18n: "Popup.Load.Save.confirm"
|
||||||
|
});
|
||||||
|
return j();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件读取
|
||||||
|
let fileReader = new FileReader();
|
||||||
|
fileReader.readAsText(file);
|
||||||
|
fileReader.onload = () => {
|
||||||
|
|
||||||
|
const loadFunc = () => {
|
||||||
|
|
||||||
|
// 进行转换
|
||||||
|
let errorMessage = status.archive.load(status.model, fileReader.result as string, file.name);
|
||||||
|
if (errorMessage) {
|
||||||
|
status.popup.showPopup(ConfirmPopup, {
|
||||||
|
infoI18n: "Popup.Load.Save.Error.Parse",
|
||||||
|
infoI18nOption: { why: errorMessage },
|
||||||
|
titleI18N: "Popup.Load.Save.Title",
|
||||||
|
yesI18n: "Popup.Load.Save.confirm"
|
||||||
|
});
|
||||||
|
j();
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
r(undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果保存进行提示
|
||||||
|
if (!status.archive.isSaved) {
|
||||||
|
status.popup.showPopup(ConfirmPopup, {
|
||||||
|
infoI18n: "Popup.Load.Save.Overwrite.Info",
|
||||||
|
titleI18N: "Popup.Load.Save.Title",
|
||||||
|
yesI18n: "Popup.Load.Save.Overwrite",
|
||||||
|
noI18n: "Popup.Action.No",
|
||||||
|
red: "yes",
|
||||||
|
yes: () => {
|
||||||
|
loadFunc();
|
||||||
|
},
|
||||||
|
no: () => {
|
||||||
|
j();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
loadFunc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileReader.onerror = () => {
|
||||||
|
status.popup.showPopup(ConfirmPopup, {
|
||||||
|
infoI18n: "Popup.Load.Save.Error.Parse",
|
||||||
|
infoI18nOption: { why: "Unknown error" },
|
||||||
|
titleI18N: "Popup.Load.Save.Title",
|
||||||
|
yesI18n: "Popup.Load.Save.confirm"
|
||||||
|
});
|
||||||
|
j();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const LoadFileView: FunctionComponent<IMixinStatusProps> = (props) => {
|
||||||
|
|
||||||
|
const [{ isOver }, drop] = useDrop(() => ({
|
||||||
|
accept: NativeTypes.FILE,
|
||||||
|
drop: (item: { files: File[] }) => {
|
||||||
|
if (props.status) {
|
||||||
|
fileChecker(props.status, item.files[0]).catch((e) => undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collect: (monitor) => ({
|
||||||
|
isOver: monitor.isOver()
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
return <>
|
||||||
|
{
|
||||||
|
isOver ? <DragFileMask/> : null
|
||||||
|
}
|
||||||
|
<div className="load-file-app-root" ref={drop}>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
const LoadFile = useStatus(LoadFileView);
|
||||||
|
|
||||||
export { LoadFile };
|
export { LoadFile };
|
@ -161,6 +161,11 @@ class Status extends Emitter<IStatusEvent> {
|
|||||||
this.emit("labelChange");
|
this.emit("labelChange");
|
||||||
this.emit("behaviorChange");
|
this.emit("behaviorChange");
|
||||||
|
|
||||||
|
// 清除焦点对象
|
||||||
|
this.setBehaviorObject();
|
||||||
|
this.setFocusObject(new Set());
|
||||||
|
this.setLabelObject();
|
||||||
|
|
||||||
// 映射
|
// 映射
|
||||||
this.emit("fileLoad");
|
this.emit("fileLoad");
|
||||||
});
|
});
|
||||||
|
@ -65,6 +65,13 @@ const EN_US = {
|
|||||||
"Popup.Delete.Behavior.Confirm": "Are you sure you want to delete this behavior? The behavior is deleted and cannot be recalled.",
|
"Popup.Delete.Behavior.Confirm": "Are you sure you want to delete this behavior? The behavior is deleted and cannot be recalled.",
|
||||||
"Popup.Restore.Behavior.Confirm": "Are you sure you want to reset all parameters of this behavior? This operation cannot be recalled.",
|
"Popup.Restore.Behavior.Confirm": "Are you sure you want to reset all parameters of this behavior? This operation cannot be recalled.",
|
||||||
"Popup.Setting.Title": "Preferences setting",
|
"Popup.Setting.Title": "Preferences setting",
|
||||||
|
"Popup.Load.Save.Title": "Load save",
|
||||||
|
"Popup.Load.Save.confirm": "Got it",
|
||||||
|
"Popup.Load.Save.Overwrite": "Overwrite and continue",
|
||||||
|
"Popup.Load.Save.Overwrite.Info": "The current workspace will be overwritten after the archive is loaded, and all unsaved progress will be lost. Are you sure you want to continue?",
|
||||||
|
"Popup.Load.Save.Error.Empty": "File information acquisition error. The file has been lost or moved.",
|
||||||
|
"Popup.Load.Save.Error.Type": "The file with extension name \"{ext}\" cannot be loaded temporarily",
|
||||||
|
"Popup.Load.Save.Error.Parse": "Archive parsing error, detailed reason: \n{why}",
|
||||||
"Popup.Add.Behavior.Title": "Add behavior",
|
"Popup.Add.Behavior.Title": "Add behavior",
|
||||||
"Popup.Add.Behavior.Action.Add": "Add all select behavior",
|
"Popup.Add.Behavior.Action.Add": "Add all select behavior",
|
||||||
"Popup.Add.Behavior.Select.Counter": "Selected {count} behavior",
|
"Popup.Add.Behavior.Select.Counter": "Selected {count} behavior",
|
||||||
|
@ -65,6 +65,13 @@ const ZH_CN = {
|
|||||||
"Popup.Delete.Behavior.Confirm": "你确定要删除这个行为吗?行为被删除将无法撤回。",
|
"Popup.Delete.Behavior.Confirm": "你确定要删除这个行为吗?行为被删除将无法撤回。",
|
||||||
"Popup.Restore.Behavior.Confirm": "你确定要重置此行为的全部参数吗?此操作无法撤回。",
|
"Popup.Restore.Behavior.Confirm": "你确定要重置此行为的全部参数吗?此操作无法撤回。",
|
||||||
"Popup.Setting.Title": "首选项设置",
|
"Popup.Setting.Title": "首选项设置",
|
||||||
|
"Popup.Load.Save.Title": "加载存档",
|
||||||
|
"Popup.Load.Save.confirm": "我知道了",
|
||||||
|
"Popup.Load.Save.Overwrite": "覆盖并继续",
|
||||||
|
"Popup.Load.Save.Overwrite.Info": "存档加载后将覆盖当前工作区,未保存的进度将全部丢失,确定要继续吗?",
|
||||||
|
"Popup.Load.Save.Error.Empty": "文件信息获取错误,文件已丢失或已被移动",
|
||||||
|
"Popup.Load.Save.Error.Type": "暂时无法加载拓展名为 \"{ext}\" 的文件",
|
||||||
|
"Popup.Load.Save.Error.Parse": "存档解析错误,详细原因: \n{why}",
|
||||||
"Popup.Add.Behavior.Title": "添加行为",
|
"Popup.Add.Behavior.Title": "添加行为",
|
||||||
"Popup.Add.Behavior.Action.Add": "添加全部选中行为",
|
"Popup.Add.Behavior.Action.Add": "添加全部选中行为",
|
||||||
"Popup.Add.Behavior.Select.Counter": "已选择 {count} 个行为",
|
"Popup.Add.Behavior.Select.Counter": "已选择 {count} 个行为",
|
||||||
|
@ -100,7 +100,7 @@ class Archive extends Emitter<IArchiveEvent> {
|
|||||||
|
|
||||||
// 解析为 JSON 对象
|
// 解析为 JSON 对象
|
||||||
const archive: IArchiveObject = JSON.parse(data);
|
const archive: IArchiveObject = JSON.parse(data);
|
||||||
console.log(archive);
|
// console.log(archive);
|
||||||
|
|
||||||
// 实例化全部对象
|
// 实例化全部对象
|
||||||
const objectPool: CtrlObject[] = [];
|
const objectPool: CtrlObject[] = [];
|
||||||
@ -254,7 +254,7 @@ class Archive extends Emitter<IArchiveEvent> {
|
|||||||
* 加载文件为模型
|
* 加载文件为模型
|
||||||
* @return Model
|
* @return Model
|
||||||
*/
|
*/
|
||||||
public load(model: Model, data: string): string | undefined {
|
public load(model: Model, data: string, name: string, url?: string): string | undefined {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.loadArchiveIntoModel(model, data);
|
this.loadArchiveIntoModel(model, data);
|
||||||
@ -262,8 +262,11 @@ class Archive extends Emitter<IArchiveEvent> {
|
|||||||
return e as string;
|
return e as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isSaved = true;
|
|
||||||
this.emit("fileLoad", this);
|
this.emit("fileLoad", this);
|
||||||
|
this.fileName = name;
|
||||||
|
this.isSaved = true;
|
||||||
|
this.isNewFile = false;
|
||||||
|
this.emit("fileSave", this);
|
||||||
};
|
};
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Component, ReactNode } from "react";
|
import { Component, ReactNode } from "react";
|
||||||
|
import { DndProvider } from 'react-dnd'
|
||||||
|
import { HTML5Backend } from 'react-dnd-html5-backend'
|
||||||
import { SettingProvider, Setting, Platform } from "@Context/Setting";
|
import { SettingProvider, Setting, Platform } from "@Context/Setting";
|
||||||
import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme";
|
import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme";
|
||||||
import { StatusProvider, Status } from "@Context/Status";
|
import { StatusProvider, Status } from "@Context/Status";
|
||||||
@ -7,12 +9,10 @@ import { initializeIcons } from '@fluentui/font-icons-mdl2';
|
|||||||
import { RootContainer } from "@Component/Container/RootContainer";
|
import { RootContainer } from "@Component/Container/RootContainer";
|
||||||
import { LayoutDirection } from "@Context/Layout";
|
import { LayoutDirection } from "@Context/Layout";
|
||||||
import { LoadFile } from "@Component/LoadFile/LoadFile";
|
import { LoadFile } from "@Component/LoadFile/LoadFile";
|
||||||
import { AllBehaviors, getBehaviorById } from "@Behavior/Behavior";
|
|
||||||
import { CommandBar } from "@Component/CommandBar/CommandBar";
|
import { CommandBar } from "@Component/CommandBar/CommandBar";
|
||||||
import { HeaderBar } from "@Component/HeaderBar/HeaderBar";
|
import { HeaderBar } from "@Component/HeaderBar/HeaderBar";
|
||||||
import { Popup } from "@Component/Popup/Popup";
|
import { Popup } from "@Component/Popup/Popup";
|
||||||
import { Entry } from "../Entry/Entry";
|
import { Entry } from "../Entry/Entry";
|
||||||
import { Group } from "@Model/Group";
|
|
||||||
import "./SimulatorWeb.scss";
|
import "./SimulatorWeb.scss";
|
||||||
|
|
||||||
initializeIcons("https://img.mrkbear.com/fabric-cdn-prod_20210407.001/");
|
initializeIcons("https://img.mrkbear.com/fabric-cdn-prod_20210407.001/");
|
||||||
@ -42,118 +42,6 @@ class SimulatorWeb extends Component {
|
|||||||
this.status.bindRenderer(classicRender);
|
this.status.bindRenderer(classicRender);
|
||||||
this.status.setting = this.setting;
|
this.status.setting = this.setting;
|
||||||
|
|
||||||
const randomPosition = (group: Group) => {
|
|
||||||
group.individuals.forEach((individual) => {
|
|
||||||
individual.position[0] = (Math.random() - .5) * 2;
|
|
||||||
individual.position[1] = (Math.random() - .5) * 2;
|
|
||||||
individual.position[2] = (Math.random() - .5) * 2;
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// 测试代码
|
|
||||||
if (false) {
|
|
||||||
let group = this.status.newGroup();
|
|
||||||
let range = this.status.newRange();
|
|
||||||
range.color = [.1, .5, .9];
|
|
||||||
group.new(100);
|
|
||||||
group.color = [.8, .1, .6];
|
|
||||||
randomPosition(group);
|
|
||||||
this.status.model.update(0);
|
|
||||||
this.status.newLabel().name = "New Label";
|
|
||||||
this.status.newLabel().name = "Test Label 01";
|
|
||||||
let template = this.status.model.addBehavior(AllBehaviors[0]);
|
|
||||||
template.name = "Template"; template.color = [150, 20, 220];
|
|
||||||
let dynamic = this.status.model.addBehavior(AllBehaviors[1]);
|
|
||||||
dynamic.name = "Dynamic"; dynamic.color = [250, 200, 80];
|
|
||||||
let brownian = this.status.model.addBehavior(AllBehaviors[2]);
|
|
||||||
brownian.name = "Brownian"; brownian.color = [200, 80, 250];
|
|
||||||
let boundary = this.status.model.addBehavior(AllBehaviors[3]);
|
|
||||||
boundary.name = "Boundary"; boundary.color = [80, 200, 250];
|
|
||||||
boundary.parameter.range.picker = this.status.model.allRangeLabel;
|
|
||||||
group.addBehavior(template);
|
|
||||||
group.addBehavior(dynamic);
|
|
||||||
group.addBehavior(brownian);
|
|
||||||
group.addBehavior(boundary);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 鱼群模型测试
|
|
||||||
if (false) {
|
|
||||||
let fish1 = this.status.newGroup();
|
|
||||||
let fish2 = this.status.newGroup();
|
|
||||||
let shark = this.status.newGroup();
|
|
||||||
let range = this.status.newRange();
|
|
||||||
|
|
||||||
range.displayName = "Experimental site";
|
|
||||||
range.color = [.8, .1, .6];
|
|
||||||
|
|
||||||
fish1.new(100);
|
|
||||||
fish1.displayName = "Fish A";
|
|
||||||
fish1.color = [.1, .5, .9];
|
|
||||||
randomPosition(fish1);
|
|
||||||
|
|
||||||
fish2.new(50);
|
|
||||||
fish2.displayName = "Fish B";
|
|
||||||
fish2.color = [.3, .2, .9];
|
|
||||||
randomPosition(fish2);
|
|
||||||
|
|
||||||
shark.new(3);
|
|
||||||
shark.displayName = "Shark";
|
|
||||||
shark.color = [.8, .2, .3];
|
|
||||||
shark.renderParameter.size = 100;
|
|
||||||
shark.renderParameter.shape = "5";
|
|
||||||
randomPosition(shark);
|
|
||||||
|
|
||||||
this.status.model.update(0);
|
|
||||||
let fishLabel = this.status.newLabel();
|
|
||||||
fishLabel.name = "Fish";
|
|
||||||
fish1.addLabel(fishLabel);
|
|
||||||
fish2.addLabel(fishLabel);
|
|
||||||
|
|
||||||
let template = this.status.model.addBehavior(getBehaviorById("Template"));
|
|
||||||
template.name = "Template"; template.color = [150, 20, 220];
|
|
||||||
|
|
||||||
let dynamicFish = this.status.model.addBehavior(getBehaviorById("PhysicsDynamics"));
|
|
||||||
dynamicFish.name = "Dynamic Fish"; dynamicFish.color = [250, 200, 80];
|
|
||||||
|
|
||||||
let dynamicShark = this.status.model.addBehavior(getBehaviorById("PhysicsDynamics"));
|
|
||||||
dynamicShark.name = "Dynamic Shark"; dynamicShark.color = [250, 200, 80];
|
|
||||||
dynamicShark.parameter.maxAcceleration = 8.5;
|
|
||||||
dynamicShark.parameter.maxVelocity = 15.8;
|
|
||||||
dynamicShark.parameter.resistance = 3.6;
|
|
||||||
|
|
||||||
let brownian = this.status.model.addBehavior(getBehaviorById("Brownian"));
|
|
||||||
brownian.name = "Brownian"; brownian.color = [200, 80, 250];
|
|
||||||
|
|
||||||
let boundary = this.status.model.addBehavior(getBehaviorById("BoundaryConstraint"));
|
|
||||||
boundary.name = "Boundary"; boundary.color = [80, 200, 250];
|
|
||||||
boundary.parameter.range.picker = this.status.model.allRangeLabel;
|
|
||||||
|
|
||||||
let tracking = this.status.model.addBehavior(getBehaviorById("Tracking"));
|
|
||||||
tracking.name = "Tracking"; tracking.color = [80, 200, 250];
|
|
||||||
tracking.parameter.target.picker = fishLabel;
|
|
||||||
|
|
||||||
let attacking = this.status.model.addBehavior(getBehaviorById("ContactAttacking"));
|
|
||||||
attacking.name = "Contact Attacking"; attacking.color = [120, 100, 250];
|
|
||||||
attacking.parameter.target.picker = fishLabel;
|
|
||||||
|
|
||||||
fish1.addBehavior(dynamicFish);
|
|
||||||
fish1.addBehavior(brownian);
|
|
||||||
fish1.addBehavior(boundary);
|
|
||||||
|
|
||||||
fish2.addBehavior(dynamicFish);
|
|
||||||
fish2.addBehavior(brownian);
|
|
||||||
fish2.addBehavior(boundary);
|
|
||||||
|
|
||||||
shark.addBehavior(dynamicShark);
|
|
||||||
shark.addBehavior(boundary);
|
|
||||||
shark.addBehavior(tracking);
|
|
||||||
shark.addBehavior(attacking);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.status.model.updateBehaviorParameter();
|
|
||||||
}, 200)
|
|
||||||
}
|
|
||||||
|
|
||||||
(window as any).LT = {
|
(window as any).LT = {
|
||||||
status: this.status,
|
status: this.status,
|
||||||
setting: this.setting
|
setting: this.setting
|
||||||
@ -193,7 +81,9 @@ class SimulatorWeb extends Component {
|
|||||||
public render(): ReactNode {
|
public render(): ReactNode {
|
||||||
return <SettingProvider value={this.setting}>
|
return <SettingProvider value={this.setting}>
|
||||||
<StatusProvider value={this.status}>
|
<StatusProvider value={this.status}>
|
||||||
|
<DndProvider backend={HTML5Backend}>
|
||||||
{this.renderContent()}
|
{this.renderContent()}
|
||||||
|
</DndProvider>
|
||||||
</StatusProvider>
|
</StatusProvider>
|
||||||
</SettingProvider>
|
</SettingProvider>
|
||||||
}
|
}
|
||||||
@ -204,8 +94,8 @@ class SimulatorWeb extends Component {
|
|||||||
backgroundLevel={BackgroundLevel.Level5}
|
backgroundLevel={BackgroundLevel.Level5}
|
||||||
fontLevel={FontLevel.Level3}
|
fontLevel={FontLevel.Level3}
|
||||||
>
|
>
|
||||||
<LoadFile/>
|
|
||||||
<Popup/>
|
<Popup/>
|
||||||
|
<LoadFile>
|
||||||
<HeaderBar height={45}/>
|
<HeaderBar height={45}/>
|
||||||
<div className="app-root-space" style={{
|
<div className="app-root-space" style={{
|
||||||
height: `calc( 100% - ${45}px)`
|
height: `calc( 100% - ${45}px)`
|
||||||
@ -213,6 +103,7 @@ class SimulatorWeb extends Component {
|
|||||||
<CommandBar/>
|
<CommandBar/>
|
||||||
<RootContainer/>
|
<RootContainer/>
|
||||||
</div>
|
</div>
|
||||||
|
</LoadFile>
|
||||||
</Theme>
|
</Theme>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user