* feat:对话的时候支持侧边栏拖拽调整宽度 * feat:对话的时候支持侧边栏拖拽调整宽度 * feat: 隐藏app sidebar 用户体验度提升,不支持隐藏对话 * fix:对话勾选知识库 国际化错误 * refactor: split the SidebarIconsManager module out of DisplaySettings * style: update SidebarIconsManager style * ci: fix typecheck * Revert "feat:对话的时候支持侧边栏拖拽调整宽度" This reverts commit 58072128f0741ecc4f918564512ec1e4ee3e9edb. * refactor: merge migrate versions * refactor: simplify sidebarIcons data structure * chore: move react-beautiful-dnd to dev dependencies * chore: use @hello-pangea/dnd replace react-beautiful-dnd * docs: update translation and formatting of input messages --------- Co-authored-by: hxp0618 <1169924772@qq.com> Co-authored-by: huang <hxp0618@gmail.com>
This commit is contained in:
parent
edac2004a0
commit
c9813bb1e2
@ -50,7 +50,7 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: ['chunk-QH6N6I7P.js', 'chunk-PB73W2YU.js']
|
exclude: ['chunk-QH6N6I7P.js', 'chunk-PB73W2YU.js', 'chunk-AFE5XGNG.js']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -89,12 +89,14 @@ class KnowledgeService {
|
|||||||
if (item.type === 'url') {
|
if (item.type === 'url') {
|
||||||
const content = item.content as string
|
const content = item.content as string
|
||||||
if (content.startsWith('http')) {
|
if (content.startsWith('http')) {
|
||||||
|
// @ts-ignore loader type
|
||||||
return await ragApplication.addLoader(new WebLoader({ urlOrContent: content }), forceReload)
|
return await ragApplication.addLoader(new WebLoader({ urlOrContent: content }), forceReload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.type === 'sitemap') {
|
if (item.type === 'sitemap') {
|
||||||
const content = item.content as string
|
const content = item.content as string
|
||||||
|
// @ts-ignore loader type
|
||||||
return await ragApplication.addLoader(new SitemapLoader({ url: content }), forceReload)
|
return await ragApplication.addLoader(new SitemapLoader({ url: content }), forceReload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,7 @@ const Sidebar: FC = () => {
|
|||||||
const { minappShow } = useRuntime()
|
const { minappShow } = useRuntime()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const { windowStyle, showTranslateIcon, showPaintingIcon, showMinappIcon, showKnowledgeIcon, showFilesIcon } =
|
const { windowStyle, sidebarIcons } = useSettings()
|
||||||
useSettings()
|
|
||||||
const { theme, toggleTheme } = useTheme()
|
const { theme, toggleTheme } = useTheme()
|
||||||
|
|
||||||
const isRoute = (path: string): string => (pathname === path ? 'active' : '')
|
const isRoute = (path: string): string => (pathname === path ? 'active' : '')
|
||||||
@ -38,6 +37,41 @@ const Sidebar: FC = () => {
|
|||||||
navigate(path)
|
navigate(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderMainMenus = () => {
|
||||||
|
return sidebarIcons.visible.map((icon) => {
|
||||||
|
const iconMap = {
|
||||||
|
assistants: <i className="iconfont icon-chat" />,
|
||||||
|
agents: <i className="iconfont icon-business-smart-assistant" />,
|
||||||
|
paintings: <PictureOutlined style={{ fontSize: 16 }} />,
|
||||||
|
translate: <TranslationOutlined />,
|
||||||
|
minapp: <i className="iconfont icon-appstore" />,
|
||||||
|
knowledge: <FileSearchOutlined />,
|
||||||
|
files: <FolderOutlined />
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathMap = {
|
||||||
|
assistants: '/',
|
||||||
|
agents: '/agents',
|
||||||
|
paintings: '/paintings',
|
||||||
|
translate: '/translate',
|
||||||
|
minapp: '/apps',
|
||||||
|
knowledge: '/knowledge',
|
||||||
|
files: '/files'
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = pathMap[icon]
|
||||||
|
const isActive = path === '/' ? isRoute(path) : isRoutes(path)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip key={icon} title={t(`${icon}.title`)} mouseEnterDelay={0.8} placement="right">
|
||||||
|
<StyledLink onClick={() => to(path)}>
|
||||||
|
<Icon className={isActive}>{iconMap[icon]}</Icon>
|
||||||
|
</StyledLink>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
id="app-sidebar"
|
id="app-sidebar"
|
||||||
@ -47,67 +81,7 @@ const Sidebar: FC = () => {
|
|||||||
}}>
|
}}>
|
||||||
<AvatarImg src={avatar || UserAvatar} draggable={false} className="nodrag" onClick={onEditUser} />
|
<AvatarImg src={avatar || UserAvatar} draggable={false} className="nodrag" onClick={onEditUser} />
|
||||||
<MainMenus>
|
<MainMenus>
|
||||||
<Menus onClick={MinApp.onClose}>
|
<Menus onClick={MinApp.onClose}>{renderMainMenus()}</Menus>
|
||||||
<Tooltip title={t('assistants.title')} mouseEnterDelay={0.8} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/')}>
|
|
||||||
<Icon className={isRoute('/')}>
|
|
||||||
<i className="iconfont icon-chat" />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip title={t('agents.title')} mouseEnterDelay={0.8} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/agents')}>
|
|
||||||
<Icon className={isRoutes('/agents')}>
|
|
||||||
<i className="iconfont icon-business-smart-assistant" />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
{showPaintingIcon && (
|
|
||||||
<Tooltip title={t('paintings.title')} mouseEnterDelay={0.8} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/paintings')}>
|
|
||||||
<Icon className={isRoute('/paintings')}>
|
|
||||||
<PictureOutlined style={{ fontSize: 16 }} />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
{showTranslateIcon && (
|
|
||||||
<Tooltip title={t('translate.title')} mouseEnterDelay={0.8} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/translate')}>
|
|
||||||
<Icon className={isRoute('/translate')}>
|
|
||||||
<TranslationOutlined />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
{showMinappIcon && (
|
|
||||||
<Tooltip title={t('minapp.title')} mouseEnterDelay={0.8} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/apps')}>
|
|
||||||
<Icon className={isRoute('/apps')}>
|
|
||||||
<i className="iconfont icon-appstore" />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
{showKnowledgeIcon && (
|
|
||||||
<Tooltip title={t('knowledge_base.title')} mouseEnterDelay={0.5} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/knowledge')}>
|
|
||||||
<Icon className={isRoute('/knowledge')}>
|
|
||||||
<FileSearchOutlined />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
{showFilesIcon && (
|
|
||||||
<Tooltip title={t('files.title')} mouseEnterDelay={0.8} placement="right">
|
|
||||||
<StyledLink onClick={() => to('/files')}>
|
|
||||||
<Icon className={isRoute('/files')}>
|
|
||||||
<FolderOutlined />
|
|
||||||
</Icon>
|
|
||||||
</StyledLink>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</Menus>
|
|
||||||
</MainMenus>
|
</MainMenus>
|
||||||
<Menus onClick={MinApp.onClose}>
|
<Menus onClick={MinApp.onClose}>
|
||||||
<Tooltip title={t('settings.theme.title')} mouseEnterDelay={0.8} placement="right">
|
<Tooltip title={t('settings.theme.title')} mouseEnterDelay={0.8} placement="right">
|
||||||
|
|||||||
@ -401,6 +401,10 @@
|
|||||||
"display.sidebar.knowledge.icon": "Show Knowledge icon",
|
"display.sidebar.knowledge.icon": "Show Knowledge icon",
|
||||||
"display.sidebar.files.icon": "Show Files icon",
|
"display.sidebar.files.icon": "Show Files icon",
|
||||||
"display.sidebar.title": "Sidebar Settings",
|
"display.sidebar.title": "Sidebar Settings",
|
||||||
|
"display.sidebar.visible": "Show my sidebar icons",
|
||||||
|
"display.sidebar.disabled": "Hide my sidebar icons",
|
||||||
|
"display.sidebar.chat.hiddenMessage": "Assistants are basic functions, not supported for hiding",
|
||||||
|
"display.sidebar.empty": "Drag the hidden feature from the left side here",
|
||||||
"display.topic.title": "Topic Settings",
|
"display.topic.title": "Topic Settings",
|
||||||
"display.custom.css": "Custom CSS",
|
"display.custom.css": "Custom CSS",
|
||||||
"display.custom.css.placeholder": "/* Put custom CSS here */",
|
"display.custom.css.placeholder": "/* Put custom CSS here */",
|
||||||
@ -411,7 +415,7 @@
|
|||||||
"messages.input.show_estimated_tokens": "Show estimated tokens",
|
"messages.input.show_estimated_tokens": "Show estimated tokens",
|
||||||
"messages.metrics": "{{time_first_token_millsec}}ms to first token | {{token_speed}} tok/sec",
|
"messages.metrics": "{{time_first_token_millsec}}ms to first token | {{token_speed}} tok/sec",
|
||||||
"messages.input.title": "Input Settings",
|
"messages.input.title": "Input Settings",
|
||||||
"messages.markdown_rendering_input_message": "Markdown render input msg",
|
"messages.markdown_rendering_input_message": "Markdown render input message",
|
||||||
"messages.math_engine": "Math render engine",
|
"messages.math_engine": "Math render engine",
|
||||||
"messages.model.title": "Model Settings",
|
"messages.model.title": "Model Settings",
|
||||||
"messages.title": "Message Settings",
|
"messages.title": "Message Settings",
|
||||||
@ -547,7 +551,7 @@
|
|||||||
"show_window": "Show Window",
|
"show_window": "Show Window",
|
||||||
"quit": "Quit"
|
"quit": "Quit"
|
||||||
},
|
},
|
||||||
"knowledge_base": {
|
"knowledge": {
|
||||||
"title": "Knowledge Base",
|
"title": "Knowledge Base",
|
||||||
"search": "Search knowledge base",
|
"search": "Search knowledge base",
|
||||||
"empty": "No knowledge base found",
|
"empty": "No knowledge base found",
|
||||||
|
|||||||
@ -399,6 +399,10 @@
|
|||||||
"display.sidebar.knowledge.icon": "ナレッジのアイコンを表示",
|
"display.sidebar.knowledge.icon": "ナレッジのアイコンを表示",
|
||||||
"display.sidebar.files.icon": "ファイルのアイコンを表示",
|
"display.sidebar.files.icon": "ファイルのアイコンを表示",
|
||||||
"display.sidebar.title": "サイドバー設定",
|
"display.sidebar.title": "サイドバー設定",
|
||||||
|
"display.sidebar.visible": "サイドバーのアイコンを表示する",
|
||||||
|
"display.sidebar.disabled": "サイドバーのアイコンを非表示にする",
|
||||||
|
"display.sidebar.chat.hiddenMessage": "アシスタントは基本的な機能であり、非表示はサポートされていません",
|
||||||
|
"display.sidebar.empty": "非表示にする機能を左側からここにドラッグ",
|
||||||
"display.topic.title": "トピック設定",
|
"display.topic.title": "トピック設定",
|
||||||
"display.custom.css": "カスタムCSS",
|
"display.custom.css": "カスタムCSS",
|
||||||
"display.custom.css.placeholder": "/* ここにカスタムCSSを入力 */",
|
"display.custom.css.placeholder": "/* ここにカスタムCSSを入力 */",
|
||||||
@ -533,7 +537,7 @@
|
|||||||
"show_window": "ウィンドウを表示",
|
"show_window": "ウィンドウを表示",
|
||||||
"quit": "終了"
|
"quit": "終了"
|
||||||
},
|
},
|
||||||
"knowledge_base": {
|
"knowledge": {
|
||||||
"title": "ナレッジベース",
|
"title": "ナレッジベース",
|
||||||
"search": "ナレッジベースを検索",
|
"search": "ナレッジベースを検索",
|
||||||
"empty": "ナレッジベースが見つかりません",
|
"empty": "ナレッジベースが見つかりません",
|
||||||
|
|||||||
@ -401,6 +401,10 @@
|
|||||||
"display.sidebar.knowledge.icon": "Показывать иконку знаний",
|
"display.sidebar.knowledge.icon": "Показывать иконку знаний",
|
||||||
"display.sidebar.files.icon": "Показывать иконку файлов",
|
"display.sidebar.files.icon": "Показывать иконку файлов",
|
||||||
"display.sidebar.title": "Настройки боковой панели",
|
"display.sidebar.title": "Настройки боковой панели",
|
||||||
|
"display.sidebar.visible": "Показать мои значки на боковой панели",
|
||||||
|
"display.sidebar.disabled": "Скрыть значок на боковой панели",
|
||||||
|
"display.sidebar.chat.hiddenMessage": "Помощник является базовой функцией и не поддерживает скрытие",
|
||||||
|
"display.sidebar.empty": "Перетащите скрываемую функцию с левой стороны сюда",
|
||||||
"display.topic.title": "Настройки топиков",
|
"display.topic.title": "Настройки топиков",
|
||||||
"display.custom.css": "Пользовательский CSS",
|
"display.custom.css": "Пользовательский CSS",
|
||||||
"display.custom.css.placeholder": "/* Здесь введите пользовательский CSS */",
|
"display.custom.css.placeholder": "/* Здесь введите пользовательский CSS */",
|
||||||
@ -547,7 +551,7 @@
|
|||||||
"show_window": "Показать окно",
|
"show_window": "Показать окно",
|
||||||
"quit": "Выйти"
|
"quit": "Выйти"
|
||||||
},
|
},
|
||||||
"knowledge_base": {
|
"knowledge": {
|
||||||
"title": "База знаний",
|
"title": "База знаний",
|
||||||
"search": "Поиск в базе знаний",
|
"search": "Поиск в базе знаний",
|
||||||
"empty": "База знаний не найдена",
|
"empty": "База знаний не найдена",
|
||||||
|
|||||||
@ -402,6 +402,10 @@
|
|||||||
"display.sidebar.knowledge.icon": "显示知识图标",
|
"display.sidebar.knowledge.icon": "显示知识图标",
|
||||||
"display.sidebar.files.icon": "显示文件图标",
|
"display.sidebar.files.icon": "显示文件图标",
|
||||||
"display.sidebar.title": "侧边栏设置",
|
"display.sidebar.title": "侧边栏设置",
|
||||||
|
"display.sidebar.visible": "显示我的侧边栏图标",
|
||||||
|
"display.sidebar.disabled": "隐藏我的侧边栏图标",
|
||||||
|
"display.sidebar.chat.hiddenMessage": "助手是基础功能,不支持隐藏",
|
||||||
|
"display.sidebar.empty": "把要隐藏的功能从左侧拖拽到这里",
|
||||||
"display.topic.title": "话题设置",
|
"display.topic.title": "话题设置",
|
||||||
"display.custom.css": "自定义 CSS",
|
"display.custom.css": "自定义 CSS",
|
||||||
"display.custom.css.placeholder": "/* 这里写自定义CSS */",
|
"display.custom.css.placeholder": "/* 这里写自定义CSS */",
|
||||||
@ -536,7 +540,7 @@
|
|||||||
"show_window": "显示窗口",
|
"show_window": "显示窗口",
|
||||||
"quit": "退出"
|
"quit": "退出"
|
||||||
},
|
},
|
||||||
"knowledge_base": {
|
"knowledge": {
|
||||||
"title": "知识库",
|
"title": "知识库",
|
||||||
"search": "搜索知识库",
|
"search": "搜索知识库",
|
||||||
"empty": "暂无知识库",
|
"empty": "暂无知识库",
|
||||||
|
|||||||
@ -402,6 +402,10 @@
|
|||||||
"display.sidebar.files.icon": "顯示文件圖示",
|
"display.sidebar.files.icon": "顯示文件圖示",
|
||||||
"display.sidebar.title": "側邊欄設定",
|
"display.sidebar.title": "側邊欄設定",
|
||||||
"display.topic.title": "話題設定",
|
"display.topic.title": "話題設定",
|
||||||
|
"display.sidebar.chat.hiddenMessage": "助手是基礎功能,不支援隱藏",
|
||||||
|
"display.sidebar.empty": "把要隱藏的功能從左側拖拽到這裡",
|
||||||
|
"display.sidebar.visible": "顯示我的側邊欄圖標",
|
||||||
|
"display.sidebar.disabled": "隱藏我的側邊欄圖標",
|
||||||
"display.custom.css": "自定義 CSS",
|
"display.custom.css": "自定義 CSS",
|
||||||
"display.custom.css.placeholder": "/* 這裡寫自定義 CSS */",
|
"display.custom.css.placeholder": "/* 這裡寫自定義 CSS */",
|
||||||
"input.auto_translate_with_space": "快速敲擊3次空格翻譯",
|
"input.auto_translate_with_space": "快速敲擊3次空格翻譯",
|
||||||
@ -535,7 +539,7 @@
|
|||||||
"show_window": "顯示視窗",
|
"show_window": "顯示視窗",
|
||||||
"quit": "退出"
|
"quit": "退出"
|
||||||
},
|
},
|
||||||
"knowledge_base": {
|
"knowledge": {
|
||||||
"title": "知識庫",
|
"title": "知識庫",
|
||||||
"search": "搜尋知識庫",
|
"search": "搜尋知識庫",
|
||||||
"empty": "暫無知識庫",
|
"empty": "暫無知識庫",
|
||||||
|
|||||||
@ -63,7 +63,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic }) => {
|
|||||||
clickAssistantToShowTopic,
|
clickAssistantToShowTopic,
|
||||||
language,
|
language,
|
||||||
autoTranslateWithSpace,
|
autoTranslateWithSpace,
|
||||||
showKnowledgeIcon
|
sidebarIcons
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
const [expended, setExpend] = useState(false)
|
const [expended, setExpend] = useState(false)
|
||||||
const [estimateTokenCount, setEstimateTokenCount] = useState(0)
|
const [estimateTokenCount, setEstimateTokenCount] = useState(0)
|
||||||
@ -85,6 +85,8 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic }) => {
|
|||||||
const isVision = useMemo(() => isVisionModel(model), [model])
|
const isVision = useMemo(() => isVisionModel(model), [model])
|
||||||
const supportExts = useMemo(() => [...textExts, ...documentExts, ...(isVision ? imageExts : [])], [isVision])
|
const supportExts = useMemo(() => [...textExts, ...documentExts, ...(isVision ? imageExts : [])], [isVision])
|
||||||
|
|
||||||
|
const showKnowledgeIcon = sidebarIcons.visible.includes('knowledge')
|
||||||
|
|
||||||
const estimateTextTokens = useCallback(debounce(estimateTxtTokens, 1000), [])
|
const estimateTextTokens = useCallback(debounce(estimateTxtTokens, 1000), [])
|
||||||
const inputTokenCount = useMemo(
|
const inputTokenCount = useMemo(
|
||||||
() => (showInputEstimatedTokens ? estimateTextTokens(text) || 0 : 0),
|
() => (showInputEstimatedTokens ? estimateTextTokens(text) || 0 : 0),
|
||||||
|
|||||||
@ -27,7 +27,7 @@ const getAvatarSource = (isLocalAi: boolean, modelId: string | undefined) => {
|
|||||||
const MessageHeader: FC<Props> = memo(({ assistant, model, message }) => {
|
const MessageHeader: FC<Props> = memo(({ assistant, model, message }) => {
|
||||||
const avatar = useAvatar()
|
const avatar = useAvatar()
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const { userName, showMinappIcon } = useSettings()
|
const { userName, sidebarIcons } = useSettings()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { isBubbleStyle } = useMessageStyle()
|
const { isBubbleStyle } = useMessageStyle()
|
||||||
|
|
||||||
@ -40,6 +40,7 @@ const MessageHeader: FC<Props> = memo(({ assistant, model, message }) => {
|
|||||||
}, [message.modelId, message.role, model?.id, model?.name, t, userName])
|
}, [message.modelId, message.role, model?.id, model?.name, t, userName])
|
||||||
|
|
||||||
const isAssistantMessage = message.role === 'assistant'
|
const isAssistantMessage = message.role === 'assistant'
|
||||||
|
const showMinappIcon = sidebarIcons.visible.includes('minapp')
|
||||||
|
|
||||||
const avatarName = useMemo(() => firstLetter(assistant?.name).toUpperCase(), [assistant?.name])
|
const avatarName = useMemo(() => firstLetter(assistant?.name).toUpperCase(), [assistant?.name])
|
||||||
const username = useMemo(() => removeLeadingEmoji(getUserName()), [getUserName])
|
const username = useMemo(() => removeLeadingEmoji(getUserName()), [getUserName])
|
||||||
|
|||||||
@ -25,7 +25,7 @@ interface Props {
|
|||||||
const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
|
const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
|
||||||
const { assistant } = useAssistant(activeAssistant.id)
|
const { assistant } = useAssistant(activeAssistant.id)
|
||||||
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
||||||
const { topicPosition, showMinappIcon } = useSettings()
|
const { topicPosition, sidebarIcons } = useSettings()
|
||||||
const { showTopics, toggleShowTopics } = useShowTopics()
|
const { showTopics, toggleShowTopics } = useShowTopics()
|
||||||
|
|
||||||
useShortcut('toggle_show_assistants', () => {
|
useShortcut('toggle_show_assistants', () => {
|
||||||
@ -79,7 +79,7 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
|
|||||||
<NavbarIcon onClick={() => SearchPopup.show()}>
|
<NavbarIcon onClick={() => SearchPopup.show()}>
|
||||||
<SearchOutlined />
|
<SearchOutlined />
|
||||||
</NavbarIcon>
|
</NavbarIcon>
|
||||||
{showMinappIcon && (
|
{sidebarIcons.visible.includes('minapp') && (
|
||||||
<AppStorePopover>
|
<AppStorePopover>
|
||||||
<NavbarIcon style={{ marginLeft: isMac ? 5 : 10 }}>
|
<NavbarIcon style={{ marginLeft: isMac ? 5 : 10 }}>
|
||||||
<i className="iconfont icon-appstore" />
|
<i className="iconfont icon-appstore" />
|
||||||
|
|||||||
@ -126,9 +126,9 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const url = await PromptPopup.show({
|
const url = await PromptPopup.show({
|
||||||
title: t('knowledge_base.add_url'),
|
title: t('knowledge.add_url'),
|
||||||
message: '',
|
message: '',
|
||||||
inputPlaceholder: t('knowledge_base.url_placeholder'),
|
inputPlaceholder: t('knowledge.url_placeholder'),
|
||||||
inputProps: {
|
inputProps: {
|
||||||
maxLength: 1000,
|
maxLength: 1000,
|
||||||
rows: 1
|
rows: 1
|
||||||
@ -139,7 +139,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
try {
|
try {
|
||||||
new URL(url)
|
new URL(url)
|
||||||
if (urlItems.find((item) => item.content === url)) {
|
if (urlItems.find((item) => item.content === url)) {
|
||||||
message.success(t('knowledge_base.url_added'))
|
message.success(t('knowledge.url_added'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addUrl(url)
|
addUrl(url)
|
||||||
@ -155,9 +155,9 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const url = await PromptPopup.show({
|
const url = await PromptPopup.show({
|
||||||
title: t('knowledge_base.add_sitemap'),
|
title: t('knowledge.add_sitemap'),
|
||||||
message: '',
|
message: '',
|
||||||
inputPlaceholder: t('knowledge_base.sitemap_placeholder'),
|
inputPlaceholder: t('knowledge.sitemap_placeholder'),
|
||||||
inputProps: {
|
inputProps: {
|
||||||
maxLength: 1000,
|
maxLength: 1000,
|
||||||
rows: 1
|
rows: 1
|
||||||
@ -168,7 +168,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
try {
|
try {
|
||||||
new URL(url)
|
new URL(url)
|
||||||
if (sitemapItems.find((item) => item.content === url)) {
|
if (sitemapItems.find((item) => item.content === url)) {
|
||||||
message.success(t('knowledge_base.sitemap_added'))
|
message.success(t('knowledge.sitemap_added'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addSitemap(url)
|
addSitemap(url)
|
||||||
@ -209,16 +209,16 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
return (
|
return (
|
||||||
<MainContent>
|
<MainContent>
|
||||||
{!base?.version && (
|
{!base?.version && (
|
||||||
<Alert message={t('knowledge_base.not_support')} type="error" style={{ marginBottom: 20 }} showIcon />
|
<Alert message={t('knowledge.not_support')} type="error" style={{ marginBottom: 20 }} showIcon />
|
||||||
)}
|
)}
|
||||||
{!providerName && (
|
{!providerName && (
|
||||||
<Alert message={t('knowledge_base.no_provider')} type="error" style={{ marginBottom: 20 }} showIcon />
|
<Alert message={t('knowledge.no_provider')} type="error" style={{ marginBottom: 20 }} showIcon />
|
||||||
)}
|
)}
|
||||||
<FileSection>
|
<FileSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('files.title')}</Title>
|
<Title level={5}>{t('files.title')}</Title>
|
||||||
<Button icon={<PlusOutlined />} onClick={handleAddFile} disabled={disabled}>
|
<Button icon={<PlusOutlined />} onClick={handleAddFile} disabled={disabled}>
|
||||||
{t('knowledge_base.add_file')}
|
{t('knowledge.add_file')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
<Dragger
|
<Dragger
|
||||||
@ -227,9 +227,9 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
multiple={true}
|
multiple={true}
|
||||||
accept={fileTypes.join(',')}
|
accept={fileTypes.join(',')}
|
||||||
style={{ marginTop: 10, background: 'transparent' }}>
|
style={{ marginTop: 10, background: 'transparent' }}>
|
||||||
<p className="ant-upload-text">{t('knowledge_base.drag_file')}</p>
|
<p className="ant-upload-text">{t('knowledge.drag_file')}</p>
|
||||||
<p className="ant-upload-hint">
|
<p className="ant-upload-hint">
|
||||||
{t('knowledge_base.file_hint', { file_types: fileTypes.join(', ').replaceAll('.', '') })}
|
{t('knowledge.file_hint', { file_types: fileTypes.join(', ').replaceAll('.', '') })}
|
||||||
</p>
|
</p>
|
||||||
</Dragger>
|
</Dragger>
|
||||||
</FileSection>
|
</FileSection>
|
||||||
@ -256,9 +256,9 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
|
|
||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.directories')}</Title>
|
<Title level={5}>{t('knowledge.directories')}</Title>
|
||||||
<Button icon={<PlusOutlined />} onClick={handleAddDirectory} disabled={disabled}>
|
<Button icon={<PlusOutlined />} onClick={handleAddDirectory} disabled={disabled}>
|
||||||
{t('knowledge_base.add_directory')}
|
{t('knowledge.add_directory')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
@ -283,9 +283,9 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
|
|
||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.urls')}</Title>
|
<Title level={5}>{t('knowledge.urls')}</Title>
|
||||||
<Button icon={<PlusOutlined />} onClick={handleAddUrl} disabled={disabled}>
|
<Button icon={<PlusOutlined />} onClick={handleAddUrl} disabled={disabled}>
|
||||||
{t('knowledge_base.add_url')}
|
{t('knowledge.add_url')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
@ -310,9 +310,9 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
|
|
||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.sitemaps')}</Title>
|
<Title level={5}>{t('knowledge.sitemaps')}</Title>
|
||||||
<Button icon={<PlusOutlined />} onClick={handleAddSitemap} disabled={disabled}>
|
<Button icon={<PlusOutlined />} onClick={handleAddSitemap} disabled={disabled}>
|
||||||
{t('knowledge_base.add_sitemap')}
|
{t('knowledge.add_sitemap')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
@ -337,9 +337,9 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
|
|
||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.notes')}</Title>
|
<Title level={5}>{t('knowledge.notes')}</Title>
|
||||||
<Button icon={<PlusOutlined />} onClick={handleAddNote} disabled={disabled}>
|
<Button icon={<PlusOutlined />} onClick={handleAddNote} disabled={disabled}>
|
||||||
{t('knowledge_base.add_note')}
|
{t('knowledge.add_note')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
@ -363,7 +363,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
<Divider style={{ margin: '10px 0' }} />
|
<Divider style={{ margin: '10px 0' }} />
|
||||||
|
|
||||||
<ModelInfo>
|
<ModelInfo>
|
||||||
<label htmlFor="model-info">{t('knowledge_base.model_info')}</label>
|
<label htmlFor="model-info">{t('knowledge.model_info')}</label>
|
||||||
<Tag color="blue">{base.model.name}</Tag>
|
<Tag color="blue">{base.model.name}</Tag>
|
||||||
<Tag color="cyan">{t('models.dimensions', { dimensions: base.dimensions || 0 })}</Tag>
|
<Tag color="cyan">{t('models.dimensions', { dimensions: base.dimensions || 0 })}</Tag>
|
||||||
{providerName && <Tag color="purple">{providerName}</Tag>}
|
{providerName && <Tag color="purple">{providerName}</Tag>}
|
||||||
@ -375,7 +375,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
onClick={() => KnowledgeSearchPopup.show({ base })}
|
onClick={() => KnowledgeSearchPopup.show({ base })}
|
||||||
icon={<SearchOutlined />}
|
icon={<SearchOutlined />}
|
||||||
disabled={disabled}>
|
disabled={disabled}>
|
||||||
{t('knowledge_base.search')}
|
{t('knowledge.search')}
|
||||||
</Button>
|
</Button>
|
||||||
</IndexSection>
|
</IndexSection>
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ const KnowledgePage: FC = () => {
|
|||||||
const prevLength = useRef(0)
|
const prevLength = useRef(0)
|
||||||
|
|
||||||
const handleAddKnowledge = async () => {
|
const handleAddKnowledge = async () => {
|
||||||
await AddKnowledgePopup.show({ title: t('knowledge_base.add.title') })
|
await AddKnowledgePopup.show({ title: t('knowledge.add.title') })
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -48,12 +48,12 @@ const KnowledgePage: FC = () => {
|
|||||||
(base: KnowledgeBase) => {
|
(base: KnowledgeBase) => {
|
||||||
const menus: MenuProps['items'] = [
|
const menus: MenuProps['items'] = [
|
||||||
{
|
{
|
||||||
label: t('knowledge_base.rename'),
|
label: t('knowledge.rename'),
|
||||||
key: 'rename',
|
key: 'rename',
|
||||||
icon: <EditOutlined />,
|
icon: <EditOutlined />,
|
||||||
async onClick() {
|
async onClick() {
|
||||||
const name = await PromptPopup.show({
|
const name = await PromptPopup.show({
|
||||||
title: t('knowledge_base.rename'),
|
title: t('knowledge.rename'),
|
||||||
message: '',
|
message: '',
|
||||||
defaultValue: base.name || ''
|
defaultValue: base.name || ''
|
||||||
})
|
})
|
||||||
@ -70,7 +70,7 @@ const KnowledgePage: FC = () => {
|
|||||||
icon: <DeleteOutlined />,
|
icon: <DeleteOutlined />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
window.modal.confirm({
|
window.modal.confirm({
|
||||||
title: t('knowledge_base.delete_confirm'),
|
title: t('knowledge.delete_confirm'),
|
||||||
centered: true,
|
centered: true,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
deleteKnowledgeBase(base.id)
|
deleteKnowledgeBase(base.id)
|
||||||
@ -88,7 +88,7 @@ const KnowledgePage: FC = () => {
|
|||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Navbar>
|
<Navbar>
|
||||||
<NavbarCenter style={{ borderRight: 'none' }}>{t('knowledge_base.title')}</NavbarCenter>
|
<NavbarCenter style={{ borderRight: 'none' }}>{t('knowledge.title')}</NavbarCenter>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
<ContentContainer id="content-container">
|
<ContentContainer id="content-container">
|
||||||
<SideNav>
|
<SideNav>
|
||||||
@ -125,7 +125,7 @@ const KnowledgePage: FC = () => {
|
|||||||
</SideNav>
|
</SideNav>
|
||||||
{bases.length === 0 ? (
|
{bases.length === 0 ? (
|
||||||
<MainContent>
|
<MainContent>
|
||||||
<Empty description={t('knowledge_base.empty')} image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
<Empty description={t('knowledge.empty')} image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
||||||
</MainContent>
|
</MainContent>
|
||||||
) : selectedBase ? (
|
) : selectedBase ? (
|
||||||
<KnowledgeContent selectedBase={selectedBase} />
|
<KnowledgeContent selectedBase={selectedBase} />
|
||||||
|
|||||||
@ -77,7 +77,7 @@ const PopupContainer: React.FC<Props> = ({ base, resolve }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={t('knowledge_base.search')}
|
title={t('knowledge.search')}
|
||||||
open={open}
|
open={open}
|
||||||
onOk={onOk}
|
onOk={onOk}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
@ -88,7 +88,7 @@ const PopupContainer: React.FC<Props> = ({ base, resolve }) => {
|
|||||||
transitionName="ant-move-down">
|
transitionName="ant-move-down">
|
||||||
<SearchContainer>
|
<SearchContainer>
|
||||||
<Search
|
<Search
|
||||||
placeholder={t('knowledge_base.search_placeholder')}
|
placeholder={t('knowledge.search_placeholder')}
|
||||||
allowClear
|
allowClear
|
||||||
enterButton
|
enterButton
|
||||||
size="large"
|
size="large"
|
||||||
@ -109,7 +109,7 @@ const PopupContainer: React.FC<Props> = ({ base, resolve }) => {
|
|||||||
<Paragraph>{highlightText(item.pageContent)}</Paragraph>
|
<Paragraph>{highlightText(item.pageContent)}</Paragraph>
|
||||||
<MetadataContainer>
|
<MetadataContainer>
|
||||||
<Text type="secondary">
|
<Text type="secondary">
|
||||||
{t('knowledge_base.source')}:{' '}
|
{t('knowledge.source')}:{' '}
|
||||||
{item.file ? (
|
{item.file ? (
|
||||||
<a href={`http://file/${item.file.name}`} target="_blank" rel="noreferrer">
|
<a href={`http://file/${item.file.name}`} target="_blank" rel="noreferrer">
|
||||||
{item.file.origin_name}
|
{item.file.origin_name}
|
||||||
|
|||||||
@ -21,13 +21,13 @@ const StatusIcon: FC<StatusIconProps> = ({ sourceId, base, getProcessingStatus }
|
|||||||
if (!status) {
|
if (!status) {
|
||||||
if (item?.uniqueId) {
|
if (item?.uniqueId) {
|
||||||
return (
|
return (
|
||||||
<Tooltip title={t('knowledge_base.status_completed')} placement="left">
|
<Tooltip title={t('knowledge.status_completed')} placement="left">
|
||||||
<CheckCircleOutlined style={{ color: '#52c41a' }} />
|
<CheckCircleOutlined style={{ color: '#52c41a' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Tooltip title={t('knowledge_base.status_new')} placement="left">
|
<Tooltip title={t('knowledge.status_new')} placement="left">
|
||||||
<Center style={{ width: '16px', height: '16px' }}>
|
<Center style={{ width: '16px', height: '16px' }}>
|
||||||
<StatusDot $status="new" />
|
<StatusDot $status="new" />
|
||||||
</Center>
|
</Center>
|
||||||
@ -38,25 +38,25 @@ const StatusIcon: FC<StatusIconProps> = ({ sourceId, base, getProcessingStatus }
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
case 'pending':
|
case 'pending':
|
||||||
return (
|
return (
|
||||||
<Tooltip title={t('knowledge_base.status_pending')} placement="left">
|
<Tooltip title={t('knowledge.status_pending')} placement="left">
|
||||||
<StatusDot $status="pending" />
|
<StatusDot $status="pending" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
case 'processing':
|
case 'processing':
|
||||||
return (
|
return (
|
||||||
<Tooltip title={t('knowledge_base.status_processing')} placement="left">
|
<Tooltip title={t('knowledge.status_processing')} placement="left">
|
||||||
<StatusDot $status="processing" />
|
<StatusDot $status="processing" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
case 'completed':
|
case 'completed':
|
||||||
return (
|
return (
|
||||||
<Tooltip title={t('knowledge_base.status_completed')} placement="left">
|
<Tooltip title={t('knowledge.status_completed')} placement="left">
|
||||||
<CheckCircleOutlined style={{ color: '#52c41a' }} />
|
<CheckCircleOutlined style={{ color: '#52c41a' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
case 'failed':
|
case 'failed':
|
||||||
return (
|
return (
|
||||||
<Tooltip title={errorText || t('knowledge_base.status_failed')} placement="left">
|
<Tooltip title={errorText || t('knowledge.status_failed')} placement="left">
|
||||||
<CloseCircleOutlined style={{ color: '#ff4d4f' }} />
|
<CloseCircleOutlined style={{ color: '#ff4d4f' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -3,21 +3,20 @@ import { useTheme } from '@renderer/context/ThemeProvider'
|
|||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
import { useAppDispatch } from '@renderer/store'
|
import { useAppDispatch } from '@renderer/store'
|
||||||
import {
|
import {
|
||||||
|
DEFAULT_SIDEBAR_ICONS,
|
||||||
setClickAssistantToShowTopic,
|
setClickAssistantToShowTopic,
|
||||||
setCustomCss,
|
setCustomCss,
|
||||||
setShowFilesIcon,
|
|
||||||
setShowKnowledgeIcon,
|
|
||||||
setShowMinappIcon,
|
|
||||||
setShowPaintingIcon,
|
|
||||||
setShowTopicTime,
|
setShowTopicTime,
|
||||||
setShowTranslateIcon
|
setSidebarIcons
|
||||||
} from '@renderer/store/settings'
|
} from '@renderer/store/settings'
|
||||||
import { ThemeMode } from '@renderer/types'
|
import { ThemeMode } from '@renderer/types'
|
||||||
import { Input, Select, Switch } from 'antd'
|
import { Button, Input, Select, Switch } from 'antd'
|
||||||
import { FC } from 'react'
|
import { FC, useCallback, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '.'
|
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..'
|
||||||
|
import SidebarIconsManager from './SidebarIconsManager'
|
||||||
|
|
||||||
const DisplaySettings: FC = () => {
|
const DisplaySettings: FC = () => {
|
||||||
const {
|
const {
|
||||||
@ -25,25 +24,33 @@ const DisplaySettings: FC = () => {
|
|||||||
theme,
|
theme,
|
||||||
windowStyle,
|
windowStyle,
|
||||||
setWindowStyle,
|
setWindowStyle,
|
||||||
showTranslateIcon,
|
|
||||||
showPaintingIcon,
|
|
||||||
showMinappIcon,
|
|
||||||
showKnowledgeIcon,
|
|
||||||
showFilesIcon,
|
|
||||||
topicPosition,
|
topicPosition,
|
||||||
setTopicPosition,
|
setTopicPosition,
|
||||||
clickAssistantToShowTopic,
|
clickAssistantToShowTopic,
|
||||||
showTopicTime,
|
showTopicTime,
|
||||||
customCss
|
customCss,
|
||||||
|
sidebarIcons
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
const { theme: themeMode } = useTheme()
|
const { theme: themeMode } = useTheme()
|
||||||
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
const handleWindowStyleChange = (checked: boolean) => {
|
const [visibleIcons, setVisibleIcons] = useState(sidebarIcons?.visible || DEFAULT_SIDEBAR_ICONS)
|
||||||
setWindowStyle(checked ? 'transparent' : 'opaque')
|
const [disabledIcons, setDisabledIcons] = useState(sidebarIcons?.disabled || [])
|
||||||
}
|
|
||||||
|
// 使用useCallback优化回调函数
|
||||||
|
const handleWindowStyleChange = useCallback(
|
||||||
|
(checked: boolean) => {
|
||||||
|
setWindowStyle(checked ? 'transparent' : 'opaque')
|
||||||
|
},
|
||||||
|
[setWindowStyle]
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleReset = useCallback(() => {
|
||||||
|
setVisibleIcons([...DEFAULT_SIDEBAR_ICONS])
|
||||||
|
setDisabledIcons([])
|
||||||
|
dispatch(setSidebarIcons({ visible: DEFAULT_SIDEBAR_ICONS, disabled: [] }))
|
||||||
|
}, [dispatch])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingContainer theme={themeMode}>
|
<SettingContainer theme={themeMode}>
|
||||||
@ -53,7 +60,7 @@ const DisplaySettings: FC = () => {
|
|||||||
<SettingRow>
|
<SettingRow>
|
||||||
<SettingRowTitle>{t('settings.theme.title')}</SettingRowTitle>
|
<SettingRowTitle>{t('settings.theme.title')}</SettingRowTitle>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={theme}
|
value={theme}
|
||||||
style={{ width: 120 }}
|
style={{ width: 120 }}
|
||||||
onChange={setTheme}
|
onChange={setTheme}
|
||||||
options={[
|
options={[
|
||||||
@ -79,7 +86,7 @@ const DisplaySettings: FC = () => {
|
|||||||
<SettingRow>
|
<SettingRow>
|
||||||
<SettingRowTitle>{t('settings.topic.position')}</SettingRowTitle>
|
<SettingRowTitle>{t('settings.topic.position')}</SettingRowTitle>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={topicPosition || 'right'}
|
value={topicPosition || 'right'}
|
||||||
style={{ width: 120 }}
|
style={{ width: 120 }}
|
||||||
onChange={setTopicPosition}
|
onChange={setTopicPosition}
|
||||||
options={[
|
options={[
|
||||||
@ -107,39 +114,27 @@ const DisplaySettings: FC = () => {
|
|||||||
</SettingRow>
|
</SettingRow>
|
||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
<SettingGroup theme={theme}>
|
<SettingGroup theme={theme}>
|
||||||
<SettingTitle>{t('settings.display.sidebar.title')}</SettingTitle>
|
<SettingTitle
|
||||||
|
style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
|
<span>{t('settings.display.sidebar.title')}</span>
|
||||||
|
<ResetButtonWrapper>
|
||||||
|
<Button onClick={handleReset}>{t('common.reset')}</Button>
|
||||||
|
</ResetButtonWrapper>
|
||||||
|
</SettingTitle>
|
||||||
<SettingDivider />
|
<SettingDivider />
|
||||||
<SettingRow>
|
<SidebarIconsManager
|
||||||
<SettingRowTitle>{t('settings.display.sidebar.translate.icon')}</SettingRowTitle>
|
visibleIcons={visibleIcons}
|
||||||
<Switch checked={showTranslateIcon} onChange={(value) => dispatch(setShowTranslateIcon(value))} />
|
disabledIcons={disabledIcons}
|
||||||
</SettingRow>
|
setVisibleIcons={setVisibleIcons}
|
||||||
<SettingDivider />
|
setDisabledIcons={setDisabledIcons}
|
||||||
<SettingRow>
|
/>
|
||||||
<SettingRowTitle>{t('settings.display.sidebar.painting.icon')}</SettingRowTitle>
|
|
||||||
<Switch checked={showPaintingIcon} onChange={(value) => dispatch(setShowPaintingIcon(value))} />
|
|
||||||
</SettingRow>
|
|
||||||
<SettingDivider />
|
|
||||||
<SettingRow>
|
|
||||||
<SettingRowTitle>{t('settings.display.sidebar.minapp.icon')}</SettingRowTitle>
|
|
||||||
<Switch checked={showMinappIcon} onChange={(value) => dispatch(setShowMinappIcon(value))} />
|
|
||||||
</SettingRow>
|
|
||||||
<SettingDivider />
|
|
||||||
<SettingRow>
|
|
||||||
<SettingRowTitle>{t('settings.display.sidebar.knowledge.icon')}</SettingRowTitle>
|
|
||||||
<Switch checked={showKnowledgeIcon} onChange={(value) => dispatch(setShowKnowledgeIcon(value))} />
|
|
||||||
</SettingRow>
|
|
||||||
<SettingDivider />
|
|
||||||
<SettingRow>
|
|
||||||
<SettingRowTitle>{t('settings.display.sidebar.files.icon')}</SettingRowTitle>
|
|
||||||
<Switch checked={showFilesIcon} onChange={(value) => dispatch(setShowFilesIcon(value))} />
|
|
||||||
</SettingRow>
|
|
||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
<SettingGroup theme={theme}>
|
<SettingGroup theme={theme}>
|
||||||
<SettingTitle>{t('settings.display.custom.css')}</SettingTitle>
|
<SettingTitle>{t('settings.display.custom.css')}</SettingTitle>
|
||||||
<SettingDivider />
|
<SettingDivider />
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
defaultValue={customCss}
|
value={customCss}
|
||||||
onBlur={(e) => dispatch(setCustomCss(e.target.value))}
|
onChange={(e) => dispatch(setCustomCss(e.target.value))}
|
||||||
placeholder={t('settings.display.custom.css.placeholder')}
|
placeholder={t('settings.display.custom.css.placeholder')}
|
||||||
style={{
|
style={{
|
||||||
minHeight: 200,
|
minHeight: 200,
|
||||||
@ -151,4 +146,10 @@ const DisplaySettings: FC = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ResetButtonWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
`
|
||||||
|
|
||||||
export default DisplaySettings
|
export default DisplaySettings
|
||||||
@ -0,0 +1,272 @@
|
|||||||
|
import { CloseOutlined } from '@ant-design/icons'
|
||||||
|
import { FileSearchOutlined, FolderOutlined, PictureOutlined, TranslationOutlined } from '@ant-design/icons'
|
||||||
|
import {
|
||||||
|
DragDropContext,
|
||||||
|
Draggable,
|
||||||
|
DraggableProvided,
|
||||||
|
Droppable,
|
||||||
|
DroppableProvided,
|
||||||
|
DropResult
|
||||||
|
} from '@hello-pangea/dnd'
|
||||||
|
import { useAppDispatch } from '@renderer/store'
|
||||||
|
import { setSidebarIcons } from '@renderer/store/settings'
|
||||||
|
import { message } from 'antd'
|
||||||
|
import { FC, useCallback, useMemo } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
import { SidebarIcon } from '../../../store/settings'
|
||||||
|
|
||||||
|
interface SidebarIconsManagerProps {
|
||||||
|
visibleIcons: SidebarIcon[]
|
||||||
|
disabledIcons: SidebarIcon[]
|
||||||
|
setVisibleIcons: (icons: SidebarIcon[]) => void
|
||||||
|
setDisabledIcons: (icons: SidebarIcon[]) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const SidebarIconsManager: FC<SidebarIconsManagerProps> = ({
|
||||||
|
visibleIcons,
|
||||||
|
disabledIcons,
|
||||||
|
setVisibleIcons,
|
||||||
|
setDisabledIcons
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
|
const onDragEnd = useCallback(
|
||||||
|
(result: DropResult) => {
|
||||||
|
if (!result.destination) return
|
||||||
|
|
||||||
|
const { source, destination } = result
|
||||||
|
|
||||||
|
// 如果是chat图标且目标是disabled区域,则不允许移动并提示
|
||||||
|
const draggedItem = source.droppableId === 'visible' ? visibleIcons[source.index] : disabledIcons[source.index]
|
||||||
|
if (draggedItem === 'assistants' && destination.droppableId === 'disabled') {
|
||||||
|
message.warning(t('settings.display.sidebar.chat.hiddenMessage'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source.droppableId === destination.droppableId) {
|
||||||
|
const list = source.droppableId === 'visible' ? [...visibleIcons] : [...disabledIcons]
|
||||||
|
const [removed] = list.splice(source.index, 1)
|
||||||
|
list.splice(destination.index, 0, removed)
|
||||||
|
|
||||||
|
if (source.droppableId === 'visible') {
|
||||||
|
setVisibleIcons(list)
|
||||||
|
dispatch(setSidebarIcons({ visible: list, disabled: disabledIcons }))
|
||||||
|
} else {
|
||||||
|
setDisabledIcons(list)
|
||||||
|
dispatch(setSidebarIcons({ visible: visibleIcons, disabled: list }))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const sourceList = source.droppableId === 'visible' ? [...visibleIcons] : [...disabledIcons]
|
||||||
|
const destList = destination.droppableId === 'visible' ? [...visibleIcons] : [...disabledIcons]
|
||||||
|
|
||||||
|
const [removed] = sourceList.splice(source.index, 1)
|
||||||
|
const targetList = destList.filter((icon) => icon !== removed)
|
||||||
|
targetList.splice(destination.index, 0, removed)
|
||||||
|
|
||||||
|
const newVisibleIcons = destination.droppableId === 'visible' ? targetList : sourceList
|
||||||
|
const newDisabledIcons = destination.droppableId === 'disabled' ? targetList : sourceList
|
||||||
|
|
||||||
|
setVisibleIcons(newVisibleIcons)
|
||||||
|
setDisabledIcons(newDisabledIcons)
|
||||||
|
dispatch(setSidebarIcons({ visible: newVisibleIcons, disabled: newDisabledIcons }))
|
||||||
|
},
|
||||||
|
[visibleIcons, disabledIcons, dispatch, setVisibleIcons, setDisabledIcons, t]
|
||||||
|
)
|
||||||
|
|
||||||
|
const onMoveIcon = useCallback(
|
||||||
|
(icon: SidebarIcon, fromList: 'visible' | 'disabled') => {
|
||||||
|
// 如果是chat图标且要移动到disabled列表,则不允许并提示
|
||||||
|
if (icon === 'assistants' && fromList === 'visible') {
|
||||||
|
message.warning(t('settings.display.sidebar.chat.hiddenMessage'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromList === 'visible') {
|
||||||
|
const newVisibleIcons = visibleIcons.filter((i) => i !== icon)
|
||||||
|
const newDisabledIcons = disabledIcons.some((i) => i === icon) ? disabledIcons : [...disabledIcons, icon]
|
||||||
|
|
||||||
|
setVisibleIcons(newVisibleIcons)
|
||||||
|
setDisabledIcons(newDisabledIcons)
|
||||||
|
dispatch(setSidebarIcons({ visible: newVisibleIcons, disabled: newDisabledIcons }))
|
||||||
|
} else {
|
||||||
|
const newDisabledIcons = disabledIcons.filter((i) => i !== icon)
|
||||||
|
const newVisibleIcons = visibleIcons.some((i) => i === icon) ? visibleIcons : [...visibleIcons, icon]
|
||||||
|
|
||||||
|
setDisabledIcons(newDisabledIcons)
|
||||||
|
setVisibleIcons(newVisibleIcons)
|
||||||
|
dispatch(setSidebarIcons({ visible: newVisibleIcons, disabled: newDisabledIcons }))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[t, visibleIcons, disabledIcons, setVisibleIcons, setDisabledIcons, dispatch]
|
||||||
|
)
|
||||||
|
|
||||||
|
// 使用useMemo缓存图标映射
|
||||||
|
const iconMap = useMemo(
|
||||||
|
() => ({
|
||||||
|
assistants: <i className="iconfont icon-chat" />,
|
||||||
|
agents: <i className="iconfont icon-business-smart-assistant" />,
|
||||||
|
paintings: <PictureOutlined style={{ fontSize: 14 }} />,
|
||||||
|
translate: <TranslationOutlined />,
|
||||||
|
minapp: <i className="iconfont icon-appstore" />,
|
||||||
|
knowledge: <FileSearchOutlined />,
|
||||||
|
files: <FolderOutlined />
|
||||||
|
}),
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
const renderIcon = (icon: SidebarIcon) => iconMap[icon] || <i className={`iconfont ${icon}`} />
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
|
<IconSection>
|
||||||
|
<IconColumn>
|
||||||
|
<h4>{t('settings.display.sidebar.visible')}</h4>
|
||||||
|
<Droppable droppableId="visible">
|
||||||
|
{(provided: DroppableProvided) => (
|
||||||
|
<IconList ref={provided.innerRef} {...provided.droppableProps}>
|
||||||
|
{visibleIcons.map((icon, index) => (
|
||||||
|
<Draggable key={icon} draggableId={icon} index={index}>
|
||||||
|
{(provided: DraggableProvided) => (
|
||||||
|
<IconItem ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
||||||
|
<IconContent>
|
||||||
|
{renderIcon(icon)}
|
||||||
|
<span>{t(`${icon}.title`)}</span>
|
||||||
|
</IconContent>
|
||||||
|
{icon !== 'assistants' && (
|
||||||
|
<CloseButton onClick={() => onMoveIcon(icon, 'visible')}>
|
||||||
|
<CloseOutlined />
|
||||||
|
</CloseButton>
|
||||||
|
)}
|
||||||
|
</IconItem>
|
||||||
|
)}
|
||||||
|
</Draggable>
|
||||||
|
))}
|
||||||
|
{provided.placeholder}
|
||||||
|
</IconList>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</IconColumn>
|
||||||
|
<IconColumn>
|
||||||
|
<h4>{t('settings.display.sidebar.disabled')}</h4>
|
||||||
|
<Droppable droppableId="disabled">
|
||||||
|
{(provided: DroppableProvided) => (
|
||||||
|
<IconList ref={provided.innerRef} {...provided.droppableProps}>
|
||||||
|
{disabledIcons.length === 0 ? (
|
||||||
|
<EmptyPlaceholder>{t('settings.display.sidebar.empty')}</EmptyPlaceholder>
|
||||||
|
) : (
|
||||||
|
disabledIcons.map((icon, index) => (
|
||||||
|
<Draggable key={icon} draggableId={icon} index={index}>
|
||||||
|
{(provided: DraggableProvided) => (
|
||||||
|
<IconItem ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
||||||
|
<IconContent>
|
||||||
|
{renderIcon(icon)}
|
||||||
|
<span>{t(`${icon}.title`)}</span>
|
||||||
|
</IconContent>
|
||||||
|
<CloseButton onClick={() => onMoveIcon(icon, 'disabled')}>
|
||||||
|
<CloseOutlined />
|
||||||
|
</CloseButton>
|
||||||
|
</IconItem>
|
||||||
|
)}
|
||||||
|
</Draggable>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
{provided.placeholder}
|
||||||
|
</IconList>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</IconColumn>
|
||||||
|
</IconSection>
|
||||||
|
</DragDropContext>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Styled components remain the same
|
||||||
|
const IconSection = styled.div`
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
background: var(--color-background);
|
||||||
|
`
|
||||||
|
|
||||||
|
const IconColumn = styled.div`
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: var(--color-text);
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const IconList = styled.div`
|
||||||
|
height: 365px;
|
||||||
|
min-height: 365px;
|
||||||
|
padding: 10px;
|
||||||
|
background: var(--color-background-soft);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: hidden;
|
||||||
|
`
|
||||||
|
|
||||||
|
const IconItem = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 12px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
background: var(--color-background);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: move;
|
||||||
|
`
|
||||||
|
|
||||||
|
const IconContent = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const CloseButton = styled.div`
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--color-text-2);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
${IconItem}:hover & {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const EmptyPlaceholder = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--color-text-2);
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export default SidebarIconsManager
|
||||||
@ -15,7 +15,7 @@ import styled from 'styled-components'
|
|||||||
|
|
||||||
import AboutSettings from './AboutSettings'
|
import AboutSettings from './AboutSettings'
|
||||||
import DataSettings from './DataSettings/DataSettings'
|
import DataSettings from './DataSettings/DataSettings'
|
||||||
import DisplaySettings from './DisplaySettings'
|
import DisplaySettings from './DisplaySettings/DisplaySettings'
|
||||||
import GeneralSettings from './GeneralSettings'
|
import GeneralSettings from './GeneralSettings'
|
||||||
import ModelSettings from './ModalSettings/ModelSettings'
|
import ModelSettings from './ModalSettings/ModelSettings'
|
||||||
import ProvidersList from './ProviderSettings'
|
import ProvidersList from './ProviderSettings'
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const persistedReducer = persistReducer(
|
|||||||
{
|
{
|
||||||
key: 'cherry-studio',
|
key: 'cherry-studio',
|
||||||
storage,
|
storage,
|
||||||
version: 52,
|
version: 54,
|
||||||
blacklist: ['runtime'],
|
blacklist: ['runtime'],
|
||||||
migrate
|
migrate
|
||||||
},
|
},
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { isEmpty } from 'lodash'
|
|||||||
import { createMigrate } from 'redux-persist'
|
import { createMigrate } from 'redux-persist'
|
||||||
|
|
||||||
import { RootState } from '.'
|
import { RootState } from '.'
|
||||||
|
import { DEFAULT_SIDEBAR_ICONS } from './settings'
|
||||||
|
|
||||||
const migrateConfig = {
|
const migrateConfig = {
|
||||||
'2': (state: RootState) => {
|
'2': (state: RootState) => {
|
||||||
@ -742,8 +743,6 @@ const migrateConfig = {
|
|||||||
return state
|
return state
|
||||||
},
|
},
|
||||||
'49': (state: RootState) => {
|
'49': (state: RootState) => {
|
||||||
state.settings.showMinappIcon = true
|
|
||||||
state.settings.showFilesIcon = true
|
|
||||||
state.settings.pasteLongTextThreshold = 1500
|
state.settings.pasteLongTextThreshold = 1500
|
||||||
if (state.shortcuts) {
|
if (state.shortcuts) {
|
||||||
state.shortcuts.shortcuts = [
|
state.shortcuts.shortcuts = [
|
||||||
@ -776,7 +775,7 @@ const migrateConfig = {
|
|||||||
state.settings.topicNamingPrompt = ''
|
state.settings.topicNamingPrompt = ''
|
||||||
return state
|
return state
|
||||||
},
|
},
|
||||||
'52': (state: RootState) => {
|
'54': (state: RootState) => {
|
||||||
if (state.shortcuts) {
|
if (state.shortcuts) {
|
||||||
state.shortcuts.shortcuts.push({
|
state.shortcuts.shortcuts.push({
|
||||||
key: 'search_message',
|
key: 'search_message',
|
||||||
@ -786,9 +785,10 @@ const migrateConfig = {
|
|||||||
system: false
|
system: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
state.settings.showTranslateIcon = true
|
state.settings.sidebarIcons = {
|
||||||
state.settings.showPaintingIcon = true
|
visible: DEFAULT_SIDEBAR_ICONS,
|
||||||
state.settings.showKnowledgeIcon = true
|
disabled: []
|
||||||
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,18 @@ import { CodeStyleVarious, LanguageVarious, ThemeMode } from '@renderer/types'
|
|||||||
|
|
||||||
export type SendMessageShortcut = 'Enter' | 'Shift+Enter' | 'Ctrl+Enter' | 'Command+Enter'
|
export type SendMessageShortcut = 'Enter' | 'Shift+Enter' | 'Ctrl+Enter' | 'Command+Enter'
|
||||||
|
|
||||||
|
export type SidebarIcon = 'assistants' | 'agents' | 'paintings' | 'translate' | 'minapp' | 'knowledge' | 'files'
|
||||||
|
|
||||||
|
export const DEFAULT_SIDEBAR_ICONS: SidebarIcon[] = [
|
||||||
|
'assistants',
|
||||||
|
'agents',
|
||||||
|
'paintings',
|
||||||
|
'translate',
|
||||||
|
'minapp',
|
||||||
|
'knowledge',
|
||||||
|
'files'
|
||||||
|
]
|
||||||
|
|
||||||
export interface SettingsState {
|
export interface SettingsState {
|
||||||
showAssistants: boolean
|
showAssistants: boolean
|
||||||
showTopics: boolean
|
showTopics: boolean
|
||||||
@ -41,14 +53,13 @@ export interface SettingsState {
|
|||||||
translateModelPrompt: string
|
translateModelPrompt: string
|
||||||
autoTranslateWithSpace: boolean
|
autoTranslateWithSpace: boolean
|
||||||
enableTopicNaming: boolean
|
enableTopicNaming: boolean
|
||||||
// Sidebar icons
|
|
||||||
showTranslateIcon: boolean
|
|
||||||
showPaintingIcon: boolean
|
|
||||||
showMinappIcon: boolean
|
|
||||||
showKnowledgeIcon: boolean
|
|
||||||
showFilesIcon: boolean
|
|
||||||
customCss: string
|
customCss: string
|
||||||
topicNamingPrompt: string
|
topicNamingPrompt: string
|
||||||
|
// Sidebar icons
|
||||||
|
sidebarIcons: {
|
||||||
|
visible: SidebarIcon[]
|
||||||
|
disabled: SidebarIcon[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: SettingsState = {
|
const initialState: SettingsState = {
|
||||||
@ -87,13 +98,12 @@ const initialState: SettingsState = {
|
|||||||
translateModelPrompt: TRANSLATE_PROMPT,
|
translateModelPrompt: TRANSLATE_PROMPT,
|
||||||
autoTranslateWithSpace: false,
|
autoTranslateWithSpace: false,
|
||||||
enableTopicNaming: true,
|
enableTopicNaming: true,
|
||||||
showTranslateIcon: true,
|
|
||||||
showPaintingIcon: true,
|
|
||||||
showMinappIcon: true,
|
|
||||||
showKnowledgeIcon: true,
|
|
||||||
showFilesIcon: true,
|
|
||||||
customCss: '',
|
customCss: '',
|
||||||
topicNamingPrompt: ''
|
topicNamingPrompt: '',
|
||||||
|
sidebarIcons: {
|
||||||
|
visible: DEFAULT_SIDEBAR_ICONS,
|
||||||
|
disabled: []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsSlice = createSlice({
|
const settingsSlice = createSlice({
|
||||||
@ -209,21 +219,6 @@ const settingsSlice = createSlice({
|
|||||||
setEnableTopicNaming: (state, action: PayloadAction<boolean>) => {
|
setEnableTopicNaming: (state, action: PayloadAction<boolean>) => {
|
||||||
state.enableTopicNaming = action.payload
|
state.enableTopicNaming = action.payload
|
||||||
},
|
},
|
||||||
setShowTranslateIcon: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.showTranslateIcon = action.payload
|
|
||||||
},
|
|
||||||
setShowPaintingIcon: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.showPaintingIcon = action.payload
|
|
||||||
},
|
|
||||||
setShowMinappIcon: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.showMinappIcon = action.payload
|
|
||||||
},
|
|
||||||
setShowKnowledgeIcon: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.showKnowledgeIcon = action.payload
|
|
||||||
},
|
|
||||||
setShowFilesIcon: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.showFilesIcon = action.payload
|
|
||||||
},
|
|
||||||
setPasteLongTextThreshold: (state, action: PayloadAction<number>) => {
|
setPasteLongTextThreshold: (state, action: PayloadAction<number>) => {
|
||||||
state.pasteLongTextThreshold = action.payload
|
state.pasteLongTextThreshold = action.payload
|
||||||
},
|
},
|
||||||
@ -232,6 +227,9 @@ const settingsSlice = createSlice({
|
|||||||
},
|
},
|
||||||
setTopicNamingPrompt: (state, action: PayloadAction<string>) => {
|
setTopicNamingPrompt: (state, action: PayloadAction<string>) => {
|
||||||
state.topicNamingPrompt = action.payload
|
state.topicNamingPrompt = action.payload
|
||||||
|
},
|
||||||
|
setSidebarIcons: (state, action: PayloadAction<{ visible: SidebarIcon[]; disabled: SidebarIcon[] }>) => {
|
||||||
|
state.sidebarIcons = action.payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -273,14 +271,10 @@ export const {
|
|||||||
setTranslateModelPrompt,
|
setTranslateModelPrompt,
|
||||||
setAutoTranslateWithSpace,
|
setAutoTranslateWithSpace,
|
||||||
setEnableTopicNaming,
|
setEnableTopicNaming,
|
||||||
setShowTranslateIcon,
|
|
||||||
setShowPaintingIcon,
|
|
||||||
setShowMinappIcon,
|
|
||||||
setShowKnowledgeIcon,
|
|
||||||
setShowFilesIcon,
|
|
||||||
setPasteLongTextThreshold,
|
setPasteLongTextThreshold,
|
||||||
setCustomCss,
|
setCustomCss,
|
||||||
setTopicNamingPrompt
|
setTopicNamingPrompt,
|
||||||
|
setSidebarIcons
|
||||||
} = settingsSlice.actions
|
} = settingsSlice.actions
|
||||||
|
|
||||||
export default settingsSlice.reducer
|
export default settingsSlice.reducer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user