mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Avoid triggering refreshStatic unless there really is a banner to display. (#14328)
This commit is contained in:
@@ -73,6 +73,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|||||||
disableMouseEvents: vi.fn(),
|
disableMouseEvents: vi.fn(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
import ansiEscapes from 'ansi-escapes';
|
||||||
import type { LoadedSettings } from '../config/settings.js';
|
import type { LoadedSettings } from '../config/settings.js';
|
||||||
import type { InitializationResult } from '../core/initializer.js';
|
import type { InitializationResult } from '../core/initializer.js';
|
||||||
import { useQuotaAndFallback } from './hooks/useQuotaAndFallback.js';
|
import { useQuotaAndFallback } from './hooks/useQuotaAndFallback.js';
|
||||||
@@ -1915,4 +1916,35 @@ describe('AppContainer State Management', () => {
|
|||||||
unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Regression Tests', () => {
|
||||||
|
it('does not refresh static on startup if banner text is empty', async () => {
|
||||||
|
// Mock banner text to be empty strings
|
||||||
|
vi.spyOn(mockConfig, 'getBannerTextNoCapacityIssues').mockResolvedValue(
|
||||||
|
'',
|
||||||
|
);
|
||||||
|
vi.spyOn(mockConfig, 'getBannerTextCapacityIssues').mockResolvedValue('');
|
||||||
|
|
||||||
|
// Clear previous calls
|
||||||
|
mocks.mockStdout.write.mockClear();
|
||||||
|
|
||||||
|
const { unmount } = renderAppContainer();
|
||||||
|
|
||||||
|
// Allow async effects to run
|
||||||
|
await waitFor(() => expect(capturedUIState).toBeTruthy());
|
||||||
|
|
||||||
|
// Wait for fetchBannerTexts to complete
|
||||||
|
await act(async () => {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check that clearTerminal was NOT written to stdout
|
||||||
|
const clearTerminalCalls = mocks.mockStdout.write.mock.calls.filter(
|
||||||
|
(call: unknown[]) => call[0] === ansiEscapes.clearTerminal,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(clearTerminalCalls).toHaveLength(0);
|
||||||
|
unmount();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ import { useSettings } from './contexts/SettingsContext.js';
|
|||||||
import { enableSupportedProtocol } from './utils/kittyProtocolDetector.js';
|
import { enableSupportedProtocol } from './utils/kittyProtocolDetector.js';
|
||||||
import { useInputHistoryStore } from './hooks/useInputHistoryStore.js';
|
import { useInputHistoryStore } from './hooks/useInputHistoryStore.js';
|
||||||
import { enableBracketedPaste } from './utils/bracketedPaste.js';
|
import { enableBracketedPaste } from './utils/bracketedPaste.js';
|
||||||
|
import { useBanner } from './hooks/useBanner.js';
|
||||||
|
|
||||||
const WARNING_PROMPT_DURATION_MS = 1000;
|
const WARNING_PROMPT_DURATION_MS = 1000;
|
||||||
const QUEUE_ERROR_DISPLAY_DURATION_MS = 3000;
|
const QUEUE_ERROR_DISPLAY_DURATION_MS = 3000;
|
||||||
@@ -203,6 +204,16 @@ export const AppContainer = (props: AppContainerProps) => {
|
|||||||
const [warningBannerText, setWarningBannerText] = useState('');
|
const [warningBannerText, setWarningBannerText] = useState('');
|
||||||
const [bannerVisible, setBannerVisible] = useState(true);
|
const [bannerVisible, setBannerVisible] = useState(true);
|
||||||
|
|
||||||
|
const bannerData = useMemo(
|
||||||
|
() => ({
|
||||||
|
defaultText: defaultBannerText,
|
||||||
|
warningText: warningBannerText,
|
||||||
|
}),
|
||||||
|
[defaultBannerText, warningBannerText],
|
||||||
|
);
|
||||||
|
|
||||||
|
const { bannerText } = useBanner(bannerData, config);
|
||||||
|
|
||||||
const extensionManager = config.getExtensionLoader() as ExtensionManager;
|
const extensionManager = config.getExtensionLoader() as ExtensionManager;
|
||||||
// We are in the interactive CLI, update how we request consent and settings.
|
// We are in the interactive CLI, update how we request consent and settings.
|
||||||
extensionManager.setRequestConsent((description) =>
|
extensionManager.setRequestConsent((description) =>
|
||||||
@@ -380,6 +391,7 @@ export const AppContainer = (props: AppContainerProps) => {
|
|||||||
}
|
}
|
||||||
setHistoryRemountKey((prev) => prev + 1);
|
setHistoryRemountKey((prev) => prev + 1);
|
||||||
}, [setHistoryRemountKey, isAlternateBuffer, stdout]);
|
}, [setHistoryRemountKey, isAlternateBuffer, stdout]);
|
||||||
|
|
||||||
const handleEditorClose = useCallback(() => {
|
const handleEditorClose = useCallback(() => {
|
||||||
if (
|
if (
|
||||||
shouldEnterAlternateScreen(isAlternateBuffer, config.getScreenReader())
|
shouldEnterAlternateScreen(isAlternateBuffer, config.getScreenReader())
|
||||||
@@ -403,6 +415,18 @@ export const AppContainer = (props: AppContainerProps) => {
|
|||||||
};
|
};
|
||||||
}, [handleEditorClose]);
|
}, [handleEditorClose]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (
|
||||||
|
!(settings.merged.ui?.hideBanner || config.getScreenReader()) &&
|
||||||
|
bannerVisible &&
|
||||||
|
bannerText
|
||||||
|
) {
|
||||||
|
// The header should show a banner but the Header is rendered in static
|
||||||
|
// so we must trigger a static refresh for it to be visible.
|
||||||
|
refreshStatic();
|
||||||
|
}
|
||||||
|
}, [bannerVisible, bannerText, settings, config, refreshStatic]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isThemeDialogOpen,
|
isThemeDialogOpen,
|
||||||
openThemeDialog,
|
openThemeDialog,
|
||||||
@@ -1388,7 +1412,6 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
|||||||
setDefaultBannerText(defaultBanner);
|
setDefaultBannerText(defaultBanner);
|
||||||
setWarningBannerText(warningBanner);
|
setWarningBannerText(warningBanner);
|
||||||
setBannerVisible(true);
|
setBannerVisible(true);
|
||||||
refreshStatic();
|
|
||||||
const authType = config.getContentGeneratorConfig()?.authType;
|
const authType = config.getContentGeneratorConfig()?.authType;
|
||||||
if (
|
if (
|
||||||
authType === AuthType.USE_GEMINI ||
|
authType === AuthType.USE_GEMINI ||
|
||||||
@@ -1497,10 +1520,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
|||||||
customDialog,
|
customDialog,
|
||||||
copyModeEnabled,
|
copyModeEnabled,
|
||||||
warningMessage,
|
warningMessage,
|
||||||
bannerData: {
|
bannerData,
|
||||||
defaultText: defaultBannerText,
|
|
||||||
warningText: warningBannerText,
|
|
||||||
},
|
|
||||||
bannerVisible,
|
bannerVisible,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
@@ -1591,8 +1611,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
|||||||
authState,
|
authState,
|
||||||
copyModeEnabled,
|
copyModeEnabled,
|
||||||
warningMessage,
|
warningMessage,
|
||||||
defaultBannerText,
|
bannerData,
|
||||||
warningBannerText,
|
|
||||||
bannerVisible,
|
bannerVisible,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user