-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
diff --git a/components/ui/skeleton.tsx b/components/ui/skeleton.tsx
index 0118624..8fc953e 100644
--- a/components/ui/skeleton.tsx
+++ b/components/ui/skeleton.tsx
@@ -4,7 +4,10 @@ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
return (
)
diff --git a/locales/ar.json b/locales/ar.json
index 9431ed5..c1182eb 100644
--- a/locales/ar.json
+++ b/locales/ar.json
@@ -47,6 +47,7 @@
"error.resourceLimit": "تم الوصول إلى حدود موارد GitHub API لهذا الطلب. حاول مرة أخرى بعد قليل.",
"error.missingUsername": "أدخل اسمين للمقارنة.",
"error.userNotFound": "لم يتم العثور على مستخدم GitHub",
+ "error.sameUser": "مطلوب اسمان مختلفان لمستخدمي GitHub.",
"explanations.contribution": "درجة المساهمات",
"explanations.line.contribution.1": "تعتمد درجة المساهمات على المشكلات والنقاشات الخارجية فقط.",
"explanations.line.contribution.2": "لا يتم احتساب الـ commits وطلبات السحب لتجنب العد المزدوج.",
diff --git a/locales/en.json b/locales/en.json
index 4a07471..af52421 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -47,6 +47,7 @@
"error.resourceLimit": "GitHub API resource limits were reached for this request. Please retry shortly.",
"error.missingUsername": "Provide two usernames to compare.",
"error.userNotFound": "GitHub user not found",
+ "error.sameUser": "Two different GitHub usernames are required.",
"explanations.contribution": "Contribution Score",
"explanations.line.contribution.1": "Contribution score is based on external issues and discussions only.",
"explanations.line.contribution.2": "Commits and pull requests are excluded to avoid double-counting.",
From 9b7a578c4265d31dc55605606c0bb3a66bf800c9 Mon Sep 17 00:00:00 2001
From: Osama Mabkhot <99215291+O2sa@users.noreply.github.com>
Date: Fri, 14 Aug 2026 02:41:31 +0300
Subject: [PATCH 8/8] fix: Cannot access ref value during render
Co-authored-by: Copilot
---
components/home-page-client.tsx | 35 +++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/components/home-page-client.tsx b/components/home-page-client.tsx
index 479ae0c..c5edf71 100644
--- a/components/home-page-client.tsx
+++ b/components/home-page-client.tsx
@@ -96,6 +96,7 @@ export function HomePageClient() {
);
const [data, setData] = useState(null);
const [displayData, setDisplayData] = useState(null);
+ const [disableDuplicateFetch, setDisableDuplicateFetch] = useState(false);
const lastFetchedKeyRef = useRef(null);
const inFlightFetchKeyRef = useRef(null);
const inFlightPromiseRef = useRef | null>(null);
@@ -235,6 +236,11 @@ export function HomePageClient() {
lastFetchedKeyRef.current = fetchKey;
+ // update duplicate fetch state for current form values
+ setDisableDuplicateFetch(
+ Boolean(lastFetchedKeyRef.current === createFetchKey(username1.trim(), username2.trim(), { selectedLanguages }) && (data || inFlightFetchKeyRef.current === fetchKey)),
+ );
+
const requestPromise = (async () => {
if (options.updateUrl !== false) {
const params = new URLSearchParams();
@@ -311,6 +317,11 @@ export function HomePageClient() {
inFlightFetchKeyRef.current = fetchKey;
inFlightPromiseRef.current = requestPromise;
+ // mark duplicate fetch disabled while request is in-flight
+ setDisableDuplicateFetch(
+ Boolean(lastFetchedKeyRef.current === createFetchKey(username1.trim(), username2.trim(), { selectedLanguages }) && (data || inFlightFetchKeyRef.current === fetchKey)),
+ );
+
return requestPromise;
};
@@ -324,6 +335,7 @@ export function HomePageClient() {
lastFetchedKeyRef.current = null;
setData(null);
resetErrors();
+ setDisableDuplicateFetch(false);
return;
}
@@ -331,10 +343,7 @@ export function HomePageClient() {
selectedLanguages: languages,
});
- if (
- lastFetchedKeyRef.current === nextKey &&
- (data || inFlightFetchKeyRef.current === nextKey)
- ) {
+ if (lastFetchedKeyRef.current === nextKey && data) {
return;
}
@@ -388,13 +397,18 @@ export function HomePageClient() {
const isRefreshing = loading && Boolean(displayData);
const isExiting = !loading && !data && Boolean(displayData);
- const currentFetchKey = createFetchKey(username1.trim(), username2.trim(), {
- selectedLanguages,
- });
- const disableDuplicateFetch = Boolean(
- lastFetchedKeyRef.current === currentFetchKey && (data || inFlightFetchKeyRef.current === currentFetchKey),
- );
+ useEffect(() => {
+ const currentFetchKey = createFetchKey(username1.trim(), username2.trim(), {
+ selectedLanguages,
+ });
+
+ const lastKey = lastFetchedKeyRef.current;
+ const inFlightKey = inFlightFetchKeyRef.current;
+
+ const disabled = Boolean(lastKey === currentFetchKey && (data || inFlightKey === currentFetchKey));
+ setDisableDuplicateFetch(disabled);
+ }, [username1, username2, selectedLanguages, data, loading]);
const handleUsername1Change = (value: string) => {
setUsername1(value);
@@ -416,6 +430,7 @@ export function HomePageClient() {
resetErrors();
inFlightFetchKeyRef.current = null;
inFlightPromiseRef.current = null;
+ setDisableDuplicateFetch(false);
setUsername1("");
setUsername2("");
setSelectedLanguages([]);