feat: new icon style

This commit is contained in:
kangfenmao 2025-04-13 15:35:37 +08:00
parent 39c614e4db
commit 5f7d8652bc
44 changed files with 310 additions and 289 deletions

View File

@ -87,12 +87,10 @@
"fs-extra": "^11.2.0",
"got-scraping": "^4.1.1",
"jsdom": "^26.0.0",
"lucide-react": "^0.487.0",
"markdown-it": "^14.1.0",
"officeparser": "^4.1.1",
"proxy-agent": "^6.5.0",
"tar": "^7.4.3",
"tiny-pinyin": "^1.3.2",
"turndown": "^7.2.0",
"turndown-plugin-gfm": "^1.0.2",
"undici": "^7.4.0",
@ -161,6 +159,7 @@
"lint-staged": "^15.5.0",
"lodash": "^4.17.21",
"lru-cache": "^11.1.0",
"lucide-react": "^0.487.0",
"mime": "^4.0.4",
"npx-scope-finder": "^1.2.0",
"openai": "patch:openai@npm%3A4.87.3#~/.yarn/patches/openai-npm-4.87.3-2b30a7685f.patch",
@ -190,6 +189,7 @@
"shiki": "^3.2.1",
"string-width": "^7.2.0",
"styled-components": "^6.1.11",
"tiny-pinyin": "^1.3.2",
"tinycolor2": "^1.6.0",
"tokenx": "^0.4.1",
"typescript": "^5.6.2",

View File

@ -281,3 +281,7 @@ body,
color: var(--color-text);
}
}
.lucide {
color: var(--color-icon);
}

View File

@ -52,7 +52,7 @@ const ListItemContainer = styled.div`
const ListItemContent = styled.div`
display: flex;
align-items: center;
gap: 5px;
gap: 2px;
overflow: hidden;
font-size: 13px;
`

View File

@ -1,4 +1,3 @@
import { SearchOutlined } from '@ant-design/icons'
import { TopView } from '@renderer/components/TopView'
import { useAgents } from '@renderer/hooks/useAgents'
import { useAssistants, useDefaultAssistant } from '@renderer/hooks/useAssistant'
@ -9,6 +8,7 @@ import { Agent, Assistant } from '@renderer/types'
import { uuid } from '@renderer/utils'
import { Divider, Input, InputRef, Modal, Tag } from 'antd'
import { take } from 'lodash'
import { Search } from 'lucide-react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -163,7 +163,7 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
<Input
prefix={
<SearchIcon>
<SearchOutlined />
<Search size={14} />
</SearchIcon>
}
ref={inputRef}
@ -177,7 +177,7 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
size="middle"
/>
</HStack>
<Divider style={{ margin: 0, borderBlockStartWidth: 0.5 }} />
<Divider style={{ margin: 0, marginTop: 4, borderBlockStartWidth: 0.5 }} />
<Container ref={containerRef}>
{take(agents, 100).map((agent, index) => (
<AgentItem
@ -237,8 +237,8 @@ const AgentItem = styled.div`
`
const SearchIcon = styled.div`
width: 36px;
height: 36px;
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
flex-direction: row;

View File

