Skip to content

Commit 14ca860

Browse files
authored
Merge pull request #3 from experdot/feat/refactor
Feat/refactor
2 parents e04b890 + 852c1da commit 14ca860

File tree

28 files changed

+1146
-825
lines changed

28 files changed

+1146
-825
lines changed

src/renderer/src/components/common/UpdateNotification.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export default function UpdateNotification() {
4949
const handleUpdateAvailable = (info: UpdateInfo) => {
5050
console.log('收到更新可用事件:', info)
5151
updateStore.handleUpdateAvailable(info)
52+
// 重置启动检查标识(有更新可用时需要显示通知)
53+
updateStore.setIsStartupCheck(false)
5254
showUpdateAvailableNotification(info)
5355
}
5456

@@ -61,13 +63,24 @@ export default function UpdateNotification() {
6163
const handleUpdateError = (error: string) => {
6264
console.error('收到更新错误事件:', error)
6365
updateStore.handleUpdateError(error)
66+
// 重置启动检查标识
67+
updateStore.setIsStartupCheck(false)
6468
// 静默处理错误,避免过多通知打扰用户
6569
console.warn('Update check failed:', error)
6670
}
6771

6872
const handleUpdateNotAvailable = (info: any) => {
6973
console.log('收到无更新事件:', info)
7074
updateStore.handleUpdateNotAvailable(info)
75+
76+
// 如果是启动检查且已是最新版本,不显示通知
77+
if (updateStore.isStartupCheck) {
78+
console.log('启动检查:已是最新版本,不显示通知')
79+
updateStore.setIsStartupCheck(false) // 重置标识
80+
return
81+
}
82+
83+
// 手动检查时显示通知
7184
notification.info({
7285
message: '当前已是最新版本',
7386
description: `当前版本: ${info.version || '未知'}`,
@@ -114,12 +127,17 @@ export default function UpdateNotification() {
114127
return
115128
}
116129

130+
// 标记为启动检查
131+
updateStore.setIsStartupCheck(true)
132+
117133
const result = await window.api.updater.checkForUpdates()
118134
console.log('启动检查更新结果:', result)
119135
} catch (error) {
120136
console.error('启动检查更新失败:', error)
121137
// 静默失败,不打扰用户
122138
console.warn('Startup update check failed:', error)
139+
// 重置启动检查标识
140+
updateStore.setIsStartupCheck(false)
123141
}
124142
}
125143

src/renderer/src/components/layout/Layout.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import Sidebar from './sidebar/Sidebar'
66
import ActivityBar, { ActivityBarTab } from './activitybar/ActivityBar'
77
import TabsArea from './tabs/TabsArea'
88
import ResizeHandle from './ResizeHandle'
9-
import Settings from '../settings/Settings'
109
import GlobalSearch from './sidebar_items/search/GlobalSearch'
1110
import TitleBar from './titlebar/TitleBar'
1211

@@ -17,7 +16,6 @@ export default function Layout() {
1716
const { clearSearch } = useSearchStore()
1817
const [activeTab, setActiveTab] = useState<ActivityBarTab>('explore')
1918
const [searchOpen, setSearchOpen] = useState(false)
20-
const [settingsOpen, setSettingsOpen] = useState(false)
2119

2220
// 处理键盘快捷键
2321
useEffect(() => {
@@ -59,10 +57,6 @@ export default function Layout() {
5957
setSearchOpen(true)
6058
}
6159

62-
const handleSettingsOpen = () => {
63-
setSettingsOpen(true)
64-
}
65-
6660
return (
6761
<div className="app-layout">
6862
{/* 自定义标题栏 */}
@@ -74,7 +68,7 @@ export default function Layout() {
7468

7569
<AntLayout className="app-main-layout">
7670
{/* ActivityBar */}
77-
<Sider width={50} collapsedWidth={50} theme="light" className="app-activity-bar">
71+
<Sider width={64} collapsedWidth={64} theme="light" className="app-activity-bar">
7872
<ActivityBar activeTab={activeTab} onTabChange={handleActivityTabChange} />
7973
</Sider>
8074

@@ -91,7 +85,7 @@ export default function Layout() {
9185
collapsed={sidebarCollapsed}
9286
activeTab={activeTab}
9387
onSearchOpen={handleSearchOpen}
94-
onSettingsOpen={handleSettingsOpen}
88+
onSettingsOpen={handleSearchOpen}
9589
/>
9690
<ResizeHandle />
9791
</Sider>
@@ -103,7 +97,6 @@ export default function Layout() {
10397

10498
{/* 全局模态框 */}
10599
<GlobalSearch visible={searchOpen} onClose={handleCloseSearch} />
106-
<Settings open={settingsOpen} onClose={() => setSettingsOpen(false)} />
107100
</div>
108101
)
109102
}

src/renderer/src/components/layout/activitybar/ActivityBar.tsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ import React from 'react'
22
import { Button, Badge, Tooltip } from 'antd'
33
import { FolderOutlined, SearchOutlined, MonitorOutlined, SettingOutlined } from '@ant-design/icons'
44
import { useAITasksStore } from '../../../stores/aiTasksStore'
5+
import { usePagesStore } from '../../../stores/pagesStore'
6+
import { useTabsStore } from '../../../stores/tabsStore'
7+
import './activitybar.css'
58

6-
export type ActivityBarTab = 'explore' | 'search' | 'tasks' | 'settings'
9+
export type ActivityBarTab = 'explore' | 'search' | 'tasks'
710

811
interface ActivityBarProps {
912
activeTab: ActivityBarTab
@@ -12,10 +15,18 @@ interface ActivityBarProps {
1215

1316
export default function ActivityBar({ activeTab, onTabChange }: ActivityBarProps) {
1417
const { getRunningTasksCount } = useAITasksStore()
18+
const { createAndOpenSettingsPage } = usePagesStore()
19+
const { openTab } = useTabsStore()
1520

1621
// 计算活跃任务数量
1722
const activeTaskCount = getRunningTasksCount()
1823

24+
// 处理设置按钮点击
25+
const handleSettingsClick = () => {
26+
const settingsPageId = createAndOpenSettingsPage('llm') // 默认打开LLM配置,因为这是用户最常需要的设置
27+
openTab(settingsPageId)
28+
}
29+
1930
const items = [
2031
{
2132
key: 'explore' as ActivityBarTab,
@@ -35,12 +46,6 @@ export default function ActivityBar({ activeTab, onTabChange }: ActivityBarProps
3546
label: '任务监控',
3647
tooltip: '任务监控 - AI任务状态',
3748
badge: activeTaskCount > 0 ? activeTaskCount : undefined
38-
},
39-
{
40-
key: 'settings' as ActivityBarTab,
41-
icon: <SettingOutlined />,
42-
label: '设置',
43-
tooltip: '设置 - 应用程序设置'
4449
}
4550
]
4651

@@ -59,6 +64,17 @@ export default function ActivityBar({ activeTab, onTabChange }: ActivityBarProps
5964
</Badge>
6065
</Tooltip>
6166
))}
67+
68+
{/* 设置按钮独立处理 */}
69+
<Tooltip title="设置 - 应用程序设置" placement="right">
70+
<Button
71+
type="text"
72+
size="large"
73+
icon={<SettingOutlined />}
74+
className="activity-bar-button"
75+
onClick={handleSettingsClick}
76+
/>
77+
</Tooltip>
6278
</div>
6379
)
6480
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.activity-bar {
2+
display: flex;
3+
flex-direction: column;
4+
align-items: center;
5+
padding: 16px 8px;
6+
background: #fafafa;
7+
border-right: 1px solid #f0f0f0;
8+
gap: 4px;
9+
}

src/renderer/src/components/layout/sidebar/Sidebar.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,7 @@ export default function Sidebar({
158158
</div>
159159
</div>
160160
)
161-
case 'settings':
162-
return (
163-
<div className="sidebar-settings">
164-
<div className="sidebar-header">
165-
<h3>设置</h3>
166-
</div>
167-
<div className="sidebar-content">
168-
<Settings open={true} onClose={() => {}} embedded={true} />
169-
</div>
170-
</div>
171-
)
161+
172162
default:
173163
return null
174164
}

src/renderer/src/components/layout/sidebar_items/chat/ChatHistoryTree.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,9 @@ export default function ChatHistoryTree({ onChatClick }: ChatHistoryTreeProps) {
287287
.filter((folder) => folder.parentId === parentId)
288288
.sort((a, b) => (a.order || 0) - (b.order || 0))
289289

290-
// 获取指定父级下的聊天
290+
// 获取指定父级下的聊天(过滤掉设置页面)
291291
const chats = pages
292-
.filter((chat) => chat.folderId === parentId)
292+
.filter((chat) => chat.folderId === parentId && chat.type !== 'settings')
293293
.sort((a, b) => (a.order || 0) - (b.order || 0))
294294

295295
// 添加文件夹

src/renderer/src/components/layout/tabs/TabsArea.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@ import { useSettingsStore } from '../../../stores/settingsStore'
1919
import { ChatWindow, ChatWindowRef } from '../../pages/chat/index'
2020
import { CrosstabChat } from '../../pages/crosstab/index'
2121
import { ObjectPage } from '../../pages/object/index'
22-
import Settings from '../../settings/Settings'
22+
import SettingsPage from '../../pages/settings/SettingsPage'
2323
import './TabsArea.css'
2424

2525
export default function TabsArea() {
26-
const { pages, createAndOpenChat, createAndOpenCrosstabChat, createAndOpenObjectChat } =
27-
usePagesStore()
26+
const {
27+
pages,
28+
createAndOpenChat,
29+
createAndOpenCrosstabChat,
30+
createAndOpenObjectChat,
31+
createAndOpenSettingsPage
32+
} = usePagesStore()
2833
const {
2934
openTabs,
3035
activeTabId,
@@ -40,7 +45,6 @@ export default function TabsArea() {
4045
const {} = useUIStore()
4146
const { settings } = useSettingsStore()
4247
const chatWindowRefs = useRef<Map<string, ChatWindowRef>>(new Map())
43-
const [settingsOpen, setSettingsOpen] = React.useState(false)
4448
const [draggedTabId, setDraggedTabId] = React.useState<string | null>(null)
4549
const [dragOverTabId, setDragOverTabId] = React.useState<string | null>(null)
4650

@@ -70,8 +74,9 @@ export default function TabsArea() {
7074

7175
// 处理打开设置
7276
const handleOpenSettings = useCallback(() => {
73-
setSettingsOpen(true)
74-
}, [])
77+
const settingsPageId = createAndOpenSettingsPage('llm') // 配置模型按钮应该打开LLM配置
78+
setActiveTab(settingsPageId)
79+
}, [createAndOpenSettingsPage, setActiveTab])
7580

7681
// 拖拽排序处理函数
7782
const handleDragStart = useCallback((event: React.DragEvent, chatId: string) => {
@@ -436,7 +441,6 @@ export default function TabsArea() {
436441
}
437442
/>
438443
)}
439-
<Settings open={settingsOpen} onClose={() => setSettingsOpen(false)} />
440444
</div>
441445
)
442446
}
@@ -474,6 +478,8 @@ export default function TabsArea() {
474478
<TableOutlined className="message-icon" />
475479
) : chat.type === 'object' ? (
476480
<BlockOutlined className="message-icon" />
481+
) : chat.type === 'settings' ? (
482+
<SettingOutlined className="message-icon" />
477483
) : (
478484
<MessageOutlined className="message-icon" />
479485
)}
@@ -494,6 +500,8 @@ export default function TabsArea() {
494500
<CrosstabChat chatId={chatId} />
495501
) : chat.type === 'object' ? (
496502
<ObjectPage chatId={chatId} />
503+
) : chat.type === 'settings' ? (
504+
<SettingsPage chatId={chatId} defaultActiveTab={chat.data?.defaultActiveTab} />
497505
) : (
498506
<ChatWindow chatId={chatId} ref={(ref) => setChatWindowRef(chatId, ref)} />
499507
),

src/renderer/src/components/pages/chat/ChatInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ const ChatInput = forwardRef<ChatInputRef, ChatInputProps>(
275275
onChange={(e) => onChange(e.target.value)}
276276
onKeyDown={handleKeyDown}
277277
autoSize={{ minRows: 1, maxRows: 10 }}
278-
disabled={disabled || hasNoModels}
278+
disabled={hasNoModels}
279279
/>
280280
<Flex align="center" gap={8} justify="space-between" style={{ width: '100%' }}>
281281
<Space>

src/renderer/src/components/pages/chat/ChatWindow.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React, { useState, useMemo, useRef, forwardRef, useImperativeHandle } from 'react'
22
import { usePagesStore } from '../../../stores/pagesStore'
3+
import { useTabsStore } from '../../../stores/tabsStore'
34
import { useUIStore } from '../../../stores/uiStore'
45
import { useSettingsStore } from '../../../stores/settingsStore'
56
import { useMessagesStore } from '../../../stores/messagesStore'
67
import ChatLogic from './ChatLogic'
78
import ChatHeader from './ChatHeader'
89
import MessageList from './MessageList'
910
import ChatInput, { ChatInputRef } from './ChatInput'
10-
import Settings from '../../settings/Settings'
1111
import PageLineageDisplay from '../../common/PageLineageDisplay'
1212
import MessageTreeSidebar from './MessageTreeSidebar'
1313
import { MessageTree } from './messageTree'
@@ -21,7 +21,8 @@ export interface ChatWindowRef {
2121
}
2222

2323
const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({ chatId }, ref) => {
24-
const { pages } = usePagesStore()
24+
const { pages, createAndOpenSettingsPage } = usePagesStore()
25+
const { setActiveTab } = useTabsStore()
2526
const {
2627
collapsedMessages,
2728
allMessagesCollapsed,
@@ -32,7 +33,6 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({ chatId }, ref)
3233
const { settings } = useSettingsStore()
3334
const { updateCurrentPath } = useMessagesStore()
3435
const [inputValue, setInputValue] = useState('')
35-
const [settingsOpen, setSettingsOpen] = useState(false)
3636
const [messageTreeCollapsed, setMessageTreeCollapsed] = useState(true)
3737
const [messageTreeWidth, setMessageTreeWidth] = useState(() => {
3838
const saved = localStorage.getItem('messageTreeWidth')
@@ -84,7 +84,8 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({ chatId }, ref)
8484
}
8585

8686
const handleOpenSettings = () => {
87-
setSettingsOpen(true)
87+
const settingsPageId = createAndOpenSettingsPage('llm') // 从聊天窗口点击设置通常是想配置模型
88+
setActiveTab(settingsPageId)
8889
}
8990

9091
const handleToggleMessageTree = () => {
@@ -239,8 +240,12 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({ chatId }, ref)
239240
onChange={setInputValue}
240241
onSend={async () => {
241242
if (inputValue.trim()) {
243+
setInputValue('') // 立即清空输入框
242244
await onSendMessage(inputValue)
243-
setInputValue('')
245+
// 在下一个tick中聚焦,确保界面更新完成
246+
setTimeout(() => {
247+
chatInputRef.current?.focus()
248+
}, 0)
244249
}
245250
}}
246251
onStop={onStopGeneration}
@@ -263,7 +268,6 @@ const ChatWindow = forwardRef<ChatWindowRef, ChatWindowProps>(({ chatId }, ref)
263268
)}
264269
</ChatLogic>
265270
</div>
266-
<Settings open={settingsOpen} onClose={() => setSettingsOpen(false)} />
267271
</div>
268272
)
269273
})

src/renderer/src/components/pages/chat/MessageItem.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export default function MessageItem({
204204
}}
205205
/>
206206
</div>
207-
<div className="message-content">
207+
<div className={isEditing ? 'message-content message-content-editing' : 'message-content'}>
208208
<div className="message-header">
209209
<div className="message-title">
210210
<Text strong>{message.role === 'user' ? '您' : 'AI助手'}</Text>
@@ -249,8 +249,8 @@ export default function MessageItem({
249249
</div>
250250
</div>
251251

252-
{/* 消息内容区域 - 可折叠 */}
253-
{!isCollapsed && (
252+
{/* 消息内容区域 - 可折叠,但编辑状态优先级最高 */}
253+
{(!isCollapsed || isEditing) && (
254254
<>
255255
{/* 推理模型思考过程展示 */}
256256
{currentReasoningContent && (
@@ -349,8 +349,8 @@ export default function MessageItem({
349349
</>
350350
)}
351351

352-
{/* 折叠状态下的预览 */}
353-
{isCollapsed && (
352+
{/* 折叠状态下的预览 - 编辑状态时不显示 */}
353+
{isCollapsed && !isEditing && (
354354
<Card size="small" className="message-card message-collapsed">
355355
<div className="message-preview">
356356
<Text type="secondary" className="message-preview-text">
@@ -425,7 +425,6 @@ export default function MessageItem({
425425
size="small"
426426
icon={<DeleteOutlined />}
427427
onClick={handleDelete}
428-
disabled={isCurrentlyStreaming}
429428
className="message-delete-btn"
430429
/>
431430
</Tooltip>

0 commit comments

Comments
 (0)