feat:对话的时候支持侧边栏拖拽调整宽度

This commit is contained in:
hxp0618 2025-01-07 13:43:07 +08:00
parent a051f9fa44
commit 58072128f0

View File

@ -7,7 +7,7 @@ import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import { Assistant, Topic } from '@renderer/types' import { Assistant, Topic } from '@renderer/types'
import { uuid } from '@renderer/utils' import { uuid } from '@renderer/utils'
import { Segmented as AntSegmented, SegmentedProps } from 'antd' import { Segmented as AntSegmented, SegmentedProps } from 'antd'
import { FC, useEffect, useState } from 'react' import { FC, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -33,6 +33,10 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
const { topicPosition } = useSettings() const { topicPosition } = useSettings()
const { defaultAssistant } = useDefaultAssistant() const { defaultAssistant } = useDefaultAssistant()
const { toggleShowTopics } = useShowTopics() const { toggleShowTopics } = useShowTopics()
const [width, setWidth] = useState(260) // 减小初始宽度
const isResizing = useRef(false)
const startX = useRef(0)
const startWidth = useRef(0)
const { t } = useTranslation() const { t } = useTranslation()
@ -63,6 +67,27 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
setActiveAssistant(assistant) setActiveAssistant(assistant)
} }
const startResizing = (e: React.MouseEvent) => {
isResizing.current = true
startX.current = e.clientX
startWidth.current = width
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', stopResizing)
}
const handleMouseMove = (e: MouseEvent) => {
if (!isResizing.current) return
const delta = position === 'left' ? e.clientX - startX.current : startX.current - e.clientX
const newWidth = Math.min(Math.max(startWidth.current + delta, 180), 400) // 调整最小和最大宽度
setWidth(newWidth)
}
const stopResizing = () => {
isResizing.current = false
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', stopResizing)
}
useEffect(() => { useEffect(() => {
const unsubscribes = [ const unsubscribes = [
EventEmitter.on(EVENT_NAMES.SHOW_ASSISTANTS, (): any => { EventEmitter.on(EVENT_NAMES.SHOW_ASSISTANTS, (): any => {
@ -94,15 +119,15 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
}, [position, tab, topicPosition]) }, [position, tab, topicPosition])
return ( return (
<Container style={border} className="home-tabs"> <Container style={{ ...border, width: `${width}px` }} className="home-tabs">
{showTab && ( {showTab && (
<Segmented <Segmented
value={tab} value={tab}
style={{ style={{
borderRadius: 0, borderRadius: 0,
padding: '10px 0', padding: '8px 0', // 减小内边距
margin: '0 10px', margin: '0 8px', // 减小外边距
paddingBottom: 10, paddingBottom: 8,
borderBottom: '0.5px solid var(--color-border)', borderBottom: '0.5px solid var(--color-border)',
gap: 2 gap: 2
}} }}
@ -139,6 +164,10 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
)} )}
{tab === 'settings' && <Settings assistant={activeAssistant} />} {tab === 'settings' && <Settings assistant={activeAssistant} />}
</TabContent> </TabContent>
<ResizeHandle
onMouseDown={startResizing}
style={{ left: position === 'left' ? 'auto' : 0, right: position === 'left' ? 0 : 'auto' }}
/>
</Container> </Container>
) )
} }
@ -146,11 +175,10 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
const Container = styled.div` const Container = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
max-width: var(--assistants-width);
min-width: var(--assistants-width);
height: calc(100vh - var(--navbar-height)); height: calc(100vh - var(--navbar-height));
background-color: var(--color-background); background-color: var(--color-background);
overflow: hidden; overflow: hidden;
position: relative;
.collapsed { .collapsed {
width: 0; width: 0;
border-left: none; border-left: none;
@ -165,12 +193,24 @@ const TabContent = styled.div`
overflow-x: hidden; overflow-x: hidden;
` `
const ResizeHandle = styled.div`
position: absolute;
top: 0;
width: 4px;
height: 100%;
cursor: col-resize;
background: transparent;
&:hover {
background: var(--color-border);
}
`
const Segmented = styled(AntSegmented)` const Segmented = styled(AntSegmented)`
.ant-segmented-item { .ant-segmented-item {
overflow: hidden; overflow: hidden;
transition: none !important; transition: none !important;
height: 34px; height: 32px; // 减小高度
line-height: 34px; line-height: 32px;
background-color: transparent; background-color: transparent;
user-select: none; user-select: none;
} }
@ -184,11 +224,11 @@ const Segmented = styled(AntSegmented)`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
font-size: 13px; font-size: 12px; // 减小字体大小
height: 100%; height: 100%;
} }
.iconfont { .iconfont {
font-size: 13px; font-size: 12px;
margin-left: -2px; margin-left: -2px;
} }
.anticon-setting { .anticon-setting {