Next to the RSS feed link on the timeline and grid headers, pointing at the public repo so visitors can find the source.
104 lines
3.4 KiB
HTML
104 lines
3.4 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Photo Gallery</title>
|
||
<link rel="stylesheet" href="{{.FontsURL}}">
|
||
<link rel="stylesheet" href="/static/style.css">
|
||
<style>:root { --serif: '{{.SerifFamily}}', Georgia, serif; --mj: '{{.MlFamily}}', sans-serif; }</style>
|
||
<link rel="alternate" type="application/atom+xml" href="/feed.xml" title="Photo Feed">
|
||
</head>
|
||
<body>
|
||
<header class="profile-hdr">
|
||
<div class="profile-inner">
|
||
<div class="avatar-ring">
|
||
<span class="avatar-initials">{{.Initial}}</span>
|
||
</div>
|
||
<div class="pinfo">
|
||
<h1>{{.Author}}</h1>
|
||
<p class="handle">{{.Handle}}</p>
|
||
<p class="pcount"><strong>{{.Total}}</strong> posts</p>
|
||
<p class="pbio">{{.Bio}}{{if .BioAlt}}<br><span class="ml">{{.BioAlt}}</span>{{end}}</p>
|
||
<a href="/" class="rss-a">Timeline</a>
|
||
<a href="/feed.xml" class="rss-a">
|
||
<svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" aria-hidden="true">
|
||
<circle cx="2.5" cy="11.5" r="1.5"/>
|
||
<path d="M1.5 7.5A5 5 0 0 1 6.5 12.5H8A6.5 6.5 0 0 0 1.5 6V7.5z"/>
|
||
<path d="M1.5 4A8.5 8.5 0 0 1 10 12.5h1.5A10 10 0 0 0 1.5 2.5V4z"/>
|
||
</svg>
|
||
RSS feed
|
||
</a>
|
||
<a href="https://git.inflo.ws/aashiks/photog" class="rss-a" target="_blank" rel="noopener">
|
||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
||
<path d="M5.7 4.3 2 8l3.7 3.7 1-1L4 8l2.7-2.7zM10.3 4.3l-1 1L12 8l-2.7 2.7 1 1L14 8z"/>
|
||
</svg>
|
||
Source
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main>
|
||
<div class="grid-wrap">
|
||
<div class="pgrid">
|
||
{{range .Photos}}
|
||
<a href="/photo/{{.Slug}}/" class="ptile">
|
||
<img src="/{{.Thumb}}" alt="{{.Caption}}" loading="lazy">
|
||
</a>
|
||
{{end}}
|
||
</div>
|
||
|
||
{{if or .PrevURL .NextURL}}
|
||
<nav class="pager">
|
||
{{if .PrevURL}}<a class="pager-newer" href="{{.PrevURL}}">← Newer</a>{{end}}
|
||
{{if .NextURL}}<a class="pager-older" href="{{.NextURL}}" data-load-more>Older →</a>{{end}}
|
||
</nav>
|
||
{{end}}
|
||
</div>
|
||
</main>
|
||
|
||
<footer class="site-footer">
|
||
© 2000–{{.Year}} {{.Author}}. All rights reserved.
|
||
</footer>
|
||
|
||
<script>
|
||
(function () {
|
||
const btn = document.querySelector('[data-load-more]');
|
||
if (!btn) return;
|
||
const grid = document.querySelector('.pgrid');
|
||
let loading = false;
|
||
|
||
async function loadMore(url) {
|
||
if (loading) return;
|
||
loading = true;
|
||
try {
|
||
const res = await fetch(url);
|
||
if (!res.ok) return;
|
||
const html = await res.text();
|
||
const doc = new DOMParser().parseFromString(html, 'text/html');
|
||
doc.querySelectorAll('.pgrid > a').forEach(t => grid.appendChild(t));
|
||
const nextBtn = doc.querySelector('[data-load-more]');
|
||
if (nextBtn) btn.href = nextBtn.getAttribute('href');
|
||
else btn.remove();
|
||
} finally {
|
||
loading = false;
|
||
}
|
||
}
|
||
|
||
btn.addEventListener('click', (e) => {
|
||
e.preventDefault();
|
||
loadMore(btn.href);
|
||
});
|
||
|
||
const io = new IntersectionObserver((entries) => {
|
||
if (entries[0].isIntersecting && document.body.contains(btn)) {
|
||
loadMore(btn.href);
|
||
}
|
||
}, { rootMargin: '400px' });
|
||
io.observe(btn);
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|