This commit is contained in:
kangfenmao 2025-11-03 18:39:39 +08:00
parent 3cc7ee01e2
commit 28fac543fc
22 changed files with 77 additions and 141 deletions

View File

@ -1,31 +0,0 @@
import { Avatar, cn } from '@heroui/react'
import { getModelLogoById } from '@renderer/config/models'
import type { ApiModel } from '@renderer/types'
import React from 'react'
import Ellipsis from './Ellipsis'
export interface ModelLabelProps extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {
model?: ApiModel
classNames?: {
container?: string
avatar?: string
modelName?: string
divider?: string
providerName?: string
}
}
export const ApiModelLabel: React.FC<ModelLabelProps> = ({ model, className, classNames, ...props }) => {
return (
<div className={cn('flex items-center gap-1', className, classNames?.container)} {...props}>
<Avatar
src={model ? (getModelLogoById(model.id) ?? getModelLogoById(model.name)) : undefined}
className={cn('h-4 w-4', classNames?.avatar)}
/>
<Ellipsis className={classNames?.modelName}>{model?.name}</Ellipsis>
<span className={classNames?.divider}> | </span>
<Ellipsis className={classNames?.providerName}>{model?.provider_name}</Ellipsis>
</div>
)
}

View File

@ -1,4 +1,4 @@
import { cn } from '@heroui/react' import { cn } from '@renderer/utils'
import type { ButtonProps } from 'antd' import type { ButtonProps } from 'antd'
import { Button } from 'antd' import { Button } from 'antd'
import React, { memo } from 'react' import React, { memo } from 'react'

View File

@ -1,5 +1,5 @@
import { cn } from '@heroui/react'
import Scrollbar from '@renderer/components/Scrollbar' import Scrollbar from '@renderer/components/Scrollbar'
import { cn } from '@renderer/utils'
import { ChevronRight } from 'lucide-react' import { ChevronRight } from 'lucide-react'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import styled from 'styled-components' import styled from 'styled-components'

View File

@ -1,5 +1,5 @@
import { cn } from '@heroui/react'
import { TopView } from '@renderer/components/TopView' import { TopView } from '@renderer/components/TopView'
import { cn } from '@renderer/utils'
import { Modal } from 'antd' import { Modal } from 'antd'
import { Bot, MessageSquare } from 'lucide-react' import { Bot, MessageSquare } from 'lucide-react'
import { useState } from 'react' import { useState } from 'react'

View File

