feat: enhance styling and icon consistency across components

This commit is contained in:
kangfenmao 2025-04-14 00:18:11 +08:00
parent 24e46efa0c
commit 0e8c053cee
25 changed files with 93 additions and 107 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -199,3 +199,11 @@
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
} }
.ant-collapse {
border: 1px solid var(--color-border);
}
.ant-collapse-content {
border-top: 1px solid var(--color-border) !important;
}

View File

@ -40,7 +40,7 @@
--color-border-soft: #ffffff10; --color-border-soft: #ffffff10;
--color-border-mute: #ffffff05; --color-border-mute: #ffffff05;
--color-error: #f44336; --color-error: #f44336;
--color-link: #1677ff; --color-link: #338cff;
--color-code-background: #323232; --color-code-background: #323232;
--color-hover: rgba(40, 40, 40, 1); --color-hover: rgba(40, 40, 40, 1);
--color-active: rgba(55, 55, 55, 1); --color-active: rgba(55, 55, 55, 1);

View File

@ -44,7 +44,7 @@ const CustomCollapse: FC<CustomCollapseProps> = ({
borderTopRightRadius: '8px' borderTopRightRadius: '8px'
}, },
body: { body: {
borderTop: '0.5px solid var(--color-border)' borderTop: 'none'
} }
} }

View File

@ -0,0 +1,32 @@
import { getLeadingEmoji } from '@renderer/utils'
import styled from 'styled-components'
const EmojiIcon = styled.div<{ $emoji: string }>`
width: 26px;
height: 26px;
border-radius: 13px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 15px;
position: relative;
overflow: hidden;
margin-right: 3px;
&:before {
width: 100%;
height: 100%;
content: ${({ $emoji }) => `'${getLeadingEmoji($emoji || ' ')}'`};
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 200%;
transform: scale(1.5);
filter: blur(5px);
opacity: 0.4;
}
`
export default EmojiIcon

View File

