adding search engine
This commit is contained in:
+200
-15
@@ -14,6 +14,7 @@ const app = {
|
||||
moveDialogMode: 'file', // Move dialog mode: 'file' or 'folder'
|
||||
isTrashView: false, // Whether we're in trash view
|
||||
currentSection: 'files', // Current section: 'files' or 'trash'
|
||||
isSearchMode: false, // Whether we're in search mode
|
||||
};
|
||||
|
||||
// DOM elements
|
||||
@@ -34,11 +35,6 @@ function initApp() {
|
||||
// Setup event listeners
|
||||
setupEventListeners();
|
||||
|
||||
// Load initial view
|
||||
app.currentPath = '';
|
||||
ui.updateBreadcrumb('');
|
||||
loadFiles();
|
||||
|
||||
// Initialize file renderer if available
|
||||
if (window.fileRenderer) {
|
||||
console.log('Using optimized file renderer');
|
||||
@@ -46,8 +42,26 @@ function initApp() {
|
||||
console.log('Using standard file rendering');
|
||||
}
|
||||
|
||||
// Check authentication
|
||||
checkAuthentication();
|
||||
// Wait for translations to load before checking authentication
|
||||
if (window.i18n && window.i18n.isLoaded && window.i18n.isLoaded()) {
|
||||
// Translations already loaded, proceed with authentication
|
||||
checkAuthentication();
|
||||
} else {
|
||||
// Wait for translations to be loaded before proceeding
|
||||
console.log('Waiting for translations to load...');
|
||||
window.addEventListener('translationsLoaded', () => {
|
||||
console.log('Translations loaded, proceeding with authentication');
|
||||
checkAuthentication();
|
||||
});
|
||||
|
||||
// Set a timeout as a fallback in case translations take too long
|
||||
setTimeout(() => {
|
||||
if (!window.i18n || !window.i18n.isLoaded || !window.i18n.isLoaded()) {
|
||||
console.warn('Translations loading timeout, proceeding with authentication anyway');
|
||||
checkAuthentication();
|
||||
}
|
||||
}, 3000); // 3 second timeout
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,6 +82,7 @@ function cacheElements() {
|
||||
elements.actionsBar = document.querySelector('.actions-bar');
|
||||
elements.navItems = document.querySelectorAll('.nav-item');
|
||||
elements.trashBtn = document.querySelector('.nav-item:nth-child(5)'); // The trash nav item
|
||||
elements.searchInput = document.querySelector('.search-container input');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,6 +92,30 @@ function setupEventListeners() {
|
||||
// Set up drag and drop
|
||||
ui.setupDragAndDrop();
|
||||
|
||||
// Search input
|
||||
elements.searchInput.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
const query = elements.searchInput.value.trim();
|
||||
if (query) {
|
||||
performSearch(query);
|
||||
} else if (app.isSearchMode) {
|
||||
// If search is empty and we're in search mode, return to normal view
|
||||
app.isSearchMode = false;
|
||||
app.currentPath = '';
|
||||
ui.updateBreadcrumb('');
|
||||
loadFiles();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Search button
|
||||
document.getElementById('search-button').addEventListener('click', () => {
|
||||
const query = elements.searchInput.value.trim();
|
||||
if (query) {
|
||||
performSearch(query);
|
||||
}
|
||||
});
|
||||
|
||||
// Upload button
|
||||
elements.uploadBtn.addEventListener('click', () => {
|
||||
elements.dropzone.style.display = elements.dropzone.style.display === 'none' ? 'block' : 'none';
|
||||
@@ -328,12 +367,17 @@ async function loadTrashItems() {
|
||||
<div class="list-header">
|
||||
<div data-i18n="files.name">Nombre</div>
|
||||
<div data-i18n="files.type">Tipo</div>
|
||||
<div data-i18n="files.original_location">Ubicación original</div>
|
||||
<div data-i18n="files.deleted_date">Fecha eliminación</div>
|
||||
<div data-i18n="files.actions">Acciones</div>
|
||||
<div data-i18n="trash.original_location">Ubicación original</div>
|
||||
<div data-i18n="trash.deleted_date">Fecha eliminación</div>
|
||||
<div data-i18n="trash.actions">Acciones</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Translate the header if i18n is available
|
||||
if (window.i18n && window.i18n.translatePage) {
|
||||
window.i18n.translatePage();
|
||||
}
|
||||
|
||||
// Update breadcrumb for trash
|
||||
ui.updateBreadcrumb(window.i18n ? window.i18n.t('nav.trash') : 'Papelera');
|
||||
|
||||
@@ -394,10 +438,10 @@ function addTrashItemToView(item) {
|
||||
<div class="file-name">${item.name}</div>
|
||||
<div class="file-info">${typeLabel} - ${formattedDate}</div>
|
||||
<div class="trash-actions">
|
||||
<button class="btn-restore" title="Restaurar">
|
||||
<button class="btn-restore" title="${window.i18n ? window.i18n.t('trash.restore') : 'Restaurar'}">
|
||||
<i class="fas fa-undo"></i>
|
||||
</button>
|
||||
<button class="btn-delete" title="Eliminar permanentemente">
|
||||
<button class="btn-delete" title="${window.i18n ? window.i18n.t('trash.delete_permanently') : 'Eliminar permanentemente'}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -438,10 +482,10 @@ function addTrashItemToView(item) {
|
||||
<div class="path-cell">${item.original_path || '--'}</div>
|
||||
<div class="date-cell">${formattedDate}</div>
|
||||
<div class="actions-cell">
|
||||
<button class="btn-restore" title="Restaurar">
|
||||
<button class="btn-restore" title="${window.i18n ? window.i18n.t('trash.restore') : 'Restaurar'}">
|
||||
<i class="fas fa-undo"></i>
|
||||
</button>
|
||||
<button class="btn-delete" title="Eliminar permanentemente">
|
||||
<button class="btn-delete" title="${window.i18n ? window.i18n.t('trash.delete_permanently') : 'Eliminar permanentemente'}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -465,11 +509,70 @@ function addTrashItemToView(item) {
|
||||
elements.filesListView.appendChild(listElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform search with the given query
|
||||
* @param {string} query - Search query
|
||||
*/
|
||||
async function performSearch(query) {
|
||||
console.log(`Performing search for: "${query}"`);
|
||||
|
||||
try {
|
||||
// Update UI to indicate search mode
|
||||
app.isSearchMode = true;
|
||||
|
||||
// Set breadcrumb for search
|
||||
ui.updateBreadcrumb(`Búsqueda: "${query}"`);
|
||||
|
||||
// Prepare search options
|
||||
const options = {
|
||||
recursive: true, // Search in all subfolders
|
||||
limit: 100 // Limit results for performance
|
||||
};
|
||||
|
||||
// Always restrict search to the user's current folder context
|
||||
// This ensures users can't search outside their personal folder
|
||||
if (!app.isTrashView) {
|
||||
// If we're in a subfolder, search from there, otherwise use the user's home folder
|
||||
options.folder_id = app.currentPath;
|
||||
|
||||
// Always include folder_id even if it's the root of user's home folder
|
||||
// so user cannot search outside their allowed scope
|
||||
if (!options.folder_id || options.folder_id === '') {
|
||||
// Fall back to user's home folder - we should never be here
|
||||
// because findUserHomeFolder should have set app.currentPath
|
||||
console.warn("Search without folder_id - this shouldn't happen with proper user context");
|
||||
|
||||
// Try to get folder from localStorage if available
|
||||
const USER_DATA_KEY = 'oxicloud_user';
|
||||
const userData = JSON.parse(localStorage.getItem(USER_DATA_KEY) || '{}');
|
||||
if (userData.username) {
|
||||
console.log("Retrieving home folder for user before search");
|
||||
await findUserHomeFolder(userData.username);
|
||||
options.folder_id = app.currentPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Searching with options:`, options);
|
||||
|
||||
// Perform the search
|
||||
const searchResults = await window.search.searchFiles(query, options);
|
||||
|
||||
// Display search results
|
||||
window.search.displaySearchResults(searchResults);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Search error:', error);
|
||||
window.ui.showNotification('Error', 'Error al realizar la búsqueda');
|
||||
}
|
||||
}
|
||||
|
||||
// Expose needed functions to global scope
|
||||
window.app = app;
|
||||
window.loadFiles = loadFiles;
|
||||
window.loadTrashItems = loadTrashItems;
|
||||
window.formatFileSize = formatFileSize;
|
||||
window.performSearch = performSearch;
|
||||
|
||||
// Set up global selectFolder function for navigation
|
||||
window.selectFolder = (id, name) => {
|
||||
@@ -479,7 +582,7 @@ window.selectFolder = (id, name) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if user is authenticated
|
||||
* Check if user is authenticated and load user's home folder
|
||||
*/
|
||||
function checkAuthentication() {
|
||||
// Nombres de variables según auth.js
|
||||
@@ -505,6 +608,88 @@ function checkAuthentication() {
|
||||
if (userAvatar) {
|
||||
userAvatar.textContent = userInitials;
|
||||
}
|
||||
|
||||
// Find and load the user's home folder
|
||||
findUserHomeFolder(userData.username);
|
||||
} else {
|
||||
// If no user data, fallback to standard load
|
||||
app.currentPath = '';
|
||||
ui.updateBreadcrumb('');
|
||||
loadFiles();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the user's home folder and load it
|
||||
* @param {string} username - The current user's username
|
||||
*/
|
||||
async function findUserHomeFolder(username) {
|
||||
try {
|
||||
console.log("Finding home folder for user:", username);
|
||||
|
||||
// First, load all folders at the root
|
||||
const response = await fetch('/api/folders');
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error loading folders: ${response.status}`);
|
||||
}
|
||||
|
||||
const folders = await response.json();
|
||||
const folderList = Array.isArray(folders) ? folders : [];
|
||||
|
||||
// Look for a folder with a name pattern that matches the user's home folder
|
||||
// Typically named "Mi Carpeta - username"
|
||||
const homeFolderPattern = `Mi Carpeta - ${username}`;
|
||||
let homeFolder = folderList.find(folder => folder.name === homeFolderPattern);
|
||||
|
||||
// If exact match not found, try a more flexible match
|
||||
if (!homeFolder) {
|
||||
homeFolder = folderList.find(folder =>
|
||||
folder.name.toLowerCase().includes(username.toLowerCase()) ||
|
||||
folder.name.startsWith('Mi Carpeta -')
|
||||
);
|
||||
}
|
||||
|
||||
if (homeFolder) {
|
||||
console.log(`Found user's home folder: ${homeFolder.name} (${homeFolder.id})`);
|
||||
|
||||
// Store the home folder ID and name in the app state
|
||||
// This is used for breadcrumb navigation and restricting user access
|
||||
app.userHomeFolderId = homeFolder.id;
|
||||
app.userHomeFolderName = homeFolder.name;
|
||||
|
||||
// Set this as the current path and load its contents
|
||||
app.currentPath = homeFolder.id;
|
||||
ui.updateBreadcrumb(homeFolder.name);
|
||||
loadFiles();
|
||||
} else {
|
||||
console.warn("Could not find user's home folder, fallback to first folder or root");
|
||||
|
||||
// If we can't find a specific home folder but there are folders,
|
||||
// use the first folder as the user's home
|
||||
if (folderList.length > 0) {
|
||||
const fallbackFolder = folderList[0];
|
||||
console.log(`Using first folder as fallback: ${fallbackFolder.name} (${fallbackFolder.id})`);
|
||||
|
||||
app.userHomeFolderId = fallbackFolder.id;
|
||||
app.userHomeFolderName = fallbackFolder.name;
|
||||
app.currentPath = fallbackFolder.id;
|
||||
ui.updateBreadcrumb(fallbackFolder.name);
|
||||
loadFiles();
|
||||
} else {
|
||||
// No folders at all - this is an edge case
|
||||
console.warn("No folders found, using root");
|
||||
app.currentPath = '';
|
||||
ui.updateBreadcrumb('');
|
||||
loadFiles();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error finding user home folder:', error);
|
||||
|
||||
// Fall back to loading root in case of error
|
||||
app.currentPath = '';
|
||||
ui.updateBreadcrumb('');
|
||||
loadFiles();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -419,7 +419,8 @@ const fileOps = {
|
||||
* @returns {Promise<boolean>} - Éxito de la operación
|
||||
*/
|
||||
async emptyTrash() {
|
||||
if (!confirm('¿Estás seguro de que quieres vaciar la papelera? Esta acción eliminará permanentemente todos los elementos y no se puede deshacer.')) {
|
||||
const confirmMsg = window.i18n ? window.i18n.t('trash.empty_confirm') : '¿Estás seguro de que quieres vaciar la papelera? Esta acción eliminará permanentemente todos los elementos.';
|
||||
if (!confirm(confirmMsg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+22
-3
@@ -227,14 +227,33 @@ function getSupportedLocales() {
|
||||
return [...supportedLocales];
|
||||
}
|
||||
|
||||
// Flag to track if translations are loaded
|
||||
let translationsLoaded = false;
|
||||
|
||||
// Initialize when DOM is ready
|
||||
document.addEventListener('DOMContentLoaded', initI18n);
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
await initI18n();
|
||||
translationsLoaded = true;
|
||||
// Dispatch an event when translations are fully loaded
|
||||
window.dispatchEvent(new Event('translationsLoaded'));
|
||||
});
|
||||
|
||||
// Improved t function with fallback for early calls
|
||||
function safeT(key, params = {}) {
|
||||
if (!translationsLoaded) {
|
||||
console.warn(`Translations for ${currentLocale} not loaded yet`);
|
||||
// Return a default value or the key depending on context
|
||||
return key.split('.').pop() || key;
|
||||
}
|
||||
return t(key, params);
|
||||
}
|
||||
|
||||
// Export functions for use in other modules
|
||||
window.i18n = {
|
||||
t,
|
||||
t: safeT,
|
||||
setLocale,
|
||||
getCurrentLocale,
|
||||
getSupportedLocales,
|
||||
translatePage
|
||||
translatePage,
|
||||
isLoaded: () => translationsLoaded
|
||||
};
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* OxiCloud - Search Module
|
||||
* This file handles search functionality for files and folders
|
||||
*/
|
||||
|
||||
const search = {
|
||||
/**
|
||||
* Perform a basic search using query string
|
||||
* @param {string} query - Search query
|
||||
* @param {Object} options - Additional search options
|
||||
* @returns {Promise<Object>} - Search results
|
||||
*/
|
||||
async searchFiles(query, options = {}) {
|
||||
try {
|
||||
// Prepare search parameters
|
||||
const params = new URLSearchParams();
|
||||
params.append('query', query);
|
||||
|
||||
// Add optional parameters
|
||||
if (options.folder_id) params.append('folder_id', options.folder_id);
|
||||
if (options.recursive !== undefined) params.append('recursive', options.recursive);
|
||||
if (options.file_types) params.append('type', options.file_types);
|
||||
if (options.min_size) params.append('min_size', options.min_size);
|
||||
if (options.max_size) params.append('max_size', options.max_size);
|
||||
if (options.created_after) params.append('created_after', options.created_after);
|
||||
if (options.created_before) params.append('created_before', options.created_before);
|
||||
if (options.modified_after) params.append('modified_after', options.modified_after);
|
||||
if (options.modified_before) params.append('modified_before', options.modified_before);
|
||||
if (options.limit) params.append('limit', options.limit);
|
||||
if (options.offset) params.append('offset', options.offset);
|
||||
|
||||
// Create search URL
|
||||
const url = `/api/search?${params.toString()}`;
|
||||
console.log(`Performing search with URL: ${url}`);
|
||||
|
||||
// Perform the search request
|
||||
const response = await fetch(url);
|
||||
|
||||
if (response.ok) {
|
||||
return await response.json();
|
||||
} else {
|
||||
let errorText = '';
|
||||
try {
|
||||
const errorJson = await response.json();
|
||||
errorText = errorJson.error || response.statusText;
|
||||
} catch (e) {
|
||||
errorText = response.statusText;
|
||||
}
|
||||
|
||||
console.error(`Search error: ${errorText}`);
|
||||
throw new Error(`Search failed: ${errorText}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error performing search:', error);
|
||||
window.ui.showNotification('Error', 'Error al realizar la búsqueda');
|
||||
return { files: [], folders: [], total_count: 0 };
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Perform advanced search with multiple criteria
|
||||
* @param {Object} criteria - Search criteria
|
||||
* @returns {Promise<Object>} - Search results
|
||||
*/
|
||||
async advancedSearch(criteria) {
|
||||
try {
|
||||
console.log('Performing advanced search with criteria:', criteria);
|
||||
|
||||
// Use POST endpoint for advanced search
|
||||
const response = await fetch('/api/search', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(criteria)
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
return await response.json();
|
||||
} else {
|
||||
let errorText = '';
|
||||
try {
|
||||
const errorJson = await response.json();
|
||||
errorText = errorJson.error || response.statusText;
|
||||
} catch (e) {
|
||||
errorText = response.statusText;
|
||||
}
|
||||
|
||||
console.error(`Advanced search error: ${errorText}`);
|
||||
throw new Error(`Advanced search failed: ${errorText}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error performing advanced search:', error);
|
||||
window.ui.showNotification('Error', 'Error al realizar la búsqueda avanzada');
|
||||
return { files: [], folders: [], total_count: 0 };
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Display search results in the UI
|
||||
* @param {Object} results - Search results object with files and folders arrays
|
||||
*/
|
||||
displaySearchResults(results) {
|
||||
// Get the files grid and list view elements
|
||||
const filesGrid = document.getElementById('files-grid');
|
||||
const filesListView = document.getElementById('files-list-view');
|
||||
|
||||
// Clear existing content
|
||||
filesGrid.innerHTML = '';
|
||||
filesListView.innerHTML = `
|
||||
<div class="list-header">
|
||||
<div data-i18n="files.name">Nombre</div>
|
||||
<div data-i18n="files.type">Tipo</div>
|
||||
<div data-i18n="files.size">Tamaño</div>
|
||||
<div data-i18n="files.modified">Modificado</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Add search results header
|
||||
const searchHeader = document.createElement('div');
|
||||
searchHeader.className = 'search-results-header';
|
||||
searchHeader.innerHTML = `
|
||||
<h3>Resultados de búsqueda (${results.total_count || (results.files.length + results.folders.length)})</h3>
|
||||
<button class="btn btn-secondary" id="clear-search-btn">
|
||||
<i class="fas fa-times"></i> Limpiar búsqueda
|
||||
</button>
|
||||
`;
|
||||
filesGrid.appendChild(searchHeader);
|
||||
|
||||
// Add event listener to clear search button
|
||||
const clearSearchBtn = document.getElementById('clear-search-btn');
|
||||
if (clearSearchBtn) {
|
||||
clearSearchBtn.addEventListener('click', () => {
|
||||
// Clear search input
|
||||
document.querySelector('.search-container input').value = '';
|
||||
|
||||
// Load regular files view
|
||||
window.app.currentPath = '';
|
||||
window.ui.updateBreadcrumb('');
|
||||
window.loadFiles();
|
||||
});
|
||||
}
|
||||
|
||||
// If no results, show empty state
|
||||
if (results.files.length === 0 && results.folders.length === 0) {
|
||||
const emptyState = document.createElement('div');
|
||||
emptyState.className = 'empty-state';
|
||||
emptyState.innerHTML = `
|
||||
<i class="fas fa-search" style="font-size: 48px; color: #ddd; margin-bottom: 16px;"></i>
|
||||
<p>No se encontraron resultados para esta búsqueda</p>
|
||||
`;
|
||||
filesGrid.appendChild(emptyState);
|
||||
return;
|
||||
}
|
||||
|
||||
// Process folders
|
||||
results.folders.forEach(folder => {
|
||||
window.ui.addFolderToView(folder);
|
||||
});
|
||||
|
||||
// Process files
|
||||
results.files.forEach(file => {
|
||||
window.ui.addFileToView(file);
|
||||
});
|
||||
|
||||
// Update file icons
|
||||
window.ui.updateFileIcons();
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear the search cache on the server
|
||||
* @returns {Promise<boolean>} - Success status
|
||||
*/
|
||||
async clearSearchCache() {
|
||||
try {
|
||||
const response = await fetch('/api/search/cache', {
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
window.ui.showNotification('Caché limpiada', 'Caché de búsqueda limpiada correctamente');
|
||||
return true;
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al limpiar la caché de búsqueda');
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error clearing search cache:', error);
|
||||
window.ui.showNotification('Error', 'Error al limpiar la caché de búsqueda');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Expose the search module globally
|
||||
window.search = search;
|
||||
+44
-9
@@ -190,19 +190,54 @@ const ui = {
|
||||
updateBreadcrumb(folderName) {
|
||||
const breadcrumb = document.querySelector('.breadcrumb');
|
||||
breadcrumb.innerHTML = '';
|
||||
|
||||
|
||||
// Get user info to help determine home folder
|
||||
const USER_DATA_KEY = 'oxicloud_user';
|
||||
const userData = JSON.parse(localStorage.getItem(USER_DATA_KEY) || '{}');
|
||||
const username = userData.username || '';
|
||||
|
||||
// Create the home item - for users, this is their personal folder
|
||||
const homeItem = document.createElement('span');
|
||||
homeItem.className = 'breadcrumb-item';
|
||||
homeItem.textContent = window.i18n ? window.i18n.t('breadcrumb.home') : 'Home';
|
||||
homeItem.addEventListener('click', () => {
|
||||
window.app.currentPath = '';
|
||||
this.updateBreadcrumb('');
|
||||
window.loadFiles();
|
||||
});
|
||||
|
||||
|
||||
// Helper function to safely get translation text
|
||||
const getTranslatedText = (key, defaultValue) => {
|
||||
if (!window.i18n || !window.i18n.t) return defaultValue;
|
||||
return window.i18n.t(key);
|
||||
};
|
||||
|
||||
// Set appropriate text for home item
|
||||
if (username && folderName && folderName.includes(username)) {
|
||||
// If the current folder is the user's home folder, label it as "Home"
|
||||
homeItem.textContent = getTranslatedText('breadcrumb.home', 'Home');
|
||||
} else if (folderName && folderName.startsWith('Mi Carpeta')) {
|
||||
// If the current folder is another user's home folder or a special folder, use its name
|
||||
homeItem.textContent = folderName;
|
||||
} else {
|
||||
// Default - use "Home" label
|
||||
homeItem.textContent = getTranslatedText('breadcrumb.home', 'Home');
|
||||
|
||||
// For searching, we might have a custom breadcrumb text
|
||||
if (folderName && folderName.startsWith('Búsqueda:')) {
|
||||
// We're in search mode - don't add click handler
|
||||
breadcrumb.appendChild(homeItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add click handler - but only if we have a user home folder to return to
|
||||
if (window.app.userHomeFolderId) {
|
||||
homeItem.addEventListener('click', () => {
|
||||
window.app.currentPath = window.app.userHomeFolderId;
|
||||
this.updateBreadcrumb(window.app.userHomeFolderName || 'Home');
|
||||
window.loadFiles();
|
||||
});
|
||||
}
|
||||
|
||||
breadcrumb.appendChild(homeItem);
|
||||
|
||||
if (folderName) {
|
||||
// If we have a subfolder, add it to the breadcrumb
|
||||
if (folderName && !folderName.startsWith('Mi Carpeta') && !folderName.startsWith('Búsqueda:')) {
|
||||
const separator = document.createElement('span');
|
||||
separator.className = 'breadcrumb-separator';
|
||||
separator.textContent = '>';
|
||||
|
||||
Reference in New Issue
Block a user