feat: improved ui effects and rendering for components
- Added smooth all property transition effect to Icon component. - Added hover effect and conditional rendering for Switch Topic Sidebar button on current assistant. - Updated the existing conditional options array to consistently include both topic and settings options. - Improved hover effects on topic list items.
This commit is contained in:
parent
1ec7df9a7e
commit
6bb7b2ca5d
@ -22,7 +22,7 @@
|
||||
|
||||
--color-background: #181818;
|
||||
--color-background-soft: var(--color-black-soft);
|
||||
--color-background-mute: var(--color-black-mute);
|
||||
--color-background-mute: var(--color-black-soft);
|
||||
|
||||
--color-primary: #00b96b;
|
||||
--color-primary-soft: #00b96b99;
|
||||
|
||||
@ -48,12 +48,12 @@ const Sidebar: FC = () => {
|
||||
<Menus onClick={MinApp.onClose}>
|
||||
<StyledLink onClick={() => to('/')}>
|
||||
<Icon className={isRoute('/')}>
|
||||
<i className="iconfont icon-chat"></i>
|
||||
<i className="iconfont icon-chat" />
|
||||
</Icon>
|
||||
</StyledLink>
|
||||
<StyledLink onClick={() => to('/agents')}>
|
||||
<Icon className={isRoute('/agents')}>
|
||||
<i className="iconfont icon-business-smart-assistant"></i>
|
||||
<i className="iconfont icon-business-smart-assistant" />
|
||||
</Icon>
|
||||
</StyledLink>
|
||||
<StyledLink onClick={() => to('/translate')}>
|
||||
@ -63,7 +63,7 @@ const Sidebar: FC = () => {
|
||||
</StyledLink>
|
||||
<StyledLink onClick={() => to('/apps')}>
|
||||
<Icon className={isRoute('/apps')}>
|
||||
<i className="iconfont icon-appstore"></i>
|
||||
<i className="iconfont icon-appstore" />
|
||||
</Icon>
|
||||
</StyledLink>
|
||||
<StyledLink onClick={() => to('/files')}>
|
||||
@ -76,7 +76,7 @@ const Sidebar: FC = () => {
|
||||
<Menus onClick={MinApp.onClose}>
|
||||
<StyledLink onClick={() => to(isLocalAi ? '/settings/assistant' : '/settings/provider')}>
|
||||
<Icon className={pathname.startsWith('/settings') ? 'active' : ''}>
|
||||
<i className="iconfont icon-setting"></i>
|
||||
<i className="iconfont icon-setting" />
|
||||
</Icon>
|
||||
</StyledLink>
|
||||
</Menus>
|
||||
@ -128,6 +128,7 @@ const Icon = styled.div`
|
||||
margin-bottom: 5px;
|
||||
transition: background-color 0.2s ease;
|
||||
-webkit-app-region: none;
|
||||
transition: all 0.2s ease;
|
||||
.iconfont,
|
||||
.anticon {
|
||||
color: var(--color-icon);
|
||||
@ -139,7 +140,7 @@ const Icon = styled.div`
|
||||
font-size: 17px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-background-mute);
|
||||
background-color: var(--color-background-soft);
|
||||
cursor: pointer;
|
||||
.iconfont,
|
||||
.anticon {
|
||||
@ -147,7 +148,7 @@ const Icon = styled.div`
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
background-color: var(--color-background-soft);
|
||||
background-color: var(--color-background-mute);
|
||||
.iconfont,
|
||||
.anticon {
|
||||
color: var(--color-icon-white);
|
||||
|
||||
@ -66,7 +66,7 @@ const resources = {
|
||||
},
|
||||
chat: {
|
||||
save: 'Save',
|
||||
'default.name': 'Default Assistant',
|
||||
'default.name': '⭐️ Default Assistant',
|
||||
'default.description': "Hello, I'm Default Assistant. You can start chatting with me right away",
|
||||
'default.topic.name': 'Default Topic',
|
||||
'topics.title': 'Topics',
|
||||
@ -344,7 +344,7 @@ const resources = {
|
||||
},
|
||||
chat: {
|
||||
save: '保存',
|
||||
'default.name': '默认助手',
|
||||
'default.name': '⭐️ 默认助手',
|
||||
'default.description': '你好,我是默认助手。你可以立刻开始跟我聊天。',
|
||||
'default.topic.name': '默认话题',
|
||||
'topics.title': '话题',
|
||||
|
||||
@ -186,6 +186,7 @@ const Assistants: FC<Props> = ({
|
||||
list={list}
|
||||
onUpdate={updateAssistants}
|
||||
droppableProps={{ isDropDisabled: !isEmpty(search) }}
|
||||
style={{ paddingBottom: dragging ? '34px' : 0 }}
|
||||
onDragStart={() => setDragging(true)}
|
||||
onDragEnd={() => setDragging(false)}>
|
||||
{(assistant) => {
|
||||
@ -194,11 +195,11 @@ const Assistants: FC<Props> = ({
|
||||
<Dropdown key={assistant.id} menu={{ items: getMenuItems(assistant) }} trigger={['contextMenu']}>
|
||||
<AssistantItem onClick={() => onSwitchAssistant(assistant)} className={isCurrent ? 'active' : ''}>
|
||||
<AssistantName className="name">{assistant.name || t('chat.default.name')}</AssistantName>
|
||||
<ArrowRightButton
|
||||
className={`arrow-button ${isCurrent ? 'active' : ''}`}
|
||||
onClick={() => EventEmitter.emit(EVENT_NAMES.SWITCH_TOPIC_SIDEBAR)}>
|
||||
{isCurrent && (
|
||||
<ArrowRightButton onClick={() => EventEmitter.emit(EVENT_NAMES.SWITCH_TOPIC_SIDEBAR)}>
|
||||
<i className="iconfont icon-gridlines" />
|
||||
</ArrowRightButton>
|
||||
)}
|
||||
{false && <TopicCount className="topics-count">{assistant.topics.length}</TopicCount>}
|
||||
</AssistantItem>
|
||||
</Dropdown>
|
||||
@ -206,10 +207,12 @@ const Assistants: FC<Props> = ({
|
||||
}}
|
||||
</DragableList>
|
||||
{!dragging && (
|
||||
<AddButton onClick={onCreateAssistant}>
|
||||
<AddButtonText>{t('chat.add.assistant.title')}</AddButtonText>
|
||||
<PlusOutlined />
|
||||
</AddButton>
|
||||
<AssistantItem onClick={onCreateAssistant}>
|
||||
<AssistantName>
|
||||
<PlusOutlined style={{ color: 'var(--color-text-2)', marginRight: 4 }} />
|
||||
{t('chat.add.assistant.title')}
|
||||
</AssistantName>
|
||||
</AssistantItem>
|
||||
)}
|
||||
</Container>
|
||||
)
|
||||
@ -230,15 +233,18 @@ const AssistantItem = styled.div`
|
||||
justify-content: space-between;
|
||||
padding: 7px 10px;
|
||||
position: relative;
|
||||
border-radius: 6px;
|
||||
border-radius: 4px;
|
||||
margin: 0 10px;
|
||||
padding-right: 35px;
|
||||
cursor: pointer;
|
||||
font-family: Ubuntu;
|
||||
cursor: pointer;
|
||||
.iconfont {
|
||||
opacity: 0;
|
||||
color: var(--color-text-3);
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-background-soft);
|
||||
}
|
||||
&.active {
|
||||
background-color: var(--color-background-mute);
|
||||
.name {
|
||||
@ -311,29 +317,4 @@ const CommandKey = styled.div`
|
||||
margin-right: -4px;
|
||||
`
|
||||
|
||||
const AddButton = styled.div`
|
||||
height: 34px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 10px;
|
||||
margin: 0 10px;
|
||||
margin-top: -2px;
|
||||
color: var(--color-text-2);
|
||||
transition: all 0.2s ease-in-out;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
border-radius: 8px;
|
||||
.anticon {
|
||||
margin: 0 4px;
|
||||
}
|
||||
&:hover {
|
||||
color: var(--color-text-1);
|
||||
background-color: var(--color-background-soft);
|
||||
}
|
||||
`
|
||||
|
||||
const AddButtonText = styled.span``
|
||||
|
||||
export default Assistants
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {
|
||||
ClearOutlined,
|
||||
ControlOutlined,
|
||||
FormOutlined,
|
||||
FullscreenExitOutlined,
|
||||
FullscreenOutlined,
|
||||
PauseCircleOutlined,
|
||||
@ -256,11 +257,6 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
|
||||
textareaRef.current?.focus()
|
||||
}, [assistant])
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('paste', onPaste)
|
||||
return () => document.removeEventListener('paste', onPaste)
|
||||
}, [onPaste])
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<AttachmentPreview files={files} setFiles={setFiles} />
|
||||
@ -281,13 +277,14 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
|
||||
onBlur={() => setInputFocus(false)}
|
||||
onInput={onInput}
|
||||
disabled={searching}
|
||||
onPaste={(e) => onPaste(e.nativeEvent)}
|
||||
onClick={() => searching && dispatch(setSearching(false))}
|
||||
/>
|
||||
<Toolbar>
|
||||
<ToolbarMenu>
|
||||
<Tooltip placement="top" title={t('chat.input.new_topic')} arrow>
|
||||
<ToolbarButton type="text" onClick={addNewTopic}>
|
||||
<i className="iconfont icon-a-addchat" />
|
||||
<FormOutlined />
|
||||
</ToolbarButton>
|
||||
</Tooltip>
|
||||
<Tooltip placement="top" title={t('chat.input.clear')} arrow>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { FormOutlined } from '@ant-design/icons'
|
||||
import { Navbar, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingPopup'
|
||||
@ -8,6 +9,7 @@ import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
|
||||
import { getDefaultTopic, syncAsistantToAgent } from '@renderer/services/assistant'
|
||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
|
||||
import { Assistant, Topic } from '@renderer/types'
|
||||
import { Switch } from 'antd'
|
||||
import { FC, useCallback } from 'react'
|
||||
@ -41,7 +43,8 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveTopic }) => {
|
||||
addTopic(topic)
|
||||
setActiveTopic(topic)
|
||||
db.topics.add({ id: topic.id, messages: [] })
|
||||
window.message.success({ content: t('message.topic.added') })
|
||||
window.message.success({ content: t('message.topic.added'), key: 'topic-added' })
|
||||
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
|
||||
}, [addTopic, setActiveTopic, t])
|
||||
|
||||
return (
|
||||
@ -52,7 +55,7 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveTopic }) => {
|
||||
<i className="iconfont icon-hide-sidebar" />
|
||||
</NewButton>
|
||||
<NewButton onClick={addNewTopic}>
|
||||
<i className="iconfont icon-a-addchat" />
|
||||
<FormOutlined />
|
||||
</NewButton>
|
||||
</NavbarLeft>
|
||||
)}
|
||||
|
||||
@ -102,8 +102,16 @@ const RightSidebar: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssist
|
||||
options={
|
||||
[
|
||||
position === 'left' && topicPosition === 'left' ? assistantTab : undefined,
|
||||
{ label: t('common.topics'), value: 'topic', icon: <BarsOutlined /> },
|
||||
{ label: t('settings.title'), value: 'settings', icon: <SettingOutlined /> }
|
||||
{
|
||||
label: t('common.topics'),
|
||||
value: 'topic',
|
||||
icon: <BarsOutlined />
|
||||
},
|
||||
{
|
||||
label: t('settings.title'),
|
||||
value: 'settings',
|
||||
icon: <SettingOutlined />
|
||||
}
|
||||
].filter(Boolean) as SegmentedProps['options']
|
||||
}
|
||||
onChange={(value) => setTab(value as 'topic' | 'settings')}
|
||||
|
||||
@ -136,8 +136,11 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
||||
return (
|
||||
<Dropdown menu={{ items: getTopicMenuItems(topic) }} trigger={['contextMenu']} key={topic.id}>
|
||||
<TopicListItem className={isActive ? 'active' : ''} onClick={() => onSwitchTopic(topic)}>
|
||||
<TopicName className="name">{topic.name}</TopicName>
|
||||
{assistant.topics.length > 1 && (
|
||||
<TopicName className="name">
|
||||
<TopicHash>#</TopicHash>
|
||||
{topic.name.replace('`', '')}
|
||||
</TopicName>
|
||||
{assistant.topics.length > 1 && isActive && (
|
||||
<MenuButton
|
||||
className="menu"
|
||||
onClick={(e) => {
|
||||
@ -171,8 +174,7 @@ const Container = styled.div`
|
||||
const TopicListItem = styled.div`
|
||||
padding: 7px 10px;
|
||||
margin: 0 10px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
border-radius: 4px;
|
||||
font-family: Ubuntu;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
@ -180,10 +182,18 @@ const TopicListItem = styled.div`
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
font-family: Ubuntu;
|
||||
cursor: pointer;
|
||||
.menu {
|
||||
opacity: 0;
|
||||
color: var(--color-text-3);
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-background-soft);
|
||||
.name {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
background-color: var(--color-background-mute);
|
||||
.name {
|
||||
@ -214,17 +224,20 @@ const MenuButton = styled.div`
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 30px;
|
||||
height: 24px;
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
border-radius: 4px;
|
||||
min-width: 22px;
|
||||
min-height: 22px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 5px;
|
||||
right: 8px;
|
||||
top: 6px;
|
||||
.anticon {
|
||||
font-size: 12px;
|
||||
}
|
||||
`
|
||||
|
||||
const TopicHash = styled.span`
|
||||
font-size: 13px;
|
||||
color: var(--color-text-3);
|
||||
margin-right: 2px;
|
||||
`
|
||||
|
||||
export default Topics
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user