You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

111 lines
5.2 KiB

{{define "content"}}
{{with .Content}}
<div data-video-browser data-date="{{.Date}}" data-active-index="{{.ActiveIndex}}" class="flex h-full min-h-[calc(100vh-7rem)] flex-col gap-4">
<div class="flex items-center justify-between gap-3">
<div>
<h1 class="text-lg font-semibold text-slate-100">{{.Date}}</h1>
<p class="text-sm text-slate-400">Videos</p>
</div>
{{if .Videos}}
<div class="flex items-center gap-2">
<a href="/day/{{.Date}}/videos?idx={{.PrevIndex}}" data-nav="prev" data-index="{{.PrevIndex}}" class="rounded-md border border-slate-700 px-3 py-2 text-sm font-medium text-slate-100 hover:bg-slate-800">Prev</a>
<a href="/day/{{.Date}}/videos?idx={{.NextIndex}}" data-nav="next" data-index="{{.NextIndex}}" class="rounded-md border border-slate-700 px-3 py-2 text-sm font-medium text-slate-100 hover:bg-slate-800">Next</a>
</div>
{{end}}
</div>
{{if .Videos}}
<div class="h-28 shrink-0 overflow-x-auto border-y border-slate-800 py-3">
<div class="flex h-full gap-3">
{{range .Videos}}
<a href="/day/{{$.Content.Date}}/videos?idx={{.Index}}" data-video-item data-index="{{.Index}}" data-stream-url="{{.StreamURL}}" data-thumb-url="{{.ThumbURL}}" class="relative h-full w-40 shrink-0 overflow-hidden rounded-md border border-slate-800 bg-slate-950 {{if .Active}}ring-2 ring-indigo-400{{end}}">
<img src="{{.ThumbURL}}" alt="{{.Filename}}" class="h-full w-full object-cover">
<span class="absolute bottom-2 right-2 rounded bg-slate-950/85 px-2 py-1 text-xs font-medium text-white">{{.DurationLabel}}</span>
</a>
{{end}}
</div>
</div>
<div class="relative min-h-0 flex-1 overflow-hidden bg-black">
<video data-video-player controls autoplay poster="{{.Current.ThumbURL}}" src="{{.Current.StreamURL}}" class="h-full max-h-[calc(100vh-15rem)] min-h-[18rem] w-full object-contain"></video>
<a href="/day/{{.Date}}/videos?idx={{.PrevIndex}}" data-nav="prev" data-index="{{.PrevIndex}}" class="absolute left-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">Prev</a>
<a href="/day/{{.Date}}/videos?idx={{.NextIndex}}" data-nav="next" data-index="{{.NextIndex}}" class="absolute right-3 top-1/2 -translate-y-1/2 rounded-md bg-slate-950/80 px-3 py-2 text-sm font-medium text-white hover:bg-slate-900">Next</a>
</div>
<script>
(() => {
const root = document.querySelector("[data-video-browser]");
if (!root) return;
const player = root.querySelector("[data-video-player]");
const items = Array.from(root.querySelectorAll("[data-video-item]"));
const prevLinks = Array.from(root.querySelectorAll('[data-nav="prev"]'));
const nextLinks = Array.from(root.querySelectorAll('[data-nav="next"]'));
const date = root.dataset.date;
let active = Number(root.dataset.activeIndex || "0");
const setNav = (links, index) => {
links.forEach((link) => {
link.dataset.index = String(index);
link.href = `/day/${date}/videos?idx=${index}`;
});
};
const setActive = (index) => {
if (!player || items.length === 0) return;
active = ((index % items.length) + items.length) % items.length;
const item = items[active];
const prev = (active - 1 + items.length) % items.length;
const next = (active + 1) % items.length;
root.dataset.activeIndex = String(active);
player.src = item.dataset.streamUrl || "";
player.poster = item.dataset.thumbUrl || "";
player.load();
void player.play().catch(() => {});
setNav(prevLinks, prev);
setNav(nextLinks, next);
items.forEach((link, itemIndex) => {
link.classList.toggle("ring-2", itemIndex === active);
link.classList.toggle("ring-indigo-400", itemIndex === active);
});
const url = new URL(window.location.href);
url.searchParams.set("idx", String(active));
window.history.pushState({ idx: active }, "", url.toString());
};
window.history.replaceState({ idx: active }, "", window.location.href);
prevLinks.forEach((link) => {
link.addEventListener("click", (event) => {
event.preventDefault();
setActive(Number(link.dataset.index || "0"));
});
});
nextLinks.forEach((link) => {
link.addEventListener("click", (event) => {
event.preventDefault();
setActive(Number(link.dataset.index || "0"));
});
});
items.forEach((item, index) => {
item.addEventListener("click", (event) => {
event.preventDefault();
setActive(index);
});
});
window.addEventListener("keydown", (event) => {
if (event.key === "ArrowLeft") setActive(active - 1);
if (event.key === "ArrowRight") setActive(active + 1);
});
})();
</script>
{{else}}
<div class="border border-slate-800 bg-slate-950 p-6 text-sm text-slate-400">No videos for this day.</div>
{{end}}
</div>
{{end}}
{{end}}