class FilePreview extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = `
`; const input = document.getElementById('attachments'); if (input) { input.addEventListener('change', this.updatePreviews.bind(this)); } // Helper functions function getFileType(file) { if (file.type.startsWith('image/')) return 'image'; if (file.type.startsWith('video/')) return 'video'; if (file.type.startsWith('audio/')) return 'audio'; return 'document'; } function getFileIcon(file) { if (file.type === 'application/pdf') return 'file-text'; if (file.type.includes('document') || file.name.match(/\.(docx?|txt|rtf)$/i)) return 'file-text'; if (file.type.includes('spreadsheet') || file.name.match(/\.(xlsx?|csv)$/i)) return 'file-text'; if (file.type.includes('presentation') || file.name.match(/\.(pptx?|key)$/i)) return 'file-text'; if (file.type.startsWith('video/')) return 'film'; if (file.type.startsWith('audio/')) return 'music'; if (file.name.match(/\.(zip|rar|7z|tar|gz)$/i)) return 'archive'; return 'file'; } function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } } updatePreviews() { const input = document.getElementById('attachments'); const previewsContainer = this.shadowRoot.getElementById('previews'); previewsContainer.innerHTML = ''; Array.from(input.files).forEach((file, index) => { const previewItem = document.createElement('div'); previewItem.className = 'preview-item'; const fileType = getFileType(file); previewItem.innerHTML = `