Skip to content

Commit 6189ea1

Browse files
committed
feat: implement dynamic GitHub contributor fetching and update contributor UI display
1 parent dd6cd10 commit 6189ea1

1 file changed

Lines changed: 72 additions & 5 deletions

File tree

src/views/Home.vue

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const activeOS = ref<string>('arch');
2424
const setupStep = ref<number>(0);
2525
const isScrolled = ref<boolean>(false);
2626
const starCount = ref<string>('160+');
27+
const contributorCount = ref<number>(5);
28+
const REPO = 'LotusInputMethod/fcitx5-lotus';
2729
2830
// --- CATPPUCCIN THEME LOGIC ---
2931
const catppuccinThemes = ['latte', 'frappe', 'macchiato', 'mocha'] as const;
@@ -71,7 +73,6 @@ const startTyping = () => {
7173
};
7274
7375
const fetchGithubStars = async () => {
74-
const REPO = 'LotusInputMethod/fcitx5-lotus';
7576
const CACHE_KEY = 'lotus_stars_cache';
7677
const CACHE_TIME_KEY = 'lotus_stars_timestamp';
7778
const TWO_HOURS = 2 * 60 * 60 * 1000;
@@ -102,6 +103,60 @@ const fetchGithubStars = async () => {
102103
}
103104
};
104105
106+
const fetchContributors = async () => {
107+
const CACHE_KEY = 'lotus_contributors_cache_v2';
108+
const CACHE_TIME_KEY = 'lotus_contributors_timestamp_v2';
109+
const TWO_HOURS = 2 * 60 * 60 * 1000;
110+
111+
const specialRoles: Record<string, string> = {
112+
nhktmdzhg: 'Founder',
113+
};
114+
115+
const blacklist = ['thanhpy2009', 'loccun'];
116+
117+
try {
118+
const cachedData = localStorage.getItem(CACHE_KEY);
119+
const lastFetch = localStorage.getItem(CACHE_TIME_KEY);
120+
const now = Date.now();
121+
122+
if (cachedData && lastFetch && now - parseInt(lastFetch) < TWO_HOURS) {
123+
const parsed = JSON.parse(cachedData);
124+
// Filter again in case the blacklist was updated and we have stale cache
125+
const filtered = parsed.filter(
126+
(c: any) => !blacklist.includes(c.name) && !c.name.includes('[bot]'),
127+
);
128+
contributors.value = filtered;
129+
contributorCount.value = filtered.length;
130+
return;
131+
}
132+
133+
const response = await fetch(`https://api.github.com/repos/${REPO}/contributors`);
134+
if (!response.ok) throw new Error('GitHub API error');
135+
136+
const data = await response.json();
137+
const fetchedContributors: Contributor[] = data
138+
.filter((item: any) => !blacklist.includes(item.login) && item.type !== 'Bot')
139+
.map((item: any) => ({
140+
name: item.login,
141+
role: specialRoles[item.login] || 'Contributor',
142+
avatar: item.avatar_url,
143+
githubUrl: item.html_url,
144+
}));
145+
146+
contributors.value = fetchedContributors;
147+
contributorCount.value = fetchedContributors.length;
148+
localStorage.setItem(CACHE_KEY, JSON.stringify(fetchedContributors));
149+
localStorage.setItem(CACHE_TIME_KEY, now.toString());
150+
} catch (error) {
151+
console.error('Lỗi khi lấy contributor từ GitHub:', error);
152+
const oldCache = localStorage.getItem(CACHE_KEY);
153+
if (oldCache) {
154+
contributors.value = JSON.parse(oldCache);
155+
contributorCount.value = contributors.value.length;
156+
}
157+
}
158+
};
159+
105160
onMounted(() => {
106161
const savedTheme = localStorage.getItem('catppuccin-theme');
107162
if (savedTheme && catppuccinThemes.includes(savedTheme as CatppuccinTheme)) {
@@ -119,6 +174,7 @@ onMounted(() => {
119174
window.addEventListener('scroll', handleScroll);
120175
startTyping();
121176
fetchGithubStars();
177+
fetchContributors();
122178
});
123179
124180
onUnmounted(() => {
@@ -269,34 +325,40 @@ interface Contributor {
269325
name: string;
270326
role: string;
271327
avatar: string;
328+
githubUrl: string;
272329
}
273-
const contributors: Contributor[] = [
330+
const contributors = ref<Contributor[]>([
274331
{
275332
name: 'Nguyen Hoang Ky',
276333
role: 'Founder',
277334
avatar: 'https://avatars.githubusercontent.com/u/57983253?v=4',
335+
githubUrl: 'https://github.com/khog9',
278336
},
279337
{
280338
name: 'Huỳnh Thiện Lộc',
281339
role: 'Contributor',
282340
avatar: 'https://avatars.githubusercontent.com/u/148019203?v=4',
341+
githubUrl: 'https://github.com/hthienloc',
283342
},
284343
{
285344
name: 'Nguyễn Hồng Hiệp',
286345
role: 'Contributor',
287346
avatar: 'https://avatars.githubusercontent.com/u/57614330?v=4',
347+
githubUrl: 'https://github.com/Hiep-N',
288348
},
289349
{
290350
name: 'Đặng Quang Hiển',
291351
role: 'Contributor',
292352
avatar: 'https://avatars.githubusercontent.com/u/83270073?v=4',
353+
githubUrl: 'https://github.com/dqhien',
293354
},
294355
{
295356
name: 'Zebra2711',
296357
role: 'Contributor',
297358
avatar: 'https://avatars.githubusercontent.com/u/89755535?v=4',
359+
githubUrl: 'https://github.com/Zebra2711',
298360
},
299-
];
361+
]);
300362
301363
// --- COMMANDS ---
302364
const commands: Record<string, string> = {
@@ -449,7 +511,7 @@ const copyToClipboard = async (text: string | undefined): Promise<void> => {
449511
<span>Distros hỗ trợ</span>
450512
</div>
451513
<div class="stat-item">
452-
<strong>5</strong>
514+
<strong>{{ contributorCount }}</strong>
453515
<span>Người đóng góp</span>
454516
</div>
455517
</div>
@@ -669,7 +731,12 @@ const copyToClipboard = async (text: string | undefined): Promise<void> => {
669731
</div>
670732

671733
<div class="contributors-flex">
672-
<div v-for="c in contributors" :key="c.name" class="contributor-item">
734+
<div
735+
v-for="c in contributors"
736+
:key="c.name"
737+
class="contributor-item"
738+
@click="openLink(c.githubUrl)"
739+
>
673740
<el-avatar :size="80" :src="c.avatar" class="contributor-avatar" />
674741
<div class="c-name">{{ c.name }}</div>
675742
<div class="c-role">{{ c.role }}</div>

0 commit comments

Comments
 (0)