mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 20:20:57 +00:00
update header display for narrow screen
This commit is contained in:
parent
881e7d038b
commit
758e5c0992
1 changed files with 72 additions and 21 deletions
|
|
@ -10,7 +10,7 @@ import Gradient from 'ink-gradient';
|
|||
import { AuthType, shortenPath, tildeifyPath } from '@qwen-code/qwen-code-core';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import { shortAsciiLogo } from './AsciiArt.js';
|
||||
import { getAsciiArtWidth } from '../utils/textUtils.js';
|
||||
import { getAsciiArtWidth, getCachedStringWidth } from '../utils/textUtils.js';
|
||||
import { useTerminalSize } from '../hooks/useTerminalSize.js';
|
||||
|
||||
interface HeaderProps {
|
||||
|
|
@ -21,15 +21,38 @@ interface HeaderProps {
|
|||
workingDirectory: string;
|
||||
}
|
||||
|
||||
function titleizeAuthType(value: string): string {
|
||||
return value
|
||||
.split(/[-_]/g)
|
||||
.filter(Boolean)
|
||||
.map((part) => {
|
||||
if (part.toLowerCase() === 'ai') {
|
||||
return 'AI';
|
||||
}
|
||||
return part.charAt(0).toUpperCase() + part.slice(1);
|
||||
})
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
// Format auth type for display
|
||||
function formatAuthType(authType?: AuthType): string {
|
||||
if (!authType) {
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
switch (authType) {
|
||||
case AuthType.QWEN_OAUTH:
|
||||
return 'Qwen OAuth';
|
||||
case AuthType.USE_OPENAI:
|
||||
return 'OpenAI';
|
||||
case AuthType.USE_GEMINI:
|
||||
return 'Gemini';
|
||||
case AuthType.USE_VERTEX_AI:
|
||||
return 'Vertex AI';
|
||||
case AuthType.USE_ANTHROPIC:
|
||||
return 'Anthropic';
|
||||
default:
|
||||
return 'Unknown';
|
||||
return titleizeAuthType(String(authType));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,30 +71,53 @@ export const Header: React.FC<HeaderProps> = ({
|
|||
|
||||
// Calculate available space properly:
|
||||
// First determine if logo can be shown, then use remaining space for path
|
||||
const logoGap = 4; // Gap between logo and info panel
|
||||
const infoPanelPadding = 4; // paddingX={1} on each side + borders = ~4 chars
|
||||
const containerMarginX = 2; // marginLeft + marginRight on the outer container
|
||||
const logoGap = 2; // Gap between logo and info panel
|
||||
const infoPanelPaddingX = 1;
|
||||
const infoPanelBorderWidth = 2; // left + right border
|
||||
const infoPanelChromeWidth = infoPanelBorderWidth + infoPanelPaddingX * 2;
|
||||
const minPathLength = 40; // Minimum readable path length
|
||||
const minInfoPanelWidth = minPathLength + infoPanelPadding;
|
||||
const minInfoPanelWidth = minPathLength + infoPanelChromeWidth;
|
||||
|
||||
const availableTerminalWidth = Math.max(
|
||||
0,
|
||||
terminalWidth - containerMarginX * 2,
|
||||
);
|
||||
|
||||
// Check if we have enough space for logo + gap + minimum info panel
|
||||
const showLogo = terminalWidth >= logoWidth + logoGap + minInfoPanelWidth;
|
||||
const showLogo =
|
||||
availableTerminalWidth >= logoWidth + logoGap + minInfoPanelWidth;
|
||||
|
||||
// Calculate available width for info panel (use all remaining space)
|
||||
const availableInfoPanelWidth = showLogo
|
||||
? terminalWidth - logoWidth - logoGap
|
||||
: terminalWidth;
|
||||
? availableTerminalWidth - logoWidth - logoGap
|
||||
: availableTerminalWidth;
|
||||
|
||||
// Calculate max path length (subtract padding/borders from available space)
|
||||
const maxPathLength = Math.max(
|
||||
minPathLength,
|
||||
availableInfoPanelWidth - infoPanelPadding,
|
||||
0,
|
||||
availableInfoPanelWidth - infoPanelChromeWidth,
|
||||
);
|
||||
|
||||
// Now shorten the path to fit the available space
|
||||
const displayPath = shortenPath(
|
||||
tildeifyPath(workingDirectory),
|
||||
maxPathLength,
|
||||
const infoPanelContentWidth = Math.max(
|
||||
0,
|
||||
availableInfoPanelWidth - infoPanelChromeWidth,
|
||||
);
|
||||
const authModelText = `${formattedAuthType} | ${model}`;
|
||||
const authHintText = ' (/auth to change)';
|
||||
const showAuthHint =
|
||||
infoPanelContentWidth > 0 &&
|
||||
getCachedStringWidth(authModelText + authHintText) <= infoPanelContentWidth;
|
||||
|
||||
// Now shorten the path to fit the available space
|
||||
const tildeifiedPath = tildeifyPath(workingDirectory);
|
||||
const shortenedPath = shortenPath(tildeifiedPath, Math.max(3, maxPathLength));
|
||||
const displayPath =
|
||||
maxPathLength <= 0
|
||||
? ''
|
||||
: shortenedPath.length > maxPathLength
|
||||
? shortenedPath.slice(0, maxPathLength)
|
||||
: shortenedPath;
|
||||
|
||||
// Use theme gradient colors if available, otherwise use text colors (excluding primary)
|
||||
const gradientColors = theme.ui.gradient || [
|
||||
|
|
@ -81,7 +127,12 @@ export const Header: React.FC<HeaderProps> = ({
|
|||
];
|
||||
|
||||
return (
|
||||
<Box flexDirection="row" alignItems="center" marginLeft={2} marginRight={2}>
|
||||
<Box
|
||||
flexDirection="row"
|
||||
alignItems="center"
|
||||
marginX={containerMarginX}
|
||||
width={availableTerminalWidth}
|
||||
>
|
||||
{/* Left side: ASCII logo (only if enough space) */}
|
||||
{showLogo && (
|
||||
<>
|
||||
|
|
@ -91,7 +142,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||
</Gradient>
|
||||
</Box>
|
||||
{/* Fixed gap between logo and info panel */}
|
||||
<Box width={4} />
|
||||
<Box width={logoGap} />
|
||||
</>
|
||||
)}
|
||||
|
||||
|
|
@ -100,7 +151,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||
flexDirection="column"
|
||||
borderStyle="round"
|
||||
borderColor={theme.border.default}
|
||||
paddingX={1}
|
||||
paddingX={infoPanelPaddingX}
|
||||
flexGrow={1}
|
||||
>
|
||||
{/* Title line: >_ Qwen Code (v{version}) */}
|
||||
|
|
@ -114,10 +165,10 @@ export const Header: React.FC<HeaderProps> = ({
|
|||
<Text> </Text>
|
||||
{/* Auth and Model line */}
|
||||
<Text>
|
||||
<Text color={theme.text.secondary}>
|
||||
{formattedAuthType} | {model}
|
||||
</Text>
|
||||
<Text color={theme.text.secondary}> (/auth to change)</Text>
|
||||
<Text color={theme.text.secondary}>{authModelText}</Text>
|
||||
{showAuthHint && (
|
||||
<Text color={theme.text.secondary}>{authHintText}</Text>
|
||||
)}
|
||||
</Text>
|
||||
{/* Directory line */}
|
||||
<Text color={theme.text.secondary}>{displayPath}</Text>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue