Improved the appearance of the Waveform
This commit is contained in:
@@ -1,15 +1,17 @@
|
|||||||
import React, {useEffect, useRef} from "react";
|
import React, {useEffect, useRef, useState} from "react";
|
||||||
|
import {BsPauseFill, BsPlayFill} from "react-icons/bs";
|
||||||
import WaveSurfer from "wavesurfer.js";
|
import WaveSurfer from "wavesurfer.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
audio: string;
|
audio: string;
|
||||||
isPlaying: boolean;
|
waveColor: string;
|
||||||
onEnd: () => void;
|
progressColor: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Waveform = ({audio, isPlaying, onEnd}: Props) => {
|
const Waveform = ({audio, waveColor, progressColor}: Props) => {
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
const waveSurferRef = useRef<WaveSurfer | null>(null);
|
const waveSurferRef = useRef<WaveSurfer | null>();
|
||||||
|
const [isPlaying, setIsPlaying] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const waveSurfer = WaveSurfer.create({
|
const waveSurfer = WaveSurfer.create({
|
||||||
@@ -17,38 +19,52 @@ const Waveform = ({audio, isPlaying, onEnd}: Props) => {
|
|||||||
responsive: true,
|
responsive: true,
|
||||||
cursorWidth: 0,
|
cursorWidth: 0,
|
||||||
height: 24,
|
height: 24,
|
||||||
waveColor: "#FCDDEC",
|
waveColor,
|
||||||
progressColor: "#EF5DA8",
|
progressColor,
|
||||||
barGap: 4,
|
barGap: 5,
|
||||||
barWidth: 4,
|
barWidth: 8,
|
||||||
barRadius: 2,
|
barRadius: 4,
|
||||||
fillParent: true,
|
fillParent: true,
|
||||||
hideScrollbar: true,
|
hideScrollbar: true,
|
||||||
normalize: true,
|
normalize: false,
|
||||||
|
autoCenter: true,
|
||||||
|
ignoreSilenceMode: true,
|
||||||
|
barMinHeight: 4,
|
||||||
});
|
});
|
||||||
waveSurfer.load(audio);
|
waveSurfer.load(audio);
|
||||||
|
|
||||||
waveSurfer.on("ready", () => {
|
waveSurfer.on("ready", () => {
|
||||||
waveSurferRef.current = waveSurfer;
|
waveSurferRef.current = waveSurfer;
|
||||||
});
|
});
|
||||||
waveSurfer.on("finish", onEnd);
|
|
||||||
|
waveSurfer.on("finish", () => setIsPlaying(false));
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
waveSurfer.destroy();
|
waveSurfer.destroy();
|
||||||
};
|
};
|
||||||
}, [audio, onEnd]);
|
}, [audio, progressColor, waveColor]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isPlaying) waveSurferRef.current?.play();
|
|
||||||
if (!isPlaying) waveSurferRef.current?.pause();
|
|
||||||
}, [isPlaying]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={() => waveSurferRef.current?.playPause()} type="button">
|
{isPlaying && (
|
||||||
{" "}
|
<BsPauseFill
|
||||||
play/pause{" "}
|
className="text-mti-gray-cool cursor-pointer w-5 h-5"
|
||||||
</button>
|
onClick={() => {
|
||||||
<div className="w-full h-fit" ref={containerRef} />
|
setIsPlaying((prev) => !prev);
|
||||||
|
waveSurferRef.current?.playPause();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!isPlaying && (
|
||||||
|
<BsPlayFill
|
||||||
|
className="text-mti-gray-cool cursor-pointer w-5 h-5"
|
||||||
|
onClick={() => {
|
||||||
|
setIsPlaying((prev) => !prev);
|
||||||
|
waveSurferRef.current?.playPause();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="w-full max-w-4xl h-fit" ref={containerRef} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ export default function Page() {
|
|||||||
const {user} = useUser({redirectTo: "/login"});
|
const {user} = useUser({redirectTo: "/login"});
|
||||||
const [recordingDuration, setRecordingDuration] = useState(0);
|
const [recordingDuration, setRecordingDuration] = useState(0);
|
||||||
const [isRecording, setIsRecording] = useState(false);
|
const [isRecording, setIsRecording] = useState(false);
|
||||||
const [isPlaying, setIsPlaying] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let recordingInterval: NodeJS.Timer | undefined = undefined;
|
let recordingInterval: NodeJS.Timer | undefined = undefined;
|
||||||
@@ -159,19 +158,7 @@ export default function Page() {
|
|||||||
)}
|
)}
|
||||||
{status === "stopped" && mediaBlobUrl && (
|
{status === "stopped" && mediaBlobUrl && (
|
||||||
<>
|
<>
|
||||||
{isPlaying && (
|
<Waveform audio={mediaBlobUrl} waveColor="#FCDDEC" progressColor="#EF5DA8" />
|
||||||
<BsPauseFill
|
|
||||||
className="text-mti-gray-cool cursor-pointer w-5 h-5"
|
|
||||||
onClick={() => setIsPlaying(false)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!isPlaying && (
|
|
||||||
<BsPlayFill
|
|
||||||
className="text-mti-gray-cool cursor-pointer w-5 h-5"
|
|
||||||
onClick={() => setIsPlaying(true)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Waveform audio={mediaBlobUrl} isPlaying={isPlaying} onEnd={() => setIsPlaying(false)} />
|
|
||||||
<div className="flex gap-4 items-center">
|
<div className="flex gap-4 items-center">
|
||||||
<BsTrashFill
|
<BsTrashFill
|
||||||
className="text-mti-gray-cool cursor-pointer w-5 h-5"
|
className="text-mti-gray-cool cursor-pointer w-5 h-5"
|
||||||
|
|||||||
Reference in New Issue
Block a user