|
1 | 1 | import React from 'react' |
2 | 2 |
|
3 | 3 | import { useTheme } from '../hooks/use-theme' |
4 | | - |
5 | 4 | import { formatResetTime } from '../utils/time-format' |
6 | | - |
7 | 5 | import type { ClaudeQuotaData } from '../hooks/use-claude-quota-query' |
8 | 6 |
|
9 | 7 | interface BottomStatusLineProps { |
@@ -74,18 +72,46 @@ export const BottomStatusLine: React.FC<BottomStatusLineProps> = ({ |
74 | 72 | {isExhausted && resetTime ? ( |
75 | 73 | <text style={{ fg: theme.muted }}>{` · resets in ${formatResetTime(resetTime)}`}</text> |
76 | 74 | ) : displayRemaining !== null ? ( |
77 | | - <text |
78 | | - style={{ |
79 | | - fg: |
80 | | - displayRemaining <= 10 |
81 | | - ? theme.error |
82 | | - : displayRemaining <= 25 |
83 | | - ? theme.warning |
84 | | - : theme.muted, |
85 | | - }} |
86 | | - >{` ${Math.round(displayRemaining)}%`}</text> |
| 75 | + <BatteryIndicator value={displayRemaining} theme={theme} /> |
87 | 76 | ) : null} |
88 | 77 | </box> |
89 | 78 | </box> |
90 | 79 | ) |
91 | 80 | } |
| 81 | + |
| 82 | +/** Battery indicator width in characters */ |
| 83 | +const BATTERY_WIDTH = 8 |
| 84 | + |
| 85 | +/** Compact battery-style progress indicator for the status line */ |
| 86 | +const BatteryIndicator: React.FC<{ |
| 87 | + value: number |
| 88 | + theme: { muted: string; warning: string; error: string } |
| 89 | +}> = ({ value, theme }) => { |
| 90 | + const clampedValue = Math.max(0, Math.min(100, value)) |
| 91 | + const filledWidth = Math.round((clampedValue / 100) * BATTERY_WIDTH) |
| 92 | + const emptyWidth = BATTERY_WIDTH - filledWidth |
| 93 | + |
| 94 | + const filledChar = '█' |
| 95 | + const emptyChar = '░' |
| 96 | + |
| 97 | + const filled = filledChar.repeat(filledWidth) |
| 98 | + const empty = emptyChar.repeat(emptyWidth) |
| 99 | + |
| 100 | + // Color based on percentage thresholds |
| 101 | + // Use muted color for healthy capacity (>25%) to avoid drawing attention, |
| 102 | + // warning/error colors only when running low |
| 103 | + const barColor = |
| 104 | + clampedValue <= 10 |
| 105 | + ? theme.error |
| 106 | + : clampedValue <= 25 |
| 107 | + ? theme.warning |
| 108 | + : theme.muted |
| 109 | + |
| 110 | + return ( |
| 111 | + <box style={{ flexDirection: 'row', alignItems: 'center', gap: 0 }}> |
| 112 | + <text style={{ fg: theme.muted }}> [</text> |
| 113 | + <text style={{ fg: barColor }}>{filled}</text> |
| 114 | + <text style={{ fg: theme.muted }}>{empty}]</text> |
| 115 | + </box> |
| 116 | + ) |
| 117 | +} |
0 commit comments