From 0a2445a06dacef19361279495224e647c33c9a4d Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Sat, 16 May 2026 23:59:04 +0200 Subject: [PATCH] fix(repo): paginate repo list alphabetically server-side MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch from /search/repositories (best-match order) to /user/repos with sort=full_name so infinite scroll appends in A–Z order instead of injecting new pages into earlier letters. --- src/hooks/useRepos.hook.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/hooks/useRepos.hook.ts b/src/hooks/useRepos.hook.ts index 79bcb39..d99cc16 100644 --- a/src/hooks/useRepos.hook.ts +++ b/src/hooks/useRepos.hook.ts @@ -12,7 +12,7 @@ const isReady = ref(false) const isLoading = ref(false) const hasCredentialError = ref(false) const currentPage = ref(0) -const totalCount = ref(0) +const hasMore = ref(true) let lastFetchedAt = 0 const { username, accessToken } = useGitHubLogin() @@ -20,7 +20,7 @@ const { username, accessToken } = useGitHubLogin() const resetState = () => { repos.value = [] currentPage.value = 0 - totalCount.value = 0 + hasMore.value = true isReady.value = false isLoading.value = false hasCredentialError.value = false @@ -32,26 +32,26 @@ const loadMore = async () => { isReady.value = true return } - if (isLoading.value) return + if (isLoading.value || !hasMore.value) return isLoading.value = true try { const octokit = await getOctokit() const nextPage = currentPage.value + 1 - const repoList = await octokit.request("GET /search/repositories", { - q: `user:${username.value}`, + const repoList = await octokit.request("GET /user/repos", { + sort: "full_name", + direction: "asc", + affiliation: "owner", per_page: PER_PAGE, page: nextPage }) currentPage.value = nextPage - totalCount.value = repoList.data.total_count - const newItems = repoList.data.items.map((item) => ({ + hasMore.value = repoList.data.length === PER_PAGE + const newItems = repoList.data.map((item) => ({ id: `${item.id}`, name: item.name, - isPrivate: item.private + isPrivate: item.private ?? false })) - repos.value = [...repos.value, ...newItems].sort((a, b) => - a.name < b.name ? -1 : 1 - ) + repos.value = [...repos.value, ...newItems] } catch (err: unknown) { if ( typeof err === "object" && @@ -79,9 +79,7 @@ watch(accessToken, (next, prev) => { }) export const useRepos = () => { - const canLoadMore = computed( - () => !isLoading.value && repos.value.length < totalCount.value - ) + const canLoadMore = computed(() => !isLoading.value && hasMore.value) const isStale = Date.now() - lastFetchedAt > STALE_TIME_MS if (!isReady.value || isStale) {