refactor: add more voice message events

This commit is contained in:
Tristan Yang
2023-04-07 20:56:35 +08:00
parent c92c552361
commit a473c8ebe5
2 changed files with 26 additions and 12 deletions
+6 -6
View File
@@ -18,19 +18,19 @@ const renderContent = (data: MessagePayload) => {
case ContentTypes.text:
res = (
<span className="max-w-lg md:truncate md:break-words md:break-all text-gray-800 dark:text-gray-100">
<LinkifyText text={content} url={false} mentionTextOnly={true} mentionPopOver={false} />
<LinkifyText text={content as string} url={false} mentionTextOnly={true} mentionPopOver={false} />
</span>
);
break;
case ContentTypes.audio:
res = (
<span className="text-gray-400 italic">[Voice Message]</span>
<span className=" text-primary-400 text-sm">[Voice Message]</span>
);
break;
case ContentTypes.markdown:
res = (
<div className="max-h-[152px] overflow-hidden dark:text-gray-100">
<MarkdownRender content={content} />
<MarkdownRender content={content as string} />
</div>
);
break;
@@ -42,10 +42,10 @@ const renderContent = (data: MessagePayload) => {
res = <img className="w-10 h-10 object-cover" src={thumbnail} />;
} else {
res = (
<>
<div className="flex gap-1">
{icon}
<span className="ml-1 text-[10px] text-gray-500 dark:text-gray-100">{name}</span>
</>
<span className="text-[10px] text-gray-500 dark:text-gray-100">{name}</span>
</div>
);
}
}
+20 -6
View File
@@ -1,4 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import dayjs from 'dayjs';
import clsx from 'clsx';
import WaveSurfer from 'wavesurfer.js';
import IconPause from '../../assets/icons/pause.svg';
import IconPlay from '../../assets/icons/play.circle.svg';
@@ -13,8 +15,9 @@ export type VoiceMessageProps = {
const VoiceMessage = ({ file_path }: { file_path: string }) => {
const waveRef = useRef<WaveSurfer | null>(null);
const containerRef = useRef(null);
const [status, setStatus] = useState<"loading" | "error" | "ready">("loading");
const [playing, setPlaying] = useState(false);
const [duration, setDuration] = useState(0);
const [duration, setDuration] = useState("");
// const [audio, setAudio] = useState<HTMLAudioElement>(new Audio(`${BASE_URL}/resource/file?file_path=${encodeURIComponent(
// file_path
// )}`));
@@ -26,17 +29,21 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
)}`;
wave = WaveSurfer.create({
container: containerRef.current,
maxCanvasWidth: 200,
// maxCanvasWidth: 200,
height: 32,
waveColor: '#0BA5EC',
cursorColor: '#0BA5AA',
progressColor: "#0BA5AA",
hideScrollbar: true,
// mediaControls: true,
normalize: true
normalize: true,
});
wave.load(audioSrc);
wave.on('error', function (err) {
console.log("voice message error", err);
setStatus("error");
});
wave.on('play', function () {
setPlaying(true);
});
@@ -44,9 +51,14 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
setPlaying(false);
});
wave.on('ready', function () {
setStatus("ready");
console.log("readd");
if (waveRef.current) {
const dur = waveRef.current.getDuration();
setDuration(Math.ceil(dur));
const num = Math.ceil(dur);
const durDisplay = dayjs.duration(num, 'seconds').format('mm:ss');
setDuration(durDisplay);
}
});
waveRef.current = wave;
@@ -67,11 +79,13 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
}
};
return (
<div className="select-none flex items-center gap-2 p-2 rounded-lg bg-primary-100 dark:bg-primary-900 max-w-sm">
<button onClick={handleClick}>
<div className={clsx("select-none flex items-center gap-2 p-2 rounded-lg max-w-sm", status === "error" ? "bg-red-200" : "bg-primary-100 dark:bg-primary-900")}>
<button className='disabled:opacity-60' onClick={handleClick} disabled={status !== "ready"}>
{playing ? <IconPause className="stroke-primary-500" /> : <IconPlay className="stroke-primary-500" />}
</button>
<div ref={containerRef} className='flex-1 h-8' >
{status == "loading" && <span className='text-xs'>Loading voice message...</span>}
{status == "error" && <span className='text-xs text-red-800'>Load voice message error</span>}
</div>
<time className='text-primary-500 text-xs whitespace-nowrap text-left'>{duration}'</time>
</div>