Browse Source

Add store and forward settings

pull/2/head
Sacha Weatherstone 5 years ago
parent
commit
b6c79afc19
  1. 22
      package.json
  2. 467
      pnpm-lock.yaml
  3. 1
      src/components/connection/Serial.tsx
  4. 14
      src/core/slices/appSlice.ts
  5. 4
      src/core/slices/meshtasticSlice.ts
  6. 15
      src/pages/Plugins/Index.tsx
  7. 96
      src/pages/Plugins/StoreAndForward.tsx

22
package.json

@ -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"
} }
} }

467
pnpm-lock.yaml

File diff suppressed because it is too large

1
src/components/connection/Serial.tsx

@ -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 />}

14
src/core/slices/appSlice.ts

@ -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;
}
}, },
}, },
}); });

4
src/core/slices/meshtasticSlice.ts

@ -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),

15
src/pages/Plugins/Index.tsx

@ -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} />,
]} ]}
/> />
); );

96
src/pages/Plugins/StoreAndForward.tsx

@ -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>
);
};
Loading…
Cancel
Save