This commit is contained in:
Sacha Weatherstone
2021-05-31 22:08:49 +10:00
parent 78bdb2b519
commit 1145df197c
7 changed files with 232 additions and 155 deletions
+22 -4
View File
@@ -1,5 +1,8 @@
import React from 'react';
import { ObservableResource } from 'observable-hooks';
import { Subject } from 'rxjs';
import type {
IBLEConnection,
ISerialConnection,
@@ -40,6 +43,18 @@ export interface languageTemplate {
no_message_placeholder: string;
}
// const adminPacketResource = useSuspense(props.connection.onAdminPacketEvent);
// const tmp$ = new Subject<Types.AdminPacket>().pipe(
// filter(
// (adminPacket) =>
// adminPacket.data.variant.oneofKind === 'getRadioResponse',
// ),
// );
// const tmp$ = props.connection.onAdminPacketEvent;
const tmpSubject = new Subject<Protobuf.RadioConfig_UserPreferences>();
export const adminPacketResource = new ObservableResource(tmpSubject);
const App = (): JSX.Element => {
const [deviceStatus, setDeviceStatus] =
React.useState<Types.DeviceStatusEnum>(
@@ -134,10 +149,13 @@ const App = (): JSX.Element => {
(adminMessage) => {
switch (adminMessage.data.variant.oneofKind) {
case 'getChannelResponse':
if (adminMessage.data.variant.getChannelResponse) {
const message = adminMessage.data.variant.getChannelResponse;
setChannels((channels) => [...channels, message]);
}
setChannels((channels) => [
...channels,
adminMessage.data.variant.getChannelResponse,
]);
break;
case 'getRadioResponse':
tmpSubject.next(adminMessage.data.variant.getRadioResponse);
break;
default:
break;
+8 -10
View File
@@ -1,9 +1,10 @@
import React, { useState } from 'react';
import Avatar from 'boring-avatars';
import {
CheckCircleIcon,
DotsCircleHorizontalIcon,
UserIcon,
} from '@heroicons/react/outline';
import type { Types } from '@meshtastic/meshtasticjs';
@@ -25,15 +26,12 @@ const ChatMessage = (props: ChatMessageProps): JSX.Element => {
}, [props.nodes, props.message]);
return (
<div className="flex items-end">
<div
className={`flex p-3 rounded-full shadow-md ${
props.message.message.packet.from !== props.myId
? 'bg-gray-300'
: 'bg-green-200'
}`}
>
<UserIcon className="m-auto w-5 h-5" />
</div>
<Avatar
size={40}
name={node?.data.user?.longName ?? 'UNK'}
variant="beam"
colors={['#213435', '#46685B', '#648A64', '#A6B985', '#E1E3AC']}
/>
<div className="flex flex-col container px-2 items-start">
<div
className={`px-4 py-2 rounded-md shadow-md ${
+1 -103
View File
@@ -1,21 +1,13 @@
import React from 'react';
import { ObservableResource, useObservableSuspense } from 'observable-hooks';
import { useForm } from 'react-hook-form';
import JSONPretty from 'react-json-pretty';
import { Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { SaveIcon } from '@heroicons/react/outline';
import type {
IBLEConnection,
IHTTPConnection,
ISerialConnection,
Types,
} from '@meshtastic/meshtasticjs';
import { Protobuf } from '@meshtastic/meshtasticjs';
import type { languageTemplate } from '../../../../src/App';
import SettingsForm from './SettingsForm';
export interface SettingsProps {
isReady: boolean;
@@ -23,110 +15,16 @@ export interface SettingsProps {
translations: languageTemplate;
}
export interface SettingsPropsNew {
isReady: boolean;
connection: ISerialConnection | IHTTPConnection | IBLEConnection;
translations: languageTemplate;
adminPacketResource: ObservableResource<Types.AdminPacket, Types.AdminPacket>;
}
const Settings = (props: SettingsProps): JSX.Element => {
// const adminPacketResource = useSuspense(props.connection.onAdminPacketEvent);
const tmp$ = new Subject<Types.AdminPacket>().pipe(
filter(
(adminPacket) =>
adminPacket.data.variant.oneofKind === 'getRadioResponse',
),
);
// const tmp$ = props.connection.onAdminPacketEvent;
const adminPacketResource = new ObservableResource(tmp$);
return (
<React.Suspense fallback={<div>Loading....</div>}>
<SettingsForm
connection={props.connection}
isReady={props.isReady}
translations={props.translations}
adminPacketResource={adminPacketResource}
/>
</React.Suspense>
);
};
const SettingsForm = (props: SettingsPropsNew): JSX.Element => {
// const adminPacket: Types.AdminPacket = props.adminPacketResource.data.read();
const adminPacket = useObservableSuspense(props.adminPacketResource);
const [preferences, setPreferences] =
React.useState<Protobuf.RadioConfig_UserPreferences>();
const { register, handleSubmit } =
useForm<Protobuf.RadioConfig_UserPreferences>({
defaultValues: preferences,
});
const onSubmit = handleSubmit((data) => console.log(data));
return (
<form onSubmit={onSubmit}>
<div>{JSON.stringify(adminPacket)}</div>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{props.translations.device_region_title}</div>
<div className="flex shadow-md rounded-md ml-2">
<select value={preferences?.region ?? Protobuf.RegionCode.Unset}>
<option value={Protobuf.RegionCode.ANZ}>
{Protobuf.RegionCode[Protobuf.RegionCode.ANZ]}
</option>
<option value={Protobuf.RegionCode.CN}>
{Protobuf.RegionCode[Protobuf.RegionCode.CN]}
</option>
<option value={Protobuf.RegionCode.EU433}>
{Protobuf.RegionCode[Protobuf.RegionCode.EU433]}
</option>
<option value={Protobuf.RegionCode.EU865}>
{Protobuf.RegionCode[Protobuf.RegionCode.EU865]}
</option>
<option value={Protobuf.RegionCode.JP}>
{Protobuf.RegionCode[Protobuf.RegionCode.JP]}
</option>
<option value={Protobuf.RegionCode.KR}>
{Protobuf.RegionCode[Protobuf.RegionCode.KR]}
</option>
<option value={Protobuf.RegionCode.TW}>
{Protobuf.RegionCode[Protobuf.RegionCode.TW]}
</option>
<option value={Protobuf.RegionCode.US}>
{Protobuf.RegionCode[Protobuf.RegionCode.US]}
</option>
<option value={Protobuf.RegionCode.Unset}>
{Protobuf.RegionCode[Protobuf.RegionCode.Unset]}
</option>
</select>
</div>
</div>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{props.translations.device_wifi_ssid}</div>
<div className="flex shadow-md rounded-md ml-2">
<input {...register('wifiSsid', {})} type="text" />
</div>
</div>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{props.translations.device_wifi_psk}</div>
<div className="flex shadow-md rounded-md ml-2">
<input {...register('wifiPassword', {})} type="password" />
</div>
</div>
<div className="flex bg-gray-100 group p-1 cursor-pointer hover:bg-gray-200 border-b">
<button
type="submit"
className="flex m-auto font-medium group-hover:text-gray-700"
>
<SaveIcon className="m-auto mr-2 group-hover:text-gray-700 w-5 h-5" />
{props.translations.save_changes_button}
</button>
</div>
<JSONPretty data={preferences} />
</form>
);
};
export default Settings;
@@ -0,0 +1,95 @@
import React from 'react';
import { useObservableSuspense } from 'observable-hooks';
import { useForm } from 'react-hook-form';
import JSONPretty from 'react-json-pretty';
import { SaveIcon } from '@heroicons/react/outline';
import type {
IBLEConnection,
IHTTPConnection,
ISerialConnection,
} from '@meshtastic/meshtasticjs';
import { Protobuf } from '@meshtastic/meshtasticjs';
import type { languageTemplate } from '../../../../src/App';
import { adminPacketResource } from '../../../../src/App';
export interface SettingsFormProps {
isReady: boolean;
connection: ISerialConnection | IHTTPConnection | IBLEConnection;
translations: languageTemplate;
}
const SettingsForm = (props: SettingsFormProps): JSX.Element => {
const preferences = useObservableSuspense(adminPacketResource);
const { register, handleSubmit } =
useForm<Protobuf.RadioConfig_UserPreferences>({
defaultValues: preferences,
});
const onSubmit = handleSubmit((data) => console.log(data));
return (
<form onSubmit={onSubmit}>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{props.translations.device_region_title}</div>
<div className="flex shadow-md rounded-md ml-2">
<select value={preferences?.region ?? Protobuf.RegionCode.Unset}>
<option value={Protobuf.RegionCode.ANZ}>
{Protobuf.RegionCode[Protobuf.RegionCode.ANZ]}
</option>
<option value={Protobuf.RegionCode.CN}>
{Protobuf.RegionCode[Protobuf.RegionCode.CN]}
</option>
<option value={Protobuf.RegionCode.EU433}>
{Protobuf.RegionCode[Protobuf.RegionCode.EU433]}
</option>
<option value={Protobuf.RegionCode.EU865}>
{Protobuf.RegionCode[Protobuf.RegionCode.EU865]}
</option>
<option value={Protobuf.RegionCode.JP}>
{Protobuf.RegionCode[Protobuf.RegionCode.JP]}
</option>
<option value={Protobuf.RegionCode.KR}>
{Protobuf.RegionCode[Protobuf.RegionCode.KR]}
</option>
<option value={Protobuf.RegionCode.TW}>
{Protobuf.RegionCode[Protobuf.RegionCode.TW]}
</option>
<option value={Protobuf.RegionCode.US}>
{Protobuf.RegionCode[Protobuf.RegionCode.US]}
</option>
<option value={Protobuf.RegionCode.Unset}>
{Protobuf.RegionCode[Protobuf.RegionCode.Unset]}
</option>
</select>
</div>
</div>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{props.translations.device_wifi_ssid}</div>
<div className="flex shadow-md rounded-md ml-2">
<input {...register('wifiSsid', {})} type="text" />
</div>
</div>
<div className="flex bg-gray-50 whitespace-nowrap p-3 justify-between border-b">
<div className="my-auto">{props.translations.device_wifi_psk}</div>
<div className="flex shadow-md rounded-md ml-2">
<input {...register('wifiPassword', {})} type="password" />
</div>
</div>
<div className="flex bg-gray-100 group p-1 cursor-pointer hover:bg-gray-200 border-b">
<button
type="submit"
className="flex m-auto font-medium group-hover:text-gray-700"
>
<SaveIcon className="m-auto mr-2 group-hover:text-gray-700 w-5 h-5" />
{props.translations.save_changes_button}
</button>
</div>
<JSONPretty data={preferences} />
</form>
);
};
export default SettingsForm;
+19 -6
View File
@@ -1,11 +1,12 @@
import React from 'react';
import Avatar from 'boring-avatars';
import { Disclosure } from '@headlessui/react';
import {
ChevronDownIcon,
ChevronRightIcon,
ClockIcon,
DesktopComputerIcon,
FlagIcon,
GlobeIcon,
LightningBoltIcon,
@@ -29,11 +30,23 @@ const Node = (props: NodeProps): JSX.Element => {
) : (
<ChevronRightIcon className="my-auto w-5 h-5 mr-2" />
)}
{props.node.data.num === props.myId ? (
<FlagIcon className="text-yellow-500 my-auto mr-2 w-5 h-5" />
) : (
<DesktopComputerIcon className="text-gray-600 my-auto mr-2 w-5 h-5" />
)}
<div className="relative">
{props.node.data.num === props.myId ? (
<FlagIcon className="absolute -right-1 -top-2 text-yellow-500 my-auto w-4 h-4" />
) : null}
<Avatar
size={30}
name={props.node.data.user?.longName}
variant="beam"
colors={[
'#213435',
'#46685B',
'#648A64',
'#A6B985',
'#E1E3AC',
]}
/>
</div>
{props.node.data.user?.longName}
</div>
</Disclosure.Button>