mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 06:49:02 +08:00
feat: optimize UI interface display
This commit is contained in:
parent
1c71e6d474
commit
93d955c4b9
@ -44,6 +44,9 @@
|
|||||||
--color-reference-text: #ffffff;
|
--color-reference-text: #ffffff;
|
||||||
--color-reference-background: #0b0e12;
|
--color-reference-background: #0b0e12;
|
||||||
|
|
||||||
|
--color-list-item: #222;
|
||||||
|
--color-list-item-hover: #1e1e1e;
|
||||||
|
|
||||||
--modal-background: #1f1f1f;
|
--modal-background: #1f1f1f;
|
||||||
|
|
||||||
--color-highlight: rgba(0, 0, 0, 1);
|
--color-highlight: rgba(0, 0, 0, 1);
|
||||||
@ -68,7 +71,7 @@
|
|||||||
--chat-background-assistant: #2c2c2c;
|
--chat-background-assistant: #2c2c2c;
|
||||||
--chat-text-user: var(--color-black);
|
--chat-text-user: var(--color-black);
|
||||||
|
|
||||||
--list-item-border-radius: 16px;
|
--list-item-border-radius: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[theme-mode='light'] {
|
[theme-mode='light'] {
|
||||||
@ -117,6 +120,9 @@
|
|||||||
--color-reference-text: #000000;
|
--color-reference-text: #000000;
|
||||||
--color-reference-background: #f1f7ff;
|
--color-reference-background: #f1f7ff;
|
||||||
|
|
||||||
|
--color-list-item: #eee;
|
||||||
|
--color-list-item-hover: #f5f5f5;
|
||||||
|
|
||||||
--modal-background: var(--color-white);
|
--modal-background: var(--color-white);
|
||||||
|
|
||||||
--color-highlight: initial;
|
--color-highlight: initial;
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { useMinapps } from '@renderer/hooks/useMinapps'
|
|||||||
import useNavBackgroundColor from '@renderer/hooks/useNavBackgroundColor'
|
import useNavBackgroundColor from '@renderer/hooks/useNavBackgroundColor'
|
||||||
import { modelGenerating, useRuntime } from '@renderer/hooks/useRuntime'
|
import { modelGenerating, useRuntime } from '@renderer/hooks/useRuntime'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
|
import i18n from '@renderer/i18n'
|
||||||
import { ThemeMode } from '@renderer/types'
|
import { ThemeMode } from '@renderer/types'
|
||||||
import { isEmoji } from '@renderer/utils'
|
import { isEmoji } from '@renderer/utils'
|
||||||
import type { MenuProps } from 'antd'
|
import type { MenuProps } from 'antd'
|
||||||
@ -19,7 +20,7 @@ import {
|
|||||||
Folder,
|
Folder,
|
||||||
Languages,
|
Languages,
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
MessageSquareQuote,
|
MessageSquare,
|
||||||
Moon,
|
Moon,
|
||||||
Palette,
|
Palette,
|
||||||
Settings,
|
Settings,
|
||||||
@ -35,7 +36,6 @@ import styled from 'styled-components'
|
|||||||
import DragableList from '../DragableList'
|
import DragableList from '../DragableList'
|
||||||
import MinAppIcon from '../Icons/MinAppIcon'
|
import MinAppIcon from '../Icons/MinAppIcon'
|
||||||
import UserPopup from '../Popups/UserPopup'
|
import UserPopup from '../Popups/UserPopup'
|
||||||
import i18n from '@renderer/i18n'
|
|
||||||
|
|
||||||
const Sidebar: FC = () => {
|
const Sidebar: FC = () => {
|
||||||
const { hideMinappPopup, openMinapp } = useMinappPopup()
|
const { hideMinappPopup, openMinapp } = useMinappPopup()
|
||||||
@ -67,9 +67,7 @@ const Sidebar: FC = () => {
|
|||||||
openMinapp({
|
openMinapp({
|
||||||
id: docsId,
|
id: docsId,
|
||||||
name: t('docs.title'),
|
name: t('docs.title'),
|
||||||
url: isChinese
|
url: isChinese ? 'https://docs.cherry-ai.com/' : 'https://docs.cherry-ai.com/cherry-studio-wen-dang/en-us',
|
||||||
? 'https://docs.cherry-ai.com/'
|
|
||||||
: 'https://docs.cherry-ai.com/cherry-studio-wen-dang/en-us',
|
|
||||||
logo: AppLogo
|
logo: AppLogo
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -151,7 +149,7 @@ const MainMenus: FC = () => {
|
|||||||
const isRoutes = (path: string): string => (pathname.startsWith(path) && !minappShow ? 'active' : '')
|
const isRoutes = (path: string): string => (pathname.startsWith(path) && !minappShow ? 'active' : '')
|
||||||
|
|
||||||
const iconMap = {
|
const iconMap = {
|
||||||
assistants: <MessageSquareQuote size={18} className="icon" />,
|
assistants: <MessageSquare size={18} className="icon" />,
|
||||||
agents: <Sparkle size={18} className="icon" />,
|
agents: <Sparkle size={18} className="icon" />,
|
||||||
paintings: <Palette size={18} className="icon" />,
|
paintings: <Palette size={18} className="icon" />,
|
||||||
translate: <Languages size={18} className="icon" />,
|
translate: <Languages size={18} className="icon" />,
|
||||||
|
|||||||
@ -48,6 +48,10 @@ const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
|
|||||||
},
|
},
|
||||||
ColorPicker: {
|
ColorPicker: {
|
||||||
fontFamily: 'var(--code-font-family)'
|
fontFamily: 'var(--code-font-family)'
|
||||||
|
},
|
||||||
|
Segmented: {
|
||||||
|
itemActiveBg: 'var(--color-background-mute)',
|
||||||
|
itemHoverBg: 'var(--color-background-mute)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
token: {
|
token: {
|
||||||
|
|||||||
@ -34,7 +34,7 @@ const Container = styled.div<{ $isDark: boolean }>`
|
|||||||
margin: 5px 20px 0 20px;
|
margin: 5px 20px 0 20px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid var(--color-border);
|
border: 0.5px solid var(--color-border);
|
||||||
`
|
`
|
||||||
|
|
||||||
const Text = styled.div`
|
const Text = styled.div`
|
||||||
|
|||||||
@ -60,7 +60,7 @@ import {
|
|||||||
} from '@renderer/types'
|
} from '@renderer/types'
|
||||||
import { modalConfirm } from '@renderer/utils'
|
import { modalConfirm } from '@renderer/utils'
|
||||||
import { Button, Col, InputNumber, Row, Select, Slider, Switch, Tooltip } from 'antd'
|
import { Button, Col, InputNumber, Row, Select, Slider, Switch, Tooltip } from 'antd'
|
||||||
import { CircleHelp, RotateCcw, Settings2 } from 'lucide-react'
|
import { CircleHelp, Settings2 } from 'lucide-react'
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
@ -72,7 +72,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SettingsTab: FC<Props> = (props) => {
|
const SettingsTab: FC<Props> = (props) => {
|
||||||
const { assistant, updateAssistantSettings, updateAssistant } = useAssistant(props.assistant.id)
|
const { assistant, updateAssistantSettings } = useAssistant(props.assistant.id)
|
||||||
const { provider } = useProvider(assistant.model.provider)
|
const { provider } = useProvider(assistant.model.provider)
|
||||||
|
|
||||||
const { messageStyle, fontSize, language } = useSettings()
|
const { messageStyle, fontSize, language } = useSettings()
|
||||||
@ -140,24 +140,6 @@ const SettingsTab: FC<Props> = (props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onReset = () => {
|
|
||||||
setTemperature(DEFAULT_TEMPERATURE)
|
|
||||||
setContextCount(DEFAULT_CONTEXTCOUNT)
|
|
||||||
updateAssistant({
|
|
||||||
...assistant,
|
|
||||||
settings: {
|
|
||||||
...assistant.settings,
|
|
||||||
temperature: DEFAULT_TEMPERATURE,
|
|
||||||
contextCount: DEFAULT_CONTEXTCOUNT,
|
|
||||||
enableMaxTokens: false,
|
|
||||||
maxTokens: DEFAULT_MAX_TOKENS,
|
|
||||||
streamOutput: true,
|
|
||||||
hideMessages: false,
|
|
||||||
customParameters: []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const codeStyle = useMemo(() => {
|
const codeStyle = useMemo(() => {
|
||||||
return codeEditor.enabled
|
return codeEditor.enabled
|
||||||
? theme === ThemeMode.light
|
? theme === ThemeMode.light
|
||||||
@ -211,14 +193,6 @@ const SettingsTab: FC<Props> = (props) => {
|
|||||||
defaultExpanded={true}
|
defaultExpanded={true}
|
||||||
extra={
|
extra={
|
||||||
<HStack alignItems="center" gap={2}>
|
<HStack alignItems="center" gap={2}>
|
||||||
<Tooltip title={t('chat.settings.reset')}>
|
|
||||||
<Button
|
|
||||||
type="text"
|
|
||||||
size="small"
|
|
||||||
onClick={onReset}
|
|
||||||
icon={<RotateCcw size={20} style={{ cursor: 'pointer', padding: '0 3px', opacity: 0.8 }} />}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
@ -714,6 +688,7 @@ const Container = styled(Scrollbar)`
|
|||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
margin-top: 3px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const SettingRowTitleSmall = styled(SettingRowTitle)`
|
const SettingRowTitleSmall = styled(SettingRowTitle)`
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
EditOutlined,
|
EditOutlined,
|
||||||
FolderOutlined,
|
FolderOutlined,
|
||||||
|
MenuOutlined,
|
||||||
PushpinOutlined,
|
PushpinOutlined,
|
||||||
QuestionCircleOutlined,
|
QuestionCircleOutlined,
|
||||||
UploadOutlined
|
UploadOutlined
|
||||||
@ -54,7 +55,7 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
const { assistants } = useAssistants()
|
const { assistants } = useAssistants()
|
||||||
const { assistant, removeTopic, moveTopic, updateTopic, updateTopics } = useAssistant(_assistant.id)
|
const { assistant, removeTopic, moveTopic, updateTopic, updateTopics } = useAssistant(_assistant.id)
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { showTopicTime, pinTopicsToTop } = useSettings()
|
const { showTopicTime, pinTopicsToTop, setTopicPosition } = useSettings()
|
||||||
|
|
||||||
const borderRadius = showTopicTime ? 12 : 'var(--list-item-border-radius)'
|
const borderRadius = showTopicTime ? 12 : 'var(--list-item-border-radius)'
|
||||||
|
|
||||||
@ -248,6 +249,23 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t('settings.topic.position'),
|
||||||
|
key: 'topic-position',
|
||||||
|
icon: <MenuOutlined />,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: t('settings.topic.position.left'),
|
||||||
|
key: 'left',
|
||||||
|
onClick: () => setTopicPosition('left')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('settings.topic.position.right'),
|
||||||
|
key: 'right',
|
||||||
|
onClick: () => setTopicPosition('right')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: t('chat.topics.copy.title'),
|
label: t('chat.topics.copy.title'),
|
||||||
key: 'copy',
|
key: 'copy',
|
||||||
@ -363,26 +381,27 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
|
|
||||||
return menus
|
return menus
|
||||||
}, [
|
}, [
|
||||||
activeTopic.id,
|
targetTopic,
|
||||||
assistant,
|
t,
|
||||||
assistants,
|
|
||||||
exportMenuOptions.docx,
|
|
||||||
exportMenuOptions.image,
|
exportMenuOptions.image,
|
||||||
exportMenuOptions.joplin,
|
|
||||||
exportMenuOptions.markdown,
|
exportMenuOptions.markdown,
|
||||||
exportMenuOptions.markdown_reason,
|
exportMenuOptions.markdown_reason,
|
||||||
|
exportMenuOptions.docx,
|
||||||
exportMenuOptions.notion,
|
exportMenuOptions.notion,
|
||||||
exportMenuOptions.obsidian,
|
|
||||||
exportMenuOptions.siyuan,
|
|
||||||
exportMenuOptions.yuque,
|
exportMenuOptions.yuque,
|
||||||
onClearMessages,
|
exportMenuOptions.obsidian,
|
||||||
onDeleteTopic,
|
exportMenuOptions.joplin,
|
||||||
onMoveTopic,
|
exportMenuOptions.siyuan,
|
||||||
onPinTopic,
|
assistants,
|
||||||
setActiveTopic,
|
assistant,
|
||||||
t,
|
|
||||||
updateTopic,
|
updateTopic,
|
||||||
targetTopic
|
activeTopic.id,
|
||||||
|
setActiveTopic,
|
||||||
|
onPinTopic,
|
||||||
|
onClearMessages,
|
||||||
|
setTopicPosition,
|
||||||
|
onMoveTopic,
|
||||||
|
onDeleteTopic
|
||||||
])
|
])
|
||||||
|
|
||||||
// Sort topics based on pinned status if pinTopicsToTop is enabled
|
// Sort topics based on pinned status if pinTopicsToTop is enabled
|
||||||
@ -486,7 +505,6 @@ const TopicListItem = styled.div`
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 0.5px solid transparent;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
width: calc(var(--assistants-width) - 20px);
|
width: calc(var(--assistants-width) - 20px);
|
||||||
.menu {
|
.menu {
|
||||||
@ -494,15 +512,10 @@ const TopicListItem = styled.div`
|
|||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--color-background-soft);
|
background-color: var(--color-list-item-hover);
|
||||||
.name {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&.active {
|
&.active {
|
||||||
background-color: var(--color-background-soft);
|
background-color: var(--color-list-item);
|
||||||
border: 0.5px solid var(--color-border);
|
|
||||||
.name {
|
|
||||||
}
|
|
||||||
.menu {
|
.menu {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
@ -383,23 +383,18 @@ const Container = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 10px;
|
padding: 0 8px;
|
||||||
height: 37px;
|
height: 37px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: var(--list-item-border-radius);
|
border-radius: var(--list-item-border-radius);
|
||||||
border: 0.5px solid transparent;
|
border: 0.5px solid transparent;
|
||||||
width: calc(var(--assistants-width) - 20px);
|
width: calc(var(--assistants-width) - 20px);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
.iconfont {
|
|
||||||
opacity: 0;
|
|
||||||
color: var(--color-text-3);
|
|
||||||
}
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--color-background-soft);
|
background-color: var(--color-list-item-hover);
|
||||||
}
|
}
|
||||||
&.active {
|
&.active {
|
||||||
background-color: var(--color-background-soft);
|
background-color: var(--color-list-item);
|
||||||
border: 0.5px solid var(--color-border);
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,7 @@ const HomeTabs: FC<Props> = ({
|
|||||||
const assistantTab = {
|
const assistantTab = {
|
||||||
label: t('assistants.abbr'),
|
label: t('assistants.abbr'),
|
||||||
value: 'assistants'
|
value: 'assistants'
|
||||||
|
// icon: <BotIcon size={16} />
|
||||||
}
|
}
|
||||||
|
|
||||||
const onCreateAssistant = async () => {
|
const onCreateAssistant = async () => {
|
||||||
@ -104,28 +105,35 @@ const HomeTabs: FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<Container style={{ ...border, ...style }} className="home-tabs">
|
<Container style={{ ...border, ...style }} className="home-tabs">
|
||||||
{(showTab || (forceToSeeAllTab == true && !showTopics)) && (
|
{(showTab || (forceToSeeAllTab == true && !showTopics)) && (
|
||||||
<Segmented
|
<>
|
||||||
value={tab}
|
<Segmented
|
||||||
style={{ borderRadius: 16, paddingTop: 10, margin: '0 10px', gap: 2 }}
|
value={tab}
|
||||||
options={
|
style={{ borderRadius: 50 }}
|
||||||
[
|
shape="round"
|
||||||
(position === 'left' && topicPosition === 'left') || (forceToSeeAllTab == true && position === 'left')
|
options={
|
||||||
? assistantTab
|
[
|
||||||
: undefined,
|
(position === 'left' && topicPosition === 'left') || (forceToSeeAllTab == true && position === 'left')
|
||||||
{
|
? assistantTab
|
||||||
label: t('common.topics'),
|
: undefined,
|
||||||
value: 'topic'
|
{
|
||||||
},
|
label: t('common.topics'),
|
||||||
{
|
value: 'topic'
|
||||||
label: t('settings.title'),
|
// icon: <MessageSquareQuote size={16} />
|
||||||
value: 'settings'
|
},
|
||||||
}
|
{
|
||||||
].filter(Boolean) as SegmentedProps['options']
|
label: t('settings.title'),
|
||||||
}
|
value: 'settings'
|
||||||
onChange={(value) => setTab(value as 'topic' | 'settings')}
|
// icon: <SettingsIcon size={16} />
|
||||||
block
|
}
|
||||||
/>
|
].filter(Boolean) as SegmentedProps['options']
|
||||||
|
}
|
||||||
|
onChange={(value) => setTab(value as 'topic' | 'settings')}
|
||||||
|
block
|
||||||
|
/>
|
||||||
|
<Divider />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<TabContent className="home-tabs-content">
|
<TabContent className="home-tabs-content">
|
||||||
{tab === 'assistants' && (
|
{tab === 'assistants' && (
|
||||||
<Assistants
|
<Assistants
|
||||||
@ -149,7 +157,7 @@ const Container = styled.div`
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: var(--assistants-width);
|
max-width: var(--assistants-width);
|
||||||
min-width: var(--assistants-width);
|
min-width: var(--assistants-width);
|
||||||
background-color: var(--color-background);
|
background-color: transparent;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
.collapsed {
|
.collapsed {
|
||||||
width: 0;
|
width: 0;
|
||||||
@ -165,14 +173,21 @@ const TabContent = styled.div`
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const Divider = styled.div`
|
||||||
|
border-top: 0.5px solid var(--color-border);
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
`
|
||||||
|
|
||||||
const Segmented = styled(AntSegmented)`
|
const Segmented = styled(AntSegmented)`
|
||||||
font-family: var(--font-family);
|
font-family: var(--font-family);
|
||||||
|
|
||||||
&.ant-segmented {
|
&.ant-segmented {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border-radius: 0 !important;
|
margin: 0 10px;
|
||||||
border-bottom: 0.5px solid var(--color-border);
|
margin-top: 10px;
|
||||||
padding-bottom: 10px;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.ant-segmented-item {
|
.ant-segmented-item {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -184,10 +199,10 @@ const Segmented = styled(AntSegmented)`
|
|||||||
border-radius: var(--list-item-border-radius);
|
border-radius: var(--list-item-border-radius);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
.ant-segmented-item-selected {
|
.ant-segmented-item-selected,
|
||||||
background-color: var(--color-background-soft);
|
.ant-segmented-item-selected:active {
|
||||||
border: 0.5px solid var(--color-border);
|
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
|
background-color: var(--color-list-item);
|
||||||
}
|
}
|
||||||
.ant-segmented-item-label {
|
.ant-segmented-item-label {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -200,25 +215,17 @@ const Segmented = styled(AntSegmented)`
|
|||||||
.ant-segmented-item-label[aria-selected='true'] {
|
.ant-segmented-item-label[aria-selected='true'] {
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
.iconfont {
|
|
||||||
font-size: 13px;
|
|
||||||
margin-left: -2px;
|
|
||||||
}
|
|
||||||
.anticon-setting {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
.icon-business-smart-assistant {
|
.icon-business-smart-assistant {
|
||||||
margin-right: -2px;
|
margin-right: -2px;
|
||||||
}
|
}
|
||||||
.ant-segmented-item-icon + * {
|
|
||||||
margin-left: 4px;
|
|
||||||
}
|
|
||||||
.ant-segmented-thumb {
|
.ant-segmented-thumb {
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
background-color: var(--color-background-soft);
|
background-color: var(--color-list-item);
|
||||||
border: 0.5px solid var(--color-border);
|
|
||||||
border-radius: var(--list-item-border-radius);
|
border-radius: var(--list-item-border-radius);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
&:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.ant-segmented-item-label,
|
.ant-segmented-item-label,
|
||||||
.ant-segmented-item-icon {
|
.ant-segmented-item-icon {
|
||||||
|
|||||||
@ -13,6 +13,8 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import ReactMarkdown from 'react-markdown'
|
import ReactMarkdown from 'react-markdown'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
import { SettingDivider } from '..'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
assistant: Assistant
|
assistant: Assistant
|
||||||
updateAssistant: (assistant: Assistant) => void
|
updateAssistant: (assistant: Assistant) => void
|
||||||
@ -90,7 +92,8 @@ const AssistantPromptSettings: React.FC<Props> = ({ assistant, updateAssistant }
|
|||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack mt={8} mb={8} alignItems="center" gap={4}>
|
<SettingDivider />
|
||||||
|
<HStack mb={8} alignItems="center" gap={4}>
|
||||||
<Box style={{ fontWeight: 'bold' }}>{t('common.prompt')}</Box>
|
<Box style={{ fontWeight: 'bold' }}>{t('common.prompt')}</Box>
|
||||||
<Tooltip title={t('agents.add.prompt.variables.tip')}>
|
<Tooltip title={t('agents.add.prompt.variables.tip')}>
|
||||||
<QuestionCircleOutlined size={14} color="var(--color-text-2)" />
|
<QuestionCircleOutlined size={14} color="var(--color-text-2)" />
|
||||||
@ -139,7 +142,6 @@ const Container = styled.div`
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 5px;
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const EmojiButtonWrapper = styled.div`
|
const EmojiButtonWrapper = styled.div`
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingTitle } from '..'
|
import { SettingDivider, SettingRow, SettingTitle } from '..'
|
||||||
|
|
||||||
const { TextArea } = Input
|
const { TextArea } = Input
|
||||||
|
|
||||||
@ -79,52 +79,50 @@ const AssistantRegularPromptsSettings: FC<AssistantRegularPromptsSettingsProps>
|
|||||||
const reversedPrompts = [...promptsList].reverse()
|
const reversedPrompts = [...promptsList].reverse()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingContainer style={{ padding: 0, background: '#0000' }}>
|
<Container>
|
||||||
<SettingGroup style={{ marginBottom: 0, padding: 0, border: 'none' }}>
|
<SettingTitle>
|
||||||
<SettingTitle>
|
{t('assistants.settings.regular_phrases.title', 'Regular Prompts')}
|
||||||
{t('assistants.settings.regular_phrases.title', 'Regular Prompts')}
|
<Button type="text" icon={<PlusOutlined />} onClick={handleAdd} />
|
||||||
<Button type="text" icon={<PlusOutlined />} onClick={handleAdd} />
|
</SettingTitle>
|
||||||
</SettingTitle>
|
<SettingDivider />
|
||||||
<SettingDivider />
|
<SettingRow>
|
||||||
<SettingRow>
|
<StyledPromptList>
|
||||||
<StyledPromptList>
|
<DragableList
|
||||||
<DragableList
|
list={reversedPrompts}
|
||||||
list={reversedPrompts}
|
onUpdate={(newPrompts) => handleUpdateOrder([...newPrompts].reverse())}
|
||||||
onUpdate={(newPrompts) => handleUpdateOrder([...newPrompts].reverse())}
|
style={{ paddingBottom: dragging ? '34px' : 0 }}
|
||||||
style={{ paddingBottom: dragging ? '34px' : 0 }}
|
onDragStart={() => setDragging(true)}
|
||||||
onDragStart={() => setDragging(true)}
|
onDragEnd={() => setDragging(false)}>
|
||||||
onDragEnd={() => setDragging(false)}>
|
{(prompt) => (
|
||||||
{(prompt) => (
|
<FileItem
|
||||||
<FileItem
|
key={prompt.id}
|
||||||
key={prompt.id}
|
fileInfo={{
|
||||||
fileInfo={{
|
name: prompt.title,
|
||||||
name: prompt.title,
|
ext: '.txt',
|
||||||
ext: '.txt',
|
extra: prompt.content,
|
||||||
extra: prompt.content,
|
actions: (
|
||||||
actions: (
|
<Flex gap={4} style={{ opacity: 0.6 }}>
|
||||||
<Flex gap={4} style={{ opacity: 0.6 }}>
|
<Button key="edit" type="text" icon={<EditOutlined />} onClick={() => handleEdit(prompt)} />
|
||||||
<Button key="edit" type="text" icon={<EditOutlined />} onClick={() => handleEdit(prompt)} />
|
<Popconfirm
|
||||||
<Popconfirm
|
title={t('assistants.settings.regular_phrases.delete', 'Delete Prompt')}
|
||||||
title={t('assistants.settings.regular_phrases.delete', 'Delete Prompt')}
|
description={t(
|
||||||
description={t(
|
'assistants.settings.regular_phrases.deleteConfirm',
|
||||||
'assistants.settings.regular_phrases.deleteConfirm',
|
'Are you sure to delete this prompt?'
|
||||||
'Are you sure to delete this prompt?'
|
)}
|
||||||
)}
|
okText={t('common.confirm')}
|
||||||
okText={t('common.confirm')}
|
cancelText={t('common.cancel')}
|
||||||
cancelText={t('common.cancel')}
|
onConfirm={() => handleDelete(prompt.id)}
|
||||||
onConfirm={() => handleDelete(prompt.id)}
|
icon={<ExclamationCircleOutlined style={{ color: 'red' }} />}>
|
||||||
icon={<ExclamationCircleOutlined style={{ color: 'red' }} />}>
|
<Button key="delete" type="text" danger icon={<DeleteOutlined />} />
|
||||||
<Button key="delete" type="text" danger icon={<DeleteOutlined />} />
|
</Popconfirm>
|
||||||
</Popconfirm>
|
</Flex>
|
||||||
</Flex>
|
)
|
||||||
)
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
</DragableList>
|
||||||
</DragableList>
|
</StyledPromptList>
|
||||||
</StyledPromptList>
|
</SettingRow>
|
||||||
</SettingRow>
|
|
||||||
</SettingGroup>
|
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title={
|
title={
|
||||||
@ -159,10 +157,16 @@ const AssistantRegularPromptsSettings: FC<AssistantRegularPromptsSettingsProps>
|
|||||||
</div>
|
</div>
|
||||||
</Space>
|
</Space>
|
||||||
</Modal>
|
</Modal>
|
||||||
</SettingContainer>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
`
|
||||||
|
|
||||||
const Label = styled.div`
|
const Label = styled.div`
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
@ -171,8 +175,6 @@ const Label = styled.div`
|
|||||||
|
|
||||||
const StyledPromptList = styled.div`
|
const StyledPromptList = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100vh - 162px); // Adjusted height to match other settings pages
|
|
||||||
overflow-y: auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|||||||
@ -66,16 +66,6 @@ export const INITIAL_PROVIDERS: Provider[] = [
|
|||||||
isSystem: true,
|
isSystem: true,
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'openrouter',
|
|
||||||
name: 'OpenRouter',
|
|
||||||
type: 'openai',
|
|
||||||
apiKey: '',
|
|
||||||
apiHost: 'https://openrouter.ai/api/v1/',
|
|
||||||
models: SYSTEM_MODELS.openrouter,
|
|
||||||
isSystem: true,
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'ppio',
|
id: 'ppio',
|
||||||
name: 'PPIO',
|
name: 'PPIO',
|
||||||
@ -96,16 +86,6 @@ export const INITIAL_PROVIDERS: Provider[] = [
|
|||||||
isSystem: true,
|
isSystem: true,
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'infini',
|
|
||||||
name: 'Infini',
|
|
||||||
type: 'openai',
|
|
||||||
apiKey: '',
|
|
||||||
apiHost: 'https://cloud.infini-ai.com/maas',
|
|
||||||
models: SYSTEM_MODELS.infini,
|
|
||||||
isSystem: true,
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'qiniu',
|
id: 'qiniu',
|
||||||
name: 'Qiniu',
|
name: 'Qiniu',
|
||||||
@ -136,6 +116,16 @@ export const INITIAL_PROVIDERS: Provider[] = [
|
|||||||
isSystem: true,
|
isSystem: true,
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'tokenflux',
|
||||||
|
name: 'TokenFlux',
|
||||||
|
type: 'openai',
|
||||||
|
apiKey: '',
|
||||||
|
apiHost: 'https://tokenflux.ai',
|
||||||
|
models: SYSTEM_MODELS.tokenflux,
|
||||||
|
isSystem: true,
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'o3',
|
id: 'o3',
|
||||||
name: 'O3',
|
name: 'O3',
|
||||||
@ -146,6 +136,16 @@ export const INITIAL_PROVIDERS: Provider[] = [
|
|||||||
isSystem: true,
|
isSystem: true,
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'openrouter',
|
||||||
|
name: 'OpenRouter',
|
||||||
|
type: 'openai',
|
||||||
|
apiKey: '',
|
||||||
|
apiHost: 'https://openrouter.ai/api/v1/',
|
||||||
|
models: SYSTEM_MODELS.openrouter,
|
||||||
|
isSystem: true,
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'ollama',
|
id: 'ollama',
|
||||||
name: 'Ollama',
|
name: 'Ollama',
|
||||||
@ -298,6 +298,16 @@ export const INITIAL_PROVIDERS: Provider[] = [
|
|||||||
isSystem: true,
|
isSystem: true,
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'infini',
|
||||||
|
name: 'Infini',
|
||||||
|
type: 'openai',
|
||||||
|
apiKey: '',
|
||||||
|
apiHost: 'https://cloud.infini-ai.com/maas',
|
||||||
|
models: SYSTEM_MODELS.infini,
|
||||||
|
isSystem: true,
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'minimax',
|
id: 'minimax',
|
||||||
name: 'MiniMax',
|
name: 'MiniMax',
|
||||||
@ -477,16 +487,6 @@ export const INITIAL_PROVIDERS: Provider[] = [
|
|||||||
models: SYSTEM_MODELS.voyageai,
|
models: SYSTEM_MODELS.voyageai,
|
||||||
isSystem: true,
|
isSystem: true,
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'tokenflux',
|
|
||||||
name: 'TokenFlux',
|
|
||||||
type: 'openai',
|
|
||||||
apiKey: '',
|
|
||||||
apiHost: 'https://tokenflux.ai',
|
|
||||||
models: SYSTEM_MODELS.tokenflux,
|
|
||||||
isSystem: true,
|
|
||||||
enabled: false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user