betterttv, send translated message.
This commit is contained in:
parent
0efb495339
commit
ccda0a7736
10 changed files with 265 additions and 41 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -108,3 +108,4 @@ backend/*
|
||||||
backend/loquendoBot_backend.exe
|
backend/loquendoBot_backend.exe
|
||||||
src/config/twitch-emotes.json
|
src/config/twitch-emotes.json
|
||||||
dist/*
|
dist/*
|
||||||
|
src/config/betterttv-emotes.json
|
||||||
|
|
|
||||||
|
|
@ -236,11 +236,14 @@ def get_translation():
|
||||||
request_data = request.json
|
request_data = request.json
|
||||||
message = request_data.get("message", "")
|
message = request_data.get("message", "")
|
||||||
detectedLanguage = request_data.get("language", "")
|
detectedLanguage = request_data.get("language", "")
|
||||||
|
try:
|
||||||
translated = MyMemoryTranslator(
|
translated = MyMemoryTranslator(
|
||||||
source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"]
|
source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"]
|
||||||
).translate(message)
|
).translate(message)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"error": "Could not translate, continuing with next language"}), 500
|
return jsonify({"error": str(e), "code":429 }), 429
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e), "code":500 }), 500
|
||||||
return jsonify({"translation": translated}), 200
|
return jsonify({"translation": translated}), 200
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -541,6 +541,10 @@ h1 {
|
||||||
margin: 20px 0px 0px 0px;
|
margin: 20px 0px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.translation-message.user {
|
||||||
|
margin: -20px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.translation-icon {
|
.translation-icon {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0px 0px 0px 0px;
|
padding: 0px 0px 0px 0px;
|
||||||
|
|
@ -558,3 +562,14 @@ h1 {
|
||||||
height: 20px !important;
|
height: 20px !important;
|
||||||
left: 18px;
|
left: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flag-icon.user {
|
||||||
|
left: -18px;
|
||||||
|
top: -15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-flag {
|
||||||
|
left: unset;
|
||||||
|
right: 18px;
|
||||||
|
top: -65px;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,16 @@
|
||||||
tip="All translated messages will be send to primary TTS voice but if message is detected in Secondary TTS language it will output it to the Secondary TTS voice"
|
tip="All translated messages will be send to primary TTS voice but if message is detected in Secondary TTS language it will output it to the Secondary TTS voice"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="AdvancedMenuRow languageDetectionInput">
|
||||||
|
<div class="AdvancedMenuLabel">Send translated messages</div>
|
||||||
|
<input type="checkbox" id="SEND_TRANSLATION" class="checkbox" />
|
||||||
|
<label for="SEND_TRANSLATION" class="toggle-small" style="margin-right: 260px"></label>
|
||||||
|
<i
|
||||||
|
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
||||||
|
id="Info_SEND_TRANSLATION"
|
||||||
|
tip="Enable sending translated messages to the chat."
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset id="NotificationMenu" class="AdvancedMenu">
|
<fieldset id="NotificationMenu" class="AdvancedMenu">
|
||||||
|
|
@ -371,6 +381,17 @@
|
||||||
tip="Test Twitch credentials"
|
tip="Test Twitch credentials"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="AdvancedMenuRow inputTwitch">
|
||||||
|
<div class="AdvancedMenuLabel">Get BetterTTV emotes</div>
|
||||||
|
<button type="text" class="AdvancedMenuButton" id="GetBetterTtvEmotes">
|
||||||
|
<img src="https://cdn.betterttv.net/emote/5f1b0186cf6d2144653d2970/3x.webp" width="30px" height="30px" />
|
||||||
|
</button>
|
||||||
|
<i
|
||||||
|
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
||||||
|
id="Info_BETTERTTV_EMOTES"
|
||||||
|
tip="Test Twitch credentials"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset id="AdvancedMenuServer" class="AdvancedMenu">
|
<fieldset id="AdvancedMenuServer" class="AdvancedMenu">
|
||||||
|
|
@ -583,19 +604,19 @@
|
||||||
</button>
|
</button>
|
||||||
<emoji-picker class="dark"></emoji-picker>
|
<emoji-picker class="dark"></emoji-picker>
|
||||||
</div>
|
</div>
|
||||||
<div class="pop in">
|
<div class="pop in send-translation">
|
||||||
<div class="miniText">In</div>
|
<div class="miniText">In</div>
|
||||||
<button class="SmallButton">
|
<button class="SmallButton">
|
||||||
<i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i>
|
<i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="pop-content"></div>
|
<div class="pop-content" id="SEND_TRANSLATION_IN"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pop out">
|
<div class="pop out send-translation">
|
||||||
<div class="miniText">Out</div>
|
<div class="miniText">Out</div>
|
||||||
<button class="SmallButton">
|
<button class="SmallButton">
|
||||||
<i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i>
|
<i class="fa-solid fa-globe fa-2x" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="pop-content"></div>
|
<div class="pop-content" id="SEND_TRANSLATION_OUT"></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- User text input-->
|
<!-- User text input-->
|
||||||
<input id="textInput" class="input-box" type="text" name="msg" placeholder="Tap 'Enter' to send a message" />
|
<input id="textInput" class="input-box" type="text" name="msg" placeholder="Tap 'Enter' to send a message" />
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,46 @@ async function getInstalledVoices() {
|
||||||
secondaryVoice.value = settings.TTS.SECONDARY_VOICE;
|
secondaryVoice.value = settings.TTS.SECONDARY_VOICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: refactor
|
||||||
|
function setTranslatedUserMessage(message) {
|
||||||
|
const userMessage = document.getElementById(message.messageId);
|
||||||
|
const messageBox = userMessage.getElementsByClassName('msg-box')[0];
|
||||||
|
|
||||||
|
const languageElement = document.createElement('span');
|
||||||
|
languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis flag-icon user-flag`;
|
||||||
|
languageElement.setAttribute('tip', message.language.selectedLanguage.name);
|
||||||
|
userMessage.appendChild(languageElement);
|
||||||
|
addSingleTooltip(languageElement);
|
||||||
|
|
||||||
|
const translationHeader = document.createElement('div');
|
||||||
|
translationHeader.className = 'translation-header user';
|
||||||
|
translationHeader.innerText = 'Translation';
|
||||||
|
messageBox.appendChild(translationHeader);
|
||||||
|
|
||||||
|
const languageElement2 = document.createElement('span');
|
||||||
|
languageElement2.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis flag-icon user`;
|
||||||
|
languageElement2.setAttribute('tip', message.language.detectedLanguage.name);
|
||||||
|
addSingleTooltip(languageElement2);
|
||||||
|
messageBox.appendChild(languageElement2);
|
||||||
|
|
||||||
|
const translationMessage = document.createElement('div');
|
||||||
|
translationMessage.className = 'translation-message user';
|
||||||
|
translationMessage.innerText = message.translation;
|
||||||
|
messageBox.appendChild(translationMessage);
|
||||||
|
}
|
||||||
|
|
||||||
function setTranslatedMessage(message) {
|
function setTranslatedMessage(message) {
|
||||||
|
// this determines if it is a message that is send by a user
|
||||||
|
const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0];
|
||||||
|
if (!languageBox) {
|
||||||
|
twitch.sendMessage(
|
||||||
|
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${message.translation}`
|
||||||
|
);
|
||||||
|
return setTranslatedUserMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
|
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
|
||||||
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
|
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
|
||||||
const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0];
|
|
||||||
|
|
||||||
languageBox.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis language-icon flag-icon`;
|
languageBox.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis language-icon flag-icon`;
|
||||||
languageBox.setAttribute('tip', message.language.detectedLanguage.name);
|
languageBox.setAttribute('tip', message.language.detectedLanguage.name);
|
||||||
|
|
@ -60,7 +96,6 @@ function setTranslatedMessage(message) {
|
||||||
const translationIcon = document.createElement('div');
|
const translationIcon = document.createElement('div');
|
||||||
translationIcon.className = 'translation-icon';
|
translationIcon.className = 'translation-icon';
|
||||||
const languageElement = document.createElement('span');
|
const languageElement = document.createElement('span');
|
||||||
const language = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
|
|
||||||
languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis flag-icon`;
|
languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis flag-icon`;
|
||||||
languageElement.setAttribute('tip', message.language.selectedLanguage.name);
|
languageElement.setAttribute('tip', message.language.selectedLanguage.name);
|
||||||
addSingleTooltip(languageElement);
|
addSingleTooltip(languageElement);
|
||||||
|
|
@ -95,7 +130,6 @@ async function getTranslatedMessage(message) {
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
message: message.message,
|
message: message.message,
|
||||||
remainder: message.remainingDetectedLanguages,
|
|
||||||
language: message.language.detectedLanguage.IETF
|
language: message.language.detectedLanguage.IETF
|
||||||
}) // Convert the data to JSON and include it in the request body
|
}) // Convert the data to JSON and include it in the request body
|
||||||
};
|
};
|
||||||
|
|
@ -111,7 +145,6 @@ async function getTranslatedMessage(message) {
|
||||||
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}`
|
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTranslatedMessage({
|
setTranslatedMessage({
|
||||||
originalMessage: message.message,
|
originalMessage: message.message,
|
||||||
translation: responseData.translation,
|
translation: responseData.translation,
|
||||||
|
|
@ -124,6 +157,7 @@ async function getTranslatedMessage(message) {
|
||||||
return message.language.detectedLanguage;
|
return message.language.detectedLanguage;
|
||||||
} else {
|
} else {
|
||||||
console.error(responseData);
|
console.error(responseData);
|
||||||
|
if (responseData.code === 500) {
|
||||||
if (message.remainingDetectedLanguages.length > 0) {
|
if (message.remainingDetectedLanguages.length > 0) {
|
||||||
message.language.detectedLanguage = getLanguageProperties(message.remainingDetectedLanguages[0]);
|
message.language.detectedLanguage = getLanguageProperties(message.remainingDetectedLanguages[0]);
|
||||||
message.remainingDetectedLanguages.shift();
|
message.remainingDetectedLanguages.shift();
|
||||||
|
|
@ -134,11 +168,31 @@ async function getTranslatedMessage(message) {
|
||||||
return getTranslatedMessage(message);
|
return getTranslatedMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (responseData.code === 429) {
|
||||||
|
message.language.detectedLanguage = getLanguageProperties('en-GB');
|
||||||
|
setTranslatedMessage({
|
||||||
|
originalMessage: message.message,
|
||||||
|
translation: 'Rate limit exceeded, please change translation service.',
|
||||||
|
messageId: message.messageId,
|
||||||
|
language: message.language,
|
||||||
|
formattedMessage: message.formattedMessage,
|
||||||
|
username: message.username,
|
||||||
|
logoUrl: message.logoUrl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error sending termination signal:', error);
|
console.error('Error sending termination signal:', error);
|
||||||
message.message = 'Error, Could not translate message';
|
|
||||||
message.language.detectedLanguage = getLanguageProperties('en-GB');
|
message.language.detectedLanguage = getLanguageProperties('en-GB');
|
||||||
getTranslatedMessage(message);
|
setTranslatedMessage({
|
||||||
|
originalMessage: message.message,
|
||||||
|
translation: 'Error, could not translate message.',
|
||||||
|
messageId: message.messageId,
|
||||||
|
language: message.language,
|
||||||
|
formattedMessage: message.formattedMessage,
|
||||||
|
username: message.username,
|
||||||
|
logoUrl: message.logoUrl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -363,4 +417,4 @@ ipcRenderer.on('quit-event', async () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = { getInternalTTSAudio, getDetectedLanguage };
|
module.exports = { getInternalTTSAudio, getDetectedLanguage, getTranslatedMessage };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* global messageTemplates, emojiPicker, settings, getPostTime, showChatMessage, twitch */
|
/* global messageTemplates,getLanguageProperties, backend, messageId emojiPicker, settings, getPostTime, showChatMessage, twitch */
|
||||||
|
|
||||||
async function getResponse() {
|
async function getResponse() {
|
||||||
const userText = document.querySelector('#textInput').value;
|
const userText = document.querySelector('#textInput').value;
|
||||||
|
|
@ -8,8 +8,11 @@ async function getResponse() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messageId++;
|
||||||
|
|
||||||
// Create chat message from received data
|
// Create chat message from received data
|
||||||
const article = document.createElement('article');
|
const article = document.createElement('article');
|
||||||
|
article.setAttribute('id', messageId);
|
||||||
article.className = 'msg-container user';
|
article.className = 'msg-container user';
|
||||||
|
|
||||||
article.innerHTML = messageTemplates.userTemplate;
|
article.innerHTML = messageTemplates.userTemplate;
|
||||||
|
|
@ -29,9 +32,7 @@ async function getResponse() {
|
||||||
|
|
||||||
const msg = article.querySelector('.msg-box');
|
const msg = article.querySelector('.msg-box');
|
||||||
if (msg) {
|
if (msg) {
|
||||||
console.log(0);
|
|
||||||
await replaceChatMessageWithCustomEmojis(userText).then(data => {
|
await replaceChatMessageWithCustomEmojis(userText).then(data => {
|
||||||
// console.log(data);
|
|
||||||
msg.innerHTML = data;
|
msg.innerHTML = data;
|
||||||
|
|
||||||
// Appends the message to the main chat box (shows the message)
|
// Appends the message to the main chat box (shows the message)
|
||||||
|
|
@ -39,6 +40,23 @@ async function getResponse() {
|
||||||
|
|
||||||
twitch.sendMessage(userText);
|
twitch.sendMessage(userText);
|
||||||
|
|
||||||
|
if (settings.LANGUAGE.SEND_TRANSLATION) {
|
||||||
|
const selectedLanguage = getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_IN);
|
||||||
|
const detectedLanguage = getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_OUT);
|
||||||
|
backend.getTranslatedMessage({
|
||||||
|
message: data,
|
||||||
|
messageId: messageId,
|
||||||
|
remainingDetectedLanguages: [],
|
||||||
|
language: {
|
||||||
|
selectedLanguage,
|
||||||
|
detectedLanguage
|
||||||
|
},
|
||||||
|
formattedMessage: data,
|
||||||
|
username: 'You',
|
||||||
|
logoUrl: settings.TWITCH.USER_LOGO_URL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Empty input box after sending message
|
// Empty input box after sending message
|
||||||
document.body.querySelector('#textInput').value = '';
|
document.body.querySelector('#textInput').value = '';
|
||||||
});
|
});
|
||||||
|
|
@ -167,3 +185,7 @@ displayPanelX('.item', '#btnChatCreator', '#btnChatCreator');
|
||||||
// #region Show/Hide Theme Creator
|
// #region Show/Hide Theme Creator
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
replaceChatMessageWithCustomEmojis
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,12 @@ const settings = main.settings;
|
||||||
const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n');
|
const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n');
|
||||||
// TODO: remove amazon voices txt and use api instead (sakura project has it)
|
// TODO: remove amazon voices txt and use api instead (sakura project has it)
|
||||||
const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n');
|
const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n');
|
||||||
const emoteListSavePath =
|
const twitchEmoteListSavePath =
|
||||||
main.isPackaged === true ? path.join(resourcesPath, './twitch-emotes.json') : path.join(resourcesPath, './config/twitch-emotes.json');
|
main.isPackaged === true ? path.join(resourcesPath, './twitch-emotes.json') : path.join(resourcesPath, './config/twitch-emotes.json');
|
||||||
|
const betterTtvEmoteListSavePath =
|
||||||
|
main.isPackaged === true
|
||||||
|
? path.join(resourcesPath, './betterttv-emotes.json')
|
||||||
|
: path.join(resourcesPath, './config/betterttv-emotes.json');
|
||||||
|
|
||||||
// html elements
|
// html elements
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
|
|
@ -178,8 +182,16 @@ function setLanguagesinSelectx(languageSelector, language) {
|
||||||
const languageSelectContent = languageSelect.querySelector('.pop-content');
|
const languageSelectContent = languageSelect.querySelector('.pop-content');
|
||||||
|
|
||||||
languageSelectContent.addEventListener('click', e => {
|
languageSelectContent.addEventListener('click', e => {
|
||||||
console.log(e.target);
|
const parent = e.target.parentElement.id;
|
||||||
language = getLanguageProperties(e.target.getAttribute('value'));
|
language = getLanguageProperties(e.target.getAttribute('value'));
|
||||||
|
|
||||||
|
if (parent === 'SEND_TRANSLATION_IN') {
|
||||||
|
settings.LANGUAGE.SEND_TRANSLATION_IN = language.IETF;
|
||||||
|
} else {
|
||||||
|
settings.LANGUAGE.SEND_TRANSLATION_OUT = language.IETF;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
setSelectedLanguageinSelect(languageSelect, language);
|
setSelectedLanguageinSelect(languageSelect, language);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -378,15 +390,22 @@ function setZoomLevel(currentZoom, zoomIn) {
|
||||||
document.body.querySelector('#ZOOMLEVEL').value = (settings.GENERAL.ZOOMLEVEL * 100).toFixed(0);
|
document.body.querySelector('#ZOOMLEVEL').value = (settings.GENERAL.ZOOMLEVEL * 100).toFixed(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.existsSync(emoteListSavePath)) {
|
// TODO: refactor
|
||||||
fs.readFile(emoteListSavePath, 'utf8', (error, data) => {
|
let twitchEmotes = null;
|
||||||
if (error) {
|
if (fs.existsSync(twitchEmoteListSavePath)) {
|
||||||
console.log(error);
|
const xxx = fs.readFileSync(twitchEmoteListSavePath);
|
||||||
return;
|
twitchEmotes = JSON.parse(xxx);
|
||||||
|
emojiPicker.customEmoji = [...twitchEmotes];
|
||||||
}
|
}
|
||||||
const emotes = JSON.parse(data);
|
let betterTtvEmotes = null;
|
||||||
emojiPicker.customEmoji = emotes;
|
if (fs.existsSync(betterTtvEmoteListSavePath)) {
|
||||||
});
|
const xxx = fs.readFileSync(betterTtvEmoteListSavePath);
|
||||||
|
betterTtvEmotes = JSON.parse(xxx);
|
||||||
|
emojiPicker.customEmoji = [...betterTtvEmotes];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (twitchEmotes && betterTtvEmotes) {
|
||||||
|
emojiPicker.customEmoji = [...twitchEmotes, ...betterTtvEmotes];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLanguageProperties(languageToDetect) {
|
function getLanguageProperties(languageToDetect) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ function getGeneralSettings() {
|
||||||
// Language detection
|
// Language detection
|
||||||
document.body.querySelector('#USE_DETECTION').checked = settings.LANGUAGE.USE_DETECTION;
|
document.body.querySelector('#USE_DETECTION').checked = settings.LANGUAGE.USE_DETECTION;
|
||||||
document.body.querySelector('#OUTPUT_TO_TTS').checked = settings.LANGUAGE.OUTPUT_TO_TTS;
|
document.body.querySelector('#OUTPUT_TO_TTS').checked = settings.LANGUAGE.OUTPUT_TO_TTS;
|
||||||
|
document.body.querySelector('#SEND_TRANSLATION').checked = settings.LANGUAGE.SEND_TRANSLATION;
|
||||||
document.body.querySelector('#BROADCAST_TRANSLATION').checked = settings.LANGUAGE.BROADCAST_TRANSLATION;
|
document.body.querySelector('#BROADCAST_TRANSLATION').checked = settings.LANGUAGE.BROADCAST_TRANSLATION;
|
||||||
|
|
||||||
// TTS
|
// TTS
|
||||||
|
|
@ -323,6 +324,11 @@ document.body.querySelector('#Info_USERNAME').addEventListener('click', async ()
|
||||||
createNotification('Saved OAuth token!', 'success');
|
createNotification('Saved OAuth token!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.body.querySelector('#GetBetterTtvEmotes').addEventListener('click', async () => {
|
||||||
|
twitch.getBetterTtvGLobalEmotes();
|
||||||
|
createNotification('Saved BetterTTV emotes!', 'success');
|
||||||
|
});
|
||||||
|
|
||||||
const hideInputToggleButton = document.body.querySelectorAll('.password-toggle-btn .password-toggle-icon .fa-eye-slash');
|
const hideInputToggleButton = document.body.querySelectorAll('.password-toggle-btn .password-toggle-icon .fa-eye-slash');
|
||||||
hideInputToggleButton.forEach(item => {
|
hideInputToggleButton.forEach(item => {
|
||||||
item.addEventListener('click', () => {
|
item.addEventListener('click', () => {
|
||||||
|
|
@ -518,6 +524,23 @@ document.body.querySelector('#USE_STT').addEventListener('change', () => {
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function toggleSendTranslation() {
|
||||||
|
const toggle = settings.LANGUAGE.SEND_TRANSLATION;
|
||||||
|
const inputs = document.getElementsByClassName('send-translation');
|
||||||
|
toggleRadio(toggle, inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleSendTranslation();
|
||||||
|
|
||||||
|
document.body.querySelector('#SEND_TRANSLATION').addEventListener('change', () => {
|
||||||
|
const toggle = document.getElementById('SEND_TRANSLATION').checked;
|
||||||
|
settings.LANGUAGE.SEND_TRANSLATION = toggle;
|
||||||
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
|
const inputs = document.getElementsByClassName('send-translation');
|
||||||
|
toggleRadio(toggle, inputs);
|
||||||
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Sending translations!`, 'success');
|
||||||
|
});
|
||||||
|
|
||||||
document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
|
document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
|
||||||
let toggle = document.getElementById('OUTPUT_TO_TTS').checked;
|
let toggle = document.getElementById('OUTPUT_TO_TTS').checked;
|
||||||
if (!settings.TTS.USE_TTS) {
|
if (!settings.TTS.USE_TTS) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* global client, playNotificationSound, messageId, addSingleTooltip, settingsPath, fs, ini, backend, main, path, resourcesPath, customEmojis, emojiPicker,config, settings, options, sound, showChatMessage, messageTemplates, getPostTime */
|
/* global client, playNotificationSound, chat, replaceChatMessageWithCustomEmojis, messageId, addSingleTooltip, settingsPath, fs, ini, backend, main, path, resourcesPath, customEmojis, emojiPicker,config, settings, options, sound, showChatMessage, messageTemplates, getPostTime */
|
||||||
|
|
||||||
const tmi = require('tmi.js');
|
const tmi = require('tmi.js');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
@ -134,11 +134,13 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await chat.replaceChatMessageWithCustomEmojis(formattedMessage.innerHTML).then(data => {
|
||||||
|
formattedMessage.innerHTML = data;
|
||||||
showChatMessage(article);
|
showChatMessage(article);
|
||||||
|
});
|
||||||
|
|
||||||
if (settings.LANGUAGE.USE_DETECTION) {
|
if (settings.LANGUAGE.USE_DETECTION) {
|
||||||
await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => {
|
await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => {
|
||||||
console.log(language);
|
|
||||||
const languageElement = document.createElement('span');
|
const languageElement = document.createElement('span');
|
||||||
languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`;
|
languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`;
|
||||||
languageElement.setAttribute('tip', language.name);
|
languageElement.setAttribute('tip', language.name);
|
||||||
|
|
@ -250,6 +252,57 @@ function formatTwitchEmotes(channel) {
|
||||||
saveTwitchEmotesToFile(customEmojis);
|
saveTwitchEmotesToFile(customEmojis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveBetterTtvEmotesToFile(BetterTtvEmotes) {
|
||||||
|
const data = JSON.stringify(BetterTtvEmotes);
|
||||||
|
const savePath =
|
||||||
|
main.isPackaged === true
|
||||||
|
? path.join(resourcesPath, './betterttv-emotes.json')
|
||||||
|
: path.join(resourcesPath, './config/betterttv-emotes.json');
|
||||||
|
fs.writeFile(savePath, data, error => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatBetterTtvEmotes(data) {
|
||||||
|
if (data.emotes.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.emotes.forEach(emote => {
|
||||||
|
const emojiToBeAdded = {
|
||||||
|
name: emote.code,
|
||||||
|
shortcodes: [emote.code],
|
||||||
|
url: `https://cdn.betterttv.net/emote/${emote.id}/1x.webp`,
|
||||||
|
category: data.name
|
||||||
|
};
|
||||||
|
customEmojis.push(emojiToBeAdded);
|
||||||
|
});
|
||||||
|
emojiPicker.customEmoji = customEmojis;
|
||||||
|
saveBetterTtvEmotesToFile(customEmojis);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBetterTtvGLobalEmotes() {
|
||||||
|
// Get user Logo with access token
|
||||||
|
options = {
|
||||||
|
method: 'GET',
|
||||||
|
url: 'https://api.betterttv.net/3/cached/emotes/global',
|
||||||
|
headers: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
axios
|
||||||
|
.request(options)
|
||||||
|
.then(response => {
|
||||||
|
formatBetterTtvEmotes({ name: 'BetterTTV Global', emotes: response.data });
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getTwitchUserFollows(paginationToken) {
|
function getTwitchUserFollows(paginationToken) {
|
||||||
let url = '';
|
let url = '';
|
||||||
if (!paginationToken) {
|
if (!paginationToken) {
|
||||||
|
|
@ -449,4 +502,13 @@ function getTwitchUserId() {
|
||||||
// Reconnect 10s later
|
// Reconnect 10s later
|
||||||
// setTimeout(ws.reconnect, 10e3);
|
// setTimeout(ws.reconnect, 10e3);
|
||||||
|
|
||||||
module.exports = { sendMessage, ping, client, getUserAvailableTwitchEmotes, getTwitchChannelId, getTwitchUserId, checkIfTokenIsValid };
|
module.exports = {
|
||||||
|
sendMessage,
|
||||||
|
ping,
|
||||||
|
client,
|
||||||
|
getBetterTtvGLobalEmotes,
|
||||||
|
getUserAvailableTwitchEmotes,
|
||||||
|
getTwitchChannelId,
|
||||||
|
getTwitchUserId,
|
||||||
|
checkIfTokenIsValid
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,11 @@ async function createIniFile() {
|
||||||
TRANSLATE_TO: 'none',
|
TRANSLATE_TO: 'none',
|
||||||
LANGUAGE_INDEX: '0',
|
LANGUAGE_INDEX: '0',
|
||||||
BROADCAST_TRANSLATION: false,
|
BROADCAST_TRANSLATION: false,
|
||||||
OUTPUT_TO: false
|
OUTPUT_TO_TTS: false,
|
||||||
|
TRANSLATE_TO_INDEX: 0,
|
||||||
|
SEND_TRANSLATION: true,
|
||||||
|
SEND_TRANSLATION_IN: 'none',
|
||||||
|
SEND_TRANSLATION_OUT: 'none'
|
||||||
},
|
},
|
||||||
TTS: {
|
TTS: {
|
||||||
USE_TTS: false,
|
USE_TTS: false,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue