2020-04-23 22:01:48 +02:00
import { Config } from "data" ;
2019-05-30 17:44:05 +02:00
import WebpackModules from "./webpackmodules" ;
2019-06-23 06:11:50 +02:00
import DiscordModules from "./discordmodules" ;
import Utilities from "./utilities" ;
import Patcher from "./patcher" ;
2019-05-30 07:06:17 +02:00
import BDLogo from "../ui/icons/bdlogo" ;
2019-05-28 23:27:25 +02:00
2020-07-16 07:42:56 +02:00
const React = DiscordModules . React ;
const Tooltip = WebpackModules . getByDisplayName ( "Tooltip" ) ;
2019-06-24 21:47:24 +02:00
export default new class ComponentPatcher {
2019-05-28 20:19:48 +02:00
initialize ( ) {
2019-06-23 06:11:50 +02:00
Utilities . suppressErrors ( this . patchSocial . bind ( this ) , "BD Social Patch" ) ( ) ;
2020-12-12 21:33:32 +01:00
/ *
2019-06-23 06:11:50 +02:00
Utilities . suppressErrors ( this . patchGuildPills . bind ( this ) , "BD Guild Pills Patch" ) ( ) ;
Utilities . suppressErrors ( this . patchGuildListItems . bind ( this ) , "BD Guild List Items Patch" ) ( ) ;
Utilities . suppressErrors ( this . patchGuildSeparator . bind ( this ) , "BD Guild Separator Patch" ) ( ) ;
2020-12-12 21:33:32 +01:00
* /
2020-07-16 07:42:56 +02:00
Utilities . suppressErrors ( this . patchMessageHeader . bind ( this ) , "BD Message Header Patch" ) ( ) ;
Utilities . suppressErrors ( this . patchMemberList . bind ( this ) , "BD Member List Patch" ) ( ) ;
2019-05-28 20:19:48 +02:00
}
2019-05-30 07:06:17 +02:00
patchSocial ( ) {
if ( this . socialPatch ) return ;
2019-06-23 06:11:50 +02:00
const TabBar = WebpackModules . getByDisplayName ( "TabBar" ) ;
const Anchor = WebpackModules . getByDisplayName ( "Anchor" ) ;
2020-04-23 22:01:48 +02:00
if ( ! TabBar ) return ;
this . socialPatch = Patcher . after ( "ComponentPatcher" , TabBar . prototype , "render" , ( thisObject , args , returnValue ) => {
2019-06-23 06:11:50 +02:00
const children = returnValue . props . children ;
2020-04-23 22:01:48 +02:00
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 ;
if ( Anchor ) {
const original = children [ children . length - 2 ] . type ;
const newOne = function ( ) {
const returnVal = original ( ... arguments ) ;
returnVal . props . children . push (
2020-07-27 00:47:04 +02:00
DiscordModules . React . createElement ( Anchor , { className : "bd-social-link" , href : "https://twitter.com/BandagedBD" , title : "BetterDiscord" , target : "_blank" } ,
2020-07-16 07:42:56 +02:00
DiscordModules . React . createElement ( BDLogo , { size : "16px" , className : "bd-social-logo" } )
)
2020-04-23 22:01:48 +02:00
) ;
return returnVal ;
} ;
children [ children . length - 2 ] . type = newOne ;
}
const injector = DiscordModules . React . createElement ( "div" , { className : "colorMuted-HdFt4q size12-3cLvbJ" } , ` Injector ${ Config . version } ` ) ;
const versionHash = ` ( ${ Config . hash ? Config . hash . substring ( 0 , 7 ) : Config . branch } ) ` ;
2020-07-27 00:47:04 +02:00
const additional = DiscordModules . React . createElement ( "div" , { className : "colorMuted-HdFt4q size12-3cLvbJ" } , ` BD ${ Config . bdVersion } ` , DiscordModules . React . createElement ( "span" , { className : "versionHash-2gXjIB da-versionHash" } , versionHash ) ) ;
2020-04-23 22:01:48 +02:00
const originalVersions = children [ children . length - 1 ] . type ;
children [ children . length - 1 ] . type = function ( ) {
const returnVal = originalVersions ( ... arguments ) ;
returnVal . props . children . splice ( returnVal . props . children . length - 1 , 0 , injector ) ;
returnVal . props . children . splice ( 1 , 0 , additional ) ;
2019-05-30 07:06:17 +02:00
return returnVal ;
} ;
2019-06-23 06:11:50 +02:00
} ) ;
2019-05-28 20:19:48 +02:00
}
2020-12-12 21:33:32 +01:00
/ *
2019-05-28 20:19:48 +02:00
patchGuildListItems ( ) {
if ( this . guildListItemsPatch ) return ;
2019-06-23 06:11:50 +02:00
const listItemClass = DiscordModules . GuildClasses . listItem . split ( " " ) [ 0 ] ;
const blobClass = DiscordModules . GuildClasses . blobContainer . split ( " " ) [ 0 ] ;
const reactInstance = Utilities . getReactInstance ( document . querySelector ( ` . ${ listItemClass } . ${ blobClass } ` ) . parentElement ) ;
2019-05-28 20:19:48 +02:00
const GuildComponent = reactInstance . return . type ;
if ( ! GuildComponent ) return ;
2020-07-16 07:42:56 +02:00
this . guildListItemsPatch = Patcher . after ( "ComponentPatcher" , GuildComponent . prototype , "render" , ( thisObject , _ , returnValue ) => {
2020-02-28 01:00:12 +01:00
if ( ! returnValue || ! thisObject ) return ;
2019-06-23 06:11:50 +02:00
const guildData = thisObject . props ;
2019-05-28 20:19:48 +02:00
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 ;
2019-06-23 06:11:50 +02:00
} ) ;
2019-05-28 20:19:48 +02:00
}
patchGuildPills ( ) {
if ( this . guildPillPatch ) return ;
2019-06-23 06:11:50 +02:00
const guildPill = WebpackModules . getModule ( m => m . default && ! m . default . displayName && m . default . toString && m . default . toString ( ) . includes ( "translate3d" ) ) ;
2019-05-28 20:19:48 +02:00
if ( ! guildPill ) return ;
2020-07-16 07:42:56 +02:00
this . guildPillPatch = Patcher . after ( "ComponentPatcher" , guildPill , "default" , ( _ , args , returnValue ) => {
2019-06-23 06:11:50 +02:00
const props = args [ 0 ] ;
if ( props . unread ) returnValue . props . className += " bd-unread" ;
if ( props . selected ) returnValue . props . className += " bd-selected" ;
if ( props . hovered ) returnValue . props . className += " bd-hovered" ;
return returnValue ;
} ) ;
2019-05-28 20:19:48 +02:00
}
patchGuildSeparator ( ) {
if ( this . guildSeparatorPatch ) return ;
2019-06-23 06:11:50 +02:00
const Guilds = WebpackModules . getByDisplayName ( "Guilds" ) ;
const guildComponents = WebpackModules . getByProps ( "renderListItem" ) ;
2019-05-28 20:19:48 +02:00
if ( ! guildComponents || ! Guilds ) return ;
const GuildSeparator = function ( ) {
2020-07-25 10:22:57 +02:00
const returnValue = guildComponents . Separator ( ... arguments ) ; // eslint-disable-line new-cap
2019-05-28 20:19:48 +02:00
returnValue . props . className += " bd-guild-separator" ;
return returnValue ;
} ;
2020-07-16 07:42:56 +02:00
this . guildSeparatorPatch = Patcher . after ( "ComponentPatcher" , Guilds . prototype , "render" , ( _ , _ _ , returnValue ) => {
2019-06-23 06:11:50 +02:00
const Separator = Utilities . findInReactTree ( returnValue , m => m . type && ! m . type . displayName && typeof ( m . type ) == "function" && Utilities . isEmpty ( m . props ) ) ;
if ( ! Separator ) return ;
Separator . type = GuildSeparator ;
} ) ;
2020-12-12 21:33:32 +01:00
} * /
2019-05-28 20:19:48 +02:00
2020-07-16 07:42:56 +02:00
patchMessageHeader ( ) {
if ( this . messageHeaderPatch ) return ;
const MessageHeader = WebpackModules . getByProps ( "MessageTimestamp" ) ;
const Anchor = WebpackModules . find ( m => m . displayName == "Anchor" ) ;
if ( ! Anchor || ! MessageHeader || ! MessageHeader . default ) return ;
this . messageHeaderPatch = Patcher . after ( "ComponentPatcher" , MessageHeader , "default" , ( _ , args , returnValue ) => {
const author = Utilities . getNestedProp ( args [ 0 ] , "message.author" ) ;
const children = Utilities . getNestedProp ( returnValue , "props.children.1.props.children.1.props.children" ) ;
if ( ! children || ! author || ! author . id || author . id !== "249746236008169473" ) return ;
if ( ! Array . isArray ( children ) ) return ;
children . push (
2021-03-06 21:26:48 +01:00
React . createElement ( Tooltip , { color : "primary" , position : "top" , text : "BetterDiscord Developer" } ,
2020-07-27 00:47:04 +02:00
props => React . createElement ( Anchor , Object . assign ( { className : "bd-chat-badge" , href : "https://github.com/rauenzi/BetterDiscordApp" , title : "BetterDiscord" , target : "_blank" } , props ) ,
2020-07-16 07:42:56 +02:00
React . createElement ( BDLogo , { size : "16px" , className : "bd-logo" } )
)
)
) ;
} ) ;
}
patchMemberList ( ) {
if ( this . memberListPatch ) return ;
const MemberListItem = WebpackModules . findByDisplayName ( "MemberListItem" ) ;
const Anchor = WebpackModules . find ( m => m . displayName == "Anchor" ) ;
if ( ! Anchor || ! MemberListItem || ! MemberListItem . prototype || ! MemberListItem . prototype . renderDecorators ) return ;
this . memberListPatch = Patcher . after ( "ComponentPatcher" , MemberListItem . prototype , "renderDecorators" , ( thisObject , args , returnValue ) => {
const user = Utilities . getNestedProp ( thisObject , "props.user" ) ;
const children = Utilities . getNestedProp ( returnValue , "props.children" ) ;
if ( ! children || ! user || ! user . id || user . id !== "249746236008169473" ) return ;
if ( ! Array . isArray ( children ) ) return ;
children . push (
2021-03-06 21:26:48 +01:00
React . createElement ( Tooltip , { color : "primary" , position : "top" , text : "BetterDiscord Developer" } ,
2020-07-27 00:47:04 +02:00
props => React . createElement ( Anchor , Object . assign ( { className : "bd-member-badge" , href : "https://github.com/rauenzi/BetterDiscordApp" , title : "BetterDiscord" , target : "_blank" } , props ) ,
2020-07-16 07:42:56 +02:00
React . createElement ( BDLogo , { size : "16px" , className : "bd-logo" } )
)
)
) ;
} ) ;
}
2020-11-07 07:03:29 +01:00
} ;
2020-11-19 18:48:51 +01:00
// as part of utility classes, i would like a way to distinguish channel types from the .content-3at_AU element. other than that, can't think of anything
// Tropical's notes
/ *
2020-12-12 21:33:32 +01:00
html [ maximized | bd | stable | canary | ptb ]
2020-11-19 18:48:51 +01:00
. iconWrapper - 2 OrFZ1 [ type ]
. sidebar - 2 K8pFh [ guild - id ]
2020-12-12 21:33:32 +01:00
. wrapper - 2 jXpOf [ voice | text | announcement | store | private | nsfw | rules ]
. chat - 3 bRxxu [ channnel - name | guild - id ]
2020-11-19 18:48:51 +01:00
. listItem - 2 P _4kh [ type | state ]
. privateChannels - 1 nO12o [ library - hidden ]
. member - 3 - YXUe [ user - id ]
2020-12-12 21:33:32 +01:00
. message - 2 qnXI6 [ type | author - id | group - end | message - content ]
2020-11-19 18:48:51 +01:00
. wrapper - 3 t9DeA [ user - id | status ]
2020-12-12 21:33:32 +01:00
. userPopout - 3 XzG _A [ user - id ]
. root - SR8cQa [ user - id ]
2020-11-19 18:48:51 +01:00
. contentRegion - 3 nDuYy [ settings - page ]
. item - PXvHYJ [ settings - page ]
2020-12-12 21:33:32 +01:00
. wrapper - 35 wsBm [ valid | expired | joined ]
2020-11-19 18:48:51 +01:00
* /