Spaces:
Sleeping
Sleeping
File size: 3,597 Bytes
260b4c9 04e24a5 bb9ca3a af9d8fe ea3a134 cad6d79 bb9ca3a ea3a134 04e24a5 1169147 ebe3b4a 1169147 ebe3b4a 1169147 5ab618a 260b4c9 5ab618a 260b4c9 1169147 5ab618a 04e24a5 260b4c9 ebe3b4a 260b4c9 04e24a5 bb9ca3a 260b4c9 5df3fb6 19d4e62 bb9ca3a 19d4e62 4a49607 bb9ca3a 260b4c9 5ab618a 260b4c9 1169147 260b4c9 5ab618a bb9ca3a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
import { useRef, useEffect } from "react";
import { TranscriberData } from "../hooks/useTranscriber";
import { formatAudioTimestamp } from "../utils/AudioUtils";
interface Props {
transcribedData: TranscriberData | undefined;
}
export default function Transcript({ transcribedData }: Props) {
const divRef = useRef<HTMLDivElement>(null);
const saveBlob = (blob: Blob, filename: string) => {
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = filename;
link.click();
URL.revokeObjectURL(url);
};
const exportTXT = () => {
let chunks = transcribedData?.chunks ?? [];
let text = chunks
.map((chunk) => chunk.text)
.join("")
.trim();
const blob = new Blob([text], { type: "text/plain" });
saveBlob(blob, "transcript.txt");
};
const exportJSON = () => {
let jsonData = JSON.stringify(transcribedData?.chunks ?? [], null, 2);
// post-process the JSON to make it more readable
const regex = /( "timestamp": )\[\s+(\S+)\s+(\S+)\s+\]/gm;
jsonData = jsonData.replace(regex, "$1[$2 $3]");
const blob = new Blob([jsonData], { type: "application/json" });
saveBlob(blob, "transcript.json");
};
// Scroll to the bottom when the component updates
useEffect(() => {
if (divRef.current) {
const diff = Math.abs(
divRef.current.offsetHeight +
divRef.current.scrollTop -
divRef.current.scrollHeight,
);
if (diff <= 64) {
// We're close enough to the bottom, so scroll to the bottom
divRef.current.scrollTop = divRef.current.scrollHeight;
}
}
});
return (
<div
ref={divRef}
className='w-full flex flex-col my-2 p-4 max-h-[20rem] overflow-y-auto'
>
{transcribedData?.chunks &&
transcribedData.chunks.map((chunk, i) => (
<div
key={`${i}-${chunk.text}`}
className='w-full flex flex-row mb-2 bg-white rounded-lg p-4 shadow-xl shadow-black/5 ring-1 ring-slate-700/10'
>
<div className='mr-5'>
{formatAudioTimestamp(chunk.timestamp[0])}
</div>
{chunk.text}
</div>
))}
{transcribedData && !transcribedData.isBusy && (
<div className='w-full text-right'>
<button
onClick={exportTXT}
className='text-white bg-green-500 hover:bg-green-600 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-4 py-2 text-center mr-2 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800 inline-flex items-center'
>
Export TXT
</button>
<button
onClick={exportJSON}
className='text-white bg-green-500 hover:bg-green-600 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-4 py-2 text-center mr-2 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800 inline-flex items-center'
>
Export JSON
</button>
</div>
)}
</div>
);
}
|