mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 10:40:07 +08:00
refactor: tooltip icons (#9841)
* refactor: add HelpTooltip, group tooltip icons * refactor: add a tip for preview tools * refactor: use HelpTooltip in SettingsTab
This commit is contained in:
parent
8a4c635c97
commit
b1a9fbc6fd
20
src/renderer/src/components/TooltipIcons/HelpTooltip.tsx
Normal file
20
src/renderer/src/components/TooltipIcons/HelpTooltip.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { Tooltip, TooltipProps } from 'antd'
|
||||
import { HelpCircle } from 'lucide-react'
|
||||
|
||||
type InheritedTooltipProps = Omit<TooltipProps, 'children'>
|
||||
|
||||
interface HelpTooltipProps extends InheritedTooltipProps {
|
||||
iconColor?: string
|
||||
iconSize?: string | number
|
||||
iconStyle?: React.CSSProperties
|
||||
}
|
||||
|
||||
const HelpTooltip = ({ iconColor = 'var(--color-text-2)', iconSize = 14, iconStyle, ...rest }: HelpTooltipProps) => {
|
||||
return (
|
||||
<Tooltip {...rest}>
|
||||
<HelpCircle size={iconSize} color={iconColor} style={{ ...iconStyle }} role="img" aria-label="Help" />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
export default HelpTooltip
|
||||
@ -9,7 +9,7 @@ interface InfoTooltipProps extends InheritedTooltipProps {
|
||||
iconStyle?: React.CSSProperties
|
||||
}
|
||||
|
||||
const InfoTooltip = ({ iconColor = 'var(--color-text-3)', iconSize = 14, iconStyle, ...rest }: InfoTooltipProps) => {
|
||||
const InfoTooltip = ({ iconColor = 'var(--color-text-2)', iconSize = 14, iconStyle, ...rest }: InfoTooltipProps) => {
|
||||
return (
|
||||
<Tooltip {...rest}>
|
||||
<Info size={iconSize} color={iconColor} style={{ ...iconStyle }} role="img" aria-label="Information" />
|
||||
3
src/renderer/src/components/TooltipIcons/index.ts
Normal file
3
src/renderer/src/components/TooltipIcons/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export { default as HelpTooltip } from './HelpTooltip'
|
||||
export { default as InfoTooltip } from './InfoTooltip'
|
||||
export { default as WarnTooltip } from './WarnTooltip'
|
||||
@ -538,7 +538,10 @@
|
||||
"tip": "The run button will be displayed in the toolbar of executable code blocks, please do not execute dangerous code!",
|
||||
"title": "Code Execution"
|
||||
},
|
||||
"code_image_tools": "Enable preview tools",
|
||||
"code_image_tools": {
|
||||
"label": "Enable preview tools",
|
||||
"tip": "Enable preview tools for images rendered from code blocks such as mermaid"
|
||||
},
|
||||
"code_wrappable": "Code block wrappable",
|
||||
"context_count": {
|
||||
"label": "Context",
|
||||
|
||||
@ -538,7 +538,10 @@
|
||||
"tip": "実行可能なコードブロックのツールバーには実行ボタンが表示されます。危険なコードを実行しないでください!",
|
||||
"title": "コード実行"
|
||||
},
|
||||
"code_image_tools": "プレビューツールを有効にする",
|
||||
"code_image_tools": {
|
||||
"label": "プレビューツールを有効にする",
|
||||
"tip": "mermaid などのコードブロックから生成された画像に対してプレビューツールを有効にする"
|
||||
},
|
||||
"code_wrappable": "コードブロック折り返し",
|
||||
"context_count": {
|
||||
"label": "コンテキスト",
|
||||
|
||||
@ -538,7 +538,10 @@
|
||||
"tip": "Выполнение кода в блоке кода возможно, но не рекомендуется выполнять опасный код!",
|
||||
"title": "Выполнение кода"
|
||||
},
|
||||
"code_image_tools": "Включить инструменты предпросмотра",
|
||||
"code_image_tools": {
|
||||
"label": "Включить инструменты предпросмотра",
|
||||
"tip": "Включить инструменты предпросмотра для изображений, сгенерированных из блоков кода (например mermaid)"
|
||||
},
|
||||
"code_wrappable": "Блок кода можно переносить",
|
||||
"context_count": {
|
||||
"label": "Контекст",
|
||||
|
||||
@ -538,7 +538,10 @@
|
||||
"tip": "可执行的代码块工具栏中会显示运行按钮,注意不要执行危险代码!",
|
||||
"title": "代码执行"
|
||||
},
|
||||
"code_image_tools": "启用预览工具",
|
||||
"code_image_tools": {
|
||||
"label": "启用预览工具",
|
||||
"tip": "为 mermaid 等代码块渲染后的图像启用预览工具"
|
||||
},
|
||||
"code_wrappable": "代码块可换行",
|
||||
"context_count": {
|
||||
"label": "上下文数",
|
||||
|
||||
@ -538,7 +538,10 @@
|
||||
"tip": "可執行的程式碼塊工具欄中會顯示運行按鈕,注意不要執行危險程式碼!",
|
||||
"title": "程式碼執行"
|
||||
},
|
||||
"code_image_tools": "啟用預覽工具",
|
||||
"code_image_tools": {
|
||||
"label": "啟用預覽工具",
|
||||
"tip": "為 mermaid 等程式碼區塊渲染後的圖像啟用預覽工具"
|
||||
},
|
||||
"code_wrappable": "程式碼區塊可自動換行",
|
||||
"context_count": {
|
||||
"label": "上下文",
|
||||
|
||||
@ -2,6 +2,7 @@ import EditableNumber from '@renderer/components/EditableNumber'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import Scrollbar from '@renderer/components/Scrollbar'
|
||||
import Selector from '@renderer/components/Selector'
|
||||
import { HelpTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { DEFAULT_CONTEXTCOUNT, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE } from '@renderer/config/constant'
|
||||
import { isOpenAIModel } from '@renderer/config/models'
|
||||
import { UNKNOWN } from '@renderer/config/translate'
|
||||
@ -48,8 +49,8 @@ import {
|
||||
import { Assistant, AssistantSettings, CodeStyleVarious, MathEngine, ThemeMode } from '@renderer/types'
|
||||
import { modalConfirm } from '@renderer/utils'
|
||||
import { getSendMessageShortcutLabel } from '@renderer/utils/input'
|
||||
import { Button, Col, InputNumber, Row, Slider, Switch, Tooltip } from 'antd'
|
||||
import { CircleHelp, Settings2 } from 'lucide-react'
|
||||
import { Button, Col, InputNumber, Row, Slider, Switch } from 'antd'
|
||||
import { Settings2 } from 'lucide-react'
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
@ -193,10 +194,10 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
}>
|
||||
<SettingGroup style={{ marginTop: 5 }}>
|
||||
<Row align="middle">
|
||||
<SettingRowTitleSmall>{t('chat.settings.temperature.label')}</SettingRowTitleSmall>
|
||||
<Tooltip title={t('chat.settings.temperature.tip')}>
|
||||
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
|
||||
</Tooltip>
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.temperature.label')}
|
||||
<HelpTooltip title={t('chat.settings.temperature.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
<Switch
|
||||
size="small"
|
||||
style={{ marginLeft: 'auto' }}
|
||||
@ -224,10 +225,10 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
<SettingDivider />
|
||||
)}
|
||||
<Row align="middle">
|
||||
<SettingRowTitleSmall>{t('chat.settings.context_count.label')}</SettingRowTitleSmall>
|
||||
<Tooltip title={t('chat.settings.context_count.tip')}>
|
||||
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
|
||||
</Tooltip>
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.context_count.label')}
|
||||
<HelpTooltip title={t('chat.settings.context_count.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
</Row>
|
||||
<Row align="middle" gutter={10}>
|
||||
<Col span={23}>
|
||||
@ -256,10 +257,10 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<Row align="middle">
|
||||
<SettingRowTitleSmall>{t('chat.settings.max_tokens.label')}</SettingRowTitleSmall>
|
||||
<Tooltip title={t('chat.settings.max_tokens.tip')}>
|
||||
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
|
||||
</Tooltip>
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.max_tokens.label')}
|
||||
<HelpTooltip title={t('chat.settings.max_tokens.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
</Row>
|
||||
<Switch
|
||||
size="small"
|
||||
@ -327,9 +328,7 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
<SettingRow>
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.thought_auto_collapse.label')}
|
||||
<Tooltip title={t('chat.settings.thought_auto_collapse.tip')}>
|
||||
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
|
||||
</Tooltip>
|
||||
<HelpTooltip title={t('chat.settings.thought_auto_collapse.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
<Switch
|
||||
size="small"
|
||||
@ -426,10 +425,8 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitleSmall>
|
||||
{t('settings.math.single_dollar.label')}{' '}
|
||||
<Tooltip title={t('settings.math.single_dollar.tip')}>
|
||||
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
|
||||
</Tooltip>
|
||||
{t('settings.math.single_dollar.label')}
|
||||
<HelpTooltip title={t('settings.math.single_dollar.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
<Switch
|
||||
size="small"
|
||||
@ -457,9 +454,7 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
<SettingRow>
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.code_execution.title')}
|
||||
<Tooltip title={t('chat.settings.code_execution.tip')}>
|
||||
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
|
||||
</Tooltip>
|
||||
<HelpTooltip title={t('chat.settings.code_execution.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
<Switch
|
||||
size="small"
|
||||
@ -473,9 +468,7 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
<SettingRow style={{ paddingLeft: 8 }}>
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.code_execution.timeout_minutes.label')}
|
||||
<Tooltip title={t('chat.settings.code_execution.timeout_minutes.tip')}>
|
||||
<CircleHelp size={14} style={{ marginLeft: 4 }} color="var(--color-text-2)" />
|
||||
</Tooltip>
|
||||
<HelpTooltip title={t('chat.settings.code_execution.timeout_minutes.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
<EditableNumber
|
||||
size="small"
|
||||
@ -563,7 +556,10 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
</SettingRow>
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingRowTitleSmall>{t('chat.settings.code_image_tools')}</SettingRowTitleSmall>
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.code_image_tools.label')}
|
||||
<HelpTooltip title={t('chat.settings.code_image_tools.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
<Switch
|
||||
size="small"
|
||||
checked={codeImageTools}
|
||||
@ -713,6 +709,7 @@ const Container = styled(Scrollbar)`
|
||||
|
||||
const SettingRowTitleSmall = styled(SettingRowTitle)`
|
||||
font-size: 13px;
|
||||
gap: 4px;
|
||||
`
|
||||
|
||||
const SettingGroup = styled.div<{ theme?: ThemeMode }>`
|
||||
|
||||
@ -25,8 +25,8 @@ const mocks = vi.hoisted(() => {
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@renderer/components/InfoTooltip', () => ({
|
||||
default: ({ title }: { title: string }) => <div>{mocks.i18n.t(title)}</div>
|
||||
vi.mock('@renderer/components/TooltipIcons', () => ({
|
||||
InfoTooltip: ({ title }: { title: string }) => <div>{mocks.i18n.t(title)}</div>
|
||||
}))
|
||||
|
||||
vi.mock('react-i18next', () => ({
|
||||
|
||||
@ -31,8 +31,8 @@ const mocks = vi.hoisted(() => ({
|
||||
}))
|
||||
|
||||
// Mock InfoTooltip component
|
||||
vi.mock('@renderer/components/InfoTooltip', () => ({
|
||||
default: ({ title, placement }: { title: string; placement: string }) => (
|
||||
vi.mock('@renderer/components/TooltipIcons', () => ({
|
||||
InfoTooltip: ({ title, placement }: { title: string; placement: string }) => (
|
||||
<span data-testid="info-tooltip" title={title} data-placement={placement}>
|
||||
ℹ️
|
||||
</span>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { KnowledgeBase } from '@renderer/types'
|
||||
import { Alert, InputNumber } from 'antd'
|
||||
import { TriangleAlert } from 'lucide-react'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import InputEmbeddingDimension from '@renderer/components/InputEmbeddingDimension'
|
||||
import ModelSelector from '@renderer/components/ModelSelector'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { DEFAULT_KNOWLEDGE_DOCUMENT_COUNT } from '@renderer/config/constant'
|
||||
import { isEmbeddingModel, isRerankModel } from '@renderer/config/models'
|
||||
import { useProviders } from '@renderer/hooks/useProvider'
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { loggerService } from '@logger'
|
||||
import AiProvider from '@renderer/aiCore'
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import InputEmbeddingDimension from '@renderer/components/InputEmbeddingDimension'
|
||||
import ModelSelector from '@renderer/components/ModelSelector'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { isEmbeddingModel, isRerankModel } from '@renderer/config/models'
|
||||
import { useModel } from '@renderer/hooks/useModel'
|
||||
import { useProviders } from '@renderer/hooks/useProvider'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// import { loggerService } from '@logger'
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import { SuccessTag } from '@renderer/components/Tags/SuccessTag'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { isMac, isWin } from '@renderer/config/constant'
|
||||
import { useOcrProvider } from '@renderer/hooks/useOcrProvider'
|
||||
import useTranslate from '@renderer/hooks/useTranslate'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// import { loggerService } from '@logger'
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import CustomTag from '@renderer/components/Tags/CustomTag'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { TESSERACT_LANG_MAP } from '@renderer/config/ocr'
|
||||
import { useOcrProvider } from '@renderer/hooks/useOcrProvider'
|
||||
import useTranslate from '@renderer/hooks/useTranslate'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { InfoCircleOutlined } from '@ant-design/icons'
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import Selector from '@renderer/components/Selector'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useEnableDeveloperMode, useSettings } from '@renderer/hooks/useSettings'
|
||||
import { useTimer } from '@renderer/hooks/useTimer'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { RedoOutlined } from '@ant-design/icons'
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import ModelSelector from '@renderer/components/ModelSelector'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { isEmbeddingModel, isRerankModel, isTextToImageModel } from '@renderer/config/models'
|
||||
import { TRANSLATE_PROMPT } from '@renderer/config/prompts'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { useProvider } from '@renderer/hooks/useProvider'
|
||||
import { Provider } from '@renderer/types'
|
||||
import { Flex, Switch } from 'antd'
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
VisionTag,
|
||||
WebSearchTag
|
||||
} from '@renderer/components/Tags/Model'
|
||||
import WarnTooltip from '@renderer/components/WarnTooltip'
|
||||
import { WarnTooltip } from '@renderer/components/TooltipIcons'
|
||||
import { endpointTypeOptions } from '@renderer/config/endpointTypes'
|
||||
import {
|
||||
isEmbeddingModel,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { loggerService } from '@logger'
|
||||
import EmojiPicker from '@renderer/components/EmojiPicker'
|
||||
import InfoTooltip from '@renderer/components/InfoTooltip'
|
||||
import { InfoTooltip } from '@renderer/components/TooltipIcons'
|
||||
import useTranslate from '@renderer/hooks/useTranslate'
|
||||
import { addCustomLanguage, updateCustomLanguage } from '@renderer/services/TranslateService'
|
||||
import { CustomTranslateLanguage } from '@renderer/types'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user