Ability to load past meetings + URL management

This commit is contained in:
Koper
2023-09-14 23:05:13 +07:00
parent 07204ee2db
commit c9d01a9d30
13 changed files with 437 additions and 59 deletions

View File

@@ -12,19 +12,22 @@ import "react-dropdown/style.css";
import { formatTime } from "../lib/time";
import { Topic } from "./webSocketTypes";
import { AudioWaveform } from "../api";
const AudioInputsDropdown: React.FC<{
audioDevices: Option[];
audioDevices?: Option[];
setDeviceId: React.Dispatch<React.SetStateAction<string | null>>;
disabled: boolean;
}> = (props) => {
const [ddOptions, setDdOptions] = useState<Option[]>([]);
useEffect(() => {
setDdOptions(props.audioDevices);
props.setDeviceId(
props.audioDevices.length > 0 ? props.audioDevices[0].value : null,
);
if (props.audioDevices) {
setDdOptions(props.audioDevices);
props.setDeviceId(
props.audioDevices.length > 0 ? props.audioDevices[0].value : null,
);
}
}, [props.audioDevices]);
const handleDropdownChange = (option: Option) => {
@@ -42,15 +45,18 @@ const AudioInputsDropdown: React.FC<{
};
type RecorderProps = {
setStream: React.Dispatch<React.SetStateAction<MediaStream | null>>;
onStop: () => void;
setStream?: React.Dispatch<React.SetStateAction<MediaStream | null>>;
onStop?: () => void;
topics: Topic[];
getAudioStream: (deviceId: string | null) => Promise<MediaStream | null>;
audioDevices: Option[];
getAudioStream?: (deviceId: string | null) => Promise<MediaStream | null>;
audioDevices?: Option[];
useActiveTopic: [
Topic | null,
React.Dispatch<React.SetStateAction<Topic | null>>,
];
waveform?: AudioWaveform | null;
isPastMeeting: boolean;
transcriptId?: string | null;
};
export default function Recorder(props: RecorderProps) {
@@ -58,7 +64,7 @@ export default function Recorder(props: RecorderProps) {
const [wavesurfer, setWavesurfer] = useState<WaveSurfer | null>(null);
const [record, setRecord] = useState<RecordPlugin | null>(null);
const [isRecording, setIsRecording] = useState<boolean>(false);
const [hasRecorded, setHasRecorded] = useState<boolean>(false);
const [hasRecorded, setHasRecorded] = useState<boolean>(props.isPastMeeting);
const [isPlaying, setIsPlaying] = useState<boolean>(false);
const [deviceId, setDeviceId] = useState<string | null>(null);
const [currentTime, setCurrentTime] = useState<number>(0);
@@ -73,9 +79,6 @@ export default function Recorder(props: RecorderProps) {
const topicsRef = useRef(props.topics);
useEffect(() => {
const playBtn = document.getElementById("play-btn");
if (playBtn) playBtn.setAttribute("disabled", "true");
if (waveformRef.current) {
const _wavesurfer = WaveSurfer.create({
container: waveformRef.current,
@@ -86,7 +89,11 @@ export default function Recorder(props: RecorderProps) {
autoCenter: true,
barWidth: 2,
height: 90,
url: props.transcriptId
? `${process.env.NEXT_PUBLIC_API_URL}/v1/transcripts/${props.transcriptId}/audio/mp3`
: undefined,
});
const wsWrapper = _wavesurfer.getWrapper();
wsWrapper.style.cursor = "pointer";
wsWrapper.style.backgroundColor = "#e0c3fc42";
@@ -103,6 +110,8 @@ export default function Recorder(props: RecorderProps) {
setRecord(_wavesurfer.registerPlugin(RecordPlugin.create()));
setWaveRegions(_wavesurfer.registerPlugin(CustomRegionsPlugin.create()));
if (props.transcriptId) _wavesurfer.toggleInteraction(true);
setWavesurfer(_wavesurfer);
return () => {
_wavesurfer.destroy();
@@ -208,18 +217,21 @@ export default function Recorder(props: RecorderProps) {
if (!record) return console.log("no record");
if (record.isRecording()) {
props.onStop();
if (props.onStop) props.onStop();
record.stopRecording();
setIsRecording(false);
setHasRecorded(true);
} else {
} else if (props.getAudioStream) {
const stream = await props.getAudioStream(deviceId);
props.setStream(stream);
if (props.setStream) props.setStream(stream);
waveRegions?.clearRegions();
if (stream) {
await record.startRecording(stream);
setIsRecording(true);
}
} else {
throw new Error("No getAudioStream function provided");
}
};
@@ -266,13 +278,26 @@ export default function Recorder(props: RecorderProps) {
>
{isPlaying ? "Pause" : "Play"}
</button>
<a
id="download-recording"
title="Download recording"
className="invisible w-9 m-auto text-center cursor-pointer text-blue-300 hover:text-blue-700"
>
<FontAwesomeIcon icon={faDownload} />
</a>
{props.transcriptId && (
<a
title="Download recording"
className="w-9 m-auto text-center cursor-pointer text-blue-300 hover:text-blue-700"
href={`${process.env.NEXT_PUBLIC_API_URL}/v1/transcripts/${props.transcriptId}/audio/mp3`}
>
<FontAwesomeIcon icon={faDownload} />
</a>
)}
{!props.transcriptId && (
<a
id="download-recording"
title="Download recording"
className="invisible w-9 m-auto text-center cursor-pointer text-blue-300 hover:text-blue-700"
>
<FontAwesomeIcon icon={faDownload} />
</a>
)}
</>
)}
</div>