diff --git a/src/js/backend.js b/src/js/backend.js
index 751deb5..b2d318a 100644
--- a/src/js/backend.js
+++ b/src/js/backend.js
@@ -47,6 +47,10 @@ async function getInstalledVoices() {
function setTranslatedMessage(message) {
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
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.setAttribute('tip', message.language.detectedLanguage.name);
const translationHeader = document.createElement('div');
translationHeader.className = 'translation-header';
@@ -57,7 +61,7 @@ function setTranslatedMessage(message) {
translationIcon.className = 'translation-icon';
const languageElement = document.createElement('span');
const language = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
- languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis`;
+ languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis flag-icon`;
languageElement.setAttribute('tip', message.language.selectedLanguage.name);
addSingleTooltip(languageElement);
translationIcon.appendChild(languageElement);
@@ -80,6 +84,7 @@ function setTranslatedMessage(message) {
language: message.language
});
}
+ return message.language.detectedLanguage;
}
async function getTranslatedMessage(message) {
@@ -90,16 +95,23 @@ async function getTranslatedMessage(message) {
},
body: JSON.stringify({
message: message.message,
+ remainder: message.remainingDetectedLanguages,
language: message.language.detectedLanguage.IETF
}) // Convert the data to JSON and include it in the request body
};
try {
const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/translate`, requestOptions);
+ const responseData = await response.json();
if (response.ok) {
- const responseData = await response.json();
-
console.log('Translated message:', responseData);
+
+ if (settings.LANGUAGE.BROADCAST_TRANSLATION) {
+ twitch.sendMessage(
+ `[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}`
+ );
+ }
+
setTranslatedMessage({
originalMessage: message.message,
translation: responseData.translation,
@@ -109,38 +121,65 @@ async function getTranslatedMessage(message) {
username: message.username,
logoUrl: message.logoUrl
});
- if (settings.LANGUAGE.BROADCAST_TRANSLATION) {
- twitch.sendMessage(
- `[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}`
- );
- }
+ return message.language.detectedLanguage;
} else {
- console.error('Failed to send termination signal to Flask server.');
- message.message = 'Error,could not translate message';
- message.languaga = 'en-GB';
- getTranslatedMessage(message);
+ console.error(responseData);
+ if (message.remainingDetectedLanguages.length > 0) {
+ message.language.detectedLanguage = getLanguageProperties(message.remainingDetectedLanguages[0]);
+ message.remainingDetectedLanguages.shift();
+ return getTranslatedMessage(message);
+ } else {
+ message.message = 'Error, Could not translate message';
+ message.language.detectedLanguage = getLanguageProperties('en-GB');
+ return getTranslatedMessage(message);
+ }
}
} catch (error) {
console.error('Error sending termination signal:', error);
+ message.message = 'Error, Could not translate message';
+ message.language.detectedLanguage = getLanguageProperties('en-GB');
+ getTranslatedMessage(message);
}
}
-function filterLanguage(message) {
+async function filterLanguage(message) {
const selectedPrimaryLanguage = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
const selectedPrimaryLanguageIndex =
message.languages.indexOf(selectedPrimaryLanguage.ISO639) === -1 ? 99 : message.languages.indexOf(selectedPrimaryLanguage.ISO639);
+
const selectedSecondaryLanguage = getLanguageProperties(settings.TTS.SECONDARY_TTS_LANGUAGE);
const selectedSecondaryLanguageIndex =
message.languages.indexOf(selectedSecondaryLanguage.ISO639) === -1 ? 99 : message.languages.indexOf(selectedSecondaryLanguage.ISO639);
- const detectedLanguage = getLanguageProperties(message.languages[0]);
+
+ let detectedLanguage = '';
+ const remainingDetectedLanguages = [];
+ const detectedLanguages = message.languages.slice();
+
+ for (const [index, language] of detectedLanguages.entries()) {
+ detectedLanguage = getLanguageProperties(language);
+
+ if (detectedLanguage !== 'error') {
+ detectedLanguages.splice(index, 1);
+ break;
+ }
+ }
+
+ for (const [index, language] of detectedLanguages.entries()) {
+ const remainderLanguage = getLanguageProperties(language);
+ if (remainderLanguage !== 'error') {
+ remainingDetectedLanguages.push(remainderLanguage.IETF);
+ }
+ }
+
const language = selectedPrimaryLanguageIndex < selectedSecondaryLanguageIndex ? selectedPrimaryLanguage : detectedLanguage;
if (settings.LANGUAGE.TRANSLATE_TO !== 'none' && selectedPrimaryLanguage.ISO639 !== detectedLanguage.ISO639) {
getTranslatedMessage({
message: message.message,
messageId: message.messageId,
+ remainingDetectedLanguages,
language: {
selectedLanguage: selectedPrimaryLanguage,
- detectedLanguage
+ detectedLanguage: detectedLanguage
},
username: message.username,
formattedMessage: message.formattedMessage,
@@ -160,6 +199,7 @@ function filterLanguage(message) {
logoUrl: message.logoUrl
});
}
+
return language;
}
@@ -182,7 +222,7 @@ async function getDetectedLanguage(message) {
const responseData = await response.json();
console.log('Detected Languages:', responseData);
- return filterLanguage({
+ return await filterLanguage({
languages: responseData.languages,
message: message.message,
messageId: message.messageId,
diff --git a/src/js/languages.js b/src/js/languages.js
index fa95e2f..8aaed9f 100644
--- a/src/js/languages.js
+++ b/src/js/languages.js
@@ -21,8 +21,8 @@ const languages = {
amharic: { IETF: 'am-ET', ISO639: 'am', ISO3166: 'et' },
'antigua and barbuda creole english': { IETF: 'aig-AG', ISO639: 'aig', ISO3166: 'ag' },
arabic: { IETF: 'ar-SA', ISO639: 'ar', ISO3166: 'sa' },
- 'arabic egyptian': { IETF: 'ar-EG', ISO639: 'ar', ISO3166: 'eg' },
- // aragonese: { IETF: 'an-ES', ISO639: 'an', ISO3166: 'es' },
+ 'arabic egyptian': { IETF: 'ar-EG', ISO639: 'arz', ISO3166: 'eg' },
+ aragonese: { IETF: 'es-ES', ISO639: 'an', ISO3166: 'es' },
armenian: { IETF: 'hy-AM', ISO639: 'hy', ISO3166: 'am' },
assamese: { IETF: 'as-IN', ISO639: 'as', ISO3166: 'in' },
asturian: { IETF: 'ast-ES', ISO639: 'ast', ISO3166: 'es' },
diff --git a/src/js/renderer.js b/src/js/renderer.js
index d4e6a4c..6fbe662 100644
--- a/src/js/renderer.js
+++ b/src/js/renderer.js
@@ -163,8 +163,25 @@ async function getAudioDevices() {
getAudioDevices();
-function setLanguagesinSelectx() {
- const languageSelect = document.querySelector('.pop-content'); // obtain the html reference of the google voices comboBox
+function setSelectedLanguageinSelect(languageSelect, language) {
+ const button = languageSelect.querySelector('.SmallButton');
+ const languageElement = document.createElement('span');
+ languageElement.classList = `fi fi-${language.ISO3166} fis pop-selection`;
+ languageElement.setAttribute('tip', language.name);
+ button.innerHTML = '';
+ button.appendChild(languageElement);
+ addSingleTooltip(languageElement);
+}
+
+function setLanguagesinSelectx(languageSelector, language) {
+ const languageSelect = document.querySelector(languageSelector); // obtain the html reference of the google voices comboBox
+ const languageSelectContent = languageSelect.querySelector('.pop-content');
+
+ languageSelectContent.addEventListener('click', e => {
+ console.log(e.target);
+ language = getLanguageProperties(e.target.getAttribute('value'));
+ setSelectedLanguageinSelect(languageSelect, language);
+ });
for (const language in languageObject.languages) {
if (Object.prototype.hasOwnProperty.call(languageObject.languages, language)) {
@@ -177,24 +194,27 @@ function setLanguagesinSelectx() {
const languageElement = document.createElement('span');
languageElement.classList = `fi fi-${ISO3166} fis`;
+ languageElement.style.pointerEvents = 'none';
option.setAttribute('tip', language);
const text = document.createElement('span');
+ text.style.pointerEvents = 'none';
text.innerHTML = ` - ${ISO639}`;
- option.value = IETF;
+ option.setAttribute('value', IETF);
- languageSelect.appendChild(option);
+ languageSelectContent.appendChild(option);
option.appendChild(languageElement);
option.appendChild(text);
addSingleTooltip(option);
}
}
- // languageSelect.selectedIndex = setting;
+ setSelectedLanguageinSelect(languageSelect, language);
}
-setLanguagesinSelectx();
+setLanguagesinSelectx('.pop.in', getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_IN));
+setLanguagesinSelectx('.pop.out', getLanguageProperties(settings.LANGUAGE.SEND_TRANSLATION_OUT));
function setLanguagesinSelect(languageSelector, setting) {
const languageSelect = document.querySelector(languageSelector); // obtain the html reference of the google voices comboBox
@@ -232,6 +252,38 @@ function addVoiceService(name) {
addToselect('#secondaryTTSService');
}
+function determineTootlTipPosition(element) {
+ const horizontal = document.body.clientWidth / 2;
+ const vertical = document.body.clientHeight / 2;
+
+ element.tip.style.left = `${element.mouse.x}px`;
+ element.tip.style.top = `${element.mouse.y}px`;
+
+ const tipPosition = element.tip.getBoundingClientRect();
+
+ if (element.position.x < horizontal && element.position.y < vertical) {
+ element.tip.style.top = `${parseInt(element.tip.style.top) + 25}px`;
+ element.tip.style.left = `${parseInt(element.tip.style.left) + 10}px`;
+ }
+
+ if (element.position.x < horizontal && element.position.y > vertical) {
+ element.tip.style.top = `${parseInt(element.tip.style.top) - tipPosition.height}px`;
+ element.tip.style.left = `${parseInt(element.tip.style.left) + 10}px`;
+ }
+
+ if (element.position.x > horizontal && element.position.y < vertical) {
+ element.tip.style.top = `${parseInt(element.tip.style.top) + 25}px`;
+ element.tip.style.left = `${parseInt(element.tip.style.left) - tipPosition.width}px`;
+ }
+
+ if (element.position.x > horizontal && element.position.y > vertical) {
+ element.tip.style.top = `${parseInt(element.tip.style.top) - tipPosition.height}px`;
+ element.tip.style.left = `${parseInt(element.tip.style.left) - tipPosition.width}px`;
+ }
+
+ element.tip.style.visibility = 'visible';
+}
+
// Small tooltip
function addSingleTooltip(el) {
const tip = document.createElement('div');
@@ -244,14 +296,14 @@ function addSingleTooltip(el) {
image.src = el.src;
tip.appendChild(image);
}
- tip.style.transform = `translate(${el.hasAttribute('tip-left') ? 'calc(-100% - 5px)' : '15px'}, ${
- el.hasAttribute('tip-top') ? '-100%' : '15px'
- })`;
body.appendChild(tip);
+ tip.pointerEvents = 'none';
element.onmousemove = e => {
- tip.style.left = `${e.x}px`;
- tip.style.top = `${e.y}px`;
- tip.style.visibility = 'visible';
+ determineTootlTipPosition({
+ position: element.getBoundingClientRect(),
+ mouse: { x: e.x, y: e.y },
+ tip
+ });
};
element.onmouseleave = e => {
tip.style.visibility = 'hidden';
@@ -270,7 +322,7 @@ function showChatMessage(article) {
const messages = document.body.querySelectorAll('.msg-container');
const lastMessage = messages[messages.length - 1];
- lastMessage.scrollIntoView();
+ lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' });
}
function getPostTime() {
@@ -338,33 +390,28 @@ if (fs.existsSync(emoteListSavePath)) {
}
function getLanguageProperties(languageToDetect) {
- const filteredLanguage = Object.keys(languageObject.languages).reduce(function (accumulator, currentValue) {
- if (
- languageObject.languages[currentValue].IETF === languageToDetect ||
- languageObject.languages[currentValue].ISO639 === languageToDetect ||
- languageObject.languages[currentValue].ISO3166 === languageToDetect
- ) {
- accumulator[currentValue] = languageObject.languages[currentValue];
- }
- return accumulator;
- }, {});
+ try {
+ const filteredLanguage = Object.keys(languageObject.languages).reduce(function (accumulator, currentValue) {
+ if (
+ languageObject.languages[currentValue].IETF === languageToDetect ||
+ languageObject.languages[currentValue].ISO639 === languageToDetect ||
+ languageObject.languages[currentValue].ISO3166 === languageToDetect
+ ) {
+ accumulator[currentValue] = languageObject.languages[currentValue];
+ }
+ return accumulator;
+ }, {});
- const language = {
- name: Object.getOwnPropertyNames(filteredLanguage)[0],
- ISO3166: filteredLanguage[Object.keys(filteredLanguage)[0]].ISO3166,
- ISO639: filteredLanguage[Object.keys(filteredLanguage)[0]].ISO639,
- IETF: filteredLanguage[Object.keys(filteredLanguage)[0]].IETF
- };
+ const language = {
+ name: Object.getOwnPropertyNames(filteredLanguage)[0],
+ ISO3166: filteredLanguage[Object.keys(filteredLanguage)[0]].ISO3166,
+ ISO639: filteredLanguage[Object.keys(filteredLanguage)[0]].ISO639,
+ IETF: filteredLanguage[Object.keys(filteredLanguage)[0]].IETF
+ };
- return language;
-}
-
-document.body.querySelector('#emojis').addEventListener('click', () => {
- emojiPicker.style.visibility === 'visible' ? (emojiPicker.style.visibility = 'hidden') : (emojiPicker.style.visibility = 'visible');
-});
-
-document.body.addEventListener('click', e => {
- if (e.target.id !== 'emojis' && e.target.nodeName !== 'EMOJI-PICKER' && emojiPicker.style.visibility === 'visible') {
- emojiPicker.style.visibility = 'hidden';
+ return language;
+ } catch (e) {
+ // console.error(error);
+ return 'error';
}
-});
+}
diff --git a/src/js/settings.js b/src/js/settings.js
index 40ffea2..a6c99af 100644
--- a/src/js/settings.js
+++ b/src/js/settings.js
@@ -752,7 +752,7 @@ document.body.querySelector('#ZOOMLEVEL').addEventListener('change', () => {
});
document.body.querySelector('emoji-picker').addEventListener('emoji-click', e => {
- console.log(e.detail);
+ // console.log(e.detail);
const div = document.getElementById('textInput');
if (e.detail.unicode === undefined) {
div.value += e.detail.name + ' ';
diff --git a/src/js/twitch.js b/src/js/twitch.js
index fc60778..bc9d74a 100644
--- a/src/js/twitch.js
+++ b/src/js/twitch.js
@@ -133,17 +133,18 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
}
});
}
+
+ showChatMessage(article);
+
if (settings.LANGUAGE.USE_DETECTION) {
await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => {
+ console.log(language);
const languageElement = document.createElement('span');
- languageElement.classList = `fi fi-${language.ISO3166} fis language-icon`;
+ languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`;
languageElement.setAttribute('tip', language.name);
article.appendChild(languageElement);
addSingleTooltip(languageElement);
- // Appends the message to the main chat box (shows the message)
- showChatMessage(article);
-
if (filteredMessage && !settings.LANGUAGE.OUTPUT_TO_TTS) {
sound.playVoice({
filteredMessage,
@@ -154,16 +155,14 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
});
}
- window.article = article;
+ // window.article = article;
});
} else {
- showChatMessage(article);
-
if (filteredMessage) {
sound.playVoice({ filteredMessage, logoUrl, username, formattedMessage });
}
- window.article = article;
+ // window.article = article;
}
sound.playNotificationSound();