Browse Source

Channel editor improvements & various fixes

pull/21/head
Sacha Weatherstone 5 years ago
parent
commit
ce95c070e0
  1. 20
      package.json
  2. 345
      pnpm-lock.yaml
  3. 263
      src/components/Channel.tsx
  4. 10
      src/components/Map/styles.ts
  5. 4
      src/core/connection.ts
  6. 82
      src/pages/settings/Channels.tsx
  7. 13
      types/static.d.ts

20
package.json

@ -12,14 +12,14 @@
"lint": "eslint 'src/**/*.{ts,tsx}'" "lint": "eslint 'src/**/*.{ts,tsx}'"
}, },
"dependencies": { "dependencies": {
"@floating-ui/react-dom": "^0.4.1", "@floating-ui/react-dom": "^0.4.3",
"@headlessui/react": "^1.4.2", "@headlessui/react": "^1.4.2",
"@meshtastic/components": "^1.0.13", "@meshtastic/components": "^1.0.15",
"@meshtastic/meshtasticjs": "^0.6.36", "@meshtastic/meshtasticjs": "^0.6.36",
"@reduxjs/toolkit": "^1.7.1", "@reduxjs/toolkit": "^1.7.1",
"base64-js": "^1.5.1", "base64-js": "^1.5.1",
"boring-avatars": "^1.6.1", "boring-avatars": "^1.6.1",
"i18next": "^21.6.4", "i18next": "^21.6.5",
"i18next-browser-languagedetector": "^6.1.2", "i18next-browser-languagedetector": "^6.1.2",
"mapbox-gl": "^2.6.1", "mapbox-gl": "^2.6.1",
"react": "^17.0.2", "react": "^17.0.2",
@ -33,11 +33,11 @@
"react-qr-code": "^2.0.3", "react-qr-code": "^2.0.3",
"react-redux": "^7.2.6", "react-redux": "^7.2.6",
"react-select": "^5.2.1", "react-select": "^5.2.1",
"rfc4648": "^1.5.0", "rfc4648": "^1.5.1",
"swr": "^1.1.2", "swr": "^1.1.2",
"timeago-react": "^3.0.4", "timeago-react": "^3.0.4",
"type-route": "^0.6.0", "type-route": "^0.6.0",
"use-breakpoint": "^3.0.0" "use-breakpoint": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/mapbox-gl": "^2.6.0", "@types/mapbox-gl": "^2.6.0",
@ -46,11 +46,11 @@
"@types/react-file-icon": "^1.0.1", "@types/react-file-icon": "^1.0.1",
"@types/w3c-web-serial": "^1.0.2", "@types/w3c-web-serial": "^1.0.2",
"@types/web-bluetooth": "^0.0.12", "@types/web-bluetooth": "^0.0.12",
"@typescript-eslint/eslint-plugin": "^5.8.1", "@typescript-eslint/eslint-plugin": "^5.9.0",
"@typescript-eslint/parser": "^5.8.1", "@typescript-eslint/parser": "^5.9.0",
"@verypossible/eslint-config": "^1.6.1", "@verypossible/eslint-config": "^1.6.1",
"@vitejs/plugin-react": "^1.1.3", "@vitejs/plugin-react": "^1.1.4",
"autoprefixer": "^10.4.1", "autoprefixer": "^10.4.2",
"babel-plugin-module-resolver": "^4.1.0", "babel-plugin-module-resolver": "^4.1.0",
"eslint": "8.6.0", "eslint": "8.6.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
@ -63,7 +63,7 @@
"gzipper": "^6.2.1", "gzipper": "^6.2.1",
"postcss": "^8.4.5", "postcss": "^8.4.5",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"tailwindcss": "^3.0.8", "tailwindcss": "^3.0.12",
"tar": "^6.1.11", "tar": "^6.1.11",
"typescript": "^4.5.4", "typescript": "^4.5.4",
"vite": "^2.7.10", "vite": "^2.7.10",

345
pnpm-lock.yaml

@ -1,9 +1,9 @@
lockfileVersion: 5.3 lockfileVersion: 5.3
specifiers: specifiers:
'@floating-ui/react-dom': ^0.4.1 '@floating-ui/react-dom': ^0.4.3
'@headlessui/react': ^1.4.2 '@headlessui/react': ^1.4.2
'@meshtastic/components': ^1.0.13 '@meshtastic/components': ^1.0.15
'@meshtastic/meshtasticjs': ^0.6.36 '@meshtastic/meshtasticjs': ^0.6.36
'@reduxjs/toolkit': ^1.7.1 '@reduxjs/toolkit': ^1.7.1
'@types/mapbox-gl': ^2.6.0 '@types/mapbox-gl': ^2.6.0
@ -12,11 +12,11 @@ specifiers:
'@types/react-file-icon': ^1.0.1 '@types/react-file-icon': ^1.0.1
'@types/w3c-web-serial': ^1.0.2 '@types/w3c-web-serial': ^1.0.2
'@types/web-bluetooth': ^0.0.12 '@types/web-bluetooth': ^0.0.12
'@typescript-eslint/eslint-plugin': ^5.8.1 '@typescript-eslint/eslint-plugin': ^5.9.0
'@typescript-eslint/parser': ^5.8.1 '@typescript-eslint/parser': ^5.9.0
'@verypossible/eslint-config': ^1.6.1 '@verypossible/eslint-config': ^1.6.1
'@vitejs/plugin-react': ^1.1.3 '@vitejs/plugin-react': ^1.1.4
autoprefixer: ^10.4.1 autoprefixer: ^10.4.2
babel-plugin-module-resolver: ^4.1.0 babel-plugin-module-resolver: ^4.1.0
base64-js: ^1.5.1 base64-js: ^1.5.1
boring-avatars: ^1.6.1 boring-avatars: ^1.6.1
@ -29,7 +29,7 @@ specifiers:
eslint-plugin-react: ^7.28.0 eslint-plugin-react: ^7.28.0
eslint-plugin-react-hooks: ^4.3.0 eslint-plugin-react-hooks: ^4.3.0
gzipper: ^6.2.1 gzipper: ^6.2.1
i18next: ^21.6.4 i18next: ^21.6.5
i18next-browser-languagedetector: ^6.1.2 i18next-browser-languagedetector: ^6.1.2
mapbox-gl: ^2.6.1 mapbox-gl: ^2.6.1
postcss: ^8.4.5 postcss: ^8.4.5
@ -45,28 +45,28 @@ specifiers:
react-qr-code: ^2.0.3 react-qr-code: ^2.0.3
react-redux: ^7.2.6 react-redux: ^7.2.6
react-select: ^5.2.1 react-select: ^5.2.1
rfc4648: ^1.5.0 rfc4648: ^1.5.1
swr: ^1.1.2 swr: ^1.1.2
tailwindcss: ^3.0.8 tailwindcss: ^3.0.12
tar: ^6.1.11 tar: ^6.1.11
timeago-react: ^3.0.4 timeago-react: ^3.0.4
type-route: ^0.6.0 type-route: ^0.6.0
typescript: ^4.5.4 typescript: ^4.5.4
use-breakpoint: ^3.0.0 use-breakpoint: ^3.0.1
vite: ^2.7.10 vite: ^2.7.10
vite-plugin-cdn-import: ^0.3.5 vite-plugin-cdn-import: ^0.3.5
vite-plugin-pwa: ^0.11.12 vite-plugin-pwa: ^0.11.12
workbox-window: ^6.4.2 workbox-window: ^6.4.2
dependencies: dependencies:
'@floating-ui/react-dom': 0.4.1_b3482aaf5744fc7c2aeb7941b0e0a78f '@floating-ui/react-dom': 0.4.3_b3482aaf5744fc7c2aeb7941b0e0a78f
'@headlessui/react': 1.4[email protected][email protected] '@headlessui/react': 1.4[email protected][email protected]
'@meshtastic/components': 1.0.13 '@meshtastic/components': 1.0.15_@[email protected]
'@meshtastic/meshtasticjs': 0.6.36 '@meshtastic/meshtasticjs': 0.6.36
'@reduxjs/toolkit': 1.7[email protected][email protected] '@reduxjs/toolkit': 1.7[email protected][email protected]
base64-js: 1.5.1 base64-js: 1.5.1
boring-avatars: 1.6.1 boring-avatars: 1.6.1
i18next: 21.6.4 i18next: 21.6.5
i18next-browser-languagedetector: 6.1.2 i18next-browser-languagedetector: 6.1.2
mapbox-gl: 2.6.1 mapbox-gl: 2.6.1
react: 17.0.2 react: 17.0.2
@ -74,17 +74,17 @@ dependencies:
react-error-boundary: 3.1[email protected] react-error-boundary: 3.1[email protected]
react-file-icon: 1.1[email protected][email protected] react-file-icon: 1.1[email protected][email protected]
react-hook-form: 7.22[email protected] react-hook-form: 7.22[email protected]
react-i18next: 11.15.3_80acb397921aff391f276c2217c76c9e react-i18next: 11.15.3_56927fec8de40d941cee913e7ea81c11
react-icons: 4.3[email protected] react-icons: 4.3[email protected]
react-json-pretty: 2.2[email protected][email protected] react-json-pretty: 2.2[email protected][email protected]
react-qr-code: 2.0[email protected] react-qr-code: 2.0[email protected]
react-redux: 7.2[email protected][email protected] react-redux: 7.2[email protected][email protected]
react-select: 5.2.1_b3482aaf5744fc7c2aeb7941b0e0a78f react-select: 5.2.1_b3482aaf5744fc7c2aeb7941b0e0a78f
rfc4648: 1.5.0 rfc4648: 1.5.1
swr: 1.1[email protected] swr: 1.1[email protected]
timeago-react: 3.0[email protected] timeago-react: 3.0[email protected]
type-route: 0.6.0 type-route: 0.6.0
use-breakpoint: 3.0.0[email protected][email protected] use-breakpoint: 3.0.1[email protected][email protected]
devDependencies: devDependencies:
'@types/mapbox-gl': 2.6.0 '@types/mapbox-gl': 2.6.0
@ -93,11 +93,11 @@ devDependencies:
'@types/react-file-icon': 1.0.1 '@types/react-file-icon': 1.0.1
'@types/w3c-web-serial': 1.0.2 '@types/w3c-web-serial': 1.0.2
'@types/web-bluetooth': 0.0.12 '@types/web-bluetooth': 0.0.12
'@typescript-eslint/eslint-plugin': 5.8.1_13039593e64cd539d0b4c5c2da390958 '@typescript-eslint/eslint-plugin': 5.9.0_bd2fd93dbcc607ad2f21b784bccfe0c8
'@typescript-eslint/parser': 5.8.1[email protected][email protected] '@typescript-eslint/parser': 5.9.0[email protected][email protected]
'@verypossible/eslint-config': 1.6[email protected] '@verypossible/eslint-config': 1.6[email protected]
'@vitejs/plugin-react': 1.1.3 '@vitejs/plugin-react': 1.1.4
autoprefixer: 10.4.1[email protected] autoprefixer: 10.4.2[email protected]
babel-plugin-module-resolver: 4.1.0 babel-plugin-module-resolver: 4.1.0
eslint: 8.6.0 eslint: 8.6.0
eslint-config-prettier: 8.3[email protected] eslint-config-prettier: 8.3[email protected]
@ -110,7 +110,7 @@ devDependencies:
gzipper: 6.2.1 gzipper: 6.2.1
postcss: 8.4.5 postcss: 8.4.5
prettier: 2.5.1 prettier: 2.5.1
tailwindcss: 3.0.8_cefe482e8d38053bbf3d5815e0c551b3 tailwindcss: 3.0.12_ef48b3b8837f8a23677bffe8f9cd866d
tar: 6.1.11 tar: 6.1.11
typescript: 4.5.4 typescript: 4.5.4
vite: 2.7.10 vite: 2.7.10
@ -251,7 +251,7 @@ packages:
'@babel/traverse': 7.16.7 '@babel/traverse': 7.16.7
debug: 4.3.3 debug: 4.3.3
lodash.debounce: 4.0.8 lodash.debounce: 4.0.8
resolve: 1.20.0 resolve: 1.21.0
semver: 6.3.0 semver: 6.3.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -1427,8 +1427,8 @@ packages:
'@floating-ui/core': 0.3.1 '@floating-ui/core': 0.3.1
dev: false dev: false
/@floating-ui/react-dom/0.4.1_b3482aaf5744fc7c2aeb7941b0e0a78f: /@floating-ui/react-dom/0.4.3_b3482aaf5744fc7c2aeb7941b0e0a78f:
resolution: {integrity: sha512-0MLbzWipGVcVliNTWSBMcD12JeGvTwzjnxpp3hoM8KHhfy9yAKVuBJwuo3P9X1eC8dSwlplVp5JNplJKsZkkIg==} resolution: {integrity: sha512-ZL88ryd9p6sFh9jIC/+05JZoNsogcq6U09cygQjiy757QtQqxIVLQwFag+BAWWYqpNEMO0S60fkqmh8KIAV4oA==}
peerDependencies: peerDependencies:
react: '>=16.8.0' react: '>=16.8.0'
react-dom: '>=16.8.0' react-dom: '>=16.8.0'
@ -1522,13 +1522,17 @@ packages:
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
dev: false dev: false
/@meshtastic/components/1.0.13: /@meshtastic/components/1.0.15_@[email protected].38:
resolution: {integrity: sha512-UdRwPVywIMaOYl0httBK51WagSuPhNPAuPG6DbvEq/TBBuJiGrTS/gYWsMb1UJhKzwb9XPKFMqAujowyBGN9cw==} resolution: {integrity: sha512-+ZT2I6shgtDTKBm3qpillRvG89wDxDf4gpD/EDhvECAjSTIFYjo0m3kiDSytVjJw/sLnj3LJljQ3U4o75J3uqw==}
dependencies: dependencies:
inter-ui: 3.19.3 inter-ui: 3.19.3
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
react-icons: 4.3[email protected] react-icons: 4.3[email protected]
react-select: 5.2.1_b3482aaf5744fc7c2aeb7941b0e0a78f
transitivePeerDependencies:
- '@babel/core'
- '@types/react'
dev: false dev: false
/@meshtastic/meshtasticjs/0.6.36: /@meshtastic/meshtasticjs/0.6.36:
@ -1582,7 +1586,7 @@ packages:
reselect: 4.1.5 reselect: 4.1.5
dev: false dev: false
/@rollup/plugin-babel/5.3.0_@[email protected][email protected]2.0: /@rollup/plugin-babel/5.3.0_@[email protected][email protected]3.0:
resolution: {integrity: sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==} resolution: {integrity: sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
peerDependencies: peerDependencies:
@ -1595,36 +1599,36 @@ packages:
dependencies: dependencies:
'@babel/core': 7.16.7 '@babel/core': 7.16.7
'@babel/helper-module-imports': 7.16.7 '@babel/helper-module-imports': 7.16.7
'@rollup/pluginutils': 3.1[email protected]2.0 '@rollup/pluginutils': 3.1[email protected]3.0
rollup: 2.62.0 rollup: 2.63.0
dev: true dev: true
/@rollup/plugin-node-resolve/[email protected]2.0: /@rollup/plugin-node-resolve/[email protected]3.0:
resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
peerDependencies: peerDependencies:
rollup: ^1.20.0||^2.0.0 rollup: ^1.20.0||^2.0.0
dependencies: dependencies:
'@rollup/pluginutils': 3.1[email protected]2.0 '@rollup/pluginutils': 3.1[email protected]3.0
'@types/resolve': 1.17.1 '@types/resolve': 1.17.1
builtin-modules: 3.2.0 builtin-modules: 3.2.0
deepmerge: 4.2.2 deepmerge: 4.2.2
is-module: 1.0.0 is-module: 1.0.0
resolve: 1.20.0 resolve: 1.21.0
rollup: 2.62.0 rollup: 2.63.0
dev: true dev: true
/@rollup/plugin-replace/[email protected]2.0: /@rollup/plugin-replace/[email protected]3.0:
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
peerDependencies: peerDependencies:
rollup: ^1.20.0 || ^2.0.0 rollup: ^1.20.0 || ^2.0.0
dependencies: dependencies:
'@rollup/pluginutils': 3.1[email protected]2.0 '@rollup/pluginutils': 3.1[email protected]3.0
magic-string: 0.25.7 magic-string: 0.25.7
rollup: 2.62.0 rollup: 2.63.0
dev: true dev: true
/@rollup/pluginutils/[email protected]2.0: /@rollup/pluginutils/[email protected]3.0:
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
engines: {node: '>= 8.0.0'} engines: {node: '>= 8.0.0'}
peerDependencies: peerDependencies:
@ -1633,7 +1637,7 @@ packages:
'@types/estree': 0.0.39 '@types/estree': 0.0.39
estree-walker: 1.0.1 estree-walker: 1.0.1
picomatch: 2.3.1 picomatch: 2.3.1
rollup: 2.62.0 rollup: 2.63.0
dev: true dev: true
/@rollup/pluginutils/4.1.2: /@rollup/pluginutils/4.1.2:
@ -1686,8 +1690,8 @@ packages:
'@types/geojson': 7946.0.8 '@types/geojson': 7946.0.8
dev: true dev: true
/@types/node/17.0.7: /@types/node/17.0.8:
resolution: {integrity: sha512-1QUk+WAUD4t8iR+Oj+UgI8oJa6yyxaB8a8pHaC8uqM6RrS1qbL7bf3Pwl5rHv0psm2CuDErgho6v5N+G+5fwtQ==} resolution: {integrity: sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==}
dev: true dev: true
/@types/parse-json/4.0.0: /@types/parse-json/4.0.0:
@ -1734,7 +1738,7 @@ packages:
/@types/resolve/1.17.1: /@types/resolve/1.17.1:
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
dependencies: dependencies:
'@types/node': 17.0.7 '@types/node': 17.0.8
dev: true dev: true
/@types/scheduler/0.16.2: /@types/scheduler/0.16.2:
@ -1778,8 +1782,8 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/eslint-plugin/5.8.1_13039593e64cd539d0b4c5c2da390958: /@typescript-eslint/eslint-plugin/5.9.0_bd2fd93dbcc607ad2f21b784bccfe0c8:
resolution: {integrity: sha512-wTZ5oEKrKj/8/366qTM366zqhIKAp6NCMweoRONtfuC07OAU9nVI2GZZdqQ1qD30WAAtcPdkH+npDwtRFdp4Rw==} resolution: {integrity: sha512-qT4lr2jysDQBQOPsCCvpPUZHjbABoTJW8V9ZzIYKHMfppJtpdtzszDYsldwhFxlhvrp7aCHeXD1Lb9M1zhwWwQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
'@typescript-eslint/parser': ^5.0.0 '@typescript-eslint/parser': ^5.0.0
@ -1789,9 +1793,10 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/experimental-utils': 5.8[email protected][email protected] '@typescript-eslint/experimental-utils': 5.9[email protected][email protected]
'@typescript-eslint/parser': 5.8[email protected][email protected] '@typescript-eslint/parser': 5.9[email protected][email protected]
'@typescript-eslint/scope-manager': 5.8.1 '@typescript-eslint/scope-manager': 5.9.0
'@typescript-eslint/type-utils': 5.9[email protected][email protected]
debug: 4.3.3 debug: 4.3.3
eslint: 8.6.0 eslint: 8.6.0
functional-red-black-tree: 1.0.1 functional-red-black-tree: 1.0.1
@ -1822,16 +1827,16 @@ packages:
- typescript - typescript
dev: true dev: true
/@typescript-eslint/experimental-utils/5.8.1[email protected][email protected]: /@typescript-eslint/experimental-utils/5.9.0[email protected][email protected]:
resolution: {integrity: sha512-fbodVnjIDU4JpeXWRDsG5IfIjYBxEvs8EBO8W1+YVdtrc2B9ppfof5sZhVEDOtgTfFHnYQJDI8+qdqLYO4ceww==} resolution: {integrity: sha512-ZnLVjBrf26dn7ElyaSKa6uDhqwvAi4jBBmHK1VxuFGPRAxhdi18ubQYSGA7SRiFiES3q9JiBOBHEBStOFkwD2g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies: dependencies:
'@types/json-schema': 7.0.9 '@types/json-schema': 7.0.9
'@typescript-eslint/scope-manager': 5.8.1 '@typescript-eslint/scope-manager': 5.9.0
'@typescript-eslint/types': 5.8.1 '@typescript-eslint/types': 5.9.0
'@typescript-eslint/typescript-estree': 5.8.1[email protected] '@typescript-eslint/typescript-estree': 5.9.0[email protected]
eslint: 8.6.0 eslint: 8.6.0
eslint-scope: 5.1.1 eslint-scope: 5.1.1
eslint-utils: 3.0[email protected] eslint-utils: 3.0[email protected]
@ -1860,8 +1865,8 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/parser/5.8.1[email protected][email protected]: /@typescript-eslint/parser/5.9.0[email protected][email protected]:
resolution: {integrity: sha512-K1giKHAjHuyB421SoXMXFHHVI4NdNY603uKw92++D3qyxSeYvC10CBJ/GE5Thpo4WTUvu1mmJI2/FFkz38F2Gw==} resolution: {integrity: sha512-/6pOPz8yAxEt4PLzgbFRDpZmHnXCeZgPDrh/1DaVKOjvn/UPMlWhbx/gA96xRi2JxY1kBl2AmwVbyROUqys5xQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@ -1870,9 +1875,9 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/scope-manager': 5.8.1 '@typescript-eslint/scope-manager': 5.9.0
'@typescript-eslint/types': 5.8.1 '@typescript-eslint/types': 5.9.0
'@typescript-eslint/typescript-estree': 5.8.1[email protected] '@typescript-eslint/typescript-estree': 5.9.0[email protected]
debug: 4.3.3 debug: 4.3.3
eslint: 8.6.0 eslint: 8.6.0
typescript: 4.5.4 typescript: 4.5.4
@ -1888,12 +1893,31 @@ packages:
'@typescript-eslint/visitor-keys': 4.33.0 '@typescript-eslint/visitor-keys': 4.33.0
dev: true dev: true
/@typescript-eslint/scope-manager/5.8.1: /@typescript-eslint/scope-manager/5.9.0:
resolution: {integrity: sha512-DGxJkNyYruFH3NIZc3PwrzwOQAg7vvgsHsHCILOLvUpupgkwDZdNq/cXU3BjF4LNrCsVg0qxEyWasys5AiJ85Q==} resolution: {integrity: sha512-DKtdIL49Qxk2a8icF6whRk7uThuVz4A6TCXfjdJSwOsf+9ree7vgQWcx0KOyCdk0i9ETX666p4aMhrRhxhUkyg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies: dependencies:
'@typescript-eslint/types': 5.8.1 '@typescript-eslint/types': 5.9.0
'@typescript-eslint/visitor-keys': 5.8.1 '@typescript-eslint/visitor-keys': 5.9.0
dev: true
/@typescript-eslint/type-utils/[email protected][email protected]:
resolution: {integrity: sha512-uVCb9dJXpBrK1071ri5aEW7ZHdDHAiqEjYznF3HSSvAJXyrkxGOw2Ejibz/q6BXdT8lea8CMI0CzKNFTNI6TEQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '*'
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/experimental-utils': 5.9[email protected][email protected]
debug: 4.3.3
eslint: 8.6.0
tsutils: 3.21[email protected]
typescript: 4.5.4
transitivePeerDependencies:
- supports-color
dev: true dev: true
/@typescript-eslint/types/4.33.0: /@typescript-eslint/types/4.33.0:
@ -1901,8 +1925,8 @@ packages:
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
dev: true dev: true
/@typescript-eslint/types/5.8.1: /@typescript-eslint/types/5.9.0:
resolution: {integrity: sha512-L/FlWCCgnjKOLefdok90/pqInkomLnAcF9UAzNr+DSqMC3IffzumHTQTrINXhP1gVp9zlHiYYjvozVZDPleLcA==} resolution: {integrity: sha512-mWp6/b56Umo1rwyGCk8fPIzb9Migo8YOniBGPAQDNC6C52SeyNGN4gsVwQTAR+RS2L5xyajON4hOLwAGwPtUwg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true dev: true
@ -1918,7 +1942,7 @@ packages:
'@typescript-eslint/types': 4.33.0 '@typescript-eslint/types': 4.33.0
'@typescript-eslint/visitor-keys': 4.33.0 '@typescript-eslint/visitor-keys': 4.33.0
debug: 4.3.3 debug: 4.3.3
globby: 11.0.4 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
semver: 7.3.5 semver: 7.3.5
tsutils: 3.21[email protected] tsutils: 3.21[email protected]
@ -1927,8 +1951,8 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/typescript-estree/5.8.1[email protected]: /@typescript-eslint/typescript-estree/5.9.0[email protected]:
resolution: {integrity: sha512-26lQ8l8tTbG7ri7xEcCFT9ijU5Fk+sx/KRRyyzCv7MQ+rZZlqiDPtMKWLC8P7o+dtCnby4c+OlxuX1tp8WfafQ==} resolution: {integrity: sha512-kxo3xL2mB7XmiVZcECbaDwYCt3qFXz99tBSuVJR4L/sR7CJ+UNAPrYILILktGj1ppfZ/jNt/cWYbziJUlHl1Pw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
@ -1936,10 +1960,10 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/types': 5.8.1 '@typescript-eslint/types': 5.9.0
'@typescript-eslint/visitor-keys': 5.8.1 '@typescript-eslint/visitor-keys': 5.9.0
debug: 4.3.3 debug: 4.3.3
globby: 11.0.4 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
semver: 7.3.5 semver: 7.3.5
tsutils: 3.21[email protected] tsutils: 3.21[email protected]
@ -1956,11 +1980,11 @@ packages:
eslint-visitor-keys: 2.1.0 eslint-visitor-keys: 2.1.0
dev: true dev: true
/@typescript-eslint/visitor-keys/5.8.1: /@typescript-eslint/visitor-keys/5.9.0:
resolution: {integrity: sha512-SWgiWIwocK6NralrJarPZlWdr0hZnj5GXHIgfdm8hNkyKvpeQuFyLP6YjSIe9kf3YBIfU6OHSZLYkQ+smZwtNg==} resolution: {integrity: sha512-6zq0mb7LV0ThExKlecvpfepiB+XEtFv/bzx7/jKSgyXTFD7qjmSu1FoiS0x3OZaiS+UIXpH2vd9O89f02RCtgw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies: dependencies:
'@typescript-eslint/types': 5.8.1 '@typescript-eslint/types': 5.9.0
eslint-visitor-keys: 3.1.0 eslint-visitor-keys: 3.1.0
dev: true dev: true
@ -1984,8 +2008,8 @@ packages:
- typescript - typescript
dev: true dev: true
/@vitejs/plugin-react/1.1.3: /@vitejs/plugin-react/1.1.4:
resolution: {integrity: sha512-xv8QujX/uR4ti8qpt0hMriM2bdpxX4jm4iU6GAZfCwHjh/ewkX/8DJgnmQpE0HSJmgz8dixyUnRJKi2Pf1nNoQ==} resolution: {integrity: sha512-cMUBDonNY8PPeHWjIrYKbRn6bLSunh/Ixo2XLLBd3DM0uYBZft+c+04zkGhhN1lAwvoRKJ2FdtvhGhPgViHc6w==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
dependencies: dependencies:
'@babel/core': 7.16.7 '@babel/core': 7.16.7
@ -1995,7 +2019,7 @@ packages:
'@babel/plugin-transform-react-jsx-source': 7.16.7_@[email protected] '@babel/plugin-transform-react-jsx-source': 7.16.7_@[email protected]
'@rollup/pluginutils': 4.1.2 '@rollup/pluginutils': 4.1.2
react-refresh: 0.11.0 react-refresh: 0.11.0
resolve: 1.20.0 resolve: 1.21.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -2169,15 +2193,15 @@ packages:
engines: {node: '>= 4.0.0'} engines: {node: '>= 4.0.0'}
dev: true dev: true
/autoprefixer/10.4.1[email protected]: /autoprefixer/10.4.2[email protected]:
resolution: {integrity: sha512-B3ZEG7wtzXDRCEFsan7HmR2AeNsxdJB0+sEC0Hc5/c2NbhJqPwuZm+tn233GBVw82L+6CtD6IPSfVruwKjfV3A==} resolution: {integrity: sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==}
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.19.1 browserslist: 4.19.1
caniuse-lite: 1.0.30001295 caniuse-lite: 1.0.30001298
fraction.js: 4.1.2 fraction.js: 4.1.2
normalize-range: 0.1.2 normalize-range: 0.1.2
picocolors: 1.0.0 picocolors: 1.0.0
@ -2204,7 +2228,7 @@ packages:
glob: 7.2.0 glob: 7.2.0
pkg-up: 3.1.0 pkg-up: 3.1.0
reselect: 4.1.5 reselect: 4.1.5
resolve: 1.20.0 resolve: 1.21.0
dev: true dev: true
/babel-plugin-polyfill-corejs2/0.3.0_@[email protected]: /babel-plugin-polyfill-corejs2/0.3.0_@[email protected]:
@ -2286,8 +2310,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.30001295 caniuse-lite: 1.0.30001298
electron-to-chromium: 1.4.31 electron-to-chromium: 1.4.38
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
@ -2326,8 +2350,8 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true dev: true
/caniuse-lite/1.0.30001295: /caniuse-lite/1.0.30001298:
resolution: {integrity: sha512-lSP16vcyC0FEy0R4ECc9duSPoKoZy+YkpGkue9G4D81OfPnliopaZrU10+qtPdT8PbGXad/PNx43TIQrOmJZSQ==} resolution: {integrity: sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ==}
dev: true dev: true
/chalk/2.4.2: /chalk/2.4.2:
@ -2646,8 +2670,8 @@ packages:
jake: 10.8.2 jake: 10.8.2
dev: true dev: true
/electron-to-chromium/1.4.31: /electron-to-chromium/1.4.38:
resolution: {integrity: sha512-t3XVQtk+Frkv6aTD4RRk0OqosU+VLe1dQFW83MDer78ZD6a52frgXuYOIsLYTQiH2Lm+JB2OKYcn7zrX+YGAiQ==} resolution: {integrity: sha512-WhHt3sZazKj0KK/UpgsbGQnUUoFeAHVishzHFExMxagpZgjiGYSC9S0ZlbhCfSH2L2i+2A1yyqOIliTctMx7KQ==}
dev: true dev: true
/emoji-regex/8.0.0: /emoji-regex/8.0.0:
@ -2932,14 +2956,14 @@ packages:
dependencies: dependencies:
babel-plugin-module-resolver: 4.1.0 babel-plugin-module-resolver: 4.1.0
pkg-up: 3.1.0 pkg-up: 3.1.0
resolve: 1.20.0 resolve: 1.21.0
dev: true dev: true
/eslint-import-resolver-node/0.3.6: /eslint-import-resolver-node/0.3.6:
resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==}
dependencies: dependencies:
debug: 3.2.7 debug: 3.2.7
resolve: 1.20.0 resolve: 1.21.0
dev: true dev: true
/eslint-import-resolver-typescript/2.5.0_157002f9dff1b62f2b20650d7e8bf1eb: /eslint-import-resolver-typescript/2.5.0_157002f9dff1b62f2b20650d7e8bf1eb:
@ -2954,7 +2978,7 @@ packages:
eslint-plugin-import: 2.25[email protected] eslint-plugin-import: 2.25[email protected]
glob: 7.2.0 glob: 7.2.0
is-glob: 4.0.3 is-glob: 4.0.3
resolve: 1.20.0 resolve: 1.21.0
tsconfig-paths: 3.12.0 tsconfig-paths: 3.12.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -2972,7 +2996,7 @@ packages:
eslint-plugin-import: 2.25[email protected] eslint-plugin-import: 2.25[email protected]
glob: 7.2.0 glob: 7.2.0
is-glob: 4.0.3 is-glob: 4.0.3
resolve: 1.20.0 resolve: 1.21.0
tsconfig-paths: 3.12.0 tsconfig-paths: 3.12.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -3000,11 +3024,11 @@ packages:
eslint-import-resolver-node: 0.3.6 eslint-import-resolver-node: 0.3.6
eslint-module-utils: 2.7.2 eslint-module-utils: 2.7.2
has: 1.0.3 has: 1.0.3
is-core-module: 2.8.0 is-core-module: 2.8.1
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 3.0.4 minimatch: 3.0.4
object.values: 1.1.5 object.values: 1.1.5
resolve: 1.20.0 resolve: 1.21.0
tsconfig-paths: 3.12.0 tsconfig-paths: 3.12.0
dev: true dev: true
@ -3022,11 +3046,11 @@ packages:
eslint-import-resolver-node: 0.3.6 eslint-import-resolver-node: 0.3.6
eslint-module-utils: 2.7.2 eslint-module-utils: 2.7.2
has: 1.0.3 has: 1.0.3
is-core-module: 2.8.0 is-core-module: 2.8.1
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 3.0.4 minimatch: 3.0.4
object.values: 1.1.5 object.values: 1.1.5
resolve: 1.20.0 resolve: 1.21.0
tsconfig-paths: 3.12.0 tsconfig-paths: 3.12.0
dev: true dev: true
@ -3065,7 +3089,7 @@ packages:
object.fromentries: 2.0.5 object.fromentries: 2.0.5
object.hasown: 1.1.0 object.hasown: 1.1.0
object.values: 1.1.5 object.values: 1.1.5
prop-types: 15.8.0 prop-types: 15.8.1
resolve: 2.0.0-next.3 resolve: 2.0.0-next.3
semver: 6.3.0 semver: 6.3.0
string.prototype.matchall: 4.0.6 string.prototype.matchall: 4.0.6
@ -3088,7 +3112,7 @@ packages:
object.fromentries: 2.0.5 object.fromentries: 2.0.5
object.hasown: 1.1.0 object.hasown: 1.1.0
object.values: 1.1.5 object.values: 1.1.5
prop-types: 15.8.0 prop-types: 15.8.1
resolve: 2.0.0-next.3 resolve: 2.0.0-next.3
semver: 6.3.0 semver: 6.3.0
string.prototype.matchall: 4.0.6 string.prototype.matchall: 4.0.6
@ -3194,7 +3218,7 @@ packages:
semver: 7.3.5 semver: 7.3.5
strip-ansi: 6.0.1 strip-ansi: 6.0.1
strip-json-comments: 3.1.1 strip-json-comments: 3.1.1
table: 6.7.5 table: 6.8.0
text-table: 0.2.0 text-table: 0.2.0
v8-compile-cache: 2.3.0 v8-compile-cache: 2.3.0
transitivePeerDependencies: transitivePeerDependencies:
@ -3318,9 +3342,9 @@ packages:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true dev: true
/fast-glob/3.2.7: /fast-glob/3.2.10:
resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} resolution: {integrity: sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A==}
engines: {node: '>=8'} engines: {node: '>=8.6.0'}
dependencies: dependencies:
'@nodelib/fs.stat': 2.0.5 '@nodelib/fs.stat': 2.0.5
'@nodelib/fs.walk': 1.2.8 '@nodelib/fs.walk': 1.2.8
@ -3414,7 +3438,7 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dependencies: dependencies:
at-least-node: 1.0.0 at-least-node: 1.0.0
graceful-fs: 4.2.8 graceful-fs: 4.2.9
jsonfile: 6.1.0 jsonfile: 6.1.0
universalify: 2.0.0 universalify: 2.0.0
dev: true dev: true
@ -3538,20 +3562,20 @@ packages:
type-fest: 0.20.2 type-fest: 0.20.2
dev: true dev: true
/globby/11.0.4: /globby/11.1.0:
resolution: {integrity: sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==} resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'} engines: {node: '>=10'}
dependencies: dependencies:
array-union: 2.1.0 array-union: 2.1.0
dir-glob: 3.0.1 dir-glob: 3.0.1
fast-glob: 3.2.7 fast-glob: 3.2.10
ignore: 5.2.0 ignore: 5.2.0
merge2: 1.4.1 merge2: 1.4.1
slash: 3.0.0 slash: 3.0.0
dev: true dev: true
/graceful-fs/4.2.8: /graceful-fs/4.2.9:
resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==} resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==}
dev: true dev: true
/grid-index/1.1.0: /grid-index/1.1.0:
@ -3635,8 +3659,8 @@ packages:
'@babel/runtime': 7.16.7 '@babel/runtime': 7.16.7
dev: false dev: false
/i18next/21.6.4: /i18next/21.6.5:
resolution: {integrity: sha512-pk0Utxtq5g//Q9ONQ0w3+PRSwOFJ7+m4rAekhHHg1Xql0KcUjJU7DzmzweGy6DsrIQ1GM/t57wLeeGuyGKtjTg==} resolution: {integrity: sha512-1oimhzFEpkmxpY2yDyghdycyA1bCKrh9zf04qiB2HytKJCqlrA5e8JfL6KyK/oZvZABLP0GohsZ+tvhHmd+OTA==}
dependencies: dependencies:
'@babel/runtime': 7.16.7 '@babel/runtime': 7.16.7
dev: false dev: false
@ -3741,8 +3765,8 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dev: true dev: true
/is-core-module/2.8.0: /is-core-module/2.8.1:
resolution: {integrity: sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==} resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
dependencies: dependencies:
has: 1.0.3 has: 1.0.3
dev: true dev: true
@ -3912,7 +3936,7 @@ packages:
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
engines: {node: '>= 10.13.0'} engines: {node: '>= 10.13.0'}
dependencies: dependencies:
'@types/node': 17.0.7 '@types/node': 17.0.8
merge-stream: 2.0.0 merge-stream: 2.0.0
supports-color: 7.2.0 supports-color: 7.2.0
dev: true dev: true
@ -3991,7 +4015,7 @@ packages:
dependencies: dependencies:
universalify: 2.0.0 universalify: 2.0.0
optionalDependencies: optionalDependencies:
graceful-fs: 4.2.8 graceful-fs: 4.2.9
dev: true dev: true
/jsonpointer/5.0.0: /jsonpointer/5.0.0:
@ -4468,9 +4492,11 @@ packages:
find-up: 3.0.0 find-up: 3.0.0
dev: true dev: true
/postcss-js/3.0.3: /postcss-js/[email protected]:
resolution: {integrity: sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw==} resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
engines: {node: '>=10.0'} engines: {node: ^12 || ^14 || >= 16}
peerDependencies:
postcss: ^8.3.3
dependencies: dependencies:
camelcase-css: 2.0.1 camelcase-css: 2.0.1
postcss: 8.4.5 postcss: 8.4.5
@ -4579,8 +4605,8 @@ packages:
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
dev: true dev: true
/prop-types/15.8.0: /prop-types/15.8.1:
resolution: {integrity: sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==} resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
dependencies: dependencies:
loose-envify: 1.4.0 loose-envify: 1.4.0
object-assign: 4.1.1 object-assign: 4.1.1
@ -4667,7 +4693,7 @@ packages:
react-dom: ^17.0.0 || ^16.2.0 react-dom: ^17.0.0 || ^16.2.0
dependencies: dependencies:
lodash.uniqueid: 4.0.1 lodash.uniqueid: 4.0.1
prop-types: 15.8.0 prop-types: 15.8.1
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
tinycolor2: 1.4.2 tinycolor2: 1.4.2
@ -4682,7 +4708,7 @@ packages:
react: 17.0.2 react: 17.0.2
dev: false dev: false
/react-i18next/11.15.3_80acb397921aff391f276c2217c76c9e: /react-i18next/11.15.3_56927fec8de40d941cee913e7ea81c11:
resolution: {integrity: sha512-RSUEM4So3Tu2JHV0JsZ5Yje+4nz66YViMfPZoywxOy0xyn3L7tE2CHvJ7Y9LUsrTU7vGmZ5bwb8PpjnkatdIxg==} resolution: {integrity: sha512-RSUEM4So3Tu2JHV0JsZ5Yje+4nz66YViMfPZoywxOy0xyn3L7tE2CHvJ7Y9LUsrTU7vGmZ5bwb8PpjnkatdIxg==}
peerDependencies: peerDependencies:
i18next: '>= 19.0.0' i18next: '>= 19.0.0'
@ -4698,7 +4724,7 @@ packages:
'@babel/runtime': 7.16.7 '@babel/runtime': 7.16.7
html-escaper: 2.0.2 html-escaper: 2.0.2
html-parse-stringify: 3.0.1 html-parse-stringify: 3.0.1
i18next: 21.6.4 i18next: 21.6.5
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
dev: false dev: false
@ -4724,7 +4750,7 @@ packages:
react: '>=15.0' react: '>=15.0'
react-dom: '>=15.0' react-dom: '>=15.0'
dependencies: dependencies:
prop-types: 15.8.0 prop-types: 15.8.1
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
dev: false dev: false
@ -4735,7 +4761,7 @@ packages:
react: ^16.x || ^17.x react: ^16.x || ^17.x
react-native-svg: '*' react-native-svg: '*'
dependencies: dependencies:
prop-types: 15.8.0 prop-types: 15.8.1
qr.js: 0.0.0 qr.js: 0.0.0
react: 17.0.2 react: 17.0.2
dev: false dev: false
@ -4756,7 +4782,7 @@ packages:
'@types/react-redux': 7.1.21 '@types/react-redux': 7.1.21
hoist-non-react-statics: 3.3.2 hoist-non-react-statics: 3.3.2
loose-envify: 1.4.0 loose-envify: 1.4.0
prop-types: 15.8.0 prop-types: 15.8.1
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
react-is: 17.0.2 react-is: 17.0.2
@ -4778,7 +4804,7 @@ packages:
'@emotion/react': 11.7.1_b08e3c15324cbe90a6ff8fcd416c932c '@emotion/react': 11.7.1_b08e3c15324cbe90a6ff8fcd416c932c
'@types/react-transition-group': 4.4.4 '@types/react-transition-group': 4.4.4
memoize-one: 5.2.1 memoize-one: 5.2.1
prop-types: 15.8.0 prop-types: 15.8.1
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
react-transition-group: 4.4[email protected][email protected] react-transition-group: 4.4[email protected][email protected]
@ -4796,7 +4822,7 @@ packages:
'@babel/runtime': 7.16.7 '@babel/runtime': 7.16.7
dom-helpers: 5.2.1 dom-helpers: 5.2.1
loose-envify: 1.4.0 loose-envify: 1.4.0
prop-types: 15.8.0 prop-types: 15.8.1
react: 17.0.2 react: 17.0.2
react-dom: 17.0[email protected] react-dom: 17.0[email protected]
dev: false dev: false
@ -4926,17 +4952,19 @@ packages:
protocol-buffers-schema: 3.6.0 protocol-buffers-schema: 3.6.0
dev: false dev: false
/resolve/1.20.0: /resolve/1.21.0:
resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==} resolution: {integrity: sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==}
hasBin: true
dependencies: dependencies:
is-core-module: 2.8.0 is-core-module: 2.8.1
path-parse: 1.0.7 path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
dev: true dev: true
/resolve/2.0.0-next.3: /resolve/2.0.0-next.3:
resolution: {integrity: sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==} resolution: {integrity: sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==}
dependencies: dependencies:
is-core-module: 2.8.0 is-core-module: 2.8.1
path-parse: 1.0.7 path-parse: 1.0.7
dev: true dev: true
@ -4945,8 +4973,8 @@ packages:
engines: {iojs: '>=1.0.0', node: '>=0.10.0'} engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
dev: true dev: true
/rfc4648/1.5.0: /rfc4648/1.5.1:
resolution: {integrity: sha512-FA6W9lDNeX8WbMY31io1xWg+TpZCbeDKsBo0ocwACZiWnh9TUAyk9CCuBQuOPmYnwwdEQZmraQ2ZK7yJsxErBg==} resolution: {integrity: sha512-60e/YWs2/D3MV1ErdjhJHcmlgnyLUiG4X/14dgsfm9/zmCWLN16xI6YqJYSCd/OANM7bUNzJqPY5B8/02S9Ibw==}
dev: false dev: false
/rimraf/3.0.2: /rimraf/3.0.2:
@ -4967,22 +4995,22 @@ packages:
magic-string: 0.25.7 magic-string: 0.25.7
dev: true dev: true
/rollup-plugin-terser/[email protected]2.0: /rollup-plugin-terser/[email protected]3.0:
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
peerDependencies: peerDependencies:
rollup: ^2.0.0 rollup: ^2.0.0
dependencies: dependencies:
'@babel/code-frame': 7.16.7 '@babel/code-frame': 7.16.7
jest-worker: 26.6.2 jest-worker: 26.6.2
rollup: 2.62.0 rollup: 2.63.0
serialize-javascript: 4.0.0 serialize-javascript: 4.0.0
terser: 5.10.0 terser: 5.10.0
transitivePeerDependencies: transitivePeerDependencies:
- acorn - acorn
dev: true dev: true
/rollup/2.62.0: /rollup/2.63.0:
resolution: {integrity: sha512-cJEQq2gwB0GWMD3rYImefQTSjrPYaC6s4J9pYqnstVLJ1CHa/aZNVkD4Epuvg4iLeMA4KRiq7UM7awKK6j7jcw==} resolution: {integrity: sha512-nps0idjmD+NXl6OREfyYXMn/dar3WGcyKn+KBzPdaLecub3x/LrId0wUcthcr8oZUAcZAR8NKcfGGFlNgGL1kQ==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
hasBin: true hasBin: true
optionalDependencies: optionalDependencies:
@ -5285,6 +5313,11 @@ packages:
has-flag: 4.0.0 has-flag: 4.0.0
dev: true dev: true
/supports-preserve-symlinks-flag/1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
dev: true
/swr/[email protected]: /swr/[email protected]:
resolution: {integrity: sha512-UsM0eo5T+kRPyWFZtWRx2XR5qzohs/LS4lDC0GCyLpCYFmsfTk28UCVDbOE9+KtoXY4FnwHYiF+ZYEU3hnJ1lQ==} resolution: {integrity: sha512-UsM0eo5T+kRPyWFZtWRx2XR5qzohs/LS4lDC0GCyLpCYFmsfTk28UCVDbOE9+KtoXY4FnwHYiF+ZYEU3hnJ1lQ==}
peerDependencies: peerDependencies:
@ -5293,8 +5326,8 @@ packages:
react: 17.0.2 react: 17.0.2
dev: false dev: false
/table/6.7.5: /table/6.8.0:
resolution: {integrity: sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==} resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
dependencies: dependencies:
ajv: 8.8.2 ajv: 8.8.2
@ -5304,8 +5337,8 @@ packages:
strip-ansi: 6.0.1 strip-ansi: 6.0.1
dev: true dev: true
/tailwindcss/3.0.8_cefe482e8d38053bbf3d5815e0c551b3: /tailwindcss/3.0.12_ef48b3b8837f8a23677bffe8f9cd866d:
resolution: {integrity: sha512-Yww1eRYO1AxITJmW/KduZPxNvYdHuedeKwPju9Oakp7MdiixRi5xkpLhirsc81QCxHL0eoce6qKmxXwYGt4Cjw==} resolution: {integrity: sha512-VqhF86z2c34sJyS5ZS8Q2nYuN0KzqZw1GGsuQQO9kJ3mY1oG7Fsag0vICkxUVXk6P+1sUkTkjMjKWCjEF0hNHw==}
engines: {node: '>=12.13.0'} engines: {node: '>=12.13.0'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -5313,7 +5346,7 @@ packages:
postcss: ^8.0.9 postcss: ^8.0.9
dependencies: dependencies:
arg: 5.0.1 arg: 5.0.1
autoprefixer: 10.4.1[email protected] autoprefixer: 10.4.2[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
@ -5321,20 +5354,19 @@ packages:
detective: 5.2.0 detective: 5.2.0
didyoumean: 1.2.2 didyoumean: 1.2.2
dlv: 1.1.3 dlv: 1.1.3
fast-glob: 3.2.7 fast-glob: 3.2.10
glob-parent: 6.0.2 glob-parent: 6.0.2
is-glob: 4.0.3 is-glob: 4.0.3
normalize-path: 3.0.0 normalize-path: 3.0.0
object-hash: 2.2.0 object-hash: 2.2.0
postcss: 8.4.5 postcss: 8.4.5
postcss-js: 3.0.3 postcss-js: 4.0[email protected]
postcss-load-config: 3.1.1 postcss-load-config: 3.1.1
postcss-nested: 5.0[email protected] postcss-nested: 5.0[email protected]
postcss-selector-parser: 6.0.8 postcss-selector-parser: 6.0.8
postcss-value-parser: 4.2.0 postcss-value-parser: 4.2.0
quick-lru: 5.1.1 quick-lru: 5.1.1
resolve: 1.20.0 resolve: 1.21.0
tmp: 0.2.1
transitivePeerDependencies: transitivePeerDependencies:
- ts-node - ts-node
dev: true dev: true
@ -5447,13 +5479,6 @@ packages:
resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==} resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==}
dev: false dev: false
/tmp/0.2.1:
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
engines: {node: '>=8.17.0'}
dependencies:
rimraf: 3.0.2
dev: true
/to-fast-properties/2.0.0: /to-fast-properties/2.0.0:
resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -5585,8 +5610,8 @@ packages:
punycode: 2.1.1 punycode: 2.1.1
dev: true dev: true
/use-breakpoint/3.0.0[email protected][email protected]: /use-breakpoint/3.0.1[email protected][email protected]:
resolution: {integrity: sha512-YWP+3xRAqqr27l+bE1J/tvDOBf0rf/sEjQhWOICDfKvsloq9iKcQlm90F3mnAjk3YM/cgJXsscEeHGBm+7gzDg==} resolution: {integrity: sha512-gQ3zg55Aa/AAicxJSsKBSs5B4pcQv8PNMaJXS+P7TzvWJ6QLY7Napa2erkA6gZDmFFdkjWsztyOax5a5nuoLGQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
peerDependencies: peerDependencies:
react: '>=16.8' react: '>=16.8'
@ -5641,9 +5666,9 @@ packages:
vite: ^2.0.0 vite: ^2.0.0
dependencies: dependencies:
debug: 4.3.3 debug: 4.3.3
fast-glob: 3.2.7 fast-glob: 3.2.10
pretty-bytes: 5.6.0 pretty-bytes: 5.6.0
rollup: 2.62.0 rollup: 2.63.0
vite: 2.7.10 vite: 2.7.10
workbox-build: 6.4.2 workbox-build: 6.4.2
workbox-window: 6.4.2 workbox-window: 6.4.2
@ -5671,8 +5696,8 @@ packages:
dependencies: dependencies:
esbuild: 0.13.15 esbuild: 0.13.15
postcss: 8.4.5 postcss: 8.4.5
resolve: 1.20.0 resolve: 1.21.0
rollup: 2.62.0 rollup: 2.63.0
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
@ -5777,9 +5802,9 @@ packages:
'@babel/core': 7.16.7 '@babel/core': 7.16.7
'@babel/preset-env': 7.16.7_@[email protected] '@babel/preset-env': 7.16.7_@[email protected]
'@babel/runtime': 7.16.7 '@babel/runtime': 7.16.7
'@rollup/plugin-babel': 5.3.0_@[email protected][email protected]2.0 '@rollup/plugin-babel': 5.3.0_@[email protected][email protected]3.0
'@rollup/plugin-node-resolve': 11.2[email protected]2.0 '@rollup/plugin-node-resolve': 11.2[email protected]3.0
'@rollup/plugin-replace': 2.4[email protected]2.0 '@rollup/plugin-replace': 2.4[email protected]3.0
'@surma/rollup-plugin-off-main-thread': 2.2.3 '@surma/rollup-plugin-off-main-thread': 2.2.3
ajv: 8.8.2 ajv: 8.8.2
common-tags: 1.8.2 common-tags: 1.8.2
@ -5788,8 +5813,8 @@ packages:
glob: 7.2.0 glob: 7.2.0
lodash: 4.17.21 lodash: 4.17.21
pretty-bytes: 5.6.0 pretty-bytes: 5.6.0
rollup: 2.62.0 rollup: 2.63.0
rollup-plugin-terser: 7.0[email protected]2.0 rollup-plugin-terser: 7.0[email protected]3.0
source-map: 0.8.0-beta.0 source-map: 0.8.0-beta.0
source-map-url: 0.4.1 source-map-url: 0.4.1
stringify-object: 3.3.0 stringify-object: 3.3.0

263
src/components/Channel.tsx

@ -3,13 +3,14 @@ import React from 'react';
import { fromByteArray, toByteArray } from 'base64-js'; import { fromByteArray, toByteArray } from 'base64-js';
import { useForm, useWatch } from 'react-hook-form'; import { useForm, useWatch } from 'react-hook-form';
import { FaQrcode } from 'react-icons/fa'; import { FaQrcode } from 'react-icons/fa';
import { FiEdit3, FiSave } from 'react-icons/fi'; import { FiChevronDown, FiChevronUp, FiSave } from 'react-icons/fi';
import { MdRefresh, MdVisibility, MdVisibilityOff } from 'react-icons/md'; import { MdRefresh, MdVisibility, MdVisibilityOff } from 'react-icons/md';
import QRCode from 'react-qr-code'; import QRCode from 'react-qr-code';
import { Loading } from '@components/generic/Loading'; import { Loading } from '@components/generic/Loading';
import { Modal } from '@components/generic/Modal'; import { Modal } from '@components/generic/Modal';
import { connection } from '@core/connection'; import { connection } from '@core/connection';
import { Disclosure } from '@headlessui/react';
import { import {
Card, Card,
Checkbox, Checkbox,
@ -21,29 +22,17 @@ import { Protobuf } from '@meshtastic/meshtasticjs';
export interface ChannelProps { export interface ChannelProps {
channel: Protobuf.Channel; channel: Protobuf.Channel;
isPrimary?: boolean;
} }
export const Channel = ({ channel, isPrimary }: ChannelProps): JSX.Element => { export const Channel = ({ channel }: ChannelProps): JSX.Element => {
const [edit, setEdit] = React.useState(false);
const [loading, setLoading] = React.useState(false); const [loading, setLoading] = React.useState(false);
const [showQr, setShowQr] = React.useState(false); const [showQr, setShowQr] = React.useState(false);
const [keySize, setKeySize] = React.useState<128 | 256>(256); const [keySize, setKeySize] = React.useState<128 | 256>(256);
const [pskHidden, setPskHidden] = React.useState(true); const [pskHidden, setPskHidden] = React.useState(true);
const { register, handleSubmit, setValue, control } = useForm<{ const { register, handleSubmit, setValue, control, formState } = useForm<
enabled: boolean; Omit<Protobuf.ChannelSettings, 'psk'> & { psk: string; enabled: boolean }
settings: { >({
name: string;
bandwidth?: number;
codingRate?: number;
spreadFactor?: number;
downlinkEnabled?: boolean;
uplinkEnabled?: boolean;
txPower?: number;
psk?: string;
};
}>({
defaultValues: { defaultValues: {
enabled: [ enabled: [
Protobuf.Channel_Role.SECONDARY, Protobuf.Channel_Role.SECONDARY,
@ -51,28 +40,20 @@ export const Channel = ({ channel, isPrimary }: ChannelProps): JSX.Element => {
].find((role) => role === channel.role) ].find((role) => role === channel.role)
? true ? true
: false, : false,
settings: { name: channel.settings?.name,
name: channel.settings?.name, psk: fromByteArray(channel.settings?.psk ?? new Uint8Array(0)),
bandwidth: channel.settings?.bandwidth,
codingRate: channel.settings?.codingRate,
spreadFactor: channel.settings?.spreadFactor,
downlinkEnabled: channel.settings?.downlinkEnabled,
uplinkEnabled: channel.settings?.uplinkEnabled,
txPower: channel.settings?.txPower,
psk: fromByteArray(channel.settings?.psk ?? new Uint8Array(0)),
},
}, },
}); });
const watchPsk = useWatch({ const watchPsk = useWatch({
control, control,
name: 'settings.psk', name: 'psk',
defaultValue: '', defaultValue: '',
}); });
const onSubmit = handleSubmit(async (data) => { const onSubmit = handleSubmit(async (data) => {
setLoading(true); setLoading(true);
const adminChannel = Protobuf.Channel.create({ const channelData = Protobuf.Channel.create({
role: role:
channel.role === Protobuf.Channel_Role.PRIMARY channel.role === Protobuf.Channel_Role.PRIMARY
? Protobuf.Channel_Role.PRIMARY ? Protobuf.Channel_Role.PRIMARY
@ -81,19 +62,19 @@ export const Channel = ({ channel, isPrimary }: ChannelProps): JSX.Element => {
: Protobuf.Channel_Role.DISABLED, : Protobuf.Channel_Role.DISABLED,
index: channel.index, index: channel.index,
settings: { settings: {
...data.settings, ...data,
psk: toByteArray(data.settings.psk ?? ''), psk: toByteArray(data.psk ?? ''),
}, },
}); });
await connection.setChannel(adminChannel, (): Promise<void> => { await connection.setChannel(channelData, (): Promise<void> => {
setLoading(false); setLoading(false);
return Promise.resolve(); return Promise.resolve();
}); });
}); });
return ( return (
<div className="relative flex justify-between p-3 bg-gray-100 rounded-md dark:bg-gray-700"> <>
<Modal <Modal
open={showQr} open={showQr}
onClose={(): void => { onClose={(): void => {
@ -107,109 +88,125 @@ export const Channel = ({ channel, isPrimary }: ChannelProps): JSX.Element => {
/> />
</Card> </Card>
</Modal> </Modal>
{edit ? ( <Disclosure
<> as="div"
{loading && <Loading />} className="bg-gray-100 rounded-md dark:bg-secondaryDark"
<div className="flex my-auto"> >
<form className="gap-3"> {({ open }): JSX.Element => (
{!isPrimary && ( <>
<Checkbox <Disclosure.Button
label="Enabled" as="div"
{...register('enabled', { valueAsNumber: true })} className="relative flex justify-between p-3"
/> >
)} <>
<Input label="Name" {...register('settings.name')} /> <div className="flex my-auto space-x-2">
<Select <div
label="Key Size" className={`h-3 my-auto w-3 rounded-full ${
options={[ [
{ name: '128 Bit', value: 128 }, Protobuf.Channel_Role.SECONDARY,
{ name: '256 Bit', value: 256 }, Protobuf.Channel_Role.PRIMARY,
]} ].find((role) => role === channel.role)
value={keySize} ? 'bg-green-500'
onChange={(e): void => { : 'bg-gray-400'
setKeySize(parseInt(e.target.value) as 128 | 256); }`}
}} />
/> <div>
<Input {channel.settings?.name.length
label="Pre-Shared Key" ? channel.settings.name
type={pskHidden ? 'password' : 'text'} : channel.role === Protobuf.Channel_Role.PRIMARY
disabled ? 'Primary'
action={ : `Channel: ${channel.index}`}
<> </div>
<IconButton </div>
onClick={(): void => { <div className="flex gap-2">
setPskHidden(!setPskHidden); {open && (
}}
icon={pskHidden ? <MdVisibility /> : <MdVisibilityOff />}
/>
<IconButton <IconButton
onClick={(): void => { onClick={async (e): Promise<void> => {
const key = new Uint8Array(keySize); e.stopPropagation();
crypto.getRandomValues(key); await onSubmit();
setValue('settings.psk', fromByteArray(key));
}} }}
icon={<MdRefresh />} disabled={loading || !formState.isDirty}
icon={<FiSave />}
/> />
</> )}
} <IconButton
{...register('settings.psk')} onClick={(e): void => {
/> e.stopPropagation();
<Checkbox setShowQr(true);
label="Uplink Enabled" }}
{...register('settings.uplinkEnabled')} icon={<FaQrcode />}
/> />
<Checkbox <IconButton
label="Downlink Enabled" icon={open ? <FiChevronUp /> : <FiChevronDown />}
{...register('settings.downlinkEnabled')} />
/> </div>
</form> </>
</div> </Disclosure.Button>
<IconButton <Disclosure.Panel className="p-2 border-t">
onClick={async (): Promise<void> => { {loading && <Loading />}
await onSubmit(); <div className="flex px-2 my-auto">
<form className="w-full gap-3">
{channel.index !== 0 && (
<>
<Checkbox
label="Enabled"
{...register('enabled', { valueAsNumber: true })}
/>
<Input label="Name" {...register('name')} />
</>
)}
setEdit(false); <Select
}} label="Key Size"
icon={<FiSave />} options={[
/> { name: '128 Bit', value: 128 },
</> { name: '256 Bit', value: 256 },
) : ( ]}
<> value={keySize}
<div className="flex my-auto space-x-2"> onChange={(e): void => {
<div setKeySize(parseInt(e.target.value) as 128 | 256);
className={`h-3 my-auto w-3 rounded-full ${ }}
[ />
Protobuf.Channel_Role.SECONDARY, <Input
Protobuf.Channel_Role.PRIMARY, label="Pre-Shared Key"
].find((role) => role === channel.role) type={pskHidden ? 'password' : 'text'}
? 'bg-green-500' disabled
: 'bg-gray-400' action={
}`} <>
/> <IconButton
<div> onClick={(): void => {
{channel.settings?.name.length setPskHidden(!setPskHidden);
? channel.settings.name }}
: channel.role === Protobuf.Channel_Role.PRIMARY icon={
? 'Primary' pskHidden ? <MdVisibility /> : <MdVisibilityOff />
: `Channel: ${channel.index}`} }
</div> />
</div> <IconButton
<div className="flex gap-2"> onClick={(): void => {
<IconButton const key = new Uint8Array(keySize);
onClick={(): void => { crypto.getRandomValues(key);
setShowQr(true); setValue('psk', fromByteArray(key));
}} }}
icon={<FaQrcode />} icon={<MdRefresh />}
/> />
<IconButton </>
onClick={(): void => { }
setEdit(true); {...register('psk')}
}} />
icon={<FiEdit3 />} <Checkbox
/> label="Uplink Enabled"
</div> {...register('uplinkEnabled')}
</> />
)} <Checkbox
</div> label="Downlink Enabled"
{...register('downlinkEnabled')}
/>
</form>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
</>
); );
}; };

10
src/components/Map/styles.ts

@ -6,23 +6,23 @@ export interface MapStyle {
export const MapStyles = { export const MapStyles = {
Streets: { Streets: {
title: 'Streets', title: 'Streets',
url: 'mapbox://styles/mapbox/streets-v11', url: 'mapbox://styles/mapbox/streets-v11?optimize=true',
} as MapStyle, } as MapStyle,
Outdoors: { Outdoors: {
title: 'Outdoors', title: 'Outdoors',
url: 'mapbox://styles/mapbox/outdoors-v11', url: 'mapbox://styles/mapbox/outdoors-v11?optimize=true',
} as MapStyle, } as MapStyle,
Light: { Light: {
title: 'Light', title: 'Light',
url: 'mapbox://styles/mapbox/light-v10', url: 'mapbox://styles/mapbox/light-v10?optimize=true',
} as MapStyle, } as MapStyle,
Dark: { Dark: {
title: 'Dark', title: 'Dark',
url: 'mapbox://styles/sachaw/ckwzwm92e1oep14pjunjqlqbo', url: 'mapbox://styles/sachaw/ckwzwm92e1oep14pjunjqlqbo?optimize=true',
} as MapStyle, } as MapStyle,
Satellite: { Satellite: {
title: 'Satellite', title: 'Satellite',
url: 'mapbox://styles/mapbox/satellite-v9', url: 'mapbox://styles/mapbox/satellite-v9?optimize=true',
} as MapStyle, } as MapStyle,
}; };

4
src/core/connection.ts

@ -159,7 +159,9 @@ const registerListeners = (): void => {
message: message, message: message,
ack: message.packet.from !== myNodeNum, ack: message.packet.from !== myNodeNum,
isSender: message.packet.from === myNodeNum, isSender: message.packet.from === myNodeNum,
received: new Date(message.packet.rxTime), received: message.packet.rxTime
? new Date(message.packet.rxTime * 1000)
: new Date(),
}), }),
); );
}); });

82
src/pages/settings/Channels.tsx

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { useForm, useWatch } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { FiCode, FiMenu } from 'react-icons/fi'; import { FiCode, FiMenu } from 'react-icons/fi';
import JSONPretty from 'react-json-pretty'; import JSONPretty from 'react-json-pretty';
@ -30,69 +30,35 @@ export const Channels = ({
setNavOpen, setNavOpen,
}: ChannelsProps): JSX.Element => { }: ChannelsProps): JSX.Element => {
const channels = useAppSelector((state) => state.meshtastic.radio.channels); const channels = useAppSelector((state) => state.meshtastic.radio.channels);
const channel = channels[0].channel; const adminChannel =
channels.find(
(channel) => channel.channel.role === Protobuf.Channel_Role.PRIMARY,
) ?? channels[0];
const [usePreset, setUsePreset] = React.useState(true);
const [debug, setDebug] = React.useState(false); const [debug, setDebug] = React.useState(false);
const [loading, setLoading] = React.useState(false); const [loading, setLoading] = React.useState(false);
const { register, handleSubmit, reset, formState, control } = useForm<{ const { register, handleSubmit, reset, formState } = useForm<
simple: boolean; DeepOmit<Protobuf.Channel, 'psk'>
preset?: Protobuf.ChannelSettings_ModemConfig; >({
enabled: boolean;
settings: {
name: string;
bandwidth?: number;
codingRate?: number;
spreadFactor?: number;
downlinkEnabled?: boolean;
uplinkEnabled?: boolean;
txPower?: number;
psk?: string;
};
}>({
defaultValues: { defaultValues: {
simple: true, ...adminChannel.channel,
enabled:
channel.role ===
(Protobuf.Channel_Role.PRIMARY || Protobuf.Channel_Role.SECONDARY)
? true
: false,
settings: {
name: channel.settings?.name,
bandwidth: channel.settings?.bandwidth,
codingRate: channel.settings?.codingRate,
spreadFactor: channel.settings?.spreadFactor,
downlinkEnabled: channel.settings?.downlinkEnabled,
uplinkEnabled: channel.settings?.uplinkEnabled,
txPower: channel.settings?.txPower,
psk: new TextDecoder().decode(channel.settings?.psk),
},
}, },
}); });
const watchSimple = useWatch({
control,
name: 'simple',
defaultValue: true,
});
const onSubmit = handleSubmit(async (data) => { const onSubmit = handleSubmit(async (data) => {
setLoading(true); setLoading(true);
const adminChannel = Protobuf.Channel.create({ const channelData = Protobuf.Channel.create({
role: data.enabled ...data,
? Protobuf.Channel_Role.SECONDARY
: Protobuf.Channel_Role.DISABLED,
index: channel.index,
settings: { settings: {
...data.settings, ...data.settings,
psk: new TextEncoder().encode(data.settings.psk), psk: adminChannel.channel.settings?.psk,
}, },
}); });
console.log(adminChannel); await connection.setChannel(channelData, (): Promise<void> => {
await connection.setChannel(adminChannel, (): Promise<void> => {
setLoading(false); setLoading(false);
return Promise.resolve(); return Promise.resolve();
}); });
@ -128,18 +94,24 @@ export const Channels = ({
} }
> >
<div className="space-y-4"> <div className="space-y-4">
{channel && ( {adminChannel && (
<Card> <Card>
{loading && <Loading />} {loading && <Loading />}
<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">
{/* TODO: get gap working */} {/* TODO: get gap working */}
<Checkbox label="Use Presets" {...register('simple')} /> <Checkbox
checked={usePreset}
label="Use Presets"
onChange={(e): void => setUsePreset(e.target.checked)}
/>
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
{watchSimple ? ( {usePreset ? (
<Select <Select
label="Preset" label="Preset"
optionsEnum={Protobuf.ChannelSettings_ModemConfig} optionsEnum={Protobuf.ChannelSettings_ModemConfig}
{...register('simple')} {...register('settings.modemConfig', {
valueAsNumber: true,
})}
/> />
) : ( ) : (
<> <>
@ -192,11 +164,7 @@ export const Channels = ({
<Cover enabled={debug} content={<JSONPretty data={channels} />} /> <Cover enabled={debug} content={<JSONPretty data={channels} />} />
<div className="w-full p-4 space-y-2 md:p-10"> <div className="w-full p-4 space-y-2 md:p-10">
{channels.map((channel) => ( {channels.map((channel) => (
<Channel <Channel key={channel.channel.index} channel={channel.channel} />
key={channel.channel.index}
channel={channel.channel}
isPrimary={channel.channel.index === 0}
/>
))} ))}
</div> </div>
</Card> </Card>

13
types/static.d.ts

@ -57,3 +57,16 @@ declare module '*.png' {
} }
/* CUSTOM: ADD YOUR OWN HERE */ /* CUSTOM: ADD YOUR OWN HERE */
type Primitive = string | number | boolean | symbol | undefined | null;
type DeepOmitHelper<T, K extends keyof T> = {
[P in K]: T[P] extends infer TP //extra level of indirection needed to trigger homomorhic behavior // distribute over unions
? TP extends Primitive
? TP // leave primitives and functions alone
: DeepOmit<TP, K>
: never;
};
type DeepOmit<T, K> = T extends Primitive
? T
: DeepOmitHelper<T, Exclude<keyof T, K>>;

Loading…
Cancel
Save