chore: heygermany customer project
This commit is contained in:
106
apps/website/i18n/config.ts
Normal file
106
apps/website/i18n/config.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { useSyncExternalStore } from 'react'
|
||||
import { DEFAULT_LOCALE, LOCALES, type SupportedLocale } from '@/config'
|
||||
|
||||
export const supportedLocales = LOCALES
|
||||
export const defaultLocale = DEFAULT_LOCALE
|
||||
export type Locale = SupportedLocale
|
||||
|
||||
const LANGUAGE_STORAGE_KEY = 'heygermany.language'
|
||||
const RTL_LOCALES = new Set(['ar', 'he', 'fa', 'ur'])
|
||||
|
||||
let activeLocale: Locale = defaultLocale
|
||||
const listeners = new Set<() => void>()
|
||||
|
||||
export const getLocale = (): Locale => activeLocale
|
||||
|
||||
export function localeDir(locale: string = defaultLocale): 'rtl' | 'ltr' {
|
||||
return RTL_LOCALES.has(locale.split('-')[0]) ? 'rtl' : 'ltr'
|
||||
}
|
||||
|
||||
const normalizeLanguage = (value: string | null | undefined): Locale | undefined => {
|
||||
const short = value?.slice(0, 2).toLowerCase()
|
||||
return supportedLocales.includes(short as Locale) ? (short as Locale) : undefined
|
||||
}
|
||||
|
||||
export function detectInitialLocale(): Locale {
|
||||
if (typeof window === 'undefined') {
|
||||
return defaultLocale
|
||||
}
|
||||
|
||||
return (
|
||||
normalizeLanguage(window.localStorage.getItem(LANGUAGE_STORAGE_KEY)) ??
|
||||
normalizeLanguage(window.navigator.language) ??
|
||||
normalizeLanguage(window.document.documentElement.lang) ??
|
||||
defaultLocale
|
||||
)
|
||||
}
|
||||
|
||||
export function setActiveLocale(next: Locale): void {
|
||||
if (next === activeLocale) {
|
||||
return
|
||||
}
|
||||
|
||||
activeLocale = next
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.localStorage.setItem(LANGUAGE_STORAGE_KEY, next)
|
||||
window.document.documentElement.lang = next
|
||||
}
|
||||
|
||||
for (const listener of listeners) {
|
||||
listener()
|
||||
}
|
||||
}
|
||||
|
||||
export function setRouteLocale(next: Locale): void {
|
||||
if (next === activeLocale) {
|
||||
return
|
||||
}
|
||||
|
||||
activeLocale = next
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.document.documentElement.lang = next
|
||||
}
|
||||
|
||||
for (const listener of listeners) {
|
||||
listener()
|
||||
}
|
||||
}
|
||||
|
||||
function subscribe(listener: () => void): () => void {
|
||||
listeners.add(listener)
|
||||
return () => listeners.delete(listener)
|
||||
}
|
||||
|
||||
activeLocale = detectInitialLocale()
|
||||
|
||||
export function useLocale(): { locale: Locale; dir: 'ltr' | 'rtl'; setLocale: (locale: Locale) => void } {
|
||||
const locale = useSyncExternalStore<Locale>(subscribe, () => activeLocale, () => activeLocale)
|
||||
return {
|
||||
locale,
|
||||
dir: localeDir(locale),
|
||||
setLocale: setActiveLocale,
|
||||
}
|
||||
}
|
||||
|
||||
export function isI18nDebug(): boolean {
|
||||
if (typeof process !== 'undefined' && process.env?.I18N_DEBUG === '1') {
|
||||
return true
|
||||
}
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
return false
|
||||
}
|
||||
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
if (params.has('i18n-debug')) {
|
||||
return params.get('i18n-debug') !== '0'
|
||||
}
|
||||
|
||||
return window.localStorage?.getItem('i18n-debug') === '1'
|
||||
}
|
||||
|
||||
export function maskI18n(value: string): string {
|
||||
return isI18nDebug() ? value.replace(/\S/g, '█') : value
|
||||
}
|
||||
Reference in New Issue
Block a user