2019-01-31 17:06:48 +01: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 {
2019-01-11 19:59:30 +01:00
getName ( ) { return "GoogleTranslateOption" ; }
2019-04-08 15:23:03 +02:00
getVersion ( ) { return "1.6.6" ; }
2019-01-26 22:45:19 +01:00
2019-04-08 15:21:20 +02:00
getAuthor ( ) { return "DevilBro" ; }
2019-01-11 19:59:30 +01:00
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
2018-10-11 10:21:26 +02:00
initConstructor ( ) {
2019-04-08 15:21:20 +02:00
this . changelog = {
"fixed" : [ [ "DeepL" , "DeepL support was removed because Discord changed their electron version to the beta 5, which no longer supports webviews like they used to. This will not be readded by me in the future, DeepL caused a lot of issues and the way it was implemented caused a log of bugs anyways. Do not bother me about it" ] ]
} ;
2018-10-11 10:21:26 +02:00
this . labels = { } ;
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
this . patchModules = {
"ChannelTextArea" : "componentDidMount" ,
"Message" : "componentDidMount" ,
2019-01-04 21:56:36 +01:00
"MessageOptionPopout" : "componentDidMount" ,
"StandardSidebarView" : "componentWillUnmount"
2019-01-02 23:28:11 +01:00
} ;
2019-01-26 22:45:19 +01:00
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 . doTranslate = false ;
this . translating = false ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . defaults = {
settings : {
2019-01-04 21:56:36 +01:00
addTranslateButton : { value : true , description : "Adds an translate button to the chatbar." } ,
2019-01-02 23:28:11 +01:00
sendOriginalMessage : { value : false , description : "Send the original message together with the translation." }
2018-10-11 10:21:26 +02:00
} ,
choices : {
inputContext : { value : "auto" , place : "Context" , direction : "Input" , popout : false , description : "Input Language in selected Messages:" } ,
outputContext : { value : "$discord" , place : "Context" , direction : "Output" , popout : false , description : "Output Language in selected Messages:" } ,
inputMessage : { value : "auto" , place : "Message" , direction : "Input" , popout : true , description : "Input Language in your Message:" } ,
outputMessage : { value : "$discord" , place : "Message" , direction : "Output" , popout : true , description : "Output Language in your Message:" }
}
} ;
2019-01-02 23:28:11 +01:00
this . messageTranslateContextEntryMarkup =
2018-10-11 10:21:26 +02:00
` <div class=" ${ BDFDB . disCN . contextmenuitemgroup } ">
2019-01-02 23:28:11 +01:00
< div class = "${BDFDB.disCN.contextmenuitem} googletranslateoption-item googletranslateoption-translate-item" >
< span class = "DevilBro-textscrollwrapper" speed = 3 > < div class = "DevilBro-textscroll" > REPLACE _context _messagetranslateoption _text < / d i v > < / s p a n >
2018-10-11 10:21:26 +02:00
< div class = "${BDFDB.disCN.contextmenuhint}" > < / d i v >
< / d i v >
< / d i v > ` ;
2019-01-02 23:28:11 +01:00
this . messageUntranslateContextEntryMarkup =
2018-10-11 10:21:26 +02:00
` <div class=" ${ BDFDB . disCN . contextmenuitemgroup } ">
2019-01-02 23:28:11 +01:00
< div class = "${BDFDB.disCN.contextmenuitem} googletranslateoption-item googletranslateoption-untranslate-item" >
< span class = "DevilBro-textscrollwrapper" speed = 3 > < div class = "DevilBro-textscroll" > REPLACE _context _messageuntranslateoption _text < / d i v > < / s p a n >
2018-10-11 10:21:26 +02:00
< div class = "${BDFDB.disCN.contextmenuhint}" > < / d i v >
< / d i v >
< / d i v > ` ;
2019-01-02 23:28:11 +01:00
this . messageSearchContextEntryMarkup =
` <div class=" ${ BDFDB . disCN . contextmenuitemgroup } ">
< div class = "${BDFDB.disCN.contextmenuitem} googletranslateoption-item googletranslateoption-search-item" >
< span class = "DevilBro-textscrollwrapper" speed = 3 > < div class = "DevilBro-textscroll" > REPLACE _context _googletranslateoption _text < / d i v > < / s p a n >
< div class = "${BDFDB.disCN.contextmenuhint}" > < / d i v >
< / d i v >
2018-10-11 10:21:26 +02:00
< / d i v > ` ;
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
this . popoutTranslateEntryMarkup =
` <button type="button" class=" ${ BDFDB . disCNS . optionpopoutitem + BDFDB . disCNS . button + BDFDB . disCNS . buttonlookblank + BDFDB . disCNS . buttoncolorbrand + BDFDB . disCN . buttongrow } googletranslateoption-itembtn googletranslateoption-translate-itembtn">
2018-10-11 10:21:26 +02:00
< div class = "${BDFDB.disCN.buttoncontents}" > REPLACE _popout _translateoption _text < / d i v >
< / b u t t o n > ` ;
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
this . popoutUntranslateEntryMarkup =
` <button type="button" class=" ${ BDFDB . disCNS . optionpopoutitem + BDFDB . disCNS . button + BDFDB . disCNS . buttonlookblank + BDFDB . disCNS . buttoncolorbrand + BDFDB . disCN . buttongrow } googletranslateoption-itembtn googletranslateoption-untranslate-itembtn">
< div class = "${BDFDB.disCN.buttoncontents}" > REPLACE _popout _untranslateoption _text < / d i v >
< / b u t t o n > ` ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . translateButtonMarkup =
2019-02-07 18:25:40 +01:00
` <button type="button" class=" ${ BDFDB . disCNS . textareabuttonwrapper + BDFDB . disCNS . button + BDFDB . disCNS . buttonlookblank + BDFDB . disCNS . buttoncolorbrand + BDFDB . disCN . buttongrow } translate-button-wrapper">
< div class = "${BDFDB.disCNS.buttoncontents + BDFDB.disCNS.textareabutton + BDFDB.disCN.textareapickerbutton} translate-button-inner" >
2018-12-08 20:35:35 +01:00
< svg version = "1.1" xmlns = "http://www.w3.org/2000/svg" class = "${BDFDB.disCN.textareaicon}" viewBox = "0 0 22 22" fill = "currentColor" >
2018-12-08 10:59:51 +01:00
< 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" / >
< / s v g >
< / d i v >
2019-02-07 18:25:40 +01:00
< / b u t t o n > ` ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . reverseButtonMarkup =
` <svg class="reverse-button ${ BDFDB . disCN . flexchild } " type="REPLACETYPE" version="1.1" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" style="flex: 0 0 auto;">
< 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" / >
< / s v g > ` ;
2019-01-26 22:45:19 +01:00
2019-01-11 20:00:07 +01:00
this . translatePopoutMarkup =
2018-10-11 10:21:26 +02:00
` <div class=" ${ BDFDB . disCNS . popout + BDFDB . disCNS . popoutbottomright + BDFDB . disCNS . popoutnoarrow + BDFDB . disCN . popoutnoshadow } popout-googletranslate DevilBro-modal" style="z-index: 2000; overflow: visible; visibility: visible; transform: translateX(-100%) translateY(-100%) translateZ(0px);">
< div class = "${BDFDB.disCN.popoutthemedpopout}" >
< div class = "${BDFDB.disCNS.flex + BDFDB.disCNS.flex2 + BDFDB.disCNS.horizontal + BDFDB.disCNS.horizontal2 + BDFDB.disCNS.directionrow + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCNS.margintop8 + BDFDB.disCN.marginbottom8}" style = "flex: 1 1 auto;" >
< h3 class = "${BDFDB.disCNS.titledefault + BDFDB.disCNS.title + BDFDB.disCNS.marginreset + BDFDB.disCNS.weightmedium + BDFDB.disCNS.size16 + BDFDB.disCNS.height24 + BDFDB.disCN.flexchild}" style = "flex: 1 1 auto;" > Words starting with "!" will be ignored < / h 3 >
< / d i v >
$ { Object . keys ( this . defaults . choices ) . map ( ( key , i ) =>
` <div class=" ${ BDFDB . disCNS . flex + BDFDB . disCNS . flex2 + BDFDB . disCNS . horizontal + BDFDB . disCNS . horizontal2 + BDFDB . disCNS . directionrow + BDFDB . disCNS . justifystart + BDFDB . disCNS . aligncenter + BDFDB . disCNS . nowrap + BDFDB . disCNS . margintop8 + BDFDB . disCN . marginbottom8 } " style="flex: 1 1 auto;">
< h3 class = "${BDFDB.disCNS.titledefault + BDFDB.disCNS.title + BDFDB.disCNS.weightmedium + BDFDB.disCNS.size16 + BDFDB.disCN.flexchild}" style = "flex: 1 1 auto;" > $ { this . defaults . choices [ key ] . description } < / h 3 >
$ { this . defaults . choices [ key ] . direction == "Output" ? this . reverseButtonMarkup . replace ( "REPLACETYPE" , key ) : "" }
< / d i v >
< div class = "${BDFDB.disCNS.flex + BDFDB.disCNS.flex2 + BDFDB.disCNS.horizontal + BDFDB.disCNS.horizontal2 + BDFDB.disCNS.directionrow + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.marginbottom8}" style = "flex: 1 1 auto;" >
< div class = "${BDFDB.disCN.selectwrap}" style = "flex: 1 1 auto;" >
< div class = "${BDFDB.disCNS.select + BDFDB.disCNS.selectsingle + BDFDB.disCN.selecthasvalue}" type = "${key}" value = "${this.defaults.choices[key].value}" >
< div class = "${BDFDB.disCN.selectcontrol}" >
< div class = "${BDFDB.disCNS.flex + BDFDB.disCNS.flex2 + BDFDB.disCNS.horizontal + BDFDB.disCNS.horizontal2 + BDFDB.disCNS.directionrow + BDFDB.disCNS.justifystart + BDFDB.disCNS.alignbaseline + BDFDB.disCNS.nowrap + BDFDB.disCN.selectvalue}" style = "flex: 1 1 auto;" >
< div class = "${BDFDB.disCNS.title + BDFDB.disCNS.medium + BDFDB.disCNS.size16 + BDFDB.disCNS.height20 + BDFDB.disCNS.primary + BDFDB.disCN.weightnormal}" style = "flex: 1 1 auto;" > < / d i v >
< / d i v >
< span class = "${BDFDB.disCN.selectarrowzone}" >
< span class = "${BDFDB.disCN.selectarrow}" > < / s p a n >
< / s p a n >
< / d i v >
< / d i v >
< / d i v >
< / d i v > ` ) . j o i n ( " " ) }
< div class = "${BDFDB.disCNS.flex + BDFDB.disCNS.flex2 + BDFDB.disCNS.horizontal + BDFDB.disCNS.horizontal2 + BDFDB.disCNS.directionrow + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.marginbottom8}" style = "flex: 1 1 auto;" >
< h3 class = "${BDFDB.disCNS.titledefault + BDFDB.disCNS.title + BDFDB.disCNS.marginreset + BDFDB.disCNS.weightmedium + BDFDB.disCNS.size16 + BDFDB.disCNS.height24 + BDFDB.disCN.flexchild}" style = "flex: 1 1 auto;" > Translate : < / h 3 >
< div class = "${BDFDB.disCNS.flexchild + BDFDB.disCNS.switchenabled + BDFDB.disCNS.switch + BDFDB.disCNS.switchvalue + BDFDB.disCNS.switchsizedefault + BDFDB.disCNS.switchsize + BDFDB.disCNS.switchthemedefault + BDFDB.disCN.switchvalueunchecked}" style = "flex: 0 0 auto;" >
< input type = "checkbox" class = "${BDFDB.disCNS.switchinnerenabled + BDFDB.disCN.switchinner}" id = "translating-checkbox" >
< / d i v >
< / d i v >
< / d i v >
< / d i v > ` ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . css = `
2019-02-07 18:25:40 +01:00
$ { BDFDB . dotCNS . textareawrapall + BDFDB . dotCN . textareainner } {
align - items : center ;
2018-12-10 15:37:56 +01:00
}
2019-02-07 18:25:40 +01:00
$ { BDFDB . dotCNS . textareawrapall + BDFDB . dotCN . textareainner } . send - button {
top : 0 ;
bottom : 0 ;
2018-12-12 12:33:39 +01:00
right : 9 px ;
2018-12-10 15:37:56 +01:00
}
2019-02-07 18:25:40 +01:00
$ { BDFDB . dotCN . textareabuttonwrapper } . popout - open $ { BDFDB . dotCN . textareabutton } . translate - button - inner {
2018-12-12 12:33:39 +01:00
opacity : 1 ;
}
2019-01-26 22:45:19 +01:00
2019-02-07 18:25:40 +01:00
$ { BDFDB . dotCN . textareabuttonwrapper + BDFDB . dotCNS . textareabuttonactive + BDFDB . dotCN . textareabutton } . translate - button - inner {
2018-12-11 12:55:15 +01:00
color : # F04747 ! important ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2019-02-07 18:25:40 +01:00
$ { BDFDB . dotCNS . textareabuttonwrapper + BDFDB . dotCN . textareabutton } . translate - button - inner $ { BDFDB . dotCN . textareaicon } {
2018-12-08 20:35:35 +01:00
height : 24 px ;
width : 24 px ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2019-02-07 18:25:40 +01:00
$ { BDFDB . dotCN . textareabuttonwrapper } . popout - open $ { BDFDB . dotCN . textareabutton } . translate - button - inner $ { BDFDB . dotCN . textareaicon } {
2018-12-12 12:33:39 +01:00
transform : none ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
. reverse - button {
margin - top : - 5 px ;
opacity : 0.2 ;
transition : all 200 ms ease ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
$ { BDFDB . dotCN . themedark } . reverse - button {
fill : # fff ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
$ { BDFDB . dotCN . themelight } . reverse - button {
fill : # 4 f545c ;
}
. reverse - button : hover {
cursor : pointer ;
opacity : 1 ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
$ { BDFDB . dotCN . popout } . popout - googletranslate $ { BDFDB . dotCN . popoutthemedpopout } {
padding : 0 10 px ;
width : 400 px ;
}
2019-01-26 22:45:19 +01:00
2019-01-11 21:02:22 +01:00
$ { BDFDB . dotCN . selectmenuouter } . inChat {
2018-10-11 10:21:26 +02:00
top : 0 % ;
transform : translateY ( - 100 % ) ;
border - radius : 4 px 4 px 0 0 ;
margin - top : 1 px ;
} ` ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
getSettingsPanel ( ) {
2019-01-22 11:28:32 +01:00
if ( ! global . BDFDB || typeof BDFDB != "object" || ! BDFDB . loaded || ! this . started ) return ;
2018-10-11 10:21:26 +02:00
var choices = BDFDB . getAllData ( this , "choices" ) ;
var settings = BDFDB . getAllData ( this , "settings" ) ;
2019-01-24 13:37:08 +01:00
var settingshtml = ` <div class=" ${ this . name } -settings DevilBro-settings"><div class=" ${ BDFDB . disCNS . titledefault + BDFDB . disCNS . title + BDFDB . disCNS . size18 + BDFDB . disCNS . height24 + BDFDB . disCNS . weightnormal + BDFDB . disCN . marginbottom8 } "> ${ this . name } </div><div class="DevilBro-settings-inner"> ` ;
2018-10-11 10:21:26 +02:00
for ( let key in choices ) {
let choice = this . getLanguageChoice ( key ) ;
settingshtml += ` <h3 class=" ${ BDFDB . disCNS . titledefault + BDFDB . disCNS . title + BDFDB . disCNS . weightmedium + BDFDB . disCNS . size16 + BDFDB . disCN . flexchild } marginBottom8-1mABJ4 marginTop8-2gOa2N" style="flex: 1 1 auto;"> ${ this . defaults . choices [ key ] . description } </h3><div class="ui-form-item ${ BDFDB . disCNS . flex + BDFDB . disCNS . flex2 + BDFDB . disCNS . horizontal + BDFDB . disCNS . horizontal2 + BDFDB . disCNS . directionrow + BDFDB . disCNS . justifystart + BDFDB . disCNS . aligncenter + BDFDB . disCNS . nowrap + BDFDB . disCN . marginbottom8 } " style="flex: 1 1 auto;"><div class=" ${ BDFDB . disCN . selectwrap } " style="flex: 1 1 auto;"><div class=" ${ BDFDB . disCNS . select + BDFDB . disCNS . selectsingle + BDFDB . disCN . selecthasvalue } " type=" ${ key } " value=" ${ choice } "><div class=" ${ BDFDB . disCN . selectcontrol } "><div class=" ${ BDFDB . disCNS . flex + BDFDB . disCNS . flex2 + BDFDB . disCNS . horizontal + BDFDB . disCNS . horizontal2 + BDFDB . disCNS . directionrow + BDFDB . disCNS . justifystart + BDFDB . disCNS . alignbaseline + BDFDB . disCNS . nowrap + BDFDB . disCN . selectvalue } " style="flex: 1 1 auto;"><div class=" ${ BDFDB . disCNS . title + BDFDB . disCNS . medium + BDFDB . disCNS . size16 + BDFDB . disCNS . height20 + BDFDB . disCNS . primary + BDFDB . disCN . weightnormal } " style="padding:0;"> ${ this . languages [ choice ] . name } </div></div><span class=" ${ BDFDB . disCN . selectarrowzone } "><span class=" ${ BDFDB . disCN . selectarrow } "></span></span></div></div></div></div> `
}
for ( let key in settings ) {
2019-01-11 19:59:30 +01:00
settingshtml += ` <div class=" ${ BDFDB . disCNS . flex + BDFDB . disCNS . flex2 + BDFDB . disCNS . horizontal + BDFDB . disCNS . horizontal2 + BDFDB . disCNS . directionrow + BDFDB . disCNS . justifystart + BDFDB . disCNS . aligncenter + BDFDB . disCNS . nowrap + BDFDB . disCN . marginbottom8 } " style="flex: 1 1 auto;"><h3 class=" ${ BDFDB . disCNS . titledefault + BDFDB . disCNS . title + BDFDB . disCNS . marginreset + BDFDB . disCNS . weightmedium + BDFDB . disCNS . size16 + BDFDB . disCNS . height24 + BDFDB . disCN . flexchild } " style="flex: 1 1 auto;"> ${ this . defaults . settings [ key ] . description } </h3><div class=" ${ BDFDB . disCNS . flexchild + BDFDB . disCNS . switchenabled + BDFDB . disCNS . switch + BDFDB . disCNS . switchvalue + BDFDB . disCNS . switchsizedefault + BDFDB . disCNS . switchsize + BDFDB . disCN . switchthemedefault } " style="flex: 0 0 auto;"><input type="checkbox" value="settings ${ key } " class=" ${ BDFDB . disCNS . switchinnerenabled + BDFDB . disCN . switchinner } settings-switch" ${ settings [ key ] ? " checked" : "" } ></div></div> ` ;
2018-10-11 10:21:26 +02:00
}
settingshtml += ` </div></div> ` ;
2019-01-26 22:45:19 +01:00
2019-01-11 19:59:30 +01:00
let settingspanel = BDFDB . htmlToElement ( settingshtml ) ;
2018-10-11 10:21:26 +02:00
2019-01-13 22:25:18 +01:00
BDFDB . initElements ( settingspanel , this ) ;
2018-10-11 10:21:26 +02:00
2019-01-17 23:48:29 +01:00
BDFDB . addEventListener ( this , settingspanel , "click" , BDFDB . dotCN . selectcontrol , e => { this . openDropdownMenu ( "inSettings" , e ) ; } ) ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
return settingspanel ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
//legacy
load ( ) { }
start ( ) {
2019-02-04 09:13:15 +01:00
if ( ! global . BDFDB ) global . BDFDB = { myPlugins : { } } ;
if ( global . BDFDB && global . BDFDB . myPlugins && typeof global . BDFDB . myPlugins == "object" ) global . BDFDB . myPlugins [ this . getName ( ) ] = this ;
2019-01-17 23:48:29 +01:00
var libraryScript = document . querySelector ( 'head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]' ) ;
if ( ! libraryScript || performance . now ( ) - libraryScript . getAttribute ( "date" ) > 600000 ) {
2018-10-11 10:21:26 +02:00
if ( libraryScript ) libraryScript . remove ( ) ;
libraryScript = document . createElement ( "script" ) ;
libraryScript . setAttribute ( "type" , "text/javascript" ) ;
libraryScript . setAttribute ( "src" , "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js" ) ;
2019-01-17 23:48:29 +01:00
libraryScript . setAttribute ( "date" , performance . now ( ) ) ;
2019-01-30 21:23:49 +01:00
libraryScript . addEventListener ( "load" , ( ) => { if ( global . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) this . initialize ( ) ; } ) ;
2018-10-11 10:21:26 +02:00
document . head . appendChild ( libraryScript ) ;
}
2019-01-17 23:48:29 +01:00
else if ( global . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) this . initialize ( ) ;
2018-10-11 10:21:26 +02:00
this . startTimeout = setTimeout ( ( ) => { this . initialize ( ) ; } , 30000 ) ;
}
initialize ( ) {
2019-01-17 23:48:29 +01:00
if ( global . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
2019-01-22 11:05:54 +01:00
if ( this . started ) return ;
2018-10-11 10:21:26 +02:00
BDFDB . loadMessage ( this ) ;
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
this . GuildUtils = BDFDB . WebModules . findByProperties ( "getGuilds" , "getGuild" ) ;
this . ChannelUtils = BDFDB . WebModules . findByProperties ( "getChannels" , "getChannel" ) ;
this . LastGuildStore = BDFDB . WebModules . findByProperties ( "getLastSelectedGuildId" ) ;
this . LastChannelStore = BDFDB . WebModules . findByProperties ( "getLastSelectedChannelId" ) ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . setLanguage ( ) ;
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
BDFDB . WebModules . forceAllUpdates ( this ) ;
2018-10-11 10:21:26 +02:00
}
else {
2019-02-12 21:56:34 +01:00
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 ( ) {
2019-01-17 23:48:29 +01:00
if ( global . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
2018-10-11 10:21:26 +02:00
document . querySelectorAll ( BDFDB . dotCN . message + ".translated" ) . forEach ( message => {
this . resetMessage ( message ) ;
} ) ;
2019-01-26 22:45:19 +01:00
2019-01-11 19:59:30 +01:00
BDFDB . removeEles ( ".translate-button-wrapper" , ".popout-googletranslate" ) ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
BDFDB . unloadMessage ( this ) ;
}
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
// begin of own functions
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
changeLanguageStrings ( ) {
2019-01-02 23:28:11 +01:00
this . messageTranslateContextEntryMarkup = this . messageTranslateContextEntryMarkup . replace ( "REPLACE_context_messagetranslateoption_text" , this . labels . context _messagetranslateoption _text ) ;
this . messageUntranslateContextEntryMarkup = this . messageUntranslateContextEntryMarkup . replace ( "REPLACE_context_messageuntranslateoption_text" , this . labels . context _messageuntranslateoption _text ) ;
this . messageSearchContextEntryMarkup = this . messageSearchContextEntryMarkup . replace ( "REPLACE_context_googletranslateoption_text" , this . labels . context _googletranslateoption _text ) ;
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
this . popoutTranslateEntryMarkup = this . popoutTranslateEntryMarkup . replace ( "REPLACE_popout_translateoption_text" , this . labels . popout _translateoption _text ) ;
this . popoutUntranslateEntryMarkup = this . popoutUntranslateEntryMarkup . replace ( "REPLACE_popout_untranslateoption_text" , this . labels . popout _untranslateoption _text ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
onMessageContextMenu ( instance , menu ) {
if ( instance . props && instance . props . message && instance . props . channel && instance . props . target && ! menu . querySelector ( ".googletranslateoption-item" ) ) {
let { messagediv , pos } = this . getMessageAndPos ( instance . props . target ) ;
if ( ! messagediv || pos == - 1 ) return ;
2019-01-11 19:59:30 +01:00
let pinentry = BDFDB . React . findDOMNodeSafe ( BDFDB . getOwnerInstance ( { node : menu , name : "MessagePinItem" } ) ) ;
2019-01-15 12:56:50 +01:00
let messageTranslateContextEntry = BDFDB . htmlToElement ( BDFDB . containsClass ( messagediv , "translated" ) ? this . messageUntranslateContextEntryMarkup : this . messageTranslateContextEntryMarkup ) ;
2019-01-11 19:59:30 +01:00
if ( pinentry ) pinentry . parentElement . insertBefore ( messageTranslateContextEntry , pinentry . nextElementSibling ) ;
else menu . insertBefore ( messageTranslateContextEntry , menu . firstElementChild ) ;
let translateitem = messageTranslateContextEntry . querySelector ( ".googletranslateoption-item" ) ;
translateitem . addEventListener ( "click" , ( ) => {
2019-03-01 21:26:41 +01:00
BDFDB . closeContextMenu ( menu ) ;
2019-01-11 19:59:30 +01:00
this . translateMessage ( instance . props . message , instance . props . target , instance . props . channel ) ;
} ) ;
if ( BDFDB . isPluginEnabled ( "MessageUtilities" ) ) {
BDFDB . setContextHint ( translateitem , bdplugins . MessageUtilities . plugin . getActiveShortcutString ( "__Translate_Message" ) ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-02 23:28:11 +01:00
let text = document . getSelection ( ) . toString ( ) ;
2019-01-11 19:59:30 +01:00
if ( text ) {
let searchentry = BDFDB . React . findDOMNodeSafe ( BDFDB . getOwnerInstance ( { node : menu , props : [ "handleSearchWithGoogle" ] } ) ) ;
if ( searchentry ) {
let messageSearchContextEntry = BDFDB . htmlToElement ( this . messageSearchContextEntryMarkup ) ;
searchentry . parentElement . appendChild ( messageSearchContextEntry ) ;
let searchitem = messageSearchContextEntry . querySelector ( ".googletranslateoption-search-item" ) ;
2019-01-14 15:16:29 +01:00
searchitem . addEventListener ( "mouseenter" , e => {
2019-01-02 23:28:11 +01:00
this . translateText ( text , "context" , ( translation , input , output ) => {
if ( translation ) {
2019-01-11 19:59:30 +01:00
var openGoogleSearch = ( ) => {
2019-03-01 21:26:41 +01:00
BDFDB . closeContextMenu ( menu ) ;
2019-01-11 19:59:30 +01:00
window . open ( this . getGoogleTranslatePageURL ( input . id , output . id , text ) , "_blank" ) ;
} ;
searchitem . removeEventListener ( "click" , openGoogleSearch ) ;
searchitem . addEventListener ( "click" , openGoogleSearch ) ;
2019-01-17 23:48:29 +01:00
let rects = BDFDB . getRects ( searchitem ) ;
2019-01-11 19:59:30 +01:00
BDFDB . createTooltip ( ` From ${ input . name } : \n ${ text } \n \n To ${ output . name } : \n ${ translation } ` , searchitem , { type : "right" , selector : "googletranslate-tooltip" , style : ` max-width: ${ window . outerWidth - rects . left - rects . width } px !important; ` } ) ;
2019-01-02 23:28:11 +01:00
}
2018-10-11 10:21:26 +02:00
} ) ;
2019-01-02 23:28:11 +01:00
} ) ;
2019-01-11 19:59:30 +01:00
}
2018-10-11 10:21:26 +02:00
}
}
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
setLanguage ( ) {
this . languages = Object . assign ( { } ,
{ "auto" : { name : "Auto" , id : "auto" , integrated : false , dic : false , deepl : true } } ,
BDFDB . languages ,
{ "binary" : { name : "Binary" , id : "binary" , integrated : false , dic : false , deepl : true } }
) ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
getLanguageChoice ( direction , place ) {
2019-04-08 15:21:20 +02:00
this . setLanguage ( ) ;
2018-10-11 10:21:26 +02:00
var type = typeof place === "undefined" ? direction : direction . toLowerCase ( ) + place . charAt ( 0 ) . toUpperCase ( ) + place . slice ( 1 ) . toLowerCase ( ) ;
var choice = BDFDB . getData ( type , this , "choices" ) ;
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
2019-01-04 21:56:36 +01:00
processStandardSidebarView ( instance , wrapper ) {
2019-01-11 19:59:30 +01:00
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
this . setLanguage ( ) ;
2019-01-04 21:56:36 +01:00
BDFDB . removeEles ( ".translate-button-wrapper" ) ;
BDFDB . WebModules . forceAllUpdates ( this , "ChannelTextArea" ) ;
}
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
processChannelTextArea ( instance , wrapper ) {
2019-01-04 21:56:36 +01:00
if ( instance . props && instance . props . type && instance . props . type == "normal" && ! instance . props . disabled && ! wrapper . querySelector ( ".translate-button-wrapper" ) && BDFDB . getData ( "addTranslateButton" , this , "settings" ) ) {
2019-01-02 23:28:11 +01:00
let textarea = wrapper . querySelector ( "textarea" ) ;
if ( textarea ) {
var buttoncontainer = wrapper . querySelector ( BDFDB . dotCN . textareapickerbuttons ) ;
2019-01-03 21:48:50 +01:00
if ( ! buttoncontainer ) return ;
2019-01-11 19:59:30 +01:00
var translateButton = BDFDB . htmlToElement ( this . translateButtonMarkup ) ;
translateButton . addEventListener ( "click" , ( ) => {
this . openTranslatePopout ( translateButton ) ;
} ) ;
translateButton . addEventListener ( "contextmenu" , ( ) => {
this . translating = ! this . translating ;
2019-01-15 12:56:50 +01:00
BDFDB . toggleClass ( document . querySelectorAll ( BDFDB . dotCNS . textareawrapchat + ".translate-button-wrapper" ) , BDFDB . disCN . textareabuttonactive , this . translating ) ;
2019-01-11 19:59:30 +01:00
} ) ;
buttoncontainer . insertBefore ( translateButton , buttoncontainer . firstElementChild ) ;
2019-01-15 12:56:50 +01:00
BDFDB . addClass ( translateButton , instance . props . type ) ;
BDFDB . toggleClass ( translateButton , BDFDB . disCN . textareabuttonactive , this . translating ) ;
2019-01-11 19:59:30 +01:00
BDFDB . addEventListener ( this , textarea , "input" , ( ) => {
if ( this . doTranslate ) {
this . doTranslate = false ;
if ( document . activeElement == textarea ) {
var text = textarea . value ;
textarea . focus ( ) ;
textarea . selectionStart = 0 ;
textarea . selectionEnd = text . length ;
document . execCommand ( "insertText" , false , "" ) ;
this . translateText ( text , "message" , ( translation , input , output ) => {
translation = ! translation ? text : ( BDFDB . getData ( "sendOriginalMessage" , this , "settings" ) ? text + "\n\n" + translation : translation ) ;
2018-10-11 10:21:26 +02:00
textarea . focus ( ) ;
2019-01-11 19:59:30 +01:00
document . execCommand ( "insertText" , false , translation + " " ) ;
BDFDB . triggerSend ( textarea ) ;
} ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-11 19:59:30 +01:00
}
} ) ;
2019-01-14 15:16:29 +01:00
BDFDB . addEventListener ( this , textarea , "keydown" , e => {
2019-01-11 19:59:30 +01:00
if ( textarea . value && this . translating && ! e . shiftKey && e . which == 13 && ! wrapper . querySelector ( BDFDB . dotCN . autocomplete ) ) {
this . doTranslate = true ;
textarea . dispatchEvent ( new Event ( "input" ) ) ;
}
} ) ;
2018-10-11 10:21:26 +02:00
}
}
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
processMessage ( instance , wrapper ) {
2019-03-01 21:26:41 +01:00
if ( instance . props && typeof instance . props . renderButtons == "function" && ! wrapper . querySelector ( BDFDB . dotCN . optionpopoutbutton ) && BDFDB . getReactValue ( instance , "props.message.author.id" ) != 1 ) {
2019-01-02 23:28:11 +01:00
let buttonwrap = wrapper . querySelector ( BDFDB . dotCN . messagebuttoncontainer ) ;
if ( buttonwrap ) {
2019-01-11 19:59:30 +01:00
let optionPopoutButton = BDFDB . htmlToElement ( ` <div class=" ${ BDFDB . disCN . optionpopoutbutton } "></div> ` ) ;
optionPopoutButton . addEventListener ( "click" , ( ) => { BDFDB . createMessageOptionPopout ( optionPopoutButton ) ; } ) ;
buttonwrap . appendChild ( optionPopoutButton ) ;
2018-10-11 10:21:26 +02:00
}
}
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
processMessageOptionPopout ( instance , wrapper ) {
if ( instance . props . message && instance . props . channel && instance . _reactInternalFiber . memoizedProps . target && ! wrapper . querySelector ( ".personalpin-itembtn" ) ) {
let { messagediv , pos } = this . getMessageAndPos ( instance . _reactInternalFiber . memoizedProps . target ) ;
if ( ! messagediv || pos == - 1 ) return ;
2019-01-15 12:56:50 +01:00
let popoutTranslateEntry = BDFDB . htmlToElement ( BDFDB . containsClass ( messagediv , "translated" ) ? this . popoutUntranslateEntryMarkup : this . popoutTranslateEntryMarkup ) ;
2019-01-11 19:59:30 +01:00
wrapper . appendChild ( popoutTranslateEntry ) ;
popoutTranslateEntry . addEventListener ( "click" , ( ) => {
this . translateMessage ( instance . props . message , instance . _reactInternalFiber . memoizedProps . target , instance . props . channel ) ;
instance . props . onClose ( ) ;
} ) ;
2019-01-02 23:28:11 +01:00
}
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
getMessageAndPos ( target ) {
let messagediv = BDFDB . getParentEle ( BDFDB . dotCN . message , target ) ;
2019-01-17 23:48:29 +01:00
let pos = messagediv ? Array . from ( messagediv . parentElement . querySelectorAll ( BDFDB . dotCN . message ) ) . indexOf ( messagediv ) : - 1 ;
2019-01-02 23:28:11 +01:00
return { messagediv , pos } ;
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
translateMessage ( message , target , channel ) {
if ( ! message || ! target ) return ;
let { messagediv , pos } = this . getMessageAndPos ( target ) ;
if ( ! messagediv || pos == - 1 ) return ;
channel = channel ? channel : this . ChannelUtils . getChannel ( message . channel _id ) ;
if ( ! messagediv . querySelector ( BDFDB . dotCN . messageedited + ".translated" ) ) {
var markup = messagediv . querySelector ( BDFDB . dotCN . messagemarkup ) ;
var fakemarkup = markup . cloneNode ( true ) ;
var oldhtml = markup . innerHTML ;
let compactheader = fakemarkup . querySelector ( BDFDB . dotCN . messageheadercompact ) ;
if ( compactheader ) compactheader . remove ( ) ;
this . translateText ( fakemarkup . innerHTML , "context" , ( translation , input , output ) => {
if ( translation ) {
2019-01-11 19:59:30 +01:00
markup . GoogleTranslateOriginalHTML = oldhtml ;
2019-01-02 23:28:11 +01:00
markup . innerHTML = ( compactheader ? "<label></label>" : "" ) + translation . replace ( /\n/g , "DevilBroBDFDBPlacerHolderN" ) . replace ( /\s/g , " " ) . replace ( /DevilBroBDFDBPlacerHolderN/g , "\n" ) . replace ( / *([<>]) */g , "$1" ) ;
2019-01-11 19:59:30 +01:00
let translatestamp = BDFDB . htmlToElement ( ` <time class=" ${ BDFDB . disCN . messageedited } translated">( ${ this . labels . translated _watermark _text } )</time> ` ) ;
translatestamp . addEventListener ( "mouseenter" , ( ) => {
BDFDB . createTooltip ( ` <div>From: ${ input . name } </div><div>To: ${ output . name } </div> ` , translatestamp , { html : true , type : "top" , selector : "translation-tooltip" } ) ;
} ) ;
markup . appendChild ( translatestamp ) ;
2019-01-15 12:56:50 +01:00
BDFDB . addClass ( messagediv , "translated" ) ;
2019-01-02 23:28:11 +01:00
if ( compactheader ) markup . insertBefore ( compactheader , markup . firstElementChild ) ;
}
} ) ;
}
else this . resetMessage ( messagediv ) ;
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
resetMessage ( messagediv ) {
2019-01-11 19:59:30 +01:00
BDFDB . removeEles ( messagediv . querySelector ( BDFDB . dotCN . messageedited + ".translated" ) ) ;
2019-01-15 12:56:50 +01:00
BDFDB . removeClass ( messagediv , "translated" ) ;
2019-01-02 23:28:11 +01:00
let markup = messagediv . querySelector ( BDFDB . dotCN . messagemarkup ) ;
2019-01-11 19:59:30 +01:00
markup . innerHTML = markup . GoogleTranslateOriginalHTML ;
delete markup . GoogleTranslateOriginalHTML ;
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-01-02 23:28:11 +01:00
var finishTranslation = ( translation , exceptions , input , output , toast ) => {
if ( translation ) translation = this . addExceptions ( translation , exceptions ) ;
2018-10-11 10:21:26 +02:00
clearInterval ( toast . interval ) ;
toast . close ( ) ;
callback ( translation , input , output ) ;
} ;
2019-01-02 23:28:11 +01: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 ) ] ) ;
var translation = "" ;
if ( translate ) {
var toast = BDFDB . showToast ( "Translating. Please wait" , { timeout : 0 } ) ;
toast . interval = setInterval ( ( ) => {
toast . textContent = toast . textContent . indexOf ( "....." ) > - 1 ? "Translating. Please wait" : toast . textContent + "." ;
} , 500 ) ;
if ( input . id == "binary" || output . id == "binary" ) {
if ( input . id == "binary" && output . id != "binary" ) translation = this . binary2string ( newtext ) ;
else if ( input . id != "binary" && output . id == "binary" ) translation = this . string2binary ( newtext ) ;
else if ( input . id == "binary" && output . id == "binary" ) translation = newtext ;
2019-01-02 23:28:11 +01:00
finishTranslation ( translation , exceptions , input , output , toast ) ;
2018-10-11 10:21:26 +02:00
}
else {
2019-04-08 15:21:20 +02:00
require ( "request" ) ( this . getGoogleTranslateApiURL ( input . id , output . id , newtext ) , ( error , response , result ) => {
if ( ! error && result ) {
result = JSON . parse ( result ) ;
result [ 0 ] . forEach ( ( array ) => { translation += array [ 0 ] ; } ) ;
if ( this . languages [ result [ 2 ] ] ) input . name = this . languages [ result [ 2 ] ] . name ;
2019-01-02 23:28:11 +01:00
finishTranslation ( translation , exceptions , input , output , toast ) ;
2019-04-08 15:21:20 +02:00
}
} ) ;
2018-10-11 10:21:26 +02:00
}
}
else {
translation = text ;
2019-01-02 23:28:11 +01:00
finishTranslation ( translation , exceptions , input , output , toast ) ;
2018-10-11 10:21:26 +02:00
}
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +01:00
addExceptions ( string , exceptions ) {
for ( let i in exceptions ) string = string . replace ( "a" + i + "_______" , exceptions [ i ] . indexOf ( "!" ) == 0 ? exceptions [ i ] . slice ( 1 ) : exceptions [ i ] ) ;
2018-10-11 10:21:26 +02:00
return string ;
}
2019-01-26 22:45:19 +01:00
2019-01-02 23:28:11 +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 ++ ;
text [ i ] = text [ i ] ? text [ i ] + chara : chara ;
if ( chara == ">" ) i ++ ;
} ) ;
for ( let j in text ) {
if ( text [ j ] . indexOf ( "<" ) == 0 ) {
newString . push ( "a" + count + "_______" ) ;
exceptions [ count ] = text [ j ] ;
count ++ ;
}
else newString . push ( text [ j ] ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-02 23:28:11 +01: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 ) ) {
newString . push ( "a" + 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
openTranslatePopout ( button ) {
2019-01-11 19:59:30 +01:00
let container = document . querySelector ( BDFDB . dotCN . popouts ) ;
2019-01-15 12:56:50 +01:00
if ( ! container || BDFDB . containsClass ( button , "popout-open" ) ) return ;
BDFDB . addClass ( button , "popout-open" ) ;
2019-01-11 20:00:07 +01:00
let translatepopout = BDFDB . htmlToElement ( this . translatePopoutMarkup ) ;
2019-01-11 19:59:30 +01:00
container . appendChild ( translatepopout ) ;
2019-01-17 23:48:29 +01:00
let buttonrects = BDFDB . getRects ( button ) ;
2019-01-11 19:59:30 +01:00
translatepopout . style . setProperty ( "left" , buttonrects . left + buttonrects . width + "px" ) ;
translatepopout . style . setProperty ( "top" , buttonrects . top - buttonrects . height / 2 + "px" )
2019-01-26 22:45:19 +01:00
2019-01-14 15:16:29 +01:00
BDFDB . addChildEventListener ( translatepopout , "click" , BDFDB . dotCN . selectcontrol , e => { this . openDropdownMenu ( "inChat" , e ) ; } ) ;
BDFDB . addChildEventListener ( translatepopout , "click" , ".reverse-button" , e => {
let place = e . currentTarget . getAttribute ( "type" ) . replace ( "output" , "" ) ;
2019-01-11 19:59:30 +01:00
let input = this . getLanguageChoice ( "output" , place ) ;
let output = this . getLanguageChoice ( "input" , place ) ;
output = output == "auto" ? "en" : output ;
let inputselect = translatepopout . querySelector ( BDFDB . dotCN . select + "[type='input" + place + "']" ) ;
let outputselect = translatepopout . querySelector ( BDFDB . dotCN . select + "[type='output" + place + "']" ) ;
inputselect . setAttribute ( "value" , input ) ;
inputselect . querySelector ( BDFDB . dotCN . title ) . innerText = this . languages [ input ] . name ;
outputselect . setAttribute ( "value" , output ) ;
outputselect . querySelector ( BDFDB . dotCN . title ) . innerText = this . languages [ output ] . name ;
BDFDB . saveData ( "input" + place , input , this , "choices" ) ;
BDFDB . saveData ( "output" + place , output , this , "choices" ) ;
2019-01-13 22:33:20 +01:00
} ) ;
2019-01-26 22:45:19 +01:00
2019-01-11 19:59:30 +01:00
translatepopout . querySelectorAll ( BDFDB . dotCN . select ) . forEach ( selectWrap => {
2018-10-11 10:21:26 +02:00
let language = this . getLanguageChoice ( selectWrap . getAttribute ( "type" ) ) ;
selectWrap . setAttribute ( "value" , language ) ;
selectWrap . querySelector ( BDFDB . dotCN . title ) . innerText = this . languages [ language ] . name ;
} ) ;
2019-01-26 22:45:19 +01:00
2019-01-11 19:59:30 +01:00
var translatecheckbox = translatepopout . querySelector ( "#translating-checkbox" ) ;
translatecheckbox . checked = this . translating ;
translatecheckbox . addEventListener ( "click" , ( ) => {
2019-01-15 12:56:50 +01:00
BDFDB . toggleClass ( button , BDFDB . disCN . textareabuttonactive , translatecheckbox . checked ) ;
2019-01-11 19:59:30 +01:00
this . translating = translatecheckbox . checked ;
2018-10-11 10:21:26 +02:00
} ) ;
2019-01-26 22:45:19 +01:00
2019-01-14 15:16:29 +01:00
var removePopout = e => {
2019-01-11 19:59:30 +01:00
if ( ! translatepopout . contains ( e . target ) ) {
document . removeEventListener ( "mousedown" , removePopout ) ;
translatepopout . remove ( ) ;
2019-01-15 12:56:50 +01:00
setTimeout ( ( ) => { BDFDB . removeClass ( button , "popout-open" ) ; } , 300 ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-11 19:59:30 +01:00
} ;
document . addEventListener ( "mousedown" , removePopout ) ;
2019-01-26 22:45:19 +01:00
2019-01-13 22:29:17 +01:00
BDFDB . initElements ( translatepopout , 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
openDropdownMenu ( selector , e ) {
2019-01-11 19:59:30 +01:00
let selectControl = e . currentTarget ;
let selectWrap = selectControl . parentElement ;
let plugincard = selector == "inSettings" ? BDFDB . getParentEle ( "li" , selectWrap ) : document . createElement ( "div" ) ;
2019-01-26 22:45:19 +01:00
2019-01-15 12:56:50 +01:00
if ( ! plugincard || BDFDB . containsClass ( selectWrap , BDFDB . disCN . selectisopen ) ) return ;
2019-01-26 22:45:19 +01:00
2019-01-15 12:56:50 +01:00
BDFDB . addClass ( selectWrap , BDFDB . disCN . selectisopen ) ;
2019-01-11 19:59:30 +01:00
plugincard . style . setProperty ( "overflow" , "visible" , "important" ) ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
var type = selectWrap . getAttribute ( "type" ) ;
var selectMenu = this . createDropdownMenu ( selectWrap . getAttribute ( "value" ) , type ) ;
2019-01-15 12:56:50 +01:00
BDFDB . addClass ( selectMenu , selector ) ;
2018-10-11 10:21:26 +02:00
selectWrap . appendChild ( selectMenu ) ;
2019-01-26 22:45:19 +01:00
2019-01-13 22:33:20 +01:00
BDFDB . addChildEventListener ( selectMenu , "mousedown" , BDFDB . dotCN . selectoption , e2 => {
2019-01-14 15:16:29 +01:00
var language = e2 . currentTarget . getAttribute ( "value" ) ;
2018-10-11 10:21:26 +02:00
selectWrap . setAttribute ( "value" , language ) ;
selectControl . querySelector ( BDFDB . dotCN . title ) . innerText = this . languages [ language ] . name ;
BDFDB . saveData ( type , language , this , "choices" ) ;
2019-01-13 22:33:20 +01:00
} ) ;
2019-01-26 22:45:19 +01:00
2019-01-14 15:16:29 +01:00
var removeMenu = e2 => {
2019-01-11 19:59:30 +01:00
if ( e2 . target . parentElement != selectMenu ) {
document . removeEventListener ( "mousedown" , removeMenu ) ;
selectMenu . remove ( ) ;
plugincard . style . removeProperty ( "overflow" ) ;
2019-01-15 12:56:50 +01:00
setTimeout ( ( ) => { BDFDB . removeClass ( selectWrap , BDFDB . disCN . selectisopen ) ; } , 100 ) ;
2019-01-11 19:59:30 +01:00
}
} ;
document . addEventListener ( "mousedown" , removeMenu ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
createDropdownMenu ( choice , type ) {
var menuhtml = ` <div class=" ${ BDFDB . disCN . selectmenuouter } "><div class=" ${ BDFDB . disCN . selectmenu } "> ` ;
for ( var key in this . languages ) {
if ( this . defaults . choices [ type ] . direction == "Output" && key == "auto" ) continue ;
var isSelected = key == choice ? ` ${ BDFDB . disCN . selectselected } ` : ` ` ;
menuhtml += ` <div value=" ${ key } " class=" ${ BDFDB . disCNS . flex + BDFDB . disCNS . flex2 + BDFDB . disCNS . horizontal + BDFDB . disCNS . horizontal2 + BDFDB . disCNS . directionrow + BDFDB . disCNS . justifystart + BDFDB . disCNS . alignbaseline + BDFDB . disCNS . nowrap + BDFDB . disCN . selectoption + isSelected } " style="flex: 1 1 auto; display:flex;"><div class=" ${ BDFDB . disCNS . title + BDFDB . disCNS . medium + BDFDB . disCNS . size16 + BDFDB . disCNS . height20 + BDFDB . disCNS . primary + BDFDB . disCN . weightnormal } " style="flex: 1 1 42%;"> ${ this . languages [ key ] . name } </div></div> `
}
menuhtml += ` </div></div> ` ;
2019-01-11 19:59:30 +01:00
return BDFDB . htmlToElement ( menuhtml ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
string2binary ( string ) {
var binary = "" ;
for ( var character of string ) binary += parseInt ( character . charCodeAt ( 0 ) . toString ( 2 ) ) . toPrecision ( 8 ) . split ( "." ) . reverse ( ) . join ( "" ) . toString ( ) + " " ;
return binary ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
binary2string ( binary ) {
var string = "" ;
binary = binary . replace ( new RegExp ( " " , "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 ;
}
}
}
else {
BDFDB . showToast ( "Invalid binary format. Only use 0s and 1s." , { type : "error" } ) ;
}
return string ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
getGoogleTranslateApiURL ( input , output , text ) {
return "https://translate.googleapis.com/translate_a/single?client=gtx&sl=" + input + "&tl=" + output + "&dt=t&ie=UTF-8&oe=UTF-8&q=" + encodeURIComponent ( text ) ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
getGoogleTranslatePageURL ( input , output , text ) {
return "https://translate.google.com/#" + input + "/" + output + "/" + encodeURIComponent ( text ) ;
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
setLabelsByLanguage ( ) {
switch ( BDFDB . getDiscordLanguage ( ) . id ) {
case "hr" : //croatian
return {
context _messagetranslateoption _text : "Prijevod poruke" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Prijenos poruke" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Traži prijevod" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Nachricht unübersetzen" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Suche Übersetzung" ,
popout _translateoption _text : "Übersetzen" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
popout _untranslateoption _text : "Traduire en arrière" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "traduit"
} ;
case "it" : //italian
return {
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Vertaal bericht terug" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Zoek vertaling" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Oversett melding tilbake" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Søk oversettelse" ,
2019-01-02 23:28:11 +01:00
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ść" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Przetłumacz wiadomość z powrotem" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Wyszukaj tłumaczenie" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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ää" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "İletiyi geri çevir" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Arama tercümesi" ,
popout _translateoption _text : "Çevirmek" ,
2019-01-02 23:28:11 +01:00
popout _untranslateoption _text : "Geri çevir" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "tercüme"
} ;
case "cs" : //czech
return {
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
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 {
2019-01-02 23:28:11 +01:00
context _messagetranslateoption _text : "Преведете на съобщението" ,
context _messageuntranslateoption _text : "Преведете съобщението обратно" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Търсене на превод" ,
2019-01-02 23:28:11 +01:00
popout _translateoption _text : "Превод" ,
popout _untranslateoption _text : "Превод обратно" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "преведена"
} ;
case "ru" : //russian
return {
context _messagetranslateoption _text : "Перевести сообщение" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Перевести сообщение обратно" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Поиск перевода" ,
2019-01-02 23:28:11 +01:00
popout _translateoption _text : "Перевести" ,
popout _untranslateoption _text : "Перевести обратно" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "переведенный"
} ;
case "uk" : //ukrainian
return {
context _messagetranslateoption _text : "Перекласти повідомлення" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Перекласти повідомлення назад" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Пошук перекладу" ,
popout _translateoption _text : "Перекласти" ,
2019-01-02 23:28:11 +01:00
popout _untranslateoption _text : "Перекласти назад" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "перекладений"
} ;
case "ja" : //japanese
return {
context _messagetranslateoption _text : "メッセージを翻訳する" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "メッセージを翻訳する" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "翻訳の検索" ,
popout _translateoption _text : "翻訳" ,
2019-01-02 23:28:11 +01:00
popout _untranslateoption _text : "翻訳する" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "翻訳された"
} ;
case "zh-TW" : //chinese (traditional)
return {
context _messagetranslateoption _text : "翻譯消息" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "翻譯消息" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "搜索翻譯" ,
popout _translateoption _text : "翻譯" ,
2019-01-02 23:28:11 +01:00
popout _untranslateoption _text : "翻譯回來" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "翻譯"
} ;
case "ko" : //korean
return {
context _messagetranslateoption _text : "메시지 번역" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "메시지 번역 뒤로" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "검색 번역" ,
2019-01-02 23:28:11 +01:00
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" ,
2019-01-02 23:28:11 +01:00
context _messageuntranslateoption _text : "Untranslate Message" ,
2018-10-11 10:21:26 +02:00
context _googletranslateoption _text : "Search translation" ,
popout _translateoption _text : "Translate" ,
2019-01-02 23:28:11 +01:00
popout _untranslateoption _text : "Untranslate" ,
2018-10-11 10:21:26 +02:00
translated _watermark _text : "translated"
} ;
}
}
}