diff --git a/.gitignore b/.gitignore index 6d4c0aa06..c754b4132 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ pnpm-debug.log* # macOS-specific files .DS_Store +_openCollectiveData.json diff --git a/src/components/Sponsor.astro b/src/components/Sponsor.astro deleted file mode 100644 index f2bce3629..000000000 --- a/src/components/Sponsor.astro +++ /dev/null @@ -1,66 +0,0 @@ ---- -import { Image } from 'astro:assets'; - -interface Props { - sponsor: Sponsor; -} - -export type Sponsor = { - id: string; - name: string; - avatarUrl: string; - profileUrl?: string; - tier?: Tier; -}; - -export type Tier = 'platinum' | 'gold' | 'silver' | 'bronze'; - -export const IMAGE_DIMENSION = 128; - -const { sponsor } = Astro.props; ---- - -{ - sponsor.tier == 'platinum' && ( - - {sponsor.name} - - ) -} - -{ - sponsor.tier == 'gold' && ( - - {sponsor.name} - - ) -} - -{ - sponsor.tier == 'silver' && ( - - {sponsor.name} - - ) -} - -{sponsor.tier == 'bronze' && sponsor.name} - - diff --git a/src/components/SponsorList.astro b/src/components/SponsorList.astro deleted file mode 100644 index 0e2978910..000000000 --- a/src/components/SponsorList.astro +++ /dev/null @@ -1,201 +0,0 @@ ---- -import { type Sponsor as SponsorType, IMAGE_DIMENSION, type Tier } from './Sponsor.astro'; -import Sponsor from './Sponsor.astro'; -const GITHUB_TOKEN = import.meta.env.GITHUB_TOKEN; -const IS_PRODUCTION = import.meta.env.NETLIFY != undefined; - -let gitHubSponsors: SponsorType[] = []; - -if (GITHUB_TOKEN || IS_PRODUCTION) { - gitHubSponsors = await getGitHubSponsors(); -} - -const gitHubSponsorsLoaded = gitHubSponsors.length > 0; - -const openCollectiveSponsors = await getOpenCollectiveSponsors(); - -async function getGitHubSponsors(): Promise { - if (!GITHUB_TOKEN) - throw Error('Error generator sponsor list: GITHUB_TOKEN is invalid or not set'); - - // https://docs.github.com/graphql - const gitHubQuery = `query { - organization(login:"tauri-apps") { - sponsors(first: 100) { - nodes { - ... on Actor { - login, - avatarUrl(size: ${IMAGE_DIMENSION}) - } - } - } - } -}`; - - const gitHubSponsorResponse = await fetch('https://api.github.com/graphql', { - method: 'POST', - body: JSON.stringify({ query: gitHubQuery }), - headers: { - Authorization: `bearer ${GITHUB_TOKEN}`, - }, - }); - - if (!gitHubSponsorResponse.ok) - throw Error( - `There was an issue with the GitHub sponsors query: ${gitHubSponsorResponse.status}: ${gitHubSponsorResponse.statusText}` - ); - - const gitHubSponsorData = (await gitHubSponsorResponse.json()).data; - return gitHubSponsorData.organization.sponsors.nodes - .map( - (node: any): SponsorType => ({ - id: node.login, - name: node.login, - avatarUrl: node.avatarUrl, - }) - ) - .sort((a: SponsorType, b: SponsorType) => a.name.localeCompare(b.name)); -} - -async function getOpenCollectiveSponsors(): Promise { - const filteredSlugs = ['github-sponsors']; - - // Documentation at https://graphql-docs-v2.opencollective.com/welcome - const openCollectiveQuery = `query account { - collective(slug: "tauri") { - contributors(limit: 1000) { - nodes { - name - image(height: ${IMAGE_DIMENSION}) - totalAmountDonated - collectiveSlug - isIncognito - } - } - } -}`; - - const openCollectiveResponse = await fetch('https://api.opencollective.com/graphql/v2', { - method: 'POST', - body: JSON.stringify({ query: openCollectiveQuery }), - headers: { - 'Content-Type': 'application/json', - }, - }); - - if (!openCollectiveResponse.ok) - throw Error( - `There was an issue with the Open Collective sponsors query: ${openCollectiveResponse.status} ${openCollectiveResponse.statusText}` - ); - - const openCollectiveData = (await openCollectiveResponse.json()).data; - return openCollectiveData.collective.contributors.nodes - .filter( - (node: any) => - !node.isIncognito && - node.totalAmountDonated > 0 && - !filteredSlugs.includes(node.collectiveSlug) && - node.name != 'Guest' - ) - .sort((a: any, b: any) => b.totalAmountDonated - a.totalAmountDonated) - .map((node: any): SponsorType => { - let tier: Tier; - let amount = node.totalAmountDonated / 100; - if (amount >= 5_000) { - tier = 'platinum'; - } else if (amount >= 500) { - tier = 'gold'; - } else if (amount >= 100) { - tier = 'silver'; - } else { - tier = 'bronze'; - } - return { - name: node.name, - id: node.name, - avatarUrl: node.image, - profileUrl: `https://opencollective.com/${node.collectiveSlug}`, - tier, - }; - }); -} - -const openCollectiveSilverOpt1 = openCollectiveSponsors.filter( - (sponsor) => sponsor.tier == 'silver' -); -const openCollectiveSilverOpt2 = openCollectiveSponsors - .filter((sponsor) => sponsor.tier == 'silver') - .map((sponsor) => sponsor.name) - .join(', '); - -const openCollectiveBronze = openCollectiveSponsors - .filter((sponsor) => sponsor.tier == 'bronze') - .map((sponsor) => sponsor.name) - .join(', '); ---- - -

