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
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}}
|
|
|