Add store and forward settings
This commit is contained in:
+11
-11
@@ -13,16 +13,16 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^1.4.2",
|
"@headlessui/react": "^1.4.2",
|
||||||
"@meshtastic/meshtasticjs": "^0.6.30",
|
"@meshtastic/meshtasticjs": "^0.6.31",
|
||||||
"@reduxjs/toolkit": "^1.6.2",
|
"@reduxjs/toolkit": "^1.6.2",
|
||||||
"boring-avatars": "^1.5.8",
|
"boring-avatars": "^1.5.8",
|
||||||
"i18next": "^21.5.2",
|
"i18next": "^21.5.3",
|
||||||
"i18next-browser-languagedetector": "^6.1.2",
|
"i18next-browser-languagedetector": "^6.1.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-file-icon": "^1.1.0",
|
"react-file-icon": "^1.1.0",
|
||||||
"react-hook-form": "^7.20.2",
|
"react-hook-form": "^7.20.4",
|
||||||
"react-i18next": "^11.14.2",
|
"react-i18next": "^11.14.3",
|
||||||
"react-icons": "^4.3.1",
|
"react-icons": "^4.3.1",
|
||||||
"react-json-pretty": "^2.2.0",
|
"react-json-pretty": "^2.2.0",
|
||||||
"react-qr-code": "^2.0.3",
|
"react-qr-code": "^2.0.3",
|
||||||
@@ -31,10 +31,10 @@
|
|||||||
"swr": "^1.0.1",
|
"swr": "^1.0.1",
|
||||||
"timeago-react": "^3.0.4",
|
"timeago-react": "^3.0.4",
|
||||||
"type-route": "^0.6.0",
|
"type-route": "^0.6.0",
|
||||||
"use-breakpoint": "^2.0.2"
|
"use-breakpoint": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^17.0.35",
|
"@types/react": "^17.0.37",
|
||||||
"@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",
|
||||||
@@ -42,10 +42,10 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
"@typescript-eslint/parser": "^5.4.0",
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
"@verypossible/eslint-config": "^1.6.1",
|
"@verypossible/eslint-config": "^1.6.1",
|
||||||
"@vitejs/plugin-react": "^1.0.9",
|
"@vitejs/plugin-react": "^1.1.0",
|
||||||
"autoprefixer": "^10.4.0",
|
"autoprefixer": "^10.4.0",
|
||||||
"babel-plugin-module-resolver": "^4.1.0",
|
"babel-plugin-module-resolver": "^4.1.0",
|
||||||
"eslint": "8.2.0",
|
"eslint": "8.3.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-import-resolver-alias": "^1.1.2",
|
"eslint-import-resolver-alias": "^1.1.2",
|
||||||
"eslint-import-resolver-babel-module": "^5.3.1",
|
"eslint-import-resolver-babel-module": "^5.3.1",
|
||||||
@@ -54,13 +54,13 @@
|
|||||||
"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",
|
||||||
"postcss": "^8.3.11",
|
"postcss": "^8.4.4",
|
||||||
"prettier": "^2.4.1",
|
"prettier": "^2.5.0",
|
||||||
"tailwindcss": "^3.0.0-alpha.2",
|
"tailwindcss": "^3.0.0-alpha.2",
|
||||||
"tar": "^6.1.11",
|
"tar": "^6.1.11",
|
||||||
"typescript": "^4.5.2",
|
"typescript": "^4.5.2",
|
||||||
"vite": "^2.6.14",
|
"vite": "^2.6.14",
|
||||||
"vite-plugin-pwa": "^0.11.6",
|
"vite-plugin-pwa": "^0.11.7",
|
||||||
"workbox-window": "^6.4.1"
|
"workbox-window": "^6.4.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+234
-233
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,6 @@ export const Serial = (): JSX.Element => {
|
|||||||
</div>
|
</div>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={async (): Promise<void> => {
|
onClick={async (): Promise<void> => {
|
||||||
dispatch(setConnType(parseInt(e.target.value)));
|
|
||||||
await setConnection(connType.SERIAL);
|
await setConnection(connType.SERIAL);
|
||||||
}}
|
}}
|
||||||
icon={<FiCheck />}
|
icon={<FiCheck />}
|
||||||
|
|||||||
@@ -74,17 +74,9 @@ export const appSlice = createSlice({
|
|||||||
params: Types.ConnectionParameters;
|
params: Types.ConnectionParameters;
|
||||||
}>,
|
}>,
|
||||||
) {
|
) {
|
||||||
switch (action.payload.type) {
|
// @ts-ignore tmp
|
||||||
case connType.BLE:
|
state.connectionParams[connType[action.payload.type]] =
|
||||||
state.connectionParams.BLE = action.payload.params;
|
action.payload.params;
|
||||||
break;
|
|
||||||
case connType.HTTP:
|
|
||||||
state.connectionParams.HTTP = action.payload.params;
|
|
||||||
break;
|
|
||||||
case connType.SERIAL:
|
|
||||||
state.connectionParams.SERIAL = action.payload.params;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ export const meshtasticSlice = createSlice({
|
|||||||
node.user = action.payload.data;
|
node.user = action.payload.data;
|
||||||
// todo: use rx time
|
// todo: use rx time
|
||||||
node.lastHeard = new Date();
|
node.lastHeard = new Date();
|
||||||
|
} else {
|
||||||
|
console.log('Node not in DB');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addPosition: (state, action: PayloadAction<Types.PositionPacket>) => {
|
addPosition: (state, action: PayloadAction<Types.PositionPacket>) => {
|
||||||
@@ -110,8 +112,6 @@ export const meshtasticSlice = createSlice({
|
|||||||
node.lastHeard = new Date(action.payload.lastHeard * 1000);
|
node.lastHeard = new Date(action.payload.lastHeard * 1000);
|
||||||
node.snr.push(action.payload.snr);
|
node.snr.push(action.payload.snr);
|
||||||
} else {
|
} else {
|
||||||
console.log('node does not exist');
|
|
||||||
|
|
||||||
state.nodes.push({
|
state.nodes.push({
|
||||||
number: action.payload.num,
|
number: action.payload.num,
|
||||||
lastHeard: new Date(action.payload.lastHeard * 1000),
|
lastHeard: new Date(action.payload.lastHeard * 1000),
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
|
|
||||||
import { FiAlignLeft, FiBell, FiFileText, FiRss } from 'react-icons/fi';
|
import {
|
||||||
|
FiAlignLeft,
|
||||||
|
FiBell,
|
||||||
|
FiFastForward,
|
||||||
|
FiFileText,
|
||||||
|
FiRss,
|
||||||
|
} from 'react-icons/fi';
|
||||||
|
|
||||||
import { PageLayout } from '@components/templates/PageLayout';
|
import { PageLayout } from '@components/templates/PageLayout';
|
||||||
|
|
||||||
@@ -8,6 +14,7 @@ import { ExternalNotification } from './ExternalNotification';
|
|||||||
import { Files } from './Files';
|
import { Files } from './Files';
|
||||||
import { RangeTest } from './RangeTest';
|
import { RangeTest } from './RangeTest';
|
||||||
import { Serial } from './Serial';
|
import { Serial } from './Serial';
|
||||||
|
import { StoreAndForward } from './StoreAndForward';
|
||||||
|
|
||||||
export const Plugins = (): JSX.Element => {
|
export const Plugins = (): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
@@ -34,12 +41,18 @@ export const Plugins = (): JSX.Element => {
|
|||||||
description: 'Send serial data over the mesh',
|
description: 'Send serial data over the mesh',
|
||||||
icon: <FiAlignLeft className="flex-shrink-0 w-6 h-6" />,
|
icon: <FiAlignLeft className="flex-shrink-0 w-6 h-6" />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Store & Forward',
|
||||||
|
description: 'Retrive message history',
|
||||||
|
icon: <FiFastForward className="flex-shrink-0 w-6 h-6" />,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
panels={[
|
panels={[
|
||||||
<RangeTest key={1} />,
|
<RangeTest key={1} />,
|
||||||
<Files key={2} />,
|
<Files key={2} />,
|
||||||
<ExternalNotification key={3} />,
|
<ExternalNotification key={3} />,
|
||||||
<Serial key={4} />,
|
<Serial key={4} />,
|
||||||
|
<StoreAndForward key={5} />,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
|
import { FiMenu } from 'react-icons/fi';
|
||||||
|
|
||||||
|
import { useAppSelector } from '@app/hooks/redux';
|
||||||
|
import { FormFooter } from '@components/FormFooter';
|
||||||
|
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 { PrimaryTemplate } from '@components/templates/PrimaryTemplate';
|
||||||
|
import { connection } from '@core/connection';
|
||||||
|
import type { RadioConfig_UserPreferences } from '@meshtastic/meshtasticjs/dist/generated';
|
||||||
|
|
||||||
|
export interface StoreAndForwardProps {
|
||||||
|
navOpen?: boolean;
|
||||||
|
setNavOpen?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const StoreAndForward = ({
|
||||||
|
navOpen,
|
||||||
|
setNavOpen,
|
||||||
|
}: StoreAndForwardProps): JSX.Element => {
|
||||||
|
const preferences = useAppSelector(
|
||||||
|
(state) => state.meshtastic.radio.preferences,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { register, handleSubmit, formState, reset, control } =
|
||||||
|
useForm<RadioConfig_UserPreferences>({
|
||||||
|
defaultValues: {
|
||||||
|
storeForwardPluginEnabled: preferences.storeForwardPluginEnabled,
|
||||||
|
storeForwardPluginRecords: preferences.storeForwardPluginRecords,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
reset({
|
||||||
|
storeForwardPluginEnabled: preferences.storeForwardPluginEnabled,
|
||||||
|
storeForwardPluginRecords: preferences.storeForwardPluginRecords,
|
||||||
|
});
|
||||||
|
}, [reset, preferences]);
|
||||||
|
|
||||||
|
const onSubmit = handleSubmit((data) => {
|
||||||
|
void connection.setPreferences(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
const watchStoreForwardPluginEnabled = useWatch({
|
||||||
|
control,
|
||||||
|
name: 'storeForwardPluginEnabled',
|
||||||
|
defaultValue: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PrimaryTemplate
|
||||||
|
title="Serial"
|
||||||
|
tagline="Plugin"
|
||||||
|
leftButton={
|
||||||
|
<IconButton
|
||||||
|
icon={<FiMenu className="w-5 h-5" />}
|
||||||
|
onClick={(): void => {
|
||||||
|
setNavOpen && setNavOpen(!navOpen);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
footer={
|
||||||
|
<FormFooter
|
||||||
|
dirty={formState.isDirty}
|
||||||
|
saveAction={onSubmit}
|
||||||
|
clearAction={reset}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="w-full space-y-4">
|
||||||
|
<Card>
|
||||||
|
<div className="w-full max-w-3xl p-10 md:max-w-xl">
|
||||||
|
<form onSubmit={onSubmit}>
|
||||||
|
<Checkbox
|
||||||
|
label="Plugin Enabled"
|
||||||
|
{...register('storeForwardPluginEnabled')}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
label="Number of records"
|
||||||
|
disabled={!watchStoreForwardPluginEnabled}
|
||||||
|
{...register('storeForwardPluginRecords', {
|
||||||
|
valueAsNumber: true,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</PrimaryTemplate>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user