import React from 'react'; import type { IBLEConnection, IHTTPConnection, ISerialConnection, } from '@meshtastic/meshtasticjs'; import { Client, Protobuf, SettingsManager, Types, } from '@meshtastic/meshtasticjs'; import Header from './components/Header'; import Main from './Main'; import Translations_English from './translations/en'; import Translations_Japanese from './translations/jp'; import Translations_Portuguese from './translations/pt'; export enum LanguageEnum { ENGLISH, JAPANESE, PORTUGUESE, } export interface languageTemplate { no_messages_message: string; ui_settings_title: string; nodes_title: string; color_scheme_title: string; language_title: string; device_settings_title: string; device_channels_title: string; device_region_title: string; device_wifi_ssid: string; device_wifi_psk: string; save_changes_button: string; no_nodes_message: string; no_message_placeholder: string; } const App = (): JSX.Element => { const [deviceStatus, setDeviceStatus] = React.useState( Types.DeviceStatusEnum.DEVICE_DISCONNECTED, ); const [myNodeInfo, setMyNodeInfo] = React.useState( Protobuf.MyNodeInfo.create(), ); const [channels, setChannels] = React.useState([] as Protobuf.Channel[]); const [nodes, setNodes] = React.useState([]); const [connection, setConnection] = React.useState(); const [isReady, setIsReady] = React.useState(false); const [lastMeshInterraction, setLastMeshInterraction] = React.useState(0); const [language, setLanguage] = React.useState( LanguageEnum.ENGLISH, ); const [translations, setTranslations] = React.useState(Translations_English); const [darkmode, setDarkmode] = React.useState(false); React.useEffect(() => { switch (language) { case LanguageEnum.ENGLISH: setTranslations(Translations_English); break; case LanguageEnum.PORTUGUESE: setTranslations(Translations_Portuguese); break; case LanguageEnum.JAPANESE: setTranslations(Translations_Japanese); break; default: break; } }, [language]); React.useEffect(() => { const client = new Client(); const connection = client.createHTTPConnection(); connection.connect({ address: import.meta.env.NODE_ENV === 'production' ? window.location.hostname : import.meta.env.SNOWPACK_PUBLIC_DEVICE_IP, receiveBatchRequests: false, tls: false, fetchInterval: 2000, }); setConnection(connection); SettingsManager.debugMode = Protobuf.LogRecord_Level.TRACE; }, []); React.useEffect(() => { console.log('UPDATING'); const deviceStatusEvent = connection?.onDeviceStatusEvent.subscribe( (status) => { setDeviceStatus(status); if (status === Types.DeviceStatusEnum.DEVICE_CONFIGURED) { setIsReady(true); } }, ); const myNodeInfoEvent = connection?.onMyNodeInfoEvent.subscribe(setMyNodeInfo); const nodeInfoPacketEvent = connection?.onNodeInfoPacketEvent.subscribe( (node) => { if ( nodes.findIndex( (currentNode) => currentNode.data.num === node.data.num, ) >= 0 ) { setNodes( nodes.map((currentNode) => currentNode.data.num === node.data.num ? node : currentNode, ), ); } else { setNodes((nodes) => [...nodes, node]); } }, ); const adminPacketEvent = connection?.onAdminPacketEvent.subscribe( (adminMessage) => { switch (adminMessage.data.variant.oneofKind) { case 'getChannelResponse': if (adminMessage.data.variant.getChannelResponse) { const message = adminMessage.data.variant.getChannelResponse; setChannels((channels) => [...channels, message]); } break; default: break; } }, ); const meshHeartbeat = connection?.onMeshHeartbeat.subscribe( setLastMeshInterraction, ); return () => { deviceStatusEvent?.unsubscribe(); myNodeInfoEvent?.unsubscribe(); nodeInfoPacketEvent?.unsubscribe(); adminPacketEvent?.unsubscribe(); meshHeartbeat?.unsubscribe(); connection?.disconnect(); }; }, [connection, nodes]); return (
); }; export default App;