fix(main.js): add missing break in swithc/case + apply linter
This commit is contained in:
+51
-54
@@ -3,8 +3,6 @@
|
|||||||
* This file contains the core functionality, initialization and state management
|
* This file contains the core functionality, initialization and state management
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
const app = window.app;
|
const app = window.app;
|
||||||
const elements = window.appElements;
|
const elements = window.appElements;
|
||||||
|
|
||||||
@@ -96,10 +94,10 @@ const ACTIONS_BAR_TEMPLATES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} mode
|
* @param {string} mode
|
||||||
* @param {boolean} [force=false]
|
* @param {boolean} [force=false]
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function setActionsBarMode(mode, force = false) {
|
function setActionsBarMode(mode, force = false) {
|
||||||
if (!elements.actionsBar) return;
|
if (!elements.actionsBar) return;
|
||||||
@@ -202,7 +200,7 @@ function setupActionsBarDelegation() {
|
|||||||
/**
|
/**
|
||||||
* Read the application hash
|
* Read the application hash
|
||||||
*
|
*
|
||||||
* format:
|
* format:
|
||||||
*
|
*
|
||||||
* #/<section>/
|
* #/<section>/
|
||||||
*
|
*
|
||||||
@@ -217,21 +215,21 @@ function setupActionsBarDelegation() {
|
|||||||
* @returns {OxiContext}
|
* @returns {OxiContext}
|
||||||
*/
|
*/
|
||||||
function deserializeHash() {
|
function deserializeHash() {
|
||||||
let hashContext = /** type {OxiContext} */ {};
|
const hashContext = /** type {OxiContext} */ {};
|
||||||
|
|
||||||
// FIXME rename files into drive ?
|
// FIXME rename files into drive ?
|
||||||
hashContext.section = 'files';
|
hashContext.section = 'files';
|
||||||
|
|
||||||
let hash_elements = window.location.hash.split("/");
|
const hash_elements = window.location.hash.split("/");
|
||||||
|
|
||||||
let section = hash_elements[1];
|
const section = hash_elements[1];
|
||||||
|
|
||||||
// FIXME: use navigation.VIEW_FLAGS
|
// FIXME: use navigation.VIEW_FLAGS
|
||||||
if (section && ['files', 'shared', 'recent', 'favorites', 'trash', 'photos'].includes(section)) {
|
if (section && ['files', 'shared', 'recent', 'favorites', 'trash', 'photos'].includes(section)) {
|
||||||
hashContext.section = section;
|
hashContext.section = section;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hash_elements[1] == 'files' && hash_elements[2] == 'folder' && hash_elements[3] !== null) {
|
if (hash_elements[1] === 'files' && hash_elements[2] === 'folder' && hash_elements[3] !== null) {
|
||||||
hashContext.path = hash_elements[3];
|
hashContext.path = hash_elements[3];
|
||||||
|
|
||||||
if (hash_elements[4] == 'file' && hash_elements[5] !== null) {
|
if (hash_elements[4] == 'file' && hash_elements[5] !== null) {
|
||||||
@@ -244,7 +242,7 @@ function deserializeHash() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* update borwser's url/history
|
* update borwser's url/history
|
||||||
*
|
*
|
||||||
* @param {boolean} insertHistory true to change url and browser's history, false to change url only
|
* @param {boolean} insertHistory true to change url and browser's history, false to change url only
|
||||||
*/
|
*/
|
||||||
function updateHistory( insertHistory) {
|
function updateHistory( insertHistory) {
|
||||||
@@ -277,8 +275,6 @@ function updateHistory( insertHistory) {
|
|||||||
console.log(`replace history with ${historyUrl}`)
|
console.log(`replace history with ${historyUrl}`)
|
||||||
window.history.replaceState(historyData, "", historyUrl);
|
window.history.replaceState(historyData, "", historyUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -295,6 +291,7 @@ function switchSectionTo(section) {
|
|||||||
switch (section) {
|
switch (section) {
|
||||||
case "files":
|
case "files":
|
||||||
switchToFilesSection();
|
switchToFilesSection();
|
||||||
|
break;
|
||||||
|
|
||||||
case "shared":
|
case "shared":
|
||||||
switchToSharedSection();
|
switchToSharedSection();
|
||||||
@@ -328,22 +325,22 @@ function switchSectionTo(section) {
|
|||||||
function initApp() {
|
function initApp() {
|
||||||
// Cache DOM elements
|
// Cache DOM elements
|
||||||
cacheElements();
|
cacheElements();
|
||||||
|
|
||||||
// Initialize file sharing module first
|
// Initialize file sharing module first
|
||||||
if (window.fileSharing && window.fileSharing.init) {
|
if (window.fileSharing && window.fileSharing.init) {
|
||||||
window.fileSharing.init();
|
window.fileSharing.init();
|
||||||
} else {
|
} else {
|
||||||
console.warn('fileSharing module not fully initialized');
|
console.warn('fileSharing module not fully initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then create menus and dialogs after modules have initialized
|
// Then create menus and dialogs after modules have initialized
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
ui.initializeContextMenus();
|
ui.initializeContextMenus();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
// Setup event listeners
|
// Setup event listeners
|
||||||
setupEventListeners();
|
setupEventListeners();
|
||||||
|
|
||||||
// Ensure inline viewer is initialized
|
// Ensure inline viewer is initialized
|
||||||
if (!window.inlineViewer && typeof InlineViewer !== 'undefined') {
|
if (!window.inlineViewer && typeof InlineViewer !== 'undefined') {
|
||||||
try {
|
try {
|
||||||
@@ -352,7 +349,7 @@ function initApp() {
|
|||||||
console.error('Error initializing inline viewer:', e);
|
console.error('Error initializing inline viewer:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize favorites module if available
|
// Initialize favorites module if available
|
||||||
if (window.favorites && window.favorites.init) {
|
if (window.favorites && window.favorites.init) {
|
||||||
console.log('Initializing favorites module');
|
console.log('Initializing favorites module');
|
||||||
@@ -360,7 +357,7 @@ function initApp() {
|
|||||||
} else {
|
} else {
|
||||||
console.warn('Favorites module not available or not initializable');
|
console.warn('Favorites module not available or not initializable');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize recent files module if available
|
// Initialize recent files module if available
|
||||||
if (window.recent && window.recent.init) {
|
if (window.recent && window.recent.init) {
|
||||||
console.log('Initializing recent files module');
|
console.log('Initializing recent files module');
|
||||||
@@ -368,13 +365,13 @@ function initApp() {
|
|||||||
} else {
|
} else {
|
||||||
console.warn('Recent files module not available or not initializable');
|
console.warn('Recent files module not available or not initializable');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize multi-select / batch actions
|
// Initialize multi-select / batch actions
|
||||||
if (window.multiSelect && window.multiSelect.init) {
|
if (window.multiSelect && window.multiSelect.init) {
|
||||||
console.log('Initializing multi-select module');
|
console.log('Initializing multi-select module');
|
||||||
window.multiSelect.init();
|
window.multiSelect.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('authenticationDone', () => {
|
window.addEventListener('authenticationDone', () => {
|
||||||
// Check if a context was provided in the URL
|
// Check if a context was provided in the URL
|
||||||
let hashContext = deserializeHash();
|
let hashContext = deserializeHash();
|
||||||
@@ -404,7 +401,7 @@ function initApp() {
|
|||||||
console.log('Translations loaded, proceeding with authentication');
|
console.log('Translations loaded, proceeding with authentication');
|
||||||
window.checkAuthentication();
|
window.checkAuthentication();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set a timeout as a fallback in case translations take too long
|
// Set a timeout as a fallback in case translations take too long
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!window.i18n || !window.i18n.isLoaded || !window.i18n.isLoaded()) {
|
if (!window.i18n || !window.i18n.isLoaded || !window.i18n.isLoaded()) {
|
||||||
@@ -440,7 +437,7 @@ function cacheElements() {
|
|||||||
function setupUploadDropdown() {
|
function setupUploadDropdown() {
|
||||||
const uploadBtn = document.getElementById('upload-btn');
|
const uploadBtn = document.getElementById('upload-btn');
|
||||||
const menu = document.getElementById('upload-dropdown-menu');
|
const menu = document.getElementById('upload-dropdown-menu');
|
||||||
|
|
||||||
if (!uploadBtn || !menu) return;
|
if (!uploadBtn || !menu) return;
|
||||||
|
|
||||||
// Abort any previous local bindings (safe across repeated/rebuilt UI)
|
// Abort any previous local bindings (safe across repeated/rebuilt UI)
|
||||||
@@ -449,7 +446,7 @@ function setupUploadDropdown() {
|
|||||||
}
|
}
|
||||||
uploadDropdownBindingsController = new AbortController();
|
uploadDropdownBindingsController = new AbortController();
|
||||||
const signal = uploadDropdownBindingsController.signal;
|
const signal = uploadDropdownBindingsController.signal;
|
||||||
|
|
||||||
// Toggle dropdown on button click
|
// Toggle dropdown on button click
|
||||||
uploadBtn.addEventListener('click', (e) => {
|
uploadBtn.addEventListener('click', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -481,14 +478,14 @@ function setupUploadDropdown() {
|
|||||||
function setupEventListeners() {
|
function setupEventListeners() {
|
||||||
// Set up drag and drop
|
// Set up drag and drop
|
||||||
ui.setupDragAndDrop();
|
ui.setupDragAndDrop();
|
||||||
|
|
||||||
// Debounce timer for live search
|
// Debounce timer for live search
|
||||||
let searchDebounceTimer = null;
|
let searchDebounceTimer = null;
|
||||||
const SEARCH_DEBOUNCE_MS = 300;
|
const SEARCH_DEBOUNCE_MS = 300;
|
||||||
const SEARCH_MIN_CHARS = 3;
|
const SEARCH_MIN_CHARS = 3;
|
||||||
|
|
||||||
// handle history / url change
|
// handle history / url change
|
||||||
window.addEventListener("popstate", (e) => {
|
window.addEventListener("popstate", (e) => {
|
||||||
if (e.state === null) {
|
if (e.state === null) {
|
||||||
// change is from user (url explicitely change, read information from hash)
|
// change is from user (url explicitely change, read information from hash)
|
||||||
let hashContext = deserializeHash();
|
let hashContext = deserializeHash();
|
||||||
@@ -512,13 +509,13 @@ function setupEventListeners() {
|
|||||||
// Cancel any pending debounce
|
// Cancel any pending debounce
|
||||||
if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
|
if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
|
||||||
const query = elements.searchInput.value.trim();
|
const query = elements.searchInput.value.trim();
|
||||||
|
|
||||||
// In shared view, filter locally
|
// In shared view, filter locally
|
||||||
if (app.isSharedView && window.sharedView) {
|
if (app.isSharedView && window.sharedView) {
|
||||||
window.sharedView.filterAndSortItems();
|
window.sharedView.filterAndSortItems();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query) {
|
if (query) {
|
||||||
window.performSearch(query);
|
window.performSearch(query);
|
||||||
} else if (app.isSearchMode) {
|
} else if (app.isSearchMode) {
|
||||||
@@ -530,12 +527,12 @@ function setupEventListeners() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Search input — Live search (debounced, after 3+ chars)
|
// Search input — Live search (debounced, after 3+ chars)
|
||||||
elements.searchInput.addEventListener('input', () => {
|
elements.searchInput.addEventListener('input', () => {
|
||||||
if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
|
if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
|
||||||
const query = elements.searchInput.value.trim();
|
const query = elements.searchInput.value.trim();
|
||||||
|
|
||||||
if (query.length >= SEARCH_MIN_CHARS) {
|
if (query.length >= SEARCH_MIN_CHARS) {
|
||||||
searchDebounceTimer = setTimeout(() => {
|
searchDebounceTimer = setTimeout(() => {
|
||||||
window.performSearch(query);
|
window.performSearch(query);
|
||||||
@@ -550,7 +547,7 @@ function setupEventListeners() {
|
|||||||
}, SEARCH_DEBOUNCE_MS);
|
}, SEARCH_DEBOUNCE_MS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Search button
|
// Search button
|
||||||
document.getElementById('search-button').addEventListener('click', () => {
|
document.getElementById('search-button').addEventListener('click', () => {
|
||||||
if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
|
if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
|
||||||
@@ -559,14 +556,14 @@ function setupEventListeners() {
|
|||||||
window.performSearch(query);
|
window.performSearch(query);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Upload dropdown
|
// Upload dropdown
|
||||||
setupUploadDropdown();
|
setupUploadDropdown();
|
||||||
setupActionsBarDelegation();
|
setupActionsBarDelegation();
|
||||||
if (elements.actionsBar) {
|
if (elements.actionsBar) {
|
||||||
elements.actionsBar.dataset.mode = 'files';
|
elements.actionsBar.dataset.mode = 'files';
|
||||||
}
|
}
|
||||||
|
|
||||||
// File input
|
// File input
|
||||||
elements.fileInput.addEventListener('change', (e) => {
|
elements.fileInput.addEventListener('change', (e) => {
|
||||||
if (e.target.files.length > 0) {
|
if (e.target.files.length > 0) {
|
||||||
@@ -574,7 +571,7 @@ function setupEventListeners() {
|
|||||||
e.target.value = ''; // reset so same file can be re-uploaded
|
e.target.value = ''; // reset so same file can be re-uploaded
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Folder input
|
// Folder input
|
||||||
const folderInput = document.getElementById('folder-input');
|
const folderInput = document.getElementById('folder-input');
|
||||||
if (folderInput) {
|
if (folderInput) {
|
||||||
@@ -585,20 +582,20 @@ function setupEventListeners() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sidebar navigation
|
// Sidebar navigation
|
||||||
elements.navItems.forEach(item => {
|
elements.navItems.forEach(item => {
|
||||||
item.addEventListener('click', () => {
|
item.addEventListener('click', () => {
|
||||||
// Remove active class from all nav items
|
// 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
|
// Add active class to clicked item
|
||||||
item.classList.add('active');
|
item.classList.add('active');
|
||||||
let _updateHistory = true;
|
let _updateHistory = true;
|
||||||
|
|
||||||
let itemI18nKey=item.querySelector('span').getAttribute('data-i18n')
|
let itemI18nKey=item.querySelector('span').getAttribute('data-i18n')
|
||||||
switch(itemI18nKey) {
|
switch(itemI18nKey) {
|
||||||
case 'nav.shared':
|
case 'nav.shared':
|
||||||
// Switch to shared view
|
// Switch to shared view
|
||||||
switchToSharedSection();
|
switchToSharedSection();
|
||||||
break;
|
break;
|
||||||
@@ -608,7 +605,7 @@ function setupEventListeners() {
|
|||||||
switchToFavoritesSection();
|
switchToFavoritesSection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'nav.recent':
|
case 'nav.recent':
|
||||||
// Switch to recent files view
|
// Switch to recent files view
|
||||||
switchToRecentFilesSection();
|
switchToRecentFilesSection();
|
||||||
break;
|
break;
|
||||||
@@ -617,7 +614,7 @@ function setupEventListeners() {
|
|||||||
switchToPhotosSection();
|
switchToPhotosSection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'nav.trash':
|
case 'nav.trash':
|
||||||
switchToTrashSection();
|
switchToTrashSection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -625,7 +622,7 @@ function setupEventListeners() {
|
|||||||
// Use the proper switchToFilesView function which handles all UI restoration
|
// Use the proper switchToFilesView function which handles all UI restoration
|
||||||
window.switchToFilesSection();
|
window.switchToFilesSection();
|
||||||
// FIXME: because fileview handles it: need to converge code
|
// FIXME: because fileview handles it: need to converge code
|
||||||
_updateHistory = false;
|
_updateHistory = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.title = `OxiCloud: ${window.i18n.t(itemI18nKey)}`;
|
document.title = `OxiCloud: ${window.i18n.t(itemI18nKey)}`;
|
||||||
@@ -635,7 +632,7 @@ function setupEventListeners() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load saved view preference
|
// Load saved view preference
|
||||||
const savedView = localStorage.getItem('oxicloud-view');
|
const savedView = localStorage.getItem('oxicloud-view');
|
||||||
if (savedView === 'list') {
|
if (savedView === 'list') {
|
||||||
@@ -643,21 +640,21 @@ function setupEventListeners() {
|
|||||||
} else {
|
} else {
|
||||||
ui.switchToGridView();
|
ui.switchToGridView();
|
||||||
}
|
}
|
||||||
|
|
||||||
// User menu
|
// User menu
|
||||||
window.setupUserMenu();
|
window.setupUserMenu();
|
||||||
|
|
||||||
// Global events to close context menus and deselect cards
|
// Global events to close context menus and deselect cards
|
||||||
document.addEventListener('click', (e) => {
|
document.addEventListener('click', (e) => {
|
||||||
const folderMenu = document.getElementById('folder-context-menu');
|
const folderMenu = document.getElementById('folder-context-menu');
|
||||||
const fileMenu = document.getElementById('file-context-menu');
|
const fileMenu = document.getElementById('file-context-menu');
|
||||||
|
|
||||||
if (folderMenu && folderMenu.style.display === 'block' &&
|
if (folderMenu && folderMenu.style.display === 'block' &&
|
||||||
!folderMenu.contains(e.target)) {
|
!folderMenu.contains(e.target)) {
|
||||||
ui.closeContextMenu();
|
ui.closeContextMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileMenu && fileMenu.style.display === 'block' &&
|
if (fileMenu && fileMenu.style.display === 'block' &&
|
||||||
!fileMenu.contains(e.target)) {
|
!fileMenu.contains(e.target)) {
|
||||||
ui.closeFileContextMenu();
|
ui.closeFileContextMenu();
|
||||||
}
|
}
|
||||||
@@ -693,7 +690,7 @@ function updateStorageUsageDisplay(userData) {
|
|||||||
usedBytes = userData.storage_used_bytes || 0;
|
usedBytes = userData.storage_used_bytes || 0;
|
||||||
// Use == null to allow 0 (unlimited) to pass through; only default to DEFAULT_QUOTA when null/undefined
|
// Use == null to allow 0 (unlimited) to pass through; only default to DEFAULT_QUOTA when null/undefined
|
||||||
quotaBytes = userData.storage_quota_bytes == null ? DEFAULT_QUOTA : userData.storage_quota_bytes;
|
quotaBytes = userData.storage_quota_bytes == null ? DEFAULT_QUOTA : userData.storage_quota_bytes;
|
||||||
|
|
||||||
// Calculate percentage (avoid division by zero)
|
// Calculate percentage (avoid division by zero)
|
||||||
if (quotaBytes > 0) {
|
if (quotaBytes > 0) {
|
||||||
usagePercentage = Math.min(Math.round((usedBytes / quotaBytes) * 100), 100);
|
usagePercentage = Math.min(Math.round((usedBytes / quotaBytes) * 100), 100);
|
||||||
@@ -707,15 +704,15 @@ function updateStorageUsageDisplay(userData) {
|
|||||||
// Update the storage display elements
|
// Update the storage display elements
|
||||||
const storageFill = document.querySelector('.storage-fill');
|
const storageFill = document.querySelector('.storage-fill');
|
||||||
const storageInfo = document.querySelector('.storage-info');
|
const storageInfo = document.querySelector('.storage-info');
|
||||||
|
|
||||||
if (storageFill) {
|
if (storageFill) {
|
||||||
storageFill.style.width = `${usagePercentage}%`;
|
storageFill.style.width = `${usagePercentage}%`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storageInfo) {
|
if (storageInfo) {
|
||||||
// Remove data-i18n attribute to prevent i18n from overwriting our value
|
// Remove data-i18n attribute to prevent i18n from overwriting our value
|
||||||
storageInfo.removeAttribute('data-i18n');
|
storageInfo.removeAttribute('data-i18n');
|
||||||
|
|
||||||
// Use i18n if available
|
// Use i18n if available
|
||||||
if (window.i18n && window.i18n.t) {
|
if (window.i18n && window.i18n.t) {
|
||||||
storageInfo.textContent = window.i18n.t('storage.used', {
|
storageInfo.textContent = window.i18n.t('storage.used', {
|
||||||
@@ -727,7 +724,7 @@ function updateStorageUsageDisplay(userData) {
|
|||||||
storageInfo.textContent = `${usagePercentage}% used (${usedFormatted} / ${quotaFormatted})`;
|
storageInfo.textContent = `${usagePercentage}% used (${usedFormatted} / ${quotaFormatted})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Updated storage display: ${usagePercentage}% (${usedFormatted} / ${quotaFormatted})`);
|
console.log(`Updated storage display: ${usagePercentage}% (${usedFormatted} / ${quotaFormatted})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user