diff --git a/static/js/app/filesView.js b/static/js/app/filesView.js
index 30c5175b..a9650ee4 100644
--- a/static/js/app/filesView.js
+++ b/static/js/app/filesView.js
@@ -134,7 +134,7 @@ async function loadFiles(options = { insertHistory: true }) {
ui.showError(`
-
${i18n ? i18n.t('files.loading') : 'Loading files…'}
+
${i18n.t('files.loading')}
`);
}, 100);
diff --git a/static/js/app/main.js b/static/js/app/main.js
index 0170c140..fa07b9d8 100644
--- a/static/js/app/main.js
+++ b/static/js/app/main.js
@@ -166,9 +166,7 @@ function setActionsBarMode(mode, force = false) {
elements.gridViewBtn = document.getElementById('grid-view-btn');
elements.listViewBtn = document.getElementById('list-view-btn');
- if (i18n?.translateElement) {
- i18n.translateElement(elements.actionsBar);
- }
+ i18n.translateElement(elements.actionsBar);
if (mode === 'files') {
setupUploadDropdown();
@@ -395,7 +393,7 @@ function initApp() {
});
// Wait for translations to load before checking authentication
- if (i18n?.isLoaded?.()) {
+ if (i18n.isLoaded()) {
// Translations already loaded, proceed with authentication
checkAuthentication();
} else {
@@ -408,7 +406,7 @@ function initApp() {
// Set a timeout as a fallback in case translations take too long
setTimeout(() => {
- if (!i18n?.isLoaded?.()) {
+ if (!i18n.isLoaded()) {
console.warn('Translations loading timeout, proceeding with authentication anyway');
checkAuthentication();
}
@@ -727,16 +725,11 @@ function updateStorageUsageDisplay(userData) {
// Remove data-i18n attribute to prevent i18n from overwriting our value
storageInfo.removeAttribute('data-i18n');
- // Use i18n if available
- if (i18n?.t) {
- storageInfo.textContent = i18n.t('storage.used', {
- percentage: usagePercentage,
- used: usedFormatted,
- total: quotaFormatted
- });
- } else {
- storageInfo.textContent = `${usagePercentage}% used (${usedFormatted} / ${quotaFormatted})`;
- }
+ storageInfo.textContent = i18n.t('storage.used', {
+ percentage: usagePercentage,
+ used: usedFormatted,
+ total: quotaFormatted
+ });
}
console.log(`Updated storage display: ${usagePercentage}% (${usedFormatted} / ${quotaFormatted})`);
diff --git a/static/js/app/navigation.js b/static/js/app/navigation.js
index 018afd9e..3e2c61b5 100644
--- a/static/js/app/navigation.js
+++ b/static/js/app/navigation.js
@@ -151,8 +151,8 @@ function setCurrentSection(section) {
// Update page title
const titleKey = `nav.${section}`;
- const defaultTitle = section.charAt(0).toUpperCase() + section.slice(1);
- appElements.pageTitle.textContent = i18n ? i18n.t(titleKey) : defaultTitle;
+ // TODO check why no more used: const defaultTitle = section.charAt(0).toUpperCase() + section.slice(1);
+ appElements.pageTitle.textContent = i18n.t(titleKey);
appElements.pageTitle.setAttribute('data-i18n', titleKey);
// Hide sharedView when switching to any other section
diff --git a/static/js/app/trashView.js b/static/js/app/trashView.js
index 102d8e56..f69d8542 100644
--- a/static/js/app/trashView.js
+++ b/static/js/app/trashView.js
@@ -15,14 +15,13 @@ async function loadTrashItems() {
try {
if (multiSelect) multiSelect.clear();
ui.resetFilesList(); // ensure also list visible & error hidden
- const _tt = i18n?.t ? i18n.t : (k) => k.split('.').pop();
elements.filesList.innerHTML = `
`;
@@ -33,7 +32,7 @@ async function loadTrashItems() {
if (trashItems.length === 0) {
ui.showError(`
- ${i18n ? i18n.t('trash.empty_state') : 'The trash is empty'}
+ ${i18n.t('trash.empty_state')}
`);
return;
}
@@ -58,12 +57,12 @@ function addTrashItemToView(item) {
let iconSpecialClass = '';
if (!isFile) {
iconClass = item.icon_class || 'fas fa-folder';
- typeLabel = i18n ? i18n.t('files.file_types.folder') : 'Folder';
+ typeLabel = i18n.t('files.file_types.folder');
} else {
iconClass = item.icon_class || (ui?.getIconClass ? ui.getIconClass(item.name) : 'fas fa-file');
iconSpecialClass = ui?.getIconSpecialClass ? ui.getIconSpecialClass(item.name) : '';
const cat = item.category || '';
- typeLabel = cat ? (i18n ? i18n.t(`files.file_types.${cat.toLowerCase()}`) || cat : cat) : i18n ? i18n.t('files.file_types.document') : 'Document';
+ typeLabel = cat ? i18n.t(`files.file_types.${cat.toLowerCase()}`) || cat : i18n.t('files.file_types.document');
}
const isFolder = !isFile;
@@ -86,10 +85,10 @@ function addTrashItemToView(item) {
${escapeHtml(item.original_path || '--')}
${escapeHtml(formattedDate)}
-
diff --git a/static/js/app/ui.js b/static/js/app/ui.js
index 4deac6bb..0bdd375d 100644
--- a/static/js/app/ui.js
+++ b/static/js/app/ui.js
@@ -542,17 +542,11 @@ const ui = {
breadcrumb.innerHTML = '';
const path = app.breadcrumbPath; // [{id, name}, ...]
- // Helper function to safely get translation text
- const getTranslatedText = (key, defaultValue) => {
- if (!i18n?.t) return defaultValue;
- return i18n.t(key);
- };
-
// -- Home icon (always present, clickable to go to root) --
const homeIcon = document.createElement('span');
homeIcon.className = 'breadcrumb-item breadcrumb-home';
homeIcon.innerHTML = '';
- homeIcon.title = getTranslatedText('breadcrumb.home', 'Home');
+ homeIcon.title = i18n.t('breadcrumb.home');
// Home is always clickable if we have a home folder
if (app.userHomeFolderId) {
@@ -1265,7 +1259,7 @@ const ui = {
- ${i18n ? i18n.t('files.file_types.folder') : 'Folder'}
+ ${i18n.t('files.file_types.folder')}
--
${formattedDate}
@@ -1288,7 +1282,7 @@ const ui = {
const iconClass = file.icon_class || this.getIconClass(file.name);
const iconSpecialClass = file.icon_special_class || this.getIconSpecialClass(file.name);
const cat = file.category || '';
- const typeLabel = cat ? (i18n ? i18n.t(`files.file_types.${cat.toLowerCase()}`) || cat : cat) : i18n ? i18n.t('files.file_types.document') : 'Document';
+ const typeLabel = cat ? i18n.t(`files.file_types.${cat.toLowerCase()}`) || cat : i18n.t('files.file_types.document');
const fileSize = file.size_formatted || formatFileSize(file.size);
const formattedDate = formatDateTime(file.modified_at);
const isFav = favorites?.isFavorite(file.id, 'file');
@@ -1352,7 +1346,7 @@ const ui = {
`;
- if (i18n?.translateElement) i18n.translateElement(filesList);
+ i18n.translateElement(filesList);
filesList.classList.remove('hidden');
filesContainerError?.classList.add('hidden');
@@ -1376,7 +1370,7 @@ const ui = {
const filesList = document.getElementById('files-list');
if (filesContainerError) filesContainerError.innerHTML = content;
- if (i18n?.translateElement) i18n.translateElement(filesContainerError);
+ i18n.translateElement(filesContainerError);
filesContainerError?.classList.remove('hidden');
filesList?.classList.add('hidden');
@@ -1642,9 +1636,9 @@ if (document.readyState === 'loading') {
* @returns {Promise} true if confirmed, false if cancelled
*/
function showConfirmDialog({ title, message, confirmText, cancelText, danger = true } = {}) {
- const ct = confirmText || (i18n ? i18n.t('actions.delete') : 'Delete');
- const cc = cancelText || (i18n ? i18n.t('actions.cancel') : 'Cancel');
- const t = title || (i18n ? i18n.t('dialogs.confirm_title') : 'Confirm action');
+ const ct = confirmText || i18n.t('actions.delete');
+ const cc = cancelText || i18n.t('actions.cancel');
+ const t = title || i18n.t('dialogs.confirm_title');
return new Promise((resolve) => {
// Remove any previous confirm dialog
diff --git a/static/js/app/userMenu.js b/static/js/app/userMenu.js
index 80432567..81e106d4 100644
--- a/static/js/app/userMenu.js
+++ b/static/js/app/userMenu.js
@@ -209,10 +209,9 @@ function showUserProfileModal() {
const usedBytes = userData.storage_used_bytes || 0;
const quotaBytes = userData.storage_quota_bytes == null ? 10 * 1024 * 1024 * 1024 : userData.storage_quota_bytes;
const percentage = quotaBytes > 0 ? Math.min(Math.round((usedBytes / quotaBytes) * 100), 100) : 0;
+ // FIXME: use classes
const barColor = percentage > 90 ? '#ef4444' : percentage > 70 ? '#f59e0b' : '#22c55e';
- const t = (key, fallback) => (i18n?.t ? i18n.t(key) || fallback : fallback);
-
const existing = document.getElementById('profile-modal-overlay');
if (existing) existing.remove();
@@ -225,11 +224,11 @@ function showUserProfileModal() {
${initials}
${username}
${email}
- ${role === 'admin' ? '🛡️ Admin' : `👤 ${t('user_menu.role_user', 'User')}`}
+ ${role === 'admin' ? '🛡️ Admin' : `👤 ${i18n.t('user_menu.role_user')}`}
- ${t('storage.title', 'Storage')}
+ ${i18n.t('storage.title')}
@@ -237,7 +236,7 @@ function showUserProfileModal() {
${percentage}% · ${formatFileSize(usedBytes)} / ${formatQuotaSize(quotaBytes)}
`;
diff --git a/static/js/core/languageSelector.js b/static/js/core/languageSelector.js
index df012709..6468f545 100644
--- a/static/js/core/languageSelector.js
+++ b/static/js/core/languageSelector.js
@@ -66,7 +66,7 @@ function createLanguageSelector(containerId = 'language-selector') {
// Get current language
const languages = getAvailableLanguages();
- const currentLocale = i18n ? i18n.getCurrentLocale() : 'en';
+ const currentLocale = i18n.getCurrentLocale();
const currentLang = languages.find((l) => l.code === currentLocale) || languages[0];
// Set initial HTML attributes
@@ -185,10 +185,7 @@ function closeDropdown(container) {
* Select a language
*/
async function selectLanguage(langCode, container) {
- // Update i18n if available
- if (i18n) {
- await i18n.setLocale(langCode);
- }
+ await i18n.setLocale(langCode);
// Update HTML lang attribute and dir for RTL languages
updateHtmlAttributes(langCode);
diff --git a/static/js/core/modal.js b/static/js/core/modal.js
index 6735c2ae..016f623d 100644
--- a/static/js/core/modal.js
+++ b/static/js/core/modal.js
@@ -108,16 +108,15 @@ const Modal = {
this.input.placeholder = placeholder;
this.input.value = value;
- // Set button text (use i18n if available)
if (confirmText) {
this.confirmBtn.textContent = confirmText;
- } else if (i18n) {
+ } else {
this.confirmBtn.textContent = i18n.t('actions.confirm');
}
if (cancelText) {
this.cancelBtn.textContent = cancelText;
- } else if (i18n) {
+ } else {
this.cancelBtn.textContent = i18n.t('actions.cancel');
}
@@ -138,14 +137,12 @@ const Modal = {
* @returns {Promise}
*/
promptNewFolder() {
- const t = i18n ? i18n.t.bind(i18n) : (k) => k;
-
return this.prompt({
- title: t('dialogs.new_folder_title') || 'New folder',
- label: t('dialogs.folder_name') || 'Folder name',
- placeholder: t('dialogs.folder_placeholder') || 'My folder',
+ title: i18n.t('dialogs.new_folder_title'),
+ label: i18n.t('dialogs.folder_name'),
+ placeholder: i18n.t('dialogs.folder_placeholder'),
icon: 'fa-folder-plus',
- confirmText: t('actions.create') || 'Create'
+ confirmText: i18n.t('actions.create')
});
},
@@ -156,18 +153,15 @@ const Modal = {
* @returns {Promise}
*/
promptRename(currentName, isFolder = false) {
- const t = i18n ? i18n.t.bind(i18n) : (k) => k;
-
- // For files, we want to select only the name part (without extension)
this._selectNameOnly = !isFolder;
return this.prompt({
- title: t('dialogs.rename_title') || 'Renombrar',
- label: t('dialogs.new_name') || 'Nuevo nombre',
+ title: i18n.t('dialogs.rename_title'),
+ label: i18n.t('dialogs.new_name'),
placeholder: '',
value: currentName,
icon: isFolder ? 'fa-folder' : 'fa-file',
- confirmText: t('actions.rename') || 'Renombrar'
+ confirmText: i18n.t('actions.rename')
});
},
diff --git a/static/js/core/notifications.js b/static/js/core/notifications.js
index 59878ee6..4fe484b8 100644
--- a/static/js/core/notifications.js
+++ b/static/js/core/notifications.js
@@ -149,9 +149,8 @@ const notifications = (() => {
item.className = 'notif-item';
item.id = batchId;
- const t = i18n?.t || ((k) => k);
- const uploadingText = folderName ? `📁 ${t('upload.uploading')} ${_esc(folderName)}…` : t('upload.uploading');
- const filesLabel = t('upload.files');
+ const uploadingText = folderName ? `📁 ${i18n.t('upload.uploading')} ${_esc(folderName)}…` : i18n.t('upload.uploading');
+ const filesLabel = i18n.t('upload.files');
item.innerHTML = `
@@ -254,8 +253,7 @@ const notifications = (() => {
const pctEl = $(`${batchId}-pct`);
const statsEl = $(`${batchId}-stats`);
- const t = i18n?.t || ((k) => k);
- const filesLabel = t('upload.files');
+ const filesLabel = i18n.t('upload.files');
if (fillEl) fillEl.style.width = `${pctVal}%`;
if (pctEl) pctEl.textContent = `${pctVal}%`;
@@ -282,8 +280,7 @@ const notifications = (() => {
const curEl = $(`${batchId}-current`);
if (curEl) curEl.textContent = '';
- const t = i18n?.t || ((k) => k);
- const completeText = t('upload.complete', {
+ const completeText = i18n.t('upload.complete', {
count: successCount,
total: totalFiles
});
diff --git a/static/js/features/auth/auth.js b/static/js/features/auth/auth.js
index 30c424f8..122ace65 100644
--- a/static/js/features/auth/auth.js
+++ b/static/js/features/auth/auth.js
@@ -511,10 +511,7 @@ function initLanguageSelector() {
localStorage.setItem(LOCALE_KEY, selectedLanguage);
localStorage.setItem(FIRST_RUN_KEY, 'true');
- // Update i18n if available
- if (i18n?.setLocale) {
- await i18n.setLocale(selectedLanguage);
- }
+ await i18n.setLocale(selectedLanguage);
// Hide language panel
hidePanel(languagePanel);
@@ -635,7 +632,7 @@ async function configureOidcLoginUI() {
// Update button text with provider name
const btnTextEl = oidcBtn.querySelector('span');
if (btnTextEl && oidcInfo.provider_name) {
- const template = i18n?.t ? i18n.t('auth.sso_login_provider') : 'Sign in with {{provider}}';
+ const template = i18n.t('auth.sso_login_provider');
btnTextEl.textContent = template.replace('{{provider}}', oidcInfo.provider_name);
}
@@ -942,8 +939,7 @@ if (isLoginPage && registerForm) {
// Validate passwords match
if (password !== confirmPassword) {
- const errorMsg = i18n ? i18n.t('auth.passwords_mismatch') : 'Passwords do not match';
- registerError.textContent = errorMsg;
+ registerError.textContent = i18n.t('auth.passwords_mismatch');
registerError.style.display = 'block';
return;
}
@@ -951,9 +947,7 @@ if (isLoginPage && registerForm) {
try {
await register(username, email, password);
- // Show success message
- const successMsg = i18n ? i18n.t('auth.account_success') : 'Account created successfully! You can now log in.';
- registerSuccess.textContent = successMsg;
+ registerSuccess.textContent = i18n.t('auth.account_success');
registerSuccess.style.display = 'block';
// Clear form
@@ -965,8 +959,7 @@ if (isLoginPage && registerForm) {
hidePanel(registerPanel);
}, 2000);
} catch (error) {
- const errorMsg = i18n ? i18n.t('auth.admin_create_error') : 'Error registering account';
- registerError.textContent = error.message || errorMsg;
+ registerError.textContent = error.message || i18n.t('auth.admin_create_error');
registerError.style.display = 'block';
}
});
@@ -988,8 +981,7 @@ if (isLoginPage && adminSetupForm) {
// Validate passwords match
if (password !== confirmPassword) {
- const errorMsg = i18n ? i18n.t('auth.passwords_mismatch') : 'Passwords do not match';
- adminSetupError.textContent = errorMsg;
+ adminSetupError.textContent = i18n.t('auth.passwords_mismatch');
adminSetupError.style.display = 'block';
return;
}
@@ -1012,11 +1004,8 @@ if (isLoginPage && adminSetupForm) {
}
await response.json();
- // Show success message in the GUI instead of alert
- const successMsg = i18n ? i18n.t('auth.admin_success') : 'Admin account created successfully! You can now log in.';
-
if (adminSetupSuccess) {
- adminSetupSuccess.textContent = successMsg;
+ adminSetupSuccess.textContent = i18n.t('auth.admin_success');
adminSetupSuccess.style.display = 'block';
}
@@ -1027,8 +1016,7 @@ if (isLoginPage && adminSetupForm) {
if (adminSetupSuccess) adminSetupSuccess.style.display = 'none';
}, 2000);
} catch (error) {
- const errorMsg = i18n ? i18n.t('auth.admin_create_error') : 'Error creating admin account';
- adminSetupError.textContent = error.message || errorMsg;
+ adminSetupError.textContent = error.message || i18n.t('auth.admin_create_error');
adminSetupError.style.display = 'block';
}
});
diff --git a/static/js/features/files/contextMenus.js b/static/js/features/files/contextMenus.js
index d95218b6..f322d365 100644
--- a/static/js/features/files/contextMenus.js
+++ b/static/js/features/files/contextMenus.js
@@ -27,7 +27,7 @@ const contextMenus = {
if (!option) return;
const label = option.querySelector('span');
if (!label) return;
- label.textContent = i18n ? i18n.t(isFavorite ? 'actions.unfavorite' : 'actions.favorite') : isFavorite ? 'Remove from favorites' : 'Add to favorites';
+ label.textContent = i18n.t(isFavorite ? 'actions.unfavorite' : 'actions.favorite');
},
/**
@@ -382,7 +382,7 @@ const contextMenus = {
renameInput.value = folder.name;
// Update header text
const headerSpan = renameDialog.querySelector('.rename-dialog-header span');
- if (headerSpan) headerSpan.textContent = i18n ? i18n.t('dialogs.rename_folder') : 'Rename folder';
+ if (headerSpan) headerSpan.textContent = i18n.t('dialogs.rename_folder');
renameDialog?.classList.remove('hidden');
renameInput.focus();
renameInput.select();
@@ -402,7 +402,7 @@ const contextMenus = {
renameInput.value = file.name;
// Update header text
const headerSpan = renameDialog.querySelector('.rename-dialog-header span');
- if (headerSpan) headerSpan.textContent = i18n ? i18n.t('dialogs.rename_file') : 'Rename file';
+ if (headerSpan) headerSpan.textContent = i18n.t('dialogs.rename_file');
renameDialog?.classList.remove('hidden');
renameInput.focus();
renameInput.select();
@@ -471,7 +471,7 @@ const contextMenus = {
// Update dialog title (preserve icon)
const dialogHeader = document.getElementById('move-file-dialog').querySelector('.rename-dialog-header');
- const titleText = mode === 'file' ? (i18n ? i18n.t('dialogs.move_file') : 'Move file') : i18n ? i18n.t('dialogs.move_folder') : 'Move folder';
+ const titleText = mode === 'file' ? i18n.t('dialogs.move_file') : i18n.t('dialogs.move_folder');
dialogHeader.innerHTML = ` ${titleText}`;
// Load folders for the starting location
@@ -496,7 +496,7 @@ const contextMenus = {
async renameItem() {
const newName = document.getElementById('rename-input').value.trim();
if (!newName) {
- alert(i18n ? i18n.t('errors.empty_name') : 'Name cannot be empty');
+ alert(i18n.t('errors.empty_name'));
return;
}
@@ -587,7 +587,7 @@ const contextMenus = {
currentFolderOption.className = 'folder-select-item folder-select-current';
currentFolderOption.innerHTML = `
- ${i18n ? i18n.t('dialogs.select_this_folder') : 'Select this folder'}
+ ${i18n.t('dialogs.select_this_folder')}
`;
currentFolderOption.addEventListener('click', () => {
document.querySelectorAll('.folder-select-item').forEach((item) => {
@@ -606,7 +606,7 @@ const contextMenus = {
parentOption.className = 'folder-select-item folder-navigate-up';
parentOption.innerHTML = `
- ${i18n ? i18n.t('dialogs.go_to_parent') : '.. (parent folder)'}
+ ${i18n.t('dialogs.go_to_parent')}
`;
parentOption.addEventListener('click', () => {
// Navigate to parent folder
@@ -664,7 +664,7 @@ const contextMenus = {
homeOption.className = 'folder-select-item folder-select-current';
homeOption.innerHTML = `
- ${i18n ? i18n.t('dialogs.move_to_home') : 'Move to Home folder'}
+ ${i18n.t('dialogs.move_to_home')}
`;
homeOption.addEventListener('click', () => {
document.querySelectorAll('.folder-select-item').forEach((item) => {
@@ -678,7 +678,7 @@ const contextMenus = {
// Inside a subfolder with no children - show empty message
const emptyMsg = document.createElement('div');
emptyMsg.className = 'folder-select-empty';
- emptyMsg.innerHTML = ` ${i18n ? i18n.t('dialogs.no_subfolders') : 'No subfolders to navigate'}`;
+ emptyMsg.innerHTML = ` ${i18n.t('dialogs.no_subfolders')}`;
folderSelectContainer.appendChild(emptyMsg);
}
@@ -686,9 +686,7 @@ const contextMenus = {
app.selectedTargetFolderId = parentFolderId || '';
// Translate new elements
- if (i18n?.translateElement) {
- i18n.translateElement(folderSelectContainer);
- }
+ i18n.translateElement(folderSelectContainer);
} catch (error) {
console.error('Error loading folders:', error);
}
@@ -798,8 +796,7 @@ const contextMenus = {
const dialogHeader = shareDialog.querySelector('.share-dialog-header');
if (dialogHeader) {
const headerSpan = dialogHeader.querySelector('span');
- const titleText =
- itemType === 'file' ? (i18n ? i18n.t('dialogs.share_file') : 'Share file') : i18n ? i18n.t('dialogs.share_folder') : 'Share folder';
+ const titleText = itemType === 'file' ? i18n.t('dialogs.share_file') : i18n.t('dialogs.share_folder');
if (headerSpan) {
headerSpan.textContent = titleText;
} else {
@@ -900,9 +897,9 @@ const contextMenus = {
const shareId = btn.getAttribute('data-share-id');
showConfirmDialog({
- title: i18n ? i18n.t('dialogs.confirm_delete_share') : 'Delete link',
- message: i18n ? i18n.t('dialogs.confirm_delete_share_msg') : 'Are you sure you want to delete this shared link?',
- confirmText: i18n ? i18n.t('actions.delete') : 'Delete'
+ title: i18n.t('dialogs.confirm_delete_share'),
+ message: i18n.t('dialogs.confirm_delete_share_msg'),
+ confirmText: i18n.t('actions.delete')
}).then(async (confirmed) => {
if (confirmed) {
await fileSharing.removeSharedLink(shareId);
@@ -997,10 +994,7 @@ const contextMenus = {
ui.setSharedVisualState(item.id, item.type, true);
// Show success message
- ui.showNotification(
- i18n ? i18n.t('notifications.link_created') : 'Link created',
- i18n ? i18n.t('notifications.share_success') : 'Shared link created successfully'
- );
+ ui.showNotification(i18n.t('notifications.link_created'), i18n.t('notifications.share_success'));
} catch (error) {
console.error('Error creating shared link:', error);
ui.showNotification('Error', error.message || 'Could not create shared link');
@@ -1088,7 +1082,7 @@ const contextMenus = {
// Update files info
if (filesInfo) {
- filesInfo.innerHTML = `${i18n ? i18n.t('music.selected_files', 'Selected:') : 'Selected:'} ${file.name}`;
+ filesInfo.innerHTML = `${i18n.t('music.selected_files')} ${file.name}`;
}
// Reset selection
@@ -1112,17 +1106,15 @@ const contextMenus = {
this._renderPlaylistSelect(container, playlists);
} catch (err) {
console.error('Error loading playlists:', err);
- container.innerHTML = `${i18n ? i18n.t('music.load_error', 'Error loading playlists') : 'Error loading playlists'}
`;
+ container.innerHTML = `${i18n.t('music.load_error')}
`;
}
},
_renderPlaylistSelect(container, playlists) {
- const t = (key, fallback) => (i18n ? i18n.t(key, fallback) : fallback);
-
container.innerHTML = '';
if (playlists.length === 0) {
- container.innerHTML = `${t('music.no_playlists', 'No playlists yet. Create one first!')}
`;
+ container.innerHTML = `${i18n.t('music.no_playlists')}
`;
return;
}
@@ -1133,7 +1125,7 @@ const contextMenus = {
item.innerHTML = `
${this._escapeHtml(playlist.name)}
- ${playlist.track_count || 0} ${t('music.tracks', 'tracks')}
+ ${playlist.track_count || 0} ${i18n.t('music.tracks')}
`;
item.addEventListener('click', () => {
@@ -1176,10 +1168,7 @@ const contextMenus = {
}
await resp.json();
- ui.showNotification(
- i18n ? i18n.t('music.added', 'Added!') : 'Added!',
- `${files.length} ${files.length === 1 ? 'track' : 'tracks'} ${i18n ? i18n.t('music.added_to_playlist', 'added to playlist') : 'added to playlist'}`
- );
+ ui.showNotification(i18n.t('music.added'), `${files.length} ${files.length === 1 ? 'track' : 'tracks'} ${i18n.t('music.added_to_playlist')}`);
this.closePlaylistDialog();
@@ -1189,7 +1178,7 @@ const contextMenus = {
}
} catch (err) {
console.error('Error adding to playlist:', err);
- ui.showNotification(i18n ? i18n.t('music.error', 'Error') : 'Error', err.message || i18n.t('music.add_error', 'Could not add tracks to playlist'));
+ ui.showNotification(i18n.t('music.error'), err.message || i18n.t('music.add_error'));
if (addBtn) addBtn.disabled = false;
}
},
diff --git a/static/js/features/files/fileOperations.js b/static/js/features/files/fileOperations.js
index 9f85102a..184c91b4 100644
--- a/static/js/features/files/fileOperations.js
+++ b/static/js/features/files/fileOperations.js
@@ -30,12 +30,12 @@ const fileOps = {
/** Start a new upload batch in the notification bell */
_initUploadToast(totalFiles, folderName) {
- this._currentBatchId = notifications ? notifications.addUploadBatch(totalFiles, folderName) : null;
+ this._currentBatchId = notifications.addUploadBatch(totalFiles, folderName);
},
/** Finalise the batch in the notification bell */
_finishUploadToast(successCount, totalFiles) {
- if (notifications && this._currentBatchId) {
+ if (this._currentBatchId) {
notifications.finishBatch(this._currentBatchId, successCount, totalFiles);
}
},
@@ -361,7 +361,7 @@ const fileOps = {
progressBar.style.width = `${(uploadedCount / totalFiles) * 100}%`;
}
// Notify bell of per-file completion
- if (notifications && batchId) {
+ if (batchId) {
try {
notifications.fileCompleted(batchId, result.ok);
} catch (e) {
@@ -383,7 +383,7 @@ const fileOps = {
});
}
if (result.isQuotaError) {
- const msg = result.errorMsg || i18n?.t('storage_quota_exceeded') || 'Storage quota exceeded';
+ const msg = result.errorMsg || i18n.t('storage_quota_exceeded');
if (notifications) {
notifications.addNotification({
icon: 'fa-exclamation-triangle',
@@ -591,7 +591,7 @@ const fileOps = {
console.warn(`[SKIP] #${idx} ${rel} — cannot read 0-byte file (FIFO/pipe?), skipping`);
uploadedCount++;
successCount++;
- if (notifications && batchId) {
+ if (batchId) {
try {
notifications.fileCompleted(batchId, true);
} catch (_) {}
@@ -623,7 +623,7 @@ const fileOps = {
uploadedCount++;
- if (notifications && batchId) {
+ if (batchId) {
try {
notifications.fileCompleted(batchId, result.ok);
} catch (_) {}
@@ -994,10 +994,7 @@ const fileOps = {
console.log('Response status:', response.status);
if (response.ok) {
- ui.showNotification(
- i18n ? i18n.t('notifications.file_renamed') : 'File renamed',
- i18n ? i18n.t('notifications.file_renamed_to', { name: newName }) : `File renamed to "${newName}"`
- );
+ ui.showNotification(i18n.t('notifications.file_renamed'), i18n.t('notifications.file_renamed_to', { name: newName }));
return true;
} else {
const errorText = await response.text();
@@ -1075,9 +1072,9 @@ const fileOps = {
*/
async deleteFile(fileId, fileName) {
const confirmed = await showConfirmDialog({
- title: i18n ? i18n.t('dialogs.confirm_delete') : 'Move to trash',
- message: i18n ? i18n.t('dialogs.confirm_delete_file', { name: fileName }) : `Are you sure you want to move the file "${fileName}" to trash?`,
- confirmText: i18n ? i18n.t('actions.delete') : 'Delete'
+ title: i18n.t('dialogs.confirm_delete'),
+ message: i18n.t('dialogs.confirm_delete_file', { name: fileName }),
+ confirmText: i18n.t('actions.delete')
});
if (!confirmed) return false;
@@ -1123,11 +1120,9 @@ const fileOps = {
*/
async deleteFolder(folderId, folderName) {
const confirmed = await showConfirmDialog({
- title: i18n ? i18n.t('dialogs.confirm_delete') : 'Move to trash',
- message: i18n
- ? i18n.t('dialogs.confirm_delete_folder', { name: folderName })
- : `Are you sure you want to move the folder "${folderName}" and all its contents to trash?`,
- confirmText: i18n ? i18n.t('actions.delete') : 'Delete'
+ title: i18n.t('dialogs.confirm_delete'),
+ message: i18n.t('dialogs.confirm_delete_folder', { name: folderName }),
+ confirmText: i18n.t('actions.delete')
});
if (!confirmed) return false;
@@ -1234,11 +1229,9 @@ const fileOps = {
*/
async deletePermanently(trashId) {
const confirmed = await showConfirmDialog({
- title: i18n ? i18n.t('dialogs.confirm_permanent_delete') : 'Delete permanently',
- message: i18n
- ? i18n.t('dialogs.confirm_permanent_delete_msg')
- : 'Are you sure you want to permanently delete this item? This action cannot be undone.',
- confirmText: i18n ? i18n.t('actions.delete_permanently') : 'Delete permanently'
+ title: i18n.t('dialogs.confirm_permanent_delete'),
+ message: i18n.t('dialogs.confirm_permanent_delete_msg'),
+ confirmText: i18n.t('actions.delete_permanently')
});
if (!confirmed) return false;
@@ -1268,9 +1261,9 @@ const fileOps = {
*/
async emptyTrash() {
const confirmed = await showConfirmDialog({
- title: i18n ? i18n.t('dialogs.confirm_empty_trash') : 'Empty trash',
- message: i18n ? i18n.t('trash.empty_confirm') : 'Are you sure you want to empty the trash? This action will permanently delete all items.',
- confirmText: i18n ? i18n.t('actions.empty_trash') : 'Empty trash'
+ title: i18n.t('dialogs.confirm_empty_trash'),
+ message: i18n.t('trash.empty_confirm'),
+ confirmText: i18n.t('actions.empty_trash')
});
if (!confirmed) return false;
diff --git a/static/js/features/files/multiSelect.js b/static/js/features/files/multiSelect.js
index a3a4a56a..f77194cd 100644
--- a/static/js/features/files/multiSelect.js
+++ b/static/js/features/files/multiSelect.js
@@ -50,12 +50,8 @@ const multiSelect = {
// ── Helpers for i18n ────────────────────────────────────
_t(key, vars) {
- if (i18n && typeof i18n.t === 'function') {
- const val = i18n.t(key, vars);
- // If i18n returned the key itself, it's missing → fall back
- if (val && val !== key) return val;
- }
- return null;
+ const val = i18n.t(key, vars);
+ return val !== key ? val : null;
},
// ── Selection state management ──────────────────────────
diff --git a/static/js/features/library/favorites.js b/static/js/features/library/favorites.js
index 43fe53be..79ab0e31 100644
--- a/static/js/features/library/favorites.js
+++ b/static/js/features/library/favorites.js
@@ -110,10 +110,7 @@ const favorites = {
// Notify user
if (ui?.showNotification) {
- ui.showNotification(
- i18n ? i18n.t('favorites.added_title') : 'Added to favorites',
- `"${name}" ${i18n ? i18n.t('favorites.added_msg') : 'added to favorites'}`
- );
+ ui.showNotification(i18n.t('favorites.added_title'), `"${name}" ${i18n.t('favorites.added_msg')}`);
}
return true;
@@ -145,10 +142,7 @@ const favorites = {
this._cache.delete(this._cacheKey(id, type));
if (ui?.showNotification) {
- ui.showNotification(
- i18n ? i18n.t('favorites.removed_title') : 'Removed from favorites',
- `"${itemName}" ${i18n ? i18n.t('favorites.removed_msg') : 'removed from favorites'}`
- );
+ ui.showNotification(i18n.t('favorites.removed_title'), `"${itemName}" ${i18n.t('favorites.removed_msg')}`);
}
return true;
@@ -182,8 +176,8 @@ const favorites = {
if (this._cache.size === 0) {
ui.showError(`
- ${i18n ? i18n.t('favorites.empty_state') : 'No favorite items'}
- ${i18n ? i18n.t('favorites.empty_hint') : 'To mark as favorite, right-click on any file or folder'}
+ ${i18n.t('favorites.empty_state')}
+ ${i18n.t('favorites.empty_hint')}
`);
return;
}
diff --git a/static/js/features/library/music.js b/static/js/features/library/music.js
index 456ec605..a75c8d00 100644
--- a/static/js/features/library/music.js
+++ b/static/js/features/library/music.js
@@ -87,9 +87,6 @@ const musicView = {
if (!this._container) return;
// FIXME should call directly
- const t = (key, _fallback = '') => {
- return i18n.t(key);
- };
// Empty state: no playlists at all — show full-width centered onboarding
if (this.playlists.length === 0) {
@@ -98,11 +95,11 @@ const musicView = {
- ${t('music.no_playlists', 'No playlists yet')}
- ${t('music.empty_hint', 'Create your first playlist to start organizing your music')}
+ ${i18n.t('music.no_playlists')}
+ ${i18n.t('music.empty_hint')}
- ${t('music.create_playlist', 'Create Playlist')}
+ ${i18n.t('music.create_playlist')}
`;
@@ -118,8 +115,8 @@ const musicView = {