-
Notifications
You must be signed in to change notification settings - Fork 737
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(PWA): Add translations loader plugin
(cherry picked from commit b1cc435)
- Loading branch information
1 parent
48d4996
commit d24ec2c
Showing
2 changed files
with
92 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
function makeTranslationFunction() { | ||
let messages = {}; | ||
return { | ||
translate, | ||
load: () => Promise.allSettled([ | ||
setup(), | ||
setupDayjs(), | ||
]), | ||
} | ||
|
||
async function setup() { | ||
if (window.frappe?.boot?.__messages) { | ||
messages = window.frappe?.boot?.__messages; | ||
return; | ||
} | ||
|
||
const url = new URL("/api/method/frappe.translate.load_all_translations", location.origin); | ||
url.searchParams.append("lang", window.frappe?.boot?.lang ?? navigator.language); | ||
url.searchParams.append("hash", window.frappe?.boot?.translations_hash || window._version_number || Math.random()); // for cache busting | ||
// url.searchParams.append("app", "hrms"); | ||
|
||
try { | ||
const response = await fetch(url); | ||
messages = await response.json() || {} | ||
} catch (error) { | ||
console.error("Failed to fetch translations:", error) | ||
} | ||
} | ||
|
||
async function setupDayjs() { | ||
// TODO | ||
} | ||
|
||
function translate(txt, replace, context = null) { | ||
if (!txt || typeof txt != "string") return txt; | ||
|
||
let translated_text = ""; | ||
let key = txt; | ||
if (context) { | ||
translated_text = messages[`${key}:${context}`]; | ||
} | ||
if (!translated_text) { | ||
translated_text = messages[key] || txt; | ||
} | ||
if (replace && typeof replace === "object") { | ||
translated_text = format(translated_text, replace); | ||
} | ||
|
||
return translated_text; | ||
} | ||
|
||
function format(str, args) { | ||
if (str == undefined) return str; | ||
|
||
let unkeyed_index = 0; | ||
return str.replace( | ||
/\{(\w*)\}/g, | ||
(match, key) => { | ||
if (key === "") { | ||
key = unkeyed_index; | ||
unkeyed_index++; | ||
} | ||
if (key == +key) { | ||
return args[key] !== undefined ? args[key] : match; | ||
} | ||
} | ||
); | ||
} | ||
} | ||
|
||
const { translate, load } = makeTranslationFunction(); | ||
|
||
export const translationsPlugin = { | ||
async isReady() { | ||
await load(); | ||
}, | ||
install(/** @type {import('vue').App} */ app, options) { | ||
const __ = translate; | ||
// app.mixin({ methods: { __ } }) | ||
app.config.globalProperties.__ = __; | ||
app.provide("$translate", __); | ||
}, | ||
} |