- | Agent Status |
+ Agent |
{agentConnected ? "Connected" : "Disconnected"}
|
@@ -124,10 +119,11 @@ export function HeaderRoomInfo() {
export function HeaderActions() {
return (
-
+ {/*
GitHub
-
+ */}
+
{/*
*/}
@@ -228,3 +224,32 @@ const NetworkIndicator = dynamic(
ssr: false,
},
)
+
+export const GitHubStar = () => {
+ const [{ data, error, isLoading }] = useCancelableSWR<{
+ stargazers_count: number
+ }>(API_GH_GET_REPO_INFO, {
+ refreshInterval: 1000 * 60 * 60, // 1 hour
+ revalidateOnFocus: false,
+ revalidateOnReconnect: false,
+ })
+
+ const starsCntMemo = React.useMemo(() => {
+ if (!data || !data.stargazers_count) return null
+ return formatNumber(data?.stargazers_count || 0)
+ }, [data?.stargazers_count])
+
+ return (
+
+ )
+}
diff --git a/demo/src/hooks/index.ts b/demo/src/hooks/index.ts
new file mode 100644
index 0000000000..da276f850c
--- /dev/null
+++ b/demo/src/hooks/index.ts
@@ -0,0 +1,32 @@
+"use client"
+
+import { type SWRResponse, type SWRConfiguration } from "swr"
+import useSWR from "swr"
+
+// https://github.com/vercel/swr/discussions/2330#discussioncomment-4460054
+export function useCancelableSWR(
+ key: string,
+ opts?: SWRConfiguration,
+): [SWRResponse, AbortController] {
+ const controller = new AbortController()
+ return [
+ useSWR(
+ key,
+ (url: string) =>
+ fetch(url, { signal: controller.signal }).then((res) => res.json()),
+ {
+ // revalidateOnFocus: false,
+ errorRetryCount: 3,
+ refreshInterval: 1000 * 60,
+ // dedupingInterval: 30000,
+ // focusThrottleInterval: 60000,
+ ...opts,
+ },
+ ),
+ controller,
+ ]
+ // to use it:
+ // const [{ data }, controller] = useCancelableSWR('/api')
+ // ...
+ // controller.abort()
+}
diff --git a/demo/src/lib/utils.ts b/demo/src/lib/utils.ts
index ca1ebd17cf..ea9cc4bf80 100644
--- a/demo/src/lib/utils.ts
+++ b/demo/src/lib/utils.ts
@@ -20,3 +20,17 @@ export function useIsMobileScreen(breakpoint?: string) {
return isMobileScreen
}
+
+export function formatNumber(num: number, decimals: number = 1): string {
+ if (num === 0) return "0"
+
+ const k = 1000
+ const sizes = ["", "K", "M", "B", "T"]
+
+ const i = Math.floor(Math.log(Math.abs(num)) / Math.log(k))
+
+ if (i === 0) return num.toString()
+
+ const scaled = num / Math.pow(k, i)
+ return `${scaled.toFixed(decimals)}${sizes[i]}`
+}