Skip to content

Commit 8024924

Browse files
committed
fix: allow Pr click
1 parent 3f542b5 commit 8024924

1 file changed

Lines changed: 35 additions & 14 deletions

File tree

src/components/MostCommentedPRs.tsx

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect, useMemo } from "react";
1+
import { useState, useEffect, useMemo, useCallback, useRef } from "react";
22
import type { MostCommentedPR } from "../types.ts";
33

44
interface MostCommentedPRsProps {
@@ -78,6 +78,7 @@ const EMOJI_MAP: Record<string, string> = {
7878
money_with_wings: "\u{1F4B8}",
7979
thread: "\u{1F9F5}",
8080
safety_vest: "\u{1F9BA}",
81+
mag_right: "\u{1F50E}",
8182
};
8283

8384
function replaceEmojiShortcodes(text: string): string {
@@ -99,29 +100,49 @@ export function MostCommentedPRs({ prs }: MostCommentedPRsProps) {
99100
const shuffled = useMemo(() => shuffle(prs), [prs]);
100101
const [index, setIndex] = useState(0);
101102
const [visible, setVisible] = useState(true);
103+
const cycleRef = useRef<ReturnType<typeof setInterval> | null>(null);
104+
const fadingRef = useRef(false);
105+
106+
const cycle = useCallback(() => {
107+
if (fadingRef.current) return;
108+
fadingRef.current = true;
109+
setVisible(false);
110+
setTimeout(() => {
111+
setIndex((prev) => (prev + 1) % shuffled.length);
112+
setVisible(true);
113+
fadingRef.current = false;
114+
}, FADE_MS);
115+
}, [shuffled.length]);
116+
117+
const resetTimer = useCallback(() => {
118+
if (cycleRef.current) clearInterval(cycleRef.current);
119+
cycleRef.current = setInterval(cycle, CYCLE_MS);
120+
}, [cycle]);
102121

103122
useEffect(() => {
104123
if (shuffled.length <= 1) return;
124+
cycleRef.current = setInterval(cycle, CYCLE_MS);
125+
return () => {
126+
if (cycleRef.current) clearInterval(cycleRef.current);
127+
};
128+
}, [shuffled.length, cycle]);
105129

106-
const interval = setInterval(() => {
107-
// fade out
108-
setVisible(false);
109-
// after fade-out, switch item and fade in
110-
setTimeout(() => {
111-
setIndex((prev) => (prev + 1) % shuffled.length);
112-
setVisible(true);
113-
}, FADE_MS);
114-
}, CYCLE_MS);
115-
116-
return () => clearInterval(interval);
117-
}, [shuffled.length]);
130+
const handleClick = useCallback(
131+
(e: React.MouseEvent) => {
132+
if ((e.target as HTMLElement).closest("a")) return;
133+
if (shuffled.length <= 1) return;
134+
cycle();
135+
resetTimer();
136+
},
137+
[cycle, resetTimer, shuffled.length],
138+
);
118139

119140
if (shuffled.length === 0) return null;
120141

121142
const pr = shuffled[index];
122143

123144
return (
124-
<section className="relative overflow-hidden bg-gradient-to-br from-blue-800 via-blue-900 to-red-800 text-white rounded-xl p-6 sm:p-8 shadow-lg shadow-blue-500/25">
145+
<section onClick={handleClick} className="relative overflow-hidden bg-gradient-to-br from-blue-800 via-blue-900 to-red-800 text-white rounded-xl p-6 sm:p-8 shadow-lg shadow-blue-500/25 cursor-pointer">
125146
{/* Animated tricolore glow */}
126147
<div
127148
className="absolute inset-0 opacity-30"

0 commit comments

Comments
 (0)