summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/hooks/usePhraseCycler.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/hooks/usePhraseCycler.ts')
-rw-r--r--packages/cli/src/ui/hooks/usePhraseCycler.ts84
1 files changed, 84 insertions, 0 deletions
diff --git a/packages/cli/src/ui/hooks/usePhraseCycler.ts b/packages/cli/src/ui/hooks/usePhraseCycler.ts
new file mode 100644
index 00000000..96bad676
--- /dev/null
+++ b/packages/cli/src/ui/hooks/usePhraseCycler.ts
@@ -0,0 +1,84 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { useState, useEffect, useRef } from 'react';
+
+export const WITTY_LOADING_PHRASES = [
+ 'Consulting the digital spirits...',
+ 'Reticulating splines...',
+ 'Warming up the AI hamsters...',
+ 'Asking the magic conch shell...',
+ 'Generating witty retort...',
+ 'Polishing the algorithms...',
+ "Don't rush perfection (or my code)...",
+ 'Brewing fresh bytes...',
+ 'Counting electrons...',
+ 'Engaging cognitive processors...',
+ 'Checking for syntax errors in the universe...',
+ 'One moment, optimizing humor...',
+ 'Shuffling punchlines...',
+ 'Untangling neural nets...',
+ 'Compiling brilliance...',
+];
+
+export const PHRASE_CHANGE_INTERVAL_MS = 15000;
+
+/**
+ * Custom hook to manage cycling through loading phrases.
+ * @param isActive Whether the phrase cycling should be active.
+ * @param isWaiting Whether to show a specific waiting phrase.
+ * @returns The current loading phrase.
+ */
+export const usePhraseCycler = (isActive: boolean, isWaiting: boolean) => {
+ const [currentLoadingPhrase, setCurrentLoadingPhrase] = useState(
+ WITTY_LOADING_PHRASES[0],
+ );
+ const phraseIntervalRef = useRef<NodeJS.Timeout | null>(null);
+ const currentPhraseIndexRef = useRef<number>(0);
+
+ useEffect(() => {
+ if (isWaiting) {
+ setCurrentLoadingPhrase('Waiting for user confirmation...');
+ if (phraseIntervalRef.current) {
+ clearInterval(phraseIntervalRef.current);
+ phraseIntervalRef.current = null;
+ }
+ } else if (isActive) {
+ if (phraseIntervalRef.current) {
+ clearInterval(phraseIntervalRef.current);
+ }
+ // Reset to the first witty phrase when starting to respond
+ currentPhraseIndexRef.current = 0;
+ setCurrentLoadingPhrase(WITTY_LOADING_PHRASES[0]);
+
+ phraseIntervalRef.current = setInterval(() => {
+ currentPhraseIndexRef.current =
+ (currentPhraseIndexRef.current + 1) % WITTY_LOADING_PHRASES.length;
+ setCurrentLoadingPhrase(
+ WITTY_LOADING_PHRASES[currentPhraseIndexRef.current],
+ );
+ }, PHRASE_CHANGE_INTERVAL_MS);
+ } else {
+ // Idle or other states, clear the phrase interval
+ // and reset to the first phrase for next active state.
+ if (phraseIntervalRef.current) {
+ clearInterval(phraseIntervalRef.current);
+ phraseIntervalRef.current = null;
+ }
+ setCurrentLoadingPhrase(WITTY_LOADING_PHRASES[0]);
+ currentPhraseIndexRef.current = 0;
+ }
+
+ return () => {
+ if (phraseIntervalRef.current) {
+ clearInterval(phraseIntervalRef.current);
+ phraseIntervalRef.current = null;
+ }
+ };
+ }, [isActive, isWaiting]);
+
+ return currentLoadingPhrase;
+};