fix(changelog): switch to page-based pagination (Gitea ignores 'since')
Build & Deploy / build-and-deploy (push) Successful in 1m13s

Gitea's commits API ignores the 'since' query param entirely, so all
360 commits were fetched via multiple pages on every load.

Replace days-based approach with simple page pagination:
- Initial load: page 1, limit=50 per repo (2 requests, ~2s)
- Load more: appends page 2, 3, ... on demand
- No more while loop or date filtering
- Remove daysProgression / currentDays state
- Clean up summary text

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
svemagie
2026-03-31 13:43:31 +02:00
parent acaff70cfe
commit b50006245d
+39 -52
View File
@@ -99,8 +99,6 @@ withSidebar: false
{# Summary #} {# Summary #}
<div x-show="commits.length > 0" class="mt-6 text-center text-xs text-surface-600 dark:text-surface-400"> <div x-show="commits.length > 0" class="mt-6 text-center text-xs text-surface-600 dark:text-surface-400">
<span x-text="commits.length + ' commits'"></span> <span x-text="commits.length + ' commits'"></span>
<span x-show="currentDays !== 'all'"> from the last <span x-text="currentDays"></span> days</span>
<span x-show="currentDays === 'all'"> (all time)</span>
</div> </div>
</div> </div>
</div> </div>
@@ -127,8 +125,8 @@ function changelogApp() {
loadingMore: false, loadingMore: false,
commits: [], commits: [],
categories: {}, categories: {},
currentDays: 30, currentPage: 1,
daysProgression: [30, 90, 180, 'all'], hasMore: false,
tabs: [ tabs: [
{ key: 'all', label: 'All' }, { key: 'all', label: 'All' },
@@ -156,67 +154,59 @@ function changelogApp() {
}, },
get canLoadMore() { get canLoadMore() {
const idx = this.daysProgression.indexOf(this.currentDays); return this.hasMore;
return idx >= 0 && idx < this.daysProgression.length - 1;
}, },
async init() { async init() {
await this.fetchChangelog(30); await this.fetchChangelog(1);
}, },
async fetchChangelog(days) { async fetchChangelog(page) {
try { try {
const since = days === 'all' const limit = 50;
? null const newCommits = [];
: new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString(); let anyHasMore = false;
const allCommits = [];
await Promise.all(GITEA_REPOS.map(async (repo) => { await Promise.all(GITEA_REPOS.map(async (repo) => {
let page = 1; const url = `${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${repo}/commits?limit=${limit}&page=${page}`;
const limit = 50; const r = await fetch(url);
while (true) { if (!r.ok) return;
let url = `${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${repo}/commits?limit=${limit}&page=${page}`; const commits = await r.json();
if (since) url += `&since=${since}`; if (!Array.isArray(commits)) return;
const r = await fetch(url); if (commits.length >= limit) anyHasMore = true;
if (!r.ok) break; for (const c of commits) {
const commits = await r.json(); const lines = (c.commit?.message || '').split('\n');
if (!Array.isArray(commits) || commits.length === 0) break; const title = lines[0];
const sinceDate = since ? new Date(since) : null; const body = lines.slice(1).join('\n').trim();
let pastCutoff = false; newCommits.push({
for (const c of commits) { sha: c.sha.slice(0, 7),
const lines = (c.commit?.message || '').split('\n'); fullSha: c.sha,
const title = lines[0]; title,
const body = lines.slice(1).join('\n').trim(); body: body || null,
const date = c.created || c.commit?.author?.date; url: c.html_url,
if (sinceDate && new Date(date) < sinceDate) { pastCutoff = true; continue; } repoUrl: `${GITEA_URL}/${GITEA_ORG}/${repo}`,
allCommits.push({ repoName: repo,
sha: c.sha.slice(0, 7), date: c.commit?.author?.date || c.created,
fullSha: c.sha, author: c.commit?.author?.name || '',
title, commitCategory: categorizeCommit(title),
body: body || null, });
url: c.html_url,
repoUrl: `${GITEA_URL}/${GITEA_ORG}/${repo}`,
repoName: repo,
date,
author: c.commit?.author?.name || '',
commitCategory: categorizeCommit(title),
});
}
if (commits.length < limit || pastCutoff) break;
page++;
} }
})); }));
allCommits.sort((a, b) => new Date(b.date) - new Date(a.date)); const merged = page === 1
? newCommits
: [...this.commits, ...newCommits];
merged.sort((a, b) => new Date(b.date) - new Date(a.date));
const categories = {}; const categories = {};
for (const c of allCommits) { for (const c of merged) {
categories[c.commitCategory] = (categories[c.commitCategory] || 0) + 1; categories[c.commitCategory] = (categories[c.commitCategory] || 0) + 1;
} }
this.commits = allCommits; this.commits = merged;
this.categories = categories; this.categories = categories;
this.currentDays = days; this.currentPage = page;
this.hasMore = anyHasMore;
} catch (err) { } catch (err) {
console.error('Changelog error:', err); console.error('Changelog error:', err);
} finally { } finally {
@@ -226,11 +216,8 @@ function changelogApp() {
}, },
async loadMore() { async loadMore() {
const idx = this.daysProgression.indexOf(this.currentDays);
if (idx < 0 || idx >= this.daysProgression.length - 1) return;
const nextDays = this.daysProgression[idx + 1];
this.loadingMore = true; this.loadingMore = true;
await this.fetchChangelog(nextDays); await this.fetchChangelog(this.currentPage + 1);
}, },
filteredCommits() { filteredCommits() {