Files
tashow-h5/src/view/home/translate.tsx
2025-09-03 15:06:16 +08:00

155 lines
4.0 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from "react";
import FloatingMenu, { FloatMenuItemConfig } from "@/component/floatingMenu";
import { Image, Toast } from "antd-mobile";
import MessageCom from "./component/message";
import VoiceRecord from "./component/voice";
import XPopup from "@/component/xpopup";
import type { Message } from "./types";
import { mockTranslateAudio } from "@/utils/voice";
import dogSvg from "@/assets/translate/dog.svg";
import catSvg from "@/assets/translate/cat.svg";
import pigSvg from "@/assets/translate/pig.svg";
import { MoreTwo } from "@icon-park/react";
interface DefinedProps {}
const menuItems: FloatMenuItemConfig[] = [
{ icon: <Image src={dogSvg} />, type: "dog" },
{ icon: <Image src={catSvg} />, type: "cat" },
{ icon: <Image src={pigSvg} />, type: "pig" },
{
icon: (
<MoreTwo
theme="outline"
size="24"
fill="#666"
strokeWidth={3}
strokeLinecap="butt"
/>
),
type: "add",
},
];
function Index(props: DefinedProps) {
// const data: Message[] = [
// {
// id: 1,
// audioUrl: "",
// duration: 0,
// translatedText: "",
// isTranslating: true,
// isPlaying: false,
// timestamp: 0,
// },
// ];
const [currentPlayingId, setCurrentPlayingId] = useState<string | null>(null); //当前播放id
const [messages, setMessages] = useState<Message[]>([]);
const [isRecording, setIsRecording] = useState(false); //是否录音中
const [currentLanguage, setCurrentLanguage] = useState<FloatMenuItemConfig>();
const [visible, setVisible] = useState<boolean>(false);
useEffect(() => {
setCurrentLanguage(menuItems[0]);
}, []);
//完成录音
const onRecordingComplete = useCallback(
(audioUrl: string, actualDuration: number) => {
const newMessage: Message = {
id: Date.now(),
type: "dog",
audioUrl,
name: "生无可恋喵",
duration: actualDuration,
timestamp: Date.now(),
isTranslating: true,
};
setMessages((prev) => [...prev, newMessage]);
setTimeout(() => {
onTranslateAudio(newMessage.id);
}, 1000);
Toast.show("语音已发送");
},
[messages]
);
//翻译
const onTranslateAudio = useCallback(
async (messageId: number) => {
try {
const translatedText = await mockTranslateAudio();
setMessages((prev) =>
prev.map((msg) =>
msg.id === messageId
? { ...msg, translatedText, isTranslating: false }
: msg
)
);
} catch (error) {
console.error("翻译失败:", error);
Toast.show("翻译失败,请重试");
setMessages((prev) =>
prev.map((msg) =>
msg.id === messageId
? {
...msg,
isTranslating: false,
translatedText: "翻译失败,请重试",
}
: msg
)
);
}
},
[messages]
);
const onSetIsRecording = (flag: boolean) => {
setIsRecording(flag);
};
const onLanguage = (item: FloatMenuItemConfig) => {
if (item.type === "add") {
setVisible(true);
} else {
setCurrentLanguage(item);
}
};
return (
<div className="translate-container">
<MessageCom data={messages} isRecording={isRecording}></MessageCom>
<VoiceRecord
onRecordingComplete={onRecordingComplete}
isRecording={isRecording}
onSetIsRecording={onSetIsRecording}
/>
<FloatingMenu
menuItems={menuItems}
value={currentLanguage}
onChange={onLanguage}
/>
<XPopup
title="选择翻译语种"
visible={visible}
onClose={() => {
setVisible(false);
}}
>
<div className="card">
<span></span>
<div></div>
</div>
<div className="card">
<span></span>
</div>
</XPopup>
</div>
);
}
export default Index;