mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-08 06:19:05 +08:00
feat: Add animation for sidebar (#9768)
This commit is contained in:
parent
1295d37ff6
commit
16b9f49cc8
@ -13,6 +13,7 @@ import { Assistant, Topic } from '@renderer/types'
|
|||||||
import { classNames } from '@renderer/utils'
|
import { classNames } from '@renderer/utils'
|
||||||
import { Flex } from 'antd'
|
import { Flex } from 'antd'
|
||||||
import { debounce } from 'lodash'
|
import { debounce } from 'lodash'
|
||||||
|
import { AnimatePresence, motion } from 'motion/react'
|
||||||
import React, { FC, useState } from 'react'
|
import React, { FC, useState } from 'react'
|
||||||
import { useHotkeys } from 'react-hotkeys-hook'
|
import { useHotkeys } from 'react-hotkeys-hook'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
@ -43,7 +44,6 @@ const Chat: FC<Props> = (props) => {
|
|||||||
const contentSearchRef = React.useRef<ContentSearchRef>(null)
|
const contentSearchRef = React.useRef<ContentSearchRef>(null)
|
||||||
const [filterIncludeUser, setFilterIncludeUser] = useState(false)
|
const [filterIncludeUser, setFilterIncludeUser] = useState(false)
|
||||||
|
|
||||||
const maxWidth = useChatMaxWidth()
|
|
||||||
const { setTimeoutTimer } = useTimer()
|
const { setTimeoutTimer } = useTimer()
|
||||||
|
|
||||||
useHotkeys('esc', () => {
|
useHotkeys('esc', () => {
|
||||||
@ -131,7 +131,7 @@ const Chat: FC<Props> = (props) => {
|
|||||||
vertical
|
vertical
|
||||||
flex={1}
|
flex={1}
|
||||||
justify="space-between"
|
justify="space-between"
|
||||||
style={{ maxWidth, height: mainHeight }}>
|
style={{ maxWidth: '100%', height: mainHeight }}>
|
||||||
<Messages
|
<Messages
|
||||||
key={props.activeTopic.id}
|
key={props.activeTopic.id}
|
||||||
assistant={assistant}
|
assistant={assistant}
|
||||||
@ -153,15 +153,24 @@ const Chat: FC<Props> = (props) => {
|
|||||||
{isMultiSelectMode && <MultiSelectActionPopup topic={props.activeTopic} />}
|
{isMultiSelectMode && <MultiSelectActionPopup topic={props.activeTopic} />}
|
||||||
</QuickPanelProvider>
|
</QuickPanelProvider>
|
||||||
</Main>
|
</Main>
|
||||||
{topicPosition === 'right' && showTopics && (
|
<AnimatePresence initial={false}>
|
||||||
<Tabs
|
{topicPosition === 'right' && showTopics && (
|
||||||
activeAssistant={assistant}
|
<motion.div
|
||||||
activeTopic={props.activeTopic}
|
initial={{ width: 0, opacity: 0 }}
|
||||||
setActiveAssistant={props.setActiveAssistant}
|
animate={{ width: 'auto', opacity: 1 }}
|
||||||
setActiveTopic={props.setActiveTopic}
|
exit={{ width: 0, opacity: 0 }}
|
||||||
position="right"
|
transition={{ duration: 0.3, ease: 'easeInOut' }}
|
||||||
/>
|
style={{ overflow: 'hidden' }}>
|
||||||
)}
|
<Tabs
|
||||||
|
activeAssistant={assistant}
|
||||||
|
activeTopic={props.activeTopic}
|
||||||
|
setActiveAssistant={props.setActiveAssistant}
|
||||||
|
setActiveTopic={props.setActiveTopic}
|
||||||
|
position="right"
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { Assistant, Topic } from '@renderer/types'
|
|||||||
import { Tooltip } from 'antd'
|
import { Tooltip } from 'antd'
|
||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import { Menu, PanelLeftClose, PanelRightClose, Search } from 'lucide-react'
|
import { Menu, PanelLeftClose, PanelRightClose, Search } from 'lucide-react'
|
||||||
|
import { AnimatePresence, motion } from 'motion/react'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
@ -80,11 +81,19 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveAssistant, activeTo
|
|||||||
</NavbarIcon>
|
</NavbarIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{!showAssistants && (
|
<AnimatePresence initial={false}>
|
||||||
<NavbarIcon onClick={onShowAssistantsDrawer} style={{ marginRight: 8 }}>
|
{!showAssistants && (
|
||||||
<Menu size={18} />
|
<motion.div
|
||||||
</NavbarIcon>
|
initial={{ width: 0, opacity: 0 }}
|
||||||
)}
|
animate={{ width: 'auto', opacity: 1 }}
|
||||||
|
exit={{ width: 0, opacity: 0 }}
|
||||||
|
transition={{ duration: 0.3, ease: 'easeInOut' }}>
|
||||||
|
<NavbarIcon onClick={onShowAssistantsDrawer} style={{ marginRight: 8 }}>
|
||||||
|
<Menu size={18} />
|
||||||
|
</NavbarIcon>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
<SelectModelButton assistant={assistant} />
|
<SelectModelButton assistant={assistant} />
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack alignItems="center" gap={8}>
|
<HStack alignItems="center" gap={8}>
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import NavigationService from '@renderer/services/NavigationService'
|
|||||||
import { newMessagesActions } from '@renderer/store/newMessage'
|
import { newMessagesActions } from '@renderer/store/newMessage'
|
||||||
import { Assistant, Topic } from '@renderer/types'
|
import { Assistant, Topic } from '@renderer/types'
|
||||||
import { MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH, SECOND_MIN_WINDOW_WIDTH } from '@shared/config/constant'
|
import { MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH, SECOND_MIN_WINDOW_WIDTH } from '@shared/config/constant'
|
||||||
|
import { AnimatePresence, motion } from 'motion/react'
|
||||||
import { FC, startTransition, useCallback, useEffect, useState } from 'react'
|
import { FC, startTransition, useCallback, useEffect, useState } from 'react'
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
@ -100,17 +101,26 @@ const HomePage: FC = () => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<ContentContainer id={isLeftNavbar ? 'content-container' : undefined}>
|
<ContentContainer id={isLeftNavbar ? 'content-container' : undefined}>
|
||||||
{showAssistants && (
|
<AnimatePresence initial={false}>
|
||||||
<ErrorBoundary>
|
{showAssistants && (
|
||||||
<HomeTabs
|
<ErrorBoundary>
|
||||||
activeAssistant={activeAssistant}
|
<motion.div
|
||||||
activeTopic={activeTopic}
|
initial={{ width: 0, opacity: 0 }}
|
||||||
setActiveAssistant={setActiveAssistant}
|
animate={{ width: 'var(--assistants-width)', opacity: 1 }}
|
||||||
setActiveTopic={setActiveTopic}
|
exit={{ width: 0, opacity: 0 }}
|
||||||
position="left"
|
transition={{ duration: 0.3, ease: 'easeInOut' }}
|
||||||
/>
|
style={{ overflow: 'hidden' }}>
|
||||||
</ErrorBoundary>
|
<HomeTabs
|
||||||
)}
|
activeAssistant={activeAssistant}
|
||||||
|
activeTopic={activeTopic}
|
||||||
|
setActiveAssistant={setActiveAssistant}
|
||||||
|
setActiveTopic={setActiveTopic}
|
||||||
|
position="left"
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
</ErrorBoundary>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<Chat
|
<Chat
|
||||||
assistant={activeAssistant}
|
assistant={activeAssistant}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import { Assistant, Topic } from '@renderer/types'
|
|||||||
import { Tooltip } from 'antd'
|
import { Tooltip } from 'antd'
|
||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import { Menu, MessageSquareDiff, PanelLeftClose, PanelRightClose, Search } from 'lucide-react'
|
import { Menu, MessageSquareDiff, PanelLeftClose, PanelRightClose, Search } from 'lucide-react'
|
||||||
|
import { AnimatePresence, motion } from 'motion/react'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
@ -68,20 +69,29 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveAssistant, activeTo
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar className="home-navbar">
|
<Navbar className="home-navbar">
|
||||||
{showAssistants && (
|
<AnimatePresence initial={false}>
|
||||||
<NavbarLeft style={{ justifyContent: 'space-between', borderRight: 'none', padding: 0 }}>
|
{showAssistants && (
|
||||||
<Tooltip title={t('navbar.hide_sidebar')} mouseEnterDelay={0.8}>
|
<motion.div
|
||||||
<NavbarIcon onClick={toggleShowAssistants} style={{ marginLeft: isMac && !isFullscreen ? 16 : 0 }}>
|
initial={{ width: 0, opacity: 0 }}
|
||||||
<PanelLeftClose size={18} />
|
animate={{ width: 'auto', opacity: 1 }}
|
||||||
</NavbarIcon>
|
exit={{ width: 0, opacity: 0 }}
|
||||||
</Tooltip>
|
transition={{ duration: 0.3, ease: 'easeInOut' }}
|
||||||
<Tooltip title={t('settings.shortcuts.new_topic')} mouseEnterDelay={0.8}>
|
style={{ overflow: 'hidden', display: 'flex', flexDirection: 'row' }}>
|
||||||
<NavbarIcon onClick={() => EventEmitter.emit(EVENT_NAMES.ADD_NEW_TOPIC)} style={{ marginRight: 5 }}>
|
<NavbarLeft style={{ justifyContent: 'space-between', borderRight: 'none', padding: 0 }}>
|
||||||
<MessageSquareDiff size={18} />
|
<Tooltip title={t('navbar.hide_sidebar')} mouseEnterDelay={0.8}>
|
||||||
</NavbarIcon>
|
<NavbarIcon onClick={toggleShowAssistants} style={{ marginLeft: isMac && !isFullscreen ? 16 : 0 }}>
|
||||||
</Tooltip>
|
<PanelLeftClose size={18} />
|
||||||
</NavbarLeft>
|
</NavbarIcon>
|
||||||
)}
|
</Tooltip>
|
||||||
|
<Tooltip title={t('settings.shortcuts.new_topic')} mouseEnterDelay={0.8}>
|
||||||
|
<NavbarIcon onClick={() => EventEmitter.emit(EVENT_NAMES.ADD_NEW_TOPIC)} style={{ marginRight: 5 }}>
|
||||||
|
<MessageSquareDiff size={18} />
|
||||||
|
</NavbarIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</NavbarLeft>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
<NavbarRight style={{ justifyContent: 'space-between', flex: 1 }} className="home-navbar-right">
|
<NavbarRight style={{ justifyContent: 'space-between', flex: 1 }} className="home-navbar-right">
|
||||||
<HStack alignItems="center">
|
<HStack alignItems="center">
|
||||||
{!showAssistants && (
|
{!showAssistants && (
|
||||||
@ -93,11 +103,20 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveAssistant, activeTo
|
|||||||
</NavbarIcon>
|
</NavbarIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{!showAssistants && (
|
<AnimatePresence initial={false}>
|
||||||
<NavbarIcon onClick={onShowAssistantsDrawer} style={{ marginRight: 8 }}>
|
{!showAssistants && (
|
||||||
<Menu size={18} />
|
<motion.div
|
||||||
</NavbarIcon>
|
initial={{ width: 0, opacity: 0 }}
|
||||||
)}
|
animate={{ width: 'auto', opacity: 1 }}
|
||||||
|
exit={{ width: 0, opacity: 0 }}
|
||||||
|
transition={{ duration: 0.3, ease: 'easeInOut' }}
|
||||||
|
style={{ overflow: 'hidden' }}>
|
||||||
|
<NavbarIcon onClick={onShowAssistantsDrawer} style={{ marginRight: 8 }}>
|
||||||
|
<Menu size={18} />
|
||||||
|
</NavbarIcon>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
<SelectModelButton assistant={assistant} />
|
<SelectModelButton assistant={assistant} />
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack alignItems="center" gap={8}>
|
<HStack alignItems="center" gap={8}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user