diff --git a/package.json b/package.json index 73b42397..ad529ad4 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "i18next": "^21.4.2", "i18next-browser-languagedetector": "^6.1.2", "react": "^17.0.2", - "react-apexcharts": "^1.3.9", "react-dom": "^17.0.2", "react-file-icon": "^1.1.0", "react-hook-form": "^7.19.4", @@ -27,8 +26,9 @@ "react-icons": "^4.3.1", "react-json-pretty": "^2.2.0", "react-redux": "^7.2.6", - "react-timeago": "^6.2.1", + "rfc4648": "^1.5.0", "swr": "^1.0.1", + "timeago-react": "^3.0.4", "type-route": "^0.6.0", "use-breakpoint": "^2.0.2" }, @@ -36,8 +36,6 @@ "@types/react": "^17.0.34", "@types/react-dom": "^17.0.11", "@types/react-file-icon": "^1.0.1", - "@types/react-redux": "^7.1.20", - "@types/react-timeago": "^4.1.3", "@types/w3c-web-serial": "^1.0.2", "@types/web-bluetooth": "^0.0.11", "@typescript-eslint/eslint-plugin": "^5.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7b8bc1b..80bbbda0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,8 +7,6 @@ specifiers: '@types/react': ^17.0.34 '@types/react-dom': ^17.0.11 '@types/react-file-icon': ^1.0.1 - '@types/react-redux': ^7.1.20 - '@types/react-timeago': ^4.1.3 '@types/w3c-web-serial': ^1.0.2 '@types/web-bluetooth': ^0.0.11 '@typescript-eslint/eslint-plugin': ^5.3.1 @@ -31,7 +29,6 @@ specifiers: postcss: ^8.3.11 prettier: ^2.4.1 react: ^17.0.2 - react-apexcharts: ^1.3.9 react-dom: ^17.0.2 react-file-icon: ^1.1.0 react-hook-form: ^7.19.4 @@ -39,10 +36,11 @@ specifiers: react-icons: ^4.3.1 react-json-pretty: ^2.2.0 react-redux: ^7.2.6 - react-timeago: ^6.2.1 + rfc4648: ^1.5.0 swr: ^1.0.1 tailwindcss: ^3.0.0-alpha.2 tar: ^6.1.11 + timeago-react: ^3.0.4 type-route: ^0.6.0 typescript: ^4.4.4 use-breakpoint: ^2.0.2 @@ -52,13 +50,12 @@ specifiers: dependencies: '@headlessui/react': 1.4.2_react-dom@17.0.2+react@17.0.2 - '@meshtastic/meshtasticjs': 0.6.27 + '@meshtastic/meshtasticjs': link:../meshtastic.js '@reduxjs/toolkit': 1.6.2_react-redux@7.2.6+react@17.0.2 boring-avatars: 1.5.8 i18next: 21.4.2 i18next-browser-languagedetector: 6.1.2 react: 17.0.2 - react-apexcharts: 1.3.9_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-hook-form: 7.19.4_react@17.0.2 @@ -66,8 +63,9 @@ dependencies: react-icons: 4.3.1_react@17.0.2 react-json-pretty: 2.2.0_react-dom@17.0.2+react@17.0.2 react-redux: 7.2.6_react-dom@17.0.2+react@17.0.2 - react-timeago: 6.2.1_react@17.0.2 + rfc4648: 1.5.0 swr: 1.0.1_react@17.0.2 + timeago-react: 3.0.4_react@17.0.2 type-route: 0.6.0 use-breakpoint: 2.0.2_react-dom@17.0.2+react@17.0.2 @@ -75,8 +73,6 @@ devDependencies: '@types/react': 17.0.34 '@types/react-dom': 17.0.11 '@types/react-file-icon': 1.0.1 - '@types/react-redux': 7.1.20 - '@types/react-timeago': 4.1.3 '@types/w3c-web-serial': 1.0.2 '@types/web-bluetooth': 0.0.11 '@typescript-eslint/eslint-plugin': 5.3.1_4653b7803b7453f5f37717b7e1448517 @@ -1359,13 +1355,6 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true - /@meshtastic/meshtasticjs/0.6.27: - resolution: {integrity: sha512-WiM9v/3+YWtt6/wLJOyyhAQdtsIGcEs3geofRZA6y/TCQkbjo/mdvY8Y+ZMZERSFXIZXiovvZgJG0vSYq7JC9A==} - dependencies: - '@protobuf-ts/runtime': 2.0.7 - sub-events: 1.8.9 - dev: false - /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1387,10 +1376,6 @@ packages: fastq: 1.13.0 dev: true - /@protobuf-ts/runtime/2.0.7: - resolution: {integrity: sha512-jT8FYEX7NkAzxZXVjshIhtCV/ReuZm/3sCH0GWnaa8woy9VG+He0N+dpj2svaJbkdUThSxJE3zwmJcH0/3vEsw==} - dev: false - /@reduxjs/toolkit/1.6.2_react-redux@7.2.6+react@17.0.2: resolution: {integrity: sha512-HbfI/hOVrAcMGAYsMWxw3UJyIoAS9JTdwddsjlr5w3S50tXhWb+EMyhIw+IAvCVCLETkzdjgH91RjDSYZekVBA==} peerDependencies: @@ -1488,6 +1473,7 @@ packages: dependencies: '@types/react': 17.0.34 hoist-non-react-statics: 3.3.2 + dev: false /@types/json-schema/7.0.9: resolution: {integrity: sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==} @@ -1527,12 +1513,7 @@ packages: '@types/react': 17.0.34 hoist-non-react-statics: 3.3.2 redux: 4.1.2 - - /@types/react-timeago/4.1.3: - resolution: {integrity: sha512-XaaMBzuXLw7lxPPDs/fenlohcf3NDqM5qP4oOL/Meu+Hb1QChW4Igw/SruS1llEqch18RQB3wDTIwvqq4nivvw==} - dependencies: - '@types/react': 17.0.34 - dev: true + dev: false /@types/react/17.0.34: resolution: {integrity: sha512-46FEGrMjc2+8XhHXILr+3+/sTe3OfzSPU9YGKILLrUYbQ1CLQC9Daqo1KzENGXAWwrFwiY0l4ZbF20gRvgpWTg==} @@ -3240,6 +3221,7 @@ packages: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: react-is: 16.13.1 + dev: false /html-parse-stringify/3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} @@ -4050,16 +4032,6 @@ packages: safe-buffer: 5.2.1 dev: true - /react-apexcharts/1.3.9_react@17.0.2: - resolution: {integrity: sha512-KPonT5uQPHOHSVgTNEzpB0HhCkZtoicQYGjR9P+3DRDSgTsC+DM2vDUfo/B2Fn1m+wdgVeDXWL0VJYDc6JD/tw==} - peerDependencies: - apexcharts: ^3.18.0 - react: '>=0.13' - dependencies: - prop-types: 15.7.2 - react: 17.0.2 - dev: false - /react-dom/17.0.2_react@17.0.2: resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} peerDependencies: @@ -4157,14 +4129,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-timeago/6.2.1_react@17.0.2: - resolution: {integrity: sha512-b9EObWO8wy4qwfOzj+g/RQZRrPvtMv1Pz12FCdAWKWCXbDGt0rZLyiyTGEr0Lh1O8w5xa48CtRpl3LI+CtGCyw==} - peerDependencies: - react: ^16.0.0 || ^17.0.0 - dependencies: - react: 17.0.2 - dev: false - /react/17.0.2: resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} engines: {node: '>=0.10.0'} @@ -4192,6 +4156,7 @@ packages: resolution: {integrity: sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==} dependencies: '@babel/runtime': 7.16.3 + dev: false /regenerate-unicode-properties/9.0.0: resolution: {integrity: sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==} @@ -4286,6 +4251,10 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true + /rfc4648/1.5.0: + resolution: {integrity: sha512-FA6W9lDNeX8WbMY31io1xWg+TpZCbeDKsBo0ocwACZiWnh9TUAyk9CCuBQuOPmYnwwdEQZmraQ2ZK7yJsxErBg==} + dev: false + /rimraf/3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true @@ -4505,11 +4474,6 @@ packages: engines: {node: '>=8'} dev: true - /sub-events/1.8.9: - resolution: {integrity: sha512-RhhA2amqVzL6nO+aiZOqxBCgcA3ZLfp4W9iHFUELwq8132TS7pUReJV+bcRjtNKdqm/Ep1sD/h01eAcTBtgrBQ==} - engines: {node: '>=10.0.0'} - dev: false - /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -4620,6 +4584,19 @@ packages: resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} dev: true + /timeago-react/3.0.4_react@17.0.2: + resolution: {integrity: sha512-cv6Bnm01VKyHoQCBKzk24+L9ycj3jLq3uEFpYILKGJT7UUXWEzC0TBCxforsvL4NSjcwqqHNKdEeqEFMNNoN2A==} + peerDependencies: + react: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + react: 17.0.2 + timeago.js: 4.0.2 + dev: false + + /timeago.js/4.0.2: + resolution: {integrity: sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w==} + dev: false + /tinycolor2/1.4.2: resolution: {integrity: sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==} dev: false diff --git a/src/components/Channel.tsx b/src/components/Channel.tsx index 3d573143..95d77a1b 100644 --- a/src/components/Channel.tsx +++ b/src/components/Channel.tsx @@ -3,54 +3,50 @@ import React from 'react'; import { useForm } from 'react-hook-form'; import { FiEdit3, FiSave } from 'react-icons/fi'; +import { Loading } from '@components/generic/Loading'; import { Protobuf } from '@meshtastic/meshtasticjs'; import { connection } from '../core/connection'; +import { Checkbox } from './generic/form/Checkbox'; import { Input } from './generic/form/Input'; -import { Select } from './generic/form/Select'; import { IconButton } from './generic/IconButton'; export interface ChannelProps { channel: Protobuf.Channel; } -interface DotProps { - role: Protobuf.Channel_Role; - admin: boolean; -} -const Dot = ({ role, admin }: DotProps): JSX.Element => ( -
-); export const Channel = ({ channel }: ChannelProps): JSX.Element => { const [edit, setEdit] = React.useState(false); const [loading, setLoading] = React.useState(false); const { register, handleSubmit, formState } = useForm<{ - role: Protobuf.Channel_Role; + enabled: boolean; settings: { name: string; bandwidth?: number; codingRate?: number; spreadFactor?: number; + downlinkEnabled?: boolean; + uplinkEnabled?: boolean; + txPower?: number; + psk?: string; }; }>({ defaultValues: { - role: channel.role, + enabled: + channel.role === + (Protobuf.Channel_Role.PRIMARY || Protobuf.Channel_Role.SECONDARY) + ? true + : false, settings: { name: channel.settings?.name, bandwidth: channel.settings?.bandwidth, codingRate: channel.settings?.codingRate, spreadFactor: channel.settings?.spreadFactor, + downlinkEnabled: channel.settings?.downlinkEnabled, + uplinkEnabled: channel.settings?.uplinkEnabled, + txPower: channel.settings?.txPower, + psk: new TextDecoder().decode(channel.settings?.psk), }, }, }); @@ -58,9 +54,14 @@ export const Channel = ({ channel }: ChannelProps): JSX.Element => { const onSubmit = handleSubmit(async (data) => { setLoading(true); const adminChannel = Protobuf.Channel.create({ - role: data.role, + role: data.enabled + ? Protobuf.Channel_Role.SECONDARY + : Protobuf.Channel_Role.DISABLED, index: channel.index, - settings: data.settings, + settings: { + ...data.settings, + psk: new TextEncoder().encode(data.settings.psk), + }, }); await connection.setChannel(adminChannel, (): Promise