style: apply linter suggestions

This commit is contained in:
Edouard Vanbelle
2026-04-07 22:50:42 +02:00
parent 1ce29c101d
commit a4266a6e93
33 changed files with 444 additions and 437 deletions
+5 -3
View File
@@ -115,7 +115,7 @@ async function checkAuthentication() {
window.location.href = '/login?source=session_expired';
return;
}
} catch (err) {
} catch (_err) {
localStorage.removeItem(USER_DATA_KEY);
window.location.href = '/login?source=session_expired';
return;
@@ -128,9 +128,11 @@ async function checkAuthentication() {
console.log('No cached user data, fetching from server');
try {
const freshData = await refreshUserData();
if (freshData && freshData.username) {
if (freshData?.username) {
const userInitials = freshData.username.substring(0, 2).toUpperCase();
document.querySelectorAll('.user-avatar, .user-menu-avatar').forEach((el) => (el.textContent = userInitials));
document.querySelectorAll('.user-avatar, .user-menu-avatar').forEach((el) => {
el.textContent = userInitials;
});
window.updateStorageUsageDisplay(freshData);
resolveHomeFolder().then(() => window.loadFiles());
} else {
+8 -11
View File
@@ -35,7 +35,7 @@ async function getFolder(id) {
cache: 'no-store'
};
let folderInformations = await fetch(`/api/folders/${id}`, requestOptions);
const folderInformations = await fetch(`/api/folders/${id}`, requestOptions);
if (folderInformations.ok) {
return folderInformations.json();
} else {
@@ -67,7 +67,7 @@ async function rebuildBreadCrumb() {
while (id !== null) {
console.log(`fetching folder information for folder ${id}`);
try {
let folderInfo = await getFolder(id);
const folderInfo = await getFolder(id);
// store the Leaf which is the current folder
if (currentFolderInfo === null) {
@@ -84,7 +84,7 @@ async function rebuildBreadCrumb() {
// iterate to parent folder
id = folderInfo.parent_id;
} catch (e) {
} catch (_e) {
console.log(`Error loading information from folder ${app.currentPath}, falling back to ${app.userHomeFolderId}`);
// fallback of root
window.uiNotifications.show(
@@ -110,7 +110,6 @@ async function rebuildBreadCrumb() {
*/
async function loadFiles(options = { insertHistory: true }) {
const app = window.app;
const elements = window.appElements;
try {
console.log('Starting loadFiles() - loading files...', options);
@@ -125,7 +124,7 @@ async function loadFiles(options = { insertHistory: true }) {
window.isLoadingFiles = true;
// This to avoid blinking page, a better solution would be to put loading on an overlay and remove timeout
let loadingFiles = setTimeout(() => {
const loadingFiles = setTimeout(() => {
// display loader after few delay (will be canceled if result take less time)
window.ui.showError(`
<div class="files-loading-spinner">
@@ -139,7 +138,7 @@ async function loadFiles(options = { insertHistory: true }) {
await window.resolveHomeFolder();
}
const timestamp = new Date().getTime();
const timestamp = Math.floor(Date.now() / 1000);
await rebuildBreadCrumb();
@@ -181,7 +180,6 @@ async function loadFiles(options = { insertHistory: true }) {
if (forceRefresh) {
url += `&force_refresh=true`;
// @ts-ignore
requestOptions.headers['X-Force-Refresh'] = 'true';
console.log('Forcing complete refresh ignoring cache');
}
@@ -226,7 +224,7 @@ async function loadFiles(options = { insertHistory: true }) {
let fileFound = null;
// lookup for the given fle
for( const file of fileList) {
for (const file of fileList) {
if (file.id === window.app.viewFile) {
fileFound = file;
break;
@@ -236,14 +234,13 @@ async function loadFiles(options = { insertHistory: true }) {
if (fileFound) {
console.log(`file ${window.app.viewFile} found, calling viewer`);
await window.inlineViewer.openFile(fileFound);
}
else {
} else {
// remove file
console.log(`file ${window.app.viewFile} not found`);
window.app.viewFile = null;
// correct url/history as file is not found
window.updateHistory( false);
window.updateHistory(false);
}
}
}
+24 -20
View File
@@ -126,7 +126,7 @@ function setActionsBarMode(mode, force = false) {
elements.gridViewBtn = document.getElementById('grid-view-btn');
elements.listViewBtn = document.getElementById('list-view-btn');
if (window.i18n && window.i18n.translateElement) {
if (window.i18n?.translateElement) {
window.i18n.translateElement(elements.actionsBar);
}
@@ -231,8 +231,8 @@ function deserializeHash() {
if (hash_elements[1] === 'files' && hash_elements[2] === 'folder' && hash_elements[3] !== null) {
hashContext.path = hash_elements[3];
if (hash_elements[4] == 'file' && hash_elements[5] !== null) {
if (hash_elements[4] === 'file' && hash_elements[5] !== null) {
hashContext.file = hash_elements[5];
}
}
@@ -248,7 +248,7 @@ function deserializeHash() {
function updateHistory(insertHistory) {
const app = window.app;
let historyData = {
const historyData = {
section: app.currentSection,
id: app.currentFolder,
file: app.viewFile
@@ -261,7 +261,7 @@ function updateHistory(insertHistory) {
historyUrl = historyUrl.concat('/folder/', app.currentFolderInfo.id);
if (window.app.viewFile) {
historyUrl = historyUrl.concat('/file/', window.app.viewFile);
historyUrl = historyUrl.concat('/file/', window.app.viewFile);
}
// update title
document.title = `OxiCloud: ${app.currentFolderInfo.path}`;
@@ -325,7 +325,7 @@ function initApp() {
cacheElements();
// Initialize file sharing module first
if (window.fileSharing && window.fileSharing.init) {
if (window.fileSharing?.init) {
window.fileSharing.init();
} else {
console.warn('fileSharing module not fully initialized');
@@ -349,7 +349,7 @@ function initApp() {
}
// Initialize favorites module if available
if (window.favorites && window.favorites.init) {
if (window.favorites?.init) {
console.log('Initializing favorites module');
window.favorites.init();
} else {
@@ -357,7 +357,7 @@ function initApp() {
}
// Initialize recent files module if available
if (window.recent && window.recent.init) {
if (window.recent?.init) {
console.log('Initializing recent files module');
window.recent.init();
} else {
@@ -365,21 +365,21 @@ function initApp() {
}
// Initialize multi-select / batch actions
if (window.multiSelect && window.multiSelect.init) {
if (window.multiSelect?.init) {
console.log('Initializing multi-select module');
window.multiSelect.init();
}
window.addEventListener('authenticationDone', () => {
// Check if a context was provided in the URL
let hashContext = deserializeHash();
const hashContext = deserializeHash();
switchSectionTo(hashContext.section);
if (hashContext.section === 'files') {
if (hashContext.path) {
console.log(`init: reusing folder from hash URL: ${hashContext.path}`);
window.app.currentPath = hashContext.path;
}
if (hashContext.file !== null) {
window.app.viewFile = hashContext.file;
}
@@ -388,7 +388,7 @@ function initApp() {
});
// Wait for translations to load before checking authentication
if (window.i18n && window.i18n.isLoaded && window.i18n.isLoaded()) {
if (window.i18n?.isLoaded?.()) {
// Translations already loaded, proceed with authentication
window.checkAuthentication();
} else {
@@ -401,7 +401,7 @@ function initApp() {
// Set a timeout as a fallback in case translations take too long
setTimeout(() => {
if (!window.i18n || !window.i18n.isLoaded || !window.i18n.isLoaded()) {
if (!window.i18n?.isLoaded?.()) {
console.warn('Translations loading timeout, proceeding with authentication anyway');
window.checkAuthentication();
}
@@ -451,7 +451,9 @@ function setupUploadDropdown() {
e.stopPropagation();
const isOpen = menu.classList.contains('show');
// Close any other open dropdowns
document.querySelectorAll('.upload-dropdown-menu.show').forEach((m) => m.classList.remove('show'));
document.querySelectorAll('.upload-dropdown-menu.show').forEach((m) => {
m.classList.remove('show');
});
if (!isOpen) {
menu.classList.add('show');
}
@@ -462,14 +464,14 @@ function setupUploadDropdown() {
// Close dropdown when clicking outside
// remove+add stable handler: guarantees exactly one global listener
if (uploadDropdownDocumentClickHandler) {
// @ts-ignore
document.removeEventListener('click', uploadDropdownDocumentClickHandler);
}
uploadDropdownDocumentClickHandler = (e) => {
if (e.target.closest('#upload-dropdown')) return;
document.querySelectorAll('.upload-dropdown-menu.show').forEach((m) => m.classList.remove('show'));
document.querySelectorAll('.upload-dropdown-menu.show').forEach((m) => {
m.classList.remove('show');
});
};
// @ts-ignore
document.addEventListener('click', uploadDropdownDocumentClickHandler);
}
@@ -587,13 +589,15 @@ function setupEventListeners() {
elements.navItems.forEach((item) => {
item.addEventListener('click', () => {
// Remove active class from all nav items
elements.navItems.forEach((navItem) => navItem.classList.remove('active'));
elements.navItems.forEach((navItem) => {
navItem.classList.remove('active');
});
// Add active class to clicked item
item.classList.add('active');
let _updateHistory = true;
let itemI18nKey = item.querySelector('span').getAttribute('data-i18n');
const itemI18nKey = item.querySelector('span').getAttribute('data-i18n');
switch (itemI18nKey) {
case 'nav.shared':
// Switch to shared view
@@ -712,7 +716,7 @@ function updateStorageUsageDisplay(userData) {
storageInfo.removeAttribute('data-i18n');
// Use i18n if available
if (window.i18n && window.i18n.t) {
if (window.i18n?.t) {
storageInfo.textContent = window.i18n.t('storage.used', {
percentage: usagePercentage,
used: usedFormatted,
+1 -1
View File
@@ -127,7 +127,7 @@ function getSectionFromNavItem(navItem) {
* @returns {boolean} true if the section changed
*/
function setCurrentSection(section) {
if (window.app.currentSection == section) return false;
if (window.app.currentSection === section) return false;
// Set all view flags - true for active section, false for others
Object.entries(VIEW_FLAGS).forEach(([key, flag]) => {
+1 -1
View File
@@ -42,7 +42,7 @@ async function performSearch(query, sortBy) {
document.addEventListener('search-resort', (e) => {
const searchInput = document.querySelector('.search-container input');
if (searchInput && searchInput.value.trim()) {
if (searchInput?.value.trim()) {
performSearch(searchInput.value.trim(), e.detail.sort_by);
}
});
+3 -3
View File
@@ -8,7 +8,7 @@ async function loadTrashItems() {
try {
if (window.multiSelect) window.multiSelect.clear();
window.ui.resetFilesList(); // ensure also list visible & error hidden
const _tt = window.i18n && window.i18n.t ? window.i18n.t : (k) => k.split('.').pop();
const _tt = window.i18n?.t ? window.i18n.t : (k) => k.split('.').pop();
elements.filesList.innerHTML = `
<div class="list-header trash-header">
<div data-i18n="files.name">${_tt('files.name')}</div>
@@ -53,8 +53,8 @@ function addTrashItemToView(item) {
iconClass = item.icon_class || 'fas fa-folder';
typeLabel = window.i18n ? window.i18n.t('files.file_types.folder') : 'Folder';
} else {
iconClass = item.icon_class || (window.ui && window.ui.getIconClass ? window.ui.getIconClass(item.name) : 'fas fa-file');
iconSpecialClass = window.ui && window.ui.getIconSpecialClass ? window.ui.getIconSpecialClass(item.name) : '';
iconClass = item.icon_class || (window.ui?.getIconClass ? window.ui.getIconClass(item.name) : 'fas fa-file');
iconSpecialClass = window.ui?.getIconSpecialClass ? window.ui.getIconSpecialClass(item.name) : '';
const cat = item.category || '';
typeLabel = cat
? window.i18n
+54 -56
View File
@@ -359,7 +359,7 @@ const ui = {
// First try directory-aware extraction (Finder folder drag & drop)
const droppedEntries = await collectDroppedEntries(e.dataTransfer);
if (droppedEntries && droppedEntries.length > 0) {
const hasFolderStructure = droppedEntries.some((x) => x.relativePath && x.relativePath.includes('/'));
const hasFolderStructure = droppedEntries.some((x) => x.relativePath?.includes('/'));
if (hasFolderStructure) {
fileOps.uploadFolderEntries(droppedEntries);
} else {
@@ -372,7 +372,7 @@ const ui = {
}
// Detect folder drops: files from folder drops have webkitRelativePath set
const hasRelativePaths = Array.from(e.dataTransfer.files).some((f) => f.webkitRelativePath && f.webkitRelativePath.includes('/'));
const hasRelativePaths = Array.from(e.dataTransfer.files).some((f) => f.webkitRelativePath?.includes('/'));
if (hasRelativePaths) {
fileOps.uploadFolderFiles(e.dataTransfer.files);
} else {
@@ -415,7 +415,7 @@ const ui = {
// First try directory-aware extraction (Finder folder drag & drop)
const droppedEntries = await collectDroppedEntries(e.dataTransfer);
if (droppedEntries && droppedEntries.length > 0) {
const hasFolderStructure = droppedEntries.some((x) => x.relativePath && x.relativePath.includes('/'));
const hasFolderStructure = droppedEntries.some((x) => x.relativePath?.includes('/'));
if (hasFolderStructure) {
fileOps.uploadFolderEntries(droppedEntries);
} else {
@@ -428,7 +428,7 @@ const ui = {
}
// Detect folder drops: files from folder drops have webkitRelativePath set
const hasRelativePaths = Array.from(e.dataTransfer.files).some((f) => f.webkitRelativePath && f.webkitRelativePath.includes('/'));
const hasRelativePaths = Array.from(e.dataTransfer.files).some((f) => f.webkitRelativePath?.includes('/'));
if (hasRelativePaths) {
fileOps.uploadFolderFiles(e.dataTransfer.files);
} else {
@@ -474,13 +474,11 @@ const ui = {
updateBreadcrumb() {
const breadcrumb = document.querySelector('.breadcrumb');
breadcrumb.innerHTML = '';
const self = this;
const path = window.app.breadcrumbPath; // [{id, name}, ...]
// Helper function to safely get translation text
const getTranslatedText = (key, defaultValue) => {
if (!window.i18n || !window.i18n.t) return defaultValue;
if (!window.i18n?.t) return defaultValue;
return window.i18n.t(key);
};
@@ -496,7 +494,7 @@ const ui = {
homeIcon.addEventListener('click', () => {
window.app.breadcrumbPath = [];
window.app.currentPath = window.app.userHomeFolderId;
self.updateBreadcrumb();
this.updateBreadcrumb();
window.loadFiles();
});
}
@@ -535,7 +533,7 @@ const ui = {
item.addEventListener('click', () => {
window.app.breadcrumbPath = path.slice(0, index + 1);
window.app.currentPath = segment.id;
self.updateBreadcrumb();
this.updateBreadcrumb();
window.loadFiles();
});
@@ -543,7 +541,7 @@ const ui = {
// dragover – only folders are valid drop targets
item.addEventListener('dragover', (e) => {
const card = e.target.closest('span');
if (!card || !card.dataset.folderId) return;
if (!card?.dataset.folderId) return;
e.preventDefault();
card.classList.add('drop-target');
});
@@ -552,7 +550,7 @@ const ui = {
item.addEventListener('dragleave', (e) => {
console.log('dragleave ', e);
const card = e.target.closest('span');
if (!card || !card.dataset.folderId) return;
if (!card?.dataset.folderId) return;
card.classList.remove('drop-target');
});
@@ -567,7 +565,7 @@ const ui = {
card.classList.remove('drop-target');
const action = e.dataTransfer?.dropEffect;
await self._dropToFolder(action, targetFolderId, e.dataTransfer);
await this._dropToFolder(action, targetFolderId, e.dataTransfer);
});
} else {
// Last segment: current location, not clickable
@@ -693,7 +691,7 @@ const ui = {
},
_upsertById(arr, item) {
if (!Array.isArray(arr) || !item || !item.id) return;
if (!Array.isArray(arr) || !item?.id) return;
const idx = arr.findIndex((x) => x && x.id === item.id);
if (idx >= 0) {
arr[idx] = item;
@@ -709,11 +707,11 @@ const ui = {
* @param {any} dataTransfer fallback if nothing is selected
*/
async _dropToFolder(action, targetFolderId, dataTransfer) {
let selection = window.multiSelect.getSelection(targetFolderId);
const selection = window.multiSelect.getSelection(targetFolderId);
window.multiSelect.clear();
if (selection.fileIds.length == 0 && selection.folderIds.length == 0) {
if (selection.fileIds.length === 0 && selection.folderIds.length === 0) {
// try to use dataTransfer (direct move without selection)
const id = dataTransfer.getData('text/plain');
const isFolder = dataTransfer.getData('application/oxicloud-folder') === 'true';
@@ -785,8 +783,6 @@ const ui = {
if (!filesList) return;
this._delegationReady = true;
const self = this;
// ── helpers ────────────────────────────────────────────────
const itemInfo = (card) => {
if (!card) return null;
@@ -796,7 +792,7 @@ const ui = {
type: 'file',
id: fileId,
name: card.dataset.fileName,
data: self._items.get(fileId)
data: this._items.get(fileId)
};
const folderId = card.dataset.folderId;
if (folderId)
@@ -804,7 +800,7 @@ const ui = {
type: 'folder',
id: folderId,
name: card.dataset.folderName,
data: self._items.get(folderId)
data: this._items.get(folderId)
};
return null;
};
@@ -818,25 +814,23 @@ const ui = {
// But NOT image files - those should be previewed in the inline viewer
const ext = (file.name || '').split('.').pop().toLowerCase();
const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'bmp', 'ico', 'heic', 'heif', 'avif', 'tiff'];
const isImage = (file.mime_type && file.mime_type.startsWith('image/')) || imageExts.includes(ext);
const isImage = file.mime_type?.startsWith('image/') || imageExts.includes(ext);
try {
if (!isImage && window.wopiEditor && await window.wopiEditor.canEdit(file.name)) {
await window.wopiEditor.openInModal(file.id, file.name, 'edit')
if (!isImage && window.wopiEditor && (await window.wopiEditor.canEdit(file.name))) {
await window.wopiEditor.openInModal(file.id, file.name, 'edit');
return;
}
}
catch (e) {
} catch (e) {
console.warn(`WOPI Editor failed, falling bck to classic view `, e);
}
if (self.isViewableFile(file) || isImage) {
if (this.isViewableFile(file) || isImage) {
if (window.inlineViewer) {
window.inlineViewer.openFile(file);
// update history
window.app.viewFile = file.id;
window.updateHistory(false);
}
else {
} else {
window.fileOps.downloadFile(file.id, file.name);
}
} else {
@@ -849,7 +843,7 @@ const ui = {
const folderName = card.dataset.folderName;
window.app.breadcrumbPath.push({ id: folderId, name: folderName });
window.app.currentPath = folderId;
self.updateBreadcrumb();
this.updateBreadcrumb();
window.loadFiles();
};
@@ -940,7 +934,7 @@ const ui = {
window.contextMenus.syncFavoriteOptionLabels();
}
if (window.contextMenus && typeof window.contextMenus.syncWopiOptionVisibility === 'function') {
window.contextMenus.syncWopiOptionVisibility().catch(function () {});
window.contextMenus.syncWopiOptionVisibility().catch(() => {});
}
menu.style.left = `${e.pageX}px`;
menu.style.top = `${e.pageY}px`;
@@ -949,7 +943,7 @@ const ui = {
// dragstart
filesList.addEventListener('dragstart', (e) => {
let card = e.target.closest('.file-item');
const card = e.target.closest('.file-item');
if (!card) {
e.preventDefault();
return;
@@ -968,11 +962,11 @@ const ui = {
// allow copy or move (handled by the browser)
e.dataTransfer.effectAllowed = 'copyMove';
self.draggedItems = document.createElement('div');
self.draggedItems.className = 'dragged-items';
this.draggedItems = document.createElement('div');
this.draggedItems.className = 'dragged-items';
let selectedCardFromList = filesList.querySelectorAll(`div.selected > div.name-cell`);
if (selectedCardFromList.length == 0) {
if (selectedCardFromList.length === 0) {
// fallback to current element
selectedCardFromList = card.querySelectorAll('div.name-cell');
}
@@ -982,8 +976,8 @@ const ui = {
let lastItemDiv = null;
while (index < selectedCardFromList.length && index < maxElements) {
let iconCell = document.createElement('div');
let icon = selectedCardFromList[index].getElementsByClassName('file-icon').item(0)?.cloneNode(true);
const iconCell = document.createElement('div');
const icon = selectedCardFromList[index].getElementsByClassName('file-icon').item(0)?.cloneNode(true);
if (icon) {
iconCell.appendChild(icon);
iconCell.querySelectorAll('img')?.forEach((img) => {
@@ -991,28 +985,28 @@ const ui = {
});
}
let nameCell = document.createElement('div');
let name = selectedCardFromList[index].getElementsByTagName('span').item(0)?.cloneNode(true);
const nameCell = document.createElement('div');
const name = selectedCardFromList[index].getElementsByTagName('span').item(0)?.cloneNode(true);
if (name) {
nameCell.appendChild(name);
}
let div = document.createElement('div');
const div = document.createElement('div');
div.className = 'file-item';
div.appendChild(iconCell);
div.appendChild(nameCell);
self.draggedItems.appendChild(div);
this.draggedItems.appendChild(div);
index += 1;
lastItemDiv = div;
}
// if more than 1 item, display the badge
if (selectedCardFromList.length > 1) {
let badge = document.createElement('span');
const badge = document.createElement('span');
badge.className = 'dragged-items-badge';
badge.innerText = `${selectedCardFromList.length}`;
self.draggedItems.appendChild(badge);
this.draggedItems.appendChild(badge);
}
// if more than maxElements display the fading
@@ -1020,14 +1014,16 @@ const ui = {
lastItemDiv.classList.add('fading');
}
self.dragPreview.appendChild(self.draggedItems);
e.dataTransfer.setDragImage(self.draggedItems, 0, 0);
this.dragPreview.appendChild(this.draggedItems);
e.dataTransfer.setDragImage(this.draggedItems, 0, 0);
});
// dragend
filesList.addEventListener('dragend', (e) => {
self.dragPreview.removeChild(self.draggedItems);
document.querySelectorAll('.drop-target').forEach((el) => el.classList.remove('drop-target'));
filesList.addEventListener('dragend', (_e) => {
this.dragPreview.removeChild(this.draggedItems);
document.querySelectorAll('.drop-target').forEach((el) => {
el.classList.remove('drop-target');
});
});
// dragover – only folders are valid drop targets
@@ -1057,7 +1053,7 @@ const ui = {
card.classList.remove('drop-target');
const action = e.dataTransfer.dropEffect;
await self._dropToFolder(action, targetFolderId, e.dataTransfer);
await this._dropToFolder(action, targetFolderId, e.dataTransfer);
});
},
@@ -1111,8 +1107,8 @@ const ui = {
// SVG icon path (after icons.js replacement)
const svg = starBtn.querySelector('svg');
const filledPath = window.OxiIcons && window.OxiIcons['star'];
const outlinePath = window.OxiIcons && window.OxiIcons['star-outline'];
const filledPath = window.OxiIcons?.star;
const outlinePath = window.OxiIcons?.['star-outline'];
const targetPath = isFavorite ? filledPath : outlinePath;
if (svg && targetPath) {
const p = svg.querySelector('path');
@@ -1159,7 +1155,7 @@ const ui = {
el.dataset.folderName = folder.name;
el.dataset.parentId = folder.parent_id || '';
const isFav = window.favorites && window.favorites.isFavorite(folder.id, 'folder');
const isFav = window.favorites?.isFavorite(folder.id, 'folder');
const formattedDate = window.formatDateTime(folder.modified_at);
el.innerHTML = `
@@ -1203,7 +1199,7 @@ const ui = {
: 'Document';
const fileSize = file.size_formatted || window.formatFileSize(file.size);
const formattedDate = window.formatDateTime(file.modified_at);
const isFav = window.favorites && window.favorites.isFavorite(file.id, 'file');
const isFav = window.favorites?.isFavorite(file.id, 'file');
const el = document.createElement('div');
el.className = 'file-item';
@@ -1213,7 +1209,7 @@ const ui = {
el.setAttribute('draggable', 'true');
el.innerHTML = `
<div class="checkbox-cell"><input type="checkbox" class="item-checkbox"></div>
<div class="name-cell">
<div class="file-icon ${iconSpecialClass}">
@@ -1262,7 +1258,7 @@ const ui = {
<div></div><!-- actions -->
</div>`;
if (window.i18n && window.i18n.translateElement) window.i18n.translateElement(filesList);
if (window.i18n?.translateElement) window.i18n.translateElement(filesList);
filesList.classList.remove('hidden');
filesContainerError?.classList.add('hidden');
@@ -1286,7 +1282,7 @@ const ui = {
const filesList = document.getElementById('files-list');
if (filesContainerError) filesContainerError.innerHTML = content;
if (window.i18n && window.i18n.translateElement) window.i18n.translateElement(filesContainerError);
if (window.i18n?.translateElement) window.i18n.translateElement(filesContainerError);
filesContainerError?.classList.remove('hidden');
filesList?.classList.add('hidden');
@@ -1384,7 +1380,9 @@ function toggleCardSelection(card, event) {
*/
function showContextMenuAtElement(triggerElement, menuId) {
// Hide any open menus first
document.querySelectorAll('.context-menu').forEach((m) => (m.style.display = 'none'));
document.querySelectorAll('.context-menu').forEach((m) => {
m.style.display = 'none';
});
const menu = document.getElementById(menuId);
if (!menu) return;
@@ -1406,7 +1404,7 @@ function showContextMenuAtElement(triggerElement, menuId) {
window.contextMenus.syncFavoriteOptionLabels();
}
if (window.contextMenus && typeof window.contextMenus.syncWopiOptionVisibility === 'function') {
window.contextMenus.syncWopiOptionVisibility().catch(function () {});
window.contextMenus.syncWopiOptionVisibility().catch(() => {});
}
menu.style.left = `${left}px`;
+1 -1
View File
@@ -6,7 +6,7 @@
const uiFileTypes = {
// TODO: 'd better to use a canViw() method in inlineViewer
isViewableFile(file) {
if (!file || !file.mime_type) return false;
if (!file?.mime_type) return false;
if (file.mime_type.startsWith('image/')) return true;
if (file.mime_type === 'application/pdf') return true;
if (file.mime_type.startsWith('audio/')) return true;
+4 -4
View File
@@ -171,7 +171,7 @@ function updateUserMenuData() {
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;
if (storageFill) storageFill.style.width = percentage + '%';
if (storageFill) storageFill.style.width = `${percentage}%`;
if (storageText) {
const used = window.formatFileSize(usedBytes);
const total = window.formatQuotaSize(quotaBytes);
@@ -206,7 +206,7 @@ function showUserProfileModal() {
const percentage = quotaBytes > 0 ? Math.min(Math.round((usedBytes / quotaBytes) * 100), 100) : 0;
const barColor = percentage > 90 ? '#ef4444' : percentage > 70 ? '#f59e0b' : '#22c55e';
const t = (key, fallback) => (window.i18n && window.i18n.t ? window.i18n.t(key) || fallback : fallback);
const t = (key, fallback) => (window.i18n?.t ? window.i18n.t(key) || fallback : fallback);
const existing = document.getElementById('profile-modal-overlay');
if (existing) existing.remove();
@@ -220,7 +220,7 @@ function showUserProfileModal() {
<div class="about-modal-avatar">${initials}</div>
<h3 class="about-modal-username">${username}</h3>
<p class="about-modal-email">${email}</p>
<span class="about-modal-role ${role === 'admin' ? 'about-modal-role-admin' : 'about-modal-role-user'}">${role === 'admin' ? '🛡️ Admin' : '👤 ' + t('user_menu.role_user', 'User')}</span>
<span class="about-modal-role ${role === 'admin' ? 'about-modal-role-admin' : 'about-modal-role-user'}">${role === 'admin' ? '🛡️ Admin' : `👤 ${t('user_menu.role_user', 'User')}`}</span>
</div>
<div class="about-modal-storage">
<div class="about-modal-storage-label">
@@ -240,7 +240,7 @@ function showUserProfileModal() {
// Set dynamic bar width and color via JS property (CSP-safe)
const barFill = overlay.querySelector('#about-bar-fill');
if (barFill) {
barFill.style.width = percentage + '%';
barFill.style.width = `${percentage}%`;
barFill.style.background = barColor;
}