fix: sticker toggle disabled state reactivity and pulse edge case

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-23 17:14:14 -04:00
parent cea0e8c2be
commit ab973cbf4f

View File

@@ -34,14 +34,19 @@ function Picker() {
const [sessionEnded, setSessionEnded] = useState(false);
const [stickerMode, setStickerMode] = useState('auto');
const stickerSendRef = useRef(null);
const [stickerWsReady, setStickerWsReady] = useState(false);
const [stickerPulse, setStickerPulse] = useState(false);
const prevStickerModeRef = useRef(stickerMode);
useEffect(() => {
if (stickerMode === 'auto' && prevStickerModeRef.current !== 'auto') {
setStickerPulse(true);
const timer = setTimeout(() => setStickerPulse(false), 2000);
prevStickerModeRef.current = stickerMode;
return () => clearTimeout(timer);
}
if (stickerMode !== 'auto') {
setStickerPulse(false);
}
prevStickerModeRef.current = stickerMode;
}, [stickerMode]);
@@ -905,7 +910,7 @@ function Picker() {
setStickerMode(opt.value);
stickerSendRef.current?.(opt.value);
}}
disabled={!stickerSendRef.current}
disabled={!stickerWsReady}
className={`px-3 py-1.5 text-xs font-medium transition ${
i === 1 ? 'border-x border-gray-300 dark:border-gray-600 ' : ''
}${
@@ -913,7 +918,7 @@ function Picker() {
? opt.activeClass
: 'bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-300'
}${
!stickerSendRef.current ? ' opacity-50 cursor-not-allowed' : ''
!stickerWsReady ? ' opacity-50 cursor-not-allowed' : ''
}`}
>
{opt.label}
@@ -1346,6 +1351,7 @@ function Picker() {
setGameSource={setGameSource}
setStickerMode={setStickerMode}
stickerSendRef={stickerSendRef}
setStickerWsReady={setStickerWsReady}
/>
</div>
</div>
@@ -1353,7 +1359,7 @@ function Picker() {
);
}
function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame, setHasPlayedGames, setLeadingGame, setPollActive, pollActiveRef, setPollResult, setPollEndingAt, setShowEndPollOptions, pollStartedAtRef, setSelectedGame, setGameSource, setStickerMode, stickerSendRef }) {
function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame, setHasPlayedGames, setLeadingGame, setPollActive, pollActiveRef, setPollResult, setPollEndingAt, setShowEndPollOptions, pollStartedAtRef, setSelectedGame, setGameSource, setStickerMode, stickerSendRef, setStickerWsReady }) {
const { isAuthenticated, token } = useAuth();
const [games, setGames] = useState([]);
const [loading, setLoading] = useState(true);
@@ -1450,6 +1456,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame, se
ws.send(JSON.stringify({ type: 'stickers.setMode', data: { mode } }));
}
};
setStickerWsReady(true);
return;
}
@@ -1552,6 +1559,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame, se
console.log('[WebSocket] Disconnected, reconnecting in 3s...');
clearInterval(pingIntervalRef.current);
stickerSendRef.current = null;
setStickerWsReady(false);
reconnectTimeoutRef.current = setTimeout(connectWs, 3000);
};
@@ -1560,7 +1568,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame, se
console.error('[WebSocket] Failed to connect:', error);
reconnectTimeoutRef.current = setTimeout(connectWs, 3000);
}
}, [sessionId, token, loadGames, setPollActive, setPollResult, setPollEndingAt, setShowEndPollOptions, setLeadingGame, pollActiveRef, pollStartedAtRef, setSelectedGame, setGameSource, setStickerMode, stickerSendRef]);
}, [sessionId, token, loadGames, setPollActive, setPollResult, setPollEndingAt, setShowEndPollOptions, setLeadingGame, pollActiveRef, pollStartedAtRef, setSelectedGame, setGameSource, setStickerMode, stickerSendRef, setStickerWsReady]);
useEffect(() => {
connectWs();
@@ -1568,6 +1576,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame, se
return () => {
clearTimeout(reconnectTimeoutRef.current);
clearInterval(pingIntervalRef.current);
setStickerWsReady(false);
if (wsRef.current) {
wsRef.current.onclose = null;
wsRef.current.close();