@ -1,6 +1,5 @@
import { import {
Button, Button,
cn,
Form, Form,
Input, Input,
Modal, Modal,
@ -25,6 +24,7 @@ import type {
Tool, Tool,
UpdateSessionForm UpdateSessionForm
} from '@renderer/types' } from '@renderer/types'
import { cn } from '@renderer/utils'
import type { FormEvent, ReactNode } from 'react' import type { FormEvent, ReactNode } from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'

View File

@ -1,6 +1,7 @@
import type { SelectedItems, SelectProps } from '@heroui/react' import type { SelectedItems, SelectProps } from '@heroui/react'
import { Chip, cn, Select, SelectItem } from '@heroui/react' import { Chip, Select, SelectItem } from '@heroui/react'
import type { Tool } from '@renderer/types' import type { Tool } from '@renderer/types'
import { cn } from '@renderer/utils'
import React, { useCallback } from 'react' import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'

View File

@ -12,19 +12,7 @@ export default function useUserTheme() {
const colorPrimary = Color(theme.colorPrimary) const colorPrimary = Color(theme.colorPrimary)
document.body.style.setProperty('--color-primary', colorPrimary.toString()) document.body.style.setProperty('--color-primary', colorPrimary.toString())
// overwrite hero UI primary color.
document.body.style.setProperty('--primary', colorPrimary.toString()) document.body.style.setProperty('--primary', colorPrimary.toString())
document.body.style.setProperty('--heroui-primary', colorPrimary.toString())
document.body.style.setProperty('--heroui-primary-900', colorPrimary.lighten(0.5).toString())
document.body.style.setProperty('--heroui-primary-800', colorPrimary.lighten(0.4).toString())
document.body.style.setProperty('--heroui-primary-700', colorPrimary.lighten(0.3).toString())
document.body.style.setProperty('--heroui-primary-600', colorPrimary.lighten(0.2).toString())
document.body.style.setProperty('--heroui-primary-500', colorPrimary.lighten(0.1).toString())
document.body.style.setProperty('--heroui-primary-400', colorPrimary.toString())
document.body.style.setProperty('--heroui-primary-300', colorPrimary.darken(0.1).toString())
document.body.style.setProperty('--heroui-primary-200', colorPrimary.darken(0.2).toString())
document.body.style.setProperty('--heroui-primary-100', colorPrimary.darken(0.3).toString())
document.body.style.setProperty('--heroui-primary-50', colorPrimary.darken(0.4).toString())
document.body.style.setProperty('--color-primary-soft', colorPrimary.alpha(0.6).toString()) document.body.style.setProperty('--color-primary-soft', colorPrimary.alpha(0.6).toString())
document.body.style.setProperty('--color-primary-mute', colorPrimary.alpha(0.3).toString()) document.body.style.setProperty('--color-primary-mute', colorPrimary.alpha(0.3).toString())

View File

@ -1,4 +1,3 @@
import { Alert } from '@heroui/react'
import { loggerService } from '@logger' import { loggerService } from '@logger'
import type { ContentSearchRef } from '@renderer/components/ContentSearch' import type { ContentSearchRef } from '@renderer/components/ContentSearch'
import { ContentSearch } from '@renderer/components/ContentSearch' import { ContentSearch } from '@renderer/components/ContentSearch'
@ -17,7 +16,7 @@ import { useTimer } from '@renderer/hooks/useTimer'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import type { Assistant, Topic } from '@renderer/types' import type { Assistant, Topic } from '@renderer/types'
import { classNames } from '@renderer/utils' import { classNames } from '@renderer/utils'
import { Flex } from 'antd' import { Alert, Flex } from 'antd'
import { debounce } from 'lodash' import { debounce } from 'lodash'
import { AnimatePresence, motion } from 'motion/react' import { AnimatePresence, motion } from 'motion/react'
import type { FC } from 'react' import type { FC } from 'react'
@ -170,11 +169,7 @@ const Chat: FC<Props> = (props) => {
return () => <div> Active Session ID is invalid.</div> return () => <div> Active Session ID is invalid.</div>
} }
if (!apiServer.enabled) { if (!apiServer.enabled) {
return () => ( return () => <Alert type="warning" message={t('agent.warning.enable_server')} style={{ margin: '5px 16px' }} />
<div>
<Alert color="warning" title={t('agent.warning.enable_server')} />
</div>
)
} }
return () => <AgentSessionMessages agentId={activeAgentId} sessionId={activeSessionId} /> return () => <AgentSessionMessages agentId={activeAgentId} sessionId={activeSessionId} />
}, [activeAgentId, activeSessionId, apiServer.enabled, t]) }, [activeAgentId, activeSessionId, apiServer.enabled, t])
@ -191,22 +186,14 @@ const Chat: FC<Props> = (props) => {
// TODO: more info // TODO: more info
const AgentInvalid = useCallback(() => { const AgentInvalid = useCallback(() => {
return ( return <Alert type="warning" message="Select an agent" style={{ margin: '5px 16px' }} />
<div className="flex h-full w-full items-center justify-center">
<div>
<Alert color="warning" title="Select an agent" />
</div>
</div>
)
}, []) }, [])
// TODO: more info // TODO: more info
const SessionInvalid = useCallback(() => { const SessionInvalid = useCallback(() => {
return ( return (
<div className="flex h-full w-full items-center justify-center"> <div className="flex h-full w-full items-center justify-center">
<div> <Alert type="warning" message="Create a session" style={{ margin: '5px 16px' }} />
<Alert color="warning" title="Create a session" />
</div>
</div> </div>
) )
}, []) }, [])

View File

@ -1,4 +1,3 @@
import { cn } from '@heroui/react'
import { loggerService } from '@logger' import { loggerService } from '@logger'
import HorizontalScrollContainer from '@renderer/components/HorizontalScrollContainer' import HorizontalScrollContainer from '@renderer/components/HorizontalScrollContainer'
import Scrollbar from '@renderer/components/Scrollbar' import Scrollbar from '@renderer/components/Scrollbar'
@ -15,7 +14,7 @@ import { getModelUniqId } from '@renderer/services/ModelService'
import { estimateMessageUsage } from '@renderer/services/TokenService' import { estimateMessageUsage } from '@renderer/services/TokenService'
import type { Assistant, Topic } from '@renderer/types' import type { Assistant, Topic } from '@renderer/types'
import type { Message, MessageBlock } from '@renderer/types/newMessage' import type { Message, MessageBlock } from '@renderer/types/newMessage'
import { classNames } from '@renderer/utils' import { classNames, cn } from '@renderer/utils'
import { isMessageProcessing } from '@renderer/utils/messageUtils/is' import { isMessageProcessing } from '@renderer/utils/messageUtils/is'
import { Divider } from 'antd' import { Divider } from 'antd'
import type { Dispatch, FC, SetStateAction } from 'react' import type { Dispatch, FC, SetStateAction } from 'react'

View File

@ -1,9 +1,10 @@
import { Button, Divider } from '@heroui/react'
import type { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession' import type { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession'
import { SettingDivider } from '@renderer/pages/settings'
import { SessionSettingsPopup } from '@renderer/pages/settings/AgentSettings' import { SessionSettingsPopup } from '@renderer/pages/settings/AgentSettings'
import AdvancedSettings from '@renderer/pages/settings/AgentSettings/AdvancedSettings' import AdvancedSettings from '@renderer/pages/settings/AgentSettings/AdvancedSettings'
import EssentialSettings from '@renderer/pages/settings/AgentSettings/EssentialSettings' import EssentialSettings from '@renderer/pages/settings/AgentSettings/EssentialSettings'
import type { GetAgentSessionResponse } from '@renderer/types' import type { GetAgentSessionResponse } from '@renderer/types'
import { Button } from 'antd'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -31,9 +32,10 @@ const SessionSettingsTab: FC<Props> = ({ session, update }) => {
return ( return (
<div className="w-[var(--assistants-width)] p-2 px-3 pt-4"> <div className="w-[var(--assistants-width)] p-2 px-3 pt-4">
<EssentialSettings agentBase={session} update={update} showModelSetting={false} /> <EssentialSettings agentBase={session} update={update} showModelSetting={false} />
<SettingDivider />
<AdvancedSettings agentBase={session} update={update} /> <AdvancedSettings agentBase={session} update={update} />
<Divider className="my-2" /> <SettingDivider />
<Button size="sm" fullWidth onPress={onMoreSetting}> <Button size="small" block onClick={onMoreSetting}>
{t('settings.moresetting.label')} {t('settings.moresetting.label')}
</Button> </Button>
</div> </div>

View File

@ -1,6 +1,7 @@
import { Alert, cn } from '@heroui/react'
import { useRuntime } from '@renderer/hooks/useRuntime' import { useRuntime } from '@renderer/hooks/useRuntime'
import { useSettings } from '@renderer/hooks/useSettings' import { useSettings } from '@renderer/hooks/useSettings'
import { cn } from '@renderer/utils'
import { Alert } from 'antd'
import { AnimatePresence, motion } from 'framer-motion' import { AnimatePresence, motion } from 'framer-motion'
import type { FC } from 'react' import type { FC } from 'react'
import { memo } from 'react' import { memo } from 'react'
@ -17,19 +18,11 @@ const SessionsTab: FC<SessionsTabProps> = () => {
const { apiServer } = useSettings() const { apiServer } = useSettings()
if (!apiServer.enabled) { if (!apiServer.enabled) {
return ( return <Alert type="warning" message={t('agent.warning.enable_server')} style={{ margin: 10 }} />
<div>
<Alert color="warning" title={t('agent.warning.enable_server')} />
</div>
)
} }
if (!activeAgentId) { if (!activeAgentId) {
return ( return <Alert type="warning" message={'Select an agent'} style={{ margin: 10 }} />
<div>
<Alert color="warning" title={'Select an agent'} />
</div>
)
} }
return ( return (

View File

@ -1,5 +1,6 @@
import type { ButtonProps } from '@heroui/react' import type { ButtonProps } from '@heroui/react'
import { Button, cn } from '@heroui/react' import { Button } from '@heroui/react'
import { cn } from '@renderer/utils'
import { PlusIcon } from 'lucide-react' import { PlusIcon } from 'lucide-react'
import type { FC } from 'react' import type { FC } from 'react'

View File

@ -1,4 +1,3 @@
import { cn, Tooltip } from '@heroui/react'
import { DeleteIcon, EditIcon } from '@renderer/components/Icons' import { DeleteIcon, EditIcon } from '@renderer/components/Icons'
import { useSessions } from '@renderer/hooks/agents/useSessions' import { useSessions } from '@renderer/hooks/agents/useSessions'
import { useSettings } from '@renderer/hooks/useSettings' import { useSettings } from '@renderer/hooks/useSettings'
@ -7,6 +6,8 @@ import { AgentLabel } from '@renderer/pages/settings/AgentSettings/shared'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import type { AgentEntity } from '@renderer/types' import type { AgentEntity } from '@renderer/types'
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from '@renderer/ui/context-menu' import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from '@renderer/ui/context-menu'
import { cn } from '@renderer/utils'
import { Tooltip } from 'antd'
import { Bot } from 'lucide-react' import { Bot } from 'lucide-react'
import type { FC } from 'react' import type { FC } from 'react'
import { memo, useCallback } from 'react' import { memo, useCallback } from 'react'
@ -118,7 +119,7 @@ export const MenuButton: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ cla
export const BotIcon: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ ...props }) => { export const BotIcon: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ ...props }) => {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (
<Tooltip content={t('common.agent_one')} delay={500} closeDelay={0}> <Tooltip title={t('common.agent_one')} mouseEnterDelay={0.5}>
<MenuButton {...props}> <MenuButton {...props}>
<Bot size={14} className="text-primary" /> <Bot size={14} className="text-primary" />
</MenuButton> </MenuButton>

View File

@ -1,4 +1,3 @@
import { cn } from '@heroui/react'
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
import EmojiIcon from '@renderer/components/EmojiIcon' import EmojiIcon from '@renderer/components/EmojiIcon'
import { CopyIcon, DeleteIcon, EditIcon } from '@renderer/components/Icons' import { CopyIcon, DeleteIcon, EditIcon } from '@renderer/components/Icons'
@ -12,7 +11,7 @@ import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import { useAppDispatch } from '@renderer/store' import { useAppDispatch } from '@renderer/store'
import { setActiveTopicOrSessionAction } from '@renderer/store/runtime' import { setActiveTopicOrSessionAction } from '@renderer/store/runtime'
import type { Assistant, AssistantsSortType } from '@renderer/types' import type { Assistant, AssistantsSortType } from '@renderer/types'
import { getLeadingEmoji, uuid } from '@renderer/utils' import { cn, getLeadingEmoji, uuid } from '@renderer/utils'
import { hasTopicPendingRequests } from '@renderer/utils/queue' import { hasTopicPendingRequests } from '@renderer/utils/queue'
import type { MenuProps } from 'antd' import type { MenuProps } from 'antd'
import { Dropdown } from 'antd' import { Dropdown } from 'antd'

View File

@ -1,5 +1,5 @@
import { DownOutlined, RightOutlined } from '@ant-design/icons' import { DownOutlined, RightOutlined } from '@ant-design/icons'
import { cn } from '@heroui/react' import { cn } from '@renderer/utils'
import { Tooltip } from 'antd' import { Tooltip } from 'antd'
import type { FC, ReactNode } from 'react' import type { FC, ReactNode } from 'react'

View File

@ -1,4 +1,4 @@
import { Alert, Skeleton } from '@heroui/react' import { Skeleton } from '@heroui/react'
import AddAssistantPopup from '@renderer/components/Popups/AddAssistantPopup' import AddAssistantPopup from '@renderer/components/Popups/AddAssistantPopup'
import { useActiveSession } from '@renderer/hooks/agents/useActiveSession' import { useActiveSession } from '@renderer/hooks/agents/useActiveSession'
import { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession' import { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession'
@ -12,6 +12,7 @@ import { setActiveAgentId, setActiveTopicOrSessionAction } from '@renderer/store
import type { Assistant, Topic } from '@renderer/types' import type { Assistant, Topic } from '@renderer/types'
import type { Tab } from '@renderer/types/chat' import type { Tab } from '@renderer/types/chat'
import { classNames, getErrorMessage, uuid } from '@renderer/utils' import { classNames, getErrorMessage, uuid } from '@renderer/utils'
import { Alert } from 'antd'
import type { FC } from 'react' import type { FC } from 'react'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -170,12 +171,13 @@ const HomeTabs: FC<Props> = ({
<SessionSettingsTab session={session} update={updateSession} /> <SessionSettingsTab session={session} update={updateSession} />
</Skeleton> </Skeleton>
)} )}
{tab === 'settings' && isSessionView && sessionError && ( {tab === 'settings' && (
<div className="w-[var(--assistants-width)] p-2 px-3 pt-4"> <div className="w-[var(--assistants-width)] p-2 px-3 pt-4">
<Alert <Alert
color="danger" type="error"
title={t('agent.session.get.error.failed')} message={t('agent.session.get.error.failed')}
description={getErrorMessage(sessionError)} description={getErrorMessage(sessionError)}
style={{ padding: '10px 15px' }}
/> />
</div> </div>
)} )}

View File

@ -1,4 +1,3 @@
import { Button } from '@heroui/react'
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
import { SelectApiModelPopup } from '@renderer/components/Popups/SelectModelPopup' import { SelectApiModelPopup } from '@renderer/components/Popups/SelectModelPopup'
import { agentModelFilter } from '@renderer/config/models' import { agentModelFilter } from '@renderer/config/models'
@ -8,6 +7,7 @@ import type { AgentBaseWithId, ApiModel } from '@renderer/types'
import { isAgentEntity } from '@renderer/types' import { isAgentEntity } from '@renderer/types'
import { getModelFilterByAgentType } from '@renderer/utils/agentSession' import { getModelFilterByAgentType } from '@renderer/utils/agentSession'
import { apiModelAdapter } from '@renderer/utils/model' import { apiModelAdapter } from '@renderer/utils/model'
import { Button } from 'antd'
import { ChevronsUpDown } from 'lucide-react' import { ChevronsUpDown } from 'lucide-react'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -37,11 +37,11 @@ const SelectAgentBaseModelButton: FC<Props> = ({ agentBase: agent, onSelect, isD
return ( return (
<Button <Button
size="sm" size="small"
variant="light" type="text"
className="nodrag h-[28px] rounded-2xl px-1" style={{ borderRadius: 20, fontSize: 12, padding: 2 }}
onPress={onSelectModel} onClick={onSelectModel}
isDisabled={isDisabled}> disabled={isDisabled}>
<div className="flex items-center gap-1.5 overflow-x-hidden"> <div className="flex items-center gap-1.5 overflow-x-hidden">
<ModelAvatar model={model ? apiModelAdapter(model) : undefined} size={20} /> <ModelAvatar model={model ? apiModelAdapter(model) : undefined} size={20} />
<span className="truncate text-[var(--color-text)]"> <span className="truncate text-[var(--color-text)]">

View File

@ -1,5 +1,5 @@
import { Button, Input } from '@heroui/react'
import { loggerService } from '@logger' import { loggerService } from '@logger'
import { Button, Input, InputRef } from 'antd'
import type { WebviewTag } from 'electron' import type { WebviewTag } from 'electron'
import { ChevronDown, ChevronUp, X } from 'lucide-react' import { ChevronDown, ChevronUp, X } from 'lucide-react'
import type { FC } from 'react' import type { FC } from 'react'
@ -22,7 +22,7 @@ const WebviewSearch: FC<WebviewSearchProps> = ({ webviewRef, isWebviewReady, app
const [query, setQuery] = useState('') const [query, setQuery] = useState('')
const [matchCount, setMatchCount] = useState(0) const [matchCount, setMatchCount] = useState(0)
const [activeIndex, setActiveIndex] = useState(0) const [activeIndex, setActiveIndex] = useState(0)
const inputRef = useRef<HTMLInputElement>(null) const inputRef = useRef<InputRef>(null)
const focusFrameRef = useRef<number | null>(null) const focusFrameRef = useRef<number | null>(null)
const lastAppIdRef = useRef<string>(appId) const lastAppIdRef = useRef<string>(appId)
const attachedWebviewRef = useRef<WebviewTag | null>(null) const attachedWebviewRef = useRef<WebviewTag | null>(null)
@ -315,19 +315,13 @@ const WebviewSearch: FC<WebviewSearchProps> = ({ webviewRef, isWebviewReady, app
ref={inputRef} ref={inputRef}
autoFocus autoFocus
value={query} value={query}
onValueChange={setQuery} onChange={(e) => setQuery(e.target.value)}
spellCheck={'false'} spellCheck={false}
placeholder={t('common.search')} placeholder={t('common.search')}
size="sm" size="small"
radius="sm" variant="borderless"
variant="flat" className="w-[240px]"
classNames={{ style={{ height: '32px' }}
base: 'w-[240px]',
inputWrapper:
'h-8 bg-transparent border border-transparent shadow-none hover:border-transparent hover:bg-transparent focus:border-transparent data-[hover=true]:border-transparent data-[focus=true]:border-transparent data-[focus-visible=true]:outline-none data-[focus-visible=true]:ring-0',
input: 'text-small focus:outline-none focus-visible:outline-none',
innerWrapper: 'gap-0'
}}
/> />
<span <span
className="min-w-[44px] text-center text-default-500 text-small tabular-nums" className="min-w-[44px] text-center text-default-500 text-small tabular-nums"
@ -339,38 +333,32 @@ const WebviewSearch: FC<WebviewSearchProps> = ({ webviewRef, isWebviewReady, app
</span> </span>
<div className="h-4 w-px bg-default-200" /> <div className="h-4 w-px bg-default-200" />
<Button <Button
size="sm" size="small"
variant="light" type="text"
radius="full" onClick={goToPrevious}
isIconOnly disabled={disableNavigation}
onPress={goToPrevious}
isDisabled={disableNavigation}
aria-label="Previous match" aria-label="Previous match"
className="text-default-500 hover:text-default-900"> icon={<ChevronUp size={16} className="w-6" />}
<ChevronUp size={16} /> className="text-default-500 hover:text-default-900"
</Button> />
<Button <Button
size="sm" size="small"
variant="light" type="text"
radius="full" onClick={goToNext}
isIconOnly disabled={disableNavigation}
onPress={goToNext}
isDisabled={disableNavigation}
aria-label="Next match" aria-label="Next match"
className="text-default-500 hover:text-default-900"> icon={<ChevronDown size={16} className="w-6" />}
<ChevronDown size={16} /> className="text-default-500 hover:text-default-900"
</Button> />
<div className="h-4 w-px bg-default-200" /> <div className="h-4 w-px bg-default-200" />
<Button <Button
size="sm" size="small"
variant="light" type="text"
radius="full" onClick={closeSearch}
isIconOnly
onPress={closeSearch}
aria-label={t('common.close')} aria-label={t('common.close')}
className="text-default-500 hover:text-default-900"> icon={<X size={16} className="w-6" />}
<X size={16} /> className="text-default-500 hover:text-default-900"
</Button> />
</div> </div>
) )
} }

View File

@ -1,10 +1,10 @@
import { Avatar } from '@heroui/react'
import { getAgentTypeAvatar } from '@renderer/config/agent' import { getAgentTypeAvatar } from '@renderer/config/agent'
import type { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent' import type { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
import type { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession' import type { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession'
import { getAgentTypeLabel } from '@renderer/i18n/label' import { getAgentTypeLabel } from '@renderer/i18n/label'
import type { GetAgentResponse, GetAgentSessionResponse } from '@renderer/types' import type { GetAgentResponse, GetAgentSessionResponse } from '@renderer/types'
import { isAgentEntity } from '@renderer/types' import { isAgentEntity } from '@renderer/types'
import { Avatar } from 'antd'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -42,7 +42,7 @@ const EssentialSettings: FC<EssentialSettingsProps> = ({ agentBase, update, show
<SettingsItem inline> <SettingsItem inline>
<SettingsTitle>{t('agent.type.label')}</SettingsTitle> <SettingsTitle>{t('agent.type.label')}</SettingsTitle>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar src={getAgentTypeAvatar(agentBase.type)} className="h-6 w-6 text-lg" /> <Avatar size={24} src={getAgentTypeAvatar(agentBase.type)} className="h-6 w-6 text-lg" />
<span>{(agentBase?.name ?? agentBase?.type) ? getAgentTypeLabel(agentBase.type) : ''}</span> <span>{(agentBase?.name ?? agentBase?.type) ? getAgentTypeLabel(agentBase.type) : ''}</span>
</div> </div>
</SettingsItem> </SettingsItem>

View File

@ -1,7 +1,7 @@
import { cn } from '@heroui/react'
import EmojiIcon from '@renderer/components/EmojiIcon' import EmojiIcon from '@renderer/components/EmojiIcon'
import { getAgentTypeLabel } from '@renderer/i18n/label' import { getAgentTypeLabel } from '@renderer/i18n/label'
import type { AgentEntity, AgentSessionEntity } from '@renderer/types' import type { AgentEntity, AgentSessionEntity } from '@renderer/types'
import { cn } from '@renderer/utils'
import { Menu, Modal } from 'antd' import { Menu, Modal } from 'antd'
import type { ReactNode } from 'react' import type { ReactNode } from 'react'
import React from 'react' import React from 'react'

View File

@ -3,7 +3,7 @@
import * as React from 'react' import * as React from 'react'
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu' import * as ContextMenuPrimitive from '@radix-ui/react-context-menu'
import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react' import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react'
import { cn } from '@heroui/react' import { cn } from '@renderer/utils'
function ContextMenu({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Root>) { function ContextMenu({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} /> return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />

View File

@ -1,5 +1,7 @@
import type { HexColor } from '@renderer/types' import type { HexColor } from '@renderer/types'
import { isHexColor } from '@renderer/types' import { isHexColor } from '@renderer/types'
import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
type ClassValue = string | number | boolean | undefined | null | ClassDictionary | ClassArray type ClassValue = string | number | boolean | undefined | null | ClassDictionary | ClassArray
@ -202,3 +204,7 @@ export function getForegroundColor(backgroundColor: HexColor): HexColor {
// ` // `
// return acc // return acc
// }, {} as MediaQueries) // }, {} as MediaQueries)
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}