summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/components/LoadingIndicator.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/components/LoadingIndicator.tsx')
-rw-r--r--packages/cli/src/ui/components/LoadingIndicator.tsx57
1 files changed, 39 insertions, 18 deletions
diff --git a/packages/cli/src/ui/components/LoadingIndicator.tsx b/packages/cli/src/ui/components/LoadingIndicator.tsx
index 6e1bc758..7ac356dd 100644
--- a/packages/cli/src/ui/components/LoadingIndicator.tsx
+++ b/packages/cli/src/ui/components/LoadingIndicator.tsx
@@ -12,6 +12,8 @@ import { useStreamingContext } from '../contexts/StreamingContext.js';
import { StreamingState } from '../types.js';
import { GeminiRespondingSpinner } from './GeminiRespondingSpinner.js';
import { formatDuration } from '../utils/formatters.js';
+import { useTerminalSize } from '../hooks/useTerminalSize.js';
+import { isNarrowWidth } from '../utils/isNarrowWidth.js';
interface LoadingIndicatorProps {
currentLoadingPhrase?: string;
@@ -27,6 +29,8 @@ export const LoadingIndicator: React.FC<LoadingIndicatorProps> = ({
thought,
}) => {
const streamingState = useStreamingContext();
+ const { columns: terminalWidth } = useTerminalSize();
+ const isNarrow = isNarrowWidth(terminalWidth);
if (streamingState === StreamingState.Idle) {
return null;
@@ -34,28 +38,45 @@ export const LoadingIndicator: React.FC<LoadingIndicatorProps> = ({
const primaryText = thought?.subject || currentLoadingPhrase;
+ const cancelAndTimerContent =
+ streamingState !== StreamingState.WaitingForConfirmation
+ ? `(esc to cancel, ${elapsedTime < 60 ? `${elapsedTime}s` : formatDuration(elapsedTime * 1000)})`
+ : null;
+
return (
- <Box marginTop={1} paddingLeft={0} flexDirection="column">
+ <Box paddingLeft={0} flexDirection="column">
{/* Main loading line */}
- <Box>
- <Box marginRight={1}>
- <GeminiRespondingSpinner
- nonRespondingDisplay={
- streamingState === StreamingState.WaitingForConfirmation
- ? '⠏'
- : ''
- }
- />
+ <Box
+ width="100%"
+ flexDirection={isNarrow ? 'column' : 'row'}
+ alignItems={isNarrow ? 'flex-start' : 'center'}
+ >
+ <Box>
+ <Box marginRight={1}>
+ <GeminiRespondingSpinner
+ nonRespondingDisplay={
+ streamingState === StreamingState.WaitingForConfirmation
+ ? '⠏'
+ : ''
+ }
+ />
+ </Box>
+ {primaryText && (
+ <Text color={Colors.AccentPurple}>{primaryText}</Text>
+ )}
+ {!isNarrow && cancelAndTimerContent && (
+ <Text color={Colors.Gray}> {cancelAndTimerContent}</Text>
+ )}
</Box>
- {primaryText && <Text color={Colors.AccentPurple}>{primaryText}</Text>}
- <Text color={Colors.Gray}>
- {streamingState === StreamingState.WaitingForConfirmation
- ? ''
- : ` (esc to cancel, ${elapsedTime < 60 ? `${elapsedTime}s` : formatDuration(elapsedTime * 1000)})`}
- </Text>
- <Box flexGrow={1}>{/* Spacer */}</Box>
- {rightContent && <Box>{rightContent}</Box>}
+ {!isNarrow && <Box flexGrow={1}>{/* Spacer */}</Box>}
+ {!isNarrow && rightContent && <Box>{rightContent}</Box>}
</Box>
+ {isNarrow && cancelAndTimerContent && (
+ <Box>
+ <Text color={Colors.Gray}>{cancelAndTimerContent}</Text>
+ </Box>
+ )}
+ {isNarrow && rightContent && <Box>{rightContent}</Box>}
</Box>
);
};