chore: translate all Spanish comments and log messages to English
This commit is contained in:
+69
-69
@@ -197,7 +197,7 @@ function setupUserMenu() {
|
||||
// Theme switching could be expanded here in the future
|
||||
window.ui.showNotification(
|
||||
dark ? '🌙' : '☀️',
|
||||
dark ? 'Modo oscuro activado (próximamente)' : 'Modo claro activado'
|
||||
dark ? 'Dark mode enabled (coming soon)' : 'Light mode enabled'
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -476,12 +476,12 @@ function setupEventListeners() {
|
||||
if (filesListView) filesListView.style.display = app.currentView === 'list' ? 'block' : 'none';
|
||||
|
||||
// Update UI
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.trash') : 'Papelera';
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.trash') : 'Trash';
|
||||
elements.actionsBar.innerHTML = `
|
||||
<div class="action-buttons">
|
||||
<button class="btn btn-danger" id="empty-trash-btn">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
<span>${window.i18n ? window.i18n.t('trash.empty_trash') : 'Vaciar papelera'}</span>
|
||||
<span>${window.i18n ? window.i18n.t('trash.empty_trash') : 'Empty trash'}</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
@@ -519,35 +519,35 @@ function setupEventListeners() {
|
||||
app.currentSection = 'files';
|
||||
|
||||
// Reset UI
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.files') : 'Archivos';
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.files') : 'Files';
|
||||
elements.actionsBar.innerHTML = `
|
||||
<div class="action-buttons">
|
||||
<div class="upload-dropdown" id="upload-dropdown">
|
||||
<button class="btn btn-primary" id="upload-btn">
|
||||
<i class="fas fa-cloud-upload-alt" style="margin-right: 5px;"></i>
|
||||
<span data-i18n="actions.upload">Subir</span>
|
||||
<span data-i18n="actions.upload">Upload</span>
|
||||
<i class="fas fa-caret-down" style="margin-left: 4px; font-size: 12px;"></i>
|
||||
</button>
|
||||
<div class="upload-dropdown-menu" id="upload-dropdown-menu">
|
||||
<button class="upload-dropdown-item" id="upload-files-btn">
|
||||
<i class="fas fa-file"></i>
|
||||
<span data-i18n="actions.upload_files">Subir archivos</span>
|
||||
<span data-i18n="actions.upload_files">Upload files</span>
|
||||
</button>
|
||||
<button class="upload-dropdown-item" id="upload-folder-btn">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
<span data-i18n="actions.upload_folder">Subir carpeta</span>
|
||||
<span data-i18n="actions.upload_folder">Upload folder</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" id="new-folder-btn">
|
||||
<i class="fas fa-folder-plus" style="margin-right: 5px;"></i> <span data-i18n="actions.new_folder">Nueva carpeta</span>
|
||||
<i class="fas fa-folder-plus" style="margin-right: 5px;"></i> <span data-i18n="actions.new_folder">New folder</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Vista de cuadrícula">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="Vista de lista">
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -623,14 +623,14 @@ function setupEventListeners() {
|
||||
*/
|
||||
async function loadFiles(options = {}) {
|
||||
try {
|
||||
console.log("Iniciando loadFiles() - cargando archivos...", options);
|
||||
console.log("Starting loadFiles() - loading files...", options);
|
||||
|
||||
// Flag para forzar el refresco completo ignorando caché
|
||||
// Flag to force complete refresh ignoring cache
|
||||
const forceRefresh = options.forceRefresh || false;
|
||||
|
||||
// Prevenir múltiples solicitudes de carga simultáneas
|
||||
// Prevent multiple simultaneous load requests
|
||||
if (window.isLoadingFiles) {
|
||||
console.log("Ya hay una carga de archivos en progreso, ignorando solicitud");
|
||||
console.log("A file load is already in progress, ignoring request");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ async function loadFiles(options = {}) {
|
||||
elements.filesGrid.innerHTML = `
|
||||
<div class="files-loading-spinner">
|
||||
<div class="spinner"></div>
|
||||
<span>${window.i18n ? window.i18n.t('files.loading') : 'Cargando archivos…'}</span>
|
||||
<span>${window.i18n ? window.i18n.t('files.loading') : 'Loading files…'}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -651,12 +651,12 @@ async function loadFiles(options = {}) {
|
||||
const userData = JSON.parse(localStorage.getItem(USER_DATA_KEY) || '{}');
|
||||
if (userData.username) {
|
||||
// Find user's home folder
|
||||
console.log("Buscando carpeta de usuario para", userData.username);
|
||||
console.log("Looking for user folder for", userData.username);
|
||||
await findUserHomeFolder(userData.username);
|
||||
}
|
||||
}
|
||||
|
||||
// Agregar timestamp para evitar caché
|
||||
// Add timestamp to avoid cache
|
||||
const timestamp = new Date().getTime();
|
||||
let url;
|
||||
|
||||
@@ -667,7 +667,7 @@ async function loadFiles(options = {}) {
|
||||
url = `/api/folders/${app.userHomeFolderId}/contents?t=${timestamp}`;
|
||||
app.currentPath = app.userHomeFolderId;
|
||||
ui.updateBreadcrumb(app.userHomeFolderName || 'Home');
|
||||
console.log(`Cargando carpeta del usuario: ${app.userHomeFolderName} (${app.userHomeFolderId})`);
|
||||
console.log(`Loading user folder: ${app.userHomeFolderName} (${app.userHomeFolderId})`);
|
||||
} else {
|
||||
// Emergency fallback - this should rarely happen but prevents errors
|
||||
url = `/api/folders?t=${timestamp}`;
|
||||
@@ -676,7 +676,7 @@ async function loadFiles(options = {}) {
|
||||
} else {
|
||||
// Normal case - viewing subfolder contents
|
||||
url = `/api/folders/${app.currentPath}/contents?t=${timestamp}`;
|
||||
console.log(`Cargando contenido de subcarpeta: ${app.currentPath}`);
|
||||
console.log(`Loading subfolder content: ${app.currentPath}`);
|
||||
}
|
||||
|
||||
const token = localStorage.getItem('oxicloud_token');
|
||||
@@ -686,14 +686,14 @@ async function loadFiles(options = {}) {
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
'Pragma': 'no-cache'
|
||||
},
|
||||
cache: 'no-store' // Instruir al navegador a no usar caché
|
||||
cache: 'no-store' // Instruct the browser not to use cache
|
||||
};
|
||||
|
||||
// Si se especifica forceRefresh, agregar un parámetro adicional para evitar caché
|
||||
// If forceRefresh is specified, add an additional parameter to avoid cache
|
||||
if (forceRefresh) {
|
||||
url += `&force_refresh=true`;
|
||||
requestOptions.headers['X-Force-Refresh'] = 'true';
|
||||
console.log('Forzando refresco completo ignorando caché');
|
||||
console.log('Forcing complete refresh ignoring cache');
|
||||
}
|
||||
|
||||
console.log(`Loading files from ${url}`);
|
||||
@@ -703,13 +703,13 @@ async function loadFiles(options = {}) {
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
console.warn("Auth error when loading files, showing empty list");
|
||||
// Just show empty state instead of causing redirect loops
|
||||
elements.filesGrid.innerHTML = '<div class="empty-state"><p>No se pudieron cargar los archivos</p></div>';
|
||||
elements.filesGrid.innerHTML = '<div class="empty-state"><p>Could not load files</p></div>';
|
||||
elements.filesListView.innerHTML = `
|
||||
<div class="list-header">
|
||||
<div>Nombre</div>
|
||||
<div>Tipo</div>
|
||||
<div>Tamaño</div>
|
||||
<div>Modificado</div>
|
||||
<div>Name</div>
|
||||
<div>Type</div>
|
||||
<div>Size</div>
|
||||
<div>Modified</div>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
@@ -724,10 +724,10 @@ async function loadFiles(options = {}) {
|
||||
elements.filesGrid.innerHTML = '';
|
||||
elements.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 data-i18n="files.name">Name</div>
|
||||
<div data-i18n="files.type">Type</div>
|
||||
<div data-i18n="files.size">Size</div>
|
||||
<div data-i18n="files.modified">Modified</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -766,11 +766,11 @@ async function loadFiles(options = {}) {
|
||||
|
||||
// Also load files in this folder
|
||||
const cacheTimestamp = new Date().getTime();
|
||||
let filesUrl = `/api/files?t=${cacheTimestamp}`; // Agregar timestamp para evitar problemas de caché
|
||||
let filesUrl = `/api/files?t=${cacheTimestamp}`; // Add timestamp to avoid cache issues
|
||||
if (app.currentPath) {
|
||||
filesUrl += `&folder_id=${app.currentPath}`;
|
||||
}
|
||||
console.log(`Cargando archivos desde: ${filesUrl}`);
|
||||
console.log(`Loading files from: ${filesUrl}`);
|
||||
|
||||
try {
|
||||
console.log(`Fetching files from: ${filesUrl}`);
|
||||
@@ -810,7 +810,7 @@ async function loadFiles(options = {}) {
|
||||
console.error('Error loading folders:', error);
|
||||
ui.showNotification('Error', 'Could not load files and folders');
|
||||
} finally {
|
||||
// Marcar que ya no estamos cargando archivos para permitir solicitudes futuras
|
||||
// Mark that we are no longer loading files to allow future requests
|
||||
window.isLoadingFiles = false;
|
||||
}
|
||||
}
|
||||
@@ -839,11 +839,11 @@ async function loadTrashItems() {
|
||||
elements.filesGrid.innerHTML = '';
|
||||
elements.filesListView.innerHTML = `
|
||||
<div class="list-header">
|
||||
<div data-i18n="files.name">Nombre</div>
|
||||
<div data-i18n="files.type">Tipo</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 data-i18n="files.name">Name</div>
|
||||
<div data-i18n="files.type">Type</div>
|
||||
<div data-i18n="trash.original_location">Original location</div>
|
||||
<div data-i18n="trash.deleted_date">Deletion date</div>
|
||||
<div data-i18n="trash.actions">Actions</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -864,7 +864,7 @@ async function loadTrashItems() {
|
||||
emptyState.className = 'empty-state';
|
||||
emptyState.innerHTML = `
|
||||
<i class="fas fa-trash" style="font-size: 48px; color: #ddd; margin-bottom: 16px;"></i>
|
||||
<p>${window.i18n ? window.i18n.t('trash.empty_state') : 'La papelera está vacía'}</p>
|
||||
<p>${window.i18n ? window.i18n.t('trash.empty_state') : 'The trash is empty'}</p>
|
||||
`;
|
||||
elements.filesGrid.appendChild(emptyState);
|
||||
return;
|
||||
@@ -877,7 +877,7 @@ async function loadTrashItems() {
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading trash items:', error);
|
||||
window.ui.showNotification('Error', 'Error al cargar elementos de la papelera');
|
||||
window.ui.showNotification('Error', 'Error loading trash items');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,8 +896,8 @@ function addTrashItemToView(item) {
|
||||
|
||||
// Item type label
|
||||
const typeLabel = isFile ?
|
||||
(window.i18n ? window.i18n.t('files.file_types.file') : 'Archivo') :
|
||||
(window.i18n ? window.i18n.t('files.file_types.folder') : 'Carpeta');
|
||||
(window.i18n ? window.i18n.t('files.file_types.file') : 'File') :
|
||||
(window.i18n ? window.i18n.t('files.file_types.folder') : 'Folder');
|
||||
|
||||
// Grid view element
|
||||
const gridElement = document.createElement('div');
|
||||
@@ -912,10 +912,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="${window.i18n ? window.i18n.t('trash.restore') : 'Restaurar'}">
|
||||
<button class="btn-restore" title="${window.i18n ? window.i18n.t('trash.restore') : 'Restore'}">
|
||||
<i class="fas fa-undo"></i>
|
||||
</button>
|
||||
<button class="btn-delete" title="${window.i18n ? window.i18n.t('trash.delete_permanently') : 'Eliminar permanentemente'}">
|
||||
<button class="btn-delete" title="${window.i18n ? window.i18n.t('trash.delete_permanently') : 'Delete permanently'}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -956,10 +956,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="${window.i18n ? window.i18n.t('trash.restore') : 'Restaurar'}">
|
||||
<button class="btn-restore" title="${window.i18n ? window.i18n.t('trash.restore') : 'Restore'}">
|
||||
<i class="fas fa-undo"></i>
|
||||
</button>
|
||||
<button class="btn-delete" title="${window.i18n ? window.i18n.t('trash.delete_permanently') : 'Eliminar permanentemente'}">
|
||||
<button class="btn-delete" title="${window.i18n ? window.i18n.t('trash.delete_permanently') : 'Delete permanently'}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -995,7 +995,7 @@ async function performSearch(query) {
|
||||
app.isSearchMode = true;
|
||||
|
||||
// Set breadcrumb for search
|
||||
ui.updateBreadcrumb(`Búsqueda: "${query}"`);
|
||||
ui.updateBreadcrumb(`Search: "${query}"`);
|
||||
|
||||
// Prepare search options
|
||||
const options = {
|
||||
@@ -1037,7 +1037,7 @@ async function performSearch(query) {
|
||||
|
||||
} catch (error) {
|
||||
console.error('Search error:', error);
|
||||
window.ui.showNotification('Error', 'Error al realizar la búsqueda');
|
||||
window.ui.showNotification('Error', 'Error performing search');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1076,7 +1076,7 @@ function switchToSharedView() {
|
||||
}
|
||||
|
||||
// Update UI
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.shared') : 'Compartidos';
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.shared') : 'Shared';
|
||||
|
||||
// Clear breadcrumb and show root
|
||||
ui.updateBreadcrumb('');
|
||||
@@ -1105,7 +1105,7 @@ function switchToFilesView() {
|
||||
app.currentSection = 'files';
|
||||
|
||||
// Update UI
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.files') : 'Archivos';
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.files') : 'Files';
|
||||
|
||||
// Remove active class from all nav items
|
||||
elements.navItems.forEach(navItem => navItem.classList.remove('active'));
|
||||
@@ -1122,29 +1122,29 @@ function switchToFilesView() {
|
||||
<div class="upload-dropdown" id="upload-dropdown">
|
||||
<button class="btn btn-primary" id="upload-btn">
|
||||
<i class="fas fa-cloud-upload-alt" style="margin-right: 5px;"></i>
|
||||
<span data-i18n="actions.upload">Subir</span>
|
||||
<span data-i18n="actions.upload">Upload</span>
|
||||
<i class="fas fa-caret-down" style="margin-left: 4px; font-size: 12px;"></i>
|
||||
</button>
|
||||
<div class="upload-dropdown-menu" id="upload-dropdown-menu">
|
||||
<button class="upload-dropdown-item" id="upload-files-btn">
|
||||
<i class="fas fa-file"></i>
|
||||
<span data-i18n="actions.upload_files">Subir archivos</span>
|
||||
<span data-i18n="actions.upload_files">Upload files</span>
|
||||
</button>
|
||||
<button class="upload-dropdown-item" id="upload-folder-btn">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
<span data-i18n="actions.upload_folder">Subir carpeta</span>
|
||||
<span data-i18n="actions.upload_folder">Upload folder</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" id="new-folder-btn">
|
||||
<i class="fas fa-folder-plus" style="margin-right: 5px;"></i> <span data-i18n="actions.new_folder">Nueva carpeta</span>
|
||||
<i class="fas fa-folder-plus" style="margin-right: 5px;"></i> <span data-i18n="actions.new_folder">New folder</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Vista de cuadrícula">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="Vista de lista">
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -1219,7 +1219,7 @@ function switchToFavoritesView() {
|
||||
}
|
||||
|
||||
// Update UI
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.favorites') : 'Favoritos';
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.favorites') : 'Favorites';
|
||||
|
||||
// Clear breadcrumb and show root
|
||||
ui.updateBreadcrumb('');
|
||||
@@ -1235,10 +1235,10 @@ function switchToFavoritesView() {
|
||||
<!-- No actions needed for favorites view -->
|
||||
</div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Vista de cuadrícula">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="Vista de lista">
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -1278,7 +1278,7 @@ function switchToFavoritesView() {
|
||||
filesGrid.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-exclamation-circle" style="font-size: 48px; color: #f44336; margin-bottom: 16px;"></i>
|
||||
<p>Error al cargar el módulo de favoritos</p>
|
||||
<p>Error loading the favorites module</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -1308,7 +1308,7 @@ function switchToRecentFilesView() {
|
||||
}
|
||||
|
||||
// Update UI
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.recent') : 'Recientes';
|
||||
elements.pageTitle.textContent = window.i18n ? window.i18n.t('nav.recent') : 'Recent';
|
||||
|
||||
// Clear breadcrumb and show root
|
||||
ui.updateBreadcrumb('');
|
||||
@@ -1322,14 +1322,14 @@ function switchToRecentFilesView() {
|
||||
elements.actionsBar.innerHTML = `
|
||||
<div class="action-buttons">
|
||||
<button class="btn btn-secondary" id="clear-recent-btn">
|
||||
<i class="fas fa-broom" style="margin-right: 5px;"></i> <span data-i18n="actions.clear_recent">Limpiar recientes</span>
|
||||
<i class="fas fa-broom" style="margin-right: 5px;"></i> <span data-i18n="actions.clear_recent">Clear recent</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Vista de cuadrícula">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="Vista de lista">
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -1341,7 +1341,7 @@ function switchToRecentFilesView() {
|
||||
if (window.recent) {
|
||||
window.recent.clearRecentFiles();
|
||||
window.recent.displayRecentFiles();
|
||||
window.ui.showNotification('Limpieza completada', 'Se ha limpiado el historial de archivos recientes');
|
||||
window.ui.showNotification('Cleanup completed', 'Recent files history has been cleared');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1378,7 +1378,7 @@ function switchToRecentFilesView() {
|
||||
filesGrid.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-exclamation-circle" style="font-size: 48px; color: #f44336; margin-bottom: 16px;"></i>
|
||||
<p>Error al cargar el módulo de archivos recientes</p>
|
||||
<p>Error loading the recent files module</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -1450,7 +1450,7 @@ window.refreshUserData = refreshUserData;
|
||||
function showUserProfileModal() {
|
||||
const USER_DATA_KEY = 'oxicloud_user';
|
||||
const userData = JSON.parse(localStorage.getItem(USER_DATA_KEY) || '{}');
|
||||
const username = userData.username || 'Usuario';
|
||||
const username = userData.username || 'User';
|
||||
const email = userData.email || '';
|
||||
const role = userData.role || 'user';
|
||||
const initials = username.substring(0, 2).toUpperCase();
|
||||
@@ -1847,7 +1847,7 @@ async function findUserHomeFolder(username) {
|
||||
* Logout - clear all auth data and redirect to login
|
||||
*/
|
||||
function logout() {
|
||||
// Nombres de variables según auth.js
|
||||
// Variable names as per auth.js
|
||||
const TOKEN_KEY = 'oxicloud_token';
|
||||
const REFRESH_TOKEN_KEY = 'oxicloud_refresh_token';
|
||||
const TOKEN_EXPIRY_KEY = 'oxicloud_token_expiry';
|
||||
|
||||
+20
-20
@@ -34,7 +34,7 @@ const LANGUAGE_TEXTS = {
|
||||
subtitle: 'Por favor, selecciona tu idioma',
|
||||
continue: 'Continuar',
|
||||
autodetected: 'Hemos detectado tu idioma',
|
||||
moreLanguages: 'Más idiomas...',
|
||||
moreLanguages: 'More languages...',
|
||||
modalTitle: 'Seleccionar idioma',
|
||||
searchPlaceholder: 'Buscar idioma...'
|
||||
},
|
||||
@@ -494,8 +494,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
console.error('Error showing initial panel:', err);
|
||||
});
|
||||
|
||||
// Siempre limpiar los contadores al cargar la página de login
|
||||
// para asegurar que no quedamos atrapados en un bucle
|
||||
// Always clear counters when loading the login page
|
||||
// to ensure we don't get trapped in a loop
|
||||
console.log('Login page loaded, clearing all counters');
|
||||
sessionStorage.removeItem('redirect_count');
|
||||
localStorage.removeItem('refresh_attempts');
|
||||
@@ -589,14 +589,14 @@ if (isLoginPage && loginForm) {
|
||||
localStorage.setItem(TOKEN_KEY, token);
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
|
||||
|
||||
// Extraer fecha de expiración desde el token JWT
|
||||
// Extract expiration date from the JWT token
|
||||
let parsedExpiry = false;
|
||||
const tokenParts = token.split('.');
|
||||
if (tokenParts.length === 3) {
|
||||
try {
|
||||
const payload = JSON.parse(atob(tokenParts[1]));
|
||||
if (payload.exp) {
|
||||
// payload.exp está en segundos desde epoch
|
||||
// payload.exp is in seconds since epoch
|
||||
const expiryDate = new Date(payload.exp * 1000);
|
||||
|
||||
// Verify the date is valid
|
||||
@@ -642,7 +642,7 @@ if (isLoginPage && loginForm) {
|
||||
// Redirect to main app
|
||||
redirectToMainApp();
|
||||
} catch (error) {
|
||||
loginError.textContent = error.message || 'Error al iniciar sesión';
|
||||
loginError.textContent = error.message || 'Error logging in';
|
||||
loginError.style.display = 'block';
|
||||
}
|
||||
});
|
||||
@@ -664,7 +664,7 @@ if (isLoginPage && registerForm) {
|
||||
|
||||
// Validate passwords match
|
||||
if (password !== confirmPassword) {
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.passwords_mismatch') : 'Las contraseñas no coinciden';
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.passwords_mismatch') : 'Passwords do not match';
|
||||
registerError.textContent = errorMsg;
|
||||
registerError.style.display = 'block';
|
||||
return;
|
||||
@@ -674,7 +674,7 @@ if (isLoginPage && registerForm) {
|
||||
const data = await register(username, email, password);
|
||||
|
||||
// Show success message
|
||||
const successMsg = window.i18n ? window.i18n.t('auth.account_success') : '¡Cuenta creada con éxito! Puedes iniciar sesión ahora.';
|
||||
const successMsg = window.i18n ? window.i18n.t('auth.account_success') : 'Account created successfully! You can now log in.';
|
||||
registerSuccess.textContent = successMsg;
|
||||
registerSuccess.style.display = 'block';
|
||||
|
||||
@@ -687,7 +687,7 @@ if (isLoginPage && registerForm) {
|
||||
registerPanel.style.display = 'none';
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.admin_create_error') : 'Error al registrar cuenta';
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.admin_create_error') : 'Error registering account';
|
||||
registerError.textContent = error.message || errorMsg;
|
||||
registerError.style.display = 'block';
|
||||
}
|
||||
@@ -710,7 +710,7 @@ if (isLoginPage && adminSetupForm) {
|
||||
|
||||
// Validate passwords match
|
||||
if (password !== confirmPassword) {
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.passwords_mismatch') : 'Las contraseñas no coinciden';
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.passwords_mismatch') : 'Passwords do not match';
|
||||
adminSetupError.textContent = errorMsg;
|
||||
adminSetupError.style.display = 'block';
|
||||
return;
|
||||
@@ -721,7 +721,7 @@ if (isLoginPage && adminSetupForm) {
|
||||
const data = await register('admin', email, password, 'admin');
|
||||
|
||||
// Show success message in the GUI instead of alert
|
||||
const successMsg = window.i18n ? window.i18n.t('auth.admin_success') : '¡Cuenta de administrador creada con éxito! Ahora puedes iniciar sesión.';
|
||||
const successMsg = window.i18n ? window.i18n.t('auth.admin_success') : 'Admin account created successfully! You can now log in.';
|
||||
|
||||
if (adminSetupSuccess) {
|
||||
adminSetupSuccess.textContent = successMsg;
|
||||
@@ -736,7 +736,7 @@ if (isLoginPage && adminSetupForm) {
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.admin_create_error') : 'Error al crear cuenta de administrador';
|
||||
const errorMsg = window.i18n ? window.i18n.t('auth.admin_create_error') : 'Error creating admin account';
|
||||
adminSetupError.textContent = error.message || errorMsg;
|
||||
adminSetupError.style.display = 'block';
|
||||
}
|
||||
@@ -792,10 +792,10 @@ async function login(username, password) {
|
||||
if (!response.ok) {
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || 'Falló la autenticación');
|
||||
throw new Error(errorData.error || 'Authentication failed');
|
||||
} catch (jsonError) {
|
||||
// If the error response is not valid JSON
|
||||
throw new Error(`Error de autenticación (${response.status}): ${response.statusText}`);
|
||||
throw new Error(`Authentication error (${response.status}): ${response.statusText}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,7 +806,7 @@ async function login(username, password) {
|
||||
return data;
|
||||
} catch (jsonError) {
|
||||
console.error('Error parsing login response:', jsonError);
|
||||
throw new Error('Error al procesar la respuesta del servidor');
|
||||
throw new Error('Error processing server response');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Login error:', error);
|
||||
@@ -848,10 +848,10 @@ async function register(username, email, password, role = 'user') {
|
||||
if (!response.ok) {
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || 'Error en el registro');
|
||||
throw new Error(errorData.error || 'Registration error');
|
||||
} catch (jsonError) {
|
||||
// If the error response is not valid JSON
|
||||
throw new Error(`Error de registro (${response.status}): ${response.statusText}`);
|
||||
throw new Error(`Registration error (${response.status}): ${response.statusText}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,7 +862,7 @@ async function register(username, email, password, role = 'user') {
|
||||
return data;
|
||||
} catch (jsonError) {
|
||||
console.error('Error parsing registration response:', jsonError);
|
||||
throw new Error('Error al procesar la respuesta del servidor');
|
||||
throw new Error('Error processing server response');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Registration error:', error);
|
||||
@@ -883,7 +883,7 @@ async function fetchUserData(token) {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Error al obtener datos del usuario');
|
||||
throw new Error('Error fetching user data');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
@@ -1092,7 +1092,7 @@ function redirectToMainApp() {
|
||||
window.location.href = '/login.html?error=redirect_fatal';
|
||||
} catch (e) {
|
||||
// Nothing more we can do
|
||||
alert('Error crítico en la redirección. Por favor, recarga la página e intenta nuevamente.');
|
||||
alert('Critical redirect error. Please reload the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-26
@@ -30,7 +30,7 @@ const contextMenus = {
|
||||
window.favorites.removeFromFavorites(folder.id, 'folder');
|
||||
// Update menu item text
|
||||
document.getElementById('favorite-folder-option').querySelector('span').textContent =
|
||||
window.i18n ? window.i18n.t('actions.favorite') : 'Añadir a favoritos';
|
||||
window.i18n ? window.i18n.t('actions.favorite') : 'Add to favorites';
|
||||
} else {
|
||||
// Add to favorites
|
||||
window.favorites.addToFavorites(
|
||||
@@ -41,7 +41,7 @@ const contextMenus = {
|
||||
);
|
||||
// Update menu item text
|
||||
document.getElementById('favorite-folder-option').querySelector('span').textContent =
|
||||
window.i18n ? window.i18n.t('actions.unfavorite') : 'Quitar de favoritos';
|
||||
window.i18n ? window.i18n.t('actions.unfavorite') : 'Remove from favorites';
|
||||
}
|
||||
}
|
||||
window.ui.closeContextMenu();
|
||||
@@ -143,7 +143,7 @@ const contextMenus = {
|
||||
window.favorites.removeFromFavorites(file.id, 'file');
|
||||
// Update menu item text
|
||||
document.getElementById('favorite-file-option').querySelector('span').textContent =
|
||||
window.i18n ? window.i18n.t('actions.favorite') : 'Añadir a favoritos';
|
||||
window.i18n ? window.i18n.t('actions.favorite') : 'Add to favorites';
|
||||
} else {
|
||||
// Add to favorites
|
||||
window.favorites.addToFavorites(
|
||||
@@ -154,7 +154,7 @@ const contextMenus = {
|
||||
);
|
||||
// Update menu item text
|
||||
document.getElementById('favorite-file-option').querySelector('span').textContent =
|
||||
window.i18n ? window.i18n.t('actions.unfavorite') : 'Quitar de favoritos';
|
||||
window.i18n ? window.i18n.t('actions.unfavorite') : 'Remove from favorites';
|
||||
}
|
||||
}
|
||||
window.ui.closeFileContextMenu();
|
||||
@@ -246,7 +246,7 @@ const contextMenus = {
|
||||
renameInput.value = folder.name;
|
||||
// Update header text
|
||||
const headerSpan = renameDialog.querySelector('.rename-dialog-header span');
|
||||
if (headerSpan) headerSpan.textContent = window.i18n ? window.i18n.t('dialogs.rename_folder') : 'Renombrar carpeta';
|
||||
if (headerSpan) headerSpan.textContent = window.i18n ? window.i18n.t('dialogs.rename_folder') : 'Rename folder';
|
||||
renameDialog.style.display = 'flex';
|
||||
renameInput.focus();
|
||||
renameInput.select();
|
||||
@@ -264,7 +264,7 @@ const contextMenus = {
|
||||
renameInput.value = file.name;
|
||||
// Update header text
|
||||
const headerSpan = renameDialog.querySelector('.rename-dialog-header span');
|
||||
if (headerSpan) headerSpan.textContent = window.i18n ? window.i18n.t('dialogs.rename_file') : 'Renombrar archivo';
|
||||
if (headerSpan) headerSpan.textContent = window.i18n ? window.i18n.t('dialogs.rename_file') : 'Rename file';
|
||||
renameDialog.style.display = 'flex';
|
||||
renameInput.focus();
|
||||
renameInput.select();
|
||||
@@ -293,8 +293,8 @@ const contextMenus = {
|
||||
// Update dialog title (preserve icon)
|
||||
const dialogHeader = document.getElementById('move-file-dialog').querySelector('.rename-dialog-header');
|
||||
const titleText = mode === 'file' ?
|
||||
(window.i18n ? window.i18n.t('dialogs.move_file') : 'Mover archivo') :
|
||||
(window.i18n ? window.i18n.t('dialogs.move_folder') : 'Mover carpeta');
|
||||
(window.i18n ? window.i18n.t('dialogs.move_file') : 'Move file') :
|
||||
(window.i18n ? window.i18n.t('dialogs.move_folder') : 'Move folder');
|
||||
dialogHeader.innerHTML = `<i class="fas fa-arrows-alt" style="color:#ff5e3a"></i> <span>${titleText}</span>`;
|
||||
|
||||
// Load all available folders
|
||||
@@ -319,7 +319,7 @@ const contextMenus = {
|
||||
async renameItem() {
|
||||
const newName = document.getElementById('rename-input').value.trim();
|
||||
if (!newName) {
|
||||
alert(window.i18n ? window.i18n.t('errors.empty_name') : 'El nombre no puede estar vacío');
|
||||
alert(window.i18n ? window.i18n.t('errors.empty_name') : 'Name cannot be empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ const contextMenus = {
|
||||
// Clear container except root option
|
||||
folderSelectContainer.innerHTML = `
|
||||
<div class="folder-select-item selected" data-folder-id="">
|
||||
<i class="fas fa-folder"></i> <span data-i18n="dialogs.root">Raíz</span>
|
||||
<i class="fas fa-folder"></i> <span data-i18n="dialogs.root">Root</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -438,8 +438,8 @@ const contextMenus = {
|
||||
|
||||
// Update dialog content
|
||||
dialogHeader.textContent = itemType === 'file' ?
|
||||
(window.i18n ? window.i18n.t('dialogs.share_file') : 'Compartir archivo') :
|
||||
(window.i18n ? window.i18n.t('dialogs.share_folder') : 'Compartir carpeta');
|
||||
(window.i18n ? window.i18n.t('dialogs.share_file') : 'Share file') :
|
||||
(window.i18n ? window.i18n.t('dialogs.share_folder') : 'Share folder');
|
||||
|
||||
itemName.textContent = item.name;
|
||||
|
||||
@@ -470,21 +470,21 @@ const contextMenus = {
|
||||
shareEl.className = 'existing-share-item';
|
||||
|
||||
const expiresText = share.expires_at ?
|
||||
`Vence: ${window.fileSharing.formatExpirationDate(share.expires_at)}` :
|
||||
'Sin vencimiento';
|
||||
`Expires: ${window.fileSharing.formatExpirationDate(share.expires_at)}` :
|
||||
'No expiration';
|
||||
|
||||
shareEl.innerHTML = `
|
||||
<div class="share-url">${share.url}</div>
|
||||
<div class="share-info">
|
||||
${share.password_protected ? '<span class="share-protected"><i class="fas fa-lock"></i> Con contraseña</span>' : ''}
|
||||
${share.password_protected ? '<span class="share-protected"><i class="fas fa-lock"></i> Password protected</span>' : ''}
|
||||
<span class="share-expiration">${expiresText}</span>
|
||||
</div>
|
||||
<div class="share-actions">
|
||||
<button class="btn btn-small copy-link-btn" data-share-url="${share.url}">
|
||||
<i class="fas fa-copy"></i> Copiar
|
||||
<i class="fas fa-copy"></i> Copy
|
||||
</button>
|
||||
<button class="btn btn-small btn-danger delete-link-btn" data-share-id="${share.id}">
|
||||
<i class="fas fa-trash"></i> Eliminar
|
||||
<i class="fas fa-trash"></i> Delete
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
@@ -507,9 +507,9 @@ const contextMenus = {
|
||||
const shareId = btn.getAttribute('data-share-id');
|
||||
|
||||
showConfirmDialog({
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_delete_share') : 'Eliminar enlace',
|
||||
message: window.i18n ? window.i18n.t('dialogs.confirm_delete_share_msg') : '¿Estás seguro de que quieres eliminar este enlace compartido?',
|
||||
confirmText: window.i18n ? window.i18n.t('actions.delete') : 'Eliminar',
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_delete_share') : 'Delete link',
|
||||
message: window.i18n ? window.i18n.t('dialogs.confirm_delete_share_msg') : 'Are you sure you want to delete this shared link?',
|
||||
confirmText: window.i18n ? window.i18n.t('actions.delete') : 'Delete',
|
||||
}).then(confirmed => {
|
||||
if (confirmed) {
|
||||
window.fileSharing.removeSharedLink(shareId);
|
||||
@@ -534,7 +534,7 @@ const contextMenus = {
|
||||
*/
|
||||
createSharedLink() {
|
||||
if (!window.app.shareDialogItem || !window.app.shareDialogItemType) {
|
||||
window.ui.showNotification('Error', 'No se pudo compartir el elemento');
|
||||
window.ui.showNotification('Error', 'Could not share the item');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -577,14 +577,14 @@ const contextMenus = {
|
||||
shareUrl.select();
|
||||
|
||||
// Show success message
|
||||
window.ui.showNotification('Enlace creado', 'Enlace compartido creado correctamente');
|
||||
window.ui.showNotification('Link created', 'Shared link created successfully');
|
||||
|
||||
// Reload existing shares
|
||||
this.showShareDialog(item, itemType);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error creating shared link:', error);
|
||||
window.ui.showNotification('Error', 'No se pudo crear el enlace compartido');
|
||||
window.ui.showNotification('Error', 'Could not create shared link');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -614,14 +614,14 @@ const contextMenus = {
|
||||
const shareUrl = window.app.notificationShareUrl;
|
||||
|
||||
if (!email || !shareUrl) {
|
||||
window.ui.showNotification('Error', 'Por favor, ingresa un correo electrónico válido');
|
||||
window.ui.showNotification('Error', 'Please enter a valid email address');
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate email format
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(email)) {
|
||||
window.ui.showNotification('Error', 'Por favor, ingresa un correo electrónico válido');
|
||||
window.ui.showNotification('Error', 'Please enter a valid email address');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -630,7 +630,7 @@ const contextMenus = {
|
||||
document.getElementById('notification-dialog').style.display = 'none';
|
||||
} catch (error) {
|
||||
console.error('Error sending notification:', error);
|
||||
window.ui.showNotification('Error', 'No se pudo enviar la notificación');
|
||||
window.ui.showNotification('Error', 'Could not send notification');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+17
-17
@@ -230,8 +230,8 @@ const favorites = {
|
||||
|
||||
// Show success notification
|
||||
window.ui.showNotification(
|
||||
'Añadido a favoritos',
|
||||
`"${name}" añadido a favoritos`
|
||||
'Added to favorites',
|
||||
`"${name}" added to favorites`
|
||||
);
|
||||
|
||||
return true;
|
||||
@@ -271,8 +271,8 @@ const favorites = {
|
||||
// Show success notification if item was found
|
||||
if (item) {
|
||||
window.ui.showNotification(
|
||||
'Eliminado de favoritos',
|
||||
`"${item.name}" eliminado de favoritos`
|
||||
'Removed from favorites',
|
||||
`"${item.name}" removed from favorites`
|
||||
);
|
||||
}
|
||||
return true;
|
||||
@@ -310,10 +310,10 @@ const favorites = {
|
||||
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 data-i18n="files.name">Name</div>
|
||||
<div data-i18n="files.type">Type</div>
|
||||
<div data-i18n="files.size">Size</div>
|
||||
<div data-i18n="files.modified">Modified</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -326,8 +326,8 @@ const favorites = {
|
||||
emptyState.className = 'empty-state';
|
||||
emptyState.innerHTML = `
|
||||
<i class="fas fa-star" style="font-size: 48px; color: #ddd; margin-bottom: 16px;"></i>
|
||||
<p>${window.i18n ? window.i18n.t('favorites.empty_state') : 'No hay elementos favoritos'}</p>
|
||||
<p>${window.i18n ? window.i18n.t('favorites.empty_hint') : 'Para marcar como favorito, haz clic derecho en cualquier archivo o carpeta'}</p>
|
||||
<p>${window.i18n ? window.i18n.t('favorites.empty_state') : 'No favorite items'}</p>
|
||||
<p>${window.i18n ? window.i18n.t('favorites.empty_hint') : 'To mark as favorite, right-click on any file or folder'}</p>
|
||||
`;
|
||||
filesGrid.appendChild(emptyState);
|
||||
return;
|
||||
@@ -359,7 +359,7 @@ const favorites = {
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error displaying favorites:', error);
|
||||
window.ui.showNotification('Error', 'Error al cargar elementos favoritos');
|
||||
window.ui.showNotification('Error', 'Error loading favorite items');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -468,7 +468,7 @@ const favorites = {
|
||||
<i class="fas fa-folder"></i>
|
||||
</div>
|
||||
<div class="file-name">${folder.name}</div>
|
||||
<div class="file-info">Carpeta</div>
|
||||
<div class="file-info">Folder</div>
|
||||
`;
|
||||
|
||||
// Click to navigate
|
||||
@@ -518,7 +518,7 @@ const favorites = {
|
||||
</div>
|
||||
<span>${folder.name}</span>
|
||||
</div>
|
||||
<div class="type-cell">${window.i18n ? window.i18n.t('files.file_types.folder') : 'Carpeta'}</div>
|
||||
<div class="type-cell">${window.i18n ? window.i18n.t('files.file_types.folder') : 'Folder'}</div>
|
||||
<div class="size-cell">--</div>
|
||||
<div class="date-cell">${formattedDate}</div>
|
||||
`;
|
||||
@@ -559,17 +559,17 @@ const favorites = {
|
||||
// Determine icon and type
|
||||
let iconClass = 'fas fa-file';
|
||||
let iconSpecialClass = '';
|
||||
let typeLabel = 'Documento';
|
||||
let typeLabel = 'Document';
|
||||
|
||||
if (file.mime_type) {
|
||||
if (file.mime_type.startsWith('image/')) {
|
||||
iconClass = 'fas fa-file-image';
|
||||
iconSpecialClass = 'image-icon';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.image') : 'Imagen';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.image') : 'Image';
|
||||
} else if (file.mime_type.startsWith('text/')) {
|
||||
iconClass = 'fas fa-file-alt';
|
||||
iconSpecialClass = 'text-icon';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.text') : 'Texto';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.text') : 'Text';
|
||||
} else if (file.mime_type.startsWith('video/')) {
|
||||
iconClass = 'fas fa-file-video';
|
||||
iconSpecialClass = 'video-icon';
|
||||
@@ -606,7 +606,7 @@ const favorites = {
|
||||
<i class="${iconClass}"></i>
|
||||
</div>
|
||||
<div class="file-name">${file.name}</div>
|
||||
<div class="file-info">Modificado ${formattedDate.split(' ')[0]}</div>
|
||||
<div class="file-info">Modified ${formattedDate.split(' ')[0]}</div>
|
||||
`;
|
||||
|
||||
// Download on click
|
||||
|
||||
+91
-91
@@ -49,8 +49,8 @@ const fileOps = {
|
||||
try {
|
||||
console.log(`Uploading file to folder: ${targetFolderId || 'root'}`);
|
||||
|
||||
// Usamos la URL correcta para la subida de archivos
|
||||
console.log('Formulario a enviar:', {
|
||||
// We use the correct URL for file upload
|
||||
console.log('Form to submit:', {
|
||||
file: file.name,
|
||||
size: file.size,
|
||||
folder_id: targetFolderId || 'root'
|
||||
@@ -59,16 +59,16 @@ const fileOps = {
|
||||
const response = await fetch('/api/files/upload', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
// Añadir cache: 'no-store' para evitar problemas de caché durante la subida
|
||||
// Add cache: 'no-store' to avoid cache issues during upload
|
||||
cache: 'no-store',
|
||||
headers: {
|
||||
...getAuthHeaders(),
|
||||
// Agregar este encabezado para forzar recargas frescas
|
||||
// Add this header to force fresh reloads
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Respuesta del servidor:', {
|
||||
console.log('Server response:', {
|
||||
status: response.status,
|
||||
statusText: response.statusText
|
||||
});
|
||||
@@ -83,11 +83,11 @@ const fileOps = {
|
||||
console.log(`Successfully uploaded ${file.name}`, responseData);
|
||||
|
||||
// Show success notification immediately
|
||||
window.ui.showNotification('Archivo subido', `${file.name} completado`);
|
||||
window.ui.showNotification('File uploaded', `${file.name} completed`);
|
||||
|
||||
if (i === totalFiles - 1) {
|
||||
// Last file uploaded - wait and reload once
|
||||
console.log('Último archivo subido, esperando antes de recargar...');
|
||||
console.log('Last file uploaded, waiting before reloading...');
|
||||
|
||||
// Wait for backend to persist
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
@@ -96,7 +96,7 @@ const fileOps = {
|
||||
try {
|
||||
await window.loadFiles({forceRefresh: true});
|
||||
} catch (reloadError) {
|
||||
console.error("Error recargando archivos:", reloadError);
|
||||
console.error("Error reloading files:", reloadError);
|
||||
}
|
||||
|
||||
// Hide upload UI
|
||||
@@ -109,11 +109,11 @@ const fileOps = {
|
||||
} else {
|
||||
const errorData = await response.text();
|
||||
console.error('Upload error:', errorData);
|
||||
window.ui.showNotification('Error', `Error al subir el archivo: ${file.name}`);
|
||||
window.ui.showNotification('Error', `Error uploading file: ${file.name}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Network error during upload:', error);
|
||||
window.ui.showNotification('Error', `Error de red al subir el archivo: ${file.name}`);
|
||||
window.ui.showNotification('Error', `Network error uploading file: ${file.name}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -181,7 +181,7 @@ const fileOps = {
|
||||
console.log(`Created folder: ${folderPath} -> ${folder.id}`);
|
||||
} else {
|
||||
console.error(`Error creating folder ${folderPath}:`, await response.text());
|
||||
window.ui.showNotification('Error', `Error creando carpeta: ${folderName}`);
|
||||
window.ui.showNotification('Error', `Error creating folder: ${folderName}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Network error creating folder ${folderPath}:`, error);
|
||||
@@ -228,7 +228,7 @@ const fileOps = {
|
||||
}
|
||||
|
||||
// Finish up
|
||||
window.ui.showNotification('Carpeta subida', `${uploadedCount} archivos subidos correctamente`);
|
||||
window.ui.showNotification('Folder uploaded', `${uploadedCount} files uploaded successfully`);
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
|
||||
@@ -253,7 +253,7 @@ const fileOps = {
|
||||
try {
|
||||
console.log('Creating folder with name:', name);
|
||||
|
||||
// Enviar la solicitud real al backend para crear la carpeta
|
||||
// Send the actual request to the backend to create the folder
|
||||
const response = await fetch('/api/folders', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -268,28 +268,28 @@ const fileOps = {
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
// Obtener la carpeta creada del backend
|
||||
// Get the created folder from the backend
|
||||
const folder = await response.json();
|
||||
console.log('Folder created successfully:', folder);
|
||||
|
||||
// Añadir la carpeta a la vista de inmediato para feedback instantáneo
|
||||
// Add the folder to the view immediately for instant feedback
|
||||
window.ui.addFolderToView(folder);
|
||||
|
||||
// Esperar para permitir que el backend guarde los cambios
|
||||
// Wait to allow the backend to save the changes
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
// Recargar los archivos para refrescar la vista
|
||||
// Reload files to refresh the view
|
||||
await window.loadFiles({forceRefresh: true});
|
||||
|
||||
window.ui.showNotification('Carpeta creada', `"${name}" creada correctamente`);
|
||||
window.ui.showNotification('Folder created', `"${name}" created successfully`);
|
||||
} else {
|
||||
const errorData = await response.text();
|
||||
console.error('Create folder error:', errorData);
|
||||
window.ui.showNotification('Error', 'Error al crear la carpeta');
|
||||
window.ui.showNotification('Error', 'Error creating the folder');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating folder:', error);
|
||||
window.ui.showNotification('Error', 'Error al crear la carpeta');
|
||||
window.ui.showNotification('Error', 'Error creating the folder');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -315,22 +315,22 @@ const fileOps = {
|
||||
if (response.ok) {
|
||||
// Reload files after moving
|
||||
await window.loadFiles();
|
||||
window.ui.showNotification('Archivo movido', 'Archivo movido correctamente');
|
||||
window.ui.showNotification('File moved', 'File moved successfully');
|
||||
return true;
|
||||
} else {
|
||||
let errorMessage = 'Error desconocido';
|
||||
let errorMessage = 'Unknown error';
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
errorMessage = errorData.error || 'Error desconocido';
|
||||
errorMessage = errorData.error || 'Unknown error';
|
||||
} catch (e) {
|
||||
errorMessage = 'Error al procesar la respuesta del servidor';
|
||||
errorMessage = 'Error processing server response';
|
||||
}
|
||||
window.ui.showNotification('Error', `Error al mover el archivo: ${errorMessage}`);
|
||||
window.ui.showNotification('Error', `Error moving the file: ${errorMessage}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error moving file:', error);
|
||||
window.ui.showNotification('Error', 'Error al mover el archivo');
|
||||
window.ui.showNotification('Error', 'Error moving the file');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@@ -357,22 +357,22 @@ const fileOps = {
|
||||
if (response.ok) {
|
||||
// Reload files after moving
|
||||
await window.loadFiles();
|
||||
window.ui.showNotification('Carpeta movida', 'Carpeta movida correctamente');
|
||||
window.ui.showNotification('Folder moved', 'Folder moved successfully');
|
||||
return true;
|
||||
} else {
|
||||
let errorMessage = 'Error desconocido';
|
||||
let errorMessage = 'Unknown error';
|
||||
try {
|
||||
const errorData = await response.json();
|
||||
errorMessage = errorData.error || 'Error desconocido';
|
||||
errorMessage = errorData.error || 'Unknown error';
|
||||
} catch (e) {
|
||||
errorMessage = 'Error al procesar la respuesta del servidor';
|
||||
errorMessage = 'Error processing server response';
|
||||
}
|
||||
window.ui.showNotification('Error', `Error al mover la carpeta: ${errorMessage}`);
|
||||
window.ui.showNotification('Error', `Error moving the folder: ${errorMessage}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error moving folder:', error);
|
||||
window.ui.showNotification('Error', 'Error al mover la carpeta');
|
||||
window.ui.showNotification('Error', 'Error moving the folder');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@@ -400,26 +400,26 @@ const fileOps = {
|
||||
|
||||
if (response.ok) {
|
||||
window.ui.showNotification(
|
||||
window.i18n ? window.i18n.t('notifications.file_renamed') : 'Archivo renombrado',
|
||||
window.i18n ? window.i18n.t('notifications.file_renamed_to', { name: newName }) : `Archivo renombrado a "${newName}"`
|
||||
window.i18n ? window.i18n.t('notifications.file_renamed') : 'File renamed',
|
||||
window.i18n ? window.i18n.t('notifications.file_renamed_to', { name: newName }) : `File renamed to "${newName}"`
|
||||
);
|
||||
return true;
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
console.error('Error response:', errorText);
|
||||
let errorMessage = 'Error desconocido';
|
||||
let errorMessage = 'Unknown error';
|
||||
try {
|
||||
const errorData = JSON.parse(errorText);
|
||||
errorMessage = errorData.error || response.statusText;
|
||||
} catch (e) {
|
||||
errorMessage = errorText || response.statusText;
|
||||
}
|
||||
window.ui.showNotification('Error', `Error al renombrar el archivo: ${errorMessage}`);
|
||||
window.ui.showNotification('Error', `Error renaming the file: ${errorMessage}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error renaming file:', error);
|
||||
window.ui.showNotification('Error', 'Error al renombrar el archivo');
|
||||
window.ui.showNotification('Error', 'Error renaming the file');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@@ -446,13 +446,13 @@ const fileOps = {
|
||||
console.log('Response status:', response.status);
|
||||
|
||||
if (response.ok) {
|
||||
window.ui.showNotification('Carpeta renombrada', `Carpeta renombrada a "${newName}"`);
|
||||
window.ui.showNotification('Folder renamed', `Folder renamed to "${newName}"`);
|
||||
return true;
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
console.error('Error response:', errorText);
|
||||
|
||||
let errorMessage = 'Error desconocido';
|
||||
let errorMessage = 'Unknown error';
|
||||
try {
|
||||
// Try to parse as JSON
|
||||
const errorData = JSON.parse(errorText);
|
||||
@@ -462,12 +462,12 @@ const fileOps = {
|
||||
errorMessage = errorText || response.statusText;
|
||||
}
|
||||
|
||||
window.ui.showNotification('Error', `Error al renombrar la carpeta: ${errorMessage}`);
|
||||
window.ui.showNotification('Error', `Error renaming the folder: ${errorMessage}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error renaming folder:', error);
|
||||
window.ui.showNotification('Error', 'Error al renombrar la carpeta');
|
||||
window.ui.showNotification('Error', 'Error renaming the folder');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@@ -480,9 +480,9 @@ const fileOps = {
|
||||
*/
|
||||
async deleteFile(fileId, fileName) {
|
||||
const confirmed = await showConfirmDialog({
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_delete') : 'Mover a papelera',
|
||||
message: window.i18n ? window.i18n.t('dialogs.confirm_delete_file', { name: fileName }) : `¿Estás seguro de que quieres mover a la papelera el archivo "${fileName}"?`,
|
||||
confirmText: window.i18n ? window.i18n.t('actions.delete') : 'Eliminar',
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_delete') : 'Move to trash',
|
||||
message: window.i18n ? window.i18n.t('dialogs.confirm_delete_file', { name: fileName }) : `Are you sure you want to move the file "${fileName}" to trash?`,
|
||||
confirmText: window.i18n ? window.i18n.t('actions.delete') : 'Delete',
|
||||
});
|
||||
if (!confirmed) return false;
|
||||
|
||||
@@ -495,7 +495,7 @@ const fileOps = {
|
||||
|
||||
if (response.ok) {
|
||||
window.loadFiles();
|
||||
window.ui.showNotification('Archivo movido a papelera', `"${fileName}" movido a la papelera`);
|
||||
window.ui.showNotification('File moved to trash', `"${fileName}" moved to trash`);
|
||||
return true;
|
||||
} else {
|
||||
// Fallback to direct deletion if trash fails
|
||||
@@ -506,16 +506,16 @@ const fileOps = {
|
||||
|
||||
if (fallbackResponse.ok) {
|
||||
window.loadFiles();
|
||||
window.ui.showNotification('Archivo eliminado', `"${fileName}" eliminado correctamente`);
|
||||
window.ui.showNotification('File deleted', `"${fileName}" deleted successfully`);
|
||||
return true;
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al eliminar el archivo');
|
||||
window.ui.showNotification('Error', 'Error deleting the file');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting file:', error);
|
||||
window.ui.showNotification('Error', 'Error al eliminar el archivo');
|
||||
window.ui.showNotification('Error', 'Error deleting the file');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@@ -528,9 +528,9 @@ const fileOps = {
|
||||
*/
|
||||
async deleteFolder(folderId, folderName) {
|
||||
const confirmed = await showConfirmDialog({
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_delete') : 'Mover a papelera',
|
||||
message: window.i18n ? window.i18n.t('dialogs.confirm_delete_folder', { name: folderName }) : `¿Estás seguro de que quieres mover a la papelera la carpeta "${folderName}" y todo su contenido?`,
|
||||
confirmText: window.i18n ? window.i18n.t('actions.delete') : 'Eliminar',
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_delete') : 'Move to trash',
|
||||
message: window.i18n ? window.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: window.i18n ? window.i18n.t('actions.delete') : 'Delete',
|
||||
});
|
||||
if (!confirmed) return false;
|
||||
|
||||
@@ -548,7 +548,7 @@ const fileOps = {
|
||||
window.ui.updateBreadcrumb('');
|
||||
}
|
||||
window.loadFiles();
|
||||
window.ui.showNotification('Carpeta movida a papelera', `"${folderName}" movida a la papelera`);
|
||||
window.ui.showNotification('Folder moved to trash', `"${folderName}" moved to trash`);
|
||||
return true;
|
||||
} else {
|
||||
// Fallback to direct deletion if trash fails
|
||||
@@ -564,23 +564,23 @@ const fileOps = {
|
||||
window.ui.updateBreadcrumb('');
|
||||
}
|
||||
window.loadFiles();
|
||||
window.ui.showNotification('Carpeta eliminada', `"${folderName}" eliminada correctamente`);
|
||||
window.ui.showNotification('Folder deleted', `"${folderName}" deleted successfully`);
|
||||
return true;
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al eliminar la carpeta');
|
||||
window.ui.showNotification('Error', 'Error deleting the folder');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting folder:', error);
|
||||
window.ui.showNotification('Error', 'Error al eliminar la carpeta');
|
||||
window.ui.showNotification('Error', 'Error deleting the folder');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Obtener elementos de la papelera
|
||||
* @returns {Promise<Array>} - Lista de elementos en la papelera
|
||||
* Get trash items
|
||||
* @returns {Promise<Array>} - List of trash items
|
||||
*/
|
||||
async getTrashItems() {
|
||||
try {
|
||||
@@ -601,9 +601,9 @@ const fileOps = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Restaurar un elemento desde la papelera
|
||||
* @param {string} trashId - ID del elemento en la papelera
|
||||
* @returns {Promise<boolean>} - Éxito de la operación
|
||||
* Restore an item from trash
|
||||
* @param {string} trashId - Trash item ID
|
||||
* @returns {Promise<boolean>} - Operation success
|
||||
*/
|
||||
async restoreFromTrash(trashId) {
|
||||
try {
|
||||
@@ -617,29 +617,29 @@ const fileOps = {
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
window.ui.showNotification('Elemento restaurado', 'Elemento restaurado correctamente');
|
||||
window.ui.showNotification('Item restored', 'Item restored successfully');
|
||||
return true;
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al restaurar el elemento');
|
||||
window.ui.showNotification('Error', 'Error restoring the item');
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error restoring item from trash:', error);
|
||||
window.ui.showNotification('Error', 'Error al restaurar el elemento');
|
||||
window.ui.showNotification('Error', 'Error restoring the item');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Eliminar permanentemente un elemento de la papelera
|
||||
* @param {string} trashId - ID del elemento en la papelera
|
||||
* @returns {Promise<boolean>} - Éxito de la operación
|
||||
* Permanently delete a trash item
|
||||
* @param {string} trashId - Trash item ID
|
||||
* @returns {Promise<boolean>} - Operation success
|
||||
*/
|
||||
async deletePermanently(trashId) {
|
||||
const confirmed = await showConfirmDialog({
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_permanent_delete') : 'Eliminar permanentemente',
|
||||
message: window.i18n ? window.i18n.t('dialogs.confirm_permanent_delete_msg') : '¿Estás seguro de que quieres eliminar permanentemente este elemento? Esta acción no se puede deshacer.',
|
||||
confirmText: window.i18n ? window.i18n.t('actions.delete_permanently') : 'Eliminar permanentemente',
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_permanent_delete') : 'Delete permanently',
|
||||
message: window.i18n ? window.i18n.t('dialogs.confirm_permanent_delete_msg') : 'Are you sure you want to permanently delete this item? This action cannot be undone.',
|
||||
confirmText: window.i18n ? window.i18n.t('actions.delete_permanently') : 'Delete permanently',
|
||||
});
|
||||
if (!confirmed) return false;
|
||||
|
||||
@@ -650,28 +650,28 @@ const fileOps = {
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
window.ui.showNotification('Elemento eliminado', 'Elemento eliminado permanentemente');
|
||||
window.ui.showNotification('Item deleted', 'Item permanently deleted');
|
||||
return true;
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al eliminar el elemento');
|
||||
window.ui.showNotification('Error', 'Error deleting the item');
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting item permanently:', error);
|
||||
window.ui.showNotification('Error', 'Error al eliminar el elemento');
|
||||
window.ui.showNotification('Error', 'Error deleting the item');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Vaciar la papelera
|
||||
* @returns {Promise<boolean>} - Éxito de la operación
|
||||
* Empty the trash
|
||||
* @returns {Promise<boolean>} - Operation success
|
||||
*/
|
||||
async emptyTrash() {
|
||||
const confirmed = await showConfirmDialog({
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_empty_trash') : 'Vaciar papelera',
|
||||
message: 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.',
|
||||
confirmText: window.i18n ? window.i18n.t('actions.empty_trash') : 'Vaciar papelera',
|
||||
title: window.i18n ? window.i18n.t('dialogs.confirm_empty_trash') : 'Empty trash',
|
||||
message: window.i18n ? window.i18n.t('trash.empty_confirm') : 'Are you sure you want to empty the trash? This action will permanently delete all items.',
|
||||
confirmText: window.i18n ? window.i18n.t('actions.empty_trash') : 'Empty trash',
|
||||
});
|
||||
if (!confirmed) return false;
|
||||
|
||||
@@ -682,23 +682,23 @@ const fileOps = {
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
window.ui.showNotification('Papelera vaciada', 'La papelera ha sido vaciada correctamente');
|
||||
window.ui.showNotification('Trash emptied', 'The trash has been emptied successfully');
|
||||
return true;
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al vaciar la papelera');
|
||||
window.ui.showNotification('Error', 'Error emptying the trash');
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error emptying trash:', error);
|
||||
window.ui.showNotification('Error', 'Error al vaciar la papelera');
|
||||
window.ui.showNotification('Error', 'Error emptying the trash');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Descargar un archivo
|
||||
* @param {string} fileId - ID del archivo
|
||||
* @param {string} fileName - Nombre del archivo
|
||||
* Download a file
|
||||
* @param {string} fileId - File ID
|
||||
* @param {string} fileName - File name
|
||||
*/
|
||||
async downloadFile(fileId, fileName) {
|
||||
try {
|
||||
@@ -716,23 +716,23 @@ const fileOps = {
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al descargar el archivo');
|
||||
window.ui.showNotification('Error', 'Error downloading the file');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error downloading file:', error);
|
||||
window.ui.showNotification('Error', 'Error al descargar el archivo');
|
||||
window.ui.showNotification('Error', 'Error downloading the file');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Descargar una carpeta como ZIP
|
||||
* @param {string} folderId - ID de la carpeta
|
||||
* @param {string} folderName - Nombre de la carpeta
|
||||
* Download a folder as ZIP
|
||||
* @param {string} folderId - Folder ID
|
||||
* @param {string} folderName - Folder name
|
||||
*/
|
||||
async downloadFolder(folderId, folderName) {
|
||||
try {
|
||||
// Show notification to user
|
||||
window.ui.showNotification('Preparando descarga', 'Preparando la carpeta para descargar...');
|
||||
window.ui.showNotification('Preparing download', 'Preparing the folder for download...');
|
||||
|
||||
const response = await fetch(`/api/folders/${folderId}/download?format=zip`, {
|
||||
headers: getAuthHeaders()
|
||||
@@ -748,11 +748,11 @@ const fileOps = {
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al descargar la carpeta');
|
||||
window.ui.showNotification('Error', 'Error downloading the folder');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error downloading folder:', error);
|
||||
window.ui.showNotification('Error', 'Error al descargar la carpeta');
|
||||
window.ui.showNotification('Error', 'Error downloading the folder');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -214,11 +214,11 @@ const fileSharing = {
|
||||
copyLinkToClipboard(url) {
|
||||
try {
|
||||
navigator.clipboard.writeText(url);
|
||||
window.ui.showNotification('Enlace copiado', 'Enlace copiado al portapapeles');
|
||||
window.ui.showNotification('Link copied', 'Link copied to clipboard');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error copying to clipboard:', error);
|
||||
window.ui.showNotification('Error', 'No se pudo copiar el enlace');
|
||||
window.ui.showNotification('Error', 'Could not copy link');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@@ -229,7 +229,7 @@ const fileSharing = {
|
||||
* @returns {string} - Formatted date string
|
||||
*/
|
||||
formatExpirationDate(dateString) {
|
||||
if (!dateString) return 'Sin vencimiento';
|
||||
if (!dateString) return 'No expiration';
|
||||
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
|
||||
@@ -252,11 +252,11 @@ const fileSharing = {
|
||||
// Simulate network delay
|
||||
//await new Promise(resolve => setTimeout(resolve, 800));
|
||||
|
||||
window.ui.showNotification('Notificación enviada', `Se envió notificación a ${recipientEmail}`);
|
||||
window.ui.showNotification('Notification sent', `Notification sent to ${recipientEmail}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error sending share notification:', error);
|
||||
window.ui.showNotification('Error', 'No se pudo enviar la notificación');
|
||||
window.ui.showNotification('Error', 'Could not send notification');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
+11
-11
@@ -110,10 +110,10 @@ const recent = {
|
||||
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.last_accessed">Último acceso</div>
|
||||
<div data-i18n="files.name">Name</div>
|
||||
<div data-i18n="files.type">Type</div>
|
||||
<div data-i18n="files.size">Size</div>
|
||||
<div data-i18n="files.last_accessed">Last accessed</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -126,8 +126,8 @@ const recent = {
|
||||
emptyState.className = 'empty-state';
|
||||
emptyState.innerHTML = `
|
||||
<i class="fas fa-clock" style="font-size: 48px; color: #ddd; margin-bottom: 16px;"></i>
|
||||
<p>${window.i18n ? window.i18n.t('recent.empty_state') : 'No hay archivos recientes'}</p>
|
||||
<p>${window.i18n ? window.i18n.t('recent.empty_hint') : 'Los archivos que abras aparecerán aquí'}</p>
|
||||
<p>${window.i18n ? window.i18n.t('recent.empty_state') : 'No recent files'}</p>
|
||||
<p>${window.i18n ? window.i18n.t('recent.empty_hint') : 'Files you open will appear here'}</p>
|
||||
`;
|
||||
filesGrid.appendChild(emptyState);
|
||||
return;
|
||||
@@ -143,7 +143,7 @@ const recent = {
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error displaying recent files:', error);
|
||||
window.ui.showNotification('Error', 'Error al cargar archivos recientes');
|
||||
window.ui.showNotification('Error', 'Error loading recent files');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -157,17 +157,17 @@ const recent = {
|
||||
// Determine icon and type
|
||||
let iconClass = 'fas fa-file';
|
||||
let iconSpecialClass = '';
|
||||
let typeLabel = 'Documento';
|
||||
let typeLabel = 'Document';
|
||||
|
||||
if (file.mime_type) {
|
||||
if (file.mime_type.startsWith('image/')) {
|
||||
iconClass = 'fas fa-file-image';
|
||||
iconSpecialClass = 'image-icon';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.image') : 'Imagen';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.image') : 'Image';
|
||||
} else if (file.mime_type.startsWith('text/')) {
|
||||
iconClass = 'fas fa-file-alt';
|
||||
iconSpecialClass = 'text-icon';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.text') : 'Texto';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.text') : 'Text';
|
||||
} else if (file.mime_type.startsWith('video/')) {
|
||||
iconClass = 'fas fa-file-video';
|
||||
iconSpecialClass = 'video-icon';
|
||||
@@ -204,7 +204,7 @@ const recent = {
|
||||
<i class="${iconClass}"></i>
|
||||
</div>
|
||||
<div class="file-name">${file.name}</div>
|
||||
<div class="file-info">Accedido ${formattedDate.split(' ')[0]}</div>
|
||||
<div class="file-info">Accessed ${formattedDate.split(' ')[0]}</div>
|
||||
`;
|
||||
|
||||
// Download on click
|
||||
|
||||
+12
-12
@@ -52,7 +52,7 @@ const search = {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error performing search:', error);
|
||||
window.ui.showNotification('Error', 'Error al realizar la búsqueda');
|
||||
window.ui.showNotification('Error', 'Error performing search');
|
||||
return { files: [], folders: [], total_count: 0 };
|
||||
}
|
||||
},
|
||||
@@ -91,7 +91,7 @@ const search = {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error performing advanced search:', error);
|
||||
window.ui.showNotification('Error', 'Error al realizar la búsqueda avanzada');
|
||||
window.ui.showNotification('Error', 'Error performing advanced search');
|
||||
return { files: [], folders: [], total_count: 0 };
|
||||
}
|
||||
},
|
||||
@@ -109,10 +109,10 @@ const search = {
|
||||
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 data-i18n="files.name">Name</div>
|
||||
<div data-i18n="files.type">Type</div>
|
||||
<div data-i18n="files.size">Size</div>
|
||||
<div data-i18n="files.modified">Modified</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -120,9 +120,9 @@ const search = {
|
||||
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>
|
||||
<h3>Search results (${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
|
||||
<i class="fas fa-times"></i> Clear search
|
||||
</button>
|
||||
`;
|
||||
filesGrid.appendChild(searchHeader);
|
||||
@@ -147,7 +147,7 @@ const search = {
|
||||
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>
|
||||
<p>No results found for this search</p>
|
||||
`;
|
||||
filesGrid.appendChild(emptyState);
|
||||
return;
|
||||
@@ -178,15 +178,15 @@ const search = {
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
window.ui.showNotification('Caché limpiada', 'Caché de búsqueda limpiada correctamente');
|
||||
window.ui.showNotification('Cache cleared', 'Search cache cleared successfully');
|
||||
return true;
|
||||
} else {
|
||||
window.ui.showNotification('Error', 'Error al limpiar la caché de búsqueda');
|
||||
window.ui.showNotification('Error', 'Error clearing search cache');
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error clearing search cache:', error);
|
||||
window.ui.showNotification('Error', 'Error al limpiar la caché de búsqueda');
|
||||
window.ui.showNotification('Error', 'Error clearing search cache');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+66
-66
@@ -16,24 +16,24 @@ const ui = {
|
||||
folderMenu.id = 'folder-context-menu';
|
||||
folderMenu.innerHTML = `
|
||||
<div class="context-menu-item" id="download-folder-option">
|
||||
<i class="fas fa-download"></i> <span data-i18n="actions.download">Descargar</span>
|
||||
<i class="fas fa-download"></i> <span data-i18n="actions.download">Download</span>
|
||||
</div>
|
||||
<div class="context-menu-item" id="favorite-folder-option">
|
||||
<i class="fas fa-star"></i> <span data-i18n="actions.favorite">Añadir a favoritos</span>
|
||||
<i class="fas fa-star"></i> <span data-i18n="actions.favorite">Add to favorites</span>
|
||||
</div>
|
||||
<div class="context-menu-item" id="share-folder-option">
|
||||
<i class="fas fa-share-alt"></i> <span data-i18n="actions.share">Compartir</span>
|
||||
<i class="fas fa-share-alt"></i> <span data-i18n="actions.share">Share</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-item" id="rename-folder-option">
|
||||
<i class="fas fa-pen"></i> <span data-i18n="actions.rename">Renombrar</span>
|
||||
<i class="fas fa-pen"></i> <span data-i18n="actions.rename">Rename</span>
|
||||
</div>
|
||||
<div class="context-menu-item" id="move-folder-option">
|
||||
<i class="fas fa-arrows-alt"></i> <span data-i18n="actions.move">Mover a...</span>
|
||||
<i class="fas fa-arrows-alt"></i> <span data-i18n="actions.move">Move to...</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-item context-menu-item-danger" id="delete-folder-option">
|
||||
<i class="fas fa-trash-alt"></i> <span data-i18n="actions.delete">Eliminar</span>
|
||||
<i class="fas fa-trash-alt"></i> <span data-i18n="actions.delete">Delete</span>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(folderMenu);
|
||||
@@ -46,28 +46,28 @@ const ui = {
|
||||
fileMenu.id = 'file-context-menu';
|
||||
fileMenu.innerHTML = `
|
||||
<div class="context-menu-item" id="view-file-option">
|
||||
<i class="fas fa-eye"></i> <span data-i18n="actions.view">Ver</span>
|
||||
<i class="fas fa-eye"></i> <span data-i18n="actions.view">View</span>
|
||||
</div>
|
||||
<div class="context-menu-item" id="download-file-option">
|
||||
<i class="fas fa-download"></i> <span data-i18n="actions.download">Descargar</span>
|
||||
<i class="fas fa-download"></i> <span data-i18n="actions.download">Download</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-item" id="favorite-file-option">
|
||||
<i class="fas fa-star"></i> <span data-i18n="actions.favorite">Añadir a favoritos</span>
|
||||
<i class="fas fa-star"></i> <span data-i18n="actions.favorite">Add to favorites</span>
|
||||
</div>
|
||||
<div class="context-menu-item" id="share-file-option">
|
||||
<i class="fas fa-share-alt"></i> <span data-i18n="actions.share">Compartir</span>
|
||||
<i class="fas fa-share-alt"></i> <span data-i18n="actions.share">Share</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-item" id="rename-file-option">
|
||||
<i class="fas fa-pen"></i> <span data-i18n="actions.rename">Renombrar</span>
|
||||
<i class="fas fa-pen"></i> <span data-i18n="actions.rename">Rename</span>
|
||||
</div>
|
||||
<div class="context-menu-item" id="move-file-option">
|
||||
<i class="fas fa-arrows-alt"></i> <span data-i18n="actions.move">Mover a...</span>
|
||||
<i class="fas fa-arrows-alt"></i> <span data-i18n="actions.move">Move to...</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-item context-menu-item-danger" id="delete-file-option">
|
||||
<i class="fas fa-trash-alt"></i> <span data-i18n="actions.delete">Eliminar</span>
|
||||
<i class="fas fa-trash-alt"></i> <span data-i18n="actions.delete">Delete</span>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(fileMenu);
|
||||
@@ -82,14 +82,14 @@ const ui = {
|
||||
<div class="rename-dialog-content">
|
||||
<div class="rename-dialog-header">
|
||||
<i class="fas fa-pen" style="color:#ff5e3a"></i>
|
||||
<span data-i18n="dialogs.rename_folder">Renombrar</span>
|
||||
<span data-i18n="dialogs.rename_folder">Rename</span>
|
||||
</div>
|
||||
<div class="rename-dialog-body">
|
||||
<input type="text" id="rename-input" data-i18n-placeholder="dialogs.new_name" placeholder="Nuevo nombre">
|
||||
<input type="text" id="rename-input" data-i18n-placeholder="dialogs.new_name" placeholder="New name">
|
||||
</div>
|
||||
<div class="rename-dialog-buttons">
|
||||
<button class="btn btn-secondary" id="rename-cancel-btn" data-i18n="actions.cancel">Cancelar</button>
|
||||
<button class="btn btn-primary" id="rename-confirm-btn" data-i18n="actions.rename">Renombrar</button>
|
||||
<button class="btn btn-secondary" id="rename-cancel-btn" data-i18n="actions.cancel">Cancel</button>
|
||||
<button class="btn btn-primary" id="rename-confirm-btn" data-i18n="actions.rename">Rename</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -105,19 +105,19 @@ const ui = {
|
||||
<div class="rename-dialog-content">
|
||||
<div class="rename-dialog-header">
|
||||
<i class="fas fa-arrows-alt" style="color:#ff5e3a"></i>
|
||||
<span data-i18n="dialogs.move_file">Mover</span>
|
||||
<span data-i18n="dialogs.move_file">Move</span>
|
||||
</div>
|
||||
<div class="rename-dialog-body">
|
||||
<p style="margin:0 0 12px;color:#718096;font-size:14px" data-i18n="dialogs.select_destination">Selecciona la carpeta destino:</p>
|
||||
<p style="margin:0 0 12px;color:#718096;font-size:14px" data-i18n="dialogs.select_destination">Select destination folder:</p>
|
||||
<div id="folder-select-container" style="max-height:220px;overflow-y:auto;">
|
||||
<div class="folder-select-item selected" data-folder-id="">
|
||||
<i class="fas fa-folder"></i> <span data-i18n="dialogs.root">Raíz</span>
|
||||
<i class="fas fa-folder"></i> <span data-i18n="dialogs.root">Root</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rename-dialog-buttons">
|
||||
<button class="btn btn-secondary" id="move-cancel-btn" data-i18n="actions.cancel">Cancelar</button>
|
||||
<button class="btn btn-primary" id="move-confirm-btn" data-i18n="actions.move_to">Mover</button>
|
||||
<button class="btn btn-secondary" id="move-cancel-btn" data-i18n="actions.cancel">Cancel</button>
|
||||
<button class="btn btn-primary" id="move-confirm-btn" data-i18n="actions.move_to">Move</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -133,67 +133,67 @@ const ui = {
|
||||
<div class="share-dialog-content">
|
||||
<div class="share-dialog-header">
|
||||
<i class="fas fa-share-alt" style="color:#ff5e3a"></i>
|
||||
<span data-i18n="dialogs.share_file">Compartir archivo</span>
|
||||
<span data-i18n="dialogs.share_file">Share file</span>
|
||||
</div>
|
||||
<div class="shared-item-info">
|
||||
<strong>Elemento:</strong> <span id="shared-item-name"></span>
|
||||
<strong>Item:</strong> <span id="shared-item-name"></span>
|
||||
</div>
|
||||
|
||||
<div id="existing-shares-section" style="display:none; margin: 15px 0;">
|
||||
<h3 data-i18n="dialogs.existing_shares">Enlaces compartidos existentes</h3>
|
||||
<h3 data-i18n="dialogs.existing_shares">Existing shared links</h3>
|
||||
<div id="existing-shares-container"></div>
|
||||
</div>
|
||||
|
||||
<div class="share-options">
|
||||
<h3 data-i18n="dialogs.share_options">Opciones de compartición</h3>
|
||||
<h3 data-i18n="dialogs.share_options">Share options</h3>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="share-password" data-i18n="dialogs.password">Contraseña (opcional):</label>
|
||||
<input type="password" id="share-password" placeholder="Proteger con contraseña">
|
||||
<label for="share-password" data-i18n="dialogs.password">Password (optional):</label>
|
||||
<input type="password" id="share-password" placeholder="Protect with password">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="share-expiration" data-i18n="dialogs.expiration">Fecha de vencimiento (opcional):</label>
|
||||
<label for="share-expiration" data-i18n="dialogs.expiration">Expiration date (optional):</label>
|
||||
<input type="date" id="share-expiration">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label data-i18n="dialogs.permissions">Permisos:</label>
|
||||
<label data-i18n="dialogs.permissions">Permissions:</label>
|
||||
<div class="permission-options">
|
||||
<div class="permission-option">
|
||||
<input type="checkbox" id="share-permission-read" checked>
|
||||
<label for="share-permission-read" data-i18n="permissions.read">Lectura</label>
|
||||
<label for="share-permission-read" data-i18n="permissions.read">Read</label>
|
||||
</div>
|
||||
<div class="permission-option">
|
||||
<input type="checkbox" id="share-permission-write">
|
||||
<label for="share-permission-write" data-i18n="permissions.write">Escritura</label>
|
||||
<label for="share-permission-write" data-i18n="permissions.write">Write</label>
|
||||
</div>
|
||||
<div class="permission-option">
|
||||
<input type="checkbox" id="share-permission-reshare">
|
||||
<label for="share-permission-reshare" data-i18n="permissions.reshare">Permitir compartir</label>
|
||||
<label for="share-permission-reshare" data-i18n="permissions.reshare">Allow sharing</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="new-share-section" style="display:none; margin: 15px 0;">
|
||||
<h3 data-i18n="dialogs.generated_link">Enlace generado</h3>
|
||||
<h3 data-i18n="dialogs.generated_link">Generated link</h3>
|
||||
<div class="form-group">
|
||||
<input type="text" id="generated-share-url" readonly>
|
||||
<div class="share-link-actions">
|
||||
<button class="btn btn-small" id="copy-share-btn">
|
||||
<i class="fas fa-copy"></i> <span data-i18n="actions.copy">Copiar</span>
|
||||
<i class="fas fa-copy"></i> <span data-i18n="actions.copy">Copy</span>
|
||||
</button>
|
||||
<button class="btn btn-small" id="notify-share-btn">
|
||||
<i class="fas fa-envelope"></i> <span data-i18n="actions.notify">Notificar</span>
|
||||
<i class="fas fa-envelope"></i> <span data-i18n="actions.notify">Notify</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="share-dialog-buttons">
|
||||
<button class="btn btn-secondary" id="share-cancel-btn" data-i18n="actions.cancel">Cancelar</button>
|
||||
<button class="btn btn-primary" id="share-confirm-btn" data-i18n="actions.share">Compartir</button>
|
||||
<button class="btn btn-secondary" id="share-cancel-btn" data-i18n="actions.cancel">Cancel</button>
|
||||
<button class="btn btn-primary" id="share-confirm-btn" data-i18n="actions.share">Share</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -228,24 +228,24 @@ const ui = {
|
||||
<div class="share-dialog-content">
|
||||
<div class="share-dialog-header">
|
||||
<i class="fas fa-envelope" style="color:#ff5e3a"></i>
|
||||
<span data-i18n="dialogs.notify">Notificar enlace compartido</span>
|
||||
<span data-i18n="dialogs.notify">Notify shared link</span>
|
||||
</div>
|
||||
|
||||
<p><strong>URL:</strong> <span id="notification-share-url"></span></p>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="notification-email" data-i18n="dialogs.recipient">Destinatario:</label>
|
||||
<input type="email" id="notification-email" placeholder="Correo electrónico">
|
||||
<label for="notification-email" data-i18n="dialogs.recipient">Recipient:</label>
|
||||
<input type="email" id="notification-email" placeholder="Email address">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="notification-message" data-i18n="dialogs.message">Mensaje (opcional):</label>
|
||||
<label for="notification-message" data-i18n="dialogs.message">Message (optional):</label>
|
||||
<textarea id="notification-message" rows="3"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="share-dialog-buttons">
|
||||
<button class="btn btn-secondary" id="notification-cancel-btn" data-i18n="actions.cancel">Cancelar</button>
|
||||
<button class="btn btn-primary" id="notification-send-btn" data-i18n="actions.send">Enviar</button>
|
||||
<button class="btn btn-secondary" id="notification-cancel-btn" data-i18n="actions.cancel">Cancel</button>
|
||||
<button class="btn btn-primary" id="notification-send-btn" data-i18n="actions.send">Send</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -402,7 +402,7 @@ const ui = {
|
||||
homeItem.textContent = getTranslatedText('breadcrumb.home', 'Home');
|
||||
|
||||
// For searching, we might have a custom breadcrumb text
|
||||
if (folderName && folderName.startsWith('Búsqueda:')) {
|
||||
if (folderName && folderName.startsWith('Search:')) {
|
||||
// We're in search mode - don't add click handler
|
||||
breadcrumb.appendChild(homeItem);
|
||||
return;
|
||||
@@ -421,7 +421,7 @@ const ui = {
|
||||
breadcrumb.appendChild(homeItem);
|
||||
|
||||
// If we have a subfolder, add it to the breadcrumb
|
||||
if (folderName && !folderName.startsWith('Mi Carpeta') && !folderName.startsWith('Búsqueda:')) {
|
||||
if (folderName && !folderName.startsWith('Mi Carpeta') && !folderName.startsWith('Search:')) {
|
||||
const separator = document.createElement('span');
|
||||
separator.className = 'breadcrumb-separator';
|
||||
separator.textContent = '>';
|
||||
@@ -633,14 +633,14 @@ const ui = {
|
||||
* @param {Object} folder - Folder object
|
||||
*/
|
||||
addFolderToView(folder) {
|
||||
// Verificar si la carpeta ya existe en la vista para evitar duplicados
|
||||
// Check if the folder already exists in the view to avoid duplicates
|
||||
if (document.querySelector(`.file-card[data-folder-id="${folder.id}"]`) ||
|
||||
document.querySelector(`.file-item[data-folder-id="${folder.id}"]`)) {
|
||||
console.log(`Carpeta ${folder.name} (${folder.id}) ya existe en la vista, no duplicando`);
|
||||
console.log(`Folder ${folder.name} (${folder.id}) already exists in the view, not duplicating`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Añadiendo carpeta a la vista: ${folder.name} (${folder.id})`);
|
||||
console.log(`Adding folder to the view: ${folder.name} (${folder.id})`);
|
||||
|
||||
// Grid view element
|
||||
const folderGridElement = document.createElement('div');
|
||||
@@ -655,7 +655,7 @@ const ui = {
|
||||
<i class="fas fa-folder"></i>
|
||||
</div>
|
||||
<div class="file-name">${folder.name}</div>
|
||||
<div class="file-info">Carpeta</div>
|
||||
<div class="file-info">Folder</div>
|
||||
`;
|
||||
|
||||
// Drag and drop setup for folders
|
||||
@@ -746,7 +746,7 @@ const ui = {
|
||||
if (id) {
|
||||
if (isFolder) {
|
||||
if (id === folder.id) {
|
||||
alert("No puedes mover una carpeta a sí misma");
|
||||
alert("You cannot move a folder to itself");
|
||||
return;
|
||||
}
|
||||
await fileOps.moveFolder(id, folder.id);
|
||||
@@ -758,7 +758,7 @@ const ui = {
|
||||
|
||||
document.getElementById('files-grid').appendChild(folderGridElement);
|
||||
|
||||
// List view element - Mejorado
|
||||
// List view element - Improved
|
||||
const folderListElement = document.createElement('div');
|
||||
folderListElement.className = 'file-item';
|
||||
folderListElement.dataset.folderId = folder.id;
|
||||
@@ -788,7 +788,7 @@ const ui = {
|
||||
});
|
||||
}
|
||||
|
||||
// Mejorado: Estructura y clases para la vista de lista
|
||||
// Improved: Structure and classes for list view
|
||||
folderListElement.innerHTML = `
|
||||
<div class="name-cell">
|
||||
<div class="file-icon folder-icon">
|
||||
@@ -796,7 +796,7 @@ const ui = {
|
||||
</div>
|
||||
<span>${folder.name}</span>
|
||||
</div>
|
||||
<div class="type-cell">${window.i18n ? window.i18n.t('files.file_types.folder') : 'Carpeta'}</div>
|
||||
<div class="type-cell">${window.i18n ? window.i18n.t('files.file_types.folder') : 'Folder'}</div>
|
||||
<div class="size-cell">--</div>
|
||||
<div class="date-cell">${formattedDate}</div>
|
||||
`;
|
||||
@@ -844,7 +844,7 @@ const ui = {
|
||||
if (id) {
|
||||
if (isFolder) {
|
||||
if (id === folder.id) {
|
||||
alert("No puedes mover una carpeta a sí misma");
|
||||
alert("You cannot move a folder to itself");
|
||||
return;
|
||||
}
|
||||
await fileOps.moveFolder(id, folder.id);
|
||||
@@ -862,29 +862,29 @@ const ui = {
|
||||
* @param {Object} file - File object
|
||||
*/
|
||||
addFileToView(file) {
|
||||
// Verificar si el archivo ya existe en la vista para evitar duplicados
|
||||
// Check if the file already exists in the view to avoid duplicates
|
||||
if (document.querySelector(`.file-card[data-file-id="${file.id}"]`) ||
|
||||
document.querySelector(`.file-item[data-file-id="${file.id}"]`)) {
|
||||
console.log(`Archivo ${file.name} (${file.id}) ya existe en la vista, no duplicando`);
|
||||
console.log(`File ${file.name} (${file.id}) already exists in the view, not duplicating`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Añadiendo archivo a la vista: ${file.name} (${file.id})`);
|
||||
console.log(`Adding file to the view: ${file.name} (${file.id})`);
|
||||
|
||||
// Determine icon and type
|
||||
let iconClass = 'fas fa-file';
|
||||
let iconSpecialClass = '';
|
||||
let typeLabel = 'Documento';
|
||||
let typeLabel = 'Document';
|
||||
|
||||
if (file.mime_type) {
|
||||
if (file.mime_type.startsWith('image/')) {
|
||||
iconClass = 'fas fa-file-image';
|
||||
iconSpecialClass = 'image-icon';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.image') : 'Imagen';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.image') : 'Image';
|
||||
} else if (file.mime_type.startsWith('text/')) {
|
||||
iconClass = 'fas fa-file-alt';
|
||||
iconSpecialClass = 'text-icon';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.text') : 'Texto';
|
||||
typeLabel = window.i18n ? window.i18n.t('files.file_types.text') : 'Text';
|
||||
} else if (file.mime_type.startsWith('video/')) {
|
||||
iconClass = 'fas fa-file-video';
|
||||
iconSpecialClass = 'video-icon';
|
||||
@@ -916,7 +916,7 @@ const ui = {
|
||||
<i class="${iconClass}"></i>
|
||||
</div>
|
||||
<div class="file-name">${file.name}</div>
|
||||
<div class="file-info">Modificado ${formattedDate.split(' ')[0]}</div>
|
||||
<div class="file-info">Modified ${formattedDate.split(' ')[0]}</div>
|
||||
`;
|
||||
|
||||
fileGridElement.dataset.fileId = file.id;
|
||||
@@ -1007,7 +1007,7 @@ const ui = {
|
||||
|
||||
document.getElementById('files-grid').appendChild(fileGridElement);
|
||||
|
||||
// List view element - Mejorado con clases específicas y diseño mejorado
|
||||
// List view element - Improved with specific classes and enhanced layout
|
||||
const fileListElement = document.createElement('div');
|
||||
fileListElement.className = 'file-item';
|
||||
fileListElement.dataset.fileId = file.id;
|
||||
@@ -1238,9 +1238,9 @@ window.initRubberBandSelection = initRubberBandSelection;
|
||||
* @returns {Promise<boolean>} true if confirmed, false if cancelled
|
||||
*/
|
||||
function showConfirmDialog({ title, message, confirmText, cancelText, danger = true } = {}) {
|
||||
const ct = confirmText || (window.i18n ? window.i18n.t('actions.delete') : 'Eliminar');
|
||||
const cc = cancelText || (window.i18n ? window.i18n.t('actions.cancel') : 'Cancelar');
|
||||
const t = title || (window.i18n ? window.i18n.t('dialogs.confirm_title') : 'Confirmar acción');
|
||||
const ct = confirmText || (window.i18n ? window.i18n.t('actions.delete') : 'Delete');
|
||||
const cc = cancelText || (window.i18n ? window.i18n.t('actions.cancel') : 'Cancel');
|
||||
const t = title || (window.i18n ? window.i18n.t('dialogs.confirm_title') : 'Confirm action');
|
||||
|
||||
return new Promise((resolve) => {
|
||||
// Remove any previous confirm dialog
|
||||
|
||||
Reference in New Issue
Block a user