WIP
This commit is contained in:
@@ -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<boolean>(false);
|
||||
const [lastMeshInterraction, setLastMeshInterraction] =
|
||||
React.useState<number>(0);
|
||||
|
||||
const [language, setLanguage] = React.useState<LanguageEnum>(
|
||||
LanguageEnum.ENGLISH,
|
||||
);
|
||||
const [darkmode, setDarkmode] = React.useState<boolean>(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}
|
||||
/>
|
||||
|
||||
+34
-36
@@ -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<React.SetStateAction<LanguageEnum>>;
|
||||
darkmode: boolean;
|
||||
setDarkmode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
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 (
|
||||
<div className="flex flex-col md:flex-row flex-grow m-3 space-y-2 md:space-y-0 space-x-0 md:space-x-2">
|
||||
<div className="flex flex-col flex-grow container mx-auto">
|
||||
<div className="flex flex-col flex-grow py-6 space-y-2">
|
||||
{messages.length ? (
|
||||
messages.map((message, Main) => (
|
||||
<ChatMessage
|
||||
key={Main}
|
||||
message={message}
|
||||
myId={props.myNodeInfo.myNodeNum}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<div className="m-auto text-2xl text-gray-500">
|
||||
{translations.no_messages_message}
|
||||
</div>
|
||||
)}
|
||||
<TranslationsContext.Provider value={translationsContextValue}>
|
||||
<div className="flex flex-col md:flex-row flex-grow m-3 space-y-2 md:space-y-0 space-x-0 md:space-x-2">
|
||||
<div className="flex flex-col flex-grow container mx-auto">
|
||||
<div className="flex flex-col flex-grow py-6 space-y-2">
|
||||
{messages.length ? (
|
||||
messages.map((message, Main) => (
|
||||
<ChatMessage
|
||||
key={Main}
|
||||
message={message}
|
||||
myId={props.myNodeInfo.myNodeNum}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<div className="m-auto text-2xl text-gray-500">
|
||||
{translations.no_messages_message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<MessageBox
|
||||
connection={props.connection}
|
||||
isReady={props.isReady}
|
||||
sidebarOpen={sidebarOpen}
|
||||
setSidebarOpen={setSidebarOpen}
|
||||
/>
|
||||
</div>
|
||||
<MessageBox
|
||||
connection={props.connection}
|
||||
isReady={props.isReady}
|
||||
<Sidebar
|
||||
myId={props.myNodeInfo.myNodeNum}
|
||||
sidebarOpen={sidebarOpen}
|
||||
setSidebarOpen={setSidebarOpen}
|
||||
darkmode={props.darkmode}
|
||||
setDarkmode={props.setDarkmode}
|
||||
/>
|
||||
</div>
|
||||
<Sidebar
|
||||
isReady={props.isReady}
|
||||
connection={props.connection}
|
||||
language={props.language}
|
||||
setLanguage={props.setLanguage}
|
||||
myId={props.myNodeInfo.myNodeNum}
|
||||
sidebarOpen={sidebarOpen}
|
||||
darkmode={props.darkmode}
|
||||
setDarkmode={props.setDarkmode}
|
||||
/>
|
||||
</div>
|
||||
</TranslationsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<React.SetStateAction<LanguageEnum>>;
|
||||
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`}
|
||||
>
|
||||
<Nodes myId={props.myId} />
|
||||
<Device isReady={props.isReady} connection={props.connection} />
|
||||
<Device />
|
||||
<Channels />
|
||||
<div className="flex-grow border-b"></div>
|
||||
<UI
|
||||
language={props.language}
|
||||
setLanguage={props.setLanguage}
|
||||
darkmode={props.darkmode}
|
||||
setDarkmode={props.setDarkmode}
|
||||
/>
|
||||
<UI darkmode={props.darkmode} setDarkmode={props.setDarkmode} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 (
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
|
||||
@@ -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 (
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
@@ -46,10 +36,7 @@ const Device = (props: DeviceProps): JSX.Element => {
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Settings
|
||||
connection={props.connection}
|
||||
isReady={props.isReady}
|
||||
/>
|
||||
<Settings />
|
||||
</React.Suspense>
|
||||
</>
|
||||
</Disclosure.Panel>
|
||||
|
||||
@@ -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 } =
|
||||
|
||||
@@ -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 (
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
|
||||
@@ -36,7 +36,7 @@ const Node = (props: NodeProps): JSX.Element => {
|
||||
) : null}
|
||||
<Avatar
|
||||
size={30}
|
||||
name={props.node.data.user?.longName}
|
||||
name={props.node.data.user?.longName ?? 'Unknown'}
|
||||
variant="beam"
|
||||
colors={[
|
||||
'#213435',
|
||||
|
||||
@@ -7,19 +7,16 @@ import {
|
||||
CogIcon,
|
||||
} from '@heroicons/react/outline';
|
||||
|
||||
import type { LanguageEnum } from '../../../translations/TranslationContext';
|
||||
import { TranslationContext } from '../../../translations/TranslationContext';
|
||||
import { TranslationsContext } from '../../../translations/TranslationsContext';
|
||||
import Translations from './Translations';
|
||||
|
||||
interface UIProps {
|
||||
language: LanguageEnum;
|
||||
setLanguage: React.Dispatch<React.SetStateAction<LanguageEnum>>;
|
||||
darkmode: boolean;
|
||||
setDarkmode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const UI = (props: UIProps): JSX.Element => {
|
||||
const { translations } = React.useContext(TranslationContext);
|
||||
const { translations } = React.useContext(TranslationsContext);
|
||||
return (
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
@@ -36,10 +33,7 @@ const UI = (props: UIProps): JSX.Element => {
|
||||
</div>
|
||||
</Disclosure.Button>
|
||||
<Disclosure.Panel>
|
||||
<Translations
|
||||
language={props.language}
|
||||
setLanguage={props.setLanguage}
|
||||
/>
|
||||
<Translations />
|
||||
</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -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<React.SetStateAction<LanguageEnum>>;
|
||||
}
|
||||
|
||||
const Translations = (props: TranslationsProps): JSX.Element => {
|
||||
const { translations } = React.useContext(TranslationContext);
|
||||
const Translations = (): JSX.Element => {
|
||||
const { translations, language, setLanguage } =
|
||||
React.useContext(TranslationsContext);
|
||||
return (
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
@@ -30,11 +26,11 @@ const Translations = (props: TranslationsProps): JSX.Element => {
|
||||
)}
|
||||
{translations.language_title}
|
||||
<div className="my-auto">
|
||||
{props.language === LanguageEnum.ENGLISH ? (
|
||||
{language === LanguageEnum.ENGLISH ? (
|
||||
<Us className="ml-2 w-8" />
|
||||
) : props.language === LanguageEnum.JAPANESE ? (
|
||||
) : language === LanguageEnum.JAPANESE ? (
|
||||
<Jp className="ml-2 w-8" />
|
||||
) : props.language === LanguageEnum.PORTUGUESE ? (
|
||||
) : language === LanguageEnum.PORTUGUESE ? (
|
||||
<Br className="ml-2 w-8" />
|
||||
) : null}
|
||||
</div>
|
||||
@@ -44,7 +40,7 @@ const Translations = (props: TranslationsProps): JSX.Element => {
|
||||
<div
|
||||
className="flex bg-gray-100 hover:bg-gray-200 cursor-pointer justify-between p-2"
|
||||
onClick={() => {
|
||||
props.setLanguage(LanguageEnum.ENGLISH);
|
||||
setLanguage(LanguageEnum.ENGLISH);
|
||||
}}
|
||||
>
|
||||
English <Us className="w-8 my-auto" />
|
||||
@@ -52,7 +48,7 @@ const Translations = (props: TranslationsProps): JSX.Element => {
|
||||
<div
|
||||
className="flex bg-gray-100 hover:bg-gray-200 cursor-pointer justify-between p-2"
|
||||
onClick={() => {
|
||||
props.setLanguage(LanguageEnum.PORTUGUESE);
|
||||
setLanguage(LanguageEnum.PORTUGUESE);
|
||||
}}
|
||||
>
|
||||
Português <Br className="w-8 my-auto" />
|
||||
@@ -60,7 +56,7 @@ const Translations = (props: TranslationsProps): JSX.Element => {
|
||||
<div
|
||||
className="flex bg-gray-100 hover:bg-gray-200 cursor-pointer justify-between p-2"
|
||||
onClick={() => {
|
||||
props.setLanguage(LanguageEnum.JAPANESE);
|
||||
setLanguage(LanguageEnum.JAPANESE);
|
||||
}}
|
||||
>
|
||||
日本語 <Jp className="w-8 my-auto" />
|
||||
|
||||
@@ -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>(
|
||||
LanguageEnum.ENGLISH,
|
||||
);
|
||||
const [translation, setTranslation] =
|
||||
React.useState<languageTemplate>(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,
|
||||
};
|
||||
};
|
||||
+1
-4
@@ -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(
|
||||
<React.StrictMode>
|
||||
<TranslationContext>
|
||||
<App />
|
||||
</TranslationContext>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
|
||||
@@ -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<React.SetStateAction<LanguageEnum>>;
|
||||
translations: languageTemplate;
|
||||
}>({
|
||||
language: LanguageEnum.ENGLISH,
|
||||
setLanguage: () => {},
|
||||
translations: Translations_EN,
|
||||
});
|
||||
|
||||
export const TranslationContext = ({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}): JSX.Element => {
|
||||
const [language, setLanguage] = React.useState<LanguageEnum>(
|
||||
LanguageEnum.ENGLISH,
|
||||
);
|
||||
const [translation, setTranslation] =
|
||||
React.useState<languageTemplate>(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 (
|
||||
<Context.Provider
|
||||
value={{
|
||||
language: language,
|
||||
setLanguage: setLanguage,
|
||||
translations: translation,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Context.Provider>
|
||||
);
|
||||
};
|
||||
@@ -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<TranslationsContextData>(
|
||||
translationsContextDefaultValue,
|
||||
);
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { languageTemplate } from './TranslationContext';
|
||||
import type { languageTemplate } from './TranslationsContext';
|
||||
|
||||
export default {
|
||||
no_messages_message: 'No messages yet',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { languageTemplate } from './TranslationContext';
|
||||
import type { languageTemplate } from './TranslationsContext';
|
||||
|
||||
export default {
|
||||
no_messages_message: 'まだメッセージはありません',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { languageTemplate } from './TranslationContext';
|
||||
import type { languageTemplate } from './TranslationsContext';
|
||||
|
||||
export default {
|
||||
no_messages_message: 'Não a mensagens ainda',
|
||||
|
||||
Reference in New Issue
Block a user