103 lines
No EOL
3.6 KiB
JavaScript
103 lines
No EOL
3.6 KiB
JavaScript
(() => {
|
|
const getLocale = () => {
|
|
const cacheLocale = localStorage.getItem('preferredLocale')
|
|
if (cacheLocale) return cacheLocale
|
|
localStorage.setItem('preferredLocale', navigator.language);
|
|
return locale
|
|
}
|
|
|
|
const setPreferredLocale = (locale) => {
|
|
localStorage.setItem('preferredLocale', locale);
|
|
setLocale()
|
|
}
|
|
|
|
const getLocaleURL = (locale = getLocale()) => {
|
|
const lang = locale.split('-')[0];
|
|
return `/res/locale/${lang}.json`
|
|
}
|
|
|
|
const loadLocale = async (locale = getLocale()) => {
|
|
// check localStorage
|
|
const cacheDate = localStorage.getItem(`locale-${locale}`)
|
|
if (cacheDate) {
|
|
if (Date.now() - cacheDate < 1000 * 60 * 60 * 24) { // 1 day
|
|
return JSON.parse(localStorage.getItem(`locale-${locale}-data`))
|
|
}
|
|
}
|
|
try {
|
|
const response = await fetch(getLocaleURL(locale), { cache: 'no-store' })
|
|
if (response.ok) {
|
|
const data = await response.json()
|
|
localStorage.setItem(`locale-${locale}`, Date.now())
|
|
localStorage.setItem(`locale-${locale}-data`, JSON.stringify(data))
|
|
return data
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
if (cacheDate) { // if error then return cache even if expired
|
|
return JSON.parse(localStorage.getItem(`locale-${locale}-data`))
|
|
} else {
|
|
if (locale !== 'en') return await loadLocale('en');
|
|
}
|
|
}
|
|
return {}
|
|
}
|
|
|
|
const setLocale = async (locale = getLocale()) => {
|
|
const data = await loadLocale(locale)
|
|
document.querySelectorAll('[data-i18n]').forEach(async (element) => {
|
|
try {
|
|
// main.intro.title => {main: {intro: {title: 'value'}}}
|
|
const keys = element.getAttribute('data-i18n').split('.');
|
|
console.log(keys)
|
|
let value = data;
|
|
keys.forEach((key) => value = value[key]);
|
|
console.log(value)
|
|
// if array then into ul list
|
|
if (Array.isArray(value)) {
|
|
element.innerHTML = ''
|
|
const ul = document.createElement('ul')
|
|
value.forEach((item) => {
|
|
const li = document.createElement('li')
|
|
li.innerHTML = item
|
|
ul.appendChild(li)
|
|
})
|
|
element.appendChild(ul)
|
|
} else {
|
|
element.innerHTML = value ?? '###';
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
element.innerHTML = '###';
|
|
}
|
|
});
|
|
document.querySelectorAll('[data-i18n-show').forEach(el => el.removeAttribute('data-i18n-show'))
|
|
}
|
|
|
|
window.locale = {
|
|
setPreferredLocale,
|
|
getLocale,
|
|
getLocaleURL,
|
|
loadLocale,
|
|
setLocale,
|
|
expireLocale: () => {
|
|
localStorage.removeItem(`locale-${getLocale()}`)
|
|
localStorage.removeItem(`locale-${getLocale()}-data`)
|
|
setLocale()
|
|
}
|
|
}
|
|
window.locale.setLocale();
|
|
|
|
// expiry management
|
|
// check if locale is older than EXPIRY_TIME then fetch again
|
|
function checkExpiry() {
|
|
const cacheDate = localStorage.getItem(`locale-${getLocale()}`)
|
|
if (cacheDate) {
|
|
if (Date.now() - cacheDate > 1000 * 60 * 60 * 24) { // 1 day
|
|
window.locale.expireLocale()
|
|
}
|
|
}
|
|
}
|
|
setInterval(checkExpiry, 1000 * 60 * 60); // 1 hour
|
|
checkExpiry()
|
|
})() |