mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 07:40:59 +00:00
2a6c771ad9
On a phone or a folded foldable turned landscape the welcome, address, TREK Cloud and plan screens were taller than the glass: the second choice and the main button sat below the edge and Back was cut at the top. There the explanation and the choices now stand side by side, the explanation pinned while a long plan list scrolls. Every screen centres while it fits and starts at the top when it does not. Upright on an iPad, half of one in Split View and an unfolded foldable, the photo spans the full width and fades only downwards, and the choices stand centred in the room below it. Buttons and fields are pills like the app's, choice cards take the app's card radius, and headings and subtitles balance their lines. In Arabic (and Hebrew, which never ran right to left here) chevrons point along the reading direction and sit at the far edge of their card, the Cloud lockup stays unmirrored on the leading edge, prices and addresses read left to right, and a plan's period no longer touches its price. The slides follow the reading direction. Russian gets Cyrillic stand-ins under the same family names, so the headline keeps a rounded face.
40 lines
1.6 KiB
TypeScript
40 lines
1.6 KiB
TypeScript
import { SUPPORTED_LANGUAGE_CODES, isRtlLanguage } from '@trek/shared/i18n'
|
|
import type { TranslationStrings } from '@trek/shared/i18n'
|
|
|
|
// Only the native strings of every locale, not the whole UI: this page ships
|
|
// inside the app binary and shows three screens.
|
|
const bundles = import.meta.glob<TranslationStrings>('../../shared/src/i18n/*/native.ts', { eager: true, import: 'default' })
|
|
|
|
function bundleFor(code: string): TranslationStrings | undefined {
|
|
return bundles[`../../shared/src/i18n/${code}/native.ts`]
|
|
}
|
|
|
|
export function pickLocale(preferred: readonly string[]): string {
|
|
for (const lang of preferred) {
|
|
const lower = lang.toLowerCase()
|
|
if (lower === 'pt-br') return 'br'
|
|
if (lower.startsWith('zh-tw') || lower.startsWith('zh-hk') || lower.startsWith('zh-hant')) return 'zh-TW'
|
|
if (lower.startsWith('el')) return 'gr'
|
|
const prefix = lower.split('-')[0]
|
|
const match = SUPPORTED_LANGUAGE_CODES.find((code) => code.toLowerCase() === lower || code === prefix)
|
|
if (match) return match
|
|
}
|
|
return 'en'
|
|
}
|
|
|
|
export function translator(code: string) {
|
|
const strings = bundleFor(code) ?? {}
|
|
const fallback = bundleFor('en') ?? {}
|
|
return (key: string, params: Record<string, string> = {}): string => {
|
|
const template = strings[key] ?? fallback[key] ?? key
|
|
return typeof template === 'string'
|
|
? template.replace(/\{(\w+)\}/g, (whole, name: string) => params[name] ?? whole)
|
|
: key
|
|
}
|
|
}
|
|
|
|
/** Arabic and Hebrew run right to left. */
|
|
export function directionOf(code: string): 'rtl' | 'ltr' {
|
|
return isRtlLanguage(code) ? 'rtl' : 'ltr'
|
|
}
|