refactor: chat navigation triggering (#6576)

* refactor(ChatNavigation): move down the navigation bar

* refactor: attach listeners to MessagesContainer for better triggering experience

* refactor: add delay to Tooltips

* refactor: exclude some toolbars areas from triggering
This commit is contained in:
one 2025-05-29 09:44:55 +08:00 committed by GitHub
parent 61fe4b950c
commit 1781f154e1
2 changed files with 29 additions and 10 deletions

View File

@ -115,7 +115,7 @@ const Chat: FC<Props> = (props) => {
includeUser={filterIncludeUser}
onIncludeUserChange={userOutlinedItemClickHandler}
/>
<MessagesContainer>
<MessagesContainer className="messages-container">
<Messages
key={props.activeTopic.id}
assistant={assistant}

View File

@ -17,6 +17,9 @@ import styled from 'styled-components'
import ChatFlowHistory from './ChatFlowHistory'
// Exclude some areas from the navigation
const EXCLUDED_SELECTORS = ['.MessageFooter', '.code-toolbar', '.ant-collapse-header']
interface ChatNavigationProps {
containerId: string
}
@ -233,6 +236,8 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
// Set up scroll event listener and mouse position tracking
useEffect(() => {
const container = document.getElementById(containerId)
const messagesContainer = container?.closest('.messages-container') as HTMLElement
if (!container) return
// Handle scroll events on the container
@ -266,10 +271,14 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
}
const rightPosition = window.innerWidth - rightOffset - triggerWidth
const topPosition = window.innerHeight * 0.3 // 30% from top
const topPosition = window.innerHeight * 0.35 // 35% from top
const height = window.innerHeight * 0.3 // 30% of window height
const target = e.target as HTMLElement
const isInExcludedArea = EXCLUDED_SELECTORS.some((selector) => target.closest(selector))
const isInTriggerArea =
!isInExcludedArea &&
e.clientX > rightPosition &&
e.clientX < rightPosition + triggerWidth &&
e.clientY > topPosition &&
@ -287,11 +296,21 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
// Use passive: true for better scroll performance
container.addEventListener('scroll', handleScroll, { passive: true })
window.addEventListener('mousemove', handleMouseMove)
if (messagesContainer) {
// Listen to the messages container (but with global coordinates)
messagesContainer.addEventListener('mousemove', handleMouseMove)
} else {
window.addEventListener('mousemove', handleMouseMove)
}
return () => {
container.removeEventListener('scroll', handleScroll)
window.removeEventListener('mousemove', handleMouseMove)
if (messagesContainer) {
messagesContainer.removeEventListener('mousemove', handleMouseMove)
} else {
window.removeEventListener('mousemove', handleMouseMove)
}
if (hideTimer) {
clearTimeout(hideTimer)
}
@ -311,7 +330,7 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
<>
<NavigationContainer $isVisible={isVisible} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<ButtonGroup>
<Tooltip title={t('chat.navigation.close')} placement="left">
<Tooltip title={t('chat.navigation.close')} placement="left" mouseEnterDelay={0.5}>
<NavigationButton
type="text"
icon={<CloseOutlined />}
@ -320,7 +339,7 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
/>
</Tooltip>
<Divider />
<Tooltip title={t('chat.navigation.top')} placement="left">
<Tooltip title={t('chat.navigation.top')} placement="left" mouseEnterDelay={0.5}>
<NavigationButton
type="text"
icon={<VerticalAlignTopOutlined />}
@ -329,7 +348,7 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
/>
</Tooltip>
<Divider />
<Tooltip title={t('chat.navigation.prev')} placement="left">
<Tooltip title={t('chat.navigation.prev')} placement="left" mouseEnterDelay={0.5}>
<NavigationButton
type="text"
icon={<ArrowUpOutlined />}
@ -338,7 +357,7 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
/>
</Tooltip>
<Divider />
<Tooltip title={t('chat.navigation.next')} placement="left">
<Tooltip title={t('chat.navigation.next')} placement="left" mouseEnterDelay={0.5}>
<NavigationButton
type="text"
icon={<ArrowDownOutlined />}
@ -347,7 +366,7 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
/>
</Tooltip>
<Divider />
<Tooltip title={t('chat.navigation.bottom')} placement="left">
<Tooltip title={t('chat.navigation.bottom')} placement="left" mouseEnterDelay={0.5}>
<NavigationButton
type="text"
icon={<VerticalAlignBottomOutlined />}
@ -356,7 +375,7 @@ const ChatNavigation: FC<ChatNavigationProps> = ({ containerId }) => {
/>
</Tooltip>
<Divider />
<Tooltip title={t('chat.navigation.history')} placement="left">
<Tooltip title={t('chat.navigation.history')} placement="left" mouseEnterDelay={0.5}>
<NavigationButton
type="text"
icon={<HistoryOutlined />}