feat: support translations that vary by operating system
This commit is contained in:
@@ -37,6 +37,7 @@ const setMenu = (database: Database) => {
|
||||
Object.fromEntries(database.raw.locales),
|
||||
getGlobalSettings().locale,
|
||||
app.getLocale(),
|
||||
process.platform,
|
||||
)
|
||||
|
||||
const template: MenuItemConstructorOptions[] = [
|
||||
|
||||
@@ -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)}
|
||||
>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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: {},
|
||||
})
|
||||
|
||||
@@ -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,
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,6 +19,7 @@ ExternalAPI.on("initial-setup", data => {
|
||||
selectedFallbackLocale={globalSettings.fallbackLocale}
|
||||
selectedLocaleEvents={ExternalAPI}
|
||||
systemLocale={systemLocale}
|
||||
platform={ExternalAPI.platform}
|
||||
locales={locales}
|
||||
ui={translations}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user