mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 04:39:06 +00:00
add markers + sync w/ topics
This commit is contained in:
@@ -11,8 +11,9 @@ export function Dashboard({
|
|||||||
finalSummary,
|
finalSummary,
|
||||||
topics,
|
topics,
|
||||||
disconnected,
|
disconnected,
|
||||||
|
useActiveTopic,
|
||||||
}) {
|
}) {
|
||||||
const [openIndex, setOpenIndex] = useState(null);
|
const [activeTopic, setActiveTopic] = useActiveTopic;
|
||||||
const [autoscrollEnabled, setAutoscrollEnabled] = useState(true);
|
const [autoscrollEnabled, setAutoscrollEnabled] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -76,18 +77,26 @@ export function Dashboard({
|
|||||||
<div key={index} className="border-b-2 py-2 hover:bg-[#8ec5fc30]">
|
<div key={index} className="border-b-2 py-2 hover:bg-[#8ec5fc30]">
|
||||||
<div
|
<div
|
||||||
className="flex justify-between items-center cursor-pointer px-4"
|
className="flex justify-between items-center cursor-pointer px-4"
|
||||||
onClick={() => setOpenIndex(openIndex === index ? null : index)}
|
onClick={() =>
|
||||||
|
setActiveTopic(
|
||||||
|
activeTopic == item.timestamp ? null : item.timestamp,
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className="w-1/4">{formatTime(item.timestamp)}</div>
|
<div className="w-1/4">{formatTime(item.timestamp)}</div>
|
||||||
<div className="w-3/4 flex justify-between items-center">
|
<div className="w-3/4 flex justify-between items-center">
|
||||||
{item.title}
|
{item.title}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
className={`transform transition-transform duration-200`}
|
className={`transform transition-transform duration-200`}
|
||||||
icon={openIndex === index ? faChevronDown : faChevronRight}
|
icon={
|
||||||
|
activeTopic == item.timestamp
|
||||||
|
? faChevronDown
|
||||||
|
: faChevronRight
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{openIndex === index && (
|
{activeTopic == item.timestamp && (
|
||||||
<div className="p-2 mt-2 -mb-2 bg-slate-50 rounded">
|
<div className="p-2 mt-2 -mb-2 bg-slate-50 rounded">
|
||||||
{item.transcript}
|
{item.transcript}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useRef, useEffect, useState } from "react";
|
import React, { useRef, useEffect, useState } from "react";
|
||||||
|
|
||||||
import WaveSurfer from "wavesurfer.js";
|
import WaveSurfer from "wavesurfer.js";
|
||||||
|
import RegionsPlugin from "wavesurfer.js/dist/plugins/regions";
|
||||||
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faDownload } from "@fortawesome/free-solid-svg-icons";
|
import { faDownload } from "@fortawesome/free-solid-svg-icons";
|
||||||
@@ -58,6 +59,9 @@ export default function Recorder(props) {
|
|||||||
const [currentTime, setCurrentTime] = useState(0);
|
const [currentTime, setCurrentTime] = useState(0);
|
||||||
const [timeInterval, setTimeInterval] = useState(null);
|
const [timeInterval, setTimeInterval] = useState(null);
|
||||||
const [duration, setDuration] = useState(0);
|
const [duration, setDuration] = useState(0);
|
||||||
|
const [waveRegions, setWaveRegions] = useState(null);
|
||||||
|
|
||||||
|
const [activeTopic, setActiveTopic] = props.useActiveTopic;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.getElementById("play-btn").disabled = true;
|
document.getElementById("play-btn").disabled = true;
|
||||||
@@ -87,6 +91,8 @@ export default function Recorder(props) {
|
|||||||
_wavesurfer.on("timeupdate", setCurrentTime);
|
_wavesurfer.on("timeupdate", setCurrentTime);
|
||||||
|
|
||||||
setRecord(_wavesurfer.registerPlugin(CustomRecordPlugin.create()));
|
setRecord(_wavesurfer.registerPlugin(CustomRecordPlugin.create()));
|
||||||
|
setWaveRegions(_wavesurfer.registerPlugin(RegionsPlugin.create()));
|
||||||
|
|
||||||
setWavesurfer(_wavesurfer);
|
setWavesurfer(_wavesurfer);
|
||||||
return () => {
|
return () => {
|
||||||
_wavesurfer.destroy();
|
_wavesurfer.destroy();
|
||||||
@@ -103,6 +109,20 @@ export default function Recorder(props) {
|
|||||||
link.href = record.getRecordedUrl();
|
link.href = record.getRecordedUrl();
|
||||||
link.download = "reflector-recording.webm";
|
link.download = "reflector-recording.webm";
|
||||||
link.style.visibility = "visible";
|
link.style.visibility = "visible";
|
||||||
|
|
||||||
|
for (let topic of props.topics) {
|
||||||
|
const region = waveRegions.addRegion({
|
||||||
|
start: topic.timestamp,
|
||||||
|
content: topic.title.slice(0, 7) + "...",
|
||||||
|
color: "f00",
|
||||||
|
drag: false,
|
||||||
|
});
|
||||||
|
region.on("click", (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setActiveTopic(region.start);
|
||||||
|
wavesurfer.setTime(region.start);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [record]);
|
}, [record]);
|
||||||
@@ -123,6 +143,12 @@ export default function Recorder(props) {
|
|||||||
}
|
}
|
||||||
}, [isRecording]);
|
}, [isRecording]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeTopic) {
|
||||||
|
wavesurfer.setTime(activeTopic);
|
||||||
|
}
|
||||||
|
}, [activeTopic]);
|
||||||
|
|
||||||
const handleRecClick = async () => {
|
const handleRecClick = async () => {
|
||||||
if (!record) return console.log("no record");
|
if (!record) return console.log("no record");
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import "../public/button.css";
|
|||||||
const App = () => {
|
const App = () => {
|
||||||
const [stream, setStream] = useState(null);
|
const [stream, setStream] = useState(null);
|
||||||
const [disconnected, setDisconnected] = useState(false);
|
const [disconnected, setDisconnected] = useState(false);
|
||||||
|
const useActiveTopic = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (process.env.NEXT_PUBLIC_ENV === "development") {
|
if (process.env.NEXT_PUBLIC_ENV === "development") {
|
||||||
@@ -38,6 +39,8 @@ const App = () => {
|
|||||||
webRTC?.peer?.send(JSON.stringify({ cmd: "STOP" }));
|
webRTC?.peer?.send(JSON.stringify({ cmd: "STOP" }));
|
||||||
setStream(null);
|
setStream(null);
|
||||||
}}
|
}}
|
||||||
|
topics={webSockets.topics}
|
||||||
|
useActiveTopic={useActiveTopic}
|
||||||
/>
|
/>
|
||||||
<Dashboard
|
<Dashboard
|
||||||
transcriptionText={webSockets.transcriptText}
|
transcriptionText={webSockets.transcriptText}
|
||||||
@@ -45,6 +48,7 @@ const App = () => {
|
|||||||
topics={webSockets.topics}
|
topics={webSockets.topics}
|
||||||
stream={stream}
|
stream={stream}
|
||||||
disconnected={disconnected}
|
disconnected={disconnected}
|
||||||
|
useActiveTopic={useActiveTopic}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user