crush-level-web/src/app/(main)/home/components/StartChat/StartChatItem.tsx

114 lines
4.1 KiB
TypeScript
Raw Normal View History

2025-11-13 08:38:25 +00:00
"use client";
import type { StartChatOutput } from "@/services/home/types";
import { formatNumberToKMB } from "@/lib/utils";
import Link from "next/link";
import { Avatar, AvatarImage } from "@/components/ui/avatar";
import { IconButton } from "@/components/ui/button";
import { useAudioPlayer } from "../../context/AudioPlayerContext";
import { WaveAnimation } from "@/components/ui/wave-animation";
interface StartChatItemProps {
character: StartChatOutput;
}
const StartChatItem = ({ character }: StartChatItemProps) => {
const { play, isPlaying } = useAudioPlayer();
const audioId = `character-${character.aiId}`;
const playing = isPlaying(audioId);
// character.dialoguePrologueSound = "https://snd.crushlevel.ai/dev/sound/17624951011014110.mp3";
// character.supportingContentList = [
// "How is your day ?",
// "How is your day ?",
// "How is your day ?",
// ]
// 处理音频播放
const handlePlayAudio = (e: React.MouseEvent) => {
e.preventDefault(); // 阻止链接跳转
e.stopPropagation(); // 阻止事件冒泡
if (character.dialoguePrologueSound) {
play(character.dialoguePrologueSound, audioId);
}
};
return (
<div
className="flex-[0_0_100%] sm:flex-[0_0_calc(50%-12px)] md:flex-[0_0_calc(50%-16px)] lg:flex-[0_0_calc(33.333%-16px)] xl:flex-[0_0_calc(25%-18px)] min-w-0 h-full mt-10"
>
<div className="cursor-pointer h-full">
<div className="px-4 pb-4 pt-16 flex flex-col items-center h-full border border-solid border-outline-normal rounded-lg relative">
{/* 头像 - 带播放按钮 */}
<div className="absolute top-0 -translate-y-1/2 z-10">
2025-11-24 03:47:20 +00:00
<Link href={`/chat/${character.aiId}`} prefetch>
2025-11-13 08:38:25 +00:00
<Avatar className="w-20 h-20">
<AvatarImage
src={character.headImg || ""}
alt={character.nickname || "Character"}
/>
</Avatar>
</Link>
{/* 播放按钮 */}
{character.dialoguePrologueSound && <div
className="absolute bottom-0 left-1/2 -translate-x-1/2 translate-y-1/2 z-10"
onClick={handlePlayAudio}
>
<IconButton
type="button"
variant="primary"
size="small"
className="pointer-events-none"
>
{
playing
? <WaveAnimation className="text-txt-primary-normal animate-pulse" />
: <i className="iconfont icon-Play text-txt-primary-normal" />
}
</IconButton>
</div>}
</div>
{/* 名字 */}
2025-11-24 03:47:20 +00:00
<Link className="block w-full" href={`/chat/${character.aiId}`} prefetch>
2025-11-13 08:38:25 +00:00
<h3 className="txt-title-m text-center truncate w-full mb-2">
{character.nickname}
</h3>
</Link>
{/* 点赞数 */}
<div className="flex items-center gap-1 mb-4">
<i className="iconfont icon-Like-fill !text-[12px]" />
<span className="txt-label-s">
{formatNumberToKMB(character.likedNum || 0)}
</span>
</div>
{/* 对话建议列表 */}
<div className="w-full space-y-2 flex-1">
{character.supportingContentList?.map((suggestion, index) => (
<Link
href={`/chat/${character.aiId}?text=${encodeURIComponent(suggestion)}`}
key={index}
2025-11-24 03:47:20 +00:00
prefetch
2025-11-13 08:38:25 +00:00
className="flex items-center justify-between gap-1 p-2 rounded-sm bg-surface-element-normal hover:bg-surface-element-hovered transition-colors group"
>
<span className="txt-body-m text-txt-secondary-normal truncate flex-1">
{suggestion}
</span>
<IconButton
iconfont="icon-icon-send"
variant="tertiary"
size="xs"
/>
</Link>
))}
</div>
</div>
</div>
</div>
);
};
export default StartChatItem;