fix(changelog): switch to page-based pagination (Gitea ignores 'since')
All checks were successful
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

View File

@@ -99,8 +99,6 @@ withSidebar: false
{# Summary #}
<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-show="currentDays !== 'all'"> from the last <span x-text="currentDays"></span> days</span>
<span x-show="currentDays === 'all'"> (all time)</span>
</div>
</div>
</div>
@@ -127,8 +125,8 @@ function changelogApp() {
loadingMore: false,
commits: [],
categories: {},
currentDays: 30,
daysProgression: [30, 90, 180, 'all'],
currentPage: 1,
hasMore: false,
tabs: [
{ key: 'all', label: 'All' },
@@ -156,67 +154,59 @@ function changelogApp() {
},
get canLoadMore() {
const idx = this.daysProgression.indexOf(this.currentDays);
return idx >= 0 && idx < this.daysProgression.length - 1;
return this.hasMore;
},
async init() {
await this.fetchChangelog(30);
await this.fetchChangelog(1);
},
async fetchChangelog(days) {
async fetchChangelog(page) {
try {
const since = days === 'all'
? null
: new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
const limit = 50;
const newCommits = [];
let anyHasMore = false;
const allCommits = [];
await Promise.all(GITEA_REPOS.map(async (repo) => {
let page = 1;
const limit = 50;
while (true) {
let url = `${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${repo}/commits?limit=${limit}&page=${page}`;
if (since) url += `&since=${since}`;
const r = await fetch(url);
if (!r.ok) break;
const commits = await r.json();
if (!Array.isArray(commits) || commits.length === 0) break;
const sinceDate = since ? new Date(since) : null;
let pastCutoff = false;
for (const c of commits) {
const lines = (c.commit?.message || '').split('\n');
const title = lines[0];
const body = lines.slice(1).join('\n').trim();
const date = c.created || c.commit?.author?.date;
if (sinceDate && new Date(date) < sinceDate) { pastCutoff = true; continue; }
allCommits.push({
sha: c.sha.slice(0, 7),
fullSha: c.sha,
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++;
const url = `${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${repo}/commits?limit=${limit}&page=${page}`;
const r = await fetch(url);
if (!r.ok) return;
const commits = await r.json();
if (!Array.isArray(commits)) return;
if (commits.length >= limit) anyHasMore = true;
for (const c of commits) {
const lines = (c.commit?.message || '').split('\n');
const title = lines[0];
const body = lines.slice(1).join('\n').trim();
newCommits.push({
sha: c.sha.slice(0, 7),
fullSha: c.sha,
title,
body: body || null,
url: c.html_url,
repoUrl: `${GITEA_URL}/${GITEA_ORG}/${repo}`,
repoName: repo,
date: c.commit?.author?.date || c.created,
author: c.commit?.author?.name || '',
commitCategory: categorizeCommit(title),
});
}
}));
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 = {};
for (const c of allCommits) {
for (const c of merged) {
categories[c.commitCategory] = (categories[c.commitCategory] || 0) + 1;
}
this.commits = allCommits;
this.commits = merged;
this.categories = categories;
this.currentDays = days;
this.currentPage = page;
this.hasMore = anyHasMore;
} catch (err) {
console.error('Changelog error:', err);
} finally {
@@ -226,11 +216,8 @@ function changelogApp() {
},
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;
await this.fetchChangelog(nextDays);
await this.fetchChangelog(this.currentPage + 1);
},
filteredCommits() {