diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba882c4..baa2b38 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,9 @@
- main.js added Dark & Light mode i18n.js keys.
- New Admin section Header Settings to change Header Title.
- Admin Panel confirm unsaved changes.
+- Added translations and data attributes for almost all user-facing text
+
+---
## Changes 4/12/2025
diff --git a/js/auth.js b/js/auth.js
index 7e838ab..bfca1e5 100644
--- a/js/auth.js
+++ b/js/auth.js
@@ -1,5 +1,5 @@
import { sendRequest } from './networkUtils.js';
-import { t } from './i18n.js';
+import { t, applyTranslations } from './i18n.js';
import {
toggleVisibility,
showToast as originalShowToast,
@@ -164,7 +164,8 @@ function updateAuthenticatedUI(data) {
restoreBtn = document.createElement("button");
restoreBtn.id = "restoreFilesBtn";
restoreBtn.classList.add("btn", "btn-warning");
- restoreBtn.innerHTML = 'restore_from_trash';
+ restoreBtn.setAttribute("data-i18n-title", "trash_restore_delete");
+ restoreBtn.innerHTML = 'restore_from_trash';
if (firstButton) insertAfter(restoreBtn, firstButton);
else headerButtons.appendChild(restoreBtn);
}
@@ -175,7 +176,8 @@ function updateAuthenticatedUI(data) {
adminPanelBtn = document.createElement("button");
adminPanelBtn.id = "adminPanelBtn";
adminPanelBtn.classList.add("btn", "btn-info");
- adminPanelBtn.innerHTML = 'admin_panel_settings';
+ adminPanelBtn.setAttribute("data-i18n-title", "admin_panel");
+ adminPanelBtn.innerHTML = 'admin_panel_settings';
insertAfter(adminPanelBtn, restoreBtn);
adminPanelBtn.addEventListener("click", openAdminPanel);
} else {
@@ -194,17 +196,19 @@ function updateAuthenticatedUI(data) {
userPanelBtn = document.createElement("button");
userPanelBtn.id = "userPanelBtn";
userPanelBtn.classList.add("btn", "btn-user");
- userPanelBtn.innerHTML = 'account_circle';
+ userPanelBtn.setAttribute("data-i18n-title", "user_panel");
+ userPanelBtn.innerHTML = 'account_circle';
+
const adminBtn = document.getElementById("adminPanelBtn");
if (adminBtn) insertAfter(userPanelBtn, adminBtn);
else if (firstButton) insertAfter(userPanelBtn, firstButton);
- else headerButtons.appendChild(userPanelBtn);
+ else headerButtons.appendChild(userPanelBtn);
userPanelBtn.addEventListener("click", openUserPanel);
} else {
userPanelBtn.style.display = "block";
}
}
-
+ applyTranslations();
updateItemsPerPageSelect();
updateLoginOptionsUIFromStorage();
}
diff --git a/js/authModals.js b/js/authModals.js
index 5060d14..7a0349e 100644
--- a/js/authModals.js
+++ b/js/authModals.js
@@ -811,7 +811,7 @@ export function openAdminPanel() {
export async function closeAdminPanel() {
if (hasUnsavedChanges()) {
- const userConfirmed = await showCustomConfirmModal("You have unsaved changes. Are you sure you want to close without saving?");
+ const userConfirmed = await showCustomConfirmModal(t("unsaved_changes_confirm"));
if (!userConfirmed) {
return;
}
diff --git a/js/domUtils.js b/js/domUtils.js
index 0e633f4..2817bad 100644
--- a/js/domUtils.js
+++ b/js/domUtils.js
@@ -117,9 +117,9 @@ export function buildSearchAndPaginationControls({ currentPage, totalPages, sear
-
- Page ${currentPage} of ${totalPages || 1}
-
+
+ ${t("page")} ${currentPage} ${t("of")} ${totalPages || 1}
+
@@ -137,7 +137,7 @@ export function buildFileTableHeader(sortOrder) {
${t("upload_date")} ${sortOrder.column === "uploaded" ? (sortOrder.ascending ? "▲" : "▼") : ""} |
${t("file_size")} ${sortOrder.column === "size" ? (sortOrder.ascending ? "▲" : "▼") : ""} |
${t("uploader")} ${sortOrder.column === "uploader" ? (sortOrder.ascending ? "▲" : "▼") : ""} |
- Actions |
+ ${t("actions")} |
`;
@@ -181,36 +181,38 @@ export function buildFileTableRow(file, folderPath) {
${file.editable ? `
` : ""}
${previewButton}
- `;
+`;
}
export function buildBottomControls(itemsPerPageSetting) {
return `
-
+
- items per page
+ ${t("items_per_page")}
`;
}
diff --git a/js/fileListView.js b/js/fileListView.js
index ca5e21d..ef2032f 100644
--- a/js/fileListView.js
+++ b/js/fileListView.js
@@ -73,7 +73,7 @@ function buildFolderSummary(filteredFiles) {
return sum + parseSizeToBytes(file.size);
}, 0);
const sizeStr = formatSize(totalBytes);
- return `Total Files: ${totalFiles} | Total Size: ${sizeStr}`;
+ return `${t('total_files')}: ${totalFiles} | ${t('total_size')}: ${sizeStr}`;
}
/**
@@ -316,7 +316,7 @@ export function renderFileTable(folder, container) {
rowHTML = rowHTML.replace(/()(.*?)(<\/td>)/, (match, p1, p2, p3) => {
return p1 + p2 + tagBadgesHTML + p3;
});
- rowHTML = rowHTML.replace(/(<\/div>\s*<\/td>\s*<\/tr>)/, ` |