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
+1 -1
View File
@@ -19,7 +19,7 @@ function getCsrfToken() {
return match ? match.split('=')[1] : '';
}
// eslint-disable-next-line no-unused-vars
// biome-ignore lint/correctness/noUnusedVariables: global function
function getCsrfHeaders() {
const token = getCsrfToken();
return token ? { 'X-CSRF-Token': token } : {};
+5 -5
View File
@@ -5,7 +5,7 @@
function escapeHtml(str) {
if (typeof str !== 'string') return '';
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#039;');
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
}
function formatFileSize(bytes) {
@@ -15,7 +15,7 @@ function formatFileSize(bytes) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
return `${parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
}
/// Formats a byte count for quota display. When bytes is 0, returns "∞" (unlimited).
@@ -34,14 +34,14 @@ function formatDateTime(value) {
} else {
dateValue = new Date(value);
}
if (isNaN(dateValue.getTime())) return String(value);
return dateValue.toLocaleDateString() + ' ' + dateValue.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
if (Number.isNaN(dateValue.getTime())) return String(value);
return `${dateValue.toLocaleDateString()} ${dateValue.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
}
function formatDateShort(value) {
if (!value) return 'N/A';
const dateValue = typeof value === 'number' ? new Date(value * 1000) : new Date(value);
if (isNaN(dateValue.getTime())) return String(value);
if (Number.isNaN(dateValue.getTime())) return String(value);
return dateValue.toLocaleDateString(undefined, {
year: 'numeric',
month: 'short',
+8 -6
View File
@@ -6,7 +6,7 @@
*/
// Current locale code (default to browser locale if available, fallback to English)
let currentLocale = (navigator.language && navigator.language.substring(0, 2)) || (navigator.userLanguage && navigator.userLanguage.substring(0, 2)) || 'en';
let currentLocale = navigator.language?.substring(0, 2) || navigator.userLanguage?.substring(0, 2) || 'en';
// Supported locales (languages that have locale files on the server)
// When a locale file is not found, the system gracefully falls back to English
@@ -93,6 +93,8 @@ function getNestedValue(obj, path) {
* @param {object} params - Parameters to replace in the translation (e.g., {name: 'John'})
* @returns {string} - The translated string or the key itself if not found
*/
// biome-ignore lint/correctness/noUnusedVariables: global function
function t(key, params = {}) {
// Get translation from cache
const localeData = translations[currentLocale];
@@ -131,8 +133,8 @@ function t(key, params = {}) {
if (!value) {
// Try fallback to English
if (currentLocale !== 'en' && translations['en']) {
let fallbackValue = getNestedValue(translations['en'], key);
if (currentLocale !== 'en' && translations.en) {
let fallbackValue = getNestedValue(translations.en, key);
if (!fallbackValue) {
const aliasMap = {
@@ -143,7 +145,7 @@ function t(key, params = {}) {
};
const aliasKey = aliasMap[key];
if (aliasKey) {
fallbackValue = getNestedValue(translations['en'], aliasKey);
fallbackValue = getNestedValue(translations.en, aliasKey);
}
}
@@ -304,8 +306,8 @@ function safeT(key, params = {}) {
let value = getNestedValue(localeData, key);
// Fallback to English
if (!value && currentLocale !== 'en' && translations['en']) {
value = getNestedValue(translations['en'], key);
if (!value && currentLocale !== 'en' && translations.en) {
value = getNestedValue(translations.en, key);
}
if (!value) return key;
+6 -8
View File
@@ -10,8 +10,6 @@
* https://fontawesome.com/license/free
*/
'use strict';
// ── Icon registry ──────────────────────────────────────────────
// Each entry: [viewBox-width, svg-path-d]
// All icons use viewBox="0 0 {width} 512" and fill="currentColor".
@@ -379,7 +377,7 @@ function oxiIcon(name, extraClass) {
const entry = _ICONS[name];
if (!entry) return '';
const [w, d] = entry;
const cls = extraClass ? 'oxi-icon ' + extraClass : 'oxi-icon';
const cls = extraClass ? `oxi-icon ${extraClass}` : 'oxi-icon';
return `<svg class="${cls}" viewBox="0 0 ${w} 512" aria-hidden="true"><path fill="currentColor" d="${d}"/></svg>`;
}
@@ -423,8 +421,8 @@ function replaceIconsInElement(container) {
}
// Use outline variant if available and element uses "far"
if (isRegular && _ICONS[iconName + '-outline']) {
iconName = iconName + '-outline';
if (isRegular && _ICONS[`${iconName}-outline`]) {
iconName = `${iconName}-outline`;
}
if (!iconName || !_ICONS[iconName]) continue;
@@ -433,12 +431,12 @@ function replaceIconsInElement(container) {
// Build SVG element
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 ' + w + ' 512');
svg.setAttribute('viewBox', `0 0 ${w} 512`);
svg.setAttribute('aria-hidden', 'true');
let svgClass = 'oxi-icon';
if (isSpin) svgClass += ' oxi-icon-spin';
if (extraClasses.length) svgClass += ' ' + extraClasses.join(' ');
if (extraClasses.length) svgClass += ` ${extraClasses.join(' ')}`;
svg.setAttribute('class', svgClass);
// Copy inline style if present
@@ -479,7 +477,7 @@ window.OxiIcons = _ICONS;
}
// Observe future mutations (dynamic renders, modals, etc.)
new MutationObserver(function (mutations) {
new MutationObserver((mutations) => {
if (raf) return;
for (let i = 0; i < mutations.length; i++) {
if (mutations[i].addedNodes.length) {
+19 -20
View File
@@ -14,8 +14,6 @@
*/
const notifications = (() => {
'use strict';
/* ── state ──────────────────────────────────────────────── */
let _badgeCount = 0;
let _batchSeq = 0;
@@ -126,7 +124,7 @@ const notifications = (() => {
// If panel is closed, bump badge
const wrapper = $('notif-wrapper');
if (!wrapper || !wrapper.classList.contains('open')) {
if (!wrapper?.classList.contains('open')) {
_incrementBadge();
}
_showEmptyIfNeeded();
@@ -141,7 +139,7 @@ const notifications = (() => {
* @param {string} [folderName] root folder name (for folder uploads)
*/
function addUploadBatch(totalFiles, folderName) {
const batchId = 'batch-' + ++_batchSeq;
const batchId = `batch-${++_batchSeq}`;
const body = $('notif-panel-body');
if (!body) return batchId;
@@ -217,9 +215,9 @@ const notifications = (() => {
if (!shouldUpdate) return;
// Show just the file name being uploaded (truncate long paths)
const curEl = $(batchId + '-current');
const curEl = $(`${batchId}-current`);
if (curEl) {
const shortName = fileName.length > 50 ? '…' + fileName.slice(-49) : fileName;
const shortName = fileName.length > 50 ? `…${fileName.slice(-49)}` : fileName;
curEl.textContent = shortName;
}
batch.lastLabelFile = fileName;
@@ -228,10 +226,10 @@ const notifications = (() => {
// Update progress bar with per-file granularity:
// overall% = (completed_files + current_file_fraction) / total_files
const overallPct = Math.round(((batch.completed + pct / 100) / batch.totalFiles) * 100);
const fillEl = $(batchId + '-fill');
const pctEl = $(batchId + '-pct');
if (fillEl) fillEl.style.width = overallPct + '%';
if (pctEl) pctEl.textContent = overallPct + '%';
const fillEl = $(`${batchId}-fill`);
const pctEl = $(`${batchId}-pct`);
if (fillEl) fillEl.style.width = `${overallPct}%`;
if (pctEl) pctEl.textContent = `${overallPct}%`;
}
}
@@ -250,15 +248,15 @@ const notifications = (() => {
if (!isLast && batch.completed % 5 !== 0) return;
const pctVal = Math.round((batch.completed / batch.totalFiles) * 100);
const fillEl = $(batchId + '-fill');
const pctEl = $(batchId + '-pct');
const statsEl = $(batchId + '-stats');
const fillEl = $(`${batchId}-fill`);
const pctEl = $(`${batchId}-pct`);
const statsEl = $(`${batchId}-stats`);
const t = window.i18n?.t || ((k) => k);
const filesLabel = t('upload.files');
if (fillEl) fillEl.style.width = pctVal + '%';
if (pctEl) pctEl.textContent = pctVal + '%';
if (fillEl) fillEl.style.width = `${pctVal}%`;
if (pctEl) pctEl.textContent = `${pctVal}%`;
if (statsEl) statsEl.textContent = `${batch.completed} / ${batch.totalFiles} ${filesLabel}`;
}
@@ -269,7 +267,7 @@ const notifications = (() => {
const batch = _batches[batchId];
if (!batch) return;
const fillEl = $(batchId + '-fill');
const fillEl = $(`${batchId}-fill`);
if (fillEl) {
fillEl.style.width = '100%';
fillEl.classList.add(successCount === totalFiles ? 'done' : 'error');
@@ -279,11 +277,10 @@ const notifications = (() => {
const iconEl = batch.el.querySelector('.notif-item-icon');
// Clear the current-file label
const curEl = $(batchId + '-current');
const curEl = $(`${batchId}-current`);
if (curEl) curEl.textContent = '';
const t = window.i18n?.t || ((k) => k);
const filesLabel = t('upload.files');
const completeText = t('upload.complete', {
count: successCount,
total: totalFiles
@@ -302,7 +299,7 @@ const notifications = (() => {
// If the panel is closed, bump badge
const wrapper = $('notif-wrapper');
if (!wrapper || !wrapper.classList.contains('open')) {
if (!wrapper?.classList.contains('open')) {
_incrementBadge();
}
}
@@ -312,7 +309,9 @@ const notifications = (() => {
const body = $('notif-panel-body');
if (!body) return;
// Remove all notif-items
body.querySelectorAll('.notif-item').forEach((el) => el.remove());
body.querySelectorAll('.notif-item').forEach((el) => {
el.remove();
});
_clearBadge();
_showEmptyIfNeeded();
// automatically close notification center on clear
+3 -3
View File
@@ -1,12 +1,12 @@
// Service Worker registration — runs after page load.
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/sw.js')
.then(function () {
.then(() => {
/* registered */
})
.catch(function (err) {
.catch((err) => {
console.log('Service Worker registration failed:', err);
});
});