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

1419 lines
70 KiB
JavaScript
Raw Normal View History

2020-10-20 23:25:34 +02:00
/**
* @name GoogleTranslateOption
2021-03-05 13:26:41 +01:00
* @author DevilBro
2020-10-20 23:25:34 +02:00
* @authorId 278543574059057154
2021-05-25 10:35:29 +02:00
* @version 2.2.5
2021-03-05 13:26:41 +01:00
* @description Allows you to translate Messages and your outgoing Message within Discord
2020-10-20 23:25:34 +02:00
* @invite Jx3TjNS
* @donate https://www.paypal.me/MircoWittrien
* @patreon https://www.patreon.com/MircoWittrien
2021-03-09 15:10:55 +01:00
* @website https://mwittrien.github.io/
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/GoogleTranslateOption/
2021-03-10 09:17:37 +01:00
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/GoogleTranslateOption/GoogleTranslateOption.plugin.js
2020-10-20 23:25:34 +02:00
*/
2018-10-11 10:21:26 +02:00
2020-09-19 20:49:33 +02:00
module.exports = (_ => {
2020-10-09 21:09:35 +02:00
const config = {
2020-09-19 20:49:33 +02:00
"info": {
"name": "GoogleTranslateOption",
"author": "DevilBro",
2021-05-25 10:35:29 +02:00
"version": "2.2.5",
2021-03-04 12:15:46 +01:00
"description": "Allows you to translate Messages and your outgoing Message within Discord"
2021-05-03 20:30:07 +02:00
},
"changeLog": {
2021-05-18 12:07:15 +02:00
"improved": {
2021-05-25 10:35:29 +02:00
"Per Channel Outgoing Translation State": "Instead of toggling the outgoing translation for every chat it now remembers the state for each channel, can be disabled to the way it worked before in the plugin settings"
2021-05-03 20:30:07 +02:00
}
2020-09-19 20:49:33 +02:00
}
2020-02-04 08:20:40 +01:00
};
2020-10-31 11:43:29 +01:00
2020-10-09 21:09:35 +02:00
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
2021-01-06 12:38:36 +01:00
getName () {return config.info.name;}
getAuthor () {return config.info.author;}
getVersion () {return config.info.version;}
2021-02-01 17:13:13 +01:00
getDescription () {return `The Library Plugin needed for ${config.info.name} is missing. Open the Plugin Settings to download it. \n\n${config.info.description}`;}
downloadLibrary () {
require("request").get("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js", (e, r, b) => {
2021-03-05 13:14:18 +01:00
if (!e && b && r.statusCode == 200) require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.showToast("Finished downloading BDFDB Library", {type: "success"}));
2021-03-06 14:59:48 +01:00
else BdApi.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
2021-02-01 17:13:13 +01:00
});
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
load () {
2020-11-19 16:51:14 +01:00
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
2020-09-19 20:49:33 +02:00
if (!window.BDFDB_Global.downloadModal) {
window.BDFDB_Global.downloadModal = true;
2021-01-14 16:14:44 +01:00
BdApi.showConfirmationModal("Library Missing", `The Library Plugin needed for ${config.info.name} is missing. Please click "Download Now" to install it.`, {
2020-09-19 20:49:33 +02:00
confirmText: "Download Now",
cancelText: "Cancel",
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
2020-09-20 08:15:13 +02:00
onConfirm: _ => {
delete window.BDFDB_Global.downloadModal;
2021-02-01 17:13:13 +01:00
this.downloadLibrary();
2020-09-20 08:15:13 +02:00
}
2020-09-19 20:49:33 +02:00
});
}
if (!window.BDFDB_Global.pluginQueue.includes(config.info.name)) window.BDFDB_Global.pluginQueue.push(config.info.name);
2020-10-09 21:09:35 +02:00
}
2021-01-06 12:38:36 +01:00
start () {this.load();}
stop () {}
getSettingsPanel () {
2020-11-28 23:12:09 +01:00
let template = document.createElement("template");
2021-01-14 16:14:44 +01:00
template.innerHTML = `<div style="color: var(--header-primary); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${config.info.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
2021-02-01 17:13:13 +01:00
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
2020-11-28 23:12:09 +01:00
return template.content.firstElementChild;
}
2020-10-09 21:09:35 +02:00
} : (([Plugin, BDFDB]) => {
2021-03-20 18:50:17 +01:00
var _this;
2021-01-21 16:15:24 +01:00
const translateIconGeneral = `<svg name="Translate" width="24" height="24" viewBox="0 0 24 24"><mask/><path fill="currentColor" mask="url(#translateIconMask)" d="M 4 2 C 2.9005593 2 2 2.9005593 2 4 L 2 17 C 2 18.10035 2.9005593 19 4 19 L 11 19 L 12 22 L 20 22 C 21.10035 22 22 21.099441 22 20 L 22 7 C 22 5.9005592 21.099441 5 20 5 L 10.880859 5 L 10 2 L 4 2 z M 11.173828 6 L 20 6 C 20.550175 6 21 6.4498249 21 7 L 21 20 C 21 20.550175 20.550176 21 20 21 L 13 21 L 15 19 L 14.185547 16.236328 L 15.105469 15.314453 L 17.791016 18 L 18.521484 17.269531 L 15.814453 14.583984 C 16.714739 13.54911 17.414914 12.335023 17.730469 11.080078 L 19 11.080078 L 19 10.039062 L 15.365234 10.039062 L 15.365234 9 L 14.324219 9 L 14.324219 10.039062 L 12.365234 10.039062 L 11.173828 6 z M 7.1660156 6.4160156 C 8.2063466 6.4160156 9.1501519 6.7857022 9.9003906 7.4804688 L 9.9648438 7.5449219 L 8.7441406 8.7246094 L 8.6855469 8.6699219 C 8.4009108 8.3998362 7.9053417 8.0859375 7.1660156 8.0859375 C 5.8555986 8.0859375 4.7890625 9.1708897 4.7890625 10.505859 C 4.7890625 11.84083 5.8555986 12.925781 7.1660156 12.925781 C 8.5364516 12.925781 9.1309647 12.050485 9.2910156 11.464844 L 7.0800781 11.464844 L 7.0800781 9.9160156 L 11.03125 9.9160156 L 11.044922 9.984375 C 11.084932 10.194442 11.099609 10.379777 11.099609 10.589844 C 11.094109 12.945139 9.4803883 14.583984 7.1660156 14.583984 C 4.9107525 14.583984 3.0800781 12.749807 3.0800781 10.5 C 3.0800781 8.2501934 4.9162088 6.4160156 7.1660156 6.4160156 z M 12.675781 11.074219 L 16.669922 11.074219 C 16.669922 11.074219 16.330807 12.390095 15.111328 13.810547 C 14.576613 13.195806 14.206233 12.595386 13.970703 12.115234 L 12.980469 12.115234 L 12.675781 11.074219 z M 13.201172 12.884766 C 13.535824 13.484957 13.940482 14.059272 14.390625 14.583984 L 13.855469 15.115234 L 13.201172 12.884766 z"/><extra/></svg>`;
const translateIconMask = `<mask id="translateIconMask" fill="black"><path fill="white" d="M 0 0 H 24 V 24 H 0 Z"/><path fill="black" d="M24 12 H 12 V 24 H 24 Z"/></mask>`;
2020-09-19 20:49:33 +02:00
const translateIcon = translateIconGeneral.replace(`<extra/>`, ``).replace(`<mask/>`, ``).replace(` mask="url(#translateIconMask)"`, ``);
2021-01-21 16:21:08 +01:00
const translateIconUntranslate = translateIconGeneral.replace(`<extra/>`, `<path fill="none" stroke="#f04747" stroke-width="2" d="m 14.702359,14.702442 8.596228,8.596148 m 0,-8.597139 -8.59722,8.596147 z"/>`).replace(`<mask/>`, translateIconMask);
2021-03-20 18:50:17 +01:00
const TranslateButtonComponent = class TranslateButton extends BdApi.React.Component {
render() {
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ChannelTextAreaButton, {
2021-05-25 10:35:29 +02:00
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN._googletranslateoptiontranslatebutton, _this.isTranslationEnabled(this.props.channelId) && BDFDB.disCN._googletranslateoptiontranslating, BDFDB.disCN.textareapickerbutton),
2021-03-20 18:50:17 +01:00
isActive: this.props.isActive,
iconSVG: translateIcon,
nativeClass: true,
onClick: _ => {
this.props.isActive = true;
BDFDB.ReactUtils.forceUpdate(this);
BDFDB.ModalUtils.open(_this, {
2021-05-12 18:41:59 +02:00
size: "LARGE",
2021-03-20 18:50:17 +01:00
header: BDFDB.LanguageUtils.LanguageStrings.SETTINGS,
subHeader: "",
onClose: _ => {
this.props.isActive = false;
BDFDB.ReactUtils.forceUpdate(this);
},
2021-05-25 10:35:29 +02:00
children: BDFDB.ReactUtils.createElement(TranslateSettingsComponent, {
channelId: this.props.channelId
})
2021-03-20 18:50:17 +01:00
});
},
onContextMenu: _ => {
2021-05-25 10:35:29 +02:00
_this.toggleTranslation(this.props.channelId);
2021-03-20 18:50:17 +01:00
BDFDB.ReactUtils.forceUpdate(this);
}
});
}
};
2021-05-12 18:41:59 +02:00
const TranslateSettingsComponent = class TranslateSettings extends BdApi.React.Component {
filterLanguages(isOutput, place) {
return BDFDB.ObjectUtils.toArray(BDFDB.ObjectUtils.map(isOutput ? BDFDB.ObjectUtils.filter(languages, lang => !lang.auto) : languages, (lang, id) => ({
value: id,
label: _this.getLanguageName(lang),
backup: this.isOnlyBackup(lang)
}))).filter(isOutput && this.isOnlyBackup(languages[_this.getLanguageChoice("input", place)]) ? (n => n.backup) : (n => n));
}
isOnlyBackup(lang) {
return lang.auto && !translationEngines[_this.settings.engines.translator].auto || !lang.auto && !lang.special && !translationEngines[_this.settings.engines.translator].languages.includes(lang.id);
}
2021-03-20 18:50:17 +01:00
render() {
2021-05-12 18:41:59 +02:00
return [
BDFDB.ArrayUtils.is(_this.settings.exceptions.wordStart) && _this.settings.exceptions.wordStart.length && [
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
className: BDFDB.disCN.marginbottom8,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsLabel, {
label: `Words starting with ${_this.settings.exceptions.wordStart.map(n => '"' + n + '"').join(", ")} will be ignored`
})
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
className: BDFDB.disCN.marginbottom8
2021-03-20 18:50:17 +01:00
})
2021-05-12 18:41:59 +02:00
],
Object.keys(_this.defaults.choices).map(key => {
const isOutput = _this.defaults.choices[key].direction == "output";
const place = _this.defaults.choices[key].place;
return [
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: _ => {
let input = _this.getLanguageChoice("input", place);
let output = _this.getLanguageChoice("output", place);
input = input == "auto" ? "en" : input;
_this.settings.choices["input" + place] = output;
_this.settings.choices["output" + place] = input;
BDFDB.DataUtils.save(_this.settings.choices, _this, "choices");
2021-03-20 18:50:17 +01:00
_this.setLanguages();
2021-05-12 18:41:59 +02:00
BDFDB.ReactUtils.forceUpdate(this);
},
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
className: BDFDB.disCN._googletranslateoptionreversebutton,
iconSVG: `<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>`
})
}) : null,
className: BDFDB.disCN.marginbottom8,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
value: _this.getLanguageChoice(key),
options: this.filterLanguages(isOutput, place),
optionRenderer: lang => languages[lang.value] ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
children: [
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
grow: 1,
children: lang.label
}),
lang.backup && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
text: "Will use Backup Translator",
tooltipConfig: {
color: "red"
},
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
nativeClass: true,
width: 20,
height: 20,
color: BDFDB.DiscordConstants.Colors.STATUS_RED,
name: BDFDB.LibraryComponents.SvgIcon.Names.WARNING
})
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FavButton, {
isFavorite: languages[lang.value].fav == 0,
onClick: value => {
2021-05-25 10:35:29 +02:00
if (value) favorites.push(lang.value);
else BDFDB.ArrayUtils.remove(favorites, lang.value, true);
BDFDB.DataUtils.save(favorites.sort(), _this, "favorites");
2021-05-12 18:41:59 +02:00
_this.setLanguages();
}
})
]
}) : null,
onChange: value => {
_this.settings.choices[key] = value;
BDFDB.DataUtils.save(_this.settings.choices, _this, "choices");
2021-03-20 18:50:17 +01:00
}
2021-05-12 18:41:59 +02:00
})
}),
isOutput && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
className: BDFDB.disCN.marginbottom8
})
];
}),
Object.keys(_this.defaults.engines).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
title: _this.defaults.engines[key].description,
className: BDFDB.disCN.marginbottom8,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
value: _this.settings.engines[key],
options: (key == "backup" ? ["----"] : []).concat(Object.keys(translationEngines)).filter(key == "backup" ? (n => n != _this.settings.engines.translator) : (n => n)).map(engineKey => ({value: engineKey, label: translationEngines[engineKey] ? translationEngines[engineKey].name : "----"})),
maxVisibleItems: 3,
onChange: value => {
_this.settings.engines[key] = value;
BDFDB.DataUtils.save(_this.settings.engines, _this, "engines");
_this.setLanguages();
BDFDB.ReactUtils.forceUpdate(this);
}
})
})),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: _this,
keys: ["general", "sendOriginalMessage"],
label: _this.defaults.general.sendOriginalMessage.description,
tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H5,
value: _this.settings.general.sendOriginalMessage
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
type: "Switch",
label: "Translate your Messages before sending",
tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H5,
2021-05-25 10:35:29 +02:00
value: _this.isTranslationEnabled(this.props.channelId),
2021-03-20 18:50:17 +01:00
onChange: value => {
2021-05-25 10:35:29 +02:00
_this.toggleTranslation(this.props.channelId);
2021-05-12 18:41:59 +02:00
BDFDB.ReactUtils.forceUpdate(this);
2021-03-20 18:50:17 +01:00
}
})
2021-05-12 18:41:59 +02:00
].flat(10).filter(n => n);
2021-03-20 18:50:17 +01:00
}
};
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
const 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-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
const 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", "_":"··−−·−"
};
const googleLanguages = ["af","am","ar","az","be","bg","bn","bs","ca","ceb","co","cs","cy","da","de","el","en","eo","es","et","eu","fa","fi","fr","fy","ga","gd","gl","gu","ha","haw","hi","hmn","hr","ht","hu","hy","id","ig","is","it","iw","ja","jw","ka","kk","km","kn","ko","ku","ky","la","lb","lo","lt","lv","mg","mi","mk","ml","mn","mr","ms","mt","my","ne","nl","no","ny","or","pa","pl","ps","pt","ro","ru","rw","sd","si","sk","sl","sm","sn","so","sq","sr","st","su","sv","sw","ta","te","tg","th","tk","tl","tr","tt","ug","uk","ur","uz","vi","xh","yi","yo","zh-CN","zu"];
const translationEngines = {
2021-05-12 14:33:47 +02:00
googleapi: {name: "Google", auto: true, funcName: "googleApiTranslate", languages: googleLanguages},
deepl: {name: "DeepL", auto: true, funcName: "deepLTranslate", languages: ["bg","cs","da","de","en","el","es","et","fi","fr","hu","it","ja","lt","lv","nl","pl","pt","ro","ru","sk","sl","sv","zh"]},
itranslate: {name: "iTranslate", auto: true, funcName: "iTranslateTranslate", languages: [...new Set(["af","ar","az","be","bg","bn","bs","ca","ceb","cs","cy","da","de","el","en","eo","es","et","eu","fa","fi","fil","fr","ga","gl","gu","ha","he","hi","hmn","hr","ht","hu","hy","id","ig","is","it","ja","jw","ka","kk","km","kn","ko","la","lo","lt","lv","mg","mi","mk","ml","mn","mr","ms","mt","my","ne","nl","no","ny","pa","pl","pt-BR","pt-PT","ro","ru","si","sk","sl","so","sq","sr","st","su","sv","sw","ta","te","tg","th","tr","uk","ur","uz","vi","we","yi","yo","zh-CN","zh-TW","zu"].concat(googleLanguages))].sort()},
yandex: {name: "Yandex", auto: true, funcName: "yandexTranslate", languages: ["af","am","ar","az","ba","be","bg","bn","bs","ca","ceb","cs","cy","da","de","el","en","eo","es","et","eu","fa","fi","fr","ga","gd","gl","gu","he","hi","hr","ht","hu","hy","id","is","it","ja","jv","ka","kk","km","kn","ko","ky","la","lb","lo","lt","lv","mg","mhr","mi","mk","ml","mn","mr","ms","mt","my","ne","nl","no","pa","pap","pl","pt","ro","ru","si","sk","sl","sq","sr","su","sv","sw","ta","te","tg","th","tl","tr","tt","udm","uk","ur","uz","vi","xh","yi","zh"]},
2020-11-19 16:51:14 +01:00
papago: {name: "Papago", auto: false, funcName: "papagoTranslate", languages: ["en","es","fr","id","ja","ko","th","vi","zh-CN","zh-TW"]}
2020-09-19 20:49:33 +02:00
};
2021-05-25 10:35:29 +02:00
var languages = {};
var favorites = [];
var translationEnabledStates = [], isTranslating;
var translatedMessages = {}, oldMessages = {};
2020-09-19 20:49:33 +02:00
2020-10-09 21:09:35 +02:00
return class GoogleTranslateOption extends Plugin {
2021-01-06 12:38:36 +01:00
onLoad () {
2021-03-20 18:50:17 +01:00
_this = this;
2020-09-19 20:49:33 +02:00
this.defaults = {
2021-03-20 18:50:17 +01:00
general: {
2021-05-25 10:35:29 +02:00
addTranslateButton: {value: true, description: "Adds a Translate Button to the Channel Textarea"},
usePerChatTranslation: {value: true, description: "Enables/Disables the Translator Button State per Channel and not globally"},
sendOriginalMessage: {value: false, description: "Sends the original Message together with the Translation"}
2020-09-19 20:49:33 +02:00
},
choices: {
2021-03-20 18:50:17 +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: "},
2021-05-12 18:41:59 +02:00
inputMessage: {value: "auto", direction: "input", place: "Message", description: "Input Language in your sent Messages: "},
outputMessage: {value: "$discord", direction: "output", place: "Message", description: "Output Language in your sent Messages: "}
2020-09-19 20:49:33 +02:00
},
2020-10-31 11:43:29 +01:00
exceptions: {
2020-11-19 16:51:14 +01:00
wordStart: {value: ["!"], max: 1, description: "Words starting with any of these will be ignored"}
2020-10-31 11:43:29 +01:00
},
2020-09-19 20:49:33 +02:00
engines: {
2021-05-12 18:41:59 +02:00
translator: {value: "googleapi", description: "Translation Engine"},
backup: {value: "----", description: "Backup Engine"}
2020-09-19 20:49:33 +02:00
}
};
2020-02-04 08:20:40 +01:00
2020-09-19 20:49:33 +02:00
this.patchedModules = {
before: {
ChannelTextAreaForm: "render",
ChannelEditorContainer: "render",
Embed: "render"
},
after: {
ChannelTextAreaContainer: "render",
Messages: "type",
MessageContent: "type",
Embed: "render"
}
};
2020-02-04 08:20:40 +01:00
2020-09-19 20:49:33 +02:00
this.css = `
${BDFDB.dotCN._googletranslateoptiontranslatebutton + BDFDB.dotCNS._googletranslateoptiontranslating + BDFDB.dotCN.textareaicon} {
color: #F04747 !important;
}
${BDFDB.dotCN._googletranslateoptionreversebutton} {
opacity: 0.5;
margin-right: 5px;
transition: all 200ms ease;
}
${BDFDB.dotCN._googletranslateoptionreversebutton}:hover {
opacity: 1;
}
`;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStart () {
2021-05-25 10:35:29 +02:00
// REMOVE 25.05.2021
let loadedFavorites = BDFDB.DataUtils.load(this, "favorites");
if (BDFDB.ObjectUtils.is(loadedFavorites) && Object.keys(loadedFavorites).length) BDFDB.DataUtils.save(Object.keys(loadedFavorites), this, "favorites")
2020-06-09 09:52:52 +02:00
this.forceUpdateAll();
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStop () {
2020-06-09 09:52:52 +02:00
this.forceUpdateAll();
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
getSettingsPanel (collapseStates = {}) {
2021-03-20 19:04:57 +01:00
let settingsPanel;
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
collapseStates: collapseStates,
children: _ => {
let settingsItems = [];
for (let key in this.defaults.general) settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
type: "Switch",
plugin: this,
keys: ["general", key],
label: this.defaults.general[key].description,
value: this.settings.general[key]
}));
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
className: BDFDB.disCNS.dividerdefault + BDFDB.disCN.marginbottom8
}));
for (let key in this.defaults.exceptions) settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
title: this.defaults.exceptions[key].description,
className: BDFDB.disCN.marginbottom8,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ListInput, {
placeholder: "New Exception",
maxLength: this.defaults.exceptions[key].max,
items: this.settings.exceptions[key],
onChange: value => {
this.SettingsUpdated = true;
BDFDB.DataUtils.save(value, this, "exceptions", key);
}
})
}));
return settingsItems.flat(10);
}
});
2020-09-19 20:49:33 +02:00
}
2020-02-04 08:20:40 +01:00
2021-01-06 12:38:36 +01:00
onSettingsClosed () {
2020-09-19 20:49:33 +02:00
if (this.SettingsUpdated) {
delete this.SettingsUpdated;
this.forceUpdateAll();
}
}
2021-01-06 12:38:36 +01:00
forceUpdateAll () {
2020-09-19 20:49:33 +02:00
favorites = BDFDB.DataUtils.load(this, "favorites");
2021-05-25 10:35:29 +02:00
favorites = !BDFDB.ArrayUtils.is(favorites) ? [] : favorites;
2020-09-19 20:49:33 +02:00
this.setLanguages();
BDFDB.PatchUtils.forceAllUpdates(this);
BDFDB.MessageUtils.rerenderAll();
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
onMessageContextMenu (e) {
if (e.instance.props.message && e.instance.props.channel) {
let translated = translatedMessages[e.instance.props.message.id];
let hint = BDFDB.BDUtils.isPluginEnabled("MessageUtilities") ? BDFDB.BDUtils.getPlugin("MessageUtilities").getActiveShortcutString("__Translate_Message") : null;
let [children, index] = BDFDB.ContextMenuUtils.findItem(e.returnvalue, {id: ["pin", "unpin"]});
if (index == -1) [children, index] = BDFDB.ContextMenuUtils.findItem(e.returnvalue, {id: ["edit", "add-reaction", "quote"]});
children.splice(index > -1 ? index + 1 : 0, 0, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: translated ? this.labels.context_messageuntranslateoption : this.labels.context_messagetranslateoption,
2020-09-19 20:49:33 +02:00
id: BDFDB.ContextMenuUtils.createItemId(this.name, translated ? "untranslate-message" : "translate-message"),
hint: hint && (_ => {
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.MenuItems.MenuHint, {
hint: hint
});
}),
disabled: !translated && isTranslating,
2021-05-18 20:09:05 +02:00
action: _ => this.translateMessage(e.instance.props.message, e.instance.props.channel)
2020-09-19 20:49:33 +02:00
}));
this.injectSearchItem(e);
}
}
onNativeContextMenu (e) {
2020-05-20 10:25:47 +02:00
this.injectSearchItem(e);
}
2020-09-19 20:49:33 +02:00
onSlateContextMenu (e) {
this.injectSearchItem(e);
}
injectSearchItem (e) {
let text = document.getSelection().toString();
if (text) {
let translating, foundTranslation, foundInput, foundOutput;
let [children, index] = BDFDB.ContextMenuUtils.findItem(e.returnvalue, {id: ["devmode-copy-id", "search-google"], group: true});
children.splice(index > -1 ? index + 1 : 0, 0, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
children: BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
id: BDFDB.ContextMenuUtils.createItemId(this.name, "search-translation"),
disabled: isTranslating,
label: this.labels.context_googletranslateoption,
2020-09-19 20:49:33 +02:00
persisting: true,
action: event => {
let item = BDFDB.DOMUtils.getParent(BDFDB.dotCN.menuitem, event.target);
if (item) {
let createTooltip = _ => {
2021-01-28 14:45:45 +01:00
BDFDB.TooltipUtils.create(item, `${BDFDB.LanguageUtils.LibraryStrings.from} ${foundInput.name}:\n${text}\n\n${BDFDB.LanguageUtils.LibraryStrings.to} ${foundOutput.name}:\n${foundTranslation}`, {
2021-01-12 19:09:01 +01:00
type: "right",
2021-01-28 14:45:45 +01:00
color: "brand",
2021-01-12 19:09:01 +01:00
className: "googletranslate-tooltip"
});
2020-09-19 20:49:33 +02:00
};
if (foundTranslation && foundInput && foundOutput) {
if (document.querySelector(".googletranslate-tooltip")) {
BDFDB.ContextMenuUtils.close(e.instance);
2021-01-10 11:41:01 +01:00
BDFDB.DiscordUtils.openLink(this.getGoogleTranslatePageURL(foundInput.id, foundOutput.id, text));
2020-05-23 14:50:13 +02:00
}
2020-09-19 20:49:33 +02:00
else createTooltip();
}
else if (!translating) {
translating = true;
this.translateText(text, "context", (translation, input, output) => {
if (translation) {
foundTranslation = translation, foundInput = input, foundOutput = output;
createTooltip();
}
});
}
2020-05-23 14:50:13 +02:00
}
2019-12-09 15:56:53 +01:00
}
2020-09-19 20:49:33 +02:00
})
}));
}
}
onMessageOptionContextMenu (e) {
if (e.instance.props.message && e.instance.props.channel) {
let translated = !!translatedMessages[e.instance.props.message.id];
let [children, index] = BDFDB.ContextMenuUtils.findItem(e.returnvalue, {id: ["pin", "unpin"]});
children.splice(index + 1, 0, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
label: translated ? this.labels.context_messageuntranslateoption : this.labels.context_messagetranslateoption,
2020-09-19 20:49:33 +02:00
disabled: isTranslating,
id: BDFDB.ContextMenuUtils.createItemId(this.name, translated ? "untranslate-message" : "translate-message"),
icon: _ => {
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.MenuItems.MenuIcon, {
icon: translated ? translateIconUntranslate : translateIcon
});
},
2021-05-18 20:09:05 +02:00
action: _ => this.translateMessage(e.instance.props.message, e.instance.props.channel)
2020-09-19 20:49:33 +02:00
}));
}
2020-02-04 08:20:40 +01:00
}
2020-09-23 09:29:56 +02:00
onMessageOptionToolbar (e) {
if (e.instance.props.expanded && e.instance.props.message && e.instance.props.channel) {
let translated = !!translatedMessages[e.instance.props.message.id];
2021-05-18 20:09:05 +02:00
e.returnvalue.props.children.unshift();
e.returnvalue.props.children.unshift(BDFDB.ReactUtils.createElement(class extends BdApi.React.Component {
render() {
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
key: translated ? "untranslate-message" : "translate-message",
text: _ => translated ? _this.labels.context_messageuntranslateoption : _this.labels.context_messagetranslateoption,
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
className: BDFDB.disCN.messagetoolbarbutton,
onClick: _ => {
if (!isTranslating) _this.translateMessage(e.instance.props.message, e.instance.props.channel).then(_ => {
translated = !!translatedMessages[e.instance.props.message.id];
BDFDB.ReactUtils.forceUpdate(this);
});
},
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
className: BDFDB.disCN.messagetoolbaricon,
iconSVG: translated ? translateIconUntranslate : translateIcon
})
})
});
}
2020-09-23 09:29:56 +02:00
}));
}
}
2020-09-19 20:49:33 +02:00
processChannelTextAreaForm (e) {
BDFDB.PatchUtils.patch(this, e.instance, "handleSendMessage", {instead: e2 => {
2021-05-25 10:35:29 +02:00
if (this.isTranslationEnabled(e.instance.props.channel.id)) {
2020-09-19 20:49:33 +02:00
e2.stopOriginalMethodCall();
this.translateText(e2.methodArguments[0], "message", (translation, input, output) => {
2021-03-20 18:50:17 +01:00
translation = !translation ? e2.methodArguments[0] : (this.settings.general.sendOriginalMessage ? (e2.methodArguments[0] + "\n\n" + translation) : translation);
2020-09-19 20:49:33 +02:00
e2.originalMethod(translation);
});
return Promise.resolve({
shouldClear: true,
shouldRefocus: true
2020-05-14 17:33:14 +02:00
});
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
else return e2.callOriginalMethodAfterwards();
}}, {force: true, noCache: true});
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
processChannelEditorContainer (e) {
2021-05-25 10:35:29 +02:00
if (this.isTranslationEnabled(e.instance.props.channel.id) && isTranslating) e.instance.props.disabled = true;
2020-09-19 20:49:33 +02:00
}
processChannelTextAreaContainer (e) {
2021-03-20 18:50:17 +01:00
if (this.settings.general.addTranslateButton) {
2020-10-31 11:43:29 +01:00
let editor = BDFDB.ReactUtils.findChild(e.returnvalue, {name: "ChannelEditorContainer"});
if (editor && editor.props.type == BDFDB.DiscordConstants.TextareaTypes.NORMAL && !editor.props.disabled) {
2020-11-19 16:51:14 +01:00
let [children, index] = BDFDB.ReactUtils.findParent(e.returnvalue, {props: [["className", BDFDB.disCN.textareapickerbuttons]]});
2021-05-25 10:35:29 +02:00
if (index > -1 && children[index].props && children[index].props.children) children[index].props.children.unshift(BDFDB.ReactUtils.createElement(TranslateButtonComponent, {
channelId: e.instance.props.channel.id
}));
2020-09-19 20:49:33 +02:00
}
2020-02-11 09:46:53 +01:00
}
2019-12-21 02:24:30 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
processMessages (e) {
e.returnvalue.props.children.props.channelStream = [].concat(e.returnvalue.props.children.props.channelStream);
for (let i in e.returnvalue.props.children.props.channelStream) {
let message = e.returnvalue.props.children.props.channelStream[i].content;
if (message) {
if (BDFDB.ArrayUtils.is(message.attachments)) this.checkMessage(e.returnvalue.props.children.props.channelStream[i], message);
else if (BDFDB.ArrayUtils.is(message)) for (let j in message) {
let childMessage = message[j].content;
if (childMessage && BDFDB.ArrayUtils.is(childMessage.attachments)) this.checkMessage(message[j], childMessage);
}
2020-05-15 09:58:08 +02:00
}
}
}
2020-09-19 20:49:33 +02:00
checkMessage (stream, message) {
let translation = translatedMessages[message.id];
if (translation) stream.content.content = translation.content;
else if (oldMessages[message.id] && Object.keys(message).some(key => !BDFDB.equals(oldMessages[message.id][key], message[key]))) {
stream.content.content = oldMessages[message.id].content;
delete oldMessages[message.id];
}
2020-05-23 14:50:13 +02:00
}
2019-12-21 11:25:13 +01:00
2020-09-19 20:49:33 +02:00
processMessageContent (e) {
if (e.instance.props.message) {
let translation = translatedMessages[e.instance.props.message.id];
2021-05-03 20:30:07 +02:00
if (translation && translation.content) e.returnvalue.props.children.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
2021-01-28 14:45:45 +01:00
text: `${BDFDB.LanguageUtils.LibraryStrings.from}: ${this.getLanguageName(translation.input)}\n${BDFDB.LanguageUtils.LibraryStrings.to}: ${this.getLanguageName(translation.output)}`,
2020-09-19 20:49:33 +02:00
tooltipConfig: {style: "max-width: 400px"},
2021-05-03 20:30:07 +02:00
children: BDFDB.ReactUtils.createElement("span", {
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN.messagetimestamp, BDFDB.disCN.messagetimestampinline, BDFDB.disCN._googletranslateoptiontranslated),
children: BDFDB.ReactUtils.createElement("span", {
className: BDFDB.disCN.messageedited,
children: `(${this.labels.translated_watermark})`
})
2020-09-19 20:49:33 +02:00
})
}));
}
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
processEmbed (e) {
2021-01-13 18:54:21 +01:00
if (e.instance.props.embed && e.instance.props.embed.message_id) {
let translation = translatedMessages[e.instance.props.embed.message_id];
2021-05-03 20:30:07 +02:00
if (translation && Object.keys(translation.embeds).length) {
2020-09-19 20:49:33 +02:00
if (!e.returnvalue) e.instance.props.embed = Object.assign({}, e.instance.props.embed, {
rawDescription: translation.embeds[e.instance.props.embed.id],
originalDescription: e.instance.props.embed.originalDescription || e.instance.props.embed.rawDescription
});
else {
let [children, index] = BDFDB.ReactUtils.findParent(e.returnvalue, {props: [["className", BDFDB.disCN.embeddescription]]});
if (index > -1) children[index].props.children.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
2021-01-28 14:45:45 +01:00
text: `${BDFDB.LanguageUtils.LibraryStrings.from}: ${this.getLanguageName(translation.input)}\n${BDFDB.LanguageUtils.LibraryStrings.to}: ${this.getLanguageName(translation.output)}`,
2020-09-19 20:49:33 +02:00
tooltipConfig: {style: "max-width: 400px"},
2021-05-03 20:30:07 +02:00
children: BDFDB.ReactUtils.createElement("span", {
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN.messagetimestamp, BDFDB.disCN.messagetimestampinline, BDFDB.disCN._googletranslateoptiontranslated),
children: BDFDB.ReactUtils.createElement("span", {
className: BDFDB.disCN.messageedited,
children: `(${this.labels.translated_watermark})`
})
2020-09-19 20:49:33 +02:00
})
}));
}
}
else if (!e.returnvalue && e.instance.props.embed.originalDescription) {
e.instance.props.embed = Object.assign({}, e.instance.props.embed, {rawDescription: e.instance.props.embed.originalDescription});
delete e.instance.props.embed.originalDescription;
2020-02-04 08:20:40 +01:00
}
2019-10-24 21:30:55 +02:00
}
2020-02-04 08:20:40 +01:00
}
2021-05-25 10:35:29 +02:00
toggleTranslation (channelId) {
if (!this.isTranslationEnabled(channelId)) translationEnabledStates.push(this.settings.general.usePerChatTranslation ? channelId : "global");
else BDFDB.ArrayUtils.remove(translationEnabledStates, this.settings.general.usePerChatTranslation ? channelId : "global", true);
}
isTranslationEnabled (channelId) {
return translationEnabledStates.includes(this.settings.general.usePerChatTranslation ? channelId : "global");
}
2019-10-24 11:47:57 +02:00
2021-01-06 12:38:36 +01:00
setLanguages () {
2021-05-12 18:41:59 +02:00
if (this.settings.engines.translator == this.settings.engines.backup) {
this.settings.engines.backup = Object.keys(translationEngines).filter(n => n != this.settings.engines.translator)[0];
BDFDB.DataUtils.save(this.settings.engines, this, "engines");
}
2021-05-15 20:55:12 +02:00
let engine = translationEngines[this.settings.engines.translator] || {};
let backup = translationEngines[this.settings.engines.backup] || {};
let languageIds = [].concat(engine.languages, backup.languages).flat(10).filter(n => n);
2020-09-19 20:49:33 +02:00
languages = BDFDB.ObjectUtils.deepAssign(
2021-05-15 20:55:12 +02:00
!engine.auto && !backup.auto ? {} : {
2020-09-19 20:49:33 +02:00
auto: {
2021-05-12 18:41:59 +02:00
auto: true,
2020-09-19 20:49:33 +02:00
name: "Auto",
id: "auto"
}
2020-06-05 20:03:21 +02:00
},
2020-09-19 20:49:33 +02:00
BDFDB.ObjectUtils.filter(BDFDB.LanguageUtils.languages, lang => languageIds.includes(lang.id)),
{
binary: {
2021-05-12 18:41:59 +02:00
special: true,
2020-09-19 20:49:33 +02:00
name: "Binary",
id: "binary"
},
braille: {
2021-05-12 18:41:59 +02:00
special: true,
2020-09-19 20:49:33 +02:00
name: "Braille 6-dot",
id: "braille"
},
morse: {
2021-05-12 18:41:59 +02:00
special: true,
2020-09-19 20:49:33 +02:00
name: "Morse",
id: "morse"
}
2020-06-05 20:03:21 +02:00
}
2020-09-19 20:49:33 +02:00
);
2021-05-25 10:35:29 +02:00
for (let id in languages) languages[id].fav = favorites.includes(id) ? 0 : 1;
2020-09-19 20:49:33 +02:00
languages = BDFDB.ObjectUtils.sort(languages, "fav");
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
getLanguageChoice (direction, place) {
this.setLanguages();
let type = place === undefined ? direction : direction.toLowerCase() + place.charAt(0).toUpperCase() + place.slice(1).toLowerCase();
2021-03-20 18:50:17 +01:00
let choice = this.settings.choices[type];
2020-09-19 20:49:33 +02:00
choice = languages[choice] ? choice : Object.keys(languages)[0];
choice = type.indexOf("output") > -1 && choice == "auto" ? "en" : choice;
return choice;
2019-09-27 09:48:32 +02:00
}
2020-09-19 20:49:33 +02:00
translateMessage (message, channel) {
2021-05-18 20:09:05 +02:00
return new Promise(callback => {
if (!message) return callback(null);
if (translatedMessages[message.id]) {
delete translatedMessages[message.id];
BDFDB.MessageUtils.rerenderAll(true);
callback(false);
}
else {
let content = message.content || "";
for (let embed of message.embeds) content += ("\n__________________ __________________ __________________\n" + embed.rawDescription);
this.translateText(content, "context", (translation, input, output) => {
if (translation) {
oldMessages[message.id] = new BDFDB.DiscordObjects.Message(message);
let strings = translation.split(/\n{0,1}__________________ __________________ __________________\n{0,1}/);
let content = strings.shift().trim(), embeds = {};
for (let i in message.embeds) {
message.embeds[i].message_id = message.id;
embeds[message.embeds[i].id] = (strings.shift() || message.embeds[i].rawDescription).trim();
}
translatedMessages[message.id] = {content, embeds, input, output};
BDFDB.MessageUtils.rerenderAll(true);
2020-09-19 20:49:33 +02:00
}
2021-05-18 20:09:05 +02:00
callback(true);
});
}
});
2019-12-09 15:56:53 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
translateText (text, type, callback) {
2021-05-12 18:41:59 +02:00
let toast = null, toastInterval, finished = false, finishTranslation = translation => {
2020-09-19 20:49:33 +02:00
isTranslating = false;
2021-01-26 21:14:48 +01:00
if (toast) toast.close();
2021-05-12 18:41:59 +02:00
BDFDB.TimeUtils.clear(toastInterval);
if (finished) return;
finished = true;
if (translation) translation = this.addExceptions(translation, excepts);
2020-09-19 20:49:33 +02:00
callback(translation == text ? "" : translation, input, output);
};
2020-10-31 11:43:29 +01:00
let [newText, excepts, translate] = this.removeExceptions(text.trim(), type);
2020-09-19 20:49:33 +02:00
let input = Object.assign({}, languages[this.getLanguageChoice("input", type)]);
let output = Object.assign({}, languages[this.getLanguageChoice("output", type)]);
2020-12-14 10:43:32 +01:00
if (translate && input.id != output.id) {
let specialCase = this.checkForSpecialCase(newText, input);
if (specialCase) {
input.name = specialCase.name;
switch (specialCase.id) {
2020-10-31 11:43:29 +01:00
case "binary": newText = this.binary2string(newText); break;
case "braille": newText = this.braille2string(newText); break;
case "morse": newText = this.morse2string(newText); break;
2020-09-19 20:49:33 +02:00
}
2020-02-04 08:20:40 +01:00
}
2021-05-12 18:41:59 +02:00
if (output.special) {
2020-09-19 20:49:33 +02:00
switch (output.id) {
2020-10-31 11:43:29 +01:00
case "binary": newText = this.string2binary(newText); break;
case "braille": newText = this.string2braille(newText); break;
case "morse": newText = this.string2morse(newText); break;
2020-09-19 20:49:33 +02:00
}
2020-10-31 11:43:29 +01:00
finishTranslation(newText);
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
else {
2021-05-12 18:41:59 +02:00
const startTranslating = engine => {
2020-09-19 20:49:33 +02:00
isTranslating = true;
2021-05-12 18:41:59 +02:00
if (toast) toast.close();
BDFDB.TimeUtils.clear(toastInterval);
let loadingString = `${this.labels.toast_translating} (${translationEngines[engine].name}) - ${BDFDB.LanguageUtils.LibraryStrings.please_wait}`;
let currentLoadingString = loadingString;
toast = BDFDB.NotificationUtils.toast(loadingString, {
timeout: 0,
position: "center",
onClose: _ => BDFDB.TimeUtils.clear(toastInterval)
});
toastInterval = BDFDB.TimeUtils.interval((_, count) => {
if (count > 40) {
finishTranslation("");
BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed} (${translationEngines[engine].name}) - ${this.labels.toast_translating_tryanother}`, {
type: "danger",
position: "center"
});
}
else {
currentLoadingString = currentLoadingString.endsWith(".....") ? loadingString : currentLoadingString + ".";
toast.update(currentLoadingString);
}
}, 500);
};
if (this.validTranslator(this.settings.engines.translator, input, output, specialCase)) {
startTranslating(this.settings.engines.translator);
this[translationEngines[this.settings.engines.translator].funcName].apply(this, [{input, output, text: newText, specialCase, engine: translationEngines[this.settings.engines.translator]}, translation => {
if (!translation && this.validTranslator(this.settings.engines.backup, input, output, specialCase)) {
startTranslating(this.settings.engines.backup);
this[translationEngines[this.settings.engines.backup].funcName].apply(this, [{input, output, text: newText, specialCase, engine: translationEngines[this.settings.engines.backup]}, finishTranslation]);
}
else finishTranslation(translation);
}]);
}
else if (this.validTranslator(this.settings.engines.backup, input, output, specialCase)) {
startTranslating(this.settings.engines.backup);
this[translationEngines[this.settings.engines.backup].funcName].apply(this, [{input, output, text: newText, specialCase, engine: translationEngines[this.settings.engines.backup]}, finishTranslation]);
}
2021-05-18 20:09:05 +02:00
else finishTranslation();
2020-02-04 08:20:40 +01:00
}
2019-12-09 15:56:53 +01:00
}
2020-09-19 20:49:33 +02:00
else finishTranslation();
2018-10-11 10:21:26 +02:00
}
2020-09-19 20:49:33 +02:00
2021-05-12 18:41:59 +02:00
validTranslator (key, input, output, specialCase) {
return translationEngines[key] && typeof this[translationEngines[key].funcName] == "function" && (specialCase || input.auto && translationEngines[key].auto || translationEngines[key].languages.includes(input.id) && translationEngines[key].languages.includes(output.id));
}
2021-05-12 14:33:47 +02:00
googleApiTranslate (data, callback) {
BDFDB.LibraryRequires.request(`https://translate.googleapis.com/translate_a/single?client=gtx&sl=${data.input.id}&tl=${data.output.id}&dt=t&dj=1&source=input&q=${encodeURIComponent(data.text)}`, (error, response, body) => {
if (!error && body && response.statusCode == 200) {
try {
body = JSON.parse(body);
if (!data.specialCase && body.src && body.src && languages[body.src]) {
data.input.name = languages[body.src].name;
data.input.ownlang = languages[body.src].ownlang;
}
callback(body.sentences.map(n => n && n.trans).filter(n => n).join(""));
}
catch (err) {callback("");}
2020-02-28 15:01:54 +01:00
}
2021-05-12 14:33:47 +02:00
else {
if (response.statusCode == 429) BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Request Limit per Hour reached.`, {
type: "danger",
position: "center"
});
else BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Translation Server might be down.`, {
type: "danger",
position: "center"
});
callback("");
2020-09-19 20:49:33 +02:00
}
});
}
2021-05-12 14:33:47 +02:00
deepLTranslate (data, callback) {
2021-05-12 18:41:59 +02:00
BDFDB.LibraryRequires.request(`https://api-free.deepl.com/v2/translate?auth_key=75cc2f40-fdae-14cd-7242-6a384e2abb9c:fx&text=${encodeURIComponent(data.text)}${data.input.auto ? "" : `&source_lang=${data.input.id}`}&target_lang=${data.output.id}`, (error, response, body) => {
2021-05-12 14:33:47 +02:00
if (!error && body && response.statusCode == 200) {
2020-02-04 08:20:40 +01:00
try {
2021-05-12 14:33:47 +02:00
body = JSON.parse(body);
if (!data.specialCase && body.translations[0] && body.translations[0].detected_source_language && languages[body.translations[0].detected_source_language.toLowerCase()]) {
data.input.name = languages[body.translations[0].detected_source_language.toLowerCase()].name;
data.input.ownlang = languages[body.translations[0].detected_source_language.toLowerCase()].ownlang;
2020-02-04 08:20:40 +01:00
}
2021-05-12 14:33:47 +02:00
callback(body.translations.map(n => n && n.text).filter(n => n).join(""));
2020-02-04 08:20:40 +01:00
}
catch (err) {callback("");}
}
else {
2021-05-18 12:07:15 +02:00
if (response.statusCode == 429 || response.statusCode == 456) BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Request Limit reached.`, {
2021-05-12 14:33:47 +02:00
type: "danger",
position: "center"
});
else if (response.statusCode == 403) BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. API-Key outdated.`, {
2021-01-26 21:14:48 +01:00
type: "danger",
2021-01-28 14:11:00 +01:00
position: "center"
2021-01-26 21:14:48 +01:00
});
else BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Translation Server might be down.`, {
type: "danger",
2021-01-28 14:11:00 +01:00
position: "center"
2021-01-26 21:14:48 +01:00
});
2020-02-04 08:20:40 +01:00
callback("");
}
});
2020-09-19 20:49:33 +02:00
}
iTranslateTranslate (data, callback) {
let translate = _ => {
2021-05-12 14:33:47 +02:00
BDFDB.LibraryRequires.request.post({
url: "https://web-api.itranslateapp.com/v3/texts/translate",
2020-09-19 20:49:33 +02:00
headers: {
"API-KEY": data.engine.APIkey
},
body: JSON.stringify({
source: {
dialect: data.input.id,
text: data.text
},
target: {
dialect: data.output.id
}
})
2021-05-12 14:33:47 +02:00
}, (error, response, body) => {
2020-09-19 20:49:33 +02:00
if (!error && response && response.statusCode == 200) {
try {
2021-05-12 14:33:47 +02:00
body = JSON.parse(body);
if (!data.specialCase && body.source && body.source.dialect && languages[body.source.dialect]) {
data.input.name = languages[body.source.dialect].name;
data.input.ownlang = languages[body.source.dialect].ownlang;
2020-09-19 20:49:33 +02:00
}
2021-05-12 14:33:47 +02:00
callback(body.target.text);
2020-09-19 20:49:33 +02:00
}
catch (err) {callback("");}
}
else {
2021-05-12 14:33:47 +02:00
if (response.statusCode == 429) BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Request Limit reached.`, {
type: "danger",
position: "center"
});
else if (response.statusCode == 403) BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. API-Key outdated.`, {
type: "danger",
position: "center"
});
else BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Translation Server might be down.`, {
2021-01-26 21:14:48 +01:00
type: "danger",
2021-01-28 14:11:00 +01:00
position: "center"
2021-01-26 21:14:48 +01:00
});
2020-09-19 20:49:33 +02:00
callback("");
}
});
};
if (data.engine.APIkey) translate();
2021-05-12 14:33:47 +02:00
else BDFDB.LibraryRequires.request("https://www.itranslate.com/js/webapp/main.js", {gzip: true}, (error, response, body) => {
if (!error && body) {
let APIkey = /var API_KEY = "(.+)"/.exec(body);
2020-09-19 20:49:33 +02:00
if (APIkey) {
data.engine.APIkey = APIkey[1];
translate();
2019-12-10 13:21:59 +01:00
}
2020-09-19 20:49:33 +02:00
else callback("");
2019-12-10 13:21:59 +01:00
}
2020-02-04 08:20:40 +01:00
else callback("");
2020-09-19 20:49:33 +02:00
});
}
yandexTranslate (data, callback) {
2021-05-12 18:41:59 +02:00
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.auto ? data.output.id : (data.input.id + "-" + data.output.id)}&options=1`, (error, response, body) => {
2021-05-12 14:33:47 +02:00
if (!error && body && response.statusCode == 200) {
body = BDFDB.DOMUtils.create(body);
let translation = body.querySelector("text");
let detected = body.querySelector("detected");
2020-09-19 20:49:33 +02:00
if (translation && detected) {
let detectedLang = detected.getAttribute("lang");
2020-12-14 10:43:32 +01:00
if (!data.specialCase && detectedLang && languages[detectedLang]) {
2020-09-19 20:49:33 +02:00
data.input.name = languages[detectedLang].name;
data.input.ownlang = languages[detectedLang].ownlang;
}
callback(translation.innerText);
}
2020-06-26 22:42:48 +02:00
else callback("");
2020-12-14 10:43:32 +01:00
}
2021-05-12 14:33:47 +02:00
if (body && body.indexOf('code="408"') > -1) {
BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Monthly Request Limit reached.`, {
2021-01-26 21:14:48 +01:00
type: "danger",
2021-01-28 14:11:00 +01:00
position: "center"
2021-01-26 21:14:48 +01:00
});
2020-12-14 10:43:32 +01:00
callback("");
2020-06-26 22:42:48 +02:00
}
2020-09-19 20:49:33 +02:00
else {
2021-05-12 14:33:47 +02:00
BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Translation Server down or API-Key outdated.`, {
2021-01-26 21:14:48 +01:00
type: "danger",
2021-01-28 14:11:00 +01:00
position: "center"
2021-01-26 21:14:48 +01:00
});
2020-09-19 20:49:33 +02:00
callback("");
}
});
}
papagoTranslate (data, callback) {
BDFDB.LibraryRequires.request.post({
url: "https://openapi.naver.com/v1/papago/n2mt",
2020-09-19 20:49:33 +02:00
form: {
source: data.input.id,
target: data.output.id,
text: data.text
},
headers: {
"X-Naver-Client-Id": "kUNGxtAmTJQFbaFehdjk",
"X-Naver-Client-Secret": "zC70k3VhpM"
}
2021-05-12 14:33:47 +02:00
}, (error, response, body) => {
if (!error && body && response.statusCode == 200) {
2020-09-19 20:49:33 +02:00
try {
2021-05-12 14:33:47 +02:00
let message = (JSON.parse(body) || {}).message;
if (message && message.body && message.body.translatedText) callback(message.body.translatedText);
2020-09-19 20:49:33 +02:00
else callback("");
}
catch (err) {callback("");}
}
else {
2021-04-07 16:36:21 +02:00
if (response.statusCode == 429) BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Request Limit per Hour is reached.`, {
type: "danger",
position: "center"
});
else BDFDB.NotificationUtils.toast(`${this.labels.toast_translating_failed}. ${this.labels.toast_translating_tryanother}. Translation Server is down or API-key outdated.`, {
2021-01-26 21:14:48 +01:00
type: "danger",
2021-01-28 14:11:00 +01:00
position: "center"
2021-01-26 21:14:48 +01:00
});
2020-09-19 20:49:33 +02:00
callback("");
}
});
}
2020-02-04 08:20:40 +01:00
2020-09-19 20:49:33 +02:00
checkForSpecialCase (text, input) {
2021-05-12 18:41:59 +02:00
if (input.special) return input;
else if (input.auto) {
2020-09-19 20:49:33 +02:00
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-12-10 13:21:59 +01:00
}
2020-09-19 20:49:33 +02:00
return null;
2019-04-16 00:30:33 +02:00
}
2020-09-19 20:49:33 +02:00
string2binary (string) {
let binary = "";
for (let character of string) binary += parseInt(character.charCodeAt(0).toString(2)).toPrecision(8).split(".").reverse().join("").toString() + " ";
return binary;
}
2019-04-16 00:30:33 +02:00
2020-09-19 20:49:33 +02:00
string2braille (string) {
let braille = "";
for (let character of string) braille += brailleConverter[character.toLowerCase()] ? brailleConverter[character.toLowerCase()] : character;
return braille;
}
2019-04-16 00:30:33 +02:00
2020-09-19 20:49:33 +02:00
string2morse (string) {
string = string.replace(/ /g, "%%%%%%%%%%");
let morse = "";
for (let character of string) morse += (morseConverter[character.toLowerCase()] ? morseConverter[character.toLowerCase()] : character) + " ";
morse = morse.split("\n");
for (let i in morse) morse[i] = morse[i].trim();
return morse.join("\n").replace(/% % % % % % % % % % /g, "/ ");
}
2019-04-16 00:30:33 +02:00
2020-09-19 20:49:33 +02:00
binary2string (binary) {
let string = "";
binary = binary.replace(/\n/g, "00001010").replace(/\r/g, "00001101").replace(/\t/g, "00001001").replace(/\s/g, "");
if (/^[0-1]*$/.test(binary)) {
2021-01-28 14:45:45 +01:00
let eightDigits = "";
2020-09-19 20:49:33 +02:00
let counter = 0;
for (let digit of binary) {
2021-01-28 14:45:45 +01:00
eightDigits += digit;
2020-09-19 20:49:33 +02:00
counter++;
if (counter > 7) {
2021-01-28 14:45:45 +01:00
string += String.fromCharCode(parseInt(eightDigits, 2).toString(10));
eightDigits = "";
2020-09-19 20:49:33 +02:00
counter = 0;
}
2020-02-04 08:20:40 +01:00
}
2019-04-16 00:30:33 +02:00
}
2021-01-26 21:14:48 +01:00
else BDFDB.NotificationUtils.toast("Invalid binary format. Only use 0s and 1s.", {
type: "danger",
2021-01-28 14:11:00 +01:00
position: "center"
2021-01-26 21:14:48 +01:00
});
2020-09-19 20:49:33 +02:00
return string;
2019-04-16 00:30:33 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
braille2string (braille) {
let string = "";
for (let character of braille) string += brailleConverter[character.toLowerCase()] ? brailleConverter[character.toLowerCase()] : character;
return string;
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
morse2string (morse) {
let 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 += morseConverter[characterstr] ? morseConverter[characterstr] : characterstr;
string += " ";
}
return string.trim();
2018-10-11 10:21:26 +02:00
}
2020-02-04 08:20:40 +01:00
2020-10-31 11:43:29 +01:00
addExceptions (string, excepts) {
for (let count in excepts) {
2021-03-20 18:50:17 +01:00
let exception = BDFDB.ArrayUtils.is(this.settings.exceptions.wordStart) && this.settings.exceptions.wordStart.some(n => excepts[count].indexOf(n) == 0) ? excepts[count].slice(1) : excepts[count];
2021-02-04 14:45:34 +01:00
let newString = string.replace(new RegExp(BDFDB.StringUtils.regEscape(`{{${count}}}`)), exception);
if (newString == string) string = newString + " " + exception;
else string = newString;
}
2020-09-19 20:49:33 +02:00
return string;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
removeExceptions (string, type) {
2020-10-31 11:43:29 +01:00
let excepts = {}, newString = [], count = 0;
2020-09-19 20:49:33 +02:00
if (type == "context") {
let text = [], i = 0;
string.split("").forEach(chara => {
if (chara == "<" && text[i]) i++;
text[i] = text[i] ? text[i] + chara : chara;
if (chara == ">") i++;
});
for (let j in text) {
if (text[j].indexOf("<") == 0) {
2021-02-04 14:45:34 +01:00
newString.push(`{{${count}}}`);
2020-10-31 11:43:29 +01:00
excepts[count] = text[j];
2020-09-19 20:49:33 +02:00
count++;
}
else newString.push(text[j]);
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
}
else {
2021-03-20 18:50:17 +01:00
let usedExceptions = BDFDB.ArrayUtils.is(this.settings.exceptions.wordStart) ? this.settings.exceptions.wordStart : [];
2020-09-19 20:49:33 +02:00
string.split(" ").forEach(word => {
2021-03-22 10:05:26 +01:00
if (word.indexOf("<@!") == 0 || word.indexOf("<#") == 0 || word.indexOf(":") == 0 || word.indexOf("<:") == 0 || word.indexOf("<a:") == 0 || word.indexOf("@") == 0 || word.indexOf("#") == 0 || usedExceptions.some(n => word.indexOf(n) == 0 && word.length > 1)) {
2021-02-04 14:45:34 +01:00
newString.push(`{{${count}}}`);
2020-10-31 11:43:29 +01:00
excepts[count] = word;
2020-09-19 20:49:33 +02:00
count++;
}
else newString.push(word);
});
}
2020-10-31 11:43:29 +01:00
return [newString.join(" "), excepts, newString.length-count != 0];
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
getGoogleTranslatePageURL (input, output, text) {
return `https://translate.google.com/#${BDFDB.LanguageUtils.languages[input] ? input : "auto"}/${output}/${encodeURIComponent(text)}`;
2020-09-19 20:49:33 +02:00
}
2020-06-09 09:52:52 +02:00
2020-09-19 20:49:33 +02:00
getLanguageName (language) {
if (language.name.startsWith("Discord")) return language.name.slice(0, -1) + (language.ownlang && languages[language.id].name != language.ownlang ? ` / ${language.ownlang}` : "") + ")";
else return language.name + (language.ownlang && language.name != language.ownlang ? ` / ${language.ownlang}` : "");
2020-02-04 08:20:40 +01:00
}
2020-07-26 17:02:25 +02:00
2021-01-06 12:38:36 +01:00
setLabelsByLanguage () {
2020-09-19 20:49:33 +02:00
switch (BDFDB.LanguageUtils.getLanguage().id) {
case "bg": // Bulgarian
return {
context_googletranslateoption: "Търсене превод",
context_messagetranslateoption: "Превод на съобщението",
context_messageuntranslateoption: "Превод на съобщението",
popout_translateoption: "Превод",
popout_untranslateoption: "Непревод",
2021-01-26 21:14:48 +01:00
toast_translating: "Превод",
toast_translating_failed: "Преводът не бе успешен",
toast_translating_tryanother: "Опитайте друг преводач",
translated_watermark: "преведено"
};
case "da": // Danish
return {
context_googletranslateoption: "Søg oversættelse",
context_messagetranslateoption: "Oversæt besked",
context_messageuntranslateoption: "Ikke-oversat besked",
popout_translateoption: "Oversætte",
popout_untranslateoption: "Untranslate",
2021-01-26 21:14:48 +01:00
toast_translating: "Oversætter",
toast_translating_failed: "Kunne ikke oversætte",
toast_translating_tryanother: "Prøv en anden oversætter",
translated_watermark: "oversat"
};
case "de": // German
return {
context_googletranslateoption: "Übersetzung suchen",
context_messagetranslateoption: "Nachricht übersetzen",
context_messageuntranslateoption: "Nachricht unübersetzen",
popout_translateoption: "Übersetzen",
popout_untranslateoption: "Unübersetzen",
2021-01-26 21:14:48 +01:00
toast_translating: "Übersetzen",
toast_translating_failed: "Übersetzung fehlgeschlagen",
toast_translating_tryanother: "Versuch einen anderen Übersetzer",
translated_watermark: "übersetzt"
};
case "el": // Greek
return {
context_googletranslateoption: "Αναζήτηση μετάφρασης",
context_messagetranslateoption: "Μετάφραση μηνύματος",
context_messageuntranslateoption: "Μη μετάφραση μηνύματος",
popout_translateoption: "Μεταφράζω",
popout_untranslateoption: "Μη μετάφραση",
2021-01-26 21:14:48 +01:00
toast_translating: "Μετάφραση",
toast_translating_failed: "Αποτυχία μετάφρασης",
toast_translating_tryanother: "Δοκιμάστε έναν άλλο Μεταφραστή",
translated_watermark: "μεταφρασμένο"
};
case "es": // Spanish
return {
context_googletranslateoption: "Buscar traducción",
context_messagetranslateoption: "Traducir mensaje",
context_messageuntranslateoption: "Mensaje sin traducir",
popout_translateoption: "Traducir",
popout_untranslateoption: "No traducir",
2021-01-26 21:14:48 +01:00
toast_translating: "Traductorio",
toast_translating_failed: "No se pudo traducir",
toast_translating_tryanother: "Prueba con otro traductor",
translated_watermark: "traducido"
};
case "fi": // Finnish
return {
context_googletranslateoption: "Hae käännöstä",
context_messagetranslateoption: "Käännä viesti",
context_messageuntranslateoption: "Käännä viesti",
popout_translateoption: "Kääntää",
popout_untranslateoption: "Käännä",
2021-01-26 21:14:48 +01:00
toast_translating: "Kääntäminen",
toast_translating_failed: "Käännös epäonnistui",
toast_translating_tryanother: "Kokeile toista kääntäjää",
translated_watermark: "käännetty"
};
case "fr": // French
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Recherche de traduction",
context_messagetranslateoption: "Traduire le message",
context_messageuntranslateoption: "Message non traduit",
popout_translateoption: "Traduire",
popout_untranslateoption: "Non traduit",
2021-01-26 21:14:48 +01:00
toast_translating: "Traduction en cours",
toast_translating_failed: "Échec de la traduction",
toast_translating_tryanother: "Essayez un autre traducteur",
translated_watermark: "traduit"
2020-09-19 20:49:33 +02:00
};
case "hr": // Croatian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Pretraži prijevod",
context_messagetranslateoption: "Prevedi poruku",
context_messageuntranslateoption: "Prevedi poruku",
popout_translateoption: "Prevedi",
popout_untranslateoption: "Neprevedi",
2021-01-26 21:14:48 +01:00
toast_translating: "Prevođenje",
toast_translating_failed: "Prijevod nije uspio",
toast_translating_tryanother: "Pokušajte s drugim prevoditeljem",
translated_watermark: "prevedeno"
2020-09-19 20:49:33 +02:00
};
case "hu": // Hungarian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Keresés a fordításban",
context_messagetranslateoption: "Üzenet lefordítása",
context_messageuntranslateoption: "Az üzenet lefordítása",
popout_translateoption: "fordít",
popout_untranslateoption: "Fordítás le",
2021-01-26 21:14:48 +01:00
toast_translating: "Fordítás",
toast_translating_failed: "Nem sikerült lefordítani",
toast_translating_tryanother: "Próbálkozzon másik fordítóval",
translated_watermark: "lefordított"
2020-09-19 20:49:33 +02:00
};
case "it": // Italian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Cerca traduzione",
context_messagetranslateoption: "Traduci messaggio",
context_messageuntranslateoption: "Annulla traduzione messaggio",
popout_translateoption: "Tradurre",
popout_untranslateoption: "Non tradurre",
2021-01-26 21:14:48 +01:00
toast_translating: "Tradurre",
toast_translating_failed: "Impossibile tradurre",
toast_translating_tryanother: "Prova un altro traduttore",
translated_watermark: "tradotto"
2020-09-19 20:49:33 +02:00
};
case "ja": // Japanese
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "翻訳を検索",
context_messagetranslateoption: "メッセージの翻訳",
context_messageuntranslateoption: "メッセージの翻訳解除",
popout_translateoption: "翻訳する",
popout_untranslateoption: "翻訳しない",
2021-01-26 21:14:48 +01:00
toast_translating: "翻訳",
toast_translating_failed: "翻訳に失敗しました",
toast_translating_tryanother: "別の翻訳者を試す",
translated_watermark: "翻訳済み"
2020-09-19 20:49:33 +02:00
};
case "ko": // Korean
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "번역 검색",
context_messagetranslateoption: "메시지 번역",
context_messageuntranslateoption: "메시지 번역 취소",
popout_translateoption: "옮기다",
popout_untranslateoption: "번역 취소",
2021-01-26 21:14:48 +01:00
toast_translating: "번역 중",
toast_translating_failed: "번역하지 못했습니다.",
toast_translating_tryanother: "다른 번역기 시도",
translated_watermark: "번역"
2020-09-19 20:49:33 +02:00
};
case "lt": // Lithuanian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Paieškos vertimas",
context_messagetranslateoption: "Versti pranešimą",
context_messageuntranslateoption: "Išversti pranešimą",
popout_translateoption: "Išversti",
popout_untranslateoption: "Neišversti",
2021-01-26 21:14:48 +01:00
toast_translating: "Vertimas",
toast_translating_failed: "Nepavyko išversti",
toast_translating_tryanother: "Išbandykite kitą vertėją",
translated_watermark: "išverstas"
2020-09-19 20:49:33 +02:00
};
case "nl": // Dutch
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Zoek vertaling",
context_messagetranslateoption: "Bericht vertalen",
context_messageuntranslateoption: "Bericht onvertalen",
popout_translateoption: "Vertalen",
popout_untranslateoption: "Onvertalen",
2021-01-26 21:14:48 +01:00
toast_translating: "Vertalen",
toast_translating_failed: "Kan niet vertalen",
toast_translating_tryanother: "Probeer een andere vertaler",
translated_watermark: "vertaald"
2020-09-19 20:49:33 +02:00
};
case "no": // Norwegian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Søk i oversettelse",
context_messagetranslateoption: "Oversett melding",
context_messageuntranslateoption: "Ikke oversett melding",
popout_translateoption: "Oversette",
popout_untranslateoption: "Ikke oversett",
2021-01-26 21:14:48 +01:00
toast_translating: "Oversetter",
toast_translating_failed: "Kunne ikke oversette",
toast_translating_tryanother: "Prøv en annen oversetter",
translated_watermark: "oversatt"
2020-09-19 20:49:33 +02:00
};
case "pl": // Polish
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Wyszukaj tłumaczenie",
context_messagetranslateoption: "Przetłumacz wiadomość",
context_messageuntranslateoption: "Nieprzetłumacz wiadomość",
popout_translateoption: "Tłumaczyć",
popout_untranslateoption: "Nie przetłumacz",
2021-01-26 21:14:48 +01:00
toast_translating: "Tłumaczenie",
toast_translating_failed: "Nie udało się przetłumaczyć",
toast_translating_tryanother: "Wypróbuj innego tłumacza",
translated_watermark: "przetłumaczony"
2020-09-19 20:49:33 +02:00
};
case "pt-BR": // Portuguese (Brazil)
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Tradução de pesquisa",
context_messagetranslateoption: "Traduzir mensagem",
context_messageuntranslateoption: "Mensagem não traduzida",
popout_translateoption: "Traduzir",
popout_untranslateoption: "Não traduzido",
2021-01-26 21:14:48 +01:00
toast_translating: "Traduzindo",
toast_translating_failed: "Falha ao traduzir",
toast_translating_tryanother: "Tente outro tradutor",
translated_watermark: "traduzido"
2020-09-19 20:49:33 +02:00
};
case "ro": // Romanian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Căutare traducere",
context_messagetranslateoption: "Traduceți mesajul",
context_messageuntranslateoption: "Untraduceți mesajul",
popout_translateoption: "Traduceți",
popout_untranslateoption: "Netradus",
2021-01-26 21:14:48 +01:00
toast_translating: "Traducere",
toast_translating_failed: "Nu s-a putut traduce",
toast_translating_tryanother: "Încercați un alt traducător",
translated_watermark: "tradus"
2020-09-19 20:49:33 +02:00
};
case "ru": // Russian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Искать перевод",
context_messagetranslateoption: "Перевести сообщение",
context_messageuntranslateoption: "Непереведенное сообщение",
popout_translateoption: "Переведите",
popout_untranslateoption: "Неперевести",
2021-01-26 21:14:48 +01:00
toast_translating: "Идет перевод",
toast_translating_failed: "Не удалось перевести",
toast_translating_tryanother: "Попробуйте другой переводчик",
translated_watermark: "переведено"
2020-09-19 20:49:33 +02:00
};
case "sv": // Swedish
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Sök översättning",
context_messagetranslateoption: "Översätt meddelande",
context_messageuntranslateoption: "Untranslate meddelande",
popout_translateoption: "Översätt",
popout_untranslateoption: "Untranslate",
2021-01-26 21:14:48 +01:00
toast_translating: "Översätter",
toast_translating_failed: "Det gick inte att översätta",
toast_translating_tryanother: "Prova en annan översättare",
translated_watermark: "översatt"
2020-09-19 20:49:33 +02:00
};
case "th": // Thai
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "ค้นหาคำแปล",
context_messagetranslateoption: "แปลข้อความ",
context_messageuntranslateoption: "ยกเลิกการแปลข้อความ",
popout_translateoption: "แปลภาษา",
popout_untranslateoption: "ไม่แปล",
2021-01-26 21:14:48 +01:00
toast_translating: "กำลังแปล",
toast_translating_failed: "แปลไม่สำเร็จ",
toast_translating_tryanother: "ลองใช้นักแปลคนอื่น",
translated_watermark: "แปล"
2020-09-19 20:49:33 +02:00
};
case "tr": // Turkish
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Çeviri ara",
context_messagetranslateoption: "Mesajı Çevir",
context_messageuntranslateoption: "Çeviriyi Kaldır Mesajı",
popout_translateoption: "Çevirmek",
popout_untranslateoption: "Çevirmeyi kaldır",
2021-01-26 21:14:48 +01:00
toast_translating: "Çeviri",
toast_translating_failed: "Tercüme edilemedi",
toast_translating_tryanother: "Başka bir Çevirmen deneyin",
translated_watermark: "tercüme"
2020-09-19 20:49:33 +02:00
};
case "uk": // Ukrainian
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Пошук перекладу",
context_messagetranslateoption: "Перекласти повідомлення",
context_messageuntranslateoption: "Неперекладене повідомлення",
popout_translateoption: "Перекласти",
popout_untranslateoption: "Неперекласти",
2021-01-26 21:14:48 +01:00
toast_translating: "Переклад",
toast_translating_failed: "Не вдалося перекласти",
toast_translating_tryanother: "Спробуйте іншого перекладача",
translated_watermark: "переклав"
2020-09-19 20:49:33 +02:00
};
case "vi": // Vietnamese
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "Tìm kiếm bản dịch",
context_messagetranslateoption: "Dịch tin nhắn",
context_messageuntranslateoption: "Thư chưa dịch",
popout_translateoption: "Phiên dịch",
popout_untranslateoption: "Chưa dịch",
2021-01-26 21:14:48 +01:00
toast_translating: "Phiên dịch",
toast_translating_failed: "Không dịch được",
toast_translating_tryanother: "Thử một Trình dịch khác",
translated_watermark: "đã dịch"
2020-09-19 20:49:33 +02:00
};
2021-01-15 17:54:22 +01:00
case "zh-CN": // Chinese (China)
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "搜索翻译",
2021-01-15 17:56:14 +01:00
context_messagetranslateoption: "翻译消息",
context_messageuntranslateoption: "取消翻译消息",
popout_translateoption: "翻译",
popout_untranslateoption: "取消翻译",
2021-01-26 21:14:48 +01:00
toast_translating: "正在翻译",
toast_translating_failed: "翻译失败",
toast_translating_tryanother: "尝试其他翻译器",
translated_watermark: "已翻译"
2020-09-19 20:49:33 +02:00
};
2021-01-15 17:54:22 +01:00
case "zh-TW": // Chinese (Taiwan)
2020-09-19 20:49:33 +02:00
return {
context_googletranslateoption: "搜索翻譯",
context_messagetranslateoption: "翻譯訊息",
2021-01-15 17:54:22 +01:00
context_messageuntranslateoption: "取消翻譯訊息",
popout_translateoption: "翻譯",
popout_untranslateoption: "取消翻譯",
2021-01-26 21:14:48 +01:00
toast_translating: "正在翻譯",
toast_translating_failed: "翻譯失敗",
toast_translating_tryanother: "嘗試其他翻譯器",
translated_watermark: "已翻譯"
2020-09-19 20:49:33 +02:00
};
default: // English
2020-09-19 20:49:33 +02:00
return {
2021-01-26 21:14:48 +01:00
context_googletranslateoption: "Search Translation",
context_messagetranslateoption: "Translate Message",
context_messageuntranslateoption: "Untranslate Message",
popout_translateoption: "Translate",
popout_untranslateoption: "Untranslate",
2021-01-26 21:14:48 +01:00
toast_translating: "Translating",
toast_translating_failed: "Failed to translate",
toast_translating_tryanother: "Try another Translator",
translated_watermark: "translated"
2020-09-19 20:49:33 +02:00
};
}
}
};
2020-10-09 21:09:35 +02:00
})(window.BDFDB_Global.PluginUtils.buildPlugin(config));
2021-05-15 20:55:12 +02:00
})();