mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
translation system
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user