From 6c71b92d1da65c8b67ba40ccd65dd206d82ae9e2 Mon Sep 17 00:00:00 2001 From: MyPrototypeWhat Date: Mon, 29 Sep 2025 18:58:46 +0800 Subject: [PATCH] refactor: remove ProviderAvatar component and related files - Deleted the ProviderAvatar component and its associated utility functions and stories to streamline the codebase. - Updated index.ts to remove the export of ProviderAvatar, ensuring a cleaner component structure. --- .../display/ProviderAvatar/index.tsx | 93 -------- .../display/ProviderAvatar/utils.ts | 37 --- packages/ui/src/components/index.ts | 1 - .../display/ProviderAvatar.stories.tsx | 210 ------------------ .../src/components/ProviderAvatar.tsx | 54 ++--- 5 files changed, 20 insertions(+), 375 deletions(-) delete mode 100644 packages/ui/src/components/display/ProviderAvatar/index.tsx delete mode 100644 packages/ui/src/components/display/ProviderAvatar/utils.ts delete mode 100644 packages/ui/stories/components/display/ProviderAvatar.stories.tsx diff --git a/packages/ui/src/components/display/ProviderAvatar/index.tsx b/packages/ui/src/components/display/ProviderAvatar/index.tsx deleted file mode 100644 index 0fd147b9b7..0000000000 --- a/packages/ui/src/components/display/ProviderAvatar/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -// Original path: src/renderer/src/components/ProviderAvatar.tsx -import React from 'react' - -import { Avatar } from '../../base/Avatar' -import { generateColorFromChar, getFirstCharacter, getForegroundColor } from './utils' - -interface ProviderAvatarProps { - providerId: string - providerName: string - logoSrc?: string - size?: 'sm' | 'md' | 'lg' | number - className?: string - style?: React.CSSProperties - renderCustomLogo?: (providerId: string) => React.ReactNode -} - -export const ProviderAvatar: React.FC = ({ - providerId, - providerName, - logoSrc, - size = 'md', - className = '', - style, - renderCustomLogo -}) => { - // Convert numeric size to HeroUI size props - const getAvatarSize = () => { - if (typeof size === 'number') { - // For custom numeric sizes, we'll use style override - return 'md' - } - return size - } - - const getCustomStyle = () => { - const baseStyle: React.CSSProperties = { - ...style - } - - if (typeof size === 'number') { - baseStyle.width = `${size}px` - baseStyle.height = `${size}px` - } - - return baseStyle - } - - // Check if custom logo renderer is provided for special providers - if (renderCustomLogo) { - const customLogo = renderCustomLogo(providerId) - if (customLogo) { - return ( -
-
{customLogo}
-
- ) - } - } - - // If logo source is provided, render image avatar - if (logoSrc) { - return ( - - ) - } - - // Default: generate avatar with first character and background color - const backgroundColor = generateColorFromChar(providerName) - const color = providerName ? getForegroundColor(backgroundColor) : 'white' - - return ( - - ) -} - -export default ProviderAvatar diff --git a/packages/ui/src/components/display/ProviderAvatar/utils.ts b/packages/ui/src/components/display/ProviderAvatar/utils.ts deleted file mode 100644 index 6e3c6126c9..0000000000 --- a/packages/ui/src/components/display/ProviderAvatar/utils.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Utility functions for ProviderAvatar component - -export function generateColorFromChar(char: string): string { - const seed = char.charCodeAt(0) - const a = 1664525 - const c = 1013904223 - const m = Math.pow(2, 32) - - let r = (a * seed + c) % m - let g = (a * r + c) % m - let b = (a * g + c) % m - - r = Math.floor((r / m) * 256) - g = Math.floor((g / m) * 256) - b = Math.floor((b / m) * 256) - - const toHex = (n: number) => n.toString(16).padStart(2, '0') - return `#${toHex(r)}${toHex(g)}${toHex(b)}` -} - -export function getFirstCharacter(str: string): string { - for (const char of str) { - return char - } - return '' -} - -export function getForegroundColor(backgroundColor: string): string { - // Simple luminance calculation - const hex = backgroundColor.replace('#', '') - const r = parseInt(hex.substring(0, 2), 16) / 255 - const g = parseInt(hex.substring(2, 4), 16) / 255 - const b = parseInt(hex.substring(4, 6), 16) / 255 - - const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b - return luminance > 0.179 ? '#000000' : '#FFFFFF' -} diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 0fa4abca08..c85d8d6bea 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -21,7 +21,6 @@ export { default as Ellipsis } from './display/Ellipsis' export { default as ExpandableText } from './display/ExpandableText' export { default as ListItem } from './display/ListItem' export { default as MaxContextCount } from './display/MaxContextCount' -export { ProviderAvatar } from './display/ProviderAvatar' export { default as ThinkingEffect } from './display/ThinkingEffect' // Layout Components diff --git a/packages/ui/stories/components/display/ProviderAvatar.stories.tsx b/packages/ui/stories/components/display/ProviderAvatar.stories.tsx deleted file mode 100644 index 33ced8ac1b..0000000000 --- a/packages/ui/stories/components/display/ProviderAvatar.stories.tsx +++ /dev/null @@ -1,210 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' - -import { ProviderAvatar } from '../../../src/components/display/ProviderAvatar' - -// 定义 Story 的元数据 -const meta: Meta = { - title: 'Display/ProviderAvatar', - component: ProviderAvatar, - parameters: { - layout: 'centered' - }, - tags: ['autodocs'], - argTypes: { - size: { - control: { type: 'range', min: 16, max: 128, step: 4 }, - description: '头像尺寸', - defaultValue: 40 - }, - providerId: { - control: 'text', - description: '提供商 ID' - }, - providerName: { - control: 'text', - description: '提供商名称' - }, - logoSrc: { - control: 'text', - description: '图片 Logo 地址' - }, - className: { - control: 'text', - description: '自定义类名' - } - } -} satisfies Meta - -export default meta -type Story = StoryObj - -// 基础用法:文字头像 -export const Default: Story = { - args: { - providerId: 'openai', - providerName: 'OpenAI', - size: 40 - } -} - -// 带图片的头像 -export const WithImage: Story = { - args: { - providerId: 'custom', - providerName: 'Custom Provider', - logoSrc: 'https://via.placeholder.com/150', - size: 40 - } -} - -// 不同尺寸展示 -export const Sizes: Story = { - render: (args) => ( -
- - - - - - -
- ), - args: { - providerId: 'size-demo' - } -} - -// 不同首字母的颜色生成 -export const ColorGeneration: Story = { - args: { - providerId: 'azure', - providerName: 'Azure', - size: 40 - }, - render: (args) => ( -
- - - - - - - - - - -
- ) -} - -// 自定义 SVG Logo -export const WithCustomSvg: Story = { - args: { - providerId: 'custom-svg', - providerName: 'Custom SVG', - size: 40, - renderCustomLogo: () => ( - - - - - - ) - } -} - -// 混合展示 -export const Mixed: Story = { - args: { - providerId: 'text', - providerName: 'Text Avatar', - size: 40 - }, - render: (args) => ( -
- - - ( - - - - )} - /> -
- ) -} - -// 空值处理 -export const EmptyValues: Story = { - args: { - providerId: 'empty', - providerName: '', - size: 40 - }, - render: (args) => ( -
-
-

