import { api } from '../api.js'; export class FileList extends HTMLElement { constructor() { super(); this.currentFolderId = null; this.files = []; this.folders = []; } async connectedCallback() { await this.loadContents(null); } async loadContents(folderId) { this.currentFolderId = folderId; try { this.folders = await api.listFolders(folderId); this.files = await api.listFiles(folderId); this.render(); } catch (error) { console.error('Failed to load contents:', error); } } setFiles(files) { this.files = files; this.folders = []; this.render(); } render() { this.innerHTML = `

Files

${this.folders.map(folder => this.renderFolder(folder)).join('')} ${this.files.map(file => this.renderFile(file)).join('')}
`; this.attachListeners(); } renderFolder(folder) { return `
📁
${folder.name}
`; } renderFile(file) { const icon = this.getFileIcon(file.mime_type); const size = this.formatFileSize(file.size); return `
${icon}
${file.name}
${size}
`; } getFileIcon(mimeType) { if (mimeType.startsWith('image/')) return '📷'; if (mimeType.startsWith('video/')) return '🎥'; if (mimeType.startsWith('audio/')) return '🎵'; if (mimeType.includes('pdf')) return '📄'; if (mimeType.includes('text')) return '📄'; return '📄'; } formatFileSize(bytes) { if (bytes < 1024) return bytes + ' B'; if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB'; if (bytes < 1073741824) return (bytes / 1048576).toFixed(1) + ' MB'; return (bytes / 1073741824).toFixed(1) + ' GB'; } attachListeners() { this.querySelector('#upload-btn')?.addEventListener('click', () => { this.dispatchEvent(new CustomEvent('upload-request')); }); this.querySelector('#create-folder-btn')?.addEventListener('click', async () => { await this.handleCreateFolder(); }); this.querySelectorAll('.folder-item').forEach(item => { item.addEventListener('dblclick', () => { const folderId = parseInt(item.dataset.folderId); this.dispatchEvent(new CustomEvent('folder-open', { detail: { folderId } })); }); }); this.querySelectorAll('.file-item:not(.folder-item)').forEach(item => { item.addEventListener('click', (e) => { if (!e.target.classList.contains('action-btn')) { const fileId = parseInt(item.dataset.fileId); const file = this.files.find(f => f.id === fileId); this.dispatchEvent(new CustomEvent('photo-click', { detail: { photo: file }, bubbles: true })); } }); }); this.querySelectorAll('.action-btn').forEach(btn => { btn.addEventListener('click', async (e) => { e.stopPropagation(); const action = btn.dataset.action; const id = parseInt(btn.dataset.id); await this.handleAction(action, id); }); }); } triggerCreateFolder() { this.handleCreateFolder(); } async handleCreateFolder() { const name = prompt('Enter folder name:'); if (name) { try { await api.createFolder(name, this.currentFolderId); await this.loadContents(this.currentFolderId); } catch (error) { alert('Failed to create folder: ' + error.message); } } } async handleAction(action, id) { try { switch (action) { case 'download': const blob = await api.downloadFile(id); const file = this.files.find(f => f.id === id); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = file.name; a.click(); URL.revokeObjectURL(url); break; case 'rename': const newName = prompt('Enter new name:'); if (newName) { await api.renameFile(id, newName); await this.loadContents(this.currentFolderId); } break; case 'delete': if (confirm('Are you sure you want to delete this file?')) { await api.deleteFile(id); await this.loadContents(this.currentFolderId); } break; case 'delete-folder': if (confirm('Are you sure you want to delete this folder?')) { await api.deleteFolder(id); await this.loadContents(this.currentFolderId); } break; case 'share': this.dispatchEvent(new CustomEvent('share-request', { detail: { fileId: id } })); break; } } catch (error) { alert('Action failed: ' + error.message); } } } customElements.define('file-list', FileList);