add: 添加 i18n 翻译

This commit is contained in:
ci
2026-06-19 13:05:35 +08:00
parent 5ebe562a62
commit 73dfe12c95
8 changed files with 654 additions and 189 deletions
+14 -14
View File
@@ -2,6 +2,7 @@
import { post } from "../rc.js";
import { getState, setState, toast } from "../state.js";
import { t } from "../i18n.js";
export async function renderRemotes() {
const app = document.getElementById("app");
@@ -10,13 +11,13 @@ export async function renderRemotes() {
app.innerHTML = `
<div class="section-head">
<div>
<h2>Remotes</h2>
<p class="subtitle">Configured cloud storage providers. Click a tile to browse, hover for edit/delete.</p>
<h2>${t("remotes.title")}</h2>
<p class="subtitle">${t("remotes.subtitle")}</p>
</div>
<a class="btn btn-primary btn-sm" href="#/configure/new">New remote</a>
<a class="btn btn-primary btn-sm" href="#/configure/new">${t("remotes.new_remote")}</a>
</div>
<div id="remote-grid" class="connector-grid">
<p class="empty" style="grid-column:1/-1">Loading remotes…</p>
<p class="empty" style="grid-column:1/-1">${t("remotes.loading")}</p>
</div>
`;
@@ -39,8 +40,8 @@ export async function renderRemotes() {
if (remotes.length === 0) {
grid.innerHTML = `
<div class="empty" style="grid-column:1/-1">
<h3>No remotes configured</h3>
<p>Click <strong>New remote</strong> above to add one from this GUI.</p>
<h3>${t("remotes.empty_title")}</h3>
<p>${t("remotes.empty_body")}</p>
</div>
`;
return;
@@ -53,15 +54,14 @@ export async function renderRemotes() {
<span class="tile-name">${escapeHtml(r.name)}</span>
<span class="badge">${escapeHtml(r.type)}</span>
<div class="tile-actions">
<button type="button" title="Edit" data-edit="${escapeHtml(r.name)}">✎</button>
<button type="button" title="Delete" class="danger" data-delete="${escapeHtml(r.name)}">🗑</button>
<button type="button" title="${t("browser.rename")}" data-edit="${escapeHtml(r.name)}">✎</button>
<button type="button" title="${t("browser.delete")}" class="danger" data-delete="${escapeHtml(r.name)}">🗑</button>
</div>
</a>
`,
)
.join("");
// Wire action buttons
grid.querySelectorAll("[data-edit]").forEach((btn) => {
btn.addEventListener("click", (e) => {
e.preventDefault();
@@ -74,24 +74,24 @@ export async function renderRemotes() {
e.preventDefault();
e.stopPropagation();
const name = btn.dataset.delete;
if (!confirm(`Delete remote ${name}? This cannot be undone.`)) return;
if (!confirm(t("remotes.delete_confirm", name))) return;
try {
await post("config/delete", { name });
toast(`Deleted ${name}`, "success");
toast(t("remotes.deleted", name), "success");
await renderRemotes();
} catch (err) {
toast(`Delete failed: ${err.message}`, "error");
toast(`${t("remotes.delete_failed")}: ${err.message}`, "error");
}
});
});
} catch (e) {
grid.innerHTML = `
<div class="empty" style="grid-column:1/-1">
<h3>Couldn’t reach rclone</h3>
<h3>${t("error.couldnt_reach")}</h3>
<p>${escapeHtml(e.message)}</p>
</div>
`;
toast(`Failed to load remotes: ${e.message}`, "error");
toast(`${t("remotes.load_failed")}: ${e.message}`, "error");
}
}