i want to make pause and resume function in the same button, but the error message indicate that the port was closed. i assume that the sendMessage failed to send a message to my background.js like the error literally said, or the speechSynthesis status like speaking, paused, etc only updated on readSelectedText() function.
here is my background.js:
let isPaused = false;
let currentUtterance = null;
function readSelectedText(text) {
chrome.storage.sync.get(["selectedVoice", "selectedRate", "selectedVolume"], (data) => {
if (speechSynthesis.speaking) {
speechSynthesis.cancel();
console.log("read text:", text, speechSynthesis.speaking);
}
let utterance = new SpeechSynthesisUtterance(text);
let voices = speechSynthesis.getVoices();
if (data.selectedVoice) {
let selectedVoice = voices.find(v => v.name === data.selectedVoice);
if (selectedVoice) {
utterance.voice = selectedVoice;
}
}
utterance.rate = data.selectedRate || 1.0;
utterance.volume = data.selectedVolume !== undefined ? data.selectedVolume : 1.0;
// Event listener for update status
utterance.onstart = () => {
isPaused = false;
chrome.storage.sync.set({ isPaused: false, isSpeaking: true });
console.log("im on start");
};
utterance.onpause = () => {
isPaused = true;
chrome.storage.sync.set({ isPaused: true });
console.log("im onpause");
};
utterance.onresume = () => {
isPaused = false;
chrome.storage.sync.set({ isPaused: false });
console.log("im onresume");
};
utterance.onend = () => {
isPaused = false;
chrome.storage.sync.set({ isPaused: false, isSpeaking: false });
console.log("im onend");
};
speechSynthesis.speak(utterance);
console.log("read text:", text, speechSynthesis.speaking);
});
}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// console.log("reciving request action:", request.action);
if (request.action === "pauseSpeech") {
if (!speechSynthesis.paused) {
// speechSynthesis.pause();
speechSynthesis.pause();
chrome.storage.sync.set({ isPaused: true });
sendResponse({ status: "paused" });
// return true;
} else {
console.log("on pause.");
sendResponse({ status: "already_paused" });
// return true;
}
}
else if (request.action === "resumeSpeech") {
if (speechSynthesis.paused) {
speechSynthesis.resume();
chrome.storage.sync.set({ isPaused: false });
sendResponse({ status: "resumed" });
// return true;
} else {
console.log("playing.");
sendResponse({ status: "already_playing" });
// return true;
}
}
return true;
});
here is my voice.js:
const pauseSpeech = document.getElementById("pauseSpeech");
const status = document.getElementById("status");
const data = document.getElementById("data");
pauseSpeech.addEventListener("click", () => {
console.log("aku paused click");
// speechSynthesis.pause();
chrome.storage.sync.get(["isPaused"], (result) => {
if (!result.isPaused) {
console.log("im if click");
chrome.runtime.sendMessage({ action: "pauseSpeech" }, (response) => {
if (chrome.runtime.lastError) {
data.innerText = `
Error sending message:, ${chrome.runtime.lastError.message}`;
return true;
} else {
data.innerText = `Status: ${response.status}`;
return true;
}
});
} else {
// speechSynthesis.resume();
chrome.runtime.sendMessage({ action: "resumeSpeech" }, (response) => {
if (chrome.runtime.lastError) {
data.innerText = `
Error sending message:, ${chrome.runtime.lastError.message}`;
console.log("im else");
return true;
} else {
data.innerText = `Status: ${response.status}`;
return true;
}
});
}
return true;
});
});
what im expecting is when user right click the selected phrase then click contextMenu "read selected" the selcted text get readed with speechSynthesis and when user click pause button the speechSynthesis get paused and if the user click pause button again the speechSynthesis get resume.
i already tried giving speechSynthesis.pause() and resume directly in voices.js the pause function is working but not the resume, here's what it's like:
pauseSpeech.addEventListener("click", () => {
console.log("pauseSpeech");
if (!isPaused) {
speechSynthesis.pause();
isPaused = true;
data.innerText = `
Speaking: ${speechSynthesis.speaking},
Paused: ${speechSynthesis.paused},
Pending: ${speechSynthesis.pending}.`;
} else{
speechSynthesis.resume();
isPaused = false;
data.innerText = `
Speaking: ${speechSynthesis.speaking},
Paused: ${speechSynthesis.paused},
Pending: ${speechSynthesis.pending}.`;
}
});