mirror of
https://github.com/meshtastic/web.git
synced 2026-05-18 19:25:09 -04:00
New UI colors and changes
This commit is contained in:
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshtastic-web",
|
||||
"version": "1.0",
|
||||
"version": "1.0.0",
|
||||
"description": "Meshtastic web client",
|
||||
"license": "GPL-3.0-only",
|
||||
"scripts": {
|
||||
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "^0.4.3",
|
||||
"@headlessui/react": "^1.4.2",
|
||||
"@meshtastic/components": "^1.0.15",
|
||||
"@headlessui/react": "^1.4.3",
|
||||
"@meshtastic/components": "^1.0.17",
|
||||
"@meshtastic/meshtasticjs": "^0.6.38",
|
||||
"@reduxjs/toolkit": "^1.7.1",
|
||||
"base64-js": "^1.5.1",
|
||||
@@ -26,7 +26,7 @@
|
||||
"react-dom": "^17.0.2",
|
||||
"react-error-boundary": "^3.1.4",
|
||||
"react-file-icon": "^1.1.0",
|
||||
"react-hook-form": "^7.23.0",
|
||||
"react-hook-form": "^7.24.0",
|
||||
"react-i18next": "^11.15.3",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-json-pretty": "^2.2.0",
|
||||
@@ -64,7 +64,7 @@
|
||||
"gzipper": "^6.2.1",
|
||||
"postcss": "^8.4.5",
|
||||
"prettier": "^2.5.1",
|
||||
"tailwindcss": "^3.0.13",
|
||||
"tailwindcss": "^3.0.15",
|
||||
"tar": "^6.1.11",
|
||||
"typescript": "^4.5.4",
|
||||
"vite": "^2.7.12",
|
||||
|
||||
100
pnpm-lock.yaml
generated
100
pnpm-lock.yaml
generated
@@ -2,8 +2,8 @@ lockfileVersion: 5.3
|
||||
|
||||
specifiers:
|
||||
'@floating-ui/react-dom': ^0.4.3
|
||||
'@headlessui/react': ^1.4.2
|
||||
'@meshtastic/components': ^1.0.15
|
||||
'@headlessui/react': ^1.4.3
|
||||
'@meshtastic/components': ^1.0.17
|
||||
'@meshtastic/meshtasticjs': ^0.6.38
|
||||
'@reduxjs/toolkit': ^1.7.1
|
||||
'@types/mapbox-gl': ^2.6.0
|
||||
@@ -38,7 +38,7 @@ specifiers:
|
||||
react-dom: ^17.0.2
|
||||
react-error-boundary: ^3.1.4
|
||||
react-file-icon: ^1.1.0
|
||||
react-hook-form: ^7.23.0
|
||||
react-hook-form: ^7.24.0
|
||||
react-i18next: ^11.15.3
|
||||
react-icons: ^4.3.1
|
||||
react-json-pretty: ^2.2.0
|
||||
@@ -48,7 +48,7 @@ specifiers:
|
||||
react-use-clipboard: ^1.0.7
|
||||
rfc4648: ^1.5.1
|
||||
swr: ^1.1.2
|
||||
tailwindcss: ^3.0.13
|
||||
tailwindcss: ^3.0.15
|
||||
tar: ^6.1.11
|
||||
timeago-react: ^3.0.4
|
||||
type-route: ^0.6.0
|
||||
@@ -61,8 +61,8 @@ specifiers:
|
||||
|
||||
dependencies:
|
||||
'@floating-ui/react-dom': 0.4.3_b3482aaf5744fc7c2aeb7941b0e0a78f
|
||||
'@headlessui/react': 1.4.2_react-dom@17.0.2+react@17.0.2
|
||||
'@meshtastic/components': 1.0.15_@types+react@17.0.38
|
||||
'@headlessui/react': 1.4.3_react-dom@17.0.2+react@17.0.2
|
||||
'@meshtastic/components': 1.0.17_@types+react@17.0.38
|
||||
'@meshtastic/meshtasticjs': 0.6.38
|
||||
'@reduxjs/toolkit': 1.7.1_react-redux@7.2.6+react@17.0.2
|
||||
base64-js: 1.5.1
|
||||
@@ -74,7 +74,7 @@ dependencies:
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react-error-boundary: 3.1.4_react@17.0.2
|
||||
react-file-icon: 1.1.0_react-dom@17.0.2+react@17.0.2
|
||||
react-hook-form: 7.23.0_react@17.0.2
|
||||
react-hook-form: 7.24.0_react@17.0.2
|
||||
react-i18next: 11.15.3_bc514be083f1f06b28df24d5713fc600
|
||||
react-icons: 4.3.1_react@17.0.2
|
||||
react-json-pretty: 2.2.0_react-dom@17.0.2+react@17.0.2
|
||||
@@ -112,7 +112,7 @@ devDependencies:
|
||||
gzipper: 6.2.1
|
||||
postcss: 8.4.5
|
||||
prettier: 2.5.1
|
||||
tailwindcss: 3.0.13_ef48b3b8837f8a23677bffe8f9cd866d
|
||||
tailwindcss: 3.0.15_ef48b3b8837f8a23677bffe8f9cd866d
|
||||
tar: 6.1.11
|
||||
typescript: 4.5.4
|
||||
vite: 2.7.12
|
||||
@@ -1443,8 +1443,8 @@ packages:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@headlessui/react/1.4.2_react-dom@17.0.2+react@17.0.2:
|
||||
resolution: {integrity: sha512-N8tv7kLhg9qGKBkVdtg572BvKvWhmiudmeEpOCyNwzOsZHCXBtl8AazGikIfUS+vBoub20Fse3BjawXDVPPdug==}
|
||||
/@headlessui/react/1.4.3_react-dom@17.0.2+react@17.0.2:
|
||||
resolution: {integrity: sha512-n2IQkaaw0aAAlQS5MEXsM4uRK+w18CrM72EqnGRl/UBOQeQajad8oiKXR9Nk15jOzTFQjpxzrZMf1NxHidFBiw==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
react: ^16 || ^17 || ^18
|
||||
@@ -1524,8 +1524,8 @@ packages:
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: false
|
||||
|
||||
/@meshtastic/components/1.0.15_@types+react@17.0.38:
|
||||
resolution: {integrity: sha512-+ZT2I6shgtDTKBm3qpillRvG89wDxDf4gpD/EDhvECAjSTIFYjo0m3kiDSytVjJw/sLnj3LJljQ3U4o75J3uqw==}
|
||||
/@meshtastic/components/1.0.17_@types+react@17.0.38:
|
||||
resolution: {integrity: sha512-e9ETFrzQUtpxVHc6NiiYMCkr7Ml4v7xlbILWK3LV48ALMDojBAFKLHdxuClpt0Rszo91ORACSSVpUkJNfWnp1A==}
|
||||
dependencies:
|
||||
inter-ui: 3.19.3
|
||||
react: 17.0.2
|
||||
@@ -1588,7 +1588,7 @@ packages:
|
||||
reselect: 4.1.5
|
||||
dev: false
|
||||
|
||||
/@rollup/plugin-babel/5.3.0_@babel+core@7.16.7+rollup@2.63.0:
|
||||
/@rollup/plugin-babel/5.3.0_@babel+core@7.16.7+rollup@2.64.0:
|
||||
resolution: {integrity: sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1601,36 +1601,36 @@ packages:
|
||||
dependencies:
|
||||
'@babel/core': 7.16.7
|
||||
'@babel/helper-module-imports': 7.16.7
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.63.0
|
||||
rollup: 2.63.0
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.64.0
|
||||
rollup: 2.64.0
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-node-resolve/11.2.1_rollup@2.63.0:
|
||||
/@rollup/plugin-node-resolve/11.2.1_rollup@2.64.0:
|
||||
resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.63.0
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.64.0
|
||||
'@types/resolve': 1.17.1
|
||||
builtin-modules: 3.2.0
|
||||
deepmerge: 4.2.2
|
||||
is-module: 1.0.0
|
||||
resolve: 1.21.0
|
||||
rollup: 2.63.0
|
||||
rollup: 2.64.0
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-replace/2.4.2_rollup@2.63.0:
|
||||
/@rollup/plugin-replace/2.4.2_rollup@2.64.0:
|
||||
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0 || ^2.0.0
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.63.0
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.64.0
|
||||
magic-string: 0.25.7
|
||||
rollup: 2.63.0
|
||||
rollup: 2.64.0
|
||||
dev: true
|
||||
|
||||
/@rollup/pluginutils/3.1.0_rollup@2.63.0:
|
||||
/@rollup/pluginutils/3.1.0_rollup@2.64.0:
|
||||
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
peerDependencies:
|
||||
@@ -1639,7 +1639,7 @@ packages:
|
||||
'@types/estree': 0.0.39
|
||||
estree-walker: 1.0.1
|
||||
picomatch: 2.3.1
|
||||
rollup: 2.63.0
|
||||
rollup: 2.64.0
|
||||
dev: true
|
||||
|
||||
/@rollup/pluginutils/4.1.2:
|
||||
@@ -2313,7 +2313,7 @@ packages:
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001299
|
||||
electron-to-chromium: 1.4.45
|
||||
electron-to-chromium: 1.4.46
|
||||
escalade: 3.1.1
|
||||
node-releases: 2.0.1
|
||||
picocolors: 1.0.0
|
||||
@@ -2559,7 +2559,7 @@ packages:
|
||||
object-is: 1.1.5
|
||||
object-keys: 1.1.1
|
||||
object.assign: 4.1.2
|
||||
regexp.prototype.flags: 1.3.2
|
||||
regexp.prototype.flags: 1.4.1
|
||||
side-channel: 1.0.4
|
||||
which-boxed-primitive: 1.0.2
|
||||
which-collection: 1.0.1
|
||||
@@ -2678,8 +2678,8 @@ packages:
|
||||
jake: 10.8.2
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium/1.4.45:
|
||||
resolution: {integrity: sha512-czF9eYVuOmlY/vxyMQz2rGlNSjZpxNQYBe1gmQv7al171qOIhgyO9k7D5AKlgeTCSPKk+LHhj5ZyIdmEub9oNg==}
|
||||
/electron-to-chromium/1.4.46:
|
||||
resolution: {integrity: sha512-UtV0xUA/dibCKKP2JMxOpDtXR74zABevuUEH4K0tvduFSIoxRVcYmQsbB51kXsFTX8MmOyWMt8tuZAlmDOqkrQ==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex/8.0.0:
|
||||
@@ -3350,8 +3350,8 @@ packages:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
||||
/fast-glob/3.2.10:
|
||||
resolution: {integrity: sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A==}
|
||||
/fast-glob/3.2.11:
|
||||
resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
@@ -3576,7 +3576,7 @@ packages:
|
||||
dependencies:
|
||||
array-union: 2.1.0
|
||||
dir-glob: 3.0.1
|
||||
fast-glob: 3.2.10
|
||||
fast-glob: 3.2.11
|
||||
ignore: 5.2.0
|
||||
merge2: 1.4.1
|
||||
slash: 3.0.0
|
||||
@@ -4707,8 +4707,8 @@ packages:
|
||||
tinycolor2: 1.4.2
|
||||
dev: false
|
||||
|
||||
/react-hook-form/7.23.0_react@17.0.2:
|
||||
resolution: {integrity: sha512-bO1JCkPAjmpuKhfUpFhsjWn2RIPgWUpep8qpMAKCoc8NM8ytBA5nDx5p99wNhZWrblYQFvU+dVy9g1oYo/JKoQ==}
|
||||
/react-hook-form/7.24.0_react@17.0.2:
|
||||
resolution: {integrity: sha512-N2GT4wmdcgP5bw72q/a+vKUBqy14iNQz+4vaFBJLz9Bw+KNYKUjTzcV/kHfOYbcboMeHP2zgf4i4wTmAwrXssg==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17
|
||||
@@ -4916,8 +4916,8 @@ packages:
|
||||
'@babel/runtime': 7.16.7
|
||||
dev: true
|
||||
|
||||
/regexp.prototype.flags/1.3.2:
|
||||
resolution: {integrity: sha512-uaro52GSI5be7+ssxjxxnLlleDBN3VHIWQHvBhfeeSXRQkuV/0Jo/hBU+omYH6NUkM+LYpTHnRRf2W/v+x7LzQ==}
|
||||
/regexp.prototype.flags/1.4.1:
|
||||
resolution: {integrity: sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
@@ -5014,22 +5014,22 @@ packages:
|
||||
magic-string: 0.25.7
|
||||
dev: true
|
||||
|
||||
/rollup-plugin-terser/7.0.2_rollup@2.63.0:
|
||||
/rollup-plugin-terser/7.0.2_rollup@2.64.0:
|
||||
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
|
||||
peerDependencies:
|
||||
rollup: ^2.0.0
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.16.7
|
||||
jest-worker: 26.6.2
|
||||
rollup: 2.63.0
|
||||
rollup: 2.64.0
|
||||
serialize-javascript: 4.0.0
|
||||
terser: 5.10.0
|
||||
transitivePeerDependencies:
|
||||
- acorn
|
||||
dev: true
|
||||
|
||||
/rollup/2.63.0:
|
||||
resolution: {integrity: sha512-nps0idjmD+NXl6OREfyYXMn/dar3WGcyKn+KBzPdaLecub3x/LrId0wUcthcr8oZUAcZAR8NKcfGGFlNgGL1kQ==}
|
||||
/rollup/2.64.0:
|
||||
resolution: {integrity: sha512-+c+lbw1lexBKSMb1yxGDVfJ+vchJH3qLbmavR+awDinTDA2C5Ug9u7lkOzj62SCu0PKUExsW36tpgW7Fmpn3yQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
@@ -5231,7 +5231,7 @@ packages:
|
||||
get-intrinsic: 1.1.1
|
||||
has-symbols: 1.0.2
|
||||
internal-slot: 1.0.3
|
||||
regexp.prototype.flags: 1.3.2
|
||||
regexp.prototype.flags: 1.4.1
|
||||
side-channel: 1.0.4
|
||||
dev: true
|
||||
|
||||
@@ -5357,8 +5357,8 @@ packages:
|
||||
strip-ansi: 6.0.1
|
||||
dev: true
|
||||
|
||||
/tailwindcss/3.0.13_ef48b3b8837f8a23677bffe8f9cd866d:
|
||||
resolution: {integrity: sha512-raRPGFwQSGXn/3h0ttHND9jyPYfqk/ur2NXtlQuK25+ZnrCjlH1s1j4/oPswHGMoZzGNykUVycZ/LcROanUE0A==}
|
||||
/tailwindcss/3.0.15_ef48b3b8837f8a23677bffe8f9cd866d:
|
||||
resolution: {integrity: sha512-bT2iy7FtjwgsXik4ZoJnHXR+SRCiGR1W95fVqpLZebr64m4ahwUwRbIAc5w5+2fzr1YF4Ct2eI7dojMRRl8sVQ==}
|
||||
engines: {node: '>=12.13.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -5374,7 +5374,7 @@ packages:
|
||||
detective: 5.2.0
|
||||
didyoumean: 1.2.2
|
||||
dlv: 1.1.3
|
||||
fast-glob: 3.2.10
|
||||
fast-glob: 3.2.11
|
||||
glob-parent: 6.0.2
|
||||
is-glob: 4.0.3
|
||||
normalize-path: 3.0.0
|
||||
@@ -5690,9 +5690,9 @@ packages:
|
||||
vite: ^2.0.0
|
||||
dependencies:
|
||||
debug: 4.3.3
|
||||
fast-glob: 3.2.10
|
||||
fast-glob: 3.2.11
|
||||
pretty-bytes: 5.6.0
|
||||
rollup: 2.63.0
|
||||
rollup: 2.64.0
|
||||
vite: 2.7.12
|
||||
workbox-build: 6.4.2
|
||||
workbox-window: 6.4.2
|
||||
@@ -5721,7 +5721,7 @@ packages:
|
||||
esbuild: 0.13.15
|
||||
postcss: 8.4.5
|
||||
resolve: 1.21.0
|
||||
rollup: 2.63.0
|
||||
rollup: 2.64.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
@@ -5826,9 +5826,9 @@ packages:
|
||||
'@babel/core': 7.16.7
|
||||
'@babel/preset-env': 7.16.8_@babel+core@7.16.7
|
||||
'@babel/runtime': 7.16.7
|
||||
'@rollup/plugin-babel': 5.3.0_@babel+core@7.16.7+rollup@2.63.0
|
||||
'@rollup/plugin-node-resolve': 11.2.1_rollup@2.63.0
|
||||
'@rollup/plugin-replace': 2.4.2_rollup@2.63.0
|
||||
'@rollup/plugin-babel': 5.3.0_@babel+core@7.16.7+rollup@2.64.0
|
||||
'@rollup/plugin-node-resolve': 11.2.1_rollup@2.64.0
|
||||
'@rollup/plugin-replace': 2.4.2_rollup@2.64.0
|
||||
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
||||
ajv: 8.8.2
|
||||
common-tags: 1.8.2
|
||||
@@ -5837,8 +5837,8 @@ packages:
|
||||
glob: 7.2.0
|
||||
lodash: 4.17.21
|
||||
pretty-bytes: 5.6.0
|
||||
rollup: 2.63.0
|
||||
rollup-plugin-terser: 7.0.2_rollup@2.63.0
|
||||
rollup: 2.64.0
|
||||
rollup-plugin-terser: 7.0.2_rollup@2.64.0
|
||||
source-map: 0.8.0-beta.0
|
||||
source-map-url: 0.4.1
|
||||
stringify-object: 3.3.0
|
||||
|
||||
28
src/App.tsx
28
src/App.tsx
@@ -3,13 +3,8 @@ import React from 'react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { FiBell } from 'react-icons/fi';
|
||||
|
||||
import { DeviceStatus } from '@app/components/menu/buttons/DeviceStatus';
|
||||
import { Connection } from '@components/Connection';
|
||||
import { MobileNavToggle } from '@components/menu/buttons/MobileNavToggle';
|
||||
import { Notifications } from '@components/menu/buttons/Notifications';
|
||||
import { ThemeToggle } from '@components/menu/buttons/ThemeToggle';
|
||||
import { Logo } from '@components/menu/Logo';
|
||||
import { MobileNav } from '@components/menu/MobileNav';
|
||||
import { Navigation } from '@components/menu/Navigation';
|
||||
import { useRoute } from '@core/router';
|
||||
import { requestNotificationPermission } from '@core/utils/notifications';
|
||||
@@ -23,6 +18,7 @@ import { Settings } from '@pages/settings/Index';
|
||||
|
||||
import { ErrorFallback } from './components/ErrorFallback';
|
||||
import { MapboxProvider } from './components/MapBox/MapboxProvider';
|
||||
import { BottomNav } from './components/menu/BottomNav';
|
||||
import { addNotification, removeNotification } from './core/slices/appSlice';
|
||||
|
||||
export const App = (): JSX.Element => {
|
||||
@@ -65,27 +61,20 @@ export const App = (): JSX.Element => {
|
||||
return (
|
||||
<div className={`h-screen w-screen ${darkMode ? 'dark' : ''}`}>
|
||||
<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-secondaryDark">
|
||||
<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: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="hidden md:flex">
|
||||
<div className="w-full overflow-hidden bg-white border-b border-gray-300 dark:border-gray-600 md:shadow-md dark:bg-secondaryDark">
|
||||
<div className="flex items-center justify-between h-12 px-4">
|
||||
<div className="flex">
|
||||
<Logo />
|
||||
</div>
|
||||
<Navigation className="hidden md:flex" />
|
||||
<MobileNavToggle />
|
||||
<div className="flex items-center space-x-2">
|
||||
<DeviceStatus />
|
||||
<Notifications />
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
<Navigation className="flex" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MobileNav />
|
||||
|
||||
<div className="flex flex-grow w-full min-h-0 md:px-6 md:mb-6">
|
||||
<div className="flex w-full bg-gray-100 md:shadow-xl md:overflow-hidden dark:bg-secondaryDark md:rounded-b-3xl">
|
||||
<div className="flex flex-grow w-full min-h-0">
|
||||
<div className="flex w-full bg-gray-100 md:shadow-xl md:overflow-hidden dark:bg-secondaryDark">
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||
{route.name === 'messages' && <Messages />}
|
||||
{route.name === 'nodes' && (
|
||||
@@ -99,6 +88,7 @@ export const App = (): JSX.Element => {
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
</div>
|
||||
<BottomNav />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
97
src/components/menu/BottomNav.tsx
Normal file
97
src/components/menu/BottomNav.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
FiBell,
|
||||
FiBluetooth,
|
||||
FiCpu,
|
||||
FiGitBranch,
|
||||
FiMoon,
|
||||
FiSun,
|
||||
FiWifi,
|
||||
} from 'react-icons/fi';
|
||||
|
||||
import {
|
||||
connType,
|
||||
openConnectionModal,
|
||||
setDarkModeEnabled,
|
||||
} from '@app/core/slices/appSlice';
|
||||
import { useAppDispatch } from '@hooks/useAppDispatch';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { Types } from '@meshtastic/meshtasticjs';
|
||||
|
||||
// export interface BottomNavProps {
|
||||
|
||||
// }
|
||||
|
||||
export const BottomNav = (): JSX.Element => {
|
||||
const dispatch = useAppDispatch();
|
||||
const meshtasticState = useAppSelector((state) => state.meshtastic);
|
||||
const appState = useAppSelector((state) => state.app);
|
||||
// @ts-ignore define version string global
|
||||
const version = window.__COMMIT_HASH__ as string;
|
||||
|
||||
return (
|
||||
<div className="flex justify-between bg-white border-t border-gray-300 dark:bg-secondaryDark dark:border-gray-600">
|
||||
<div
|
||||
className={`flex p-1 cursor-pointer group w-min hover:bg-opacity-80 ${
|
||||
[
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED,
|
||||
Types.DeviceStatusEnum.DEVICE_CONFIGURED,
|
||||
].includes(meshtasticState.deviceStatus)
|
||||
? 'bg-primary'
|
||||
: [
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTING,
|
||||
Types.DeviceStatusEnum.DEVICE_RECONNECTING,
|
||||
Types.DeviceStatusEnum.DEVICE_CONFIGURING,
|
||||
].includes(meshtasticState.deviceStatus)
|
||||
? 'bg-yellow-400'
|
||||
: 'bg-gray-400'
|
||||
}`}
|
||||
onClick={(): void => {
|
||||
dispatch(dispatch(openConnectionModal()));
|
||||
}}
|
||||
>
|
||||
{appState.connType === connType.BLE ? (
|
||||
<FiBluetooth className="mr-1 p-0.5 group-active:scale-90" />
|
||||
) : appState.connType === connType.SERIAL ? (
|
||||
<FiCpu className="mr-1 p-0.5 group-active:scale-90" />
|
||||
) : (
|
||||
<FiWifi className="mr-1 p-0.5 group-active:scale-90" />
|
||||
)}
|
||||
<div className="text-xs font-medium truncate group-active:scale-90">
|
||||
{meshtasticState.nodes.find(
|
||||
(node) => node.number === meshtasticState.radio.hardware.myNodeNum,
|
||||
)?.user?.longName ?? 'Disconnected'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex">
|
||||
<a
|
||||
href={`https://github.com/meshtastic/meshtastic-web/commit/${version}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="flex p-1 border-l border-gray-300 cursor-pointer select-none group dark:border-gray-600 dark:text-white hover:bg-gray-200 dark:hover:bg-primaryDark"
|
||||
>
|
||||
<FiGitBranch className="p-0.5 mr-1 group-active:scale-90" />
|
||||
<p className="text-xs opacity-60">{version}</p>
|
||||
</a>
|
||||
<div className="flex p-1 border-l border-gray-300 cursor-pointer select-none group dark:border-gray-600 dark:text-white hover:bg-gray-200 dark:hover:bg-primaryDark">
|
||||
<FiBell className="p-0.5 mr-1 group-active:scale-90" />
|
||||
<p className="text-xs opacity-60">Example Notification</p>
|
||||
</div>
|
||||
<div
|
||||
className="p-1 border-l border-gray-300 cursor-pointer group dark:border-gray-600 dark:text-white hover:bg-gray-200 dark:hover:bg-primaryDark"
|
||||
onClick={(): void => {
|
||||
dispatch(setDarkModeEnabled(!appState.darkMode));
|
||||
}}
|
||||
>
|
||||
{appState.darkMode ? (
|
||||
<FiSun className="p-0.5 group-active:scale-90" />
|
||||
) : (
|
||||
<FiMoon className="p-0.5 group-active:scale-90" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import { Drawer } from '@components/generic/Drawer';
|
||||
import { closeMobileNav } from '@core/slices/appSlice';
|
||||
import { useAppDispatch } from '@hooks/useAppDispatch';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
|
||||
import { Logo } from './Logo';
|
||||
import { Navigation } from './Navigation';
|
||||
|
||||
export const MobileNav = (): JSX.Element => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const mobileNavOpen = useAppSelector((state) => state.app.mobileNavOpen);
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
open={mobileNavOpen}
|
||||
onClose={(): void => {
|
||||
dispatch(closeMobileNav());
|
||||
}}
|
||||
className="z-50"
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
<div className="m-auto my-6">
|
||||
<Logo />
|
||||
</div>
|
||||
<Navigation
|
||||
onClick={(): void => {
|
||||
dispatch(closeMobileNav());
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Drawer>
|
||||
);
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
import type React from 'react';
|
||||
|
||||
import { FiGrid, FiMessageSquare, FiPackage, FiSettings } from 'react-icons/fi';
|
||||
import type { Link } from 'type-route';
|
||||
|
||||
import { routes, useRoute } from '@core/router';
|
||||
import { Button } from '@meshtastic/components';
|
||||
|
||||
type DefaultDivProps = JSX.IntrinsicElements['div'];
|
||||
|
||||
@@ -15,51 +15,59 @@ export const Navigation = ({
|
||||
...props
|
||||
}: NavigationProps): JSX.Element => {
|
||||
const route = useRoute();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`px-4 md:space-x-2 space-y-2 md:space-y-0 ${className}`}
|
||||
{...props}
|
||||
>
|
||||
<div onClick={onClick}>
|
||||
<Button
|
||||
icon={<FiMessageSquare className="w-5 h-5" />}
|
||||
active={route.name === 'messages'}
|
||||
className="w-full md:w-auto"
|
||||
{...routes.messages().link}
|
||||
>
|
||||
Messages
|
||||
</Button>
|
||||
</div>
|
||||
<div onClick={onClick}>
|
||||
<Button
|
||||
icon={<FiGrid className="w-5 h-5" />}
|
||||
className="w-full md:w-auto"
|
||||
active={route.name === 'nodes'}
|
||||
{...routes.nodes().link}
|
||||
>
|
||||
Nodes
|
||||
</Button>
|
||||
</div>
|
||||
<div onClick={onClick}>
|
||||
<Button
|
||||
icon={<FiPackage className="w-5 h-5" />}
|
||||
className="w-full md:w-auto"
|
||||
active={route.name === 'plugins'}
|
||||
{...routes.plugins().link}
|
||||
>
|
||||
Plugins
|
||||
</Button>
|
||||
</div>
|
||||
<div onClick={onClick}>
|
||||
<Button
|
||||
icon={<FiSettings className="w-5 h-5" />}
|
||||
className="w-full md:w-auto"
|
||||
active={route.name === 'settings'}
|
||||
{...routes.settings().link}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex h-full mt-2 border-t border-l border-r border-gray-300 rounded-t dark:text-white dark:border-gray-600">
|
||||
<NavLink
|
||||
name="Messages"
|
||||
icon={
|
||||
<FiMessageSquare className="w-5 h-5 my-auto group-active:scale-90" />
|
||||
}
|
||||
active={route.name === 'messages'}
|
||||
link={routes.messages().link}
|
||||
/>
|
||||
|
||||
<NavLink
|
||||
name="Nodes"
|
||||
icon={<FiGrid className="w-5 h-5 my-auto group-active:scale-90" />}
|
||||
active={route.name === 'nodes'}
|
||||
link={routes.nodes().link}
|
||||
/>
|
||||
|
||||
<NavLink
|
||||
name="Plugins"
|
||||
icon={<FiPackage className="w-5 h-5 my-auto group-active:scale-90" />}
|
||||
active={route.name === 'plugins'}
|
||||
link={routes.plugins().link}
|
||||
/>
|
||||
|
||||
<NavLink
|
||||
name="Settings"
|
||||
icon={<FiSettings className="w-5 h-5 my-auto group-active:scale-90" />}
|
||||
active={route.name === 'settings'}
|
||||
link={routes.settings().link}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface NavLinkProps {
|
||||
name: string;
|
||||
icon: JSX.Element;
|
||||
active: boolean;
|
||||
link: Link;
|
||||
}
|
||||
|
||||
const NavLink = ({ name, icon, active, link }: NavLinkProps): JSX.Element => {
|
||||
return (
|
||||
<a
|
||||
className={`flex h-full gap-1 p-2 cursor-pointer group hover:bg-gray-200 dark:hover:bg-primaryDark ${
|
||||
active ? 'dark:bg-primaryDark bg-gray-200' : 'bg-transparent'
|
||||
}`}
|
||||
{...link}
|
||||
>
|
||||
{icon}
|
||||
<div className="hidden my-auto md:flex">{name}</div>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import type React from 'react';
|
||||
|
||||
import { FiMoon, FiSun } from 'react-icons/fi';
|
||||
|
||||
import { setDarkModeEnabled } from '@core/slices/appSlice';
|
||||
import { useAppDispatch } from '@hooks/useAppDispatch';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
import { IconButton } from '@meshtastic/components';
|
||||
|
||||
export const ThemeToggle = (): JSX.Element => {
|
||||
const dispatch = useAppDispatch();
|
||||
const darkMode = useAppSelector((state) => state.app.darkMode);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
icon={
|
||||
darkMode ? (
|
||||
<FiSun className="w-5 h-5" />
|
||||
) : (
|
||||
<FiMoon className="w-5 h-5" />
|
||||
)
|
||||
}
|
||||
onClick={(): void => {
|
||||
dispatch(setDarkModeEnabled(!darkMode));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FiXCircle } from 'react-icons/fi';
|
||||
import { FiMenu, FiXCircle } from 'react-icons/fi';
|
||||
|
||||
import { Drawer } from '@components/generic/Drawer';
|
||||
import type { SidebarItemProps } from '@components/generic/SidebarItem';
|
||||
@@ -37,10 +37,11 @@ export const PageLayout = ({
|
||||
}}
|
||||
>
|
||||
<Tab.List className="flex flex-col border-b border-gray-300 divide-y divide-gray-300 dark:divide-gray-600 dark:border-gray-600">
|
||||
<div className="flex items-center justify-between m-6 mr-6">
|
||||
<div className="text-4xl font-extrabold leading-none tracking-tight">
|
||||
<div className="flex items-center justify-between m-4">
|
||||
<div className="text-2xl font-extrabold leading-none tracking-tight">
|
||||
{title}
|
||||
</div>
|
||||
<IconButton icon={<FiMenu />} />
|
||||
<div className="md:hidden">
|
||||
<IconButton
|
||||
icon={<FiXCircle className="w-5 h-5" />}
|
||||
|
||||
@@ -14,6 +14,8 @@ import { IconButton } from '@meshtastic/components';
|
||||
import { NodeCard } from './NodeCard';
|
||||
import { Sidebar } from './Sidebar';
|
||||
|
||||
// const getMarkerRadius = ():number => {}
|
||||
|
||||
export const Nodes = (): JSX.Element => {
|
||||
const myNodeInfo = useAppSelector((state) => state.meshtastic.radio.hardware);
|
||||
|
||||
@@ -99,7 +101,11 @@ export const Nodes = (): JSX.Element => {
|
||||
setSelectedNode(node);
|
||||
setSidebarOpen(true);
|
||||
}}
|
||||
className="z-50 bg-blue-500 border-2 border-blue-500 rounded-full bg-opacity-30"
|
||||
className={`z-50 border-2 rounded-full bg-opacity-30 ${
|
||||
node.number === selectedNode?.number
|
||||
? 'bg-green-500 border-green-500'
|
||||
: 'bg-blue-500 border-blue-500'
|
||||
}`}
|
||||
>
|
||||
<div className="m-4 ">
|
||||
<FiMapPin className="w-5 h-5" />
|
||||
|
||||
@@ -76,9 +76,9 @@ export const Sidebar = ({ node, closeSidebar }: SidebarProps): JSX.Element => {
|
||||
<Tab.Panel className="p-2">Content 1</Tab.Panel>
|
||||
<Tab.Panel className="p-2">
|
||||
{node.currentPosition && (
|
||||
<div className="flex justify-between h-10 px-1 bg-transparent border border-gray-300 rounded-md select-none dark:border-gray-600">
|
||||
<div className="my-auto">
|
||||
{(node.currentPosition.latitudeI / 1e7).toPrecision(6)},
|
||||
<div className="flex justify-between h-10 px-1 text-gray-500 bg-transparent bg-gray-200 border border-gray-300 rounded-md select-none dark:border-gray-600 dark:bg-secondaryDark dark:text-gray-400 ">
|
||||
<div className="px-1 my-auto">
|
||||
{(node.currentPosition.latitudeI / 1e7).toPrecision(6)},
|
||||
{(node.currentPosition?.longitudeI / 1e7).toPrecision(6)}
|
||||
</div>
|
||||
<IconButton
|
||||
|
||||
@@ -74,7 +74,7 @@ export const Files = ({ navOpen, setNavOpen }: RangeTestProps): JSX.Element => {
|
||||
{data.data.files.map((file: IFile) => (
|
||||
<div
|
||||
key={file.name}
|
||||
className="flex justify-between mx-4 bg-gray-300 rounded-md dark:bg-gray-600 "
|
||||
className="flex justify-between mx-4 bg-gray-300 rounded-md dark:bg-secondaryDark "
|
||||
>
|
||||
<div className="flex p-2 max-h-12">
|
||||
<div className="flex w-12">
|
||||
|
||||
@@ -10,8 +10,10 @@ module.exports = {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#67ea94',
|
||||
primaryDark: '#1E293B',
|
||||
secondaryDark: '#0F172A',
|
||||
// primaryDark: '#1E293B',
|
||||
primaryDark: '#25262C',
|
||||
// secondaryDark: '#0F172A',
|
||||
secondaryDark: '#1C1D23',
|
||||
},
|
||||
boxShadow: {
|
||||
border: '0 0 0 1px #67ea94',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { execSync } from 'child_process';
|
||||
import path from 'path';
|
||||
import { defineConfig } from 'vite';
|
||||
import importToCDN from 'vite-plugin-cdn-import';
|
||||
@@ -7,6 +8,11 @@ import react from '@vitejs/plugin-react';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
define: {
|
||||
__COMMIT_HASH__: JSON.stringify(
|
||||
execSync('git rev-parse --short HEAD').toString().trim(),
|
||||
),
|
||||
},
|
||||
plugins: [
|
||||
react(),
|
||||
importToCDN({
|
||||
|
||||
Reference in New Issue
Block a user