2020-02-27 08:44:03 +01:00
//META{"name":"PluginRepo","authorId":"278543574059057154","invite":"Jx3TjNS","donate":"https://www.paypal.me/MircoWittrien","patreon":"https://www.patreon.com/MircoWittrien","website":"https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/PluginRepo","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/PluginRepo/PluginRepo.plugin.js"}*//
2018-10-11 10:21:26 +02:00
2020-02-10 15:05:58 +01:00
var PluginRepo = ( _ => {
2020-02-10 15:53:30 +01:00
var loading , cachedPlugins , grabbedPlugins , foundPlugins , loadedPlugins , updateInterval ;
2020-02-10 15:05:58 +01:00
const pluginStates = {
UPDATED : 0 ,
OUTDATED : 1 ,
DOWNLOADABLE : 2
} ;
const buttonData = {
UPDATED : {
colorClass : "GREEN" ,
backgroundColor : "STATUS_GREEN" ,
text : "Updated"
} ,
OUTDATED : {
colorClass : "RED" ,
backgroundColor : "STATUS_RED" ,
text : "Outdated"
} ,
DOWNLOADABLE : {
colorClass : "BRAND" ,
backgroundColor : "BRAND" ,
text : "Download"
2019-04-16 09:52:09 +02:00
}
2020-02-10 15:05:58 +01:00
} ;
const favStates = {
FAVORIZED : 0 ,
NOT _FAVORIZED : 1
} ;
const newStates = {
NEW : 0 ,
NOT _NEW : 1
} ;
const sortKeys = {
NAME : "Name" ,
AUTHOR : "Author" ,
VERSION : "Version" ,
DESCRIPTION : "Description" ,
STATE : "Update State" ,
FAV : "Favorites" ,
NEW : "New Plugins"
} ;
const orderKeys = {
ASC : "Ascending" ,
DESC : "Descending"
} ;
const pluginRepoIcon = ` <svg width="34" height="31" viewBox="0 0 400 382"><path d="M0.000 183.023 L 0.000 366.046 46.377 366.046 L 92.754 366.046 92.754 312.629 L 92.754 259.213 127.223 259.213 C 174.433 259.213,187.432 257.146,210.766 245.926 C 311.105 197.681,301.344 41.358,195.859 7.193 C 173.603 -0.015,173.838 0.000,80.846 0.000 L 0.000 0.000 0.000 183.023 M157.615 88.195 C 193.007 97.413,198.827 152.678,166.407 171.674 C 158.993 176.019,155.494 176.398,122.807 176.398 L 92.754 176.398 92.754 131.677 L 92.754 86.957 122.807 86.957 C 146.807 86.957,153.819 87.206,157.615 88.195" stroke="none" fill="#7289da" fill-rule="evenodd"></path><path d="M226.647 3.824 C 258.085 21.580,282.721 54.248,291.095 89.281 C 292.183 93.834,293.041 95.659,294.560 96.655 C 310.880 107.348,312.400 140.701,297.286 156.464 C 293.685 160.221,293.134 161.348,291.162 169.006 C 282.026 204.468,259.916 235.185,230.701 253.002 C 229.548 253.705,235.510 262.261,270.237 309.731 L 311.131 365.631 355.565 365.846 L 400.000 366.060 400.000 348.309 L 400.000 330.557 364.338 285.630 L 328.676 240.703 333.494 238.892 C 373.356 223.907,395.248 189.691,399.313 136.020 C 404.504 67.495,372.510 19.710,311.375 4.675 C 294.592 0.548,287.694 -0.000,252.482 0.000 L 219.876 0.000 226.647 3.824 M202.899 265.964 C 183.869 272.635,168.536 274.960,139.752 275.540 L 116.770 276.003 116.770 321.024 L 116.770 366.046 163.975 366.046 L 211.180 366.046 211.180 314.700 C 211.180 286.460,210.901 263.386,210.559 263.425 C 210.217 263.464,206.770 264.607,202.899 265.964" stroke="none" fill="#7f8186" fill-rule="evenodd"></path></svg> ` ;
const repoListComponent = class PluginList extends BdApi . React . Component {
render ( ) {
let list = BDFDB . ReactUtils . createElement ( "ul" , {
className : BDFDB . disCN . _repolist ,
style : {
display : "flex" ,
flexDirection : "column" ,
margin : "unset" ,
width : "unset"
} ,
2020-02-10 17:05:29 +01:00
children : [ ] . concat ( this . props . entries ) . filter ( n => n ) . map ( entry => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . AddonCard , entry ) )
2020-02-10 15:05:58 +01:00
} ) ;
BDFDB . ReactUtils . forceStyle ( list , [ "display" , "flex-direction" , "margin" , "width" ] ) ;
return list ;
2018-10-11 10:21:26 +02:00
}
2020-02-10 15:05:58 +01:00
} ;
return class PluginRepo {
getName ( ) { return "PluginRepo" ; }
2019-01-26 22:45:19 +01:00
2020-03-29 22:40:13 +02:00
getVersion ( ) { return "1.9.5" ; }
2018-10-11 10:21:26 +02:00
2020-02-10 15:05:58 +01:00
getAuthor ( ) { return "DevilBro" ; }
2018-10-11 10:21:26 +02:00
2020-02-10 15:05:58 +01:00
getDescription ( ) { return "Allows you to look at all plugins from the plugin repo and download them on the fly. Repo button is in the plugins settings." ; }
2019-01-26 22:45:19 +01:00
2020-03-26 20:20:37 +01:00
constructor ( ) {
2020-02-10 15:05:58 +01:00
this . patchedModules = {
after : {
V2C _ContentColumn : "render"
}
} ;
2019-05-26 13:55:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
initConstructor ( ) {
loading = { is : false , timeout : null , amount : 0 } ;
cachedPlugins = [ ] ;
grabbedPlugins = [ ] ;
foundPlugins = [ ] ;
loadedPlugins = { } ;
this . defaults = {
settings : {
useChromium : { value : false , description : "Use an inbuilt browser window instead of opening your default browser" } ,
notifyOutdated : { value : true , description : "Notifies you when one of your Plugins is outdated" } ,
notifyNewentries : { value : true , description : "Notifies you when there are new entries in the Repo" }
} ,
modalSettings : {
updated : { value : true , modify : true , description : "Show updated Plugins" , } ,
outdated : { value : true , modify : true , description : "Show outdated Plugins" } ,
downloadable : { value : true , modify : true , description : "Show downloadable Plugins" } ,
rnmStart : { value : true , modify : false , description : "Start Plugin after Download" }
}
} ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
this . css = `
. $ { this . name } - modal . repo - modal {
max - width : 800 px ;
min - height : 90 vh ;
max - height : 90 vh ;
}
` ;
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
getSettingsPanel ( collapseStates = { } ) {
if ( ! window . BDFDB || typeof BDFDB != "object" || ! BDFDB . loaded || ! this . started ) return ;
let settings = BDFDB . DataUtils . get ( this , "settings" ) ;
let customList = this . getCustomList ( ) , customUrl = "" ;
2020-03-28 07:55:39 +01:00
let settingsPanel , settingsItems = [ ] ;
2020-02-10 15:05:58 +01:00
2020-03-28 07:55:39 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-10 15:05:58 +01:00
title : "Settings" ,
collapseStates : collapseStates ,
children : Object . keys ( settings ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom8 ,
type : "Switch" ,
plugin : this ,
keys : [ "settings" , key ] ,
label : this . defaults . settings [ key ] . description ,
value : settings [ key ]
} ) )
} ) ) ;
2020-03-28 07:55:39 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-10 15:05:58 +01:00
title : "Custom Plugins" ,
collapseStates : collapseStates ,
dividertop : true ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Add Plugin:" ,
tag : BDFDB . LibraryComponents . FormComponents . FormTitleTags . H3 ,
className : BDFDB . disCNS . margintop4 + BDFDB . disCN . marginbottom8 ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
placeholder : customUrl ,
placeholder : "Insert Raw Github Link of Plugin (https://raw.githubusercontent.com/...)" ,
onChange : value => { customUrl = value . trim ( ) ; }
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
onClick : _ => {
if ( customUrl ) {
customList . push ( customUrl ) ;
BDFDB . DataUtils . save ( BDFDB . ArrayUtils . removeCopies ( customList ) , this , "custom" ) ;
2020-03-28 07:55:39 +01:00
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
2020-02-10 15:05:58 +01:00
}
} ,
children : BDFDB . LanguageUtils . LanguageStrings . ADD
} )
]
} )
} ) ,
customList . length ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelInner , {
title : "Custom Plugin List:" ,
className : BDFDB . disCNS . margintop8 + BDFDB . disCN . marginbottom20 ,
first : true ,
last : true ,
children : customList . map ( url => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Card , {
children : url ,
onRemove : _ => {
BDFDB . ArrayUtils . remove ( customList , url , true ) ;
BDFDB . DataUtils . save ( customList , this , "custom" ) ;
2020-03-28 07:55:39 +01:00
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
2020-02-10 15:05:58 +01:00
}
} ) )
} ) : null ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Button" ,
color : BDFDB . LibraryComponents . Button . Colors . RED ,
label : "Remove all custom added Plugins" ,
onClick : _ => {
BDFDB . ModalUtils . confirm ( this , "Are you sure you want to remove all added Plugins from your own list" , _ => {
BDFDB . DataUtils . save ( [ ] , this , "custom" ) ;
2020-03-28 07:55:39 +01:00
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
2020-02-10 15:05:58 +01:00
} ) ;
} ,
children : BDFDB . LanguageUtils . LanguageStrings . REMOVE
} )
] . flat ( 10 ) . filter ( n => n )
} ) ) ;
2020-03-28 07:55:39 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-10 15:05:58 +01:00
title : "Refetch All" ,
collapseStates : collapseStates ,
dividertop : true ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Button" ,
label : "Force all Plugins to be fetched again" ,
onClick : _ => {
loading = { is : false , timeout : null , amount : 0 } ;
this . loadPlugins ( ) ;
} ,
children : BDFDB . LanguageUtils . LanguageStrings . ERRORS _RELOAD
} )
} ) ) ;
2020-03-28 07:55:39 +01:00
return settingsPanel = BDFDB . PluginUtils . createSettingsPanel ( this , settingsItems ) ;
2018-10-11 10:21:26 +02:00
}
2020-02-10 15:05:58 +01:00
//legacy
load ( ) { }
start ( ) {
if ( ! window . BDFDB ) window . BDFDB = { myPlugins : { } } ;
if ( window . BDFDB && window . BDFDB . myPlugins && typeof window . BDFDB . myPlugins == "object" ) window . BDFDB . myPlugins [ this . getName ( ) ] = this ;
let libraryScript = document . querySelector ( "head script#BDFDBLibraryScript" ) ;
if ( ! libraryScript || ( performance . now ( ) - libraryScript . getAttribute ( "date" ) ) > 600000 ) {
if ( libraryScript ) libraryScript . remove ( ) ;
libraryScript = document . createElement ( "script" ) ;
libraryScript . setAttribute ( "id" , "BDFDBLibraryScript" ) ;
libraryScript . setAttribute ( "type" , "text/javascript" ) ;
libraryScript . setAttribute ( "src" , "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js" ) ;
libraryScript . setAttribute ( "date" , performance . now ( ) ) ;
libraryScript . addEventListener ( "load" , _ => { this . initialize ( ) ; } ) ;
document . head . appendChild ( libraryScript ) ;
}
else if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) this . initialize ( ) ;
this . startTimeout = setTimeout ( _ => {
try { return this . initialize ( ) ; }
catch ( err ) { console . error ( ` %c[ ${ this . getName ( ) } ]%c ` , "color: #3a71c1; font-weight: 700;" , "" , "Fatal Error: Could not initiate plugin! " + err ) ; }
} , 30000 ) ;
}
2018-10-11 10:21:26 +02:00
2020-02-10 15:05:58 +01:00
initialize ( ) {
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
if ( this . started ) return ;
BDFDB . PluginUtils . init ( this ) ;
2020-02-13 13:59:37 +01:00
// REMOVE 10.02.2020
2020-02-10 15:05:58 +01:00
let olddata = BDFDB . DataUtils . load ( this , "ownlist" , "ownlist" ) ;
if ( olddata ) {
BDFDB . DataUtils . save ( olddata , this , "custom" ) ;
BDFDB . DataUtils . remove ( this , "ownlist" ) ;
}
2019-10-22 11:37:23 +02:00
2020-02-10 15:05:58 +01:00
this . loadPlugins ( ) ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
updateInterval = BDFDB . TimeUtils . interval ( _ => { this . checkForNewPlugins ( ) ; } , 1000 * 60 * 30 ) ;
2019-09-04 12:34:02 +02:00
2020-02-10 15:05:58 +01:00
BDFDB . ModuleUtils . forceAllUpdates ( this ) ;
2019-04-07 21:23:38 +02:00
}
2020-02-10 15:05:58 +01:00
else console . error ( ` %c[ ${ this . getName ( ) } ]%c ` , "color: #3a71c1; font-weight: 700;" , "" , "Fatal Error: Could not load BD functions!" ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
stop ( ) {
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
this . stopping = true ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
BDFDB . TimeUtils . clear ( updateInterval ) ;
BDFDB . TimeUtils . clear ( loading . timeout ) ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
BDFDB . ModuleUtils . forceAllUpdates ( this ) ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
BDFDB . DOMUtils . remove ( ".bd-pluginrepobutton" , ".pluginrepo-notice" , ".pluginrepo-loadingicon" ) ;
let frame = document . querySelector ( "iframe.discordSandbox" ) ;
if ( frame ) {
window . removeEventListener ( "message" , frame . messageReceived ) ;
BDFDB . DOMUtils . remove ( frame ) ;
}
BDFDB . PluginUtils . clear ( this ) ;
2018-10-11 10:21:26 +02:00
}
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
// begin of own functions
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
onUserSettingsCogContextMenu ( e ) {
BDFDB . TimeUtils . timeout ( _ => {
let [ children , index ] = BDFDB . ReactUtils . findChildren ( e . returnvalue , { props : [ [ "label" , "BandagedBD" ] ] } ) ;
if ( index > - 1 ) children [ index ] . props . render . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . ContextMenuItems . Item , {
label : "Plugin Repo" ,
action : _ => {
if ( ! loading . is ) BDFDB . ContextMenuUtils . close ( e . instance ) ;
this . openPluginRepoModal ( ) ;
}
} ) ) ;
} ) ;
2019-04-16 09:52:09 +02:00
}
2020-02-10 15:05:58 +01:00
processV2CContentColumn ( e ) {
2020-03-26 20:20:37 +01:00
if ( typeof e . instance . props . title == "string" && e . instance . props . title . toUpperCase ( ) . indexOf ( "PLUGINS" ) == 0 ) {
2020-02-10 15:05:58 +01:00
let [ children , index ] = BDFDB . ReactUtils . findChildren ( e . returnvalue , { key : "folder-button" } ) ;
if ( index > - 1 ) children . splice ( index + 1 , 0 , BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : "Open Plugin Repo" ,
children : BDFDB . ReactUtils . createElement ( "button" , {
2020-03-26 20:20:37 +01:00
className : ` ${ BDFDB . disCNS . _repobutton + BDFDB . disCN . _repofolderbutton } bd-pluginrepobutton ` ,
2020-02-10 15:05:58 +01:00
onClick : _ => { this . openPluginRepoModal ( ) ; } ,
children : "PluginRepo"
} )
} ) ) ;
2019-01-14 18:55:51 +01:00
}
2019-01-07 20:25:35 +01:00
}
2020-02-10 15:05:58 +01:00
getCustomList ( ) {
let customlist = BDFDB . DataUtils . load ( this , "custom" ) ;
return BDFDB . ArrayUtils . is ( customlist ) ? customlist : [ ] ;
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
openPluginRepoModal ( options = { } ) {
if ( loading . is ) BDFDB . NotificationUtils . toast ( ` Plugins are still being fetched. Try again in some seconds. ` , { type : "danger" } ) ;
else {
2020-02-10 15:53:30 +01:00
let modalSettings = BDFDB . DataUtils . get ( this , "modalSettings" ) ;
let searchTimeout , automaticLoading = BDFDB . BDUtils . isAutoLoadEnabled ( ) ;
options = Object . assign ( options , modalSettings ) ;
options . updated = options . updated && ! options . showOnlyOutdated ;
options . outdated = options . updated || options . showOnlyOutdated ;
options . downloadable = options . downloadable && ! options . showOnlyOutdated ;
options . searchString = "" ;
options . sortKey = options . forcedSort || Object . keys ( sortKeys ) [ 0 ] ;
options . orderKey = options . forcedOrder || Object . keys ( orderKeys ) [ 0 ] ;
let entries = this . createEntries ( options ) ;
2020-02-10 15:05:58 +01:00
BDFDB . ModalUtils . open ( this , {
className : "repo-modal" ,
size : "LARGE" ,
header : "Plugin Repository" ,
subheader : BDFDB . ReactUtils . createElement ( class RepoAmount extends BDFDB . ReactUtils . Component {
render ( ) { return ` ${ this . props . entries . length } / ${ Object . keys ( loadedPlugins ) . length } Plugins ` }
} , { entries } ) ,
tabBarChildren : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SearchBar , {
autoFocus : true ,
2020-02-10 15:53:30 +01:00
query : options . searchString ,
2020-02-10 15:05:58 +01:00
onChange : ( value , instance ) => {
BDFDB . TimeUtils . clear ( searchTimeout ) ;
searchTimeout = BDFDB . TimeUtils . timeout ( _ => {
2020-02-10 15:53:30 +01:00
options . searchString = value . replace ( /[<|>]/g , "" ) . toUpperCase ( ) ;
this . updateList ( instance , options ) ;
2020-02-10 15:05:58 +01:00
} , 1000 ) ;
} ,
onClear : instance => {
2020-02-10 15:53:30 +01:00
options . searchString = "" ;
this . updateList ( instance , options ) ;
2020-02-10 15:05:58 +01:00
}
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . QuickSelect , {
label : "Sort by:" ,
value : {
2020-02-10 15:53:30 +01:00
label : sortKeys [ options . sortKey ] ,
value : options . sortKey
2020-02-10 15:05:58 +01:00
} ,
2020-03-15 11:08:37 +01:00
options : Object . keys ( sortKeys ) . filter ( n => n != "NEW" || Object . keys ( loadedPlugins ) . some ( p => ! cachedPlugins . includes ( p ) ) ) . map ( key => ( {
2020-02-10 15:05:58 +01:00
label : sortKeys [ key ] ,
value : key
2020-03-15 11:06:38 +01:00
} ) ) ,
2020-02-10 15:05:58 +01:00
onChange : ( key , instance ) => {
2020-02-10 15:53:30 +01:00
options . sortKey = key ;
this . updateList ( instance , options ) ;
2020-02-10 15:05:58 +01:00
}
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . QuickSelect , {
label : "Order:" ,
value : {
2020-02-10 15:53:30 +01:00
label : orderKeys [ options . orderKey ] ,
value : options . orderKey
2020-02-10 15:05:58 +01:00
} ,
2020-03-15 11:06:38 +01:00
options : Object . keys ( orderKeys ) . map ( key => ( {
2020-02-10 15:05:58 +01:00
label : orderKeys [ key ] ,
value : key
2020-03-15 11:06:38 +01:00
} ) ) ,
2020-02-10 15:05:58 +01:00
onChange : ( key , instance ) => {
2020-02-10 15:53:30 +01:00
options . orderKey = key ;
this . updateList ( instance , options ) ;
2020-02-10 15:05:58 +01:00
}
} )
} )
] ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . ModalComponents . ModalTabContent , {
tab : "Plugins" ,
children : BDFDB . ReactUtils . createElement ( repoListComponent , {
plugin : this ,
entries : entries
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . ModalComponents . ModalTabContent , {
tab : BDFDB . LanguageUtils . LanguageStrings . SETTINGS ,
children : [
! automaticLoading && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom20 ,
children : BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCNS . titledefault + BDFDB . disCN . cursordefault ,
style : { maxWidth : 760 } ,
children : "To experience PluginRepo in the best way. I would recommend you to enable BD intern reload function, that way all downloaded files are loaded into Discord without the need to reload."
} )
} ) ,
Object . keys ( modalSettings ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom20 ,
type : "Switch" ,
plugin : this ,
keys : [ "modalSettings" , key ] ,
label : this . defaults . modalSettings [ key ] . description ,
note : key == "rnmStart" && ! automaticLoading && "Automatic Loading has to be enabled" ,
disabled : key == "rnmStart" && ! automaticLoading ,
2020-02-10 15:53:30 +01:00
value : options [ key ] ,
2020-02-10 15:05:58 +01:00
onChange : ( value , instance ) => {
2020-02-10 15:53:30 +01:00
options [ key ] = value ;
this . updateList ( instance , options ) ;
2020-02-10 15:05:58 +01:00
}
} ) )
] . flat ( 10 ) . filter ( n => n )
} )
]
} ) ;
2019-01-14 18:55:51 +01:00
}
2020-02-10 15:05:58 +01:00
}
2020-02-10 15:53:30 +01:00
updateList ( instance , options = { } ) {
2020-02-10 15:05:58 +01:00
let modalIns = BDFDB . ReactUtils . findOwner ( instance , { name : "BDFDB_Modal" , up : true } ) ;
if ( modalIns ) {
2020-02-10 17:05:29 +01:00
let listIns = BDFDB . ReactUtils . findOwner ( modalIns , { name : "PluginList" } ) ;
2020-02-10 15:05:58 +01:00
let amountIns = BDFDB . ReactUtils . findOwner ( modalIns , { name : "RepoAmount" } ) ;
if ( listIns && amountIns ) {
2020-02-10 15:53:30 +01:00
let entries = this . createEntries ( options ) ;
2020-02-10 15:05:58 +01:00
listIns . props . entries = entries ;
amountIns . props . entries = entries ;
BDFDB . ReactUtils . forceUpdate ( listIns , amountIns ) ;
}
2019-01-14 18:55:51 +01:00
}
2020-02-10 15:05:58 +01:00
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:53:30 +01:00
createEntries ( options = { } ) {
2020-02-10 15:05:58 +01:00
let favorites = BDFDB . DataUtils . load ( this , "favorites" ) ;
let plugins = Object . keys ( loadedPlugins ) . map ( url => {
let plugin = loadedPlugins [ url ] ;
let instPlugin = BDFDB . BDUtils . getPlugin ( plugin . getName ) ;
if ( instPlugin && typeof instPlugin . getAuthor == "function" && this . getString ( instPlugin . getAuthor ( ) ) . toUpperCase ( ) == plugin . getAuthor . toUpperCase ( ) ) plugin . getState = this . getString ( instPlugin . getVersion ( ) ) != plugin . getVersion ? pluginStates . OUTDATED : pluginStates . UPDATED ;
else plugin . getState = pluginStates . DOWNLOADABLE ;
return {
url : plugin . url ,
search : ( plugin . getName + " " + plugin . getVersion + " " + plugin . getAuthor + " " + plugin . getDescription ) . toUpperCase ( ) ,
name : plugin . getName ,
version : plugin . getVersion ,
author : plugin . getAuthor ,
2020-02-10 17:05:29 +01:00
description : plugin . getDescription || "No Description found." ,
2020-02-10 15:05:58 +01:00
fav : favorites [ url ] ? favStates . FAVORIZED : favStates . NOT _FAVORIZED ,
new : ! cachedPlugins . includes ( url ) ? newStates . NEW : newStates . NOT _NEW ,
state : plugin . getState
} ;
} ) ;
2020-03-15 15:46:55 +01:00
if ( ! options . updated ) plugins = plugins . filter ( plugin => plugin . state != pluginStates . UPDATED ) ;
if ( ! options . outdated ) plugins = plugins . filter ( plugin => plugin . state != pluginStates . OUTDATED ) ;
if ( ! options . downloadable ) plugins = plugins . filter ( plugin => plugin . state != pluginStates . DOWNLOADABLE ) ;
2020-02-10 15:53:30 +01:00
if ( options . searchString ) plugins = plugins . filter ( plugin => plugin . search . indexOf ( options . searchString ) > - 1 ) . map ( plugin => Object . assign ( { } , plugin , {
name : BDFDB . ReactUtils . elementToReact ( BDFDB . DOMUtils . create ( BDFDB . StringUtils . highlight ( plugin . name , options . searchString ) ) ) || plugin . name ,
version : BDFDB . ReactUtils . elementToReact ( BDFDB . DOMUtils . create ( BDFDB . StringUtils . highlight ( plugin . version , options . searchString ) ) ) || plugin . version ,
author : BDFDB . ReactUtils . elementToReact ( BDFDB . DOMUtils . create ( BDFDB . StringUtils . highlight ( plugin . author , options . searchString ) ) ) || plugin . author ,
description : BDFDB . ReactUtils . elementToReact ( BDFDB . DOMUtils . create ( BDFDB . StringUtils . highlight ( plugin . description , options . searchString ) ) ) || plugin . description
2020-02-10 15:05:58 +01:00
} ) ) ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:53:30 +01:00
BDFDB . ArrayUtils . keySort ( plugins , ( options . sortKey == "NEW" && ! plugins . some ( plugin => plugin . new == newStates . NEW ) ? Object . keys ( sortKeys ) [ 0 ] : options . sortKey ) . toLowerCase ( ) ) ;
if ( options . orderKey == "DESC" ) plugins . reverse ( ) ;
2020-02-10 15:05:58 +01:00
return plugins . map ( plugin => {
let buttonConfig = buttonData [ ( Object . entries ( pluginStates ) . find ( n => n [ 1 ] == plugin . state ) || [ ] ) [ 0 ] ]
return buttonConfig && {
data : plugin ,
controls : [
2020-02-11 17:11:59 +01:00
plugin . new == newStates . NEW && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Badges . TextBadge , {
2020-02-10 15:05:58 +01:00
style : {
borderRadius : 3 ,
textTransform : "uppercase" ,
background : BDFDB . DiscordConstants . Colors . STATUS _YELLOW
} ,
text : BDFDB . LanguageUtils . LanguageStrings . NEW
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FavButton , {
className : BDFDB . disCNS . _repoentryiconwrapper + BDFDB . disCN . cursorpointer ,
isFavorite : plugin . fav == favStates . FAVORIZED ,
onClick : value => {
plugin . fav = value ? favStates . FAVORIZED : favStates . NOT _FAVORIZED ;
if ( value ) BDFDB . DataUtils . save ( true , this , "favorites" , plugin . url ) ;
else BDFDB . DataUtils . remove ( this , "favorites" , plugin . url ) ;
}
} ) ,
2020-03-29 22:40:13 +02:00
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _repocontrolsbutton ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : "Go to Source" ,
2020-02-10 15:05:58 +01:00
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
2020-03-29 22:40:13 +02:00
name : BDFDB . LibraryComponents . SvgIcon . Names . GITHUB ,
className : BDFDB . disCN . _repoicon ,
onClick : _ => {
let giturl = null ;
if ( plugin . url . indexOf ( "https://raw.githubusercontent.com" ) == 0 ) {
let temp = plugin . url . replace ( "//raw.githubusercontent" , "//github" ) . split ( "/" ) ;
temp . splice ( 5 , 0 , "blob" ) ;
giturl = temp . join ( "/" ) ;
}
else if ( plugin . url . indexOf ( "https://gist.githubusercontent.com/" ) == 0 ) {
giturl = plugin . url . replace ( "//gist.githubusercontent" , "//gist.github" ) . split ( "/raw/" ) [ 0 ] ;
}
if ( giturl ) BDFDB . DiscordUtils . openLink ( giturl , BDFDB . DataUtils . get ( this , "settings" , "useChromium" ) ) ;
}
2020-02-10 15:05:58 +01:00
} )
} )
2020-03-29 22:40:13 +02:00
} ) ,
2020-02-10 15:05:58 +01:00
] ,
buttons : [
2020-03-29 22:40:13 +02:00
plugin . state != pluginStates . DOWNLOADABLE && BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _repocontrolsbutton ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : "Delete Pluginfile" ,
2020-02-10 15:05:58 +01:00
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
2020-03-29 22:40:13 +02:00
name : BDFDB . LibraryComponents . SvgIcon . Names . NOVA _TRASH ,
className : BDFDB . disCN . _repoicon ,
onClick : ( e , instance ) => {
this . deletePluginFile ( plugin ) ;
BDFDB . TimeUtils . timeout ( _ => {
this . updateList ( instance , options ) ;
if ( ! BDFDB . BDUtils . isAutoLoadEnabled ( ) ) this . stopPlugin ( plugin ) ;
} , 3000 ) ;
}
} )
2020-02-10 15:05:58 +01:00
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
size : BDFDB . LibraryComponents . Button . Sizes . MIN ,
color : BDFDB . LibraryComponents . Button . Colors [ buttonConfig . colorClass ] ,
style : { backgroundColor : BDFDB . DiscordConstants . Colors [ buttonConfig . backgroundColor ] } ,
children : buttonConfig . text ,
onClick : ( e , instance ) => {
this . downloadPlugin ( plugin ) ;
BDFDB . TimeUtils . timeout ( _ => {
2020-02-10 15:53:30 +01:00
this . updateList ( instance , options ) ;
if ( options . rnmStart ) this . startPlugin ( plugin ) ;
2020-02-10 15:05:58 +01:00
} , 3000 ) ;
}
} )
]
} ;
} ) . filter ( n => n ) ;
2019-01-07 20:25:35 +01:00
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
loadPlugins ( ) {
BDFDB . DOMUtils . remove ( "iframe.discordSandbox" , ".pluginrepo-loadingicon" ) ;
let settings = BDFDB . DataUtils . load ( this , "settings" ) ;
2020-03-04 10:58:44 +01:00
let getPluginInfo , extractConfigInfo , createFrame , runInFrame ;
2020-02-10 15:05:58 +01:00
let frame , framerunning = false , framequeue = [ ] , outdated = 0 , newentries = 0 , i = 0 ;
let tags = [ "getName" , "getVersion" , "getAuthor" , "getDescription" ] ;
let seps = [ "\"" , "\'" , "\`" ] ;
let newentriesdata = BDFDB . DataUtils . load ( this , "newentriesdata" ) , customList = this . getCustomList ( ) ;
cachedPlugins = ( newentriesdata . urlbase64 ? atob ( newentriesdata . urlbase64 ) . split ( "\n" ) : [ ] ) . concat ( customList ) ;
BDFDB . LibraryRequires . request ( "https://mwittrien.github.io/BetterDiscordAddons/Plugins/PluginRepo/res/PluginList.txt" , ( error , response , result ) => {
if ( ! error && result ) {
result = result . replace ( /[\r\t]/g , "" ) ;
BDFDB . DataUtils . save ( btoa ( result ) , this , "newentriesdata" , "urlbase64" ) ;
loadedPlugins = { } ;
grabbedPlugins = result . split ( "\n" ) . filter ( n => n ) ;
foundPlugins = grabbedPlugins . concat ( customList ) ;
loading = { is : true , timeout : BDFDB . TimeUtils . timeout ( _ => {
BDFDB . TimeUtils . clear ( loading . timeout ) ;
if ( this . started ) {
if ( loading . is && loading . amount < 4 ) BDFDB . TimeUtils . timeout ( _ => { this . loadPlugins ( ) ; } , 10000 ) ;
loading = { is : false , timeout : null , amount : loading . amount } ;
2018-11-25 19:54:05 +01:00
}
2020-02-10 15:05:58 +01:00
} , 1200000 ) , amount : loading . amount + 1 } ;
let loadingicon = BDFDB . DOMUtils . create ( pluginRepoIcon ) ;
BDFDB . DOMUtils . addClass ( loadingicon , "pluginrepo-loadingicon" ) ;
loadingicon . addEventListener ( "mouseenter" , _ => {
BDFDB . TooltipUtils . create ( loadingicon , this . getLoadingTooltipText ( ) , {
type : "left" ,
delay : 500 ,
style : "max-width: unset;" ,
selector : "pluginrepo-loading-tooltip"
} ) ;
} ) ;
BDFDB . PluginUtils . addLoadingIcon ( loadingicon ) ;
createFrame ( ) . then ( _ => {
getPluginInfo ( _ => {
if ( ! this . started ) {
BDFDB . TimeUtils . clear ( loading . timeout ) ;
BDFDB . DOMUtils . remove ( frame ) ;
2019-04-07 21:17:10 +02:00
if ( frame && frame . messageReceived ) window . removeEventListener ( "message" , frame . messageReceived ) ;
2020-02-10 15:05:58 +01:00
return ;
}
let finishCounter = 0 , finishInterval = BDFDB . TimeUtils . interval ( _ => {
if ( ( framequeue . length == 0 && ! framerunning ) || finishCounter > 300 || ! loading . is ) {
BDFDB . TimeUtils . clear ( loading . timeout ) ;
BDFDB . TimeUtils . clear ( finishInterval ) ;
BDFDB . DOMUtils . remove ( frame , loadingicon , ".pluginrepo-loadingicon" ) ;
if ( frame && frame . messageReceived ) window . removeEventListener ( "message" , frame . messageReceived ) ;
loading = { is : false , timeout : null , amount : loading . amount } ;
BDFDB . LogUtils . log ( "Finished fetching Plugins." , this . name ) ;
if ( document . querySelector ( ".bd-pluginrepobutton" ) ) BDFDB . NotificationUtils . toast ( ` Finished fetching Plugins. ` , { type : "success" } ) ;
if ( ( settings . notifyOutdated || settings . notifyOutdated == undefined ) && outdated > 0 ) {
let oldbarbutton = document . querySelector ( ".pluginrepo-outdate-notice " + BDFDB . dotCN . noticedismiss ) ;
if ( oldbarbutton ) oldbarbutton . click ( ) ;
let bar = BDFDB . NotificationUtils . notice ( ` ${ outdated } of your Plugins ${ outdated == 1 ? "is" : "are" } outdated. Check: ` , {
type : "danger" ,
btn : "PluginRepo" ,
selector : "pluginrepo-notice pluginrepo-outdate-notice" ,
customicon : pluginRepoIcon . replace ( /#7289da/gi , "#FFF" ) . replace ( /#7f8186/gi , "#B9BBBE" )
} ) ;
bar . querySelector ( BDFDB . dotCN . noticebutton ) . addEventListener ( "click" , _ => {
this . openPluginRepoModal ( { showOnlyOutdated : true } ) ;
bar . querySelector ( BDFDB . dotCN . noticedismiss ) . click ( ) ;
} ) ;
}
if ( ( settings . notifyNewentries || settings . notifyNewentries == undefined ) && newentries > 0 ) {
let oldbarbutton = document . querySelector ( ".pluginrepo-newentries-notice " + BDFDB . dotCN . noticedismiss ) ;
if ( oldbarbutton ) oldbarbutton . click ( ) ;
let single = newentries == 1 ;
let bar = BDFDB . NotificationUtils . notice ( ` There ${ single ? "is" : "are" } ${ newentries } new Plugin ${ single ? "" : "s" } in the Repo. Check: ` , {
type : "success" ,
btn : "PluginRepo" ,
selector : "pluginrepo-notice pluginrepo-newentries-notice" ,
customicon : pluginRepoIcon . replace ( /#7289da/gi , "#FFF" ) . replace ( /#7f8186/gi , "#B9BBBE" )
} ) ;
bar . querySelector ( BDFDB . dotCN . noticebutton ) . addEventListener ( "click" , _ => {
this . openPluginRepoModal ( { forcedSort : "NEW" , forcedOrder : "ASC" } ) ;
bar . querySelector ( BDFDB . dotCN . noticedismiss ) . click ( ) ;
2018-11-03 21:25:45 +01:00
} ) ;
}
2020-02-10 15:05:58 +01:00
if ( BDFDB . UserUtils . me . id == "278543574059057154" ) {
let wrongUrls = [ ] ;
for ( let url of foundPlugins ) if ( url && ! loadedPlugins [ url ] && ! wrongUrls . includes ( url ) ) wrongUrls . push ( url ) ;
if ( wrongUrls . length ) {
let bar = BDFDB . NotificationUtils . notice ( ` PluginRepo: ${ wrongUrls . length } Plugin ${ wrongUrls . length > 1 ? "s" : "" } could not be loaded. ` , {
type : "danger" ,
btn : "List" ,
selector : "pluginrepo-notice pluginrepo-fail-notice" ,
customicon : pluginRepoIcon . replace ( /#7289da/gi , "#FFF" ) . replace ( /#7f8186/gi , "#B9BBBE" )
} ) ;
bar . querySelector ( BDFDB . dotCN . noticebutton ) . addEventListener ( "click" , e => {
let toast = BDFDB . NotificationUtils . toast ( wrongUrls . join ( "\n" ) , { type : "error" } ) ;
toast . style . setProperty ( "overflow" , "hidden" ) ;
for ( let url of wrongUrls ) console . log ( url ) ;
} ) ;
}
}
2018-11-03 21:25:45 +01:00
}
2020-02-10 15:05:58 +01:00
else finishCounter ++ ;
} , 1000 ) ;
} ) ;
2018-11-03 21:25:45 +01:00
} ) ;
2020-02-10 15:05:58 +01:00
}
} ) ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
getPluginInfo = ( callback ) => {
if ( i >= foundPlugins . length || ! this . started || ! loading . is ) {
callback ( ) ;
return ;
2018-10-18 12:10:34 +02:00
}
2020-02-10 15:05:58 +01:00
let url = foundPlugins [ i ] ;
BDFDB . LibraryRequires . request ( url , ( error , response , body ) => {
if ( ! response ) {
if ( url && BDFDB . ArrayUtils . getAllIndexes ( foundPlugins , url ) . length < 2 ) foundPlugins . push ( url ) ;
2018-10-11 10:21:26 +02:00
}
2020-02-10 15:05:58 +01:00
else if ( body && body . indexOf ( "404: Not Found" ) != 0 && response . statusCode == 200 ) {
let plugin = { } ;
2020-03-04 10:58:44 +01:00
let bodyCopy = body ;
2020-02-10 15:05:58 +01:00
if ( body . length / body . split ( "\n" ) . length > 1000 ) {
/* code is minified -> add newlines */
2020-03-04 10:58:44 +01:00
bodyCopy = body . replace ( /}/g , "}\n" ) ;
2020-02-10 15:05:58 +01:00
}
2020-03-04 10:58:44 +01:00
let bodyWithoutSpecial = bodyCopy . replace ( /\n|\r|\t/g , "" ) ;
2020-03-09 22:03:40 +01:00
let configreg = /(\.exports|config)\s*=\s*\{["'`]*info["'`]*\s*:\s*/i . exec ( bodyWithoutSpecial ) ;
2020-02-10 15:05:58 +01:00
if ( url != "https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/PluginRepo/PluginRepo.plugin.js" && configreg ) {
try {
2020-03-09 22:03:40 +01:00
extractConfigInfo ( plugin , JSON . parse ( '{"info":' + bodyWithoutSpecial . substring ( configreg . index ) . split ( configreg [ 0 ] ) [ 1 ] . split ( "};" ) [ 0 ] . split ( "}}," ) [ 0 ] + '}' ) ) ;
2020-03-04 10:58:44 +01:00
}
catch ( err ) {
2020-03-09 22:03:40 +01:00
try { extractConfigInfo ( plugin , JSON . parse ( ( '{"info":' + bodyWithoutSpecial . substring ( configreg . index ) . split ( configreg [ 0 ] ) [ 1 ] . split ( "};" ) [ 0 ] . split ( "}}," ) [ 0 ] + '}' ) . replace ( /,/g , ',"' ) . replace ( /:/g , '":' ) . replace ( /{/g , '{"' ) . replace ( /""/g , '"' ) . replace ( /" /g , ' ' ) . replace ( /,"{/g , ',{' ) . replace ( /,"\[/g , ',[' ) . replace ( /":\/\//g , ':\/\/' ) ) ) ; }
2020-03-04 10:58:44 +01:00
catch ( err2 ) { }
2018-11-25 23:57:37 +01:00
}
2018-11-25 19:54:05 +01:00
}
2020-02-10 15:05:58 +01:00
else {
for ( let tag of tags ) {
2020-03-04 10:58:44 +01:00
let result = new RegExp ( tag + "[\\s|\\t|\\n|\\r|=|>|_|:|function|\(|\)|\{|return]*([\"|\'|\`]).*\\1" , "gi" ) . exec ( bodyCopy ) ;
if ( ! result ) result = new RegExp ( "get " + tag . replace ( "get" , "" ) . toLowerCase ( ) + "[\\s|\\t|\\n|\\r|=|>|_|:|function|\(|\)|\{|return]*([\"|\'|\`]).*\\1" , "gi" ) . exec ( bodyCopy ) ;
2020-02-10 15:05:58 +01:00
if ( result ) {
let separator = result [ 1 ] ;
result = result [ 0 ] . replace ( new RegExp ( "\\\\" + separator , "g" ) , separator ) . split ( separator ) ;
if ( result . length > 2 ) {
result = result . slice ( 1 , - 1 ) . join ( separator ) . replace ( /\\n/g , "<br>" ) . replace ( /\\/g , "" ) ;
result = tag != "getVersion" ? result . charAt ( 0 ) . toUpperCase ( ) + result . slice ( 1 ) : result ;
plugin [ tag ] = result ? result . trim ( ) : result ;
}
2018-11-25 19:54:05 +01:00
}
2018-10-11 10:21:26 +02:00
}
}
2020-02-10 15:05:58 +01:00
if ( ! tags . some ( tag => ! plugin [ tag ] || plugin [ tag ] . length > 10000 ) ) {
plugin . url = url ;
loadedPlugins [ url ] = plugin ;
2020-02-10 15:53:30 +01:00
if ( this . isPluginOutdated ( plugin , url ) ) outdated ++ ;
2020-02-10 15:05:58 +01:00
if ( ! cachedPlugins . includes ( url ) ) newentries ++ ;
}
else if ( frame && frame . contentWindow ) {
framequeue . push ( { body , url } ) ;
runInFrame ( ) ;
}
2018-10-11 10:21:26 +02:00
}
2020-02-10 15:05:58 +01:00
i ++ ;
let loadingtooltip = document . querySelector ( ".pluginrepo-loading-tooltip" ) ;
if ( loadingtooltip ) {
BDFDB . DOMUtils . setText ( loadingtooltip , this . getLoadingTooltipText ( ) ) ;
BDFDB . TooltipUtils . update ( loadingtooltip ) ;
2018-10-11 10:21:26 +02:00
}
2020-02-10 15:05:58 +01:00
getPluginInfo ( callback ) ;
} ) ;
2020-03-04 10:58:44 +01:00
} ;
extractConfigInfo = ( plugin , config ) => {
plugin . getName = BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( config . info . name ) ;
plugin . getDescription = BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( config . info . description ) ;
plugin . getVersion = config . info . version ;
plugin . getAuthor = "" ;
if ( typeof config . info . author == "string" ) plugin . getAuthor = BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( config . info . author ) ;
else if ( typeof config . info . authors == "string" ) plugin . getAuthor = BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( config . info . authors ) ;
else if ( Array . isArray ( config . info . authors ) ) for ( let author of config . info . authors ) {
plugin . getAuthor += ( plugin . getAuthor + ( plugin . getAuthor ? ", " : "" ) + BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( typeof author == "string" ? author : author . name || "" ) ) ;
}
} ;
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
createFrame = _ => {
return new Promise ( callback => {
frame = BDFDB . DOMUtils . create ( ` <iframe class="discordSandbox" style="position: absolute !important; opacity: 0 !important; pointer-events: none !important;" src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/DiscordPreview.html"></iframe> ` ) ;
frame . startTimeout = BDFDB . TimeUtils . timeout ( _ => {
callback ( ) ;
} , 600000 ) ;
frame . messageReceived = e => {
if ( ! document . contains ( frame ) ) {
window . removeEventListener ( "message" , frame . messageReceived ) ;
2019-04-07 21:17:10 +02:00
}
2020-02-10 15:05:58 +01:00
else if ( typeof e . data === "object" && e . data . origin == "DiscordPreview" ) {
switch ( e . data . reason ) {
case "OnLoad" :
frame . contentWindow . postMessage ( {
origin : "PluginRepo" ,
reason : "OnLoad" ,
classes : JSON . stringify ( BDFDB . DiscordClasses ) ,
classmodules : JSON . stringify ( BDFDB . DiscordClassModules )
} , "*" ) ;
callback ( ) ;
break ;
}
}
} ;
window . addEventListener ( "message" , frame . messageReceived ) ;
2019-09-04 12:34:02 +02:00
2020-02-10 15:05:58 +01:00
document . body . appendChild ( frame ) ;
} ) ;
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
runInFrame = _ => {
if ( framerunning ) return ;
let framedata = framequeue . shift ( ) ;
if ( ! framedata ) return ;
framerunning = true ;
let { body , url } = framedata ;
let name = body . replace ( /\s*:\s*/g , ":" ) . split ( '"name":"' ) ;
if ( name . length > 1 ) {
name = name [ 1 ] . split ( '"' ) [ 0 ] ;
let processResult = plugin => {
if ( BDFDB . ObjectUtils . is ( plugin ) ) {
plugin . url = url ;
loadedPlugins [ url ] = plugin ;
2020-02-10 15:53:30 +01:00
if ( this . isPluginOutdated ( plugin , url ) ) outdated ++ ;
2020-02-10 15:05:58 +01:00
if ( ! cachedPlugins . includes ( url ) ) newentries ++ ;
2019-04-07 21:17:10 +02:00
}
2020-02-10 15:05:58 +01:00
framerunning = false ;
runInFrame ( ) ;
} ;
let evalResultReceived = e => {
if ( typeof e . data === "object" && e . data . origin == "DiscordPreview" ) {
switch ( e . data . reason ) {
case "EvalResult" :
window . removeEventListener ( "message" , evalResultReceived ) ;
processResult ( e . data . result ) ;
break ;
}
}
} ;
window . addEventListener ( "message" , evalResultReceived ) ;
2020-03-04 10:58:44 +01:00
if ( frame . contentWindow ) frame . contentWindow . postMessage ( { origin : "PluginRepo" , reason : "Eval" , jsstring : `
2020-02-10 15:05:58 +01:00
try {
$ { body }
var p = new $ { name } ( ) ;
var data = {
"getName" : getString ( p . getName ( ) ) ,
"getAuthor" : getString ( p . getAuthor ( ) ) ,
"getVersion" : getString ( p . getVersion ( ) ) ,
"getDescription" : getString ( p . getDescription ( ) )
} ;
window . evalResult = data ;
}
catch ( err ) {
window . evalResult = null ;
} `
} , "*" ) ;
}
2018-11-03 21:25:45 +01:00
}
2018-11-03 18:03:47 +01:00
}
2019-09-04 12:34:02 +02:00
2020-02-10 15:05:58 +01:00
getLoadingTooltipText ( ) {
return ` Loading PluginRepo - [ ${ Object . keys ( loadedPlugins ) . length } / ${ Object . keys ( grabbedPlugins ) . length } ] ` ;
2019-03-27 22:17:07 +01:00
}
2020-02-10 15:53:30 +01:00
isPluginOutdated ( plugin , url ) {
let instPlugin = BDFDB . BDUtils . getPlugin ( plugin . getName ) ;
return instPlugin && typeof instPlugin . getAuthor == "function" && this . getString ( instPlugin . getAuthor ( ) ) . toUpperCase ( ) == plugin . getAuthor . toUpperCase ( ) && this . getString ( instPlugin . getVersion ( ) ) != plugin . getVersion && ! this . pluginHasUpdateCheck ( url ) ;
}
pluginHasUpdateCheck ( url ) {
if ( ! BDFDB . ObjectUtils . is ( window . PluginUpdates ) || ! BDFDB . ObjectUtils . is ( window . PluginUpdates . plugins ) ) return false ;
if ( window . PluginUpdates . plugins [ url ] ) return true ;
else {
let temp = "https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/PluginRepo/PluginRepo.plugin.js" . replace ( "//raw.githubusercontent.com" , "//" ) . split ( "/" ) ;
let gitname = temp . splice ( 3 , 1 ) ;
temp . splice ( 4 , 1 ) ;
temp . splice ( 2 , 1 , gitname + ".github.io" ) ;
return ! ! window . PluginUpdates . plugins [ temp . join ( "/" ) ] ;
}
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
getString ( obj ) {
let string = "" ;
if ( typeof obj == "string" ) string = obj ;
else if ( obj && obj . props ) {
if ( typeof obj . props . children == "string" ) string = obj . props . children ;
else if ( Array . isArray ( obj . props . children ) ) for ( let c of obj . props . children ) string += typeof c == "string" ? c : this . getString ( c ) ;
2018-12-14 11:43:54 +01:00
}
2020-02-10 15:05:58 +01:00
return string ;
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
checkForNewPlugins ( ) {
BDFDB . LibraryRequires . request ( "https://mwittrien.github.io/BetterDiscordAddons/Plugins/PluginRepo/res/PluginList.txt" , ( error , response , result ) => {
if ( response && ! BDFDB . equals ( result . replace ( /\t|\r/g , "" ) . split ( "\n" ) . filter ( n => n ) , grabbedPlugins ) ) {
loading = { is : false , timeout : null , amount : 0 } ;
this . loadPlugins ( ) ;
}
} ) ;
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
downloadPlugin ( data ) {
BDFDB . LibraryRequires . request ( data . url , ( error , response , body ) => {
if ( error ) BDFDB . NotificationUtils . toast ( ` Unable to download Plugin " ${ plugin . getName } ". ` , { type : "danger" } ) ;
else this . createPluginFile ( data . url . split ( "/" ) . pop ( ) , body ) ;
} ) ;
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
createPluginFile ( filename , content ) {
BDFDB . LibraryRequires . fs . writeFile ( BDFDB . LibraryRequires . path . join ( BDFDB . BDUtils . getPluginsFolder ( ) , filename ) , content , ( error ) => {
if ( error ) BDFDB . NotificationUtils . toast ( ` Unable to save Plugin " ${ filename } ". ` , { type : "danger" } ) ;
else BDFDB . NotificationUtils . toast ( ` Successfully saved Plugin " ${ filename } ". ` , { type : "success" } ) ;
} ) ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
startPlugin ( data ) {
if ( BDFDB . BDUtils . isPluginEnabled ( data . name ) == false ) {
2020-03-15 10:21:23 +01:00
BDFDB . BDUtils . enablePlugin ( data . name , false ) ;
2020-02-10 15:05:58 +01:00
BDFDB . LogUtils . log ( ` Started Plugin ${ data . name } . ` , this . name ) ;
}
}
2019-01-26 22:45:19 +01:00
2020-02-10 15:05:58 +01:00
deletePluginFile ( data ) {
let filename = data . url . split ( "/" ) . pop ( ) ;
BDFDB . LibraryRequires . fs . unlink ( BDFDB . LibraryRequires . path . join ( BDFDB . BDUtils . getPluginsFolder ( ) , filename ) , ( error ) => {
if ( error ) BDFDB . NotificationUtils . toast ( ` Unable to delete Plugin " ${ filename } ". ` , { type : "danger" } ) ;
else BDFDB . NotificationUtils . toast ( ` Successfully deleted Plugin " ${ filename } ". ` ) ;
} ) ;
}
stopPlugin ( data ) {
if ( BDFDB . BDUtils . isPluginEnabled ( data . name ) == true ) {
2020-03-15 10:21:23 +01:00
BDFDB . BDUtils . disablePlugin ( data . name , false ) ;
2020-02-10 15:05:58 +01:00
BDFDB . LogUtils . log ( ` Stopped Plugin ${ data . name } . ` , this . name ) ;
}
2018-10-11 10:21:26 +02:00
}
}
2020-02-10 15:05:58 +01:00
} ) ( ) ;