WIP
This commit is contained in:
+22
-4
@@ -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;
|
||||
|
||||
@@ -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,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;
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user