85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
|
|
/**
|
||
|
|
* @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;
|
||
|
|
};
|