mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-24 23:06:51 +00:00
fix: 优化消息搜索体验
- 去掉切换按钮,搜索框直接同时搜索会话名和消息内容 - 消息搜索加 400ms 防抖,输入停止后再请求 - 全局消息结果显示会话 displayName,点击跳转并清空搜索框 - 修复跨会话搜索 meta 为 null 导致无结果的问题(C++ 层)
This commit is contained in:
@@ -2646,27 +2646,34 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// 全局消息搜索
|
// 全局消息搜索
|
||||||
|
const globalMsgSearchTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
const handleGlobalMsgSearch = useCallback(async (keyword: string) => {
|
const handleGlobalMsgSearch = useCallback(async (keyword: string) => {
|
||||||
setGlobalMsgQuery(keyword)
|
setGlobalMsgQuery(keyword)
|
||||||
|
if (globalMsgSearchTimerRef.current) clearTimeout(globalMsgSearchTimerRef.current)
|
||||||
if (!keyword.trim()) {
|
if (!keyword.trim()) {
|
||||||
setGlobalMsgResults([])
|
setGlobalMsgResults([])
|
||||||
|
setShowGlobalMsgSearch(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setGlobalMsgSearching(true)
|
setShowGlobalMsgSearch(true)
|
||||||
try {
|
globalMsgSearchTimerRef.current = setTimeout(async () => {
|
||||||
const res = await window.electronAPI.chat.searchMessages(keyword.trim(), undefined, 50, 0)
|
setGlobalMsgSearching(true)
|
||||||
setGlobalMsgResults(res?.messages || [])
|
try {
|
||||||
} catch {
|
const res = await window.electronAPI.chat.searchMessages(keyword.trim(), undefined, 50, 0)
|
||||||
setGlobalMsgResults([])
|
setGlobalMsgResults(res?.messages || [])
|
||||||
} finally {
|
} catch {
|
||||||
setGlobalMsgSearching(false)
|
setGlobalMsgResults([])
|
||||||
}
|
} finally {
|
||||||
|
setGlobalMsgSearching(false)
|
||||||
|
}
|
||||||
|
}, 400)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleCloseGlobalMsgSearch = useCallback(() => {
|
const handleCloseGlobalMsgSearch = useCallback(() => {
|
||||||
setShowGlobalMsgSearch(false)
|
setShowGlobalMsgSearch(false)
|
||||||
setGlobalMsgQuery('')
|
setGlobalMsgQuery('')
|
||||||
setGlobalMsgResults([])
|
setGlobalMsgResults([])
|
||||||
|
if (globalMsgSearchTimerRef.current) clearTimeout(globalMsgSearchTimerRef.current)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// 滚动加载更多 + 显示/隐藏回到底部按钮(优化:节流,避免频繁执行)
|
// 滚动加载更多 + 显示/隐藏回到底部按钮(优化:节流,避免频繁执行)
|
||||||
@@ -3956,26 +3963,20 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
<input
|
<input
|
||||||
ref={searchInputRef}
|
ref={searchInputRef}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={showGlobalMsgSearch ? '搜索消息内容...' : '搜索'}
|
placeholder="搜索"
|
||||||
value={showGlobalMsgSearch ? globalMsgQuery : searchKeyword}
|
value={searchKeyword}
|
||||||
onChange={(e) => showGlobalMsgSearch ? handleGlobalMsgSearch(e.target.value) : handleSearch(e.target.value)}
|
onChange={(e) => {
|
||||||
|
handleSearch(e.target.value)
|
||||||
|
handleGlobalMsgSearch(e.target.value)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{(showGlobalMsgSearch ? globalMsgQuery : searchKeyword) && (
|
{searchKeyword && (
|
||||||
<button className="close-search" onClick={showGlobalMsgSearch ? handleCloseGlobalMsgSearch : handleCloseSearch}>
|
<button className="close-search" onClick={() => { handleCloseSearch(); handleCloseGlobalMsgSearch() }}>
|
||||||
<X size={12} />
|
<X size={12} />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
{globalMsgSearching && <Loader2 size={12} className="spin" style={{ flexShrink: 0 }} />}
|
||||||
</div>
|
</div>
|
||||||
<button
|
|
||||||
className={`icon-btn msg-search-toggle-btn ${showGlobalMsgSearch ? 'active' : ''}`}
|
|
||||||
onClick={() => {
|
|
||||||
if (showGlobalMsgSearch) handleCloseGlobalMsgSearch()
|
|
||||||
else { setShowGlobalMsgSearch(true); setTimeout(() => searchInputRef.current?.focus(), 50) }
|
|
||||||
}}
|
|
||||||
title={showGlobalMsgSearch ? '退出消息搜索' : '搜索消息内容'}
|
|
||||||
>
|
|
||||||
<MessageSquare size={15} />
|
|
||||||
</button>
|
|
||||||
<button className="icon-btn refresh-btn" onClick={handleRefresh} disabled={isLoadingSessions || isRefreshingSessions}>
|
<button className="icon-btn refresh-btn" onClick={handleRefresh} disabled={isLoadingSessions || isRefreshingSessions}>
|
||||||
<RefreshCw size={16} className={(isLoadingSessions || isRefreshingSessions) ? 'spin' : ''} />
|
<RefreshCw size={16} className={(isLoadingSessions || isRefreshingSessions) ? 'spin' : ''} />
|
||||||
</button>
|
</button>
|
||||||
@@ -3989,22 +3990,27 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
{!globalMsgSearching && globalMsgQuery && globalMsgResults.length === 0 && (
|
{!globalMsgSearching && globalMsgQuery && globalMsgResults.length === 0 && (
|
||||||
<div className="global-msg-empty">没有找到相关消息</div>
|
<div className="global-msg-empty">没有找到相关消息</div>
|
||||||
)}
|
)}
|
||||||
{globalMsgResults.map((msg, i) => (
|
{globalMsgResults.map((msg, i) => {
|
||||||
<div key={i} className="global-msg-result-item" onClick={() => {
|
const sid = msg._session_id || msg.username || ''
|
||||||
const sid = msg._session_id || msg.username
|
const sessionObj = sessions.find(s => s.username === sid)
|
||||||
if (sid) {
|
const sessionName = sessionObj?.displayName || sid || '未知会话'
|
||||||
const target = sessions.find(s => s.username === sid)
|
const content = (msg.content || msg.strContent || msg.message_content || '').slice(0, 60)
|
||||||
if (target) {
|
const ts = msg.createTime || msg.create_time
|
||||||
handleSelectSession(target)
|
const timeStr = ts ? new Date(ts * 1000).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }) : ''
|
||||||
|
return (
|
||||||
|
<div key={i} className="global-msg-result-item" onClick={() => {
|
||||||
|
if (sessionObj) {
|
||||||
|
handleSelectSession(sessionObj)
|
||||||
handleCloseGlobalMsgSearch()
|
handleCloseGlobalMsgSearch()
|
||||||
|
setSearchKeyword('')
|
||||||
}
|
}
|
||||||
}
|
}}>
|
||||||
}}>
|
<div className="global-msg-result-session">{sessionName}</div>
|
||||||
<div className="global-msg-result-session">{msg._session_id || msg.username || '未知会话'}</div>
|
<div className="global-msg-result-content">{content}</div>
|
||||||
<div className="global-msg-result-content">{(msg.content || msg.strContent || msg.message_content || '').slice(0, 60)}</div>
|
<div className="global-msg-result-time">{timeStr}</div>
|
||||||
<div className="global-msg-result-time">{(msg.createTime || msg.create_time) ? new Date((msg.createTime || msg.create_time) * 1000).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }) : ''}</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
))}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user