Skip to content

Commit

Permalink
feat: change text direction based on locale
Browse files Browse the repository at this point in the history
  • Loading branch information
KaiVandivier committed Jan 16, 2024
1 parent 31a6f53 commit dc43300
Showing 1 changed file with 49 additions and 10 deletions.
59 changes: 49 additions & 10 deletions adapter/src/utils/useLocale.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,45 @@ import i18n from '@dhis2/d2-i18n'
import moment from 'moment'
import { useState, useEffect } from 'react'

i18n.setDefaultNamespace('default')
const I18N_NAMESPACE = 'default'
i18n.setDefaultNamespace(I18N_NAMESPACE)

const simplifyLocale = (locale) => {
const idx = locale.indexOf('-')
if (idx === -1) {
const transformJavaLocale = (locale) => {
return locale.replace('_', '-')
}

// if translation resources aren't found for the given locale, try shorter
// versions of the locale
// e.g. 'pt_BR_Cyrl_asdf' => 'pt_BR', or 'ar-NotFound' => 'ar'
const validateLocaleByBundle = (locale) => {
if (i18n.hasResourceBundle(locale, I18N_NAMESPACE)) {
return locale
}

console.log(`Translations for locale ${locale} not found`)

// see if we can try basic versions of the locale
// (e.g. 'ar' instead of 'ar_IQ')
const match = /[_-]/.exec(locale)
if (!match) {
return locale
}
return locale.substr(0, idx)

const separator = match[0] // '-' or '_'
const splitLocale = locale.split(separator)
for (let i = splitLocale.length - 1; i > 0; i--) {
const shorterLocale = splitLocale.slice(0, i).join(separator)
if (i18n.hasResourceBundle(shorterLocale, I18N_NAMESPACE)) {
return shorterLocale
}
console.log(`Translations for locale ${shorterLocale} not found`)
}

// if nothing else works, use the initially provided locale
return locale
}

// Set locale for Moment and i18n
const setGlobalLocale = (locale) => {
if (locale !== 'en' && locale !== 'en-us') {
import(
Expand All @@ -23,22 +52,30 @@ const setGlobalLocale = (locale) => {
}
moment.locale(locale)

const simplifiedLocale = simplifyLocale(locale)
i18n.changeLanguage(simplifiedLocale)
// for i18n.dir, need JS-formatted locale
const jsLocale = transformJavaLocale(locale)
const direction = i18n.dir(jsLocale)
// set `dir` globally (then override in app wrapper if needed)
document.body.setAttribute('dir', direction)

const resolvedLocale = validateLocaleByBundle(locale)
i18n.changeLanguage(resolvedLocale)

console.log('🗺 Global d2-i18n locale initialized:', resolvedLocale)
}

export const useLocale = (locale) => {
const [result, setResult] = useState(undefined)
const [result, setResult] = useState({})

useEffect(() => {
if (!locale) {
return
}

setGlobalLocale(locale)
setResult(locale)

console.log('🗺 Global d2-i18n locale initialized:', locale)
}, [locale])

return result
}

Expand All @@ -47,6 +84,8 @@ const settingsQuery = {
resource: 'userSettings',
},
}
// note: userSettings.keyUiLocale is expected to be in the Java format,
// e.g. 'ar', 'ar_IQ', 'uz_UZ_Cyrl', etc.
export const useCurrentUserLocale = () => {
const { loading, error, data } = useDataQuery(settingsQuery)
const locale = useLocale(
Expand Down

0 comments on commit dc43300

Please sign in to comment.