diff --git a/packages/app/app/app.vue b/packages/app/app/app.vue index ba445552..1cba544c 100644 --- a/packages/app/app/app.vue +++ b/packages/app/app/app.vue @@ -11,8 +11,7 @@ useHead({ useSeoMeta({ title: "pkg.pr.new", - description: - "Search repositories on GitHub to list their continuous releases.", + description: "Search repositories to list their continuous releases.", }); diff --git a/packages/app/app/components/Commits.vue b/packages/app/app/components/Commits.vue index f31a6241..606fae7f 100644 --- a/packages/app/app/components/Commits.vue +++ b/packages/app/app/components/Commits.vue @@ -12,18 +12,24 @@ const props = defineProps<{ repo: string; }>(); -const data = await $fetch("/api/repo/commits", { - query: { - owner: props.owner, - repo: props.repo, - }, -}); +const requestFetch = useRequestFetch(); + +const { data } = await useAsyncData( + `repo-commits:${props.owner}:${props.repo}:page:1`, + () => + requestFetch("/api/repo/commits", { + query: { + owner: props.owner, + repo: props.repo, + }, + }), +); -if (!data) { +if (!data.value) { throw createError("Could not load Commits"); } -const branch = shallowReactive(data); +const branch = shallowReactive(data.value); const commitsWithRelease = computed(() => branch.target.history.nodes @@ -113,58 +119,78 @@ onBeforeUnmount(() => { // Pagination const fetching = ref(false); -const fetchMoreForceDisabled = ref(!commitsWithRelease.value.length); +const currentPage = ref(branch.target.history.pageInfo.currentPage || 1); +const totalPages = computed( + () => branch.target.history.pageInfo.totalPages || 1, +); +const hasNextPage = computed(() => currentPage.value < totalPages.value); +const hasPrevPage = computed(() => currentPage.value > 1); -async function fetchMore() { - if (!branch.target.history.pageInfo.hasNextPage) { - return; +const paginationItems = computed<(number | "...")[]>(() => { + const total = totalPages.value; + const page = currentPage.value; + if (total <= 7) { + return Array.from({ length: total }, (_, i) => i + 1); + } + + const items: (number | "...")[] = [1]; + const start = Math.max(2, page - 1); + const end = Math.min(total - 1, page + 1); + + if (start > 2) { + items.push("..."); } + for (let i = start; i <= end; i++) { + items.push(i); + } + if (end < total - 1) { + items.push("..."); + } + items.push(total); + return items; +}); +async function fetchPage(page: number) { if (fetching.value) { return; } try { fetching.value = true; - - const cursor = branch.target.history.pageInfo.endCursor; - const result = await $fetch("/api/repo/commits", { query: { owner: props.owner, repo: props.repo, - cursor, + page: String(page), }, }); - const count = commitsWithRelease.value.length; - - branch.target = { - ...branch.target, - history: { - ...branch.target.history, - nodes: [...branch.target.history.nodes, ...result.target.history.nodes], - pageInfo: result.target.history.pageInfo, - }, - }; - - if (count === commitsWithRelease.value.length) { - fetchMoreForceDisabled.value = true; - } + currentPage.value = result.target.history.pageInfo.currentPage || page; + branch.id = result.id; + branch.name = result.name; + branch.target = result.target; } finally { fetching.value = false; } } + +async function goNextPage() { + if (!hasNextPage.value) { + return; + } + await fetchPage(currentPage.value + 1); +} + +async function goPrevPage() { + if (!hasPrevPage.value) { + return; + } + await fetchPage(currentPage.value - 1); +}