mirror of
https://github.com/tauri-apps/tauri-docs.git
synced 2026-01-31 00:35:16 +01:00
format
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
# Generated reference docs
|
||||
src/content/docs/reference
|
||||
src/content/docs/release
|
||||
|
||||
# Git Modules
|
||||
packages/tauri
|
||||
|
||||
@@ -1,79 +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<any[]> {
|
||||
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 && <p>_error_loading_</p>}
|
||||
{
|
||||
gitHubSponsorsLoaded && (
|
||||
<div class="sponsor-grid github">
|
||||
{gitHubSponsors.map((sponsor) => (
|
||||
<div class="sponsor" />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
---
|
||||
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<any[]> {
|
||||
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 && <p>_error_loading_</p>}
|
||||
{
|
||||
gitHubSponsorsLoaded && (
|
||||
<div class="sponsor-grid github">
|
||||
{gitHubSponsors.map((sponsor) => (
|
||||
<div class="sponsor" />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,122 +1,122 @@
|
||||
---
|
||||
import { Image } from 'astro:assets';
|
||||
import { IMAGE_DIMENSION, type Sponsor } from './_types';
|
||||
|
||||
interface Props {
|
||||
sponsor: Sponsor;
|
||||
|
||||
needComma?: boolean;
|
||||
}
|
||||
|
||||
const { sponsor, needComma } = Astro.props;
|
||||
|
||||
const roundingStyle: Record<Sponsor['type'], string> = {
|
||||
ORGANIZATION: 'rounded-lg',
|
||||
INDIVIDUAL: 'rounded-full',
|
||||
};
|
||||
---
|
||||
|
||||
{
|
||||
(sponsor.tier === 'platinum' || sponsor.tier === 'gold' || sponsor.tier === 'silver') && (
|
||||
<div class="image-container">
|
||||
<a href={sponsor.profileUrl} target="_blank" rel="noopener noreferrer">
|
||||
<Image
|
||||
src={sponsor.avatarUrl}
|
||||
alt={sponsor.name}
|
||||
width={IMAGE_DIMENSION}
|
||||
height={IMAGE_DIMENSION}
|
||||
class={`image ${sponsor.tier} ${roundingStyle[sponsor.type]}`}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
!sponsor.tier && sponsor.avatarUrl && (
|
||||
<div class="image-container">
|
||||
fallback
|
||||
<a
|
||||
href={sponsor.profileUrl || `https://github.com/${sponsor.name}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
src={sponsor.avatarUrl}
|
||||
alt={sponsor.name}
|
||||
width={IMAGE_DIMENSION}
|
||||
height={IMAGE_DIMENSION}
|
||||
class={`image ${roundingStyle[sponsor.type]}`}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
sponsor.tier === 'bronze' && (
|
||||
<>
|
||||
<a href={sponsor.profileUrl} target="_blank" rel="noopener noreferrer" class="bronze-sponsor">
|
||||
{sponsor.name}
|
||||
</a>
|
||||
{needComma && <span class="bronze-separator">, </span>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
<style define:vars={{ dimension: `${IMAGE_DIMENSION}px` }}>
|
||||
.rounded-full {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.rounded-lg {
|
||||
border-radius: 8px;
|
||||
}
|
||||
.image {
|
||||
object-fit: cover;
|
||||
background-color: white;
|
||||
border: 2px solid var(--sl-color-gray-1);
|
||||
}
|
||||
|
||||
.image-container {
|
||||
aspect-ratio: 1;
|
||||
width: fit-content;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 1s ease;
|
||||
}
|
||||
|
||||
.image-container:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.platinum {
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
}
|
||||
|
||||
.gold {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
.silver {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
.bronze-sponsor {
|
||||
filter: brightness(0.8);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.bronze-sponsor:hover {
|
||||
filter: brightness(1.2);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.bronze-separator {
|
||||
color: var(--sl-color-text-muted);
|
||||
padding-inline-end: 2px;
|
||||
}
|
||||
</style>
|
||||
---
|
||||
import { Image } from 'astro:assets';
|
||||
import { IMAGE_DIMENSION, type Sponsor } from './_types';
|
||||
|
||||
interface Props {
|
||||
sponsor: Sponsor;
|
||||
|
||||
needComma?: boolean;
|
||||
}
|
||||
|
||||
const { sponsor, needComma } = Astro.props;
|
||||
|
||||
const roundingStyle: Record<Sponsor['type'], string> = {
|
||||
ORGANIZATION: 'rounded-lg',
|
||||
INDIVIDUAL: 'rounded-full',
|
||||
};
|
||||
---
|
||||
|
||||
{
|
||||
(sponsor.tier === 'platinum' || sponsor.tier === 'gold' || sponsor.tier === 'silver') && (
|
||||
<div class="image-container">
|
||||
<a href={sponsor.profileUrl} target="_blank" rel="noopener noreferrer">
|
||||
<Image
|
||||
src={sponsor.avatarUrl}
|
||||
alt={sponsor.name}
|
||||
width={IMAGE_DIMENSION}
|
||||
height={IMAGE_DIMENSION}
|
||||
class={`image ${sponsor.tier} ${roundingStyle[sponsor.type]}`}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
!sponsor.tier && sponsor.avatarUrl && (
|
||||
<div class="image-container">
|
||||
fallback
|
||||
<a
|
||||
href={sponsor.profileUrl || `https://github.com/${sponsor.name}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
src={sponsor.avatarUrl}
|
||||
alt={sponsor.name}
|
||||
width={IMAGE_DIMENSION}
|
||||
height={IMAGE_DIMENSION}
|
||||
class={`image ${roundingStyle[sponsor.type]}`}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
sponsor.tier === 'bronze' && (
|
||||
<>
|
||||
<a href={sponsor.profileUrl} target="_blank" rel="noopener noreferrer" class="bronze-sponsor">
|
||||
{sponsor.name}
|
||||
</a>
|
||||
{needComma && <span class="bronze-separator">, </span>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
<style define:vars={{ dimension: `${IMAGE_DIMENSION}px` }}>
|
||||
.rounded-full {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.rounded-lg {
|
||||
border-radius: 8px;
|
||||
}
|
||||
.image {
|
||||
object-fit: cover;
|
||||
background-color: white;
|
||||
border: 2px solid var(--sl-color-gray-1);
|
||||
}
|
||||
|
||||
.image-container {
|
||||
aspect-ratio: 1;
|
||||
width: fit-content;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 1s ease;
|
||||
}
|
||||
|
||||
.image-container:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.platinum {
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
}
|
||||
|
||||
.gold {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
.silver {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
.bronze-sponsor {
|
||||
filter: brightness(0.8);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.bronze-sponsor:hover {
|
||||
filter: brightness(1.2);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.bronze-separator {
|
||||
color: var(--sl-color-text-muted);
|
||||
padding-inline-end: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export type Sponsor = {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
profileUrl?: string;
|
||||
tier?: Tier;
|
||||
type: 'ORGANIZATION' | 'INDIVIDUAL';
|
||||
};
|
||||
|
||||
export type Tier = 'platinum' | 'gold' | 'silver' | 'bronze';
|
||||
export const IMAGE_DIMENSION = 256;
|
||||
export type Sponsor = {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
profileUrl?: string;
|
||||
tier?: Tier;
|
||||
type: 'ORGANIZATION' | 'INDIVIDUAL';
|
||||
};
|
||||
|
||||
export type Tier = 'platinum' | 'gold' | 'silver' | 'bronze';
|
||||
export const IMAGE_DIMENSION = 256;
|
||||
|
||||
@@ -1,62 +1,62 @@
|
||||
---
|
||||
import { Image } from 'astro:assets';
|
||||
|
||||
interface ServiceProvider {
|
||||
name: string;
|
||||
image?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const serviceProviders: ServiceProvider[] = [
|
||||
{
|
||||
name: 'Netlify',
|
||||
url: 'https://www.netlify.com/',
|
||||
},
|
||||
{
|
||||
name: 'Meilisearch',
|
||||
url: 'https://www.meilisearch.com/',
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
{
|
||||
serviceProviders.length > 0 && (
|
||||
<div class="service-providers">
|
||||
{serviceProviders.map((provider) => (
|
||||
<div class="service-provider not-content">
|
||||
<a href={provider.url} target="_blank" rel="noopener noreferrer">
|
||||
{provider.name}
|
||||
</a>
|
||||
{provider.image && <Image src={provider.image} inferSize alt={provider.name} />}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<style>
|
||||
.service-providers {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.service-provider {
|
||||
padding: 1rem;
|
||||
border: 4px solid var(--sl-color-gray-5);
|
||||
border-radius: 8px;
|
||||
background: var(--sl-color-bg-nav);
|
||||
}
|
||||
|
||||
.service-provider a {
|
||||
font-weight: 600;
|
||||
color: var(--sl-color-text);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.service-provider a:hover {
|
||||
color: var(--sl-color-accent);
|
||||
}
|
||||
</style>
|
||||
---
|
||||
import { Image } from 'astro:assets';
|
||||
|
||||
interface ServiceProvider {
|
||||
name: string;
|
||||
image?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const serviceProviders: ServiceProvider[] = [
|
||||
{
|
||||
name: 'Netlify',
|
||||
url: 'https://www.netlify.com/',
|
||||
},
|
||||
{
|
||||
name: 'Meilisearch',
|
||||
url: 'https://www.meilisearch.com/',
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
{
|
||||
serviceProviders.length > 0 && (
|
||||
<div class="service-providers">
|
||||
{serviceProviders.map((provider) => (
|
||||
<div class="service-provider not-content">
|
||||
<a href={provider.url} target="_blank" rel="noopener noreferrer">
|
||||
{provider.name}
|
||||
</a>
|
||||
{provider.image && <Image src={provider.image} inferSize alt={provider.name} />}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<style>
|
||||
.service-providers {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.service-provider {
|
||||
padding: 1rem;
|
||||
border: 4px solid var(--sl-color-gray-5);
|
||||
border-radius: 8px;
|
||||
background: var(--sl-color-bg-nav);
|
||||
}
|
||||
|
||||
.service-provider a {
|
||||
font-weight: 600;
|
||||
color: var(--sl-color-text);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.service-provider a:hover {
|
||||
color: var(--sl-color-accent);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,7 +27,6 @@ import { Card, CardGrid, LinkCard } from '@astrojs/starlight/components';
|
||||
import Cta from '@fragments/cta.mdx';
|
||||
import SponsorList from '@components/sponsors/SponsorList.astro';
|
||||
|
||||
|
||||
<div class="hero-bg">
|
||||
<div class="bg-logo"></div>
|
||||
<div class="bg-grad"></div>
|
||||
@@ -40,36 +39,32 @@ import SponsorList from '@components/sponsors/SponsorList.astro';
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
<CardGrid stagger>
|
||||
<Card title="Frontend Independent" icon="rocket">
|
||||
Bring your existing web stack to Tauri or start that new dream project.
|
||||
Tauri supports any frontend framework so you don't need to change your
|
||||
stack.
|
||||
</Card>
|
||||
<Card title="Cross Platform" icon="rocket">
|
||||
Build your app for Linux, macOS, Windows, Android and iOS - all from a
|
||||
single codebase.
|
||||
</Card>
|
||||
<Card title="Inter-Process Communication" icon="rocket">
|
||||
Write your frontend in JavaScript, application logic in Rust, and integrate
|
||||
deep into the system with Swift and Kotlin.
|
||||
</Card>
|
||||
<Card title="Maximum Security" icon="rocket">
|
||||
Front-of-mind for the Tauri Team that drives our highest priorities and
|
||||
biggest innovations.
|
||||
</Card>
|
||||
<Card title="Minimal Size" icon="rocket">
|
||||
By using the OS's native web renderer, the size of a Tauri app can be little
|
||||
as 600KB.
|
||||
</Card>
|
||||
<Card title="Powered by Rust" icon="rocket">
|
||||
With performance and security at the center, Rust is the language for the
|
||||
next generation of apps.
|
||||
</Card>
|
||||
</CardGrid> */}
|
||||
|
||||
<Card title="Frontend Independent" icon="rocket">
|
||||
Bring your existing web stack to Tauri or start that new dream project.
|
||||
Tauri supports any frontend framework so you don't need to change your
|
||||
stack.
|
||||
</Card>
|
||||
<Card title="Cross Platform" icon="rocket">
|
||||
Build your app for Linux, macOS, Windows, Android and iOS - all from a
|
||||
single codebase.
|
||||
</Card>
|
||||
<Card title="Inter-Process Communication" icon="rocket">
|
||||
Write your frontend in JavaScript, application logic in Rust, and integrate
|
||||
deep into the system with Swift and Kotlin.
|
||||
</Card>
|
||||
<Card title="Maximum Security" icon="rocket">
|
||||
Front-of-mind for the Tauri Team that drives our highest priorities and
|
||||
biggest innovations.
|
||||
</Card>
|
||||
<Card title="Minimal Size" icon="rocket">
|
||||
By using the OS's native web renderer, the size of a Tauri app can be little
|
||||
as 600KB.
|
||||
</Card>
|
||||
<Card title="Powered by Rust" icon="rocket">
|
||||
With performance and security at the center, Rust is the language for the
|
||||
next generation of apps.
|
||||
</Card>
|
||||
</CardGrid>
|
||||
|
||||
<SponsorList />
|
||||
|
||||
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
import {
|
||||
IMAGE_DIMENSION,
|
||||
type Sponsor,
|
||||
type Tier,
|
||||
} from '@components/sponsors/OpenCollective/_types';
|
||||
|
||||
export const PLATINUM_THRESHOLD = 5_000;
|
||||
export const GOLD_THRESHOLD = 500;
|
||||
export const SILVER_THRESHOLD = 100;
|
||||
|
||||
export async function fetchOpenCollectiveData() {
|
||||
const filteredSlugs = ['github-sponsors'];
|
||||
|
||||
// Documentation at https://graphql-docs-v2.opencollective.com/welcome
|
||||
const query = `query account {
|
||||
collective(slug: "tauri") {
|
||||
contributors(limit: 1000) {
|
||||
nodes {
|
||||
account {
|
||||
name
|
||||
type
|
||||
imageUrl(height: ${IMAGE_DIMENSION})
|
||||
slug
|
||||
isIncognito
|
||||
}
|
||||
totalAmountContributed {
|
||||
value
|
||||
currency
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const res = await fetch('https://api.opencollective.com/graphql/v2', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw Error(
|
||||
`Open Collective query failed: ${res.status} ${res.statusText} \n ${JSON.stringify(await res.json(), null, 2)}, `
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: handle currency
|
||||
|
||||
const openCollectiveData = (await res.json()).data;
|
||||
return openCollectiveData.collective.contributors.nodes
|
||||
.filter(
|
||||
(node: any) =>
|
||||
!node.account.isIncognito &&
|
||||
node.totalAmountContributed.value > 0 &&
|
||||
!filteredSlugs.includes(node.account.slug) &&
|
||||
node.account.name != 'Guest'
|
||||
)
|
||||
.sort((a: any, b: any) => b.totalAmountContributed.value - a.totalAmountContributed.value)
|
||||
.map((node: any): Sponsor => {
|
||||
let tier: Tier;
|
||||
let amount = node.totalAmountContributed.value;
|
||||
if (amount >= PLATINUM_THRESHOLD) {
|
||||
tier = 'platinum';
|
||||
} else if (amount >= GOLD_THRESHOLD) {
|
||||
tier = 'gold';
|
||||
} else if (amount >= SILVER_THRESHOLD) {
|
||||
tier = 'silver';
|
||||
} else {
|
||||
tier = 'bronze';
|
||||
}
|
||||
const { slug, name, type, isIncognito, imageUrl } = node.account;
|
||||
|
||||
return {
|
||||
name,
|
||||
id: name,
|
||||
avatarUrl: imageUrl,
|
||||
profileUrl: `https://opencollective.com/${slug}`,
|
||||
tier,
|
||||
type,
|
||||
};
|
||||
});
|
||||
}
|
||||
import {
|
||||
IMAGE_DIMENSION,
|
||||
type Sponsor,
|
||||
type Tier,
|
||||
} from '@components/sponsors/OpenCollective/_types';
|
||||
|
||||
export const PLATINUM_THRESHOLD = 5_000;
|
||||
export const GOLD_THRESHOLD = 500;
|
||||
export const SILVER_THRESHOLD = 100;
|
||||
|
||||
export async function fetchOpenCollectiveData() {
|
||||
const filteredSlugs = ['github-sponsors'];
|
||||
|
||||
// Documentation at https://graphql-docs-v2.opencollective.com/welcome
|
||||
const query = `query account {
|
||||
collective(slug: "tauri") {
|
||||
contributors(limit: 1000) {
|
||||
nodes {
|
||||
account {
|
||||
name
|
||||
type
|
||||
imageUrl(height: ${IMAGE_DIMENSION})
|
||||
slug
|
||||
isIncognito
|
||||
}
|
||||
totalAmountContributed {
|
||||
value
|
||||
currency
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const res = await fetch('https://api.opencollective.com/graphql/v2', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw Error(
|
||||
`Open Collective query failed: ${res.status} ${res.statusText} \n ${JSON.stringify(await res.json(), null, 2)}, `
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: handle currency
|
||||
|
||||
const openCollectiveData = (await res.json()).data;
|
||||
return openCollectiveData.collective.contributors.nodes
|
||||
.filter(
|
||||
(node: any) =>
|
||||
!node.account.isIncognito &&
|
||||
node.totalAmountContributed.value > 0 &&
|
||||
!filteredSlugs.includes(node.account.slug) &&
|
||||
node.account.name != 'Guest'
|
||||
)
|
||||
.sort((a: any, b: any) => b.totalAmountContributed.value - a.totalAmountContributed.value)
|
||||
.map((node: any): Sponsor => {
|
||||
let tier: Tier;
|
||||
let amount = node.totalAmountContributed.value;
|
||||
if (amount >= PLATINUM_THRESHOLD) {
|
||||
tier = 'platinum';
|
||||
} else if (amount >= GOLD_THRESHOLD) {
|
||||
tier = 'gold';
|
||||
} else if (amount >= SILVER_THRESHOLD) {
|
||||
tier = 'silver';
|
||||
} else {
|
||||
tier = 'bronze';
|
||||
}
|
||||
const { slug, name, type, isIncognito, imageUrl } = node.account;
|
||||
|
||||
return {
|
||||
name,
|
||||
id: name,
|
||||
avatarUrl: imageUrl,
|
||||
profileUrl: `https://opencollective.com/${slug}`,
|
||||
tier,
|
||||
type,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": ".",
|
||||
"name": "docs"
|
||||
},
|
||||
{
|
||||
"path": "packages",
|
||||
"name": "packages",
|
||||
"folders": [
|
||||
{
|
||||
"path": "js-api-generator",
|
||||
},
|
||||
{
|
||||
"path": "config-generator",
|
||||
},
|
||||
{
|
||||
"path": "cli-generator",
|
||||
},
|
||||
{
|
||||
"path": "releases-generator",
|
||||
},
|
||||
{
|
||||
"path": "compatibility-table",
|
||||
}
|
||||
]
|
||||
},
|
||||
// todo: fix paths so that we can see docs, packages and submodules
|
||||
{
|
||||
"path": "packages",
|
||||
"name": "submodules",
|
||||
"folders": [
|
||||
{
|
||||
"path": "awesome-tauri",
|
||||
},
|
||||
{
|
||||
"path": "tauri",
|
||||
},
|
||||
{
|
||||
"path": "plugins-workspace",
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": ".",
|
||||
"name": "docs",
|
||||
},
|
||||
{
|
||||
"path": "packages",
|
||||
"name": "packages",
|
||||
"folders": [
|
||||
{
|
||||
"path": "js-api-generator",
|
||||
},
|
||||
{
|
||||
"path": "config-generator",
|
||||
},
|
||||
{
|
||||
"path": "cli-generator",
|
||||
},
|
||||
{
|
||||
"path": "releases-generator",
|
||||
},
|
||||
{
|
||||
"path": "compatibility-table",
|
||||
},
|
||||
],
|
||||
},
|
||||
// todo: fix paths so that we can see docs, packages and submodules
|
||||
{
|
||||
"path": "packages",
|
||||
"name": "submodules",
|
||||
"folders": [
|
||||
{
|
||||
"path": "awesome-tauri",
|
||||
},
|
||||
{
|
||||
"path": "tauri",
|
||||
},
|
||||
{
|
||||
"path": "plugins-workspace",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"settings": {},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user