const fs = require('fs'); const ini = require('ini'); const path = require('path'); // get directory path const { ipcRenderer } = require('electron'); // necessary electron libraries to send data to the app const say = require('say'); const request = require('request'); const langdetect = require('langdetect'); const io = require('socket.io-client'); const util = require('util'); const exec = util.promisify(require('child_process').exec); const GoogleTTS = require('node-google-tts-api'); const tts = new GoogleTTS(); const { Socket } = require('socket.io-client'); const main = ipcRenderer.sendSync('environment'); const resourcesPath = main.resourcesPath; const settingsPath = main.settingsPath.toString(); const settings = main.settings; // TODO: remove gooogle voices txt and use api instead const googleVoices = fs.readFileSync(path.join(resourcesPath, './config/googleVoices.txt')).toString().split('\r\n'); // TODO: remove amazon voices txt and use api instead (sakura project has it) const amazonVoices = fs.readFileSync(path.join(resourcesPath, './config/amazonVoices.txt')).toString().split('\r\n'); const languagesObject = fs.readFileSync(path.join(resourcesPath, './config/languages.txt')).toString().split('\r\n'); // html elements const root = document.documentElement; const ttsSelector = document.body.querySelector('#TTSSelector'); const amazonVoiceSelect = document.querySelector('#amazonVoice'); // obtain the html reference of the amazon voices comboBox const notificationAudioDevices = document.querySelector('#notificationAudioDevice'); // obtain the html reference of the installedTTS comboBox const devicesDropdown = document.querySelector('#devicesDropdown'); const notificationSound = document.querySelector('#notification'); // obtain the html reference of the sound comboBox const ttsAudioDevices = document.querySelector('#ttsAudioDevice'); // obtain the html reference of the installedTTS comboBox // laod local javascript files const chat = require(path.join(resourcesPath, './js/chat')); const messageTemplates = require(path.join(resourcesPath, './js/messageTemplates')); const logger = require(path.join(resourcesPath, './js/logger')); const sound = require(path.join(resourcesPath, './js/sound')); const talk = require(path.join(resourcesPath, './js/voiceQueue')); // Voice queue system const config = require(path.join(resourcesPath, './js/settings')); let notificationSounds = path.join(resourcesPath, './sounds/notifications'); let twitch = require(path.join(resourcesPath, './js/twitch')); function reset() { ipcRenderer.send('restart'); } let server; let socket; function setServer() { if (!settings.SERVER.USE_SERVER) { return; } server = require(path.join(resourcesPath, './js/server')); socket = io(`http://localhost:${settings.SERVER.PORT}`); // Connect to your Socket.IO server } setServer(); const Polly = settings.AMAZON.USE_AMAZON ? require(path.join(resourcesPath, './js/amazon')) : ''; const google = settings.GOOGLE.USE_GOOGLE ? require(path.join(resourcesPath, './js/amazon')) : ''; const theme = require(path.join(resourcesPath, './js/theme')); // initialize values config.getGeneralSettings(); const TTSVolume = 1; const notificationSoundVolume = 1; // const slider = document.body.querySelector('#slider'); const StartDateAndTime = Date.now(); const speakButton = document.querySelector('#speakBtn'); const amazonCredentials = { accessKeyId: settings.AMAZON.ACCESS_KEY, secretAccessKey: settings.AMAZON.ACCESS_SECRET, }; // Check for installed sounds fs.readdir(notificationSounds, (err, files) => { files.forEach((file, i) => { // Create a new option element. const option = document.createElement('option'); // Set the options value and text. option.value = i; option.innerHTML = file; // Add the option to the sound selector. notificationSound.appendChild(option); }); // set the saved notification sound notificationSound.selectedIndex = settings.AUDIO.NOTIFICATION_SOUND; }); async function getAudioDevices() { if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { // logger.info('enumerateDevices() not supported.'); return; } const devices = await navigator.mediaDevices.enumerateDevices(); const audioOutputDevices = devices.filter((device) => device.kind === 'audiooutput'); audioOutputDevices.forEach((device) => { const option = document.createElement('option'); option.text = device.label || `Output ${device.deviceId}`; option.value = device.deviceId; ttsAudioDevices.appendChild(option); }); ttsAudioDevices.selectedIndex = settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE; } getAudioDevices(); function setLanguagesinSelect(languageSelector, setting) { let languageSelect = document.querySelector(languageSelector); // obtain the html reference of the google voices comboBox const languages = Object.keys(languagesObject); languages.forEach((language) => { const option = document.createElement('option'); option.value = language; option.innerHTML = languagesObject[language]; languageSelect.appendChild(option); }); languageSelect.selectedIndex = setting; } setLanguagesinSelect('#primaryLanguage', settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX); setLanguagesinSelect('#secondaryLanguage', settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX); function getInstalledVoices(callback) { say.getInstalledVoices((err, voices) => { function setVoicesinSelect(voiceSelector) { let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox const internalTTSHeader = document.createElement('optgroup'); internalTTSHeader.label = 'Internal TTS'; voiceSelect.appendChild(internalTTSHeader); // const installedTTS = document.querySelector('#installedTTS'); // obtain the html reference of the installedTTS comboBox voices.forEach((voice, i) => { const option = document.createElement('option'); option.value = i; option.innerHTML = voice; // installedTTS.appendChild(option); internalTTSHeader.appendChild(option); }); } setVoicesinSelect('#primaryVoice'); setVoicesinSelect('#secondaryVoice'); callback(); }); } function getAmazonVoices(callback) { if (!settings.AMAZON.USE_AMAZON) { callback(); return; } function setVoicesinSelect(voiceSelector) { let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox const internalTTSHeader = document.createElement('optgroup'); internalTTSHeader.label = 'Amazon TTS'; voiceSelect.appendChild(internalTTSHeader); const voices = Object.keys(amazonVoices); voices.forEach((voice) => { const option = document.createElement('option'); option.value = voice; option.innerHTML = amazonVoices[voice]; internalTTSHeader.appendChild(option); }); } setVoicesinSelect('#primaryVoice'); setVoicesinSelect('#secondaryVoice'); callback(); } function getGoogleVoices(callback) { if (!settings.GOOGLE.USE_GOOGLE) { callback(); return; } function setVoicesinSelect(voiceSelector) { let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox const internalTTSHeader = document.createElement('optgroup'); internalTTSHeader.label = 'Google TTS'; voiceSelect.appendChild(internalTTSHeader); const googleVoiceSelect = document.querySelector('#googleVoice'); // obtain the html reference of the google voices comboBox const voices = Object.keys(googleVoices); voices.forEach((voice) => { const option = document.createElement('option'); option.classList.add('option'); option.value = voice; option.innerHTML = googleVoices[voice]; internalTTSHeader.appendChild(option); }); } setVoicesinSelect('#primaryVoice'); setVoicesinSelect('#secondaryVoice'); callback(); } getGoogleVoices(function () { getAmazonVoices(function () { getInstalledVoices(function () { let primaryVoice = document.querySelector('#primaryVoice'); primaryVoice.selectedIndex = settings.TTS.PRIMARY_TTS_VOICE; let secondaryVoice = document.querySelector('#secondaryVoice'); secondaryVoice.selectedIndex = settings.TTS.SECONDARY_TTS_VOICE; }); }); }); // Small tooltip Array.from(document.body.querySelectorAll('[tip]')).forEach((el) => { const tip = document.createElement('div'); const body = document.querySelector('.container'); const element = el; tip.classList.add('tooltip'); tip.classList.add('tooltiptext'); tip.innerText = el.getAttribute('tip'); tip.style.transform = `translate(${el.hasAttribute('tip-left') ? 'calc(-100% - 5px)' : '15px'}, ${ el.hasAttribute('tip-top') ? '-100%' : '15px' })`; body.appendChild(tip); element.onmousemove = (e) => { tip.style.left = `${e.x}px`; tip.style.top = `${e.y}px`; tip.style.zIndex = 1; tip.style.visibility = 'visible'; }; element.onmouseleave = (e) => { tip.style.visibility = 'hidden'; }; }); function showChatMessage(article) { document.querySelector('#chatBox').appendChild(article); const messages = Array.from(document.body.querySelectorAll('.msg-container')); const lastMessage = messages[messages.length - 1]; lastMessage.scrollIntoView({ behavior: 'smooth' }); } function getPostTime() { const date = new Date(); document.body.querySelectorAll('.container').innerHTML = date.getHours(); const hours = date.getHours(); const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes(); const time = `${hours}:${minutes}`; return time; } function showPreviewChatMessage() { const message = messageTemplates.messageTemplate; document.querySelector('#mini-mid').innerHTML += message; const messages = Array.from(document.body.querySelectorAll('#mini-mid')); const lastMessage = messages[messages.length - 1]; lastMessage.scrollIntoView({ behavior: 'smooth' }); } showPreviewChatMessage(); function hideText(button, field) { document.body.querySelector(button).addEventListener('click', () => { const passwordInput = document.querySelector(field); if (passwordInput.type === 'password') { passwordInput.type = 'lol'; } else { passwordInput.type = 'password'; } }); } hideText('.password-toggle-btn1', '#TWITCH_OAUTH_TOKEN'); hideText('.password-toggle-btn4', '#AMAZON_ACCESS_KEY'); hideText('.password-toggle-btn5', '#AMAZON_ACCESS_SECRET'); hideText('.password-toggle-btn6', '#GOOGLE_API_KEY'); // Amazon TTS // const polly = new Polly(amazonCredentials); // const options = { // text: 'Hallo mijn naam is KEES', // voiceId: 'Lotte', // }; // const fileStream = fs.createWriteStream(path.join(resourcesPath, '/public/sounds/tts/Amazon_audio.mp3')); // polly.textToSpeech(options, (err, audioStream) => { // if (err) { // return console.warn(err.message); // } // audioStream.pipe(fileStream); // return 1; // });