BetterDiscordAddons/Plugins/GoogleTranslateOption/GoogleTranslateOption.plugi...

955 lines
49 KiB
JavaScript
Raw Normal View History

2019-09-20 22:32:52 +02:00
//META{"name":"GoogleTranslateOption","website":"https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/GoogleTranslateOption","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/GoogleTranslateOption/GoogleTranslateOption.plugin.js"}*//
2018-10-11 10:21:26 +02:00
class GoogleTranslateOption {
getName () {return "GoogleTranslateOption";}
2020-01-01 20:39:49 +01:00
getVersion () {return "1.9.1";}
2019-01-26 22:45:19 +01:00
2019-04-08 15:21:20 +02:00
getAuthor () {return "DevilBro";}
2019-04-08 15:21:20 +02:00
getDescription () {return "Adds a Google Translate option to your context menu, which shows a preview of the translated text and on click will open the selected text in Google Translate. Also adds a translation button to your textareas, which will automatically translate the text for you before it is being send.";}
2019-01-26 22:45:19 +01:00
2019-09-04 12:34:02 +02:00
constructor () {
2019-04-08 15:21:20 +02:00
this.changelog = {
2019-12-10 13:21:59 +01:00
"improved":[["Messages stay translated", "Messages will stay translated even if you switch channels"],["iTranslate & Yandex","Added iTranslate and Yandex engine, these engines got a montly rate limit, so if they don't work switch back to Google"]],
2020-01-01 20:39:49 +01:00
"fixed":[["Translated Stamp","Now properly aligned with the message again"]]
2019-04-08 15:21:20 +02:00
};
2019-09-04 12:34:02 +02:00
2019-11-14 17:56:26 +01:00
this.patchedModules = {
2019-12-09 15:56:53 +01:00
before: {
2019-12-21 11:25:13 +01:00
ChannelTextAreaForm: "render",
ChannelEditorContainer: "render"
2019-12-09 15:56:53 +01:00
},
2019-11-14 17:56:26 +01:00
after: {
2019-12-21 02:24:30 +01:00
ChannelTextAreaContainer: "render",
2019-12-09 15:56:53 +01:00
MessageContent: "render"
2019-11-14 17:56:26 +01:00
}
};
2019-09-04 12:34:02 +02:00
}
2019-01-26 22:45:19 +01:00
2019-09-04 12:34:02 +02:00
initConstructor () {
2018-10-11 10:21:26 +02:00
this.languages = {};
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this.translating = false;
2019-12-09 15:56:53 +01:00
this.isTranslating = false;
this.translatedMessages = {};
2019-09-04 12:34:02 +02:00
2019-04-16 00:30:33 +02:00
this.brailleConverter = {
"0":"⠴", "1":"⠂", "2":"⠆", "3":"⠒", "4":"⠲", "5":"⠢", "6":"⠖", "7":"⠶", "8":"⠦", "9":"⠔", "!":"⠮", "\"":"⠐", "#":"⠼", "$":"⠫", "%":"⠩", "&":"⠯", "'":"⠄", "(":"⠷", ")":"⠾", "*":"⠡", "+":"⠬", ",":"⠠", "-":"⠤", ".":"⠨", "/":"⠌", ":":"⠱", ";":"⠰", "<":"⠣", "=":"⠿", ">":"⠜", "?":"⠹", "@":"⠈", "a":"⠁", "b":"⠃", "c":"⠉", "d":"⠙", "e":"⠑", "f":"⠋", "g":"⠛", "h":"⠓", "i":"⠊", "j":"⠚", "k":"⠅", "l":"⠇", "m":"⠍", "n":"⠝", "o":"⠕", "p":"⠏", "q":"⠟", "r":"⠗", "s":"⠎", "t":"⠞", "u":"⠥", "v":"⠧", "w":"⠺", "x":"⠭", "y":"⠽", "z":"⠵", "[":"⠪", "\\":"⠳", "]":"⠻", "^":"⠘", "⠁":"a", "⠂":"1", "⠃":"b", "⠄":"'", "⠅":"k", "⠆":"2", "⠇":"l", "⠈":"@", "⠉":"c", "⠊":"i", "⠋":"f", "⠌":"/", "⠍":"m", "⠎":"s", "⠏":"p", "⠐":"\"", "⠑":"e", "⠒":"3", "⠓":"h", "⠔":"9", "⠕":"o", "⠖":"6", "⠗":"r", "⠘":"^", "⠙":"d", "⠚":"j", "⠛":"g", "⠜":">", "⠝":"n", "⠞":"t", "⠟":"q", "⠠":", ", "⠡":"*", "⠢":"5", "⠣":"<", "⠤":"-", "⠥":"u", "⠦":"8", "⠧":"v", "⠨":".", "⠩":"%", "⠪":"[", "⠫":"$", "⠬":"+", "⠭":"x", "⠮":"!", "⠯":"&", "⠰":";", "⠱":":", "⠲":"4", "⠳":"\\", "⠴":"0", "⠵":"z", "⠶":"7", "⠷":"(", "⠸":"_", "⠹":"?", "⠺":"w", "⠻":"]", "⠼":"#", "⠽":"y", "⠾":")", "⠿":"=", "_":"⠸"
};
2019-09-04 12:34:02 +02:00
2019-04-16 00:30:33 +02:00
this.morseConverter = {
"0":"", "1":"·−−−−", "2":"··−−−", "3":"···−−", "4":"····−", "5":"·····", "6":"−····", "7":"−−···", "8":"−−−··", "9":"−−−−·", "!":"−·−·−−", "\"":"·−··−·", "$":"···−··−", "&":"·−···", "'":"·−−−−·", "(":"−·−−·", ")":"−·−−·−", "+":"·−·−·", ",":"−−··−−", "-":"−····−", ".":"·−·−·−", "/":"−··−·", ":":"−−−···", ";":"−·−·−·", "=":"−···−", "?":"··−−··", "@":"·−−·−·", "a":"·−", "b":"−···", "c":"−·−·", "d":"−··", "e":"·", "f":"··−·", "g":"−−·", "h":"····", "i":"··", "j":"·−−−", "k":"−·−", "l":"·−··", "m":"", "n":"−·", "o":"", "p":"·−−·", "q":"−−·−", "r":"·−·", "s":"···", "t":"", "u":"··−", "v":"···−", "w":"·−−", "x":"−··−", "y":"−·−−", "z":"−−··", "·":"e", "··":"i", "···":"s", "····":"h", "·····":"5", "····−":"4", "···−":"v", "···−··−":"$", "···−−":"3", "··−":"u", "··−·":"f", "··−−··":"?", "··−−·−":"_", "··−−−":"2", "·−":"a", "·−·":"r", "·−··":"l", "·−···":"&", "·−··−·":"\"", "·−·−·":"+", "·−·−·−":".", "·−−":"w", "·−−·":"p", "·−−·−·":"@", "·−−−":"j", "·−−−−":"1", "·−−−−·":"'", "":"t", "−·":"n", "−··":"d", "−···":"b", "−····":"6", "−····−":"-", "−···−":"=", "−··−":"x", "−··−·":"/", "−·−":"k", "−·−·":"c", "−·−·−·":";", "−·−·−−":"!", "−·−−":"y", "−·−−·":"(", "−·−−·−":")", "":"m", "−−·":"g", "−−··":"z", "−−···":"7", "−−··−−":",", "−−·−":"q", "":"o", "−−−··":"8", "−−−···":":", "−−−−·":"9", "":"0", "_":"··−−·−"
};
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this.defaults = {
settings: {
2019-11-29 19:11:56 +01:00
useChromium: {value:false, description:"Use an inbuilt browser window instead of opening your default browser"},
addTranslateButton: {value:true, description:"Adds an translate button to the chatbar"},
sendOriginalMessage: {value:false, description:"Send the original message together with the translation"}
2018-10-11 10:21:26 +02:00
},
choices: {
2019-11-18 13:46:07 +01:00
inputContext: {value:"auto", direction:"input", place:"Context", description:"Input Language in received Messages:"},
outputContext: {value:"$discord", direction:"output", place:"Context", description:"Output Language in received Messages:"},
inputMessage: {value:"auto", direction:"input", place:"Message", description:"Input Language in sent Messages:"},
outputMessage: {value:"$discord", direction:"output", place:"Message", description:"Output Language in sent Messages:"}
2019-12-09 15:56:53 +01:00
},
engines: {
translator: {value:"google", description:"Translation Engine:"}
2018-10-11 10:21:26 +02:00
}
};
2019-12-09 15:56:53 +01:00
this.translationEngines = {
2019-12-10 13:21:59 +01:00
google: {name:"Google", func:this.googleTranslate, languages: ["af","sq","am","ar","hy","az","eu","be","bn","bs","bg","my","ca","ceb","ny","zh-CN","co","hr","cs","da","nl","en","eo","et","fi","fr","fy","gl","ka","de","el","gu","ht","ha","haw","iw","hi","hmn","hu","is","ig","id","ga","it","ja","jw","kn","kk","km","ko","ku","ky","lo","la","lv","lt","lb","mk","mg","ms","ml","mt","mi","mr","mn","ne","no","ps","fa","pl","pt","pa","ro","ru","sm","gd","sr","st","sn","sd","si","sk","sl","so","es","sw","sv","tg","ta","te","th","tr","uk","ur","uz","vi","cy","xh","yi","yo","zu"]},
itranslate: {name:"iTranslate", func:this.iTranslateTranslate, languages: ["af","sq","ar","hy","az","eu","be","bn","bs","bg","ca","ceb","ny","zh-CN","zh-TW","hr","cs","da","nl","en","eo","et","fil","fi","fr","gl","ka","de","el","gu","ht","he","ha","hi","hmn","hu","is","ig","id","ga","it","ja","jw","kn","kk","km","ko","lo","la","lv","lt","mk","mg","ms","ml","mt","mi","mr","mn","my","ne","no","fa","pl","pt-BR","pt-PT","pa","ro","ru","sr","st","si","sk","sl","so","es","su","sw","sv","tg","ta","te","th","tr","uk","ur","uz","vi","we","yi","yo","zu"]},
yandex: {name:"Yandex", func:this.yandexTranslate, languages: ["af","sq","am","ar","hy","az","ba","eu","be","bn","bs","bg","my","ca","ceb","zh","hr","cs","da","nl","en","eo","et","fi","fr","gl","ka","de","el","gu","ht","he","hi","hu","is","id","ga","it","ja","jv","kn","kk","km","ko","ky","lo","la","lv","lt","lb","mk","mg","ms","ml","mt","mi","mr","mhr","mn","ne","no","pap","fa","pl","pt","pa","ro","ru","gd","sr","si","sk","sl","es","su","sw","sv","tl","tg","ta","tt","te","th","tr","udm","uk","ur","uz","vi","cy","xh","yi"]}
2019-12-09 15:56:53 +01:00
};
2018-10-11 10:21:26 +02:00
this.css = `
2019-12-09 15:56:53 +01:00
${BDFDB.dotCN._googletranslateoptiontranslatebutton + BDFDB.dotCNS._googletranslateoptiontranslating + BDFDB.dotCN.textareaicon} {
2018-12-11 12:55:15 +01:00
color: #F04747 !important;
2018-10-11 10:21:26 +02:00
}
2019-12-09 15:56:53 +01:00
${BDFDB.dotCN._googletranslateoptionreversebutton} {
2019-11-07 13:45:41 +01:00
opacity: 0.5;
2019-10-24 11:47:57 +02:00
margin-right: 5px;
2018-10-11 10:21:26 +02:00
transition: all 200ms ease;
}
2019-12-09 15:56:53 +01:00
${BDFDB.dotCN._googletranslateoptionreversebutton}:hover {
2018-10-11 10:21:26 +02:00
opacity: 1;
}`;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
getSettingsPanel () {
2020-01-17 19:50:31 +01:00
if (!window.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return;
2019-10-24 11:47:57 +02:00
let settings = BDFDB.DataUtils.get(this, "settings");
2019-12-18 16:45:08 +01:00
let settingspanel, settingsitems = [];
2019-10-24 11:47:57 +02:00
settingsitems = settingsitems.concat(this.createSelects(false));
2019-11-05 21:16:39 +01:00
for (let key in settings) settingsitems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
2019-10-24 11:47:57 +02:00
className: BDFDB.disCN.marginbottom8,
2019-11-05 21:16:39 +01:00
type: "Switch",
2019-10-24 11:47:57 +02:00
plugin: this,
keys: ["settings", key],
label: this.defaults.settings[key].description,
value: settings[key]
}));
2019-12-18 16:45:08 +01:00
return settingspanel = BDFDB.PluginUtils.createSettingsPanel(this, settingsitems);
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
//legacy
load () {}
start () {
2020-01-17 19:50:31 +01:00
if (!window.BDFDB) window.BDFDB = {myPlugins:{}};
if (window.BDFDB && window.BDFDB.myPlugins && typeof window.BDFDB.myPlugins == "object") window.BDFDB.myPlugins[this.getName()] = this;
2020-01-21 12:56:26 +01:00
let libraryScript = document.querySelector("head script#BDFDBLibraryScript");
2019-05-26 13:55:26 +02:00
if (!libraryScript || (performance.now() - libraryScript.getAttribute("date")) > 600000) {
2018-10-11 10:21:26 +02:00
if (libraryScript) libraryScript.remove();
libraryScript = document.createElement("script");
2019-05-26 13:55:26 +02:00
libraryScript.setAttribute("id", "BDFDBLibraryScript");
2018-10-11 10:21:26 +02:00
libraryScript.setAttribute("type", "text/javascript");
2019-10-18 10:56:41 +02:00
libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js");
2019-01-17 23:48:29 +01:00
libraryScript.setAttribute("date", performance.now());
2020-01-14 00:06:07 +01:00
libraryScript.addEventListener("load", _ => {this.initialize();});
2018-10-11 10:21:26 +02:00
document.head.appendChild(libraryScript);
}
2020-01-17 19:50:31 +01:00
else if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize();
2020-01-14 00:06:07 +01:00
this.startTimeout = setTimeout(_ => {
2019-11-01 10:27:07 +01:00
try {return this.initialize();}
catch (err) {console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not initiate plugin! " + err);}
}, 30000);
2018-10-11 10:21:26 +02:00
}
initialize () {
2020-01-17 19:50:31 +01:00
if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
2019-01-22 11:05:54 +01:00
if (this.started) return;
2019-10-22 18:55:25 +02:00
BDFDB.PluginUtils.init(this);
2019-01-26 22:45:19 +01:00
2019-09-24 11:00:04 +02:00
this.setLanguages();
2019-01-26 22:45:19 +01:00
2019-10-22 18:55:25 +02:00
BDFDB.ModuleUtils.forceAllUpdates(this);
2018-10-11 10:21:26 +02:00
}
2019-11-01 10:14:50 +01:00
else console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not load BD functions!");
2018-10-11 10:21:26 +02:00
}
stop () {
2020-01-17 19:50:31 +01:00
if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
2019-10-22 11:37:23 +02:00
this.stopping = true;
2019-12-09 15:56:53 +01:00
for (let id in this.translatedMessages) this.formatMessage(this.translatedMessages[id].message, this.translatedMessages[id].oldString);
this.translatedMessages = {};
let instances = BDFDB.ReactUtils.findOwner(document.querySelector(BDFDB.dotCN.app), {name:["Message", "Embeds"], all:true, group:true, unlimited:true});
if (instances.Message) for (let ins of instances.Message) ins.props.message = new BDFDB.DiscordObjects.Message(ins.props.message);
BDFDB.ReactUtils.forceUpdate(instances.Message, instances.Embeds);
2019-10-24 11:47:57 +02:00
2019-12-21 11:25:13 +01:00
BDFDB.ModuleUtils.forceAllUpdates(this, ["ChannelTextAreaForm", "ChannelTextAreaContainer"]);
2019-01-26 22:45:19 +01:00
2019-10-22 18:55:25 +02:00
BDFDB.PluginUtils.clear(this);
2018-10-11 10:21:26 +02:00
}
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
// begin of own functions
2019-11-29 19:11:56 +01:00
onSettingsClosed (instance, wrapper, returnvalue) {
if (this.SettingsUpdated) {
delete this.SettingsUpdated;
this.setLanguages();
2019-12-21 11:25:13 +01:00
BDFDB.ModuleUtils.forceAllUpdates(this, ["ChannelTextAreaForm", "ChannelTextAreaContainer"]);
2019-11-29 19:11:56 +01:00
}
}
2019-01-26 22:45:19 +01:00
2019-11-29 19:11:56 +01:00
onMessageContextMenu (e) {
if (e.instance.props.message && e.instance.props.channel && e.instance.props.target) {
2019-12-09 15:56:53 +01:00
let translated = this.translatedMessages[e.instance.props.message.id];
2019-11-29 19:11:56 +01:00
let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {name:"MessagePinItem"});
2019-12-09 15:56:53 +01:00
if (index > -1) children.splice(index > -1 ? index : children.length, 0, BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ContextMenuItems.Item, {
2019-09-11 12:14:43 +02:00
label: translated ? this.labels.context_messageuntranslateoption_text : this.labels.context_messagetranslateoption_text,
2019-10-23 11:10:01 +02:00
hint: BDFDB.BDUtils.isPluginEnabled("MessageUtilities") ? BDFDB.BDUtils.getPlugin("MessageUtilities").getActiveShortcutString("__Translate_Message") : null,
2019-12-09 15:56:53 +01:00
disabled: !translated && this.isTranslating,
2019-11-21 11:38:04 +01:00
action: _ => {
2019-11-29 19:11:56 +01:00
BDFDB.ContextMenuUtils.close(e.instance);
this.translateMessage(e.instance.props.message, e.instance.props.target, e.instance.props.channel);
2019-09-11 12:14:43 +02:00
}
2019-12-09 15:56:53 +01:00
}));
let text = document.getSelection().toString();
if (text) {
2019-10-23 11:10:01 +02:00
let GSRstring = BDFDB.ReactUtils.getValue(BDFDB.BDUtils.getPlugin("GoogleSearchReplace", true), "labels.context_googlesearchreplace_text");
2019-12-09 15:56:53 +01:00
let translating, foundtranslation, foundinput, foundoutput;
2019-11-29 19:11:56 +01:00
let [children2, index2] = BDFDB.ReactUtils.findChildren(e.returnvalue, {name:"SearchWithGoogle", props: GSRstring ? [["label", GSRstring]] : null});
2019-12-09 15:56:53 +01:00
if (index2 > -1) children2.splice(index2 > -1 ? index2 : children2.length, 0, BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ContextMenuItems.Item, {
2019-09-11 12:14:43 +02:00
label: this.labels.context_googletranslateoption_text,
2019-12-09 15:56:53 +01:00
disabled: this.isTranslating,
2019-11-21 11:38:04 +01:00
action: event => {
2019-12-09 15:56:53 +01:00
let item = BDFDB.DOMUtils.getParent(BDFDB.dotCN.contextmenuitem, event.target);
2019-09-11 12:14:43 +02:00
if (item) {
2019-12-09 15:56:53 +01:00
var createTooltip = _ => {
2019-10-22 18:55:25 +02:00
BDFDB.TooltipUtils.create(item, `From ${foundinput.name}:\n${text}\n\nTo ${foundoutput.name}:\n${foundtranslation}`, {type:"right", selector:"googletranslate-tooltip"});
2019-09-11 12:14:43 +02:00
};
if (foundtranslation && foundinput && foundoutput) {
if (document.querySelector(".googletranslate-tooltip")) {
2019-12-07 11:56:11 +01:00
BDFDB.ContextMenuUtils.close(e.instance);
2019-11-29 19:11:56 +01:00
BDFDB.DiscordUtils.openLink(this.getGoogleTranslatePageURL(foundinput.id, foundoutput.id, text), BDFDB.DataUtils.get(this, "settings", "useChromium"));
2019-09-11 12:14:43 +02:00
}
else createTooltip();
}
2019-12-09 15:56:53 +01:00
else if (!translating) {
translating = true;
this.translateText(text, "context", (translation, input, output) => {
if (translation) {
foundtranslation = translation, foundinput = input, foundoutput = output;
createTooltip();
}
});
}
2019-09-11 12:14:43 +02:00
}
}
2019-12-09 15:56:53 +01:00
}));
2018-10-11 10:21:26 +02:00
}
}
}
2019-01-26 22:45:19 +01:00
2019-11-29 19:11:56 +01:00
onMessageOptionPopout (e) {
if (e.instance.props.message && e.instance.props.channel && e.instance.props.target) {
let {messagediv, pos} = this.getMessageAndPos(e.instance.props.target);
2019-09-11 12:14:43 +02:00
if (!messagediv || pos == -1) return;
2019-10-23 11:10:01 +02:00
let translated = BDFDB.DOMUtils.containsClass(messagediv, "GTO-translated-message");
2019-11-29 19:11:56 +01:00
let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {props:[["label", [BDFDB.LanguageUtils.LanguageStrings.PIN, BDFDB.LanguageUtils.LanguageStrings.UNPIN]]]});
2019-12-05 09:10:14 +01:00
children.splice(index + 1, 0, BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ContextMenuItems.Item, {
2019-09-11 12:14:43 +02:00
label: this.labels[translated ? "popout_untranslateoption_text" : "popout_translateoption_text"],
2019-11-07 22:33:27 +01:00
className: BDFDB.disCN.optionpopoutitem,
2019-12-09 15:56:53 +01:00
disabled: this.isTranslating,
2019-11-21 11:38:04 +01:00
action: _ => {
2019-11-29 19:11:56 +01:00
this.translateMessage(e.instance.props.message, e.instance.props.target, e.instance.props.channel);
e.instance.props.onClose();
2019-09-11 12:14:43 +02:00
}
2019-11-07 22:33:27 +01:00
}));
2019-09-11 12:14:43 +02:00
}
}
2019-12-21 02:24:30 +01:00
2019-12-21 11:25:13 +01:00
processChannelTextAreaForm (e) {
if (!BDFDB.ModuleUtils.isPatched(this, e.instance, "handleSendMessage")) BDFDB.ModuleUtils.patch(this, e.instance, "handleSendMessage", {instead: e2 => {
2019-12-21 02:24:30 +01:00
if (this.translating) {
e2.stopOriginalMethodCall();
this.translateText(e2.methodArguments[0], "message", (translation, input, output) => {
translation = !translation ? e2.methodArguments[0] : (BDFDB.DataUtils.get(this, "settings", "sendOriginalMessage") ? e2.methodArguments[0] + "\n\n" + translation : translation);
e2.originalMethod(translation);
});
2019-12-21 11:25:13 +01:00
return Promise.resolve({
shouldClear: true,
shouldRefocus: true
});
2019-12-21 02:24:30 +01:00
}
2019-12-21 11:25:13 +01:00
else return e2.callOriginalMethodAfterwards();
2019-12-21 02:24:30 +01:00
}}, true);
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2019-12-21 11:25:13 +01:00
processChannelEditorContainer (e) {
if (this.translating && this.isTranslating) e.instance.props.disabled = true;
}
processChannelTextAreaContainer (e) {
let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {name: "ChannelEditorContainer"});
2019-12-21 11:47:27 +01:00
if (index > -1 && children[index].props.type == BDFDB.DiscordConstants.TextareaTypes.NORMAL && !children[index].props.disabled) {
2019-12-21 11:25:13 +01:00
let [children2, index2] = BDFDB.ReactUtils.findChildren(e.returnvalue, {props:[["className", BDFDB.disCN.textareapickerbuttons]]});
if (index2 > -1 && children2[index2].props && children2[index2].props.children) children2[index2].props.children.unshift(this.createTranslateButton());
}
}
2019-11-29 19:11:56 +01:00
processMessageContent (e) {
2019-12-09 15:56:53 +01:00
if (typeof e.returnvalue.props.children == "function") {
let renderChildren = e.returnvalue.props.children;
e.returnvalue.props.children = (...args) => {
let renderedChildren = renderChildren(...args);
let translatedMessage = this.translatedMessages[e.instance.props.message.id];
if (translatedMessage) {
2020-01-01 20:39:49 +01:00
let [children, index] = BDFDB.ReactUtils.findChildren(renderedChildren, {props: [["className", BDFDB.disCN.messagemarkuprtl]]});
if (index > -1 && children[index].props && children[index].props.children && children[index].props.children.props && BDFDB.ArrayUtils.is(children[index].props.children.props.children)) children[index].props.children.props.children.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
2019-12-09 15:56:53 +01:00
text: `From: ${this.getLanguageName(translatedMessage.input)}\nTo: ${this.getLanguageName(translatedMessage.output)}`,
tooltipConfig: {style: "max-width: 400px"},
children: BDFDB.ReactUtils.createElement("time", {
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN.messageedited, BDFDB.disCN._googletranslateoptiontranslated),
children: `(${this.labels.translated_watermark_text})`
})
}));
}
return renderedChildren;
};
2019-10-24 11:47:57 +02:00
}
}
2019-10-24 21:30:55 +02:00
createTranslateButton () {
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.PopoutContainer, {
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ChannelTextAreaButton, {
2019-12-09 15:56:53 +01:00
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN._googletranslateoptiontranslatebutton, this.translating && BDFDB.disCN._googletranslateoptiontranslating, BDFDB.disCN.textareapickerbutton),
2019-11-07 13:45:41 +01:00
iconClassName: BDFDB.disCN.textareaicon,
iconSVG: `<svg x="0" y="0" aria-hidden="false" width="22" height="22" viewBox="0 0 22 22" fill="currentColor"><path d="M 19.794, 3.299 H 9.765 L 8.797, 0 h -6.598 C 0.99, 0, 0, 0.99, 0, 2.199 V 16.495 c 0, 1.21, 0.99, 2.199, 2.199, 2.199 H 9.897 l 1.1, 3.299 H 19.794 c 1.21, 0, 2.199 -0.99, 2.199 -2.199 V 5.498 C 21.993, 4.289, 21.003, 3.299, 19.794, 3.299 z M 5.68, 13.839 c -2.48, 0 -4.492 -2.018 -4.492 -4.492 s 2.018 -4.492, 4.492 -4.492 c 1.144, 0, 2.183, 0.407, 3.008, 1.171 l 0.071, 0.071 l -1.342, 1.298 l -0.066 -0.06 c -0.313 -0.297 -0.858 -0.643 -1.671 -0.643 c -1.441, 0 -2.612, 1.193 -2.612, 2.661 c 0, 1.468, 1.171, 2.661, 2.612, 2.661 c 1.507, 0, 2.161 -0.962, 2.337 -1.606 h -2.43 v -1.704 h 4.344 l 0.016, 0.077 c 0.044, 0.231, 0.06, 0.434, 0.06, 0.665 C 10.001, 12.036, 8.225, 13.839, 5.68, 13.839 z M 11.739, 9.979 h 4.393 c 0, 0 -0.374, 1.446 -1.715, 3.008 c -0.588 -0.676 -0.995 -1.336 -1.254 -1.864 h -1.089 L 11.739, 9.979 z M 13.625, 13.839 l -0.588, 0.583 l -0.72 -2.452 C 12.685, 12.63, 13.13, 13.262, 13.625, 13.839 z M 20.893, 19.794 c 0, 0.605 -0.495, 1.1 -1.1, 1.1 H 12.096 l 2.199 -2.199 l -0.896 -3.041 l 1.012 -1.012 l 2.953, 2.953 l 0.803 -0.803 l -2.975 -2.953 c 0.99 -1.138, 1.759 -2.474, 2.106 -3.854 h 1.397 V 8.841 H 14.697 v -1.144 h -1.144 v 1.144 H 11.398 l -1.309 -4.443 H 19.794 c 0.605, 0, 1.1, 0.495, 1.1, 1.1 V 19.794 z"/></svg>`
2019-10-24 21:30:55 +02:00
}),
width: 400,
padding: 10,
animation: BDFDB.LibraryComponents.PopoutContainer.Animation.SCALE,
position: BDFDB.LibraryComponents.PopoutContainer.Positions.TOP,
align: BDFDB.LibraryComponents.PopoutContainer.Align.RIGHT,
onClose: instance => {
2019-11-07 13:45:41 +01:00
let channelTextareaButtonIns = BDFDB.ReactUtils.findOwner(instance, {name:"BDFDB_ChannelTextAreaButton"});
2019-10-24 21:30:55 +02:00
if (channelTextareaButtonIns) {
channelTextareaButtonIns.props.isActive = false;
BDFDB.ReactUtils.forceUpdate(channelTextareaButtonIns);
}
},
2019-11-07 13:45:41 +01:00
onContextMenu: (e, instance) => {
2019-10-24 21:30:55 +02:00
this.translating = !this.translating;
2019-11-07 13:45:41 +01:00
let channelTextareaButtonIns = BDFDB.ReactUtils.findOwner(instance, {name:"BDFDB_ChannelTextAreaButton"});
2019-10-24 21:30:55 +02:00
if (channelTextareaButtonIns) {
2019-12-09 15:58:27 +01:00
channelTextareaButtonIns.props.className = BDFDB.DOMUtils.formatClassName(BDFDB.disCN._googletranslateoptiontranslatebutton, this.translating && BDFDB.disCN._googletranslateoptiontranslating, BDFDB.disCN.textareapickerbutton);
2019-10-24 21:30:55 +02:00
BDFDB.ReactUtils.forceUpdate(channelTextareaButtonIns);
instance.close();
}
},
renderPopout: instance => {
2019-11-07 13:45:41 +01:00
let channelTextareaButtonIns = BDFDB.ReactUtils.findOwner(instance, {name:"BDFDB_ChannelTextAreaButton"});
2019-10-24 21:30:55 +02:00
if (channelTextareaButtonIns) {
channelTextareaButtonIns.props.isActive = true;
BDFDB.ReactUtils.forceUpdate(channelTextareaButtonIns);
}
let popoutelements = [];
popoutelements.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
2019-10-28 09:52:23 +01:00
className: BDFDB.disCN.marginbottom8,
2019-10-24 21:30:55 +02:00
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsLabel, {
label: `Words starting with "!" will be ignored`
})
}));
popoutelements.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
className: BDFDB.disCN.marginbottom8
})),
popoutelements = popoutelements.concat(this.createSelects(true));
popoutelements.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
type: "Switch",
2019-10-28 09:52:23 +01:00
className: BDFDB.disCN.marginbottom8,
2019-11-18 13:46:07 +01:00
label: "Translate your Messages before sending",
2019-10-24 21:30:55 +02:00
value: this.translating,
onChange: value => {
this.translating = value;
if (channelTextareaButtonIns) {
2019-12-09 15:58:27 +01:00
channelTextareaButtonIns.props.className = BDFDB.DOMUtils.formatClassName(BDFDB.disCN._googletranslateoptiontranslatebutton, this.translating && BDFDB.disCN._googletranslateoptiontranslating, BDFDB.disCN.textareapickerbutton);
2019-10-24 21:30:55 +02:00
BDFDB.ReactUtils.forceUpdate(channelTextareaButtonIns);
}
}
}));
return popoutelements;
}
});
}
2019-10-24 11:47:57 +02:00
createSelects (inPopout) {
let selects = [];
for (let key in this.defaults.choices) {
let isOutput = this.defaults.choices[key].direction == "output";
selects.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
title: this.defaults.choices[key].description,
titlechildren: isOutput ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
look: BDFDB.LibraryComponents.Button.Looks.BLANK,
size: BDFDB.LibraryComponents.Button.Sizes.NONE,
onClick: e => {
let place = this.defaults.choices[key].place;
2019-11-02 10:16:39 +01:00
let input = this.getLanguageChoice("input", place);
let output = this.getLanguageChoice("output", place);
input = input == "auto" ? "en" : input;
BDFDB.DataUtils.save(output, this, "choices", "input" + place);
BDFDB.DataUtils.save(input, this, "choices", "output" + place);
2019-11-02 10:06:49 +01:00
for (let selectIns of BDFDB.ReactUtils.findOwner(BDFDB.ReactUtils.findOwner(e._targetInst, {name:["BDFDB_Popout", "BDFDB_SettingsPanel"], up:true}), {name:"BDFDB_Select", all:true, noCopies:true})) if (selectIns && selectIns.props && selectIns.props.id && this.defaults.choices[selectIns.props.id].place == place) {
selectIns.props.value = this.defaults.choices[selectIns.props.id].direction == "input" ? output : input;
BDFDB.ReactUtils.forceUpdate(selectIns);
2019-10-24 11:47:57 +02:00
}
this.setLanguages();
},
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
2019-12-09 15:56:53 +01:00
iconSVG: `<svg class="${BDFDB.disCN._googletranslateoptionreversebutton}" version="1.1" xmlns="http://www.w3.org/2000/svg" width="21" height="21" fill="currentColor"><path d="M 0, 10.515 c 0, 2.892, 1.183, 5.521, 3.155, 7.361 L 0, 21.031 h 7.887 V 13.144 l -2.892, 2.892 C 3.549, 14.722, 2.629, 12.75, 2.629, 10.515 c 0 -3.418, 2.235 -6.309, 5.258 -7.492 v -2.629 C 3.418, 1.577, 0, 5.652, 0, 10.515 z M 21.031, 0 H 13.144 v 7.887 l 2.892 -2.892 C 17.482, 6.309, 18.402, 8.281, 18.402, 10.515 c 0, 3.418 -2.235, 6.309 -5.258, 7.492 V 20.768 c 4.469 -1.183, 7.887 -5.258, 7.887 -10.121 c 0 -2.892 -1.183 -5.521 -3.155 -7.361 L 21.031, 0 z"/></svg>`
2019-10-24 11:47:57 +02:00
})
}) : null,
className: BDFDB.disCN.marginbottom8,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
menuPlacement: inPopout ? BDFDB.LibraryComponents.Select.MenuPlacements.TOP : BDFDB.LibraryComponents.Select.MenuPlacements.BOTTOM,
value: this.getLanguageChoice(key),
id: key,
2019-12-07 11:56:11 +01:00
options: BDFDB.ObjectUtils.toArray(BDFDB.ObjectUtils.map(isOutput ? BDFDB.ObjectUtils.filter(this.languages, lang => lang.id != "auto") : this.languages, (lang, id) => {return {value:id, label:this.getLanguageName(lang)}})),
2019-10-24 11:47:57 +02:00
searchable: true,
optionRenderer: lang => {
2019-12-20 14:14:34 +01:00
return this.languages[lang.value] ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
2019-10-24 11:47:57 +02:00
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
children: [
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
grow: 1,
children: lang.label
}),
inPopout ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FavButton, {
isFavorite: this.languages[lang.value].fav == 0,
onClick: value => {
if (value) BDFDB.DataUtils.save(true, this, "favorites", lang.value);
else BDFDB.DataUtils.remove(this, "favorites", lang.value);
this.setLanguages();
}
}) : null
]
2019-12-20 14:14:34 +01:00
}) : null;
2019-10-24 11:47:57 +02:00
},
onChange: lang => {
BDFDB.DataUtils.save(lang.value, this, "choices", key);
}
})
}));
if (isOutput) selects.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
className: BDFDB.disCN.marginbottom8
}));
}
2019-12-09 15:56:53 +01:00
let engines = BDFDB.DataUtils.get(this, "engines");
for (let key in engines) {
selects.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
title: this.defaults.engines[key].description,
className: BDFDB.disCN.marginbottom8,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
menuPlacement: inPopout ? BDFDB.LibraryComponents.Select.MenuPlacements.TOP : BDFDB.LibraryComponents.Select.MenuPlacements.BOTTOM,
value: engines[key],
id: key,
options: Object.keys(this.translationEngines).map(engineKey => {return {value:engineKey, label:this.translationEngines[engineKey].name}}),
searchable: true,
2019-12-20 14:14:34 +01:00
onChange: (engine, instance) => {
2019-12-09 15:56:53 +01:00
BDFDB.DataUtils.save(engine.value, this, "engines", key);
2019-12-09 20:32:05 +01:00
this.setLanguages();
2019-12-20 14:14:34 +01:00
let popoutInstance = BDFDB.ReactUtils.findOwner(instance, {name: "BDFDB_PopoutContainer", up:true});
if (popoutInstance) {
popoutInstance.close();
popoutInstance.handleClick();
}
2019-12-09 15:56:53 +01:00
}
})
}));
}
2019-10-24 11:47:57 +02:00
return selects;
}
setLanguages () {
2019-12-09 15:56:53 +01:00
let languageIds = (this.translationEngines[BDFDB.DataUtils.get(this, "engines", "translator")] || {}).languages || [];
this.languages = Object.assign(
{"auto": {name:"Auto", id:"auto", integrated:false, dic:false}},
BDFDB.ObjectUtils.filter(BDFDB.LanguageUtils.languages, lang => languageIds.includes(lang.id)),
{"binary": {name:"Binary", id:"binary", integrated:false, dic:false}},
{"braille": {name:"Braille 6-dot", id:"braille", integrated:false, dic:false}},
{"morse": {name:"Morse", id:"morse", integrated:false, dic:false}}
);
2019-10-24 11:47:57 +02:00
let favorites = BDFDB.DataUtils.load(this, "favorites");
for (let id in this.languages) this.languages[id].fav = favorites[id] != undefined ? 0 : 1;
this.languages = BDFDB.ObjectUtils.sort(this.languages, "fav");
}
getLanguageChoice (direction, place) {
this.setLanguages();
var type = place === undefined ? direction : direction.toLowerCase() + place.charAt(0).toUpperCase() + place.slice(1).toLowerCase();
var choice = BDFDB.DataUtils.get(this, "choices", type);
choice = this.languages[choice] ? choice : Object.keys(this.languages)[0];
choice = type.indexOf("output") > -1 && choice == "auto" ? "en" : choice;
return choice;
}
2019-01-26 22:45:19 +01:00
getMessageAndPos (target) {
2019-11-08 14:36:57 +01:00
let messagediv = BDFDB.DOMUtils.getParent(BDFDB.dotCN.messagegroup + "> [aria-disabled]," + BDFDB.dotCN.messagegroup + "> * > [aria-disabled]", target);
2019-09-11 12:14:43 +02:00
let pos = messagediv ? Array.from(messagediv.parentElement.childNodes).filter(n => n.nodeType != Node.TEXT_NODE).indexOf(messagediv) : -1;
return {messagediv, pos};
}
2019-01-26 22:45:19 +01:00
translateMessage (message, target, channel) {
if (!message || !target) return;
2019-12-09 15:56:53 +01:00
let messageIns = BDFDB.ReactUtils.findOwner(target, {name:"Message", up:true});
let embedsIns = BDFDB.ReactUtils.findOwner(messageIns, {name:"Embed", all:true});
if (messageIns) {
let {oldString} = this.translatedMessages[message.id] || {};
if (oldString) {
delete this.translatedMessages[message.id];
this.formatMessage(message, oldString);
for (let i in message.embeds) if (embedsIns[i]) embedsIns[i].props.embed.rawDescription = message.embeds[i].rawDescription;
messageIns.props.message = new BDFDB.DiscordObjects.Message(message);
BDFDB.ReactUtils.forceUpdate(messageIns, embedsIns);
2019-09-27 09:48:32 +02:00
}
2019-12-09 15:56:53 +01:00
else {
oldString = message.content || "";
for (let embed of message.embeds) oldString += ("\n__________________ __________________ __________________\n" + embed.rawDescription);
this.translateText(oldString, "context", (translation, input, output) => {
if (translation) {
this.translatedMessages[message.id] = {oldString, message, input, output};
this.formatMessage(message, translation);
for (let i in message.embeds) if (embedsIns[i]) embedsIns[i].props.embed.rawDescription = message.embeds[i].rawDescription;
messageIns.props.message = new BDFDB.DiscordObjects.Message(message);
BDFDB.ReactUtils.forceUpdate(messageIns, embedsIns);
2019-09-27 09:48:32 +02:00
}
2019-12-09 15:56:53 +01:00
});
}
}
}
2019-12-09 15:56:53 +01:00
formatMessage (message, string) {
let strings = string.split("\n__________________ __________________ __________________\n");
message.content = strings.shift().trim();
for (let i in message.embeds) message.embeds[i].rawDescription = strings.shift().trim() || message.embeds[i].rawDescription;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
translateText (text, type, callback) {
2019-12-09 15:56:53 +01:00
var toast = null, finishTranslation = translation => {
this.isTranslating = false;
if (translation) translation = this.addExceptions(translation, exceptions);
2019-04-16 00:30:33 +02:00
if (toast) {
2019-11-01 11:09:32 +01:00
BDFDB.TimeUtils.clear(toast.interval);
2019-04-16 00:30:33 +02:00
toast.close();
}
2019-12-09 15:56:53 +01:00
callback(translation == text ? "" : translation, input, output);
2018-10-11 10:21:26 +02:00
};
var [newtext, exceptions, translate] = this.removeExceptions(text.trim(), type);
2018-10-11 10:21:26 +02:00
var input = Object.assign({}, this.languages[this.getLanguageChoice("input", type)]);
var output = Object.assign({}, this.languages[this.getLanguageChoice("output", type)]);
if (translate) {
2019-12-10 13:21:59 +01:00
let timer = 0;
2019-10-22 18:55:25 +02:00
toast = BDFDB.NotificationUtils.toast("Translating. Please wait", {timeout:0});
2019-12-10 13:21:59 +01:00
toast.interval = BDFDB.TimeUtils.interval(_ => {
if (timer++ > 40) {
finishTranslation("");
BDFDB.NotificationUtils.toast("Failed to translate text. Try another Translate Engine.", {type:"error"});
}
else toast.textContent = toast.textContent.indexOf(".....") > -1 ? "Translating. Please wait" : toast.textContent + ".";
}, 500);
2019-12-09 15:56:53 +01:00
let specialcase = this.checkForSpecialCase(newtext, input);
2019-04-16 00:30:33 +02:00
if (specialcase) {
input.name = specialcase.name;
switch (specialcase.id) {
case "binary": newtext = this.binary2string(newtext); break;
case "braille": newtext = this.braille2string(newtext); break;
case "morse": newtext = this.morse2string(newtext); break;
2019-04-13 07:09:34 +02:00
}
2019-04-16 00:30:33 +02:00
}
if (output.id == "binary" || output.id == "braille" || output.id == "morse") {
switch (output.id) {
case "binary": newtext = this.string2binary(newtext); break;
case "braille": newtext = this.string2braille(newtext); break;
case "morse": newtext = this.string2morse(newtext); break;
2019-04-13 07:09:34 +02:00
}
2019-12-09 15:56:53 +01:00
finishTranslation(newtext);
2018-10-11 10:21:26 +02:00
}
else {
2019-12-09 15:56:53 +01:00
let translator = BDFDB.DataUtils.get(this, "engines", "translator");
if (this.translationEngines[translator] && typeof this.translationEngines[translator].func == "function") {
this.isTranslating = true;
2019-12-10 13:21:59 +01:00
this.translationEngines[translator].func.apply(this, [{input, output, text:newtext, specialcase, engine:this.translationEngines[translator]}, finishTranslation]);
2019-12-09 15:56:53 +01:00
}
else finishTranslation("");
2018-10-11 10:21:26 +02:00
}
}
2019-12-09 15:56:53 +01:00
else finishTranslation(text);
}
googleTranslate (data, callback) {
let googleTranslateWindow = BDFDB.WindowUtils.open(this, this.getGoogleTranslatePageURL(data.input.id, data.output.id, data.text));
googleTranslateWindow.webContents.on("did-finish-load", _ => {
googleTranslateWindow.webContents.executeJavaScript(`require("electron").ipcRenderer.sendTo(${BDFDB.LibraryRequires.electron.remote.getCurrentWindow().webContents.id}, "GTO-translation", [(document.querySelector(".translation") || {}).innerText, [(new RegExp("{code:'([^']*)',name:'" + [(new RegExp((window.source_language_detected || "").replace("%1$s", "([A-z]{2,})"), "g")).exec(document.body.innerHTML)].flat()[1] +"'}", "g")).exec(document.body.innerHTML)].flat()[1]]);`);
});
BDFDB.WindowUtils.addListener(this, "GTO-translation", (event, messagedata) => {
BDFDB.WindowUtils.close(googleTranslateWindow);
BDFDB.WindowUtils.removeListener(this, "GTO-translation");
if (!data.specialcase && messagedata[1] && this.languages[messagedata[1]]) {
data.input.name = this.languages[messagedata[1]].name;
data.input.ownlang = this.languages[messagedata[1]].ownlang;
}
callback(messagedata[0]);
});
2018-10-11 10:21:26 +02:00
}
2019-12-09 20:32:05 +01:00
iTranslateTranslate (data, callback) {
2019-12-10 13:21:59 +01:00
let translate = _ => {
2019-12-17 11:07:41 +01:00
BDFDB.LibraryRequires.request({
method: "POST",
url: "https://web-api.itranslateapp.com/v3/texts/translate",
headers: {
"API-KEY": "d2aefeac9dc661bc98eebd6cc12f0b82"
2019-12-10 13:21:59 +01:00
},
2019-12-17 11:07:41 +01:00
body: JSON.stringify({
source: {
dialect: data.input.id,
text: data.text
},
target: {
dialect: data.output.id
}
})
}, (error, response, result) => {
if (!error && response && response.statusCode == 200) {
try {
let response = JSON.parse(result);
if (!data.specialcase && response.source && response.source.detected && this.languages[response.source.detected]) {
data.input.name = this.languages[response.source.detected].name;
data.input.ownlang = this.languages[response.source.detected].ownlang;
2019-12-10 13:21:59 +01:00
}
2019-12-17 11:07:41 +01:00
callback(response.target.text);
2019-12-10 13:21:59 +01:00
}
2019-12-17 11:07:41 +01:00
catch (err) {callback("");}
2019-12-10 13:21:59 +01:00
}
2019-12-17 11:07:41 +01:00
else {
BDFDB.NotificationUtils.toast("Failed to translate text. Translation Server is down or API-key outdated. Try another Translate Engine.", {type:"error"});
callback("");
}
});
2019-12-10 13:21:59 +01:00
};
if (data.engine.APIkey) translate();
else BDFDB.LibraryRequires.request("https://www.itranslate.com/themes/itranslate2016/assets/webapp/js/main.js", {gzip: true}, (error, response, result) => {
2019-12-09 20:32:05 +01:00
if (!error && result) {
2019-12-10 13:21:59 +01:00
let APIkey = /var API_KEY = "(.+)"/.exec(result);
if (APIkey) {
data.engine.APIkey = APIkey[1];
translate();
}
else callback("");
}
else callback("");
});
}
yandexTranslate (data, callback) {
BDFDB.LibraryRequires.request(`https://translate.yandex.net/api/v1.5/tr/translate?key=trnsl.1.1.20191206T223907Z.52bd512eca953a5b.1ec123ce4dcab3ae859f312d27cdc8609ab280de&text=${encodeURIComponent(data.text)}&lang=${data.specialcase || data.input.id == "auto" ? data.output.id : (data.input.id + "-" + data.output.id)}&options=1`, (error, response, result) => {
2019-12-17 11:07:41 +01:00
if (!error && result && response.statusCode == 200) {
2019-12-10 13:21:59 +01:00
result = BDFDB.DOMUtils.create(result);
let translation = result.querySelector("text");
let detected = result.querySelector("detected");
if (translation && detected) {
let detectedlang = detected.getAttribute("lang");
if (!data.specialcase && detectedlang && this.languages[detectedlang]) {
data.input.name = this.languages[detectedlang].name;
data.input.ownlang = this.languages[detectedlang].ownlang;
}
callback(translation.innerText);
}
else callback("");
2019-12-09 20:32:05 +01:00
}
2019-12-17 11:07:41 +01:00
else {
BDFDB.NotificationUtils.toast("Failed to translate text. Translation Server is down or API-key outdated. Try another Translate Engine.", {type:"error"});
callback("");
}
2019-12-09 20:32:05 +01:00
});
}
2019-09-04 12:34:02 +02:00
2019-04-16 00:30:33 +02:00
checkForSpecialCase (text, input) {
if (input.id == "binary" || input.id == "braille" || input.id == "morse") return input;
else if (input.id == "auto") {
if (/^[0-1]*$/.test(text.replace(/\s/g, ""))) {
return {id: "binary", name: "Binary"};
}
else if (/^[⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿]*$/.test(text.replace(/\s/g, ""))) {
return {id: "braille", name: "Braille 6-dot"};
}
else if (/^[/|·−._-]*$/.test(text.replace(/\s/g, ""))) {
return {id: "morse", name: "Morse"};
}
}
2019-09-04 12:34:02 +02:00
return null;
2019-04-16 00:30:33 +02:00
}
string2binary (string) {
var binary = "";
for (let character of string) binary += parseInt(character.charCodeAt(0).toString(2)).toPrecision(8).split(".").reverse().join("").toString() + " ";
return binary;
}
string2braille (string) {
var braille = "";
for (let character of string) braille += this.brailleConverter[character.toLowerCase()] ? this.brailleConverter[character.toLowerCase()] : character;
return braille;
}
string2morse (string) {
string = string.replace(/ /g, "%%%%%%%%%%");
var morse = "";
for (let character of string) morse += (this.morseConverter[character.toLowerCase()] ? this.morseConverter[character.toLowerCase()] : character) + " ";
morse = morse.split("\n");
for (let i in morse) morse[i] = morse[i].trim();
return morse.join("\n").replace(/% % % % % % % % % % /g, "/ ");
}
binary2string (binary) {
var string = "";
binary = binary.replace(/\n/g, "00001010").replace(/\r/g, "00001101").replace(/\t/g, "00001001").replace(/\s/g, "");
if (/^[0-1]*$/.test(binary)) {
var eightdigits = "";
var counter = 0;
for (var digit of binary) {
eightdigits += digit;
counter++;
if (counter > 7) {
string += String.fromCharCode(parseInt(eightdigits,2).toString(10));
eightdigits = "";
counter = 0;
}
}
}
2019-10-22 18:55:25 +02:00
else BDFDB.NotificationUtils.toast("Invalid binary format. Only use 0s and 1s.", {type:"error"});
2019-04-16 00:30:33 +02:00
return string;
}
braille2string (braille) {
var string = "";
for (let character of braille) string += this.brailleConverter[character.toLowerCase()] ? this.brailleConverter[character.toLowerCase()] : character;
return string;
}
morse2string (morse) {
var string = "";
for (let word of morse.replace(/[_-]/g, "").replace(/\./g, "·").replace(/\r|\t/g, "").split(/\/|\||\n/g)) {
for (let characterstr of word.trim().split(" ")) string += this.morseConverter[characterstr] ? this.morseConverter[characterstr] : characterstr;
string += " ";
}
return string.trim();
}
2019-01-26 22:45:19 +01:00
addExceptions (string, exceptions) {
2019-12-11 10:51:40 +01:00
for (let count in exceptions) {
let exception = exceptions[count].indexOf("!") == 0 ? exceptions[count].slice(1) : exceptions[count];
let newstring = string.replace(new RegExp(`\[/////[ ]*${count}\]`), exception);
if (newstring == string) string = newstring + " " + exception;
else string = newstring;
}
2018-10-11 10:21:26 +02:00
return string;
}
2019-01-26 22:45:19 +01:00
removeExceptions (string, type) {
var exceptions = {}, newString = [], count = 0;
if (type == "context") {
let text = [], i = 0;
string.split("").forEach(chara => {
if (chara == "<" && text[i]) i++;
2019-09-04 12:34:02 +02:00
text[i] = text[i] ? text[i] + chara : chara;
if (chara == ">") i++;
});
for (let j in text) {
if (text[j].indexOf("<") == 0) {
2019-12-11 10:51:40 +01:00
newString.push(`[/////${count}]`);
exceptions[count] = text[j];
count++;
}
else newString.push(text[j]);
2018-10-11 10:21:26 +02:00
}
}
else {
string.split(" ").forEach(word => {
if (word.indexOf("<@!") == 0 || word.indexOf(":") == 0 || word.indexOf("@") == 0 || word.indexOf("#") == 0 || (word.indexOf("!") == 0 && word.length > 1)) {
2019-12-11 10:51:40 +01:00
newString.push(`[/////${count}]`);
exceptions[count] = word;
count++;
}
else newString.push(word);
});
}
return [newString.join(" "), exceptions, newString.length-count != 0];
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
getGoogleTranslatePageURL (input, output, text) {
2019-10-22 18:55:25 +02:00
input = BDFDB.LanguageUtils.languages[input] ? input : "auto";
2018-10-11 10:21:26 +02:00
return "https://translate.google.com/#" + input + "/" + output + "/" + encodeURIComponent(text);
}
2019-12-07 11:56:11 +01:00
getLanguageName (language) {
if (language.name.startsWith("Discord")) return language.name.slice(0, -1) + (language.ownlang && this.languages[language.id].name != language.ownlang ? ` / ${language.ownlang}` : "") + ")";
else return language.name + (language.ownlang && language.name != language.ownlang ? ` / ${language.ownlang}` : "");
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
setLabelsByLanguage () {
2019-10-24 11:47:57 +02:00
switch (BDFDB.LanguageUtils.getLanguage().id) {
2018-10-11 10:21:26 +02:00
case "hr": //croatian
return {
context_messagetranslateoption_text: "Prijevod poruke",
context_messageuntranslateoption_text: "Prijenos poruke",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Traži prijevod",
popout_translateoption_text: "Prevesti",
popout_untranslateoption_text: "Prevesti natrag",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "preveo"
};
case "da": //danish
return {
context_messagetranslateoption_text: "Oversæt Besked",
context_messageuntranslateoption_text: "Oversæt Besked tilbage",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Søg oversættelse",
popout_translateoption_text: "Oversætte",
popout_untranslateoption_text: "Oversæt tilbage",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "oversat"
};
case "de": //german
return {
context_messagetranslateoption_text: "Nachricht übersetzen",
context_messageuntranslateoption_text: "Nachricht unübersetzen",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Suche Übersetzung",
popout_translateoption_text: "Übersetzen",
popout_untranslateoption_text: "Unübersetzen",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "übersetzt"
};
case "es": //spanish
return {
context_messagetranslateoption_text: "Traducir mensaje",
context_messageuntranslateoption_text: "Traducir mensaje de vuelta",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Buscar traducción",
popout_translateoption_text: "Traducir",
popout_untranslateoption_text: "Traducir de vuelta",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "traducido"
};
case "fr": //french
return {
context_messagetranslateoption_text: "Traduire le message",
context_messageuntranslateoption_text: "Traduire le message en retour",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Rechercher une traduction",
popout_translateoption_text: "Traduire",
popout_untranslateoption_text: "Traduire en arrière",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "traduit"
};
case "it": //italian
return {
context_messagetranslateoption_text: "Tradurre il messaggio",
context_messageuntranslateoption_text: "Tradurre il messaggio indietro",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Cerca la traduzione",
popout_translateoption_text: "Traduci",
popout_untranslateoption_text: "Traduci indietro",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "tradotto"
};
case "nl": //dutch
return {
context_messagetranslateoption_text: "Vertaal bericht",
context_messageuntranslateoption_text: "Vertaal bericht terug",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Zoek vertaling",
popout_translateoption_text: "Vertaal",
popout_untranslateoption_text: "Vertaal terug",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "vertaalde"
};
case "no": //norwegian
return {
context_messagetranslateoption_text: "Oversett melding",
context_messageuntranslateoption_text: "Oversett melding tilbake",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Søk oversettelse",
popout_translateoption_text: "Oversett",
popout_untranslateoption_text: "Oversett tilbake",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "oversatt"
};
case "pl": //polish
return {
context_messagetranslateoption_text: "Przetłumacz wiadomość",
context_messageuntranslateoption_text: "Przetłumacz wiadomość z powrotem",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Wyszukaj tłumaczenie",
popout_translateoption_text: "Przetłumacz",
popout_untranslateoption_text: "Przetłumacz ponownie",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "przetłumaczony"
};
case "pt-BR": //portuguese (brazil)
return {
context_messagetranslateoption_text: "Traduzir mensagem",
context_messageuntranslateoption_text: "Traduzir mensagem de volta",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Pesquisar tradução",
popout_translateoption_text: "Traduzir",
popout_untranslateoption_text: "Traduzir de volta",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "traduzido"
};
case "fi": //finnish
return {
context_messagetranslateoption_text: "Käännä viesti",
context_messageuntranslateoption_text: "Käännä viesti takaisin",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Etsi käännös",
popout_translateoption_text: "Kääntää",
popout_untranslateoption_text: "Käännä takaisin",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "käännetty"
};
case "sv": //swedish
return {
context_messagetranslateoption_text: "Översätt meddelande",
context_messageuntranslateoption_text: "Översätt meddelandet tillbaka",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Sök översättning",
popout_translateoption_text: "Översätt",
popout_untranslateoption_text: "Översätt tillbaka",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "översatt"
};
case "tr": //turkish
return {
context_messagetranslateoption_text: "Mesajı çevir",
context_messageuntranslateoption_text: "İletiyi geri çevir",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Arama tercümesi",
popout_translateoption_text: "Çevirmek",
popout_untranslateoption_text: "Geri çevir",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "tercüme"
};
case "cs": //czech
return {
context_messagetranslateoption_text: "Přeposlat zprávu",
context_messageuntranslateoption_text: "Přeposlat zprávu zpátky",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Hledat překlad",
popout_translateoption_text: "Přeposlat",
popout_untranslateoption_text: "Přeposlat zpět",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "přeloženo"
};
case "bg": //bulgarian
return {
context_messagetranslateoption_text: "Преведете на съобщението",
context_messageuntranslateoption_text: "Преведете съобщението обратно",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Търсене на превод",
popout_translateoption_text: "Превод",
popout_untranslateoption_text: "Превод обратно",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "преведена"
};
case "ru": //russian
return {
context_messagetranslateoption_text: "Перевести сообщение",
context_messageuntranslateoption_text: "Перевести сообщение обратно",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Поиск перевода",
popout_translateoption_text: "Перевести",
popout_untranslateoption_text: "Перевести обратно",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "переведенный"
};
case "uk": //ukrainian
return {
context_messagetranslateoption_text: "Перекласти повідомлення",
context_messageuntranslateoption_text: "Перекласти повідомлення назад",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Пошук перекладу",
popout_translateoption_text: "Перекласти",
popout_untranslateoption_text: "Перекласти назад",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "перекладений"
};
case "ja": //japanese
return {
context_messagetranslateoption_text: "メッセージを翻訳する",
context_messageuntranslateoption_text: "メッセージを翻訳する",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "翻訳の検索",
popout_translateoption_text: "翻訳",
popout_untranslateoption_text: "翻訳する",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "翻訳された"
};
case "zh-TW": //chinese (traditional)
return {
context_messagetranslateoption_text: "翻譯消息",
context_messageuntranslateoption_text: "翻譯消息",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "搜索翻譯",
popout_translateoption_text: "翻譯",
popout_untranslateoption_text: "翻譯回來",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "翻譯"
};
case "ko": //korean
return {
context_messagetranslateoption_text: "메시지 번역",
context_messageuntranslateoption_text: "메시지 번역 뒤로",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "검색 번역",
popout_translateoption_text: "다시",
popout_untranslateoption_text: "다시 번역",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "번역 된"
};
default: //default: english
return {
context_messagetranslateoption_text: "Translate Message",
context_messageuntranslateoption_text: "Untranslate Message",
2018-10-11 10:21:26 +02:00
context_googletranslateoption_text: "Search translation",
popout_translateoption_text: "Translate",
popout_untranslateoption_text: "Untranslate",
2018-10-11 10:21:26 +02:00
translated_watermark_text: "translated"
};
}
}
}