upload-service/web/batch.html

143 lines
5.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.Count}} files — upload.jeffemmett.com</title>
<link rel="stylesheet" href="/static/style.css?v=6">
</head>
<body>
<div class="container batch-container">
<div class="batch-header">
<div>
<h1>{{.Count}} files</h1>
<p class="subtitle">{{formatSize .TotalSize}} total</p>
</div>
<a href="/{{.BatchID}}/dl" class="btn">Download all</a>
</div>
<div class="batch-grid">
{{range .Files}}
<div class="batch-card">
{{if eq .ThumbType "image"}}
<a href="{{.PreviewURL}}" class="batch-card-preview" data-lightbox data-filename="{{.Filename}}" data-dl="/f/{{.ID}}/dl">
<img src="{{.PreviewURL}}" alt="{{.Filename}}" loading="lazy">
</a>
{{else}}
<a href="/f/{{.ID}}" class="batch-card-preview">
{{if eq .ThumbType "video"}}
<video src="{{.PreviewURL}}" preload="metadata" muted playsinline></video>
{{else if eq .ThumbType "audio"}}
<div class="batch-card-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M9 18V5l12-2v13"/>
<circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/>
</svg>
</div>
{{else if eq .ThumbType "pdf"}}
<div class="batch-card-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
</svg>
</div>
{{else}}
<div class="batch-card-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/>
<polyline points="13 2 13 9 20 9"/>
</svg>
</div>
{{end}}
</a>
{{end}}
<div class="batch-card-footer">
<a href="/f/{{.ID}}" class="batch-card-name" title="{{.Filename}}">{{.Filename}}</a>
<span class="batch-card-size">{{formatSize .Size}}</span>
</div>
</div>
{{end}}
</div>
<footer>
<a href="/">upload.jeffemmett.com</a>
</footer>
</div>
<!-- Lightbox -->
<div id="lightbox" class="lightbox hidden">
<div class="lightbox-backdrop"></div>
<button class="lightbox-close" title="Close">&times;</button>
<button class="lightbox-prev" title="Previous">&#8249;</button>
<button class="lightbox-next" title="Next">&#8250;</button>
<div class="lightbox-content">
<img id="lightbox-img" src="" alt="">
</div>
<div class="lightbox-footer">
<span id="lightbox-filename"></span>
<a id="lightbox-dl" href="" class="lightbox-dl-btn">Download</a>
</div>
</div>
<script>
(() => {
const lightbox = document.getElementById('lightbox');
const lbImg = document.getElementById('lightbox-img');
const lbName = document.getElementById('lightbox-filename');
const lbDl = document.getElementById('lightbox-dl');
const items = [...document.querySelectorAll('[data-lightbox]')];
let current = -1;
if (items.length === 0) return;
function open(index) {
const el = items[index];
current = index;
lbImg.src = el.href;
lbName.textContent = el.dataset.filename;
lbDl.href = el.dataset.dl;
lightbox.classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
function close() {
lightbox.classList.add('hidden');
document.body.style.overflow = '';
current = -1;
}
function prev() {
if (current <= 0) return;
open(current - 1);
}
function next() {
if (current >= items.length - 1) return;
open(current + 1);
}
items.forEach((el, i) => {
el.addEventListener('click', (e) => {
e.preventDefault();
open(i);
});
});
lightbox.querySelector('.lightbox-backdrop').addEventListener('click', close);
lightbox.querySelector('.lightbox-close').addEventListener('click', close);
lightbox.querySelector('.lightbox-prev').addEventListener('click', prev);
lightbox.querySelector('.lightbox-next').addEventListener('click', next);
document.addEventListener('keydown', (e) => {
if (current === -1) return;
if (e.key === 'Escape') close();
else if (e.key === 'ArrowLeft') prev();
else if (e.key === 'ArrowRight') next();
});
})();
</script>
</body>
</html>