diff --git a/src/components/modals/FilePreviewModal.astro b/src/components/modals/FilePreviewModal.astro index 0e639d0..69475d6 100644 --- a/src/components/modals/FilePreviewModal.astro +++ b/src/components/modals/FilePreviewModal.astro @@ -399,24 +399,24 @@ const { } createFileCard(file) { - const fileType = this.getFileType(file.name); const card = document.createElement("div"); card.className = "card bg-base-200 hover:bg-base-300 cursor-pointer transition-colors"; + const fileType = this.getFileType(file.name); let preview = ""; + if (fileType === "image") { preview = `
- ${file.name} + ${file.name}
`; } else { + const icon = this.getFileTypeIcon(fileType); preview = `
- - - + ${icon}
`; } @@ -427,40 +427,125 @@ const {

${file.name}

+

${this.getFileTypeLabel(fileType)}

`; - card.addEventListener("click", () => this.showFile(file)); return card; } + getFileTypeLabel(fileType) { + switch (fileType) { + case "image": + return "Image"; + case "video": + return "Video"; + case "audio": + return "Audio"; + case "pdf": + return "PDF Document"; + case "word": + return "Word Document"; + case "excel": + return "Excel Spreadsheet"; + case "powerpoint": + return "PowerPoint Presentation"; + case "text": + return "Text Document"; + case "code": + return "Code File"; + case "archive": + return "Archive"; + default: + return "File"; + } + } + async show(files) { this.modal.showModal(); - if (!Array.isArray(files)) { - // Single file - await this.showFile(files); - } else if (files.length === 1) { - // Single file in array - await this.showFile(files[0]); - } else { - // Multiple files - this.singleView.classList.add("hidden"); - this.multipleView.classList.remove("hidden"); + // Show loading state immediately + this.showLoading(false); + this.showLoading(true); - // Show loading state - this.showLoading(true); + try { + // Normalize input to array + const fileArray = Array.isArray(files) ? files : [files]; + + // Handle empty files + if (fileArray.length === 0) { + this.previewContainer.innerHTML = ` +
+
+

No files available

+
+
+ `; + this.hideLoading(false); + return; + } + + // Single file view + if (fileArray.length === 1) { + this.singleView.classList.remove("hidden"); + this.multipleView.classList.add("hidden"); + await this.showFile(fileArray[0]); + } + // Multiple files view + else { + this.singleView.classList.add("hidden"); + this.multipleView.classList.remove("hidden"); - try { // Clear and populate file grid this.fileGrid.innerHTML = ""; - files.forEach((file) => { - this.fileGrid.appendChild(this.createFileCard(file)); + + // Create all file cards and handle their loading + const loadingPromises = fileArray.map(async (file) => { + const card = this.createFileCard(file); + this.fileGrid.appendChild(card); + + // If it's an image, wait for it to load + if (this.getFileType(file.name) === "image") { + const img = card.querySelector("img"); + if (img) { + await new Promise((resolve, reject) => { + img.onload = resolve; + img.onerror = reject; + // Add a timeout to prevent infinite loading + setTimeout(resolve, 5000); // 5 second timeout + }).catch(console.warn); // Log but don't fail if image fails to load + } + } + return card; + }); + + // Wait for all cards to be processed + await Promise.all(loadingPromises); + + // Add click handlers after all cards are loaded + const cards = this.fileGrid.querySelectorAll(".card"); + cards.forEach((card, index) => { + card.addEventListener("click", () => { + this.showFile(fileArray[index]); + this.singleView.classList.remove("hidden"); + this.multipleView.classList.add("hidden"); + }); }); - } finally { - // Hide loading state - this.hideLoading(true); } + } catch (error) { + console.error("Error showing files:", error); + this.previewContainer.innerHTML = ` +
+
+

Failed to load files

+

${error instanceof Error ? error.message : "Unknown error"}

+
+
+ `; + } finally { + // Hide both loading states + this.hideLoading(false); + this.hideLoading(true); } }