Browse Source

Fixes

pull/2/head
Sacha Weatherstone 5 years ago
parent
commit
a5d67279de
  1. 10
      package.json
  2. 336
      pnpm-lock.yaml
  3. 23
      src/App.tsx
  4. 30
      src/components/generic/IconButton.tsx
  5. 10
      src/core/connection.ts
  6. 32
      src/core/slices/meshtasticSlice.ts
  7. 16
      src/pages/Plugins/Files.tsx
  8. 1
      src/pages/Plugins/Index.tsx
  9. 282
      src/pages/settings/Connection.tsx

10
package.json

@ -12,7 +12,7 @@
}, },
"dependencies": { "dependencies": {
"@headlessui/react": "^1.4.1", "@headlessui/react": "^1.4.1",
"@meshtastic/meshtasticjs": "^0.6.19", "@meshtastic/meshtasticjs": "^0.6.22",
"@reduxjs/toolkit": "^1.6.2", "@reduxjs/toolkit": "^1.6.2",
"apexcharts": "^3.29.0", "apexcharts": "^3.29.0",
"boring-avatars": "^1.5.8", "boring-avatars": "^1.5.8",
@ -24,8 +24,8 @@
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-file-icon": "^1.1.0", "react-file-icon": "^1.1.0",
"react-flags-select": "^2.1.2", "react-flags-select": "^2.1.2",
"react-hook-form": "^7.17.5", "react-hook-form": "^7.18.0",
"react-i18next": "^11.12.0", "react-i18next": "^11.13.0",
"react-icons": "^4.3.1", "react-icons": "^4.3.1",
"react-redux": "^7.2.6", "react-redux": "^7.2.6",
"swr": "^1.0.1", "swr": "^1.0.1",
@ -42,10 +42,12 @@
"@types/react-file-icon": "^1.0.1", "@types/react-file-icon": "^1.0.1",
"@types/react-redux": "^7.1.20", "@types/react-redux": "^7.1.20",
"@types/snowpack-env": "^2.3.4", "@types/snowpack-env": "^2.3.4",
"@types/w3c-web-serial": "^1.0.2",
"@types/web-bluetooth": "^0.0.11",
"@typescript-eslint/eslint-plugin": "^5.2.0", "@typescript-eslint/eslint-plugin": "^5.2.0",
"@typescript-eslint/parser": "^5.2.0", "@typescript-eslint/parser": "^5.2.0",
"@verypossible/eslint-config": "^1.6.1", "@verypossible/eslint-config": "^1.6.1",
"autoprefixer": "^10.3.7", "autoprefixer": "^10.4.0",
"babel-plugin-module-resolver": "^4.1.0", "babel-plugin-module-resolver": "^4.1.0",
"eslint": "8.1.0", "eslint": "8.1.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",

336
pnpm-lock.yaml

@ -2,7 +2,7 @@ lockfileVersion: 5.3
specifiers: specifiers:
'@headlessui/react': ^1.4.1 '@headlessui/react': ^1.4.1
'@meshtastic/meshtasticjs': ^0.6.19 '@meshtastic/meshtasticjs': ^0.6.22
'@reduxjs/toolkit': ^1.6.2 '@reduxjs/toolkit': ^1.6.2
'@snowpack/plugin-dotenv': ^2.2.0 '@snowpack/plugin-dotenv': ^2.2.0
'@snowpack/plugin-postcss': ^1.4.3 '@snowpack/plugin-postcss': ^1.4.3
@ -13,11 +13,13 @@ specifiers:
'@types/react-file-icon': ^1.0.1 '@types/react-file-icon': ^1.0.1
'@types/react-redux': ^7.1.20 '@types/react-redux': ^7.1.20
'@types/snowpack-env': ^2.3.4 '@types/snowpack-env': ^2.3.4
'@types/w3c-web-serial': ^1.0.2
'@types/web-bluetooth': ^0.0.11
'@typescript-eslint/eslint-plugin': ^5.2.0 '@typescript-eslint/eslint-plugin': ^5.2.0
'@typescript-eslint/parser': ^5.2.0 '@typescript-eslint/parser': ^5.2.0
'@verypossible/eslint-config': ^1.6.1 '@verypossible/eslint-config': ^1.6.1
apexcharts: ^3.29.0 apexcharts: ^3.29.0
autoprefixer: ^10.3.7 autoprefixer: ^10.4.0
babel-plugin-module-resolver: ^4.1.0 babel-plugin-module-resolver: ^4.1.0
boring-avatars: ^1.5.8 boring-avatars: ^1.5.8
eslint: 8.1.0 eslint: 8.1.0
@ -38,8 +40,8 @@ specifiers:
react-dom: ^17.0.2 react-dom: ^17.0.2
react-file-icon: ^1.1.0 react-file-icon: ^1.1.0
react-flags-select: ^2.1.2 react-flags-select: ^2.1.2
react-hook-form: ^7.17.5 react-hook-form: ^7.18.0
react-i18next: ^11.12.0 react-i18next: ^11.13.0
react-icons: ^4.3.1 react-icons: ^4.3.1
react-redux: ^7.2.6 react-redux: ^7.2.6
snowpack: ^3.8.8 snowpack: ^3.8.8
@ -52,7 +54,7 @@ specifiers:
dependencies: dependencies:
'@headlessui/react': 1.4[email protected][email protected] '@headlessui/react': 1.4[email protected][email protected]
'@meshtastic/meshtasticjs': 0.6.19 '@meshtastic/meshtasticjs': 0.6.22
'@reduxjs/toolkit': 1.6[email protected][email protected] '@reduxjs/toolkit': 1.6[email protected][email protected]
apexcharts: 3.29.0 apexcharts: 3.29.0
boring-avatars: 1.5.8 boring-avatars: 1.5.8
@ -64,8 +66,8 @@ dependencies:
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
react-file-icon: 1.1[email protected][email protected] react-file-icon: 1.1[email protected][email protected]
react-flags-select: 2.1[email protected][email protected] react-flags-select: 2.1[email protected][email protected]
react-hook-form: 7.17.5[email protected] react-hook-form: 7.18.0[email protected]
react-i18next: 11.12[email protected][email protected] react-i18next: 11.13[email protected][email protected]
react-icons: 4.3[email protected] react-icons: 4.3[email protected]
react-redux: 7.2[email protected][email protected] react-redux: 7.2[email protected][email protected]
swr: 1.0[email protected] swr: 1.0[email protected]
@ -82,10 +84,12 @@ devDependencies:
'@types/react-file-icon': 1.0.1 '@types/react-file-icon': 1.0.1
'@types/react-redux': 7.1.20 '@types/react-redux': 7.1.20
'@types/snowpack-env': 2.3.4 '@types/snowpack-env': 2.3.4
'@types/w3c-web-serial': 1.0.2
'@types/web-bluetooth': 0.0.11
'@typescript-eslint/eslint-plugin': 5.2.0_9a56ca1c5fc1d82b3da3317a5c6f9ab1 '@typescript-eslint/eslint-plugin': 5.2.0_9a56ca1c5fc1d82b3da3317a5c6f9ab1
'@typescript-eslint/parser': 5.2[email protected][email protected] '@typescript-eslint/parser': 5.2[email protected][email protected]
'@verypossible/eslint-config': 1.6[email protected] '@verypossible/eslint-config': 1.6[email protected]
autoprefixer: 10.3.7[email protected] autoprefixer: 10.4.0[email protected]
babel-plugin-module-resolver: 4.1.0 babel-plugin-module-resolver: 4.1.0
eslint: 8.1.0 eslint: 8.1.0
eslint-config-prettier: 8.3[email protected] eslint-config-prettier: 8.3[email protected]
@ -98,7 +102,7 @@ devDependencies:
postcss: 8.3.11 postcss: 8.3.11
prettier: 2.4.1 prettier: 2.4.1
snowpack: 3.8.8 snowpack: 3.8.8
tailwindcss: 3.0.0-alpha.1_fa866e6aa6eb85ed70431566fb699b34 tailwindcss: 3.0.0-alpha.1_0c54bdadaf9d9c9c6c134cb2c6c061a3
tar: 6.1.11 tar: 6.1.11
typescript: 4.4.4 typescript: 4.4.4
@ -107,34 +111,34 @@ packages:
/@babel/code-frame/7.12.11: /@babel/code-frame/7.12.11:
resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==}
dependencies: dependencies:
'@babel/highlight': 7.14.5 '@babel/highlight': 7.16.0
dev: true dev: true
/@babel/code-frame/7.15.8: /@babel/code-frame/7.16.0:
resolution: {integrity: sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==} resolution: {integrity: sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/highlight': 7.14.5 '@babel/highlight': 7.16.0
dev: true dev: true
/@babel/compat-data/7.15.0: /@babel/compat-data/7.16.0:
resolution: {integrity: sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==} resolution: {integrity: sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/core/7.15.8: /@babel/core/7.16.0:
resolution: {integrity: sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==} resolution: {integrity: sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/code-frame': 7.15.8 '@babel/code-frame': 7.16.0
'@babel/generator': 7.15.8 '@babel/generator': 7.16.0
'@babel/helper-compilation-targets': 7.15.4_@[email protected] '@babel/helper-compilation-targets': 7.16.0_@[email protected]
'@babel/helper-module-transforms': 7.15.8 '@babel/helper-module-transforms': 7.16.0
'@babel/helpers': 7.15.4 '@babel/helpers': 7.16.0
'@babel/parser': 7.15.8 '@babel/parser': 7.16.0
'@babel/template': 7.15.4 '@babel/template': 7.16.0
'@babel/traverse': 7.15.4 '@babel/traverse': 7.16.0
'@babel/types': 7.15.6 '@babel/types': 7.16.0
convert-source-map: 1.8.0 convert-source-map: 1.8.0
debug: 4.3.2 debug: 4.3.2
gensync: 1.0.0-beta.2 gensync: 1.0.0-beta.2
@ -145,86 +149,86 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/generator/7.15.8: /@babel/generator/7.16.0:
resolution: {integrity: sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==} resolution: {integrity: sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
jsesc: 2.5.2 jsesc: 2.5.2
source-map: 0.5.7 source-map: 0.5.7
dev: true dev: true
/@babel/helper-compilation-targets/7.15.4_@[email protected]: /@babel/helper-compilation-targets/7.16.0_@[email protected]:
resolution: {integrity: sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==} resolution: {integrity: sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0 '@babel/core': ^7.0.0
dependencies: dependencies:
'@babel/compat-data': 7.15.0 '@babel/compat-data': 7.16.0
'@babel/core': 7.15.8 '@babel/core': 7.16.0
'@babel/helper-validator-option': 7.14.5 '@babel/helper-validator-option': 7.14.5
browserslist: 4.17.5 browserslist: 4.17.5
semver: 6.3.0 semver: 6.3.0
dev: true dev: true
/@babel/helper-function-name/7.15.4: /@babel/helper-function-name/7.16.0:
resolution: {integrity: sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==} resolution: {integrity: sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/helper-get-function-arity': 7.15.4 '@babel/helper-get-function-arity': 7.16.0
'@babel/template': 7.15.4 '@babel/template': 7.16.0
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-get-function-arity/7.15.4: /@babel/helper-get-function-arity/7.16.0:
resolution: {integrity: sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==} resolution: {integrity: sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-hoist-variables/7.15.4: /@babel/helper-hoist-variables/7.16.0:
resolution: {integrity: sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==} resolution: {integrity: sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-member-expression-to-functions/7.15.4: /@babel/helper-member-expression-to-functions/7.16.0:
resolution: {integrity: sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==} resolution: {integrity: sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-module-imports/7.15.4: /@babel/helper-module-imports/7.16.0:
resolution: {integrity: sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==} resolution: {integrity: sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-module-transforms/7.15.8: /@babel/helper-module-transforms/7.16.0:
resolution: {integrity: sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==} resolution: {integrity: sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/helper-module-imports': 7.15.4 '@babel/helper-module-imports': 7.16.0
'@babel/helper-replace-supers': 7.15.4 '@babel/helper-replace-supers': 7.16.0
'@babel/helper-simple-access': 7.15.4 '@babel/helper-simple-access': 7.16.0
'@babel/helper-split-export-declaration': 7.15.4 '@babel/helper-split-export-declaration': 7.16.0
'@babel/helper-validator-identifier': 7.15.7 '@babel/helper-validator-identifier': 7.15.7
'@babel/template': 7.15.4 '@babel/template': 7.16.0
'@babel/traverse': 7.15.4 '@babel/traverse': 7.16.0
'@babel/types': 7.15.6 '@babel/types': 7.16.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@babel/helper-optimise-call-expression/7.15.4: /@babel/helper-optimise-call-expression/7.16.0:
resolution: {integrity: sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==} resolution: {integrity: sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-plugin-utils/7.14.5: /@babel/helper-plugin-utils/7.14.5:
@ -232,30 +236,30 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/helper-replace-supers/7.15.4: /@babel/helper-replace-supers/7.16.0:
resolution: {integrity: sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==} resolution: {integrity: sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/helper-member-expression-to-functions': 7.15.4 '@babel/helper-member-expression-to-functions': 7.16.0
'@babel/helper-optimise-call-expression': 7.15.4 '@babel/helper-optimise-call-expression': 7.16.0
'@babel/traverse': 7.15.4 '@babel/traverse': 7.16.0
'@babel/types': 7.15.6 '@babel/types': 7.16.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@babel/helper-simple-access/7.15.4: /@babel/helper-simple-access/7.16.0:
resolution: {integrity: sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==} resolution: {integrity: sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-split-export-declaration/7.15.4: /@babel/helper-split-export-declaration/7.16.0:
resolution: {integrity: sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==} resolution: {integrity: sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/helper-validator-identifier/7.15.7: /@babel/helper-validator-identifier/7.15.7:
@ -268,19 +272,19 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/helpers/7.15.4: /@babel/helpers/7.16.0:
resolution: {integrity: sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==} resolution: {integrity: sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/template': 7.15.4 '@babel/template': 7.16.0
'@babel/traverse': 7.15.4 '@babel/traverse': 7.16.0
'@babel/types': 7.15.6 '@babel/types': 7.16.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@babel/highlight/7.14.5: /@babel/highlight/7.16.0:
resolution: {integrity: sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==} resolution: {integrity: sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/helper-validator-identifier': 7.15.7 '@babel/helper-validator-identifier': 7.15.7
@ -288,55 +292,55 @@ packages:
js-tokens: 4.0.0 js-tokens: 4.0.0
dev: true dev: true
/@babel/parser/7.15.8: /@babel/parser/7.16.0:
resolution: {integrity: sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==} resolution: {integrity: sha512-TEHWXf0xxpi9wKVyBCmRcSSDjbJ/cl6LUdlbYUHEaNQUJGhreJbZrXT6sR4+fZLxVUJqNRB4KyOvjuy/D9009A==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
dev: true dev: true
/@babel/plugin-syntax-class-properties/7.12.13_@[email protected]5.8: /@babel/plugin-syntax-class-properties/7.12.13_@[email protected]6.0:
resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/core': 7.15.8 '@babel/core': 7.16.0
'@babel/helper-plugin-utils': 7.14.5 '@babel/helper-plugin-utils': 7.14.5
dev: true dev: true
/@babel/runtime/7.15.4: /@babel/runtime/7.16.0:
resolution: {integrity: sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==} resolution: {integrity: sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
regenerator-runtime: 0.13.9 regenerator-runtime: 0.13.9
/@babel/template/7.15.4: /@babel/template/7.16.0:
resolution: {integrity: sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==} resolution: {integrity: sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/code-frame': 7.15.8 '@babel/code-frame': 7.16.0
'@babel/parser': 7.15.8 '@babel/parser': 7.16.0
'@babel/types': 7.15.6 '@babel/types': 7.16.0
dev: true dev: true
/@babel/traverse/7.15.4: /@babel/traverse/7.16.0:
resolution: {integrity: sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==} resolution: {integrity: sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/code-frame': 7.15.8 '@babel/code-frame': 7.16.0
'@babel/generator': 7.15.8 '@babel/generator': 7.16.0
'@babel/helper-function-name': 7.15.4 '@babel/helper-function-name': 7.16.0
'@babel/helper-hoist-variables': 7.15.4 '@babel/helper-hoist-variables': 7.16.0
'@babel/helper-split-export-declaration': 7.15.4 '@babel/helper-split-export-declaration': 7.16.0
'@babel/parser': 7.15.8 '@babel/parser': 7.16.0
'@babel/types': 7.15.6 '@babel/types': 7.16.0
debug: 4.3.2 debug: 4.3.2
globals: 11.12.0 globals: 11.12.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@babel/types/7.15.6: /@babel/types/7.16.0:
resolution: {integrity: sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==} resolution: {integrity: sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/helper-validator-identifier': 7.15.7 '@babel/helper-validator-identifier': 7.15.7
@ -350,7 +354,7 @@ packages:
ajv: 6.12.6 ajv: 6.12.6
debug: 4.3.2 debug: 4.3.2
espree: 7.3.1 espree: 7.3.1
globals: 13.11.0 globals: 13.12.0
ignore: 4.0.6 ignore: 4.0.6
import-fresh: 3.3.0 import-fresh: 3.3.0
js-yaml: 3.14.1 js-yaml: 3.14.1
@ -367,7 +371,7 @@ packages:
ajv: 6.12.6 ajv: 6.12.6
debug: 4.3.2 debug: 4.3.2
espree: 9.0.0 espree: 9.0.0
globals: 13.11.0 globals: 13.12.0
ignore: 4.0.6 ignore: 4.0.6
import-fresh: 3.3.0 import-fresh: 3.3.0
js-yaml: 3.14.1 js-yaml: 3.14.1
@ -422,10 +426,11 @@ packages:
resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==} resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==}
dev: true dev: true
/@meshtastic/meshtasticjs/0.6.19: /@meshtastic/meshtasticjs/0.6.22:
resolution: {integrity: sha512-bdFkgAjjnnBm1J7dJjCxgQ0+ftu6txLAkO698YFodwGRbvb+io+N2ie6fInqvIFvoCPA9R1fUZa6WhGpIiVZGA==} resolution: {integrity: sha512-3G1dwVmwwtrR/TVbCGKcqXDgLDCkUPERiw8P8ZXdYLxYrmlAy2WAZEclzWdQtEmhvBKpXm1+pEBlycN4DXBDXw==}
dependencies: dependencies:
'@protobuf-ts/runtime': 2.0.7 '@protobuf-ts/runtime': 2.0.7
node-fetch: 3.0.0
sub-events: 1.8.9 sub-events: 1.8.9
dev: false dev: false
@ -595,9 +600,9 @@ packages:
immer: 9.0.6 immer: 9.0.6
react: 17.0.2 react: 17.0.2
react-redux: 7.2[email protected][email protected] react-redux: 7.2[email protected][email protected]
redux: 4.1.1 redux: 4.1.2
redux-thunk: 2.4[email protected].1 redux-thunk: 2.4[email protected].2
reselect: 4.1.0 reselect: 4.1.1
dev: false dev: false
/@rollup/plugin-commonjs/[email protected]: /@rollup/plugin-commonjs/[email protected]:
@ -705,8 +710,8 @@ packages:
react: '>=16.9.0' react: '>=16.9.0'
react-dom: '>=16.9.0' react-dom: '>=16.9.0'
dependencies: dependencies:
'@babel/core': 7.15.8 '@babel/core': 7.16.0
'@babel/plugin-syntax-class-properties': 7.12.13_@[email protected]5.8 '@babel/plugin-syntax-class-properties': 7.12.13_@[email protected]6.0
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
react-refresh: 0.9.0 react-refresh: 0.9.0
@ -806,7 +811,7 @@ packages:
'@types/hoist-non-react-statics': 3.3.1 '@types/hoist-non-react-statics': 3.3.1
'@types/react': 17.0.33 '@types/react': 17.0.33
hoist-non-react-statics: 3.3.2 hoist-non-react-statics: 3.3.2
redux: 4.1.1 redux: 4.1.2
/@types/react/17.0.33: /@types/react/17.0.33:
resolution: {integrity: sha512-pLWntxXpDPaU+RTAuSGWGSEL2FRTNyRQOjSWDke/rxRg14ncsZvx8AKWMWZqvc1UOaJIAoObdZhAWvRaHFi5rw==} resolution: {integrity: sha512-pLWntxXpDPaU+RTAuSGWGSEL2FRTNyRQOjSWDke/rxRg14ncsZvx8AKWMWZqvc1UOaJIAoObdZhAWvRaHFi5rw==}
@ -834,6 +839,14 @@ packages:
resolution: {integrity: sha512-zYzMb2aMyzXW5VgOQHy+FgI8N5tLFb+tIsUqk35CIgSr9pT4pji2GR8BCOTMdniusVuRHIp/DaYQNQGYGLVZHQ==} resolution: {integrity: sha512-zYzMb2aMyzXW5VgOQHy+FgI8N5tLFb+tIsUqk35CIgSr9pT4pji2GR8BCOTMdniusVuRHIp/DaYQNQGYGLVZHQ==}
dev: true dev: true
/@types/w3c-web-serial/1.0.2:
resolution: {integrity: sha512-Ftx4BtLxgAnel7V7GbHylCYjSq827A+jeEE3SnTS7huCGUN0pSwUn+CchTCT9TkZj9w+NVMUq4Bk2R0GvUNmAQ==}
dev: true
/@types/web-bluetooth/0.0.11:
resolution: {integrity: sha512-2CF3Kk2Rcvg/c2QzO7mXUhY7eL9CC3aKzrF+dNWNmp7Q8bmlvjmUM1nFPMSngawdJ+CcIdu8eJlQRytBgAZR9w==}
dev: true
/@typescript-eslint/eslint-plugin/4.33.0_cc617358c89d3f38c52462f6d809db4c: /@typescript-eslint/eslint-plugin/4.33.0_cc617358c89d3f38c52462f6d809db4c:
resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==} resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
@ -1300,18 +1313,18 @@ packages:
resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=}
dev: true dev: true
/autoprefixer/10.3.7[email protected]: /autoprefixer/10.4.0[email protected]:
resolution: {integrity: sha512-EmGpu0nnQVmMhX8ROoJ7Mx8mKYPlcUHuxkwrRYEYMz85lu7H09v8w6R1P0JPdn/hKU32GjpLBFEOuIlDWCRWvg==} resolution: {integrity: sha512-7FdJ1ONtwzV1G43GDD0kpVMn/qbiNqyOPMFTX5nRffI+7vgWoFEc6DcXOxHJxrWNDXrZh18eDsZjvZGUljSRGA==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
postcss: ^8.1.0 postcss: ^8.1.0
dependencies: dependencies:
browserslist: 4.17.5 browserslist: 4.17.5
caniuse-lite: 1.0.30001271 caniuse-lite: 1.0.30001272
fraction.js: 4.1.1 fraction.js: 4.1.1
normalize-range: 0.1.2 normalize-range: 0.1.2
picocolors: 0.2.1 picocolors: 1.0.0
postcss: 8.3.11 postcss: 8.3.11
postcss-value-parser: 4.1.0 postcss-value-parser: 4.1.0
dev: true dev: true
@ -1336,7 +1349,7 @@ packages:
find-babel-config: 1.2.0 find-babel-config: 1.2.0
glob: 7.2.0 glob: 7.2.0
pkg-up: 3.1.0 pkg-up: 3.1.0
reselect: 4.1.0 reselect: 4.1.1
resolve: 1.20.0 resolve: 1.20.0
dev: true dev: true
@ -1409,8 +1422,8 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true hasBin: true
dependencies: dependencies:
caniuse-lite: 1.0.30001271 caniuse-lite: 1.0.30001272
electron-to-chromium: 1.3.879 electron-to-chromium: 1.3.885
escalade: 3.1.1 escalade: 3.1.1
node-releases: 2.0.1 node-releases: 2.0.1
picocolors: 1.0.0 picocolors: 1.0.0
@ -1497,8 +1510,8 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true dev: true
/caniuse-lite/1.0.30001271: /caniuse-lite/1.0.30001272:
resolution: {integrity: sha512-BBruZFWmt3HFdVPS8kceTBIguKxu4f99n5JNp06OlPD/luoAMIaIK5ieV5YjnBLH3Nysai9sxj9rpJj4ZisXOA==} resolution: {integrity: sha512-DV1j9Oot5dydyH1v28g25KoVm7l8MTxazwuiH3utWiAS6iL/9Nh//TGwqFEeqqN8nnWYQ8HHhUq+o4QPt9kvYw==}
dev: true dev: true
/caseless/0.12.0: /caseless/0.12.0:
@ -1722,6 +1735,11 @@ packages:
assert-plus: 1.0.0 assert-plus: 1.0.0
dev: true dev: true
/data-uri-to-buffer/3.0.1:
resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==}
engines: {node: '>= 6'}
dev: false
/debug/2.6.9: /debug/2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
dependencies: dependencies:
@ -1933,8 +1951,8 @@ packages:
safer-buffer: 2.1.2 safer-buffer: 2.1.2
dev: true dev: true
/electron-to-chromium/1.3.879: /electron-to-chromium/1.3.885:
resolution: {integrity: sha512-zJo+D9GwbJvM31IdFmwcGvychhk4KKbKYo2GWlsn+C/dxz2NwmbhGJjWwTfFSF2+eFH7VvfA8MCZ8SOqTrlnpw==} resolution: {integrity: sha512-JXKFJcVWrdHa09n4CNZYfYaK6EW5aAew7/wr3L1OnsD1L+JHL+RCtd7QgIsxUbFPeTwPlvnpqNNTOLkoefmtXg==}
dev: true dev: true
/emoji-regex/8.0.0: /emoji-regex/8.0.0:
@ -2360,7 +2378,7 @@ packages:
file-entry-cache: 6.0.1 file-entry-cache: 6.0.1
functional-red-black-tree: 1.0.1 functional-red-black-tree: 1.0.1
glob-parent: 5.1.2 glob-parent: 5.1.2
globals: 13.11.0 globals: 13.12.0
ignore: 4.0.6 ignore: 4.0.6
import-fresh: 3.3.0 import-fresh: 3.3.0
imurmurhash: 0.1.4 imurmurhash: 0.1.4
@ -2408,7 +2426,7 @@ packages:
file-entry-cache: 6.0.1 file-entry-cache: 6.0.1
functional-red-black-tree: 1.0.1 functional-red-black-tree: 1.0.1
glob-parent: 6.0.2 glob-parent: 6.0.2
globals: 13.11.0 globals: 13.12.0
ignore: 4.0.6 ignore: 4.0.6
import-fresh: 3.3.0 import-fresh: 3.3.0
imurmurhash: 0.1.4 imurmurhash: 0.1.4
@ -2558,6 +2576,13 @@ packages:
resolution: {integrity: sha512-IgTtZwL52tx2wqWeuGDzXYTnNsEjNLahZpJw30hCQDyVnoHXwY5acNDnjGImTTL1R0z1PCyLw20VAbE5qLic3Q==} resolution: {integrity: sha512-IgTtZwL52tx2wqWeuGDzXYTnNsEjNLahZpJw30hCQDyVnoHXwY5acNDnjGImTTL1R0z1PCyLw20VAbE5qLic3Q==}
dev: true dev: true
/fetch-blob/3.1.3:
resolution: {integrity: sha512-ax1Y5I9w+9+JiM+wdHkhBoxew+zG4AJ2SvAD1v1szpddUIiPERVGBxrMcB2ZqW0Y3PP8bOWYv2zqQq1Jp2kqUQ==}
engines: {node: ^12.20 || >= 14.13}
dependencies:
web-streams-polyfill: 3.1.1
dev: false
/file-entry-cache/6.0.1: /file-entry-cache/6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
@ -2774,8 +2799,8 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
/globals/13.11.0: /globals/13.12.0:
resolution: {integrity: sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==} resolution: {integrity: sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==}
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
type-fest: 0.20.2 type-fest: 0.20.2
@ -2878,7 +2903,7 @@ packages:
/history/5.0.1: /history/5.0.1:
resolution: {integrity: sha512-5qC/tFUKfVci5kzgRxZxN5Mf1CV8NmJx9ByaPX0YTLx5Vz3Svh7NYp6eA4CpDq4iA9D0C1t8BNIfvQIrUI3mVw==} resolution: {integrity: sha512-5qC/tFUKfVci5kzgRxZxN5Mf1CV8NmJx9ByaPX0YTLx5Vz3Svh7NYp6eA4CpDq4iA9D0C1t8BNIfvQIrUI3mVw==}
dependencies: dependencies:
'@babel/runtime': 7.15.4 '@babel/runtime': 7.16.0
dev: false dev: false
/hoist-non-react-statics/3.3.2: /hoist-non-react-statics/3.3.2:
@ -2969,13 +2994,13 @@ packages:
/i18next-browser-languagedetector/6.1.2: /i18next-browser-languagedetector/6.1.2:
resolution: {integrity: sha512-YDzIGHhMRvr7M+c8B3EQUKyiMBhfqox4o1qkFvt4QXuu5V2cxf74+NCr+VEkUuU0y+RwcupA238eeolW1Yn80g==} resolution: {integrity: sha512-YDzIGHhMRvr7M+c8B3EQUKyiMBhfqox4o1qkFvt4QXuu5V2cxf74+NCr+VEkUuU0y+RwcupA238eeolW1Yn80g==}
dependencies: dependencies:
'@babel/runtime': 7.15.4 '@babel/runtime': 7.16.0
dev: false dev: false
/i18next/21.3.3: /i18next/21.3.3:
resolution: {integrity: sha512-Wv5arCT9pK35nfhOzTdS64T7JpPcoqnkOEidxc4zF0DZ8KetpvmnkO+uWkXy+DFz6zWzPX7U9bIemwBqpFRprw==} resolution: {integrity: sha512-Wv5arCT9pK35nfhOzTdS64T7JpPcoqnkOEidxc4zF0DZ8KetpvmnkO+uWkXy+DFz6zWzPX7U9bIemwBqpFRprw==}
dependencies: dependencies:
'@babel/runtime': 7.15.4 '@babel/runtime': 7.16.0
dev: false dev: false
/iconv-lite/0.6.3: /iconv-lite/0.6.3:
@ -3725,6 +3750,14 @@ packages:
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
dev: true dev: true
/node-fetch/3.0.0:
resolution: {integrity: sha512-bKMI+C7/T/SPU1lKnbQbwxptpCrG9ashG+VkytmXCPZyuM9jB6VU+hY0oi4lC8LxTtAeWdckNCTa3nrGsAdA3Q==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
data-uri-to-buffer: 3.0.1
fetch-blob: 3.1.3
dev: false
/node-gyp-build/4.3.0: /node-gyp-build/4.3.0:
resolution: {integrity: sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==} resolution: {integrity: sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==}
hasBin: true hasBin: true
@ -4112,7 +4145,7 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
'@babel/code-frame': 7.15.8 '@babel/code-frame': 7.16.0
error-ex: 1.3.2 error-ex: 1.3.2
json-parse-even-better-errors: 2.3.1 json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.1.6 lines-and-columns: 1.1.6
@ -4168,10 +4201,6 @@ packages:
is-reference: 1.2.1 is-reference: 1.2.1
dev: true dev: true
/picocolors/0.2.1:
resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==}
dev: true
/picocolors/1.0.0: /picocolors/1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true dev: true
@ -4444,21 +4473,21 @@ packages:
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
dev: false dev: false
/react-hook-form/7.17.5[email protected]: /react-hook-form/7.18.0[email protected]:
resolution: {integrity: sha512-4bPtPGkpVhZlgtTbtMGi0RFphKHgxCj5u3AsGz3SBdleELlG1pDf9zRQOtfGlOGkZlc7u78RzD0xu9kOw7PYdQ==} resolution: {integrity: sha512-aTFs1jXGvpBBv4vYuhheVd9KbAZw/l3DOZhLIadNDyFddaDQmn+yJa63IZ14GDFz4NFgIi+ROkubfGJG2x6q2Q==}
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17 react: ^16.8.0 || ^17
dependencies: dependencies:
react: 17.0.2 react: 17.0.2
dev: false dev: false
/react-i18next/11.12[email protected][email protected]: /react-i18next/11.13[email protected][email protected]:
resolution: {integrity: sha512-M9BT+hqVG03ywrl+L7CK74ugK+4jIo7AeKJ17+g9BoqJz2+/aVbs8SIVXT4KMQ1rjIdcw+GcSRDy1CXjcz6tLQ==} resolution: {integrity: sha512-AY8ydSqx8LVm1Tn5yXFA0JwCeSWpcFOSr96HrjUXXVAWWbptamZOY2iMxVaGNlGxSLnRY0U2sdCIPVYHcmhBxQ==}
peerDependencies: peerDependencies:
i18next: '>= 19.0.0' i18next: '>= 19.0.0'
react: '>= 16.8.0' react: '>= 16.8.0'
dependencies: dependencies:
'@babel/runtime': 7.15.4 '@babel/runtime': 7.16.0
html-parse-stringify: 3.0.1 html-parse-stringify: 3.0.1
i18next: 21.3.3 i18next: 21.3.3
react: 17.0.2 react: 17.0.2
@ -4491,7 +4520,7 @@ packages:
react-native: react-native:
optional: true optional: true
dependencies: dependencies:
'@babel/runtime': 7.15.4 '@babel/runtime': 7.16.0
'@types/react-redux': 7.1.20 '@types/react-redux': 7.1.20
hoist-non-react-statics: 3.3.2 hoist-non-react-statics: 3.3.2
loose-envify: 1.4.0 loose-envify: 1.4.0
@ -4554,18 +4583,18 @@ packages:
picomatch: 2.3.0 picomatch: 2.3.0
dev: true dev: true
/redux-thunk/[email protected].1: /redux-thunk/[email protected].2:
resolution: {integrity: sha512-/y6ZKQNU/0u8Bm7ROLq9Pt/7lU93cT0IucYMrubo89ENjxPa7i8pqLKu6V4X7/TvYovQ6x01unTeyeZ9lgXiTA==} resolution: {integrity: sha512-/y6ZKQNU/0u8Bm7ROLq9Pt/7lU93cT0IucYMrubo89ENjxPa7i8pqLKu6V4X7/TvYovQ6x01unTeyeZ9lgXiTA==}
peerDependencies: peerDependencies:
redux: ^4 redux: ^4
dependencies: dependencies:
redux: 4.1.1 redux: 4.1.2
dev: false dev: false
/redux/4.1.1: /redux/4.1.2:
resolution: {integrity: sha512-hZQZdDEM25UY2P493kPYuKqviVwZ58lEmGQNeQ+gXa+U0gYPUBf7NKYazbe3m+bs/DzM/ahN12DbF+NG8i0CWw==} resolution: {integrity: sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==}
dependencies: dependencies:
'@babel/runtime': 7.15.4 '@babel/runtime': 7.16.0
/regenerator-runtime/0.13.9: /regenerator-runtime/0.13.9:
resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==}
@ -4615,8 +4644,8 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/reselect/4.1.0: /reselect/4.1.1:
resolution: {integrity: sha512-An39mlrk9bnL39pq9M6th54FaL7VaqZe2m8tBb746udYYO6MD7MOIdaqZ+tABkAOmHQSTqtL3NhUNE8HVvVcQQ==} resolution: {integrity: sha512-Jjt8Us6hAWJpjucyladHvUGR+q1mHHgWtGDXlhvvKyNyIeQ3bjuWLDX0bsTLhbm/gd4iXEACBlODUHBlLWiNnA==}
/resolve-alpn/1.2.1: /resolve-alpn/1.2.1:
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
@ -5098,7 +5127,7 @@ packages:
strip-ansi: 6.0.1 strip-ansi: 6.0.1
dev: true dev: true
/tailwindcss/3.0.0-alpha.1_fa866e6aa6eb85ed70431566fb699b34: /tailwindcss/3.0.0-alpha.1_0c54bdadaf9d9c9c6c134cb2c6c061a3:
resolution: {integrity: sha512-VweVLyu1tpo/i2MnoyDIunToZHYhHRZLGuKDt9I+nnjFoW07NhDwwHWsUyRHKowP5MZaHduhV+AVlM6Auy7m3A==} resolution: {integrity: sha512-VweVLyu1tpo/i2MnoyDIunToZHYhHRZLGuKDt9I+nnjFoW07NhDwwHWsUyRHKowP5MZaHduhV+AVlM6Auy7m3A==}
engines: {node: '>=12.13.0'} engines: {node: '>=12.13.0'}
hasBin: true hasBin: true
@ -5107,7 +5136,7 @@ packages:
postcss: ^8.0.9 postcss: ^8.0.9
dependencies: dependencies:
arg: 5.0.1 arg: 5.0.1
autoprefixer: 10.3.7[email protected] autoprefixer: 10.4.0[email protected]
chalk: 4.1.2 chalk: 4.1.2
chokidar: 3.5.2 chokidar: 3.5.2
color-name: 1.1.4 color-name: 1.1.4
@ -5358,6 +5387,11 @@ packages:
resolution: {integrity: sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==} resolution: {integrity: sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==}
dev: true dev: true
/web-streams-polyfill/3.1.1:
resolution: {integrity: sha512-Czi3fG883e96T4DLEPRvufrF2ydhOOW1+1a6c3gNjH2aIh50DNFBdfwh2AKoOf1rXvpvavAoA11Qdq9+BKjE0Q==}
engines: {node: '>= 8'}
dev: false
/which-boxed-primitive/1.0.2: /which-boxed-primitive/1.0.2:
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
dependencies: dependencies:

23
src/App.tsx

@ -7,7 +7,7 @@ import { ThemeToggle } from '@components/menu/buttons/ThemeToggle';
import { Logo } from '@components/menu/Logo'; import { Logo } from '@components/menu/Logo';
import { MobileNav } from '@components/menu/MobileNav'; import { MobileNav } from '@components/menu/MobileNav';
import { Navigation } from '@components/menu/Navigation'; import { Navigation } from '@components/menu/Navigation';
import { connection } from '@core/connection'; import { connection, setConnection } from '@core/connection';
import { useRoute } from '@core/router'; import { useRoute } from '@core/router';
import { import {
addChannel, addChannel,
@ -20,14 +20,19 @@ import {
setReady, setReady,
setUser, setUser,
} from '@core/slices/meshtasticSlice'; } from '@core/slices/meshtasticSlice';
import { Protobuf, SettingsManager, Types } from '@meshtastic/meshtasticjs'; import {
IHTTPConnection,
Protobuf,
SettingsManager,
Types,
} from '@meshtastic/meshtasticjs';
import { About } from '@pages/About'; import { About } from '@pages/About';
import { Messages } from '@pages/Messages'; import { Messages } from '@pages/Messages';
import { Nodes } from '@pages/Nodes/Index'; import { Nodes } from '@pages/Nodes/Index';
import { Settings } from '@pages/settings/Index'; import { Settings } from '@pages/settings/Index';
import { NotFound } from './pages/NotFound'; import { NotFound } from './pages/NotFound';
import { Plugins } from './pages/Plugins/Index.jsx'; import { Plugins } from './pages/Plugins/Index';
const App = (): JSX.Element => { const App = (): JSX.Element => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -38,6 +43,7 @@ const App = (): JSX.Element => {
const hostOverrideEnabled = useAppSelector( const hostOverrideEnabled = useAppSelector(
(state) => state.meshtastic.hostOverrideEnabled, (state) => state.meshtastic.hostOverrideEnabled,
); );
const hostOverride = useAppSelector((state) => state.meshtastic.hostOverride); const hostOverride = useAppSelector((state) => state.meshtastic.hostOverride);
const connectionURL = hostOverrideEnabled const connectionURL = hostOverrideEnabled
@ -50,6 +56,7 @@ const App = (): JSX.Element => {
React.useEffect(() => { React.useEffect(() => {
SettingsManager.debugMode = Protobuf.LogRecord_Level.TRACE; SettingsManager.debugMode = Protobuf.LogRecord_Level.TRACE;
setConnection(new IHTTPConnection());
void connection.connect({ void connection.connect({
address: connectionURL, address: connectionURL,
tls: false, tls: false,
@ -74,8 +81,13 @@ const App = (): JSX.Element => {
dispatch(setMyNodeInfo(nodeInfo)); dispatch(setMyNodeInfo(nodeInfo));
}); });
connection.onUserDataPacket.subscribe((user) => { connection.onUserPacket.subscribe((user) => {
dispatch(setUser(user)); dispatch(
setUser({
nodeNum: user.packet.from,
user: user.data,
}),
);
}); });
connection.onNodeInfoPacket.subscribe((nodeInfoPacket) => connection.onNodeInfoPacket.subscribe((nodeInfoPacket) =>
@ -117,7 +129,6 @@ const App = (): JSX.Element => {
return (): void => { return (): void => {
connection.onDeviceStatus.cancelAll(); connection.onDeviceStatus.cancelAll();
connection.onMyNodeInfo.cancelAll(); connection.onMyNodeInfo.cancelAll();
connection.onUserDataPacket.cancelAll();
connection.onNodeInfoPacket.cancelAll(); connection.onNodeInfoPacket.cancelAll();
connection.onAdminPacket.cancelAll(); connection.onAdminPacket.cancelAll();
connection.onMeshHeartbeat.cancelAll(); connection.onMeshHeartbeat.cancelAll();

30
src/components/generic/IconButton.tsx

@ -1,47 +1,23 @@
import React from 'react'; import React from 'react';
import { FiCheck } from 'react-icons/fi';
type DefaulButtonProps = JSX.IntrinsicElements['button']; type DefaulButtonProps = JSX.IntrinsicElements['button'];
export interface IconButtonProps extends DefaulButtonProps { export interface IconButtonProps extends DefaulButtonProps {
icon: React.ReactNode; icon: React.ReactNode;
confirmAction?: () => void;
} }
export const IconButton = ({ export const IconButton = ({
icon, icon,
confirmAction,
...props ...props
}: IconButtonProps): JSX.Element => { }: IconButtonProps): JSX.Element => {
const [hasConfirmed, setHasConfirmed] = React.useState(false);
const handleConfirm = (): void => {
if (confirmAction) {
if (hasConfirmed) {
void confirmAction();
}
setHasConfirmed(true);
setTimeout(() => {
setHasConfirmed(false);
}, 3000);
}
};
return ( return (
<div <div className="my-auto text-gray-500 dark:text-gray-400">
className="my-auto text-gray-500 dark:text-gray-400"
onClick={handleConfirm}
>
<button <button
type="button" type="button"
className={`p-2 rounded-md active:scale-95 ${ className="p-2 rounded-md active:scale-95 hover:bg-gray-200 dark:hover:bg-gray-600"
hasConfirmed
? 'bg-red-500'
: 'hover:bg-gray-200 dark:hover:bg-gray-600'
}`}
{...props} {...props}
> >
{hasConfirmed ? <FiCheck /> : icon} {icon}
<span className="sr-only">Refresh</span> <span className="sr-only">Refresh</span>
</button> </button>
</div> </div>

10
src/core/connection.ts

@ -4,6 +4,10 @@ import {
ISerialConnection, ISerialConnection,
} from '@meshtastic/meshtasticjs'; } from '@meshtastic/meshtasticjs';
export const connection = new IHTTPConnection(); type connectionType = IBLEConnection | IHTTPConnection | ISerialConnection;
export const bleConnection = new IBLEConnection();
export const serialConnection = new ISerialConnection(); export let connection: connectionType = new IHTTPConnection();
export const setConnection = (conn: connectionType): void => {
connection = conn;
};

32
src/core/slices/meshtasticSlice.ts

@ -10,6 +10,11 @@ export interface MessageWithAck {
isSender: boolean; isSender: boolean;
received: Date; received: Date;
} }
enum connType {
HTTP,
BLE,
SERIAL,
}
interface MeshtasticState { interface MeshtasticState {
deviceStatus: Types.DeviceStatusEnum; deviceStatus: Types.DeviceStatusEnum;
@ -24,6 +29,7 @@ interface MeshtasticState {
messages: MessageWithAck[]; messages: MessageWithAck[];
hostOverrideEnabled: boolean; hostOverrideEnabled: boolean;
hostOverride: string; hostOverride: string;
connectionType: connType;
} }
const initialState: MeshtasticState = { const initialState: MeshtasticState = {
@ -40,6 +46,7 @@ const initialState: MeshtasticState = {
hostOverrideEnabled: hostOverrideEnabled:
localStorage.getItem('hostOverrideEnabled') === 'true' ?? false, localStorage.getItem('hostOverrideEnabled') === 'true' ?? false,
hostOverride: localStorage.getItem('hostOverride') ?? '', hostOverride: localStorage.getItem('hostOverride') ?? '',
connectionType: parseInt(localStorage.getItem('connectionType') ?? '0'),
}; };
export const meshtasticSlice = createSlice({ export const meshtasticSlice = createSlice({
@ -58,8 +65,21 @@ export const meshtasticSlice = createSlice({
setMyNodeInfo: (state, action: PayloadAction<Protobuf.MyNodeInfo>) => { setMyNodeInfo: (state, action: PayloadAction<Protobuf.MyNodeInfo>) => {
state.myNodeInfo = action.payload; state.myNodeInfo = action.payload;
}, },
setUser: (state, action: PayloadAction<Protobuf.User>) => { setUser: (
state.user = action.payload; state,
action: PayloadAction<{
nodeNum: number;
user: Protobuf.User;
}>,
) => {
if (action.payload.nodeNum === state.myNodeInfo.myNodeNum) {
state.user = action.payload.user;
} else {
const num = state.nodes.findIndex(
(node) => node.num === action.payload.nodeNum,
);
state.nodes[num].user = action.payload.user;
}
}, },
addPositionPacket: (state, action: PayloadAction<Types.PositionPacket>) => { addPositionPacket: (state, action: PayloadAction<Types.PositionPacket>) => {
state.positionPackets.push(action.payload); state.positionPackets.push(action.payload);
@ -75,7 +95,6 @@ export const meshtasticSlice = createSlice({
state.nodes.push(action.payload); state.nodes.push(action.payload);
} }
}, },
addChannel: (state, action: PayloadAction<Protobuf.Channel>) => { addChannel: (state, action: PayloadAction<Protobuf.Channel>) => {
if ( if (
state.channels.findIndex( state.channels.findIndex(
@ -121,6 +140,13 @@ export const meshtasticSlice = createSlice({
connection.disconnect(); connection.disconnect();
} }
}, },
setConnectionType: (state, action: PayloadAction<connType>) => {
state.connectionType = action.payload;
localStorage.setItem('connectionType', String(action.payload));
if (state.connectionType !== action.payload) {
connection.disconnect();
}
},
}, },
}); });

16
src/pages/Plugins/Files.tsx

@ -118,14 +118,14 @@ export const Files = ({ navOpen, setNavOpen }: RangeTestProps): JSX.Element => {
</div> </div>
<IconButton <IconButton
className="mx-2 my-auto" className="mx-2 my-auto"
confirmAction={async (): Promise<void> => { // confirmAction={async (): Promise<void> => {
await fetch( // await fetch(
`http://${connectionURL}/json/spiffs/delete/static?remove=${file.name}`, // `http://${connectionURL}/json/spiffs/delete/static?remove=${file.name}`,
{ // {
method: 'DELETE', // method: 'DELETE',
}, // },
); // );
}} // }}
icon={<FiTrash className="w-5 h-5" />} icon={<FiTrash className="w-5 h-5" />}
/> />
</div> </div>

1
src/pages/Plugins/Index.tsx

@ -34,7 +34,6 @@ export const Plugins = (): JSX.Element => {
<div className="md:hidden"> <div className="md:hidden">
<IconButton <IconButton
icon={<FiXCircle className="w-5 h-5" />} icon={<FiXCircle className="w-5 h-5" />}
circle
onClick={(): void => { onClick={(): void => {
setNavOpen(false); setNavOpen(false);
}} }}

282
src/pages/settings/Connection.tsx

@ -2,39 +2,125 @@ import React from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FiLink2, FiMenu, FiSave } from 'react-icons/fi'; import { FiCheck, FiMenu, FiSave } from 'react-icons/fi';
import { Card } from '@app/components/generic/Card'; import { Card } from '@app/components/generic/Card';
import { EnumSelect } from '@app/components/generic/form/EnumSelect';
import { Input } from '@app/components/generic/form/Input'; import { Input } from '@app/components/generic/form/Input';
import { IconButton } from '@app/components/generic/IconButton.jsx'; import { IconButton } from '@app/components/generic/IconButton';
import { Tabs } from '@app/components/generic/Tabs';
import { Toggle } from '@app/components/generic/Toggle'; import { Toggle } from '@app/components/generic/Toggle';
import { bleConnection, serialConnection } from '@app/core/connection'; import { connection, setConnection } from '@app/core/connection';
import { useAppSelector } from '@app/hooks/redux'; import { useAppDispatch, useAppSelector } from '@app/hooks/redux';
import { Button } from '@components/generic/Button'; import { Button } from '@components/generic/Button';
import { PrimaryTemplate } from '@components/templates/PrimaryTemplate'; import { PrimaryTemplate } from '@components/templates/PrimaryTemplate';
import type { Protobuf } from '@meshtastic/meshtasticjs'; import {
IBLEConnection,
IHTTPConnection,
ISerialConnection,
} from '@meshtastic/meshtasticjs';
import type {
BLEConnectionParameters,
HTTPConnectionParameters,
SerialConnectionParameters,
} from '@meshtastic/meshtasticjs/dist/types';
export interface ConnectionProps { export interface ConnectionProps {
navOpen: boolean; navOpen: boolean;
setNavOpen: React.Dispatch<React.SetStateAction<boolean>>; setNavOpen: React.Dispatch<React.SetStateAction<boolean>>;
} }
enum connType {
HTTP,
BLE,
SERIAL,
}
export const Connection = ({ export const Connection = ({
navOpen, navOpen,
setNavOpen, setNavOpen,
}: ConnectionProps): JSX.Element => { }: ConnectionProps): JSX.Element => {
const dispatch = useAppDispatch();
const [selectedConnType, setSelectedConnType] = React.useState(connType.HTTP);
const [bleDevices, setBleDevices] = React.useState<BluetoothDevice[]>([]);
const [serialDevices, setSerialDevices] = React.useState<SerialPort[]>([]);
const [httpIpSource, setHttpIpSource] = React.useState<'local' | 'remote'>(
'local',
);
const { t } = useTranslation(); const { t } = useTranslation();
const user = useAppSelector((state) => state.meshtastic.user); const hostOverrideEnabled = useAppSelector(
(state) => state.meshtastic.hostOverrideEnabled,
);
const hostOverride = useAppSelector((state) => state.meshtastic.hostOverride);
const { register, handleSubmit, formState } = useForm<Protobuf.User>({ const { register, handleSubmit, formState } = useForm<{
defaultValues: user, method: connType;
}>({
defaultValues: {
method: connType.HTTP,
},
}); });
const connect = (
connectionType: connType,
params:
| HTTPConnectionParameters
| SerialConnectionParameters
| BLEConnectionParameters,
): void => {
connection.complete();
connection.disconnect();
if (connectionType === connType.BLE) {
setConnection(new IBLEConnection());
} else if (connectionType === connType.HTTP) {
setConnection(new IHTTPConnection());
} else {
setConnection(new ISerialConnection());
}
console.log(params);
// @ts-ignore
connection.connect(params);
console.log(connection);
};
const updateBleDeviceList = async (): Promise<void> => {
const devices = await ble.getDevices();
setBleDevices(devices);
};
const updateSerialDeviceList = async (): Promise<void> => {
const devices = await serial.getPorts();
console.log(devices);
setSerialDevices(devices);
};
React.useEffect(() => {
if (selectedConnType === connType.BLE) {
updateBleDeviceList();
}
if (selectedConnType === connType.SERIAL) {
updateSerialDeviceList();
}
}, [selectedConnType]);
const onSubmit = handleSubmit((data) => { const onSubmit = handleSubmit((data) => {
// void connection.setOwner(data); // void connection.setOwner(data);
}); });
const connectionURL: string = hostOverrideEnabled
? hostOverride
: import.meta.env.NODE_ENV === 'production'
? window.location.hostname
: (import.meta.env.SNOWPACK_PUBLIC_DEVICE_IP as string) ??
'http://meshtastic.local';
const ble = new IBLEConnection();
const serial = new ISerialConnection();
return ( return (
<PrimaryTemplate <PrimaryTemplate
title="Connection" title="Connection"
@ -64,73 +150,127 @@ export const Connection = ({
description="Device name and user parameters" description="Device name and user parameters"
> >
<div className="w-full max-w-3xl p-10 md:max-w-xl"> <div className="w-full max-w-3xl p-10 md:max-w-xl">
<div className="flex w-full p-2 mb-2 border dark:border-gray-600 rounded-3xl">
Current connection method:
<div className="px-1 my-auto ml-2 text-sm bg-gray-400 rounded-full dark:bg-primaryDark">
BLE
</div>
</div>
<form className="space-y-2" onSubmit={onSubmit}> <form className="space-y-2" onSubmit={onSubmit}>
<Tabs <EnumSelect
className="mb-10 h-60" label="Method"
tabs={[ optionsEnum={connType}
{ value={selectedConnType}
name: 'HTTP', onChange={(e): void => {
body: ( setSelectedConnType(parseInt(e.target.value));
<div className="space-y-2"> }}
<Input label={'Device URL'} /> />
<Toggle label="Use TLS?" /> {selectedConnType === connType.HTTP && (
</div> <>
), <EnumSelect
}, label="Host Source"
{ options={[
name: 'Bluetooth', {
body: ( name: 'Local',
<div className="space-y-2"> value: 'local',
Devices: },
<Button {
onClick={async (): Promise<void> => { name: 'Remote',
console.log(await bleConnection.getDevices()); value: 'remote',
},
]}
value={httpIpSource}
onChange={(e): void => {
setHttpIpSource(e.target.value as 'local' | 'remote');
}}
/>
{httpIpSource === 'local' ? (
<Input label="Host" value={connectionURL} disabled />
) : (
<Input label="Host" />
)}
<Toggle label="Use TLS?" />
</>
)}
{selectedConnType === connType.BLE && (
<div>
<div className="flex space-x-2">
<Button border onClick={updateBleDeviceList}>
Refresh List
</Button>
<Button
border
onClick={() => {
ble.getDevice();
}}
>
New Device
</Button>
</div>
<div className="space-y-2">
<div>Previously connected devices</div>
{bleDevices.map((device) => (
<div
onClick={() => {
console.log('clicked');
connect(connType.BLE, {
device: device,
});
}}
className="flex justify-between p-2 bg-gray-700 rounded-md"
key={device.id}
>
<div className="my-auto">{device.name}</div>
<IconButton
onClick={() => {
console.log('clicked');
connect(connType.BLE, {
device: device,
});
}} }}
> icon={<FiCheck />}
Get Devices />
</Button>
<div className="flex justify-between p-2 border rounded-3xl dark:border-600">
Device Name
<FiLink2 className="w-5 h-5 my-auto mr-2 text-gray-300" />
</div>
<div className="flex justify-between p-2 border rounded-3xl dark:border-600">
Device Name
<FiLink2 className="w-5 h-5 my-auto mr-2 text-gray-600" />
</div>
</div> </div>
), ))}
}, </div>
{ </div>
name: 'Serial', )}
body: ( {selectedConnType === connType.SERIAL && (
<div className="space-y-2"> <div>
Devices: <div className="flex space-x-2">
<Button <Button border onClick={updateBleDeviceList}>
onClick={async (): Promise<void> => { Refresh List
console.log(await serialConnection.getPorts()); </Button>
}} <Button
> border
Get Devices onClick={() => {
</Button> serial.getPort();
<div className="flex justify-between p-2 border rounded-3xl dark:border-600"> }}
Device Name >
<FiLink2 className="w-5 h-5 my-auto mr-2 text-gray-300" /> New Device
</div> </Button>
<div className="flex justify-between p-2 border rounded-3xl dark:border-600"> </div>
Device Name <div className="space-y-2">
<FiLink2 className="w-5 h-5 my-auto mr-2 text-gray-600" /> <div>Previously connected devices</div>
{serialDevices.map((device) => (
<div
className="flex justify-between p-2 bg-gray-700 rounded-md"
key={device.getInfo().usbProductId}
>
<div className="my-auto">
{device.getInfo().usbProductId}
{device.getInfo().usbVendorId}
</div> </div>
<IconButton
onClick={() => {
connect(connType.SERIAL, {
// @ts-ignore
device: device,
});
}}
icon={<FiCheck />}
/>
</div> </div>
), ))}
}, </div>
]} </div>
/> )}
</form> </form>
</div> </div>
</Card> </Card>

Loading…
Cancel
Save