diff options
Diffstat (limited to 'views.ts')
| -rw-r--r-- | views.ts | 85 |
1 files changed, 36 insertions, 49 deletions
@@ -67,22 +67,25 @@ export async function renderUploadPage(chunked = false): Promise<string> { export async function renderBrowsePage(files: Array<{ name: string; size: number; uploaded: Date }>): Promise<string> { const browseTemplate = await loadTemplate("./templates/browse.html"); + const fileRowTemplate = await loadTemplate("./templates/partials/file-row.html"); + const emptyFilesTemplate = await loadTemplate("./templates/partials/empty-files.html"); const fileRows = files.map(file => { const mimeType = getMimeType(file.name); const viewable = isViewableInBrowser(mimeType); - - return ` - <tr> - <td><a href="/download/${file.name}" target="_blank">${file.name}</a></td> - <td>${formatFileSize(file.size)}</td> - <td>${file.uploaded.toLocaleString()}</td> - <td> - ${viewable ? `<a href="/download/${file.name}" target="_blank" class="button" style="margin-right: 10px; background-color: #28a745; color: white; border-color: #28a745;">View</a>` : ''} - <a href="/download/${file.name}" download class="button">Download</a> - </td> - </tr> - `; + const encodedName = encodeURIComponent(file.name); + + const viewButton = viewable + ? `<a href="/download/${encodedName}" target="_blank" class="button" style="margin-right: 10px; background-color: #28a745; color: white; border-color: #28a745;">View</a>` + : ''; + + return replaceVariables(fileRowTemplate, { + "encoded-name": encodedName, + "filename": file.name, + "size": formatFileSize(file.size), + "uploaded": file.uploaded.toLocaleString(), + "view-button": viewButton, + }); }).join(''); const filesContent = files.length > 0 ? ` @@ -99,13 +102,7 @@ export async function renderBrowsePage(files: Array<{ name: string; size: number ${fileRows} </tbody> </table> - ` : ` - <div style="text-align: center; padding: 60px 20px; color: #666;"> - <div style="font-size: 64px; margin-bottom: 20px;">📭</div> - <h3>No files uploaded yet</h3> - <p>Upload some files to see them here!</p> - </div> - `; + ` : emptyFilesTemplate; const content = replaceVariables(browseTemplate, { "files-content": filesContent, @@ -116,7 +113,8 @@ export async function renderBrowsePage(files: Array<{ name: string; size: number export async function renderGalleryPage(files: Array<{ name: string; size: number; uploaded: Date }>): Promise<string> { const galleryTemplate = await loadTemplate("./templates/gallery.html"); - const galleryCss = await loadTemplate("./templates/styles/gallery.css"); + const galleryItemTemplate = await loadTemplate("./templates/partials/gallery-item.html"); + const emptyGalleryTemplate = await loadTemplate("./templates/partials/empty-gallery.html"); // Filter only images and videos const mediaFiles = files.filter(file => { @@ -127,36 +125,25 @@ export async function renderGalleryPage(files: Array<{ name: string; size: numbe const galleryItems = mediaFiles.map((file, index) => { const mimeType = getMimeType(file.name); const isVideo = mimeType.startsWith("video/"); - - return ` - <div class="gallery-item" data-index="${index}"> - <a href="#" onclick="openSlideshow(${index}); return false;"> - ${isVideo ? ` - <video src="/download/${file.name}" style="width: 100%; height: 200px; object-fit: cover; border-radius: 4px;"></video> - <div class="video-overlay">▶</div> - ` : ` - <img src="/download/${file.name}" alt="${file.name}" style="width: 100%; height: 200px; object-fit: cover; border-radius: 4px;"> - `} - </a> - <div class="gallery-info"> - <div class="gallery-filename" title="${file.name}">${file.name}</div> - <div class="gallery-meta">${formatFileSize(file.size)} • ${file.uploaded.toLocaleDateString()}</div> - </div> - </div> - `; + const encodedName = encodeURIComponent(file.name); + + const media = isVideo + ? `<video src="/download/${encodedName}" style="width: 100%; height: 200px; object-fit: cover; border-radius: 4px;"></video> + <div class="video-overlay">▶</div>` + : `<img src="/download/${encodedName}" alt="${file.name}" style="width: 100%; height: 200px; object-fit: cover; border-radius: 4px;">`; + + return replaceVariables(galleryItemTemplate, { + "index": String(index), + "media": media, + "filename": file.name, + "size": formatFileSize(file.size), + "uploaded": file.uploaded.toLocaleDateString(), + }); }).join(''); - const galleryContent = mediaFiles.length > 0 ? ` - <div class="gallery-grid"> - ${galleryItems} - </div> - ` : ` - <div style="text-align: center; padding: 60px 20px; color: #666;"> - <div style="font-size: 64px; margin-bottom: 20px;">🖼️</div> - <h3>No images or videos yet</h3> - <p>Upload some media files to see them here!</p> - </div> - `; + const galleryContent = mediaFiles.length > 0 + ? `<div class="gallery-grid">\n${galleryItems}\n</div>` + : emptyGalleryTemplate; const content = replaceVariables(galleryTemplate, { "gallery-content": galleryContent, @@ -174,7 +161,7 @@ export async function renderGalleryPage(files: Array<{ name: string; size: numbe "media-files-json": mediaFilesJson, }); - const styles = `<style>\n${galleryCss}\n</style>`; + const styles = '<link rel="stylesheet" href="/css/gallery.css">'; const scripts = `<script>\n${scriptContent}\n</script>`; return renderLayout("Gallery", content, scripts, styles); |
