diff --git a/package.json b/package.json
index 679864e3..c31233cc 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"react-i18next": "^11.14.2",
"react-icons": "^4.3.1",
"react-json-pretty": "^2.2.0",
+ "react-qr-code": "^2.0.3",
"react-redux": "^7.2.6",
"rfc4648": "^1.5.0",
"swr": "^1.0.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3554e977..d76d08a3 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -36,6 +36,7 @@ specifiers:
react-i18next: ^11.14.2
react-icons: ^4.3.1
react-json-pretty: ^2.2.0
+ react-qr-code: ^2.0.3
react-redux: ^7.2.6
rfc4648: ^1.5.0
swr: ^1.0.1
@@ -63,6 +64,7 @@ dependencies:
react-i18next: 11.14.2_i18next@21.5.2+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-qr-code: 2.0.3_react@17.0.2
react-redux: 7.2.6_react-dom@17.0.2+react@17.0.2
rfc4648: 1.5.0
swr: 1.0.1_react@17.0.2
@@ -4063,6 +4065,10 @@ packages:
engines: {node: '>=6'}
dev: true
+ /qr.js/0.0.0:
+ resolution: {integrity: sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=}
+ dev: false
+
/queue-microtask/1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: true
@@ -4149,6 +4155,17 @@ packages:
react-dom: 17.0.2_react@17.0.2
dev: false
+ /react-qr-code/2.0.3_react@17.0.2:
+ resolution: {integrity: sha512-6GDH0l53lksf2JgZwwcoS0D60a1OAal/GQRyNFkMBW19HjSqvtD5S20scmSQsKl+BgWM85Wd5DCcUYoHd+PZnQ==}
+ peerDependencies:
+ react: ^16.x || ^17.x
+ react-native-svg: '*'
+ dependencies:
+ prop-types: 15.7.2
+ qr.js: 0.0.0
+ react: 17.0.2
+ dev: false
+
/react-redux/7.2.6_react-dom@17.0.2+react@17.0.2:
resolution: {integrity: sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==}
peerDependencies:
diff --git a/src/components/Channel.tsx b/src/components/Channel.tsx
index f60b3fa9..d2b0249f 100644
--- a/src/components/Channel.tsx
+++ b/src/components/Channel.tsx
@@ -1,16 +1,19 @@
import React from 'react';
import { useForm } from 'react-hook-form';
+import { FaQrcode } from 'react-icons/fa';
import { FiEdit3, FiSave } from 'react-icons/fi';
+import QRCode from 'react-qr-code';
+import { Card } from '@components/generic/Card';
+import { Checkbox } from '@components/generic/form/Checkbox';
+import { Input } from '@components/generic/form/Input';
+import { IconButton } from '@components/generic/IconButton';
import { Loading } from '@components/generic/Loading';
+import { Modal } from '@components/generic/Modal';
+import { connection } from '@core/connection';
import { Protobuf } from '@meshtastic/meshtasticjs';
-import { connection } from '../core/connection';
-import { Checkbox } from './generic/form/Checkbox';
-import { Input } from './generic/form/Input';
-import { IconButton } from './generic/IconButton';
-
export interface ChannelProps {
channel: Protobuf.Channel;
hideEnabled?: boolean;
@@ -22,6 +25,7 @@ export const Channel = ({
}: ChannelProps): JSX.Element => {
const [edit, setEdit] = React.useState(false);
const [loading, setLoading] = React.useState(false);
+ const [showQr, setShowQr] = React.useState(false);
const { register, handleSubmit } = useForm<{
enabled: boolean;
@@ -80,6 +84,16 @@ export const Channel = ({
return (
+ {
+ setShowQr(false);
+ }}
+ >
+
+
+
+
{edit ? (
<>
{loading && }
@@ -139,12 +153,20 @@ export const Channel = ({
: `Channel: ${channel.index}`}
- {
- setEdit(true);
- }}
- icon={}
- />
+
+ {
+ setShowQr(true);
+ }}
+ icon={}
+ />
+ {
+ setEdit(true);
+ }}
+ icon={}
+ />
+
>
)}
diff --git a/src/components/Connection.tsx b/src/components/Connection.tsx
index 0747d6eb..c6dd267b 100644
--- a/src/components/Connection.tsx
+++ b/src/components/Connection.tsx
@@ -1,267 +1,114 @@
import React from 'react';
-import { FiCheck } from 'react-icons/fi';
-import JSONPretty from 'react-json-pretty';
-
import { useAppDispatch, useAppSelector } from '@app/hooks/redux';
+import { Serial } from '@components/connection/Serial';
import { Button } from '@components/generic/Button';
import { Card } from '@components/generic/Card';
-import { Checkbox } from '@components/generic/form/Checkbox';
-import { Input } from '@components/generic/form/Input';
import { Select } from '@components/generic/form/Select';
-import { IconButton } from '@components/generic/IconButton';
import { Modal } from '@components/generic/Modal';
import {
- ble,
+ cleanupListeners,
connection,
connectionUrl,
- serial,
setConnection,
} from '@core/connection';
-import { closeConnectionModal } from '@core/slices/appSlice';
import {
- IBLEConnection,
- IHTTPConnection,
- ISerialConnection,
- Protobuf,
- SettingsManager,
-} from '@meshtastic/meshtasticjs';
-import type {
- BLEConnectionParameters,
- HTTPConnectionParameters,
- SerialConnectionParameters,
-} from '@meshtastic/meshtasticjs/dist/types';
-
-import { DeviceStatus } from './menu/buttons/DeviceStatus';
+ closeConnectionModal,
+ connType,
+ setConnectionParams,
+ setConnType,
+} from '@core/slices/appSlice';
+import { Types } from '@meshtastic/meshtasticjs';
-enum connType {
- HTTP,
- BLE,
- SERIAL,
-}
+import { BLE } from './connection/BLE';
+import { HTTP } from './connection/HTTP';
export const Connection = (): JSX.Element => {
const dispatch = useAppDispatch();
- const [selectedConnType, setSelectedConnType] = React.useState(connType.HTTP);
- const [bleDevices, setBleDevices] = React.useState([]);
- const [serialDevices, setSerialDevices] = React.useState([]);
- const [httpIpSource, setHttpIpSource] = React.useState<'local' | 'remote'>(
- 'local',
- );
- const hostOverrideEnabled = useAppSelector(
- (state) => state.meshtastic.hostOverrideEnabled,
- );
- const hostOverride = useAppSelector((state) => state.meshtastic.hostOverride);
- const connectionModalOpen = useAppSelector(
- (state) => state.app.connectionModalOpen,
- );
- const ready = useAppSelector((state) => state.meshtastic.ready);
- const connect = async (
- connectionType: connType,
- params:
- | HTTPConnectionParameters
- | SerialConnectionParameters
- | BLEConnectionParameters,
- ): Promise => {
- connection.complete();
- await connection.disconnect();
-
- if (connectionType === connType.BLE) {
- setConnection(new IBLEConnection());
- } else if (connectionType === connType.HTTP) {
- setConnection(new IHTTPConnection());
- } else {
- setConnection(new ISerialConnection());
- }
-
- // @ts-ignore tmp
- await connection.connect(params);
- };
-
- const updateBleDeviceList = React.useCallback(async (): Promise => {
- const devices = await ble.getDevices();
- setBleDevices(devices);
- }, []);
-
- const updateSerialDeviceList = React.useCallback(async (): Promise => {
- const devices = await serial.getPorts();
- setSerialDevices(devices);
- }, []);
-
- React.useEffect(() => {
- if (ready) {
- dispatch(closeConnectionModal());
- }
- }, [ready, dispatch]);
- React.useEffect(() => {
- if (selectedConnType === connType.BLE) {
- void updateBleDeviceList();
- }
- if (selectedConnType === connType.SERIAL) {
- void updateSerialDeviceList();
- }
- }, [selectedConnType, updateBleDeviceList, updateSerialDeviceList]);
+ const state = useAppSelector((state) => state.meshtastic);
+ const appState = useAppSelector((state) => state.app);
React.useEffect(() => {
- const connectionMethod = localStorage.getItem('connectionMethod');
-
- switch (connectionMethod) {
- case 'serial':
- setConnection(new ISerialConnection());
- //show connection dialogue
- break;
- case 'bluetooth':
- setConnection(new IBLEConnection());
- //show connection dialogue
- break;
- default:
- setConnection(new IHTTPConnection());
- void connection.connect({
+ dispatch(
+ setConnectionParams({
+ type: connType.HTTP,
+ params: {
address: connectionUrl,
tls: false,
receiveBatchRequests: false,
fetchInterval: 2000,
- });
- break;
+ },
+ }),
+ );
+ void setConnection(connType.HTTP);
+ }, [dispatch]);
+
+ React.useEffect(() => {
+ if (state.ready) {
+ dispatch(closeConnectionModal());
}
- SettingsManager.debugMode = Protobuf.LogRecord_Level.TRACE;
- }, [hostOverrideEnabled, hostOverride]);
+ }, [state.ready, dispatch]);
return (
{
dispatch(closeConnectionModal());
}}
>
-