2015-08-27 15:46:53 +02:00
/ * B e t t e r D i s c o r d A p p C o r e J a v a S c r i p t
2017-04-30 03:11:22 +02:00
* Version : 1.78
2015-08-27 15:46:53 +02:00
* Author : Jiiks | http : //jiiks.net
* Date : 27 / 08 / 2015 - 16 : 36
2016-04-30 23:25:14 +02:00
* Last Update : 01 / 05 / 2016
2015-08-27 15:46:53 +02:00
* https : //github.com/Jiiks/BetterDiscordApp
* /
2017-01-09 06:41:36 +01:00
2018-08-19 23:15:23 +02:00
/* Localstorage fix */
2017-01-11 10:21:17 +01:00
( function ( ) {
2020-02-27 03:43:16 +01:00
const _ _fs = window . require ( "fs" ) ;
const _ _process = window . require ( "process" ) ;
const _ _platform = _ _process . platform ;
const _ _dataPath = ( _ _platform === "win32" ? _ _process . env . APPDATA : _ _platform === "darwin" ? _ _process . env . HOME + "/Library/Preferences" : process . env . HOME + "/.config" ) + "/BetterDiscord/" ;
const localStorageFile = "localStorage.json" ;
2017-01-22 19:00:24 +01:00
2020-02-27 04:14:00 +01:00
let _ _data = { } ;
2018-08-19 23:15:23 +02:00
if ( _ _fs . existsSync ( ` ${ _ _dataPath } ${ localStorageFile } ` ) ) {
2017-01-22 19:00:24 +01:00
try {
2018-01-09 04:24:00 +01:00
_ _data = JSON . parse ( _ _fs . readFileSync ( ` ${ _ _dataPath } ${ localStorageFile } ` ) ) ;
2018-08-19 23:15:23 +02:00
}
catch ( err ) {
2017-01-22 19:00:24 +01:00
console . log ( err ) ;
}
2018-08-19 23:15:23 +02:00
}
else if ( _ _fs . existsSync ( localStorageFile ) ) {
2017-01-11 10:21:17 +01:00
try {
2018-01-09 04:24:00 +01:00
_ _data = JSON . parse ( _ _fs . readFileSync ( localStorageFile ) ) ;
2018-08-19 23:15:23 +02:00
}
catch ( err ) {
2017-01-11 10:23:15 +01:00
console . log ( err ) ;
}
2017-01-11 10:21:17 +01:00
}
2020-02-27 03:43:16 +01:00
const _ _ls = _ _data ;
2019-03-13 18:13:43 +01:00
_ _ls . setItem = function ( i , v ) {
2017-01-11 10:21:17 +01:00
_ _ls [ i ] = v ;
2017-01-11 11:43:46 +01:00
this . save ( ) ;
2017-01-11 10:21:17 +01:00
} ;
_ _ls . getItem = function ( i ) {
2017-01-11 19:59:24 +01:00
return _ _ls [ i ] || null ;
2017-01-11 10:21:17 +01:00
} ;
2017-01-11 11:43:46 +01:00
_ _ls . save = function ( ) {
2018-01-09 04:24:00 +01:00
_ _fs . writeFileSync ( ` ${ _ _dataPath } ${ localStorageFile } ` , JSON . stringify ( this ) , null , 4 ) ;
2017-01-11 10:21:17 +01:00
} ;
2020-02-27 03:43:16 +01:00
const _ _proxy = new Proxy ( _ _ls , {
2017-11-03 04:05:33 +01:00
set : function ( target , name , val ) {
2017-01-11 11:43:46 +01:00
_ _ls [ name ] = val ;
_ _ls . save ( ) ;
} ,
2017-11-03 04:05:33 +01:00
get : function ( target , name ) {
2017-01-11 19:59:24 +01:00
return _ _ls [ name ] || null ;
2017-01-11 11:43:46 +01:00
}
} ) ;
window . localStorage = _ _proxy ;
2017-01-11 10:25:20 +01:00
} ) ( ) ;
2017-01-11 10:21:17 +01:00
2017-04-30 03:11:22 +02:00
( ( ) => {
2020-02-27 03:43:16 +01:00
const v2Loader = document . createElement ( "div" ) ;
2017-04-30 03:11:22 +02:00
v2Loader . className = "bd-loaderv2" ;
2018-10-28 21:28:13 +01:00
v2Loader . title = "BandagedBD is loading..." ;
2017-04-30 03:11:22 +02:00
document . body . appendChild ( v2Loader ) ;
} ) ( ) ;
2018-10-14 09:45:56 +02:00
/* global DiscordNative:false */
2018-03-15 15:30:14 +01:00
2018-10-19 05:59:27 +02:00
var DataStore = ( ( ) => {
const fs = require ( "fs" ) ;
const path = require ( "path" ) ;
const releaseChannel = DiscordNative . globals . releaseChannel ;
2018-10-15 01:56:16 +02:00
2018-10-19 05:59:27 +02:00
return new class DataStore {
constructor ( ) {
this . data = { settings : { stable : { } , canary : { } , ptb : { } } } ;
this . pluginData = { } ;
}
2017-01-09 06:41:36 +01:00
2018-10-19 05:59:27 +02:00
initialize ( ) {
2018-10-24 20:14:35 +02:00
try {
if ( ! fs . existsSync ( this . BDFile ) ) fs . writeFileSync ( this . BDFile , JSON . stringify ( this . data , null , 4 ) ) ;
2018-11-02 18:45:50 +01:00
const data = require ( this . BDFile ) ;
if ( data . hasOwnProperty ( "settings" ) ) this . data = data ;
2018-10-24 20:14:35 +02:00
if ( ! fs . existsSync ( this . settingsFile ) ) return ;
let settings = require ( this . settingsFile ) ;
fs . unlinkSync ( this . settingsFile ) ;
if ( settings . hasOwnProperty ( "settings" ) ) settings = Object . assign ( { stable : { } , canary : { } , ptb : { } } , { [ releaseChannel ] : settings } ) ;
else settings = Object . assign ( { stable : { } , canary : { } , ptb : { } } , settings ) ;
this . setBDData ( "settings" , settings ) ;
}
catch ( err ) {
BdApi . alert ( "Corrupt Storage" , "The bd storage has somehow become corrupt. You may either try to salvage the file or delete it then reload." ) ;
}
2018-10-19 05:59:27 +02:00
}
get BDFile ( ) { return this . _BDFile || ( this . _BDFile = path . resolve ( bdConfig . dataPath , "bdstorage.json" ) ) ; }
get settingsFile ( ) { return this . _settingsFile || ( this . _settingsFile = path . resolve ( bdConfig . dataPath , "bdsettings.json" ) ) ; }
getPluginFile ( pluginName ) { return path . resolve ( ContentManager . pluginsFolder , pluginName + ".config.json" ) ; }
2018-10-14 09:45:56 +02:00
2018-10-19 05:59:27 +02:00
getSettingGroup ( key ) {
return this . data . settings [ releaseChannel ] [ key ] || null ;
2018-08-19 23:15:23 +02:00
}
2018-10-19 05:59:27 +02:00
setSettingGroup ( key , data ) {
this . data . settings [ releaseChannel ] [ key ] = data ;
fs . writeFileSync ( this . BDFile , JSON . stringify ( this . data , null , 4 ) ) ;
2018-08-19 23:15:23 +02:00
}
2018-10-19 05:59:27 +02:00
getBDData ( key ) {
return this . data [ key ] || "" ;
}
setBDData ( key , value ) {
this . data [ key ] = value ;
fs . writeFileSync ( this . BDFile , JSON . stringify ( this . data , null , 4 ) ) ;
}
getPluginData ( pluginName , key ) {
if ( this . pluginData [ pluginName ] !== undefined ) return this . pluginData [ pluginName ] [ key ] || undefined ;
if ( ! fs . existsSync ( this . getPluginFile ( pluginName ) ) ) return undefined ;
this . pluginData [ pluginName ] = JSON . parse ( fs . readFileSync ( this . getPluginFile ( pluginName ) ) ) ;
return this . pluginData [ pluginName ] [ key ] || undefined ;
}
setPluginData ( pluginName , key , value ) {
if ( value === undefined ) return ;
if ( this . pluginData [ pluginName ] === undefined ) this . pluginData [ pluginName ] = { } ;
this . pluginData [ pluginName ] [ key ] = value ;
fs . writeFileSync ( this . getPluginFile ( pluginName ) , JSON . stringify ( this . pluginData [ pluginName ] , null , 4 ) ) ;
}
deletePluginData ( pluginName , key ) {
if ( this . pluginData [ pluginName ] === undefined ) this . pluginData [ pluginName ] = { } ;
delete this . pluginData [ pluginName ] [ key ] ;
fs . writeFileSync ( this . getPluginFile ( pluginName ) , JSON . stringify ( this . pluginData [ pluginName ] , null , 4 ) ) ;
}
} ;
} ) ( ) ;
2018-10-28 21:28:13 +01:00
var BDEvents = ( ( ) => {
const EventEmitter = require ( "events" ) ;
return new class BDEvents extends EventEmitter {
dispatch ( eventName , ... args ) { this . emit ( eventName , ... args ) ; }
off ( eventName , eventAction ) { this . removeListener ( eventName , eventAction ) ; }
} ;
} ) ( ) ;
2018-10-19 05:59:27 +02:00
window . bdStorage = class bdPluginStorage {
static get ( key ) {
2018-11-10 06:00:53 +01:00
Utils . warn ( "Deprecation Notice" , "Please use BdApi.getBDData(). bdStorage may be removed in future versions." ) ;
2018-10-19 05:59:27 +02:00
return DataStore . getBDData ( key ) ;
2018-08-19 23:15:23 +02:00
}
2018-04-15 20:13:25 +02:00
2018-10-19 05:59:27 +02:00
static set ( key , data ) {
2018-11-10 06:00:53 +01:00
Utils . warn ( "Deprecation Notice" , "Please use BdApi.setBDData(). bdStorage may be removed in future versions." ) ;
2018-10-19 05:59:27 +02:00
DataStore . setBDData ( key , data ) ;
}
2018-08-19 23:15:23 +02:00
} ;
2018-04-15 20:13:25 +02:00
2018-10-19 05:59:27 +02:00
window . bdPluginStorage = class bdPluginStorage {
static get ( pluginName , key ) {
2018-11-10 06:00:53 +01:00
Utils . warn ( "Deprecation Notice" , ` ${ pluginName } , please use BdApi.loadData() or BdApi.getData(). bdPluginStorage may be removed in future versions. ` ) ;
2018-10-19 05:59:27 +02:00
return DataStore . getPluginData ( pluginName , key ) || null ;
2018-04-15 20:13:25 +02:00
}
2018-10-19 05:59:27 +02:00
static set ( pluginName , key , data ) {
2018-11-10 06:00:53 +01:00
Utils . warn ( "Deprecation Notice" , ` ${ pluginName } , please use BdApi.saveData() or BdApi.setData(). bdPluginStorage may be removed in future versions. ` ) ;
if ( typeof ( data ) === "undefined" ) return Utils . warn ( "Deprecation Notice" , "Trying to set undefined value in plugin " + pluginName ) ;
2018-10-19 05:59:27 +02:00
DataStore . setPluginData ( pluginName , key , data ) ;
}
static delete ( pluginName , key ) {
2018-11-10 06:00:53 +01:00
Utils . warn ( "Deprecation Notice" , ` ${ pluginName } , please use BdApi.deleteData(). bdPluginStorage may be removed in future versions. ` ) ;
2018-10-19 05:59:27 +02:00
DataStore . deletePluginData ( pluginName , key ) ;
2018-04-15 20:13:25 +02:00
}
2018-08-19 23:15:23 +02:00
} ;
2018-04-15 20:13:25 +02:00
2018-10-14 09:45:56 +02:00
var settingsPanel , emoteModule , quickEmoteMenu , voiceMode , pluginModule , themeModule , dMode , publicServersModule ;
2018-10-19 05:59:27 +02:00
var minSupportedVersion = "0.3.0" ;
2020-02-27 03:43:16 +01:00
var bbdVersion = "0.2.24" ;
2020-02-10 06:57:25 +01:00
var bbdChangelog = {
2020-02-27 03:43:16 +01:00
description : "Mostly behind the scenes changes here." ,
2020-02-10 06:57:25 +01:00
changes : [
2020-02-27 03:43:16 +01:00
{ title : "What's New?" , items : [ "**Dark Mode is back!** Or rather... it's toggleable again and no longer forced on." , "**Changes for developers!** Plugin and theme developers will now have more options to customize their plugin cards in their METAs and also a new META structure." ] } ,
{ title : "Fixes" , type : "fixed" , items : [ "**Emote Menu** should now show both Twich Global emotes and your favorites, you should even be able to click on them again!" ] } ,
{ title : "Minor Stuff" , type : "improved" , items : [ "**Clean Code.** Well not really. But BD's code is starting to be cleaned up to make it easier to maintain and better performing." ] }
2020-02-10 06:57:25 +01:00
]
} ;
2015-08-29 11:36:47 +02:00
2015-08-27 15:46:53 +02:00
2015-10-26 06:27:55 +01:00
var mainCore ;
2015-08-27 15:46:53 +02:00
2015-08-29 11:36:47 +02:00
var settings = {
2018-08-19 23:15:23 +02:00
"Custom css live update" : { id : "bda-css-0" , info : "" , implemented : true , hidden : true , cat : "core" } ,
"Custom css auto udpate" : { id : "bda-css-1" , info : "" , implemented : true , hidden : true , cat : "core" } ,
2019-05-22 07:20:54 +02:00
"BetterDiscord Blue" : { id : "bda-gs-b" , info : "Replace Discord blue with BD Blue" , implemented : false , hidden : false , cat : "core" } ,
2016-04-09 21:56:29 +02:00
2019-05-25 06:43:09 +02:00
/* Core */
/* ====== */
2019-05-28 19:23:01 +02:00
"Public Servers" : { id : "bda-gs-1" , info : "Display public servers button" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
"Minimal Mode" : { id : "bda-gs-2" , info : "Hide elements and reduce the size of elements." , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
"Voice Mode" : { id : "bda-gs-4" , info : "Only show voice chat" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
"Hide Channels" : { id : "bda-gs-3" , info : "Hide channels in minimal mode" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
2020-02-27 03:43:16 +01:00
"Dark Mode" : { id : "bda-gs-5" , info : "Make certain elements dark by default(wip)" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
2019-05-28 19:23:01 +02:00
"Voice Disconnect" : { id : "bda-dc-0" , info : "Disconnect from voice server when closing Discord" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
"24 Hour Timestamps" : { id : "bda-gs-6" , info : "Replace 12hr timestamps with proper ones" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
2020-02-10 06:57:25 +01:00
"Colored Text" : { id : "bda-gs-7" , info : "Make text color the same as role color" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
2019-05-28 19:23:01 +02:00
"Normalize Classes" : { id : "fork-ps-4" , info : "Adds stable classes to elements to help themes. (e.g. adds .da-channels to .channels-Ie2l6A)" , implemented : true , hidden : false , cat : "core" , category : "modules" } ,
2019-05-25 06:43:09 +02:00
/* Content */
2019-05-28 19:23:01 +02:00
"Content Error Modal" : { id : "fork-ps-1" , info : "Shows a modal with plugin/theme errors" , implemented : true , hidden : false , cat : "core" , category : "content manager" } ,
"Show Toasts" : { id : "fork-ps-2" , info : "Shows a small notification for important information" , implemented : true , hidden : false , cat : "core" , category : "content manager" } ,
"Scroll To Settings" : { id : "fork-ps-3" , info : "Auto-scrolls to a plugin's settings when the button is clicked (only if out of view)" , implemented : true , hidden : false , cat : "core" , category : "content manager" } ,
"Automatic Loading" : { id : "fork-ps-5" , info : "Automatically loads, reloads, and unloads plugins and themes" , implemented : true , hidden : false , cat : "core" , category : "content manager" } ,
2019-05-25 06:43:09 +02:00
/* Developer */
"Developer Mode" : { id : "bda-gs-8" , info : "Developer Mode" , implemented : true , hidden : false , cat : "core" , category : "developer settings" } ,
"Copy Selector" : { id : "fork-dm-1" , info : "Adds a \"Copy Selector\" option to context menus when developer mode is active" , implemented : true , hidden : false , cat : "core" , category : "developer settings" } ,
/* Window Prefs */
"Enable Transparency" : { id : "fork-wp-1" , info : "Enables the main window to be see-through (requires restart)" , implemented : true , hidden : false , cat : "core" , category : "window preferences" } ,
"Window Frame" : { id : "fork-wp-2" , info : "Adds the native os window frame to the main window" , implemented : false , hidden : true , cat : "core" , category : "window preferences" } ,
/* Emotes */
/* ====== */
"Download Emotes" : { id : "fork-es-3" , info : "Download emotes when the cache is expired" , implemented : true , hidden : false , cat : "emote" } ,
2018-08-19 23:15:23 +02:00
"Twitch Emotes" : { id : "bda-es-7" , info : "Show Twitch emotes" , implemented : true , hidden : false , cat : "emote" } ,
"FrankerFaceZ Emotes" : { id : "bda-es-1" , info : "Show FrankerFaceZ Emotes" , implemented : true , hidden : false , cat : "emote" } ,
"BetterTTV Emotes" : { id : "bda-es-2" , info : "Show BetterTTV Emotes" , implemented : true , hidden : false , cat : "emote" } ,
"Emote Menu" : { id : "bda-es-0" , info : "Show Twitch/Favourite emotes in emote menu" , implemented : true , hidden : false , cat : "emote" } ,
"Emoji Menu" : { id : "bda-es-9" , info : "Show Discord emoji menu" , implemented : true , hidden : false , cat : "emote" } ,
"Emote Auto Capitalization" : { id : "bda-es-4" , info : "Autocapitalize emote commands" , implemented : true , hidden : false , cat : "emote" } ,
"Show Names" : { id : "bda-es-6" , info : "Show emote names on hover" , implemented : true , hidden : false , cat : "emote" } ,
"Show emote modifiers" : { id : "bda-es-8" , info : "Enable emote mods (flip, spin, pulse, spin2, spin3, 1spin, 2spin, 3spin, tr, bl, br, shake, shake2, shake3, flap)" , implemented : true , hidden : false , cat : "emote" } ,
2019-05-25 06:43:09 +02:00
"Animate On Hover" : { id : "fork-es-2" , info : "Only animate the emote modifiers on hover" , implemented : true , hidden : false , cat : "emote" }
2016-01-08 16:33:43 +01:00
} ;
2015-08-29 11:36:47 +02:00
var defaultCookie = {
2018-03-29 09:56:07 +02:00
"bda-gs-1" : true ,
2015-12-23 22:48:59 +01:00
"bda-gs-2" : false ,
2015-11-29 18:21:58 +01:00
"bda-gs-3" : false ,
"bda-gs-4" : false ,
2020-02-27 03:43:16 +01:00
"bda-gs-5" : true ,
2016-05-06 20:31:20 +02:00
"bda-gs-6" : false ,
"bda-gs-7" : false ,
2016-05-24 22:33:24 +02:00
"bda-gs-8" : false ,
2015-11-29 18:21:58 +01:00
"bda-es-0" : true ,
2015-12-23 09:56:16 +01:00
"bda-es-1" : true ,
2015-12-23 22:48:59 +01:00
"bda-es-2" : true ,
2015-11-29 18:21:58 +01:00
"bda-es-4" : false ,
"bda-es-6" : true ,
"bda-es-7" : true ,
2018-05-05 16:54:21 +02:00
"bda-gs-b" : false ,
2016-04-02 09:56:19 +02:00
"bda-es-8" : true ,
2016-04-08 00:21:30 +02:00
"bda-dc-0" : false ,
"bda-css-0" : false ,
2016-04-09 08:04:34 +02:00
"bda-css-1" : false ,
2017-12-24 07:51:24 +01:00
"bda-es-9" : true ,
2018-08-19 23:15:23 +02:00
"fork-dm-1" : false ,
2017-12-24 07:51:24 +01:00
"fork-ps-1" : true ,
"fork-ps-2" : true ,
2018-08-19 23:15:23 +02:00
"fork-ps-3" : true ,
"fork-ps-4" : true ,
2018-10-19 05:59:27 +02:00
"fork-ps-5" : true ,
2018-05-22 06:29:04 +02:00
"fork-es-2" : false ,
2018-10-19 08:27:02 +02:00
"fork-es-3" : true ,
"fork-wp-1" : false ,
"fork-wp-2" : false
2015-11-29 18:21:58 +01:00
} ;
2015-08-29 11:36:47 +02:00
var settingsCookie = { } ;
2015-08-27 15:46:53 +02:00
2018-10-19 05:59:27 +02:00
var bdpluginErrors = [ ] , bdthemeErrors = [ ] ; // define for backwards compatibility
2017-11-03 21:01:49 +01:00
2018-01-09 04:24:00 +01:00
var bdConfig = null ;
function Core ( config ) {
window . bdConfig = config ;
}
2015-08-27 15:46:53 +02:00
2018-03-15 15:30:14 +01:00
Core . prototype . init = async function ( ) {
2018-10-15 01:56:16 +02:00
if ( bdConfig . version < minSupportedVersion ) {
2018-10-19 05:59:27 +02:00
this . alert ( "Not Supported" , "BetterDiscord v" + bdConfig . version + " (your version)" + " is not supported by the latest js (" + bbdVersion + ").<br><br> Please download the latest version from <a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>GitHub</a>" ) ;
2015-10-26 06:27:55 +01:00
return ;
}
2015-08-29 11:36:47 +02:00
2019-08-25 18:39:36 +02:00
if ( window . ED ) {
this . alert ( "Not Supported" , "BandagedBD does not work with EnhancedDiscord. Please uninstall one of them." ) ;
return ;
}
if ( window . WebSocket && window . WebSocket . name && window . WebSocket . name . includes ( "Patched" ) ) {
this . alert ( "Not Supported" , "BandagedBD does not work with Powercord. Please uninstall one of them." ) ;
return ;
}
2019-05-28 19:23:01 +02:00
const latestLocalVersion = bdConfig . updater ? bdConfig . updater . LatestVersion : bdConfig . latestVersion ;
if ( latestLocalVersion > bdConfig . version ) {
2018-10-14 19:08:51 +02:00
this . alert ( "Update Available" , `
2019-05-28 19:23:01 +02:00
An update for BandagedBD is available ( $ { latestLocalVersion } ) ! Please Reinstall ! < br / > < br / >
2018-10-14 19:08:51 +02:00
< a href = 'https://github.com/rauenzi/BetterDiscordApp/releases/latest' target = '_blank' > Download Installer < / a >
` );
}
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Initializing Settings" ) ;
2018-05-22 06:29:04 +02:00
this . initSettings ( ) ;
2018-04-16 00:58:48 +02:00
emoteModule = new EmoteModule ( ) ;
2015-08-27 15:46:53 +02:00
quickEmoteMenu = new QuickEmoteMenu ( ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Initializing EmoteModule" ) ;
2018-10-14 09:45:56 +02:00
window . emotePromise = emoteModule . init ( ) . then ( ( ) => {
emoteModule . initialized = true ;
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Initializing QuickEmoteMenu" ) ;
2018-10-14 09:45:56 +02:00
quickEmoteMenu . init ( ) ;
} ) ;
publicServersModule = new V2 _PublicServers ( ) ;
2018-10-29 01:34:29 +01:00
2015-10-26 06:27:55 +01:00
voiceMode = new VoiceMode ( ) ;
2016-05-24 22:33:24 +02:00
dMode = new devMode ( ) ;
2018-10-29 01:34:29 +01:00
2018-10-14 19:08:51 +02:00
this . injectExternals ( ) ;
2015-08-27 15:46:53 +02:00
2018-10-14 19:08:51 +02:00
await this . checkForGuilds ( ) ;
2018-10-29 01:34:29 +01:00
BDV2 . initialize ( ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Updating Settings" ) ;
2018-10-14 19:08:51 +02:00
settingsPanel = new V2 _SettingsPanel ( ) ;
2018-11-10 06:00:53 +01:00
settingsPanel . initializeSettings ( ) ;
2015-08-31 15:59:34 +02:00
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Loading Plugins" ) ;
2018-10-14 19:08:51 +02:00
pluginModule = new PluginModule ( ) ;
pluginModule . loadPlugins ( ) ;
2019-03-13 18:13:43 +01:00
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Loading Themes" ) ;
2018-10-14 19:08:51 +02:00
themeModule = new ThemeModule ( ) ;
themeModule . loadThemes ( ) ;
$ ( "#customcss" ) . detach ( ) . appendTo ( document . head ) ;
2019-03-13 18:13:43 +01:00
2018-10-14 19:08:51 +02:00
window . addEventListener ( "beforeunload" , function ( ) {
if ( settingsCookie [ "bda-dc-0" ] ) document . querySelector ( ".btn.btn-disconnect" ) . click ( ) ;
} ) ;
2019-03-13 18:13:43 +01:00
2018-10-14 19:08:51 +02:00
emoteModule . autoCapitalize ( ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Removing Loading Icon" ) ;
2018-10-14 19:08:51 +02:00
document . getElementsByClassName ( "bd-loaderv2" ) [ 0 ] . remove ( ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Initializing Main Observer" ) ;
2018-10-14 19:08:51 +02:00
this . initObserver ( ) ;
2019-03-13 18:13:43 +01:00
2018-10-14 19:08:51 +02:00
// Show loading errors
if ( settingsCookie [ "fork-ps-1" ] ) {
2018-11-10 06:00:53 +01:00
Utils . log ( "Startup" , "Collecting Startup Errors" ) ;
2018-10-28 21:28:13 +01:00
this . showContentErrors ( { plugins : bdpluginErrors , themes : bdthemeErrors } ) ;
2018-10-19 05:59:27 +02:00
}
2019-05-22 07:20:54 +02:00
2020-02-10 06:57:25 +01:00
const previousVersion = DataStore . getBDData ( "version" ) ;
if ( bbdVersion > previousVersion ) {
if ( bbdChangelog ) this . showChangelogModal ( bbdChangelog ) ;
DataStore . setBDData ( "version" , bbdVersion ) ;
}
2018-10-14 19:08:51 +02:00
} ;
2015-08-31 15:59:34 +02:00
2018-10-14 19:08:51 +02:00
Core . prototype . checkForGuilds = function ( ) {
2019-11-19 23:17:03 +01:00
let timesChecked = 0 ;
2018-10-14 19:08:51 +02:00
return new Promise ( resolve => {
const checkForGuilds = function ( ) {
2019-04-21 17:14:03 +02:00
const wrapper = BDV2 . guildClasses . wrapper . split ( " " ) [ 0 ] ;
2019-11-28 08:01:48 +01:00
if ( document . querySelectorAll ( ` . ${ wrapper } ` ) . length > 0 ) timesChecked ++ ;
2019-05-23 08:35:35 +02:00
const guild = BDV2 . guildClasses . listItem . split ( " " ) [ 0 ] ;
const blob = BDV2 . guildClasses . blobContainer . split ( " " ) [ 0 ] ;
if ( document . querySelectorAll ( ` . ${ wrapper } . ${ guild } . ${ blob } ` ) . length > 0 ) return resolve ( bdConfig . deferLoaded = true ) ;
2019-11-19 23:17:03 +01:00
else if ( timesChecked >= 50 ) return resolve ( bdConfig . deferLoaded = true ) ;
2018-10-14 19:08:51 +02:00
setTimeout ( checkForGuilds , 100 ) ;
} ;
$ ( document ) . ready ( function ( ) {
setTimeout ( checkForGuilds , 100 ) ;
} ) ;
2015-10-26 06:27:55 +01:00
} ) ;
} ;
2015-08-27 15:46:53 +02:00
2018-10-28 21:28:13 +01:00
Core . prototype . injectExternals = async function ( ) {
await Utils . injectJs ( "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js" ) ;
if ( require . original ) window . require = require . original ;
2017-11-01 06:28:53 +01:00
} ;
2016-01-08 16:33:43 +01:00
Core . prototype . initSettings = function ( ) {
2018-10-19 05:59:27 +02:00
DataStore . initialize ( ) ;
if ( ! DataStore . getSettingGroup ( "settings" ) ) {
2015-08-29 11:36:47 +02:00
settingsCookie = defaultCookie ;
this . saveSettings ( ) ;
2018-04-15 20:13:25 +02:00
}
else {
2015-08-29 11:36:47 +02:00
this . loadSettings ( ) ;
2019-04-29 17:34:30 +02:00
$ ( "<style id=\"customcss\">" ) . text ( atob ( DataStore . getBDData ( "bdcustomcss" ) ) ) . appendTo ( document . head ) ;
2016-01-08 16:33:43 +01:00
for ( var setting in defaultCookie ) {
if ( settingsCookie [ setting ] == undefined ) {
2015-10-26 06:27:55 +01:00
settingsCookie [ setting ] = defaultCookie [ setting ] ;
2015-08-29 11:36:47 +02:00
this . saveSettings ( ) ;
}
2015-08-27 15:46:53 +02:00
}
}
2015-10-26 06:27:55 +01:00
} ;
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
Core . prototype . saveSettings = function ( ) {
2018-10-19 05:59:27 +02:00
DataStore . setSettingGroup ( "settings" , settingsCookie ) ;
2015-10-26 06:27:55 +01:00
} ;
2015-08-29 11:36:47 +02:00
2016-01-08 16:33:43 +01:00
Core . prototype . loadSettings = function ( ) {
2018-10-19 05:59:27 +02:00
settingsCookie = DataStore . getSettingGroup ( "settings" ) ;
2015-10-26 06:27:55 +01:00
} ;
2016-04-09 08:04:34 +02:00
2016-01-08 16:33:43 +01:00
Core . prototype . initObserver = function ( ) {
2018-08-06 07:37:31 +02:00
const mainObserver = new MutationObserver ( ( mutations ) => {
2016-05-21 11:19:29 +02:00
2018-08-06 07:37:31 +02:00
for ( let i = 0 , mlen = mutations . length ; i < mlen ; i ++ ) {
2018-04-06 08:46:34 +02:00
let mutation = mutations [ i ] ;
2016-04-04 16:22:53 +02:00
if ( typeof pluginModule !== "undefined" ) pluginModule . rawObserver ( mutation ) ;
2019-03-13 18:13:43 +01:00
2017-10-30 22:04:48 +01:00
// if there was nothing added, skip
2018-04-06 16:49:26 +02:00
if ( ! mutation . addedNodes . length || ! ( mutation . addedNodes [ 0 ] instanceof Element ) ) continue ;
2019-03-13 18:13:43 +01:00
2017-10-30 21:53:27 +01:00
let node = mutation . addedNodes [ 0 ] ;
2019-03-13 18:13:43 +01:00
2018-05-05 15:45:34 +02:00
if ( node . classList . contains ( "layer-3QrUeG" ) ) {
2018-08-19 23:15:23 +02:00
if ( node . getElementsByClassName ( "guild-settings-base-section" ) . length ) node . setAttribute ( "layer-id" , "server-settings" ) ;
2019-03-13 18:13:43 +01:00
2018-05-05 15:45:34 +02:00
if ( node . getElementsByClassName ( "socialLinks-3jqNFy" ) . length ) {
2018-08-19 23:15:23 +02:00
node . setAttribute ( "layer-id" , "user-settings" ) ;
node . setAttribute ( "id" , "user-settings" ) ;
2018-04-06 08:46:34 +02:00
if ( ! document . getElementById ( "bd-settings-sidebar" ) ) settingsPanel . renderSidebar ( ) ;
2017-11-01 06:28:53 +01:00
}
}
2019-03-13 18:13:43 +01:00
2019-06-04 22:06:16 +02:00
if ( node . parentElement == document . body && node . querySelector ( "#ace_settingsmenu" ) ) node . id = "ace_settingsmenu_container" ;
2018-05-05 22:33:36 +02:00
// Emoji Picker
2019-11-28 08:01:48 +01:00
//node.getElementsByClassName("emojiPicker-3m1S-j").length && !node.querySelector(".emojiPicker-3m1S-j").parentElement.classList.contains("animatorLeft-1EQxU0")
if ( node . classList . contains ( "layer-v9HyYc" ) && node . getElementsByClassName ( "emojiPicker-3m1S-j" ) . length && ! node . querySelector ( ".emojiPicker-3m1S-j" ) . parentElement . classList . contains ( "animatorLeft-1EQxU0" ) ) quickEmoteMenu . obsCallback ( node ) ;
2018-04-06 16:49:26 +02:00
2018-04-06 08:46:34 +02:00
}
2015-08-29 11:36:47 +02:00
} ) ;
2016-01-08 16:33:43 +01:00
mainObserver . observe ( document , {
childList : true ,
subtree : true
} ) ;
2015-10-26 06:27:55 +01:00
} ;
2015-08-29 11:36:47 +02:00
2018-08-19 23:15:23 +02:00
Core . prototype . inject24Hour = function ( ) {
2018-08-05 07:01:33 +02:00
if ( this . cancel24Hour ) return ;
2017-11-04 06:59:30 +01:00
2018-10-14 09:45:56 +02:00
const twelveHour = new RegExp ( ` ([0-9]{1,2}):([0-9]{1,2}) \\ s(AM|PM) ` ) ;
2019-05-22 07:20:54 +02:00
const convert = ( data ) => {
2018-08-05 07:01:33 +02:00
if ( ! settingsCookie [ "bda-gs-6" ] ) return ;
2018-10-14 09:45:56 +02:00
const matched = data . returnValue . match ( twelveHour ) ;
if ( ! matched || matched . length !== 4 ) return ;
if ( matched [ 3 ] === "AM" ) return data . returnValue = data . returnValue . replace ( matched [ 0 ] , ` ${ matched [ 1 ] === "12" ? "00" : matched [ 1 ] . padStart ( 2 , "0" ) } : ${ matched [ 2 ] } ` ) ;
2018-10-19 05:59:27 +02:00
return data . returnValue = data . returnValue . replace ( matched [ 0 ] , ` ${ matched [ 1 ] === "12" ? "12" : parseInt ( matched [ 1 ] ) + 12 } : ${ matched [ 2 ] } ` ) ;
2019-05-22 07:20:54 +02:00
} ;
const cancelCozy = Utils . monkeyPatch ( BDV2 . TimeFormatter , "calendarFormat" , { after : convert } ) ; // Called in Cozy mode
const cancelCompact = Utils . monkeyPatch ( BDV2 . TimeFormatter , "dateFormat" , { after : convert } ) ; // Called in Compact mode
this . cancel24Hour = ( ) => { cancelCozy ( ) ; cancelCompact ( ) ; } ; // Cancel both
2017-10-30 21:53:27 +01:00
} ;
2018-08-19 23:15:23 +02:00
Core . prototype . injectColoredText = function ( ) {
2018-08-05 07:01:33 +02:00
if ( this . cancelColoredText ) return ;
2020-02-10 06:57:25 +01:00
if ( ! BDV2 . MessageComponent ) return ;
2018-08-05 07:01:33 +02:00
2020-02-10 06:57:25 +01:00
this . cancelColoredText = Utils . monkeyPatch ( BDV2 . MessageComponent , "default" , { before : ( data ) => {
const props = data . methodArguments [ 0 ] ;
2020-02-11 17:34:54 +01:00
if ( ! props || ! props . childrenMessageContent ) return ;
2020-02-10 06:57:25 +01:00
const messageContent = props . childrenMessageContent ;
2020-02-11 17:34:54 +01:00
if ( ! messageContent . type || ! messageContent . type . type || messageContent . type . type . displayName != "MessageContent" ) return ;
2020-02-10 06:57:25 +01:00
const originalType = messageContent . type . type ;
2020-02-11 04:14:39 +01:00
if ( originalType . _ _originalMethod ) return ; // Don't patch again
2020-02-11 03:41:39 +01:00
messageContent . type . type = function ( props ) {
const returnValue = originalType ( props ) ;
2020-02-11 04:14:39 +01:00
const roleColor = settingsCookie [ "bda-gs-7" ] ? props . message . colorString || "" : "" ;
2020-02-10 06:57:25 +01:00
returnValue . props . style = { color : roleColor } ;
return returnValue ;
} ;
2020-02-11 04:14:39 +01:00
messageContent . type . type . _ _originalMethod = originalType ;
2020-02-11 17:34:54 +01:00
Object . assign ( messageContent . type . type , originalType ) ;
2018-08-05 07:01:33 +02:00
} } ) ;
2017-10-30 21:53:27 +01:00
} ;
2018-08-19 23:15:23 +02:00
Core . prototype . removeColoredText = function ( ) {
document . querySelectorAll ( ".markup-2BOw-j" ) . forEach ( elem => {
2018-08-05 07:01:33 +02:00
elem . style . setProperty ( "color" , "" ) ;
2017-11-04 06:59:30 +01:00
} ) ;
} ;
2017-11-03 18:34:26 +01:00
Core . prototype . alert = function ( title , content ) {
let modal = $ ( ` <div class="bd-modal-wrapper theme-dark">
2018-08-19 23:15:23 +02:00
< div class = "bd-backdrop backdrop-1wrmKB" > < / d i v >
2018-05-05 16:54:21 +02:00
< div class = "bd-modal modal-1UGdnR" >
< div class = "bd-modal-inner inner-1JeGVc" >
< div class = "header header-1R_AjF" >
2017-11-03 18:34:26 +01:00
< div class = "title" > $ { title } < / d i v >
< / d i v >
< div class = "bd-modal-body" >
< div class = "scroller-wrap fade" >
< div class = "scroller" >
$ { content }
< / d i v >
< / d i v >
< / d i v >
2018-05-05 16:54:21 +02:00
< div class = "footer footer-2yfCgX" >
2017-11-03 18:34:26 +01:00
< button type = "button" > Okay < / b u t t o n >
< / d i v >
< / d i v >
< / d i v >
< / d i v > ` ) ;
2018-08-19 23:15:23 +02:00
modal . find ( ".footer button" ) . on ( "click" , ( ) => {
modal . addClass ( "closing" ) ;
2017-11-03 18:34:26 +01:00
setTimeout ( ( ) => { modal . remove ( ) ; } , 300 ) ;
} ) ;
2018-08-19 23:15:23 +02:00
modal . find ( ".bd-backdrop" ) . on ( "click" , ( ) => {
modal . addClass ( "closing" ) ;
2017-11-03 18:34:26 +01:00
setTimeout ( ( ) => { modal . remove ( ) ; } , 300 ) ;
} ) ;
modal . appendTo ( "#app-mount" ) ;
} ;
2018-10-28 21:28:13 +01:00
Core . prototype . showContentErrors = function ( { plugins : pluginErrors = [ ] , themes : themeErrors = [ ] } ) {
2018-10-19 05:59:27 +02:00
if ( ! pluginErrors || ! themeErrors ) return ;
if ( ! pluginErrors . length && ! themeErrors . length ) return ;
2017-11-03 18:34:26 +01:00
let modal = $ ( ` <div class="bd-modal-wrapper theme-dark">
2018-08-19 23:15:23 +02:00
< div class = "bd-backdrop backdrop-1wrmKB" > < / d i v >
2018-10-28 21:28:13 +01:00
< div class = "bd-modal bd-content-modal modal-1UGdnR" >
2018-05-05 16:54:21 +02:00
< div class = "bd-modal-inner inner-1JeGVc" >
2018-10-28 21:28:13 +01:00
< div class = "header header-1R_AjF" > < div class = "title" > Content Errors < / d i v > < / d i v >
2017-11-03 18:34:26 +01:00
< div class = "bd-modal-body" >
< div class = "tab-bar-container" >
< div class = "tab-bar TOP" >
< div class = "tab-bar-item" > Plugins < / d i v >
< div class = "tab-bar-item" > Themes < / d i v >
< / d i v >
< / d i v >
< div class = "table-header" >
< div class = "table-column column-name" > Name < / d i v >
2018-10-28 21:28:13 +01:00
< div class = "table-column column-message" > Message < / d i v >
2017-11-03 18:34:26 +01:00
< div class = "table-column column-error" > Error < / d i v >
< / d i v >
< div class = "scroller-wrap fade" >
< div class = "scroller" >
< / d i v >
< / d i v >
< / d i v >
2018-05-05 16:54:21 +02:00
< div class = "footer footer-2yfCgX" >
2017-11-03 18:34:26 +01:00
< button type = "button" > Okay < / b u t t o n >
< / d i v >
< / d i v >
< / d i v >
< / d i v > ` ) ;
function generateTab ( errors ) {
let container = $ ( ` <div class="errors"> ` ) ;
for ( let err of errors ) {
let error = $ ( ` <div class="error">
< div class = "table-column column-name" > $ { err . name ? err . name : err . file } < / d i v >
2018-10-28 21:28:13 +01:00
< div class = "table-column column-message" > $ { err . message } < / d i v >
2017-11-03 18:34:26 +01:00
< div class = "table-column column-error" > < a class = "error-link" href = "" > $ { err . error ? err . error . message : "" } < / a > < / d i v >
< / d i v > ` ) ;
container . append ( error ) ;
if ( err . error ) {
2018-08-19 23:15:23 +02:00
error . find ( "a" ) . on ( "click" , ( e ) => {
2017-11-03 18:34:26 +01:00
e . preventDefault ( ) ;
2018-11-10 06:00:53 +01:00
Utils . err ( "ContentManager" , ` Error details for ${ err . name ? err . name : err . file } . ` , err . error ) ;
2017-11-03 18:34:26 +01:00
} ) ;
}
}
return container ;
}
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
let tabs = [ generateTab ( pluginErrors ) , generateTab ( themeErrors ) ] ;
2017-11-03 18:34:26 +01:00
2018-08-19 23:15:23 +02:00
modal . find ( ".tab-bar-item" ) . on ( "click" , ( e ) => {
2017-11-03 18:34:26 +01:00
e . preventDefault ( ) ;
2018-08-19 23:15:23 +02:00
modal . find ( ".tab-bar-item" ) . removeClass ( "selected" ) ;
$ ( e . target ) . addClass ( "selected" ) ;
modal . find ( ".scroller" ) . empty ( ) . append ( tabs [ $ ( e . target ) . index ( ) ] ) ;
2017-11-03 18:34:26 +01:00
} ) ;
2018-08-19 23:15:23 +02:00
modal . find ( ".footer button" ) . on ( "click" , ( ) => {
modal . addClass ( "closing" ) ;
2017-11-03 18:34:26 +01:00
setTimeout ( ( ) => { modal . remove ( ) ; } , 300 ) ;
} ) ;
2018-08-19 23:15:23 +02:00
modal . find ( ".bd-backdrop" ) . on ( "click" , ( ) => {
modal . addClass ( "closing" ) ;
2017-11-03 18:34:26 +01:00
setTimeout ( ( ) => { modal . remove ( ) ; } , 300 ) ;
} ) ;
modal . appendTo ( "#app-mount" ) ;
2018-10-19 05:59:27 +02:00
if ( pluginErrors . length ) modal . find ( ".tab-bar-item" ) [ 0 ] . click ( ) ;
else modal . find ( ".tab-bar-item" ) [ 1 ] . click ( ) ;
2017-11-03 18:34:26 +01:00
} ;
2017-11-03 20:52:35 +01:00
/ * *
* This shows a toast similar to android towards the bottom of the screen .
2019-03-13 18:13:43 +01:00
*
2017-11-03 20:52:35 +01:00
* @ param { string } content The string to show in the toast .
* @ param { object } options Options object . Optional parameter .
* @ param { string } options . type Changes the type of the toast stylistically and semantically . Choices : "" , "info" , "success" , "danger" / "error" , "warning" / "warn" . Default : ""
* @ param { boolean } options . icon Determines whether the icon should show corresponding to the type . A toast without type will always have no icon . Default : true
* @ param { number } options . timeout Adjusts the time ( in ms ) the toast should be shown for before disappearing automatically . Default : 3000
* /
Core . prototype . showToast = function ( content , options = { } ) {
2018-04-16 00:58:48 +02:00
if ( ! bdConfig . deferLoaded ) return ;
2018-08-19 23:15:23 +02:00
if ( ! document . querySelector ( ".bd-toasts" ) ) {
2017-11-03 20:52:35 +01:00
let toastWrapper = document . createElement ( "div" ) ;
toastWrapper . classList . add ( "bd-toasts" ) ;
2018-08-19 23:15:23 +02:00
let boundingElement = document . querySelector ( ".chat-3bRxxu form, #friends, .noChannel-Z1DQK7, .activityFeed-28jde9" ) ;
2017-11-03 20:52:35 +01:00
toastWrapper . style . setProperty ( "left" , boundingElement ? boundingElement . getBoundingClientRect ( ) . left + "px" : "0px" ) ;
toastWrapper . style . setProperty ( "width" , boundingElement ? boundingElement . offsetWidth + "px" : "100%" ) ;
2018-08-19 23:15:23 +02:00
toastWrapper . style . setProperty ( "bottom" , ( document . querySelector ( ".chat-3bRxxu form" ) ? document . querySelector ( ".chat-3bRxxu form" ) . offsetHeight : 80 ) + "px" ) ;
2019-01-12 01:15:45 +01:00
document . querySelector ( ".app, .app-2rEoOp" ) . appendChild ( toastWrapper ) ;
2017-11-03 20:52:35 +01:00
}
const { type = "" , icon = true , timeout = 3000 } = options ;
let toastElem = document . createElement ( "div" ) ;
toastElem . classList . add ( "bd-toast" ) ;
2018-08-19 23:15:23 +02:00
if ( type ) toastElem . classList . add ( "toast-" + type ) ;
if ( type && icon ) toastElem . classList . add ( "icon" ) ;
2017-11-03 20:52:35 +01:00
toastElem . innerText = content ;
2018-08-19 23:15:23 +02:00
document . querySelector ( ".bd-toasts" ) . appendChild ( toastElem ) ;
2017-11-03 20:52:35 +01:00
setTimeout ( ( ) => {
2018-08-19 23:15:23 +02:00
toastElem . classList . add ( "closing" ) ;
2017-11-03 20:52:35 +01:00
setTimeout ( ( ) => {
toastElem . remove ( ) ;
2018-08-19 23:15:23 +02:00
if ( ! document . querySelectorAll ( ".bd-toasts .bd-toast" ) . length ) document . querySelector ( ".bd-toasts" ) . remove ( ) ;
2017-11-03 20:52:35 +01:00
} , 300 ) ;
} , timeout ) ;
} ;
2020-02-10 06:57:25 +01:00
Core . prototype . showChangelogModal = function ( options = { } ) {
const ModalStack = BdApi . findModuleByProps ( "push" , "update" , "pop" , "popWithKey" ) ;
const ChangelogClasses = BdApi . findModuleByProps ( "fixed" , "improved" ) ;
const TextElement = BdApi . findModuleByProps ( "Sizes" , "Weights" ) ;
const FlexChild = BdApi . findModuleByProps ( "Child" ) ;
const Titles = BdApi . findModuleByProps ( "Tags" , "default" ) ;
const Changelog = BdApi . findModule ( m => m . defaultProps && m . defaultProps . selectable == false ) ;
const MarkdownParser = BdApi . findModuleByProps ( "defaultRules" , "parse" ) ;
if ( ! Changelog || ! ModalStack || ! ChangelogClasses || ! TextElement || ! FlexChild || ! Titles || ! MarkdownParser ) return ;
const { image = "https://repository-images.githubusercontent.com/105473537/957b5480-7c26-11e9-8401-50fa820cbae5" , description = "" , changes = [ ] , title = "BandagedBD" , subtitle = ` v ${ bbdVersion } ` , footer } = options ;
const ce = BdApi . React . createElement ;
const changelogItems = [ ce ( "img" , { src : image } ) ] ;
if ( description ) changelogItems . push ( ce ( "p" , null , MarkdownParser . parse ( description ) ) ) ;
for ( let c = 0 ; c < changes . length ; c ++ ) {
const entry = changes [ c ] ;
const type = ChangelogClasses [ entry . type ] ? ChangelogClasses [ entry . type ] : ChangelogClasses . added ;
const margin = c == 0 ? ChangelogClasses . marginTop : "" ;
changelogItems . push ( ce ( "h1" , { className : ` ${ type } ${ margin } ` , } , entry . title ) ) ;
const list = ce ( "ul" , null , entry . items . map ( i => ce ( "li" , null , MarkdownParser . parse ( i ) ) ) ) ;
changelogItems . push ( list ) ;
}
const renderHeader = function ( ) {
return ce ( FlexChild . Child , { grow : 1 , shrink : 1 } ,
ce ( Titles . default , { tag : Titles . Tags . H4 } , title ) ,
ce ( TextElement , { size : TextElement . Sizes . SMALL , color : TextElement . Colors . PRIMARY , className : ChangelogClasses . date } , subtitle )
) ;
} ;
const renderFooter = ( ) => {
const Anchor = BdApi . findModule ( m => m . displayName == "Anchor" ) ;
const AnchorClasses = BdApi . findModuleByProps ( "anchorUnderlineOnHover" ) || { anchor : "anchor-3Z-8Bb" , anchorUnderlineOnHover : "anchorUnderlineOnHover-2ESHQB" } ;
const joinSupportServer = ( click ) => {
click . preventDefault ( ) ;
click . stopPropagation ( ) ;
ModalStack . pop ( ) ;
BDV2 . joinBD2 ( ) ;
} ;
const supportLink = Anchor ? ce ( Anchor , { onClick : joinSupportServer } , "Join our Discord Server." ) : ce ( "a" , { className : ` ${ AnchorClasses . anchor } ${ AnchorClasses . anchorUnderlineOnHover } ` , onClick : joinSupportServer } , "Join our Discord Server." ) ;
const defaultFooter = ce ( TextElement , { size : TextElement . Sizes . SMALL , color : TextElement . Colors . PRIMARY } , "Need support? " , supportLink ) ;
return ce ( FlexChild . Child , { grow : 1 , shrink : 1 } , footer ? footer : defaultFooter ) ;
} ;
ModalStack . push ( function ( props ) {
return ce ( Changelog , Object . assign ( {
className : ChangelogClasses . container ,
selectable : true ,
onScroll : _ => _ ,
onClose : _ => _ ,
renderHeader : renderHeader ,
renderFooter : renderFooter ,
children : changelogItems
} , props ) ) ;
} ) ;
} ;
2017-10-30 23:14:26 +01:00
2015-08-27 15:46:53 +02:00
/ * B e t t e r D i s c o r d A p p E m o t e M o d u l e J a v a S c r i p t
2015-10-26 06:27:55 +01:00
* Version : 1.5
2015-08-27 15:46:53 +02:00
* Author : Jiiks | http : //jiiks.net
* Date : 26 / 08 / 2015 - 15 : 29
2015-10-14 08:50:34 +02:00
* Last Update : 14 / 10 / 2015 - 09 : 48
2015-08-27 15:46:53 +02:00
* https : //github.com/Jiiks/BetterDiscordApp
* Note : Due to conflicts autocapitalize only supports global emotes
* /
2015-10-26 06:27:55 +01:00
/ *
* = Changelog =
* - v1 . 5
* -- Twitchemotes . com api
* /
2018-08-19 23:15:23 +02:00
window . emotesFfz = { } ;
window . emotesBTTV = { } ;
window . emotesBTTV2 = { } ;
window . emotesTwitch = { } ;
window . subEmotesTwitch = { } ;
2015-08-27 15:46:53 +02:00
2018-01-09 04:24:00 +01:00
window . bdEmotes = {
TwitchGlobal : { } ,
TwitchSubscriber : { } ,
BTTV : { } ,
2018-01-24 00:08:20 +01:00
FrankerFaceZ : { } ,
2018-01-09 04:24:00 +01:00
BTTV2 : { }
2018-08-19 23:15:23 +02:00
} ;
2018-01-09 04:24:00 +01:00
window . bdEmoteSettingIDs = {
TwitchGlobal : "bda-es-7" ,
TwitchSubscriber : "bda-es-7" ,
BTTV : "bda-es-2" ,
2018-01-24 00:08:20 +01:00
FrankerFaceZ : "bda-es-1" ,
BTTV2 : "bda-es-2"
2018-08-19 23:15:23 +02:00
} ;
2018-01-09 04:24:00 +01:00
2019-01-04 01:49:09 +01:00
function EmoteModule ( ) {
2018-11-10 06:00:53 +01:00
Object . defineProperty ( this , "categories" , {
get : function ( ) {
const cats = [ ] ;
for ( const current in window . bdEmoteSettingIDs ) {
if ( settingsCookie [ window . bdEmoteSettingIDs [ current ] ] ) cats . push ( current ) ;
}
return cats ;
}
} ) ;
2019-01-04 01:49:09 +01:00
}
EmoteModule . prototype . init = async function ( ) {
this . modifiers = [ "flip" , "spin" , "pulse" , "spin2" , "spin3" , "1spin" , "2spin" , "3spin" , "tr" , "bl" , "br" , "shake" , "shake2" , "shake3" , "flap" ] ;
this . overrides = [ "twitch" , "bttv" , "ffz" ] ;
2018-01-09 04:24:00 +01:00
let emoteInfo = {
2018-08-19 23:15:23 +02:00
TwitchGlobal : {
2020-01-08 20:30:39 +01:00
url : ` https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_global.json ` ,
2018-08-19 23:15:23 +02:00
variable : "TwitchGlobal" ,
oldVariable : "emotesTwitch" ,
2020-01-08 20:30:39 +01:00
getEmoteURL : ( e ) => ` https://static-cdn.jtvnw.net/emoticons/v1/ ${ e } /1.0 `
2018-01-09 04:24:00 +01:00
} ,
2018-08-19 23:15:23 +02:00
TwitchSubscriber : {
2019-02-12 05:53:29 +01:00
url : ` https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_subscriber.json ` ,
2018-08-19 23:15:23 +02:00
variable : "TwitchSubscriber" ,
oldVariable : "subEmotesTwitch" ,
2020-01-08 20:30:39 +01:00
getEmoteURL : ( e ) => ` https://static-cdn.jtvnw.net/emoticons/v1/ ${ e } /1.0 `
2018-01-09 04:24:00 +01:00
} ,
2018-08-19 23:15:23 +02:00
FrankerFaceZ : {
2019-01-04 01:49:09 +01:00
url : ` https://rauenzi.github.io/BetterDiscordApp/data/emotedata_ffz.json ` ,
2018-08-19 23:15:23 +02:00
variable : "FrankerFaceZ" ,
2018-02-13 08:49:11 +01:00
oldVariable : "emotesFfz" ,
2020-01-08 20:30:39 +01:00
getEmoteURL : ( e ) => ` https://cdn.frankerfacez.com/emoticon/ ${ e } /1 `
2018-01-09 04:24:00 +01:00
} ,
2018-08-19 23:15:23 +02:00
BTTV : {
2020-01-08 20:30:39 +01:00
url : ` https://rauenzi.github.io/BetterDiscordApp/data/emotedata_bttv.json ` ,
2018-08-19 23:15:23 +02:00
variable : "BTTV" ,
2018-02-13 08:49:11 +01:00
oldVariable : "emotesBTTV" ,
2020-01-08 20:30:39 +01:00
getEmoteURL : ( e ) => ` https://cdn.betterttv.net/emote/ ${ e } /1x `
2018-01-09 04:24:00 +01:00
} ,
2018-08-19 23:15:23 +02:00
BTTV2 : {
2020-01-08 20:30:39 +01:00
url : ` https://rauenzi.github.io/BetterDiscordApp/data/emotedata_bttv2.json ` ,
2018-08-19 23:15:23 +02:00
variable : "BTTV2" ,
2018-02-13 08:49:11 +01:00
oldVariable : "emotesBTTV2" ,
2020-01-08 20:30:39 +01:00
getEmoteURL : ( e ) => ` https://cdn.betterttv.net/emote/ ${ e } /1x `
2018-01-09 04:24:00 +01:00
}
} ;
2018-08-23 08:21:10 +02:00
await this . getBlacklist ( ) ;
await this . loadEmoteData ( emoteInfo ) ;
2018-08-05 07:01:33 +02:00
2020-02-10 06:57:25 +01:00
while ( ! BDV2 . MessageComponent ) await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
2019-03-13 18:13:43 +01:00
2018-08-05 07:01:33 +02:00
if ( this . cancelEmoteRender ) return ;
2020-02-10 06:57:25 +01:00
this . cancelEmoteRender = Utils . monkeyPatch ( BDV2 . MessageComponent , "default" , { before : ( { methodArguments } ) => {
const nodes = methodArguments [ 0 ] . childrenMessageContent . props . content ;
if ( ! nodes || ! nodes . length ) return ;
for ( let n = 0 ; n < nodes . length ; n ++ ) {
const node = nodes [ n ] ;
if ( typeof ( node ) !== "string" ) continue ;
const words = node . split ( /([^\s]+)([\s]|$)/g ) ;
for ( let c = 0 , clen = this . categories . length ; c < clen ; c ++ ) {
for ( let w = 0 , wlen = words . length ; w < wlen ; w ++ ) {
let emote = words [ w ] ;
let emoteSplit = emote . split ( ":" ) ;
let emoteName = emoteSplit [ 0 ] ;
let emoteModifier = emoteSplit [ 1 ] ? emoteSplit [ 1 ] : "" ;
let emoteOverride = emoteModifier . slice ( 0 ) ;
if ( emoteName . length < 4 || bemotes . includes ( emoteName ) ) continue ;
if ( ! this . modifiers . includes ( emoteModifier ) || ! settingsCookie [ "bda-es-8" ] ) emoteModifier = "" ;
if ( ! this . overrides . includes ( emoteOverride ) ) emoteOverride = "" ;
else emoteModifier = emoteOverride ;
let current = this . categories [ c ] ;
if ( emoteOverride === "twitch" ) {
if ( window . bdEmotes . TwitchGlobal [ emoteName ] ) current = "TwitchGlobal" ;
else if ( window . bdEmotes . TwitchSubscriber [ emoteName ] ) current = "TwitchSubscriber" ;
}
else if ( emoteOverride === "bttv" ) {
if ( window . bdEmotes . BTTV [ emoteName ] ) current = "BTTV" ;
else if ( window . bdEmotes . BTTV2 [ emoteName ] ) current = "BTTV2" ;
}
else if ( emoteOverride === "ffz" ) {
if ( window . bdEmotes . FrankerFaceZ [ emoteName ] ) current = "FrankerFaceZ" ;
}
if ( ! window . bdEmotes [ current ] [ emoteName ] || ! settingsCookie [ window . bdEmoteSettingIDs [ current ] ] ) continue ;
const results = nodes [ n ] . match ( new RegExp ( ` ([ \\ s]|^) ${ Utils . escape ( emoteModifier ? emoteName + ":" + emoteModifier : emoteName ) } ([ \\ s]| $ ) ` ) ) ;
if ( ! results ) continue ;
const pre = nodes [ n ] . substring ( 0 , results . index + results [ 1 ] . length ) ;
const post = nodes [ n ] . substring ( results . index + results [ 0 ] . length - results [ 2 ] . length ) ;
nodes [ n ] = pre ;
const emoteComponent = BDV2 . react . createElement ( BDEmote , { name : emoteName , url : window . bdEmotes [ current ] [ emoteName ] , modifier : emoteModifier } ) ;
nodes . splice ( n + 1 , 0 , post ) ;
nodes . splice ( n + 1 , 0 , emoteComponent ) ;
}
}
}
const onlyEmotes = nodes . every ( r => {
if ( typeof ( r ) == "string" && r . replace ( /\s*/ , "" ) == "" ) return true ;
else if ( r . type && r . type . name == "BDEmote" ) return true ;
else if ( r . props && r . props . children && r . props . children . props && r . props . children . props . emojiName ) return true ;
return false ;
} ) ;
if ( ! onlyEmotes ) return ;
for ( let node of nodes ) {
if ( typeof ( node ) != "object" ) continue ;
if ( node . type . name == "BDEmote" ) node . props . jumboable = true ;
else if ( node . props && node . props . children && node . props . children . props && node . props . children . props . emojiName ) node . props . children . props . jumboable = true ;
}
2018-08-05 07:01:33 +02:00
} } ) ;
2018-01-09 04:24:00 +01:00
} ;
2018-11-10 06:00:53 +01:00
EmoteModule . prototype . disable = function ( ) {
this . disableAutoCapitalize ( ) ;
if ( this . cancelEmoteRender ) return ;
this . cancelEmoteRender ( ) ;
this . cancelEmoteRender = null ;
} ;
2018-01-09 04:24:00 +01:00
EmoteModule . prototype . clearEmoteData = async function ( ) {
let _fs = require ( "fs" ) ;
let emoteFile = "emote_data.json" ;
let file = bdConfig . dataPath + emoteFile ;
let exists = _fs . existsSync ( file ) ;
if ( exists ) _fs . unlinkSync ( file ) ;
2018-10-19 05:59:27 +02:00
DataStore . setBDData ( "emoteCacheDate" , ( new Date ( ) ) . toJSON ( ) ) ;
2018-01-09 04:24:00 +01:00
window . bdEmotes = {
TwitchGlobal : { } ,
TwitchSubscriber : { } ,
BTTV : { } ,
2018-01-24 00:08:20 +01:00
FrankerFaceZ : { } ,
2018-01-09 04:24:00 +01:00
BTTV2 : { }
2018-08-19 23:15:23 +02:00
} ;
2018-01-09 04:24:00 +01:00
} ;
2018-10-14 09:45:56 +02:00
EmoteModule . prototype . isCacheValid = function ( ) {
2019-05-28 19:23:01 +02:00
const cacheLength = DataStore . getBDData ( "emoteCacheDays" ) || DataStore . setBDData ( "emoteCacheDays" , 7 ) || 7 ;
2018-10-19 05:59:27 +02:00
const cacheDate = new Date ( DataStore . getBDData ( "emoteCacheDate" ) || null ) ;
2018-10-14 09:45:56 +02:00
const currentDate = new Date ( ) ;
const daysBetween = Math . round ( Math . abs ( ( currentDate . getTime ( ) - cacheDate . getTime ( ) ) / ( 24 * 60 * 60 * 1000 ) ) ) ;
2019-05-28 19:23:01 +02:00
if ( daysBetween > cacheLength ) {
2018-10-19 05:59:27 +02:00
DataStore . setBDData ( "emoteCacheDate" , currentDate . toJSON ( ) ) ;
2018-10-14 09:45:56 +02:00
return false ;
}
return true ;
} ;
2018-01-09 04:24:00 +01:00
EmoteModule . prototype . loadEmoteData = async function ( emoteInfo ) {
2019-06-19 04:28:48 +02:00
const fs = require ( "fs" ) ;
2018-10-14 09:45:56 +02:00
const emoteFile = "emote_data.json" ;
const file = bdConfig . dataPath + emoteFile ;
2019-06-19 04:28:48 +02:00
const exists = await new Promise ( r => fs . exists ( file , r ) ) ;
2019-03-13 18:13:43 +01:00
2018-10-14 09:45:56 +02:00
if ( exists && this . isCacheValid ( ) ) {
2018-02-13 17:06:19 +01:00
if ( settingsCookie [ "fork-ps-2" ] ) mainCore . showToast ( "Loading emotes from cache." , { type : "info" } ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "Emotes" , "Loading emotes from local cache." ) ;
2019-03-13 18:13:43 +01:00
2018-10-14 09:45:56 +02:00
const data = await new Promise ( resolve => {
2019-06-19 04:28:48 +02:00
fs . readFile ( file , "utf8" , ( err , data ) => {
Utils . log ( "Emotes" , "Emote file read." ) ;
2018-04-16 00:58:48 +02:00
if ( err ) data = { } ;
2018-08-19 23:15:23 +02:00
resolve ( data ) ;
2018-04-16 00:58:48 +02:00
} ) ;
} ) ;
2019-03-13 18:13:43 +01:00
2019-06-19 04:28:48 +02:00
const parsed = Utils . testJSON ( data ) ;
let isValid = ! ! parsed ;
if ( isValid ) window . bdEmotes = parsed ;
2018-01-09 18:16:48 +01:00
2018-10-14 09:45:56 +02:00
for ( const e in emoteInfo ) {
2018-08-19 23:15:23 +02:00
isValid = Object . keys ( window . bdEmotes [ emoteInfo [ e ] . variable ] ) . length > 0 ;
2018-01-09 04:24:00 +01:00
}
2018-01-09 18:16:48 +01:00
if ( isValid ) {
2018-08-19 23:15:23 +02:00
if ( settingsCookie [ "fork-ps-2" ] ) mainCore . showToast ( "Emotes successfully loaded." , { type : "success" } ) ;
2018-01-09 18:16:48 +01:00
return ;
2018-01-09 04:24:00 +01:00
}
2018-01-09 18:16:48 +01:00
2018-11-10 06:00:53 +01:00
Utils . log ( "Emotes" , "Cache was corrupt, downloading..." ) ;
2019-06-19 04:28:48 +02:00
await new Promise ( r => fs . unlink ( file , r ) ) ;
2018-01-09 04:24:00 +01:00
}
2018-10-29 01:34:29 +01:00
if ( ! settingsCookie [ "fork-es-3" ] ) return ;
2018-02-13 17:06:19 +01:00
if ( settingsCookie [ "fork-ps-2" ] ) mainCore . showToast ( "Downloading emotes in the background do not reload." , { type : "info" } ) ;
2018-01-09 18:16:48 +01:00
2018-01-09 04:24:00 +01:00
for ( let e in emoteInfo ) {
2018-08-23 08:21:10 +02:00
await new Promise ( r => setTimeout ( r , 1000 ) ) ;
2018-01-09 04:24:00 +01:00
let data = await this . downloadEmotes ( emoteInfo [ e ] ) ;
2018-08-19 23:15:23 +02:00
window . bdEmotes [ emoteInfo [ e ] . variable ] = data ;
2018-01-09 04:24:00 +01:00
}
2018-02-13 17:06:19 +01:00
if ( settingsCookie [ "fork-ps-2" ] ) mainCore . showToast ( "All emotes successfully downloaded." , { type : "success" } ) ;
2018-01-09 18:16:48 +01:00
2019-06-19 04:28:48 +02:00
try { await new Promise ( r => fs . writeFile ( file , JSON . stringify ( window . bdEmotes ) , "utf8" , r ) ) ; }
2018-11-10 06:00:53 +01:00
catch ( err ) { Utils . err ( "Emotes" , "Could not save emote data." , err ) ; }
2018-08-19 23:15:23 +02:00
} ;
2018-01-09 04:24:00 +01:00
EmoteModule . prototype . downloadEmotes = function ( emoteMeta ) {
let request = require ( "request" ) ;
let options = {
url : emoteMeta . url ,
2019-06-19 04:28:48 +02:00
timeout : emoteMeta . timeout ? emoteMeta . timeout : 5000 ,
json : true
2018-01-09 04:24:00 +01:00
} ;
2019-01-04 01:49:09 +01:00
Utils . log ( "Emotes" , ` Downloading: ${ emoteMeta . variable } ( ${ emoteMeta . url } ) ` ) ;
2018-01-09 04:24:00 +01:00
return new Promise ( ( resolve , reject ) => {
2019-06-19 04:28:48 +02:00
request ( options , ( error , response , parsedData ) => {
2018-01-09 04:24:00 +01:00
if ( error ) {
2018-11-10 06:00:53 +01:00
Utils . err ( "Emotes" , "Could not download " + emoteMeta . variable , error ) ;
2018-01-09 04:24:00 +01:00
if ( emoteMeta . backup ) {
emoteMeta . url = emoteMeta . backup ;
emoteMeta . backup = null ;
2018-04-16 06:57:38 +02:00
if ( emoteMeta . backupParser ) emoteMeta . parser = emoteMeta . backupParser ;
2018-04-16 00:58:48 +02:00
return resolve ( this . downloadEmotes ( emoteMeta ) ) ;
2018-01-09 04:24:00 +01:00
}
2018-04-16 00:58:48 +02:00
return reject ( { } ) ;
2018-01-09 04:24:00 +01:00
}
2018-08-19 23:15:23 +02:00
if ( typeof ( emoteMeta . parser ) === "function" ) parsedData = emoteMeta . parser ( parsedData ) ;
for ( let emote in parsedData ) {
2018-11-10 06:00:53 +01:00
if ( emote . length < 4 || bemotes . includes ( emote ) ) {
delete parsedData [ emote ] ;
continue ;
}
2018-08-19 23:15:23 +02:00
parsedData [ emote ] = emoteMeta . getEmoteURL ( parsedData [ emote ] ) ;
2018-01-09 04:24:00 +01:00
}
2018-08-19 23:15:23 +02:00
resolve ( parsedData ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "Emotes" , "Downloaded: " + emoteMeta . variable ) ;
2018-01-09 04:24:00 +01:00
} ) ;
} ) ;
2018-08-19 23:15:23 +02:00
} ;
2018-01-09 04:24:00 +01:00
2016-01-08 16:33:43 +01:00
EmoteModule . prototype . getBlacklist = function ( ) {
2018-08-23 08:21:10 +02:00
return new Promise ( resolve => {
2019-01-04 01:49:09 +01:00
$ . getJSON ( ` https://rauenzi.github.io/BetterDiscordApp/data/emotefilter.json ` , function ( data ) {
2018-08-23 08:21:10 +02:00
resolve ( bemotes = data . blacklist ) ;
} ) ;
2016-01-08 16:33:43 +01:00
} ) ;
2015-11-01 12:44:25 +01:00
} ;
2015-08-27 15:46:53 +02:00
2015-11-01 12:44:25 +01:00
var bemotes = [ ] ;
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
EmoteModule . prototype . autoCapitalize = function ( ) {
2018-11-10 06:00:53 +01:00
if ( ! settingsCookie [ "bda-es-4" ] || this . autoCapitalizeActive ) return ;
2020-02-27 03:43:16 +01:00
$ ( "body" ) . on ( "keyup.bdac change.bdac paste.bdac" , $ ( ".channelTextArea-rNsIhG textarea:first" ) , ( ) => {
var text = $ ( ".channelTextArea-rNsIhG textarea:first" ) . val ( ) ;
2016-01-08 16:33:43 +01:00
if ( text == undefined ) return ;
2015-08-29 11:36:47 +02:00
2015-08-27 15:46:53 +02:00
var lastWord = text . split ( " " ) . pop ( ) ;
2016-01-08 16:33:43 +01:00
if ( lastWord . length > 3 ) {
if ( lastWord == "danSgame" ) return ;
2018-08-06 07:37:31 +02:00
var ret = this . capitalize ( lastWord . toLowerCase ( ) ) ;
2016-01-08 16:33:43 +01:00
if ( ret !== null && ret !== undefined ) {
2018-10-14 09:45:56 +02:00
Utils . insertText ( Utils . getTextArea ( ) [ 0 ] , text . replace ( lastWord , ret ) ) ;
2015-08-27 15:46:53 +02:00
}
}
} ) ;
2018-11-10 06:00:53 +01:00
this . autoCapitalizeActive = true ;
2015-10-26 06:27:55 +01:00
} ;
2015-08-27 15:46:53 +02:00
2016-01-08 16:33:43 +01:00
EmoteModule . prototype . capitalize = function ( value ) {
2018-08-19 23:15:23 +02:00
var res = window . bdEmotes . TwitchGlobal ;
2016-01-08 16:33:43 +01:00
for ( var p in res ) {
2018-08-19 23:15:23 +02:00
if ( res . hasOwnProperty ( p ) && value == ( p + "" ) . toLowerCase ( ) ) {
2015-12-11 07:43:36 +01:00
return p ;
}
2015-08-27 15:46:53 +02:00
}
2015-10-26 06:27:55 +01:00
} ;
2016-12-05 21:05:48 +01:00
2018-11-10 06:00:53 +01:00
EmoteModule . prototype . disableAutoCapitalize = function ( ) {
this . autoCapitalizeActive = false ;
$ ( "body" ) . off ( ".bdac" ) ;
} ;
2017-04-30 03:11:22 +02:00
/ * B e t t e r D i s c o r d A p p Q u i c k E m o t e M e n u J a v a S c r i p t
* Version : 1.3
* Author : Jiiks | http : //jiiks.net
* Date : 26 / 08 / 2015 - 11 : 49
* Last Update : 29 / 08 / 2015 - 11 : 46
* https : //github.com/Jiiks/BetterDiscordApp
* /
2015-12-31 18:27:43 +01:00
2017-04-30 03:11:22 +02:00
function QuickEmoteMenu ( ) {
2015-12-31 18:27:43 +01:00
}
2017-04-30 03:11:22 +02:00
QuickEmoteMenu . prototype . init = function ( ) {
2019-01-04 01:49:09 +01:00
this . initialized = true ;
2017-04-30 03:11:22 +02:00
$ ( document ) . on ( "mousedown" , function ( e ) {
2018-08-19 23:15:23 +02:00
if ( e . target . id != "rmenu" ) $ ( "#rmenu" ) . remove ( ) ;
2017-04-30 03:11:22 +02:00
} ) ;
this . favoriteEmotes = { } ;
2018-10-19 05:59:27 +02:00
var fe = DataStore . getBDData ( "bdfavemotes" ) ;
2017-04-30 03:11:22 +02:00
if ( fe !== "" && fe !== null ) {
this . favoriteEmotes = JSON . parse ( atob ( fe ) ) ;
2016-01-08 16:33:43 +01:00
}
2015-12-31 18:27:43 +01:00
2017-11-01 06:03:48 +01:00
var qmeHeader = "" ;
2017-04-30 03:11:22 +02:00
qmeHeader += "<div id=\"bda-qem\">" ;
2017-11-03 04:05:33 +01:00
qmeHeader += " <button class=\"active\" id=\"bda-qem-twitch\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Twitch</button>" ;
qmeHeader += " <button id=\"bda-qem-favourite\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Favourite</button>" ;
qmeHeader += " <button id=\"bda-qem-emojis\" onclick='quickEmoteMenu.switchHandler(this); return false;'>Emojis</buttond>" ;
2017-11-01 06:03:48 +01:00
qmeHeader += "</div>" ;
2017-04-30 03:11:22 +02:00
this . qmeHeader = qmeHeader ;
2015-12-31 18:27:43 +01:00
2017-11-01 06:03:48 +01:00
var teContainer = "" ;
2017-04-30 03:11:22 +02:00
teContainer += "<div id=\"bda-qem-twitch-container\">" ;
2019-01-16 23:06:39 +01:00
teContainer += " <div class=\"scroller-wrap scrollerWrap-2lJEkd fade\">" ;
teContainer += " <div class=\"scroller scroller-2FKFPG\">" ;
2017-04-30 03:11:22 +02:00
teContainer += " <div class=\"emote-menu-inner\">" ;
2018-08-19 23:15:23 +02:00
var url = "" ;
for ( let emote in window . bdEmotes . TwitchGlobal ) {
if ( window . bdEmotes . TwitchGlobal . hasOwnProperty ( emote ) ) {
url = window . bdEmotes . TwitchGlobal [ emote ] ;
2017-04-30 03:11:22 +02:00
teContainer += "<div class=\"emote-container\">" ;
2018-01-09 04:24:00 +01:00
teContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\">" ;
2017-04-30 03:11:22 +02:00
teContainer += " </img>" ;
teContainer += "</div>" ;
}
2015-12-31 18:27:43 +01:00
}
2017-11-03 04:05:33 +01:00
teContainer += " </div>" ;
teContainer += " </div>" ;
teContainer += " </div>" ;
teContainer += "</div>" ;
2017-04-30 03:11:22 +02:00
this . teContainer = teContainer ;
2015-12-31 18:27:43 +01:00
2017-11-01 06:03:48 +01:00
var faContainer = "" ;
2017-04-30 03:11:22 +02:00
faContainer += "<div id=\"bda-qem-favourite-container\">" ;
2019-01-16 23:06:39 +01:00
faContainer += " <div class=\"scroller-wrap scrollerWrap-2lJEkd fade\">" ;
faContainer += " <div class=\"scroller scroller-2FKFPG\">" ;
2017-04-30 03:11:22 +02:00
faContainer += " <div class=\"emote-menu-inner\">" ;
2017-11-03 04:05:33 +01:00
for ( let emote in this . favoriteEmotes ) {
2018-08-19 23:15:23 +02:00
url = this . favoriteEmotes [ emote ] ;
2017-04-30 03:11:22 +02:00
faContainer += "<div class=\"emote-container\">" ;
2017-11-01 06:03:48 +01:00
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\" oncontextmenu='quickEmoteMenu.favContext(event, this);'>" ;
2017-04-30 03:11:22 +02:00
faContainer += " </img>" ;
faContainer += "</div>" ;
2015-12-31 18:27:43 +01:00
}
2017-11-01 06:03:48 +01:00
faContainer += " </div>" ;
faContainer += " </div>" ;
faContainer += " </div>" ;
faContainer += "</div>" ;
2017-04-30 03:11:22 +02:00
this . faContainer = faContainer ;
2015-12-31 18:27:43 +01:00
} ;
2017-04-30 03:11:22 +02:00
QuickEmoteMenu . prototype . favContext = function ( e , em ) {
e . stopPropagation ( ) ;
2019-05-22 07:20:54 +02:00
var menu = $ ( "<div>" , { "id" : "removemenu" , "data-emoteid" : $ ( em ) . prop ( "title" ) , "text" : "Remove" , "class" : "bd-context-menu context-menu theme-dark" } ) ;
2017-04-30 03:11:22 +02:00
menu . css ( {
top : e . pageY - $ ( "#bda-qem-favourite-container" ) . offset ( ) . top ,
left : e . pageX - $ ( "#bda-qem-favourite-container" ) . offset ( ) . left
} ) ;
$ ( em ) . parent ( ) . append ( menu ) ;
menu . on ( "click" , function ( e ) {
e . preventDefault ( ) ;
e . stopPropagation ( ) ;
$ ( this ) . remove ( ) ;
2015-12-31 18:27:43 +01:00
2017-04-30 03:11:22 +02:00
delete quickEmoteMenu . favoriteEmotes [ $ ( this ) . data ( "emoteid" ) ] ;
quickEmoteMenu . updateFavorites ( ) ;
return false ;
} ) ;
return false ;
2015-12-31 18:27:43 +01:00
} ;
2017-04-30 03:11:22 +02:00
QuickEmoteMenu . prototype . switchHandler = function ( e ) {
this . switchQem ( $ ( e ) . attr ( "id" ) ) ;
2016-01-07 07:35:40 +01:00
} ;
2015-12-12 09:50:25 +01:00
2017-04-30 03:11:22 +02:00
QuickEmoteMenu . prototype . switchQem = function ( id ) {
var twitch = $ ( "#bda-qem-twitch" ) ;
var fav = $ ( "#bda-qem-favourite" ) ;
var emojis = $ ( "#bda-qem-emojis" ) ;
twitch . removeClass ( "active" ) ;
fav . removeClass ( "active" ) ;
emojis . removeClass ( "active" ) ;
2015-12-12 09:50:25 +01:00
2018-05-05 15:45:34 +02:00
$ ( ".emojiPicker-3m1S-j" ) . hide ( ) ;
2017-04-30 03:11:22 +02:00
$ ( "#bda-qem-favourite-container" ) . hide ( ) ;
$ ( "#bda-qem-twitch-container" ) . hide ( ) ;
2015-12-12 09:50:25 +01:00
2018-08-19 23:15:23 +02:00
switch ( id ) {
2017-04-30 03:11:22 +02:00
case "bda-qem-twitch" :
twitch . addClass ( "active" ) ;
$ ( "#bda-qem-twitch-container" ) . show ( ) ;
break ;
case "bda-qem-favourite" :
fav . addClass ( "active" ) ;
$ ( "#bda-qem-favourite-container" ) . show ( ) ;
break ;
case "bda-qem-emojis" :
emojis . addClass ( "active" ) ;
2018-05-05 15:45:34 +02:00
$ ( ".emojiPicker-3m1S-j" ) . show ( ) ;
2020-02-27 03:43:16 +01:00
$ ( ".emojiPicker-3m1S-j input" ) . focus ( ) ;
2017-04-30 03:11:22 +02:00
break ;
}
this . lastTab = id ;
2015-12-12 09:50:25 +01:00
2017-04-30 03:11:22 +02:00
var emoteIcon = $ ( ".emote-icon" ) ;
emoteIcon . off ( ) ;
emoteIcon . on ( "click" , function ( ) {
var emote = $ ( this ) . attr ( "title" ) ;
2020-02-27 03:43:16 +01:00
const newTextarea = document . querySelector ( ` . ${ BDV2 . slateEditorClasses . slateTextArea . split ( " " ) [ 0 ] } ` ) ;
if ( newTextarea ) {
const instance = BdApi . getInternalInstance ( newTextarea ) ;
const insert = Utils . getNestedProp ( instance , "memoizedProps.children.props.editor.insertText" ) ;
if ( insert ) insert ( ` ${ emote } ` ) ;
}
else {
var ta = Utils . getTextArea ( ) ;
Utils . insertText ( ta [ 0 ] , ta . val ( ) . slice ( - 1 ) == " " ? ta . val ( ) + emote : ta . val ( ) + " " + emote ) ;
}
2017-04-30 03:11:22 +02:00
} ) ;
2015-12-12 09:50:25 +01:00
} ;
2017-10-29 21:33:48 +01:00
QuickEmoteMenu . prototype . obsCallback = function ( elem ) {
2019-01-04 01:49:09 +01:00
if ( ! this . initialized ) return ;
2017-10-29 21:33:48 +01:00
var e = $ ( elem ) ;
2018-08-19 23:15:23 +02:00
if ( ! settingsCookie [ "bda-es-9" ] ) {
2017-04-30 03:11:22 +02:00
e . addClass ( "bda-qme-hidden" ) ;
2018-08-19 23:15:23 +02:00
}
else {
2017-04-30 03:11:22 +02:00
e . removeClass ( "bda-qme-hidden" ) ;
2015-12-12 09:50:25 +01:00
}
2018-08-19 23:15:23 +02:00
if ( ! settingsCookie [ "bda-es-0" ] ) return ;
2015-12-12 09:50:25 +01:00
2017-04-30 03:11:22 +02:00
e . prepend ( this . qmeHeader ) ;
e . append ( this . teContainer ) ;
e . append ( this . faContainer ) ;
2018-08-19 23:15:23 +02:00
if ( this . lastTab == undefined ) {
2019-05-22 07:20:54 +02:00
this . lastTab = "bda-qem-emojis" ;
2019-03-13 18:13:43 +01:00
}
2017-04-30 03:11:22 +02:00
this . switchQem ( this . lastTab ) ;
2015-12-12 13:53:07 +01:00
} ;
2017-04-30 03:11:22 +02:00
QuickEmoteMenu . prototype . favorite = function ( name , url ) {
2016-01-08 16:33:43 +01:00
2017-04-30 03:11:22 +02:00
if ( ! this . favoriteEmotes . hasOwnProperty ( name ) ) {
this . favoriteEmotes [ name ] = url ;
2015-12-12 17:54:44 +01:00
}
2017-04-30 03:11:22 +02:00
this . updateFavorites ( ) ;
2015-12-12 13:53:07 +01:00
} ;
2017-04-30 03:11:22 +02:00
QuickEmoteMenu . prototype . updateFavorites = function ( ) {
2016-01-08 16:33:43 +01:00
2017-11-01 06:03:48 +01:00
var faContainer = "" ;
2017-04-30 03:11:22 +02:00
faContainer += "<div id=\"bda-qem-favourite-container\">" ;
2019-01-16 23:06:39 +01:00
faContainer += " <div class=\"scroller-wrap scrollerWrap-2lJEkd fade\">" ;
faContainer += " <div class=\"scroller scroller-2FKFPG\">" ;
2017-04-30 03:11:22 +02:00
faContainer += " <div class=\"emote-menu-inner\">" ;
for ( var emote in this . favoriteEmotes ) {
var url = this . favoriteEmotes [ emote ] ;
faContainer += "<div class=\"emote-container\">" ;
2017-11-03 20:52:35 +01:00
faContainer += " <img class=\"emote-icon\" alt=\"\" src=\"" + url + "\" title=\"" + emote + "\" oncontextmenu=\"quickEmoteMenu.favContext(event, this);\">" ;
2017-04-30 03:11:22 +02:00
faContainer += " </img>" ;
faContainer += "</div>" ;
2015-12-12 17:54:44 +01:00
}
2017-11-01 06:03:48 +01:00
faContainer += " </div>" ;
faContainer += " </div>" ;
faContainer += " </div>" ;
faContainer += "</div>" ;
2017-04-30 03:11:22 +02:00
this . faContainer = faContainer ;
$ ( "#bda-qem-favourite-container" ) . replaceWith ( faContainer ) ;
2018-10-19 05:59:27 +02:00
DataStore . setBDData ( "bdfavemotes" , btoa ( JSON . stringify ( this . favoriteEmotes ) ) ) ;
2016-01-07 07:35:40 +01:00
} ;
2017-04-30 03:11:22 +02:00
2017-05-04 17:47:16 +02:00
2017-04-30 03:11:22 +02:00
/ * B e t t e r D i s c o r d A p p U t i l i t i e s J a v a S c r i p t
2018-10-15 01:56:16 +02:00
* Version : 2.0 . 0
2017-04-30 03:11:22 +02:00
* Author : Jiiks | http : //jiiks.net
* Date : 26 / 08 / 2015 - 15 : 54
* https : //github.com/Jiiks/BetterDiscordApp
* /
2018-10-15 01:56:16 +02:00
var Utils = class {
2018-10-19 05:59:27 +02:00
/** Document/window width */
static get screenWidth ( ) { return Math . max ( document . documentElement . clientWidth , window . innerWidth || 0 ) ; }
/** Document/window height */
static get screenHeight ( ) { return Math . max ( document . documentElement . clientHeight , window . innerHeight || 0 ) ; }
static stripBOM ( content ) {
if ( content . charCodeAt ( 0 ) === 0xFEFF ) {
content = content . slice ( 1 ) ;
}
return content ;
}
2018-10-15 01:56:16 +02:00
2018-10-14 09:45:56 +02:00
static getTextArea ( ) {
2020-02-27 03:43:16 +01:00
return $ ( ".channelTextArea-rNsIhG textarea" ) ;
2017-04-30 03:11:22 +02:00
}
2018-10-14 09:45:56 +02:00
static insertText ( textarea , text ) {
textarea . focus ( ) ;
textarea . selectionStart = 0 ;
textarea . selectionEnd = textarea . value . length ;
document . execCommand ( "insertText" , false , text ) ;
2017-10-31 07:35:38 +01:00
}
2017-04-30 03:11:22 +02:00
2018-10-14 09:45:56 +02:00
static injectCss ( uri ) {
$ ( "<link/>" , {
type : "text/css" ,
rel : "stylesheet" ,
href : uri
} ) . appendTo ( $ ( "head" ) ) ;
}
2018-02-28 08:25:06 +01:00
2018-10-14 09:45:56 +02:00
static injectJs ( uri ) {
2018-10-28 21:28:13 +01:00
return new Promise ( resolve => {
$ ( "<script/>" , {
type : "text/javascript" ,
src : uri ,
onload : resolve
} ) . appendTo ( $ ( "body" ) ) ;
} ) ;
2018-10-14 09:45:56 +02:00
}
2018-02-28 08:25:06 +01:00
2018-10-14 09:45:56 +02:00
static escapeID ( id ) {
2019-06-19 04:28:48 +02:00
return id . replace ( /^[^a-z]+|[^\w-]+/gi , "-" ) ;
2018-10-14 09:45:56 +02:00
}
2018-02-28 08:25:06 +01:00
2018-11-10 06:00:53 +01:00
static log ( moduleName , message ) {
console . log ( ` %c[BandagedBD]%c [ ${ moduleName } ]%c ${ message } ` , "color: #3a71c1; font-weight: 700;" , "color: #3a71c1;" , "" ) ;
2018-10-14 09:45:56 +02:00
}
2018-02-28 08:25:06 +01:00
2018-11-10 06:00:53 +01:00
static warn ( moduleName , message ) {
console . warn ( ` %c[BandagedBD]%c [ ${ moduleName } ]%c ${ message } ` , "color: #E8A400; font-weight: 700;" , "color: #E8A400;" , "" ) ;
2018-10-15 01:56:16 +02:00
}
2018-11-10 06:00:53 +01:00
static err ( moduleName , message , error ) {
console . log ( ` %c[BandagedBD]%c [ ${ moduleName } ]%c ${ message } ` , "color: red; font-weight: 700;" , "color: red;" , "" ) ;
2018-10-14 09:45:56 +02:00
if ( error ) {
console . groupCollapsed ( "%cError: " + error . message , "color: red;" ) ;
console . error ( error . stack ) ;
console . groupEnd ( ) ;
}
}
2018-02-28 08:25:06 +01:00
2018-10-14 09:45:56 +02:00
static escape ( s ) {
return s . replace ( /[-/\\^$*+?.()|[\]{}]/g , "\\$&" ) ;
2018-02-28 08:25:06 +01:00
}
2018-10-14 09:45:56 +02:00
static testJSON ( data ) {
try {
2019-06-19 04:28:48 +02:00
return JSON . parse ( data ) ;
2018-10-14 09:45:56 +02:00
}
catch ( err ) {
return false ;
}
2018-08-19 23:15:23 +02:00
}
2018-10-14 09:45:56 +02:00
2019-06-19 04:28:48 +02:00
static isEmpty ( obj ) {
if ( obj == null || obj == undefined || obj == "" ) return true ;
if ( typeof ( obj ) !== "object" ) return false ;
if ( Array . isArray ( obj ) ) return obj . length == 0 ;
for ( const key in obj ) {
if ( obj . hasOwnProperty ( key ) ) return false ;
}
return true ;
}
2018-10-15 01:56:16 +02:00
static suppressErrors ( method , message ) {
2018-10-14 09:45:56 +02:00
return ( ... params ) => {
try { return method ( ... params ) ; }
2019-05-23 08:35:35 +02:00
catch ( e ) { this . err ( "SuppressedError" , "Error occurred in " + message , e ) ; }
2018-08-19 23:15:23 +02:00
} ;
2018-10-14 09:45:56 +02:00
}
static monkeyPatch ( what , methodName , options ) {
const { before , after , instead , once = false , silent = false , force = false } = options ;
2020-02-10 06:57:25 +01:00
const displayName = options . displayName || what . displayName || what [ methodName ] . displayName || what . name || what . constructor . displayName || what . constructor . name ;
2018-10-14 09:45:56 +02:00
if ( ! silent ) console . log ( "patch" , methodName , "of" , displayName ) ; // eslint-disable-line no-console
if ( ! what [ methodName ] ) {
if ( force ) what [ methodName ] = function ( ) { } ;
else return console . error ( methodName , "does not exist for" , displayName ) ; // eslint-disable-line no-console
2018-08-19 23:15:23 +02:00
}
2018-10-14 09:45:56 +02:00
const origMethod = what [ methodName ] ;
const cancel = ( ) => {
if ( ! silent ) console . log ( "unpatch" , methodName , "of" , displayName ) ; // eslint-disable-line no-console
what [ methodName ] = origMethod ;
} ;
what [ methodName ] = function ( ) {
const data = {
thisObject : this ,
methodArguments : arguments ,
cancelPatch : cancel ,
originalMethod : origMethod ,
callOriginalMethod : ( ) => data . returnValue = data . originalMethod . apply ( data . thisObject , data . methodArguments )
} ;
if ( instead ) {
const tempRet = Utils . suppressErrors ( instead , "`instead` callback of " + what [ methodName ] . displayName ) ( data ) ;
if ( tempRet !== undefined ) data . returnValue = tempRet ;
2018-08-23 05:30:07 +02:00
}
2018-10-14 09:45:56 +02:00
else {
if ( before ) Utils . suppressErrors ( before , "`before` callback of " + what [ methodName ] . displayName ) ( data ) ;
data . callOriginalMethod ( ) ;
if ( after ) Utils . suppressErrors ( after , "`after` callback of " + what [ methodName ] . displayName ) ( data ) ;
}
if ( once ) cancel ( ) ;
return data . returnValue ;
} ;
2020-02-10 15:43:44 +01:00
Object . assign ( what [ methodName ] , origMethod ) ;
2018-10-14 09:45:56 +02:00
what [ methodName ] . _ _monkeyPatched = true ;
2020-02-10 06:57:25 +01:00
what [ methodName ] . displayName = displayName ;
2020-02-10 15:43:44 +01:00
if ( ! what [ methodName ] . _ _originalMethod ) {
what [ methodName ] . _ _originalMethod = origMethod ;
what [ methodName ] . toString = function ( ) { return origMethod . toString ( ) ; } ;
}
2018-10-14 09:45:56 +02:00
return cancel ;
}
static onRemoved ( node , callback ) {
const observer = new MutationObserver ( ( mutations ) => {
for ( let m = 0 ; m < mutations . length ; m ++ ) {
const mutation = mutations [ m ] ;
const nodes = Array . from ( mutation . removedNodes ) ;
const directMatch = nodes . indexOf ( node ) > - 1 ;
const parentMatch = nodes . some ( parent => parent . contains ( node ) ) ;
if ( directMatch || parentMatch ) {
observer . disconnect ( ) ;
callback ( ) ;
}
}
} ) ;
2019-03-13 18:13:43 +01:00
2018-10-14 09:45:56 +02:00
observer . observe ( document . body , { subtree : true , childList : true } ) ;
}
2020-01-08 19:26:25 +01:00
static getNestedProp ( obj , path ) {
return path . split ( /\s?\.\s?/ ) . reduce ( function ( obj , prop ) {
return obj && obj [ prop ] ;
} , obj ) ;
}
2018-08-28 01:38:49 +02:00
} ;
2018-08-23 05:30:07 +02:00
2018-03-12 19:36:13 +01:00
2017-11-04 03:43:59 +01:00
2017-04-30 03:11:22 +02:00
/ * B e t t e r D i s c o r d A p p V o i c e M o d e J a v a S c r i p t
* Version : 1.0
* Author : Jiiks | http : //jiiks.net
* Date : 25 / 10 / 2015 - 19 : 10
* https : //github.com/Jiiks/BetterDiscordApp
* /
function VoiceMode ( ) {
}
VoiceMode . prototype . enable = function ( ) {
$ ( ".scroller.guild-channels ul" ) . first ( ) . css ( "display" , "none" ) ;
$ ( ".scroller.guild-channels header" ) . first ( ) . css ( "display" , "none" ) ;
2019-01-12 01:15:45 +01:00
$ ( ".app.flex-vertical, .app-2rEoOp" ) . first ( ) . css ( "overflow" , "hidden" ) ;
2018-08-06 07:37:31 +02:00
$ ( ".chat-3bRxxu" ) . first ( ) . css ( "visibility" , "hidden" ) . css ( "min-width" , "0px" ) ;
2017-04-30 03:11:22 +02:00
$ ( ".flex-vertical.channels-wrap" ) . first ( ) . css ( "flex-grow" , "100000" ) ;
$ ( ".guild-header .btn.btn-hamburger" ) . first ( ) . css ( "visibility" , "hidden" ) ;
} ;
VoiceMode . prototype . disable = function ( ) {
$ ( ".scroller.guild-channels ul" ) . first ( ) . css ( "display" , "" ) ;
$ ( ".scroller.guild-channels header" ) . first ( ) . css ( "display" , "" ) ;
2019-01-12 01:15:45 +01:00
$ ( ".app.flex-vertical, .app-2rEoOp" ) . first ( ) . css ( "overflow" , "" ) ;
2018-08-06 07:37:31 +02:00
$ ( ".chat-3bRxxu" ) . first ( ) . css ( "visibility" , "" ) . css ( "min-width" , "" ) ;
2017-04-30 03:11:22 +02:00
$ ( ".flex-vertical.channels-wrap" ) . first ( ) . css ( "flex-grow" , "" ) ;
$ ( ".guild-header .btn.btn-hamburger" ) . first ( ) . css ( "visibility" , "" ) ;
} ;
2018-10-19 05:59:27 +02:00
// e.remote.app.getAppPath()
// path = require("path")
// require("path").resolve(require("electron").remote.app.getAppPath(), "node_modules", "request", "index.js");
window . bdthemes = { } ;
window . bdplugins = { } ;
var ContentManager = ( ( ) => {
const path = require ( "path" ) ;
const fs = require ( "fs" ) ;
const Module = require ( "module" ) . Module ;
Module . globalPaths . push ( path . resolve ( require ( "electron" ) . remote . app . getAppPath ( ) , "node_modules" ) ) ;
class MetaError extends Error {
constructor ( message ) {
super ( message ) ;
this . name = "MetaError" ;
}
}
2018-10-28 21:28:13 +01:00
const originalJSRequire = Module . _extensions [ ".js" ] ;
2018-10-19 05:59:27 +02:00
const originalCSSRequire = Module . _extensions [ ".css" ] ? Module . _extensions [ ".css" ] : ( ) => { return null ; } ;
2019-06-19 23:26:17 +02:00
const splitRegex = /[^\S\r\n]*?(?:\r\n|\n)[^\S\r\n]*?\*[^\S\r\n]?/ ;
2019-06-19 04:28:48 +02:00
const escapedAtRegex = /^\\@/ ;
2018-10-19 05:59:27 +02:00
return new class ContentManager {
constructor ( ) {
this . timeCache = { } ;
this . watchers = { } ;
Module . _extensions [ ".js" ] = this . getContentRequire ( "plugin" ) ;
Module . _extensions [ ".css" ] = this . getContentRequire ( "theme" ) ;
}
get pluginsFolder ( ) { return this . _pluginsFolder || ( this . _pluginsFolder = fs . realpathSync ( path . resolve ( bdConfig . dataPath + "plugins/" ) ) ) ; }
get themesFolder ( ) { return this . _themesFolder || ( this . _themesFolder = fs . realpathSync ( path . resolve ( bdConfig . dataPath + "themes/" ) ) ) ; }
watchContent ( contentType ) {
if ( this . watchers [ contentType ] ) return ;
const isPlugin = contentType === "plugin" ;
const baseFolder = isPlugin ? this . pluginsFolder : this . themesFolder ;
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css" ;
this . watchers [ contentType ] = fs . watch ( baseFolder , { persistent : false } , async ( eventType , filename ) => {
if ( ! eventType || ! filename || ! filename . endsWith ( fileEnding ) ) return ;
await new Promise ( r => setTimeout ( r , 50 ) ) ;
2018-10-21 00:02:53 +02:00
try { fs . statSync ( path . resolve ( baseFolder , filename ) ) ; }
2018-10-19 05:59:27 +02:00
catch ( err ) {
if ( err . code !== "ENOENT" ) return ;
delete this . timeCache [ filename ] ;
2018-10-28 21:28:13 +01:00
if ( isPlugin ) return pluginModule . unloadPlugin ( filename ) ;
return themeModule . unloadTheme ( filename ) ;
2018-10-19 05:59:27 +02:00
}
2018-10-21 00:02:53 +02:00
if ( ! fs . statSync ( path . resolve ( baseFolder , filename ) ) . isFile ( ) ) return ;
const stats = fs . statSync ( path . resolve ( baseFolder , filename ) ) ;
2018-10-19 05:59:27 +02:00
if ( ! stats || ! stats . mtime || ! stats . mtime . getTime ( ) ) return ;
if ( typeof ( stats . mtime . getTime ( ) ) !== "number" ) return ;
if ( this . timeCache [ filename ] == stats . mtime . getTime ( ) ) return ;
this . timeCache [ filename ] = stats . mtime . getTime ( ) ;
if ( eventType == "rename" ) {
if ( isPlugin ) pluginModule . loadPlugin ( filename ) ;
else themeModule . loadTheme ( filename ) ;
}
if ( eventType == "change" ) {
2018-10-28 21:28:13 +01:00
if ( isPlugin ) pluginModule . reloadPlugin ( filename ) ;
else themeModule . reloadTheme ( filename ) ;
2018-10-19 05:59:27 +02:00
}
} ) ;
}
unwatchContent ( contentType ) {
if ( ! this . watchers [ contentType ] ) return ;
this . watchers [ contentType ] . close ( ) ;
2018-10-29 18:53:10 +01:00
delete this . watchers [ contentType ] ;
2018-10-19 05:59:27 +02:00
}
extractMeta ( content ) {
2019-06-19 04:28:48 +02:00
const firstLine = content . split ( "\n" ) [ 0 ] ;
const hasOldMeta = firstLine . includes ( "//META" ) ;
if ( hasOldMeta ) return this . parseOldMeta ( content ) ;
const hasNewMeta = firstLine . includes ( "/**" ) ;
if ( hasNewMeta ) return this . parseNewMeta ( content ) ;
throw new MetaError ( "META was not found." ) ;
}
parseOldMeta ( content ) {
2018-10-19 05:59:27 +02:00
const meta = content . split ( "\n" ) [ 0 ] ;
const rawMeta = meta . substring ( meta . lastIndexOf ( "//META" ) + 6 , meta . lastIndexOf ( "*//" ) ) ;
if ( meta . indexOf ( "META" ) < 0 ) throw new MetaError ( "META was not found." ) ;
2019-06-19 04:28:48 +02:00
const parsed = Utils . testJSON ( rawMeta ) ;
if ( ! parsed ) throw new MetaError ( "META could not be parsed." ) ;
2018-10-19 05:59:27 +02:00
if ( ! parsed . name ) throw new MetaError ( "META missing name data." ) ;
2019-06-19 23:26:17 +02:00
parsed . format = "json" ;
2018-10-19 05:59:27 +02:00
return parsed ;
}
2019-06-19 17:52:32 +02:00
2019-06-19 04:28:48 +02:00
parseNewMeta ( content ) {
const block = content . split ( "/**" , 2 ) [ 1 ] . split ( "*/" , 1 ) [ 0 ] ;
const out = { } ;
let field = "" ;
let accum = "" ;
for ( const line of block . split ( splitRegex ) ) {
if ( line . length === 0 ) continue ;
if ( line . charAt ( 0 ) === "@" && line . charAt ( 1 ) !== " " ) {
out [ field ] = accum ;
const l = line . indexOf ( " " ) ;
field = line . substr ( 1 , l - 1 ) ;
accum = line . substr ( l + 1 ) ;
}
else {
accum += " " + line . replace ( "\\n" , "\n" ) . replace ( escapedAtRegex , "@" ) ;
}
}
out [ field ] = accum . trim ( ) ;
delete out [ "" ] ;
2019-06-19 23:26:17 +02:00
out . format = "jsdoc" ;
2019-06-19 04:28:48 +02:00
return out ;
}
2018-10-19 05:59:27 +02:00
getContentRequire ( type ) {
const isPlugin = type === "plugin" ;
const self = this ;
const originalRequire = isPlugin ? originalJSRequire : originalCSSRequire ;
return function ( module , filename ) {
2018-10-24 20:14:35 +02:00
const baseFolder = isPlugin ? self . pluginsFolder : self . themesFolder ;
const possiblePath = path . resolve ( baseFolder , path . basename ( filename ) ) ;
if ( ! fs . existsSync ( possiblePath ) || filename !== fs . realpathSync ( possiblePath ) ) return Reflect . apply ( originalRequire , this , arguments ) ;
2018-10-19 05:59:27 +02:00
let content = fs . readFileSync ( filename , "utf8" ) ;
content = Utils . stripBOM ( content ) ;
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
const meta = self . extractMeta ( content ) ;
meta . filename = path . basename ( filename ) ;
if ( ! isPlugin ) {
2019-06-19 17:52:32 +02:00
meta . css = content ;
2019-06-19 23:26:17 +02:00
if ( meta . format == "json" ) meta . css = meta . css . split ( "\n" ) . slice ( 1 ) . join ( "\n" ) ;
2018-10-19 05:59:27 +02:00
content = ` module.exports = ${ JSON . stringify ( meta ) } ; ` ;
}
if ( isPlugin ) {
2019-06-19 04:28:48 +02:00
module . _compile ( content , module . filename ) ;
const didExport = ! Utils . isEmpty ( module . exports ) ;
if ( didExport ) {
meta . type = module . exports ;
module . exports = meta ;
content = "" ;
}
else {
content += ` \n module.exports = ${ JSON . stringify ( meta ) } ; \n module.exports.type = ${ meta . exports || meta . name } ; ` ;
}
2018-10-19 05:59:27 +02:00
}
module . _compile ( content , filename ) ;
} ;
}
makePlaceholderPlugin ( data ) {
return { plugin : {
start : ( ) => { } ,
getName : ( ) => { return data . name || data . filename ; } ,
getAuthor : ( ) => { return "???" ; } ,
getDescription : ( ) => { return data . message ? data . message : "This plugin was unable to be loaded. Check the author's page for updates." ; } ,
getVersion : ( ) => { return "???" ; }
} ,
name : data . name || data . filename ,
filename : data . filename ,
source : data . source ? data . source : "" ,
website : data . website ? data . website : ""
} ;
}
loadContent ( filename , type ) {
if ( typeof ( filename ) === "undefined" || typeof ( type ) === "undefined" ) return ;
const isPlugin = type === "plugin" ;
const baseFolder = isPlugin ? this . pluginsFolder : this . themesFolder ;
try { require ( path . resolve ( baseFolder , filename ) ) ; }
2018-10-28 21:28:13 +01:00
catch ( error ) { return { name : filename , file : filename , message : "Could not be compiled." , error : { message : error . message , stack : error . stack } } ; }
2018-10-19 05:59:27 +02:00
const content = require ( path . resolve ( baseFolder , filename ) ) ;
2019-06-19 04:28:48 +02:00
content . id = Utils . escapeID ( content . name ) ;
2018-10-19 05:59:27 +02:00
if ( isPlugin ) {
if ( ! content . type ) return ;
2018-10-19 08:27:02 +02:00
try {
content . plugin = new content . type ( ) ;
delete bdplugins [ content . plugin . getName ( ) ] ;
bdplugins [ content . plugin . getName ( ) ] = content ;
}
2018-10-28 21:28:13 +01:00
catch ( error ) { return { name : filename , file : filename , message : "Could not be constructed." , error : { message : error . message , stack : error . stack } } ; }
2018-10-19 05:59:27 +02:00
}
else {
delete bdthemes [ content . name ] ;
bdthemes [ content . name ] = content ;
}
}
unloadContent ( filename , type ) {
if ( typeof ( filename ) === "undefined" || typeof ( type ) === "undefined" ) return ;
const isPlugin = type === "plugin" ;
const baseFolder = isPlugin ? this . pluginsFolder : this . themesFolder ;
try {
2018-10-28 21:28:13 +01:00
delete require . cache [ require . resolve ( path . resolve ( baseFolder , filename ) ) ] ;
2018-10-19 05:59:27 +02:00
}
2018-10-28 21:28:13 +01:00
catch ( err ) { return { name : filename , file : filename , message : "Could not be unloaded." , error : { message : err . message , stack : err . stack } } ; }
2018-10-19 05:59:27 +02:00
}
isLoaded ( filename , type ) {
const isPlugin = type === "plugin" ;
const baseFolder = isPlugin ? this . pluginsFolder : this . themesFolder ;
2018-10-28 21:28:13 +01:00
try { require . cache [ require . resolve ( path . resolve ( baseFolder , filename ) ) ] ; }
2018-10-19 05:59:27 +02:00
catch ( err ) { return false ; }
return true ;
}
reloadContent ( filename , type ) {
2018-10-28 21:28:13 +01:00
const cantUnload = this . unloadContent ( filename , type ) ;
if ( cantUnload ) return cantUnload ;
2018-10-19 05:59:27 +02:00
return this . loadContent ( filename , type ) ;
}
loadNewContent ( type ) {
const isPlugin = type === "plugin" ;
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css" ;
const basedir = isPlugin ? this . pluginsFolder : this . themesFolder ;
const files = fs . readdirSync ( basedir ) ;
const contentList = Object . values ( isPlugin ? bdplugins : bdthemes ) ;
const removed = contentList . filter ( t => ! files . includes ( t . filename ) ) . map ( c => isPlugin ? c . plugin . getName ( ) : c . name ) ;
const added = files . filter ( f => ! contentList . find ( t => t . filename == f ) && f . endsWith ( fileEnding ) && fs . statSync ( path . resolve ( basedir , f ) ) . isFile ( ) ) ;
return { added , removed } ;
}
loadAllContent ( type ) {
const isPlugin = type === "plugin" ;
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css" ;
const basedir = isPlugin ? this . pluginsFolder : this . themesFolder ;
const errors = [ ] ;
const files = fs . readdirSync ( basedir ) ;
for ( const filename of files ) {
if ( ! fs . statSync ( path . resolve ( basedir , filename ) ) . isFile ( ) || ! filename . endsWith ( fileEnding ) ) continue ;
const error = this . loadContent ( filename , type ) ;
if ( error ) errors . push ( error ) ;
}
return errors ;
}
loadPlugins ( ) { return this . loadAllContent ( "plugin" ) ; }
loadThemes ( ) { return this . loadAllContent ( "theme" ) ; }
} ;
} ) ( ) ;
2017-04-30 03:11:22 +02:00
/ * B e t t e r D i s c o r d A p p P l u g i n M o d u l e J a v a S c r i p t
* Version : 1.0
* Author : Jiiks | http : //jiiks.net
* Date : 16 / 12 / 2015
* https : //github.com/Jiiks/BetterDiscordApp
* /
var pluginCookie = { } ;
function PluginModule ( ) {
2019-03-13 18:13:43 +01:00
2017-04-30 03:11:22 +02:00
}
PluginModule . prototype . loadPlugins = function ( ) {
this . loadPluginData ( ) ;
2018-10-19 05:59:27 +02:00
bdpluginErrors = ContentManager . loadPlugins ( ) ;
2017-10-31 07:39:42 +01:00
var plugins = Object . keys ( bdplugins ) ;
2017-10-31 07:35:38 +01:00
for ( var i = 0 ; i < plugins . length ; i ++ ) {
2017-10-31 07:58:39 +01:00
var plugin , name ;
2017-10-31 07:35:38 +01:00
2017-10-31 07:58:39 +01:00
try {
plugin = bdplugins [ plugins [ i ] ] . plugin ;
2017-10-29 22:58:35 +01:00
name = plugin . getName ( ) ;
2018-08-28 01:19:17 +02:00
if ( plugin . load && typeof ( plugin . load ) == "function" ) plugin . load ( ) ;
2017-10-29 22:58:35 +01:00
}
2017-10-31 09:26:30 +01:00
catch ( err ) {
pluginCookie [ name ] = false ;
2018-11-10 06:00:53 +01:00
Utils . err ( "Plugins" , name + " could not be loaded." , err ) ;
2018-10-28 21:28:13 +01:00
bdpluginErrors . push ( { name : name , file : bdplugins [ plugins [ i ] ] . filename , message : "load() could not be fired." , error : { message : err . message , stack : err . stack } } ) ;
2017-10-31 22:28:49 +01:00
continue ;
2017-10-31 09:26:30 +01:00
}
2017-04-30 03:11:22 +02:00
2017-10-31 07:58:39 +01:00
if ( ! pluginCookie [ name ] ) pluginCookie [ name ] = false ;
2017-04-30 03:11:22 +02:00
2017-10-31 07:58:39 +01:00
if ( pluginCookie [ name ] ) {
2017-11-03 21:08:53 +01:00
try {
plugin . start ( ) ;
2017-12-24 07:51:24 +01:00
if ( settingsCookie [ "fork-ps-2" ] ) mainCore . showToast ( ` ${ plugin . getName ( ) } v ${ plugin . getVersion ( ) } has started. ` ) ;
2017-11-03 21:08:53 +01:00
}
2017-10-31 09:26:30 +01:00
catch ( err ) {
pluginCookie [ name ] = false ;
2018-11-10 06:00:53 +01:00
Utils . err ( "Plugins" , name + " could not be started." , err ) ;
2018-10-28 21:28:13 +01:00
bdpluginErrors . push ( { name : name , file : bdplugins [ plugins [ i ] ] . filename , message : "start() could not be fired." , error : { message : err . message , stack : err . stack } } ) ;
2017-10-31 09:26:30 +01:00
}
2017-04-30 03:11:22 +02:00
}
2017-10-31 07:35:38 +01:00
}
2017-10-31 09:26:30 +01:00
this . savePluginData ( ) ;
2018-08-05 07:01:33 +02:00
require ( "electron" ) . remote . getCurrentWebContents ( ) . on ( "did-navigate-in-page" , this . channelSwitch . bind ( this ) ) ;
2018-10-19 05:59:27 +02:00
// if (settingsCookie["fork-ps-5"]) ContentManager.watchContent("plugin");
2017-10-31 09:26:30 +01:00
} ;
2018-10-19 05:59:27 +02:00
PluginModule . prototype . startPlugin = function ( plugin , reload = false ) {
2017-11-03 20:52:35 +01:00
try {
bdplugins [ plugin ] . plugin . start ( ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] && ! reload ) mainCore . showToast ( ` ${ bdplugins [ plugin ] . plugin . getName ( ) } v ${ bdplugins [ plugin ] . plugin . getVersion ( ) } has started. ` ) ;
2017-11-03 20:52:35 +01:00
}
2017-10-31 09:26:30 +01:00
catch ( err ) {
2018-11-10 06:00:53 +01:00
if ( settingsCookie [ "fork-ps-2" ] && ! reload ) mainCore . showToast ( ` ${ bdplugins [ plugin ] . plugin . getName ( ) } v ${ bdplugins [ plugin ] . plugin . getVersion ( ) } could not be started. ` , { type : "error" } ) ;
2017-10-31 09:26:30 +01:00
pluginCookie [ plugin ] = false ;
this . savePluginData ( ) ;
2019-06-19 04:28:48 +02:00
Utils . err ( "Plugins" , plugin + " could not be started." , err ) ;
2017-10-31 09:26:30 +01:00
}
} ;
2018-10-19 05:59:27 +02:00
PluginModule . prototype . stopPlugin = function ( plugin , reload = false ) {
2017-11-03 20:52:35 +01:00
try {
bdplugins [ plugin ] . plugin . stop ( ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] && ! reload ) mainCore . showToast ( ` ${ bdplugins [ plugin ] . plugin . getName ( ) } v ${ bdplugins [ plugin ] . plugin . getVersion ( ) } has stopped. ` ) ;
2017-11-03 20:52:35 +01:00
}
catch ( err ) {
2018-11-10 06:00:53 +01:00
if ( settingsCookie [ "fork-ps-2" ] && ! reload ) mainCore . showToast ( ` ${ bdplugins [ plugin ] . plugin . getName ( ) } v ${ bdplugins [ plugin ] . plugin . getVersion ( ) } could not be stopped. ` , { type : "error" } ) ;
Utils . err ( "Plugins" , bdplugins [ plugin ] . plugin . getName ( ) + " could not be stopped." , err ) ;
2017-11-03 20:52:35 +01:00
}
2017-10-31 09:26:30 +01:00
} ;
2018-10-19 05:59:27 +02:00
PluginModule . prototype . enablePlugin = function ( plugin , reload = false ) {
if ( pluginCookie [ plugin ] ) return ;
2017-10-31 09:26:30 +01:00
pluginCookie [ plugin ] = true ;
this . savePluginData ( ) ;
2018-10-19 05:59:27 +02:00
this . startPlugin ( plugin , reload ) ;
2017-10-31 09:26:30 +01:00
} ;
2018-10-19 05:59:27 +02:00
PluginModule . prototype . disablePlugin = function ( plugin , reload = false ) {
if ( ! pluginCookie [ plugin ] ) return ;
2017-10-31 09:26:30 +01:00
pluginCookie [ plugin ] = false ;
this . savePluginData ( ) ;
2018-10-19 05:59:27 +02:00
this . stopPlugin ( plugin , reload ) ;
2017-10-31 09:26:30 +01:00
} ;
PluginModule . prototype . togglePlugin = function ( plugin ) {
2017-11-01 18:46:13 +01:00
if ( pluginCookie [ plugin ] ) this . disablePlugin ( plugin ) ;
else this . enablePlugin ( plugin ) ;
2017-04-30 03:11:22 +02:00
} ;
2018-10-19 05:59:27 +02:00
PluginModule . prototype . loadPlugin = function ( filename ) {
const error = ContentManager . loadContent ( filename , "plugin" ) ;
2018-10-28 21:28:13 +01:00
if ( error ) {
if ( settingsCookie [ "fork-ps-1" ] ) mainCore . showContentErrors ( { plugins : [ error ] } ) ;
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ filename } could not be loaded. ` , { type : "error" } ) ;
2018-11-10 06:00:53 +01:00
return Utils . err ( "ContentManager" , ` ${ filename } could not be loaded. ` , error ) ;
2018-10-19 05:59:27 +02:00
}
const plugin = Object . values ( bdplugins ) . find ( p => p . filename == filename ) . plugin ;
2018-11-10 06:00:53 +01:00
try { if ( plugin . load && typeof ( plugin . load ) == "function" ) plugin . load ( ) ; }
catch ( err ) { if ( settingsCookie [ "fork-ps-1" ] ) mainCore . showContentErrors ( { plugins : [ err ] } ) ; }
Utils . log ( "ContentManager" , ` ${ plugin . getName ( ) } v ${ plugin . getVersion ( ) } was loaded. ` ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ plugin . getName ( ) } v ${ plugin . getVersion ( ) } was loaded. ` , { type : "success" } ) ;
2018-10-28 21:28:13 +01:00
BDEvents . dispatch ( "plugin-loaded" , plugin . getName ( ) ) ;
2018-10-19 05:59:27 +02:00
} ;
2018-10-28 21:28:13 +01:00
PluginModule . prototype . unloadPlugin = function ( filenameOrName ) {
const bdplugin = Object . values ( bdplugins ) . find ( p => p . filename == filenameOrName ) || bdplugins [ filenameOrName ] ;
if ( ! bdplugin ) return ;
const plugin = bdplugin . plugin . getName ( ) ;
2018-10-19 05:59:27 +02:00
if ( pluginCookie [ plugin ] ) this . disablePlugin ( plugin , true ) ;
const error = ContentManager . unloadContent ( bdplugins [ plugin ] . filename , "plugin" ) ;
delete bdplugins [ plugin ] ;
2018-10-28 21:28:13 +01:00
if ( error ) {
if ( settingsCookie [ "fork-ps-1" ] ) mainCore . showContentErrors ( { plugins : [ error ] } ) ;
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ plugin } could not be unloaded. It may have not been loaded yet. ` , { type : "error" } ) ;
2018-11-10 06:00:53 +01:00
return Utils . err ( "ContentManager" , ` ${ plugin } could not be unloaded. It may have not been loaded yet. ` , error ) ;
2018-10-19 05:59:27 +02:00
}
2018-11-10 06:00:53 +01:00
Utils . log ( "ContentManager" , ` ${ plugin } was unloaded. ` ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ plugin } was unloaded. ` , { type : "success" } ) ;
2018-10-28 21:28:13 +01:00
BDEvents . dispatch ( "plugin-unloaded" , plugin ) ;
2018-10-19 05:59:27 +02:00
} ;
2018-10-28 21:28:13 +01:00
PluginModule . prototype . reloadPlugin = function ( filenameOrName ) {
const bdplugin = Object . values ( bdplugins ) . find ( p => p . filename == filenameOrName ) || bdplugins [ filenameOrName ] ;
if ( ! bdplugin ) return this . loadPlugin ( filenameOrName ) ;
const plugin = bdplugin . plugin . getName ( ) ;
2018-10-19 05:59:27 +02:00
const enabled = pluginCookie [ plugin ] ;
if ( enabled ) this . stopPlugin ( plugin , true ) ;
const error = ContentManager . reloadContent ( bdplugins [ plugin ] . filename , "plugin" ) ;
2018-10-28 21:28:13 +01:00
if ( error ) {
if ( settingsCookie [ "fork-ps-1" ] ) mainCore . showContentErrors ( { plugins : [ error ] } ) ;
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ plugin } could not be reloaded. ` , { type : "error" } ) ;
2018-11-10 06:00:53 +01:00
return Utils . err ( "ContentManager" , ` ${ plugin } could not be reloaded. ` , error ) ;
2018-10-19 05:59:27 +02:00
}
2018-11-03 15:47:41 +01:00
if ( bdplugins [ plugin ] . plugin . load && typeof ( bdplugins [ plugin ] . plugin . load ) == "function" ) bdplugins [ plugin ] . plugin . load ( ) ;
if ( enabled ) this . startPlugin ( plugin , true ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "ContentManager" , ` ${ plugin } v ${ bdplugins [ plugin ] . plugin . getVersion ( ) } was reloaded. ` ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ plugin } v ${ bdplugins [ plugin ] . plugin . getVersion ( ) } was reloaded. ` , { type : "success" } ) ;
2018-10-28 21:28:13 +01:00
BDEvents . dispatch ( "plugin-reloaded" , plugin ) ;
2018-10-19 05:59:27 +02:00
} ;
PluginModule . prototype . updatePluginList = function ( ) {
const results = ContentManager . loadNewContent ( "plugin" ) ;
for ( const filename of results . added ) this . loadPlugin ( filename ) ;
for ( const name of results . removed ) this . unloadPlugin ( name ) ;
} ;
2017-04-30 03:11:22 +02:00
PluginModule . prototype . loadPluginData = function ( ) {
2018-10-19 05:59:27 +02:00
let saved = DataStore . getSettingGroup ( "plugins" ) ;
2018-04-15 20:13:25 +02:00
if ( saved ) {
pluginCookie = saved ;
2017-04-30 03:11:22 +02:00
}
} ;
PluginModule . prototype . savePluginData = function ( ) {
2018-10-19 05:59:27 +02:00
DataStore . setSettingGroup ( "plugins" , pluginCookie ) ;
2017-04-30 03:11:22 +02:00
} ;
PluginModule . prototype . newMessage = function ( ) {
2017-10-31 08:28:03 +01:00
var plugins = Object . keys ( bdplugins ) ;
for ( var i = 0 ; i < plugins . length ; i ++ ) {
var plugin = bdplugins [ plugins [ i ] ] . plugin ;
2017-10-31 22:28:49 +01:00
if ( ! pluginCookie [ plugin . getName ( ) ] ) continue ;
2017-10-31 08:28:03 +01:00
if ( typeof plugin . onMessage === "function" ) {
try { plugin . onMessage ( ) ; }
2018-11-10 06:00:53 +01:00
catch ( err ) { Utils . err ( "Plugins" , "Unable to fire onMessage for " + plugin . getName ( ) + "." , err ) ; }
2017-04-30 03:11:22 +02:00
}
2017-10-31 08:28:03 +01:00
}
2017-04-30 03:11:22 +02:00
} ;
PluginModule . prototype . channelSwitch = function ( ) {
2017-10-31 08:28:03 +01:00
var plugins = Object . keys ( bdplugins ) ;
for ( var i = 0 ; i < plugins . length ; i ++ ) {
var plugin = bdplugins [ plugins [ i ] ] . plugin ;
2017-10-31 22:28:49 +01:00
if ( ! pluginCookie [ plugin . getName ( ) ] ) continue ;
2017-10-31 08:28:03 +01:00
if ( typeof plugin . onSwitch === "function" ) {
try { plugin . onSwitch ( ) ; }
2018-11-10 06:00:53 +01:00
catch ( err ) { Utils . err ( "Plugins" , "Unable to fire onSwitch for " + plugin . getName ( ) + "." , err ) ; }
2017-04-30 03:11:22 +02:00
}
2017-10-31 08:28:03 +01:00
}
2017-04-30 03:11:22 +02:00
} ;
PluginModule . prototype . rawObserver = function ( e ) {
2017-10-31 08:28:03 +01:00
var plugins = Object . keys ( bdplugins ) ;
for ( var i = 0 ; i < plugins . length ; i ++ ) {
var plugin = bdplugins [ plugins [ i ] ] . plugin ;
2017-10-31 22:28:49 +01:00
if ( ! pluginCookie [ plugin . getName ( ) ] ) continue ;
2017-10-31 08:28:03 +01:00
if ( typeof plugin . observer === "function" ) {
try { plugin . observer ( e ) ; }
2018-11-10 06:00:53 +01:00
catch ( err ) { Utils . err ( "Plugins" , "Unable to fire observer for " + plugin . getName ( ) + "." , err ) ; }
2017-04-30 03:11:22 +02:00
}
2017-10-31 08:28:03 +01:00
}
2017-04-30 03:11:22 +02:00
} ;
2017-10-30 04:45:07 +01:00
2017-04-30 03:11:22 +02:00
/ * B e t t e r D i s c o r d A p p T h e m e M o d u l e J a v a S c r i p t
* Version : 1.0
* Author : Jiiks | http : //jiiks.net
* Date : 16 / 12 / 2015
* https : //github.com/Jiiks/BetterDiscordApp
* /
var themeCookie = { } ;
function ThemeModule ( ) {
}
ThemeModule . prototype . loadThemes = function ( ) {
this . loadThemeData ( ) ;
2018-10-19 05:59:27 +02:00
bdthemeErrors = ContentManager . loadThemes ( ) ;
2017-10-31 07:58:39 +01:00
var themes = Object . keys ( bdthemes ) ;
2019-03-13 18:13:43 +01:00
2017-10-31 08:28:03 +01:00
for ( var i = 0 ; i < themes . length ; i ++ ) {
2019-06-19 04:28:48 +02:00
var theme = bdthemes [ themes [ i ] ] ;
if ( ! themeCookie [ theme . name ] ) themeCookie [ theme . name ] = false ;
if ( themeCookie [ theme . name ] ) $ ( "head" ) . append ( $ ( "<style>" , { id : theme . id , text : unescape ( theme . css ) } ) ) ;
2017-10-31 08:28:03 +01:00
}
2018-04-15 20:13:25 +02:00
for ( let theme in themeCookie ) {
if ( ! bdthemes [ theme ] ) delete themeCookie [ theme ] ;
}
this . saveThemeData ( ) ;
2018-10-19 05:59:27 +02:00
// if (settingsCookie["fork-ps-5"]) ContentManager.watchContent("theme");
2017-04-30 03:11:22 +02:00
} ;
2019-06-19 04:28:48 +02:00
ThemeModule . prototype . enableTheme = function ( name , reload = false ) {
themeCookie [ name ] = true ;
2017-11-01 18:34:00 +01:00
this . saveThemeData ( ) ;
2019-06-19 04:28:48 +02:00
const theme = bdthemes [ name ] ;
$ ( "head" ) . append ( $ ( "<style>" , { id : theme . id , text : unescape ( theme . css ) } ) ) ;
if ( settingsCookie [ "fork-ps-2" ] && ! reload ) mainCore . showToast ( ` ${ theme . name } v ${ theme . version } has been applied. ` ) ;
2017-11-01 18:34:00 +01:00
} ;
2019-06-19 04:28:48 +02:00
ThemeModule . prototype . disableTheme = function ( name , reload = false ) {
themeCookie [ name ] = false ;
2017-11-01 18:34:00 +01:00
this . saveThemeData ( ) ;
2019-06-19 04:28:48 +02:00
const theme = bdthemes [ name ] ;
$ ( ` # ${ theme . id } ` ) . remove ( ) ;
if ( settingsCookie [ "fork-ps-2" ] && ! reload ) mainCore . showToast ( ` ${ theme . name } v ${ theme . version } has been disabled. ` ) ;
2017-11-01 18:34:00 +01:00
} ;
2018-10-19 05:59:27 +02:00
ThemeModule . prototype . toggleTheme = function ( theme ) {
2017-11-01 18:46:13 +01:00
if ( themeCookie [ theme ] ) this . disableTheme ( theme ) ;
else this . enableTheme ( theme ) ;
2017-11-01 18:34:00 +01:00
} ;
2018-10-19 05:59:27 +02:00
ThemeModule . prototype . loadTheme = function ( filename ) {
const error = ContentManager . loadContent ( filename , "theme" ) ;
2018-10-28 21:28:13 +01:00
if ( error ) {
if ( settingsCookie [ "fork-ps-1" ] ) mainCore . showContentErrors ( { themes : [ error ] } ) ;
2018-11-10 06:00:53 +01:00
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ filename } could not be loaded. It may not have been loaded. ` , { type : "error" } ) ;
return Utils . err ( "ContentManager" , ` ${ filename } could not be loaded. ` , error ) ;
2018-10-19 05:59:27 +02:00
}
const theme = Object . values ( bdthemes ) . find ( p => p . filename == filename ) ;
2018-11-10 06:00:53 +01:00
Utils . log ( "ContentManager" , ` ${ theme . name } v ${ theme . version } was loaded. ` ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ theme . name } v ${ theme . version } was loaded. ` , { type : "success" } ) ;
2018-10-28 21:28:13 +01:00
BDEvents . dispatch ( "theme-loaded" , theme . name ) ;
2018-10-19 05:59:27 +02:00
} ;
2018-10-28 21:28:13 +01:00
ThemeModule . prototype . unloadTheme = function ( filenameOrName ) {
const bdtheme = Object . values ( bdthemes ) . find ( p => p . filename == filenameOrName ) || bdthemes [ filenameOrName ] ;
if ( ! bdtheme ) return ;
const theme = bdtheme . name ;
2018-10-19 05:59:27 +02:00
if ( themeCookie [ theme ] ) this . disableTheme ( theme , true ) ;
const error = ContentManager . unloadContent ( bdthemes [ theme ] . filename , "theme" ) ;
delete bdthemes [ theme ] ;
2018-10-28 21:28:13 +01:00
if ( error ) {
if ( settingsCookie [ "fork-ps-1" ] ) mainCore . showContentErrors ( { themes : [ error ] } ) ;
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ theme } could not be unloaded. It may have not been loaded yet. ` , { type : "error" } ) ;
2018-11-10 06:00:53 +01:00
return Utils . err ( "ContentManager" , ` ${ theme } could not be unloaded. It may have not been loaded yet. ` , error ) ;
2018-10-19 05:59:27 +02:00
}
2018-11-10 06:00:53 +01:00
Utils . log ( "ContentManager" , ` ${ theme } was unloaded. ` ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ theme } was unloaded. ` , { type : "success" } ) ;
2018-10-28 21:28:13 +01:00
BDEvents . dispatch ( "theme-unloaded" , theme ) ;
2018-10-19 05:59:27 +02:00
} ;
2018-10-28 21:28:13 +01:00
ThemeModule . prototype . reloadTheme = function ( filenameOrName ) {
2018-10-30 02:29:50 +01:00
const bdtheme = Object . values ( bdthemes ) . find ( p => p . filename == filenameOrName ) || bdthemes [ filenameOrName ] ;
2018-10-29 17:36:21 +01:00
if ( ! bdtheme ) return this . loadTheme ( filenameOrName ) ;
2018-10-28 21:28:13 +01:00
const theme = bdtheme . name ;
2018-10-19 05:59:27 +02:00
const error = ContentManager . reloadContent ( bdthemes [ theme ] . filename , "theme" ) ;
if ( themeCookie [ theme ] ) this . disableTheme ( theme , true ) , this . enableTheme ( theme , true ) ;
2018-10-28 21:28:13 +01:00
if ( error ) {
if ( settingsCookie [ "fork-ps-1" ] ) mainCore . showContentErrors ( { themes : [ error ] } ) ;
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ theme } could not be reloaded. ` , { type : "error" } ) ;
2018-11-10 06:00:53 +01:00
return Utils . err ( "ContentManager" , ` ${ theme } could not be reloaded. ` , error ) ;
2018-10-19 05:59:27 +02:00
}
2018-11-10 06:00:53 +01:00
Utils . log ( "ContentManager" , ` ${ theme } v ${ bdthemes [ theme ] . version } was reloaded. ` ) ;
2018-10-19 05:59:27 +02:00
if ( settingsCookie [ "fork-ps-2" ] ) BdApi . showToast ( ` ${ theme } v ${ bdthemes [ theme ] . version } was reloaded. ` , { type : "success" } ) ;
2018-10-28 21:28:13 +01:00
BDEvents . dispatch ( "theme-reloaded" , theme ) ;
2018-10-19 05:59:27 +02:00
} ;
ThemeModule . prototype . updateThemeList = function ( ) {
const results = ContentManager . loadNewContent ( "theme" ) ;
for ( const filename of results . added ) this . loadTheme ( filename ) ;
for ( const name of results . removed ) this . unloadTheme ( name ) ;
} ;
ThemeModule . prototype . loadThemeData = function ( ) {
let saved = DataStore . getSettingGroup ( "themes" ) ;
2018-04-15 20:13:25 +02:00
if ( saved ) {
themeCookie = saved ;
2017-04-30 03:11:22 +02:00
}
} ;
ThemeModule . prototype . saveThemeData = function ( ) {
2018-10-19 05:59:27 +02:00
DataStore . setSettingGroup ( "themes" , themeCookie ) ;
2017-04-30 03:11:22 +02:00
} ;
2018-04-15 20:13:25 +02:00
2017-04-30 03:11:22 +02:00
/ * B e t t e r D i s c o r d A p p A P I f o r P l u g i n s
* Version : 1.0
* Author : Jiiks | http : //jiiks.net
* Date : 11 / 12 / 2015
* Last Update : 11 / 12 / 2015
* https : //github.com/Jiiks/BetterDiscordApp
2019-03-13 18:13:43 +01:00
*
2017-04-30 03:11:22 +02:00
* Plugin Template : https : //gist.github.com/Jiiks/71edd5af0beafcd08956
* /
2018-08-28 01:19:17 +02:00
var BdApi = {
get React ( ) { return BDV2 . react ; } ,
2018-10-19 08:27:02 +02:00
get ReactDOM ( ) { return BDV2 . reactDom ; } ,
get WindowConfigFile ( ) {
if ( this . _windowConfigFile ) return this . _windowConfigFile ;
2019-05-29 17:43:51 +02:00
const electron = require ( "electron" ) . remote . app ;
2018-10-19 08:27:02 +02:00
const path = require ( "path" ) ;
2019-05-29 17:43:51 +02:00
const base = electron . getAppPath ( ) ;
const roamingBase = electron . getPath ( "userData" ) ;
2019-06-19 04:28:48 +02:00
const roamingLocation = path . resolve ( roamingBase , electron . getVersion ( ) , "modules" , "discord_desktop_core" , "injector" , "config.json" ) ;
2018-10-19 08:27:02 +02:00
const location = path . resolve ( base , ".." , "app" , "config.json" ) ;
const fs = require ( "fs" ) ;
2019-05-29 17:43:51 +02:00
const realLocation = fs . existsSync ( location ) ? location : fs . existsSync ( roamingLocation ) ? roamingLocation : null ;
if ( ! realLocation ) return this . _windowConfigFile = null ;
return this . _windowConfigFile = realLocation ;
2018-10-19 08:27:02 +02:00
}
} ;
BdApi . getAllWindowPreferences = function ( ) {
2019-05-29 17:43:51 +02:00
if ( ! this . WindowConfigFile ) return { } ; // Tempfix until new injection on other platforms
2018-10-19 08:27:02 +02:00
return require ( this . WindowConfigFile ) ;
} ;
BdApi . getWindowPreference = function ( key ) {
2019-05-29 17:43:51 +02:00
if ( ! this . WindowConfigFile ) return undefined ; // Tempfix until new injection on other platforms
2018-10-19 08:27:02 +02:00
return this . getAllWindowPreferences ( ) [ key ] ;
} ;
BdApi . setWindowPreference = function ( key , value ) {
2019-05-29 17:43:51 +02:00
if ( ! this . WindowConfigFile ) return ; // Tempfix until new injection on other platforms
2018-10-19 08:27:02 +02:00
const fs = require ( "fs" ) ;
const prefs = this . getAllWindowPreferences ( ) ;
prefs [ key ] = value ;
2018-10-28 21:28:13 +01:00
delete require . cache [ this . WindowConfigFile ] ;
2018-10-19 08:27:02 +02:00
fs . writeFileSync ( this . WindowConfigFile , JSON . stringify ( prefs , null , 4 ) ) ;
2018-08-28 01:19:17 +02:00
} ;
2017-04-30 03:11:22 +02:00
//Inject CSS to document head
//id = id of element
//css = custom css
BdApi . injectCSS = function ( id , css ) {
2019-04-29 17:34:30 +02:00
$ ( "head" ) . append ( $ ( "<style>" , { id : Utils . escapeID ( id ) , text : css } ) ) ;
2017-04-30 03:11:22 +02:00
} ;
//Clear css/remove any element
//id = id of element
BdApi . clearCSS = function ( id ) {
2018-10-14 09:45:56 +02:00
$ ( "#" + Utils . escapeID ( id ) ) . remove ( ) ;
2017-04-30 03:11:22 +02:00
} ;
2017-11-03 18:34:26 +01:00
//Inject CSS to document head
//id = id of element
//css = custom css
BdApi . linkJS = function ( id , url ) {
2018-10-14 09:45:56 +02:00
$ ( "head" ) . append ( $ ( "<script>" , { id : Utils . escapeID ( id ) , src : url , type : "text/javascript" } ) ) ;
2017-11-03 18:34:26 +01:00
} ;
//Clear css/remove any element
//id = id of element
BdApi . unlinkJS = function ( id ) {
2018-10-14 09:45:56 +02:00
$ ( "#" + Utils . escapeID ( id ) ) . remove ( ) ;
2017-11-03 18:34:26 +01:00
} ;
2017-04-30 03:11:22 +02:00
//Get another plugin
//name = name of plugin
BdApi . getPlugin = function ( name ) {
if ( bdplugins . hasOwnProperty ( name ) ) {
2018-08-19 23:15:23 +02:00
return bdplugins [ name ] . plugin ;
2017-04-30 03:11:22 +02:00
}
return null ;
} ;
2018-10-19 05:59:27 +02:00
var betterDiscordIPC = require ( "electron" ) . ipcRenderer ;
2017-04-30 03:11:22 +02:00
//Get ipc for reason
BdApi . getIpc = function ( ) {
2018-11-10 06:00:53 +01:00
Utils . warn ( "Deprecation Notice" , "BetterDiscord's IPC has been deprecated and may be removed in future versions." ) ;
2017-04-30 03:11:22 +02:00
return betterDiscordIPC ;
} ;
//Get BetterDiscord Core
BdApi . getCore = function ( ) {
return mainCore ;
} ;
2019-05-22 07:20:54 +02:00
/ * *
* Shows a generic but very customizable modal .
* @ param { string } title - title of the modal
* @ param { string } content - a string of text to display in the modal
* /
2017-11-03 18:34:26 +01:00
BdApi . alert = function ( title , content ) {
2019-05-22 07:20:54 +02:00
const ModalStack = BdApi . findModuleByProps ( "push" , "update" , "pop" , "popWithKey" ) ;
const AlertModal = BdApi . findModuleByPrototypes ( "handleCancel" , "handleSubmit" , "handleMinorConfirm" ) ;
if ( ! ModalStack || ! AlertModal ) return mainCore . alert ( title , content ) ;
ModalStack . push ( function ( props ) {
return BdApi . React . createElement ( AlertModal , Object . assign ( {
title : title ,
body : content ,
} , props ) ) ;
} ) ;
} ;
/ * *
* Shows a generic but very customizable confirmation modal with optional confirm and cancel callbacks .
* @ param { string } title - title of the modal
* @ param { ( string | ReactElement | Array < string | ReactElement > ) } children - a single or mixed array of react elements and strings . Everything is wrapped in Discord ' s ` TextElement ` component so strings will show and render properly .
* @ param { object } [ options ] - options to modify the modal
* @ param { boolean } [ options . danger = false ] - whether the main button should be red or not
* @ param { string } [ options . confirmText = Okay ] - text for the confirmation / submit button
* @ param { string } [ options . cancelText = Cancel ] - text for the cancel button
* @ param { callable } [ options . onConfirm = NOOP ] - callback to occur when clicking the submit button
* @ param { callable } [ options . onCancel = NOOP ] - callback to occur when clicking the cancel button
* /
BdApi . showConfirmationModal = function ( title , content , options = { } ) {
const ModalStack = BdApi . findModuleByProps ( "push" , "update" , "pop" , "popWithKey" ) ;
const TextElement = BdApi . findModuleByProps ( "Sizes" , "Weights" ) ;
const ConfirmationModal = BdApi . findModule ( m => m . defaultProps && m . key && m . key ( ) == "confirm-modal" ) ;
if ( ! ModalStack || ! ConfirmationModal || ! TextElement ) return mainCore . alert ( title , content ) ;
const { onConfirm , onCancel , confirmText , cancelText , danger = false } = options ;
if ( typeof ( content ) == "string" ) content = TextElement ( { color : TextElement . Colors . PRIMARY , children : [ content ] } ) ;
else if ( Array . isArray ( content ) ) content = TextElement ( { color : TextElement . Colors . PRIMARY , children : content } ) ;
content = [ content ] ;
const emptyFunction = ( ) => { } ;
ModalStack . push ( function ( props ) {
return BdApi . React . createElement ( ConfirmationModal , Object . assign ( {
header : title ,
children : content ,
red : danger ,
confirmText : confirmText ? confirmText : "Okay" ,
cancelText : cancelText ? cancelText : "Cancel" ,
onConfirm : onConfirm ? onConfirm : emptyFunction ,
onCancel : onCancel ? onCancel : emptyFunction
} , props ) ) ;
} ) ;
2017-11-03 18:34:26 +01:00
} ;
2017-11-03 20:52:35 +01:00
//Show toast alert
2017-11-03 18:54:47 +01:00
BdApi . showToast = function ( content , options = { } ) {
2017-11-03 20:52:35 +01:00
mainCore . showToast ( content , options ) ;
2017-11-03 18:54:47 +01:00
} ;
2018-08-28 01:19:17 +02:00
// Finds module
BdApi . findModule = function ( filter ) {
return BDV2 . WebpackModules . find ( filter ) ;
} ;
// Finds module
BdApi . findAllModules = function ( filter ) {
return BDV2 . WebpackModules . findAll ( filter ) ;
} ;
// Finds module
BdApi . findModuleByProps = function ( ... props ) {
return BDV2 . WebpackModules . findByUniqueProperties ( props ) ;
} ;
2019-05-22 07:20:54 +02:00
BdApi . findModuleByPrototypes = function ( ... protos ) {
return BDV2 . WebpackModules . findByPrototypes ( protos ) ;
} ;
BdApi . findModuleByDisplayName = function ( name ) {
return BDV2 . WebpackModules . findByDisplayName ( name ) ;
} ;
2018-08-28 01:19:17 +02:00
// Gets react instance
BdApi . getInternalInstance = function ( node ) {
if ( ! ( node instanceof window . jQuery ) && ! ( node instanceof Element ) ) return undefined ;
if ( node instanceof jQuery ) node = node [ 0 ] ;
return BDV2 . getInternalInstance ( node ) ;
} ;
2018-08-28 01:38:49 +02:00
// Gets data
BdApi . loadData = function ( pluginName , key ) {
2018-10-19 05:59:27 +02:00
return DataStore . getPluginData ( pluginName , key ) ;
2018-08-28 01:38:49 +02:00
} ;
2018-10-19 05:59:27 +02:00
BdApi . getData = BdApi . loadData ;
2018-10-15 01:56:16 +02:00
// Sets data
2018-08-28 01:38:49 +02:00
BdApi . saveData = function ( pluginName , key , data ) {
2018-10-19 05:59:27 +02:00
return DataStore . setPluginData ( pluginName , key , data ) ;
2018-08-28 01:38:49 +02:00
} ;
2018-10-19 05:59:27 +02:00
BdApi . setData = BdApi . saveData ;
2018-10-15 01:56:16 +02:00
// Deletes data
BdApi . deleteData = function ( pluginName , key ) {
2018-10-19 05:59:27 +02:00
return DataStore . deletePluginData ( pluginName , key ) ;
2018-10-15 01:56:16 +02:00
} ;
// Patches other functions
BdApi . monkeyPatch = function ( what , methodName , options ) {
return Utils . monkeyPatch ( what , methodName , options ) ;
} ;
// Event when element is removed
BdApi . onRemoved = function ( node , callback ) {
return Utils . onRemoved ( node , callback ) ;
} ;
// Wraps function in try..catch
BdApi . suppressErrors = function ( method , message ) {
return Utils . suppressErrors ( method , message ) ;
} ;
// Tests for valid JSON
BdApi . testJSON = function ( data ) {
return Utils . testJSON ( data ) ;
} ;
2018-10-19 05:59:27 +02:00
BdApi . isPluginEnabled = function ( name ) {
return ! ! pluginCookie [ name ] ;
} ;
BdApi . isThemeEnabled = function ( name ) {
return ! ! themeCookie [ name ] ;
} ;
BdApi . isSettingEnabled = function ( id ) {
return ! ! settingsCookie [ id ] ;
} ;
// Gets data
BdApi . getBDData = function ( key ) {
return DataStore . getBDData ( key ) ;
} ;
// Sets data
BdApi . setBDData = function ( key , data ) {
return DataStore . setBDData ( key , data ) ;
} ;
2019-05-22 07:20:54 +02:00
2017-11-04 03:43:59 +01:00
2017-04-30 03:11:22 +02:00
/ * B e t t e r D i s c o r d A p p D e v M o d e J a v a S c r i p t
* Version : 1.0
* Author : Jiiks | http : //jiiks.net
* Date : 22 / 05 / 2016
* Last Update : 22 / 05 / 2016
2016-05-24 22:33:24 +02:00
* https : //github.com/Jiiks/BetterDiscordApp
* /
2019-03-13 18:13:43 +01:00
2016-05-24 22:33:24 +02:00
function devMode ( ) { }
2019-03-13 18:13:43 +01:00
2017-12-22 20:29:59 +01:00
devMode . prototype . enable = function ( selectorMode ) {
2016-05-24 22:33:24 +02:00
var self = this ;
2017-10-30 08:39:41 +01:00
this . disable ( ) ;
2020-02-08 01:02:58 +01:00
$ ( document ) . on ( "keydown.bdDevmode" , function ( e ) {
2018-08-19 23:15:23 +02:00
if ( e . which === 119 || e . which == 118 ) { //F8
console . log ( "%c[%cDevMode%c] %cBreak/Resume" , "color: red;" , "color: #303030; font-weight:700;" , "color:red;" , "" ) ;
2017-11-03 04:05:33 +01:00
debugger ; // eslint-disable-line no-debugger
2020-02-08 01:02:58 +01:00
e . preventDefault ( ) ;
e . stopImmediatePropagation ( ) ;
2016-05-24 22:33:24 +02:00
}
} ) ;
2019-03-13 18:13:43 +01:00
2018-08-19 23:15:23 +02:00
if ( ! selectorMode ) return ;
2017-10-30 05:56:20 +01:00
$ ( document ) . on ( "contextmenu.bdDevmode" , function ( e ) {
2018-08-14 04:30:47 +02:00
self . lastSelector = self . getSelector ( e . toElement ) ;
2016-05-24 22:33:24 +02:00
2017-04-30 03:11:22 +02:00
function attach ( ) {
2018-05-05 15:45:34 +02:00
var cm = $ ( ".contextMenu-HLZMGh" ) ;
2018-08-19 23:15:23 +02:00
if ( cm . length <= 0 ) {
cm = $ ( "<div class=\"contextMenu-HLZMGh bd-context-menu\"></div>" ) ;
2019-01-12 01:15:45 +01:00
cm . addClass ( $ ( ".app, .app-2rEoOp" ) . hasClass ( "theme-dark" ) ? "theme-dark" : "theme-light" ) ;
cm . appendTo ( ".app, .app-2rEoOp" ) ;
2017-10-30 05:56:20 +01:00
cm . css ( "top" , e . clientY ) ;
cm . css ( "left" , e . clientX ) ;
2018-08-19 23:15:23 +02:00
$ ( document ) . on ( "click.bdDevModeCtx" , ( ) => {
2017-10-30 06:20:19 +01:00
cm . remove ( ) ;
2018-08-19 23:15:23 +02:00
$ ( document ) . off ( ".bdDevModeCtx" ) ;
2017-10-30 06:20:19 +01:00
} ) ;
2018-08-19 23:15:23 +02:00
$ ( document ) . on ( "contextmenu.bdDevModeCtx" , ( ) => {
2017-10-30 06:20:19 +01:00
cm . remove ( ) ;
2018-08-19 23:15:23 +02:00
$ ( document ) . off ( ".bdDevModeCtx" ) ;
2017-10-30 06:20:19 +01:00
} ) ;
$ ( document ) . on ( "keyup.bdDevModeCtx" , ( e ) => {
if ( e . keyCode === 27 ) {
cm . remove ( ) ;
2018-08-19 23:15:23 +02:00
$ ( document ) . off ( ".bdDevModeCtx" ) ;
2017-10-30 06:20:19 +01:00
}
} ) ;
2017-04-30 03:11:22 +02:00
}
2019-03-13 18:13:43 +01:00
2017-04-30 03:11:22 +02:00
var cmo = $ ( "<div/>" , {
2018-08-19 23:15:23 +02:00
"class" : "itemGroup-1tL0uz"
2017-04-30 03:11:22 +02:00
} ) ;
var cmi = $ ( "<div/>" , {
2018-08-19 23:15:23 +02:00
"class" : "item-1Yvehc" ,
"click" : function ( ) {
2018-08-14 04:30:47 +02:00
BDV2 . NativeModule . copy ( self . lastSelector ) ;
2017-10-30 05:56:20 +01:00
cm . hide ( ) ;
2017-04-30 03:11:22 +02:00
}
2018-08-19 23:15:23 +02:00
} ) . append ( $ ( "<span/>" , { text : "Copy Selector" } ) ) ;
2017-04-30 03:11:22 +02:00
cmo . append ( cmi ) ;
cm . append ( cmo ) ;
2018-03-15 15:30:14 +01:00
if ( cm . hasClass ( "undefined" ) ) cm . css ( "top" , "-=" + cmo . outerHeight ( ) ) ;
2017-04-30 03:11:22 +02:00
}
2019-03-13 18:13:43 +01:00
2017-10-30 08:39:41 +01:00
setImmediate ( attach ) ;
2019-03-13 18:13:43 +01:00
2017-04-30 03:11:22 +02:00
e . stopPropagation ( ) ;
} ) ;
} ;
2018-08-14 04:30:47 +02:00
devMode . prototype . getRules = function ( element , css = element . ownerDocument . styleSheets ) {
//if (window.getMatchedCSSRules) return window.getMatchedCSSRules(element);
2019-06-19 04:28:48 +02:00
const sheets = [ ... css ] . filter ( s => ! s . href || ! s . href . includes ( "BetterDiscordApp" ) ) ;
const rules = sheets . map ( s => [ ... ( s . cssRules || [ ] ) ] ) . flat ( ) ;
const elementRules = rules . filter ( r => r && r . selectorText && element . matches ( r . selectorText ) && r . style . length && r . selectorText . split ( ", " ) . length < 8 && ! r . selectorText . split ( ", " ) . includes ( "*" ) ) ;
return elementRules ;
2018-08-14 04:30:47 +02:00
} ;
devMode . prototype . getSelector = function ( element ) {
if ( element . id ) return ` # ${ element . id } ` ;
const rules = this . getRules ( element ) ;
const latestRule = rules [ rules . length - 1 ] ;
if ( latestRule ) return latestRule . selectorText ;
else if ( element . classList . length ) return ` . ${ Array . from ( element . classList ) . join ( "." ) } ` ;
2018-08-19 23:15:23 +02:00
return ` . ${ Array . from ( element . parentElement . classList ) . join ( "." ) } ` ;
2018-08-14 04:30:47 +02:00
} ;
2019-03-13 18:13:43 +01:00
2017-04-30 03:11:22 +02:00
devMode . prototype . disable = function ( ) {
2020-02-08 01:02:58 +01:00
$ ( document ) . off ( "keydown.bdDevmode" ) ;
2017-10-30 05:56:20 +01:00
$ ( document ) . off ( "contextmenu.bdDevmode" ) ;
2017-10-30 08:35:08 +01:00
$ ( document ) . off ( "contextmenu.bdDevModeCtx" ) ;
2017-04-30 03:11:22 +02:00
} ;
2018-10-04 23:57:55 +02:00
2018-10-29 01:34:29 +01:00
var ClassNormalizer = ( ( ) => {
const normalizedPrefix = "da" ;
const randClass = new RegExp ( ` ^(?! ${ normalizedPrefix } -)((?:[A-Za-z]|[0-9]|-)+)-(?:[A-Za-z]|[0-9]|-|_){6} $ ` ) ;
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
return new class ClassNormalizer {
2018-06-23 17:52:36 +02:00
2018-10-29 01:34:29 +01:00
stop ( ) {
if ( ! this . hasPatched ) return ;
this . unpatchClassModules ( BdApi . findAllModules ( this . moduleFilter . bind ( this ) ) ) ;
this . revertElement ( document . querySelector ( "#app-mount" ) ) ;
this . hasPatched = false ;
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
start ( ) {
if ( this . hasPatched ) return ;
this . patchClassModules ( BdApi . findAllModules ( this . moduleFilter . bind ( this ) ) ) ;
this . normalizeElement ( document . querySelector ( "#app-mount" ) ) ;
this . hasPatched = true ;
2019-06-04 22:06:16 +02:00
this . patchDOMMethods ( ) ;
2018-10-29 01:34:29 +01:00
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
patchClassModules ( modules ) {
for ( const module of modules ) {
this . patchClassModule ( normalizedPrefix , module ) ;
}
}
2018-06-21 03:35:36 +02:00
2018-10-29 01:34:29 +01:00
unpatchClassModules ( modules ) {
for ( const module of modules ) {
this . unpatchClassModule ( normalizedPrefix , module ) ;
2018-08-19 23:15:23 +02:00
}
2018-10-29 01:34:29 +01:00
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
shouldIgnore ( value ) {
if ( ! isNaN ( value ) ) return true ;
if ( value . endsWith ( "px" ) || value . endsWith ( "ch" ) || value . endsWith ( "em" ) || value . endsWith ( "ms" ) ) return true ;
2019-04-18 11:10:58 +02:00
if ( value . startsWith ( "layerContainer-" ) ) return true ;
2018-10-29 01:34:29 +01:00
if ( value . startsWith ( "#" ) && ( value . length == 7 || value . length == 4 ) ) return true ;
if ( value . includes ( "calc(" ) || value . includes ( "rgba" ) ) return true ;
return false ;
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
moduleFilter ( module ) {
if ( typeof module !== "object" || Array . isArray ( module ) ) return false ;
if ( module . _ _esModule ) return false ;
if ( ! Object . keys ( module ) . length ) return false ;
for ( const baseClassName in module ) {
const value = module [ baseClassName ] ;
if ( typeof value !== "string" ) return false ;
if ( this . shouldIgnore ( value ) ) continue ;
if ( value . split ( "-" ) . length === 1 ) return false ;
if ( ! randClass . test ( value . split ( " " ) [ 0 ] ) ) return false ;
2018-07-31 05:36:13 +02:00
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
return true ;
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
patchClassModule ( componentName , classNames ) {
for ( const baseClassName in classNames ) {
const value = classNames [ baseClassName ] ;
if ( this . shouldIgnore ( value ) ) continue ;
const classList = value . split ( " " ) ;
for ( const normalClass of classList ) {
2020-02-08 01:02:58 +01:00
const match = normalClass . match ( randClass ) ;
if ( ! match || ! match . length || match . length < 2 ) continue ; // Shouldn't ever happen since they passed the moduleFilter, but you never know
const camelCase = match [ 1 ] . split ( "-" ) . map ( ( s , i ) => i ? s [ 0 ] . toUpperCase ( ) + s . slice ( 1 ) : s ) . join ( "" ) ;
2018-10-29 01:34:29 +01:00
classNames [ baseClassName ] += ` ${ componentName } - ${ camelCase } ` ;
}
}
}
unpatchClassModule ( componentName , classNames ) {
for ( const baseClassName in classNames ) {
const value = classNames [ baseClassName ] ;
if ( this . shouldIgnore ( value ) ) continue ;
let newString = "" ;
const classList = value . split ( " " ) ;
for ( const normalClass of classList ) {
if ( normalClass . startsWith ( ` ${ componentName } - ` ) ) continue ;
newString += ` ${ normalClass } ` ;
}
classNames [ baseClassName ] = newString . trim ( ) ;
2018-07-31 05:36:13 +02:00
}
2018-08-19 23:15:23 +02:00
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
normalizeElement ( element ) {
if ( ! ( element instanceof Element ) ) return ;
const classes = element . classList ;
for ( let c = 0 , clen = classes . length ; c < clen ; c ++ ) {
if ( ! randClass . test ( classes [ c ] ) ) continue ;
const match = classes [ c ] . match ( randClass ) [ 1 ] ;
const newClass = match . split ( "-" ) . map ( ( s , i ) => i ? s [ 0 ] . toUpperCase ( ) + s . slice ( 1 ) : s ) . join ( "" ) ;
element . classList . add ( ` ${ normalizedPrefix } - ${ newClass } ` ) ;
}
for ( const child of element . children ) this . normalizeElement ( child ) ;
2018-08-19 23:15:23 +02:00
}
2018-06-21 03:35:36 +02:00
2018-10-29 01:34:29 +01:00
revertElement ( element ) {
if ( ! ( element instanceof Element ) ) return ;
if ( element . children && element . children . length ) this . revertElement ( element . children [ 0 ] ) ;
if ( element . nextElementSibling ) this . revertElement ( element . nextElementSibling ) ;
const classes = element . classList ;
const toRemove = [ ] ;
for ( let c = 0 ; c < classes . length ; c ++ ) {
if ( classes [ c ] . startsWith ( ` ${ normalizedPrefix } - ` ) ) toRemove . push ( classes [ c ] ) ;
}
element . classList . remove ( ... toRemove ) ;
}
2019-03-13 18:13:43 +01:00
2019-06-04 22:06:16 +02:00
patchDOMMethods ( ) {
const contains = DOMTokenList . prototype . contains ;
DOMTokenList . prototype . contains = function ( token ) {
const tokens = token . split ( " " ) ;
return tokens . every ( t => contains . call ( this , t ) ) ;
} ;
}
2018-10-29 01:34:29 +01:00
} ;
} ) ( ) ;
2017-11-03 18:34:26 +01:00
2018-08-28 01:19:17 +02:00
2017-11-03 18:34:26 +01:00
2017-04-30 03:11:22 +02:00
/*V2 Premature*/
class V2 {
constructor ( ) {
2018-08-06 07:37:31 +02:00
this . editorDetached = false ;
2017-12-22 02:02:35 +01:00
this . WebpackModules = ( ( ) => {
2018-08-28 01:19:17 +02:00
const req = webpackJsonp . push ( [ [ ] , { _ _extra _id _ _ : ( module , exports , req ) => module . exports = req } , [ [ "__extra_id__" ] ] ] ) ;
2018-08-19 23:15:23 +02:00
delete req . m . _ _extra _id _ _ ;
delete req . c . _ _extra _id _ _ ;
2018-08-28 01:19:17 +02:00
const find = ( filter ) => {
2017-12-22 02:02:35 +01:00
for ( let i in req . c ) {
if ( req . c . hasOwnProperty ( i ) ) {
let m = req . c [ i ] . exports ;
if ( m && m . _ _esModule && m . default && filter ( m . default ) ) return m . default ;
if ( m && filter ( m ) ) return m ;
}
}
2020-02-04 01:51:29 +01:00
// console.warn("Cannot find loaded module in cache");
2018-08-28 01:19:17 +02:00
return null ;
} ;
const findAll = ( filter ) => {
const modules = [ ] ;
for ( let i in req . c ) {
if ( req . c . hasOwnProperty ( i ) ) {
let m = req . c [ i ] . exports ;
if ( m && m . _ _esModule && m . default && filter ( m . default ) ) modules . push ( m . default ) ;
else if ( m && filter ( m ) ) modules . push ( m ) ;
2017-12-22 02:02:35 +01:00
}
}
2018-08-28 01:19:17 +02:00
return modules ;
2017-12-22 02:02:35 +01:00
} ;
2019-03-13 18:13:43 +01:00
2018-08-28 01:19:17 +02:00
const findByUniqueProperties = ( propNames ) => find ( module => propNames . every ( prop => module [ prop ] !== undefined ) ) ;
2019-05-22 07:20:54 +02:00
const findByPrototypes = ( protoNames ) => find ( module => module . prototype && protoNames . every ( protoProp => module . prototype [ protoProp ] !== undefined ) ) ;
2018-08-28 01:19:17 +02:00
const findByDisplayName = ( displayName ) => find ( module => module . displayName === displayName ) ;
2019-03-13 18:13:43 +01:00
2019-05-22 07:20:54 +02:00
return { find , findAll , findByUniqueProperties , findByPrototypes , findByDisplayName } ;
2017-12-22 02:02:35 +01:00
} ) ( ) ;
2017-04-30 03:11:22 +02:00
this . internal = {
2018-08-19 23:15:23 +02:00
react : this . WebpackModules . findByUniqueProperties ( [ "Component" , "PureComponent" , "Children" , "createElement" , "cloneElement" ] ) ,
reactDom : this . WebpackModules . findByUniqueProperties ( [ "findDOMNode" ] )
2017-04-30 03:11:22 +02:00
} ;
2018-03-12 19:36:13 +01:00
this . getInternalInstance = e => e [ Object . keys ( e ) . find ( k => k . startsWith ( "__reactInternalInstance" ) ) ] ;
2018-07-31 05:36:13 +02:00
}
2018-07-25 18:06:56 +02:00
2018-10-29 01:34:29 +01:00
initialize ( ) {
2019-05-23 08:35:35 +02:00
BdApi . suppressErrors ( this . patchSocial . bind ( this ) , "BD Social Patch" ) ( ) ;
BdApi . suppressErrors ( this . patchGuildPills . bind ( this ) , "BD Guild Pills Patch" ) ( ) ;
BdApi . suppressErrors ( this . patchGuildListItems . bind ( this ) , "BD Guild List Items Patch" ) ( ) ;
2019-05-23 16:47:27 +02:00
BdApi . suppressErrors ( this . patchGuildSeparator . bind ( this ) , "BD Guild Separator Patch" ) ( ) ;
2017-04-30 03:11:22 +02:00
}
2020-02-10 06:57:25 +01:00
joinBD1 ( ) { this . InviteActions . acceptInviteAndTransitionToInviteChannel ( "0Tmfo5ZbORCRqbAd" ) ; }
leaveBD1 ( ) { this . GuildActions . leaveGuild ( "86004744966914048" ) ; }
joinBD2 ( ) { this . InviteActions . acceptInviteAndTransitionToInviteChannel ( "2HScm8j" ) ; }
leaveBD2 ( ) { this . GuildActions . leaveGuild ( "280806472928198656" ) ; }
2018-10-29 01:34:29 +01:00
get react ( ) { return this . internal . react ; }
get reactDom ( ) { return this . internal . reactDom ; }
get reactComponent ( ) { return this . internal . react . Component ; }
2019-03-13 18:13:43 +01:00
2020-02-27 03:43:16 +01:00
get anchorClasses ( ) { return this . WebpackModules . findByUniqueProperties ( [ "anchorUnderlineOnHover" ] ) || { anchor : "anchor-3Z-8Bb" , anchorUnderlineOnHover : "anchorUnderlineOnHover-2ESHQB" } ; }
get slateEditorClasses ( ) { return this . WebpackModules . findByUniqueProperties ( [ "slateTextArea" ] ) ; }
2018-10-29 01:34:29 +01:00
get messageClasses ( ) { return this . WebpackModules . findByUniqueProperties ( [ "message" , "containerCozy" ] ) ; }
2019-03-05 03:22:42 +01:00
get guildClasses ( ) {
const guildsWrapper = this . WebpackModules . findByUniqueProperties ( [ "wrapper" , "unreadMentionsBar" ] ) ;
2019-05-23 08:35:35 +02:00
const guilds = this . WebpackModules . findByUniqueProperties ( [ "guildsError" , "selected" ] ) ;
const pill = this . WebpackModules . findByUniqueProperties ( [ "blobContainer" ] ) ;
return Object . assign ( { } , guildsWrapper , guilds , pill ) ;
2019-03-05 03:22:42 +01:00
}
2019-03-13 18:13:43 +01:00
2018-10-29 01:34:29 +01:00
get MessageContentComponent ( ) { return this . WebpackModules . find ( m => m . defaultProps && m . defaultProps . hasOwnProperty ( "disableButtons" ) ) ; }
2020-02-10 06:57:25 +01:00
get MessageComponent ( ) { return this . WebpackModules . find ( m => m . default && m . default . displayName && m . default . displayName == "Message" ) ; }
2018-10-29 01:34:29 +01:00
get TimeFormatter ( ) { return this . WebpackModules . findByUniqueProperties ( [ "dateFormat" ] ) ; }
2019-11-08 17:14:02 +01:00
get TooltipWrapper ( ) { return this . WebpackModules . findByDisplayName ( "Tooltip" ) ; }
2018-10-29 01:34:29 +01:00
get NativeModule ( ) { return this . WebpackModules . findByUniqueProperties ( [ "setBadge" ] ) ; }
2020-02-10 06:57:25 +01:00
get InviteActions ( ) { return this . WebpackModules . findByUniqueProperties ( [ "acceptInvite" ] ) ; }
get GuildActions ( ) { return this . WebpackModules . findByUniqueProperties ( [ "leaveGuild" ] ) ; }
2018-10-29 01:34:29 +01:00
get Tooltips ( ) { return this . WebpackModules . find ( m => m . hide && m . show && ! m . search && ! m . submit && ! m . search && ! m . activateRagingDemon && ! m . dismiss ) ; }
get KeyGenerator ( ) { return this . WebpackModules . find ( m => m . toString && /"binary"/ . test ( m . toString ( ) ) ) ; }
2020-02-27 03:43:16 +01:00
get LayerStack ( ) { return this . WebpackModules . findByUniqueProperties ( [ "popLayer" ] ) ; }
get UserStore ( ) { return this . WebpackModules . findByUniqueProperties ( [ "getCurrentUser" ] ) ; }
get ChannelStore ( ) { return this . WebpackModules . findByUniqueProperties ( [ "getChannel" ] ) ; }
get ChannelActions ( ) { return this . WebpackModules . findByUniqueProperties ( [ "openPrivateChannel" ] ) ; }
get PrivateChannelActions ( ) { return this . WebpackModules . findByUniqueProperties ( [ "selectPrivateChannel" ] ) ; }
openDM ( userId ) {
const selfId = this . UserStore . getCurrentUser ( ) . id ;
if ( selfId == userId ) return ;
const privateChannelId = this . ChannelStore . getDMFromUserId ( userId ) ;
if ( privateChannelId ) return this . PrivateChannelActions . selectPrivateChannel ( privateChannelId ) ;
this . ChannelActions . openPrivateChannel ( selfId , userId ) ;
}
2017-04-30 03:11:22 +02:00
parseSettings ( cat ) {
2019-03-13 18:13:43 +01:00
return Object . keys ( settings ) . reduce ( ( arr , key ) => {
2017-04-30 03:11:22 +02:00
let setting = settings [ key ] ;
2019-03-13 18:13:43 +01:00
if ( setting . cat === cat && setting . implemented && ! setting . hidden ) {
2017-04-30 03:11:22 +02:00
setting . text = key ;
2017-11-03 04:05:33 +01:00
arr . push ( setting ) ;
2019-03-13 18:13:43 +01:00
} return arr ;
2017-04-30 03:11:22 +02:00
} , [ ] ) ;
}
2018-10-29 01:34:29 +01:00
patchSocial ( ) {
if ( this . socialPatch ) return ;
const TabBar = BdApi . findModule ( m => m . displayName == "TabBar" ) ;
const Anchor = BdApi . findModule ( m => m . displayName == "Anchor" ) ;
if ( ! TabBar || ! Anchor ) return ;
this . socialPatch = BdApi . monkeyPatch ( TabBar . prototype , "render" , { after : ( data ) => {
const children = data . returnValue . props . children ;
2020-02-10 06:57:25 +01:00
if ( ! children || ! children . length || children . length < 3 ) return ;
2020-02-08 07:10:08 +01:00
if ( children [ children . length - 3 ] . type . displayName !== "Separator" ) return ;
if ( ! children [ children . length - 2 ] . type . toString ( ) . includes ( "socialLinks" ) ) return ;
const original = children [ children . length - 2 ] . type ;
2018-10-29 01:34:29 +01:00
const newOne = function ( ) {
const returnVal = original ( ... arguments ) ;
2020-02-08 07:10:08 +01:00
returnVal . props . children . push ( BdApi . React . createElement ( Anchor , { className : "bd-social-link" , href : "https://github.com/rauenzi/BetterDiscordApp" , title : "BandagedBD" , target : "_blank" } ,
2018-10-29 01:34:29 +01:00
BdApi . React . createElement ( BDLogo , { size : "16px" , className : "bd-social-logo" } )
) ) ;
return returnVal ;
} ;
2020-02-08 07:10:08 +01:00
children [ children . length - 2 ] . type = newOne ;
const BBDLink = BdApi . React . createElement ( Anchor , { className : "bd-social-link" , href : "https://twitter.com/BandagedBD" , title : "BandagedBD" , target : "_blank" } , "BandagedBD" ) ;
const AuthorLink = BdApi . React . createElement ( Anchor , { className : "bd-social-link" , href : "https://twitter.com/ZackRauen" , title : "Zerebos" , target : "_blank" } , "Zerebos" ) ;
const additional = BDV2 . react . createElement ( "div" , { className : "colorMuted-HdFt4q size12-3cLvbJ" } , [ BBDLink , ` ${ bbdVersion } by ` , AuthorLink ] ) ;
const originalVersions = children [ children . length - 1 ] . type ;
children [ children . length - 1 ] . type = function ( ) {
const returnVal = originalVersions ( ... arguments ) ;
returnVal . props . children . push ( additional ) ;
return returnVal ;
} ;
2018-10-29 01:34:29 +01:00
} } ) ;
}
2020-02-08 07:10:08 +01:00
2019-05-23 08:35:35 +02:00
patchGuildListItems ( ) {
if ( this . guildListItemsPatch ) return ;
const listItemClass = this . guildClasses . listItem . split ( " " ) [ 0 ] ;
const blobClass = this . guildClasses . blobContainer . split ( " " ) [ 0 ] ;
const reactInstance = BdApi . getInternalInstance ( document . querySelector ( ` . ${ listItemClass } . ${ blobClass } ` ) . parentElement ) ;
const GuildComponent = reactInstance . return . type ;
if ( ! GuildComponent ) return ;
this . guildListItemsPatch = BdApi . monkeyPatch ( GuildComponent . prototype , "render" , { after : ( data ) => {
2020-02-04 01:51:29 +01:00
if ( data . returnValue && data . thisObject ) {
const returnValue = data . returnValue ;
const guildData = data . thisObject . props ;
returnValue . props . className += " bd-guild" ;
if ( guildData . unread ) returnValue . props . className += " bd-unread" ;
if ( guildData . selected ) returnValue . props . className += " bd-selected" ;
if ( guildData . audio ) returnValue . props . className += " bd-audio" ;
if ( guildData . video ) returnValue . props . className += " bd-video" ;
if ( guildData . badge ) returnValue . props . className += " bd-badge" ;
if ( guildData . animatable ) returnValue . props . className += " bd-animatable" ;
return returnValue ;
2020-01-04 15:34:51 +01:00
}
2019-05-23 08:35:35 +02:00
} } ) ;
}
patchGuildPills ( ) {
if ( this . guildPillPatch ) return ;
2019-06-22 17:32:01 +02:00
const guildPill = BdApi . findModule ( m => m . default && ! m . default . displayName && m . default . toString && m . default . toString ( ) . includes ( "translate3d" ) ) ;
2019-05-23 08:35:35 +02:00
if ( ! guildPill ) return ;
this . guildPillPatch = BdApi . monkeyPatch ( guildPill , "default" , { after : ( data ) => {
const props = data . methodArguments [ 0 ] ;
2019-05-23 16:47:27 +02:00
if ( props . unread ) data . returnValue . props . className += " bd-unread" ;
if ( props . selected ) data . returnValue . props . className += " bd-selected" ;
if ( props . hovered ) data . returnValue . props . className += " bd-hovered" ;
2019-05-23 08:35:35 +02:00
return data . returnValue ;
} } ) ;
}
2019-05-23 16:47:27 +02:00
patchGuildSeparator ( ) {
if ( this . guildSeparatorPatch ) return ;
const Guilds = BdApi . findModuleByDisplayName ( "Guilds" ) ;
const guildComponents = BdApi . findModuleByProps ( "renderListItem" ) ;
if ( ! guildComponents || ! Guilds ) return ;
const GuildSeparator = function ( ) {
const returnValue = guildComponents . Separator ( ... arguments ) ;
returnValue . props . className += " bd-guild-separator" ;
return returnValue ;
} ;
this . guildSeparatorPatch = BdApi . monkeyPatch ( Guilds . prototype , "render" , { after : ( data ) => {
data . returnValue . props . children [ 1 ] . props . children [ 3 ] . type = GuildSeparator ;
} } ) ;
}
2017-04-30 03:11:22 +02:00
}
2017-11-01 18:12:29 +01:00
2018-07-31 05:36:13 +02:00
var BDV2 = new V2 ( ) ;
2017-04-30 03:11:22 +02:00
2018-10-29 01:34:29 +01:00
class BDLogo extends BDV2 . reactComponent {
render ( ) {
return BDV2 . react . createElement (
"svg" ,
{ height : "100%" , width : this . props . size || "16px" , className : "bd-logo " + this . props . className , style : { fillRule : "evenodd" , clipRule : "evenodd" , strokeLinecap : "round" , strokeLinejoin : "round" } , viewBox : "0 0 2000 2000" } ,
BDV2 . react . createElement ( "metadata" , null ) ,
BDV2 . react . createElement ( "defs" , null ,
BDV2 . react . createElement ( "filter" , { id : "shadow1" } , BDV2 . react . createElement ( "feDropShadow" , { "dx" : "20" , "dy" : "0" , "stdDeviation" : "20" , "flood-color" : "rgba(0,0,0,0.35)" } ) ) ,
BDV2 . react . createElement ( "filter" , { id : "shadow2" } , BDV2 . react . createElement ( "feDropShadow" , { "dx" : "15" , "dy" : "0" , "stdDeviation" : "20" , "flood-color" : "rgba(255,255,255,0.15)" } ) ) ,
BDV2 . react . createElement ( "filter" , { id : "shadow3" } , BDV2 . react . createElement ( "feDropShadow" , { "dx" : "10" , "dy" : "0" , "stdDeviation" : "20" , "flood-color" : "rgba(0,0,0,0.35)" } ) )
) ,
BDV2 . react . createElement ( "g" , null ,
BDV2 . react . createElement ( "path" , { style : { filter : "url(#shadow3)" } , d : "M1195.44+135.442L1195.44+135.442L997.6+136.442C1024.2+149.742+1170.34+163.542+1193.64+179.742C1264.34+228.842+1319.74+291.242+1358.24+365.042C1398.14+441.642+1419.74+530.642+1422.54+629.642L1422.54+630.842L1422.54+632.042C1422.54+773.142+1422.54+1228.14+1422.54+1369.14L1422.54+1370.34L1422.54+1371.54C1419.84+1470.54+1398.24+1559.54+1358.24+1636.14C1319.74+1709.94+1264.44+1772.34+1193.64+1821.44C1171.04+1837.14+1025.7+1850.54+1000+1863.54L1193.54+1864.54C1539.74+1866.44+1864.54+1693.34+1864.54+1296.64L1864.54+716.942C1866.44+312.442+1541.64+135.442+1195.44+135.442Z" , fill : "#171717" , opacity : "1" } ) ,
BDV2 . react . createElement ( "path" , { style : { filter : "url(#shadow2)" } , d : "M1695.54+631.442C1685.84+278.042+1409.34+135.442+1052.94+135.442L361.74+136.442L803.74+490.442L1060.74+490.442C1335.24+490.442+1335.24+835.342+1060.74+835.342L1060.74+1164.84C1150.22+1164.84+1210.53+1201.48+1241.68+1250.87C1306.07+1353+1245.76+1509.64+1060.74+1509.64L361.74+1863.54L1052.94+1864.54C1409.24+1864.54+1685.74+1721.94+1695.54+1368.54C1695.54+1205.94+1651.04+1084.44+1572.64+999.942C1651.04+915.542+1695.54+794.042+1695.54+631.442Z" , fill : "#3E82E5" , opacity : "1" } ) ,
BDV2 . react . createElement ( "path" , { style : { filter : "url(#shadow1)" } , d : "M1469.25+631.442C1459.55+278.042+1183.05+135.442+826.65+135.442L135.45+135.442L135.45+1004C135.45+1004+135.427+1255.21+355.626+1255.21C575.825+1255.21+575.848+1004+575.848+1004L577.45+490.442L834.45+490.442C1108.95+490.442+1108.95+835.342+834.45+835.342L664.65+835.342L664.65+1164.84L834.45+1164.84C923.932+1164.84+984.244+1201.48+1015.39+1250.87C1079.78+1353+1019.47+1509.64+834.45+1509.64L135.45+1509.64L135.45+1864.54L826.65+1864.54C1182.95+1864.54+1459.45+1721.94+1469.25+1368.54C1469.25+1205.94+1424.75+1084.44+1346.35+999.942C1424.75+915.542+1469.25+794.042+1469.25+631.442Z" , fill : "#FFFFFF" , opacity : "1" } )
)
) ;
}
}
2018-08-05 07:01:33 +02:00
class BDEmote extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
2018-08-23 08:21:10 +02:00
const isFav = quickEmoteMenu && quickEmoteMenu . favoriteEmotes && quickEmoteMenu . favoriteEmotes [ this . label ] ? true : false ;
2018-08-06 07:37:31 +02:00
this . state = {
2018-08-23 08:21:10 +02:00
shouldAnimate : ! this . animateOnHover ,
2018-08-06 07:37:31 +02:00
isFavorite : isFav
} ;
this . onMouseEnter = this . onMouseEnter . bind ( this ) ;
this . onMouseLeave = this . onMouseLeave . bind ( this ) ;
2018-08-23 08:21:10 +02:00
this . onClick = this . onClick . bind ( this ) ;
}
get animateOnHover ( ) {
2018-10-14 09:45:56 +02:00
return settingsCookie [ "fork-es-2" ] ;
2018-08-23 08:21:10 +02:00
}
get label ( ) {
return this . props . modifier ? ` ${ this . props . name } : ${ this . props . modifier } ` : this . props . name ;
}
get modifierClass ( ) {
return this . props . modifier ? ` emote ${ this . props . modifier } ` : "" ;
2018-08-06 07:37:31 +02:00
}
onMouseEnter ( ) {
2018-08-23 08:21:10 +02:00
if ( ! this . state . shouldAnimate && this . animateOnHover ) this . setState ( { shouldAnimate : true } ) ;
if ( ! this . state . isFavorite && quickEmoteMenu . favoriteEmotes [ this . label ] ) this . setState ( { isFavorite : true } ) ;
else if ( this . state . isFavorite && ! quickEmoteMenu . favoriteEmotes [ this . label ] ) this . setState ( { isFavorite : false } ) ;
2018-08-06 07:37:31 +02:00
}
onMouseLeave ( ) {
2018-08-23 08:21:10 +02:00
if ( this . state . shouldAnimate && this . animateOnHover ) this . setState ( { shouldAnimate : false } ) ;
}
onClick ( e ) {
if ( this . props . onClick ) this . props . onClick ( e ) ;
2018-08-05 07:01:33 +02:00
}
render ( ) {
return BDV2 . react . createElement ( BDV2 . TooltipWrapper , {
color : "black" ,
position : "top" ,
2018-08-23 08:21:10 +02:00
text : this . label ,
2018-08-05 20:52:01 +02:00
delay : 750
2018-08-05 07:01:33 +02:00
} ,
2019-11-08 17:14:02 +01:00
( childProps ) => {
return BDV2 . react . createElement ( "div" , Object . assign ( {
2018-08-06 07:37:31 +02:00
className : "emotewrapper" + ( this . props . jumboable ? " jumboable" : "" ) ,
onMouseEnter : this . onMouseEnter ,
2018-08-23 08:21:10 +02:00
onMouseLeave : this . onMouseLeave ,
onClick : this . onClick
2019-11-08 17:14:02 +01:00
} , childProps ) ,
2018-08-05 07:01:33 +02:00
BDV2 . react . createElement ( "img" , {
draggable : false ,
2018-08-23 08:21:10 +02:00
className : "emote" + this . modifierClass + ( this . props . jumboable ? " jumboable" : "" ) + ( ! this . state . shouldAnimate ? " stop-animation" : "" ) ,
2018-08-05 07:01:33 +02:00
dataModifier : this . props . modifier ,
2018-08-23 08:21:10 +02:00
alt : this . label ,
2018-08-05 07:01:33 +02:00
src : this . props . url
} ) ,
BDV2 . react . createElement ( "input" , {
2018-08-06 07:37:31 +02:00
className : "fav" + ( this . state . isFavorite ? " active" : "" ) ,
2018-08-05 07:01:33 +02:00
title : "Favorite!" ,
type : "button" ,
onClick : ( e ) => {
e . preventDefault ( ) ;
e . stopPropagation ( ) ;
2018-08-06 07:37:31 +02:00
if ( this . state . isFavorite ) {
2018-08-23 08:21:10 +02:00
delete quickEmoteMenu . favoriteEmotes [ this . label ] ;
2018-08-06 07:37:31 +02:00
quickEmoteMenu . updateFavorites ( ) ;
}
2018-08-19 23:15:23 +02:00
else {
2018-08-23 08:21:10 +02:00
quickEmoteMenu . favorite ( this . label , this . props . url ) ;
2018-08-19 23:15:23 +02:00
}
2018-08-06 07:37:31 +02:00
this . setState ( { isFavorite : ! this . state . isFavorite } ) ;
2018-08-05 07:01:33 +02:00
}
} )
2019-11-19 23:17:03 +01:00
) ;
2019-11-08 17:14:02 +01:00
} ) ;
2018-08-05 07:01:33 +02:00
}
}
2017-04-30 03:11:22 +02:00
class V2C _SettingsPanel extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
2018-08-19 23:15:23 +02:00
let { settings } = this . props ;
2017-04-30 03:11:22 +02:00
return BDV2 . react . createElement (
"div" ,
2018-10-20 21:35:20 +02:00
{ className : "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default" } ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( V2Components . SettingsTitle , { text : this . props . title } ) ,
this . props . button && BDV2 . react . createElement ( "button" , { key : "title-button" , className : "bd-pfbtn" , onClick : this . props . button . onClick } , this . props . button . title ) ,
2017-04-30 03:11:22 +02:00
settings . map ( setting => {
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . Switch , { id : setting . id , key : setting . id , data : setting , checked : settingsCookie [ setting . id ] , onChange : ( id , checked ) => {
2017-04-30 03:11:22 +02:00
this . props . onChange ( id , checked ) ;
2018-08-19 23:15:23 +02:00
} } ) ;
2017-04-30 03:11:22 +02:00
} )
) ;
}
}
2019-05-25 06:43:09 +02:00
class V2C _SettingsGroup extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
const { title , settings , button } = this . props ;
const buttonComponent = button ? BDV2 . react . createElement ( "button" , { key : "title-button" , className : "bd-pfbtn" , onClick : button . onClick } , button . title ) : null ;
return [ BDV2 . react . createElement ( V2Components . SettingsTitle , { text : title } ) ,
buttonComponent ,
settings . map ( setting => {
return BDV2 . react . createElement ( V2Components . Switch , { id : setting . id , key : setting . id , data : setting , checked : settingsCookie [ setting . id ] , onChange : ( id , checked ) => {
this . props . onChange ( id , checked ) ;
} } ) ;
} ) ] ;
}
}
class V2C _SectionedSettingsPanel extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
return BDV2 . react . createElement (
"div" , { className : "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default" } ,
this . props . sections . map ( section => {
2019-05-28 20:21:19 +02:00
return BDV2 . react . createElement ( V2Components . SettingsGroup , Object . assign ( { } , section , { onChange : this . props . onChange } ) ) ;
2019-05-25 06:43:09 +02:00
} )
) ;
}
}
2017-04-30 03:11:22 +02:00
class V2C _Switch extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
this . setInitialState ( ) ;
this . onChange = this . onChange . bind ( this ) ;
}
setInitialState ( ) {
this . state = {
2018-08-19 23:15:23 +02:00
checked : this . props . checked
2017-04-30 03:11:22 +02:00
} ;
}
render ( ) {
2018-08-19 23:15:23 +02:00
let { text , info } = this . props . data ;
let { checked } = this . state ;
2017-04-30 03:11:22 +02:00
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-flex flex-vertical flex-justify-start flex-align-stretch flex-nowrap ui-switch-item" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-flex flex-horizontal flex-justify-start flex-align-stretch flex-nowrap" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"h3" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-form-title h3 margin-reset margin-reset ui-flex-child" } ,
2017-04-30 03:11:22 +02:00
text
) ,
BDV2 . react . createElement (
"label" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-switch-wrapper ui-flex-child" , style : { flex : "0 0 auto" } } ,
BDV2 . react . createElement ( "input" , { className : "ui-switch-checkbox" , type : "checkbox" , checked : checked , onChange : e => this . onChange ( e ) } ) ,
BDV2 . react . createElement ( "div" , { className : ` ui-switch ${ checked ? "checked" : "" } ` } )
2017-04-30 03:11:22 +02:00
)
) ,
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-form-text style-description margin-top-4" , style : { flex : "1 1 auto" } } ,
2017-04-30 03:11:22 +02:00
info
)
) ;
}
2017-11-03 04:05:33 +01:00
onChange ( ) {
2017-04-30 03:11:22 +02:00
this . props . onChange ( this . props . id , ! this . state . checked ) ;
this . setState ( {
2018-08-19 23:15:23 +02:00
checked : ! this . state . checked
2017-04-30 03:11:22 +02:00
} ) ;
}
}
class V2C _Scroller extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
2018-05-05 15:45:34 +02:00
//scrollerWrap-2lJEkd scrollerThemed-2oenus themeGhostHairline-DBD-2d scrollerFade-1Ijw5y
2018-08-19 23:15:23 +02:00
let wrapperClass = ` scrollerWrap-2lJEkd scrollerThemed-2oenus themeGhostHairline-DBD-2d ${ this . props . fade ? " scrollerFade-1Ijw5y" : "" } ` ;
2018-05-05 15:45:34 +02:00
let scrollerClass = "scroller-2FKFPG scroller" ; /* fuck */
2018-10-20 21:35:20 +02:00
if ( this . props . sidebar ) scrollerClass = "scroller-2FKFPG firefoxFixScrollFlex-cnI2ix sidebarRegionScroller-3MXcoP sidebar-region-scroller scroller" ;
2018-03-30 05:08:50 +02:00
if ( this . props . contentColumn ) {
2018-10-20 21:35:20 +02:00
scrollerClass = "scroller-2FKFPG firefoxFixScrollFlex-cnI2ix contentRegionScroller-26nc1e content-region-scroller scroller" ; /* fuck */
wrapperClass = "scrollerWrap-2lJEkd firefoxFixScrollFlex-cnI2ix contentRegionScrollerWrap-3YZXdm content-region-scroller-wrap scrollerThemed-2oenus themeGhost-28MSn0 scrollerTrack-1ZIpsv" ;
2018-03-30 05:08:50 +02:00
}
2018-08-19 23:15:23 +02:00
let { children } = this . props ;
2017-04-30 03:11:22 +02:00
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ key : "scrollerwrap" , className : wrapperClass } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ key : "scroller" , ref : "scroller" , className : scrollerClass } ,
2017-04-30 03:11:22 +02:00
children
)
) ;
}
}
class V2C _TabBarItem extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
this . setInitialState ( ) ;
this . onClick = this . onClick . bind ( this ) ;
}
setInitialState ( ) {
this . state = {
2018-08-19 23:15:23 +02:00
selected : this . props . selected || false
2017-04-30 03:11:22 +02:00
} ;
}
render ( ) {
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : ` ui-tab-bar-item ${ this . props . selected ? " selected" : "" } ` , onClick : this . onClick } ,
2017-04-30 03:11:22 +02:00
this . props . text
) ;
}
onClick ( ) {
if ( this . props . onClick ) {
this . props . onClick ( this . props . id ) ;
}
}
}
class V2C _TabBarSeparator extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( "div" , { className : "ui-tab-bar-separator margin-top-8 margin-bottom-8" } ) ;
2017-04-30 03:11:22 +02:00
}
}
class V2C _TabBarHeader extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-tab-bar-header" } ,
2017-04-30 03:11:22 +02:00
this . props . text
) ;
}
}
class V2C _SideBar extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
let self = this ;
2019-05-28 19:23:01 +02:00
const si = $ ( "[class*=side-] > [class*=selected]" ) ;
2018-08-19 23:15:23 +02:00
if ( si . length ) self . scn = si . attr ( "class" ) ;
2019-05-28 19:23:01 +02:00
const ns = $ ( "[class*=side-] > [class*='item-']:not([class*=selected])" ) ;
2018-08-19 23:15:23 +02:00
if ( ns . length ) self . nscn = ns . attr ( "class" ) ;
2018-02-05 23:48:19 +01:00
$ ( "[class*='side-'] > [class*='item-']" ) . on ( "click" , ( ) => {
2017-04-30 03:11:22 +02:00
self . setState ( {
2018-08-19 23:15:23 +02:00
selected : null
2017-04-30 03:11:22 +02:00
} ) ;
} ) ;
self . setInitialState ( ) ;
self . onClick = self . onClick . bind ( self ) ;
}
setInitialState ( ) {
let self = this ;
self . state = {
2018-08-19 23:15:23 +02:00
selected : null ,
items : self . props . items
2017-04-30 03:11:22 +02:00
} ;
let initialSelection = self . props . items . find ( item => {
return item . selected ;
} ) ;
if ( initialSelection ) {
self . state . selected = initialSelection . id ;
}
}
render ( ) {
let self = this ;
2018-08-19 23:15:23 +02:00
let { headerText } = self . props ;
let { items , selected } = self . state ;
2017-04-30 03:11:22 +02:00
return BDV2 . react . createElement (
"div" ,
null ,
BDV2 . react . createElement ( V2Components . TabBar . Separator , null ) ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( V2Components . TabBar . Header , { text : headerText } ) ,
2017-04-30 03:11:22 +02:00
items . map ( item => {
2018-08-19 23:15:23 +02:00
let { id , text } = item ;
return BDV2 . react . createElement ( V2Components . TabBar . Item , { key : id , selected : selected === id , text : text , id : id , onClick : self . onClick } ) ;
2017-04-30 03:11:22 +02:00
} )
) ;
}
onClick ( id ) {
let self = this ;
2017-06-17 19:08:43 +02:00
const si = $ ( "[class*=side] > [class*=selected]" ) ;
2018-08-19 23:15:23 +02:00
if ( si . length ) {
2017-06-17 19:08:43 +02:00
si . off ( "click.bdsb" ) . on ( "click.bsb" , e => {
$ ( e . target ) . attr ( "class" , self . scn ) ;
} ) ;
si . attr ( "class" , self . nscn ) ;
}
2018-08-19 23:15:23 +02:00
self . setState ( { selected : null } ) ;
self . setState ( { selected : id } ) ;
2017-04-30 03:11:22 +02:00
if ( self . props . onClick ) self . props . onClick ( id ) ;
}
}
2018-10-19 05:59:27 +02:00
class V2C _ReloadIcon extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
return BDV2 . react . createElement ( "svg" , {
xmlns : "http://www.w3.org/2000/svg" ,
viewBox : "0 0 24 24" ,
fill : "#dcddde" ,
className : "bd-reload " + this . props . className ,
onClick : this . props . onClick ,
style : { width : this . props . size || "24px" , height : this . props . size || "24px" }
} ,
BDV2 . react . createElement ( "path" , { d : "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" } ) ,
BDV2 . react . createElement ( "path" , { fill : "none" , d : "M0 0h24v24H0z" } )
) ;
}
}
2017-04-30 03:11:22 +02:00
class V2C _XSvg extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
return BDV2 . react . createElement (
"svg" ,
2018-08-19 23:15:23 +02:00
{ xmlns : "http://www.w3.org/2000/svg" , viewBox : "0 0 12 12" , style : { width : "18px" , height : "18px" } } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"g" ,
2018-08-19 23:15:23 +02:00
{ className : "background" , fill : "none" , fillRule : "evenodd" } ,
BDV2 . react . createElement ( "path" , { d : "M0 0h12v12H0" } ) ,
BDV2 . react . createElement ( "path" , { className : "fill" , fill : "#dcddde" , d : "M9.5 3.205L8.795 2.5 6 5.295 3.205 2.5l-.705.705L5.295 6 2.5 8.795l.705.705L6 6.705 8.795 9.5l.705-.705L6.705 6" } )
2017-04-30 03:11:22 +02:00
)
) ;
}
}
class V2C _Tools extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
this . onClick = this . onClick . bind ( this ) ;
}
render ( ) {
2018-10-20 09:23:31 +02:00
return BDV2 . react . createElement ( "div" , { className : "tools-container toolsContainer-1edPuj" } ,
BDV2 . react . createElement ( "div" , { className : "tools tools-3-3s-N" } ,
BDV2 . react . createElement ( "div" , { className : "container-1sFeqf" } ,
BDV2 . react . createElement ( "div" ,
{ className : "btn-close closeButton-1tv5uR" , onClick : this . onClick } ,
BDV2 . react . createElement ( V2Components . XSvg , null )
) ,
BDV2 . react . createElement (
"div" ,
{ className : "esc-text keybind-KpFkfr" } ,
"ESC"
)
2018-08-14 04:30:47 +02:00
)
2017-04-30 03:11:22 +02:00
)
) ;
}
onClick ( ) {
if ( this . props . onClick ) {
this . props . onClick ( ) ;
}
2018-08-14 04:30:47 +02:00
$ ( ".closeButton-1tv5uR" ) . first ( ) . click ( ) ;
2017-04-30 03:11:22 +02:00
}
}
class V2C _SettingsTitle extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
2019-05-25 06:43:09 +02:00
//h2-2gWE-o title-3sZWYQ size16-14cGz5 height20-mO2eIN weightSemiBold-NJexzi da-h2 da-title da-size16 da-height20 da-weightSemiBold defaultColor-1_ajX0 da-defaultColor marginTop60-3PGbtK da-marginTop60 marginBottom20-32qID7 da-marginBottom20
2017-04-30 03:11:22 +02:00
render ( ) {
return BDV2 . react . createElement (
"h2" ,
2019-05-25 06:43:09 +02:00
{ className : "ui-form-title h2 margin-reset margin-bottom-20 marginTop60-3PGbtK da-marginTop6" } ,
2017-04-30 03:11:22 +02:00
this . props . text
) ;
}
}
class V2C _Checkbox extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
this . onClick = this . onClick . bind ( this ) ;
this . setInitialState ( ) ;
}
setInitialState ( ) {
this . state = {
2018-08-19 23:15:23 +02:00
checked : this . props . checked || false
2017-04-30 03:11:22 +02:00
} ;
}
render ( ) {
return BDV2 . react . createElement (
"li" ,
null ,
BDV2 . react . createElement (
"div" ,
2019-11-19 23:17:03 +01:00
{ className : "checkbox checkbox-3kaeSU da-checkbox" , onClick : this . onClick } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"div" ,
2019-01-16 23:06:39 +01:00
{ className : "checkbox-inner checkboxInner-3yjcPe da-checkboxInner" } ,
BDV2 . react . createElement ( "input" , { className : "checkboxElement-1qV33p da-checkboxElement" , checked : this . state . checked , onChange : ( ) => { } , type : "checkbox" } ) ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement ( "span" , null )
) ,
BDV2 . react . createElement (
"span" ,
null ,
this . props . text
)
)
) ;
}
onClick ( ) {
this . props . onChange ( this . props . id , ! this . state . checked ) ;
this . setState ( {
2018-08-19 23:15:23 +02:00
checked : ! this . state . checked
2017-04-30 03:11:22 +02:00
} ) ;
}
}
class V2C _CssEditorDetached extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
let self = this ;
self . onClick = self . onClick . bind ( self ) ;
self . updateCss = self . updateCss . bind ( self ) ;
self . saveCss = self . saveCss . bind ( self ) ;
self . onChange = self . onChange . bind ( self ) ;
}
componentDidMount ( ) {
2018-08-19 23:15:23 +02:00
$ ( "#app-mount" ) . addClass ( "bd-detached-editor" ) ;
2018-08-06 07:37:31 +02:00
BDV2 . editorDetached = true ;
2018-01-10 02:08:59 +01:00
// this.updateLineCount();
this . editor = ace . edit ( "bd-customcss-editor-detached" ) ;
this . editor . setTheme ( "ace/theme/monokai" ) ;
this . editor . session . setMode ( "ace/mode/css" ) ;
this . editor . setShowPrintMargin ( false ) ;
this . editor . setFontSize ( 14 ) ;
2018-08-19 23:15:23 +02:00
this . editor . on ( "change" , ( ) => {
2018-01-10 02:08:59 +01:00
if ( ! settingsCookie [ "bda-css-0" ] ) return ;
this . saveCss ( ) ;
this . updateCss ( ) ;
} ) ;
2018-08-23 05:30:07 +02:00
2017-04-30 03:11:22 +02:00
}
componentWillUnmount ( ) {
2018-08-19 23:15:23 +02:00
$ ( "#app-mount" ) . removeClass ( "bd-detached-editor" ) ;
2018-08-06 07:37:31 +02:00
BDV2 . editorDetached = false ;
2018-01-10 02:08:59 +01:00
this . editor . destroy ( ) ;
2017-04-30 03:11:22 +02:00
}
2019-03-13 18:13:43 +01:00
2018-08-19 23:15:23 +02:00
updateLineCount ( ) {
let lineCount = this . refs . editor . value . split ( "\n" ) . length ;
if ( lineCount == this . props . lines ) return ;
this . refs . lines . textContent = Array . from ( new Array ( lineCount ) , ( _ , i ) => i + 1 ) . join ( ".\n" ) + "." ;
this . props . lines = lineCount ;
}
2017-04-30 03:11:22 +02:00
get options ( ) {
return {
lineNumbers : true ,
2018-08-19 23:15:23 +02:00
mode : "css" ,
2017-04-30 03:11:22 +02:00
indentUnit : 4 ,
2018-08-19 23:15:23 +02:00
theme : "material" ,
scrollbarStyle : "simple"
2017-04-30 03:11:22 +02:00
} ;
}
get css ( ) {
2018-10-19 05:59:27 +02:00
let _ccss = DataStore . getBDData ( "bdcustomcss" ) ;
2017-04-30 03:11:22 +02:00
let ccss = "" ;
if ( _ccss && _ccss !== "" ) {
ccss = atob ( _ccss ) ;
}
return ccss ;
}
get root ( ) {
let _root = $ ( "#bd-customcss-detach-container" ) ;
if ( ! _root . length ) {
if ( ! this . injectRoot ( ) ) return null ;
return this . detachedRoot ;
}
return _root [ 0 ] ;
}
injectRoot ( ) {
2019-01-12 01:15:45 +01:00
if ( ! $ ( ".app, .app-2rEoOp" ) . length ) return false ;
2017-04-30 03:11:22 +02:00
$ ( "<div/>" , {
2018-08-19 23:15:23 +02:00
id : "bd-customcss-detach-container"
2019-01-12 01:15:45 +01:00
} ) . insertAfter ( $ ( ".app, .app-2rEoOp" ) ) ;
2017-04-30 03:11:22 +02:00
return true ;
}
render ( ) {
let self = this ;
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "bd-detached-css-editor" , id : "bd-customcss-detach-editor" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ id : "bd-customcss-innerpane" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement ( "div" , { className : "editor-wrapper" } ,
2018-01-10 02:08:59 +01:00
BDV2 . react . createElement ( "div" , { id : "bd-customcss-editor-detached" , className : "editor" , ref : "editor" } , self . css )
2018-08-19 23:15:23 +02:00
) ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ id : "bd-customcss-attach-controls" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"ul" ,
2018-08-19 23:15:23 +02:00
{ className : "checkbox-group" } ,
BDV2 . react . createElement ( V2Components . Checkbox , { id : "live-update" , text : "Live Update" , onChange : self . onChange , checked : settingsCookie [ "bda-css-0" ] } )
2017-04-30 03:11:22 +02:00
) ,
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ id : "bd-customcss-detach-controls-button" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ style : { borderRadius : "3px 0 0 3px" , borderRight : "1px solid #3f4146" } , className : "btn btn-primary" , onClick : ( ) => {
2017-04-30 03:11:22 +02:00
self . onClick ( "update" ) ;
2018-08-19 23:15:23 +02:00
} } ,
2017-04-30 03:11:22 +02:00
"Update"
) ,
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ style : { borderRadius : "0" , borderLeft : "1px solid #2d2d2d" , borderRight : "1px solid #2d2d2d" } , className : "btn btn-primary" , onClick : ( ) => {
2017-04-30 03:11:22 +02:00
self . onClick ( "save" ) ;
2018-08-19 23:15:23 +02:00
} } ,
2017-04-30 03:11:22 +02:00
"Save"
) ,
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ style : { borderRadius : "0 3px 3px 0" , borderLeft : "1px solid #3f4146" } , className : "btn btn-primary" , onClick : ( ) => {
2017-04-30 03:11:22 +02:00
self . onClick ( "attach" ) ;
2018-08-19 23:15:23 +02:00
} } ,
2017-04-30 03:11:22 +02:00
"Attach"
) ,
BDV2 . react . createElement (
"span" ,
2018-08-19 23:15:23 +02:00
{ style : { fontSize : "10px" , marginLeft : "5px" } } ,
2017-04-30 03:11:22 +02:00
"Unsaved changes are lost on attach"
)
)
)
)
) ;
}
onChange ( id , checked ) {
switch ( id ) {
2018-08-19 23:15:23 +02:00
case "live-update" :
2017-04-30 03:11:22 +02:00
settingsCookie [ "bda-css-0" ] = checked ;
mainCore . saveSettings ( ) ;
break ;
}
}
onClick ( id ) {
let self = this ;
switch ( id ) {
2018-08-19 23:15:23 +02:00
case "attach" :
2017-04-30 04:21:08 +02:00
if ( $ ( "#editor-detached" ) . length ) self . props . attach ( ) ;
2017-04-30 03:11:22 +02:00
BDV2 . reactDom . unmountComponentAtNode ( self . root ) ;
2017-10-31 08:28:03 +01:00
self . root . remove ( ) ;
2017-04-30 03:11:22 +02:00
break ;
2018-08-19 23:15:23 +02:00
case "update" :
2017-04-30 03:11:22 +02:00
self . updateCss ( ) ;
break ;
2018-08-19 23:15:23 +02:00
case "save" :
2017-04-30 03:11:22 +02:00
self . saveCss ( ) ;
break ;
}
}
updateCss ( ) {
if ( $ ( "#customcss" ) . length == 0 ) {
2018-08-19 23:15:23 +02:00
$ ( "head" ) . append ( "<style id=\"customcss\"></style>" ) ;
2017-04-30 03:11:22 +02:00
}
2019-04-29 17:34:30 +02:00
$ ( "#customcss" ) . text ( this . editor . session . getValue ( ) ) . detach ( ) . appendTo ( document . head ) ;
2017-04-30 03:11:22 +02:00
}
saveCss ( ) {
2018-10-19 05:59:27 +02:00
DataStore . setBDData ( "bdcustomcss" , btoa ( this . editor . session . getValue ( ) ) ) ;
2017-04-30 03:11:22 +02:00
}
}
class V2C _CssEditor extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
let self = this ;
2018-08-19 23:15:23 +02:00
self . props . lines = 0 ;
2017-04-30 03:11:22 +02:00
self . setInitialState ( ) ;
2017-04-30 04:21:08 +02:00
self . attach = self . attach . bind ( self ) ;
2018-08-19 23:15:23 +02:00
self . detachedEditor = BDV2 . react . createElement ( V2C _CssEditorDetached , { attach : self . attach } ) ;
2017-04-30 03:11:22 +02:00
self . onClick = self . onClick . bind ( self ) ;
self . updateCss = self . updateCss . bind ( self ) ;
self . saveCss = self . saveCss . bind ( self ) ;
self . detach = self . detach . bind ( self ) ;
}
setInitialState ( ) {
this . state = {
2018-08-19 23:15:23 +02:00
detached : this . props . detached || BDV2 . editorDetached
2017-04-30 03:11:22 +02:00
} ;
}
componentDidMount ( ) {
2018-01-10 02:08:59 +01:00
// this.updateLineCount();
this . editor = ace . edit ( "bd-customcss-editor" ) ;
this . editor . setTheme ( "ace/theme/monokai" ) ;
this . editor . session . setMode ( "ace/mode/css" ) ;
this . editor . setShowPrintMargin ( false ) ;
this . editor . setFontSize ( 14 ) ;
2018-08-19 23:15:23 +02:00
this . editor . on ( "change" , ( ) => {
2018-01-10 02:08:59 +01:00
if ( ! settingsCookie [ "bda-css-0" ] ) return ;
this . saveCss ( ) ;
this . updateCss ( ) ;
} ) ;
}
componentWillUnmount ( ) {
this . editor . destroy ( ) ;
2017-04-30 03:11:22 +02:00
}
componentDidUpdate ( prevProps , prevState ) {
let self = this ;
if ( prevState . detached && ! self . state . detached ) {
BDV2 . reactDom . unmountComponentAtNode ( self . detachedRoot ) ;
}
}
codeMirror ( ) {
}
get options ( ) {
return {
lineNumbers : true ,
2018-08-19 23:15:23 +02:00
mode : "css" ,
2017-04-30 03:11:22 +02:00
indentUnit : 4 ,
2018-08-19 23:15:23 +02:00
theme : "material" ,
scrollbarStyle : "simple"
2017-04-30 03:11:22 +02:00
} ;
}
get css ( ) {
2018-10-19 05:59:27 +02:00
let _ccss = DataStore . getBDData ( "bdcustomcss" ) ;
2017-04-30 03:11:22 +02:00
let ccss = "" ;
if ( _ccss && _ccss !== "" ) {
ccss = atob ( _ccss ) ;
}
return ccss ;
}
2019-03-13 18:13:43 +01:00
2018-08-19 23:15:23 +02:00
updateLineCount ( ) {
let lineCount = this . refs . editor . value . split ( "\n" ) . length ;
if ( lineCount == this . props . lines ) return ;
this . refs . lines . textContent = Array . from ( new Array ( lineCount ) , ( _ , i ) => i + 1 ) . join ( ".\n" ) + "." ;
this . props . lines = lineCount ;
}
2017-04-30 03:11:22 +02:00
render ( ) {
let self = this ;
2018-08-19 23:15:23 +02:00
let { detached } = self . state ;
2017-04-30 03:11:22 +02:00
return BDV2 . react . createElement (
"div" ,
2018-10-20 21:35:20 +02:00
{ className : "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default" , style : { padding : "60px 40px 0px" } } ,
2017-04-30 03:11:22 +02:00
detached && BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ id : "editor-detached" } ,
BDV2 . react . createElement ( V2Components . SettingsTitle , { text : "Custom CSS Editor" } ) ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"h3" ,
null ,
"Editor Detached"
) ,
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ className : "btn btn-primary" , onClick : ( ) => {
2017-04-30 03:11:22 +02:00
self . attach ( ) ;
2018-08-19 23:15:23 +02:00
} } ,
2017-04-30 03:11:22 +02:00
"Attach"
)
) ,
! detached && BDV2 . react . createElement (
"div" ,
null ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( V2Components . SettingsTitle , { text : "Custom CSS Editor" } ) ,
BDV2 . react . createElement ( "div" , { className : "editor-wrapper" } ,
BDV2 . react . createElement ( "div" , { id : "bd-customcss-editor" , className : "editor" , ref : "editor" } , self . css )
) ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ id : "bd-customcss-attach-controls" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"ul" ,
2018-08-19 23:15:23 +02:00
{ className : "checkbox-group" } ,
BDV2 . react . createElement ( V2Components . Checkbox , { id : "live-update" , text : "Live Update" , onChange : this . onChange , checked : settingsCookie [ "bda-css-0" ] } )
2017-04-30 03:11:22 +02:00
) ,
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ id : "bd-customcss-detach-controls-button" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ style : { borderRadius : "3px 0 0 3px" , borderRight : "1px solid #3f4146" } , className : "btn btn-primary" , onClick : ( ) => {
2017-04-30 03:11:22 +02:00
self . onClick ( "update" ) ;
2018-08-19 23:15:23 +02:00
} } ,
2017-04-30 03:11:22 +02:00
"Update"
) ,
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ style : { borderRadius : "0" , borderLeft : "1px solid #2d2d2d" , borderRight : "1px solid #2d2d2d" } , className : "btn btn-primary" , onClick : ( ) => {
2017-04-30 03:11:22 +02:00
self . onClick ( "save" ) ;
2018-08-19 23:15:23 +02:00
} } ,
2017-04-30 03:11:22 +02:00
"Save"
) ,
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ style : { borderRadius : "0 3px 3px 0" , borderLeft : "1px solid #3f4146" } , className : "btn btn-primary" , onClick : ( ) => {
2017-04-30 03:11:22 +02:00
self . onClick ( "detach" ) ;
2018-08-19 23:15:23 +02:00
} } ,
2017-04-30 03:11:22 +02:00
"Detach"
) ,
BDV2 . react . createElement (
"span" ,
2018-08-19 23:15:23 +02:00
{ style : { fontSize : "10px" , marginLeft : "5px" } } ,
2017-04-30 03:11:22 +02:00
"Unsaved changes are lost on detach"
2019-05-22 07:20:54 +02:00
) ,
BDV2 . react . createElement ( "div" , { className : "help-text" } ,
"Press " ,
BDV2 . react . createElement ( "code" , { className : "inline" } , "ctrl" ) ,
"+" ,
BDV2 . react . createElement ( "span" , { className : "inline" } , "," ) ,
" with the editor focused to access the editor's settings."
2017-04-30 03:11:22 +02:00
)
)
)
)
) ;
}
onClick ( arg ) {
let self = this ;
switch ( arg ) {
2018-08-19 23:15:23 +02:00
case "update" :
2017-04-30 03:11:22 +02:00
self . updateCss ( ) ;
break ;
2018-08-19 23:15:23 +02:00
case "save" :
2017-04-30 03:11:22 +02:00
self . saveCss ( ) ;
break ;
2018-08-19 23:15:23 +02:00
case "detach" :
2017-04-30 03:11:22 +02:00
self . detach ( ) ;
break ;
}
}
onChange ( id , checked ) {
switch ( id ) {
2018-08-19 23:15:23 +02:00
case "live-update" :
2017-04-30 03:11:22 +02:00
settingsCookie [ "bda-css-0" ] = checked ;
mainCore . saveSettings ( ) ;
break ;
}
}
updateCss ( ) {
if ( $ ( "#customcss" ) . length == 0 ) {
2018-08-19 23:15:23 +02:00
$ ( "head" ) . append ( "<style id=\"customcss\"></style>" ) ;
2017-04-30 03:11:22 +02:00
}
2019-04-29 17:34:30 +02:00
$ ( "#customcss" ) . text ( this . editor . session . getValue ( ) ) . detach ( ) . appendTo ( document . head ) ;
2017-04-30 03:11:22 +02:00
}
saveCss ( ) {
2018-10-19 05:59:27 +02:00
DataStore . setBDData ( "bdcustomcss" , btoa ( this . editor . session . getValue ( ) ) ) ;
2017-04-30 03:11:22 +02:00
}
detach ( ) {
let self = this ;
self . setState ( {
2018-08-19 23:15:23 +02:00
detached : true
2017-04-30 03:11:22 +02:00
} ) ;
let droot = self . detachedRoot ;
if ( ! droot ) {
console . log ( "FAILED TO INJECT ROOT: .app" ) ;
return ;
}
BDV2 . reactDom . render ( self . detachedEditor , droot ) ;
}
get detachedRoot ( ) {
let _root = $ ( "#bd-customcss-detach-container" ) ;
if ( ! _root . length ) {
if ( ! this . injectDetachedRoot ( ) ) return null ;
return this . detachedRoot ;
}
return _root [ 0 ] ;
}
injectDetachedRoot ( ) {
2019-01-12 01:15:45 +01:00
if ( ! $ ( ".app, .app-2rEoOp" ) . length ) return false ;
2017-04-30 03:11:22 +02:00
$ ( "<div/>" , {
2018-08-19 23:15:23 +02:00
id : "bd-customcss-detach-container"
2019-01-12 01:15:45 +01:00
} ) . insertAfter ( $ ( ".app, .app-2rEoOp" ) ) ;
2017-04-30 03:11:22 +02:00
return true ;
}
attach ( ) {
let self = this ;
self . setState ( {
2018-08-19 23:15:23 +02:00
detached : false
2017-04-30 03:11:22 +02:00
} ) ;
}
}
class V2C _List extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
return BDV2 . react . createElement (
"ul" ,
2018-08-19 23:15:23 +02:00
{ className : this . props . className } ,
2017-04-30 03:11:22 +02:00
this . props . children
) ;
}
}
class V2C _ContentColumn extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
return BDV2 . react . createElement (
"div" ,
2018-10-20 21:35:20 +02:00
{ className : "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default" } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement (
"h2" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-form-title h2 margin-reset margin-bottom-20" } ,
2017-04-30 03:11:22 +02:00
this . props . title
) ,
this . props . children
) ;
}
}
class V2C _PluginCard extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
let self = this ;
self . onChange = self . onChange . bind ( self ) ;
self . showSettings = self . showSettings . bind ( self ) ;
self . setInitialState ( ) ;
2018-08-19 23:15:23 +02:00
self . hasSettings = typeof self . props . plugin . getSettingsPanel === "function" ;
self . settingsPanel = "" ;
2018-10-19 05:59:27 +02:00
this . reload = this . reload . bind ( this ) ;
2018-10-28 21:28:13 +01:00
this . onReload = this . onReload . bind ( this ) ;
2017-04-30 03:11:22 +02:00
}
setInitialState ( ) {
this . state = {
2018-08-19 23:15:23 +02:00
checked : pluginCookie [ this . props . plugin . getName ( ) ] ,
2018-10-19 05:59:27 +02:00
settings : false ,
reloads : 0
2017-04-30 03:11:22 +02:00
} ;
}
2018-10-28 21:28:13 +01:00
// componentDidMount() {
// BDEvents.on("plugin-reloaded", this.onReload);
// }
// componentWillUnmount() {
// BDEvents.off("plugin-reloaded", this.onReload);
// }
onReload ( pluginName ) {
if ( pluginName !== this . props . plugin . getName ( ) ) return ;
this . setState ( { reloads : this . state . reloads + 1 } ) ;
}
2017-04-30 03:11:22 +02:00
componentDidUpdate ( ) {
if ( this . state . settings ) {
2017-04-30 13:02:42 +02:00
if ( typeof this . settingsPanel === "object" ) {
this . refs . settingspanel . appendChild ( this . settingsPanel ) ;
}
2019-03-13 18:13:43 +01:00
2018-08-19 23:15:23 +02:00
if ( ! settingsCookie [ "fork-ps-3" ] ) return ;
2020-02-27 03:43:16 +01:00
const isHidden = ( container , element ) => {
2018-08-19 23:15:23 +02:00
2020-02-27 03:43:16 +01:00
const cTop = container . scrollTop ;
const cBottom = cTop + container . clientHeight ;
2018-08-19 23:15:23 +02:00
2020-02-27 03:43:16 +01:00
const eTop = element . offsetTop ;
const eBottom = eTop + element . clientHeight ;
2018-08-19 23:15:23 +02:00
return ( eTop < cTop || eBottom > cBottom ) ;
} ;
2019-03-13 18:13:43 +01:00
2020-02-27 03:43:16 +01:00
const self = $ ( BDV2 . reactDom . findDOMNode ( this ) ) ;
const container = self . parents ( ".scroller" ) ;
2018-08-19 23:15:23 +02:00
if ( ! isHidden ( container [ 0 ] , self [ 0 ] ) ) return ;
container . animate ( {
scrollTop : self . offset ( ) . top - container . offset ( ) . top + container . scrollTop ( ) - 30
} , 300 ) ;
2017-04-30 03:11:22 +02:00
}
}
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
reload ( ) {
const plugin = this . props . plugin . getName ( ) ;
pluginModule . reloadPlugin ( plugin ) ;
this . props . plugin = bdplugins [ plugin ] . plugin ;
2018-10-28 21:28:13 +01:00
this . onReload ( this . props . plugin . getName ( ) ) ;
2018-10-19 05:59:27 +02:00
}
2017-04-30 03:11:22 +02:00
2019-05-22 07:20:54 +02:00
getString ( value ) {
return typeof value == "string" ? value : value . toString ( ) ;
}
2020-02-27 03:43:16 +01:00
makeLink ( title , url ) {
const props = { className : "bda-link bda-link-website" , target : "_blank" } ;
if ( typeof ( url ) == "string" ) props . href = url ;
if ( typeof ( url ) == "function" ) props . onClick = ( event ) => { event . preventDefault ( ) ; event . stopPropagation ( ) ; url ( ) ; } ;
return BDV2 . react . createElement ( "a" , props , title ) ;
}
2017-04-30 03:11:22 +02:00
render ( ) {
2020-02-27 03:43:16 +01:00
const self = this ;
const { plugin } = this . props ;
const name = this . getString ( plugin . getName ( ) ) ;
const author = this . getString ( plugin . getAuthor ( ) ) ;
const description = this . getString ( plugin . getDescription ( ) ) ;
const version = this . getString ( plugin . getVersion ( ) ) ;
const meta = bdplugins [ name ] ;
2017-04-30 03:11:22 +02:00
if ( this . state . settings ) {
2018-08-19 23:15:23 +02:00
try { self . settingsPanel = plugin . getSettingsPanel ( ) ; }
2018-11-10 06:00:53 +01:00
catch ( err ) { Utils . err ( "Plugins" , "Unable to get settings panel for " + plugin . getName ( ) + "." , err ) ; }
2019-03-13 18:13:43 +01:00
2017-11-01 18:28:04 +01:00
return BDV2 . react . createElement ( "li" , { className : "settings-open ui-switch-item" } ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( "div" , { style : { "float" : "right" , "cursor" : "pointer" } , onClick : ( ) => {
2017-11-01 18:12:29 +01:00
this . refs . settingspanel . innerHTML = "" ;
2018-08-19 23:15:23 +02:00
self . setState ( { settings : false } ) ;
2017-11-01 18:28:04 +01:00
} } ,
2017-04-30 03:11:22 +02:00
BDV2 . react . createElement ( V2Components . XSvg , null )
) ,
2018-08-19 23:15:23 +02:00
typeof self . settingsPanel === "object" && BDV2 . react . createElement ( "div" , { id : ` plugin-settings- ${ name } ` , className : "plugin-settings" , ref : "settingspanel" } ) ,
typeof self . settingsPanel !== "object" && BDV2 . react . createElement ( "div" , { id : ` plugin-settings- ${ name } ` , className : "plugin-settings" , ref : "settingspanel" , dangerouslySetInnerHTML : { _ _html : self . settingsPanel } } )
2017-04-30 03:11:22 +02:00
) ;
}
2020-02-27 03:43:16 +01:00
const links = [ ] ;
if ( meta . website ) links . push ( this . makeLink ( "Website" , meta . website ) ) ;
if ( meta . source ) links . push ( this . makeLink ( "Source" , meta . source ) ) ;
if ( meta . invite ) {
links . push ( this . makeLink ( "Support Server" , ( ) => {
const tester = /\.gg\/(.*)$/ ;
let code = meta . invite ;
if ( tester . test ( code ) ) code = code . match ( tester ) [ 1 ] ;
BDV2 . LayerStack . popLayer ( ) ;
BDV2 . InviteActions . acceptInviteAndTransitionToInviteChannel ( code ) ;
} ) ) ;
}
if ( meta . donate ) links . push ( this . makeLink ( "Donate" , meta . donate ) ) ;
if ( meta . patreon ) links . push ( this . makeLink ( "Patreon" , meta . patreon ) ) ;
const authorProps = { className : "bda-author" } ;
if ( meta . authorLink || meta . authorId ) {
authorProps . className += ` ${ BDV2 . anchorClasses . anchor } ${ BDV2 . anchorClasses . anchorUnderlineOnHover } ` ;
authorProps . target = "_blank" ;
if ( meta . authorLink ) authorProps . href = meta . authorLink ;
if ( meta . authorId ) authorProps . onClick = ( ) => { BDV2 . LayerStack . popLayer ( ) ; BDV2 . openDM ( meta . authorId ) ; } ;
}
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( "li" , { "data-name" : name , "data-version" : version , "className" : "settings-closed ui-switch-item" } ,
2017-11-01 18:12:29 +01:00
BDV2 . react . createElement ( "div" , { className : "bda-header" } ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( "span" , { className : "bda-header-title" } ,
BDV2 . react . createElement ( "span" , { className : "bda-name" } , name ) ,
2017-11-01 17:09:58 +01:00
" v" ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( "span" , { className : "bda-version" } , version ) ,
2017-11-01 17:09:58 +01:00
" by " ,
2020-02-27 03:43:16 +01:00
BDV2 . react . createElement ( meta . authorLink || meta . authorId ? "a" : "span" , authorProps , author )
2017-11-01 17:09:58 +01:00
) ,
2018-10-19 05:59:27 +02:00
BDV2 . react . createElement ( "div" , { className : "bda-controls" } ,
! settingsCookie [ "fork-ps-5" ] && BDV2 . react . createElement ( V2Components . TooltipWrap ( V2Components . ReloadIcon , { color : "black" , side : "top" , text : "Reload" } ) , { className : "bd-reload-card" , onClick : this . reload } ) ,
BDV2 . react . createElement ( "label" , { className : "ui-switch-wrapper ui-flex-child" , style : { flex : "0 0 auto" } } ,
BDV2 . react . createElement ( "input" , { checked : this . state . checked , onChange : this . onChange , className : "ui-switch-checkbox" , type : "checkbox" } ) ,
BDV2 . react . createElement ( "div" , { className : this . state . checked ? "ui-switch checked" : "ui-switch" } )
)
2017-04-30 03:11:22 +02:00
)
) ,
2017-11-01 18:12:29 +01:00
BDV2 . react . createElement ( "div" , { className : "bda-description-wrap scroller-wrap fade" } ,
BDV2 . react . createElement ( "div" , { className : "bda-description scroller" } , description )
2017-11-01 16:21:55 +01:00
) ,
2020-02-27 03:43:16 +01:00
( links . length || this . hasSettings ) && BDV2 . react . createElement ( "div" , { className : "bda-footer" } ,
2017-11-01 18:12:29 +01:00
BDV2 . react . createElement ( "span" , { className : "bda-links" } ,
2020-02-27 03:43:16 +01:00
... ( links . map ( ( element , index ) => index < links . length - 1 ? [ element , " | " ] : element ) . flat ( ) )
2017-11-01 18:12:29 +01:00
) ,
2017-12-22 20:29:59 +01:00
this . hasSettings && BDV2 . react . createElement ( "button" , { onClick : this . showSettings , className : "bda-settings-button" , disabled : ! this . state . checked } , "Settings" )
2017-04-30 03:11:22 +02:00
)
) ;
}
onChange ( ) {
2018-08-19 23:15:23 +02:00
this . setState ( { checked : ! this . state . checked } ) ;
2017-11-01 18:34:00 +01:00
pluginModule . togglePlugin ( this . props . plugin . getName ( ) ) ;
2017-04-30 03:11:22 +02:00
}
2019-03-13 18:13:43 +01:00
showSettings ( ) {
2017-12-22 20:29:59 +01:00
if ( ! this . hasSettings ) return ;
2018-08-19 23:15:23 +02:00
this . setState ( { settings : true } ) ;
2017-04-30 03:11:22 +02:00
}
}
class V2C _ThemeCard extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
this . setInitialState ( ) ;
this . onChange = this . onChange . bind ( this ) ;
2018-10-19 05:59:27 +02:00
this . reload = this . reload . bind ( this ) ;
2017-04-30 03:11:22 +02:00
}
setInitialState ( ) {
this . state = {
2018-10-19 05:59:27 +02:00
checked : themeCookie [ this . props . theme . name ] ,
reloads : 0
2017-04-30 03:11:22 +02:00
} ;
}
2018-10-28 21:28:13 +01:00
// componentDidMount() {
// BDEvents.on("theme-reloaded", this.onReload);
// }
// componentWillUnmount() {
// BDEvents.off("theme-reloaded", this.onReload);
// }
onReload ( themeName ) {
if ( themeName !== this . props . theme . name ) return ;
this . setState ( { reloads : this . state . reloads + 1 } ) ;
}
2018-10-19 05:59:27 +02:00
reload ( ) {
const theme = this . props . theme . name ;
const error = themeModule . reloadTheme ( theme ) ;
if ( error ) mainCore . showToast ( ` Could not reload ${ bdthemes [ theme ] . name } . Check console for details. ` , { type : "error" } ) ;
else mainCore . showToast ( ` ${ bdthemes [ theme ] . name } v ${ bdthemes [ theme ] . version } has been reloaded. ` , { type : "success" } ) ;
// this.setState(this.state);
this . props . theme = bdthemes [ theme ] ;
2018-10-28 21:28:13 +01:00
this . onReload ( this . props . theme . name ) ;
2018-10-19 05:59:27 +02:00
}
2020-02-27 03:43:16 +01:00
makeLink ( title , url ) {
const props = { className : "bda-link bda-link-website" , target : "_blank" } ;
if ( typeof ( url ) == "string" ) props . href = url ;
if ( typeof ( url ) == "function" ) props . onClick = ( event ) => { event . preventDefault ( ) ; event . stopPropagation ( ) ; url ( ) ; } ;
return BDV2 . react . createElement ( "a" , props , title ) ;
}
2017-04-30 03:11:22 +02:00
render ( ) {
2020-02-27 03:43:16 +01:00
const { theme } = this . props ;
const name = theme . name ;
const description = theme . description ;
const version = theme . version ;
const author = theme . author ;
const meta = bdthemes [ name ] ;
const links = [ ] ;
if ( meta . website ) links . push ( this . makeLink ( "Website" , meta . website ) ) ;
if ( meta . source ) links . push ( this . makeLink ( "Source" , meta . source ) ) ;
if ( meta . invite ) {
links . push ( this . makeLink ( "Support Server" , ( ) => {
const tester = /\.gg\/(.*)$/ ;
let code = meta . invite ;
if ( tester . test ( code ) ) code = code . match ( tester ) [ 1 ] ;
BDV2 . LayerStack . popLayer ( ) ;
BDV2 . InviteActions . acceptInviteAndTransitionToInviteChannel ( code ) ;
} ) ) ;
}
if ( meta . donate ) links . push ( this . makeLink ( "Donate" , meta . donate ) ) ;
if ( meta . patreon ) links . push ( this . makeLink ( "Patreon" , meta . patreon ) ) ;
const authorProps = { className : "bda-author" } ;
if ( meta . authorLink || meta . authorId ) {
authorProps . className += ` ${ BDV2 . anchorClasses . anchor } ${ BDV2 . anchorClasses . anchorUnderlineOnHover } ` ;
authorProps . target = "_blank" ;
if ( meta . authorLink ) authorProps . href = meta . authorLink ;
if ( meta . authorId ) authorProps . onClick = ( ) => { BDV2 . LayerStack . popLayer ( ) ; BDV2 . openDM ( meta . authorId ) ; } ;
}
2017-11-01 17:09:58 +01:00
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( "li" , { "data-name" : name , "data-version" : version , "className" : "settings-closed ui-switch-item" } ,
2017-11-01 18:28:04 +01:00
BDV2 . react . createElement ( "div" , { className : "bda-header" } ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( "span" , { className : "bda-header-title" } ,
BDV2 . react . createElement ( "span" , { className : "bda-name" } , name ) ,
2017-11-01 17:09:58 +01:00
" v" ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( "span" , { className : "bda-version" } , version ) ,
2017-11-01 17:09:58 +01:00
" by " ,
2020-02-27 03:43:16 +01:00
BDV2 . react . createElement ( meta . authorLink || meta . authorId ? "a" : "span" , authorProps , author )
2017-11-01 17:09:58 +01:00
) ,
2018-10-19 05:59:27 +02:00
BDV2 . react . createElement ( "div" , { className : "bda-controls" } ,
! settingsCookie [ "fork-ps-5" ] && BDV2 . react . createElement ( V2Components . TooltipWrap ( V2Components . ReloadIcon , { color : "black" , side : "top" , text : "Reload" } ) , { className : "bd-reload-card" , onClick : this . reload } ) ,
BDV2 . react . createElement ( "label" , { className : "ui-switch-wrapper ui-flex-child" , style : { flex : "0 0 auto" } } ,
BDV2 . react . createElement ( "input" , { checked : this . state . checked , onChange : this . onChange , className : "ui-switch-checkbox" , type : "checkbox" } ) ,
BDV2 . react . createElement ( "div" , { className : this . state . checked ? "ui-switch checked" : "ui-switch" } )
)
2017-11-01 17:56:51 +01:00
)
2017-04-30 03:11:22 +02:00
) ,
2017-11-01 18:28:04 +01:00
BDV2 . react . createElement ( "div" , { className : "bda-description-wrap scroller-wrap fade" } ,
BDV2 . react . createElement ( "div" , { className : "bda-description scroller" } , description )
2017-11-01 17:09:58 +01:00
) ,
2020-02-27 03:43:16 +01:00
( ! ! links . length ) && BDV2 . react . createElement ( "div" , { className : "bda-footer" } ,
2017-11-01 18:12:29 +01:00
BDV2 . react . createElement ( "span" , { className : "bda-links" } ,
2020-02-27 03:43:16 +01:00
... ( links . map ( ( element , index ) => index < links . length - 1 ? [ element , " | " ] : element ) . flat ( ) )
2017-11-01 18:12:29 +01:00
)
2017-04-30 03:11:22 +02:00
)
) ;
}
onChange ( ) {
2018-08-19 23:15:23 +02:00
this . setState ( { checked : ! this . state . checked } ) ;
2017-11-01 18:34:00 +01:00
themeModule . toggleTheme ( this . props . theme . name ) ;
2017-04-30 03:11:22 +02:00
}
}
class V2Cs _TabBar {
static get Item ( ) {
return V2C _TabBarItem ;
}
static get Header ( ) {
return V2C _TabBarHeader ;
}
static get Separator ( ) {
return V2C _TabBarSeparator ;
}
}
2018-01-09 04:24:00 +01:00
class V2Components {
2019-05-25 06:43:09 +02:00
static get SettingsGroup ( ) {
return V2C _SettingsGroup ;
}
static get SectionedSettingsPanel ( ) {
return V2C _SectionedSettingsPanel ;
}
2018-01-09 04:24:00 +01:00
static get SettingsPanel ( ) {
return V2C _SettingsPanel ;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
static get Switch ( ) {
return V2C _Switch ;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
static get Scroller ( ) {
return V2C _Scroller ;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
static get TabBar ( ) {
return V2Cs _TabBar ;
}
static get SideBar ( ) {
return V2C _SideBar ;
}
static get Tools ( ) {
return V2C _Tools ;
}
static get SettingsTitle ( ) {
return V2C _SettingsTitle ;
}
static get CssEditor ( ) {
return V2C _CssEditor ;
}
static get Checkbox ( ) {
return V2C _Checkbox ;
}
static get List ( ) {
return V2C _List ;
}
static get PluginCard ( ) {
return V2C _PluginCard ;
}
static get ThemeCard ( ) {
return V2C _ThemeCard ;
}
static get ContentColumn ( ) {
return V2C _ContentColumn ;
}
2018-10-19 05:59:27 +02:00
static get ReloadIcon ( ) {
return V2C _ReloadIcon ;
}
2018-01-09 04:24:00 +01:00
static get XSvg ( ) {
return V2C _XSvg ;
}
static get Layer ( ) {
return V2C _Layer ;
}
static get SidebarView ( ) {
return V2C _SidebarView ;
}
static get ServerCard ( ) {
return V2C _ServerCard ;
2017-04-30 03:11:22 +02:00
}
2018-10-19 05:59:27 +02:00
static TooltipWrap ( Component , options ) {
const { style = "black" , side = "top" , text = "" } = options ;
2019-03-13 18:13:43 +01:00
const id = BDV2 . KeyGenerator ( ) ;
2018-10-19 05:59:27 +02:00
return class extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
this . onMouseEnter = this . onMouseEnter . bind ( this ) ;
this . onMouseLeave = this . onMouseLeave . bind ( this ) ;
}
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
componentDidMount ( ) {
this . node = BDV2 . reactDom . findDOMNode ( this ) ;
this . node . addEventListener ( "mouseenter" , this . onMouseEnter ) ;
this . node . addEventListener ( "mouseleave" , this . onMouseLeave ) ;
}
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
componentWillUnmount ( ) {
this . node . removeEventListener ( "mouseenter" , this . onMouseEnter ) ;
this . node . removeEventListener ( "mouseleave" , this . onMouseLeave ) ;
}
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
onMouseEnter ( ) {
2019-04-18 10:50:33 +02:00
if ( ! BDV2 . Tooltips ) return ;
2018-10-19 05:59:27 +02:00
const { left , top , width , height } = this . node . getBoundingClientRect ( ) ;
BDV2 . Tooltips . show ( id , {
position : side ,
text : text ,
color : style ,
targetWidth : width ,
targetHeight : height ,
windowWidth : Utils . screenWidth ,
windowHeight : Utils . screenHeight ,
x : left ,
y : top
} ) ;
const observer = new MutationObserver ( ( mutations ) => {
mutations . forEach ( ( mutation ) => {
const nodes = Array . from ( mutation . removedNodes ) ;
const directMatch = nodes . indexOf ( this . node ) > - 1 ;
const parentMatch = nodes . some ( parent => parent . contains ( this . node ) ) ;
if ( directMatch || parentMatch ) {
this . onMouseLeave ( ) ;
observer . disconnect ( ) ;
}
} ) ;
} ) ;
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
observer . observe ( document . body , { subtree : true , childList : true } ) ;
}
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
onMouseLeave ( ) {
2019-04-18 10:50:33 +02:00
if ( ! BDV2 . Tooltips ) return ;
2018-10-19 05:59:27 +02:00
BDV2 . Tooltips . hide ( id ) ;
}
2019-03-13 18:13:43 +01:00
2018-10-19 05:59:27 +02:00
render ( ) {
return BDV2 . react . createElement ( Component , this . props ) ;
}
} ;
}
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
class V2 _SettingsPanel _Sidebar {
2017-04-30 03:11:22 +02:00
2018-01-09 04:24:00 +01:00
constructor ( onClick ) {
this . onClick = onClick ;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
get items ( ) {
2019-05-25 06:43:09 +02:00
return [ { text : "Settings" , id : "core" } , { text : "Emotes" , id : "emotes" } , { text : "Plugins" , id : "plugins" } , { text : "Themes" , id : "themes" } , { text : "Custom CSS" , id : "customcss" } ] ;
2018-01-09 04:24:00 +01:00
}
get component ( ) {
2020-02-10 06:57:25 +01:00
return BDV2 . react . createElement ( "span" , null , BDV2 . react . createElement ( V2Components . SideBar , { onClick : this . onClick , headerText : "Bandaged BD" , items : this . items } ) ) ;
2017-04-30 03:11:22 +02:00
}
2018-01-09 04:24:00 +01:00
get root ( ) {
let _root = $ ( "#bd-settings-sidebar" ) ;
if ( ! _root . length ) {
if ( ! this . injectRoot ( ) ) return null ;
return this . root ;
}
return _root [ 0 ] ;
}
injectRoot ( ) {
2018-02-05 23:48:19 +01:00
let changeLog = $ ( "[class*='side-'] > [class*='item-']:not([class*=Danger])" ) . last ( ) ;
2018-01-09 04:24:00 +01:00
if ( ! changeLog . length ) return false ;
2018-08-19 23:15:23 +02:00
$ ( "<span/>" , { id : "bd-settings-sidebar" } ) . insertBefore ( changeLog . prev ( ) ) ;
2018-01-09 04:24:00 +01:00
return true ;
2017-04-30 03:11:22 +02:00
}
render ( ) {
2018-01-09 04:24:00 +01:00
let root = this . root ;
if ( ! root ) {
2018-02-05 23:48:19 +01:00
console . log ( "FAILED TO LOCATE ROOT: [class*='side-'] > [class*='item-']:not([class*=Danger])" ) ;
2018-01-09 04:24:00 +01:00
return ;
}
BDV2 . reactDom . render ( this . component , root ) ;
2018-08-23 05:30:07 +02:00
Utils . onRemoved ( root , ( ) => {
BDV2 . reactDom . unmountComponentAtNode ( root ) ;
} ) ;
2018-01-09 04:24:00 +01:00
}
}
2017-04-30 03:11:22 +02:00
class V2 _SettingsPanel {
constructor ( ) {
let self = this ;
self . sideBarOnClick = self . sideBarOnClick . bind ( self ) ;
self . onChange = self . onChange . bind ( self ) ;
self . updateSettings = this . updateSettings . bind ( self ) ;
self . sidebar = new V2 _SettingsPanel _Sidebar ( self . sideBarOnClick ) ;
}
get root ( ) {
let _root = $ ( "#bd-settingspane-container" ) ;
if ( ! _root . length ) {
if ( ! this . injectRoot ( ) ) return null ;
return this . root ;
}
return _root [ 0 ] ;
}
injectRoot ( ) {
2018-10-20 21:35:20 +02:00
if ( ! $ ( ".layer-3QrUeG .standardSidebarView-3F1I7i, .layer-3QrUeG .ui-standard-sidebar-view" ) . length ) return false ;
2018-08-23 05:40:26 +02:00
const root = $ ( "<div/>" , {
2018-10-20 21:35:20 +02:00
"class" : "contentRegion-3nDuYy content-region" ,
2018-08-19 23:15:23 +02:00
"id" : "bd-settingspane-container"
2018-08-23 05:40:26 +02:00
} ) ;
2018-10-20 21:35:20 +02:00
$ ( ".layer-3QrUeG .standardSidebarView-3F1I7i, .layer-3QrUeG .ui-standard-sidebar-view" ) . append ( root ) ;
2018-08-23 08:21:10 +02:00
2018-08-23 05:40:26 +02:00
Utils . onRemoved ( root [ 0 ] , ( ) => {
BDV2 . reactDom . unmountComponentAtNode ( root [ 0 ] ) ;
} ) ;
2017-04-30 03:11:22 +02:00
return true ;
}
get coreSettings ( ) {
2019-05-25 06:43:09 +02:00
const settings = this . getSettings ( "core" ) ;
const categories = [ ... new Set ( settings . map ( s => s . category ) ) ] ;
const sections = categories . map ( c => { return { title : c , settings : settings . filter ( s => s . category == c ) } ; } ) ;
return sections ;
2017-04-30 03:11:22 +02:00
}
2019-05-25 06:43:09 +02:00
2017-04-30 03:11:22 +02:00
get emoteSettings ( ) {
return this . getSettings ( "emote" ) ;
}
getSettings ( category ) {
return Object . keys ( settings ) . reduce ( ( arr , key ) => {
let setting = settings [ key ] ;
if ( setting . cat === category && setting . implemented && ! setting . hidden ) {
setting . text = key ;
arr . push ( setting ) ;
}
return arr ;
} , [ ] ) ;
}
sideBarOnClick ( id ) {
let self = this ;
2018-10-20 21:35:20 +02:00
$ ( ".contentRegion-3nDuYy, .content-region" ) . first ( ) . hide ( ) ;
2017-04-30 03:11:22 +02:00
$ ( self . root ) . show ( ) ;
switch ( id ) {
2018-08-19 23:15:23 +02:00
case "core" :
2017-04-30 03:11:22 +02:00
self . renderCoreSettings ( ) ;
break ;
2018-08-19 23:15:23 +02:00
case "emotes" :
2017-04-30 03:11:22 +02:00
self . renderEmoteSettings ( ) ;
break ;
2018-08-19 23:15:23 +02:00
case "customcss" :
2017-04-30 03:11:22 +02:00
self . renderCustomCssEditor ( ) ;
break ;
2018-08-19 23:15:23 +02:00
case "plugins" :
2017-04-30 03:11:22 +02:00
self . renderPluginPane ( ) ;
break ;
2018-08-19 23:15:23 +02:00
case "themes" :
2017-04-30 03:11:22 +02:00
self . renderThemePane ( ) ;
break ;
}
}
2017-11-03 04:05:33 +01:00
onClick ( ) { }
2017-04-30 03:11:22 +02:00
onChange ( id , checked ) {
2018-11-10 06:00:53 +01:00
this . updateSettings ( id , checked ) ;
2017-04-30 03:11:22 +02:00
}
2018-11-10 06:00:53 +01:00
updateSettings ( id , enabled ) {
settingsCookie [ id ] = enabled ;
2017-10-30 22:33:38 +01:00
2019-05-22 07:20:54 +02:00
// if (id == "bda-gs-b") {
// if (enabled) $("body").addClass("bd-blue");
// else $("body").removeClass("bd-blue");
// }
2017-10-30 22:33:38 +01:00
2018-11-10 06:00:53 +01:00
if ( id == "bda-gs-2" ) {
if ( enabled ) $ ( "body" ) . addClass ( "bd-minimal" ) ;
else $ ( "body" ) . removeClass ( "bd-minimal" ) ;
2017-10-30 22:33:38 +01:00
}
2018-11-10 06:00:53 +01:00
if ( id == "bda-gs-3" ) {
if ( enabled ) $ ( "body" ) . addClass ( "bd-minimal-chan" ) ;
else $ ( "body" ) . removeClass ( "bd-minimal-chan" ) ;
2017-10-30 22:33:38 +01:00
}
2018-11-10 06:00:53 +01:00
if ( id == "bda-gs-1" ) {
2019-06-19 04:28:48 +02:00
if ( enabled ) publicServersModule . addButton ( ) ;
else publicServersModule . removeButton ( ) ;
2017-10-30 22:33:38 +01:00
}
2018-11-10 06:00:53 +01:00
if ( id == "bda-gs-4" ) {
if ( enabled ) voiceMode . enable ( ) ;
else voiceMode . disable ( ) ;
2017-10-30 22:33:38 +01:00
}
2020-02-27 03:43:16 +01:00
if ( id == "bda-gs-5" ) {
if ( enabled ) $ ( "#app-mount" ) . addClass ( "bda-dark" ) ;
else $ ( "#app-mount" ) . removeClass ( "bda-dark" ) ;
}
2017-10-30 22:33:38 +01:00
2018-11-10 06:00:53 +01:00
if ( enabled && id == "bda-gs-6" ) mainCore . inject24Hour ( ) ;
2017-11-04 06:59:30 +01:00
2018-11-10 06:00:53 +01:00
if ( id == "bda-gs-7" ) {
if ( enabled ) mainCore . injectColoredText ( ) ;
else mainCore . removeColoredText ( ) ;
2018-08-05 07:01:33 +02:00
}
2018-11-10 06:00:53 +01:00
if ( id == "bda-es-4" ) {
if ( enabled ) emoteModule . autoCapitalize ( ) ;
else emoteModule . disableAutoCapitalize ( ) ;
2017-11-04 06:59:30 +01:00
}
2019-03-13 18:13:43 +01:00
2018-11-10 06:00:53 +01:00
if ( id == "fork-ps-4" ) {
if ( enabled ) ClassNormalizer . start ( ) ;
else ClassNormalizer . stop ( ) ;
2018-10-19 05:59:27 +02:00
}
2018-11-10 06:00:53 +01:00
if ( id == "fork-ps-5" ) {
if ( enabled ) {
ContentManager . watchContent ( "plugin" ) ;
ContentManager . watchContent ( "theme" ) ;
}
else {
ContentManager . unwatchContent ( "plugin" ) ;
ContentManager . unwatchContent ( "theme" ) ;
}
2018-10-19 05:59:27 +02:00
}
2018-10-19 08:27:02 +02:00
2018-11-10 06:00:53 +01:00
if ( id == "fork-wp-1" ) {
BdApi . setWindowPreference ( "transparent" , enabled ) ;
if ( enabled ) BdApi . setWindowPreference ( "backgroundColor" , null ) ;
2018-10-19 18:55:17 +02:00
else BdApi . setWindowPreference ( "backgroundColor" , "#2f3136" ) ;
2018-10-19 08:27:02 +02:00
}
2018-10-20 19:27:58 +02:00
/ * i f ( _ c [ " f o r k - w p - 2 " ] ) {
2018-10-19 08:27:02 +02:00
const current = BdApi . getWindowPreference ( "frame" ) ;
if ( current != _c [ "fork-wp-2" ] ) BdApi . setWindowPreference ( "frame" , _c [ "fork-wp-2" ] ) ;
2018-10-20 19:27:58 +02:00
} * /
2019-03-13 18:13:43 +01:00
2017-10-30 22:33:38 +01:00
2018-11-10 06:00:53 +01:00
if ( id == "bda-gs-8" ) {
if ( enabled ) dMode . enable ( settingsCookie [ "fork-dm-1" ] ) ;
else dMode . disable ( ) ;
2018-08-19 23:15:23 +02:00
}
2018-11-10 06:00:53 +01:00
2019-06-19 04:28:48 +02:00
if ( id == "fork-dm-1" ) {
if ( settingsCookie [ "bda-gs-8" ] ) dMode . enable ( enabled ) ;
}
2018-11-10 06:00:53 +01:00
mainCore . saveSettings ( ) ;
}
initializeSettings ( ) {
2020-02-08 01:02:58 +01:00
2019-05-22 07:20:54 +02:00
// if (settingsCookie["bda-gs-b"]) $("body").addClass("bd-blue");
2018-11-10 06:00:53 +01:00
if ( settingsCookie [ "bda-gs-2" ] ) $ ( "body" ) . addClass ( "bd-minimal" ) ;
if ( settingsCookie [ "bda-gs-3" ] ) $ ( "body" ) . addClass ( "bd-minimal-chan" ) ;
2019-06-19 04:28:48 +02:00
if ( settingsCookie [ "bda-gs-1" ] ) publicServersModule . addButton ( ) ;
2018-11-10 06:00:53 +01:00
if ( settingsCookie [ "bda-gs-4" ] ) voiceMode . enable ( ) ;
2020-02-27 03:43:16 +01:00
if ( settingsCookie [ "bda-gs-5" ] ) $ ( "#app-mount" ) . addClass ( "bda-dark" ) ;
2018-11-10 06:00:53 +01:00
if ( settingsCookie [ "bda-gs-6" ] ) mainCore . inject24Hour ( ) ;
if ( settingsCookie [ "bda-gs-7" ] ) mainCore . injectColoredText ( ) ;
if ( settingsCookie [ "bda-es-4" ] ) emoteModule . autoCapitalize ( ) ;
if ( settingsCookie [ "fork-ps-4" ] ) ClassNormalizer . start ( ) ;
if ( settingsCookie [ "fork-ps-5" ] ) {
ContentManager . watchContent ( "plugin" ) ;
ContentManager . watchContent ( "theme" ) ;
2017-10-30 22:33:38 +01:00
}
2018-11-10 06:00:53 +01:00
if ( settingsCookie [ "bda-gs-8" ] ) dMode . enable ( settingsCookie [ "fork-dm-1" ] ) ;
2017-10-30 22:33:38 +01:00
mainCore . saveSettings ( ) ;
2017-04-30 03:11:22 +02:00
}
renderSidebar ( ) {
let self = this ;
2018-08-19 23:15:23 +02:00
$ ( "[class*='side-'] > [class*='item-']" ) . off ( "click.v2settingspanel" ) . on ( "click.v2settingspanel" , ( ) => {
2017-04-30 03:11:22 +02:00
BDV2 . reactDom . unmountComponentAtNode ( self . root ) ;
$ ( self . root ) . hide ( ) ;
2018-10-20 21:35:20 +02:00
$ ( ".contentRegion-3nDuYy, .content-region" ) . first ( ) . show ( ) ;
2017-04-30 03:11:22 +02:00
} ) ;
self . sidebar . render ( ) ;
}
get coreComponent ( ) {
2019-05-25 06:43:09 +02:00
return BDV2 . react . createElement ( V2Components . Scroller , { contentColumn : true , fade : true , dark : true , children : [
BDV2 . react . createElement ( V2Components . SectionedSettingsPanel , { key : "cspanel" , onChange : this . onChange , sections : this . coreSettings } ) ,
BDV2 . react . createElement ( V2Components . Tools , { key : "tools" } )
] } ) ;
2017-12-24 07:51:24 +01:00
}
2017-04-30 03:11:22 +02:00
get emoteComponent ( ) {
2019-05-23 08:35:35 +02:00
return BDV2 . react . createElement ( V2Components . Scroller , {
contentColumn : true , fade : true , dark : true , children : [
BDV2 . react . createElement ( V2Components . SettingsPanel , { key : "espanel" , title : "Emote Settings" , onChange : this . onChange , settings : this . emoteSettings , button : {
title : "Clear Emote Cache" ,
onClick : ( ) => { emoteModule . clearEmoteData ( ) ; emoteModule . init ( ) ; quickEmoteMenu . init ( ) ; }
} } ) ,
BDV2 . react . createElement ( V2Components . Tools , { key : "tools" } )
] } ) ;
2017-04-30 03:11:22 +02:00
}
get customCssComponent ( ) {
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . Scroller , { contentColumn : true , fade : true , dark : true , children : [ BDV2 . react . createElement ( V2Components . CssEditor , { key : "csseditor" } ) , BDV2 . react . createElement ( V2Components . Tools , { key : "tools" } ) ] } ) ;
2017-04-30 03:11:22 +02:00
}
2018-10-28 21:28:13 +01:00
contentComponent ( type ) {
const componentElement = type == "plugins" ? this . pluginsComponent : this . themesComponent ;
const prefix = type . replace ( "s" , "" ) ;
const settingsList = this ;
class ContentList extends BDV2 . react . Component {
constructor ( props ) {
super ( props ) ;
this . onChange = this . onChange . bind ( this ) ;
}
componentDidMount ( ) {
BDEvents . on ( ` ${ prefix } -reloaded ` , this . onChange ) ;
BDEvents . on ( ` ${ prefix } -loaded ` , this . onChange ) ;
BDEvents . on ( ` ${ prefix } -unloaded ` , this . onChange ) ;
}
2019-03-13 18:13:43 +01:00
2018-10-28 21:28:13 +01:00
componentWillUnmount ( ) {
BDEvents . off ( ` ${ prefix } -reloaded ` , this . onChange ) ;
BDEvents . off ( ` ${ prefix } -loaded ` , this . onChange ) ;
BDEvents . off ( ` ${ prefix } -unloaded ` , this . onChange ) ;
}
2019-03-13 18:13:43 +01:00
2018-10-28 21:28:13 +01:00
onChange ( ) {
settingsList . sideBarOnClick ( type ) ;
}
render ( ) { return componentElement ; }
}
return BDV2 . react . createElement ( ContentList ) ;
}
2017-04-30 03:11:22 +02:00
get pluginsComponent ( ) {
2018-10-19 05:59:27 +02:00
let plugins = Object . keys ( bdplugins ) . sort ( ( a , b ) => a . toLowerCase ( ) . localeCompare ( b . toLowerCase ( ) ) ) . reduce ( ( arr , key ) => {
2018-08-19 23:15:23 +02:00
arr . push ( BDV2 . react . createElement ( V2Components . PluginCard , { key : key , plugin : bdplugins [ key ] . plugin } ) ) ; return arr ;
2017-04-30 03:11:22 +02:00
} , [ ] ) ;
2018-08-19 23:15:23 +02:00
let list = BDV2 . react . createElement ( V2Components . List , { key : "plugin-list" , className : "bda-slist" , children : plugins } ) ;
2018-10-19 05:59:27 +02:00
let refreshIcon = ! settingsCookie [ "fork-ps-5" ] && BDV2 . react . createElement ( V2Components . TooltipWrap ( V2Components . ReloadIcon , { color : "black" , side : "top" , text : "Reload Plugin List" } ) , { className : "bd-reload-header" , size : "18px" , onClick : async ( ) => {
pluginModule . updatePluginList ( ) ;
this . sideBarOnClick ( "plugins" ) ;
} } ) ;
let pfBtn = BDV2 . react . createElement ( "button" , { key : "folder-button" , className : "bd-pfbtn" , onClick : ( ) => { require ( "electron" ) . shell . openItem ( ContentManager . pluginsFolder ) ; } } , "Open Plugin Folder" ) ;
let contentColumn = BDV2 . react . createElement ( V2Components . ContentColumn , { key : "pcolumn" , title : "Plugins" , children : [ refreshIcon , pfBtn , list ] } ) ;
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . Scroller , { contentColumn : true , fade : true , dark : true , children : [ contentColumn , BDV2 . react . createElement ( V2Components . Tools , { key : "tools" } ) ] } ) ;
2017-04-30 03:11:22 +02:00
}
get themesComponent ( ) {
2018-10-19 05:59:27 +02:00
let themes = Object . keys ( bdthemes ) . sort ( ( a , b ) => a . toLowerCase ( ) . localeCompare ( b . toLowerCase ( ) ) ) . reduce ( ( arr , key ) => {
2018-08-19 23:15:23 +02:00
arr . push ( BDV2 . react . createElement ( V2Components . ThemeCard , { key : key , theme : bdthemes [ key ] } ) ) ; return arr ;
2017-04-30 03:11:22 +02:00
} , [ ] ) ;
2018-08-19 23:15:23 +02:00
let list = BDV2 . react . createElement ( V2Components . List , { key : "theme-list" , className : "bda-slist" , children : themes } ) ;
2018-10-19 05:59:27 +02:00
let refreshIcon = ! settingsCookie [ "fork-ps-5" ] && BDV2 . react . createElement ( V2Components . TooltipWrap ( V2Components . ReloadIcon , { color : "black" , side : "top" , text : "Reload Theme List" } ) , { className : "bd-reload-header" , size : "18px" , onClick : async ( ) => {
themeModule . updateThemeList ( ) ;
this . sideBarOnClick ( "themes" ) ;
} } ) ;
let tfBtn = BDV2 . react . createElement ( "button" , { key : "folder-button" , className : "bd-pfbtn" , onClick : ( ) => { require ( "electron" ) . shell . openItem ( ContentManager . themesFolder ) ; } } , "Open Theme Folder" ) ;
let contentColumn = BDV2 . react . createElement ( V2Components . ContentColumn , { key : "tcolumn" , title : "Themes" , children : [ refreshIcon , tfBtn , list ] } ) ;
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . Scroller , { contentColumn : true , fade : true , dark : true , children : [ contentColumn , BDV2 . react . createElement ( V2Components . Tools , { key : "tools" } ) ] } ) ;
2017-04-30 03:11:22 +02:00
}
renderCoreSettings ( ) {
let root = this . root ;
if ( ! root ) {
2018-10-20 09:23:31 +02:00
console . log ( "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i" ) ;
2017-04-30 03:11:22 +02:00
return ;
}
BDV2 . reactDom . render ( this . coreComponent , root ) ;
}
2019-03-13 18:13:43 +01:00
2017-04-30 03:11:22 +02:00
renderEmoteSettings ( ) {
let root = this . root ;
if ( ! root ) {
2018-10-20 09:23:31 +02:00
console . log ( "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i" ) ;
2017-04-30 03:11:22 +02:00
return ;
}
BDV2 . reactDom . render ( this . emoteComponent , root ) ;
}
renderCustomCssEditor ( ) {
let root = this . root ;
if ( ! root ) {
2018-10-20 09:23:31 +02:00
console . log ( "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i" ) ;
2017-04-30 03:11:22 +02:00
return ;
}
BDV2 . reactDom . render ( this . customCssComponent , root ) ;
}
renderPluginPane ( ) {
let root = this . root ;
if ( ! root ) {
2018-10-20 09:23:31 +02:00
console . log ( "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i" ) ;
2017-04-30 03:11:22 +02:00
return ;
}
2018-10-28 21:28:13 +01:00
BDV2 . reactDom . render ( this . contentComponent ( "plugins" ) , root ) ;
2017-04-30 03:11:22 +02:00
}
renderThemePane ( ) {
let root = this . root ;
if ( ! root ) {
2018-10-20 09:23:31 +02:00
console . log ( "FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i" ) ;
2017-04-30 03:11:22 +02:00
return ;
}
2018-10-28 21:28:13 +01:00
BDV2 . reactDom . render ( this . contentComponent ( "themes" ) , root ) ;
2017-04-30 03:11:22 +02:00
}
}
2018-01-09 04:24:00 +01:00
class V2C _Layer extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
componentDidMount ( ) {
$ ( window ) . on ( ` keyup. ${ this . props . id } ` , e => {
if ( e . which === 27 ) {
BDV2 . reactDom . unmountComponentAtNode ( this . refs . root . parentNode ) ;
}
} ) ;
2018-03-29 09:56:07 +02:00
$ ( ` # ${ this . props . id } ` ) . animate ( { opacity : 1 } , {
2018-08-19 23:15:23 +02:00
step : function ( now ) {
2019-03-13 18:13:43 +01:00
$ ( this ) . css ( "transform" , ` scale( ${ 1.1 - 0.1 * now } ) translateZ(0px) ` ) ;
2018-03-29 09:56:07 +02:00
} ,
duration : 200 ,
done : ( ) => { $ ( ` # ${ this . props . id } ` ) . css ( "opacity" , "" ) . css ( "transform" , "" ) ; }
} ) ;
2018-01-09 04:24:00 +01:00
}
componentWillUnmount ( ) {
$ ( window ) . off ( ` keyup. ${ this . props . id } ` ) ;
2018-03-29 09:56:07 +02:00
$ ( ` # ${ this . props . id } ` ) . animate ( { opacity : 0 } , {
2018-08-19 23:15:23 +02:00
step : function ( now ) {
2019-03-13 18:13:43 +01:00
$ ( this ) . css ( "transform" , ` scale( ${ 1.1 - 0.1 * now } ) translateZ(0px) ` ) ;
2018-03-29 09:56:07 +02:00
} ,
duration : 200 ,
done : ( ) => { $ ( ` # ${ this . props . rootId } ` ) . remove ( ) ; }
} ) ;
2019-03-13 18:13:43 +01:00
2018-08-19 23:15:23 +02:00
$ ( "[class*=\"layer-\"]" ) . removeClass ( "publicServersOpen" ) . animate ( { opacity : 1 } , {
step : function ( now ) {
2019-03-13 18:13:43 +01:00
$ ( this ) . css ( "transform" , ` scale( ${ 0.07 * now + 0.93 } ) translateZ(0px) ` ) ;
2018-03-29 09:56:07 +02:00
} ,
duration : 200 ,
2018-08-19 23:15:23 +02:00
done : ( ) => { $ ( "[class*=\"layer-\"]" ) . css ( "opacity" , "" ) . css ( "transform" , "" ) ; }
2018-03-29 09:56:07 +02:00
} ) ;
2019-03-13 18:13:43 +01:00
2018-03-29 09:56:07 +02:00
}
componentWillMount ( ) {
2018-08-19 23:15:23 +02:00
$ ( "[class*=\"layer-\"]" ) . addClass ( "publicServersOpen" ) . animate ( { opacity : 0 } , {
step : function ( now ) {
2019-03-13 18:13:43 +01:00
$ ( this ) . css ( "transform" , ` scale( ${ 0.07 * now + 0.93 } ) translateZ(0px) ` ) ;
2018-03-29 09:56:07 +02:00
} ,
duration : 200
} ) ;
2018-01-09 04:24:00 +01:00
}
render ( ) {
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "layer bd-layer layer-3QrUeG" , id : this . props . id , ref : "root" , style : { opacity : 0 , transform : "scale(1.1) translateZ(0px)" } } ,
2018-01-09 04:24:00 +01:00
this . props . children
) ;
}
}
class V2C _SidebarView extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
}
render ( ) {
2018-08-19 23:15:23 +02:00
let { sidebar , content , tools } = this . props . children ;
2018-01-09 04:24:00 +01:00
return BDV2 . react . createElement (
"div" ,
2018-10-20 21:35:20 +02:00
{ className : "standardSidebarView-3F1I7i ui-standard-sidebar-view" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-10-20 21:35:20 +02:00
{ className : "sidebarRegion-VFTUkN sidebar-region" } ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( V2Components . Scroller , { key : "sidebarScroller" , ref : "sidebarScroller" , sidebar : true , fade : sidebar . fade || true , dark : sidebar . dark || true , children : sidebar . component } )
2018-01-09 04:24:00 +01:00
) ,
2018-10-20 21:35:20 +02:00
BDV2 . react . createElement ( "div" , { className : "contentRegion-3nDuYy content-region" } ,
BDV2 . react . createElement ( "div" , { className : "contentTransitionWrap-3hqOEW content-transition-wrap" } ,
BDV2 . react . createElement ( "div" , { className : "scrollerWrap-2lJEkd firefoxFixScrollFlex-cnI2ix contentRegionScrollerWrap-3YZXdm content-region-scroller-wrap scrollerThemed-2oenus themeGhost-28MSn0 scrollerTrack-1ZIpsv" } ,
BDV2 . react . createElement ( "div" , { className : "scroller-2FKFPG firefoxFixScrollFlex-cnI2ix contentRegionScroller-26nc1e content-region-scroller scroller" , ref : "contentScroller" } ,
BDV2 . react . createElement ( "div" , { className : "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default" } , content . component ) ,
2018-01-09 04:24:00 +01:00
tools . component
)
)
)
)
) ;
}
}
class V2 _PublicServers {
2019-06-19 04:28:48 +02:00
constructor ( ) {
this . _appendButton = this . _appendButton . bind ( this ) ;
}
2018-01-09 04:24:00 +01:00
get component ( ) {
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . Layer , { rootId : "pubslayerroot" , id : "pubslayer" , children : BDV2 . react . createElement ( V2C _PublicServers , { rootId : "pubslayerroot" } ) } ) ;
2018-01-09 04:24:00 +01:00
}
get root ( ) {
let _root = document . getElementById ( "pubslayerroot" ) ;
if ( ! _root ) {
if ( ! this . injectRoot ( ) ) return null ;
return this . root ;
}
return _root ;
}
injectRoot ( ) {
2018-05-05 15:45:34 +02:00
if ( ! $ ( ".layers, .layers-3iHuyZ" ) . length ) return false ;
$ ( ".layers, .layers-3iHuyZ" ) . append ( $ ( "<div/>" , {
2018-08-19 23:15:23 +02:00
id : "pubslayerroot"
2018-01-09 04:24:00 +01:00
} ) ) ;
return true ;
}
render ( ) {
2019-05-22 07:20:54 +02:00
// BdApi.alert("Broken", "Sorry but the Public Servers modules is currently broken, I recommend disabling this feature for now.");
let root = this . root ;
if ( ! root ) {
console . log ( "FAILED TO LOCATE ROOT: .layers" ) ;
return ;
}
BDV2 . reactDom . render ( this . component , root ) ;
2018-01-09 04:24:00 +01:00
}
get button ( ) {
let btn = $ ( "<div/>" , {
2019-05-22 07:20:54 +02:00
"class" : BDV2 . guildClasses . listItem ,
2019-05-23 19:59:23 +02:00
"id" : "bd-pub-li" ,
"style" : settingsCookie [ "bda-gs-1" ] ? "" : "display: none;"
2018-01-09 04:24:00 +01:00
} ) . append ( $ ( "<div/>" , {
2019-05-22 07:20:54 +02:00
"class" : "wrapper-25eVIn " + BDV2 . guildClasses . circleButtonMask ,
"text" : "public" ,
"id" : "bd-pub-button" ,
"click" : ( ) => { this . render ( ) ; }
} ) ) ;
2018-01-09 04:24:00 +01:00
return btn ;
}
2019-06-19 04:28:48 +02:00
_appendButton ( ) {
if ( $ ( "#bd-pub-li" ) . length ) return ;
2019-04-21 17:14:03 +02:00
const wrapper = BDV2 . guildClasses . wrapper . split ( " " ) [ 0 ] ;
2019-04-21 16:31:45 +02:00
const guilds = $ ( ` . ${ wrapper } .scroller-2FKFPG >:first-child ` ) ;
2018-01-09 04:24:00 +01:00
guilds . after ( this . button ) ;
2018-08-19 23:15:23 +02:00
}
2019-06-19 04:28:48 +02:00
addButton ( ) {
if ( this . guildPatch ) return ;
const GuildList = BdApi . findModuleByDisplayName ( "Guilds" ) ;
this . guildPatch = BdApi . monkeyPatch ( GuildList . prototype , "render" , { after : this . _appendButton } ) ;
this . _appendButton ( ) ;
}
removeButton ( ) {
this . guildPatch ( ) ;
delete this . guildPatch ;
$ ( "#bd-pub-li" ) . remove ( ) ;
}
2018-01-09 04:24:00 +01:00
}
class V2C _ServerCard extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
2018-03-29 09:56:07 +02:00
if ( ! this . props . server . iconUrl ) this . props . server . iconUrl = this . props . fallback ;
2018-01-09 04:24:00 +01:00
this . state = {
imageError : false ,
joined : this . props . guildList . includes ( this . props . server . identifier )
} ;
}
render ( ) {
2018-08-19 23:15:23 +02:00
let { server } = this . props ;
2018-01-09 04:24:00 +01:00
return BDV2 . react . createElement (
2018-05-05 15:45:34 +02:00
"div" , // cardPrimary-1Hv-to
2018-08-19 23:15:23 +02:00
{ className : ` card-3Qj_Yx cardPrimary-1Hv-to marginBottom8-AtZOdT bd-server-card ${ server . pinned ? " bd-server-card-pinned" : "" } ` } ,
2018-03-29 09:56:07 +02:00
// BDV2.react.createElement(
// "div",
2018-05-05 15:45:34 +02:00
// { className: "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY flex-1O1GKY directionRow-3v3tfG justifyStart-2yIZo0 alignStretch-1hwxMa noWrap-3jynv6" },
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( "img" , { ref : "img" , className : "bd-server-image" , src : server . iconUrl , onError : this . handleError . bind ( this ) } ) ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "flexChild-faoVW3 bd-server-content" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6 bd-server-header" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
2018-03-29 09:56:07 +02:00
"h5" ,
2018-08-19 23:15:23 +02:00
{ className : "h5-18_1nd defaultColor-1_ajX0 margin-reset bd-server-name" } ,
2018-03-29 09:56:07 +02:00
server . name
2018-01-09 04:24:00 +01:00
) ,
BDV2 . react . createElement (
2018-03-29 09:56:07 +02:00
"h5" ,
2018-08-19 23:15:23 +02:00
{ className : "h5-18_1nd defaultColor-1_ajX0 margin-reset bd-server-member-count" } ,
2018-03-29 09:56:07 +02:00
server . members ,
" Members"
2018-01-09 04:24:00 +01:00
)
) ,
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "scrollerWrap-2lJEkd scrollerThemed-2oenus themeGhostHairline-DBD-2d scrollerFade-1Ijw5y bd-server-description-container" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "scroller-2FKFPG scroller bd-server-description" } ,
2018-01-09 04:24:00 +01:00
server . description
)
)
) ,
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6 bd-server-footer" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "flexChild-faoVW3 bd-server-tags" , style : { flex : "1 1 auto" } } ,
server . categories . join ( ", " )
2018-01-09 04:24:00 +01:00
) ,
this . state . joined && BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ type : "button" , className : "button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN colorGreen-29iAKY" , style : { minHeight : "12px" , marginTop : "4px" , backgroundColor : "#3ac15c" } } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-button-contents" } ,
2018-01-09 04:24:00 +01:00
"Joined"
)
) ,
server . error && BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ type : "button" , className : "button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN disabled-9aF2ug" , style : { minHeight : "12px" , marginTop : "4px" , backgroundColor : "#c13a3a" } } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-button-contents" } ,
2018-01-09 04:24:00 +01:00
"Error"
)
) ,
2018-03-29 09:56:07 +02:00
! server . error && ! this . state . joined && BDV2 . react . createElement (
2018-01-09 04:24:00 +01:00
"button" ,
2018-08-19 23:15:23 +02:00
{ type : "button" , className : "button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN" , style : { minHeight : "12px" , marginTop : "4px" } , onClick : ( ) => { this . join ( ) ; } } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-button-contents" } ,
2018-01-09 04:24:00 +01:00
"Join"
)
)
)
)
2018-03-29 09:56:07 +02:00
// )
2018-01-09 04:24:00 +01:00
) ;
}
handleError ( ) {
2018-03-29 09:56:07 +02:00
this . props . server . iconUrl = this . props . fallback ;
2018-01-09 04:24:00 +01:00
this . setState ( { imageError : true } ) ;
}
join ( ) {
2018-03-29 09:56:07 +02:00
this . props . join ( this ) ;
//this.setState({joined: true});
2018-01-09 04:24:00 +01:00
}
}
class V2C _PublicServers extends BDV2 . reactComponent {
constructor ( props ) {
super ( props ) ;
this . setInitialState ( ) ;
this . close = this . close . bind ( this ) ;
this . changeCategory = this . changeCategory . bind ( this ) ;
this . search = this . search . bind ( this ) ;
this . searchKeyDown = this . searchKeyDown . bind ( this ) ;
this . checkConnection = this . checkConnection . bind ( this ) ;
this . join = this . join . bind ( this ) ;
2018-03-29 09:56:07 +02:00
this . connect = this . connect . bind ( this ) ;
2018-01-09 04:24:00 +01:00
this . GuildStore = BDV2 . WebpackModules . findByUniqueProperties ( [ "getGuilds" ] ) ;
this . AvatarDefaults = BDV2 . WebpackModules . findByUniqueProperties ( [ "getUserAvatarURL" , "DEFAULT_AVATARS" ] ) ;
2018-08-19 23:15:23 +02:00
this . InviteActions = BDV2 . WebpackModules . findByUniqueProperties ( [ "acceptInvite" ] ) ;
this . SortedGuildStore = BDV2 . WebpackModules . findByUniqueProperties ( [ "getSortedGuilds" ] ) ;
2018-01-09 04:24:00 +01:00
}
componentDidMount ( ) {
this . checkConnection ( ) ;
2018-06-28 02:34:02 +02:00
}
2018-01-09 04:24:00 +01:00
setInitialState ( ) {
this . state = {
2018-08-19 23:15:23 +02:00
selectedCategory : - 1 ,
title : "Loading..." ,
loading : true ,
servers : [ ] ,
next : null ,
connection : {
state : 0 ,
user : null
2018-01-09 04:24:00 +01:00
}
} ;
}
close ( ) {
BDV2 . reactDom . unmountComponentAtNode ( document . getElementById ( this . props . rootId ) ) ;
}
search ( query , clear ) {
let self = this ;
$ . ajax ( {
2018-08-19 23:15:23 +02:00
method : "GET" ,
2018-03-29 09:56:07 +02:00
url : ` ${ self . endPoint } ${ query } ${ query ? "&schema=new" : "?schema=new" } ` ,
2018-01-09 04:24:00 +01:00
success : data => {
let servers = data . results . reduce ( ( arr , server ) => {
server . joined = false ;
arr . push ( server ) ;
// arr.push(<V2Components.ServerCard server={server} join={self.join}/>);
return arr ;
} , [ ] ) ;
if ( ! clear ) {
servers = self . state . servers . concat ( servers ) ;
2018-08-19 23:15:23 +02:00
}
else {
2018-01-09 04:24:00 +01:00
//servers.unshift(self.bdServer);
}
let end = data . size + data . from ;
2018-03-29 09:56:07 +02:00
data . next = ` ?from= ${ end } ` ;
if ( self . state . term ) data . next += ` &term= ${ self . state . term } ` ;
if ( self . state . selectedCategory ) data . next += ` &category= ${ self . categoryButtons [ self . state . selectedCategory ] } ` ;
2018-01-09 04:24:00 +01:00
if ( end >= data . total ) {
end = data . total ;
data . next = null ;
}
let title = ` Showing 1- ${ end } of ${ data . total } results in ${ self . categoryButtons [ self . state . selectedCategory ] } ` ;
if ( self . state . term ) title += ` for ${ self . state . term } ` ;
self . setState ( {
2018-08-19 23:15:23 +02:00
loading : false ,
title : title ,
servers : servers ,
next : data . next
2018-01-09 04:24:00 +01:00
} ) ;
if ( clear ) {
2018-08-19 23:15:23 +02:00
//console.log(self);
2018-02-28 08:25:06 +01:00
self . refs . sbv . refs . contentScroller . scrollTop = 0 ;
2018-01-09 04:24:00 +01:00
}
} ,
2018-08-19 23:15:23 +02:00
error : ( ) => {
2018-01-09 04:24:00 +01:00
self . setState ( {
2018-08-19 23:15:23 +02:00
loading : false ,
title : "Failed to load servers. Check console for details"
2018-01-09 04:24:00 +01:00
} ) ;
}
} ) ;
}
2018-03-29 09:56:07 +02:00
join ( serverCard ) {
if ( serverCard . props . pinned ) return this . InviteActions . acceptInvite ( serverCard . props . invite _code ) ;
$ . ajax ( {
2018-08-19 23:15:23 +02:00
method : "GET" ,
2018-03-29 09:56:07 +02:00
url : ` ${ this . joinEndPoint } / ${ serverCard . props . server . identifier } ` ,
2019-03-13 18:13:43 +01:00
headers : {
"Accept" : "application/json;" ,
2018-03-29 09:56:07 +02:00
"Content-Type" : "application/json;" ,
"x-discord-token" : this . state . connection . user . accessToken
} ,
crossDomain : true ,
xhrFields : {
withCredentials : true
} ,
2018-08-19 23:15:23 +02:00
success : ( ) => {
2018-03-29 09:56:07 +02:00
serverCard . setState ( { joined : true } ) ;
}
} ) ;
}
connect ( ) {
let self = this ;
let options = self . windowOptions ;
options . x = Math . round ( window . screenX + window . innerWidth / 2 - options . width / 2 ) ;
options . y = Math . round ( window . screenY + window . innerHeight / 2 - options . height / 2 ) ;
2018-08-19 23:15:23 +02:00
self . joinWindow = new ( window . require ( "electron" ) . remote . BrowserWindow ) ( options ) ;
2019-05-22 07:20:54 +02:00
const url = "https://auth.discordservers.com/connect?scopes=guilds.join&previousUrl=https://auth.discordservers.com/info" ;
2018-08-19 23:15:23 +02:00
self . joinWindow . webContents . on ( "did-navigate" , ( event , url ) => {
2019-05-22 07:20:54 +02:00
if ( url != "https://auth.discordservers.com/info" ) return ;
2018-03-29 09:56:07 +02:00
self . joinWindow . close ( ) ;
self . checkConnection ( ) ;
} ) ;
self . joinWindow . loadURL ( url ) ;
}
get windowOptions ( ) {
return {
width : 500 ,
height : 550 ,
2018-08-19 23:15:23 +02:00
backgroundColor : "#282b30" ,
2018-03-29 09:56:07 +02:00
show : true ,
resizable : false ,
maximizable : false ,
minimizable : false ,
alwaysOnTop : true ,
frame : false ,
2019-05-22 07:20:54 +02:00
center : false ,
webPreferences : {
nodeIntegration : false
}
2018-03-29 09:56:07 +02:00
} ;
}
2018-01-09 04:24:00 +01:00
get bdServer ( ) {
let server = {
2018-08-19 23:15:23 +02:00
name : "BetterDiscord" ,
online : "7500+" ,
members : "20000+" ,
categories : [ "community" , "programming" , "support" ] ,
description : "Official BetterDiscord server for support etc" ,
identifier : "86004744966914048" ,
iconUrl : "https://cdn.discordapp.com/icons/86004744966914048/292e7f6bfff2b71dfd13e508a859aedd.webp" ,
nativejoin : true ,
invite _code : "0Tmfo5ZbORCRqbAd" ,
pinned : true
2018-01-09 04:24:00 +01:00
} ;
2019-08-26 07:31:47 +02:00
let guildList = this . SortedGuildStore . getFlattenedGuildIds ( ) ;
2018-01-09 04:24:00 +01:00
let defaultList = this . AvatarDefaults . DEFAULT _AVATARS ;
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . ServerCard , { server : server , pinned : true , join : this . join , guildList : guildList , fallback : defaultList [ Math . floor ( Math . random ( ) * 5 ) ] } ) ;
2018-01-09 04:24:00 +01:00
}
get endPoint ( ) {
2018-08-19 23:15:23 +02:00
return "https://search.discordservers.com" ;
2018-01-09 04:24:00 +01:00
}
get joinEndPoint ( ) {
2019-05-22 07:20:54 +02:00
return "https://j.discordservers.com" ;
2018-01-09 04:24:00 +01:00
}
get connectEndPoint ( ) {
2018-08-19 23:15:23 +02:00
return "https://join.discordservers.com/connect" ;
2018-01-09 04:24:00 +01:00
}
checkConnection ( ) {
let self = this ;
try {
$ . ajax ( {
2018-08-19 23:15:23 +02:00
method : "GET" ,
2019-05-22 07:20:54 +02:00
url : ` https://auth.discordservers.com/info ` ,
2019-03-13 18:13:43 +01:00
headers : {
"Accept" : "application/json;" ,
"Content-Type" : "application/json;"
2018-03-29 09:56:07 +02:00
} ,
crossDomain : true ,
xhrFields : {
withCredentials : true
} ,
2018-01-09 04:24:00 +01:00
success : data => {
2019-05-24 22:11:17 +02:00
// Utils.log("PublicServer", "Got data: " + JSON.stringify(data));
2018-01-09 04:24:00 +01:00
self . setState ( {
2018-08-19 23:15:23 +02:00
selectedCategory : 0 ,
connection : {
state : 2 ,
user : data
2018-01-09 04:24:00 +01:00
}
} ) ;
self . search ( "" , true ) ;
2019-03-13 18:13:43 +01:00
2018-01-09 04:24:00 +01:00
} ,
2019-05-25 06:43:09 +02:00
error : ( ) => {
self . setState ( {
title : "Not connected to discordservers.com!" ,
loading : true ,
selectedCategory : - 1 ,
connection : {
state : 1 ,
user : null
}
} ) ;
2018-01-09 04:24:00 +01:00
}
} ) ;
}
2018-08-19 23:15:23 +02:00
catch ( error ) {
2018-01-09 04:24:00 +01:00
self . setState ( {
2018-08-19 23:15:23 +02:00
title : "Not connected to discordservers.com!" ,
loading : true ,
selectedCategory : - 1 ,
connection : {
state : 1 ,
user : null
2018-01-09 04:24:00 +01:00
}
} ) ;
}
}
render ( ) {
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . SidebarView , { ref : "sbv" , children : this . component } ) ;
2018-01-09 04:24:00 +01:00
}
get component ( ) {
return {
2018-08-19 23:15:23 +02:00
sidebar : {
component : this . sidebar
2018-01-09 04:24:00 +01:00
} ,
2018-08-19 23:15:23 +02:00
content : {
component : this . content
2018-01-09 04:24:00 +01:00
} ,
2018-08-19 23:15:23 +02:00
tools : {
component : BDV2 . react . createElement ( V2Components . Tools , { key : "pt" , ref : "tools" , onClick : this . close } )
2018-01-09 04:24:00 +01:00
}
} ;
}
get sidebar ( ) {
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "sidebar" , key : "ps" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-tab-bar SIDE" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-tab-bar-header" , style : { fontSize : "16px" } } ,
2018-01-09 04:24:00 +01:00
"Public Servers"
) ,
BDV2 . react . createElement ( V2Components . TabBar . Separator , null ) ,
this . searchInput ,
BDV2 . react . createElement ( V2Components . TabBar . Separator , null ) ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( V2Components . TabBar . Header , { text : "Categories" } ) ,
2018-01-09 04:24:00 +01:00
this . categoryButtons . map ( ( value , index ) => {
2018-08-19 23:15:23 +02:00
return BDV2 . react . createElement ( V2Components . TabBar . Item , { id : index , onClick : this . changeCategory , key : index , text : value , selected : this . state . selectedCategory === index } ) ;
2018-01-09 04:24:00 +01:00
} ) ,
BDV2 . react . createElement ( V2Components . TabBar . Separator , null ) ,
2018-03-29 09:56:07 +02:00
this . footer ,
this . connection
2018-01-09 04:24:00 +01:00
)
) ;
}
get searchInput ( ) {
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-form-item" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-text-input flex-vertical" , style : { width : "172px" , marginLeft : "10px" } } ,
BDV2 . react . createElement ( "input" , { ref : "searchinput" , onKeyDown : this . searchKeyDown , onChange : ( ) => { } , type : "text" , className : "input default" , placeholder : "Search..." , maxLength : "50" } )
2018-01-09 04:24:00 +01:00
)
) ;
}
searchKeyDown ( e ) {
let self = this ;
if ( self . state . loading || e . which !== 13 ) return ;
self . setState ( {
2018-08-19 23:15:23 +02:00
loading : true ,
title : "Loading..." ,
term : e . target . value
2018-01-09 04:24:00 +01:00
} ) ;
let query = ` ?term= ${ e . target . value } ` ;
if ( self . state . selectedCategory !== 0 ) {
query += ` &category= ${ self . categoryButtons [ self . state . selectedCategory ] } ` ;
}
self . search ( query , true ) ;
}
get categoryButtons ( ) {
2019-05-22 07:20:54 +02:00
return [ "All" , "FPS Games" , "MMO Games" , "Strategy Games" , "MOBA Games" , "RPG Games" , "Tabletop Games" , "Sandbox Games" , "Simulation Games" , "Music" , "Community" , "Language" , "Programming" , "Other" ] ;
2018-01-09 04:24:00 +01:00
}
changeCategory ( id ) {
let self = this ;
if ( self . state . loading ) return ;
self . refs . searchinput . value = "" ;
self . setState ( {
2018-08-19 23:15:23 +02:00
loading : true ,
selectedCategory : id ,
title : "Loading..." ,
term : null
2018-01-09 04:24:00 +01:00
} ) ;
if ( id === 0 ) {
self . search ( "" , true ) ;
return ;
}
self . search ( ` ?category= ${ self . categoryButtons [ id ] } ` , true ) ;
}
get content ( ) {
let self = this ;
2019-08-26 07:31:47 +02:00
let guildList = this . SortedGuildStore . getFlattenedGuildIds ( ) ;
2018-01-09 04:24:00 +01:00
let defaultList = this . AvatarDefaults . DEFAULT _AVATARS ;
if ( self . state . connection . state === 1 ) return self . notConnected ;
return [ BDV2 . react . createElement (
"div" ,
2018-10-20 21:35:20 +02:00
{ ref : "content" , key : "pc" , className : "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default" } ,
2018-08-19 23:15:23 +02:00
BDV2 . react . createElement ( V2Components . SettingsTitle , { text : self . state . title } ) ,
2018-01-09 04:24:00 +01:00
self . bdServer ,
2018-08-19 23:15:23 +02:00
self . state . servers . map ( ( server ) => {
return BDV2 . react . createElement ( V2Components . ServerCard , { key : server . identifier , server : server , join : self . join , guildList : guildList , fallback : defaultList [ Math . floor ( Math . random ( ) * 5 ) ] } ) ;
2018-01-09 04:24:00 +01:00
} ) ,
self . state . next && BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ type : "button" , onClick : ( ) => {
if ( self . state . loading ) return ; self . setState ( { loading : true } ) ; self . search ( self . state . next , false ) ;
} , className : "ui-button filled brand small grow" , style : { width : "100%" , marginTop : "10px" , marginBottom : "10px" } } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-button-contents" } ,
self . state . loading ? "Loading" : "Load More"
2018-01-09 04:24:00 +01:00
)
) ,
2018-08-19 23:15:23 +02:00
self . state . servers . length > 0 && BDV2 . react . createElement ( V2Components . SettingsTitle , { text : self . state . title } )
2018-01-09 04:24:00 +01:00
) ] ;
}
2018-03-29 09:56:07 +02:00
get notConnected ( ) {
let self = this ;
//return BDV2.react.createElement(V2Components.SettingsTitle, { text: self.state.title });
return [ BDV2 . react . createElement (
"div" ,
2018-10-20 21:35:20 +02:00
{ key : "ncc" , ref : "content" , className : "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default" } ,
2018-03-29 09:56:07 +02:00
BDV2 . react . createElement (
"h2" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-form-title h2 margin-reset margin-bottom-20" } ,
2018-03-29 09:56:07 +02:00
"Not connected to discordservers.com!" ,
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{
onClick : self . connect ,
type : "button" ,
className : "ui-button filled brand small grow" ,
style : {
display : "inline-block" ,
minHeight : "18px" ,
marginLeft : "10px" ,
lineHeight : "14px"
}
} ,
2018-03-29 09:56:07 +02:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-button-contents" } ,
2018-03-29 09:56:07 +02:00
"Connect"
)
)
) , self . bdServer
) ] ;
}
2018-01-09 04:24:00 +01:00
get footer ( ) {
return BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-tab-bar-header" } ,
2018-01-09 04:24:00 +01:00
BDV2 . react . createElement (
"a" ,
2018-08-19 23:15:23 +02:00
{ href : "https://discordservers.com" , target : "_blank" } ,
2018-01-09 04:24:00 +01:00
"Discordservers.com"
)
) ;
}
2018-03-29 09:56:07 +02:00
get connection ( ) {
let self = this ;
2018-08-19 23:15:23 +02:00
let { connection } = self . state ;
2018-03-29 09:56:07 +02:00
if ( connection . state !== 2 ) return BDV2 . react . createElement ( "span" , null ) ;
return BDV2 . react . createElement (
"span" ,
null ,
BDV2 . react . createElement ( V2Components . TabBar . Separator , null ) ,
BDV2 . react . createElement (
"span" ,
2018-08-19 23:15:23 +02:00
{ style : { color : "#b9bbbe" , fontSize : "10px" , marginLeft : "10px" } } ,
2018-03-29 09:56:07 +02:00
"Connected as: " ,
` ${ connection . user . username } # ${ connection . user . discriminator } `
) ,
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ style : { padding : "5px 10px 0 10px" } } ,
2018-03-29 09:56:07 +02:00
BDV2 . react . createElement (
"button" ,
2018-08-19 23:15:23 +02:00
{ style : { width : "100%" , minHeight : "20px" } , type : "button" , className : "ui-button filled brand small grow" } ,
2018-03-29 09:56:07 +02:00
BDV2 . react . createElement (
"div" ,
2018-08-19 23:15:23 +02:00
{ className : "ui-button-contents" , onClick : self . connect } ,
2018-03-29 09:56:07 +02:00
"Reconnect"
)
)
)
) ;
}
2019-03-13 18:13:43 +01:00
}