25 changed files with 555 additions and 262 deletions
@ -2,7 +2,6 @@ lockfileVersion: 5.3 |
|||
|
|||
specifiers: |
|||
'@headlessui/react': ^1.4.1 |
|||
'@heroicons/react': ^1.0.4 |
|||
'@meshtastic/meshtasticjs': ^0.6.17 |
|||
'@reduxjs/toolkit': ^1.6.2 |
|||
'@snowpack/plugin-dotenv': ^2.2.0 |
|||
@ -11,6 +10,7 @@ specifiers: |
|||
'@snowpack/plugin-typescript': ^1.2.1 |
|||
'@types/react': ^17.0.27 |
|||
'@types/react-dom': ^17.0.9 |
|||
'@types/react-file-icon': ^1.0.1 |
|||
'@types/react-redux': ^7.1.19 |
|||
'@types/snowpack-env': ^2.3.4 |
|||
'@typescript-eslint/eslint-plugin': ^4.33.0 |
|||
@ -36,12 +36,15 @@ specifiers: |
|||
react: ^17.0.2 |
|||
react-apexcharts: ^1.3.9 |
|||
react-dom: ^17.0.2 |
|||
react-file-icon: ^1.1.0 |
|||
react-flags-select: ^2.1.2 |
|||
react-hook-form: ^7.17.2 |
|||
react-i18next: ^11.12.0 |
|||
react-icons: ^4.3.1 |
|||
react-redux: ^7.2.5 |
|||
snowpack: ^3.8.8 |
|||
tailwindcss: ^2.2.16 |
|||
swr: ^1.0.1 |
|||
tailwindcss: ^3.0.0-alpha.1 |
|||
tar: ^6.1.11 |
|||
type-route: ^0.6.0 |
|||
typescript: ^4.4.3 |
|||
@ -49,7 +52,6 @@ specifiers: |
|||
|
|||
dependencies: |
|||
'@headlessui/react': 1.4[email protected][email protected] |
|||
'@heroicons/react': 1.0[email protected] |
|||
'@meshtastic/meshtasticjs': 0.6.17 |
|||
'@reduxjs/toolkit': 1.6[email protected][email protected] |
|||
apexcharts: 3.28.3 |
|||
@ -60,10 +62,13 @@ dependencies: |
|||
react: 17.0.2 |
|||
react-apexcharts: 1.3[email protected][email protected] |
|||
react-dom: 17.0[email protected] |
|||
react-file-icon: 1.1[email protected][email protected] |
|||
react-flags-select: 2.1[email protected][email protected] |
|||
react-hook-form: 7.17[email protected] |
|||
react-i18next: 11.12[email protected][email protected] |
|||
react-icons: 4.3[email protected] |
|||
react-redux: 7.2[email protected][email protected] |
|||
swr: 1.0[email protected] |
|||
type-route: 0.6.0 |
|||
use-breakpoint: 2.0[email protected][email protected] |
|||
|
|||
@ -74,6 +79,7 @@ devDependencies: |
|||
'@snowpack/plugin-typescript': 1.2[email protected] |
|||
'@types/react': 17.0.27 |
|||
'@types/react-dom': 17.0.9 |
|||
'@types/react-file-icon': 1.0.1 |
|||
'@types/react-redux': 7.1.19 |
|||
'@types/snowpack-env': 2.3.4 |
|||
'@typescript-eslint/eslint-plugin': 4.33.0_d753869925cce96d3eb2141eeedafe57 |
|||
@ -92,7 +98,7 @@ devDependencies: |
|||
postcss: 8.3.9 |
|||
prettier: 2.4.1 |
|||
snowpack: 3.8.8 |
|||
tailwindcss: 2.2.16_96f83969316717847b3edf58a3f353f3 |
|||
tailwindcss: 3.0.0-alpha.1_96f83969316717847b3edf58a3f353f3 |
|||
tar: 6.1.11 |
|||
typescript: 4.4.3 |
|||
|
|||
@ -369,14 +375,6 @@ packages: |
|||
react-dom: 17.0[email protected] |
|||
dev: false |
|||
|
|||
/@heroicons/react/[email protected]: |
|||
resolution: {integrity: sha512-3kOrTmo8+Z8o6AL0rzN82MOf8J5CuxhRLFhpI8mrn+3OqekA6d5eb1GYO3EYYo1Vn6mYQSMNTzCWbEwUInb0cQ==} |
|||
peerDependencies: |
|||
react: '>= 16' |
|||
dependencies: |
|||
react: 17.0.2 |
|||
dev: false |
|||
|
|||
/@humanwhocodes/config-array/0.5.0: |
|||
resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} |
|||
engines: {node: '>=10.10.0'} |
|||
@ -768,6 +766,12 @@ packages: |
|||
'@types/react': 17.0.27 |
|||
dev: true |
|||
|
|||
/@types/react-file-icon/1.0.1: |
|||
resolution: {integrity: sha512-QTdYCkYXzh/PfKEIwcPxRdaPQkii5R4Ke7fcO+KB++IDPbYAG1jj+ulEcTA7pRf0gZ5jAvjWcTXBJJRtfYHjlw==} |
|||
dependencies: |
|||
'@types/react': 17.0.27 |
|||
dev: true |
|||
|
|||
/@types/react-redux/7.1.19: |
|||
resolution: {integrity: sha512-L37dSCT0aoJnCgpR8Iuginlbxoh7qhWOXiaDqEsxVMrER1CmVhFD+63NxgJeT4pkmEM28oX0NH4S4f+sXHTZjA==} |
|||
dependencies: |
|||
@ -1277,11 +1281,6 @@ packages: |
|||
resolution: {integrity: sha1-y5T662HIaWRR2zZTThQi+U8K7og=} |
|||
dev: true |
|||
|
|||
/bytes/3.1.0: |
|||
resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} |
|||
engines: {node: '>= 0.8'} |
|||
dev: true |
|||
|
|||
/cacache/15.3.0: |
|||
resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} |
|||
engines: {node: '>= 10'} |
|||
@ -1471,20 +1470,6 @@ packages: |
|||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} |
|||
dev: true |
|||
|
|||
/color-string/1.6.0: |
|||
resolution: {integrity: sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==} |
|||
dependencies: |
|||
color-name: 1.1.4 |
|||
simple-swizzle: 0.2.2 |
|||
dev: true |
|||
|
|||
/color/4.0.1: |
|||
resolution: {integrity: sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==} |
|||
dependencies: |
|||
color-convert: 2.0.1 |
|||
color-string: 1.6.0 |
|||
dev: true |
|||
|
|||
/combined-stream/1.0.8: |
|||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} |
|||
engines: {node: '>= 0.8'} |
|||
@ -1492,11 +1477,6 @@ packages: |
|||
delayed-stream: 1.0.0 |
|||
dev: true |
|||
|
|||
/commander/6.2.1: |
|||
resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} |
|||
engines: {node: '>= 6'} |
|||
dev: true |
|||
|
|||
/commander/7.2.0: |
|||
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} |
|||
engines: {node: '>= 10'} |
|||
@ -1559,10 +1539,6 @@ packages: |
|||
which: 2.0.2 |
|||
dev: true |
|||
|
|||
/css-color-names/0.0.4: |
|||
resolution: {integrity: sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=} |
|||
dev: true |
|||
|
|||
/css-select/4.1.3: |
|||
resolution: {integrity: sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==} |
|||
dependencies: |
|||
@ -1573,10 +1549,6 @@ packages: |
|||
nth-check: 2.0.1 |
|||
dev: true |
|||
|
|||
/css-unit-converter/1.1.2: |
|||
resolution: {integrity: sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==} |
|||
dev: true |
|||
|
|||
/css-what/5.1.0: |
|||
resolution: {integrity: sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==} |
|||
engines: {node: '>= 6'} |
|||
@ -1706,6 +1678,11 @@ packages: |
|||
engines: {node: '>= 0.6'} |
|||
dev: true |
|||
|
|||
/dequal/2.0.2: |
|||
resolution: {integrity: sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==} |
|||
engines: {node: '>=6'} |
|||
dev: false |
|||
|
|||
/detect-port/1.3.0: |
|||
resolution: {integrity: sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==} |
|||
engines: {node: '>= 4.2.1'} |
|||
@ -2364,15 +2341,6 @@ packages: |
|||
resolution: {integrity: sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg==} |
|||
dev: true |
|||
|
|||
/fs-extra/10.0.0: |
|||
resolution: {integrity: sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==} |
|||
engines: {node: '>=12'} |
|||
dependencies: |
|||
graceful-fs: 4.2.8 |
|||
jsonfile: 6.1.0 |
|||
universalify: 2.0.0 |
|||
dev: true |
|||
|
|||
/fs-minipass/2.1.0: |
|||
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} |
|||
engines: {node: '>= 8'} |
|||
@ -2596,10 +2564,6 @@ packages: |
|||
function-bind: 1.1.1 |
|||
dev: true |
|||
|
|||
/hex-color-regex/1.1.0: |
|||
resolution: {integrity: sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==} |
|||
dev: true |
|||
|
|||
/history/5.0.1: |
|||
resolution: {integrity: sha512-5qC/tFUKfVci5kzgRxZxN5Mf1CV8NmJx9ByaPX0YTLx5Vz3Svh7NYp6eA4CpDq4iA9D0C1t8BNIfvQIrUI3mVw==} |
|||
dependencies: |
|||
@ -2622,25 +2586,12 @@ packages: |
|||
lru-cache: 6.0.0 |
|||
dev: true |
|||
|
|||
/hsl-regex/1.0.0: |
|||
resolution: {integrity: sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=} |
|||
dev: true |
|||
|
|||
/hsla-regex/1.0.0: |
|||
resolution: {integrity: sha1-wc56MWjIxmFAM6S194d/OyJfnDg=} |
|||
dev: true |
|||
|
|||
/html-parse-stringify/3.0.1: |
|||
resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} |
|||
dependencies: |
|||
void-elements: 3.1.0 |
|||
dev: false |
|||
|
|||
/html-tags/3.1.0: |
|||
resolution: {integrity: sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==} |
|||
engines: {node: '>=8'} |
|||
dev: true |
|||
|
|||
/htmlparser2/6.1.0: |
|||
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} |
|||
dependencies: |
|||
@ -2837,10 +2788,6 @@ packages: |
|||
resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=} |
|||
dev: true |
|||
|
|||
/is-arrayish/0.3.2: |
|||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} |
|||
dev: true |
|||
|
|||
/is-bigint/1.0.4: |
|||
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} |
|||
dependencies: |
|||
@ -2867,17 +2814,6 @@ packages: |
|||
engines: {node: '>= 0.4'} |
|||
dev: true |
|||
|
|||
/is-color-stop/1.1.0: |
|||
resolution: {integrity: sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=} |
|||
dependencies: |
|||
css-color-names: 0.0.4 |
|||
hex-color-regex: 1.1.0 |
|||
hsl-regex: 1.0.0 |
|||
hsla-regex: 1.0.0 |
|||
rgb-regex: 1.0.1 |
|||
rgba-regex: 1.0.0 |
|||
dev: true |
|||
|
|||
/is-core-module/2.7.0: |
|||
resolution: {integrity: sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==} |
|||
dependencies: |
|||
@ -3136,14 +3072,6 @@ packages: |
|||
minimist: 1.2.5 |
|||
dev: true |
|||
|
|||
/jsonfile/6.1.0: |
|||
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} |
|||
dependencies: |
|||
universalify: 2.0.0 |
|||
optionalDependencies: |
|||
graceful-fs: 4.2.8 |
|||
dev: true |
|||
|
|||
/jsonparse/1.3.1: |
|||
resolution: {integrity: sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=} |
|||
engines: {'0': node >= 0.2.0} |
|||
@ -3268,17 +3196,13 @@ packages: |
|||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} |
|||
dev: true |
|||
|
|||
/lodash.topath/4.5.2: |
|||
resolution: {integrity: sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=} |
|||
dev: true |
|||
|
|||
/lodash.truncate/4.4.2: |
|||
resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=} |
|||
dev: true |
|||
|
|||
/lodash/4.17.21: |
|||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} |
|||
dev: true |
|||
/lodash.uniqueid/4.0.1: |
|||
resolution: {integrity: sha1-MmjyanyI5PSxdY1nknGBTjH6WyY=} |
|||
dev: false |
|||
|
|||
/loose-envify/1.4.0: |
|||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} |
|||
@ -3470,11 +3394,6 @@ packages: |
|||
hasBin: true |
|||
dev: true |
|||
|
|||
/modern-normalize/1.1.0: |
|||
resolution: {integrity: sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==} |
|||
engines: {node: '>=6'} |
|||
dev: true |
|||
|
|||
/moment/2.29.1: |
|||
resolution: {integrity: sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==} |
|||
dev: false |
|||
@ -3506,12 +3425,6 @@ packages: |
|||
engines: {node: '>= 0.6'} |
|||
dev: true |
|||
|
|||
/node-emoji/1.11.0: |
|||
resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} |
|||
dependencies: |
|||
lodash: 4.17.21 |
|||
dev: true |
|||
|
|||
/node-gyp-build/4.3.0: |
|||
resolution: {integrity: sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==} |
|||
hasBin: true |
|||
@ -4123,10 +4036,6 @@ packages: |
|||
util-deprecate: 1.0.2 |
|||
dev: true |
|||
|
|||
/postcss-value-parser/3.3.1: |
|||
resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} |
|||
dev: true |
|||
|
|||
/postcss-value-parser/4.1.0: |
|||
resolution: {integrity: sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==} |
|||
dev: true |
|||
@ -4151,11 +4060,6 @@ packages: |
|||
hasBin: true |
|||
dev: true |
|||
|
|||
/pretty-hrtime/1.0.3: |
|||
resolution: {integrity: sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=} |
|||
engines: {node: '>= 0.8'} |
|||
dev: true |
|||
|
|||
/proc-log/1.0.0: |
|||
resolution: {integrity: sha512-aCk8AO51s+4JyuYGg3Q/a6gnrlDO09NpVWePtjp7xwphcoQ04x5WAfCyugcsbLooWcMJ87CLkD4+604IckEdhg==} |
|||
dev: true |
|||
@ -4212,16 +4116,6 @@ packages: |
|||
engines: {node: '>=6'} |
|||
dev: true |
|||
|
|||
/purgecss/4.0.3: |
|||
resolution: {integrity: sha512-PYOIn5ibRIP34PBU9zohUcCI09c7drPJJtTDAc0Q6QlRz2/CHQ8ywGLdE7ZhxU2VTqB7p5wkvj5Qcm05Rz3Jmw==} |
|||
hasBin: true |
|||
dependencies: |
|||
commander: 6.2.1 |
|||
glob: 7.2.0 |
|||
postcss: 8.3.9 |
|||
postcss-selector-parser: 6.0.6 |
|||
dev: true |
|||
|
|||
/qs/6.5.2: |
|||
resolution: {integrity: sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==} |
|||
engines: {node: '>=0.6'} |
|||
@ -4258,6 +4152,19 @@ packages: |
|||
scheduler: 0.20.2 |
|||
dev: false |
|||
|
|||
/react-file-icon/[email protected][email protected]: |
|||
resolution: {integrity: sha512-jYf+wrrdngnXal8UbgQMEsjJ2lshzAC2/gIBbPh1ui68rLe4P215cshqkur4IK+FTPNWUGbm0yuYwpYSSJUksg==} |
|||
peerDependencies: |
|||
react: ^17.0.0 || ^16.2.0 |
|||
react-dom: ^17.0.0 || ^16.2.0 |
|||
dependencies: |
|||
lodash.uniqueid: 4.0.1 |
|||
prop-types: 15.7.2 |
|||
react: 17.0.2 |
|||
react-dom: 17.0[email protected] |
|||
tinycolor2: 1.4.2 |
|||
dev: false |
|||
|
|||
/react-flags-select/[email protected][email protected]: |
|||
resolution: {integrity: sha512-nx/6mY/nKVJB9sVZOylJoSI6idTYZfu0dtUQ0N1L+cD8VAPNl5c/lxL7yyi9vtn66hDRFy6Sr16GzsBj3aoZfQ==} |
|||
peerDependencies: |
|||
@ -4289,6 +4196,14 @@ packages: |
|||
react: 17.0.2 |
|||
dev: false |
|||
|
|||
/react-icons/[email protected]: |
|||
resolution: {integrity: sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==} |
|||
peerDependencies: |
|||
react: '*' |
|||
dependencies: |
|||
react: 17.0.2 |
|||
dev: false |
|||
|
|||
/react-is/16.13.1: |
|||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} |
|||
|
|||
@ -4384,13 +4299,6 @@ packages: |
|||
picomatch: 2.3.0 |
|||
dev: true |
|||
|
|||
/reduce-css-calc/2.1.8: |
|||
resolution: {integrity: sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==} |
|||
dependencies: |
|||
css-unit-converter: 1.1.2 |
|||
postcss-value-parser: 3.3.1 |
|||
dev: true |
|||
|
|||
/redux-thunk/2.3.0: |
|||
resolution: {integrity: sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==} |
|||
dev: false |
|||
@ -4495,14 +4403,6 @@ packages: |
|||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'} |
|||
dev: true |
|||
|
|||
/rgb-regex/1.0.1: |
|||
resolution: {integrity: sha1-wODWiC3w4jviVKR16O3UGRX+rrE=} |
|||
dev: true |
|||
|
|||
/rgba-regex/1.0.0: |
|||
resolution: {integrity: sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=} |
|||
dev: true |
|||
|
|||
/rimraf/3.0.2: |
|||
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} |
|||
hasBin: true |
|||
@ -4597,12 +4497,6 @@ packages: |
|||
resolution: {integrity: sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==} |
|||
dev: true |
|||
|
|||
/simple-swizzle/0.2.2: |
|||
resolution: {integrity: sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=} |
|||
dependencies: |
|||
is-arrayish: 0.3.2 |
|||
dev: true |
|||
|
|||
/skypack/0.3.2: |
|||
resolution: {integrity: sha512-je1pix0QYER6iHuUGbgcafRJT5TI+EGUIBfzBLMqo3Wi22I2SzB9TVHQqwKCw8pzJMuHqhVTFEHc3Ey+ra25Sw==} |
|||
engines: {node: '>=10.19.0'} |
|||
@ -4951,6 +4845,15 @@ packages: |
|||
svg.js: 2.7.1 |
|||
dev: false |
|||
|
|||
/swr/[email protected]: |
|||
resolution: {integrity: sha512-EPQAxSjoD4IaM49rpRHK0q+/NzcwoT8c0/Ylu/u3/6mFj/CWnQVjNJ0MV2Iuw/U+EJSd2TX5czdAwKPYZIG0YA==} |
|||
peerDependencies: |
|||
react: ^16.11.0 || ^17.0.0 |
|||
dependencies: |
|||
dequal: 2.0.2 |
|||
react: 17.0.2 |
|||
dev: false |
|||
|
|||
/table/6.7.2: |
|||
resolution: {integrity: sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==} |
|||
engines: {node: '>=10.0.0'} |
|||
@ -4963,8 +4866,8 @@ packages: |
|||
strip-ansi: 6.0.1 |
|||
dev: true |
|||
|
|||
/tailwindcss/2.2.16_96f83969316717847b3edf58a3f353f3: |
|||
resolution: {integrity: sha512-EireCtpQyyJ4Xz8NYzHafBoy4baCOO96flM0+HgtsFcIQ9KFy/YBK3GEtlnD+rXen0e4xm8t3WiUcKBJmN6yjg==} |
|||
/tailwindcss/3.0.0-alpha.1_96f83969316717847b3edf58a3f353f3: |
|||
resolution: {integrity: sha512-VweVLyu1tpo/i2MnoyDIunToZHYhHRZLGuKDt9I+nnjFoW07NhDwwHWsUyRHKowP5MZaHduhV+AVlM6Auy7m3A==} |
|||
engines: {node: '>=12.13.0'} |
|||
hasBin: true |
|||
peerDependencies: |
|||
@ -4973,24 +4876,16 @@ packages: |
|||
dependencies: |
|||
arg: 5.0.1 |
|||
autoprefixer: 10.3[email protected] |
|||
bytes: 3.1.0 |
|||
chalk: 4.1.2 |
|||
chokidar: 3.5.2 |
|||
color: 4.0.1 |
|||
color-name: 1.1.4 |
|||
cosmiconfig: 7.0.1 |
|||
detective: 5.2.0 |
|||
didyoumean: 1.2.2 |
|||
dlv: 1.1.3 |
|||
fast-glob: 3.2.7 |
|||
fs-extra: 10.0.0 |
|||
glob-parent: 6.0.2 |
|||
html-tags: 3.1.0 |
|||
is-color-stop: 1.1.0 |
|||
is-glob: 4.0.3 |
|||
lodash: 4.17.21 |
|||
lodash.topath: 4.5.2 |
|||
modern-normalize: 1.1.0 |
|||
node-emoji: 1.11.0 |
|||
normalize-path: 3.0.0 |
|||
object-hash: 2.2.0 |
|||
postcss: 8.3.9 |
|||
@ -4999,10 +4894,7 @@ packages: |
|||
postcss-nested: 5.0[email protected] |
|||
postcss-selector-parser: 6.0.6 |
|||
postcss-value-parser: 4.1.0 |
|||
pretty-hrtime: 1.0.3 |
|||
purgecss: 4.0.3 |
|||
quick-lru: 5.1.1 |
|||
reduce-css-calc: 2.1.8 |
|||
resolve: 1.20.0 |
|||
tmp: 0.2.1 |
|||
transitivePeerDependencies: |
|||
@ -5025,6 +4917,10 @@ packages: |
|||
resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} |
|||
dev: true |
|||
|
|||
/tinycolor2/1.4.2: |
|||
resolution: {integrity: sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==} |
|||
dev: false |
|||
|
|||
/tmp/0.2.1: |
|||
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} |
|||
engines: {node: '>=8.17.0'} |
|||
@ -5144,11 +5040,6 @@ packages: |
|||
imurmurhash: 0.1.4 |
|||
dev: true |
|||
|
|||
/universalify/2.0.0: |
|||
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} |
|||
engines: {node: '>= 10.0.0'} |
|||
dev: true |
|||
|
|||
/untildify/2.1.0: |
|||
resolution: {integrity: sha1-F+soB5h/dpUunASF/DEdBqgmouA=} |
|||
engines: {node: '>=0.10.0'} |
|||
|
|||
@ -1,20 +1,22 @@ |
|||
import React from 'react'; |
|||
|
|||
import { FiWifi, FiWifiOff } from 'react-icons/fi'; |
|||
|
|||
import { useAppSelector } from '@app/hooks/redux'; |
|||
import { Button } from '@components/generic/Button'; |
|||
import { SwitchVerticalIcon } from '@heroicons/react/outline'; |
|||
|
|||
export const DeviceStatusDropdown = (): JSX.Element => { |
|||
const ready = useAppSelector((state) => state.meshtastic.ready); |
|||
|
|||
return ( |
|||
<Button |
|||
icon={ |
|||
<SwitchVerticalIcon |
|||
className={`h-6 w-6 ${!ready ? 'animate-pulse' : ''}`} |
|||
/> |
|||
} |
|||
circle |
|||
/> |
|||
return !ready ? ( |
|||
<Button icon={<FiWifi className="w-6 h-6" />} circle /> |
|||
) : ( |
|||
<div className="flex bg-black rounded-full bg-opacity-20"> |
|||
<div className="flex px-2 my-auto text-white"> |
|||
<div className="my-auto mx-2 w-2 h-2 rounded-full bg-yellow-400 min-w-[2]"></div> |
|||
Loading |
|||
</div> |
|||
<Button icon={<FiWifiOff className="w-6 h-6 animate-pulse" />} circle /> |
|||
</div> |
|||
); |
|||
}; |
|||
|
|||
@ -0,0 +1,7 @@ |
|||
export default async function fetcher<JSON>( |
|||
input: RequestInfo, |
|||
init?: RequestInit, |
|||
): Promise<JSON> { |
|||
const res = await fetch(input, init); |
|||
return res.json() as Promise<JSON>; |
|||
} |
|||
@ -0,0 +1,143 @@ |
|||
import React from 'react'; |
|||
|
|||
import { DefaultExtensionType, defaultStyles, FileIcon } from 'react-file-icon'; |
|||
import { FiMenu, FiTrash, FiUploadCloud } from 'react-icons/fi'; |
|||
import useSWR from 'swr'; |
|||
|
|||
import { Card } from '@app/components/generic/Card'; |
|||
import fetcher from '@app/core/utils/fetcher.js'; |
|||
import { useAppSelector } from '@app/hooks/redux'; |
|||
import { Button } from '@components/generic/Button'; |
|||
import { PrimaryTemplate } from '@components/templates/PrimaryTemplate'; |
|||
|
|||
export interface RangeTestProps { |
|||
navOpen: boolean; |
|||
setNavOpen: React.Dispatch<React.SetStateAction<boolean>>; |
|||
} |
|||
interface IFile { |
|||
name: string; |
|||
nameModified: string; |
|||
size: number; |
|||
} |
|||
interface IFiles { |
|||
data: { |
|||
files: IFile[]; |
|||
filesystem: { |
|||
free: number; |
|||
total: number; |
|||
used: number; |
|||
}; |
|||
}; |
|||
|
|||
status: boolean; |
|||
} |
|||
|
|||
export const Files = ({ navOpen, setNavOpen }: RangeTestProps): JSX.Element => { |
|||
const hostOverrideEnabled = useAppSelector( |
|||
(state) => state.meshtastic.hostOverrideEnabled, |
|||
); |
|||
const hostOverride = useAppSelector((state) => state.meshtastic.hostOverride); |
|||
|
|||
const connectionURL = hostOverrideEnabled |
|||
? hostOverride |
|||
: import.meta.env.NODE_ENV === 'production' |
|||
? window.location.hostname |
|||
: (import.meta.env.SNOWPACK_PUBLIC_DEVICE_IP as string) ?? |
|||
'http://meshtastic.local'; |
|||
|
|||
const { data } = useSWR<IFiles>( |
|||
`http://${connectionURL}/json/spiffs/browse/static`, |
|||
fetcher, |
|||
); |
|||
|
|||
return ( |
|||
<PrimaryTemplate |
|||
title="File Browser" |
|||
tagline="Plugin" |
|||
button={ |
|||
<Button |
|||
icon={<FiMenu className="w-5 h-5" />} |
|||
onClick={(): void => { |
|||
setNavOpen(!navOpen); |
|||
}} |
|||
circle |
|||
/> |
|||
} |
|||
> |
|||
<div className="flex flex-col justify-between w-full gap-4 md:flex-row-reverse"> |
|||
<Card title="SPIFFS" description="Statistics"> |
|||
{data ? ( |
|||
<div className="flex"> |
|||
<div className="mx-auto my-4 bg-gray-500 rounded-3xl"> |
|||
<div></div> |
|||
{JSON.stringify(data.data.filesystem.used)} bytes total |
|||
</div> |
|||
</div> |
|||
) : ( |
|||
<div>Loading...</div> |
|||
)} |
|||
</Card> |
|||
<Card |
|||
title="Files" |
|||
description="SPIFFS Contents" |
|||
buttons={ |
|||
<Button active className="font-medium"> |
|||
<FiUploadCloud className="w-8 h-8" /> |
|||
</Button> |
|||
} |
|||
className="md:w-1/3" |
|||
> |
|||
{data ? ( |
|||
<div className="flex flex-col my-4 space-y-2"> |
|||
{data.data.files.map((file: IFile) => ( |
|||
<div |
|||
key={file.name} |
|||
className="flex p-2 mx-4 bg-gray-300 rounded-md max-h-14 dark:bg-gray-600 " |
|||
> |
|||
<div className="flex w-12"> |
|||
<FileIcon |
|||
extension={ |
|||
(file.nameModified ?? file.name).split('.')[ |
|||
(file.nameModified ?? file.name).split('.').length - 1 |
|||
] |
|||
} |
|||
{...defaultStyles[ |
|||
(file.nameModified ?? file.name).split('.')[ |
|||
(file.nameModified ?? file.name).split('.').length - 1 |
|||
] as DefaultExtensionType |
|||
]} |
|||
/> |
|||
</div> |
|||
<a |
|||
href={`http://${connectionURL}/${file.name.replace( |
|||
'static/', |
|||
'', |
|||
)}`}
|
|||
className="my-auto font-semibold" |
|||
> |
|||
{file.nameModified ?? file.name} |
|||
</a> |
|||
<Button |
|||
className="ml-auto space-x-0" |
|||
active |
|||
confirmAction={async (): Promise<void> => { |
|||
await fetch( |
|||
`http://${connectionURL}/json/spiffs/delete`, |
|||
{ |
|||
method: 'DELETE', |
|||
}, |
|||
); |
|||
}} |
|||
icon={<FiTrash />} |
|||
/> |
|||
</div> |
|||
))} |
|||
</div> |
|||
) : ( |
|||
<div>Loading...</div> |
|||
)} |
|||
</Card> |
|||
</div> |
|||
</PrimaryTemplate> |
|||
); |
|||
}; |
|||
@ -0,0 +1,87 @@ |
|||
import React from 'react'; |
|||
|
|||
import { FiFileText, FiRss, FiXCircle } from 'react-icons/fi'; |
|||
|
|||
import { useBreakpoint } from '@app/hooks/breakpoint'; |
|||
import { Button } from '@components/generic/Button'; |
|||
import { Drawer } from '@components/generic/Drawer'; |
|||
import { SidebarItem } from '@components/generic/SidebarItem'; |
|||
import { Tab } from '@headlessui/react'; |
|||
|
|||
import { Files } from './Files'; |
|||
import { RangeTest } from './RangeTest'; |
|||
|
|||
export const Plugins = (): JSX.Element => { |
|||
const [navOpen, setNavOpen] = React.useState(false); |
|||
|
|||
const { breakpoint } = useBreakpoint(); |
|||
|
|||
return ( |
|||
<Tab.Group> |
|||
<div className="relative flex w-full dark:text-white"> |
|||
<Drawer |
|||
open={breakpoint === 'sm' ? navOpen : true} |
|||
permenant={breakpoint !== 'sm'} |
|||
onClose={(): void => { |
|||
setNavOpen(!navOpen); |
|||
}} |
|||
> |
|||
<Tab.List className="flex flex-col border-b divide-y divide-gray-300 dark:divide-gray-600 dark:border-gray-600"> |
|||
<div className="flex items-center justify-between m-8 mr-6 md:my-10"> |
|||
<div className="text-4xl font-extrabold leading-none tracking-tight"> |
|||
Plugins |
|||
</div> |
|||
<div className="md:hidden"> |
|||
<Button |
|||
icon={<FiXCircle className="w-5 h-5" />} |
|||
circle |
|||
onClick={(): void => { |
|||
setNavOpen(false); |
|||
}} |
|||
/> |
|||
</div> |
|||
</div> |
|||
<Tab |
|||
onClick={(): void => { |
|||
setNavOpen(false); |
|||
}} |
|||
> |
|||
{({ selected }): JSX.Element => ( |
|||
<SidebarItem |
|||
title="Range Test" |
|||
description="Test the range of your Meshtastic node" |
|||
selected={selected} |
|||
icon={<FiRss className="flex-shrink-0 w-6 h-6" />} |
|||
/> |
|||
)} |
|||
</Tab> |
|||
<Tab |
|||
onClick={(): void => { |
|||
setNavOpen(false); |
|||
}} |
|||
> |
|||
{({ selected }): JSX.Element => ( |
|||
<SidebarItem |
|||
title="File Browser" |
|||
description="HTTP only file browser" |
|||
selected={selected} |
|||
icon={<FiFileText className="flex-shrink-0 w-6 h-6" />} |
|||
/> |
|||
)} |
|||
</Tab> |
|||
</Tab.List> |
|||
</Drawer> |
|||
<div className="flex w-full"> |
|||
<Tab.Panels className="flex w-full"> |
|||
<Tab.Panel className="flex w-full"> |
|||
<RangeTest navOpen={navOpen} setNavOpen={setNavOpen} /> |
|||
</Tab.Panel> |
|||
<Tab.Panel className="flex w-full"> |
|||
<Files navOpen={navOpen} setNavOpen={setNavOpen} /> |
|||
</Tab.Panel> |
|||
</Tab.Panels> |
|||
</div> |
|||
</div> |
|||
</Tab.Group> |
|||
); |
|||
}; |
|||
@ -0,0 +1,112 @@ |
|||
import React from 'react'; |
|||
|
|||
import { useForm } from 'react-hook-form'; |
|||
import { useTranslation } from 'react-i18next'; |
|||
import { FiMenu, FiSave } from 'react-icons/fi'; |
|||
|
|||
import { Card } from '@app/components/generic/Card'; |
|||
import { Input } from '@app/components/generic/Input.jsx'; |
|||
import { Toggle } from '@app/components/generic/Toggle'; |
|||
import { connection } from '@app/core/connection.js'; |
|||
import { useAppSelector } from '@app/hooks/redux'; |
|||
import { Button } from '@components/generic/Button'; |
|||
import { PrimaryTemplate } from '@components/templates/PrimaryTemplate'; |
|||
import type { RadioConfig_UserPreferences } from '@meshtastic/meshtasticjs/dist/generated'; |
|||
|
|||
export interface RangeTestProps { |
|||
navOpen: boolean; |
|||
setNavOpen: React.Dispatch<React.SetStateAction<boolean>>; |
|||
} |
|||
|
|||
export const RangeTest = ({ |
|||
navOpen, |
|||
setNavOpen, |
|||
}: RangeTestProps): JSX.Element => { |
|||
const { t } = useTranslation(); |
|||
const preferences = useAppSelector((state) => state.meshtastic.preferences); |
|||
|
|||
const { register, handleSubmit, formState } = |
|||
useForm<RadioConfig_UserPreferences>({ |
|||
defaultValues: { |
|||
rangeTestPluginEnabled: preferences.rangeTestPluginEnabled, |
|||
rangeTestPluginSave: preferences.rangeTestPluginSave, |
|||
rangeTestPluginSender: preferences.rangeTestPluginSender, |
|||
}, |
|||
}); |
|||
|
|||
const onSubmit = handleSubmit((data) => { |
|||
console.log(data); |
|||
|
|||
void connection.setPreferences(data); |
|||
}); |
|||
|
|||
return ( |
|||
<PrimaryTemplate |
|||
title="Range Test" |
|||
tagline="Plugin" |
|||
button={ |
|||
<Button |
|||
icon={<FiMenu className="w-5 h-5" />} |
|||
onClick={(): void => { |
|||
setNavOpen(!navOpen); |
|||
}} |
|||
circle |
|||
/> |
|||
} |
|||
footer={ |
|||
<Button |
|||
className="px-10 ml-auto" |
|||
icon={<FiSave className="w-5 h-5" />} |
|||
disabled={!formState.isDirty} |
|||
onClick={onSubmit} |
|||
active |
|||
border |
|||
> |
|||
{t('strings.save_changes')} |
|||
</Button> |
|||
} |
|||
> |
|||
<div className="w-full space-y-4"> |
|||
<Card title="..." description="..."> |
|||
<div className="w-full max-w-3xl p-10 md:max-w-xl"> |
|||
<form onSubmit={onSubmit}> |
|||
<Toggle |
|||
label="Range Test Plugin Enabled?" |
|||
checked={preferences.rangeTestPluginEnabled} |
|||
action={(checked): void => { |
|||
void connection.setPreferences({ |
|||
...preferences, |
|||
rangeTestPluginEnabled: checked, |
|||
}); |
|||
}} |
|||
/> |
|||
<Toggle |
|||
label="Range Test Plugin Save?" |
|||
checked={preferences.rangeTestPluginEnabled} |
|||
action={(checked): void => { |
|||
void connection.setPreferences({ |
|||
...preferences, |
|||
rangeTestPluginSave: checked, |
|||
}); |
|||
}} |
|||
/> |
|||
<Toggle |
|||
label="Range Test Plugin Save?" |
|||
{...register('rangeTestPluginEnabled', { |
|||
valueAsNumber: true, |
|||
})} |
|||
/> |
|||
<Input |
|||
type="number" |
|||
label="Message Interval" |
|||
{...register('rangeTestPluginSender', { |
|||
valueAsNumber: true, |
|||
})} |
|||
/> |
|||
</form> |
|||
</div> |
|||
</Card> |
|||
</div> |
|||
</PrimaryTemplate> |
|||
); |
|||
}; |
|||
Loading…
Reference in new issue