Misc fixes
This commit is contained in:
+5
-4
@@ -12,12 +12,13 @@
|
|||||||
"lint": "eslint 'src/**/*.{ts,tsx}'"
|
"lint": "eslint 'src/**/*.{ts,tsx}'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@floating-ui/react-dom": "^0.3.3",
|
||||||
"@headlessui/react": "^1.4.2",
|
"@headlessui/react": "^1.4.2",
|
||||||
"@meshtastic/meshtasticjs": "^0.6.35",
|
"@meshtastic/meshtasticjs": "^0.6.35",
|
||||||
"@reduxjs/toolkit": "^1.7.1",
|
"@reduxjs/toolkit": "^1.7.1",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
"boring-avatars": "^1.5.8",
|
"boring-avatars": "^1.5.8",
|
||||||
"i18next": "^21.6.0",
|
"i18next": "^21.6.2",
|
||||||
"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",
|
||||||
@@ -42,7 +43,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/w3c-web-serial": "^1.0.2",
|
"@types/w3c-web-serial": "^1.0.2",
|
||||||
"@types/web-bluetooth": "^0.0.11",
|
"@types/web-bluetooth": "^0.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
||||||
"@typescript-eslint/parser": "^5.7.0",
|
"@typescript-eslint/parser": "^5.7.0",
|
||||||
"@verypossible/eslint-config": "^1.6.1",
|
"@verypossible/eslint-config": "^1.6.1",
|
||||||
@@ -60,10 +61,10 @@
|
|||||||
"gzipper": "^6.0.0",
|
"gzipper": "^6.0.0",
|
||||||
"postcss": "^8.4.5",
|
"postcss": "^8.4.5",
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.5.1",
|
||||||
"tailwindcss": "^3.0.5",
|
"tailwindcss": "^3.0.6",
|
||||||
"tar": "^6.1.11",
|
"tar": "^6.1.11",
|
||||||
"typescript": "^4.5.4",
|
"typescript": "^4.5.4",
|
||||||
"vite": "^2.7.2",
|
"vite": "^2.7.3",
|
||||||
"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"
|
||||||
|
|||||||
Generated
+65
-42
@@ -1,6 +1,7 @@
|
|||||||
lockfileVersion: 5.3
|
lockfileVersion: 5.3
|
||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
|
'@floating-ui/react-dom': ^0.3.3
|
||||||
'@headlessui/react': ^1.4.2
|
'@headlessui/react': ^1.4.2
|
||||||
'@meshtastic/meshtasticjs': ^0.6.35
|
'@meshtastic/meshtasticjs': ^0.6.35
|
||||||
'@reduxjs/toolkit': ^1.7.1
|
'@reduxjs/toolkit': ^1.7.1
|
||||||
@@ -9,7 +10,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/w3c-web-serial': ^1.0.2
|
'@types/w3c-web-serial': ^1.0.2
|
||||||
'@types/web-bluetooth': ^0.0.11
|
'@types/web-bluetooth': ^0.0.12
|
||||||
'@typescript-eslint/eslint-plugin': ^5.7.0
|
'@typescript-eslint/eslint-plugin': ^5.7.0
|
||||||
'@typescript-eslint/parser': ^5.7.0
|
'@typescript-eslint/parser': ^5.7.0
|
||||||
'@verypossible/eslint-config': ^1.6.1
|
'@verypossible/eslint-config': ^1.6.1
|
||||||
@@ -27,7 +28,7 @@ specifiers:
|
|||||||
eslint-plugin-react: ^7.27.1
|
eslint-plugin-react: ^7.27.1
|
||||||
eslint-plugin-react-hooks: ^4.3.0
|
eslint-plugin-react-hooks: ^4.3.0
|
||||||
gzipper: ^6.0.0
|
gzipper: ^6.0.0
|
||||||
i18next: ^21.6.0
|
i18next: ^21.6.2
|
||||||
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
|
||||||
@@ -44,31 +45,32 @@ specifiers:
|
|||||||
react-select: ^5.2.1
|
react-select: ^5.2.1
|
||||||
rfc4648: ^1.5.0
|
rfc4648: ^1.5.0
|
||||||
swr: ^1.1.2-beta.0
|
swr: ^1.1.2-beta.0
|
||||||
tailwindcss: ^3.0.5
|
tailwindcss: ^3.0.6
|
||||||
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.0
|
||||||
vite: ^2.7.2
|
vite: ^2.7.3
|
||||||
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.3.3_5539cae010396b202b015f3568914e95
|
||||||
'@headlessui/react': 1.4.2_react-dom@17.0.2+react@17.0.2
|
'@headlessui/react': 1.4.2_react-dom@17.0.2+react@17.0.2
|
||||||
'@meshtastic/meshtasticjs': 0.6.35
|
'@meshtastic/meshtasticjs': link:../meshtastic.js
|
||||||
'@reduxjs/toolkit': 1.7.1_react-redux@7.2.6+react@17.0.2
|
'@reduxjs/toolkit': 1.7.1_react-redux@7.2.6+react@17.0.2
|
||||||
base64-js: 1.5.1
|
base64-js: 1.5.1
|
||||||
boring-avatars: 1.5.8
|
boring-avatars: 1.5.8
|
||||||
i18next: 21.6.0
|
i18next: 21.6.2
|
||||||
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
|
||||||
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.22.1_react@17.0.2
|
react-hook-form: 7.22.1_react@17.0.2
|
||||||
react-i18next: 11.15.1_i18next@21.6.0+react@17.0.2
|
react-i18next: 11.15.1_i18next@21.6.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-json-pretty: 2.2.0_react-dom@17.0.2+react@17.0.2
|
||||||
react-qr-code: 2.0.3_react@17.0.2
|
react-qr-code: 2.0.3_react@17.0.2
|
||||||
@@ -86,7 +88,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/w3c-web-serial': 1.0.2
|
'@types/w3c-web-serial': 1.0.2
|
||||||
'@types/web-bluetooth': 0.0.11
|
'@types/web-bluetooth': 0.0.12
|
||||||
'@typescript-eslint/eslint-plugin': 5.7.0_915acdfead96f701b1277a1a723fc8d4
|
'@typescript-eslint/eslint-plugin': 5.7.0_915acdfead96f701b1277a1a723fc8d4
|
||||||
'@typescript-eslint/parser': 5.7.0_eslint@8.4.1+typescript@4.5.4
|
'@typescript-eslint/parser': 5.7.0_eslint@8.4.1+typescript@4.5.4
|
||||||
'@verypossible/eslint-config': 1.6.1_typescript@4.5.4
|
'@verypossible/eslint-config': 1.6.1_typescript@4.5.4
|
||||||
@@ -104,12 +106,12 @@ devDependencies:
|
|||||||
gzipper: 6.0.0
|
gzipper: 6.0.0
|
||||||
postcss: 8.4.5
|
postcss: 8.4.5
|
||||||
prettier: 2.5.1
|
prettier: 2.5.1
|
||||||
tailwindcss: 3.0.5_16a290f6d0e3717bf6d2667234aebd30
|
tailwindcss: 3.0.6_16a290f6d0e3717bf6d2667234aebd30
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
typescript: 4.5.4
|
typescript: 4.5.4
|
||||||
vite: 2.7.2
|
vite: 2.7.3
|
||||||
vite-plugin-cdn-import: 0.3.5
|
vite-plugin-cdn-import: 0.3.5
|
||||||
vite-plugin-pwa: 0.11.12_vite@2.7.2
|
vite-plugin-pwa: 0.11.12_vite@2.7.3
|
||||||
workbox-window: 6.4.2
|
workbox-window: 6.4.2
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
@@ -1410,6 +1412,30 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@floating-ui/core/0.2.1:
|
||||||
|
resolution: {integrity: sha512-fhFNlxBdiA8RVdVcZUllwvIgwvj3QL1o5MxthjgPmkc6nizu1/qwTVMhpr9QRdkF6DwNQnu0rvgb0r7Ml3i4mw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@floating-ui/dom/0.1.7:
|
||||||
|
resolution: {integrity: sha512-aA0i/ov24v+f6YCobJecoDBcOikn1W7+q9txSXQmezfPEJ6P9QFRrFvuYGaO0EevgexmJ3PlrfSR4dKhNHRP0Q==}
|
||||||
|
dependencies:
|
||||||
|
'@floating-ui/core': 0.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@floating-ui/react-dom/0.3.3_5539cae010396b202b015f3568914e95:
|
||||||
|
resolution: {integrity: sha512-ALPyo9zJkRKsUFHNXtvBVB1B5zOhDfLtq4eJHYMt6DHt4wPiHgCoM8XtMiFz5s5P3cbznkNa6cUUIRn9j2F5/A==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8.0'
|
||||||
|
react-dom: '>=16.8.0'
|
||||||
|
dependencies:
|
||||||
|
'@floating-ui/dom': 0.1.7
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
use-isomorphic-layout-effect: 1.1.1_cfedea9b3ed0faf0dded75c187406c5e
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@headlessui/react/1.4.2_react-dom@17.0.2+react@17.0.2:
|
/@headlessui/react/1.4.2_react-dom@17.0.2+react@17.0.2:
|
||||||
resolution: {integrity: sha512-N8tv7kLhg9qGKBkVdtg572BvKvWhmiudmeEpOCyNwzOsZHCXBtl8AazGikIfUS+vBoub20Fse3BjawXDVPPdug==}
|
resolution: {integrity: sha512-N8tv7kLhg9qGKBkVdtg572BvKvWhmiudmeEpOCyNwzOsZHCXBtl8AazGikIfUS+vBoub20Fse3BjawXDVPPdug==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -1491,13 +1517,6 @@ packages:
|
|||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@meshtastic/meshtasticjs/0.6.35:
|
|
||||||
resolution: {integrity: sha512-vr6t3/VvgVynmVevZnRsJc+G/TvmP5eTeIZHOrC1N+SX0r/CIs4IbZFTqp5frvwJYqyyBXSxixm5JN5+byFS9A==}
|
|
||||||
dependencies:
|
|
||||||
'@protobuf-ts/runtime': 2.1.0
|
|
||||||
sub-events: 1.8.9
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@nodelib/fs.scandir/2.1.5:
|
/@nodelib/fs.scandir/2.1.5:
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -1519,10 +1538,6 @@ packages:
|
|||||||
fastq: 1.13.0
|
fastq: 1.13.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@protobuf-ts/runtime/2.1.0:
|
|
||||||
resolution: {integrity: sha512-HZwkgJW9SGiE9+0lWKr1X997tmG01/40j+hr9yBVk+hTQcm7Hsf77XhMNtsDjWUOcspG6GBXu8o3g4i3kD5/zQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@reduxjs/toolkit/1.7.1_react-redux@7.2.6+react@17.0.2:
|
/@reduxjs/toolkit/1.7.1_react-redux@7.2.6+react@17.0.2:
|
||||||
resolution: {integrity: sha512-wXwXYjBVz/ItxB7SMzEAMmEE/FBiY1ze18N+VVVX7NtVbRUrdOGKhpQMHivIJfkbJvSdLUU923a/yAagJQzY0Q==}
|
resolution: {integrity: sha512-wXwXYjBVz/ItxB7SMzEAMmEE/FBiY1ze18N+VVVX7NtVbRUrdOGKhpQMHivIJfkbJvSdLUU923a/yAagJQzY0Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1708,8 +1723,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Ftx4BtLxgAnel7V7GbHylCYjSq827A+jeEE3SnTS7huCGUN0pSwUn+CchTCT9TkZj9w+NVMUq4Bk2R0GvUNmAQ==}
|
resolution: {integrity: sha512-Ftx4BtLxgAnel7V7GbHylCYjSq827A+jeEE3SnTS7huCGUN0pSwUn+CchTCT9TkZj9w+NVMUq4Bk2R0GvUNmAQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/web-bluetooth/0.0.11:
|
/@types/web-bluetooth/0.0.12:
|
||||||
resolution: {integrity: sha512-2CF3Kk2Rcvg/c2QzO7mXUhY7eL9CC3aKzrF+dNWNmp7Q8bmlvjmUM1nFPMSngawdJ+CcIdu8eJlQRytBgAZR9w==}
|
resolution: {integrity: sha512-Q4sUrowpylCOWjUWFtNwkNBHQUnCL8y44Iq2ZLtVMAuAGIwPSXa3kqIvu2LwXoc2d1jyaaw4Bg354degHrsADw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/eslint-plugin/4.33.0_3289a875d95a672b97ebf589745c66ef:
|
/@typescript-eslint/eslint-plugin/4.33.0_3289a875d95a672b97ebf589745c66ef:
|
||||||
@@ -2224,7 +2239,7 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001287
|
caniuse-lite: 1.0.30001287
|
||||||
electron-to-chromium: 1.4.20
|
electron-to-chromium: 1.4.22
|
||||||
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
|
||||||
@@ -2509,8 +2524,8 @@ packages:
|
|||||||
jake: 10.8.2
|
jake: 10.8.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/electron-to-chromium/1.4.20:
|
/electron-to-chromium/1.4.22:
|
||||||
resolution: {integrity: sha512-N7ZVNrdzX8NE90OXEFBMsBf3fp8P/vVDUER3WCUZjzC7OkNTXHVoF6W9qVhq8+dA8tGnbDajzUpj2ISNVVyj+Q==}
|
resolution: {integrity: sha512-IiW8cV8eyjMhuWqk9wwHRPOVN+5Fa7NHOTjogrwg2H9TNiLVA8ywjOJnVKoywaqUHryDUOpK7Mg6P1FETisi0g==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/emoji-regex/8.0.0:
|
/emoji-regex/8.0.0:
|
||||||
@@ -3461,8 +3476,8 @@ packages:
|
|||||||
'@babel/runtime': 7.16.5
|
'@babel/runtime': 7.16.5
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/i18next/21.6.0:
|
/i18next/21.6.2:
|
||||||
resolution: {integrity: sha512-RjNuACL35wWZgtkyMcjcCmK7R72u3P6jTNbGKzrvHGI9M0iK5Vn1DsBIwOByppaXLIbe0viJ79Nz2h8w1UwPoQ==}
|
resolution: {integrity: sha512-S1zSTrs2lgPH8iG68pMWh3P7OzQMcs3+Qr5F39JTyGbe/xl5cW4cF8MTPKSy6F25tFTcKBq915IoEZUWewkldg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.16.5
|
'@babel/runtime': 7.16.5
|
||||||
dev: false
|
dev: false
|
||||||
@@ -4377,7 +4392,7 @@ packages:
|
|||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/react-i18next/11.15.1_i18next@21.6.0+react@17.0.2:
|
/react-i18next/11.15.1_i18next@21.6.2+react@17.0.2:
|
||||||
resolution: {integrity: sha512-lnje1uKu5XeM5MLvfbt1oygF+nEIZnpOM4Iu8bkx5ECD4XRYgi3SJDmolrp0EDxDHeK2GgFb+vEEK0hsZ9sjeA==}
|
resolution: {integrity: sha512-lnje1uKu5XeM5MLvfbt1oygF+nEIZnpOM4Iu8bkx5ECD4XRYgi3SJDmolrp0EDxDHeK2GgFb+vEEK0hsZ9sjeA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
i18next: '>= 19.0.0'
|
i18next: '>= 19.0.0'
|
||||||
@@ -4386,7 +4401,7 @@ packages:
|
|||||||
'@babel/runtime': 7.16.5
|
'@babel/runtime': 7.16.5
|
||||||
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.0
|
i18next: 21.6.2
|
||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@@ -4860,11 +4875,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==}
|
resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/sub-events/1.8.9:
|
|
||||||
resolution: {integrity: sha512-RhhA2amqVzL6nO+aiZOqxBCgcA3ZLfp4W9iHFUELwq8132TS7pUReJV+bcRjtNKdqm/Ep1sD/h01eAcTBtgrBQ==}
|
|
||||||
engines: {node: '>=10.0.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/supercluster/7.1.4:
|
/supercluster/7.1.4:
|
||||||
resolution: {integrity: sha512-GhKkRM1jMR6WUwGPw05fs66pOFWhf59lXq+Q3J3SxPvhNcmgOtLRV6aVQPMRsmXdpaeFJGivt+t7QXUPL3ff4g==}
|
resolution: {integrity: sha512-GhKkRM1jMR6WUwGPw05fs66pOFWhf59lXq+Q3J3SxPvhNcmgOtLRV6aVQPMRsmXdpaeFJGivt+t7QXUPL3ff4g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4904,8 +4914,8 @@ packages:
|
|||||||
strip-ansi: 6.0.1
|
strip-ansi: 6.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/tailwindcss/3.0.5_16a290f6d0e3717bf6d2667234aebd30:
|
/tailwindcss/3.0.6_16a290f6d0e3717bf6d2667234aebd30:
|
||||||
resolution: {integrity: sha512-59pNgzx2o+wkAk7IZGIH7H9eNS53gzZGrO3+NPyOEWHDbquHgiLL/c993T5t1vPSAeBxox4X5OgZwNuRvXVf+g==}
|
resolution: {integrity: sha512-+CA2f09rbHFDsdQ1iDvsOGbF1tZFmyPoRhUeaF9/5FRT5GYObtp+UjTSCdmeDcu6T90bx4WAaOkddYFPBkjbAA==}
|
||||||
engines: {node: '>=12.13.0'}
|
engines: {node: '>=12.13.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -5149,6 +5159,19 @@ packages:
|
|||||||
react-dom: 17.0.2_react@17.0.2
|
react-dom: 17.0.2_react@17.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/use-isomorphic-layout-effect/1.1.1_cfedea9b3ed0faf0dded75c187406c5e:
|
||||||
|
resolution: {integrity: sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
react: ^16.8.0 || ^17.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 17.0.37
|
||||||
|
react: 17.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/util-deprecate/1.0.2:
|
/util-deprecate/1.0.2:
|
||||||
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
|
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -5170,7 +5193,7 @@ packages:
|
|||||||
- rollup
|
- rollup
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-pwa/0.11.12_vite@2.7.2:
|
/vite-plugin-pwa/0.11.12_vite@2.7.3:
|
||||||
resolution: {integrity: sha512-XqFmA4y9C4RBb5osSsa26GVwOSwbzf2GNVcT5+06KYYdguqLpuI9FW7iV/akZqg0OUNUpH4tHfme8SnHA4PIXA==}
|
resolution: {integrity: sha512-XqFmA4y9C4RBb5osSsa26GVwOSwbzf2GNVcT5+06KYYdguqLpuI9FW7iV/akZqg0OUNUpH4tHfme8SnHA4PIXA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: ^2.0.0
|
vite: ^2.0.0
|
||||||
@@ -5179,7 +5202,7 @@ packages:
|
|||||||
fast-glob: 3.2.7
|
fast-glob: 3.2.7
|
||||||
pretty-bytes: 5.6.0
|
pretty-bytes: 5.6.0
|
||||||
rollup: 2.61.1
|
rollup: 2.61.1
|
||||||
vite: 2.7.2
|
vite: 2.7.3
|
||||||
workbox-build: 6.4.2
|
workbox-build: 6.4.2
|
||||||
workbox-window: 6.4.2
|
workbox-window: 6.4.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -5188,8 +5211,8 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite/2.7.2:
|
/vite/2.7.3:
|
||||||
resolution: {integrity: sha512-wMffVVdKZRZP/HwW3yttKL8X+IJePz7bUcnGm0vqljffpVwHpjWC3duZtJQHAGvy+wrTjmwU7vkULpZ1dVXY6w==}
|
resolution: {integrity: sha512-GAY1P+9fLJOju1SRm8+hykVnEXog+E+KXuqqyMBQDriKCUIKzWnPn142yNNhSdf/ixYGYdUa5ce3A8WaEajzGw==}
|
||||||
engines: {node: '>=12.2.0'}
|
engines: {node: '>=12.2.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|||||||
+36
-3
@@ -1,9 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { FiBell } from 'react-icons/fi';
|
||||||
|
|
||||||
import { DeviceStatus } from '@app/components/menu/buttons/DeviceStatus';
|
import { DeviceStatus } from '@app/components/menu/buttons/DeviceStatus';
|
||||||
import { useAppSelector } from '@app/hooks/redux';
|
import { useAppDispatch, useAppSelector } from '@app/hooks/redux';
|
||||||
import { Connection } from '@components/Connection';
|
import { Connection } from '@components/Connection';
|
||||||
import { MobileNavToggle } from '@components/menu/buttons/MobileNavToggle';
|
import { MobileNavToggle } from '@components/menu/buttons/MobileNavToggle';
|
||||||
|
import { Notifications } from '@components/menu/buttons/Notifications';
|
||||||
import { ThemeToggle } from '@components/menu/buttons/ThemeToggle';
|
import { ThemeToggle } from '@components/menu/buttons/ThemeToggle';
|
||||||
import { Logo } from '@components/menu/Logo';
|
import { Logo } from '@components/menu/Logo';
|
||||||
import { MobileNav } from '@components/menu/MobileNav';
|
import { MobileNav } from '@components/menu/MobileNav';
|
||||||
@@ -16,22 +19,51 @@ import { NotFound } from '@pages/NotFound';
|
|||||||
import { Plugins } from '@pages/Plugins/Index';
|
import { Plugins } from '@pages/Plugins/Index';
|
||||||
import { Settings } from '@pages/settings/Index';
|
import { Settings } from '@pages/settings/Index';
|
||||||
|
|
||||||
|
import { addNotification, removeNotification } from './core/slices/appSlice.js';
|
||||||
|
|
||||||
export const App = (): JSX.Element => {
|
export const App = (): JSX.Element => {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const notifications = useAppSelector((state) => state.app.notifications);
|
||||||
const darkMode = useAppSelector((state) => state.app.darkMode);
|
const darkMode = useAppSelector((state) => state.app.darkMode);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
if (
|
||||||
|
Notification.permission !== 'granted' &&
|
||||||
|
notifications.findIndex((n) => n.id === 'notification-permission') === -1
|
||||||
|
) {
|
||||||
|
dispatch(
|
||||||
|
addNotification({
|
||||||
|
id: 'notification-permission',
|
||||||
|
icon: <FiBell className="w-4 h-4" />,
|
||||||
|
read: Notification.permission === 'denied',
|
||||||
|
title: 'Enable Push Notifications',
|
||||||
|
action: {
|
||||||
|
message: 'Enable',
|
||||||
|
action: async () => await requestNotificationPermission(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notification.permission === ''
|
||||||
requestNotificationPermission().catch((e) => {
|
requestNotificationPermission().catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
}, []);
|
}, [dispatch, notifications]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (Notification.permission === 'granted') {
|
||||||
|
dispatch(removeNotification('notification-permission'));
|
||||||
|
}
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`h-screen w-screen ${darkMode ? 'dark' : ''}`}>
|
<div className={`h-screen w-screen ${darkMode ? 'dark' : ''}`}>
|
||||||
<Connection />
|
<Connection />
|
||||||
<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 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="w-full overflow-hidden bg-white border-b border-gray-300 md:mt-6 md:mx-6 md:py-2 md:rounded-t-3xl dark:border-gray-600 md:shadow-md dark:bg-primaryDark">
|
||||||
<div className="flex items-center justify-between h-12 px-4 md:px-6">
|
<div className="flex items-center justify-between h-12 px-4 md:px-6">
|
||||||
<div className="hidden md:flex">
|
<div className="hidden md:flex">
|
||||||
<Logo />
|
<Logo />
|
||||||
@@ -40,6 +72,7 @@ export const App = (): JSX.Element => {
|
|||||||
<MobileNavToggle />
|
<MobileNavToggle />
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<DeviceStatus />
|
<DeviceStatus />
|
||||||
|
<Notifications />
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ export const Connection = (): JSX.Element => {
|
|||||||
{state.deviceStatus ===
|
{state.deviceStatus ===
|
||||||
Types.DeviceStatusEnum.DEVICE_CONNECTED && (
|
Types.DeviceStatusEnum.DEVICE_CONNECTED && (
|
||||||
<Button
|
<Button
|
||||||
padding={2}
|
|
||||||
border
|
border
|
||||||
onClick={async (): Promise<void> => {
|
onClick={async (): Promise<void> => {
|
||||||
await connection.disconnect();
|
await connection.disconnect();
|
||||||
|
|||||||
@@ -3,13 +3,15 @@ import React from 'react';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { FiCheck } from 'react-icons/fi';
|
import { FiCheck } from 'react-icons/fi';
|
||||||
|
|
||||||
|
import { useAppDispatch } from '@app/hooks/redux';
|
||||||
import { Button } from '@components/generic/Button';
|
import { Button } from '@components/generic/Button';
|
||||||
import { IconButton } from '@components/generic/IconButton';
|
import { IconButton } from '@components/generic/IconButton';
|
||||||
import { serial, setConnection } from '@core/connection';
|
import { serial, setConnection } from '@core/connection';
|
||||||
import { connType } from '@core/slices/appSlice';
|
import { connType, setConnectionParams } from '@core/slices/appSlice';
|
||||||
|
|
||||||
export const Serial = (): JSX.Element => {
|
export const Serial = (): JSX.Element => {
|
||||||
const [serialDevices, setSerialDevices] = React.useState<SerialPort[]>([]);
|
const [serialDevices, setSerialDevices] = React.useState<SerialPort[]>([]);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const { register, handleSubmit, control } = useForm<{
|
const { register, handleSubmit, control } = useForm<{
|
||||||
device?: SerialPort;
|
device?: SerialPort;
|
||||||
@@ -45,6 +47,14 @@ export const Serial = (): JSX.Element => {
|
|||||||
</div>
|
</div>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={async (): Promise<void> => {
|
onClick={async (): Promise<void> => {
|
||||||
|
dispatch(
|
||||||
|
setConnectionParams({
|
||||||
|
type: connType.SERIAL,
|
||||||
|
params: {
|
||||||
|
port: device,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
await setConnection(connType.SERIAL);
|
await setConnection(connType.SERIAL);
|
||||||
}}
|
}}
|
||||||
icon={<FiCheck />}
|
icon={<FiCheck />}
|
||||||
|
|||||||
@@ -6,23 +6,21 @@ type DefaultButtonProps = JSX.IntrinsicElements['button'];
|
|||||||
|
|
||||||
interface ButtonProps extends DefaultButtonProps {
|
interface ButtonProps extends DefaultButtonProps {
|
||||||
icon?: JSX.Element;
|
icon?: JSX.Element;
|
||||||
circle?: boolean;
|
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
border?: boolean;
|
border?: boolean;
|
||||||
padding?: number;
|
padding?: string;
|
||||||
confirmAction?: () => void;
|
confirmAction?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Button = ({
|
export const Button = ({
|
||||||
icon,
|
icon,
|
||||||
circle,
|
|
||||||
className,
|
className,
|
||||||
active,
|
active,
|
||||||
border,
|
border,
|
||||||
confirmAction,
|
confirmAction,
|
||||||
disabled,
|
disabled,
|
||||||
children,
|
children,
|
||||||
padding = 3,
|
padding = '2',
|
||||||
...props
|
...props
|
||||||
}: ButtonProps): JSX.Element => {
|
}: ButtonProps): JSX.Element => {
|
||||||
const [hasConfirmed, setHasConfirmed] = React.useState(false);
|
const [hasConfirmed, setHasConfirmed] = React.useState(false);
|
||||||
@@ -42,27 +40,17 @@ export const Button = ({
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
onClick={handleConfirm}
|
onClick={handleConfirm}
|
||||||
className={`items-center select-none flex dark:text-white active:scale-95 transition duration-200 ease-in-out ${
|
className={`items-center select-none flex border border-transparent dark:text-white active:scale-95 transition duration-200 ease-in-out focus-within:border-primary dark:focus-within:border-primary focus-within:shadow-border rounded-md p-${padding} space-x-3 text-sm ${
|
||||||
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-${padding} space-x-3 text-sm`
|
|
||||||
} ${
|
} ${
|
||||||
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-gray-400 dark:border-gray-200' : ''} ${className}`}
|
||||||
border ? 'border border-gray-400 dark:border-gray-200' : ''
|
|
||||||
} ${className}`}
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{icon && (
|
{icon && (
|
||||||
<div
|
<div className="text-gray-500 dark:text-gray-400">
|
||||||
className={`text-gray-500 dark:text-gray-400 ${
|
|
||||||
circle ? 'mx-auto' : ''
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{hasConfirmed ? <FiCheck /> : icon}
|
{hasConfirmed ? <FiCheck /> : icon}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const Navigation = ({
|
|||||||
>
|
>
|
||||||
<div onClick={onClick}>
|
<div onClick={onClick}>
|
||||||
<Button
|
<Button
|
||||||
icon={<FiMessageSquare className="w-6 h-6" />}
|
icon={<FiMessageSquare className="w-5 h-5" />}
|
||||||
active={route.name === 'messages'}
|
active={route.name === 'messages'}
|
||||||
className="w-full md:w-auto"
|
className="w-full md:w-auto"
|
||||||
{...routes.messages().link}
|
{...routes.messages().link}
|
||||||
@@ -32,7 +32,7 @@ export const Navigation = ({
|
|||||||
</div>
|
</div>
|
||||||
<div onClick={onClick}>
|
<div onClick={onClick}>
|
||||||
<Button
|
<Button
|
||||||
icon={<FiGrid className="w-6 h-6" />}
|
icon={<FiGrid className="w-5 h-5" />}
|
||||||
className="w-full md:w-auto"
|
className="w-full md:w-auto"
|
||||||
active={route.name === 'nodes'}
|
active={route.name === 'nodes'}
|
||||||
{...routes.nodes().link}
|
{...routes.nodes().link}
|
||||||
@@ -42,7 +42,7 @@ export const Navigation = ({
|
|||||||
</div>
|
</div>
|
||||||
<div onClick={onClick}>
|
<div onClick={onClick}>
|
||||||
<Button
|
<Button
|
||||||
icon={<FiPackage className="w-6 h-6" />}
|
icon={<FiPackage className="w-5 h-5" />}
|
||||||
className="w-full md:w-auto"
|
className="w-full md:w-auto"
|
||||||
active={route.name === 'plugins'}
|
active={route.name === 'plugins'}
|
||||||
{...routes.plugins().link}
|
{...routes.plugins().link}
|
||||||
@@ -52,7 +52,7 @@ export const Navigation = ({
|
|||||||
</div>
|
</div>
|
||||||
<div onClick={onClick}>
|
<div onClick={onClick}>
|
||||||
<Button
|
<Button
|
||||||
icon={<FiSettings className="w-6 h-6" />}
|
icon={<FiSettings className="w-5 h-5" />}
|
||||||
className="w-full md:w-auto"
|
className="w-full md:w-auto"
|
||||||
active={route.name === 'settings'}
|
active={route.name === 'settings'}
|
||||||
{...routes.settings().link}
|
{...routes.settings().link}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const DeviceStatus = (): JSX.Element => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
padding={0}
|
padding="0"
|
||||||
active
|
active
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
dispatch(dispatch(openConnectionModal()));
|
dispatch(dispatch(openConnectionModal()));
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { FiBell, FiX } from 'react-icons/fi';
|
||||||
|
|
||||||
|
import { useAppSelector } from '@app/hooks/redux';
|
||||||
|
import { Button } from '@components/generic/Button';
|
||||||
|
import { IconButton } from '@components/generic/IconButton';
|
||||||
|
import { shift, useFloating } from '@floating-ui/react-dom';
|
||||||
|
import { Popover } from '@headlessui/react';
|
||||||
|
|
||||||
|
export const Notifications = (): JSX.Element => {
|
||||||
|
const [unreadCount, setUnreadCount] = React.useState(0);
|
||||||
|
const notifications = useAppSelector((state) => state.app.notifications);
|
||||||
|
|
||||||
|
const { x, y, reference, floating, strategy } = useFloating({
|
||||||
|
placement: 'bottom',
|
||||||
|
middleware: [shift()],
|
||||||
|
});
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
setUnreadCount(
|
||||||
|
notifications.filter((notification) => !notification.read).length,
|
||||||
|
);
|
||||||
|
}, [notifications]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover>
|
||||||
|
<Popover.Button as="div" className="relative" ref={reference}>
|
||||||
|
<IconButton icon={<FiBell className="w-5 h-5" />} />
|
||||||
|
{unreadCount > 0 && (
|
||||||
|
<div className="absolute pointer-events-none top-1 right-1">
|
||||||
|
<div className="w-3 h-3 text-xs font-semibold leading-3 text-center text-white bg-orange-500 rounded-full">
|
||||||
|
{unreadCount}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Popover.Button>
|
||||||
|
|
||||||
|
<Popover.Panel
|
||||||
|
ref={floating}
|
||||||
|
style={{
|
||||||
|
position: strategy,
|
||||||
|
top: y ?? '',
|
||||||
|
left: x ?? '',
|
||||||
|
}}
|
||||||
|
className="fixed z-50 border border-gray-300 rounded-md shadow-md w-72 bg-primaryDark dark:border-gray-600"
|
||||||
|
>
|
||||||
|
<div className="divide-y divide-gray-600">
|
||||||
|
{notifications.map((notification, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`p-1 flex text-sm justify-between ${
|
||||||
|
notification.read
|
||||||
|
? 'text-gray-600 dark:text-gray-300'
|
||||||
|
: 'text-gray-900 dark:text-white'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="my-auto">{notification.icon}</div>
|
||||||
|
|
||||||
|
<div className="my-auto font-light">{notification.title}</div>
|
||||||
|
|
||||||
|
<div className="flex space-x-1">
|
||||||
|
{notification.action ? (
|
||||||
|
<div className="my-auto w-18">
|
||||||
|
<Button
|
||||||
|
border
|
||||||
|
padding="0.5"
|
||||||
|
onClick={notification.action.action}
|
||||||
|
>
|
||||||
|
{notification.action.message}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="w-16" />
|
||||||
|
)}
|
||||||
|
<IconButton icon={<FiX />} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Popover.Panel>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -34,8 +34,7 @@ export const connectionUrl = state.hostOverrideEnabled
|
|||||||
? state.hostOverride
|
? state.hostOverride
|
||||||
: import.meta.env.PROD
|
: import.meta.env.PROD
|
||||||
? window.location.hostname
|
? window.location.hostname
|
||||||
: (import.meta.env.VITE_PUBLIC_DEVICE_IP as string) ??
|
: (import.meta.env.VITE_PUBLIC_DEVICE_IP as string) ?? 'meshtastic.local';
|
||||||
'http://meshtastic.local';
|
|
||||||
|
|
||||||
export const ble = new IBLEConnection();
|
export const ble = new IBLEConnection();
|
||||||
export const serial = new ISerialConnection();
|
export const serial = new ISerialConnection();
|
||||||
|
|||||||
@@ -10,6 +10,17 @@ export enum connType {
|
|||||||
SERIAL,
|
SERIAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
id: string;
|
||||||
|
icon: React.ReactNode;
|
||||||
|
title: string;
|
||||||
|
action?: {
|
||||||
|
message: string;
|
||||||
|
action: () => void;
|
||||||
|
};
|
||||||
|
read: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface AppState {
|
interface AppState {
|
||||||
mobileNavOpen: boolean;
|
mobileNavOpen: boolean;
|
||||||
connectionModalOpen: boolean;
|
connectionModalOpen: boolean;
|
||||||
@@ -21,6 +32,7 @@ interface AppState {
|
|||||||
HTTP: Types.HTTPConnectionParameters;
|
HTTP: Types.HTTPConnectionParameters;
|
||||||
SERIAL: Types.SerialConnectionParameters;
|
SERIAL: Types.SerialConnectionParameters;
|
||||||
};
|
};
|
||||||
|
notifications: Notification[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: AppState = {
|
const initialState: AppState = {
|
||||||
@@ -39,6 +51,7 @@ const initialState: AppState = {
|
|||||||
},
|
},
|
||||||
SERIAL: {},
|
SERIAL: {},
|
||||||
},
|
},
|
||||||
|
notifications: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const appSlice = createSlice({
|
export const appSlice = createSlice({
|
||||||
@@ -78,6 +91,17 @@ export const appSlice = createSlice({
|
|||||||
state.connectionParams[connType[action.payload.type]] =
|
state.connectionParams[connType[action.payload.type]] =
|
||||||
action.payload.params;
|
action.payload.params;
|
||||||
},
|
},
|
||||||
|
addNotification(state, action: PayloadAction<Notification>) {
|
||||||
|
state.notifications.push(action.payload);
|
||||||
|
},
|
||||||
|
removeNotification(state, action: PayloadAction<string>) {
|
||||||
|
state.notifications.splice(
|
||||||
|
state.notifications.findIndex(
|
||||||
|
(notification) => notification.id === action.payload,
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -90,6 +114,8 @@ export const {
|
|||||||
setCurrentPage,
|
setCurrentPage,
|
||||||
setConnType,
|
setConnType,
|
||||||
setConnectionParams,
|
setConnectionParams,
|
||||||
|
addNotification,
|
||||||
|
removeNotification,
|
||||||
} = appSlice.actions;
|
} = appSlice.actions;
|
||||||
|
|
||||||
export default appSlice.reducer;
|
export default appSlice.reducer;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import JSONPretty from 'react-json-pretty';
|
|||||||
import { useAppSelector } from '@app/hooks/redux';
|
import { useAppSelector } from '@app/hooks/redux';
|
||||||
import { Channel } from '@components/Channel';
|
import { Channel } from '@components/Channel';
|
||||||
import { FormFooter } from '@components/FormFooter';
|
import { FormFooter } from '@components/FormFooter';
|
||||||
import { Button } from '@components/generic/Button';
|
|
||||||
import { Card } from '@components/generic/Card';
|
import { Card } from '@components/generic/Card';
|
||||||
import { Cover } from '@components/generic/Cover';
|
import { Cover } from '@components/generic/Cover';
|
||||||
import { Checkbox } from '@components/generic/form/Checkbox';
|
import { Checkbox } from '@components/generic/form/Checkbox';
|
||||||
@@ -249,18 +248,6 @@ export const Channels = ({
|
|||||||
isPrimary={channel.channel.index === 0}
|
isPrimary={channel.channel.index === 0}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<div className="flex justify-between">
|
|
||||||
<div
|
|
||||||
onClick={(): Promise<void> => {
|
|
||||||
return connection.confirmSetChannel();
|
|
||||||
}}
|
|
||||||
className="text-sm font-thin text-gray-400 dark:text-gray-300"
|
|
||||||
>
|
|
||||||
Please ensure any changes are working before confirming
|
|
||||||
</div>
|
|
||||||
<Button active>Confirm</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ export const Interface = ({
|
|||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
setNavOpen && setNavOpen(!navOpen);
|
setNavOpen && setNavOpen(!navOpen);
|
||||||
}}
|
}}
|
||||||
circle
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
footer={
|
footer={
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ export const WiFi = ({ navOpen, setNavOpen }: WiFiProps): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="password"
|
type="password"
|
||||||
|
autoComplete="off"
|
||||||
label={t('strings.wifi_psk')}
|
label={t('strings.wifi_psk')}
|
||||||
disabled={watchWifiApMode}
|
disabled={watchWifiApMode}
|
||||||
{...register('wifiPassword')}
|
{...register('wifiPassword')}
|
||||||
|
|||||||
Reference in New Issue
Block a user