From 541d36a8e2793f11aaf154e3c18e455ee016fa65 Mon Sep 17 00:00:00 2001 From: Dreamacro <305009791@qq.com> Date: Wed, 3 Jul 2019 22:32:19 +0800 Subject: [PATCH] Migration: remove all class component --- configs/webpack/dev.js | 5 + package-lock.json | 429 +++++++++++------- package.json | 9 +- src/containers/App.tsx | 56 +-- .../ExternalControllerDrawer/index.tsx | 155 +++---- src/containers/Overview/index.tsx | 34 +- .../Proxies/components/Group/index.tsx | 57 ++- .../ModifyProxyDialog/FormItems.tsx | 144 ------ .../components/ModifyProxyDialog/index.tsx | 224 --------- .../components/ModifyProxyDialog/style.scss | 51 --- .../Proxies/components/Proxy/index.tsx | 106 ++--- src/containers/Proxies/components/index.ts | 1 - src/containers/Proxies/index.tsx | 86 ++-- src/containers/Rules/index.tsx | 74 ++- src/containers/Settings/index.tsx | 343 +++++++------- src/lib/createStore.ts | 14 - src/lib/request.ts | 5 +- src/models/BaseProps.ts | 12 +- src/render.tsx | 14 +- src/stores/ConfigStore.ts | 228 ---------- src/stores/RouterStore.ts | 14 - src/stores/index.ts | 2 - 22 files changed, 683 insertions(+), 1380 deletions(-) delete mode 100644 src/containers/Proxies/components/ModifyProxyDialog/FormItems.tsx delete mode 100644 src/containers/Proxies/components/ModifyProxyDialog/index.tsx delete mode 100644 src/containers/Proxies/components/ModifyProxyDialog/style.scss delete mode 100644 src/lib/createStore.ts delete mode 100644 src/stores/ConfigStore.ts delete mode 100644 src/stores/RouterStore.ts diff --git a/configs/webpack/dev.js b/configs/webpack/dev.js index 38aa491..d1c3598 100644 --- a/configs/webpack/dev.js +++ b/configs/webpack/dev.js @@ -17,6 +17,11 @@ module.exports = merge(commonConfig, { hot: true, // enable HMR on the server noInfo: true, }, + resolve: { + alias: { + 'react-dom': '@hot-loader/react-dom' + } + }, devtool: 'cheap-module-eval-source-map', plugins: [ new webpack.HotModuleReplacementPlugin(), // enable HMR globally diff --git a/package-lock.json b/package-lock.json index f92b306..a112459 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,14 +20,6 @@ "output-file-sync": "^2.0.0", "slash": "^2.0.0", "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/code-frame": { @@ -70,32 +62,11 @@ "ms": "^2.1.1" } }, - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, @@ -110,14 +81,6 @@ "lodash": "^4.17.11", "source-map": "^0.5.0", "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/helper-annotate-as-pure": { @@ -925,6 +888,18 @@ "to-fast-properties": "^2.0.0" } }, + "@hot-loader/react-dom": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/@hot-loader/react-dom/-/react-dom-16.8.6.tgz", + "integrity": "sha512-+JHIYh33FVglJYZAUtRjfT5qZoT2mueJGNzU5weS2CVw26BgbxGKSujlJhO85BaRbg8sqNWyW1hYBILgK3ZCgA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -1021,15 +996,6 @@ "@types/react": "*" } }, - "@types/react-i18next": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/react-i18next/-/react-i18next-8.1.0.tgz", - "integrity": "sha512-d4xhcjX5b3roNMObRNMfb1HinHQlQLPo8xlDj60dnHeeAw2bBymR2cy/l1giJpHzo/ZFgSvgVUvIWr4kCrenCg==", - "dev": true, - "requires": { - "react-i18next": "*" - } - }, "@types/react-router": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.0.3.tgz", @@ -1317,6 +1283,7 @@ "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -1327,12 +1294,14 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true }, "ajv-keywords": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", - "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==" + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", + "dev": true }, "ansi-colors": { "version": "3.2.4", @@ -1385,7 +1354,8 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true }, "arch": { "version": "2.1.1", @@ -1894,7 +1864,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", @@ -1975,7 +1946,8 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true }, "bignumber.js": { "version": "2.4.0", @@ -2245,7 +2217,8 @@ "bluebird": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "dev": true }, "bmp-js": { "version": "0.0.3", @@ -2318,6 +2291,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2492,7 +2466,8 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, "buffer-indexof": { "version": "1.1.1", @@ -2528,6 +2503,7 @@ "version": "11.3.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", + "dev": true, "requires": { "bluebird": "^3.5.5", "chownr": "^1.1.1", @@ -2543,6 +2519,23 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } } }, "cache-base": { @@ -2742,7 +2735,8 @@ "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "dev": true }, "chrome-trace-event": { "version": "1.0.2", @@ -2798,6 +2792,14 @@ "dev": true, "requires": { "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "cliui": { @@ -2948,12 +2950,14 @@ "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true }, "component-emitter": { "version": "1.3.0", @@ -2999,12 +3003,14 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -3091,6 +3097,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, "requires": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", @@ -3139,7 +3146,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cosmiconfig": { "version": "5.2.1", @@ -3212,26 +3220,6 @@ "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "optional": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true, - "optional": true - } } }, "crypto-browserify": { @@ -3315,15 +3303,6 @@ "requires": { "mdn-data": "~1.1.0", "source-map": "^0.5.3" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "optional": true - } } }, "css-url-regex": { @@ -3365,13 +3344,6 @@ "mdn-data": "~1.1.0", "source-map": "^0.5.3" } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "optional": true } } }, @@ -3405,7 +3377,8 @@ "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true }, "d": { "version": "1.0.1", @@ -4016,6 +3989,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -4075,7 +4049,8 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true }, "encodeurl": { "version": "1.0.2", @@ -4087,6 +4062,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, "requires": { "once": "^1.4.0" } @@ -4112,6 +4088,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, "requires": { "prr": "~1.0.1" } @@ -4582,7 +4559,8 @@ "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true }, "fast-glob": { "version": "2.2.7", @@ -4601,7 +4579,8 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -4631,7 +4610,8 @@ "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true }, "figures": { "version": "1.7.0", @@ -4741,6 +4721,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -4751,6 +4732,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -4808,6 +4790,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, "requires": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" @@ -4887,6 +4870,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" @@ -4909,6 +4893,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, "requires": { "graceful-fs": "^4.1.2", "iferr": "^0.1.5", @@ -4919,7 +4904,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "1.2.9", @@ -5579,6 +5565,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5729,7 +5716,8 @@ "graceful-fs": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", - "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", + "dev": true }, "graceful-readlink": { "version": "1.0.1", @@ -6182,7 +6170,8 @@ "iferr": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true }, "ignore": { "version": "3.3.10", @@ -6439,7 +6428,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "indent-string": { "version": "2.1.0", @@ -6461,6 +6451,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -6469,7 +6460,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "ini": { "version": "1.3.5", @@ -6931,7 +6923,8 @@ "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true }, "isarray": { "version": "0.0.1", @@ -7066,7 +7059,8 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stringify-safe": { "version": "5.0.1", @@ -7081,9 +7075,10 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, "requires": { "minimist": "^1.2.0" }, @@ -7091,7 +7086,8 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true } } }, @@ -7212,16 +7208,35 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, "requires": { "big.js": "^5.2.2", "emojis-list": "^2.0.0", "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -7345,17 +7360,21 @@ } }, "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "optional": true, "requires": { - "yallist": "^3.0.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -7659,6 +7678,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7666,7 +7686,8 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true }, "minimist-options": { "version": "3.0.2", @@ -7682,6 +7703,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, "requires": { "concat-stream": "^1.5.0", "duplexify": "^3.4.2", @@ -7738,37 +7760,16 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, "requires": { "minimist": "0.0.8" } }, - "mobx": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.10.1.tgz", - "integrity": "sha512-L+akEGxdkKYssejgW9ayRPx5cZYJfxvTmdBUeR3S9oeumScV7Jj57yPeh9WMEk6NWeG8Wx3H0cWhqs0pftbtmg==" - }, - "mobx-react": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-6.1.1.tgz", - "integrity": "sha512-hjACWCTpxZf9Sv1YgWF/r6HS6Nsly1SYF22qBJeUE3j+FMfoptgjf8Zmcx2d6uzA07Cezwap5Cobq9QYa0MKUw==", - "requires": { - "mobx-react-lite": "1.4.0" - } - }, - "mobx-react-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-1.4.0.tgz", - "integrity": "sha512-5xCuus+QITQpzKOjAOIQ/YxNhOl/En+PlNJF+5QU4Qxn9gnNMJBbweAdEW3HnuVQbfqDYEUnkGs5hmkIIStehg==" - }, - "mobx-react-router": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/mobx-react-router/-/mobx-react-router-4.0.7.tgz", - "integrity": "sha512-x7eza70EimFyvF0VPyj5X2MYo9jksy61UVwz5ERXWnXVE911XRTL/V2kXiX7fvVtMHzp5m2q/kxBoti9uNixEw==" - }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, "requires": { "aproba": "^1.1.1", "copy-concurrently": "^1.0.0", @@ -8229,6 +8230,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -8380,6 +8382,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -8388,6 +8391,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -8443,7 +8447,8 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "pako": { "version": "1.0.10", @@ -8455,6 +8460,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, "requires": { "cyclist": "~0.2.2", "inherits": "^2.0.3", @@ -8573,12 +8579,14 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-is-inside": { "version": "1.0.2", @@ -8664,7 +8672,8 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true }, "pinkie": { "version": "2.0.4", @@ -8694,6 +8703,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, "requires": { "find-up": "^3.0.0" } @@ -8788,6 +8798,12 @@ "supports-color": "^6.1.0" }, "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -9013,12 +9029,14 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true }, "prop-types": { "version": "15.7.2", @@ -9050,7 +9068,8 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true }, "pseudomap": { "version": "1.0.2", @@ -9083,6 +9102,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -9092,6 +9112,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, "requires": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -9102,6 +9123,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -9112,7 +9134,8 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "q": { "version": "1.5.1", @@ -9243,9 +9266,9 @@ } }, "react-hot-loader": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.12.0.tgz", - "integrity": "sha512-N+8ct1euiQnwqqDyX+SrxsgZ13ax4e8JiHbSAPf7xAshPxF3iTqVJQUxOLH90RXOFaT8LLynq0VPz3rCK7AW1A==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.12.1.tgz", + "integrity": "sha512-/DxbaR1/PYaCu8HHjD2U8Wxvy//MeHMppsa63UPFzkSoUSuDJ/SfZdff2IMz0JbIhkKFvalA98nPiBppNLIP8g==", "dev": true, "requires": { "fast-levenshtein": "^2.0.6", @@ -9418,6 +9441,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -9431,7 +9455,8 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true } } }, @@ -9799,6 +9824,7 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -9817,6 +9843,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, "requires": { "aproba": "^1.1.1" } @@ -9824,7 +9851,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "safe-regex": { "version": "1.1.0", @@ -9891,6 +9919,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, "requires": { "ajv": "^6.1.0", "ajv-errors": "^1.0.0", @@ -9937,7 +9966,8 @@ "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true }, "semver-regex": { "version": "2.0.0", @@ -10011,7 +10041,8 @@ "serialize-javascript": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", - "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==" + "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", + "dev": true }, "serve-index": { "version": "1.9.1", @@ -10239,12 +10270,6 @@ "requires": { "is-extendable": "^0.1.0" } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, @@ -10397,12 +10422,14 @@ "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "source-map-resolve": { "version": "0.5.2", @@ -10421,9 +10448,18 @@ "version": "0.5.12", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "source-map-url": { @@ -10620,6 +10656,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, "requires": { "figgy-pudding": "^3.5.1" } @@ -10678,6 +10715,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "stream-shift": "^1.0.0" @@ -10699,7 +10737,8 @@ "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true }, "stream-to": { "version": "0.2.2", @@ -10765,6 +10804,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -11436,16 +11476,26 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/terser/-/terser-4.0.2.tgz", "integrity": "sha512-IWLuJqTvx97KP3uTYkFVn93cXO+EtlzJu8TdJylq+H0VBDlPMIfQA9MBS5Vc5t3xTEUG1q0hIfHMpAP2R+gWTw==", + "dev": true, "requires": { "commander": "^2.19.0", "source-map": "~0.6.1", "source-map-support": "~0.5.10" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "terser-webpack-plugin": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz", "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==", + "dev": true, "requires": { "cacache": "^11.3.2", "find-cache-dir": "^2.0.0", @@ -11457,6 +11507,14 @@ "terser": "^4.0.0", "webpack-sources": "^1.3.0", "worker-farm": "^1.7.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "through": { @@ -11470,6 +11528,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -11777,7 +11836,8 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true }, "typescript": { "version": "3.5.2", @@ -11799,6 +11859,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -11889,6 +11955,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, "requires": { "unique-slug": "^2.0.0" } @@ -11897,6 +11964,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, "requires": { "imurmurhash": "^0.1.4" } @@ -12029,6 +12097,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -12132,7 +12201,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true }, "util.promisify": { "version": "1.0.0", @@ -12611,9 +12681,18 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "dev": true, "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "websocket-driver": { @@ -12652,6 +12731,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, "requires": { "errno": "~0.1.7" } @@ -12710,7 +12790,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write": { "version": "1.0.3", @@ -12782,17 +12863,21 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true, + "optional": true }, "yaml": { "version": "1.6.0", diff --git a/package.json b/package.json index ebf7016..9db7a00 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,11 @@ "@babel/core": "^7.4.5", "@babel/preset-env": "^7.4.5", "@babel/preset-react": "^7.0.0", + "@hot-loader/react-dom": "^16.8.6", "@types/classnames": "^2.2.8", "@types/node": "^12.0.10", "@types/react": "^16.8.22", "@types/react-dom": "^16.8.4", - "@types/react-i18next": "^8.1.0", "@types/react-router-dom": "^4.3.4", "@types/react-sortable-hoc": "^0.6.5", "@types/react-virtualized": "^9.21.2", @@ -53,13 +53,14 @@ "offline-plugin": "^5.0.7", "postcss-loader": "^3.0.0", "react-addons-test-utils": "^15.6.2", - "react-hot-loader": "^4.12.0", + "react-hot-loader": "^4.12.1", "sass": "^1.22.2", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "stylelint": "^10.1.0", "stylelint-config-standard": "^18.3.0", "stylelint-webpack-plugin": "^0.10.5", + "terser-webpack-plugin": "^1.3.0", "tslint": "^5.18.0", "tslint-config-standard": "^8.0.1", "tslint-loader": "^3.6.0", @@ -78,16 +79,12 @@ "i18next": "^17.0.6", "i18next-browser-languagedetector": "^3.0.1", "immer": "^3.1.3", - "mobx": "^5.10.1", - "mobx-react": "^6.1.1", - "mobx-react-router": "^4.0.7", "react": "^16.8.6", "react-dom": "^16.8.6", "react-i18next": "^10.11.2", "react-router-dom": "^5.0.1", "react-sortable-hoc": "^1.9.1", "react-virtualized": "^9.21.1", - "terser-webpack-plugin": "^1.3.0", "typescript": "^3.5.2", "unstated-next": "^1.1.0", "use-immer": "^0.3.2", diff --git a/src/containers/App.tsx b/src/containers/App.tsx index cfcbab4..ae21200 100644 --- a/src/containers/App.tsx +++ b/src/containers/App.tsx @@ -1,6 +1,6 @@ -import * as React from 'react' +import React, { useEffect } from 'react' import { Route, Redirect } from 'react-router-dom' -import { hot } from 'react-hot-loader' +import { hot } from 'react-hot-loader/root' import classnames from 'classnames' import { I18nProps } from '@models' import { isClashX } from '@lib/jsBridge' @@ -18,33 +18,33 @@ import { getLogsStreamReader } from '@lib/request' export interface AppProps extends I18nProps { } -@hot(module) -export default class App extends React.Component { - componentDidMount () { +function App () { + useEffect(() => { getLogsStreamReader() - } - render () { - const routes = [ - // { path: '/', name: 'Overview', component: Overview, exact: true }, - { path: '/proxies', name: 'Proxies', component: Proxies }, - { path: '/logs', name: 'Logs', component: Logs }, - { path: '/rules', name: 'Rules', component: Rules, noMobile: true }, - { path: '/settings', name: 'Settings', component: Settings } - ] + }, []) - return ( -
- -
- }/> - { - routes.map( - route => - ) - } -
- + const routes = [ + // { path: '/', name: 'Overview', component: Overview, exact: true }, + { path: '/proxies', name: 'Proxies', component: Proxies }, + { path: '/logs', name: 'Logs', component: Logs }, + { path: '/rules', name: 'Rules', component: Rules, noMobile: true }, + { path: '/settings', name: 'Settings', component: Settings } + ] + + return ( +
+ +
+ }/> + { + routes.map( + route => + ) + }
- ) - } + +
+ ) } + +export default hot(App) diff --git a/src/containers/ExternalControllerDrawer/index.tsx b/src/containers/ExternalControllerDrawer/index.tsx index 12775b2..ade828a 100644 --- a/src/containers/ExternalControllerDrawer/index.tsx +++ b/src/containers/ExternalControllerDrawer/index.tsx @@ -1,96 +1,77 @@ -import * as React from 'react' -import { withTranslation, WithTranslation } from 'react-i18next' -import { inject, observer } from 'mobx-react' -import { storeKeys } from '@lib/createStore' +import React, { useEffect } from 'react' +import { useTranslation } from 'react-i18next' +import { useObject } from '@lib/hook' import { Modal, Input, Row, Col, Alert } from '@components' -import { BaseProps } from '@models' +import { APIInfo, ExternalControllerModal } from '@stores' import './style.scss' -interface ExternalControllerModalProps extends BaseProps, WithTranslation {} - -interface ExternalControllerModalState { - hostname: string - port: string - secret: string -} - -@inject(...storeKeys) -@observer -class ExternalController extends React.Component { - - state = { +export default function ExternalController () { + const { t } = useTranslation(['Settings']) + const { data: info, update, fetch } = APIInfo.useContainer() + const { hidden, visible } = ExternalControllerModal.useContainer() + const { value, set, change } = useObject({ hostname: '', port: '', secret: '' + }) + + useEffect(() => { + fetch() + }, []) + + useEffect(() => { + set({ hostname: info.hostname, port: info.port, secret: info.secret }) + }, [info]) + + function handleOk () { + const { hostname, port, secret } = value + update({ hostname, port, secret }) } - private handleOk = () => { - const { hostname, port, secret } = this.state - this.props.store.updateAPIInfo({ hostname, port, secret }) - } - - private handleCancel = () => { - this.props.store.setShowAPIModal(false) - } - - async componentWillMount () { - await this.props.store.fetchAPIInfo() - const info = this.props.store.apiInfo - this.setState({ hostname: info.hostname, port: info.port, secret: info.secret }) - } - - render () { - const { t } = this.props - const { hostname, port, secret } = this.state - const show = this.props.store.showAPIModal - - return ( - - -

{t('externalControllerSetting.note')}

-
- - {t('externalControllerSetting.host')} - - this.setState({ hostname })} - /> - - - - {t('externalControllerSetting.port')} - - this.setState({ port })} - /> - - - - {t('externalControllerSetting.secret')} - - this.setState({ secret })} - /> - - -
- ) - } + return ( + + +

{t('externalControllerSetting.note')}

+
+ + {t('externalControllerSetting.host')} + + change('hostname', hostname)} + /> + + + + {t('externalControllerSetting.port')} + + change('port', port)} + /> + + + + {t('externalControllerSetting.secret')} + + change('secret', secret)} + /> + + +
+ ) } - -export default withTranslation(['Settings'])(ExternalController) diff --git a/src/containers/Overview/index.tsx b/src/containers/Overview/index.tsx index 2f4e3d0..84149ef 100644 --- a/src/containers/Overview/index.tsx +++ b/src/containers/Overview/index.tsx @@ -1,23 +1,21 @@ import * as React from 'react' const logo = require('@assets/LOGO-fixing.svg') -export default class Overview extends React.Component<{}, {}> { - render () { - return ( -
- Logo +export default function Overview () { + return ( +
+ Logo -

Coming Soon...

-
- ) - } +

Coming Soon...

+
+ ) } diff --git a/src/containers/Proxies/components/Group/index.tsx b/src/containers/Proxies/components/Group/index.tsx index e691a20..cb4f7db 100644 --- a/src/containers/Proxies/components/Group/index.tsx +++ b/src/containers/Proxies/components/Group/index.tsx @@ -1,43 +1,38 @@ import * as React from 'react' -import { inject } from 'mobx-react' -import { BaseComponentProps } from '@models' -import { ConfigStore } from '@stores' +import { Data } from '@stores' import { changeProxySelected, Group as IGroup } from '@lib/request' -import { storeKeys } from '@lib/createStore' import { Tags } from '@components' import './style.scss' -interface GroupProps extends BaseComponentProps { +interface GroupProps { config: IGroup - store?: ConfigStore } -@inject(...storeKeys) -export class Group extends React.Component { - handleChangeProxySelected = async (name: string) => { - await changeProxySelected(this.props.config.name, name) - await this.props.store.fetchData() +export function Group (props: GroupProps) { + const { fetch } = Data.useContainer() + const { config } = props + + async function handleChangeProxySelected (name: string) { + await changeProxySelected(props.config.name, name) + await fetch() } - render () { - const { config } = this.props - const canClick = config.type === 'Selector' - return ( -
-
- { config.name } - { config.type } -
-
- -
+ const canClick = config.type === 'Selector' + return ( +
+
+ { config.name } + { config.type }
- ) - } +
+ +
+
+ ) } diff --git a/src/containers/Proxies/components/ModifyProxyDialog/FormItems.tsx b/src/containers/Proxies/components/ModifyProxyDialog/FormItems.tsx deleted file mode 100644 index 866ed95..0000000 --- a/src/containers/Proxies/components/ModifyProxyDialog/FormItems.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import * as React from 'react' -import classnames from 'classnames' -import { Row, Col, Input, Icon, Select, Option, Switch } from '@components' -import { noop } from '@lib/helper' - -// type selector -export function ProxyTypeSelector ({ types, label, value, onSelect = noop }: { - types: { [key: string]: string }, - label: string, - value: string, - onSelect?: (type: string) => void -}) { - return ( - - {label} - - - - - ) -} - -// color selector -export function ProxyColorSelector ({ colors, value, onSelect = noop }: { - colors: string[], - value: string, - onSelect?: (color: string) => void -}) { - return ( - -
- { - colors.map(color => ( - onSelect(color)} - /> - )) - } -
-
- ) -} - -// input form -export function ProxyInputForm ({ label, value, onChange = noop }: { - label: string, - value: string, - onChange?: (value: string) => void -}) { - return ( - - {label} - - - - - ) -} - -// switch form -export function ProxySwitch ({ label, value, onChange = noop }: { - label: string, - value: boolean, - onChange?: (value: boolean) => void -}) { - return ( - - {label} - - - - - ) -} - -// password form -export class ProxyPasswordForm extends React.Component<{ - label: string, - value: string, - onChange?: (value: string) => void -}, { showPassword: boolean }> { - - state = { - showPassword: false - } - - render () { - const { label, value, onChange } = this.props - const { showPassword } = this.state - const type = showPassword ? 'text' : 'password' - return ( - - {label} - - - this.setState({ showPassword: !showPassword })} - /> - - - ) - } -} - -// cipher selector -export function ProxyCipherSelector ({ ciphers, label, value, onSelect = noop }: { - ciphers: string[], - label: string, - value: string, - onSelect?: (type: string) => void -}) { - return ( - - {label} - - - - - ) -} diff --git a/src/containers/Proxies/components/ModifyProxyDialog/index.tsx b/src/containers/Proxies/components/ModifyProxyDialog/index.tsx deleted file mode 100644 index 322c38b..0000000 --- a/src/containers/Proxies/components/ModifyProxyDialog/index.tsx +++ /dev/null @@ -1,224 +0,0 @@ -import * as React from 'react' -import { withTranslation, WithTranslation } from 'react-i18next' -import { Modal } from '@components' -import { getLocalStorageItem, setLocalStorageItem } from '@lib/helper' -import './style.scss' - -import { - BaseComponentProps, - Proxy as IProxy, - SsProxyConfigList, VmessProxyConfigList, Socks5ProxyConfigList, - TagColors, - ProxyType, - SsCipher, VmessCipher, pickCipherWithAlias -} from '@models' - -import { - ProxyInputForm, - ProxySwitch, - ProxyColorSelector, - ProxyTypeSelector, - ProxyPasswordForm, - ProxyCipherSelector -} from './FormItems' - -interface ModifyProxyDialogProps extends BaseComponentProps, WithTranslation { - config: IProxy - onOk?: (config: IProxy) => void - onCancel?: () => void -} - -interface ModifyProxyDialogState { - config: IProxy - currentColor: string -} - -class RawDialog extends React.Component { - - constructor (props: ModifyProxyDialogProps) { - super(props) - - this.state = { - config: props.config, - currentColor: getLocalStorageItem(props.config.name) - } - } - - componentDidMount () { - console.log(this.props.config) - } - - handleOk = () => { - const { onOk } = this.props - const { config, currentColor } = this.state - setLocalStorageItem(config.name, currentColor) - - onOk(config) - } - - handleConfigChange = (key: string, value: any) => { - console.log(key, value) - const { config } = this.state - this.setState({ config: { ...config, [key]: value } }) - } - - getCipherFromType (type) { - switch (type) { - case 'ss': - return SsCipher - case 'vmess': - return VmessCipher - default: - return [] - } - } - - getConfigListFromType (type) { - switch (type) { - case 'ss': - return SsProxyConfigList - case 'vmess': - return VmessProxyConfigList - case 'socks5': - return Socks5ProxyConfigList - default: - return [] - } - } - - renderFormItem (key) { - const { t } = this.props - const { config } = this.state - - switch (key) { - case 'type': - return ( - this.handleConfigChange('type', value)} - /> - ) - case 'name': - return ( - this.handleConfigChange('name', value)} - /> - ) - case 'server': - return ( - this.handleConfigChange('server', value)} - /> - ) - case 'port': - return ( - this.handleConfigChange('port', +value)} - /> - ) - case 'password': - return ( - this.handleConfigChange('password', value)} - /> - ) - case 'cipher': - return ( - this.handleConfigChange('cipher', value)} - /> - ) - case 'obfs': - return ( - this.handleConfigChange('obfs', value)} - /> - ) - case 'obfs-host': - return ( - this.handleConfigChange('obfs-host', value)} - /> - ) - case 'uuid': - return ( - this.handleConfigChange('uuid', value)} - /> - ) - case 'alterId': - return ( - this.handleConfigChange('alterId', +value)} - /> - ) - case 'tls': - return ( - this.handleConfigChange('tls', !!value)} - /> - ) - default: - return null - } - } - - render () { - const { onCancel, t } = this.props - const { currentColor, config } = this.state - const { type } = config - const configList = this.getConfigListFromType(type) - - return - this.setState({ currentColor: color })} - /> - { - configList.map(c => this.renderFormItem(c)) - } - - } -} - -export const ModifyProxyDialog = withTranslation(['Proxies'])(RawDialog) diff --git a/src/containers/Proxies/components/ModifyProxyDialog/style.scss b/src/containers/Proxies/components/ModifyProxyDialog/style.scss deleted file mode 100644 index 6de7ed5..0000000 --- a/src/containers/Proxies/components/ModifyProxyDialog/style.scss +++ /dev/null @@ -1,51 +0,0 @@ -@import '~@styles/variables'; - -.proxy-editor { - .proxy-editor-row { - padding: 5px 0; - - .proxy-editor-label { - padding-left: 0; - line-height: 30px; - } - - .proxy-editor-value { - position: relative; - - .proxy-editor-passsword-icon { - position: absolute; - right: 15px; - top: 4px; - cursor: pointer; - color: $color-primary-darken; - user-select: none; - } - } - } - - .proxy-editor-color-selector { - display: flex; - align-items: center; - - .color-item { - position: relative; - margin-right: 20px; - width: 16px; - height: 16px; - border-radius: 50%; - cursor: pointer; - } - - .color-item-active::after { - position: absolute; - left: -3px; - top: -3px; - content: ''; - display: block; - width: 22px; - height: 22px; - border-radius: 50%; - border: 1px solid $color-gray-dark; - } - } -} diff --git a/src/containers/Proxies/components/Proxy/index.tsx b/src/containers/Proxies/components/Proxy/index.tsx index 57b1537..5fd579f 100644 --- a/src/containers/Proxies/components/Proxy/index.tsx +++ b/src/containers/Proxies/components/Proxy/index.tsx @@ -1,4 +1,4 @@ -import * as React from 'react' +import React, { useState, useMemo, useLayoutEffect, useEffect } from 'react' import classnames from 'classnames' import { BaseComponentProps, TagColors } from '@models' import { getProxyDelay, Proxy as IProxy } from '@lib/request' @@ -9,82 +9,54 @@ import './style.scss' interface ProxyProps extends BaseComponentProps { config: IProxy - // onEdit?: (e: React.MouseEvent) => void } -interface ProxyState { - delay: number - hasError: boolean - color: string +async function getDelay (name: string) { + if (isClashX()) { + const delay = await jsBridge.getProxyDelay(name) + return delay + } + + const { data: { delay } } = await getProxyDelay(name) + return delay } -export class Proxy extends React.Component { - constructor (props: ProxyProps) { - super(props) +export function Proxy (props: ProxyProps) { + const { config, className } = props + const [delay, setDelay] = useState(0) - const { config } = props - const { name } = config - let color = getLocalStorageItem(name) + async function speedTest () { + const [delay, err] = await to(getDelay(config.name)) + setDelay(err ? 0 : delay) + } + + useEffect(() => { + setDelay(config.history.length ? config.history.slice(-1)[0].delay : 0) + }, [config]) + + useLayoutEffect(() => { + EE.subscribe(Action.SPEED_NOTIFY, speedTest) + return () => EE.unsubscribe(Action.SPEED_NOTIFY, speedTest) + }, []) + + const hasError = useMemo(() => delay === 0, [delay]) + const color = useMemo(() => { + let color = getLocalStorageItem(config.name) if (!color) { color = sample(TagColors) setLocalStorageItem(name, color) } - const delay = config.history.length ? config.history.slice(-1)[0].delay : 0 - this.state = { - delay, - hasError: delay === 0, - color - } - } + return color + }, [config]) - componentWillUpdate () { - const { config: { name } } = this.props - const { color: rawColor } = this.state - const color = getLocalStorageItem(name) - - if (rawColor !== color) { - this.setState({ color }) - } - } - - componentDidMount () { - EE.subscribe(Action.SPEED_NOTIFY, this.speedTest) - } - - componentWillUnmount () { - EE.unsubscribe(Action.SPEED_NOTIFY, this.speedTest) - } - - getDelay = async (name: string) => { - if (isClashX()) { - const delay = await jsBridge.getProxyDelay(name) - return delay - } - - const { data: { delay } } = await getProxyDelay(name) - return delay - } - - speedTest = async () => { - const { config } = this.props - const [delay, err] = await to(this.getDelay(config.name)) - this.setState({ delay: err ? -1 : delay, hasError: !!err }) - } - - render () { - const { config, className } = this.props - const { delay, color, hasError } = this.state - const backgroundColor = hasError ? undefined : color - - return ( -
- {config.type} -

{config.name}

-

{delay === 0 ? '-' : `${delay}ms`}

- {/* */} -
- ) - } + const backgroundColor = hasError ? undefined : color + return ( +
+ {config.type} +

{config.name}

+

{delay === 0 ? '-' : `${delay}ms`}

+
+ ) } diff --git a/src/containers/Proxies/components/index.ts b/src/containers/Proxies/components/index.ts index fe4b070..80408ae 100644 --- a/src/containers/Proxies/components/index.ts +++ b/src/containers/Proxies/components/index.ts @@ -1,3 +1,2 @@ export * from './Proxy' export * from './Group' -export * from './ModifyProxyDialog' diff --git a/src/containers/Proxies/index.tsx b/src/containers/Proxies/index.tsx index 067acb7..7fd0334 100644 --- a/src/containers/Proxies/index.tsx +++ b/src/containers/Proxies/index.tsx @@ -1,67 +1,55 @@ -import * as React from 'react' -import { withTranslation, WithTranslation } from 'react-i18next' -import { inject, observer } from 'mobx-react' -import { storeKeys } from '@lib/createStore' +import React, { useLayoutEffect } from 'react' +import { useTranslation } from 'react-i18next' import EE from '@lib/event' import { Card, Header, Icon } from '@components' -import { BaseRouterProps } from '@models' +import { Data } from '@stores' import { Proxy, Group } from './components' import './style.scss' -interface ProxiesProps extends BaseRouterProps, WithTranslation {} +export default function Proxies () { + const { data, fetch } = Data.useContainer() + const { t } = useTranslation(['Proxies']) -interface ProxiesState { -} + useLayoutEffect(() => { + fetch() + }, []) -@inject(...storeKeys) -@observer -class Proxies extends React.Component { - componentDidMount () { - this.props.store.fetchData() - } - - handleNotitySpeedTest = () => { + function handleNotitySpeedTest () { EE.notifySpeedTest() } - render () { - const { t, store } = this.props - - return ( -
-
-
- -
    - { - store.data.proxyGroup.map(p => ( -
  • - -
  • - )) - } -
-
-
-
-
- - {t('speedTestText')} -
-
    + return ( +
    +
    +
    + +
      { - store.data.proxy.map(p => ( -
    • - + data.proxyGroup.map(p => ( +
    • +
    • )) }
    -
    +
    - ) - } +
    +
    + + {t('speedTestText')} +
    +
      + { + data.proxy.map(p => ( +
    • + +
    • + )) + } +
    +
    +
+ ) } - -export default withTranslation(['Proxies'])(Proxies) diff --git a/src/containers/Rules/index.tsx b/src/containers/Rules/index.tsx index b99d181..bfa632d 100644 --- a/src/containers/Rules/index.tsx +++ b/src/containers/Rules/index.tsx @@ -1,24 +1,20 @@ -import * as React from 'react' -import { withTranslation, WithTranslation } from 'react-i18next' +import React, { useEffect } from 'react' +import { useTranslation } from 'react-i18next' import { Header, Card, Row, Col } from '@components' -import { BaseRouterProps } from '@models' import './style.scss' -import { storeKeys } from '@lib/createStore' -import { inject, observer } from 'mobx-react' +import { Data } from '@stores' import { List, AutoSizer } from 'react-virtualized' -interface RulesProps extends BaseRouterProps, WithTranslation {} +export default function Rules () { + const { data, fetch } = Data.useContainer() + const { t } = useTranslation(['Rules']) + const { rules } = data -@inject(...storeKeys) -@observer -class Rules extends React.Component { + useEffect(() => { + fetch() + }, []) - componentWillMount () { - this.props.store.fetchData() - } - - renderRuleItem = ({ index, key, style }) => { - const { rules } = this.props.store.data + function renderRuleItem ({ index, key, style }) { const rule = rules[index] return (
  • @@ -37,31 +33,25 @@ class Rules extends React.Component { ) } - render () { - const { t } = this.props - const { rules } = this.props.store.data - return ( -
    -
    - - - { - ({ height, width }) => ( - - ) - } - - -
    - ) - } + return ( +
    +
    + + + { + ({ height, width }) => ( + + ) + } + + +
    + ) } - -export default withTranslation(['Rules'])(Rules) diff --git a/src/containers/Settings/index.tsx b/src/containers/Settings/index.tsx index df3628d..9781700 100644 --- a/src/containers/Settings/index.tsx +++ b/src/containers/Settings/index.tsx @@ -1,225 +1,208 @@ -import * as React from 'react' -import { withTranslation, WithTranslation } from 'react-i18next' +import React, { useEffect } from 'react' +import { useTranslation } from 'react-i18next' import i18next from 'i18next' -import { inject, observer } from 'mobx-react' import { Header, Card, Row, Col, Switch, ButtonSelect, ButtonSelectOptions, Input, Icon } from '@components' -import { BaseRouterProps } from '@models' +import { APIInfo, Data, ClashXData, ExternalControllerModal } from '@stores' import { updateConfig } from '@lib/request' +import { useObject } from '@lib/hook' import { to } from '@lib/helper' -import { rootStores, storeKeys } from '@lib/createStore' -import './style.scss' import { isClashX, jsBridge } from '@lib/jsBridge' +import './style.scss' -interface SettingProps extends BaseRouterProps, WithTranslation {} +const languageOptions: ButtonSelectOptions[] = [{ label: '中文', value: 'zh' }, { label: 'English', value: 'en' }] -@inject(...storeKeys) -@observer -class Settings extends React.Component { - state = { +function changeLanguage (language: string) { + i18next.changeLanguage(language) +} + +async function handleStartAtLoginChange (state: boolean) { + await jsBridge.setStartAtLogin(state) +} + +async function handleSetSystemProxy (state: boolean) { + await jsBridge.setSystemProxy(state) +} + +export default function Settings () { + const { data: clashXData, fetch: fetchClashXData } = ClashXData.useContainer() + const { data, fetch } = Data.useContainer() + const { data: apiInfo } = APIInfo.useContainer() + const { show } = ExternalControllerModal.useContainer() + const { t, i18n } = useTranslation(['Settings']) + const { value: info, change } = useObject({ socks5ProxyPort: 7891, httpProxyPort: 7890, isClashX: false - } + }) - languageOptions: ButtonSelectOptions[] = [{ label: '中文', value: 'zh' }, { label: 'English', value: 'en' }] + useEffect(() => { + fetch() + if (isClashX()) { + fetchClashXData().then(() => change('isClashX', true)) + } + }, []) - changeLanguage = (language: string) => { - i18next.changeLanguage(language) - } + useEffect(() => { + change('socks5ProxyPort', data.general.socksPort) + change('httpProxyPort', data.general.port) + }, [data]) - handleProxyModeChange = async (mode: string) => { + async function handleProxyModeChange (mode: string) { const [, err] = await to(updateConfig({ mode })) if (!err) { - rootStores.store.fetchData() + fetch() } } - handleHttpPortSave = async () => { - const [, err] = await to(updateConfig({ 'port': this.state.httpProxyPort })) + async function handleHttpPortSave () { + const [, err] = await to(updateConfig({ 'port': info.httpProxyPort })) if (!err) { - await this.props.store.fetchData() - this.setState({ httpProxyPort: this.props.store.data.general.port }) + await fetch() + change('httpProxyPort', data.general.port) } } - handleSocksPortSave = async () => { - const [, err] = await to(updateConfig({ 'socks-port': this.state.socks5ProxyPort })) + async function handleSocksPortSave () { + const [, err] = await to(updateConfig({ 'socks-port': info.socks5ProxyPort })) if (!err) { - await this.props.store.fetchData() - this.setState({ socks5ProxyPort: this.props.store.data.general.socksPort }) + await fetch() + change('socks5ProxyPort', data.general.socksPort) } } - handleAllowLanChange = async (state: boolean) => { + async function handleAllowLanChange (state: boolean) { const [, err] = await to(updateConfig({ 'allow-lan': state })) if (!err) { - await this.props.store.fetchData() + await fetch() } } - handleStartAtLoginChange = async (state: boolean) => { - await jsBridge.setStartAtLogin(state) - this.setState({ startAtLogin: state }) - } + const { + hostname: externalControllerHost, + port: externalControllerPort + } = apiInfo - handleSetSystemProxy = async (state: boolean) => { - await jsBridge.setSystemProxy(state) - this.setState({ setAsSystemProxy: state }) - } + const { allowLan, mode } = data.general + const { + startAtLogin, + systemProxy + } = clashXData - async componentDidMount () { - await rootStores.store.fetchData() - if (isClashX()) { - await rootStores.store.fetchClashXData() - this.setState({ - isClashX: true - }) - } + const proxyModeOptions: ButtonSelectOptions[] = [ + { label: t('values.global'), value: 'Global' }, + { label: t('values.rules'), value: 'Rule' }, + { label: t('values.direct'), value: 'Direct' } + ] - const general = this.props.store.data.general - this.setState({ - socks5ProxyPort: general.socksPort, - httpProxyPort: general.port - }) - } - - render () { - const { t, i18n, store } = this.props - const { - isClashX, - socks5ProxyPort, - httpProxyPort - } = this.state - - const { - hostname: externalControllerHost, - port: externalControllerPort - } = store.apiInfo - - const { allowLan, mode } = store.data.general - const { - startAtLogin, - systemProxy - } = store.clashxData - const proxyModeOptions: ButtonSelectOptions[] = [ - { label: t('values.global'), value: 'Global' }, - { label: t('values.rules'), value: 'Rule' }, - { label: t('values.direct'), value: 'Direct' } - ] - - return ( -
    -
    - - - - - {t('labels.startAtLogin')} - - - - + return ( +
    +
    + + + + + {t('labels.startAtLogin')} - - - {t('labels.language')} - - - - + + - - - - - {t('labels.setAsSystemProxy')} - - - - + + + + {t('labels.language')} - - - {t('labels.allowConnectFromLan')} - - - - + + - - + + + + + + {t('labels.setAsSystemProxy')} + + + + + + + + {t('labels.allowConnectFromLan')} + + + + + + + - - - - - {t('labels.proxyMode')} - - - - + + + + + {t('labels.proxyMode')} - - - {t('labels.socks5ProxyPort')} - - - this.setState({ socks5ProxyPort: parseInt(socks5ProxyPort, 10) })} - onBlur={this.handleSocksPortSave} - /> - + + - - - - - {t('labels.httpProxyPort')} - - - this.setState({ httpProxyPort: parseInt(httpProxyPort, 10) })} - onBlur={this.handleHttpPortSave} - /> - + + + + {t('labels.socks5ProxyPort')} - - - {t('labels.externalController')} - - - this.props.store.setShowAPIModal(true)}> - {`${externalControllerHost}:${externalControllerPort}`} - - + + change('socks5ProxyPort', parseInt(socks5ProxyPort, 10))} + onBlur={handleSocksPortSave} + /> - - + + + + + + {t('labels.httpProxyPort')} + + + change('httpProxyPort', parseInt(httpProxyPort, 10))} + onBlur={handleHttpPortSave} + /> + + + + + {t('labels.externalController')} + + + + {`${externalControllerHost}:${externalControllerPort}`} + + + + + - - - - -

    {t('versionString', { version: 'unknown' })}

    - {t('checkUpdate')} -
    -
    - ) - } + + + + +

    {t('versionString', { version: 'unknown' })}

    + {t('checkUpdate')} +
    +
    + ) } - -export default withTranslation(['Settings'])(Settings) diff --git a/src/lib/createStore.ts b/src/lib/createStore.ts deleted file mode 100644 index 5d915ba..0000000 --- a/src/lib/createStore.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createHashHistory } from 'history' -import { configure } from 'mobx' -import { RouterStore, ConfigStore } from '@stores' - -// prepare MobX stores -configure({ enforceActions: 'observed' }) -const history = createHashHistory() - -export const rootStores = { - router: new RouterStore(history), - store: new ConfigStore() -} - -export const storeKeys = Object.keys(rootStores) diff --git a/src/lib/request.ts b/src/lib/request.ts index f4e85b5..bccd5f4 100644 --- a/src/lib/request.ts +++ b/src/lib/request.ts @@ -1,7 +1,7 @@ import axios, { AxiosInstance } from 'axios' import { Partial, getLocalStorageItem } from '@lib/helper' import { isClashX, jsBridge } from '@lib/jsBridge' -import { rootStores } from '@lib/createStore' +import { ExternalControllerModal } from '@stores' import { Log } from '@models/Log' import { StreamReader } from './streamer' @@ -117,7 +117,8 @@ export async function getInstance () { resp => resp, err => { if (!err.response || err.response.status === 401) { - rootStores.store.setShowAPIModal(true) + const { show } = ExternalControllerModal.useContainer() + show() } throw err } diff --git a/src/models/BaseProps.ts b/src/models/BaseProps.ts index aaccaa1..d9363e9 100644 --- a/src/models/BaseProps.ts +++ b/src/models/BaseProps.ts @@ -1,21 +1,11 @@ import { CSSProperties, ReactNode } from 'react' import { RouteComponentProps } from 'react-router' -import { RouterStore, ConfigStore } from '@stores' /** * expose base router component props * and mobx store to props */ -export interface BaseRouterProps extends RouteComponentProps, BaseProps {} - -/** - * use when component is inject by mobx - */ -export interface BaseProps extends BaseComponentProps { - styles?: any - router?: RouterStore - store?: ConfigStore -} +export interface BaseRouterProps extends RouteComponentProps {} export interface BaseComponentProps { className?: string diff --git a/src/render.tsx b/src/render.tsx index 069df3d..52c4361 100644 --- a/src/render.tsx +++ b/src/render.tsx @@ -1,9 +1,7 @@ import * as React from 'react' import { render } from 'react-dom' -import { Provider } from 'mobx-react' import { HashRouter } from 'react-router-dom' import { I18nextProvider } from 'react-i18next' -import { rootStores } from '@lib/createStore' import { BaseComponentProps } from '@models/BaseProps' import { APIInfo, Data, ClashXData, ExternalControllerModal } from '@stores' import App from '@containers/App' @@ -27,13 +25,11 @@ export default function renderApp () { const rootEl = document.getElementById('root') const AppInstance = ( - - - - - - - + + + + + ) diff --git a/src/stores/ConfigStore.ts b/src/stores/ConfigStore.ts deleted file mode 100644 index 7811616..0000000 --- a/src/stores/ConfigStore.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { observable, action, runInAction } from 'mobx' -import * as yaml from 'yaml' -import * as Models from '@models' -import { jsBridge, isClashX } from '@lib/jsBridge' -import * as API from '@lib/request' -import { getLocalStorageItem, setLocalStorageItem, partition } from '@lib/helper' - -export class ConfigStore { - - @observable - config: Models.Config = { - proxy: [], - proxyGroup: [], - rules: [] - } - - @observable - data: Models.Data = { - general: {}, - proxy: [], - proxyGroup: [], - rules: [] - } - - @observable - apiInfo: Models.APIInfo = { - hostname: '127.0.0.1', - port: '9090', - secret: '' - } - - @observable - showAPIModal = false - - @observable - clashxData: Models.ClashXData = { - startAtLogin: false, - systemProxy: false - } - - @action - async fetchAPIInfo () { - if (isClashX()) { - const apiInfo = await jsBridge.getAPIInfo() - runInAction(() => { - this.apiInfo = { hostname: apiInfo.host, port: apiInfo.port, secret: apiInfo.secret } - }) - return - } - const info = await API.getExternalControllerConfig() - - runInAction(() => { - this.apiInfo = { ...info } - }) - } - - @action - async fetchData () { - const [{ data: general }, rawProxies, rules] = await Promise.all([API.getConfig(), API.getProxies(), API.getRules()]) - - runInAction(() => { - this.data.general = { - port: general.port, - socksPort: general['socks-port'], - redirPort: general['redir-port'], - mode: general.mode, - logLevel: general['log-level'], - allowLan: general['allow-lan'] - } - - const policyGroup = new Set(['Selector', 'URLTest', 'Fallback', 'LoadBalance']) - const unUsedProxy = new Set(['DIRECT', 'REJECT', 'GLOBAL']) - const proxyList = rawProxies.data.proxies['GLOBAL'] as API.Group - const proxies = proxyList.all - .filter(key => !unUsedProxy.has(key)) - .map(key => ({ ...rawProxies.data.proxies[key], name: key })) - const [proxy, groups] = partition(proxies, proxy => !policyGroup.has(proxy.type)) - this.data.proxy = proxy as API.Proxy[] - this.data.proxyGroup = groups as API.Group[] - this.data.rules = rules.data.rules - }) - } - - @action - async fetchClashXData () { - const startAtLogin = await jsBridge.getStartAtLogin() - const systemProxy = await jsBridge.isSystemProxySet() - - runInAction(() => { - this.clashxData = { - startAtLogin, - systemProxy - } - }) - } - - @action - async fetchAndParseConfig () { - const rawConfig = await jsBridge.readConfigString() - - runInAction(() => { - // emit error when config is empty - // because read config might be error - if (!rawConfig) { - return - } - - // otherwise parse ini - const config = yaml.parse(rawConfig) - const externalController = config['external-controller'] as string || '' - const host = externalController.split(':') - - const proxies = config.Proxy as any[] || [] - const proxy: Models.Proxy[] = proxies - .filter(p => ['vmess', 'ss', 'socks5'].includes(p.type)) - - const proxyGroups = config['Proxy Group'] as any[] || [] - const proxyGroup: Models.ProxyGroup[] = proxyGroups - .filter(p => ['url-test', 'select', 'fallback'].includes(p.type)) - const rules = config['Rule'] as any[] || [] - const rule: Models.Rule[] = rules.map(r => r.split(',')).filter(r => r.length >= 3).map(r => ({ - type: Models.RuleType[r[0] as string], - payload: r[1], - proxy: r[2] - })) - this.config = { - general: { - port: config.port || 0, - socksPort: config['socks-port'] || 0, - redirPort: config['redir-port'] || 0, - allowLan: config['allow-lan'] || false, - externalControllerAddr: host[0] || '', - externalControllerPort: host[1] || '', - secret: config.secret || '', - logLevel: config['log-level'] || 'info', - mode: config.mode || 'Rule' - }, - proxy, - proxyGroup, - rules: rule || [] - } - }) - } - - @action - async fetchConfig () { - const { data: config } = await API.getConfig() - this.config = { - general: { - port: config.port, - socksPort: config['socks-port'], - redirPort: config['redir-port'], - allowLan: config['allow-lan'], - mode: config.mode, - externalControllerAddr: getLocalStorageItem('externalControllerAddr', '127.0.0.1'), - externalControllerPort: getLocalStorageItem('externalControllerPort', '9090'), - secret: getLocalStorageItem('secret', '') - } - } - } - - @action - async updateConfig () { - const { general, proxy, proxyGroup, rules } = this.config - const externalController = `${general.externalControllerAddr}:${general.externalControllerPort}` - const Rule = rules.map(r => [r.type, r.payload, r.proxy].join(',')) - const config = { - 'external-controller': externalController, - port: general.port, - 'socks-port': general.socksPort, - 'redir-port': general.redirPort, - 'allow-lan': general.allowLan, - secret: general.secret, - 'log-level': general.logLevel, - mode: general.mode, - Proxy: proxy, - 'Proxy Group': proxyGroup, - Rule - } - const data = yaml.stringify(config) - // console.log(data) - jsBridge.writeConfigWithString(data) - } - - @action - async updateAPIInfo (info: Models.APIInfo) { - const { hostname, port, secret } = info - setLocalStorageItem('externalControllerAddr', hostname) - setLocalStorageItem('externalControllerPort', port) - setLocalStorageItem('secret', secret) - window.location.reload() - } - - @action - setShowAPIModal (visible: boolean) { - runInAction(() => { - this.showAPIModal = visible - }) - } - - @action - async modifyProxyByIndexAndSave (index: number, config: Models.Proxy) { - const { proxy } = this.config - const fomatedConfig: Models.Proxy = {} - const { type } = config - let configList: string[] = [] - - switch (type) { - case 'ss': - configList = Models.SsProxyConfigList - break - case 'vmess': - configList = Models.VmessProxyConfigList - break - case 'socks5': - configList = Models.Socks5ProxyConfigList - break - } - - for (const configKey of configList) { - fomatedConfig[configKey] = config[configKey] - } - - proxy[index] = fomatedConfig - await this.updateConfig() - await this.fetchAndParseConfig() - } -} diff --git a/src/stores/RouterStore.ts b/src/stores/RouterStore.ts deleted file mode 100644 index 465ff1b..0000000 --- a/src/stores/RouterStore.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { History } from 'history' -import { RouterStore as BaseRouterStore, syncHistoryWithStore } from 'mobx-react-router' - -export class RouterStore extends BaseRouterStore { - constructor (history?: History) { - super() - - if (history) { - this.history = syncHistoryWithStore(history, this) - } - } -} - -export default RouterStore diff --git a/src/stores/index.ts b/src/stores/index.ts index 7b72f63..81bcfaa 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -1,3 +1 @@ -export * from './ConfigStore' -export * from './RouterStore' export * from './HookStore'