@ -1,4 +1,4 @@
import { PushpinOutlined, SearchOutlined } from '@ant-design/icons'
import { PushpinOutlined } from '@ant-design/icons'
import { TopView } from '@renderer/components/TopView'
import { getModelLogo, isEmbeddingModel, isRerankModel } from '@renderer/config/models'
import db from '@renderer/databases'
@ -7,6 +7,7 @@ import { getModelUniqId } from '@renderer/services/ModelService'
import { Model } from '@renderer/types'
import { Avatar, Divider, Empty, Input, InputRef, Menu, MenuProps, Modal } from 'antd'
import { first, sortBy } from 'lodash'
import { Search } from 'lucide-react'
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -383,7 +384,7 @@ const PopupContainer: React.FC<PopupContainerProps> = ({ model, resolve }) => {
<Input
prefix={
<SearchIcon>
<SearchOutlined />
<Search size={15} />
</SearchIcon>
}
ref={inputRef}
@ -403,7 +404,7 @@ const PopupContainer: React.FC<PopupContainerProps> = ({ model, resolve }) => {
}}
/>
</HStack>
<Divider style={{ margin: 0, borderBlockStartWidth: 0.5 }} />
<Divider style={{ margin: 0, marginTop: 4, borderBlockStartWidth: 0.5 }} />
<Scrollbar style={{ height: '50vh' }} ref={scrollContainerRef}>
<Container>
{processedItems.length > 0 ? (
@ -510,8 +511,8 @@ const EmptyState = styled.div`
`
const SearchIcon = styled.div`
width: 36px;
height: 36px;
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
flex-direction: row;

View File

@ -603,6 +603,7 @@ const QuickPanelItem = styled.div`
cursor: pointer;
transition: background-color 0.1s ease;
margin-bottom: 1px;
font-family: Ubuntu;
&.selected {
background-color: var(--selected-color);
&.focused {

View File

@ -1,10 +1,11 @@
import { LoadingOutlined, TranslationOutlined } from '@ant-design/icons'
import { LoadingOutlined } from '@ant-design/icons'
import { useDefaultModel } from '@renderer/hooks/useAssistant'
import { useSettings } from '@renderer/hooks/useSettings'
import { fetchTranslate } from '@renderer/services/ApiService'
import { getDefaultTopic, getDefaultTranslateAssistant } from '@renderer/services/AssistantService'
import { getUserMessage } from '@renderer/services/MessagesService'
import { Button, Tooltip } from 'antd'
import { Languages } from 'lucide-react'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -82,7 +83,7 @@ const TranslateButton: FC<Props> = ({ text, onTranslated, disabled, style, isLoa
title={t('chat.input.translate', { target_language: t(`languages.${targetLanguage.toString()}`) })}
arrow>
<ToolbarButton onClick={handleTranslate} disabled={disabled || isTranslating} style={style} type="text">
{isTranslating ? <LoadingOutlined spin /> : <TranslationOutlined />}
{isTranslating ? <LoadingOutlined spin /> : <Languages size={18} />}
</ToolbarButton>
</Tooltip>
)

View File

@ -1,10 +1,3 @@
import {
FileSearchOutlined,
FolderOutlined,
PictureOutlined,
QuestionCircleOutlined,
TranslationOutlined
} from '@ant-design/icons'
import { isMac } from '@renderer/config/constant'
import { AppLogo, UserAvatar } from '@renderer/config/env'
import { useTheme } from '@renderer/context/ThemeProvider'
@ -17,6 +10,19 @@ import { useSettings } from '@renderer/hooks/useSettings'
import { isEmoji } from '@renderer/utils'
import type { MenuProps } from 'antd'
import { Avatar, Dropdown, Tooltip } from 'antd'
import {
CircleHelp,
Folder,
Languages,
LayoutGrid,
LibraryBig,
MessageSquareQuote,
Moon,
Palette,
Settings,
Sparkle,
Sun
} from 'lucide-react'
import { FC, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useLocation, useNavigate } from 'react-router-dom'
@ -84,7 +90,7 @@ const Sidebar: FC = () => {
<Menus>
<Tooltip title={t('docs.title')} mouseEnterDelay={0.8} placement="right">
<Icon theme={theme} onClick={onOpenDocs} className={minappShow && currentMinappId === docsId ? 'active' : ''}>
<QuestionCircleOutlined />
<CircleHelp size={20} />
</Icon>
</Tooltip>
<Tooltip
@ -92,22 +98,17 @@ const Sidebar: FC = () => {
mouseEnterDelay={0.8}
placement="right">
<Icon theme={theme} onClick={() => toggleTheme()}>
{theme === 'dark' ? (
<i className="iconfont icon-theme icon-dark1" />
) : (
<i className="iconfont icon-theme icon-theme-light" />
)}
{theme === 'dark' ? <Moon size={20} /> : <Sun size={20} />}
</Icon>
</Tooltip>
<Tooltip title={t('settings.title')} mouseEnterDelay={0.8} placement="right">
<StyledLink
onClick={async () => {
hideMinappPopup()
await modelGenerating()
await to('/settings/provider')
}}>
<Icon theme={theme} className={pathname.startsWith('/settings') && !minappShow ? 'active' : ''}>
<i className="iconfont icon-setting" />
<Settings size={20} />
</Icon>
</StyledLink>
</Tooltip>
@ -129,13 +130,13 @@ const MainMenus: FC = () => {
const isRoutes = (path: string): string => (pathname.startsWith(path) && !minappShow ? 'active' : '')
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 />
assistants: <MessageSquareQuote size={18} />,
agents: <Sparkle size={18} />,
paintings: <Palette size={18} />,
translate: <Languages size={18} />,
minapp: <LayoutGrid size={18} />,
knowledge: <LibraryBig size={18} />,
files: <Folder size={17} />
}
const pathMap = {

View File

@ -33,7 +33,11 @@ const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
boxShadowSecondary: 'none',
defaultShadow: 'none',
dangerShadow: 'none',
primaryShadow: 'none'
primaryShadow: 'none',
borderRadius: 20
},
Select: {
borderRadius: 20
}
},
token: {

View File

@ -1,4 +1,4 @@
import { PlusOutlined, SearchOutlined } from '@ant-design/icons'
import { PlusOutlined } from '@ant-design/icons'
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import CustomTag from '@renderer/components/CustomTag'
import ListItem from '@renderer/components/ListItem'
@ -9,6 +9,7 @@ import { Agent } from '@renderer/types'
import { uuid } from '@renderer/utils'
import { Button, Empty, Flex, Input } from 'antd'
import { omit } from 'lodash'
import { Search } from 'lucide-react'
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import ReactMarkdown from 'react-markdown'
@ -150,7 +151,7 @@ const AgentsPage: FC = () => {
variant="filled"
allowClear
onClear={handleSearchClear}
suffix={<SearchOutlined onClick={handleSearch} />}
suffix={<Search size={14} color="var(--color-icon)" onClick={handleSearch} />}
value={searchInput}
maxLength={50}
onChange={(e) => setSearchInput(e.target.value)}

View File

@ -1,9 +1,9 @@
import { SearchOutlined } from '@ant-design/icons'
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import { Center } from '@renderer/components/Layout'
import { useMinapps } from '@renderer/hooks/useMinapps'
import { Empty, Input } from 'antd'
import { isEmpty } from 'lodash'
import { Search } from 'lucide-react'
import React, { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -40,10 +40,10 @@ const AppsPage: FC = () => {
<Input
placeholder={t('common.search')}
className="nodrag"
style={{ width: '30%', height: 28 }}
style={{ width: '30%', height: 28, borderRadius: 15 }}
size="small"
variant="filled"
suffix={<SearchOutlined />}
suffix={<Search size={18} />}
value={search}
onChange={(e) => setSearch(e.target.value)}
/>

View File

@ -2,24 +2,21 @@ import {
DeleteOutlined,
EditOutlined,
ExclamationCircleOutlined,
FileImageOutlined,
FilePdfOutlined,
FileTextOutlined,
SortAscendingOutlined,
SortDescendingOutlined
} from '@ant-design/icons'
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import ListItem from '@renderer/components/ListItem'
import TextEditPopup from '@renderer/components/Popups/TextEditPopup'
import db from '@renderer/databases'
import { useProviders } from '@renderer/hooks/useProvider'
import FileManager from '@renderer/services/FileManager'
import store from '@renderer/store'
import { FileType, FileTypes } from '@renderer/types'
import { formatFileSize } from '@renderer/utils'
import type { MenuProps } from 'antd'
import { Button, Empty, Flex, Menu, Popconfirm } from 'antd'
import { Button, Empty, Flex, Popconfirm } from 'antd'
import dayjs from 'dayjs'
import { useLiveQuery } from 'dexie-react-hooks'
import { File as FileIcon, FileImage, FileText, FileType as FileTypeIcon } from 'lucide-react'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -34,9 +31,6 @@ const FilesPage: FC = () => {
const [fileType, setFileType] = useState<string>('document')
const [sortField, setSortField] = useState<SortField>('created_at')
const [sortOrder, setSortOrder] = useState<SortOrder>('desc')
const { providers } = useProviders()
const geminiProviders = providers.filter((provider) => provider.type === 'gemini')
const tempFilesSort = (files: FileType[]) => {
return files.sort((a, b) => {
@ -144,16 +138,11 @@ const FilesPage: FC = () => {
})
const menuItems = [
{ key: FileTypes.DOCUMENT, label: t('files.document'), icon: <FilePdfOutlined /> },
{ key: FileTypes.IMAGE, label: t('files.image'), icon: <FileImageOutlined /> },
{ key: FileTypes.TEXT, label: t('files.text'), icon: <FileTextOutlined /> },
...geminiProviders.map((provider) => ({
key: 'gemini_' + provider.id,
label: provider.name,
icon: <FilePdfOutlined />
})),
{ key: 'all', label: t('files.all'), icon: <FileTextOutlined /> }
].filter(Boolean) as MenuProps['items']
{ key: FileTypes.DOCUMENT, label: t('files.document'), icon: <FileIcon size={16} /> },
{ key: FileTypes.IMAGE, label: t('files.image'), icon: <FileImage size={16} /> },
{ key: FileTypes.TEXT, label: t('files.text'), icon: <FileTypeIcon size={16} /> },
{ key: 'all', label: t('files.all'), icon: <FileText size={16} /> }
]
return (
<Container>
@ -162,7 +151,15 @@ const FilesPage: FC = () => {
</Navbar>
<ContentContainer id="content-container">
<SideNav>
<Menu selectedKeys={[fileType]} items={menuItems} onSelect={({ key }) => setFileType(key as FileTypes)} />
{menuItems.map((item) => (
<ListItem
key={item.key}
icon={item.icon}
title={item.label}
active={fileType === item.key}
onClick={() => setFileType(item.key as FileTypes)}
/>
))}
</SideNav>
<MainContent>
<SortContainer>
@ -223,10 +220,13 @@ const ContentContainer = styled.div`
`
const SideNav = styled.div`
display: flex;
flex-direction: column;
width: var(--settings-width);
border-right: 0.5px solid var(--color-border);
padding: 7px 12px;
padding: 12px 10px;
user-select: none;
gap: 6px;
.ant-menu {
border-inline-end: none !important;

View File

@ -1,7 +1,8 @@
import { ArrowLeftOutlined, EnterOutlined, SearchOutlined } from '@ant-design/icons'
import { ArrowLeftOutlined, EnterOutlined } from '@ant-design/icons'
import { Message, Topic } from '@renderer/types'
import { Input, InputRef } from 'antd'
import { last } from 'lodash'
import { Search } from 'lucide-react'
import { FC, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -83,7 +84,7 @@ const TopicsPage: FC = () => {
allowClear
ref={inputRef}
onChange={(e) => setSearch(e.target.value.trimStart())}
suffix={search.length >= 2 ? <EnterOutlined /> : <SearchOutlined />}
suffix={search.length >= 2 ? <EnterOutlined /> : <Search size={16} />}
onPressEnter={onSearch}
/>
</Header>

View File

@ -1,8 +1,8 @@
import { PaperClipOutlined } from '@ant-design/icons'
import { isVisionModel } from '@renderer/config/models'
import { FileType, Model } from '@renderer/types'
import { documentExts, imageExts, textExts } from '@shared/config/constant'
import { Tooltip } from 'antd'
import { Paperclip } from 'lucide-react'
import { FC, useCallback, useImperativeHandle, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
@ -57,9 +57,7 @@ const AttachmentButton: FC<Props> = ({ ref, model, files, setFiles, ToolbarButto
title={isVisionModel(model) ? t('chat.input.upload') : t('chat.input.upload.document')}
arrow>
<ToolbarButton type="text" onClick={onSelectFile} disabled={disabled}>
<PaperClipOutlined
style={{ fontSize: 17, color: files.length ? 'var(--color-primary)' : 'var(--color-icon)' }}
/>
<Paperclip size={18} style={{ color: files.length ? 'var(--color-primary)' : 'var(--color-icon)' }} />
</ToolbarButton>
</Tooltip>
)

View File

@ -1,7 +1,7 @@
import { PictureOutlined } from '@ant-design/icons'
import { isGenerateImageModel } from '@renderer/config/models'
import { Assistant, Model } from '@renderer/types'
import { Tooltip } from 'antd'
import { Image } from 'lucide-react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
@ -27,7 +27,7 @@ const GenerateImageButton: FC<Props> = ({ model, ToolbarButton, assistant, onEna
}
arrow>
<ToolbarButton type="text" disabled={!isGenerateImageModel(model)} onClick={onEnableGenerateImage}>
<PictureOutlined style={{ color: assistant.enableGenerateImage ? 'var(--color-link)' : 'var(--color-icon)' }} />
<Image size={18} color={assistant.enableGenerateImage ? 'var(--color-link)' : 'var(--color-icon)'} />
</ToolbarButton>
</Tooltip>
)

View File

@ -1,11 +1,6 @@
import {
ClearOutlined,
CodeOutlined,
FileSearchOutlined,
FormOutlined,
FullscreenExitOutlined,
FullscreenOutlined,
GlobalOutlined,
HolderOutlined,
PaperClipOutlined,
PauseCircleOutlined,
@ -44,6 +39,7 @@ import TextArea, { TextAreaRef } from 'antd/es/input/TextArea'
import dayjs from 'dayjs'
import Logger from 'electron-log/renderer'
import { debounce, isEmpty } from 'lodash'
import { Globe, Maximize, MessageSquareDiff, Minimize, PaintbrushVertical } from 'lucide-react'
import React, { CSSProperties, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
@ -935,7 +931,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
<ToolbarMenu>
<Tooltip placement="top" title={t('chat.input.new_topic', { Command: newTopicShortcut })} arrow>
<ToolbarButton type="text" onClick={addNewTopic}>
<FormOutlined />
<MessageSquareDiff size={18} />
</ToolbarButton>
</Tooltip>
<AttachmentButton
@ -947,7 +943,8 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
/>
<Tooltip placement="top" title={t('chat.input.web_search')} arrow>
<ToolbarButton type="text" onClick={onEnableWebSearch}>
<GlobalOutlined
<Globe
size={18}
style={{ color: assistant.enableWebSearch ? 'var(--color-link)' : 'var(--color-icon)' }}
/>
</ToolbarButton>
@ -989,12 +986,12 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
/>
<Tooltip placement="top" title={t('chat.input.clear', { Command: cleanTopicShortcut })} arrow>
<ToolbarButton type="text" onClick={clearTopic}>
<ClearOutlined style={{ fontSize: 17 }} />
<PaintbrushVertical size={18} />
</ToolbarButton>
</Tooltip>
<Tooltip placement="top" title={isExpended ? t('chat.input.collapse') : t('chat.input.expand')} arrow>
<ToolbarButton type="text" onClick={onToggleExpended}>
{isExpended ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
{isExpended ? <Minimize size={18} /> : <Maximize size={18} />}
</ToolbarButton>
</Tooltip>
<NewContextButton onNewContext={onNewContext} ToolbarButton={ToolbarButton} />

View File

@ -4,6 +4,7 @@ import { QuickPanelListItem, useQuickPanel } from '@renderer/components/QuickPan
import { useAppSelector } from '@renderer/store'
import { KnowledgeBase } from '@renderer/types'
import { Tooltip } from 'antd'
import { LibraryBig } from 'lucide-react'
import { FC, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'
@ -88,7 +89,7 @@ const KnowledgeBaseButton: FC<Props> = ({ ref, selectedBases, onSelect, disabled
return (
<Tooltip placement="top" title={t('chat.input.knowledge_base')} arrow>
<ToolbarButton type="text" onClick={handleOpenQuickPanel} disabled={disabled}>
<FileSearchOutlined />
<LibraryBig size={18} />
</ToolbarButton>
</Tooltip>
)

View File

@ -3,6 +3,7 @@ import { QuickPanelListItem, useQuickPanel } from '@renderer/components/QuickPan
import { useMCPServers } from '@renderer/hooks/useMCPServers'
import { MCPPrompt, MCPServer } from '@renderer/types'
import { Form, Input, Modal, Tooltip } from 'antd'
import { SquareTerminal } from 'lucide-react'
import { FC, useCallback, useImperativeHandle, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'
@ -303,7 +304,7 @@ const MCPToolsButton: FC<Props> = ({
return (
<Tooltip placement="top" title={t('settings.mcp.title')} arrow>
<ToolbarButton type="text" onClick={handleOpenQuickPanel}>
<CodeOutlined style={{ color: buttonEnabled ? 'var(--color-primary)' : 'var(--color-icon)' }} />
<SquareTerminal size={18} color={buttonEnabled ? 'var(--color-primary)' : 'var(--color-icon)'} />
</ToolbarButton>
</Tooltip>
)

View File

@ -9,6 +9,7 @@ import { getModelUniqId } from '@renderer/services/ModelService'
import { Model } from '@renderer/types'
import { Avatar, Tooltip } from 'antd'
import { first, sortBy } from 'lodash'
import { AtSign } from 'lucide-react'
import { FC, useCallback, useEffect, useImperativeHandle, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'
@ -104,7 +105,7 @@ const MentionModelsButton: FC<Props> = ({ ref, mentionModels, onMentionModel, To
return (
<Tooltip placement="top" title={t('agents.edit.model.select.title')} arrow>
<ToolbarButton type="text" onClick={handleOpenQuickPanel}>
<i className="iconfont icon-at" style={{ fontSize: 18 }}></i>
<AtSign size={18} />
</ToolbarButton>
</Tooltip>
)

View File

@ -1,6 +1,6 @@
import { PicCenterOutlined } from '@ant-design/icons'
import { useShortcut, useShortcutDisplay } from '@renderer/hooks/useShortcuts'
import { Tooltip } from 'antd'
import { CircleFadingPlus } from 'lucide-react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -20,7 +20,7 @@ const NewContextButton: FC<Props> = ({ onNewContext, ToolbarButton }) => {
<Container>
<Tooltip placement="top" title={t('chat.input.new.context', { Command: newContextShortcut })} arrow>
<ToolbarButton type="text" onClick={onNewContext}>
<PicCenterOutlined />
<CircleFadingPlus size={18} />
</ToolbarButton>
</Tooltip>
</Container>

View File

@ -4,6 +4,7 @@ import { QuickPanelListItem, QuickPanelOpenOptions } from '@renderer/components/
import QuickPhraseService from '@renderer/services/QuickPhraseService'
import { QuickPhrase } from '@renderer/types'
import { Tooltip } from 'antd'
import { Zap } from 'lucide-react'
import { memo, useCallback, useEffect, useImperativeHandle, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'
@ -99,7 +100,7 @@ const QuickPhrasesButton = ({ ref, setInputValue, resizeTextArea, ToolbarButton
return (
<Tooltip placement="top" title={t('settings.quickPhrase.title')} arrow>
<ToolbarButton type="text" onClick={handleOpenQuickPanel}>
<ThunderboltOutlined />
<Zap size={18} />
</ToolbarButton>
</Tooltip>
)

View File

@ -1,4 +1,4 @@
import { SearchOutlined, SyncOutlined, TranslationOutlined } from '@ant-design/icons'
import { SyncOutlined, TranslationOutlined } from '@ant-design/icons'
import { isOpenAIWebSearch } from '@renderer/config/models'
import { getModelUniqId } from '@renderer/services/ModelService'
import { Message, Model } from '@renderer/types'
@ -6,6 +6,7 @@ import { getBriefInfo } from '@renderer/utils'
import { withMessageThought } from '@renderer/utils/formats'
import { Divider, Flex } from 'antd'
import { clone } from 'lodash'
import { Search } from 'lucide-react'
import React, { Fragment, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import BarLoader from 'react-spinners/BarLoader'
@ -182,7 +183,7 @@ const MessageContent: React.FC<Props> = ({ message: _message, model }) => {
if (message.status === 'searching') {
return (
<SearchingContainer>
<SearchOutlined size={24} />
<Search size={24} />
<SearchingText>{t('message.searching')}</SearchingText>
<BarLoader color="#1677ff" />
</SearchingContainer>

View File

@ -1,17 +1,4 @@
import {
CheckOutlined,
DeleteOutlined,
EditOutlined,
ForkOutlined,
LikeFilled,
LikeOutlined,
MenuOutlined,
QuestionCircleOutlined,
SaveOutlined,
SyncOutlined,
TranslationOutlined
} from '@ant-design/icons'
import { UploadOutlined } from '@ant-design/icons'
import { CheckOutlined, EditOutlined, QuestionCircleOutlined, SyncOutlined } from '@ant-design/icons'
import ObsidianExportPopup from '@renderer/components/Popups/ObsidianExportPopup'
import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup'
import TextEditPopup from '@renderer/components/Popups/TextEditPopup'
@ -37,6 +24,20 @@ import { withMessageThought } from '@renderer/utils/formats'
import { Button, Dropdown, Popconfirm, Tooltip } from 'antd'
import dayjs from 'dayjs'
import { clone } from 'lodash'
import {
AtSign,
Copy,
FilePenLine,
Languages,
Menu,
RefreshCw,
Save,
Share,
Split,
ThumbsDown,
ThumbsUp,
Trash
} from 'lucide-react'
import { FC, memo, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
@ -159,22 +160,29 @@ const MessageMenubar: FC<Props> = (props) => {
content: content.trim(),
metadata: {
...message.metadata,
generateImage: imageUrls.length > 0 ? {
generateImage:
imageUrls.length > 0
? {
type: 'url',
images: imageUrls
} : undefined
}
: undefined
}
})
resendMessage && handleResendUserMessage({
resendMessage &&
handleResendUserMessage({
...message,
content: content.trim(),
metadata: {
...message.metadata,
generateImage: imageUrls.length > 0 ? {
generateImage:
imageUrls.length > 0
? {
type: 'url',
images: imageUrls
} : undefined
}
: undefined
}
})
}
@ -213,18 +221,28 @@ const MessageMenubar: FC<Props> = (props) => {
{
label: t('chat.save'),
key: 'save',
icon: <SaveOutlined />,
icon: <Save size={16} />,
onClick: () => {
const fileName = dayjs(message.createdAt).format('YYYYMMDDHHmm') + '.md'
window.api.file.save(fileName, message.content)
}
},
{ label: t('common.edit'), key: 'edit', icon: <EditOutlined />, onClick: onEdit },
{ label: t('chat.message.new.branch'), key: 'new-branch', icon: <ForkOutlined />, onClick: onNewBranch },
{
label: t('common.edit'),
key: 'edit',
icon: <FilePenLine size={16} />,
onClick: onEdit
},
{
label: t('chat.message.new.branch'),
key: 'new-branch',
icon: <Split size={16} />,
onClick: onNewBranch
},
{
label: t('chat.topics.export.title'),
key: 'export',
icon: <UploadOutlined />,
icon: <Share size={16} color="var(--color-icon)" style={{ marginTop: 3 }} />,
children: [
exportMenuOptions.image && {
label: t('chat.topics.copy.image'),
@ -361,7 +379,7 @@ const MessageMenubar: FC<Props> = (props) => {
)}
<Tooltip title={t('common.copy')} mouseEnterDelay={0.8}>
<ActionButton className="message-action-button" onClick={onCopy}>
{!copied && <i className="iconfont icon-copy"></i>}
{!copied && <Copy size={16} />}
{copied && <CheckOutlined style={{ color: 'var(--color-primary)' }} />}
</ActionButton>
</Tooltip>
@ -378,7 +396,7 @@ const MessageMenubar: FC<Props> = (props) => {
open={showRegenerateTooltip}
onOpenChange={setShowRegenerateTooltip}>
<ActionButton className="message-action-button">
<SyncOutlined />
<RefreshCw size={16} />
</ActionButton>
</Tooltip>
</Popconfirm>
@ -386,7 +404,7 @@ const MessageMenubar: FC<Props> = (props) => {
{isAssistantMessage && (
<Tooltip title={t('message.mention.title')} mouseEnterDelay={0.8}>
<ActionButton className="message-action-button" onClick={onMentionModel}>
<i className="iconfont icon-at" style={{ fontSize: 16 }}></i>
<AtSign size={16} />
</ActionButton>
</Tooltip>
)}
@ -412,7 +430,7 @@ const MessageMenubar: FC<Props> = (props) => {
arrow>
<Tooltip title={t('chat.translate')} mouseEnterDelay={1.2}>
<ActionButton className="message-action-button" onClick={(e) => e.stopPropagation()}>
<TranslationOutlined />
<Languages size={16} />
</ActionButton>
</Tooltip>
</Dropdown>
@ -420,7 +438,7 @@ const MessageMenubar: FC<Props> = (props) => {
{isAssistantMessage && isGrouped && (
<Tooltip title={t('chat.message.useful')} mouseEnterDelay={0.8}>
<ActionButton className="message-action-button" onClick={onUseful}>
{message.useful ? <LikeFilled /> : <LikeOutlined />}
{message.useful ? <ThumbsUp size={16} /> : <ThumbsDown size={16} />}
</ActionButton>
</Tooltip>
)}
@ -436,7 +454,7 @@ const MessageMenubar: FC<Props> = (props) => {
mouseEnterDelay={1}
open={showDeleteTooltip}
onOpenChange={setShowDeleteTooltip}>
<DeleteOutlined />
<Trash size={16} />
</Tooltip>
</ActionButton>
</Popconfirm>
@ -447,7 +465,7 @@ const MessageMenubar: FC<Props> = (props) => {
placement="topRight"
arrow>
<ActionButton className="message-action-button" onClick={(e) => e.stopPropagation()}>
<MenuOutlined />
<Menu size={19} />
</ActionButton>
</Dropdown>
)}

View File

@ -29,7 +29,6 @@ import ChatNavigation from './ChatNavigation'
import MessageAnchorLine from './MessageAnchorLine'
import MessageGroup from './MessageGroup'
import NarrowLayout from './NarrowLayout'
import NewTopicButton from './NewTopicButton'
import Prompt from './Prompt'
interface MessagesProps {
@ -225,7 +224,6 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
ref={containerRef}
$right={topicPosition === 'left'}>
<NarrowLayout style={{ display: 'flex', flexDirection: 'column-reverse' }}>
{messages.length >= 2 && !loading && <NewTopicButton />}
<InfiniteScroll
dataLength={displayMessages.length}
next={loadMoreMessages}

View File

@ -1,4 +1,3 @@
import { FormOutlined, SearchOutlined } from '@ant-design/icons'
import { Navbar, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar'
import { HStack } from '@renderer/components/Layout'
import MinAppsPopover from '@renderer/components/Popups/MinAppsPopover'
@ -15,6 +14,7 @@ import { setNarrowMode } from '@renderer/store/settings'
import { Assistant, Topic } from '@renderer/types'
import { Tooltip } from 'antd'
import { t } from 'i18next'
import { LayoutGrid, MessageSquareDiff, PanelLeftClose, PanelRightClose, Search } from 'lucide-react'
import { FC } from 'react'
import styled from 'styled-components'
@ -61,12 +61,12 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
<NavbarLeft style={{ justifyContent: 'space-between', borderRight: 'none', padding: 0 }}>
<Tooltip title={t('navbar.hide_sidebar')} mouseEnterDelay={0.8}>
<NavbarIcon onClick={toggleShowAssistants} style={{ marginLeft: isMac ? 16 : 0 }}>
<i className="iconfont icon-hide-sidebar" />
<PanelLeftClose size={18} />
</NavbarIcon>
</Tooltip>
<Tooltip title={t('settings.shortcuts.new_topic')} mouseEnterDelay={0.8}>
<NavbarIcon onClick={() => EventEmitter.emit(EVENT_NAMES.ADD_NEW_TOPIC)}>
<FormOutlined />
<NavbarIcon onClick={() => EventEmitter.emit(EVENT_NAMES.ADD_NEW_TOPIC)} style={{ marginRight: 5 }}>
<MessageSquareDiff size={18} />
</NavbarIcon>
</Tooltip>
</NavbarLeft>
@ -78,7 +78,7 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
<NavbarIcon
onClick={() => toggleShowAssistants()}
style={{ marginRight: 8, marginLeft: isMac ? 4 : -12 }}>
<i className="iconfont icon-show-sidebar" />
<PanelRightClose size={18} />
</NavbarIcon>
</Tooltip>
)}
@ -88,7 +88,7 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
<UpdateAppButton />
<Tooltip title={t('chat.assistant.search.placeholder')} mouseEnterDelay={0.8}>
<NarrowIcon onClick={() => SearchPopup.show()}>
<SearchOutlined />
<Search size={18} />
</NarrowIcon>
</Tooltip>
<Tooltip title={t('navbar.expand')} mouseEnterDelay={0.8}>
@ -100,14 +100,14 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
<MinAppsPopover>
<Tooltip title={t('minapp.title')} mouseEnterDelay={0.8}>
<NarrowIcon>
<i className="iconfont icon-appstore" />
<LayoutGrid size={18} />
</NarrowIcon>
</Tooltip>
</MinAppsPopover>
)}
{topicPosition === 'right' && (
<NarrowIcon onClick={toggleShowTopics}>
<i className={`iconfont icon-${showTopics ? 'show' : 'hide'}-sidebar`} />
{showTopics ? <PanelRightClose size={18} /> : <PanelLeftClose size={18} />}
</NarrowIcon>
)}
</HStack>

View File

@ -1,4 +1,4 @@
import { CheckOutlined, QuestionCircleOutlined, ReloadOutlined, SettingOutlined } from '@ant-design/icons'
import { CheckOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import Scrollbar from '@renderer/components/Scrollbar'
import {
@ -44,6 +44,7 @@ import {
import { Assistant, AssistantSettings, CodeStyleVarious, ThemeMode, TranslateLanguageVarious } from '@renderer/types'
import { modalConfirm } from '@renderer/utils'
import { Button, Col, InputNumber, Row, Segmented, Select, Slider, Switch, Tooltip } from 'antd'
import { CircleHelp, RotateCcw, Settings2 } from 'lucide-react'
import { FC, useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -179,13 +180,13 @@ const SettingsTab: FC<Props> = (props) => {
<HStack alignItems="center">
{t('assistants.settings.title')}{' '}
<Tooltip title={t('chat.settings.reset')}>
<ReloadOutlined onClick={onReset} style={{ cursor: 'pointer', fontSize: 12, padding: '0 3px' }} />
<RotateCcw size={20} onClick={onReset} style={{ cursor: 'pointer', padding: '0 3px' }} />
</Tooltip>
</HStack>
<Button
type="text"
size="small"
icon={<SettingOutlined />}
icon={<Settings2 size={16} />}
onClick={() => AssistantSettingsPopup.show({ assistant, tab: 'model' })}
/>
</SettingSubtitle>
@ -193,7 +194,7 @@ const SettingsTab: FC<Props> = (props) => {
<Row align="middle">
<Label>{t('chat.settings.temperature')}</Label>
<Tooltip title={t('chat.settings.temperature.tip')}>
<QuestionIcon />
<CircleHelp size={14} color="var(--color-text-2)" />
</Tooltip>
</Row>
<Row align="middle" gutter={10}>
@ -211,7 +212,7 @@ const SettingsTab: FC<Props> = (props) => {
<Row align="middle">
<Label>{t('chat.settings.context_count')}</Label>
<Tooltip title={t('chat.settings.context_count.tip')}>
<QuestionIcon />
<CircleHelp size={14} color="var(--color-text-2)" />
</Tooltip>
</Row>
<Row align="middle" gutter={10}>
@ -243,7 +244,7 @@ const SettingsTab: FC<Props> = (props) => {
<HStack alignItems="center">
<Label>{t('chat.settings.max_tokens')}</Label>
<Tooltip title={t('chat.settings.max_tokens.tip')}>
<QuestionIcon />
<CircleHelp size={14} color="var(--color-text-2)" />
</Tooltip>
</HStack>
<Switch
@ -288,7 +289,7 @@ const SettingsTab: FC<Props> = (props) => {
<Row align="middle">
<Label>{t('assistants.settings.reasoning_effort')}</Label>
<Tooltip title={t('assistants.settings.reasoning_effort.tip')}>
<QuestionIcon />
<CircleHelp size={14} color="var(--color-text-2)" />
</Tooltip>
</Row>
<Row align="middle" gutter={10}>
@ -371,7 +372,7 @@ const SettingsTab: FC<Props> = (props) => {
<SettingRowTitleSmall>
{t('chat.settings.code_cacheable')}{' '}
<Tooltip title={t('chat.settings.code_cacheable.tip')}>
<QuestionIcon style={{ marginLeft: 4 }} />
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
</Tooltip>
</SettingRowTitleSmall>
<Switch size="small" checked={codeCacheable} onChange={(checked) => dispatch(setCodeCacheable(checked))} />
@ -383,7 +384,7 @@ const SettingsTab: FC<Props> = (props) => {
<SettingRowTitleSmall>
{t('chat.settings.code_cache_max_size')}
<Tooltip title={t('chat.settings.code_cache_max_size.tip')}>
<QuestionIcon style={{ marginLeft: 4 }} />
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
</Tooltip>
</SettingRowTitleSmall>
<InputNumber
@ -401,7 +402,7 @@ const SettingsTab: FC<Props> = (props) => {
<SettingRowTitleSmall>
{t('chat.settings.code_cache_ttl')}
<Tooltip title={t('chat.settings.code_cache_ttl.tip')}>
<QuestionIcon style={{ marginLeft: 4 }} />
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
</Tooltip>
</SettingRowTitleSmall>
<InputNumber
@ -419,7 +420,7 @@ const SettingsTab: FC<Props> = (props) => {
<SettingRowTitleSmall>
{t('chat.settings.code_cache_threshold')}
<Tooltip title={t('chat.settings.code_cache_threshold.tip')}>
<QuestionIcon style={{ marginLeft: 4 }} />
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
</Tooltip>
</SettingRowTitleSmall>
<InputNumber
@ -439,7 +440,7 @@ const SettingsTab: FC<Props> = (props) => {
<SettingRowTitleSmall>
{t('chat.settings.thought_auto_collapse')}
<Tooltip title={t('chat.settings.thought_auto_collapse.tip')}>
<QuestionIcon style={{ marginLeft: 4 }} />
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
</Tooltip>
</SettingRowTitleSmall>
<Switch
@ -663,12 +664,6 @@ const Label = styled.p`
margin-right: 5px;
`
const QuestionIcon = styled(QuestionCircleOutlined)`
font-size: 12px;
cursor: pointer;
color: var(--color-text-3);
`
const SettingRowTitleSmall = styled(SettingRowTitle)`
font-size: 13px;
`

View File

@ -1,4 +1,3 @@
import { BarsOutlined, SettingOutlined } from '@ant-design/icons'
import AddAssistantPopup from '@renderer/components/Popups/AddAssistantPopup'
import { useAssistants, useDefaultAssistant } from '@renderer/hooks/useAssistant'
import { useSettings } from '@renderer/hooks/useSettings'
@ -48,8 +47,7 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
const assistantTab = {
label: t('assistants.abbr'),
value: 'assistants',
icon: <i className="iconfont icon-business-smart-assistant" />
value: 'assistants'
}
const onCreateAssistant = async () => {
@ -104,13 +102,11 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
position === 'left' && topicPosition === 'left' ? assistantTab : undefined,
{
label: t('common.topics'),
value: 'topic',
icon: <BarsOutlined />
value: 'topic'
},
{
label: t('settings.title'),
value: 'settings',
icon: <SettingOutlined />
value: 'settings'
}
].filter(Boolean) as SegmentedProps['options']
}

View File

@ -1,14 +1,4 @@
import {
ColumnHeightOutlined,
CopyOutlined,
DeleteOutlined,
EditOutlined,
PlusOutlined,
RedoOutlined,
SearchOutlined,
SettingOutlined,
VerticalAlignMiddleOutlined
} from '@ant-design/icons'
import { CopyOutlined, DeleteOutlined, EditOutlined, RedoOutlined } from '@ant-design/icons'
import CustomTag from '@renderer/components/CustomTag'
import Ellipsis from '@renderer/components/Ellipsis'
import { HStack } from '@renderer/components/Layout'
@ -23,6 +13,7 @@ import { formatFileSize } from '@renderer/utils'
import { bookExts, documentExts, textExts, thirdPartyApplicationExts } from '@shared/config/constant'
import { Alert, Button, Dropdown, Empty, message, Tag, Tooltip, Upload } from 'antd'
import dayjs from 'dayjs'
import { ChevronsDown, ChevronsUp, Plus, Search, Settings2 } from 'lucide-react'
import VirtualList from 'rc-virtual-list'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -238,7 +229,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
<ModelInfo>
<Button
type="text"
icon={<SettingOutlined />}
icon={<Settings2 size={18} color="var(--color-icon)" />}
onClick={() => KnowledgeSettingsPopup.show({ base })}
size="small"
/>
@ -277,7 +268,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
size="small"
shape="round"
onClick={() => KnowledgeSearchPopup.show({ base })}
icon={<SearchOutlined />}
icon={<Search size={14} />}
disabled={disabled}>
{t('knowledge.search')}
</Button>
@ -286,7 +277,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
size="small"
shape="circle"
onClick={() => setExpandAll(!expandAll)}
icon={expandAll ? <VerticalAlignMiddleOutlined /> : <ColumnHeightOutlined />}
icon={expandAll ? <ChevronsUp size={14} /> : <ChevronsDown size={14} />}
disabled={disabled}
/>
</Tooltip>
@ -306,7 +297,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
extra={
<Button
type="text"
icon={<PlusOutlined />}
icon={<Plus size={16} />}
onClick={(e) => {
e.stopPropagation()
handleAddFile()
@ -393,7 +384,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
extra={
<Button
type="text"
icon={<PlusOutlined />}
icon={<Plus size={16} />}
onClick={(e) => {
e.stopPropagation()
handleAddDirectory()
@ -445,7 +436,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
extra={
<Button
type="text"
icon={<PlusOutlined />}
icon={<Plus size={16} />}
onClick={(e) => {
e.stopPropagation()
handleAddUrl()
@ -522,7 +513,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
extra={
<Button
type="text"
icon={<PlusOutlined />}
icon={<Plus size={16} />}
onClick={(e) => {
e.stopPropagation()
handleAddSitemap()
@ -577,7 +568,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
extra={
<Button
type="text"
icon={<PlusOutlined />}
icon={<Plus size={16} />}
onClick={(e) => {
e.stopPropagation()
handleAddNote()

View File

@ -1,11 +1,4 @@
import {
DeleteOutlined,
EditOutlined,
FileTextOutlined,
PlusOutlined,
SearchOutlined,
SettingOutlined
} from '@ant-design/icons'
import { DeleteOutlined, EditOutlined, SettingOutlined } from '@ant-design/icons'
import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar'
import DragableList from '@renderer/components/DragableList'
import { HStack } from '@renderer/components/Layout'
@ -18,6 +11,7 @@ import { NavbarIcon } from '@renderer/pages/home/Navbar'
import KnowledgeSearchPopup from '@renderer/pages/knowledge/components/KnowledgeSearchPopup'
import { KnowledgeBase } from '@renderer/types'
import { Dropdown, Empty, MenuProps } from 'antd'
import { Book, Plus, Search } from 'lucide-react'
import { FC, useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -105,7 +99,7 @@ const KnowledgePage: FC = () => {
<NavbarRight>
<HStack alignItems="center">
<NarrowIcon onClick={() => selectedBase && KnowledgeSearchPopup.show({ base: selectedBase })}>
<SearchOutlined />
<Search size={18} />
</NarrowIcon>
</HStack>
</NavbarRight>
@ -124,7 +118,7 @@ const KnowledgePage: FC = () => {
<div>
<ListItem
active={selectedBase?.id === base.id}
icon={<FileTextOutlined />}
icon={<Book size={16} />}
title={base.name}
onClick={() => setSelectedBase(base)}
/>
@ -135,7 +129,7 @@ const KnowledgePage: FC = () => {
{!isDragging && (
<AddKnowledgeItem onClick={handleAddKnowledge}>
<AddKnowledgeName>
<PlusOutlined style={{ color: 'var(--color-text-2)', marginRight: 4 }} />
<Plus size={18} />
{t('button.add')}
</AddKnowledgeName>
</AddKnowledgeItem>
@ -243,6 +237,10 @@ const AddKnowledgeName = styled.div`
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 13px;
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
`
const NarrowIcon = styled(NavbarIcon)`

View File

@ -1,5 +1,4 @@
import { GithubOutlined } from '@ant-design/icons'
import { FileProtectOutlined, GlobalOutlined, MailOutlined, SoundOutlined } from '@ant-design/icons'
import IndicatorLight from '@renderer/components/IndicatorLight'
import { HStack } from '@renderer/components/Layout'
import { isWindows } from '@renderer/config/constant'
@ -15,6 +14,7 @@ import { ThemeMode } from '@renderer/types'
import { compareVersions, runAsyncFunction } from '@renderer/utils'
import { Avatar, Button, Progress, Row, Switch, Tag } from 'antd'
import { debounce } from 'lodash'
import { FileCheck, Github, Globe, Mail, Rss } from 'lucide-react'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Markdown from 'react-markdown'
@ -181,7 +181,7 @@ const AboutSettings: FC = () => {
<SettingGroup theme={theme}>
<SettingRow>
<SettingRowTitle>
<SoundOutlined />
<Rss size={18} />
{t('settings.about.releases.title')}
</SettingRowTitle>
<Button onClick={showReleases}>{t('settings.about.releases.button')}</Button>
@ -189,7 +189,7 @@ const AboutSettings: FC = () => {
<SettingDivider />
<SettingRow>
<SettingRowTitle>
<GlobalOutlined />
<Globe size={18} />
{t('settings.about.website.title')}
</SettingRowTitle>
<Button onClick={() => onOpenWebsite('https://cherry-ai.com')}>{t('settings.about.website.button')}</Button>
@ -197,7 +197,7 @@ const AboutSettings: FC = () => {
<SettingDivider />
<SettingRow>
<SettingRowTitle>
<GithubOutlined />
<Github size={18} />
{t('settings.about.feedback.title')}
</SettingRowTitle>
<Button onClick={() => onOpenWebsite('https://github.com/CherryHQ/cherry-studio/issues/new/choose')}>
@ -207,7 +207,7 @@ const AboutSettings: FC = () => {
<SettingDivider />
<SettingRow>
<SettingRowTitle>
<FileProtectOutlined />
<FileCheck size={18} />
{t('settings.about.license.title')}
</SettingRowTitle>
<Button onClick={showLicense}>{t('settings.about.license.button')}</Button>
@ -215,7 +215,8 @@ const AboutSettings: FC = () => {
<SettingDivider />
<SettingRow>
<SettingRowTitle>
<MailOutlined /> {t('settings.about.contact.title')}
<Mail size={18} />
{t('settings.about.contact.title')}
</SettingRowTitle>
<Button onClick={mailto}>{t('settings.about.contact.button')}</Button>
</SettingRow>

View File

@ -1,5 +1,4 @@
import { CloseOutlined } from '@ant-design/icons'
import { FileSearchOutlined, FolderOutlined, PictureOutlined, TranslationOutlined } from '@ant-design/icons'
import {
DragDropContext,
Draggable,
@ -11,6 +10,7 @@ import {
import { useAppDispatch } from '@renderer/store'
import { setSidebarIcons } from '@renderer/store/settings'
import { message } from 'antd'
import { Folder, Languages, LayoutGrid, LibraryBig, MessageSquareQuote, Palette, Sparkle } from 'lucide-react'
import { FC, useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -109,13 +109,13 @@ const SidebarIconsManager: FC<SidebarIconsManagerProps> = ({
// 使用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 />
assistants: <MessageSquareQuote size={16} />,
agents: <Sparkle size={16} />,
paintings: <Palette size={16} />,
translate: <Languages size={16} />,
minapp: <LayoutGrid size={16} />,
knowledge: <LibraryBig size={16} />,
files: <Folder size={15} />
}),
[]
)

View File

@ -1,8 +1,9 @@
import { EditOutlined, ExportOutlined, SearchOutlined } from '@ant-design/icons'
import { EditOutlined, ExportOutlined } from '@ant-design/icons'
import { NavbarRight } from '@renderer/components/app/Navbar'
import { HStack } from '@renderer/components/Layout'
import { isWindows } from '@renderer/config/constant'
import { Button } from 'antd'
import { Search } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'
@ -21,7 +22,7 @@ export const McpSettingsNavbar = () => {
size="small"
type="text"
onClick={() => navigate('/settings/mcp/npx-search')}
icon={<SearchOutlined />}
icon={<Search size={14} />}
className="nodrag"
style={{ fontSize: 13, height: 28, borderRadius: 20 }}>
{t('settings.mcp.searchNpx')}

View File

@ -1,4 +1,4 @@
import { EditOutlined, MessageOutlined, RedoOutlined, SettingOutlined, TranslationOutlined } from '@ant-design/icons'
import { RedoOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import PromptPopup from '@renderer/components/Popups/PromptPopup'
import { isEmbeddingModel } from '@renderer/config/models'
@ -13,6 +13,7 @@ import { setTranslateModelPrompt } from '@renderer/store/settings'
import { Model } from '@renderer/types'
import { Button, Select, Tooltip } from 'antd'
import { find, sortBy } from 'lodash'
import { FolderPen, Languages, MessageSquareMore, Settings2 } from 'lucide-react'
import { FC, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
@ -82,10 +83,10 @@ const ModelSettings: FC = () => {
<SettingContainer theme={theme}>
<SettingGroup theme={theme}>
<SettingTitle style={{ marginBottom: 12 }}>
<div>
<MessageOutlined style={iconStyle} />
<HStack alignItems="center" gap={10}>
<MessageSquareMore size={18} color="var(--color-text)" />
{t('settings.models.default_assistant_model')}
</div>
</HStack>
</SettingTitle>
<HStack alignItems="center">
<Select
@ -97,16 +98,16 @@ const ModelSettings: FC = () => {
showSearch
placeholder={t('settings.models.empty')}
/>
<Button icon={<SettingOutlined />} style={{ marginLeft: 8 }} onClick={DefaultAssistantSettings.show} />
<Button icon={<Settings2 size={16} />} style={{ marginLeft: 8 }} onClick={DefaultAssistantSettings.show} />
</HStack>
<SettingDescription>{t('settings.models.default_assistant_model_description')}</SettingDescription>
</SettingGroup>
<SettingGroup theme={theme}>
<SettingTitle style={{ marginBottom: 12 }}>
<div>
<EditOutlined style={iconStyle} />
<HStack alignItems="center" gap={10}>
<FolderPen size={18} color="var(--color-text)" />
{t('settings.models.topic_naming_model')}
</div>
</HStack>
</SettingTitle>
<HStack alignItems="center">
<Select
@ -118,16 +119,16 @@ const ModelSettings: FC = () => {
showSearch
placeholder={t('settings.models.empty')}
/>
<Button icon={<SettingOutlined />} style={{ marginLeft: 8 }} onClick={TopicNamingModalPopup.show} />
<Button icon={<Settings2 size={16} />} style={{ marginLeft: 8 }} onClick={TopicNamingModalPopup.show} />
</HStack>
<SettingDescription>{t('settings.models.topic_naming_model_description')}</SettingDescription>
</SettingGroup>
<SettingGroup theme={theme}>
<SettingTitle style={{ marginBottom: 12 }}>
<div>
<TranslationOutlined style={iconStyle} />
<HStack alignItems="center" gap={10}>
<Languages size={18} color="var(--color-text)" />
{t('settings.models.translate_model')}
</div>
</HStack>
</SettingTitle>
<HStack alignItems="center">
<Select
@ -139,7 +140,7 @@ const ModelSettings: FC = () => {
showSearch
placeholder={t('settings.models.empty')}
/>
<Button icon={<SettingOutlined />} style={{ marginLeft: 8 }} onClick={onUpdateTranslateModel} />
<Button icon={<Settings2 size={16} />} style={{ marginLeft: 8 }} onClick={onUpdateTranslateModel} />
{translateModelPrompt !== TRANSLATE_PROMPT && (
<Tooltip title={t('common.reset')}>
<Button icon={<RedoOutlined />} style={{ marginLeft: 8 }} onClick={onResetTranslatePrompt}></Button>

View File

@ -1,4 +1,4 @@
import { LoadingOutlined, MinusOutlined, PlusOutlined, SearchOutlined } from '@ant-design/icons'
import { LoadingOutlined, MinusOutlined, PlusOutlined } from '@ant-design/icons'
import CustomCollapse from '@renderer/components/CustomCollapse'
import CustomTag from '@renderer/components/CustomTag'
import ModelTagsWithLabel from '@renderer/components/ModelTagsWithLabel'
@ -21,6 +21,7 @@ import { getDefaultGroupName, isFreeModel, runAsyncFunction } from '@renderer/ut
import { Avatar, Button, Empty, Flex, Modal, Tabs, Tooltip, Typography } from 'antd'
import Input from 'antd/es/input/Input'
import { groupBy, isEmpty, uniqBy } from 'lodash'
import { Search } from 'lucide-react'
import { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -180,7 +181,7 @@ const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => {
centered>
<SearchContainer>
<Input
prefix={<SearchOutlined />}
prefix={<Search size={14} />}
size="large"
ref={searchInputRef}
placeholder={t('settings.provider.search_placeholder')}

View File

@ -1,7 +1,6 @@
import {
CheckCircleFilled,
CloseCircleFilled,
EditOutlined,
ExclamationCircleFilled,
LoadingOutlined,
MinusCircleOutlined,
@ -23,6 +22,7 @@ import { Model } from '@renderer/types'
import { maskApiKey } from '@renderer/utils/api'
import { Avatar, Button, Flex, Tooltip, Typography } from 'antd'
import { groupBy, sortBy, toPairs } from 'lodash'
import { ListCheck } from 'lucide-react'
import React, { memo, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -333,7 +333,7 @@ const ModelList: React.FC<ModelListProps> = ({ providerId, modelStatuses = [], s
)}
</Flex>
<Flex gap={10} style={{ marginTop: '10px' }}>
<Button type="primary" onClick={onManageModel} icon={<EditOutlined />}>
<Button type="primary" onClick={onManageModel} icon={<ListCheck size={18} />}>
{t('button.manage')}
</Button>
<Button type="default" onClick={onAddModel} icon={<PlusOutlined />}>

View File

@ -1,5 +1,5 @@
import { SearchOutlined } from '@ant-design/icons'
import { Input, Tooltip } from 'antd'
import { Search } from 'lucide-react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -33,7 +33,7 @@ const ModelListSearchBar: React.FC<ModelListSearchBarProps> = ({ onSearch }) =>
placeholder={t('models.search')}
size="small"
style={{ width: '160px' }}
suffix={<SearchOutlined style={{ color: 'var(--color-text-3)' }} />}
suffix={<Search size={14} />}
onChange={(e) => handleTextChange(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Escape') {
@ -50,7 +50,12 @@ const ModelListSearchBar: React.FC<ModelListSearchBarProps> = ({ onSearch }) =>
/>
) : (
<Tooltip title={t('models.search')} mouseEnterDelay={0.5}>
<SearchOutlined onClick={() => setSearchVisible(true)} />
<Search
size={14}
color="var(--color-icon)"
onClick={() => setSearchVisible(true)}
style={{ cursor: 'pointer' }}
/>
</Tooltip>
)
}

View File

@ -1,4 +1,4 @@
import { CheckOutlined, ExportOutlined, LoadingOutlined, SettingOutlined } from '@ant-design/icons'
import { CheckOutlined, LoadingOutlined, SettingOutlined } from '@ant-design/icons'
import { StreamlineGoodHealthAndWellBeing } from '@renderer/components/Icons/SVGIcon'
import { HStack } from '@renderer/components/Layout'
import OAuthButton from '@renderer/components/OAuth/OAuthButton'
@ -17,6 +17,7 @@ import { providerCharge } from '@renderer/utils/oauth'
import { Button, Divider, Flex, Input, Space, Switch, Tooltip } from 'antd'
import Link from 'antd/es/typography/Link'
import { debounce, isEmpty } from 'lodash'
import { SquareArrowOutUpRight } from 'lucide-react'
import { FC, useCallback, useDeferredValue, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -279,8 +280,8 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
<Flex align="center" gap={8}>
<ProviderName>{provider.isSystem ? t(`provider.${provider.id}`) : provider.name}</ProviderName>
{officialWebsite! && (
<Link target="_blank" href={providerConfig.websites.official}>
<ExportOutlined style={{ color: 'var(--color-text)', fontSize: '12px' }} />
<Link target="_blank" href={providerConfig.websites.official} style={{ display: 'flex' }}>
<SquareArrowOutUpRight size={14} color="var(--color-text)" />
</Link>
)}
{!provider.isSystem && (
@ -383,10 +384,10 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
{provider.id === 'copilot' && <GithubCopilotSettings provider={provider} setApiKey={setApiKey} />}
<SettingSubtitle style={{ marginBottom: 5 }}>
<Space align="center" style={{ width: '100%', justifyContent: 'space-between' }}>
<Space>
<HStack alignItems="center" gap={5}>
<SettingSubtitle style={{ marginTop: 0 }}>{t('common.models')}</SettingSubtitle>
{!isEmpty(models) && <ModelListSearchBar onSearch={setModelSearchText} />}
</Space>
</HStack>
{!isEmpty(models) && (
<Tooltip title={t('settings.models.check.button_caption')} mouseEnterDelay={0.5}>
<Button

View File

@ -1,4 +1,4 @@
import { DeleteOutlined, EditOutlined, PlusOutlined, SearchOutlined } from '@ant-design/icons'
import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons'
import { DragDropContext, Draggable, Droppable, DropResult } from '@hello-pangea/dnd'
import Scrollbar from '@renderer/components/Scrollbar'
import { getProviderLogo } from '@renderer/config/providers'
@ -7,6 +7,7 @@ import ImageStorage from '@renderer/services/ImageStorage'
import { Provider } from '@renderer/types'
import { droppableReorder, generateColorFromChar, getFirstCharacter, uuid } from '@renderer/utils'
import { Avatar, Button, Dropdown, Input, MenuProps, Tag } from 'antd'
import { Search } from 'lucide-react'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -178,7 +179,7 @@ const ProvidersList: FC = () => {
const getProviderAvatar = (provider: Provider) => {
if (provider.isSystem) {
return <ProviderLogo shape="square" src={getProviderLogo(provider.id)} size={25} />
return <ProviderLogo shape="circle" src={getProviderLogo(provider.id)} size={25} />
}
const customLogo = providerLogos[provider.id]
@ -222,7 +223,7 @@ const ProvidersList: FC = () => {
placeholder={t('settings.provider.search')}
value={searchText}
style={{ borderRadius: 'var(--list-item-border-radius)', height: 35 }}
suffix={<SearchOutlined style={{ color: 'var(--color-text-3)' }} />}
suffix={<Search size={14} />}
onChange={(e) => setSearchText(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Escape') {

View File

@ -1,19 +1,20 @@
import {
AppstoreOutlined,
CloudOutlined,
CodeOutlined,
GlobalOutlined,
InfoCircleOutlined,
LayoutOutlined,
MacCommandOutlined,
RocketOutlined,
SaveOutlined,
SettingOutlined,
ThunderboltOutlined
} from '@ant-design/icons'
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import { useSidebarIconShow } from '@renderer/hooks/useSidebarIcon'
import ModelSettings from '@renderer/pages/settings/ModelSettings/ModelSettings'
import {
Cloud,
Command,
Globe,
HardDrive,
Info,
LayoutGrid,
MonitorCog,
Package,
Rocket,
Settings2,
SquareTerminal,
Zap
} from 'lucide-react'
// 导入useAppSelector
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
@ -51,75 +52,75 @@ const SettingsPage: FC = () => {
<SettingMenus>
<MenuItemLink to="/settings/provider">
<MenuItem className={isRoute('/settings/provider')}>
<CloudOutlined />
<Cloud size={18} />
{t('settings.provider.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/model">
<MenuItem className={isRoute('/settings/model')}>
<i className="iconfont icon-ai-model" />
<Package size={18} />
{t('settings.model')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/web-search">
<MenuItem className={isRoute('/settings/web-search')}>
<GlobalOutlined />
<Globe size={18} />
{t('settings.websearch.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/mcp">
<MenuItem className={isRoute('/settings/mcp')}>
<CodeOutlined />
<SquareTerminal size={18} />
{t('settings.mcp.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/general">
<MenuItem className={isRoute('/settings/general')}>
<SettingOutlined />
<Settings2 size={18} />
{t('settings.general')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/display">
<MenuItem className={isRoute('/settings/display')}>
<LayoutOutlined />
<MonitorCog size={18} />
{t('settings.display.title')}
</MenuItem>
</MenuItemLink>
{showMiniAppSettings && (
<MenuItemLink to="/settings/miniapps">
<MenuItem className={isRoute('/settings/miniapps')}>
<AppstoreOutlined />
<LayoutGrid size={18} />
{t('settings.miniapps.title')}
</MenuItem>
</MenuItemLink>
)}
<MenuItemLink to="/settings/shortcut">
<MenuItem className={isRoute('/settings/shortcut')}>
<MacCommandOutlined />
<Command size={18} />
{t('settings.shortcuts.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/quickAssistant">
<MenuItem className={isRoute('/settings/quickAssistant')}>
<RocketOutlined />
<Rocket size={18} />
{t('settings.quickAssistant.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/quickPhrase">
<MenuItem className={isRoute('/settings/quickPhrase')}>
<ThunderboltOutlined />
<Zap size={18} />
{t('settings.quickPhrase.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/data">
<MenuItem className={isRoute('/settings/data')}>
<SaveOutlined />
<HardDrive size={18} />
{t('settings.data.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/about">
<MenuItem className={isRoute('/settings/about')}>
<InfoCircleOutlined />
<Info size={18} />
{t('settings.about')}
</MenuItem>
</MenuItemLink>

View File

@ -316,6 +316,7 @@ const ShortcutSettings: FC = () => {
<Button
icon={<UndoOutlined />}
size="small"
shape="circle"
onClick={() => handleResetShortcut(record)}
disabled={!isShortcutModified(record)}
/>
@ -324,6 +325,7 @@ const ShortcutSettings: FC = () => {
<Button
icon={<ClearOutlined />}
size="small"
shape="circle"
onClick={() => handleClear(record)}
disabled={record.shortcut.length === 0 || !record.editable}
/>

View File

@ -1,9 +1,9 @@
import { InfoCircleOutlined } from '@ant-design/icons'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useAppDispatch, useAppSelector } from '@renderer/store'
import { setEnhanceMode, setMaxResult, setOverwrite, setSearchWithTime } from '@renderer/store/websearch'
import { Slider, Switch, Tooltip } from 'antd'
import { t } from 'i18next'
import { Info } from 'lucide-react'
import { FC } from 'react'
import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..'
@ -31,7 +31,7 @@ const BasicSettings: FC = () => {
<SettingRowTitle>
{t('settings.websearch.overwrite')}
<Tooltip title={t('settings.websearch.overwrite_tooltip')} placement="right">
<InfoCircleOutlined style={{ marginLeft: 5, color: 'var(--color-icon)', cursor: 'pointer' }} />
<Info size={16} color="var(--color-icon)" style={{ marginLeft: 5, cursor: 'pointer' }} />
</Tooltip>
</SettingRowTitle>
<Switch checked={overwrite} onChange={(checked) => dispatch(setOverwrite(checked))} />
@ -41,7 +41,7 @@ const BasicSettings: FC = () => {
<SettingRowTitle>
{t('settings.websearch.enhance_mode')}
<Tooltip title={t('settings.websearch.enhance_mode_tooltip')} placement="right">
<InfoCircleOutlined style={{ marginLeft: 5, color: 'var(--color-icon)', cursor: 'pointer' }} />
<Info size={16} color="var(--color-icon)" style={{ marginLeft: 5, cursor: 'pointer' }} />
</Tooltip>
</SettingRowTitle>
<Switch checked={enhanceMode} onChange={(checked) => dispatch(setEnhanceMode(checked))} />

View File

@ -1,4 +1,4 @@
import { CheckOutlined, ExportOutlined, InfoCircleOutlined, LoadingOutlined } from '@ant-design/icons'
import { CheckOutlined, ExportOutlined, LoadingOutlined } from '@ant-design/icons'
import { getWebSearchProviderLogo, WEB_SEARCH_PROVIDER_CONFIG } from '@renderer/config/webSearchProviders'
import { useWebSearchProvider } from '@renderer/hooks/useWebSearchProviders'
import { formatApiKeys } from '@renderer/services/ApiService'
@ -7,6 +7,7 @@ import { WebSearchProvider } from '@renderer/types'
import { hasObjectKey } from '@renderer/utils'
import { Avatar, Button, Divider, Flex, Input } from 'antd'
import Link from 'antd/es/typography/Link'
import { Info } from 'lucide-react'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -53,7 +54,7 @@ const WebSearchProviderSetting: FC<Props> = ({ provider: _provider }) => {
window.message.error({
content: t('settings.websearch.no_provider_selected'),
duration: 3,
icon: <InfoCircleOutlined />,
icon: <Info size={18} />,
key: 'no-provider-selected'
})
return

View File

@ -61,6 +61,9 @@ export const SettingRowTitle = styled.div`
font-size: 14px;
line-height: 18px;
color: var(--color-text-1);
display: flex;
flex-direction: row;
align-items: center;
`
export const SettingHelpTextRow = styled.div`

View File

@ -1,12 +1,4 @@
import {
CheckOutlined,
DeleteOutlined,
HistoryOutlined,
SendOutlined,
SettingOutlined,
SyncOutlined,
WarningOutlined
} from '@ant-design/icons'
import { CheckOutlined, DeleteOutlined, HistoryOutlined, SendOutlined } from '@ant-design/icons'
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import CopyIcon from '@renderer/components/Icons/CopyIcon'
import { isLocalAi } from '@renderer/config/env'
@ -22,6 +14,7 @@ import TextArea, { TextAreaRef } from 'antd/es/input/TextArea'
import dayjs from 'dayjs'
import { useLiveQuery } from 'dexie-react-hooks'
import { isEmpty } from 'lodash'
import { Mouse, Settings2, TriangleAlert } from 'lucide-react'
import { FC, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
@ -167,18 +160,18 @@ const TranslatePage: FC = () => {
if (translateModel) {
return (
<Link to="/settings/model" style={{ color: 'var(--color-text-2)' }}>
<SettingOutlined />
<Link to="/settings/model" style={{ color: 'var(--color-text-2)', display: 'flex' }}>
<Settings2 size={18} />
</Link>
)
}
return (
<Link to="/settings/model" style={{ marginLeft: -10 }}>
<Link to="/settings/model" style={{ marginLeft: -10, display: 'flex' }}>
<Button
type="link"
style={{ color: 'var(--color-error)', textDecoration: 'underline' }}
icon={<WarningOutlined />}>
icon={<TriangleAlert size={16} />}>
{t('translate.error.not_configured')}
</Button>
</Link>
@ -304,11 +297,11 @@ const TranslatePage: FC = () => {
<Tooltip
mouseEnterDelay={0.5}
title={isScrollSyncEnabled ? t('translate.scroll_sync.disable') : t('translate.scroll_sync.enable')}>
<SyncOutlined
style={{
color: isScrollSyncEnabled ? 'var(--color-primary)' : 'var(--color-text-2)'
}}
<Mouse
size={16}
onClick={toggleScrollSync}
style={{ cursor: 'pointer' }}
color={isScrollSyncEnabled ? 'var(--color-primary)' : 'var(--color-icon)'}
/>
</Tooltip>
</Flex>