Fixes, new debug output & more.
This commit is contained in:
+6
-3
@@ -16,7 +16,7 @@
|
|||||||
"@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",
|
||||||
"i18next": "^21.4.1",
|
"i18next": "^21.4.2",
|
||||||
"i18next-browser-languagedetector": "^6.1.2",
|
"i18next-browser-languagedetector": "^6.1.2",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
@@ -24,9 +24,11 @@
|
|||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-file-icon": "^1.1.0",
|
"react-file-icon": "^1.1.0",
|
||||||
"react-hook-form": "^7.19.1",
|
"react-hook-form": "^7.19.1",
|
||||||
"react-i18next": "^11.13.0",
|
"react-i18next": "^11.14.0",
|
||||||
"react-icons": "^4.3.1",
|
"react-icons": "^4.3.1",
|
||||||
|
"react-json-pretty": "^2.2.0",
|
||||||
"react-redux": "^7.2.6",
|
"react-redux": "^7.2.6",
|
||||||
|
"react-timeago": "^6.2.1",
|
||||||
"swr": "^1.0.1",
|
"swr": "^1.0.1",
|
||||||
"type-route": "^0.6.0",
|
"type-route": "^0.6.0",
|
||||||
"use-breakpoint": "^2.0.2"
|
"use-breakpoint": "^2.0.2"
|
||||||
@@ -40,6 +42,7 @@
|
|||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
"@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/react-timeago": "^4.1.3",
|
||||||
"@types/snowpack-env": "^2.3.4",
|
"@types/snowpack-env": "^2.3.4",
|
||||||
"@types/w3c-web-serial": "^1.0.2",
|
"@types/w3c-web-serial": "^1.0.2",
|
||||||
"@types/web-bluetooth": "^0.0.11",
|
"@types/web-bluetooth": "^0.0.11",
|
||||||
@@ -54,7 +57,7 @@
|
|||||||
"eslint-import-resolver-typescript": "^2.5.0",
|
"eslint-import-resolver-typescript": "^2.5.0",
|
||||||
"eslint-plugin-import": "^2.25.2",
|
"eslint-plugin-import": "^2.25.2",
|
||||||
"eslint-plugin-react": "^7.26.1",
|
"eslint-plugin-react": "^7.26.1",
|
||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.3.0",
|
||||||
"gzipper": "^6.0.0",
|
"gzipper": "^6.0.0",
|
||||||
"postcss": "^8.3.11",
|
"postcss": "^8.3.11",
|
||||||
"prettier": "^2.4.1",
|
"prettier": "^2.4.1",
|
||||||
|
|||||||
Generated
+93
-62
@@ -12,6 +12,7 @@ specifiers:
|
|||||||
'@types/react-dom': ^17.0.11
|
'@types/react-dom': ^17.0.11
|
||||||
'@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/react-timeago': ^4.1.3
|
||||||
'@types/snowpack-env': ^2.3.4
|
'@types/snowpack-env': ^2.3.4
|
||||||
'@types/w3c-web-serial': ^1.0.2
|
'@types/w3c-web-serial': ^1.0.2
|
||||||
'@types/web-bluetooth': ^0.0.11
|
'@types/web-bluetooth': ^0.0.11
|
||||||
@@ -28,9 +29,9 @@ specifiers:
|
|||||||
eslint-import-resolver-typescript: ^2.5.0
|
eslint-import-resolver-typescript: ^2.5.0
|
||||||
eslint-plugin-import: ^2.25.2
|
eslint-plugin-import: ^2.25.2
|
||||||
eslint-plugin-react: ^7.26.1
|
eslint-plugin-react: ^7.26.1
|
||||||
eslint-plugin-react-hooks: ^4.2.0
|
eslint-plugin-react-hooks: ^4.3.0
|
||||||
gzipper: ^6.0.0
|
gzipper: ^6.0.0
|
||||||
i18next: ^21.4.1
|
i18next: ^21.4.2
|
||||||
i18next-browser-languagedetector: ^6.1.2
|
i18next-browser-languagedetector: ^6.1.2
|
||||||
moment: ^2.29.1
|
moment: ^2.29.1
|
||||||
postcss: ^8.3.11
|
postcss: ^8.3.11
|
||||||
@@ -40,9 +41,11 @@ specifiers:
|
|||||||
react-dom: ^17.0.2
|
react-dom: ^17.0.2
|
||||||
react-file-icon: ^1.1.0
|
react-file-icon: ^1.1.0
|
||||||
react-hook-form: ^7.19.1
|
react-hook-form: ^7.19.1
|
||||||
react-i18next: ^11.13.0
|
react-i18next: ^11.14.0
|
||||||
react-icons: ^4.3.1
|
react-icons: ^4.3.1
|
||||||
|
react-json-pretty: ^2.2.0
|
||||||
react-redux: ^7.2.6
|
react-redux: ^7.2.6
|
||||||
|
react-timeago: ^6.2.1
|
||||||
snowpack: ^3.8.8
|
snowpack: ^3.8.8
|
||||||
swr: ^1.0.1
|
swr: ^1.0.1
|
||||||
tailwindcss: ^3.0.0-alpha.2
|
tailwindcss: ^3.0.0-alpha.2
|
||||||
@@ -57,7 +60,7 @@ dependencies:
|
|||||||
'@reduxjs/toolkit': 1.6.2_react-redux@7.2.6+react@17.0.2
|
'@reduxjs/toolkit': 1.6.2_react-redux@7.2.6+react@17.0.2
|
||||||
apexcharts: 3.29.0
|
apexcharts: 3.29.0
|
||||||
boring-avatars: 1.5.8
|
boring-avatars: 1.5.8
|
||||||
i18next: 21.4.1
|
i18next: 21.4.2
|
||||||
i18next-browser-languagedetector: 6.1.2
|
i18next-browser-languagedetector: 6.1.2
|
||||||
moment: 2.29.1
|
moment: 2.29.1
|
||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
@@ -65,9 +68,11 @@ dependencies:
|
|||||||
react-dom: 17.0.2_react@17.0.2
|
react-dom: 17.0.2_react@17.0.2
|
||||||
react-file-icon: 1.1.0_react-dom@17.0.2+react@17.0.2
|
react-file-icon: 1.1.0_react-dom@17.0.2+react@17.0.2
|
||||||
react-hook-form: 7.19.1_react@17.0.2
|
react-hook-form: 7.19.1_react@17.0.2
|
||||||
react-i18next: 11.13.0_i18next@21.4.1+react@17.0.2
|
react-i18next: 11.14.0_i18next@21.4.2+react@17.0.2
|
||||||
react-icons: 4.3.1_react@17.0.2
|
react-icons: 4.3.1_react@17.0.2
|
||||||
|
react-json-pretty: 2.2.0_react-dom@17.0.2+react@17.0.2
|
||||||
react-redux: 7.2.6_react-dom@17.0.2+react@17.0.2
|
react-redux: 7.2.6_react-dom@17.0.2+react@17.0.2
|
||||||
|
react-timeago: 6.2.1_react@17.0.2
|
||||||
swr: 1.0.1_react@17.0.2
|
swr: 1.0.1_react@17.0.2
|
||||||
type-route: 0.6.0
|
type-route: 0.6.0
|
||||||
use-breakpoint: 2.0.2_react-dom@17.0.2+react@17.0.2
|
use-breakpoint: 2.0.2_react-dom@17.0.2+react@17.0.2
|
||||||
@@ -81,6 +86,7 @@ devDependencies:
|
|||||||
'@types/react-dom': 17.0.11
|
'@types/react-dom': 17.0.11
|
||||||
'@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/react-timeago': 4.1.3
|
||||||
'@types/snowpack-env': 2.3.4
|
'@types/snowpack-env': 2.3.4
|
||||||
'@types/w3c-web-serial': 1.0.2
|
'@types/w3c-web-serial': 1.0.2
|
||||||
'@types/web-bluetooth': 0.0.11
|
'@types/web-bluetooth': 0.0.11
|
||||||
@@ -95,7 +101,7 @@ devDependencies:
|
|||||||
eslint-import-resolver-typescript: 2.5.0_3f013334cb52440e201498cdb6b29798
|
eslint-import-resolver-typescript: 2.5.0_3f013334cb52440e201498cdb6b29798
|
||||||
eslint-plugin-import: 2.25.2_eslint@8.2.0
|
eslint-plugin-import: 2.25.2_eslint@8.2.0
|
||||||
eslint-plugin-react: 7.26.1_eslint@8.2.0
|
eslint-plugin-react: 7.26.1_eslint@8.2.0
|
||||||
eslint-plugin-react-hooks: 4.2.0_eslint@8.2.0
|
eslint-plugin-react-hooks: 4.3.0_eslint@8.2.0
|
||||||
gzipper: 6.0.0
|
gzipper: 6.0.0
|
||||||
postcss: 8.3.11
|
postcss: 8.3.11
|
||||||
prettier: 2.4.1
|
prettier: 2.4.1
|
||||||
@@ -130,12 +136,12 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.16.0
|
'@babel/code-frame': 7.16.0
|
||||||
'@babel/generator': 7.16.0
|
'@babel/generator': 7.16.0
|
||||||
'@babel/helper-compilation-targets': 7.16.0_@babel+core@7.16.0
|
'@babel/helper-compilation-targets': 7.16.3_@babel+core@7.16.0
|
||||||
'@babel/helper-module-transforms': 7.16.0
|
'@babel/helper-module-transforms': 7.16.0
|
||||||
'@babel/helpers': 7.16.0
|
'@babel/helpers': 7.16.3
|
||||||
'@babel/parser': 7.16.2
|
'@babel/parser': 7.16.3
|
||||||
'@babel/template': 7.16.0
|
'@babel/template': 7.16.0
|
||||||
'@babel/traverse': 7.16.0
|
'@babel/traverse': 7.16.3
|
||||||
'@babel/types': 7.16.0
|
'@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
|
||||||
@@ -156,8 +162,8 @@ packages:
|
|||||||
source-map: 0.5.7
|
source-map: 0.5.7
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@babel/helper-compilation-targets/7.16.0_@babel+core@7.16.0:
|
/@babel/helper-compilation-targets/7.16.3_@babel+core@7.16.0:
|
||||||
resolution: {integrity: sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==}
|
resolution: {integrity: sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0
|
'@babel/core': ^7.0.0
|
||||||
@@ -216,7 +222,7 @@ packages:
|
|||||||
'@babel/helper-split-export-declaration': 7.16.0
|
'@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.16.0
|
'@babel/template': 7.16.0
|
||||||
'@babel/traverse': 7.16.0
|
'@babel/traverse': 7.16.3
|
||||||
'@babel/types': 7.16.0
|
'@babel/types': 7.16.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -240,7 +246,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/helper-member-expression-to-functions': 7.16.0
|
'@babel/helper-member-expression-to-functions': 7.16.0
|
||||||
'@babel/helper-optimise-call-expression': 7.16.0
|
'@babel/helper-optimise-call-expression': 7.16.0
|
||||||
'@babel/traverse': 7.16.0
|
'@babel/traverse': 7.16.3
|
||||||
'@babel/types': 7.16.0
|
'@babel/types': 7.16.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -270,12 +276,12 @@ packages:
|
|||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@babel/helpers/7.16.0:
|
/@babel/helpers/7.16.3:
|
||||||
resolution: {integrity: sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==}
|
resolution: {integrity: sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/template': 7.16.0
|
'@babel/template': 7.16.0
|
||||||
'@babel/traverse': 7.16.0
|
'@babel/traverse': 7.16.3
|
||||||
'@babel/types': 7.16.0
|
'@babel/types': 7.16.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -290,8 +296,8 @@ packages:
|
|||||||
js-tokens: 4.0.0
|
js-tokens: 4.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@babel/parser/7.16.2:
|
/@babel/parser/7.16.3:
|
||||||
resolution: {integrity: sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==}
|
resolution: {integrity: sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
@@ -305,8 +311,8 @@ packages:
|
|||||||
'@babel/helper-plugin-utils': 7.14.5
|
'@babel/helper-plugin-utils': 7.14.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@babel/runtime/7.16.0:
|
/@babel/runtime/7.16.3:
|
||||||
resolution: {integrity: sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==}
|
resolution: {integrity: sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime: 0.13.9
|
regenerator-runtime: 0.13.9
|
||||||
@@ -316,12 +322,12 @@ packages:
|
|||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.16.0
|
'@babel/code-frame': 7.16.0
|
||||||
'@babel/parser': 7.16.2
|
'@babel/parser': 7.16.3
|
||||||
'@babel/types': 7.16.0
|
'@babel/types': 7.16.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@babel/traverse/7.16.0:
|
/@babel/traverse/7.16.3:
|
||||||
resolution: {integrity: sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==}
|
resolution: {integrity: sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.16.0
|
'@babel/code-frame': 7.16.0
|
||||||
@@ -329,7 +335,7 @@ packages:
|
|||||||
'@babel/helper-function-name': 7.16.0
|
'@babel/helper-function-name': 7.16.0
|
||||||
'@babel/helper-hoist-variables': 7.16.0
|
'@babel/helper-hoist-variables': 7.16.0
|
||||||
'@babel/helper-split-export-declaration': 7.16.0
|
'@babel/helper-split-export-declaration': 7.16.0
|
||||||
'@babel/parser': 7.16.2
|
'@babel/parser': 7.16.3
|
||||||
'@babel/types': 7.16.0
|
'@babel/types': 7.16.0
|
||||||
debug: 4.3.2
|
debug: 4.3.2
|
||||||
globals: 11.12.0
|
globals: 11.12.0
|
||||||
@@ -811,6 +817,12 @@ packages:
|
|||||||
hoist-non-react-statics: 3.3.2
|
hoist-non-react-statics: 3.3.2
|
||||||
redux: 4.1.2
|
redux: 4.1.2
|
||||||
|
|
||||||
|
/@types/react-timeago/4.1.3:
|
||||||
|
resolution: {integrity: sha512-XaaMBzuXLw7lxPPDs/fenlohcf3NDqM5qP4oOL/Meu+Hb1QChW4Igw/SruS1llEqch18RQB3wDTIwvqq4nivvw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 17.0.34
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/react/17.0.34:
|
/@types/react/17.0.34:
|
||||||
resolution: {integrity: sha512-46FEGrMjc2+8XhHXILr+3+/sTe3OfzSPU9YGKILLrUYbQ1CLQC9Daqo1KzENGXAWwrFwiY0l4ZbF20gRvgpWTg==}
|
resolution: {integrity: sha512-46FEGrMjc2+8XhHXILr+3+/sTe3OfzSPU9YGKILLrUYbQ1CLQC9Daqo1KzENGXAWwrFwiY0l4ZbF20gRvgpWTg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1069,7 +1081,7 @@ packages:
|
|||||||
eslint-import-resolver-typescript: 2.5.0_560ef94424f7023f0ab025f67f79aa67
|
eslint-import-resolver-typescript: 2.5.0_560ef94424f7023f0ab025f67f79aa67
|
||||||
eslint-plugin-import: 2.25.2_eslint@7.32.0
|
eslint-plugin-import: 2.25.2_eslint@7.32.0
|
||||||
eslint-plugin-react: 7.26.1_eslint@7.32.0
|
eslint-plugin-react: 7.26.1_eslint@7.32.0
|
||||||
eslint-plugin-react-hooks: 4.2.0_eslint@7.32.0
|
eslint-plugin-react-hooks: 4.3.0_eslint@7.32.0
|
||||||
prettier: 2.4.1
|
prettier: 2.4.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
@@ -1319,7 +1331,7 @@ packages:
|
|||||||
postcss: ^8.1.0
|
postcss: ^8.1.0
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.17.6
|
browserslist: 4.17.6
|
||||||
caniuse-lite: 1.0.30001278
|
caniuse-lite: 1.0.30001279
|
||||||
fraction.js: 4.1.1
|
fraction.js: 4.1.1
|
||||||
normalize-range: 0.1.2
|
normalize-range: 0.1.2
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
@@ -1420,8 +1432,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.30001278
|
caniuse-lite: 1.0.30001279
|
||||||
electron-to-chromium: 1.3.891
|
electron-to-chromium: 1.3.893
|
||||||
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
|
||||||
@@ -1508,8 +1520,8 @@ packages:
|
|||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/caniuse-lite/1.0.30001278:
|
/caniuse-lite/1.0.30001279:
|
||||||
resolution: {integrity: sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==}
|
resolution: {integrity: sha512-VfEHpzHEXj6/CxggTwSFoZBBYGQfQv9Cf42KPlO79sWXCD1QNKWKsKzFeWL7QpZHJQYAvocqV6Rty1yJMkqWLQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/caseless/0.12.0:
|
/caseless/0.12.0:
|
||||||
@@ -1653,7 +1665,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
|
resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-db: 1.50.0
|
mime-db: 1.51.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/concat-map/0.0.1:
|
/concat-map/0.0.1:
|
||||||
@@ -1945,8 +1957,8 @@ packages:
|
|||||||
safer-buffer: 2.1.2
|
safer-buffer: 2.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/electron-to-chromium/1.3.891:
|
/electron-to-chromium/1.3.893:
|
||||||
resolution: {integrity: sha512-3cpwR82QkIS01CN/dup/4Yr3BiOiRLlZlcAFn/5FbNCunMO9ojqDgEP9JEo1QNLflu3pEnPWve50gHOEKc7r6w==}
|
resolution: {integrity: sha512-ChtwF7qB03INq1SyMpue08wc6cve+ktj2UC/Y7se9vB+JryfzziJeYwsgb8jLaCA5GMkHCdn5M62PfSMWhifZg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/emoji-regex/8.0.0:
|
/emoji-regex/8.0.0:
|
||||||
@@ -2225,20 +2237,20 @@ packages:
|
|||||||
tsconfig-paths: 3.11.0
|
tsconfig-paths: 3.11.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-react-hooks/4.2.0_eslint@7.32.0:
|
/eslint-plugin-react-hooks/4.3.0_eslint@7.32.0:
|
||||||
resolution: {integrity: sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==}
|
resolution: {integrity: sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-react-hooks/4.2.0_eslint@8.2.0:
|
/eslint-plugin-react-hooks/4.3.0_eslint@8.2.0:
|
||||||
resolution: {integrity: sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==}
|
resolution: {integrity: sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.2.0
|
eslint: 8.2.0
|
||||||
dev: true
|
dev: true
|
||||||
@@ -2642,12 +2654,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
|
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
flatted: 3.2.2
|
flatted: 3.2.4
|
||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/flatted/3.2.2:
|
/flatted/3.2.4:
|
||||||
resolution: {integrity: sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==}
|
resolution: {integrity: sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/foreach/2.0.5:
|
/foreach/2.0.5:
|
||||||
@@ -2664,7 +2676,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
asynckit: 0.4.0
|
asynckit: 0.4.0
|
||||||
combined-stream: 1.0.8
|
combined-stream: 1.0.8
|
||||||
mime-types: 2.1.33
|
mime-types: 2.1.34
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/formdata-polyfill/4.0.10:
|
/formdata-polyfill/4.0.10:
|
||||||
@@ -2904,7 +2916,7 @@ packages:
|
|||||||
/history/5.1.0:
|
/history/5.1.0:
|
||||||
resolution: {integrity: sha512-zPuQgPacm2vH2xdORvGGz1wQMuHSIB56yNAy5FnLuwOwgSYyPKptJtcMm6Ev+hRGeS+GzhbmRacHzvlESbFwDg==}
|
resolution: {integrity: sha512-zPuQgPacm2vH2xdORvGGz1wQMuHSIB56yNAy5FnLuwOwgSYyPKptJtcMm6Ev+hRGeS+GzhbmRacHzvlESbFwDg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.16.0
|
'@babel/runtime': 7.16.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/hoist-non-react-statics/3.3.2:
|
/hoist-non-react-statics/3.3.2:
|
||||||
@@ -2995,13 +3007,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.16.0
|
'@babel/runtime': 7.16.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/i18next/21.4.1:
|
/i18next/21.4.2:
|
||||||
resolution: {integrity: sha512-uTCDfoMKTX6b/Amss7w/hQU8NV80ahmoKKNYUg0qbLbtUAMvYIWS2VvCCeNEGQIaEjyC4GV4W+iQbBcv3A/ViA==}
|
resolution: {integrity: sha512-vVWsmTnZNdYHPLt01MvT5YNM2lxec2R6r5T72J89eaazp8XQnGSqA66O+a918qqmjHZGB6HHRSs02xp753he9g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.16.0
|
'@babel/runtime': 7.16.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/iconv-lite/0.6.3:
|
/iconv-lite/0.6.3:
|
||||||
@@ -3603,16 +3615,16 @@ packages:
|
|||||||
picomatch: 2.3.0
|
picomatch: 2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/mime-db/1.50.0:
|
/mime-db/1.51.0:
|
||||||
resolution: {integrity: sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==}
|
resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/mime-types/2.1.33:
|
/mime-types/2.1.34:
|
||||||
resolution: {integrity: sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==}
|
resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-db: 1.50.0
|
mime-db: 1.51.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/mimic-fn/2.1.0:
|
/mimic-fn/2.1.0:
|
||||||
@@ -4468,15 +4480,15 @@ packages:
|
|||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/react-i18next/11.13.0_i18next@21.4.1+react@17.0.2:
|
/react-i18next/11.14.0_i18next@21.4.2+react@17.0.2:
|
||||||
resolution: {integrity: sha512-AY8ydSqx8LVm1Tn5yXFA0JwCeSWpcFOSr96HrjUXXVAWWbptamZOY2iMxVaGNlGxSLnRY0U2sdCIPVYHcmhBxQ==}
|
resolution: {integrity: sha512-2xuQgd+Arzl3uZKkcKVk1V3rdiyXJrDkVAMxVtX2i3o+sDc+g+YjWoHh7Hw336wd+UGTI+F30ZCkb3X2VCixEQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
i18next: '>= 19.0.0'
|
i18next: '>= 19.0.0'
|
||||||
react: '>= 16.8.0'
|
react: '>= 16.8.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.16.0
|
'@babel/runtime': 7.16.3
|
||||||
html-parse-stringify: 3.0.1
|
html-parse-stringify: 3.0.1
|
||||||
i18next: 21.4.1
|
i18next: 21.4.2
|
||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@@ -4495,6 +4507,17 @@ packages:
|
|||||||
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-json-pretty/2.2.0_react-dom@17.0.2+react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-3UMzlAXkJ4R8S4vmkRKtvJHTewG4/rn1Q18n0zqdu/ipZbUPLVZD+QwC7uVcD/IAY3s8iNVHlgR2dMzIUS0n1A==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=15.0'
|
||||||
|
react-dom: '>=15.0'
|
||||||
|
dependencies:
|
||||||
|
prop-types: 15.7.2
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-redux/7.2.6_react-dom@17.0.2+react@17.0.2:
|
/react-redux/7.2.6_react-dom@17.0.2+react@17.0.2:
|
||||||
resolution: {integrity: sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==}
|
resolution: {integrity: sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -4507,7 +4530,7 @@ packages:
|
|||||||
react-native:
|
react-native:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.16.0
|
'@babel/runtime': 7.16.3
|
||||||
'@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
|
||||||
@@ -4522,6 +4545,14 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/react-timeago/6.2.1_react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-b9EObWO8wy4qwfOzj+g/RQZRrPvtMv1Pz12FCdAWKWCXbDGt0rZLyiyTGEr0Lh1O8w5xa48CtRpl3LI+CtGCyw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.0.0 || ^17.0.0
|
||||||
|
dependencies:
|
||||||
|
react: 17.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react/17.0.2:
|
/react/17.0.2:
|
||||||
resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
|
resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -4581,7 +4612,7 @@ packages:
|
|||||||
/redux/4.1.2:
|
/redux/4.1.2:
|
||||||
resolution: {integrity: sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==}
|
resolution: {integrity: sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.16.0
|
'@babel/runtime': 7.16.3
|
||||||
|
|
||||||
/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==}
|
||||||
@@ -4616,7 +4647,7 @@ packages:
|
|||||||
is-typedarray: 1.0.0
|
is-typedarray: 1.0.0
|
||||||
isstream: 0.1.2
|
isstream: 0.1.2
|
||||||
json-stringify-safe: 5.0.1
|
json-stringify-safe: 5.0.1
|
||||||
mime-types: 2.1.33
|
mime-types: 2.1.34
|
||||||
oauth-sign: 0.9.0
|
oauth-sign: 0.9.0
|
||||||
performance-now: 2.1.0
|
performance-now: 2.1.0
|
||||||
qs: 6.5.2
|
qs: 6.5.2
|
||||||
@@ -4838,7 +4869,7 @@ packages:
|
|||||||
kleur: 4.1.4
|
kleur: 4.1.4
|
||||||
magic-string: 0.25.7
|
magic-string: 0.25.7
|
||||||
meriyah: 3.1.6
|
meriyah: 3.1.6
|
||||||
mime-types: 2.1.33
|
mime-types: 2.1.34
|
||||||
mkdirp: 1.0.4
|
mkdirp: 1.0.4
|
||||||
npm-run-path: 4.0.1
|
npm-run-path: 4.0.1
|
||||||
open: 8.4.0
|
open: 8.4.0
|
||||||
|
|||||||
+8
-10
@@ -13,12 +13,12 @@ import {
|
|||||||
addChannel,
|
addChannel,
|
||||||
addMessage,
|
addMessage,
|
||||||
addNode,
|
addNode,
|
||||||
|
addUser,
|
||||||
setDeviceStatus,
|
setDeviceStatus,
|
||||||
setLastMeshInterraction,
|
setLastMeshInterraction,
|
||||||
setMyNodeInfo,
|
setMyNodeInfo,
|
||||||
setPreferences,
|
setPreferences,
|
||||||
setReady,
|
setReady,
|
||||||
setUser,
|
|
||||||
} from '@core/slices/meshtasticSlice';
|
} from '@core/slices/meshtasticSlice';
|
||||||
import {
|
import {
|
||||||
IHTTPConnection,
|
IHTTPConnection,
|
||||||
@@ -82,17 +82,15 @@ const App = (): JSX.Element => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
connection.onUserPacket.subscribe((user) => {
|
connection.onUserPacket.subscribe((user) => {
|
||||||
dispatch(
|
console.log('got user packet');
|
||||||
setUser({
|
|
||||||
nodeNum: user.packet.from,
|
dispatch(addUser(user.data));
|
||||||
user: user.data,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
connection.onNodeInfoPacket.subscribe(
|
connection.onNodeInfoPacket.subscribe(
|
||||||
(nodeInfoPacket): void | { payload: Protobuf.NodeInfo; type: string } =>
|
(nodeInfoPacket): void | { payload: Protobuf.NodeInfo; type: string } => {
|
||||||
dispatch(addNode(nodeInfoPacket.data)),
|
dispatch(addNode(nodeInfoPacket.data));
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
connection.onAdminPacket.subscribe((adminPacket) => {
|
connection.onAdminPacket.subscribe((adminPacket) => {
|
||||||
@@ -145,7 +143,7 @@ const App = (): JSX.Element => {
|
|||||||
>
|
>
|
||||||
<div className="flex flex-col h-full bg-gray-200 dark:bg-primaryDark">
|
<div className="flex flex-col h-full bg-gray-200 dark:bg-primaryDark">
|
||||||
<div className="flex flex-shrink-0 overflow-hidden bg-primary dark:bg-primary">
|
<div className="flex flex-shrink-0 overflow-hidden bg-primary dark:bg-primary">
|
||||||
<div className="w-full overflow-hidden bg-white border-b md:mt-6 md:mx-6 md:pt-4 md:pb-3 md:rounded-t-3xl dark:border-gray-600 md:shadow-md dark:bg-primaryDark">
|
<div className="w-full overflow-hidden bg-white border-b border-gray-300 md:mt-6 md:mx-6 md:pt-4 md:pb-3 md:rounded-t-3xl dark:border-gray-600 md:shadow-md dark:bg-primaryDark">
|
||||||
<div className="flex items-center justify-between h-16 px-4 md:px-6">
|
<div className="flex items-center justify-between h-16 px-4 md:px-6">
|
||||||
<div className="hidden md:flex">
|
<div className="hidden md:flex">
|
||||||
<Logo />
|
<Logo />
|
||||||
|
|||||||
@@ -39,12 +39,19 @@ export const Channel = ({ channel }: ChannelProps): JSX.Element => {
|
|||||||
role: Protobuf.Channel_Role;
|
role: Protobuf.Channel_Role;
|
||||||
settings: {
|
settings: {
|
||||||
name: string;
|
name: string;
|
||||||
|
modemConfig: Protobuf.ChannelSettings_ModemConfig;
|
||||||
|
bandwidth?: number;
|
||||||
|
codingRate?: number;
|
||||||
|
spreadFactor?: number;
|
||||||
};
|
};
|
||||||
}>({
|
}>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
role: channel.role,
|
role: channel.role,
|
||||||
settings: {
|
settings: {
|
||||||
name: channel.settings?.name,
|
name: channel.settings?.name,
|
||||||
|
bandwidth: channel.settings?.bandwidth,
|
||||||
|
codingRate: channel.settings?.codingRate,
|
||||||
|
spreadFactor: channel.settings?.spreadFactor,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -77,6 +84,7 @@ export const Channel = ({ channel }: ChannelProps): JSX.Element => {
|
|||||||
<div className="my-auto space-x-2">
|
<div className="my-auto space-x-2">
|
||||||
<form>
|
<form>
|
||||||
<div className="flex space-x-2">
|
<div className="flex space-x-2">
|
||||||
|
{/* @todo: change to disable & make primary buttons */}
|
||||||
<Select
|
<Select
|
||||||
label="Channel Type"
|
label="Channel Type"
|
||||||
optionsEnum={Protobuf.Channel_Role}
|
optionsEnum={Protobuf.Channel_Role}
|
||||||
@@ -88,6 +96,23 @@ export const Channel = ({ channel }: ChannelProps): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Input label="Name" {...register('settings.name')} />
|
<Input label="Name" {...register('settings.name')} />
|
||||||
|
<Input
|
||||||
|
label="Bandwidth"
|
||||||
|
type="number"
|
||||||
|
{...register('settings.bandwidth')}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="Spread Factor"
|
||||||
|
type="number"
|
||||||
|
min={7}
|
||||||
|
max={12}
|
||||||
|
{...register('settings.spreadFactor')}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="Coding Rate"
|
||||||
|
type="number"
|
||||||
|
{...register('settings.codingRate')}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export const Button = ({
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
onClick={handleConfirm}
|
onClick={handleConfirm}
|
||||||
className={`items-center select-none flex dark:text-white active:scale-95 ${
|
className={`items-center select-none flex dark:text-white active:scale-95 transition duration-200 ease-in-out ${
|
||||||
active && !disabled ? 'bg-gray-100 dark:bg-gray-700' : ''
|
active && !disabled ? 'bg-gray-100 dark:bg-gray-700' : ''
|
||||||
} ${
|
} ${
|
||||||
circle ? 'rounded-full h-10 w-10' : 'rounded-md p-3 space-x-3 text-sm'
|
circle ? 'rounded-full h-10 w-10' : 'rounded-md p-3 space-x-3 text-sm'
|
||||||
@@ -48,7 +48,9 @@ export const Button = ({
|
|||||||
disabled
|
disabled
|
||||||
? 'cursor-not-allowed dark:bg-primaryDark bg-white'
|
? 'cursor-not-allowed dark:bg-primaryDark bg-white'
|
||||||
: 'cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 hover:shadow-md'
|
: 'cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 hover:shadow-md'
|
||||||
} ${border ? 'border dark:border-gray-600' : ''} ${className}`}
|
} ${
|
||||||
|
border ? 'border border-gray-400 dark:border-gray-200' : ''
|
||||||
|
} ${className}`}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{icon && (
|
{icon && (
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const Card = ({
|
|||||||
}: CardProps): JSX.Element => {
|
}: CardProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`flex flex-col flex-auto dark:text-white border shadow-md select-none dark:bg-primaryDark dark:border-transparent rounded-3xl ${className}`}
|
className={`flex flex-col flex-auto dark:text-white border-y md:border shadow-md select-none dark:bg-primaryDark border-gray-300 dark:border-transparent md:rounded-3xl ${className}`}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between mx-10 mt-10">
|
<div className="flex items-center justify-between mx-10 mt-10">
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export interface CoverProps {
|
||||||
|
content: JSX.Element;
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Cover = ({ content, enabled }: CoverProps): JSX.Element => {
|
||||||
|
return enabled ? <div className="m-4 ">{content}</div> : <></>;
|
||||||
|
};
|
||||||
@@ -26,7 +26,7 @@ export const Drawer = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<aside
|
<aside
|
||||||
className={`transform top-0 left-0 bg-white dark:bg-secondaryDark shadow-md max-w-xs w-full border-r dark:border-gray-600 h-full overflow-auto ease-in-out transition-all duration-300 z-30 ${
|
className={`transform top-0 left-0 bg-white dark:bg-secondaryDark shadow-md max-w-xs w-full border-r dark:border-gray-600 border-gray-300 h-full overflow-auto ease-in-out transition-all duration-300 z-30 ${
|
||||||
permenant ? '' : 'absolute'
|
permenant ? '' : 'absolute'
|
||||||
} ${open ? 'translate-x-0' : '-translate-x-full'} ${className}`}
|
} ${open ? 'translate-x-0' : '-translate-x-full'} ${className}`}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const IconButton = ({
|
|||||||
<div className="my-auto text-gray-500 dark:text-gray-400">
|
<div className="my-auto text-gray-500 dark:text-gray-400">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="p-2 rounded-md active:scale-95 hover:bg-gray-200 dark:hover:bg-gray-600"
|
className="p-2 transition duration-200 ease-in-out rounded-md active:scale-95 hover:bg-gray-200 dark:hover:bg-gray-600"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{icon}
|
{icon}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export interface StatCardProps {
|
||||||
|
title: string;
|
||||||
|
value: string | JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const StatCard = ({ title, value }: StatCardProps): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<div className="w-full border-gray-300 shadow-md border-y md:border h-28 md:rounded-3xl dark:bg-primaryDark dark:border-transparent ">
|
||||||
|
<div className="m-4">
|
||||||
|
<div className="text-lg font-light">{title}</div>
|
||||||
|
<div className="text-3xl font-bold">{value}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Tab } from '@headlessui/react';
|
|
||||||
|
|
||||||
type DefaultDivProps = JSX.IntrinsicElements['div'];
|
|
||||||
|
|
||||||
interface TabProps extends DefaultDivProps {
|
|
||||||
tabs: {
|
|
||||||
name: string;
|
|
||||||
body: JSX.Element;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Tabs = ({ tabs, className, ...props }: TabProps): JSX.Element => {
|
|
||||||
return (
|
|
||||||
<Tab.Group as="div" className={className}>
|
|
||||||
<Tab.List className="flex border-l border-r border-t shadow-md rounded-t-3xl dark:border-gray-600">
|
|
||||||
{tabs.map((tab) => (
|
|
||||||
<Tab
|
|
||||||
key={tab.name}
|
|
||||||
className={({ selected }): string =>
|
|
||||||
`w-full text-lg font-medium p-2 border-b-2 ${
|
|
||||||
selected
|
|
||||||
? 'dark:border-gray-200 border-gray-600'
|
|
||||||
: 'border-transparent dark:border-transparent'
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{tab.name}
|
|
||||||
</Tab>
|
|
||||||
))}
|
|
||||||
</Tab.List>
|
|
||||||
<Tab.Panels className="h-full">
|
|
||||||
{tabs.map((tab, index) => (
|
|
||||||
<Tab.Panel
|
|
||||||
key={index}
|
|
||||||
className={
|
|
||||||
'border dark:border-gray-600 rounded-b-3xl p-4 h-full shadow-md'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{tab.body}
|
|
||||||
</Tab.Panel>
|
|
||||||
))}
|
|
||||||
</Tab.Panels>
|
|
||||||
</Tab.Group>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -12,38 +12,37 @@ interface CheckboxProps extends DefaultInputProps {
|
|||||||
error?: boolean;
|
error?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Checkbox = ({
|
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
|
||||||
label,
|
function Input(
|
||||||
valid,
|
{ label, valid, validationMessage, id, error, ...props }: CheckboxProps,
|
||||||
validationMessage,
|
ref,
|
||||||
id,
|
) {
|
||||||
error,
|
return (
|
||||||
...props
|
<div className="flex flex-col w-full">
|
||||||
}: CheckboxProps): JSX.Element => {
|
<Label label={label} />
|
||||||
return (
|
<div className="ml-auto">
|
||||||
<div className="flex flex-col w-full">
|
<input
|
||||||
<Label label={label} />
|
ref={ref}
|
||||||
<div className="ml-auto">
|
type="checkbox"
|
||||||
<input
|
id={id}
|
||||||
type="checkbox"
|
className={`appearance-none w-8 h-8 border rounded-md focus:outline-none checked:bg-primary checked:border-transparent transition duration-200 ease-in-out border-gray-400 dark:border-gray-200 ${
|
||||||
id={id}
|
props.disabled
|
||||||
className={`appearance-none w-8 h-8 border rounded-md focus:outline-none checked:bg-primary checked:border-transparent ${
|
? 'bg-gray-200 text-gray-500 dark:bg-gray-800 dark:text-gray-400 border-gray-400'
|
||||||
props.disabled
|
: ''
|
||||||
? 'bg-gray-200 text-gray-500 dark:bg-gray-800 dark:text-gray-400 border-gray-400'
|
} ${
|
||||||
: ''
|
error
|
||||||
} ${
|
? 'border-red-500'
|
||||||
error
|
: props.disabled
|
||||||
? 'border-red-500'
|
? 'border-gray-200'
|
||||||
: props.disabled
|
: ' focus-within:border-primary hover:border-primary'
|
||||||
? 'border-gray-200'
|
}`}
|
||||||
: ' focus-within:border-primary hover:border-primary'
|
{...props}
|
||||||
}`}
|
/>
|
||||||
{...props}
|
</div>
|
||||||
/>
|
{!valid && (
|
||||||
|
<div className="text-sm text-gray-600">{validationMessage}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!valid && (
|
);
|
||||||
<div className="text-sm text-gray-600">{validationMessage}</div>
|
},
|
||||||
)}
|
);
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const InputWrapper = ({
|
|||||||
children,
|
children,
|
||||||
}: LabelProps): JSX.Element => (
|
}: LabelProps): JSX.Element => (
|
||||||
<div
|
<div
|
||||||
className={`flex w-full border-y border rounded-md ${
|
className={`flex w-full border-gray-400 dark:border-gray-200 border-y border rounded-md transition duration-200 ease-in-out ${
|
||||||
disabled
|
disabled
|
||||||
? 'bg-gray-200 text-gray-500 dark:bg-gray-800 dark:text-gray-400 border-gray-400'
|
? 'bg-gray-200 text-gray-500 dark:bg-gray-800 dark:text-gray-400 border-gray-400'
|
||||||
: ''
|
: ''
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ export interface LabelProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Label = ({ label, error }: LabelProps): JSX.Element => (
|
export const Label = ({ label, error }: LabelProps): JSX.Element => (
|
||||||
<label className="flex py-1 text-xs font-semibold text-gray-500">
|
<label className="flex py-1 text-xs font-semibold text-gray-500 dark:text-gray-400">
|
||||||
{label}
|
{label}
|
||||||
{error && <span className="ml-2 text-red-500">{error}</span>}
|
{error && <span className="ml-2 text-red-500">{error}</span>}
|
||||||
<div className="flex-grow h-0.5 my-auto ml-2 dark:bg-gray-600 bg-gray-500" />
|
<div className="flex-grow h-0.5 my-auto ml-2 dark:bg-gray-700 bg-gray-300 rounded-full" />
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export const PageLayout = ({
|
|||||||
setNavOpen(!navOpen);
|
setNavOpen(!navOpen);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tab.List className="flex flex-col border-b divide-y divide-gray-300 dark:divide-gray-600 dark:border-gray-600">
|
<Tab.List className="flex flex-col border-b border-gray-300 divide-y divide-gray-300 dark:divide-gray-600 dark:border-gray-600">
|
||||||
<div className="flex items-center justify-between m-8 mr-6 md:my-10">
|
<div className="flex items-center justify-between m-8 mr-6 md:my-10">
|
||||||
<div className="text-4xl font-extrabold leading-none tracking-tight">
|
<div className="text-4xl font-extrabold leading-none tracking-tight">
|
||||||
{title}
|
{title}
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ export const PrimaryTemplate = ({
|
|||||||
}: PrimaryTemplateProps): JSX.Element => {
|
}: PrimaryTemplateProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col flex-auto h-full min-w-0">
|
<div className="flex flex-col flex-auto h-full min-w-0">
|
||||||
<div className="flex p-4 bg-white border-b md:flex-row flex-0 md:items-center md:justify-between md:px-10 dark:border-gray-600 dark:bg-secondaryDark">
|
<div className="flex p-4 bg-white border-b border-gray-300 md:flex-row flex-0 md:items-center md:justify-between md:px-10 dark:border-gray-600 dark:bg-secondaryDark">
|
||||||
{button && <div className="pr-2 m-auto md:hidden">{button}</div>}
|
{button && <div className="pr-2 m-auto md:hidden">{button}</div>}
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<a className="whitespace-nowrap font-medium text-primary">
|
<a className="font-medium whitespace-nowrap text-primary">
|
||||||
{tagline}
|
{tagline}
|
||||||
</a>
|
</a>
|
||||||
<h2 className="text-3xl font-extrabold leading-7 tracking-tight truncate md:text-4xl md:leading-10 dark:text-white">
|
<h2 className="text-3xl font-extrabold leading-7 tracking-tight truncate md:text-4xl md:leading-10 dark:text-white">
|
||||||
@@ -28,11 +28,11 @@ export const PrimaryTemplate = ({
|
|||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-auto flex-grow p-6 overflow-y-auto bg-white md:p-10 dark:bg-secondaryDark">
|
<div className="flex-auto flex-grow py-6 overflow-y-auto bg-white md:p-10 dark:bg-secondaryDark">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
{footer && (
|
{footer && (
|
||||||
<div className="flex p-4 bg-white border-t md:flex-row flex-0 md:items-center md:justify-between md:px-10 dark:border-gray-600 dark:bg-secondaryDark">
|
<div className="flex p-4 bg-white border-t border-gray-300 md:flex-row flex-0 md:items-center md:justify-between md:px-10 dark:border-gray-600 dark:bg-secondaryDark">
|
||||||
{button && <div className="pr-2 m-auto md:hidden">{button}</div>}
|
{button && <div className="pr-2 m-auto md:hidden">{button}</div>}
|
||||||
<div className="flex-1 min-w-0">{footer}</div>
|
<div className="flex-1 min-w-0">{footer}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ interface MeshtasticState {
|
|||||||
lastMeshInterraction: number;
|
lastMeshInterraction: number;
|
||||||
ready: boolean;
|
ready: boolean;
|
||||||
myNodeInfo: Protobuf.MyNodeInfo;
|
myNodeInfo: Protobuf.MyNodeInfo;
|
||||||
user: Protobuf.User;
|
myNode: Protobuf.NodeInfo;
|
||||||
|
users: Protobuf.User[];
|
||||||
|
myUser: Protobuf.User;
|
||||||
positionPackets: Types.PositionPacket[];
|
positionPackets: Types.PositionPacket[];
|
||||||
nodes: Protobuf.NodeInfo[];
|
nodes: Protobuf.NodeInfo[];
|
||||||
channels: Protobuf.Channel[];
|
channels: Protobuf.Channel[];
|
||||||
@@ -37,7 +39,9 @@ const initialState: MeshtasticState = {
|
|||||||
lastMeshInterraction: 0,
|
lastMeshInterraction: 0,
|
||||||
ready: false,
|
ready: false,
|
||||||
myNodeInfo: Protobuf.MyNodeInfo.create(),
|
myNodeInfo: Protobuf.MyNodeInfo.create(),
|
||||||
user: Protobuf.User.create(),
|
myNode: Protobuf.NodeInfo.create(),
|
||||||
|
users: [],
|
||||||
|
myUser: Protobuf.User.create(),
|
||||||
positionPackets: [],
|
positionPackets: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
channels: [],
|
channels: [],
|
||||||
@@ -65,26 +69,27 @@ 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: (
|
addUser: (state, action: PayloadAction<Protobuf.User>) => {
|
||||||
state,
|
if (action.payload.id === state.myNode.user?.id) {
|
||||||
action: PayloadAction<{
|
state.myUser = action.payload;
|
||||||
nodeNum: number;
|
}
|
||||||
user: Protobuf.User;
|
if (
|
||||||
}>,
|
state.users.findIndex((user) => user.id === action.payload.id) !== -1
|
||||||
) => {
|
) {
|
||||||
if (action.payload.nodeNum === state.myNodeInfo.myNodeNum) {
|
state.users = state.users.map((user) => {
|
||||||
state.user = action.payload.user;
|
return user.id === action.payload.id ? action.payload : user;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
const num = state.nodes.findIndex(
|
state.users.push(action.payload);
|
||||||
(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);
|
||||||
},
|
},
|
||||||
addNode: (state, action: PayloadAction<Protobuf.NodeInfo>) => {
|
addNode: (state, action: PayloadAction<Protobuf.NodeInfo>) => {
|
||||||
|
if (action.payload.num === state.myNodeInfo.myNodeNum) {
|
||||||
|
state.myNode = action.payload;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
state.nodes.findIndex((node) => node.num === action.payload.num) !== -1
|
state.nodes.findIndex((node) => node.num === action.payload.num) !== -1
|
||||||
) {
|
) {
|
||||||
@@ -155,7 +160,7 @@ export const {
|
|||||||
setLastMeshInterraction,
|
setLastMeshInterraction,
|
||||||
setReady,
|
setReady,
|
||||||
setMyNodeInfo,
|
setMyNodeInfo,
|
||||||
setUser,
|
addUser,
|
||||||
addPositionPacket,
|
addPositionPacket,
|
||||||
addNode,
|
addNode,
|
||||||
addChannel,
|
addChannel,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export const Messages = (): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col flex-grow p-6 space-y-2 overflow-y-auto bg-white border-b md:py-8 md:px-10 dark:border-gray-600 dark:bg-secondaryDark">
|
<div className="flex flex-col flex-grow p-6 space-y-2 overflow-y-auto bg-white border-b border-gray-300 md:py-8 md:px-10 dark:border-gray-600 dark:bg-secondaryDark">
|
||||||
{messages.map((message, index) => (
|
{messages.map((message, index) => (
|
||||||
<Message
|
<Message
|
||||||
key={index}
|
key={index}
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
|
import 'react-json-pretty/themes/acai.css';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { FiMenu, FiTerminal } from 'react-icons/fi';
|
import { FiMenu, FiTerminal } from 'react-icons/fi';
|
||||||
|
import JSONPretty from 'react-json-pretty';
|
||||||
|
import TimeAgo from 'react-timeago';
|
||||||
|
|
||||||
import { Card } from '@app/components/generic/Card';
|
import { Card } from '@app/components/generic/Card';
|
||||||
import { Chart } from '@app/components/generic/Chart';
|
import { Chart } from '@app/components/generic/Chart';
|
||||||
import { Checkbox } from '@app/components/generic/form/Checkbox';
|
import { Checkbox } from '@app/components/generic/form/Checkbox';
|
||||||
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.jsx';
|
||||||
|
import { StatCard } from '@app/components/generic/StatCard';
|
||||||
import { PrimaryTemplate } from '@components/templates/PrimaryTemplate';
|
import { PrimaryTemplate } from '@components/templates/PrimaryTemplate';
|
||||||
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
import type { Protobuf } from '@meshtastic/meshtasticjs';
|
||||||
|
|
||||||
@@ -32,6 +37,13 @@ export const Node = ({ navOpen, setNavOpen, node }: NodeProps): JSX.Element => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="w-full space-y-4">
|
<div className="w-full space-y-4">
|
||||||
|
<div className="justify-between space-y-2 md:space-y-0 md:space-x-2 md:flex">
|
||||||
|
<StatCard
|
||||||
|
title="Last heard"
|
||||||
|
value={<TimeAgo date={new Date(node.lastHeard * 1000)} />}
|
||||||
|
/>
|
||||||
|
<StatCard title="SNR" value={node.snr.toString()} />
|
||||||
|
</div>
|
||||||
<Chart
|
<Chart
|
||||||
title={`${node.user?.longName ?? 'UNK'}`}
|
title={`${node.user?.longName ?? 'UNK'}`}
|
||||||
description="Airtime"
|
description="Airtime"
|
||||||
@@ -145,12 +157,12 @@ export const Node = ({ navOpen, setNavOpen, node }: NodeProps): JSX.Element => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<Card title="Position" description={node.num.toString()}>
|
<Card
|
||||||
|
title="Position"
|
||||||
|
description={new Date(node.lastHeard * 1000).toLocaleString()}
|
||||||
|
>
|
||||||
<div className="p-10">
|
<div className="p-10">
|
||||||
<div>
|
<JSONPretty data={node.position} />
|
||||||
<div></div>
|
|
||||||
<div>{node.position?.satsInView}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<Card
|
<Card
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FiMenu, FiSave } from 'react-icons/fi';
|
import { FiCode, FiMenu, FiSave } from 'react-icons/fi';
|
||||||
|
import JSONPretty from 'react-json-pretty';
|
||||||
|
|
||||||
import { Channel } from '@app/components/Channel.jsx';
|
import { Channel } from '@app/components/Channel.jsx';
|
||||||
import { Card } from '@app/components/generic/Card';
|
import { Card } from '@app/components/generic/Card';
|
||||||
|
import { Cover } from '@app/components/generic/Cover.jsx';
|
||||||
import { IconButton } from '@app/components/generic/IconButton.jsx';
|
import { IconButton } from '@app/components/generic/IconButton.jsx';
|
||||||
import { connection } from '@app/core/connection.js';
|
import { connection } from '@app/core/connection.js';
|
||||||
import { useAppSelector } from '@app/hooks/redux.js';
|
import { useAppSelector } from '@app/hooks/redux.js';
|
||||||
@@ -22,6 +24,7 @@ export const Channels = ({
|
|||||||
}: ChannelsProps): JSX.Element => {
|
}: ChannelsProps): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const channels = useAppSelector((state) => state.meshtastic.channels);
|
const channels = useAppSelector((state) => state.meshtastic.channels);
|
||||||
|
const [debug, setDebug] = React.useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PrimaryTemplate
|
<PrimaryTemplate
|
||||||
@@ -49,20 +52,22 @@ export const Channels = ({
|
|||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Card
|
<Card
|
||||||
title="Manage Channels"
|
title="Manage Channels"
|
||||||
description={
|
description="Edit channel throughput and other settings"
|
||||||
<div className="flex space-x-2 truncate">
|
buttons={
|
||||||
<div className="w-3 h-3 my-auto bg-green-500 rounded-full" />
|
<Button
|
||||||
- Primary
|
border
|
||||||
<div className="w-3 h-3 my-auto rounded-full bg-cyan-500" />
|
active={debug}
|
||||||
- Secondary
|
onClick={(): void => {
|
||||||
<div className="w-3 h-3 my-auto bg-gray-400 rounded-full" />
|
setDebug(!debug);
|
||||||
- Disabled
|
}}
|
||||||
<div className="w-3 h-3 my-auto rounded-full bg-amber-400" />
|
icon={<FiCode />}
|
||||||
- Admin
|
>
|
||||||
</div>
|
Debug
|
||||||
|
</Button>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="w-full max-w-3xl p-4 space-y-2 md:p-10 md:max-w-xl">
|
<Cover enabled={debug} content={<JSONPretty data={channels} />} />
|
||||||
|
<div className="w-full p-4 space-y-2 md:p-10">
|
||||||
{channels.map((channel) => (
|
{channels.map((channel) => (
|
||||||
<Channel key={channel.index} channel={channel} />
|
<Channel key={channel.index} channel={channel} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -2,13 +2,17 @@ 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 { FiMenu, FiSave } from 'react-icons/fi';
|
import { FiCode, FiMenu, FiSave } from 'react-icons/fi';
|
||||||
|
import JSONPretty from 'react-json-pretty';
|
||||||
|
|
||||||
import { Card } from '@app/components/generic/Card';
|
import { Card } from '@app/components/generic/Card';
|
||||||
|
import { Cover } from '@app/components/generic/Cover.jsx';
|
||||||
import { Checkbox } from '@app/components/generic/form/Checkbox';
|
import { Checkbox } from '@app/components/generic/form/Checkbox';
|
||||||
|
import { Select } from '@app/components/generic/form/Select.jsx';
|
||||||
import { IconButton } from '@app/components/generic/IconButton.jsx';
|
import { IconButton } from '@app/components/generic/IconButton.jsx';
|
||||||
import { connection } from '@app/core/connection';
|
import { connection } from '@app/core/connection';
|
||||||
import { useAppSelector } from '@app/hooks/redux';
|
import { addUser } from '@app/core/slices/meshtasticSlice.js';
|
||||||
|
import { useAppDispatch, useAppSelector } from '@app/hooks/redux';
|
||||||
import { Button } from '@components/generic/Button';
|
import { Button } from '@components/generic/Button';
|
||||||
import { Input } from '@components/generic/form/Input';
|
import { Input } from '@components/generic/form/Input';
|
||||||
import { PrimaryTemplate } from '@components/templates/PrimaryTemplate';
|
import { PrimaryTemplate } from '@components/templates/PrimaryTemplate';
|
||||||
@@ -21,21 +25,27 @@ export interface DeviceProps {
|
|||||||
|
|
||||||
export const Device = ({ navOpen, setNavOpen }: DeviceProps): JSX.Element => {
|
export const Device = ({ navOpen, setNavOpen }: DeviceProps): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const user = useAppSelector((state) => state.meshtastic.user);
|
const [debug, setDebug] = React.useState(false);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const user = useAppSelector((state) => state.meshtastic.myUser);
|
||||||
const { register, handleSubmit, formState } = useForm<{
|
const { register, handleSubmit, formState } = useForm<{
|
||||||
longName: string;
|
longName: string;
|
||||||
shortName: string;
|
shortName: string;
|
||||||
isLicensed: boolean;
|
isLicensed: boolean;
|
||||||
|
team: Protobuf.Team;
|
||||||
}>({
|
}>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
longName: user.longName,
|
longName: user.longName,
|
||||||
shortName: user.shortName,
|
shortName: user.shortName,
|
||||||
isLicensed: user.isLicensed,
|
isLicensed: user.isLicensed,
|
||||||
|
team: user.team,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = handleSubmit((data) => {
|
const onSubmit = handleSubmit((data) => {
|
||||||
void connection.setOwner({ ...user, ...data });
|
void connection.setOwner({ ...user, ...data });
|
||||||
|
// TODO: can be remove once getUser is implemented
|
||||||
|
dispatch(addUser({ ...user, ...data }));
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -66,7 +76,20 @@ export const Device = ({ navOpen, setNavOpen }: DeviceProps): JSX.Element => {
|
|||||||
<Card
|
<Card
|
||||||
title="Basic settings"
|
title="Basic settings"
|
||||||
description="Device name and user parameters"
|
description="Device name and user parameters"
|
||||||
|
buttons={
|
||||||
|
<Button
|
||||||
|
border
|
||||||
|
active={debug}
|
||||||
|
onClick={(): void => {
|
||||||
|
setDebug(!debug);
|
||||||
|
}}
|
||||||
|
icon={<FiCode />}
|
||||||
|
>
|
||||||
|
Debug
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
|
<Cover enabled={debug} content={<JSONPretty data={user} />} />
|
||||||
<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">
|
||||||
<form className="space-y-2" onSubmit={onSubmit}>
|
<form className="space-y-2" onSubmit={onSubmit}>
|
||||||
<Input label={'Device ID'} value={user.id} disabled />
|
<Input label={'Device ID'} value={user.id} disabled />
|
||||||
@@ -82,6 +105,11 @@ export const Device = ({ navOpen, setNavOpen }: DeviceProps): JSX.Element => {
|
|||||||
{...register('shortName')}
|
{...register('shortName')}
|
||||||
/>
|
/>
|
||||||
<Checkbox label="Licenced Operator?" {...register('isLicensed')} />
|
<Checkbox label="Licenced Operator?" {...register('isLicensed')} />
|
||||||
|
<Select
|
||||||
|
label="Team"
|
||||||
|
optionsEnum={Protobuf.Team}
|
||||||
|
{...register('team')}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ 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 { FiMenu, FiSave, FiXCircle } from 'react-icons/fi';
|
import { FiCode, FiMenu, FiSave, FiXCircle } from 'react-icons/fi';
|
||||||
|
import JSONPretty from 'react-json-pretty';
|
||||||
|
|
||||||
import { Card } from '@app/components/generic/Card';
|
import { Card } from '@app/components/generic/Card';
|
||||||
|
import { Cover } from '@app/components/generic/Cover.jsx';
|
||||||
import { Checkbox } from '@app/components/generic/form/Checkbox';
|
import { Checkbox } from '@app/components/generic/form/Checkbox';
|
||||||
import { Select } from '@app/components/generic/form/Select.jsx';
|
import { Select } from '@app/components/generic/form/Select.jsx';
|
||||||
import { IconButton } from '@app/components/generic/IconButton.jsx';
|
import { IconButton } from '@app/components/generic/IconButton.jsx';
|
||||||
@@ -23,6 +25,7 @@ export interface RadioProps {
|
|||||||
export const Radio = ({ navOpen, setNavOpen }: RadioProps): JSX.Element => {
|
export const Radio = ({ navOpen, setNavOpen }: RadioProps): JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const radioConfig = useAppSelector((state) => state.meshtastic.preferences);
|
const radioConfig = useAppSelector((state) => state.meshtastic.preferences);
|
||||||
|
const [debug, setDebug] = React.useState(false);
|
||||||
|
|
||||||
const { register, handleSubmit, formState, reset } =
|
const { register, handleSubmit, formState, reset } =
|
||||||
useForm<Protobuf.RadioConfig_UserPreferences>({
|
useForm<Protobuf.RadioConfig_UserPreferences>({
|
||||||
@@ -69,7 +72,20 @@ export const Radio = ({ navOpen, setNavOpen }: RadioProps): JSX.Element => {
|
|||||||
<Card
|
<Card
|
||||||
title="Basic settings"
|
title="Basic settings"
|
||||||
description="Device name and user parameters"
|
description="Device name and user parameters"
|
||||||
|
buttons={
|
||||||
|
<Button
|
||||||
|
border
|
||||||
|
active={debug}
|
||||||
|
onClick={(): void => {
|
||||||
|
setDebug(!debug);
|
||||||
|
}}
|
||||||
|
icon={<FiCode />}
|
||||||
|
>
|
||||||
|
Debug
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
|
<Cover enabled={debug} content={<JSONPretty data={radioConfig} />} />
|
||||||
<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">
|
||||||
<form className="space-y-2" onSubmit={onSubmit}>
|
<form className="space-y-2" onSubmit={onSubmit}>
|
||||||
<div>WiFi</div>
|
<div>WiFi</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user