your personal website on atproto - mirror
blento.app
1import type { CardDefinition } from '../../types';
2import GitHubContributorsCard from './GitHubContributorsCard.svelte';
3import CreateGitHubContributorsCardModal from './CreateGitHubContributorsCardModal.svelte';
4import GitHubContributorsCardSettings from './GitHubContributorsCardSettings.svelte';
5import { fetchGitHubContributors } from './api.remote';
6
7export type GitHubContributor = {
8 username: string;
9 avatarUrl: string | null;
10 contributions: number;
11 anonymous: boolean;
12};
13
14export type GitHubContributorsLoadedData = Record<string, GitHubContributor[] | undefined>;
15
16export const GitHubContributorsCardDefinition = {
17 type: 'githubContributors',
18 contentComponent: GitHubContributorsCard,
19 creationModalComponent: CreateGitHubContributorsCardModal,
20 settingsComponent: GitHubContributorsCardSettings,
21 createNew: (card) => {
22 card.w = 4;
23 card.h = 2;
24 card.mobileW = 8;
25 card.mobileH = 4;
26 card.cardData.owner = '';
27 card.cardData.repo = '';
28 },
29 loadData: async (items) => {
30 const contributorsData: GitHubContributorsLoadedData = {};
31 for (const item of items) {
32 const { owner, repo } = item.cardData;
33 if (!owner || !repo) continue;
34 const key = `${owner}/${repo}`;
35 if (contributorsData[key]) continue;
36 try {
37 const data = await fetchGitHubContributors({ owner, repo });
38 if (data) contributorsData[key] = data;
39 } catch (error) {
40 console.error('Failed to fetch GitHub contributors:', error);
41 }
42 }
43 return contributorsData;
44 },
45 loadDataServer: async (items) => {
46 const contributorsData: GitHubContributorsLoadedData = {};
47 for (const item of items) {
48 const { owner, repo } = item.cardData;
49 if (!owner || !repo) continue;
50 const key = `${owner}/${repo}`;
51 if (contributorsData[key]) continue;
52 try {
53 const data = await fetchGitHubContributors({ owner, repo });
54 if (data) contributorsData[key] = data;
55 } catch (error) {
56 console.error('Failed to fetch GitHub contributors:', error);
57 }
58 }
59 return contributorsData;
60 },
61 onUrlHandler: (url, item) => {
62 const match = url.match(/github\.com\/([^/]+)\/([^/]+)/);
63 if (!match) return null;
64
65 item.cardData.owner = match[1];
66 item.cardData.repo = match[2];
67
68 item.w = 4;
69 item.h = 2;
70 item.mobileW = 8;
71 item.mobileH = 4;
72
73 return item;
74 },
75 urlHandlerPriority: 1,
76 allowSetColor: true,
77 defaultColor: 'base',
78 minW: 2,
79 minH: 2,
80 name: 'GitHub Contributors',
81 groups: ['Social'],
82 keywords: ['github', 'contributors', 'open source', 'repository'],
83 icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /></svg>`,
84 canHaveLabel: true
85} as CardDefinition & { type: 'githubContributors' };