From 339143ef7f58020403d6505c5f0f48ca8828cade Mon Sep 17 00:00:00 2001 From: Sacha Weatherstone Date: Tue, 15 Jun 2021 23:15:33 +1000 Subject: [PATCH] WIP --- package.json | 5 +- snowpack.config.js => snowpack.config.mjs | 5 +- src/App.tsx | 7 --- src/Main.tsx | 70 ++++++++++----------- src/components/MessageBox.tsx | 4 +- src/components/Sidebar.tsx | 20 +----- src/components/Sidebar/Channels/Index.tsx | 4 +- src/components/Sidebar/Device/Index.tsx | 21 ++----- src/components/Sidebar/Device/Settings.tsx | 16 +---- src/components/Sidebar/Nodes/Index.tsx | 4 +- src/components/Sidebar/Nodes/Node.tsx | 2 +- src/components/Sidebar/UI/Index.tsx | 12 +--- src/components/Sidebar/UI/Translations.tsx | 26 ++++---- src/hooks/useTranslationsContextValue.ts | 42 +++++++++++++ src/index.tsx | 5 +- src/translations/TranslationContext.tsx | 73 ---------------------- src/translations/TranslationsContext.tsx | 41 ++++++++++++ src/translations/en.ts | 2 +- src/translations/jp.ts | 2 +- src/translations/pt.ts | 2 +- tsconfig.json | 2 +- yarn.lock | 13 ++-- 22 files changed, 161 insertions(+), 217 deletions(-) rename snowpack.config.js => snowpack.config.mjs (93%) create mode 100644 src/hooks/useTranslationsContextValue.ts delete mode 100644 src/translations/TranslationContext.tsx create mode 100644 src/translations/TranslationsContext.tsx diff --git a/package.json b/package.json index 7bc7b392..20a1ab70 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,9 @@ "react": "^18.0.0-alpha-dbe3363cc", "react-dom": "^18.0.0-alpha-dbe3363cc", "react-flags-select": "^2.1.2", - "react-hook-form": "^7.8.4", + "react-hook-form": "^7.8.6", "react-json-pretty": "^2.2.0", - "rxjs": "^7.1.0", - "yarn": "^1.22.10" + "rxjs": "^7.1.0" }, "devDependencies": { "@snowpack/plugin-dotenv": "^2.0.5", diff --git a/snowpack.config.js b/snowpack.config.mjs similarity index 93% rename from snowpack.config.js rename to snowpack.config.mjs index f664f4c1..388dbafd 100644 --- a/snowpack.config.js +++ b/snowpack.config.mjs @@ -1,13 +1,13 @@ /** @type {import("snowpack").SnowpackUserConfig } */ -module.exports = { +export default { mount: { public: { url: '/', static: true }, src: { url: '/static' }, }, plugins: [ - '@snowpack/plugin-postcss', '@snowpack/plugin-react-refresh', '@snowpack/plugin-dotenv', + '@snowpack/plugin-postcss', [ '@snowpack/plugin-typescript', { @@ -21,6 +21,7 @@ module.exports = { // {"match": "routes", "src": ".*", "dest": "/index.html"}, ], optimize: { + /* Example: Bundle your final build: */ bundle: true, sourcemap: false, splitting: true, diff --git a/src/App.tsx b/src/App.tsx index b7306874..60f969cd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,7 +15,6 @@ import { import Header from './components/Header'; import Main from './Main'; import { channelSubject$, nodeSubject$, preferencesSubject$ } from './streams'; -import { LanguageEnum } from './translations/TranslationContext'; const App = (): JSX.Element => { const [deviceStatus, setDeviceStatus] = @@ -31,10 +30,6 @@ const App = (): JSX.Element => { const [isReady, setIsReady] = React.useState(false); const [lastMeshInterraction, setLastMeshInterraction] = React.useState(0); - - const [language, setLanguage] = React.useState( - LanguageEnum.ENGLISH, - ); const [darkmode, setDarkmode] = React.useState(false); React.useEffect(() => { @@ -115,8 +110,6 @@ const App = (): JSX.Element => { isReady={isReady} myNodeInfo={myNodeInfo} connection={connection} - language={language} - setLanguage={setLanguage} darkmode={darkmode} setDarkmode={setDarkmode} /> diff --git a/src/Main.tsx b/src/Main.tsx index e4babc94..49312b92 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -11,21 +11,21 @@ import type { 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'; +import { useTranslationsContextValue } from './hooks/useTranslationsContextValue'; +import { TranslationsContext } from './translations/TranslationsContext'; interface MainProps { connection: ISerialConnection | IHTTPConnection | IBLEConnection; myNodeInfo: Protobuf.MyNodeInfo; isReady: boolean; - language: LanguageEnum; - setLanguage: React.Dispatch>; darkmode: boolean; setDarkmode: React.Dispatch>; } const Main = (props: MainProps): JSX.Element => { - const { translations } = React.useContext(TranslationContext); + const translationsContextValue = useTranslationsContextValue(); + const { translations } = React.useContext(TranslationsContext); + const [messages, setMessages] = React.useState< { message: Types.TextPacket; ack: boolean }[] >([]); @@ -65,41 +65,39 @@ const Main = (props: MainProps): JSX.Element => { }, [props.connection, messages]); return ( -
-
-
- {messages.length ? ( - messages.map((message, Main) => ( - - )) - ) : ( -
- {translations.no_messages_message} -
- )} + +
+
+
+ {messages.length ? ( + messages.map((message, Main) => ( + + )) + ) : ( +
+ {translations.no_messages_message} +
+ )} +
+
-
- -
+ ); }; diff --git a/src/components/MessageBox.tsx b/src/components/MessageBox.tsx index 5486a821..8853eee5 100644 --- a/src/components/MessageBox.tsx +++ b/src/components/MessageBox.tsx @@ -7,7 +7,7 @@ import type { ISerialConnection, } from '@meshtastic/meshtasticjs'; -import { TranslationContext } from '../translations/TranslationContext'; +import { TranslationsContext } from '../translations/TranslationsContext'; export interface MessageBoxProps { sidebarOpen: boolean; @@ -17,7 +17,7 @@ export interface MessageBoxProps { } const MessageBox = (props: MessageBoxProps): JSX.Element => { - const { translations } = React.useContext(TranslationContext); + const { translations } = React.useContext(TranslationsContext); const [currentMessage, setCurrentMessage] = React.useState(''); const sendMessage = () => { if (props.isReady) { diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 51b48fe0..e4a1a4f0 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -1,22 +1,11 @@ import React from 'react'; -import type { - IBLEConnection, - IHTTPConnection, - ISerialConnection, -} from '@meshtastic/meshtasticjs'; - -import type { LanguageEnum } from '../translations/TranslationContext'; import Channels from './Sidebar/Channels/Index'; import Device from './Sidebar/Device/Index'; import Nodes from './Sidebar/Nodes/Index'; import UI from './Sidebar/UI/Index'; interface SidebarProps { - isReady: boolean; - connection: ISerialConnection | IHTTPConnection | IBLEConnection; - language: LanguageEnum; - setLanguage: React.Dispatch>; myId: number; sidebarOpen: boolean; darkmode: boolean; @@ -31,15 +20,10 @@ const Sidebar = (props: SidebarProps): JSX.Element => { } flex-col rounded-md md:ml-0 shadow-md border w-full max-w-sm`} > - +
- +
); }; diff --git a/src/components/Sidebar/Channels/Index.tsx b/src/components/Sidebar/Channels/Index.tsx index 99ddf0e1..6a9ad25e 100644 --- a/src/components/Sidebar/Channels/Index.tsx +++ b/src/components/Sidebar/Channels/Index.tsx @@ -7,11 +7,11 @@ import { HashtagIcon, } from '@heroicons/react/outline'; -import { TranslationContext } from '../../../translations/TranslationContext'; +import { TranslationsContext } from '../../../translations/TranslationsContext'; import ChannelList from './ChannelList'; const Channels = (): JSX.Element => { - const { translations } = React.useContext(TranslationContext); + const { translations } = React.useContext(TranslationsContext); return ( {({ open }) => ( diff --git a/src/components/Sidebar/Device/Index.tsx b/src/components/Sidebar/Device/Index.tsx index e56e492f..0890b73a 100644 --- a/src/components/Sidebar/Device/Index.tsx +++ b/src/components/Sidebar/Device/Index.tsx @@ -6,22 +6,12 @@ import { ChevronDownIcon, ChevronRightIcon, } from '@heroicons/react/outline'; -import type { - IBLEConnection, - IHTTPConnection, - ISerialConnection, -} from '@meshtastic/meshtasticjs'; -import { TranslationContext } from '../../../translations/TranslationContext'; +import { TranslationsContext } from '../../../translations/TranslationsContext'; import Settings from './Settings'; -interface DeviceProps { - isReady: boolean; - connection: ISerialConnection | IHTTPConnection | IBLEConnection; -} - -const Device = (props: DeviceProps): JSX.Element => { - const { translations } = React.useContext(TranslationContext); +const Device = (): JSX.Element => { + const { translations } = React.useContext(TranslationsContext); return ( {({ open }) => ( @@ -46,10 +36,7 @@ const Device = (props: DeviceProps): JSX.Element => {
} > - + diff --git a/src/components/Sidebar/Device/Settings.tsx b/src/components/Sidebar/Device/Settings.tsx index ff8cceaa..7500494b 100644 --- a/src/components/Sidebar/Device/Settings.tsx +++ b/src/components/Sidebar/Device/Settings.tsx @@ -5,23 +5,13 @@ 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 { preferencesResource } from '../../../streams'; -import { TranslationContext } from '../../../translations/TranslationContext'; +import { TranslationsContext } from '../../../translations/TranslationsContext'; -export interface SettingsProps { - isReady: boolean; - connection: ISerialConnection | IHTTPConnection | IBLEConnection; -} - -const Settings = (props: SettingsProps): JSX.Element => { - const { translations } = React.useContext(TranslationContext); +const Settings = (): JSX.Element => { + const { translations } = React.useContext(TranslationsContext); const preferences = useObservableSuspense(preferencesResource); const { register, handleSubmit } = diff --git a/src/components/Sidebar/Nodes/Index.tsx b/src/components/Sidebar/Nodes/Index.tsx index 79fc11f9..2742df4b 100644 --- a/src/components/Sidebar/Nodes/Index.tsx +++ b/src/components/Sidebar/Nodes/Index.tsx @@ -7,7 +7,7 @@ import { UsersIcon, } from '@heroicons/react/outline'; -import { TranslationContext } from '../../../translations/TranslationContext'; +import { TranslationsContext } from '../../../translations/TranslationsContext'; import NodeList from './NodeList'; interface NodesProps { @@ -15,7 +15,7 @@ interface NodesProps { } const Nodes = (props: NodesProps): JSX.Element => { - const { translations } = React.useContext(TranslationContext); + const { translations } = React.useContext(TranslationsContext); return ( {({ open }) => ( diff --git a/src/components/Sidebar/Nodes/Node.tsx b/src/components/Sidebar/Nodes/Node.tsx index 329627bb..2749bdb1 100644 --- a/src/components/Sidebar/Nodes/Node.tsx +++ b/src/components/Sidebar/Nodes/Node.tsx @@ -36,7 +36,7 @@ const Node = (props: NodeProps): JSX.Element => { ) : null} >; darkmode: boolean; setDarkmode: React.Dispatch>; } const UI = (props: UIProps): JSX.Element => { - const { translations } = React.useContext(TranslationContext); + const { translations } = React.useContext(TranslationsContext); return ( {({ open }) => ( @@ -36,10 +33,7 @@ const UI = (props: UIProps): JSX.Element => { - + )} diff --git a/src/components/Sidebar/UI/Translations.tsx b/src/components/Sidebar/UI/Translations.tsx index 4d4343e5..9e365588 100644 --- a/src/components/Sidebar/UI/Translations.tsx +++ b/src/components/Sidebar/UI/Translations.tsx @@ -7,16 +7,12 @@ import { ChevronDownIcon, ChevronRightIcon } from '@heroicons/react/outline'; import { LanguageEnum, - TranslationContext, -} from '../../../translations/TranslationContext'; + TranslationsContext, +} from '../../../translations/TranslationsContext'; -export interface TranslationsProps { - language: LanguageEnum; - setLanguage: React.Dispatch>; -} - -const Translations = (props: TranslationsProps): JSX.Element => { - const { translations } = React.useContext(TranslationContext); +const Translations = (): JSX.Element => { + const { translations, language, setLanguage } = + React.useContext(TranslationsContext); return ( {({ open }) => ( @@ -30,11 +26,11 @@ const Translations = (props: TranslationsProps): JSX.Element => { )} {translations.language_title}
- {props.language === LanguageEnum.ENGLISH ? ( + {language === LanguageEnum.ENGLISH ? ( - ) : props.language === LanguageEnum.JAPANESE ? ( + ) : language === LanguageEnum.JAPANESE ? ( - ) : props.language === LanguageEnum.PORTUGUESE ? ( + ) : language === LanguageEnum.PORTUGUESE ? (
) : null}
@@ -44,7 +40,7 @@ const Translations = (props: TranslationsProps): JSX.Element => {
{ - props.setLanguage(LanguageEnum.ENGLISH); + setLanguage(LanguageEnum.ENGLISH); }} > English @@ -52,7 +48,7 @@ const Translations = (props: TranslationsProps): JSX.Element => {
{ - props.setLanguage(LanguageEnum.PORTUGUESE); + setLanguage(LanguageEnum.PORTUGUESE); }} > Português
@@ -60,7 +56,7 @@ const Translations = (props: TranslationsProps): JSX.Element => {
{ - props.setLanguage(LanguageEnum.JAPANESE); + setLanguage(LanguageEnum.JAPANESE); }} > 日本語 diff --git a/src/hooks/useTranslationsContextValue.ts b/src/hooks/useTranslationsContextValue.ts new file mode 100644 index 00000000..91b4fde0 --- /dev/null +++ b/src/hooks/useTranslationsContextValue.ts @@ -0,0 +1,42 @@ +import React from 'react'; + +import Translations_EN from '../translations/en'; +import Translations_JP from '../translations/jp'; +import Translations_PT from '../translations/pt'; +import type { + languageTemplate, + TranslationsContextData, +} from '../translations/TranslationsContext'; +import { LanguageEnum } from '../translations/TranslationsContext'; + +export const useTranslationsContextValue = (): TranslationsContextData => { + const [currentLanguage, setcurrentLanguage] = React.useState( + LanguageEnum.ENGLISH, + ); + const [translation, setTranslation] = + React.useState(Translations_EN); + + const setLanguage = React.useCallback( + (language: LanguageEnum) => { + setcurrentLanguage(language); + switch (language) { + case LanguageEnum.ENGLISH: + setTranslation(Translations_EN); + break; + case LanguageEnum.JAPANESE: + setTranslation(Translations_JP); + break; + case LanguageEnum.PORTUGUESE: + setTranslation(Translations_PT); + break; + } + }, + [setcurrentLanguage, setTranslation], + ); + + return { + language: currentLanguage, + setLanguage: setLanguage, + translations: translation, + }; +}; diff --git a/src/index.tsx b/src/index.tsx index 70db53be..6ed01259 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; -import { TranslationContext } from './translations/TranslationContext'; const rootElement = document.getElementById('root'); if (!rootElement) throw new Error('Failed to find the root element'); @@ -12,9 +11,7 @@ const root = ReactDOM.createRoot(rootElement); root.render( - - - + , ); diff --git a/src/translations/TranslationContext.tsx b/src/translations/TranslationContext.tsx deleted file mode 100644 index 3c2d00a6..00000000 --- a/src/translations/TranslationContext.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; - -import Translations_EN from './en'; -import Translations_JP from './jp'; -import Translations_PT from './pt'; - -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, -} - -const Context = React.createContext<{ - language: LanguageEnum; - setLanguage: React.Dispatch>; - translations: languageTemplate; -}>({ - language: LanguageEnum.ENGLISH, - setLanguage: () => {}, - translations: Translations_EN, -}); - -export const TranslationContext = ({ - children, -}: { - children: React.ReactNode; -}): JSX.Element => { - const [language, setLanguage] = React.useState( - LanguageEnum.ENGLISH, - ); - const [translation, setTranslation] = - React.useState(Translations_EN); - React.useEffect(() => { - switch (language) { - case LanguageEnum.ENGLISH: - setTranslation(Translations_EN); - break; - case LanguageEnum.JAPANESE: - setTranslation(Translations_JP); - break; - case LanguageEnum.PORTUGUESE: - setTranslation(Translations_PT); - break; - } - }, [language]); - return ( - - {children} - - ); -}; diff --git a/src/translations/TranslationsContext.tsx b/src/translations/TranslationsContext.tsx new file mode 100644 index 00000000..eb8f186b --- /dev/null +++ b/src/translations/TranslationsContext.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +import Translations_EN 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 interface TranslationsContextData { + language: LanguageEnum; + setLanguage: (postId: number) => void; + translations: languageTemplate; +} + +export const translationsContextDefaultValue: TranslationsContextData = { + language: LanguageEnum.ENGLISH, + setLanguage: () => null, + translations: Translations_EN, +}; + +export const TranslationsContext = React.createContext( + translationsContextDefaultValue, +); diff --git a/src/translations/en.ts b/src/translations/en.ts index 2d3e28f3..7a2425c4 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -1,4 +1,4 @@ -import type { languageTemplate } from './TranslationContext'; +import type { languageTemplate } from './TranslationsContext'; export default { no_messages_message: 'No messages yet', diff --git a/src/translations/jp.ts b/src/translations/jp.ts index 206ec8f2..f509828c 100644 --- a/src/translations/jp.ts +++ b/src/translations/jp.ts @@ -1,4 +1,4 @@ -import type { languageTemplate } from './TranslationContext'; +import type { languageTemplate } from './TranslationsContext'; export default { no_messages_message: 'まだメッセージはありません', diff --git a/src/translations/pt.ts b/src/translations/pt.ts index cbc64526..5fb5e132 100644 --- a/src/translations/pt.ts +++ b/src/translations/pt.ts @@ -1,4 +1,4 @@ -import type { languageTemplate } from './TranslationContext'; +import type { languageTemplate } from './TranslationsContext'; export default { no_messages_message: 'Não a mensagens ainda', diff --git a/tsconfig.json b/tsconfig.json index d5d19899..cc1b5b2f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,6 @@ "moduleResolution": "node", "jsx": "preserve", "baseUrl": "./", - "types": ["react/next", "react-dom/next"], /* paths - import rewriting/resolving */ "paths": { // If you configured any Snowpack aliases, add them here. @@ -20,6 +19,7 @@ "strict": true, "strictNullChecks": true, "skipLibCheck": true, + "types": ["react/next", "react-dom/next", "snowpack-env"], "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "allowSyntheticDefaultImports": true, diff --git a/yarn.lock b/yarn.lock index db79c206..e63ffa44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3302,10 +3302,10 @@ react-flags-select@^2.1.2: dependencies: classnames "^2.2.6" -react-hook-form@^7.8.4: - version "7.8.4" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.8.4.tgz#4405b242db7b946f387f2a6c01f92390a2564893" - integrity sha512-hVh7uAJZS4/c20kNjW4rW+pD7+4RhuMDF3qY82f8wFuuPkoO+Pg5JHSJUqGdPdlI82snOlZ4DK/avIBn5SxItg== +react-hook-form@^7.8.6: + version "7.8.6" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.8.6.tgz#93335fbada5eae3ddee8f6dffe5bac868295ec4d" + integrity sha512-kKdaySvv21tyH8WM5jYpKRxTFdknmHi7ssdBrU7cW0qRwXcr9lxVyO14MjUFlfEGe9S5VzBmTz7NKNSarV3AFw== react-is@^16.8.1: version "16.13.1" @@ -4156,8 +4156,3 @@ yargs@^16.0.0: string-width "^4.2.0" y18n "^5.0.5" yargs-parser "^20.2.2" - -yarn@^1.22.10: - version "1.22.10" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c" - integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==