mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-06 07:37:19 +02:00
539 lines
23 KiB
TypeScript
Executable File
539 lines
23 KiB
TypeScript
Executable File
import { StorageKey } from "@/enums/pref-keys";
|
||
import { NATIVE_FETCH } from "./bx-flags";
|
||
import { BxLogger } from "./bx-logger";
|
||
import { GhPagesUtils } from "./gh-pages";
|
||
|
||
export const SUPPORTED_LANGUAGES = {
|
||
'en-US': 'English (US)',
|
||
|
||
'ca-CA': 'Català',
|
||
'da-DK': 'dansk',
|
||
'de-DE': 'Deutsch',
|
||
'en-ID': 'Bahasa Indonesia',
|
||
'es-ES': 'español (España)',
|
||
'fr-FR': 'français',
|
||
'it-IT': 'italiano',
|
||
'ja-JP': '日本語',
|
||
'ko-KR': '한국어',
|
||
'pl-PL': 'polski',
|
||
'pt-BR': 'português (Brasil)',
|
||
'ru-RU': 'русский',
|
||
'th-TH': 'ภาษาไทย',
|
||
'tr-TR': 'Türkçe',
|
||
'uk-UA': 'українська',
|
||
'vi-VN': 'Tiếng Việt',
|
||
'zh-CN': '中文(简体)',
|
||
'zh-TW': '中文(繁體)',
|
||
};
|
||
|
||
const Texts = {
|
||
"activate": "Activate",
|
||
"activated": "Activated",
|
||
"active": "Active",
|
||
"advanced": "Advanced",
|
||
"always-off": "Always off",
|
||
"always-on": "Always on",
|
||
"amd-fidelity-cas": "AMD FidelityFX CAS",
|
||
"app-settings": "App settings",
|
||
"apply": "Apply",
|
||
"aspect-ratio": "Aspect ratio",
|
||
"aspect-ratio-note": "Don't use with native touch games",
|
||
"audio": "Audio",
|
||
"auto": "Auto",
|
||
"back-to-home": "Back to home",
|
||
"back-to-home-confirm": "Do you want to go back to the home page (without disconnecting)?",
|
||
"battery": "Battery",
|
||
"battery-saving": "Battery saving",
|
||
"better-xcloud": "Better xCloud",
|
||
"bitrate-audio-maximum": "Maximum audio bitrate",
|
||
"bitrate-video-maximum": "Maximum video bitrate",
|
||
"bottom": "Bottom",
|
||
"bottom-half": "Bottom half",
|
||
"bottom-left": "Bottom-left",
|
||
"bottom-right": "Bottom-right",
|
||
"brazil": "Brazil",
|
||
"brightness": "Brightness",
|
||
"browser-unsupported-feature": "Your browser doesn't support this feature",
|
||
"bypass-region-restriction": "Bypass region restriction",
|
||
"can-stream-xbox-360-games": "Can stream Xbox 360 games",
|
||
"cancel": "Cancel",
|
||
"cant-stream-xbox-360-games": "Can't stream Xbox 360 games",
|
||
"center": "Center",
|
||
"clarity-boost": "Clarity boost",
|
||
"clarity-boost-warning": "These settings don't work when the Clarity Boost mode is ON",
|
||
"clear": "Clear",
|
||
"clear-data": "Clear data",
|
||
"clear-data-confirm": "Do you want to clear all Better xCloud settings and data?",
|
||
"clear-data-success": "Data cleared! Refresh the page to apply the changes.",
|
||
"clock": "Clock",
|
||
"close": "Close",
|
||
"close-app": "Close app",
|
||
"combine-audio-video-streams": "Combine audio & video streams",
|
||
"combine-audio-video-streams-summary": "May fix the laggy audio problem",
|
||
"conditional-formatting": "Conditional formatting text color",
|
||
"confirm-delete-preset": "Do you want to delete this preset?",
|
||
"confirm-reload-stream": "Do you want to refresh the stream?",
|
||
"connected": "Connected",
|
||
"console-connect": "Connect",
|
||
"continent-asia": "Asia",
|
||
"continent-australia": "Australia",
|
||
"continent-europe": "Europe",
|
||
"continent-north-america": "North America",
|
||
"continent-south-america": "South America",
|
||
"contrast": "Contrast",
|
||
"controller": "Controller",
|
||
"controller-friendly-ui": "Controller-friendly UI",
|
||
"controller-shortcuts": "Controller shortcuts",
|
||
"controller-shortcuts-connect-note": "Connect a controller to use this feature",
|
||
"controller-shortcuts-in-game": "In-game controller shortcuts",
|
||
"controller-shortcuts-xbox-note": "Button to open the Guide menu",
|
||
"controller-vibration": "Controller vibration",
|
||
"copy": "Copy",
|
||
"create-shortcut": "Shortcut",
|
||
"custom": "Custom",
|
||
"deadzone-counterweight": "Deadzone counterweight",
|
||
"decrease": "Decrease",
|
||
"default": "Default",
|
||
"default-preset-note": "You can't modify default presets. Create a new one to customize it.",
|
||
"delete": "Delete",
|
||
"device": "Device",
|
||
"device-unsupported-touch": "Your device doesn't have touch support",
|
||
"device-vibration": "Device vibration",
|
||
"device-vibration-not-using-gamepad": "On when not using gamepad",
|
||
"disable": "Disable",
|
||
"disable-byog-feature": "Disable \"Stream your own game\" feature",
|
||
"disable-home-context-menu": "Disable context menu in Home page",
|
||
"disable-post-stream-feedback-dialog": "Disable post-stream feedback dialog",
|
||
"disable-social-features": "Disable social features",
|
||
"disable-xcloud-analytics": "Disable xCloud analytics",
|
||
"disabled": "Disabled",
|
||
"disconnected": "Disconnected",
|
||
"download": "Download",
|
||
"downloaded": "Downloaded",
|
||
"edit": "Edit",
|
||
"enable-controller-shortcuts": "Enable controller shortcuts",
|
||
"enable-local-co-op-support": "Enable local co-op support",
|
||
"enable-local-co-op-support-note": "Only works with some games",
|
||
"enable-mic-on-startup": "Enable microphone on game launch",
|
||
"enable-mkb": "Emulate controller with Mouse & Keyboard",
|
||
"enable-quick-glance-mode": "Enable \"Quick Glance\" mode",
|
||
"enable-remote-play-feature": "Enable the \"Remote Play\" feature",
|
||
"enable-volume-control": "Enable volume control feature",
|
||
"enabled": "Enabled",
|
||
"experimental": "Experimental",
|
||
"export": "Export",
|
||
"fast": "Fast",
|
||
"force-native-mkb-games": "Force native Mouse & Keyboard for these games",
|
||
"fortnite-allow-stw-mode": "Allows playing \"Save the World\" mode on mobile",
|
||
"fortnite-force-console-version": "Fortnite: force console version",
|
||
"game-bar": "Game Bar",
|
||
"getting-consoles-list": "Getting the list of consoles...",
|
||
"guide": "Guide",
|
||
"help": "Help",
|
||
"hide": "Hide",
|
||
"hide-idle-cursor": "Hide mouse cursor on idle",
|
||
"hide-scrollbar": "Hide web page's scrollbar",
|
||
"hide-sections": "Hide sections",
|
||
"hide-system-menu-icon": "Hide System menu's icon",
|
||
"hide-touch-controller": "Hide touch controller",
|
||
"high-performance": "High performance",
|
||
"highest-quality": "Highest quality",
|
||
"highest-quality-note": "Your device may not be powerful enough to use these settings",
|
||
"horizontal-scroll-sensitivity": "Horizontal scroll sensitivity",
|
||
"horizontal-sensitivity": "Horizontal sensitivity",
|
||
"how-to-fix": "How to fix",
|
||
"how-to-improve-app-performance": "How to improve app's performance",
|
||
"ignore": "Ignore",
|
||
"import": "Import",
|
||
"increase": "Increase",
|
||
"install-android": "Better xCloud app for Android",
|
||
"japan": "Japan",
|
||
"jitter": "Jitter",
|
||
"keyboard-key": "Keyboard key",
|
||
"keyboard-shortcuts": "Keyboard shortcuts",
|
||
"keyboard-shortcuts-in-game": "In-game keyboard shortcuts",
|
||
"korea": "Korea",
|
||
"language": "Language",
|
||
"large": "Large",
|
||
"layout": "Layout",
|
||
"left-stick": "Left stick",
|
||
"load-failed-message": "Failed to run Better xCloud",
|
||
"loading-screen": "Loading screen",
|
||
"local-co-op": "Local co-op",
|
||
"lowest-quality": "Lowest quality",
|
||
"manage": "Manage",
|
||
"map-mouse-to": "Map mouse to",
|
||
"max-fps": "Max FPS",
|
||
"may-not-work-properly": "May not work properly!",
|
||
"menu": "Menu",
|
||
"microphone": "Microphone",
|
||
"mkb-adjust-ingame-settings": "You may also need to adjust the in-game sensitivity & deadzone settings",
|
||
"mkb-click-to-activate": "Click to activate",
|
||
"mkb-disclaimer": "This could be viewed as cheating when playing online",
|
||
"modifiers-note": "To use more than one key, include Ctrl, Alt or Shift in your shortcut. Command key is not allowed.",
|
||
"mouse-and-keyboard": "Mouse & Keyboard",
|
||
"mouse-click": "Mouse click",
|
||
"mouse-wheel": "Mouse wheel",
|
||
"muted": "Muted",
|
||
"name": "Name",
|
||
"native-mkb": "Native Mouse & Keyboard",
|
||
"new": "New",
|
||
"new-version-available": [
|
||
(e: any) => `Version ${e.version} available`,
|
||
(e: any) => `Versió ${e.version} disponible`,
|
||
,
|
||
(e: any) => `Version ${e.version} verfügbar`,
|
||
(e: any) => `Versi ${e.version} tersedia`,
|
||
(e: any) => `Versión ${e.version} disponible`,
|
||
(e: any) => `Version ${e.version} disponible`,
|
||
(e: any) => `Disponibile la versione ${e.version}`,
|
||
(e: any) => `Ver ${e.version} が利用可能です`,
|
||
(e: any) => `${e.version} 버전 사용가능`,
|
||
(e: any) => `Dostępna jest nowa wersja ${e.version}`,
|
||
(e: any) => `Versão ${e.version} disponível`,
|
||
(e: any) => `Версия ${e.version} доступна`,
|
||
(e: any) => `เวอร์ชัน ${e.version} พร้อมใช้งานแล้ว`,
|
||
(e: any) => `${e.version} sayılı yeni sürüm mevcut`,
|
||
(e: any) => `Доступна версія ${e.version}`,
|
||
(e: any) => `Đã có phiên bản ${e.version}`,
|
||
(e: any) => `版本 ${e.version} 可供更新`,
|
||
(e: any) => `已可更新為 ${e.version} 版`,
|
||
],
|
||
"no-consoles-found": "No consoles found",
|
||
"no-controllers-connected": "No controllers connected",
|
||
"normal": "Normal",
|
||
"off": "Off",
|
||
"official": "Official",
|
||
"on": "On",
|
||
"only-supports-some-games": "Only supports some games",
|
||
"opacity": "Opacity",
|
||
"other": "Other",
|
||
"playing": "Playing",
|
||
"playtime": "Playtime",
|
||
"poland": "Poland",
|
||
"polling-rate": "Polling rate",
|
||
"position": "Position",
|
||
"powered-off": "Powered off",
|
||
"powered-on": "Powered on",
|
||
"prefer-ipv6-server": "Prefer IPv6 server",
|
||
"preferred-game-language": "Preferred game's language",
|
||
"preset": "Preset",
|
||
"press-esc-to-cancel": "Press Esc to cancel",
|
||
"press-key-to-toggle-mkb": [
|
||
(e: any) => `Press ${e.key} to toggle this feature`,
|
||
(e: any) => `Premeu ${e.key} per alternar aquesta funció`,
|
||
(e: any) => `Tryk på ${e.key} for at slå denne funktion til`,
|
||
(e: any) => `${e.key}: Funktion an-/ausschalten`,
|
||
(e: any) => `Tekan ${e.key} untuk mengaktifkan fitur ini`,
|
||
(e: any) => `Pulsa ${e.key} para alternar esta función`,
|
||
(e: any) => `Appuyez sur ${e.key} pour activer cette fonctionnalité`,
|
||
(e: any) => `Premi ${e.key} per attivare questa funzionalità`,
|
||
(e: any) => `${e.key} でこの機能を切替`,
|
||
(e: any) => `${e.key} 키를 눌러 이 기능을 켜고 끄세요`,
|
||
(e: any) => `Naciśnij ${e.key} aby przełączyć tę funkcję`,
|
||
(e: any) => `Pressione ${e.key} para alternar este recurso`,
|
||
(e: any) => `Нажмите ${e.key} для переключения этой функции`,
|
||
(e: any) => `กด ${e.key} เพื่อสลับคุณสมบัตินี้`,
|
||
(e: any) => `Etkinleştirmek için ${e.key} tuşuna basın`,
|
||
(e: any) => `Натисніть ${e.key} щоб перемкнути цю функцію`,
|
||
(e: any) => `Nhấn ${e.key} để bật/tắt tính năng này`,
|
||
(e: any) => `按下 ${e.key} 来切换此功能`,
|
||
(e: any) => `按下 ${e.key} 來啟用此功能`,
|
||
],
|
||
"press-to-bind": "Press a key or do a mouse click to bind...",
|
||
"prompt-preset-name": "Preset's name:",
|
||
"recommended": "Recommended",
|
||
"recommended-settings-for-device": [
|
||
(e: any) => `Recommended settings for ${e.device}`,
|
||
(e: any) => `Configuració recomanada per a ${e.device}`,
|
||
,
|
||
(e: any) => `Empfohlene Einstellungen für ${e.device}`,
|
||
(e: any) => `Rekomendasi pengaturan untuk ${e.device}`,
|
||
(e: any) => `Ajustes recomendados para ${e.device}`,
|
||
(e: any) => `Paramètres recommandés pour ${e.device}`,
|
||
(e: any) => `Configurazioni consigliate per ${e.device}`,
|
||
(e: any) => `${e.device} の推奨設定`,
|
||
(e: any) => `다음 기기에서 권장되는 설정: ${e.device}`,
|
||
(e: any) => `Zalecane ustawienia dla ${e.device}`,
|
||
(e: any) => `Configurações recomendadas para ${e.device}`,
|
||
(e: any) => `Рекомендуемые настройки для ${e.device}`,
|
||
(e: any) => `การตั้งค่าที่แนะนำสำหรับ ${e.device}`,
|
||
(e: any) => `${e.device} için önerilen ayarlar`,
|
||
(e: any) => `Рекомендовані налаштування для ${e.device}`,
|
||
(e: any) => `Cấu hình được đề xuất cho ${e.device}`,
|
||
(e: any) => `${e.device} 的推荐设置`,
|
||
(e: any) => `${e.device} 推薦的設定`,
|
||
],
|
||
"reduce-animations": "Reduce UI animations",
|
||
"region": "Region",
|
||
"reload-page": "Reload page",
|
||
"remote-play": "Remote Play",
|
||
"rename": "Rename",
|
||
"renderer": "Renderer",
|
||
"renderer-configuration": "Renderer configuration",
|
||
"right-click-to-unbind": "Right-click on a key to unbind it",
|
||
"right-stick": "Right stick",
|
||
"rocket-always-hide": "Always hide",
|
||
"rocket-always-show": "Always show",
|
||
"rocket-animation": "Rocket animation",
|
||
"rocket-hide-queue": "Hide when queuing",
|
||
"saturation": "Saturation",
|
||
"save": "Save",
|
||
"screen": "Screen",
|
||
"screenshot-apply-filters": "Apply video filters to screenshots",
|
||
"section-all-games": "All games",
|
||
"section-byog": "Stream your own game",
|
||
"section-most-popular": "Most popular",
|
||
"section-native-mkb": "Play with mouse & keyboard",
|
||
"section-news": "News",
|
||
"section-play-with-friends": "Play with friends",
|
||
"section-touch": "Play with touch",
|
||
"separate-touch-controller": "Separate Touch controller & Controller #1",
|
||
"separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2",
|
||
"server": "Server",
|
||
"server-locations": "Server locations",
|
||
"settings": "Settings",
|
||
"settings-reload": "Reload page to reflect changes",
|
||
"settings-reload-note": "Settings in this tab only go into effect on the next page load",
|
||
"settings-reloading": "Reloading...",
|
||
"sharpness": "Sharpness",
|
||
"shortcut-keys": "Shortcut keys",
|
||
"show": "Show",
|
||
"show-controller-connection-status": "Show controller connection status",
|
||
"show-game-art": "Show game art",
|
||
"show-hide": "Show/hide",
|
||
"show-stats-on-startup": "Show stats when starting the game",
|
||
"show-touch-controller": "Show touch controller",
|
||
"show-wait-time": "Show the estimated wait time",
|
||
"show-wait-time-in-game-card": "Show wait time in game card",
|
||
"simplify-stream-menu": "Simplify Stream's menu",
|
||
"skip-splash-video": "Skip Xbox splash video",
|
||
"slow": "Slow",
|
||
"small": "Small",
|
||
"smart-tv": "Smart TV",
|
||
"sound": "Sound",
|
||
"standard": "Standard",
|
||
"standby": "Standby",
|
||
"stat-bitrate": "Bitrate",
|
||
"stat-decode-time": "Decode time",
|
||
"stat-fps": "FPS",
|
||
"stat-frames-lost": "Frames lost",
|
||
"stat-packets-lost": "Packets lost",
|
||
"stat-ping": "Ping",
|
||
"stats": "Stats",
|
||
"stick-decay-minimum": "Stick decay minimum",
|
||
"stick-decay-strength": "Stick decay strength",
|
||
"stream": "Stream",
|
||
"stream-settings": "Stream settings",
|
||
"stream-stats": "Stream stats",
|
||
"stretch": "Stretch",
|
||
"suggest-settings": "Suggest settings",
|
||
"suggest-settings-link": "Suggest recommended settings for this device",
|
||
"support-better-xcloud": "Support Better xCloud",
|
||
"swap-buttons": "Swap buttons",
|
||
"take-screenshot": "Take screenshot",
|
||
"target-resolution": "Target resolution",
|
||
"tc-all-games": "All games",
|
||
"tc-all-white": "All white",
|
||
"tc-auto-off": "Off when controller found",
|
||
"tc-availability": "Availability",
|
||
"tc-custom-layout-style": "Custom layout's button style",
|
||
"tc-default-opacity": "Default opacity",
|
||
"tc-muted-colors": "Muted colors",
|
||
"tc-standard-layout-style": "Standard layout's button style",
|
||
"text-size": "Text size",
|
||
"toggle": "Toggle",
|
||
"top": "Top",
|
||
"top-center": "Top-center",
|
||
"top-half": "Top half",
|
||
"top-left": "Top-left",
|
||
"top-right": "Top-right",
|
||
"touch-control-layout": "Touch control layout",
|
||
"touch-control-layout-by": [
|
||
(e: any) => `Touch control layout by ${e.name}`,
|
||
(e: any) => `Format del control tàctil per ${e.name}`,
|
||
(e: any) => `Touch-kontrol layout af ${e.name}`,
|
||
(e: any) => `Touch-Steuerungslayout von ${e.name}`,
|
||
(e: any) => `Tata letak Sentuhan layar oleh ${e.name}`,
|
||
(e: any) => `Disposición del control táctil por ${e.nombre}`,
|
||
(e: any) => `Disposition du contrôleur tactile par ${e.name}`,
|
||
(e: any) => `Configurazione dei comandi su schermo creata da ${e.name}`,
|
||
(e: any) => `タッチ操作レイアウト作成者: ${e.name}`,
|
||
(e: any) => `${e.name} 제작, 터치 컨트롤 레이아웃`,
|
||
(e: any) => `Układ sterowania dotykowego stworzony przez ${e.name}`,
|
||
(e: any) => `Disposição de controle por toque feito por ${e.name}`,
|
||
(e: any) => `Сенсорная раскладка по ${e.name}`,
|
||
(e: any) => `รูปแบบการควบคุมแบบสัมผัสโดย ${e.name}`,
|
||
(e: any) => `${e.name} kişisinin dokunmatik kontrolcü tuş şeması`,
|
||
(e: any) => `Розташування сенсорного керування від ${e.name}`,
|
||
(e: any) => `Bố cục điều khiển cảm ứng tạo bởi ${e.name}`,
|
||
(e: any) => `由 ${e.name} 提供的虚拟按键样式`,
|
||
(e: any) => `觸控遊玩佈局由 ${e.name} 提供`,
|
||
],
|
||
"touch-controller": "Touch controller",
|
||
"transparent-background": "Transparent background",
|
||
"true-achievements": "TrueAchievements",
|
||
"ui": "UI",
|
||
"unexpected-behavior": "May cause unexpected behavior",
|
||
"united-states": "United States",
|
||
"unknown": "Unknown",
|
||
"unlimited": "Unlimited",
|
||
"unmuted": "Unmuted",
|
||
"unofficial": "Unofficial",
|
||
"unofficial-game-list": "Unofficial game list",
|
||
"unsharp-masking": "Unsharp masking",
|
||
"upload": "Upload",
|
||
"uploaded": "Uploaded",
|
||
"use-mouse-absolute-position": "Use mouse's absolute position",
|
||
"use-this-at-your-own-risk": "Use this at your own risk",
|
||
"user-agent-profile": "User-Agent profile",
|
||
"vertical-scroll-sensitivity": "Vertical scroll sensitivity",
|
||
"vertical-sensitivity": "Vertical sensitivity",
|
||
"vibration-intensity": "Vibration intensity",
|
||
"vibration-status": "Vibration",
|
||
"video": "Video",
|
||
"virtual-controller": "Virtual controller",
|
||
"virtual-controller-slot": "Virtual controller slot",
|
||
"visual-quality": "Visual quality",
|
||
"visual-quality-high": "High",
|
||
"visual-quality-low": "Low",
|
||
"visual-quality-normal": "Normal",
|
||
"volume": "Volume",
|
||
"wait-time-countdown": "Countdown",
|
||
"wait-time-estimated": "Estimated finish time",
|
||
"waiting-for-input": "Waiting for input...",
|
||
"wallpaper": "Wallpaper",
|
||
"webgl2": "WebGL2",
|
||
};
|
||
|
||
export class Translations {
|
||
private static readonly EN_US = 'en-US';
|
||
private static readonly KEY_LOCALE = StorageKey.LOCALE;
|
||
private static readonly KEY_TRANSLATIONS = StorageKey.LOCALE_TRANSLATIONS;
|
||
|
||
private static selectedLocaleIndex = -1;
|
||
private static selectedLocale: keyof typeof SUPPORTED_LANGUAGES = 'en-US';
|
||
|
||
private static supportedLocales = Object.keys(SUPPORTED_LANGUAGES);
|
||
private static foreignTranslations: any = {};
|
||
|
||
private static enUsIndex = Translations.supportedLocales.indexOf(Translations.EN_US);
|
||
|
||
static async init() {
|
||
Translations.refreshLocale();
|
||
await Translations.loadTranslations();
|
||
}
|
||
|
||
static refreshLocale(newLocale?: string) {
|
||
let locale;
|
||
if (newLocale) {
|
||
localStorage.setItem(Translations.KEY_LOCALE, newLocale);
|
||
locale = newLocale;
|
||
} else {
|
||
locale = localStorage.getItem(Translations.KEY_LOCALE);
|
||
}
|
||
const supportedLocales = Translations.supportedLocales;
|
||
|
||
if (!locale) {
|
||
// Get browser's locale
|
||
locale = window.navigator.language || Translations.EN_US;
|
||
if (supportedLocales.indexOf(locale) === -1) {
|
||
locale = Translations.EN_US;
|
||
}
|
||
localStorage.setItem(Translations.KEY_LOCALE, locale);
|
||
}
|
||
|
||
Translations.selectedLocale = locale as keyof typeof SUPPORTED_LANGUAGES;
|
||
Translations.selectedLocaleIndex = supportedLocales.indexOf(locale);
|
||
}
|
||
|
||
static get<T=string>(key: keyof typeof Texts, values?: any): T {
|
||
let text = null;
|
||
|
||
if (Translations.foreignTranslations && Translations.selectedLocale !== Translations.EN_US) {
|
||
text = Translations.foreignTranslations[key];
|
||
}
|
||
|
||
if (!text) {
|
||
text = Texts[key] || alert(`Missing translation key: ${key}`);
|
||
}
|
||
|
||
let translation: unknown;
|
||
if (Array.isArray(text)) {
|
||
translation = text[Translations.selectedLocaleIndex] || text[Translations.enUsIndex];
|
||
return (translation as any)(values);
|
||
}
|
||
|
||
translation = text;
|
||
return translation as T;
|
||
}
|
||
|
||
private static async loadTranslations() {
|
||
if (Translations.selectedLocale === Translations.EN_US) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
Translations.foreignTranslations = JSON.parse(window.localStorage.getItem(Translations.KEY_TRANSLATIONS)!);
|
||
} catch(e) {}
|
||
|
||
if (!Translations.foreignTranslations) {
|
||
await this.downloadTranslations(Translations.selectedLocale);
|
||
}
|
||
}
|
||
|
||
static async updateTranslations(async=false) {
|
||
// Don't have to download en-US
|
||
if (Translations.selectedLocale === Translations.EN_US) {
|
||
localStorage.removeItem(Translations.KEY_TRANSLATIONS);
|
||
return;
|
||
}
|
||
|
||
if (async) {
|
||
Translations.downloadTranslationsAsync(Translations.selectedLocale);
|
||
} else {
|
||
await Translations.downloadTranslations(Translations.selectedLocale);
|
||
}
|
||
}
|
||
|
||
static async downloadTranslations(locale: string) {
|
||
try {
|
||
const resp = await NATIVE_FETCH(GhPagesUtils.getUrl(`translations/${locale}.json`));
|
||
const translations = await resp.json();
|
||
|
||
// Prevent saving incorrect translations
|
||
let currentLocale = localStorage.getItem(Translations.KEY_LOCALE);
|
||
if (currentLocale === locale) {
|
||
window.localStorage.setItem(Translations.KEY_TRANSLATIONS, JSON.stringify(translations));
|
||
Translations.foreignTranslations = translations;
|
||
}
|
||
return true;
|
||
} catch (e) {
|
||
debugger;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
static downloadTranslationsAsync(locale: string) {
|
||
NATIVE_FETCH(GhPagesUtils.getUrl(`translations/${locale}.json`))
|
||
.then(resp => resp.json())
|
||
.then(translations => {
|
||
window.localStorage.setItem(Translations.KEY_TRANSLATIONS, JSON.stringify(translations));
|
||
Translations.foreignTranslations = translations;
|
||
});
|
||
}
|
||
|
||
static switchLocale(locale: string) {
|
||
localStorage.setItem(Translations.KEY_LOCALE, locale);
|
||
}
|
||
}
|
||
|
||
export const t = Translations.get;
|
||
export const ut = (text: string): string => {
|
||
BxLogger.warning('Untranslated text', text);
|
||
return text;
|
||
}
|
||
|
||
Translations.init();
|