Add button to copy generated text to clipboard

This commit is contained in:
ChaoticByte 2025-06-08 14:08:13 +02:00
parent 3b9fab0ebb
commit b6fd46b87d
No known key found for this signature in database
4 changed files with 37 additions and 8 deletions

View file

@ -15,7 +15,10 @@
<audio class="nodisplay" id="audioPrev" controls></audio> <audio class="nodisplay" id="audioPrev" controls></audio>
<button class="transcribeBtn symbtn nodisplay" id="transcribeBtn"></button> <button class="transcribeBtn symbtn nodisplay" id="transcribeBtn"></button>
</div> </div>
<div class="transcript" id="transcript"></div> <div class="transcriptContainer">
<div class="transcript" id="transcript"></div>
<button class="copyBtn symbtn nodisplay" id="copyBtn"></button>
</div>
<script src="main.js" type="module"></script> <script src="main.js" type="module"></script>
</body> </body>
</html> </html>

View file

@ -87,13 +87,28 @@ button {
background-repeat: no-repeat; background-repeat: no-repeat;
background-image: url("material-icons/transcribe.svg"); background-image: url("material-icons/transcribe.svg");
} }
.transcript { .copyBtn {
width: 2.5rem;
height: 2.5rem;
background-size: 2rem;
background-image: url("material-icons/copy.svg");
}
.transcriptContainer {
margin-top: 5rem; margin-top: 5rem;
display: block; display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
gap: 1rem;
width: 60%; width: 60%;
height: fit-content; height: fit-content;
text-align: center; text-align: center;
} }
.transcript {
display: block;
width: 100%;
height: 100%;
}
.transcript.loading { .transcript.loading {
font-size: 0; font-size: 0;
background-image: url("material-icons/cycle.svg"); background-image: url("material-icons/cycle.svg");
@ -112,7 +127,7 @@ button {
} }
} }
@media only screen and (max-width: 800px) { @media only screen and (max-width: 800px) {
.transcript { .transcriptContainer {
width: 90%; width: 90%;
} }
} }

View file

@ -17,6 +17,7 @@ async function api_is_online(settings) {
let audioPrev = document.getElementById("audioPrev"); let audioPrev = document.getElementById("audioPrev");
let transcribeBtn = document.getElementById("transcribeBtn"); let transcribeBtn = document.getElementById("transcribeBtn");
let transcriptText = document.getElementById("transcript"); let transcriptText = document.getElementById("transcript");
let copyBtn = document.getElementById("copyBtn");
// Load Settings // Load Settings
const settings_resp = await fetch("settings.json"); const settings_resp = await fetch("settings.json");
const settings = await settings_resp.json(); const settings = await settings_resp.json();
@ -24,7 +25,7 @@ async function api_is_online(settings) {
settings.api_url = settings.api_url.substring(0, settings.api_url.length - 1); settings.api_url = settings.api_url.substring(0, settings.api_url.length - 1);
} }
if (await api_is_online(settings)) { if (await api_is_online(settings)) {
// Recorder // Audio Recorder
let audioBlob; let audioBlob;
const recorder = new Recorder(startBtn, stopBtn, async (blob) => { const recorder = new Recorder(startBtn, stopBtn, async (blob) => {
audioBlob = blob; audioBlob = blob;
@ -34,16 +35,22 @@ async function api_is_online(settings) {
transcribeBtn.classList.remove("nodisplay"); transcribeBtn.classList.remove("nodisplay");
}); });
recorder.init(); recorder.init();
// Additional handlers // Handlers
copyBtn.addEventListener("click", () => {
navigator.clipboard.writeText(transcriptText.innerText);
});
startBtn.addEventListener("click", () => { startBtn.addEventListener("click", () => {
// Recording
audioPrev.classList.add("nodisplay"); audioPrev.classList.add("nodisplay");
transcribeBtn.classList.add("nodisplay"); transcribeBtn.classList.add("nodisplay");
transcriptText.innerText = ""; transcriptText.innerText = "";
}) copyBtn.classList.add("nodisplay");
// Transcribe });
transcribeBtn.addEventListener("click", async () => { transcribeBtn.addEventListener("click", async () => {
// Transcription
transcribeBtn.disabled = true; transcribeBtn.disabled = true;
transcriptText.classList.add("loading"); transcriptText.classList.add("loading");
copyBtn.classList.add("nodisplay");
const formData = new FormData(); const formData = new FormData();
formData.append("audio", audioBlob); formData.append("audio", audioBlob);
let response = await fetch(settings.api_url, { let response = await fetch(settings.api_url, {
@ -52,6 +59,9 @@ async function api_is_online(settings) {
}); });
let t = await response.text(); let t = await response.text();
transcriptText.innerText = t; transcriptText.innerText = t;
if (transcriptText.innerText.length > 0) {
copyBtn.classList.remove("nodisplay");
}
transcriptText.classList.remove("loading"); transcriptText.classList.remove("loading");
transcribeBtn.disabled = false; transcribeBtn.disabled = false;
}); });

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z"/></svg>

After

Width:  |  Height:  |  Size: 340 B