Last active
November 19, 2023 12:29
-
-
Save barakplasma/5f76c6bcd38cfc4d7c1ee59c429279a4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Text-To-Speech Toggle | |
// @namespace http://tampermonkey.net/ | |
// @version 0.4 | |
// @description text to speech for qireader articles with toggle button | |
// @author Michael Salaverry | |
// @match https://www.qireader.com/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=qireader.com | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
let utterance; | |
let button; // Keep a reference to the button | |
function updateButtonIcon() { | |
if (button) { | |
button.textContent = speechSynthesis.speaking ? '๐' : '๐'; | |
} | |
} | |
function read() { | |
if (!speechSynthesis.speaking) { | |
const article = document.querySelector('#root article'); | |
if (article) { | |
const text = article.innerText; | |
utterance = new SpeechSynthesisUtterance(text); | |
utterance.onstart = () => { | |
updateButtonIcon(); | |
}; | |
utterance.onend = () => { | |
updateButtonIcon(); | |
}; | |
utterance.onerror = () => { | |
updateButtonIcon(); | |
}; | |
speechSynthesis.speak(utterance); | |
} | |
} else { | |
speechSynthesis.cancel(); | |
updateButtonIcon(); // Update the icon immediately when stopping the speech | |
} | |
} | |
function createTTSButton() { | |
button = document.createElement('button'); | |
updateButtonIcon(); // Set the initial icon | |
button.addEventListener('click', read); | |
// Prepend the button to the beginning of the navigation bar | |
const blankSpace = document.querySelector('#root .article-page nav div.blank-space'); | |
if (blankSpace) { | |
blankSpace.insertAdjacentElement('afterend', button); | |
} else { | |
console.error('Navigation bar element not found!'); | |
} | |
} | |
// Poll the DOM until the element is available | |
const checkExist = setInterval(function() { | |
const navBar = document.querySelector('#root .article-page nav'); | |
if (navBar) { | |
clearInterval(checkExist); | |
createTTSButton(); | |
} | |
}, 100); // check every 100ms | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment