fix(repo): paginate repo list alphabetically server-side
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.
This commit is contained in:
@@ -12,7 +12,7 @@ const isReady = ref(false)
|
|||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
const hasCredentialError = ref(false)
|
const hasCredentialError = ref(false)
|
||||||
const currentPage = ref(0)
|
const currentPage = ref(0)
|
||||||
const totalCount = ref(0)
|
const hasMore = ref(true)
|
||||||
let lastFetchedAt = 0
|
let lastFetchedAt = 0
|
||||||
|
|
||||||
const { username, accessToken } = useGitHubLogin()
|
const { username, accessToken } = useGitHubLogin()
|
||||||
@@ -20,7 +20,7 @@ const { username, accessToken } = useGitHubLogin()
|
|||||||
const resetState = () => {
|
const resetState = () => {
|
||||||
repos.value = []
|
repos.value = []
|
||||||
currentPage.value = 0
|
currentPage.value = 0
|
||||||
totalCount.value = 0
|
hasMore.value = true
|
||||||
isReady.value = false
|
isReady.value = false
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
hasCredentialError.value = false
|
hasCredentialError.value = false
|
||||||
@@ -32,26 +32,26 @@ const loadMore = async () => {
|
|||||||
isReady.value = true
|
isReady.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (isLoading.value) return
|
if (isLoading.value || !hasMore.value) return
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
try {
|
try {
|
||||||
const octokit = await getOctokit()
|
const octokit = await getOctokit()
|
||||||
const nextPage = currentPage.value + 1
|
const nextPage = currentPage.value + 1
|
||||||
const repoList = await octokit.request("GET /search/repositories", {
|
const repoList = await octokit.request("GET /user/repos", {
|
||||||
q: `user:${username.value}`,
|
sort: "full_name",
|
||||||
|
direction: "asc",
|
||||||
|
affiliation: "owner",
|
||||||
per_page: PER_PAGE,
|
per_page: PER_PAGE,
|
||||||
page: nextPage
|
page: nextPage
|
||||||
})
|
})
|
||||||
currentPage.value = nextPage
|
currentPage.value = nextPage
|
||||||
totalCount.value = repoList.data.total_count
|
hasMore.value = repoList.data.length === PER_PAGE
|
||||||
const newItems = repoList.data.items.map((item) => ({
|
const newItems = repoList.data.map((item) => ({
|
||||||
id: `${item.id}`,
|
id: `${item.id}`,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
isPrivate: item.private
|
isPrivate: item.private ?? false
|
||||||
}))
|
}))
|
||||||
repos.value = [...repos.value, ...newItems].sort((a, b) =>
|
repos.value = [...repos.value, ...newItems]
|
||||||
a.name < b.name ? -1 : 1
|
|
||||||
)
|
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (
|
if (
|
||||||
typeof err === "object" &&
|
typeof err === "object" &&
|
||||||
@@ -79,9 +79,7 @@ watch(accessToken, (next, prev) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const useRepos = () => {
|
export const useRepos = () => {
|
||||||
const canLoadMore = computed(
|
const canLoadMore = computed(() => !isLoading.value && hasMore.value)
|
||||||
() => !isLoading.value && repos.value.length < totalCount.value
|
|
||||||
)
|
|
||||||
|
|
||||||
const isStale = Date.now() - lastFetchedAt > STALE_TIME_MS
|
const isStale = Date.now() - lastFetchedAt > STALE_TIME_MS
|
||||||
if (!isReady.value || isStale) {
|
if (!isReady.value || isStale) {
|
||||||
|
|||||||
Reference in New Issue
Block a user