translation system

This commit is contained in:
MathieuG-P
2022-07-09 00:01:23 +02:00
parent 9ba97497b1
commit 71fdd5a6f0
12 changed files with 188 additions and 18 deletions
@@ -14,12 +14,10 @@ export function SettingRadioArray({items, selectedItem = items[0].id, onItemSele
<h2 className="font-extrabold">{i.text}</h2>
</div>
{i.icon && (
<>
<div className="flex items-center">
{i.textIcon && <span>{i.textIcon}</span>}
</div>
<div className="flex items-center">
{i.textIcon && <span className="text-sm">{i.textIcon}</span>}
<BsmIcon icon={i.icon}/>
</>
</div>
)}
</div>
)) }
@@ -1,9 +1,11 @@
export const defaultConfiguration: {[key in DefaultConfigKey]: any} = {
"first-color": "#3b82ff",
"second-color": "#ff4444",
"theme": "os"
"theme": "os",
"language": window.navigator.language.length <= 2 ? `${window.navigator.language}-${window.navigator.language.toLocaleUpperCase()}` : window.navigator.language,
"supported_languages": ["en-US", "en-EN", "fr-FR", "es-ES"],
}
export type DefaultConfigKey = "first-color" | "second-color" | "theme";
export type DefaultConfigKey = "first-color" | "second-color" | "theme" | "language" | "supported_languages";
export type ThemeConfig = "dark" | "light" | "os"
@@ -0,0 +1,11 @@
import { useMemo } from "react";
import { I18nService } from "renderer/services/i18n.service"
export function useTranslation(): (translationKey: string) => string{
const i18nService = I18nService.getInstance();
return (key: string) => {
return useMemo(() => i18nService.translate(key), [key, i18nService.currentLanguage]);
}
}
+29 -5
View File
@@ -5,9 +5,11 @@ import { RadioItem, SettingRadioArray } from "renderer/components/settings/setti
import { BsmButton } from "renderer/components/shared/bsm-button.component";
import { DefaultConfigKey, ThemeConfig } from "renderer/config/default-configuration.config";
import { useObservable } from "renderer/hooks/use-observable.hook";
import { useTranslation } from "renderer/hooks/use-translation.hook";
import { AuthUserService } from "renderer/services/auth-user.service";
import { BsDownloaderService } from "renderer/services/bs-downloader.service";
import { ConfigurationService } from "renderer/services/configuration.service"
import { I18nService } from "renderer/services/i18n.service";
import { IpcService } from "renderer/services/ipc.service";
import { ModalExitCode, ModalService, ModalType } from "renderer/services/modale.service";
import { NotificationService } from "renderer/services/notification.service";
@@ -24,6 +26,12 @@ export function SettingsPage() {
const progressBarService: ProgressBarService = ProgressBarService.getInstance();
const authService: AuthUserService = AuthUserService.getInstance();
const notificationService: NotificationService = NotificationService.getInstance();
const i18nService: I18nService = I18nService.getInstance();
const firstColor = useObservable(configService.watch<string>("first-color"));
const secondColor = useObservable(configService.watch<string>("second-color"));
const sessionExist = useObservable(authService.sessionExist$);
const t = useTranslation();
const themeItem: RadioItem[] = [
{id: 0, text: "Dark", value: "dark" as ThemeConfig},
@@ -31,12 +39,16 @@ export function SettingsPage() {
{id: 3, text: "Operating System", value: "os" as ThemeConfig}
];
const firstColor = useObservable(configService.watch<string>("first-color"));
const secondColor = useObservable(configService.watch<string>("second-color"));
const sessionExist = useObservable(authService.sessionExist$);
const languagesItems: RadioItem[] = i18nService.getSupportedLanguages().map((l, index) => {
return {id: index, text: t(`pages.settings.languages.${l}`), value: l, textIcon:t(`pages.settings.languages.translated.${l}`), icon: "trash"};
});
const[themeIdSelected, setThemeIdSelected]= useState(themeItem.find(e => e.value === themeService.getTheme()).id);
const[languageSelected, setLanguageSelected]= useState(languagesItems.find(e => e.value === i18nService.currentLanguage).id);
const [installationFolder, setInstallationFolder] = useState(null);
console.log(t("test"));
useEffect(() => {
loadInstallationFolder();
}, []);
@@ -58,6 +70,12 @@ export function SettingsPage() {
themeService.setTheme(themeItem.find(e => e.id === id).value);
}
const handleChangeLanguage = (id: number) => {
const selectedLanguage = languagesItems.find(l => l.id === id).value;
i18nService.setLanguage(selectedLanguage);
setLanguageSelected(languagesItems.find(l => l.value === i18nService.currentLanguage).id);
}
const setDefaultInstallationFolder = () => {
modalService.openModal(ModalType.INSTALLATION_FOLDER).then(async res => {
if(res.exitCode !== ModalExitCode.COMPLETED){ return; }
@@ -87,9 +105,9 @@ export function SettingsPage() {
};
return (
<div className="w-full flex justify-center px-40 pt-10 text-gray-800 dark:text-gray-200">
<div className="w-full h-full flex justify-center overflow-y-scroll pb-12 scrollbar-thin scrollbar-thumb-neutral-900 text-gray-800 dark:text-gray-200">
<div className="w-fit max-w-full">
<div className="w-fit max-w-full mt-10">
<SettingContainer title="Steam" description="If you logout of your Steam account, you must reconect for download a new BS instance">
<BsmButton onClick={deleteSteamSession} className={`bg-red-500 w-fit px-3 py-[2px] text-white rounded-md`} withBar={false} text="Logout of Steam" disabled={!sessionExist}/>
@@ -115,6 +133,12 @@ export function SettingsPage() {
</div>
</SettingContainer>
<SettingContainer title="Language" description="Select a language">
<SettingRadioArray items={languagesItems} selectedItem={languageSelected} onItemSelected={handleChangeLanguage}/>
</SettingContainer>
<div className="h-10"></div>
</div>
</div>
)
@@ -37,8 +37,6 @@ export function VersionViewer() {
const bsDownloaderService = BsDownloaderService.getInstance();
const progressService = ProgressBarService.getInstance();
const [launchRes, setLaunchRes] = useState(null);
useEffect(() => {
setOculusMode(!!configService.get<boolean>(LaunchMods.OCULUS_MOD));
setDesktopMode(!!configService.get<boolean>(LaunchMods.DESKTOP_MOD));
+56
View File
@@ -0,0 +1,56 @@
import { DefaultConfigKey } from "renderer/config/default-configuration.config";
import { distinctUntilChanged, filter, map, Observable } from "rxjs";
import { ConfigurationService } from "./configuration.service";
import { getProperty } from "dot-prop";
export class I18nService {
private static instance: I18nService;
private readonly LANG_CONFIG_KEY: DefaultConfigKey = "language";
private readonly LANG_FALLBACK = "en-EN";
private readonly configService: ConfigurationService;
private dictionary: Object;
public static getInstance(): I18nService{
if(!I18nService.instance){ I18nService.instance = new I18nService(); }
return I18nService.instance;
}
private constructor(){
this.configService = ConfigurationService.getInstance();
this.currentLanguage$.pipe(filter(l => !!l), distinctUntilChanged()).subscribe(lang => {
this.dictionary = require(`../../../assets/jsons/translations/${lang}.json`);
});
}
public getSupportedLanguages(): string[]{ return this.configService.get("supported_languages" as DefaultConfigKey); }
public getFallbackLanguage(): string{ return this.LANG_FALLBACK; }
public get currentLanguage(): string{
return this.getSupportedLanguages().includes(this.configService.get(this.LANG_CONFIG_KEY)) ? this.configService.get(this.LANG_CONFIG_KEY) : this.LANG_FALLBACK;
}
public get currentLanguage$(): Observable<string>{
return this.configService.watch<string>("language" as DefaultConfigKey).pipe(map(l => this.getSupportedLanguages().includes(l) ? l : this.LANG_FALLBACK));
}
public setLanguage(lang: string){
this.configService.set("language" as DefaultConfigKey, this.getSupportedLanguages().includes(lang) ? lang : this.LANG_FALLBACK);
}
public translate(translationKey: string): string{
return getProperty(this.dictionary, translationKey) || translationKey;
}
}