-
Notifications
You must be signed in to change notification settings - Fork 0
/
foreground.js
92 lines (84 loc) · 2.08 KB
/
foreground.js
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
const input = document.querySelector('textarea');
const button = document.querySelector('button.absolute');
const mic = new webkitSpeechRecognition();
const speaker = new SpeechSynthesisUtterance();
mic.continuous = true;
speaker.rate = 0.8;
let results;
let interval;
let prevWords = '';
let answerIndex = 0;
let answer = [];
// Popup actions
chrome.runtime.onMessage.addListener((request) => {
switch (request.operation) {
case 'START_RECORD':
mic.start();
break;
case 'STOP_RECORD':
mic.stop();
break;
default:
break;
}
});
// Mic start event as a cleanup
mic.onstart = () => {
prevWords = '';
answerIndex = 0;
answer = [];
};
// Mic results and send to ChatGPT
mic.onresult = (e) => {
mic.stop();
const question = e.results[e.results.length - 1][0].transcript;
input.innerText = question;
button.click();
input.innerText = '';
};
// ChatGPT answer catcher
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation, i) => {
if (mutation.type === 'characterData' && results) {
const text = mutation.target.data.replace(prevWords, '');
const index = text.indexOf(text.match(/[?.,!;:]/));
if (index !== -1) {
answer.push(text.trim());
prevWords = mutation.target.data;
if (answer.length === 1) {
speak(answer[0]);
}
}
}
});
});
// Function for synchronous reading (recursively)
function speak(text) {
if (text) {
speaker.text = text;
speaker.onend = () => {
answerIndex++;
if (!answer[answerIndex]) {
results = null;
scanResults();
mic.start();
} else {
speak(answer[answerIndex]);
}
};
window.speechSynthesis.speak(speaker);
}
}
// Is ChatGPT start to work?
function scanResults() {
interval = setInterval(() => {
if (results) {
observer.observe(results, { characterData: true, childList: true, subtree: true });
clearInterval(interval);
} else {
results = document.querySelector('div.result-streaming');
}
}, 500);
}
// Let's play!
scanResults();