feat: support translations that vary by operating system

This commit is contained in:
Lukas Obermann
2023-10-03 20:54:56 +02:00
parent 17dded32a1
commit e4a842f066
8 changed files with 33 additions and 7 deletions
+1
View File
@@ -37,6 +37,7 @@ const setMenu = (database: Database) => {
Object.fromEntries(database.raw.locales),
getGlobalSettings().locale,
app.getLocale(),
process.platform,
)
const template: MenuItemConstructorOptions[] = [
+1
View File
@@ -176,6 +176,7 @@ ExternalAPI.on("initial-setup", ({ database, globalSettings }) => {
selectedFallbackLocale={globalSettings.fallbackLocale}
selectedLocaleEvents={ExternalAPI}
systemLocale={ExternalAPI.systemLocale}
platform={ExternalAPI.platform}
locales={Object.fromEntries(database.raw.locales)}
ui={Object.fromEntries(database.raw.ui)}
>
+1
View File
@@ -18,6 +18,7 @@ ExternalAPI.on("initial-setup", ({ translations, locales, systemLocale, settings
selectedFallbackLocale={settings.fallbackLocale}
selectedLocaleEvents={ExternalAPI}
systemLocale={systemLocale}
platform={ExternalAPI.platform}
locales={locales}
ui={translations}
>
@@ -13,6 +13,7 @@ type Props = {
"fallback-locale-changed": [locale: string | undefined]
}>
systemLocale: string
platform: NodeJS.Platform
locales: Record<string, Locale>
ui: Record<string, UI>
}
@@ -25,6 +26,7 @@ export const LocalizationProvider: FCC<Props> = props => {
const {
children,
locales,
platform,
selectedLocale: initialSelectedLocale,
selectedFallbackLocale: initialSelectedFallbackLocale,
selectedLocaleEvents,
@@ -49,7 +51,7 @@ export const LocalizationProvider: FCC<Props> = props => {
return (
<LocalizationContext.Provider
value={{ locales, selectedLocale, selectedFallbackLocale, systemLocale, ui }}
value={{ locales, platform, selectedLocale, selectedFallbackLocale, systemLocale, ui }}
>
{children}
</LocalizationContext.Provider>
+2
View File
@@ -10,6 +10,7 @@ export type LocalizationContext = {
selectedLocale: string | undefined
selectedFallbackLocale: string | undefined
systemLocale: string
platform: NodeJS.Platform
locales: Record<string, Locale>
ui: Record<string, UI>
}
@@ -23,6 +24,7 @@ export const LocalizationContext = createContext<LocalizationContext>({
selectedLocale: undefined,
selectedFallbackLocale: undefined,
systemLocale: "en-US",
platform: "win32",
locales: {},
ui: {},
})
+2
View File
@@ -16,12 +16,14 @@ export const useTranslate = () => {
localizationContext.locales,
localizationContext.selectedLocale,
localizationContext.systemLocale,
localizationContext.platform,
),
[
localizationContext.locales,
localizationContext.selectedLocale,
localizationContext.systemLocale,
localizationContext.ui,
localizationContext.platform,
],
)
+22 -6
View File
@@ -1,6 +1,6 @@
import { Locale } from "optolith-database-schema/types/Locale"
import { UI } from "optolith-database-schema/types/UI"
import { PluralizationCategories } from "optolith-database-schema/types/_I18n"
import { PluralizationCategories, VaryBySystem } from "optolith-database-schema/types/_I18n"
import { LocaleMap } from "optolith-database-schema/types/_LocaleMap"
const insertParams = (str: string, params: (string | number)[]): string =>
@@ -25,6 +25,14 @@ export type Translate = <K extends keyof UI>(
: [...params: (string | number)[]]
) => string
const isPluralizationCategories = (
value: string | PluralizationCategories | VaryBySystem,
): value is PluralizationCategories => typeof value === "object" && "other" in value
const isVaryBySystem = (
value: string | PluralizationCategories | VaryBySystem,
): value is VaryBySystem => typeof value === "object" && "mac" in value
/**
* Creates a translate function based on the given environment, translations and
* locales.
@@ -34,17 +42,25 @@ export const createTranslate = (
locales: Record<string, Locale>,
selectedLocale: string | undefined,
systemLocale: string,
platform: NodeJS.Platform,
pluralRulesOptions?: Intl.PluralRulesOptions,
) => {
const locale = selectedLocale ?? matchSystemLocaleToSupported(Object.keys(locales), systemLocale)
const pluralRules = new Intl.PluralRules(locale)
const pluralRules = new Intl.PluralRules(locale, pluralRulesOptions)
const translate: Translate = (key, ...options) => {
const value = translations[locale]?.[key] ?? key
if (typeof value === "object" && typeof options[0] === "number") {
const [count] = options
const selectedValue = value[pluralRules.select(count)] ?? value.other
return insertParams(selectedValue, options)
if (isVaryBySystem(value)) {
return platform === "darwin" ? value.mac : platform === "win32" ? value.windows : value.linux
} else if (isPluralizationCategories(value)) {
if (typeof options[0] === "number") {
const [count] = options
const selectedValue = value[pluralRules.select(count)] ?? value.other
return insertParams(selectedValue, options)
} else {
return insertParams(value.other, options)
}
} else {
const str = typeof value === "string" ? value : key
return options.length > 0 ? insertParams(str, options) : str
+1
View File
@@ -19,6 +19,7 @@ ExternalAPI.on("initial-setup", data => {
selectedFallbackLocale={globalSettings.fallbackLocale}
selectedLocaleEvents={ExternalAPI}
systemLocale={systemLocale}
platform={ExternalAPI.platform}
locales={locales}
ui={translations}
>