update it
This commit is contained in:
@@ -29,7 +29,9 @@ export const onRequestGet: PagesFunction<Env> = async (context) => {
|
||||
);
|
||||
}
|
||||
//处理avatar_url
|
||||
userInfo.avatar_url = `${env.NEXT_PUBLIC_CF_IMAGES_DELIVERY_URL}/${userInfo.avatar_url}/public`;
|
||||
if (userInfo.avatar_url) {
|
||||
userInfo.avatar_url = `${env.NEXT_PUBLIC_CF_IMAGES_DELIVERY_URL}/${userInfo.avatar_url}/public`;
|
||||
}
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
|
||||
@@ -73,7 +73,9 @@ export const onRequestPost: PagesFunction<Env> = async (context) => {
|
||||
WHERE id = ?
|
||||
`).bind(data.user.userId).first();
|
||||
//处理avatar_url
|
||||
userInfo.avatar_url = `${env.NEXT_PUBLIC_CF_IMAGES_DELIVERY_URL}/${userInfo.avatar_url}/public`;
|
||||
if (userInfo.avatar_url) {
|
||||
userInfo.avatar_url = `${env.NEXT_PUBLIC_CF_IMAGES_DELIVERY_URL}/${userInfo.avatar_url}/public`;
|
||||
}
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
success: true,
|
||||
|
||||
@@ -22,94 +22,8 @@ import { MembersManagement } from '@/pages/chat/components/MembersManagement';
|
||||
import Sidebar from './Sidebar';
|
||||
import { AdBanner, AdBannerMobile } from './AdSection';
|
||||
import { useUserStore } from '@/store/userStore';
|
||||
// 使用本地头像数据,避免外部依赖
|
||||
const getAvatarData = (name: string) => {
|
||||
const colors = ['#1abc9c', '#3498db', '#9b59b6', '#f1c40f', '#e67e22'];
|
||||
const index = (name.charCodeAt(0) + (name.charCodeAt(1) || 0 )) % colors.length;
|
||||
return {
|
||||
backgroundColor: colors[index],
|
||||
text: name[0],
|
||||
};
|
||||
};
|
||||
import { getAvatarData } from '@/utils/avatar';
|
||||
|
||||
// 单个完整头像
|
||||
const SingleAvatar = ({ user }: { user: User | AICharacter }) => {
|
||||
// 如果有头像就使用头像,否则使用默认的文字头像
|
||||
if ('avatar' in user && user.avatar) {
|
||||
return (
|
||||
<div className="w-full h-full">
|
||||
<img src={user.avatar} alt={user.name} className="w-full h-full object-cover" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const avatarData = getAvatarData(user.name);
|
||||
return (
|
||||
<div
|
||||
className="w-full h-full flex items-center justify-center text-xs text-white font-medium"
|
||||
style={{ backgroundColor: avatarData.backgroundColor }}
|
||||
>
|
||||
{avatarData.text}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 左右分半头像
|
||||
const HalfAvatar = ({ user, isFirst }: { user: User, isFirst: boolean }) => {
|
||||
if ('avatar' in user && user.avatar) {
|
||||
return (
|
||||
<div
|
||||
className="w-1/2 h-full"
|
||||
style={{
|
||||
borderRight: isFirst ? '1px solid white' : 'none'
|
||||
}}
|
||||
>
|
||||
<img src={user.avatar} alt={user.name} className="w-full h-full object-cover" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const avatarData = getAvatarData(user.name);
|
||||
return (
|
||||
<div
|
||||
className="w-1/2 h-full flex items-center justify-center text-xs text-white font-medium"
|
||||
style={{
|
||||
backgroundColor: avatarData.backgroundColor,
|
||||
borderRight: isFirst ? '1px solid white' : 'none'
|
||||
}}
|
||||
>
|
||||
{avatarData.text}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 四分之一头像
|
||||
const QuarterAvatar = ({ user, index }: { user: User, index: number }) => {
|
||||
if ('avatar' in user && user.avatar) {
|
||||
return (
|
||||
<div
|
||||
className="aspect-square"
|
||||
style={{
|
||||
borderRight: index % 2 === 0 ? '1px solid white' : 'none',
|
||||
borderBottom: index < 2 ? '1px solid white' : 'none'
|
||||
}}
|
||||
>
|
||||
<img src={user.avatar} alt={user.name} className="w-full h-full object-cover" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const avatarData = getAvatarData(user.name);
|
||||
return (
|
||||
<div
|
||||
className="aspect-square flex items-center justify-center text-[8px] text-white font-medium"
|
||||
style={{
|
||||
backgroundColor: avatarData.backgroundColor,
|
||||
borderRight: index % 2 === 0 ? '1px solid white' : 'none',
|
||||
borderBottom: index < 2 ? '1px solid white' : 'none'
|
||||
}}
|
||||
>
|
||||
{avatarData.text}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 修改 KaTeXStyle 组件
|
||||
const KaTeXStyle = () => (
|
||||
@@ -212,7 +126,7 @@ const ChatUI = () => {
|
||||
userStore.setUserInfo(userInfo.data);
|
||||
|
||||
setUsers([
|
||||
{ id: 1, name: userInfo.data.nickname, avatar: userInfo.data.avatar_url },
|
||||
{ id: 1, name: userInfo.data.nickname, avatar: userInfo.data.avatar_url? userInfo.data.avatar_url : null },
|
||||
...groupAiCharacters
|
||||
]);
|
||||
} catch (error) {
|
||||
@@ -531,7 +445,7 @@ const ChatUI = () => {
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<Avatar className="w-7 h-7 border-2 border-white">
|
||||
{'avatar' in user && user.avatar ? (
|
||||
{'avatar' in user && user.avatar && user.avatar !== null ? (
|
||||
<AvatarImage src={user.avatar} />
|
||||
) : (
|
||||
<AvatarFallback style={{ backgroundColor: avatarData.backgroundColor, color: 'white' }}>
|
||||
|
||||
@@ -3,17 +3,13 @@ import { cn } from "@/lib/utils";
|
||||
import { Edit2Icon, LogOutIcon, CheckIcon, XIcon } from 'lucide-react';
|
||||
import { request } from '@/utils/request';
|
||||
import { useUserStore } from '@/store/userStore';
|
||||
import { getAvatarData } from '@/utils/avatar';
|
||||
|
||||
|
||||
interface UserSectionProps {
|
||||
isOpen: boolean;
|
||||
}
|
||||
|
||||
// 添加用户信息接口
|
||||
interface UserInfo {
|
||||
nickname: string;
|
||||
avatar_url?: string;
|
||||
}
|
||||
|
||||
export const UserSection: React.FC<UserSectionProps> = ({ isOpen }) => {
|
||||
const [isHovering, setIsHovering] = useState(false);
|
||||
@@ -107,7 +103,8 @@ export const UserSection: React.FC<UserSectionProps> = ({ isOpen }) => {
|
||||
onChange={handleAvatarUpload}
|
||||
/>
|
||||
<div
|
||||
className="w-10 h-10 rounded-full bg-gradient-to-br from-orange-400 to-rose-400 flex items-center justify-center shadow-sm overflow-hidden"
|
||||
className="w-10 h-10 rounded-full flex items-center justify-center shadow-sm overflow-hidden"
|
||||
style={{ backgroundColor: getAvatarData(userStore.userInfo?.nickname || '我').backgroundColor }}
|
||||
onClick={() => !uploadingAvatar && fileInputRef.current?.click()}
|
||||
>
|
||||
{uploadingAvatar ? (
|
||||
@@ -121,8 +118,10 @@ export const UserSection: React.FC<UserSectionProps> = ({ isOpen }) => {
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<span className="text-base font-medium text-white">
|
||||
{userStore.userInfo?.nickname?.[0] || '我'}
|
||||
<span
|
||||
className="text-base font-medium text-white"
|
||||
>
|
||||
{getAvatarData(userStore.userInfo?.nickname || '我').text}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
97
src/utils/avatar.ts
Normal file
97
src/utils/avatar.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import React from 'react';
|
||||
|
||||
interface User {
|
||||
id: number | string;
|
||||
name: string;
|
||||
avatar?: string;
|
||||
}
|
||||
|
||||
interface AICharacter {
|
||||
id: string;
|
||||
name: string;
|
||||
personality: string;
|
||||
model: string;
|
||||
avatar?: string;
|
||||
custom_prompt?: string;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
export const getAvatarData = (name: string) => {
|
||||
const colors = ['#1abc9c', '#3498db', '#9b59b6', '#f1c40f', '#e67e22'];
|
||||
const index = (name.charCodeAt(0) + (name.charCodeAt(1) || 0)) % colors.length;
|
||||
return {
|
||||
backgroundColor: colors[index],
|
||||
text: name[0],
|
||||
};
|
||||
};
|
||||
|
||||
// 获取单个头像的样式和内容
|
||||
export const getSingleAvatarData = (user: User | AICharacter) => {
|
||||
if ('avatar' in user && user.avatar) {
|
||||
return {
|
||||
type: 'image',
|
||||
src: user.avatar,
|
||||
alt: user.name,
|
||||
className: 'w-full h-full object-cover'
|
||||
};
|
||||
}
|
||||
const avatarData = getAvatarData(user.name);
|
||||
return {
|
||||
type: 'text',
|
||||
text: avatarData.text,
|
||||
className: 'w-full h-full flex items-center justify-center text-xs text-white font-medium',
|
||||
style: { backgroundColor: avatarData.backgroundColor }
|
||||
};
|
||||
};
|
||||
|
||||
// 获取半头像的样式和内容
|
||||
export const getHalfAvatarData = (user: User, isFirst: boolean) => {
|
||||
if ('avatar' in user && user.avatar) {
|
||||
return {
|
||||
type: 'image',
|
||||
src: user.avatar,
|
||||
alt: user.name,
|
||||
className: 'w-full h-full object-cover',
|
||||
containerStyle: {
|
||||
borderRight: isFirst ? '1px solid white' : 'none'
|
||||
}
|
||||
};
|
||||
}
|
||||
const avatarData = getAvatarData(user.name);
|
||||
return {
|
||||
type: 'text',
|
||||
text: avatarData.text,
|
||||
className: 'w-1/2 h-full flex items-center justify-center text-xs text-white font-medium',
|
||||
style: {
|
||||
backgroundColor: avatarData.backgroundColor,
|
||||
borderRight: isFirst ? '1px solid white' : 'none'
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 获取四分之一头像的样式和内容
|
||||
export const getQuarterAvatarData = (user: User, index: number) => {
|
||||
if ('avatar' in user && user.avatar) {
|
||||
return {
|
||||
type: 'image',
|
||||
src: user.avatar,
|
||||
alt: user.name,
|
||||
className: 'w-full h-full object-cover',
|
||||
containerStyle: {
|
||||
borderRight: index % 2 === 0 ? '1px solid white' : 'none',
|
||||
borderBottom: index < 2 ? '1px solid white' : 'none'
|
||||
}
|
||||
};
|
||||
}
|
||||
const avatarData = getAvatarData(user.name);
|
||||
return {
|
||||
type: 'text',
|
||||
text: avatarData.text,
|
||||
className: 'aspect-square flex items-center justify-center text-[8px] text-white font-medium',
|
||||
style: {
|
||||
backgroundColor: avatarData.backgroundColor,
|
||||
borderRight: index % 2 === 0 ? '1px solid white' : 'none',
|
||||
borderBottom: index < 2 ? '1px solid white' : 'none'
|
||||
}
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user