refactor(cli): code review cleanup fix for tab+tab (#18967)

This commit is contained in:
Jacob Richman
2026-02-17 07:16:37 -08:00
committed by GitHub
parent e5ff2023ad
commit 366f1df120
14 changed files with 334 additions and 197 deletions

View File

@@ -0,0 +1,69 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { useRef, useCallback, useEffect, useState } from 'react';
export interface UseRepeatedKeyPressOptions {
onRepeat?: (count: number) => void;
onReset?: () => void;
windowMs: number;
}
export function useRepeatedKeyPress(options: UseRepeatedKeyPressOptions) {
const [pressCount, setPressCount] = useState(0);
const pressCountRef = useRef(0);
const timerRef = useRef<NodeJS.Timeout | null>(null);
// To avoid stale closures
const optionsRef = useRef(options);
useEffect(() => {
optionsRef.current = options;
}, [options]);
const resetCount = useCallback(() => {
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
if (pressCountRef.current > 0) {
pressCountRef.current = 0;
setPressCount(0);
optionsRef.current.onReset?.();
}
}, []);
const handlePress = useCallback((): number => {
const newCount = pressCountRef.current + 1;
pressCountRef.current = newCount;
setPressCount(newCount);
if (timerRef.current) {
clearTimeout(timerRef.current);
}
timerRef.current = setTimeout(() => {
pressCountRef.current = 0;
setPressCount(0);
timerRef.current = null;
optionsRef.current.onReset?.();
}, optionsRef.current.windowMs);
optionsRef.current.onRepeat?.(newCount);
return newCount;
}, []);
useEffect(
() => () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
},
[],
);
return { pressCount, handlePress, resetCount };
}

View File

@@ -0,0 +1,79 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { useState, useRef, useCallback, useEffect } from 'react';
import { persistentState } from '../../utils/persistentState.js';
export const APPROVAL_MODE_REVEAL_DURATION_MS = 1200;
const FOCUS_UI_ENABLED_STATE_KEY = 'focusUiEnabled';
export function useVisibilityToggle() {
const [focusUiEnabledByDefault] = useState(
() => persistentState.get(FOCUS_UI_ENABLED_STATE_KEY) === true,
);
const [cleanUiDetailsVisible, setCleanUiDetailsVisibleState] = useState(
!focusUiEnabledByDefault,
);
const modeRevealTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const cleanUiDetailsPinnedRef = useRef(!focusUiEnabledByDefault);
const clearModeRevealTimeout = useCallback(() => {
if (modeRevealTimeoutRef.current) {
clearTimeout(modeRevealTimeoutRef.current);
modeRevealTimeoutRef.current = null;
}
}, []);
const persistFocusUiPreference = useCallback((isFullUiVisible: boolean) => {
persistentState.set(FOCUS_UI_ENABLED_STATE_KEY, !isFullUiVisible);
}, []);
const setCleanUiDetailsVisible = useCallback(
(visible: boolean) => {
clearModeRevealTimeout();
cleanUiDetailsPinnedRef.current = visible;
setCleanUiDetailsVisibleState(visible);
persistFocusUiPreference(visible);
},
[clearModeRevealTimeout, persistFocusUiPreference],
);
const toggleCleanUiDetailsVisible = useCallback(() => {
clearModeRevealTimeout();
setCleanUiDetailsVisibleState((visible) => {
const nextVisible = !visible;
cleanUiDetailsPinnedRef.current = nextVisible;
persistFocusUiPreference(nextVisible);
return nextVisible;
});
}, [clearModeRevealTimeout, persistFocusUiPreference]);
const revealCleanUiDetailsTemporarily = useCallback(
(durationMs: number = APPROVAL_MODE_REVEAL_DURATION_MS) => {
if (cleanUiDetailsPinnedRef.current) {
return;
}
clearModeRevealTimeout();
setCleanUiDetailsVisibleState(true);
modeRevealTimeoutRef.current = setTimeout(() => {
if (!cleanUiDetailsPinnedRef.current) {
setCleanUiDetailsVisibleState(false);
}
modeRevealTimeoutRef.current = null;
}, durationMs);
},
[clearModeRevealTimeout],
);
useEffect(() => () => clearModeRevealTimeout(), [clearModeRevealTimeout]);
return {
cleanUiDetailsVisible,
setCleanUiDetailsVisible,
toggleCleanUiDetailsVisible,
revealCleanUiDetailsTemporarily,
};
}