feat: translate
This commit is contained in:
@@ -6,10 +6,12 @@ import catSvg from "@/assets/translate/cat.svg";
|
||||
import pigSvg from "@/assets/translate/pig.svg";
|
||||
import { Message } from "../../../types";
|
||||
import "./index.less";
|
||||
import { Refresh } from "@icon-park/react";
|
||||
|
||||
interface DefinedProps {
|
||||
data: Message[];
|
||||
isRecording: boolean;
|
||||
onRefresh: (formData: FormData, messageId: number) => void;
|
||||
}
|
||||
|
||||
function Index(props: DefinedProps) {
|
||||
@@ -26,16 +28,16 @@ function Index(props: DefinedProps) {
|
||||
const onVoiceChange = () => {
|
||||
setIsPlating(!isPlaying);
|
||||
};
|
||||
const playAudio = (messageId: number, audioUrl: string) => {
|
||||
const playAudio = (id: number, audioUrl: string) => {
|
||||
if (isRecording) {
|
||||
Toast.show("录音中,无法播放音频");
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentPlayingId === messageId) {
|
||||
if (audioRefs.current[messageId]) {
|
||||
audioRefs.current[messageId].pause();
|
||||
audioRefs.current[messageId].currentTime = 0;
|
||||
if (currentPlayingId === id && audioRefs.current[id]) {
|
||||
if (audioRefs.current[id]) {
|
||||
audioRefs.current[id].pause();
|
||||
audioRefs.current[id].currentTime = 0;
|
||||
}
|
||||
setCurrentPlayingId(undefined);
|
||||
setIsPlating(false);
|
||||
@@ -43,11 +45,11 @@ function Index(props: DefinedProps) {
|
||||
}
|
||||
|
||||
stopAllAudio();
|
||||
if (!audioRefs.current[messageId]) {
|
||||
audioRefs.current[messageId] = new Audio(audioUrl);
|
||||
if (!audioRefs.current[id]) {
|
||||
audioRefs.current[id] = new Audio(audioUrl);
|
||||
}
|
||||
|
||||
const audio = audioRefs.current[messageId];
|
||||
const audio = audioRefs.current[id];
|
||||
audio.currentTime = 0;
|
||||
|
||||
audio.onended = () => {
|
||||
@@ -55,8 +57,24 @@ function Index(props: DefinedProps) {
|
||||
setIsPlating(false);
|
||||
};
|
||||
|
||||
audio.onerror = (error) => {
|
||||
console.error("音频播放错误:", error);
|
||||
audio.onerror = () => {
|
||||
const error = audio.error;
|
||||
switch (error?.code) {
|
||||
case MediaError.MEDIA_ERR_ABORTED:
|
||||
console.warn("音频播放被用户中断");
|
||||
break;
|
||||
case MediaError.MEDIA_ERR_NETWORK:
|
||||
console.warn("网络错误,无法加载音频");
|
||||
break;
|
||||
case MediaError.MEDIA_ERR_DECODE:
|
||||
console.warn("解码失败,可能是格式不支持");
|
||||
break;
|
||||
case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:
|
||||
console.warn("浏览器不支持该音频格式");
|
||||
break;
|
||||
default:
|
||||
console.warn("未知错误");
|
||||
};
|
||||
Toast.show("音频播放失败");
|
||||
setIsPlating(false);
|
||||
};
|
||||
@@ -64,7 +82,7 @@ function Index(props: DefinedProps) {
|
||||
audio
|
||||
.play()
|
||||
.then(() => {
|
||||
setCurrentPlayingId(messageId);
|
||||
setCurrentPlayingId(id);
|
||||
setIsPlating(true);
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -87,7 +105,7 @@ function Index(props: DefinedProps) {
|
||||
}
|
||||
});
|
||||
};
|
||||
const renderAvatar = (type?: "pig" | "cat" | "dog") => {
|
||||
const renderAvatar = (type?: "pig" | "cat" | "dog" | "") => {
|
||||
if (type === "pig") {
|
||||
<Image src={pigSvg} width={40} height={40} fit="cover" style={{ borderRadius: 32 }} />;
|
||||
}
|
||||
@@ -97,31 +115,43 @@ function Index(props: DefinedProps) {
|
||||
return <Image src={dogSvg} width={40} height={40} fit="cover" style={{ borderRadius: 32 }} />;
|
||||
};
|
||||
|
||||
const refreshMessage = async (messageId: number, e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
const formData = new FormData();
|
||||
formData.append("msgId", messageId.toString());
|
||||
props.onRefresh(formData, messageId);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="message">
|
||||
{data.map((item, index) => (
|
||||
<div className="item" key={index} onClick={() => playAudio(item.id, item.audioUrl)}>
|
||||
{renderAvatar(item.type)}
|
||||
<div className="item" key={index} onClick={() => playAudio(item.id, item.contentText)}>
|
||||
{renderAvatar(item.petType)}
|
||||
<div className="rig">
|
||||
<div>
|
||||
<span className="name">{item.name}</span>
|
||||
<span className="name">{item.petName}</span>
|
||||
<Divider direction="vertical" style={{ margin: "0px 8px" }} />
|
||||
<span className="">{item.timestamp}</span>
|
||||
<span className="">{item.createTime}</span>
|
||||
</div>
|
||||
<div className="voice-container">
|
||||
<VoiceIcon
|
||||
onChange={onVoiceChange}
|
||||
isPlaying={isPlaying && currentPlayingId === item.id}
|
||||
/>
|
||||
<div className="time">{item.duration}''</div>
|
||||
<div className="time">{item.contentDuration}''</div>
|
||||
</div>
|
||||
{item.isTranslating ? (
|
||||
<div className="translate">
|
||||
<SpinLoading color="default" style={{ "--size": "12px" }} />
|
||||
<span>翻译中...</span>
|
||||
</div>
|
||||
) : item.transStatus === 1 ? (
|
||||
<div className="translate">{item.transResult ?? "暂无翻译结果"}</div>
|
||||
) : (
|
||||
<div className="translate">{item.translatedText}</div>
|
||||
<div className="translate">
|
||||
<span> 翻译失败,请重试</span>
|
||||
<Refresh onClick={(e) => refreshMessage(item.id, e)} size="12" fill="#333" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,6 +171,8 @@ function Index(props: DefinedProps) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ height: "130px", width: "100%" }}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user