1 parent
99ee3385ac
commit
53f4812adc
14 files changed
+730
-192
No files matched your search
@@ -299,7 +299,46 @@ function tr(key, fallback = key) {
|
||||
}
|
||||
|
||||
function trText(text) {
|
||||
return state.translations?._text?.[text] || text;
|
||||
const source = String(text ?? "");
|
||||
const map = state.translations?._text || {};
|
||||
if (map[source]) return map[source];
|
||||
if (!source || !Object.keys(map).length) return source;
|
||||
if (trText._map !== map) {
|
||||
trText._map = map;
|
||||
trText._templates = Object.entries(map)
|
||||
.filter(([template]) => /\{\w+\}/.test(template))
|
||||
.map(([template, translated]) => {
|
||||
const names = [];
|
||||
const pattern = template
|
||||
.split(/(\{\w+\})/g)
|
||||
.filter(Boolean)
|
||||
.map((part) => {
|
||||
const match = /^\{(\w+)\}$/.exec(part);
|
||||
if (match) { names.push(match[1]); return "(.+?)"; }
|
||||
return part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
})
|
||||
.join("");
|
||||
return {
|
||||
regex: new RegExp(`^${pattern}$`, "s"),
|
||||
names,
|
||||
translated,
|
||||
staticLength: template.replace(/\{\w+\}/g, "").length,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => b.staticLength - a.staticLength);
|
||||
}
|
||||
for (const entry of trText._templates || []) {
|
||||
const match = entry.regex.exec(source);
|
||||
if (!match) continue;
|
||||
let translated = entry.translated;
|
||||
entry.names.forEach((name, index) => { translated = translated.replaceAll(`{${name}}`, match[index + 1]); });
|
||||
return translated;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
function fmtText(template, values = {}) {
|
||||
return trText(template).replace(/\{(\w+)\}/g, (_, key) => String(values[key] ?? ""));
|
||||
}
|
||||
|
||||
function applyPreferences() {
|
||||
@@ -612,7 +651,7 @@ async function reconcileImapLabels() {
|
||||
return;
|
||||
}
|
||||
if (button) button.disabled = true;
|
||||
if (status) status.textContent = "Reconciling…";
|
||||
if (status) status.textContent = trText("Reconciling…");
|
||||
try {
|
||||
const result = await request("/tags/reconcile", { method: "POST", body: "{}" });
|
||||
const added = Number(result.labels_added || 0);
|
||||
@@ -934,7 +973,7 @@ async function loadAuthPolicy() {
|
||||
});
|
||||
["#login-remember-label", "#add-account-remember-label"].forEach((selector) => {
|
||||
const label = $(selector);
|
||||
if (label) label.textContent = "Keep me signed in";
|
||||
if (label) label.textContent = trText("Keep me signed in");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1029,7 +1068,7 @@ function renderAccountNotificationSettings() {
|
||||
saveNotificationAccountSelection();
|
||||
if (input.checked && typeof loadNotificationPreferencesForAccount === "function") void loadNotificationPreferencesForAccount(account.id);
|
||||
});
|
||||
label.append(input, el("span", "", "Notify"));
|
||||
label.append(input, el("span", "", trText("Notify")));
|
||||
row.append(details, label);
|
||||
list.append(row);
|
||||
}
|
||||
@@ -1093,7 +1132,7 @@ function renderAccountSettings() {
|
||||
? state.accounts
|
||||
: state.accounts.filter((account) => account.id === state.accountId);
|
||||
if (!accounts.length) {
|
||||
list.append(el("div", "empty-list", "No active accounts."));
|
||||
list.append(el("div", "empty-list", trText("No active accounts.")));
|
||||
renderAccountSwitcher();
|
||||
renderAccountNotificationSettings();
|
||||
return;
|
||||
@@ -1107,7 +1146,7 @@ function renderAccountSettings() {
|
||||
use.addEventListener("click", () => switchAccount(account.id));
|
||||
row.append(email, use);
|
||||
if (multiAccountEnabled()) {
|
||||
const remove = el("button", "button quiet danger", "Remove");
|
||||
const remove = el("button", "button quiet danger", trText("Remove"));
|
||||
remove.type = "button";
|
||||
remove.addEventListener("click", () => removeBrowserAccount(account.id));
|
||||
row.append(remove);
|
||||
@@ -1121,13 +1160,13 @@ function renderAccountSettings() {
|
||||
async function loadActiveSessions() {
|
||||
const list = $("#account-session-list");
|
||||
if (!list) return;
|
||||
list.replaceChildren(el("div", "empty-list", "Loading sessions…"));
|
||||
list.replaceChildren(el("div", "empty-list", trText("Loading sessions…")));
|
||||
try {
|
||||
const data = await request("/auth/sessions", { method: "GET" });
|
||||
const sessions = data.sessions || [];
|
||||
list.replaceChildren();
|
||||
if (!sessions.length) {
|
||||
list.append(el("div", "empty-list", "No active sessions."));
|
||||
list.append(el("div", "empty-list", trText("No active sessions.")));
|
||||
return;
|
||||
}
|
||||
for (const session of sessions) {
|
||||
|
||||
Reference in new issue
Block a user