diff --git a/package.json b/package.json index 3c013050..a7c395c5 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,8 @@ "dependencies": { "@headlessui/react": "^1.2.0", "@heroicons/react": "^1.0.1", - "@meshtastic/meshtasticjs": "^0.6.12", - "@react-rxjs/core": "^0.8.0", - "boring-avatars": "^1.5.4", + "@meshtastic/meshtasticjs": "^0.6.13", + "boring-avatars": "^1.5.5", "observable-hooks": "^4.0.3", "react": "^0.0.0-experimental-d75105fa9", "react-dom": "^0.0.0-experimental-d75105fa9", @@ -34,8 +33,8 @@ "@types/react": "^17.0.8", "@types/react-dom": "^17.0.5", "@types/snowpack-env": "^2.3.2", - "@typescript-eslint/eslint-plugin": "^4.25.0", - "@typescript-eslint/parser": "^4.25.0", + "@typescript-eslint/eslint-plugin": "^4.26.0", + "@typescript-eslint/parser": "^4.26.0", "autoprefixer": "^10.2.6", "eslint": "^7.27.0", "eslint-config-prettier": "^8.3.0", diff --git a/src/App.tsx b/src/App.tsx index be082d41..f030bf3a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,8 +1,5 @@ import React from 'react'; -import { ObservableResource } from 'observable-hooks'; -import { Subject } from 'rxjs'; - import type { IBLEConnection, ISerialConnection, @@ -17,43 +14,12 @@ import { import Header from './components/Header'; import Main from './Main'; +import { channelSubject$, nodeSubject$, preferencesSubject$ } from './streams'; 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 adminPacketResource = useSuspense(props.connection.onAdminPacketEvent); -// const tmp$ = new Subject().pipe( -// filter( -// (adminPacket) => -// adminPacket.data.variant.oneofKind === 'getRadioResponse', -// ), -// ); -// const tmp$ = props.connection.onAdminPacketEvent; -const tmpSubject = new Subject(); - -export const adminPacketResource = new ObservableResource(tmpSubject); +import type { languageTemplate } from './translations/TranslationContext'; +import { LanguageEnum } from './translations/TranslationContext'; const App = (): JSX.Element => { const [deviceStatus, setDeviceStatus] = @@ -63,7 +29,7 @@ const App = (): JSX.Element => { const [myNodeInfo, setMyNodeInfo] = React.useState( Protobuf.MyNodeInfo.create(), ); - const [channels, setChannels] = React.useState([] as Protobuf.Channel[]); + // const [channels, setChannels] = React.useState([] as Protobuf.Channel[]); const [nodes, setNodes] = React.useState([]); const [connection, setConnection] = React.useState< ISerialConnection | IHTTPConnection | IBLEConnection @@ -98,9 +64,9 @@ const App = (): JSX.Element => { React.useEffect(() => { const client = new Client(); - const connection = client.createHTTPConnection(); + const tmpConnection = client.createHTTPConnection(); - connection.connect({ + tmpConnection.connect({ address: import.meta.env.NODE_ENV === 'production' ? window.location.hostname @@ -109,13 +75,11 @@ const App = (): JSX.Element => { tls: false, fetchInterval: 2000, }); - setConnection(connection); + setConnection(tmpConnection); SettingsManager.debugMode = Protobuf.LogRecord_Level.TRACE; }, []); React.useEffect(() => { - console.log('UPDATING'); - const deviceStatusEvent = connection.onDeviceStatusEvent.subscribe( (status) => { setDeviceStatus(status); @@ -128,34 +92,21 @@ const App = (): JSX.Element => { 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]); - } - }, + (node) => nodeSubject$.next(node), ); const adminPacketEvent = connection.onAdminPacketEvent.subscribe( (adminMessage) => { switch (adminMessage.data.variant.oneofKind) { case 'getChannelResponse': - setChannels((channels) => [ - ...channels, - adminMessage.data.variant.getChannelResponse, - ]); + channelSubject$.next(adminMessage.data.variant.getChannelResponse); break; case 'getRadioResponse': - tmpSubject.next(adminMessage.data.variant.getRadioResponse); + if (adminMessage.data.variant.getRadioResponse.preferences) { + preferencesSubject$.next( + adminMessage.data.variant.getRadioResponse.preferences, + ); + } break; default: break; @@ -190,11 +141,8 @@ const App = (): JSX.Element => { isReady={isReady} myNodeInfo={myNodeInfo} connection={connection} - nodes={nodes} - channels={channels} language={language} setLanguage={setLanguage} - translations={translations} darkmode={darkmode} setDarkmode={setDarkmode} /> diff --git a/src/Main.tsx b/src/Main.tsx index d67d7bc4..e4babc94 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -8,25 +8,24 @@ import type { Types, } from '@meshtastic/meshtasticjs'; -import type { LanguageEnum, languageTemplate } from './App'; import ChatMessage from './components/ChatMessage'; import MessageBox from './components/MessageBox'; import Sidebar from './components/Sidebar'; +import type { LanguageEnum } from './translations/TranslationContext'; +import { TranslationContext } from './translations/TranslationContext'; interface MainProps { connection: ISerialConnection | IHTTPConnection | IBLEConnection; myNodeInfo: Protobuf.MyNodeInfo; - nodes: Types.NodeInfoPacket[]; - channels: Protobuf.Channel[]; isReady: boolean; language: LanguageEnum; setLanguage: React.Dispatch>; - translations: languageTemplate; darkmode: boolean; setDarkmode: React.Dispatch>; } const Main = (props: MainProps): JSX.Element => { + const { translations } = React.useContext(TranslationContext); const [messages, setMessages] = React.useState< { message: Types.TextPacket; ack: boolean }[] >([]); @@ -72,7 +71,6 @@ const Main = (props: MainProps): JSX.Element => { {messages.length ? ( messages.map((message, Main) => ( { )) ) : (
- {props.translations.no_messages_message} + {translations.no_messages_message}
)} @@ -89,17 +87,13 @@ const Main = (props: MainProps): JSX.Element => { isReady={props.isReady} sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} - translations={props.translations} /> { + const nodeSource = useObservableSuspense(nodeResource); + + const [nodes, setNodes] = React.useState([]); + + React.useEffect(() => { + if ( + nodes.findIndex( + (currentNode) => currentNode.data.num === nodeSource.data.num, + ) >= 0 + ) { + setNodes( + nodes.map((currentNode) => + currentNode.data.num === nodeSource.data.num + ? nodeSource + : currentNode, + ), + ); + } else { + setNodes((nodes) => [...nodes, nodeSource]); + } + }, [nodeSource, nodes]); const [node, setNode] = useState(); React.useEffect(() => { setNode( - props.nodes.find( - (node) => node.data.num === props.message.message.packet.from, - ), + nodes.find((node) => node.data.num === props.message.message.packet.from), ); - }, [props.nodes, props.message]); + }, [nodes, props.message]); return (
>; connection: ISerialConnection | IHTTPConnection | IBLEConnection; @@ -18,6 +17,7 @@ export interface MessageBoxProps { } const MessageBox = (props: MessageBoxProps): JSX.Element => { + const { translations } = React.useContext(TranslationContext); const [currentMessage, setCurrentMessage] = React.useState(''); const sendMessage = () => { if (props.isReady) { @@ -45,7 +45,7 @@ const MessageBox = (props: MessageBoxProps): JSX.Element => { {props.isReady} { diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index af437d67..51b48fe0 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -4,11 +4,9 @@ import type { IBLEConnection, IHTTPConnection, ISerialConnection, - Protobuf, - Types, } from '@meshtastic/meshtasticjs'; -import type { LanguageEnum, languageTemplate } from '../App'; +import type { LanguageEnum } from '../translations/TranslationContext'; import Channels from './Sidebar/Channels/Index'; import Device from './Sidebar/Device/Index'; import Nodes from './Sidebar/Nodes/Index'; @@ -16,12 +14,9 @@ import UI from './Sidebar/UI/Index'; interface SidebarProps { isReady: boolean; - nodes: Types.NodeInfoPacket[]; - channels: Protobuf.Channel[]; connection: ISerialConnection | IHTTPConnection | IBLEConnection; language: LanguageEnum; setLanguage: React.Dispatch>; - translations: languageTemplate; myId: number; sidebarOpen: boolean; darkmode: boolean; @@ -35,27 +30,13 @@ const Sidebar = (props: SidebarProps): JSX.Element => { props.sidebarOpen ? 'flex' : 'hidden md:flex' } flex-col rounded-md md:ml-0 shadow-md border w-full max-w-sm`} > - - - + + +
diff --git a/src/components/Sidebar/Channels/ChannelList.tsx b/src/components/Sidebar/Channels/ChannelList.tsx new file mode 100644 index 00000000..0001fc9c --- /dev/null +++ b/src/components/Sidebar/Channels/ChannelList.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +import { useObservableSuspense } from 'observable-hooks'; + +import { Protobuf } from '@meshtastic/meshtasticjs'; + +import { channelResource } from '../../../streams'; +import Channel from './Channel'; + +const ChannelList = (): JSX.Element => { + const channelSource = useObservableSuspense(channelResource); + + const [channels, setChannels] = React.useState([]); + + React.useEffect(() => { + if ( + channels.findIndex( + (currentChannel) => currentChannel.index === channelSource.index, + ) >= 0 + ) { + setChannels( + channels.map((currentChannel) => + currentChannel.index === channelSource.index + ? channelSource + : currentChannel, + ), + ); + } else { + setChannels((channels) => [...channels, channelSource]); + } + }, [channelSource, channels]); + + return ( + <> + {channels.map((channel, index) => { + if (channel.role !== Protobuf.Channel_Role.DISABLED) + return ; + })} + + ); +}; + +export default ChannelList; diff --git a/src/components/Sidebar/Channels/Index.tsx b/src/components/Sidebar/Channels/Index.tsx index 57d2e120..99ddf0e1 100644 --- a/src/components/Sidebar/Channels/Index.tsx +++ b/src/components/Sidebar/Channels/Index.tsx @@ -6,18 +6,12 @@ import { ChevronRightIcon, HashtagIcon, } from '@heroicons/react/outline'; -import { Protobuf } from '@meshtastic/meshtasticjs'; -import type { languageTemplate } from '../../../App'; -import Channel from './Channel'; +import { TranslationContext } from '../../../translations/TranslationContext'; +import ChannelList from './ChannelList'; -export interface ChannelsProps { - isReady: boolean; - channels: Protobuf.Channel[]; - translations: languageTemplate; -} - -const Channels = (props: ChannelsProps): JSX.Element => { +const Channels = (): JSX.Element => { + const { translations } = React.useContext(TranslationContext); return ( {({ open }) => ( @@ -30,16 +24,19 @@ const Channels = (props: ChannelsProps): JSX.Element => { )} - {props.translations.device_channels_title} + {translations.device_channels_title}
- <> - {props.channels.map((channel, index) => { - if (channel.role !== Protobuf.Channel_Role.DISABLED) - return ; - })} - + +
Loading...
+ + } + > + +
)} diff --git a/src/components/Sidebar/Device/Index.tsx b/src/components/Sidebar/Device/Index.tsx index dcd0cbce..e56e492f 100644 --- a/src/components/Sidebar/Device/Index.tsx +++ b/src/components/Sidebar/Device/Index.tsx @@ -1,4 +1,4 @@ -import React, { Suspense } from 'react'; +import React from 'react'; import { Disclosure } from '@headlessui/react'; import { @@ -12,16 +12,16 @@ import type { ISerialConnection, } from '@meshtastic/meshtasticjs'; -import type { languageTemplate } from '../../../App'; +import { TranslationContext } from '../../../translations/TranslationContext'; import Settings from './Settings'; interface DeviceProps { isReady: boolean; connection: ISerialConnection | IHTTPConnection | IBLEConnection; - translations: languageTemplate; } const Device = (props: DeviceProps): JSX.Element => { + const { translations } = React.useContext(TranslationContext); return ( {({ open }) => ( @@ -34,18 +34,23 @@ const Device = (props: DeviceProps): JSX.Element => { )} - {props.translations.device_settings_title} + {translations.device_settings_title} <> - loading}> + +
Loading...
+ + } + > -
+
diff --git a/src/components/Sidebar/Device/Settings.tsx b/src/components/Sidebar/Device/Settings.tsx index c129f09a..ff8cceaa 100644 --- a/src/components/Sidebar/Device/Settings.tsx +++ b/src/components/Sidebar/Device/Settings.tsx @@ -1,29 +1,94 @@ 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 SettingsForm from './SettingsForm'; +import { preferencesResource } from '../../../streams'; +import { TranslationContext } from '../../../translations/TranslationContext'; export interface SettingsProps { isReady: boolean; connection: ISerialConnection | IHTTPConnection | IBLEConnection; - translations: languageTemplate; } const Settings = (props: SettingsProps): JSX.Element => { + const { translations } = React.useContext(TranslationContext); + const preferences = useObservableSuspense(preferencesResource); + + const { register, handleSubmit } = + useForm({ + defaultValues: preferences, + }); + + const onSubmit = handleSubmit((data) => console.log(data)); return ( - Loading....}> - - +
+
+
{translations.device_region_title}
+
+ +
+
+
+
{translations.device_wifi_ssid}
+
+ +
+
+
+
{translations.device_wifi_psk}
+
+ +
+
+
+ +
+ + ); }; diff --git a/src/components/Sidebar/Device/SettingsForm.tsx b/src/components/Sidebar/Device/SettingsForm.tsx deleted file mode 100644 index fd14831b..00000000 --- a/src/components/Sidebar/Device/SettingsForm.tsx +++ /dev/null @@ -1,95 +0,0 @@ -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({ - defaultValues: preferences, - }); - - const onSubmit = handleSubmit((data) => console.log(data)); - return ( -
-
-
{props.translations.device_region_title}
-
- -
-
-
-
{props.translations.device_wifi_ssid}
-
- -
-
-
-
{props.translations.device_wifi_psk}
-
- -
-
-
- -
- - - ); -}; - -export default SettingsForm; diff --git a/src/components/Sidebar/Nodes/Index.tsx b/src/components/Sidebar/Nodes/Index.tsx index ca66c65b..79fc11f9 100644 --- a/src/components/Sidebar/Nodes/Index.tsx +++ b/src/components/Sidebar/Nodes/Index.tsx @@ -6,19 +6,16 @@ import { ChevronRightIcon, UsersIcon, } from '@heroicons/react/outline'; -import type { Types } from '@meshtastic/meshtasticjs'; -import type { languageTemplate } from '../../../App'; -import Node from './Node'; +import { TranslationContext } from '../../../translations/TranslationContext'; +import NodeList from './NodeList'; interface NodesProps { - isReady: boolean; - nodes: Types.NodeInfoPacket[]; - translations: languageTemplate; myId: number; } const Nodes = (props: NodesProps): JSX.Element => { + const { translations } = React.useContext(TranslationContext); return ( {({ open }) => ( @@ -31,21 +28,21 @@ const Nodes = (props: NodesProps): JSX.Element => { )} - {props.translations.nodes_title} + {translations.nodes_title} - {props.nodes.length ? ( - props.nodes.map((node, index) => ( - - )) - ) : ( -
-
- {props.translations.no_nodes_message} + +
+ {translations.no_nodes_message} +
-
- )} + } + > + +
)} diff --git a/src/components/Sidebar/Nodes/NodeList.tsx b/src/components/Sidebar/Nodes/NodeList.tsx new file mode 100644 index 00000000..2fc7ff1e --- /dev/null +++ b/src/components/Sidebar/Nodes/NodeList.tsx @@ -0,0 +1,46 @@ +import React from 'react'; + +import { useObservableSuspense } from 'observable-hooks'; + +import type { Types } from '@meshtastic/meshtasticjs'; + +import { nodeResource } from '../../../streams'; +import Node from './Node'; + +export interface NodeListProps { + myId: number; +} + +const NodeList = (props: NodeListProps): JSX.Element => { + const nodeSource = useObservableSuspense(nodeResource); + + const [nodes, setNodes] = React.useState([]); + + React.useEffect(() => { + if ( + nodes.findIndex( + (currentNode) => currentNode.data.num === nodeSource.data.num, + ) >= 0 + ) { + setNodes( + nodes.map((currentNode) => + currentNode.data.num === nodeSource.data.num + ? nodeSource + : currentNode, + ), + ); + } else { + setNodes((nodes) => [...nodes, nodeSource]); + } + }, [nodeSource, nodes]); + + return ( + <> + {nodes.map((node, index) => ( + + ))} + + ); +}; + +export default NodeList; diff --git a/src/components/Sidebar/UI/Index.tsx b/src/components/Sidebar/UI/Index.tsx index 8ea83a27..537467fd 100644 --- a/src/components/Sidebar/UI/Index.tsx +++ b/src/components/Sidebar/UI/Index.tsx @@ -7,18 +7,19 @@ import { CogIcon, } from '@heroicons/react/outline'; -import type { LanguageEnum, languageTemplate } from '../../../App'; +import type { LanguageEnum } from '../../../translations/TranslationContext'; +import { TranslationContext } from '../../../translations/TranslationContext'; import Translations from './Translations'; interface UIProps { language: LanguageEnum; setLanguage: React.Dispatch>; - translations: languageTemplate; darkmode: boolean; setDarkmode: React.Dispatch>; } const UI = (props: UIProps): JSX.Element => { + const { translations } = React.useContext(TranslationContext); return ( {({ open }) => ( @@ -31,14 +32,13 @@ const UI = (props: UIProps): JSX.Element => { )} - {props.translations.ui_settings_title} + {translations.ui_settings_title} diff --git a/src/components/Sidebar/UI/Translations.tsx b/src/components/Sidebar/UI/Translations.tsx index ffa8cf25..4d4343e5 100644 --- a/src/components/Sidebar/UI/Translations.tsx +++ b/src/components/Sidebar/UI/Translations.tsx @@ -5,16 +5,18 @@ import { Br, Jp, Us } from 'react-flags-select'; import { Disclosure } from '@headlessui/react'; import { ChevronDownIcon, ChevronRightIcon } from '@heroicons/react/outline'; -import type { languageTemplate } from '../../../App'; -import { LanguageEnum } from '../../../App'; +import { + LanguageEnum, + TranslationContext, +} from '../../../translations/TranslationContext'; export interface TranslationsProps { language: LanguageEnum; setLanguage: React.Dispatch>; - translations: languageTemplate; } const Translations = (props: TranslationsProps): JSX.Element => { + const { translations } = React.useContext(TranslationContext); return ( {({ open }) => ( @@ -26,7 +28,7 @@ const Translations = (props: TranslationsProps): JSX.Element => { ) : ( )} - {props.translations.language_title} + {translations.language_title}
{props.language === LanguageEnum.ENGLISH ? ( diff --git a/src/index.tsx b/src/index.tsx index ec5c07ee..3d2b7be8 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,13 +7,27 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; +import Translations_English from './translations/en'; +import { + LanguageEnum, + TranslationContext, +} from './translations/TranslationContext'; const element = document.getElementById('root'); if (element) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore ReactDOM.createRoot(element).render( - + + + , ); } diff --git a/src/streams.ts b/src/streams.ts new file mode 100644 index 00000000..c6f904a2 --- /dev/null +++ b/src/streams.ts @@ -0,0 +1,17 @@ +import { ObservableResource } from 'observable-hooks'; +import { Subject } from 'rxjs'; + +import type { Protobuf, Types } from '@meshtastic/meshtasticjs'; + +export const preferencesSubject$ = + new Subject(); + +export const preferencesResource = new ObservableResource(preferencesSubject$); + +export const nodeSubject$ = new Subject(); + +export const nodeResource = new ObservableResource(nodeSubject$); + +export const channelSubject$ = new Subject(); + +export const channelResource = new ObservableResource(channelSubject$); diff --git a/src/translations/TranslationContext.tsx b/src/translations/TranslationContext.tsx new file mode 100644 index 00000000..cdb7363a --- /dev/null +++ b/src/translations/TranslationContext.tsx @@ -0,0 +1,39 @@ +import React from 'react'; + +import Translations_English from './en'; + +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; +} + +export enum LanguageEnum { + ENGLISH, + JAPANESE, + PORTUGUESE, +} + +export const TranslationContext = React.createContext({ + language: LanguageEnum.ENGLISH, + translations: Translations_English, +}); + +// const TranslationProvider: React.FC = ({ children }) => { +// const [language, setLanguage] = React.useState( +// LanguageEnum.ENGLISH, +// ); +// return { children }; +// }; + +// export default TranslationProvider; diff --git a/src/translations/en.ts b/src/translations/en.ts index 0b8fa486..2d3e28f3 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -1,4 +1,4 @@ -import type { languageTemplate } from '../App'; +import type { languageTemplate } from './TranslationContext'; export default { no_messages_message: 'No messages yet', diff --git a/src/translations/jp.ts b/src/translations/jp.ts index 003b5661..206ec8f2 100644 --- a/src/translations/jp.ts +++ b/src/translations/jp.ts @@ -1,4 +1,4 @@ -import type { languageTemplate } from '../App'; +import type { languageTemplate } from './TranslationContext'; export default { no_messages_message: 'まだメッセージはありません', diff --git a/src/translations/pt.ts b/src/translations/pt.ts index e4737540..cbc64526 100644 --- a/src/translations/pt.ts +++ b/src/translations/pt.ts @@ -1,4 +1,4 @@ -import type { languageTemplate } from '../App'; +import type { languageTemplate } from './TranslationContext'; export default { no_messages_message: 'Não a mensagens ainda', diff --git a/tsconfig.json b/tsconfig.json index da987e44..296d1405 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,20 +17,7 @@ "noEmit": true, /* Additional Options */ "strict": true, - "noImplicitAny": true, - "noImplicitThis": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // "noUncheckedIndexedAccess": true, - "noPropertyAccessFromIndexSignature": true, - "strictBindCallApply": true, - "strictFunctionTypes": true, "strictNullChecks": true, - "strictPropertyInitialization": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, diff --git a/yarn.lock b/yarn.lock index 175de8a9..1ce76563 100644 --- a/yarn.lock +++ b/yarn.lock @@ -259,13 +259,13 @@ resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.1.tgz#66d25f6441920bd5c2146ea27fd33995885452dd" integrity sha512-uikw2gKCmqnvjVxitecWfFLMOKyL9BTFcU4VM3hHj9OMwpkCr5Ke+MRMyY2/aQVmsYs4VTq7NCFX05MYwAHi3g== -"@meshtastic/meshtasticjs@^0.6.12": - version "0.6.12" - resolved "https://registry.yarnpkg.com/@meshtastic/meshtasticjs/-/meshtasticjs-0.6.12.tgz#10368d67d983fdedae46fc176bc9da07bb67e7e7" - integrity sha512-Ys8odPrmWaLHcyzRE8+iQT2TCMIWPQXldIkEc7ydmAZO3Hc5Ol1pOHHsd/EMh9AvM/pR5ZhbSX2j8q5hBhG6UQ== +"@meshtastic/meshtasticjs@^0.6.13": + version "0.6.13" + resolved "https://registry.yarnpkg.com/@meshtastic/meshtasticjs/-/meshtasticjs-0.6.13.tgz#4e459a1380a8761dc119e5f43bbc42c18b18e5a1" + integrity sha512-NdS5Cx/da7NW2FXgWvk+3lyFh/iVV3KpoEFkTFOS06liPYty1eKJo/sZgfNd/7DfdiWEDeOq9UG4aAVVsIxnlw== dependencies: - "@protobuf-ts/runtime" "^2.0.0-alpha.21" - rxjs "^6.6.7" + "@protobuf-ts/runtime" "^2.0.0-alpha.25" + rxjs "^7.1.0" "@nodelib/fs.scandir@2.1.4": version "2.1.4" @@ -341,15 +341,10 @@ node-gyp "^7.1.0" read-package-json-fast "^2.0.1" -"@protobuf-ts/runtime@^2.0.0-alpha.21": - version "2.0.0-alpha.21" - resolved "https://registry.yarnpkg.com/@protobuf-ts/runtime/-/runtime-2.0.0-alpha.21.tgz#0814f365d1f155f55a83e13f38dba92856e66ec5" - integrity sha512-m6Ohw3ke0RiCW41kKbkPW7z+wEgchX99iAwPjFMHRYEf1w1fX8IBIzANHe13lg2MP1P7zmZYGbQ5nupFqo4cWw== - -"@react-rxjs/core@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@react-rxjs/core/-/core-0.8.0.tgz#b73c0480a457b654fdcd6d6ede36bbd99c691b2e" - integrity sha512-LvmVEel9MPykAJoI0oZafmui2JOU18bmIf0X0P+oEtVii0LNaj8p/3eL52NfWgsQd6hSrjevSwNbbrScsYuaFg== +"@protobuf-ts/runtime@^2.0.0-alpha.25": + version "2.0.0-alpha.25" + resolved "https://registry.yarnpkg.com/@protobuf-ts/runtime/-/runtime-2.0.0-alpha.25.tgz#e8e7067c77ddf35a3e310ea93f58a58aa42e9bc2" + integrity sha512-+N3Jj61AY8u0MxxaxtovLDWgVdTmOhDG4lDDyfRQPGFzpz+ACFEcTE6WRIj1xe62kbgyQFiWkIfPO1F/mHBF3g== "@snowpack/plugin-dotenv@^2.0.5": version "2.1.0" @@ -402,7 +397,7 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== -"@types/json-schema@*", "@types/json-schema@^7.0.3": +"@types/json-schema@*", "@types/json-schema@^7.0.7": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== @@ -457,74 +452,74 @@ resolved "https://registry.yarnpkg.com/@types/snowpack-env/-/snowpack-env-2.3.3.tgz#d2dfb1fb8557aa8bb517606d5dfa249cc861c3ff" integrity sha512-riJuu2fR3qhBfpWJtqQtNwYJFvquiXfqdprXvZjSNmscnZbIVyHoM49ZVEM1bciKM1mWOCdjXymOYHyGh2WLtg== -"@typescript-eslint/eslint-plugin@^4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.25.0.tgz#d82657b6ab4caa4c3f888ff923175fadc2f31f2a" - integrity sha512-Qfs3dWkTMKkKwt78xp2O/KZQB8MPS1UQ5D3YW2s6LQWBE1074BE+Rym+b1pXZIX3M3fSvPUDaCvZLKV2ylVYYQ== +"@typescript-eslint/eslint-plugin@^4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.0.tgz#12bbd6ebd5e7fabd32e48e1e60efa1f3554a3242" + integrity sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg== dependencies: - "@typescript-eslint/experimental-utils" "4.25.0" - "@typescript-eslint/scope-manager" "4.25.0" - debug "^4.1.1" + "@typescript-eslint/experimental-utils" "4.26.0" + "@typescript-eslint/scope-manager" "4.26.0" + debug "^4.3.1" functional-red-black-tree "^1.0.1" - lodash "^4.17.15" - regexpp "^3.0.0" - semver "^7.3.2" - tsutils "^3.17.1" - -"@typescript-eslint/experimental-utils@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.25.0.tgz#b2febcfa715d2c1806fd5f0335193a6cd270df54" - integrity sha512-f0doRE76vq7NEEU0tw+ajv6CrmPelw5wLoaghEHkA2dNLFb3T/zJQqGPQ0OYt5XlZaS13MtnN+GTPCuUVg338w== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.25.0" - "@typescript-eslint/types" "4.25.0" - "@typescript-eslint/typescript-estree" "4.25.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - -"@typescript-eslint/parser@^4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.25.0.tgz#6b2cb6285aa3d55bfb263c650739091b0f19aceb" - integrity sha512-OZFa1SKyEJpAhDx8FcbWyX+vLwh7OEtzoo2iQaeWwxucyfbi0mT4DijbOSsTgPKzGHr6GrF2V5p/CEpUH/VBxg== - dependencies: - "@typescript-eslint/scope-manager" "4.25.0" - "@typescript-eslint/types" "4.25.0" - "@typescript-eslint/typescript-estree" "4.25.0" - debug "^4.1.1" - -"@typescript-eslint/scope-manager@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.25.0.tgz#9d86a5bcc46ef40acd03d85ad4e908e5aab8d4ca" - integrity sha512-2NElKxMb/0rya+NJG1U71BuNnp1TBd1JgzYsldsdA83h/20Tvnf/HrwhiSlNmuq6Vqa0EzidsvkTArwoq+tH6w== - dependencies: - "@typescript-eslint/types" "4.25.0" - "@typescript-eslint/visitor-keys" "4.25.0" - -"@typescript-eslint/types@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.25.0.tgz#0e444a5c5e3c22d7ffa5e16e0e60510b3de5af87" - integrity sha512-+CNINNvl00OkW6wEsi32wU5MhHti2J25TJsJJqgQmJu3B3dYDBcmOxcE5w9cgoM13TrdE/5ND2HoEnBohasxRQ== + lodash "^4.17.21" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.25.0.tgz#942e4e25888736bff5b360d9b0b61e013d0cfa25" - integrity sha512-1B8U07TGNAFMxZbSpF6jqiDs1cVGO0izVkf18Q/SPcUAc9LhHxzvSowXDTvkHMWUVuPpagupaW63gB6ahTXVlg== +"@typescript-eslint/experimental-utils@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.0.tgz#ba7848b3f088659cdf71bce22454795fc55be99a" + integrity sha512-TH2FO2rdDm7AWfAVRB5RSlbUhWxGVuxPNzGT7W65zVfl8H/WeXTk1e69IrcEVsBslrQSTDKQSaJD89hwKrhdkw== dependencies: - "@typescript-eslint/types" "4.25.0" - "@typescript-eslint/visitor-keys" "4.25.0" - debug "^4.1.1" - globby "^11.0.1" + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.26.0" + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/typescript-estree" "4.26.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.26.0.tgz#31b6b732c9454f757b020dab9b6754112aa5eeaf" + integrity sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg== + dependencies: + "@typescript-eslint/scope-manager" "4.26.0" + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/typescript-estree" "4.26.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz#60d1a71df162404e954b9d1c6343ff3bee496194" + integrity sha512-G6xB6mMo4xVxwMt5lEsNTz3x4qGDt0NSGmTBNBPJxNsrTXJSm21c6raeYroS2OwQsOyIXqKZv266L/Gln1BWqg== + dependencies: + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/visitor-keys" "4.26.0" + +"@typescript-eslint/types@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.0.tgz#7c6732c0414f0a69595f4f846ebe12616243d546" + integrity sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A== + +"@typescript-eslint/typescript-estree@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz#aea17a40e62dc31c63d5b1bbe9a75783f2ce7109" + integrity sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg== + dependencies: + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/visitor-keys" "4.26.0" + debug "^4.3.1" + globby "^11.0.3" is-glob "^4.0.1" - semver "^7.3.2" - tsutils "^3.17.1" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.25.0.tgz#863e7ed23da4287c5b469b13223255d0fde6aaa7" - integrity sha512-AmkqV9dDJVKP/TcZrbf6s6i1zYXt5Hl8qOLrRDTFfRNae4+LB8A4N3i+FLZPW85zIxRy39BgeWOfMS3HoH5ngg== +"@typescript-eslint/visitor-keys@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz#26d2583169222815be4dcd1da4fe5459bc3bcc23" + integrity sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg== dependencies: - "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/types" "4.26.0" eslint-visitor-keys "^2.0.0" abbrev@1: @@ -780,10 +775,10 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -boring-avatars@^1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/boring-avatars/-/boring-avatars-1.5.4.tgz#4ca5608fb16b75322cf5e1bcdc49debfeb2dfd0d" - integrity sha512-sSfAGVAjN0LNILSoQRT2zbG6Dy4j4WMqoDoydsU9xoIi9LKYae4DgaqRhCoGjn0iYRwsWtAu0PsohH1rLVPm+A== +boring-avatars@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/boring-avatars/-/boring-avatars-1.5.5.tgz#ea0b0f0f40299283586c31070ead7285956c0869" + integrity sha512-sIvumj2yscTQwcAdp/ANi4i97OKq5yPgXY6MfdHW4b6k6iljn9gFZa6TXgWyBnKXMPytx5e04mxrv7OCZKX9Wg== bplist-parser@^0.1.0: version "0.1.1" @@ -1087,7 +1082,7 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== @@ -1438,7 +1433,7 @@ eslint-plugin-react@^7.24.0: resolve "^2.0.0-next.3" string.prototype.matchall "^4.0.5" -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -1446,13 +1441,20 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: +eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" @@ -1828,7 +1830,7 @@ globals@^13.6.0: dependencies: type-fest "^0.20.2" -globby@^11.0.0, globby@^11.0.1: +globby@^11.0.0, globby@^11.0.3: version "11.0.3" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== @@ -2469,7 +2471,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: +lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3396,7 +3398,7 @@ regexp.prototype.flags@^1.3.0, regexp.prototype.flags@^1.3.1: call-bind "^1.0.2" define-properties "^1.1.3" -regexpp@^3.0.0, regexpp@^3.1.0: +regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== @@ -3494,13 +3496,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^6.6.7: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - rxjs@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.1.0.tgz#94202d27b19305ef7b1a4f330277b2065df7039e" @@ -3912,7 +3907,7 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -3922,7 +3917,7 @@ tslib@~2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tsutils@^3.17.1: +tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==