更新包

-- [CST 2026-08-04 Tuesday 16:05:05]
This commit is contained in:
biss
2026-08-04 16:05:05 +08:00 Unverified
commit f839e19947
112 changed files with 63309 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
function randomPost(trigger) {
const source = trigger instanceof Element
? trigger
: document.activeElement?.closest?.('.nav-random, [onclick*="randomPost"]');
const overlay = document.createElement('div');
const reduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;
overlay.className = 'random-post-transition';
overlay.setAttribute('role', 'status');
overlay.setAttribute('aria-live', 'polite');
overlay.innerHTML = `
<div class="random-post-flight" aria-hidden="true"></div>
<div class="random-post-transition-card">
<i class="fa-solid fa-shuffle" aria-hidden="true"></i>
<span>\u6b63\u5728\u62bd\u53d6\u4e00\u7bc7\u6587\u7ae0</span>
</div>
`;
source?.classList.add('is-randomizing');
source?.setAttribute('aria-busy', 'true');
document.body.appendChild(overlay);
requestAnimationFrame(() => overlay.classList.add('is-visible'));
const finish = href => {
const delay = reduceMotion ? 80 : 1250;
window.setTimeout(() => {
location.href = href;
}, delay);
};
const startCardFlight = posts => {
if (reduceMotion) return;
const flight = overlay.querySelector('.random-post-flight');
if (!flight) return;
const candidates = posts
.filter(post => post && typeof post.href === 'string' && post.href.startsWith('/posts/'))
.map(post => ({
title: typeof post.title === 'string' && post.title.trim() ? post.title.trim() : '\u672a\u547d\u540d\u6587\u7ae0',
meta: typeof post.category === 'string' && post.category.trim() ? post.category.trim() : '\u968f\u673a\u6587\u7ae0',
}));
const pool = candidates.length ? candidates : [{ title: '\u968f\u673a\u6587\u7ae0', meta: '\u6b63\u5728\u62bd\u53d6' }];
const count = Math.min(9, Math.max(5, pool.length));
for (let index = 0; index < count; index += 1) {
const post = pool[Math.floor(Math.random() * pool.length)];
const card = document.createElement('div');
card.className = 'random-post-flying-card';
card.style.setProperty('--flight-delay', `${index * 0.11}s`);
card.style.setProperty('--flight-y', `${-42 + Math.random() * 84}px`);
card.style.setProperty('--flight-rotate', `${-8 + Math.random() * 16}deg`);
const meta = document.createElement('small');
const title = document.createElement('strong');
meta.textContent = post.meta;
title.textContent = post.title;
card.append(meta, title);
flight.appendChild(card);
}
};
const reset = () => {
source?.classList.remove('is-randomizing');
source?.removeAttribute('aria-busy');
overlay.classList.remove('is-visible');
window.setTimeout(() => overlay.remove(), reduceMotion ? 0 : 180);
};
fetch('/api/posts.json')
.then(res => {
if (!res.ok) throw new Error(`Failed to load posts: ${res.status}`);
return res.json();
})
.then(posts => {
const postLinks = posts
.map(post => post && post.href)
.filter(href => typeof href === 'string' && href.startsWith('/posts/'));
if (postLinks.length === 0) {
console.warn('No posts available for random navigation.');
reset();
return;
}
startCardFlight(posts);
finish(postLinks[Math.floor(Math.random() * postLinks.length)]);
})
.catch(error => {
console.error('Random post navigation failed:', error);
reset();
});
}