From 99962b740c982b007d4e57114c5c8c8fd989fb35 Mon Sep 17 00:00:00 2001 From: MyPrototypeWhat Date: Mon, 29 Sep 2025 17:47:17 +0800 Subject: [PATCH] feat: add EmojiAvatar component and update component exports - Introduced a new EmojiAvatar component for enhanced avatar functionality. - Updated index.ts to export the new EmojiAvatar alongside existing components. - Removed the old display/EmojiAvatar component to streamline the codebase. - Adjusted various components to utilize the new Avatar structure and styling. --- .../components/base/Avatar/EmojiAvatar.tsx | 43 +++++++++++++++ .../ui/src/components/base/Avatar/index.tsx | 26 +++++++++ .../components/display/EmojiAvatar/index.tsx | 35 ------------ .../display/ProviderAvatar/index.tsx | 2 +- packages/ui/src/components/index.ts | 2 +- .../{display => base}/EmojiAvatar.stories.tsx | 2 +- .../src/components/Avatar/EmojiAvatar.tsx | 53 ------------------- .../src/components/Avatar/ModelAvatar.tsx | 21 ++------ .../MinApp/MinappPopupContainer.tsx | 5 +- src/renderer/src/components/ModelSelector.tsx | 5 +- .../Popups/SelectModelPopup/popup.tsx | 5 +- .../src/components/Popups/UserPopup.tsx | 4 +- .../src/components/ProviderAvatar.tsx | 15 ++++-- .../components/ProviderLogoPicker/index.tsx | 2 +- src/renderer/src/components/app/Sidebar.tsx | 4 +- src/renderer/src/hooks/useOcrProvider.tsx | 6 +-- src/renderer/src/pages/code/CodeToolsPage.tsx | 5 +- .../home/Inputbar/MentionModelsButton.tsx | 7 +-- .../pages/home/Messages/ChatFlowHistory.tsx | 11 ++-- .../pages/home/Messages/MessageAnchorLine.tsx | 8 +-- .../home/Messages/MessageGroupModelList.tsx | 27 ++++++++-- .../src/pages/home/Messages/MessageHeader.tsx | 8 +-- src/renderer/src/pages/minapps/MinAppPage.tsx | 4 +- .../minapps/components/MinAppFullPageView.tsx | 4 +- .../src/pages/paintings/AihubmixPage.tsx | 15 ++++-- .../src/pages/paintings/DmxapiPage.tsx | 18 ++++--- .../src/pages/paintings/NewApiPage.tsx | 19 +++---- .../src/pages/paintings/TokenFluxPage.tsx | 19 ++++--- .../src/pages/paintings/ZhipuPage.tsx | 9 ++-- .../src/pages/settings/AboutSettings.tsx | 5 +- .../PreprocessProviderSettings.tsx | 9 +++- .../settings/MemorySettings/UserSelector.tsx | 5 +- .../ModelList/ManageModelsList.tsx | 8 ++- .../ModelList/ModelListGroup.tsx | 1 + .../ModelList/ModelListItem.tsx | 5 +- .../selection/toolbar/SelectionToolbar.tsx | 2 +- 36 files changed, 225 insertions(+), 194 deletions(-) create mode 100644 packages/ui/src/components/base/Avatar/EmojiAvatar.tsx create mode 100644 packages/ui/src/components/base/Avatar/index.tsx delete mode 100644 packages/ui/src/components/display/EmojiAvatar/index.tsx rename packages/ui/stories/components/{display => base}/EmojiAvatar.stories.tsx (98%) delete mode 100644 src/renderer/src/components/Avatar/EmojiAvatar.tsx diff --git a/packages/ui/src/components/base/Avatar/EmojiAvatar.tsx b/packages/ui/src/components/base/Avatar/EmojiAvatar.tsx new file mode 100644 index 0000000000..20df79d9e0 --- /dev/null +++ b/packages/ui/src/components/base/Avatar/EmojiAvatar.tsx @@ -0,0 +1,43 @@ +import { cn } from '@heroui/react' +import React, { memo } from 'react' + +interface EmojiAvatarProps { + children: string + size?: number + fontSize?: number + onClick?: React.MouseEventHandler + className?: string + style?: React.CSSProperties +} + +const EmojiAvatar = ({ + children, + size = 31, + fontSize, + onClick, + className, + style +}: EmojiAvatarProps) => ( +
+ {children} +
+) + +EmojiAvatar.displayName = 'EmojiAvatar' + +export default memo(EmojiAvatar) \ No newline at end of file diff --git a/packages/ui/src/components/base/Avatar/index.tsx b/packages/ui/src/components/base/Avatar/index.tsx new file mode 100644 index 0000000000..f962b4e789 --- /dev/null +++ b/packages/ui/src/components/base/Avatar/index.tsx @@ -0,0 +1,26 @@ +import type { AvatarProps as HeroUIAvatarProps } from '@heroui/react' +import { Avatar as HeroUIAvatar, AvatarGroup as HeroUIAvatarGroup, cn } from '@heroui/react' + +import EmojiAvatar from './EmojiAvatar' + +export interface AvatarProps extends Omit { + size?: 'xs' | 'sm' | 'md' | 'lg' +} + +const Avatar = (props: AvatarProps) => { + const { size, className = '', ...rest } = props + const isExtraSmall = size === 'xs' + + const resolvedSize = isExtraSmall ? undefined : size + const mergedClassName = cn(isExtraSmall && 'w-6 h-6 text-tiny', 'shadow-lg', className) + + return +} + +Avatar.displayName = 'Avatar' + +const AvatarGroup = HeroUIAvatarGroup + +AvatarGroup.displayName = 'AvatarGroup' + +export { Avatar, AvatarGroup, EmojiAvatar } diff --git a/packages/ui/src/components/display/EmojiAvatar/index.tsx b/packages/ui/src/components/display/EmojiAvatar/index.tsx deleted file mode 100644 index 1386a889b2..0000000000 --- a/packages/ui/src/components/display/EmojiAvatar/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -// Original path: src/renderer/src/components/Avatar/EmojiAvatar.tsx -import { memo } from 'react' - -interface EmojiAvatarProps { - children: string - size?: number - fontSize?: number - onClick?: React.MouseEventHandler - className?: string - style?: React.CSSProperties - ref?: React.RefObject -} - -const EmojiAvatar = ({ children, size = 31, fontSize, onClick, className = '', style, ref }: EmojiAvatarProps) => { - const computedFontSize = fontSize ?? size * 0.5 - - return ( -
- {children} -
- ) -} - -EmojiAvatar.displayName = 'EmojiAvatar' - -export default memo(EmojiAvatar) diff --git a/packages/ui/src/components/display/ProviderAvatar/index.tsx b/packages/ui/src/components/display/ProviderAvatar/index.tsx index 7baa984ad2..0fd147b9b7 100644 --- a/packages/ui/src/components/display/ProviderAvatar/index.tsx +++ b/packages/ui/src/components/display/ProviderAvatar/index.tsx @@ -1,7 +1,7 @@ // Original path: src/renderer/src/components/ProviderAvatar.tsx -import { Avatar } from '@heroui/react' import React from 'react' +import { Avatar } from '../../base/Avatar' import { generateColorFromChar, getFirstCharacter, getForegroundColor } from './utils' interface ProviderAvatarProps { diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 9999c43ec7..0fa4abca08 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -1,4 +1,5 @@ // Base Components +export { Avatar, AvatarGroup, type AvatarProps,EmojiAvatar } from './base/Avatar' export { default as Button, type ButtonProps } from './base/Button' export { default as CopyButton } from './base/CopyButton' export { default as CustomCollapse } from './base/CustomCollapse' @@ -17,7 +18,6 @@ export { getToastUtilities, type ToastUtilities } from './base/Toast' // Display Components export { default as Ellipsis } from './display/Ellipsis' -export { default as EmojiAvatar } from './display/EmojiAvatar' export { default as ExpandableText } from './display/ExpandableText' export { default as ListItem } from './display/ListItem' export { default as MaxContextCount } from './display/MaxContextCount' diff --git a/packages/ui/stories/components/display/EmojiAvatar.stories.tsx b/packages/ui/stories/components/base/EmojiAvatar.stories.tsx similarity index 98% rename from packages/ui/stories/components/display/EmojiAvatar.stories.tsx rename to packages/ui/stories/components/base/EmojiAvatar.stories.tsx index affce714d2..54e6e09903 100644 --- a/packages/ui/stories/components/display/EmojiAvatar.stories.tsx +++ b/packages/ui/stories/components/base/EmojiAvatar.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react' -import EmojiAvatar from '../../../src/components/display/EmojiAvatar' +import EmojiAvatar from '../../../src/components/base/Avatar/EmojiAvatar' const meta: Meta = { title: 'Display/EmojiAvatar', diff --git a/src/renderer/src/components/Avatar/EmojiAvatar.tsx b/src/renderer/src/components/Avatar/EmojiAvatar.tsx deleted file mode 100644 index e01024735a..0000000000 --- a/src/renderer/src/components/Avatar/EmojiAvatar.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React, { memo } from 'react' -import styled from 'styled-components' - -interface EmojiAvatarProps { - children: string - size?: number - fontSize?: number - onClick?: React.MouseEventHandler - className?: string - style?: React.CSSProperties -} - -const EmojiAvatar = ({ - ref, - children, - size = 31, - fontSize, - onClick, - className, - style -}: EmojiAvatarProps & { ref?: React.RefObject }) => ( - - {children} - -) - -EmojiAvatar.displayName = 'EmojiAvatar' - -const StyledEmojiAvatar = styled.div<{ $size: number; $fontSize: number }>` - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-background-soft); - border: 0.5px solid var(--color-border); - border-radius: 20%; - cursor: pointer; - width: ${(props) => props.$size}px; - height: ${(props) => props.$size}px; - font-size: ${(props) => props.$fontSize}px; - transition: opacity 0.3s ease; - - &:hover { - opacity: 0.8; - } -` - -export default memo(EmojiAvatar) diff --git a/src/renderer/src/components/Avatar/ModelAvatar.tsx b/src/renderer/src/components/Avatar/ModelAvatar.tsx index d1589822b0..dccbeb0a68 100644 --- a/src/renderer/src/components/Avatar/ModelAvatar.tsx +++ b/src/renderer/src/components/Avatar/ModelAvatar.tsx @@ -1,7 +1,7 @@ +import type { AvatarProps } from '@cherrystudio/ui' +import { Avatar, cn } from '@cherrystudio/ui' import { getModelLogo } from '@renderer/config/models' import type { Model } from '@renderer/types' -import type { AvatarProps } from 'antd' -import { Avatar } from 'antd' import { first } from 'lodash' import type { FC } from 'react' @@ -12,21 +12,10 @@ interface Props { className?: string } -const ModelAvatar: FC = ({ model, size, props, className }) => { +const ModelAvatar: FC = ({ model, size, className, ...props }) => { + const classNames = cn('flex items-center justify-center', `h-[${size}px] w-[${size}px]`, `${className || ''}`) return ( - + {first(model?.name)} ) diff --git a/src/renderer/src/components/MinApp/MinappPopupContainer.tsx b/src/renderer/src/components/MinApp/MinappPopupContainer.tsx index 10df610f80..693bf9f9de 100644 --- a/src/renderer/src/components/MinApp/MinappPopupContainer.tsx +++ b/src/renderer/src/components/MinApp/MinappPopupContainer.tsx @@ -11,6 +11,7 @@ import { ReloadOutlined } from '@ant-design/icons' import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' import WindowControls from '@renderer/components/WindowControls' @@ -25,7 +26,7 @@ import { useTimer } from '@renderer/hooks/useTimer' import type { MinAppType } from '@renderer/types' import { delay } from '@renderer/utils' import { clearWebviewState, getWebviewLoaded, setWebviewLoaded } from '@renderer/utils/webviewStateManager' -import { Alert, Avatar, Drawer, Tooltip } from 'antd' +import { Alert, Drawer, Tooltip } from 'antd' import type { WebviewTag } from 'electron' import { useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -550,7 +551,7 @@ const MinappPopupContainer: React.FC = () => { diff --git a/src/renderer/src/components/ModelSelector.tsx b/src/renderer/src/components/ModelSelector.tsx index 12666b4d4b..ee06bb6525 100644 --- a/src/renderer/src/components/ModelSelector.tsx +++ b/src/renderer/src/components/ModelSelector.tsx @@ -1,10 +1,11 @@ +import { Avatar } from '@cherrystudio/ui' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import { getModelUniqId } from '@renderer/services/ModelService' import type { Model, Provider } from '@renderer/types' import { matchKeywordsInString } from '@renderer/utils' import { getFancyProviderName } from '@renderer/utils/naming' import type { SelectProps } from 'antd' -import { Avatar, Select } from 'antd' +import { Select } from 'antd' import { sortBy } from 'lodash' import type { BaseSelectRef } from 'rc-select' import { memo, useCallback, useMemo } from 'react' @@ -107,7 +108,7 @@ const ModelSelector = ({ } else { return (
- {showAvatar && } + {showAvatar && } {t('knowledge.error.model_invalid')}
) diff --git a/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx b/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx index c9c6abd532..1f50cc1598 100644 --- a/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx +++ b/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx @@ -1,5 +1,6 @@ import { PushpinOutlined } from '@ant-design/icons' import { Flex } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { FreeTrialModelTag } from '@renderer/components/FreeTrialModelTag' import ModelTagsWithLabel from '@renderer/components/ModelTagsWithLabel' import { TopView } from '@renderer/components/TopView' @@ -12,7 +13,7 @@ import type { Model, ModelType, Provider } from '@renderer/types' import { objectEntries } from '@renderer/types' import { classNames, filterModelsByKeywords, getFancyProviderName } from '@renderer/utils' import { getModelTags } from '@renderer/utils/model' -import { Avatar, Divider, Empty, Modal, Tooltip } from 'antd' +import { Divider, Empty, Modal, Tooltip } from 'antd' import { first, sortBy } from 'lodash' import { Settings2 } from 'lucide-react' import React, { @@ -124,7 +125,7 @@ const PopupContainer: React.FC = ({ model, filter: baseFilter, showTagFil ), icon: ( - + {first(model.name) || 'M'} ), diff --git a/src/renderer/src/components/Popups/UserPopup.tsx b/src/renderer/src/components/Popups/UserPopup.tsx index 24c6eb47e7..b627e42135 100644 --- a/src/renderer/src/components/Popups/UserPopup.tsx +++ b/src/renderer/src/components/Popups/UserPopup.tsx @@ -1,12 +1,12 @@ import { Center, ColFlex, RowFlex } from '@cherrystudio/ui' +import { Avatar, EmojiAvatar } from '@cherrystudio/ui' import { cacheService } from '@data/CacheService' import { usePreference } from '@data/hooks/usePreference' import DefaultAvatar from '@renderer/assets/images/avatar.png' -import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import useAvatar from '@renderer/hooks/useAvatar' import ImageStorage from '@renderer/services/ImageStorage' import { compressImage, isEmoji } from '@renderer/utils' -import { Avatar, Dropdown, Input, Modal, Popover, Upload } from 'antd' +import { Dropdown, Input, Modal, Popover, Upload } from 'antd' import React, { useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' diff --git a/src/renderer/src/components/ProviderAvatar.tsx b/src/renderer/src/components/ProviderAvatar.tsx index 1861539040..02ec09388e 100644 --- a/src/renderer/src/components/ProviderAvatar.tsx +++ b/src/renderer/src/components/ProviderAvatar.tsx @@ -1,8 +1,8 @@ +import { Avatar } from '@cherrystudio/ui' import { PoeLogo } from '@renderer/components/Icons' import { getProviderLogo } from '@renderer/config/providers' import type { Provider } from '@renderer/types' import { generateColorFromChar, getFirstCharacter, getForegroundColor } from '@renderer/utils' -import { Avatar } from 'antd' import React from 'react' import styled from 'styled-components' @@ -63,7 +63,13 @@ export const ProviderAvatarPrimitive: React.FC = ( if (logoSrc) { return ( - + ) } @@ -72,10 +78,11 @@ export const ProviderAvatarPrimitive: React.FC = ( return ( = ({ onProviderClick }) => { {filteredProviders.map(({ id, name, logo }) => ( handleProviderClick(e, id)}> - + ))} diff --git a/src/renderer/src/components/app/Sidebar.tsx b/src/renderer/src/components/app/Sidebar.tsx index 5dd406b353..b0a3117a8e 100644 --- a/src/renderer/src/components/app/Sidebar.tsx +++ b/src/renderer/src/components/app/Sidebar.tsx @@ -1,5 +1,5 @@ +import { Avatar, EmojiAvatar } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import { isMac } from '@renderer/config/constant' import { UserAvatar } from '@renderer/config/env' import { useTheme } from '@renderer/context/ThemeProvider' @@ -13,7 +13,7 @@ import { useSettings } from '@renderer/hooks/useSettings' import { getSidebarIconLabel, getThemeModeLabel } from '@renderer/i18n/label' import { isEmoji } from '@renderer/utils' import { ThemeMode } from '@shared/data/preference/preferenceTypes' -import { Avatar, Tooltip } from 'antd' +import { Tooltip } from 'antd' import { Code, FileSearch, diff --git a/src/renderer/src/hooks/useOcrProvider.tsx b/src/renderer/src/hooks/useOcrProvider.tsx index d430245d68..d34a2915dd 100644 --- a/src/renderer/src/hooks/useOcrProvider.tsx +++ b/src/renderer/src/hooks/useOcrProvider.tsx @@ -1,3 +1,4 @@ +import { Avatar } from '@cherrystudio/ui' import { loggerService } from '@logger' import PaddleocrLogo from '@renderer/assets/images/providers/paddleocr.png' import TesseractLogo from '@renderer/assets/images/providers/Tesseract.js.png' @@ -7,7 +8,6 @@ import { useAppSelector } from '@renderer/store' import { addOcrProvider, removeOcrProvider, setImageOcrProviderId, updateOcrProviderConfig } from '@renderer/store/ocr' import type { ImageOcrProvider, OcrProvider, OcrProviderConfig } from '@renderer/types' import { isBuiltinOcrProvider, isBuiltinOcrProviderId, isImageOcrProvider } from '@renderer/types' -import { Avatar } from 'antd' import { FileQuestionMarkIcon, MonitorIcon } from 'lucide-react' import { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -72,11 +72,11 @@ export const useOcrProviders = () => { if (isBuiltinOcrProvider(p)) { switch (p.id) { case 'tesseract': - return + return case 'system': return case 'paddleocr': - return + return } } return diff --git a/src/renderer/src/pages/code/CodeToolsPage.tsx b/src/renderer/src/pages/code/CodeToolsPage.tsx index 8243884b87..6e33566600 100644 --- a/src/renderer/src/pages/code/CodeToolsPage.tsx +++ b/src/renderer/src/pages/code/CodeToolsPage.tsx @@ -1,4 +1,5 @@ import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import AiProvider from '@renderer/aiCore' import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' import ModelSelector from '@renderer/components/ModelSelector' @@ -17,7 +18,7 @@ import { setIsBunInstalled } from '@renderer/store/mcp' import type { EndpointType, Model } from '@renderer/types' import type { TerminalConfig } from '@shared/config/constant' import { codeTools, terminalApps } from '@shared/config/constant' -import { Alert, Avatar, Checkbox, Input, Popover, Select, Space, Tooltip } from 'antd' +import { Alert, Checkbox, Input, Popover, Select, Space, Tooltip } from 'antd' import { ArrowUpRight, Download, FolderOpen, HelpCircle, Terminal, X } from 'lucide-react' import type { FC } from 'react' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -363,7 +364,7 @@ const CodeToolsPage: FC = () => { key={provider.id} style={{ color: 'var(--color-text)', display: 'flex', alignItems: 'center', gap: 4 }} to={`/settings/provider?id=${provider.id}`}> - + {getProviderLabel(provider.id)} diff --git a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx index a383d72c8e..aadea82508 100644 --- a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx @@ -1,3 +1,4 @@ +import { Avatar } from '@cherrystudio/ui' import { ActionIconButton } from '@renderer/components/Buttons' import ModelTagsWithLabel from '@renderer/components/ModelTagsWithLabel' import { type QuickPanelListItem, QuickPanelReservedSymbol, useQuickPanel } from '@renderer/components/QuickPanel' @@ -7,7 +8,7 @@ import { useProviders } from '@renderer/hooks/useProvider' import { getModelUniqId } from '@renderer/services/ModelService' import type { FileType, Model } from '@renderer/types' import { getFancyProviderName } from '@renderer/utils' -import { Avatar, Tooltip } from 'antd' +import { Tooltip } from 'antd' import { useLiveQuery } from 'dexie-react-hooks' import { first, sortBy } from 'lodash' import { AtSign, CircleX, Plus } from 'lucide-react' @@ -135,7 +136,7 @@ const MentionModelsButton: FC = ({ ), description: , icon: ( - + {first(m.name)} ), @@ -171,7 +172,7 @@ const MentionModelsButton: FC = ({ ), description: , icon: ( - + {first(m.name)} ), diff --git a/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx b/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx index ee086d18c2..46347780af 100644 --- a/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx +++ b/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx @@ -1,8 +1,9 @@ import '@xyflow/react/dist/style.css' import { RobotOutlined, UserOutlined } from '@ant-design/icons' +import { Avatar } from '@cherrystudio/ui' +import { EmojiAvatar } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import { getModelLogo } from '@renderer/config/models' import { useTheme } from '@renderer/context/ThemeProvider' @@ -17,7 +18,7 @@ import { getMainTextContent } from '@renderer/utils/messageUtils/find' import type { Edge, Node, NodeTypes } from '@xyflow/react' import { Controls, Handle, MiniMap, ReactFlow, ReactFlowProvider } from '@xyflow/react' import { Position, useEdgesState, useNodesState } from '@xyflow/react' -import { Avatar, Spin, Tooltip } from 'antd' +import { Spin, Tooltip } from 'antd' import { isEqual } from 'lodash' import type { FC } from 'react' import { memo, useCallback, useEffect, useMemo, useState } from 'react' @@ -77,7 +78,7 @@ const CustomNode: FC<{ data: any }> = ({ data }) => { avatar = } } else { - avatar = } style={{ backgroundColor: 'var(--color-info)' }} /> + avatar = } className="bg-info" /> } } else if (nodeType === 'assistant') { borderColor = 'var(--color-primary)' @@ -94,11 +95,11 @@ const CustomNode: FC<{ data: any }> = ({ data }) => { : undefined} - style={{ backgroundColor: 'var(--color-primary)' }} + className="bg-primary" /> ) } else { - avatar = } style={{ backgroundColor: 'var(--color-primary)' }} /> + avatar = } className="bg-primary" /> } } diff --git a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx index cfd48ca0c2..9853c6b6c0 100644 --- a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx +++ b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx @@ -1,5 +1,5 @@ +import { Avatar, EmojiAvatar } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' -import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import { APP_NAME, AppLogo, isLocalAi } from '@renderer/config/env' import { getModelLogo } from '@renderer/config/models' import { useTheme } from '@renderer/context/ThemeProvider' @@ -13,7 +13,6 @@ import { newMessagesActions } from '@renderer/store/newMessage' import type { Message } from '@renderer/types/newMessage' import { isEmoji, removeLeadingEmoji } from '@renderer/utils' import { getMainTextContent } from '@renderer/utils/messageUtils/find' -import { Avatar } from 'antd' import { CircleChevronDown } from 'lucide-react' import { type FC, useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -227,8 +226,9 @@ const MessageAnchorLine: FC = ({ messages }) => { {message.role === 'assistant' ? ( = ({ messages }) => { {avatar} ) : ( - + )} )} diff --git a/src/renderer/src/pages/home/Messages/MessageGroupModelList.tsx b/src/renderer/src/pages/home/Messages/MessageGroupModelList.tsx index 42b153f398..096829c8dc 100644 --- a/src/renderer/src/pages/home/Messages/MessageGroupModelList.tsx +++ b/src/renderer/src/pages/home/Messages/MessageGroupModelList.tsx @@ -1,13 +1,15 @@ import { ArrowsAltOutlined, ShrinkOutlined } from '@ant-design/icons' -import { RowFlex } from '@cherrystudio/ui' +import { Avatar, AvatarGroup, RowFlex } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import Scrollbar from '@renderer/components/Scrollbar' +import { getModelLogo } from '@renderer/config/models' import type { Model } from '@renderer/types' import { AssistantMessageStatus, type Message } from '@renderer/types/newMessage' import { lightbulbSoftVariants } from '@renderer/utils/motionVariants' import type { MultiModelFoldDisplayMode } from '@shared/data/preference/preferenceTypes' -import { Avatar, Segmented as AntdSegmented, Tooltip } from 'antd' +import { Segmented as AntdSegmented, Tooltip } from 'antd' +import { first } from 'lodash' import { motion } from 'motion/react' import type { FC } from 'react' import { memo, useCallback } from 'react' @@ -83,7 +85,26 @@ const MessageGroupModelList: FC = ({ messages, selec {isCompact ? ( /* Compact style display */ - {messages.map((message) => renderLabel(message))} + + {messages.map((message) => { + const modelTip = message.model?.name + const isSelected = message.id === selectMessageId + + return ( + + setSelectedMessage(message)} + className="shadow-lg" + /> + + ) + })} + ) : ( /* Expanded style display */ = memo(({ assistant, model, message, topic, isGro {isAssistantMessage ? ( = memo(({ assistant, model, message, topic, isGro ) : ( UserPopup.show()} /> diff --git a/src/renderer/src/pages/minapps/MinAppPage.tsx b/src/renderer/src/pages/minapps/MinAppPage.tsx index a3b9eeac45..031cf14ec3 100644 --- a/src/renderer/src/pages/minapps/MinAppPage.tsx +++ b/src/renderer/src/pages/minapps/MinAppPage.tsx @@ -1,3 +1,4 @@ +import { Avatar } from '@cherrystudio/ui' import { loggerService } from '@logger' import { DEFAULT_MIN_APPS } from '@renderer/config/minapps' import { useMinappPopup } from '@renderer/hooks/useMinappPopup' @@ -5,7 +6,6 @@ import { useMinapps } from '@renderer/hooks/useMinapps' import { useNavbarPosition } from '@renderer/hooks/useNavbar' import TabsService from '@renderer/services/TabsService' import { getWebviewLoaded, onWebviewStateChange, setWebviewLoaded } from '@renderer/utils/webviewStateManager' -import { Avatar } from 'antd' import type { WebviewTag } from 'electron' import type { FC } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' @@ -187,7 +187,7 @@ const MinAppPage: FC = () => { {!isReady && ( - + )} diff --git a/src/renderer/src/pages/minapps/components/MinAppFullPageView.tsx b/src/renderer/src/pages/minapps/components/MinAppFullPageView.tsx index 24aca3db0c..ca1fdaaf1f 100644 --- a/src/renderer/src/pages/minapps/components/MinAppFullPageView.tsx +++ b/src/renderer/src/pages/minapps/components/MinAppFullPageView.tsx @@ -1,9 +1,9 @@ +import { Avatar } from '@cherrystudio/ui' import { loggerService } from '@logger' import WebviewContainer from '@renderer/components/MinApp/WebviewContainer' import { useSettings } from '@renderer/hooks/useSettings' import type { MinAppType } from '@renderer/types' import { getWebviewLoaded, setWebviewLoaded } from '@renderer/utils/webviewStateManager' -import { Avatar } from 'antd' import type { WebviewTag } from 'electron' import type { FC } from 'react' import { useCallback, useEffect, useRef, useState } from 'react' @@ -110,7 +110,7 @@ const MinAppFullPageView: FC = ({ app }) => { {!isReady && ( - + diff --git a/src/renderer/src/pages/paintings/AihubmixPage.tsx b/src/renderer/src/pages/paintings/AihubmixPage.tsx index 13961c30fd..bebd958df8 100644 --- a/src/renderer/src/pages/paintings/AihubmixPage.tsx +++ b/src/renderer/src/pages/paintings/AihubmixPage.tsx @@ -1,6 +1,7 @@ import { PlusOutlined, RedoOutlined } from '@ant-design/icons' import { Button, RowFlex } from '@cherrystudio/ui' import { Switch } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' @@ -21,7 +22,7 @@ import { translateText } from '@renderer/services/TranslateService' import type { FileMetadata } from '@renderer/types' import type { PaintingAction, PaintingsState } from '@renderer/types' import { getErrorMessage, uuid } from '@renderer/utils' -import { Avatar, Input, InputNumber, Radio, Segmented, Select, Slider, Tooltip, Upload } from 'antd' +import { Input, InputNumber, Radio, Segmented, Select, Slider, Tooltip, Upload } from 'antd' import TextArea from 'antd/es/input/TextArea' import { Info } from 'lucide-react' import type { FC } from 'react' @@ -839,10 +840,10 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { {t('common.provider')} {t('paintings.learn_more')} - @@ -852,7 +853,11 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => { {providerOptions.map((provider) => ( - + {provider.label} diff --git a/src/renderer/src/pages/paintings/DmxapiPage.tsx b/src/renderer/src/pages/paintings/DmxapiPage.tsx index e9d244c85b..ea441205af 100644 --- a/src/renderer/src/pages/paintings/DmxapiPage.tsx +++ b/src/renderer/src/pages/paintings/DmxapiPage.tsx @@ -1,6 +1,7 @@ import { PlusOutlined, RedoOutlined } from '@ant-design/icons' import { Button, RowFlex } from '@cherrystudio/ui' import { Switch } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import DMXAPIToImg from '@renderer/assets/images/providers/DMXAPI-to-img.webp' import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar' @@ -14,7 +15,7 @@ import FileManager from '@renderer/services/FileManager' import type { FileMetadata } from '@renderer/types' import { convertToBase64, uuid } from '@renderer/utils' import type { DmxapiPainting } from '@types' -import { Avatar, Input, InputNumber, Segmented, Select, Tooltip } from 'antd' +import { Input, InputNumber, Segmented, Select, Tooltip } from 'antd' import TextArea from 'antd/es/input/TextArea' import { Info } from 'lucide-react' import type { FC } from 'react' @@ -804,10 +805,10 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => { {t('paintings.top_up')} - @@ -816,7 +817,11 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => { {providerOptions.map((provider) => ( - + {provider.label} @@ -1028,9 +1033,6 @@ const ProviderTitleContainer = styled.div` margin-bottom: 5px; ` -const ProviderLogo = styled(Avatar)` - border: 0.5px solid var(--color-border); -` const SelectOptionContainer = styled.div` display: flex; align-items: center; diff --git a/src/renderer/src/pages/paintings/NewApiPage.tsx b/src/renderer/src/pages/paintings/NewApiPage.tsx index a5bd667e65..293468a13d 100644 --- a/src/renderer/src/pages/paintings/NewApiPage.tsx +++ b/src/renderer/src/pages/paintings/NewApiPage.tsx @@ -1,5 +1,6 @@ import { PlusOutlined } from '@ant-design/icons' import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' @@ -28,7 +29,7 @@ import { translateText } from '@renderer/services/TranslateService' import type { PaintingAction, PaintingsState } from '@renderer/types' import type { FileMetadata } from '@renderer/types' import { getErrorMessage, uuid } from '@renderer/utils' -import { Avatar, Empty, InputNumber, Segmented, Select, Upload } from 'antd' +import { Empty, InputNumber, Segmented, Select, Upload } from 'antd' import TextArea from 'antd/es/input/TextArea' import type { FC } from 'react' import React from 'react' @@ -502,10 +503,10 @@ const NewApiPage: FC<{ Options: string[] }> = ({ Options }) => { {t('common.provider')} {t('paintings.learn_more')} - @@ -518,7 +519,11 @@ const NewApiPage: FC<{ Options: string[] }> = ({ Options }) => { {providerOptions.map((provider) => ( - + {provider.label} @@ -787,10 +792,6 @@ const ToolbarMenu = styled.div` gap: 6px; ` -const ProviderLogo = styled(Avatar)` - border: 0.5px solid var(--color-border); -` - // 添加新的样式组件 const ModeSegmentedContainer = styled.div` display: flex; diff --git a/src/renderer/src/pages/paintings/TokenFluxPage.tsx b/src/renderer/src/pages/paintings/TokenFluxPage.tsx index 1d0cd68350..42e5dadba0 100644 --- a/src/renderer/src/pages/paintings/TokenFluxPage.tsx +++ b/src/renderer/src/pages/paintings/TokenFluxPage.tsx @@ -1,5 +1,6 @@ import { PlusOutlined } from '@ant-design/icons' import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import { usePreference } from '@data/hooks/usePreference' import { loggerService } from '@logger' @@ -16,7 +17,7 @@ import FileManager from '@renderer/services/FileManager' import { translateText } from '@renderer/services/TranslateService' import type { TokenFluxPainting } from '@renderer/types' import { getErrorMessage, uuid } from '@renderer/utils' -import { Avatar, Select, Tooltip } from 'antd' +import { Select, Tooltip } from 'antd' import TextArea from 'antd/es/input/TextArea' import { Info } from 'lucide-react' import type { FC } from 'react' @@ -381,7 +382,11 @@ const TokenFluxPage: FC<{ Options: string[] }> = ({ Options }) => { {t('common.provider')} {t('paintings.learn_more')} - + @@ -392,7 +397,11 @@ const TokenFluxPage: FC<{ Options: string[] }> = ({ Options }) => { {providerOptions.map((provider) => ( - + {provider.label} @@ -763,10 +772,6 @@ const InfoIcon = styled(Info)` } ` -const ProviderLogo = styled(Avatar)` - border: 0.5px solid var(--color-border); -` - const ProviderTitleContainer = styled.div` display: flex; justify-content: space-between; diff --git a/src/renderer/src/pages/paintings/ZhipuPage.tsx b/src/renderer/src/pages/paintings/ZhipuPage.tsx index 0fcd00861e..8e71fede9e 100644 --- a/src/renderer/src/pages/paintings/ZhipuPage.tsx +++ b/src/renderer/src/pages/paintings/ZhipuPage.tsx @@ -1,6 +1,7 @@ import { PlusOutlined } from '@ant-design/icons' import { RowFlex } from '@cherrystudio/ui' import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { useCache } from '@data/hooks/useCache' import AiProvider from '@renderer/aiCore' import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar' @@ -12,7 +13,7 @@ import { useAllProviders } from '@renderer/hooks/useProvider' import { getProviderLabel } from '@renderer/i18n/label' import FileManager from '@renderer/services/FileManager' import { getErrorMessage, uuid } from '@renderer/utils' -import { Avatar, InputNumber, Radio, Select } from 'antd' +import { InputNumber, Radio, Select } from 'antd' import TextArea from 'antd/es/input/TextArea' import type { FC } from 'react' import { useEffect, useState } from 'react' @@ -367,9 +368,9 @@ const ZhipuPage: FC<{ Options: string[] }> = ({ Options }) => { {t('paintings.paint_course')} @@ -378,7 +379,7 @@ const ZhipuPage: FC<{ Options: string[] }> = ({ Options }) => { {providerOptions.map((provider) => ( - + {provider.label} diff --git a/src/renderer/src/pages/settings/AboutSettings.tsx b/src/renderer/src/pages/settings/AboutSettings.tsx index 3dbf8211e1..23acd9055f 100644 --- a/src/renderer/src/pages/settings/AboutSettings.tsx +++ b/src/renderer/src/pages/settings/AboutSettings.tsx @@ -2,6 +2,7 @@ import { GithubOutlined } from '@ant-design/icons' import { RowFlex } from '@cherrystudio/ui' import { Switch } from '@cherrystudio/ui' import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { usePreference } from '@data/hooks/usePreference' import IndicatorLight from '@renderer/components/IndicatorLight' import { APP_NAME, AppLogo } from '@renderer/config/env' @@ -15,7 +16,7 @@ import { handleSaveData } from '@renderer/store' import { runAsyncFunction } from '@renderer/utils' import { UpgradeChannel } from '@shared/data/preference/preferenceTypes' import { ThemeMode } from '@shared/data/preference/preferenceTypes' -import { Avatar, Progress, Radio, Row, Tag, Tooltip } from 'antd' +import { Progress, Radio, Row, Tag, Tooltip } from 'antd' import { debounce } from 'lodash' import { Bug, FileCheck, Globe, Mail, Rss } from 'lucide-react' import { BadgeQuestionMark } from 'lucide-react' @@ -208,7 +209,7 @@ const AboutSettings: FC = () => { strokeColor="#67ad5b" /> )} - + {APP_NAME} diff --git a/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx index 002e4e3cee..b100753576 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/PreprocessProviderSettings.tsx @@ -1,12 +1,13 @@ import { ExportOutlined } from '@ant-design/icons' import { Flex } from '@cherrystudio/ui' import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import { ApiKeyListPopup } from '@renderer/components/Popups/ApiKeyListPopup' import { getPreprocessProviderLogo, PREPROCESS_PROVIDER_CONFIG } from '@renderer/config/preprocessProviders' import { usePreprocessProvider } from '@renderer/hooks/usePreprocess' import type { PreprocessProvider } from '@renderer/types' import { formatApiKeys, hasObjectKey } from '@renderer/utils' -import { Avatar, Divider, Input, Tooltip } from 'antd' +import { Divider, Input, Tooltip } from 'antd' import Link from 'antd/es/typography/Link' import { List } from 'lucide-react' import type { FC } from 'react' @@ -73,7 +74,11 @@ const PreprocessProviderSettings: FC = ({ provider: _provider }) => { <> - + {preprocessProvider.name} {officialWebsite && preprocessProviderConfig?.websites && ( diff --git a/src/renderer/src/pages/settings/MemorySettings/UserSelector.tsx b/src/renderer/src/pages/settings/MemorySettings/UserSelector.tsx index 4a574b0b95..5ff1969eb7 100644 --- a/src/renderer/src/pages/settings/MemorySettings/UserSelector.tsx +++ b/src/renderer/src/pages/settings/MemorySettings/UserSelector.tsx @@ -1,6 +1,7 @@ import { Flex, RowFlex } from '@cherrystudio/ui' import { Button } from '@cherrystudio/ui' -import { Avatar, Select, Tooltip } from 'antd' +import { Avatar } from '@cherrystudio/ui' +import { Select, Tooltip } from 'antd' import { UserRoundPlus } from 'lucide-react' import { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' @@ -25,7 +26,7 @@ const UserSelector: React.FC = ({ currentUser, uniqueUsers, o (userId: string, userName: string) => { return ( - + {getUserAvatar(userId)} {userName} diff --git a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx index 7b23d3a9b5..3bc1c205cc 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx @@ -1,5 +1,6 @@ import { Flex } from '@cherrystudio/ui' import { Button } from '@cherrystudio/ui' +import { Avatar } from '@cherrystudio/ui' import ExpandableText from '@renderer/components/ExpandableText' import ModelIdWithTags from '@renderer/components/ModelIdWithTags' import CustomTag from '@renderer/components/Tags/CustomTag' @@ -10,7 +11,6 @@ import FileItem from '@renderer/pages/files/FileItem' import NewApiBatchAddModelPopup from '@renderer/pages/settings/ProviderSettings/ModelList/NewApiBatchAddModelPopup' import type { Model, Provider } from '@renderer/types' import { Tooltip } from 'antd' -import { Avatar } from 'antd' import { ChevronRight, Minus, Plus } from 'lucide-react' import React, { memo, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -202,7 +202,11 @@ const ModelListItem: React.FC = memo(({ model, provider, onA boxShadow: 'none' }} fileInfo={{ - icon: {model?.name?.[0]?.toUpperCase()}, + icon: ( + + {model?.name?.[0]?.toUpperCase()} + + ), name: , extra: model.description && , ext: '.model', diff --git a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListGroup.tsx b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListGroup.tsx index fa4ac0cfcc..6bc2f63731 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListGroup.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListGroup.tsx @@ -64,6 +64,7 @@ const ModelListGroup: React.FC = ({ indicator: (