2020-03-29 11:17:12 +02:00
import { bdConfig , minSupportedVersion , bbdVersion , settingsCookie , bdpluginErrors , bdthemeErrors , bbdChangelog , defaultCookie , currentDiscordVersion } from "../0globals" ;
2020-02-27 08:01:51 +01:00
import Utils from "./utils" ;
import emoteModule from "./emoteModule" ;
import quickEmoteMenu from "./quickEmoteMenu" ;
2020-03-29 11:17:12 +02:00
2020-02-27 08:01:51 +01:00
import BDV2 from "./v2" ;
import settingsPanel from "./settingsPanel" ;
import pluginModule from "./pluginModule" ;
import themeModule from "./themeModule" ;
import DataStore from "./dataStore" ;
import WebpackModules from "./webpackModules" ;
2020-03-29 11:17:12 +02:00
import DOM from "./domtools" ;
2020-02-27 08:01:51 +01:00
2020-03-25 05:19:02 +01:00
import BDLogo from "../ui/bdLogo" ;
2020-03-28 03:44:59 +01:00
import TooltipWrap from "../ui/tooltipWrap" ;
2020-02-27 08:01:51 +01:00
2020-03-28 03:44:59 +01:00
function Core ( ) { }
Core . prototype . setConfig = function ( config ) {
2020-02-27 08:01:51 +01:00
Object . assign ( bdConfig , config ) ;
2020-03-28 03:44:59 +01:00
} ;
2020-02-27 08:01:51 +01:00
Core . prototype . init = async function ( ) {
2020-03-29 11:17:12 +02:00
if ( ! Array . prototype . flat ) {
Utils . alert ( "Not Supported" , "BetterDiscord v" + bbdVersion + " does not support this old version (" + currentDiscordVersion + ") of Discord. Please update your Discord installation before proceeding." ) ;
return ;
}
2020-03-28 03:44:59 +01:00
2020-02-27 08:01:51 +01:00
if ( bdConfig . version < minSupportedVersion ) {
Utils . 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>" ) ;
return ;
}
if ( window . ED ) {
Utils . 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" ) ) {
Utils . alert ( "Not Supported" , "BandagedBD does not work with Powercord. Please uninstall one of them." ) ;
return ;
}
const latestLocalVersion = bdConfig . updater ? bdConfig . updater . LatestVersion : bdConfig . latestVersion ;
if ( latestLocalVersion > bdConfig . version ) {
Utils . alert ( "Update Available" , `
An update for BandagedBD is available ( $ { latestLocalVersion } ) ! Please Reinstall ! < br / > < br / >
< a href = 'https://github.com/rauenzi/BetterDiscordApp/releases/latest' target = '_blank' > Download Installer < / a >
` );
}
Utils . log ( "Startup" , "Initializing Settings" ) ;
this . initSettings ( ) ;
Utils . log ( "Startup" , "Initializing EmoteModule" ) ;
window . emotePromise = emoteModule . init ( ) . then ( ( ) => {
emoteModule . initialized = true ;
Utils . log ( "Startup" , "Initializing QuickEmoteMenu" ) ;
quickEmoteMenu . init ( ) ;
} ) ;
this . injectExternals ( ) ;
await this . checkForGuilds ( ) ;
BDV2 . initialize ( ) ;
Utils . log ( "Startup" , "Updating Settings" ) ;
settingsPanel . initializeSettings ( ) ;
Utils . log ( "Startup" , "Loading Plugins" ) ;
pluginModule . loadPlugins ( ) ;
Utils . log ( "Startup" , "Loading Themes" ) ;
themeModule . loadThemes ( ) ;
2020-03-29 11:17:12 +02:00
DOM . addStyle ( "customcss" , atob ( DataStore . getBDData ( "bdcustomcss" ) ) ) ;
2020-02-27 08:01:51 +01:00
window . addEventListener ( "beforeunload" , function ( ) {
if ( settingsCookie [ "bda-dc-0" ] ) document . querySelector ( ".btn.btn-disconnect" ) . click ( ) ;
} ) ;
Utils . log ( "Startup" , "Removing Loading Icon" ) ;
if ( document . getElementsByClassName ( "bd-loaderv2" ) . length ) document . getElementsByClassName ( "bd-loaderv2" ) [ 0 ] . remove ( ) ;
Utils . log ( "Startup" , "Initializing Main Observer" ) ;
this . initObserver ( ) ;
// Show loading errors
if ( settingsCookie [ "fork-ps-1" ] ) {
Utils . log ( "Startup" , "Collecting Startup Errors" ) ;
Utils . showContentErrors ( { plugins : bdpluginErrors , themes : bdthemeErrors } ) ;
}
const previousVersion = DataStore . getBDData ( "version" ) ;
if ( bbdVersion > previousVersion ) {
if ( bbdChangelog ) this . showChangelogModal ( bbdChangelog ) ;
2020-03-28 04:12:11 +01:00
DataStore . setBDData ( "version" , bbdVersion ) ;
2020-02-27 08:01:51 +01:00
}
Utils . suppressErrors ( this . patchSocial . bind ( this ) , "BD Social Patch" ) ( ) ;
Utils . suppressErrors ( this . patchGuildPills . bind ( this ) , "BD Guild Pills Patch" ) ( ) ;
Utils . suppressErrors ( this . patchGuildListItems . bind ( this ) , "BD Guild List Items Patch" ) ( ) ;
Utils . suppressErrors ( this . patchGuildSeparator . bind ( this ) , "BD Guild Separator Patch" ) ( ) ;
} ;
Core . prototype . checkForGuilds = function ( ) {
let timesChecked = 0 ;
return new Promise ( resolve => {
const checkForGuilds = function ( ) {
const wrapper = BDV2 . guildClasses . wrapper . split ( " " ) [ 0 ] ;
if ( document . querySelectorAll ( ` . ${ wrapper } ` ) . length > 0 ) timesChecked ++ ;
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 ) ;
else if ( timesChecked >= 50 ) return resolve ( bdConfig . deferLoaded = true ) ;
setTimeout ( checkForGuilds , 100 ) ;
} ;
2020-03-29 11:17:12 +02:00
if ( document . readyState != "loading" ) setTimeout ( checkForGuilds , 100 ) ;
document . addEventListener ( "DOMContentLoaded" , ( ) => { setTimeout ( checkForGuilds , 100 ) ; } ) ;
2020-02-27 08:01:51 +01:00
} ) ;
} ;
Core . prototype . injectExternals = async function ( ) {
2020-03-29 11:17:12 +02:00
await DOM . addScript ( "ace-script" , "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js" ) ;
2020-02-27 23:09:08 +01:00
if ( window . require . original ) window . require = window . require . original ;
2020-02-27 08:01:51 +01:00
} ;
Core . prototype . initSettings = function ( ) {
DataStore . initialize ( ) ;
if ( ! DataStore . getSettingGroup ( "settings" ) ) {
Object . assign ( settingsCookie , defaultCookie ) ;
settingsPanel . saveSettings ( ) ;
}
else {
settingsPanel . loadSettings ( ) ;
for ( const setting in defaultCookie ) {
if ( settingsCookie [ setting ] == undefined ) {
settingsCookie [ setting ] = defaultCookie [ setting ] ;
settingsPanel . saveSettings ( ) ;
}
}
}
} ;
Core . prototype . initObserver = function ( ) {
const mainObserver = new MutationObserver ( ( mutations ) => {
for ( let i = 0 , mlen = mutations . length ; i < mlen ; i ++ ) {
const mutation = mutations [ i ] ;
if ( typeof pluginModule !== "undefined" ) pluginModule . rawObserver ( mutation ) ;
// if there was nothing added, skip
if ( ! mutation . addedNodes . length || ! ( mutation . addedNodes [ 0 ] instanceof Element ) ) continue ;
const node = mutation . addedNodes [ 0 ] ;
if ( node . classList . contains ( "layer-3QrUeG" ) ) {
if ( node . getElementsByClassName ( "guild-settings-base-section" ) . length ) node . setAttribute ( "layer-id" , "server-settings" ) ;
if ( node . getElementsByClassName ( "socialLinks-3jqNFy" ) . length ) {
node . setAttribute ( "layer-id" , "user-settings" ) ;
node . setAttribute ( "id" , "user-settings" ) ;
if ( ! document . getElementById ( "bd-settings-sidebar" ) ) settingsPanel . renderSidebar ( ) ;
}
}
if ( node . parentElement == document . body && node . querySelector ( "#ace_settingsmenu" ) ) node . id = "ace_settingsmenu_container" ;
// Emoji Picker
//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 ) ;
}
} ) ;
mainObserver . observe ( document , {
childList : true ,
subtree : true
} ) ;
} ;
Core . prototype . showChangelogModal = function ( options = { } ) {
2020-03-28 03:44:59 +01:00
return Utils . showChangelogModal ( options ) ;
2020-02-27 08:01:51 +01:00
} ;
Core . prototype . patchSocial = function ( ) {
if ( this . socialPatch ) return ;
const TabBar = WebpackModules . find ( m => m . displayName == "TabBar" ) ;
const Anchor = WebpackModules . find ( m => m . displayName == "Anchor" ) ;
if ( ! TabBar || ! Anchor ) return ;
this . socialPatch = Utils . monkeyPatch ( TabBar . prototype , "render" , { after : ( data ) => {
const children = data . returnValue . props . children ;
if ( ! children || ! children . length || children . length < 3 ) return ;
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 ;
const newOne = function ( ) {
const returnVal = original ( ... arguments ) ;
2020-03-28 03:44:59 +01:00
returnVal . props . children . push (
BDV2 . React . createElement ( TooltipWrap , { color : "black" , side : "top" , text : "BandagedBD" } ,
BDV2 . React . createElement ( Anchor , { className : "bd-social-link" , href : "https://github.com/rauenzi/BetterDiscordApp" , title : "BandagedBD" , target : "_blank" } ,
BDV2 . React . createElement ( BDLogo , { size : "16px" , className : "bd-social-logo" } )
)
)
) ;
2020-02-27 08:01:51 +01:00
return returnVal ;
} ;
children [ children . length - 2 ] . type = newOne ;
const BBDLink = BDV2 . React . createElement ( Anchor , { className : "bd-social-link" , href : "https://twitter.com/BandagedBD" , title : "BandagedBD" , target : "_blank" } , "BandagedBD" ) ;
const AuthorLink = BDV2 . 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 ] ) ;
2020-03-27 19:48:57 +01:00
const injector = BDV2 . react . createElement ( "div" , { className : "colorMuted-HdFt4q size12-3cLvbJ" } , [ "BBD Injector" , ` ${ bdConfig . version } by ` , AuthorLink ] ) ;
2020-02-27 08:01:51 +01:00
const originalVersions = children [ children . length - 1 ] . type ;
children [ children . length - 1 ] . type = function ( ) {
const returnVal = originalVersions ( ... arguments ) ;
2020-03-15 02:31:05 +01:00
returnVal . props . children . push ( injector ) ;
2020-02-27 08:01:51 +01:00
returnVal . props . children . push ( additional ) ;
return returnVal ;
} ;
} } ) ;
} ;
const getGuildClasses = function ( ) {
const guildsWrapper = WebpackModules . findByProps ( "wrapper" , "unreadMentionsBar" ) ;
const guilds = WebpackModules . findByProps ( "guildsError" , "selected" ) ;
const pill = WebpackModules . findByProps ( "blobContainer" ) ;
return Object . assign ( { } , guildsWrapper , guilds , pill ) ;
} ;
Core . prototype . patchGuildListItems = function ( ) {
if ( this . guildListItemsPatch ) return ;
const GuildClasses = getGuildClasses ( ) ;
const listItemClass = GuildClasses . listItem . split ( " " ) [ 0 ] ;
const blobClass = GuildClasses . blobContainer . split ( " " ) [ 0 ] ;
const reactInstance = BDV2 . getInternalInstance ( document . querySelector ( ` . ${ listItemClass } . ${ blobClass } ` ) . parentElement ) ;
const GuildComponent = reactInstance . return . type ;
if ( ! GuildComponent ) return ;
this . guildListItemsPatch = Utils . monkeyPatch ( GuildComponent . prototype , "render" , { after : ( data ) => {
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 ;
}
} } ) ;
} ;
Core . prototype . patchGuildPills = function ( ) {
if ( this . guildPillPatch ) return ;
const guildPill = WebpackModules . find ( m => m . default && ! m . default . displayName && m . default . toString && m . default . toString ( ) . includes ( "translate3d" ) ) ;
if ( ! guildPill ) return ;
this . guildPillPatch = Utils . monkeyPatch ( guildPill , "default" , { after : ( data ) => {
const props = data . methodArguments [ 0 ] ;
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" ;
return data . returnValue ;
} } ) ;
} ;
Core . prototype . patchGuildSeparator = function ( ) {
if ( this . guildSeparatorPatch ) return ;
const Guilds = WebpackModules . findByDisplayName ( "Guilds" ) ;
const guildComponents = WebpackModules . findByProps ( "renderListItem" ) ;
if ( ! guildComponents || ! Guilds ) return ;
const GuildSeparator = function ( ) {
const returnValue = guildComponents . Separator ( ... arguments ) ;
returnValue . props . className += " bd-guild-separator" ;
return returnValue ;
} ;
this . guildSeparatorPatch = Utils . monkeyPatch ( Guilds . prototype , "render" , { after : ( data ) => {
data . returnValue . props . children [ 1 ] . props . children [ 3 ] . type = GuildSeparator ;
} } ) ;
} ;
2020-03-28 03:44:59 +01:00
export default new Core ( ) ;