@@ -11,7 +11,6 @@ import { Box, Text } from 'ink';
1111import { Colors } from '../colors.js' ;
1212import { type Config , SessionManager , ProxyAuthManager } from 'deepv-code-core' ;
1313import { t } from '../utils/i18n.js' ;
14- import path from 'path' ;
1514import { cuteVLogo } from './AsciiArt.js' ;
1615import { getShortModelName } from '../utils/footerUtils.js' ;
1716
@@ -26,9 +25,8 @@ interface RecentSessionDisplay {
2625 description : string ;
2726}
2827
29- // 每日技巧键名列表 - 从 i18n 中获取实际文本(只保留最有用的)
28+ // 每日技巧键名列表 - 从 i18n 中获取
3029const DAILY_TIP_KEYS = [
31- // 斜杠命令 - 最实用的
3230 'tip.help' ,
3331 'tip.theme' ,
3432 'tip.auth' ,
@@ -42,64 +40,37 @@ const DAILY_TIP_KEYS = [
4240 'tip.docs' ,
4341 'tip.session' ,
4442 'tip.restore' ,
45-
46- // 特殊输入符号
4743 'tip.at.filepath' ,
4844 'tip.shell.command' ,
4945 'tip.shell.mode' ,
50-
51- // 快捷键 - 只保留最常用的
5246 'tip.ctrl.j' ,
53-
54- // CLI 启动参数
5547 'tip.cli.update' ,
5648 'tip.cli.cloud' ,
5749] ;
5850
59- // 格式化相对时间
60- function formatRelativeTime ( date : Date ) : string {
61- const now = new Date ( ) ;
62- const diffMs = now . getTime ( ) - date . getTime ( ) ;
63- const diffMins = Math . floor ( diffMs / 60000 ) ;
64- const diffHours = Math . floor ( diffMs / 3600000 ) ;
65- const diffDays = Math . floor ( diffMs / 86400000 ) ;
66- const diffWeeks = Math . floor ( diffMs / 604800000 ) ;
67-
68- if ( diffMins < 1 ) return 'just now' ;
69- if ( diffMins < 60 ) return `${ diffMins } m ago` ;
70- if ( diffHours < 24 ) return `${ diffHours } h ago` ;
71- if ( diffDays < 7 ) return `${ diffDays } d ago` ;
72- return `${ diffWeeks } w ago` ;
73- }
74-
7551export const WelcomeScreen : React . FC < WelcomeScreenProps > = ( {
7652 config,
7753 version,
78- customProxyUrl,
7954} ) => {
80- // 直接同步获取用户名,不使用 state
8155 const userName = useMemo ( ( ) => {
8256 const authManager = ProxyAuthManager . getInstance ( ) ;
8357 const userInfo = authManager . getUserInfo ( ) ;
8458 return userInfo ?. name ;
8559 } , [ ] ) ;
8660
87- // 获取当前模型和 credits 信息
8861 const modelInfo = useMemo ( ( ) => {
8962 const currentModel = config . getModel ( ) ;
9063 const cloudModelInfo = config . getCloudModelInfo ( currentModel ) ;
9164
9265 if ( cloudModelInfo ) {
9366 const credits = cloudModelInfo . creditsPerRequest ;
94- // 使用简化的模型名称(中等缩写)
9567 const shortName = getShortModelName ( cloudModelInfo . displayName , true ) ;
9668 return {
9769 displayName : shortName ,
9870 creditsText : `${ credits } x credits` ,
9971 } ;
10072 }
10173
102- // 如果没有 cloud model info,使用基本信息
10374 const modelName = currentModel === 'auto' ? 'Gemini' : currentModel ;
10475 const shortName = getShortModelName ( modelName , true ) ;
10576 return {
@@ -110,113 +81,93 @@ export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({
11081
11182 const [ recentSessions , setRecentSessions ] = useState < RecentSessionDisplay [ ] > ( [ ] ) ;
11283
113- // 获取最近会话
11484 useEffect ( ( ) => {
11585 const loadRecentSessions = async ( ) => {
116- // 🚀 启动优化:将非核心任务推迟执行
11786 await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
11887 try {
11988 const sessionManager = new SessionManager ( config . getProjectRoot ( ) ) ;
12089 const sessions = await sessionManager . listSessions ( ) ;
12190
12291 const recentDisplays : RecentSessionDisplay [ ] = sessions
123- . slice ( 0 , 4 )
92+ . slice ( 0 , 1 )
12493 . map ( session => ( {
125- time : formatRelativeTime ( new Date ( session . lastActiveAt ) ) ,
94+ time : '' ,
12695 description : session . title || session . firstUserMessage ?. slice ( 0 , 30 ) || 'Untitled session' ,
12796 } ) ) ;
12897
12998 setRecentSessions ( recentDisplays ) ;
13099 } catch ( error ) {
131- // 忽略错误,不显示历史
100+ // 忽略错误
132101 }
133102 } ;
134103
135104 loadRecentSessions ( ) ;
136105 } , [ config ] ) ;
137106
138- // 获取当前目录名称
139- const currentDir = useMemo ( ( ) => {
140- const fullPath = config . getProjectRoot ( ) ;
141- return path . basename ( fullPath ) ;
142- } , [ config ] ) ;
143-
144- // 获取完整路径
145- const fullPath = config . getProjectRoot ( ) ;
146-
147107 // 随机选择一条每日技巧
148108 const dailyTip = useMemo ( ( ) => {
149109 const randomIndex = Math . floor ( Math . random ( ) * DAILY_TIP_KEYS . length ) ;
150110 const tipKey = DAILY_TIP_KEYS [ randomIndex ] ;
151- return t ( tipKey as any ) ; // 类型断言,因为技巧键是动态的
111+ const rawTip = t ( tipKey as any ) ;
112+ return rawTip
113+ . replace ( / ^ T i p : \s * / i, '' )
114+ . replace ( / [ \u{1F300} - \u{1F9FF} \u{2600} - \u{26FF} \u{2700} - \u{27BF} ] / gu, '' )
115+ . trim ( ) ;
152116 } , [ ] ) ;
153117
154- // 友好的欢迎消息
155- const welcomeMessage = userName ? `Welcome back, ${ userName } !` : 'Welcome to DeepV Code!' ;
118+ const fullPath = config . getProjectRoot ( ) ;
119+ const welcomeMessage = userName ? `Welcome back, ${ userName } !` : 'Welcome back!' ;
120+
121+ // 处理 Logo 字符串
122+ const trimmedLogo = cuteVLogo . trim ( ) ;
123+
124+ // 🎯 极致紧凑宽度
125+ const COMPACT_WIDTH = 68 ;
156126
157127 return (
158- < Box flexDirection = "column" marginBottom = { 1 } borderStyle = "round" borderColor = "gray" paddingX = { 1 } minWidth = { 80 } >
159- { /* 顶部标题行 - 包含像素机器人 logo */ }
160- < Box flexDirection = "row" marginBottom = { 1 } >
161- < Box marginRight = { 2 } >
162- < Text color = { Colors . AccentBlue } > { cuteVLogo } </ Text >
163- </ Box >
164- < Box flexDirection = "column" justifyContent = "center" >
165- < Text > DeepV Code </ Text >
166- < Text dimColor > v{ version } </ Text >
167- < Text dimColor > { modelInfo . displayName } · { modelInfo . creditsText } </ Text >
168- </ Box >
128+ < Box flexDirection = "column" width = { COMPACT_WIDTH } marginBottom = { 0 } >
129+ { /* 顶部标题行 */ }
130+ < Box justifyContent = "space-between" paddingX = { 1 } >
131+ < Text color = { Colors . AccentBlue } bold > DeepV Code v{ version } </ Text >
132+ < Text dimColor wrap = "truncate-middle" > { fullPath } </ Text >
169133 </ Box >
170134
171- { /* 用户欢迎信息 */ }
172- < Box >
173- < Text color = { Colors . AccentGreen } > { welcomeMessage } </ Text >
174- </ Box >
135+ { /* 内容主体 */ }
136+ < Box
137+ flexDirection = "column"
138+ borderStyle = "round"
139+ borderColor = "gray"
140+ paddingX = { 1 }
141+ paddingY = { 0 }
142+ >
143+ < Box flexDirection = "row" paddingX = { 0 } >
144+ { /* 左侧:Logo 区域收缩宽度,移除偏移,让整体更内敛 */ }
145+ < Box flexDirection = "column" width = { 18 } justifyContent = "center" alignItems = "center" >
146+ < Text color = { Colors . AccentBlue } > { trimmedLogo } </ Text >
147+ </ Box >
175148
176- { /* 主内容区 - 左对齐布局 */ }
177- < Box flexDirection = "column" >
178- { /* 项目路径 */ }
179- < Box >
180- < Text dimColor > { fullPath } </ Text >
181- </ Box >
149+ { /* 右侧:内容右对齐 */ }
150+ < Box flexDirection = "column" flexGrow = { 1 } justifyContent = "center" alignItems = "flex-end" paddingLeft = { 1 } >
151+ < Box >
152+ < Text color = { Colors . AccentBlue } bold wrap = "truncate-end" > { welcomeMessage } </ Text >
153+ </ Box >
182154
183- { /* Custom server info */ }
184- { customProxyUrl && (
185- < Box flexDirection = "column" marginBottom = { 1 } >
186- < Text color = { Colors . AccentOrange } > 🔗 Custom server: { customProxyUrl } </ Text >
187- < Text color = { Colors . AccentOrange } > Please verify trustworthiness and monitor your API usage.</ Text >
188- </ Box >
189- ) }
190-
191- { /* Recent activity */ }
192- { recentSessions . length > 0 && (
193- < Box flexDirection = "column" >
194- < Text color = { Colors . AccentOrange } > Recent activity</ Text >
195- < Box flexDirection = "column" >
196- { recentSessions . map ( ( session , idx ) => (
197- < Box key = { idx } >
198- < Text dimColor > { session . time . padEnd ( 10 ) } </ Text >
199- < Text > { session . description . slice ( 0 , 30 ) } </ Text >
200- </ Box >
201- ) ) }
202- < Box >
203- < Text dimColor > ... /resume for more</ Text >
204- </ Box >
155+ < Box >
156+ < Text dimColor wrap = "truncate-end" > { modelInfo . displayName } </ Text >
205157 </ Box >
206- </ Box >
207- ) }
208158
209- { /* 每日技巧 */ }
210- < Box flexDirection = "column" >
211- < Text > 💡 { t ( 'welcome.daily.tip.title' ) } </ Text >
212- < Box flexDirection = "column" >
213- < Text > { dailyTip } </ Text >
214159 < Box >
215- < Text dimColor > { t ( 'welcome.daily.tip.more' ) } </ Text >
160+ < Text color = { Colors . AccentCyan } wrap = "truncate-end" > { dailyTip } </ Text >
216161 </ Box >
162+
163+ { recentSessions . length > 0 && (
164+ < Box >
165+ < Text dimColor wrap = "truncate-end" > Last: { recentSessions [ 0 ] . description } </ Text >
166+ </ Box >
167+ ) }
217168 </ Box >
218169 </ Box >
219170 </ Box >
220171 </ Box >
221172 ) ;
222- } ;
173+ } ;
0 commit comments