forked from nebulosus/web
feat: update site
This commit is contained in:
parent
71b2aaae4f
commit
a6ff285b2e
6 changed files with 321 additions and 37 deletions
103
public/res/locale.js
Normal file
103
public/res/locale.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
(() => {
|
||||
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()
|
||||
})()
|
Loading…
Add table
Add a link
Reference in a new issue