Sponsors

-

Open Collective

- - - - -
- {openCollectiveSilverOpt2} -
- -

GitHub

-{ - !gitHubSponsorsLoaded && ( -

- GITHUB_TOKEN environment variable not set so GitHub sponsors could not be loaded. -

- ) -} -{ - gitHubSponsorsLoaded && ( - - ) -} - - diff --git a/src/components/sponsors/GitHub/Main.astro b/src/components/sponsors/GitHub/Main.astro new file mode 100644 index 000000000..28ff9ea2d --- /dev/null +++ b/src/components/sponsors/GitHub/Main.astro @@ -0,0 +1,79 @@ +--- +const GITHUB_TOKEN = import.meta.env.GITHUB_TOKEN; + +let gitHubSponsors = []; + +export type Sponsor = { + id: string; + name: string; + avatarUrl: string; + profileUrl?: string; + tier?: Tier; +}; + +export const IMAGE_DIMENSION = 64; + +const IS_PRODUCTION = import.meta.env.NETLIFY != undefined; + +export type Tier = 'platinum' | 'gold' | 'silver' | 'bronze'; + +if (GITHUB_TOKEN || IS_PRODUCTION) { + gitHubSponsors = await getGitHubSponsors(); +} + +const gitHubSponsorsLoaded = gitHubSponsors.length > 0; + +async function getGitHubSponsors(): Promise { + if (!GITHUB_TOKEN) + throw Error('Error generator sponsor list: GITHUB_TOKEN is invalid or not set'); + + // https://docs.github.com/graphql + const gitHubQuery = `query { + organization(login:"tauri-apps") { + sponsors(first: 100) { + nodes { + ... on Actor { + login, + avatarUrl(size: ${IMAGE_DIMENSION}) + } + } + } + } +}`; + + const gitHubSponsorResponse = await fetch('https://api.github.com/graphql', { + method: 'POST', + body: JSON.stringify({ query: gitHubQuery }), + headers: { + Authorization: `bearer ${GITHUB_TOKEN}`, + }, + }); + + if (!gitHubSponsorResponse.ok) + throw Error( + `There was an issue with the GitHub sponsors query: ${gitHubSponsorResponse.status}: ${gitHubSponsorResponse.statusText}` + ); + + const gitHubSponsorData = (await gitHubSponsorResponse.json()).data; + return gitHubSponsorData.organization.sponsors.nodes + .map( + (node: any): Sponsor => ({ + id: node.login, + name: node.login, + avatarUrl: node.avatarUrl, + }) + ) + .sort((a: Sponsor, b: Sponsor) => a.name.localeCompare(b.name)); +} +--- + +{!gitHubSponsorsLoaded &&

_error_loading_

} +{ + gitHubSponsorsLoaded && ( +