diff --git a/src/components/Stats.astro b/src/components/Stats.astro
index bd492ad..9843514 100644
--- a/src/components/Stats.astro
+++ b/src/components/Stats.astro
@@ -11,6 +11,7 @@ import {
emulators,
appContributorsData,
storeContributorsData,
+ totalDownloads,
} from "../scripts/getters";
---
@@ -29,7 +30,9 @@ import {
-
10+
+
{totalDownloads}+
Downloads
@@ -72,15 +75,3 @@ import {
-
-
diff --git a/src/scripts/getters.ts b/src/scripts/getters.ts
index 31a490f..f254764 100644
--- a/src/scripts/getters.ts
+++ b/src/scripts/getters.ts
@@ -32,6 +32,80 @@ export const releaseData = await fetch(
return { tag_name: "unknown" };
});
+async function getTotalDownloads(owner: string, repo: string): Promise {
+ let totalDownloads = 0;
+ let cursor: string | null = null;
+ let hasNextPage = true;
+
+ while (hasNextPage) {
+ const res = await fetch("https://api.github.com/graphql", {
+ method: "POST",
+ headers: {
+ ...githubHeaders.headers,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ query: `{
+ repository(owner: "${owner}", name: "${repo}") {
+ releases(first: 100${cursor ? `, after: "${cursor}"` : ""}) {
+ pageInfo {
+ hasNextPage
+ endCursor
+ }
+ nodes {
+ releaseAssets(first: 100) {
+ nodes {
+ downloadCount
+ }
+ }
+ }
+ }
+ }
+ }`,
+ }),
+ });
+
+ if (!res.ok) {
+ throw new Error(`GitHub API error: ${res.status} ${res.statusText}`);
+ }
+
+ const json: any = await res.json();
+
+ if (json.errors) {
+ throw new Error(
+ `GraphQL error: ${json.errors.map((e: any) => e.message).join(", ")}`,
+ );
+ }
+
+ const releases = json.data?.repository?.releases;
+
+ if (!releases) {
+ throw new Error(
+ `Repository ${owner}/${repo} not found or not accessible`,
+ );
+ }
+
+ for (const release of releases.nodes) {
+ for (const asset of release.releaseAssets.nodes) {
+ totalDownloads += asset.downloadCount;
+ }
+ }
+
+ hasNextPage = releases.pageInfo.hasNextPage;
+ cursor = releases.pageInfo.endCursor;
+ }
+
+ return totalDownloads;
+}
+
+export const totalDownloads = await getTotalDownloads(
+ "simeonradivoev",
+ "gameflow-deck",
+).catch((e) => {
+ console.error(e);
+ return 0;
+});
+
export const appContributorsData = await fetch(
"https://api.github.com/repos/simeonradivoev/gameflow-deck/contributors",
githubHeaders,