221 lines
6.4 KiB
TypeScript
221 lines
6.4 KiB
TypeScript
import AddAssistantPopup from '@renderer/components/Popups/AddAssistantPopup'
|
|
import { useAssistants, useDefaultAssistant } from '@renderer/hooks/useAssistant'
|
|
import { useSettings } from '@renderer/hooks/useSettings'
|
|
import { useShowTopics } from '@renderer/hooks/useStore'
|
|
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
|
import { Assistant, Topic } from '@renderer/types'
|
|
import { uuid } from '@renderer/utils'
|
|
import { Segmented as AntSegmented, SegmentedProps } from 'antd'
|
|
import { FC, useEffect, useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import styled from 'styled-components'
|
|
|
|
import Assistants from './AssistantsTab'
|
|
import Settings from './SettingsTab'
|
|
import Topics from './TopicsTab'
|
|
|
|
interface Props {
|
|
activeAssistant: Assistant
|
|
activeTopic: Topic
|
|
setActiveAssistant: (assistant: Assistant) => void
|
|
setActiveTopic: (topic: Topic) => void
|
|
position: 'left' | 'right'
|
|
}
|
|
|
|
type Tab = 'assistants' | 'topic' | 'settings'
|
|
|
|
let _tab: any = ''
|
|
|
|
const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant, setActiveTopic, position }) => {
|
|
const { addAssistant } = useAssistants()
|
|
const [tab, setTab] = useState<Tab>(position === 'left' ? _tab || 'assistants' : 'topic')
|
|
const { topicPosition } = useSettings()
|
|
const { defaultAssistant } = useDefaultAssistant()
|
|
const { toggleShowTopics } = useShowTopics()
|
|
|
|
const { t } = useTranslation()
|
|
|
|
const borderStyle = '0.5px solid var(--color-border)'
|
|
const border =
|
|
position === 'left' ? { borderRight: borderStyle } : { borderLeft: borderStyle, borderTopLeftRadius: 0 }
|
|
|
|
if (position === 'left' && topicPosition === 'left') {
|
|
_tab = tab
|
|
}
|
|
|
|
const showTab = !(position === 'left' && topicPosition === 'right')
|
|
|
|
const assistantTab = {
|
|
label: t('assistants.abbr'),
|
|
value: 'assistants'
|
|
}
|
|
|
|
const onCreateAssistant = async () => {
|
|
const assistant = await AddAssistantPopup.show()
|
|
assistant && setActiveAssistant(assistant)
|
|
}
|
|
|
|
const onCreateDefaultAssistant = () => {
|
|
const assistant = { ...defaultAssistant, id: uuid() }
|
|
addAssistant(assistant)
|
|
setActiveAssistant(assistant)
|
|
}
|
|
|
|
useEffect(() => {
|
|
const unsubscribes = [
|
|
EventEmitter.on(EVENT_NAMES.SHOW_ASSISTANTS, (): any => {
|
|
showTab && setTab('assistants')
|
|
}),
|
|
EventEmitter.on(EVENT_NAMES.SHOW_TOPIC_SIDEBAR, (): any => {
|
|
showTab && setTab('topic')
|
|
}),
|
|
EventEmitter.on(EVENT_NAMES.SHOW_CHAT_SETTINGS, (): any => {
|
|
showTab && setTab('settings')
|
|
}),
|
|
EventEmitter.on(EVENT_NAMES.SWITCH_TOPIC_SIDEBAR, () => {
|
|
showTab && setTab('topic')
|
|
if (position === 'left' && topicPosition === 'right') {
|
|
toggleShowTopics()
|
|
}
|
|
})
|
|
]
|
|
return () => unsubscribes.forEach((unsub) => unsub())
|
|
}, [position, showTab, tab, toggleShowTopics, topicPosition])
|
|
|
|
useEffect(() => {
|
|
if (position === 'right' && topicPosition === 'right' && tab === 'assistants') {
|
|
setTab('topic')
|
|
}
|
|
if (position === 'left' && topicPosition === 'right' && tab !== 'assistants') {
|
|
setTab('assistants')
|
|
}
|
|
}, [position, tab, topicPosition])
|
|
|
|
return (
|
|
<Container style={border} className="home-tabs">
|
|
{showTab && (
|
|
<Segmented
|
|
value={tab}
|
|
style={{ borderRadius: 16, paddingTop: 10, margin: '0 10px', gap: 2 }}
|
|
options={
|
|
[
|
|
position === 'left' && topicPosition === 'left' ? assistantTab : undefined,
|
|
{
|
|
label: t('common.topics'),
|
|
value: 'topic'
|
|
},
|
|
{
|
|
label: t('settings.title'),
|
|
value: 'settings'
|
|
}
|
|
].filter(Boolean) as SegmentedProps['options']
|
|
}
|
|
onChange={(value) => setTab(value as 'topic' | 'settings')}
|
|
block
|
|
/>
|
|
)}
|
|
<TabContent className="home-tabs-content">
|
|
{tab === 'assistants' && (
|
|
<Assistants
|
|
activeAssistant={activeAssistant}
|
|
setActiveAssistant={setActiveAssistant}
|
|
onCreateAssistant={onCreateAssistant}
|
|
onCreateDefaultAssistant={onCreateDefaultAssistant}
|
|
/>
|
|
)}
|
|
{tab === 'topic' && (
|
|
<Topics assistant={activeAssistant} activeTopic={activeTopic} setActiveTopic={setActiveTopic} />
|
|
)}
|
|
{tab === 'settings' && <Settings assistant={activeAssistant} />}
|
|
</TabContent>
|
|
</Container>
|
|
)
|
|
}
|
|
|
|
const Container = styled.div`
|
|
display: flex;
|
|
flex-direction: column;
|
|
max-width: var(--assistants-width);
|
|
min-width: var(--assistants-width);
|
|
height: calc(100vh - var(--navbar-height));
|
|
background-color: var(--color-background);
|
|
overflow: hidden;
|
|
.collapsed {
|
|
width: 0;
|
|
border-left: none;
|
|
}
|
|
`
|
|
|
|
const TabContent = styled.div`
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
`
|
|
|
|
const Segmented = styled(AntSegmented)`
|
|
&.ant-segmented {
|
|
background-color: transparent;
|
|
border-radius: 0 !important;
|
|
border-bottom: 0.5px solid var(--color-border);
|
|
padding-bottom: 10px;
|
|
}
|
|
.ant-segmented-item {
|
|
overflow: hidden;
|
|
transition: none !important;
|
|
height: 34px;
|
|
line-height: 34px;
|
|
background-color: transparent;
|
|
user-select: none;
|
|
border-radius: var(--list-item-border-radius);
|
|
box-shadow: none;
|
|
}
|
|
.ant-segmented-item-selected {
|
|
background-color: var(--color-background-soft);
|
|
border: 0.5px solid var(--color-border);
|
|
transition: none !important;
|
|
}
|
|
.ant-segmented-item-label {
|
|
align-items: center;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: center;
|
|
font-size: 13px;
|
|
height: 100%;
|
|
}
|
|
.ant-segmented-item-label[aria-selected='true'] {
|
|
color: var(--color-text);
|
|
}
|
|
.iconfont {
|
|
font-size: 13px;
|
|
margin-left: -2px;
|
|
}
|
|
.anticon-setting {
|
|
font-size: 12px;
|
|
}
|
|
.icon-business-smart-assistant {
|
|
margin-right: -2px;
|
|
}
|
|
.ant-segmented-item-icon + * {
|
|
margin-left: 4px;
|
|
}
|
|
.ant-segmented-thumb {
|
|
transition: none !important;
|
|
background-color: var(--color-background-soft);
|
|
border: 0.5px solid var(--color-border);
|
|
border-radius: var(--list-item-border-radius);
|
|
box-shadow: none;
|
|
}
|
|
.ant-segmented-item-label,
|
|
.ant-segmented-item-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
/* These styles ensure the same appearance as before */
|
|
border-radius: 0;
|
|
box-shadow: none;
|
|
`
|
|
|
|
export default HomeTabs
|