feat: add show or hide assistant sidebar
This commit is contained in:
parent
a0c147ae3f
commit
f434fe1231
@ -12,7 +12,7 @@
|
||||
--color-white-mute: #f2f2f2;
|
||||
|
||||
--color-black: #1b1b1f;
|
||||
--color-black-soft: #303030;
|
||||
--color-black-soft: #262626;
|
||||
--color-black-mute: #363636;
|
||||
|
||||
--color-gray-1: #515c67;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||
import { toggleRightSidebar } from '@renderer/store/settings'
|
||||
import { toggleRightSidebar, toggleShowAssistants } from '@renderer/store/settings'
|
||||
|
||||
export function useShowRightSidebar() {
|
||||
const showRightSidebar = useAppSelector((state) => state.settings.showRightSidebar)
|
||||
@ -7,6 +7,16 @@ export function useShowRightSidebar() {
|
||||
|
||||
return {
|
||||
showRightSidebar,
|
||||
setShowRightSidebar: () => dispatch(toggleRightSidebar())
|
||||
toggleRightSidebar: () => dispatch(toggleRightSidebar())
|
||||
}
|
||||
}
|
||||
|
||||
export function useShowAssistants() {
|
||||
const showAssistants = useAppSelector((state) => state.settings.showAssistants)
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
return {
|
||||
showAssistants,
|
||||
toggleShowAssistants: () => dispatch(toggleShowAssistants())
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,15 +5,17 @@ import styled from 'styled-components'
|
||||
import Chat from './components/Chat'
|
||||
import Assistants from './components/Assistants'
|
||||
import { uuid } from '@renderer/utils'
|
||||
import { useShowRightSidebar } from '@renderer/hooks/useStore'
|
||||
import { useShowAssistants, useShowRightSidebar } from '@renderer/hooks/useStore'
|
||||
import { Tooltip } from 'antd'
|
||||
import Navigation from './components/Navigation'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { PlusSquareOutlined } from '@ant-design/icons'
|
||||
|
||||
const HomePage: FC = () => {
|
||||
const { assistants, addAssistant } = useAssistants()
|
||||
const [activeAssistant, setActiveAssistant] = useState(assistants[0])
|
||||
const { showRightSidebar, setShowRightSidebar } = useShowRightSidebar()
|
||||
const { showRightSidebar, toggleRightSidebar } = useShowRightSidebar()
|
||||
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
||||
const { defaultAssistant } = useDefaultAssistant()
|
||||
const { t } = useTranslation()
|
||||
|
||||
@ -26,29 +28,36 @@ const HomePage: FC = () => {
|
||||
return (
|
||||
<Container>
|
||||
<Navbar>
|
||||
<NavbarLeft style={{ justifyContent: 'flex-end', borderRight: 'none' }}>
|
||||
<NewButton onClick={onCreateAssistant}>
|
||||
<i className="iconfont icon-a-addchat"></i>
|
||||
</NewButton>
|
||||
</NavbarLeft>
|
||||
{showAssistants && (
|
||||
<NavbarLeft style={{ justifyContent: 'space-between', borderRight: 'none', padding: '0 8px' }}>
|
||||
<NewButton onClick={toggleShowAssistants} style={{ marginLeft: 8 }}>
|
||||
<i className="iconfont icon-hidesidebarhoriz" />
|
||||
</NewButton>
|
||||
<NewButton onClick={onCreateAssistant}>
|
||||
<PlusSquareOutlined />
|
||||
</NewButton>
|
||||
</NavbarLeft>
|
||||
)}
|
||||
<Navigation activeAssistant={activeAssistant} />
|
||||
<NavbarRight style={{ justifyContent: 'flex-end', padding: 5 }}>
|
||||
<Tooltip
|
||||
placement="left"
|
||||
title={showRightSidebar ? t('assistant.topics.hide_topics') : t('assistant.topics.show_topics')}
|
||||
arrow>
|
||||
<NewButton onClick={setShowRightSidebar}>
|
||||
<NewButton onClick={toggleRightSidebar}>
|
||||
<i className={`iconfont ${showRightSidebar ? 'icon-showsidebarhoriz' : 'icon-hidesidebarhoriz'}`} />
|
||||
</NewButton>
|
||||
</Tooltip>
|
||||
</NavbarRight>
|
||||
</Navbar>
|
||||
<ContentContainer>
|
||||
<Assistants
|
||||
activeAssistant={activeAssistant}
|
||||
setActiveAssistant={setActiveAssistant}
|
||||
onCreateAssistant={onCreateAssistant}
|
||||
/>
|
||||
{showAssistants && (
|
||||
<Assistants
|
||||
activeAssistant={activeAssistant}
|
||||
setActiveAssistant={setActiveAssistant}
|
||||
onCreateAssistant={onCreateAssistant}
|
||||
/>
|
||||
)}
|
||||
<Chat assistant={activeAssistant} />
|
||||
</ContentContainer>
|
||||
</Container>
|
||||
@ -59,33 +68,31 @@ const Container = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - var(--navbar-height));
|
||||
`
|
||||
|
||||
const ContentContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
`
|
||||
|
||||
const NewButton = styled.div`
|
||||
export const NewButton = styled.div`
|
||||
-webkit-app-region: none;
|
||||
border-radius: 4px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all 0.2s ease-in-out;
|
||||
color: var(--color-icon);
|
||||
.iconfont {
|
||||
font-size: 22px;
|
||||
.anticon {
|
||||
font-size: 18px;
|
||||
}
|
||||
.icon-showsidebarhoriz,
|
||||
.icon-hidesidebarhoriz {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-background-soft);
|
||||
|
||||
@ -7,6 +7,9 @@ import { Button, Dropdown, MenuProps } from 'antd'
|
||||
import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
import { NewButton } from '../HomePage'
|
||||
import { useShowAssistants } from '@renderer/hooks/useStore'
|
||||
import { capitalizeFirstLetter } from '@renderer/utils'
|
||||
|
||||
interface Props {
|
||||
activeAssistant: Assistant
|
||||
@ -17,6 +20,7 @@ const Navigation: FC<Props> = ({ activeAssistant }) => {
|
||||
const { model, setModel } = useAssistant(activeAssistant.id)
|
||||
const { providers } = useProviders()
|
||||
const { t } = useTranslation()
|
||||
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
||||
|
||||
const items: MenuProps['items'] = providers
|
||||
.filter((p) => p.models.length > 0)
|
||||
@ -33,12 +37,17 @@ const Navigation: FC<Props> = ({ activeAssistant }) => {
|
||||
}))
|
||||
|
||||
return (
|
||||
<NavbarCenter style={{ border: 'none', padding: '0 15px' }}>
|
||||
{assistant?.name}
|
||||
<NavbarCenter style={{ border: 'none', paddingLeft: showAssistants ? 8 : 16 }}>
|
||||
{!showAssistants && (
|
||||
<NewButton onClick={toggleShowAssistants} style={{ marginRight: 8 }}>
|
||||
<i className="iconfont icon-showsidebarhoriz" />
|
||||
</NewButton>
|
||||
)}
|
||||
<AssistantName>{assistant?.name}</AssistantName>
|
||||
<DropdownMenu menu={{ items, style: { maxHeight: '80vh', overflow: 'auto' } }} trigger={['click']}>
|
||||
<Button size="small" type="primary" ghost style={{ fontSize: '11px' }}>
|
||||
{model ? model.name : t('button.select_model')}
|
||||
</Button>
|
||||
<DropdownButton size="small" type="primary" ghost>
|
||||
{model ? capitalizeFirstLetter(model.name) : t('button.select_model')}
|
||||
</DropdownButton>
|
||||
</DropdownMenu>
|
||||
</NavbarCenter>
|
||||
)
|
||||
@ -49,4 +58,15 @@ const DropdownMenu = styled(Dropdown)`
|
||||
margin-left: 10px;
|
||||
`
|
||||
|
||||
const AssistantName = styled.span`
|
||||
font-weight: bold;
|
||||
margin-left: 5px;
|
||||
`
|
||||
|
||||
const DropdownButton = styled(Button)`
|
||||
font-size: 10px;
|
||||
border-radius: 15px;
|
||||
padding: 0 8px;
|
||||
`
|
||||
|
||||
export default Navigation
|
||||
|
||||
@ -19,7 +19,7 @@ const persistedReducer = persistReducer(
|
||||
{
|
||||
key: 'cherry-studio',
|
||||
storage,
|
||||
version: 13,
|
||||
version: 14,
|
||||
blacklist: ['runtime'],
|
||||
migrate
|
||||
},
|
||||
|
||||
@ -243,6 +243,16 @@ const migrate = createMigrate({
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// @ts-ignore store type is unknown
|
||||
'14': (state: RootState) => {
|
||||
return {
|
||||
...state,
|
||||
settings: {
|
||||
...state.settings,
|
||||
showAssistants: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -4,12 +4,14 @@ export type SendMessageShortcut = 'Enter' | 'Shift+Enter'
|
||||
|
||||
export interface SettingsState {
|
||||
showRightSidebar: boolean
|
||||
showAssistants: boolean
|
||||
sendMessageShortcut: SendMessageShortcut
|
||||
language: string
|
||||
}
|
||||
|
||||
const initialState: SettingsState = {
|
||||
showRightSidebar: true,
|
||||
showAssistants: true,
|
||||
sendMessageShortcut: 'Enter',
|
||||
language: navigator.language
|
||||
}
|
||||
@ -21,6 +23,9 @@ const settingsSlice = createSlice({
|
||||
toggleRightSidebar: (state) => {
|
||||
state.showRightSidebar = !state.showRightSidebar
|
||||
},
|
||||
toggleShowAssistants: (state) => {
|
||||
state.showAssistants = !state.showAssistants
|
||||
},
|
||||
setSendMessageShortcut: (state, action: PayloadAction<SendMessageShortcut>) => {
|
||||
state.sendMessageShortcut = action.payload
|
||||
},
|
||||
@ -30,6 +35,6 @@ const settingsSlice = createSlice({
|
||||
}
|
||||
})
|
||||
|
||||
export const { toggleRightSidebar, setSendMessageShortcut, setLanguage } = settingsSlice.actions
|
||||
export const { toggleRightSidebar, toggleShowAssistants, setSendMessageShortcut, setLanguage } = settingsSlice.actions
|
||||
|
||||
export default settingsSlice.reducer
|
||||
|
||||
@ -198,3 +198,8 @@ export function estimateHistoryTokenCount(assistant: Assistant, msgs: Message[])
|
||||
|
||||
return all.usedTokens - 7
|
||||
}
|
||||
|
||||
// 首字母大写
|
||||
export const capitalizeFirstLetter = (str: string) => {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user