@ -1,5 +1,5 @@
import { EyeOutlined } from '@ant-design/icons'
import { Tooltip } from 'antd' import { Tooltip } from 'antd'
import { ImageIcon } from 'lucide-react'
import React, { FC } from 'react' import React, { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -10,7 +10,7 @@ const VisionIcon: FC<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>,
return ( return (
<Container> <Container>
<Tooltip title={t('models.type.vision')} placement="top"> <Tooltip title={t('models.type.vision')} placement="top">
<Icon {...(props as any)} /> <Icon size={15} {...(props as any)} />
</Tooltip> </Tooltip>
</Container> </Container>
) )
@ -22,9 +22,8 @@ const Container = styled.div`
align-items: center; align-items: center;
` `
const Icon = styled(EyeOutlined)` const Icon = styled(ImageIcon)`
color: var(--color-primary); color: var(--color-primary);
font-size: 15px;
margin-right: 6px; margin-right: 6px;
` `

View File

@ -13,6 +13,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
import EmojiIcon from '../EmojiIcon'
import { HStack } from '../Layout' import { HStack } from '../Layout'
import Scrollbar from '../Scrollbar' import Scrollbar from '../Scrollbar'
@ -186,12 +187,9 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
onClick={() => onCreateAssistant(agent)} onClick={() => onCreateAssistant(agent)}
className={`agent-item ${agent.id === 'default' ? 'default' : ''} ${index === selectedIndex ? 'keyboard-selected' : ''}`} className={`agent-item ${agent.id === 'default' ? 'default' : ''} ${index === selectedIndex ? 'keyboard-selected' : ''}`}
onMouseEnter={() => setSelectedIndex(index)}> onMouseEnter={() => setSelectedIndex(index)}>
<HStack <HStack alignItems="center" gap={5} style={{ overflow: 'hidden', maxWidth: '100%' }}>
alignItems="center" <EmojiIcon $emoji={agent.emoji || ''}>{agent.emoji}</EmojiIcon>
gap={5} <span className="text-nowrap">{agent.name}</span>
style={{ overflow: 'hidden', maxWidth: '100%' }}
className="text-nowrap">
{agent.emoji} {agent.name}
</HStack> </HStack>
{agent.id === 'default' && <Tag color="green">{t('agents.tag.system')}</Tag>} {agent.id === 'default' && <Tag color="green">{t('agents.tag.system')}</Tag>}
{agent.type === 'agent' && <Tag color="orange">{t('agents.tag.agent')}</Tag>} {agent.type === 'agent' && <Tag color="orange">{t('agents.tag.agent')}</Tag>}
@ -220,13 +218,11 @@ const AgentItem = styled.div`
margin-bottom: 8px; margin-bottom: 8px;
cursor: pointer; cursor: pointer;
overflow: hidden; overflow: hidden;
border: 1px solid transparent;
&.default { &.default {
background-color: var(--color-background-mute); background-color: var(--color-background-mute);
} }
&.keyboard-selected { &.keyboard-selected {
background-color: var(--color-background-mute); background-color: var(--color-background-mute);
border: 1px solid var(--color-primary);
} }
.anticon { .anticon {
font-size: 16px; font-size: 16px;

View File

@ -12,15 +12,15 @@ import type { MenuProps } from 'antd'
import { Avatar, Dropdown, Tooltip } from 'antd' import { Avatar, Dropdown, Tooltip } from 'antd'
import { import {
CircleHelp, CircleHelp,
FileSearch,
Folder, Folder,
Languages, Languages,
LayoutGrid, LayoutGrid,
LibraryBig,
MessageSquareQuote, MessageSquareQuote,
Moon, Moon,
Palette, Palette,
Settings, Settings,
Sparkles, Sparkle,
Sun Sun
} from 'lucide-react' } from 'lucide-react'
import { FC, useEffect } from 'react' import { FC, useEffect } from 'react'
@ -131,11 +131,11 @@ const MainMenus: FC = () => {
const iconMap = { const iconMap = {
assistants: <MessageSquareQuote size={18} className="icon" />, assistants: <MessageSquareQuote size={18} className="icon" />,
agents: <Sparkles size={18} className="icon" />, agents: <Sparkle size={18} className="icon" />,
paintings: <Palette size={18} className="icon" />, paintings: <Palette size={18} className="icon" />,
translate: <Languages size={18} className="icon" />, translate: <Languages size={18} className="icon" />,
minapp: <LayoutGrid size={18} className="icon" />, minapp: <LayoutGrid size={18} className="icon" />,
knowledge: <LibraryBig size={18} className="icon" />, knowledge: <FileSearch size={18} className="icon" />,
files: <Folder size={17} className="icon" /> files: <Folder size={17} className="icon" />
} }

View File

@ -1,7 +1,7 @@
import ZhinaoProviderLogo from '@renderer/assets/images/models/360.png' import ZhinaoProviderLogo from '@renderer/assets/images/models/360.png'
import HunyuanProviderLogo from '@renderer/assets/images/models/hunyuan.png' import HunyuanProviderLogo from '@renderer/assets/images/models/hunyuan.png'
import AzureProviderLogo from '@renderer/assets/images/models/microsoft.png' import AzureProviderLogo from '@renderer/assets/images/models/microsoft.png'
import AiHubMixProviderLogo from '@renderer/assets/images/providers/aihubmix.jpg' import AiHubMixProviderLogo from '@renderer/assets/images/providers/aihubmix.webp'
import AlayaNewProviderLogo from '@renderer/assets/images/providers/alayanew.webp' import AlayaNewProviderLogo from '@renderer/assets/images/providers/alayanew.webp'
import AnthropicProviderLogo from '@renderer/assets/images/providers/anthropic.png' import AnthropicProviderLogo from '@renderer/assets/images/providers/anthropic.png'
import BaichuanProviderLogo from '@renderer/assets/images/providers/baichuan.png' import BaichuanProviderLogo from '@renderer/assets/images/providers/baichuan.png'

View File

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

View File

@ -33,7 +33,7 @@
}, },
"assistants": { "assistants": {
"title": "Assistants", "title": "Assistants",
"abbr": "Assistant", "abbr": "Assistants",
"settings.title": "Assistant Settings", "settings.title": "Assistant Settings",
"clear.content": "Clearing the topic will delete all topics and files in the assistant. Are you sure you want to continue?", "clear.content": "Clearing the topic will delete all topics and files in the assistant. Are you sure you want to continue?",
"clear.title": "Clear topics", "clear.title": "Clear topics",

View File

@ -932,7 +932,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
<ToolbarMenu> <ToolbarMenu>
<Tooltip placement="top" title={t('chat.input.new_topic', { Command: newTopicShortcut })} arrow> <Tooltip placement="top" title={t('chat.input.new_topic', { Command: newTopicShortcut })} arrow>
<ToolbarButton type="text" onClick={addNewTopic}> <ToolbarButton type="text" onClick={addNewTopic}>
<MessageSquareDiff size={18} /> <MessageSquareDiff size={19} />
</ToolbarButton> </ToolbarButton>
</Tooltip> </Tooltip>
<AttachmentButton <AttachmentButton

View File

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

View File

@ -34,7 +34,7 @@ const CitationsList: React.FC<CitationsListProps> = ({ citations }) => {
{citation.showFavicon && citation.url && ( {citation.showFavicon && citation.url && (
<Favicon hostname={new URL(citation.url).hostname} alt={citation.title || citation.hostname || ''} /> <Favicon hostname={new URL(citation.url).hostname} alt={citation.title || citation.hostname || ''} />
)} )}
<CitationLink href={citation.url} target="_blank" rel="noopener noreferrer"> <CitationLink href={citation.url} className="text-nowrap" target="_blank" rel="noopener noreferrer">
{citation.title ? citation.title : <span className="hostname">{citation.hostname}</span>} {citation.title ? citation.title : <span className="hostname">{citation.hostname}</span>}
</CitationLink> </CitationLink>
</HStack> </HStack>

View File

@ -263,7 +263,7 @@ const ToolResponseContainer = styled.div`
padding: 12px 16px; padding: 12px 16px;
overflow: auto; overflow: auto;
max-height: 300px; max-height: 300px;
border-top: 1px solid var(--color-border); border-top: none;
position: relative; position: relative;
` `

View File

@ -32,10 +32,9 @@ const Prompt: FC<Props> = ({ assistant, topic }) => {
const Container = styled.div<{ $isDark: boolean }>` const Container = styled.div<{ $isDark: boolean }>`
padding: 10px 20px; padding: 10px 20px;
margin: 5px 20px 0 20px; margin: 5px 20px 0 20px;
border-radius: 6px; border-radius: 10px;
cursor: pointer; cursor: pointer;
border: 0.5px solid var(--color-border); border: 1px solid var(--color-border);
background-color: ${({ $isDark }) => ($isDark ? 'var(--color-background-opacity)' : 'transparent')};
` `
const Text = styled.div` const Text = styled.div`

View File

@ -8,6 +8,7 @@ import {
SortDescendingOutlined SortDescendingOutlined
} from '@ant-design/icons' } from '@ant-design/icons'
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
import EmojiIcon from '@renderer/components/EmojiIcon'
import CopyIcon from '@renderer/components/Icons/CopyIcon' import CopyIcon from '@renderer/components/Icons/CopyIcon'
import { useAssistant } from '@renderer/hooks/useAssistant' import { useAssistant } from '@renderer/hooks/useAssistant'
import { useAssistants } from '@renderer/hooks/useAssistant' import { useAssistants } from '@renderer/hooks/useAssistant'
@ -215,11 +216,11 @@ const AssistantItem: FC<AssistantItemProps> = ({ assistant, isActive, onSwitch,
/> />
) : ( ) : (
assistantIconType === 'emoji' && ( assistantIconType === 'emoji' && (
<AssistantEmoji <EmojiIcon
$emoji={assistant.emoji || assistantName.slice(0, 1)} $emoji={assistant.emoji || assistantName.slice(0, 1)}
className={isPending && !isActive ? 'animation-pulse' : ''}> className={isPending && !isActive ? 'animation-pulse' : ''}>
{assistant.emoji || assistantName.slice(0, 1)} {assistant.emoji || assistantName.slice(0, 1)}
</AssistantEmoji> </EmojiIcon>
) )
)} )}
<AssistantName className="text-nowrap">{assistantName}</AssistantName> <AssistantName className="text-nowrap">{assistantName}</AssistantName>
@ -270,34 +271,6 @@ const AssistantNameRow = styled.div`
gap: 8px; gap: 8px;
` `
const AssistantEmoji = styled.div<{ $emoji: string }>`
width: 26px;
height: 26px;
border-radius: 13px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 15px;
position: relative;
overflow: hidden;
margin-right: 3px;
&:before {
width: 100%;
height: 100%;
content: ${({ $emoji }) => `'${$emoji || ' '}'`};
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 200%;
transform: scale(1.5);
filter: blur(5px);
opacity: 0.4;
}
`
const AssistantName = styled.div` const AssistantName = styled.div`
font-size: 13px; font-size: 13px;
` `

View File

@ -184,6 +184,9 @@ const Segmented = styled(AntSegmented)`
font-size: 13px; font-size: 13px;
height: 100%; height: 100%;
} }
.ant-segmented-item-label[aria-selected='true'] {
color: var(--color-text);
}
.iconfont { .iconfont {
font-size: 13px; font-size: 13px;
margin-left: -2px; margin-left: -2px;
@ -204,6 +207,11 @@ const Segmented = styled(AntSegmented)`
border-radius: var(--list-item-border-radius); border-radius: var(--list-item-border-radius);
box-shadow: none; box-shadow: none;
} }
.ant-segmented-item-label,
.ant-segmented-item-icon {
display: flex;
align-items: center;
}
/* These styles ensure the same appearance as before */ /* These styles ensure the same appearance as before */
border-radius: 0; border-radius: 0;
box-shadow: none; box-shadow: none;

View File

@ -1,5 +1,4 @@
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
import ModelTags from '@renderer/components/ModelTags'
import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup' import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup'
import { isLocalAi } from '@renderer/config/env' import { isLocalAi } from '@renderer/config/env'
import { useAssistant } from '@renderer/hooks/useAssistant' import { useAssistant } from '@renderer/hooks/useAssistant'
@ -33,13 +32,12 @@ const SelectModelButton: FC<Props> = ({ assistant }) => {
const providerName = getProviderName(model?.provider) const providerName = getProviderName(model?.provider)
return ( return (
<DropdownButton size="small" type="default" onClick={onSelectModel}> <DropdownButton size="small" type="text" onClick={onSelectModel}>
<ButtonContent> <ButtonContent>
<ModelAvatar model={model} size={20} /> <ModelAvatar model={model} size={20} />
<ModelName> <ModelName>
{model ? model.name : t('button.select_model')} {providerName ? '| ' + providerName : ''} {model ? model.name : t('button.select_model')} {providerName ? '| ' + providerName : ''}
</ModelName> </ModelName>
<ModelTags model={model} showFree={false} showReasoning={false} showToolsCalling={false} />
</ButtonContent> </ButtonContent>
</DropdownButton> </DropdownButton>
) )

View File

@ -13,7 +13,7 @@ import { formatFileSize } from '@renderer/utils'
import { bookExts, documentExts, textExts, thirdPartyApplicationExts } from '@shared/config/constant' import { bookExts, documentExts, textExts, thirdPartyApplicationExts } from '@shared/config/constant'
import { Alert, Button, Dropdown, Empty, message, Tag, Tooltip, Upload } from 'antd' import { Alert, Button, Dropdown, Empty, message, Tag, Tooltip, Upload } from 'antd'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { ChevronsDown, ChevronsUp, Plus, Search, Settings2 } from 'lucide-react' import { ChevronsDown, ChevronsUp, Plus, Settings2 } from 'lucide-react'
import VirtualList from 'rc-virtual-list' import VirtualList from 'rc-virtual-list'
import { FC, useState } from 'react' import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -21,7 +21,6 @@ import styled from 'styled-components'
import CustomCollapse from '../../components/CustomCollapse' import CustomCollapse from '../../components/CustomCollapse'
import FileItem from '../files/FileItem' import FileItem from '../files/FileItem'
import KnowledgeSearchPopup from './components/KnowledgeSearchPopup'
import KnowledgeSettingsPopup from './components/KnowledgeSettingsPopup' import KnowledgeSettingsPopup from './components/KnowledgeSettingsPopup'
import StatusIcon from './components/StatusIcon' import StatusIcon from './components/StatusIcon'
@ -58,7 +57,6 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
} = useKnowledge(selectedBase.id || '') } = useKnowledge(selectedBase.id || '')
const providerName = getProviderName(base?.model.provider || '') const providerName = getProviderName(base?.model.provider || '')
const rerankModelProviderName = getProviderName(base?.rerankModel?.provider || '')
const disabled = !base?.version || !providerName const disabled = !base?.version || !providerName
if (!base) { if (!base) {
@ -239,7 +237,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
</div> </div>
<Tooltip title={providerName} placement="bottom"> <Tooltip title={providerName} placement="bottom">
<div className="tag-column"> <div className="tag-column">
<Tag color="geekblue" style={{ borderRadius: 20, margin: 0 }}> <Tag color="green" style={{ borderRadius: 20, margin: 0 }}>
{base.model.name} {base.model.name}
</Tag> </Tag>
</div> </div>
@ -248,30 +246,8 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
{t('models.dimensions', { dimensions: base.dimensions || 0 })} {t('models.dimensions', { dimensions: base.dimensions || 0 })}
</Tag> </Tag>
</div> </div>
{base.rerankModel && (
<div className="model-row">
<div className="label-column">
<label>{t('models.rerank_model')}</label>
</div>
<Tooltip title={rerankModelProviderName} placement="bottom">
<div className="tag-column">
<Tag color="green" style={{ borderRadius: 20, margin: 0 }}>
{base.rerankModel?.name}
</Tag>
</div>
</Tooltip>
</div>
)}
</ModelInfo> </ModelInfo>
<HStack gap={8} alignItems="center"> <HStack gap={8} alignItems="center">
<Button
size="small"
shape="round"
onClick={() => KnowledgeSearchPopup.show({ base })}
icon={<Search size={14} />}
disabled={disabled}>
{t('knowledge.search')}
</Button>
<Tooltip title={expandAll ? t('common.collapse') : t('common.expand')}> <Tooltip title={expandAll ? t('common.collapse') : t('common.expand')}>
<Button <Button
size="small" size="small"

View File

@ -1,10 +1,7 @@
import { import {
CloudSyncOutlined, CloudSyncOutlined,
DatabaseOutlined,
FileMarkdownOutlined,
FileSearchOutlined, FileSearchOutlined,
FolderOpenOutlined, FolderOpenOutlined,
MenuOutlined,
SaveOutlined, SaveOutlined,
YuqueOutlined YuqueOutlined
} from '@ant-design/icons' } from '@ant-design/icons'
@ -20,6 +17,7 @@ import { reset } from '@renderer/services/BackupService'
import { AppInfo } from '@renderer/types' import { AppInfo } from '@renderer/types'
import { formatFileSize } from '@renderer/utils' import { formatFileSize } from '@renderer/utils'
import { Button, Typography } from 'antd' import { Button, Typography } from 'antd'
import { FileText, FolderCog, FolderInput } from 'lucide-react'
import { FC, useEffect, useState } from 'react' import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -44,7 +42,7 @@ const DataSettings: FC = () => {
//joplin icon needs to be updated into iconfont //joplin icon needs to be updated into iconfont
const JoplinIcon = () => ( const JoplinIcon = () => (
<svg viewBox="0 0 24 24" width="16" height="16" fill="grey" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 24 24" width="16" height="16" fill="var(--color-icon)" xmlns="http://www.w3.org/2000/svg">
<path d="M20.97 0h-8.9a.15.15 0 00-.16.15v2.83c0 .1.08.17.18.17h1.22c.49 0 .89.38.93.86V17.4l-.01.36-.05.29-.04.13a2.06 2.06 0 01-.38.7l-.02.03a2.08 2.08 0 01-.37.34c-.5.35-1.17.5-1.92.43a4.66 4.66 0 01-2.67-1.22 3.96 3.96 0 01-1.34-2.42c-.1-.78.14-1.47.65-1.93l.07-.05c.37-.31.84-.5 1.39-.55a.09.09 0 00.01 0l.3-.01.35.01h.02a4.39 4.39 0 011.5.44c.15.08.17 0 .18-.06V9.63a.26.26 0 00-.2-.26 7.5 7.5 0 00-6.76 1.61 6.37 6.37 0 00-2.03 5.5 8.18 8.18 0 002.71 5.08A9.35 9.35 0 0011.81 24c1.88 0 3.62-.64 4.9-1.81a6.32 6.32 0 002.06-4.3l.01-10.86V4.08a.95.95 0 01.95-.93h1.22a.17.17 0 00.17-.17V.15a.15.15 0 00-.15-.15z" /> <path d="M20.97 0h-8.9a.15.15 0 00-.16.15v2.83c0 .1.08.17.18.17h1.22c.49 0 .89.38.93.86V17.4l-.01.36-.05.29-.04.13a2.06 2.06 0 01-.38.7l-.02.03a2.08 2.08 0 01-.37.34c-.5.35-1.17.5-1.92.43a4.66 4.66 0 01-2.67-1.22 3.96 3.96 0 01-1.34-2.42c-.1-.78.14-1.47.65-1.93l.07-.05c.37-.31.84-.5 1.39-.55a.09.09 0 00.01 0l.3-.01.35.01h.02a4.39 4.39 0 011.5.44c.15.08.17 0 .18-.06V9.63a.26.26 0 00-.2-.26 7.5 7.5 0 00-6.76 1.61 6.37 6.37 0 00-2.03 5.5 8.18 8.18 0 002.71 5.08A9.35 9.35 0 0011.81 24c1.88 0 3.62-.64 4.9-1.81a6.32 6.32 0 002.06-4.3l.01-10.86V4.08a.95.95 0 01.95-.93h1.22a.17.17 0 00.17-.17V.15a.15.15 0 00-.15-.15z" />
</svg> </svg>
) )
@ -67,7 +65,7 @@ const DataSettings: FC = () => {
const menuItems = [ const menuItems = [
{ key: 'divider_0', isDivider: true, text: t('settings.data.divider.basic') }, { key: 'divider_0', isDivider: true, text: t('settings.data.divider.basic') },
{ key: 'data', title: 'settings.data.data.title', icon: <DatabaseOutlined style={{ fontSize: 16 }} /> }, { key: 'data', title: 'settings.data.data.title', icon: <FolderCog size={16} /> },
{ key: 'divider_1', isDivider: true, text: t('settings.data.divider.cloud_storage') }, { key: 'divider_1', isDivider: true, text: t('settings.data.divider.cloud_storage') },
{ key: 'webdav', title: 'settings.data.webdav.title', icon: <CloudSyncOutlined style={{ fontSize: 16 }} /> }, { key: 'webdav', title: 'settings.data.webdav.title', icon: <CloudSyncOutlined style={{ fontSize: 16 }} /> },
{ key: 'nutstore', title: 'settings.data.nutstore.title', icon: <NutstoreIcon /> }, { key: 'nutstore', title: 'settings.data.nutstore.title', icon: <NutstoreIcon /> },
@ -75,12 +73,12 @@ const DataSettings: FC = () => {
{ {
key: 'export_menu', key: 'export_menu',
title: 'settings.data.export_menu.title', title: 'settings.data.export_menu.title',
icon: <MenuOutlined style={{ fontSize: 16 }} /> icon: <FolderInput size={16} />
}, },
{ {
key: 'markdown_export', key: 'markdown_export',
title: 'settings.data.markdown_export.title', title: 'settings.data.markdown_export.title',
icon: <FileMarkdownOutlined style={{ fontSize: 16 }} /> icon: <FileText size={16} />
}, },
{ key: 'divider_3', isDivider: true, text: t('settings.data.divider.third_party') }, { key: 'divider_3', isDivider: true, text: t('settings.data.divider.third_party') },
{ key: 'notion', title: 'settings.data.notion.title', icon: <i className="iconfont icon-notion" /> }, { key: 'notion', title: 'settings.data.notion.title', icon: <i className="iconfont icon-notion" /> },

View File

@ -5,8 +5,7 @@ import {
LoadingOutlined, LoadingOutlined,
MinusCircleOutlined, MinusCircleOutlined,
MinusOutlined, MinusOutlined,
PlusOutlined, PlusOutlined
SettingOutlined
} from '@ant-design/icons' } from '@ant-design/icons'
import CustomCollapse from '@renderer/components/CustomCollapse' import CustomCollapse from '@renderer/components/CustomCollapse'
import { HStack } from '@renderer/components/Layout' import { HStack } from '@renderer/components/Layout'
@ -22,7 +21,7 @@ import { Model } from '@renderer/types'
import { maskApiKey } from '@renderer/utils/api' import { maskApiKey } from '@renderer/utils/api'
import { Avatar, Button, Flex, Tooltip, Typography } from 'antd' import { Avatar, Button, Flex, Tooltip, Typography } from 'antd'
import { groupBy, sortBy, toPairs } from 'lodash' import { groupBy, sortBy, toPairs } from 'lodash'
import { ListCheck } from 'lucide-react' import { Bolt, ListCheck } from 'lucide-react'
import React, { memo, useCallback, useMemo, useState } from 'react' import React, { memo, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -302,7 +301,7 @@ const ModelList: React.FC<ModelListProps> = ({ providerId, modelStatuses = [], s
type="text" type="text"
onClick={() => !isChecking && onEditModel(model)} onClick={() => !isChecking && onEditModel(model)}
disabled={isChecking} disabled={isChecking}
icon={<SettingOutlined />} icon={<Bolt size={16} />}
/> />
<Button <Button
type="text" type="text"

View File

@ -1,4 +1,4 @@
import { CheckOutlined, LoadingOutlined, SettingOutlined } from '@ant-design/icons' import { CheckOutlined, LoadingOutlined } from '@ant-design/icons'
import { StreamlineGoodHealthAndWellBeing } from '@renderer/components/Icons/SVGIcon' import { StreamlineGoodHealthAndWellBeing } from '@renderer/components/Icons/SVGIcon'
import { HStack } from '@renderer/components/Layout' import { HStack } from '@renderer/components/Layout'
import OAuthButton from '@renderer/components/OAuth/OAuthButton' import OAuthButton from '@renderer/components/OAuth/OAuthButton'
@ -17,7 +17,7 @@ import { providerCharge } from '@renderer/utils/oauth'
import { Button, Divider, Flex, Input, Space, Switch, Tooltip } from 'antd' import { Button, Divider, Flex, Input, Space, Switch, Tooltip } from 'antd'
import Link from 'antd/es/typography/Link' import Link from 'antd/es/typography/Link'
import { debounce, isEmpty } from 'lodash' import { debounce, isEmpty } from 'lodash'
import { SquareArrowOutUpRight } from 'lucide-react' import { Settings, SquareArrowOutUpRight } from 'lucide-react'
import { FC, useCallback, useDeferredValue, useEffect, useState } from 'react' import { FC, useCallback, useDeferredValue, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -285,9 +285,10 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
</Link> </Link>
)} )}
{!provider.isSystem && ( {!provider.isSystem && (
<SettingOutlined <Settings
type="text" type="text"
style={{ width: 30 }} size={16}
style={{ cursor: 'pointer' }}
onClick={() => ProviderSettingsPopup.show({ provider })} onClick={() => ProviderSettingsPopup.show({ provider })}
/> />
)} )}

View File

@ -12,7 +12,7 @@ export function getDefaultAssistant(): Assistant {
return { return {
id: 'default', id: 'default',
name: i18n.t('chat.default.name'), name: i18n.t('chat.default.name'),
emoji: '⭐️', emoji: '😀',
prompt: '', prompt: '',
topics: [getDefaultTopic('default')], topics: [getDefaultTopic('default')],
messages: [], messages: [],