Skip to content
55 changes: 50 additions & 5 deletions src/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,24 @@ const currentPath = Astro.url.pathname;

<!-- Right Actions -->
<div class="flex items-center gap-3 flex-shrink-0">
<!-- Star on GitHub -->
<a
href="https://github.com/future-agi"
href="https://github.com/future-agi/future-agi"
target="_blank"
rel="noopener noreferrer"
aria-label="GitHub"
class="hidden sm:inline-flex items-center p-1.5 text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors"
class="hidden sm:inline-flex items-center gap-1.5 px-2.5 py-1.5 text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] transition-colors group"
aria-label="Star on GitHub"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0022 12.017C22 6.484 17.522 2 12 2z"/>
<span>Star on</span>
<svg class="w-[18px] h-[18px]" fill="currentColor" viewBox="0 0 24 24">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" />
</svg>
<span class="inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md bg-[var(--color-bg-tertiary)] border border-[var(--color-border-subtle)] text-[11px] text-[var(--color-text-secondary)] group-hover:border-[var(--color-border-accent)] transition-colors min-w-[28px] justify-center">
<svg class="w-2.5 h-2.5" style="color: #fbbf24;" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
</svg>
<span data-github-stars>—</span>
</span>
</a>

<a
Expand Down Expand Up @@ -257,5 +265,42 @@ const currentPath = Astro.url.pathname;

setupHeader();
document.addEventListener('astro:page-load', setupHeader);

// GitHub star counter - fetches live count, caches for 10 min
function formatStars(count) {
if (count >= 1000) {
return (count / 1000).toFixed(count >= 10000 ? 0 : 1).replace(/\.0$/, '') + 'k';
}
return String(count);
}

async function loadGitHubStars() {
const targets = document.querySelectorAll('[data-github-stars]');
if (!targets.length) return;
const CACHE_KEY = 'gh-stars-future-agi';
const CACHE_TTL = 10 * 60 * 1000;
try {
const cached = localStorage.getItem(CACHE_KEY);
if (cached) {
const { count, ts } = JSON.parse(cached);
if (Date.now() - ts < CACHE_TTL && typeof count === 'number') {
targets.forEach(el => { el.textContent = formatStars(count); });
return;
}
}
} catch {}
try {
const res = await fetch('https://api.github.com/repos/future-agi/future-agi');
if (!res.ok) throw new Error('GitHub API error');
const data = await res.json();
const count = data.stargazers_count || 0;
targets.forEach(el => { el.textContent = formatStars(count); });
try { localStorage.setItem(CACHE_KEY, JSON.stringify({ count, ts: Date.now() })); } catch {}
} catch {
targets.forEach(el => { el.textContent = '★'; });
}
}
loadGitHubStars();
document.addEventListener('astro:page-load', loadGitHubStars);
})();
</script>
Loading