空名称

- -
-
-

正常显示

- -
-
- ) -} - -// 自定义样式 -export const CustomStyle: Story = { - args: { - providerId: 'custom-style', - providerName: 'Custom', - size: 40, - style: { - border: '2px solid #FF6B6B', - boxShadow: '0 4px 8px rgba(0,0,0,0.1)' - } - } -} - -// 响应式网格展示 -export const ResponsiveGrid: Story = { - args: { - providerId: 'provider-a', - providerName: 'Provider A', - size: 48 - }, - render: (args) => ( -
- {['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'].map((letter) => ( -
- -
{letter}
-
- ))} -
- ) -} diff --git a/src/renderer/src/components/ProviderAvatar.tsx b/src/renderer/src/components/ProviderAvatar.tsx index 02ec09388e..5460ed66bb 100644 --- a/src/renderer/src/components/ProviderAvatar.tsx +++ b/src/renderer/src/components/ProviderAvatar.tsx @@ -1,10 +1,9 @@ -import { Avatar } from '@cherrystudio/ui' +import { Avatar, cn } 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 React from 'react' -import styled from 'styled-components' interface ProviderAvatarPrimitiveProps { providerId: string @@ -23,28 +22,6 @@ interface ProviderAvatarProps { style?: React.CSSProperties } -const ProviderSvgLogo = styled.div` - width: 100%; - height: 100%; - - display: flex; - align-items: center; - justify-content: center; - border: 0.5px solid var(--color-border); - border-radius: 100%; - - & > svg { - width: 80%; - height: 80%; - } -` - -const ProviderLogo = styled(Avatar)` - width: 100%; - height: 100%; - border: 0.5px solid var(--color-border); -` - export const ProviderAvatarPrimitive: React.FC = ({ providerId, providerName, @@ -53,33 +30,42 @@ export const ProviderAvatarPrimitive: React.FC = ( className, style }) => { + // Special handling for Poe provider if (providerId === 'poe') { return ( - - - +
+ +
) } + // If logo source is provided, render image avatar if (logoSrc) { return ( - ) } + // Default: generate avatar with first character and background color const backgroundColor = generateColorFromChar(providerName) const color = providerName ? getForegroundColor(backgroundColor) : 'white' return ( - = ( ...style }}> {getFirstCharacter(providerName)} - +
) }