Skip to content

Commit 642a77d

Browse files
committed
feat(app): add Github star count
1 parent 04453e6 commit 642a77d

File tree

5 files changed

+110
-19
lines changed

5 files changed

+110
-19
lines changed

content/1-reactivity/2-update-state/react/Name.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { useEffect, useState } from "react";
33
export default function Name() {
44
const [name, setName] = useState("John");
55

6-
useEffect(() => setName("Jane"), []);
6+
useEffect(() => {
7+
setName("Jane");
8+
}, []);
79

810
return <h1>Hello {name}</h1>;
9-
}
11+
}

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
:root {
5858
/* bg-gray-900 */
5959
--bg-color: rgb(17 24 39);
60+
color-scheme: dark;
6061
}
6162

6263
html {

src/app.css

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
:root {
2-
color-scheme: dark;
3-
}
4-
51
@tailwind base;
62
@tailwind components;
73
@tailwind utilities;
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<script>
2+
import { onMount } from "svelte";
3+
import createLocaleStorage from "../lib/createLocaleStorage";
4+
import GithubIcon from "./GithubIcon.svelte";
5+
6+
const REPOSITORY_PATH = "matschik/component-party.dev";
7+
const DURATION_2_MIN = 1000 * 60 * 2;
8+
const STAR_COUNT_DURATION_EXPIRATION = DURATION_2_MIN;
9+
10+
const starCountStorage = createLocaleStorage("github-star-count");
11+
12+
let starCount = 0;
13+
let isFetchingStarCount = false;
14+
15+
async function getRepoStarCount() {
16+
const starCountStorageData = starCountStorage.getJSON();
17+
if (starCountStorageData) {
18+
starCount = starCountStorageData.value;
19+
if (
20+
starCountStorageData.fetchedAt >
21+
Date.now() - STAR_COUNT_DURATION_EXPIRATION
22+
) {
23+
return;
24+
}
25+
}
26+
27+
isFetchingStarCount = true;
28+
29+
// Github public API rate limit: 60 requests per hour
30+
const data = await fetch(
31+
`https://api.github.com/repos/${REPOSITORY_PATH}`,
32+
{
33+
headers: {
34+
Accept: "application/vnd.github.v3.star+json",
35+
Authorization: "",
36+
},
37+
}
38+
)
39+
.finally(() => {
40+
isFetchingStarCount = false;
41+
})
42+
.then((r) => r.json());
43+
44+
if (data.stargazers_count) {
45+
starCount = data.stargazers_count;
46+
starCountStorage.setJSON({
47+
value: starCount,
48+
fetchedAt: Date.now(),
49+
});
50+
}
51+
}
52+
53+
onMount(() => {
54+
getRepoStarCount();
55+
});
56+
57+
function onButtonClick() {
58+
starCountStorage.remove();
59+
}
60+
</script>
61+
62+
<a
63+
class="bg-[#21262d] text-[#c9d1d9] border border-[#373b43] py-1 rounded flex items-center text-sm shadow-inner hover:opacity-90"
64+
href={`https://github.com/${REPOSITORY_PATH}`}
65+
target="_blank"
66+
aria-label={`Star ${REPOSITORY_PATH} on GitHub`}
67+
on:click={onButtonClick}
68+
>
69+
<span
70+
class="space-x-2 flex items-center border-r border-[#373b43] font-medium px-2"
71+
>
72+
<GithubIcon class="w-[1.1rem] h-[1.1rem]" />
73+
<span class="mt-px">Star</span>
74+
</span>
75+
{#if isFetchingStarCount || starCount !== 0}
76+
<div class="h-full flex justify-center items-center pl-3 pr-3 font-medium">
77+
{#if isFetchingStarCount && starCount === 0}
78+
<svg
79+
class="animate-spin h-4 w-4 mx-1"
80+
xmlns="http://www.w3.org/2000/svg"
81+
fill="none"
82+
viewBox="0 0 24 24"
83+
>
84+
<circle
85+
class="opacity-25"
86+
cx="12"
87+
cy="12"
88+
r="10"
89+
stroke="currentColor"
90+
stroke-width="4"
91+
/>
92+
<path
93+
class="opacity-75"
94+
fill="currentColor"
95+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
96+
/>
97+
</svg>
98+
{:else}
99+
<span class="mt-px">{starCount}</span>
100+
{/if}
101+
</div>
102+
{/if}
103+
</a>

src/components/Header.svelte

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script>
2-
import GithubIcon from "./GithubIcon.svelte";
2+
import GithubStarButton from "./GithubStarButton.svelte";
33
</script>
44

55
<header class="backdrop-blur bg-gray-900/80 border-b border-gray-700">
@@ -9,18 +9,7 @@
99
<img src="/popper.svg" alt="logo" class="w-5 h-5" />
1010
<span>Component party</span>
1111
</a>
12-
13-
<div>
14-
<a
15-
href="https://github.com/matschik/component-party"
16-
title="Contribute on Github"
17-
target="_blank"
18-
rel="noopener noreferrer"
19-
>
20-
<GithubIcon class="h-6 w-6" />
21-
<span class="sr-only">github</span>
22-
</a>
23-
</div>
12+
<GithubStarButton />
2413
</div>
2514
</div>
2615
</header>

0 commit comments

Comments
 (0)