2020-10-20 23:25:34 +02:00
/ * *
* @ name ThemeSettings
* @ authorId 278543574059057154
* @ invite Jx3TjNS
* @ donate https : //www.paypal.me/MircoWittrien
* @ patreon https : //www.patreon.com/MircoWittrien
* @ website https : //github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ThemeSettings
* @ source https : //raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/ThemeSettings/ThemeSettings.plugin.js
2020-11-12 17:30:48 +01:00
* @ updateUrl https : //raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/ThemeSettings/ThemeSettings.plugin.js
2020-10-20 23:25:34 +02:00
* /
2018-12-11 19:43:51 +01:00
2020-09-19 20:49:33 +02:00
module . exports = ( _ => {
2020-10-09 21:09:35 +02:00
const config = {
2020-09-19 20:49:33 +02:00
"info" : {
"name" : "ThemeSettings" ,
"author" : "DevilBro" ,
2020-12-02 20:57:32 +01:00
"version" : "1.2.9" ,
2020-10-16 10:25:30 +02:00
"description" : "Allow you to change Theme Variables within BetterDiscord. Adds a Settings button (similar to Plugins) to customizable Themes in your Themes Page"
2020-10-14 21:08:41 +02:00
} ,
"changeLog" : {
"fixed" : {
2020-12-02 20:57:32 +01:00
"Works again" : "Yes"
2020-10-14 21:08:41 +02:00
}
2020-03-28 07:55:39 +01:00
}
2020-09-19 20:49:33 +02:00
} ;
2020-11-13 19:47:44 +01:00
2020-10-09 21:09:35 +02:00
return ! window . BDFDB _Global || ( ! window . BDFDB _Global . loaded && ! window . BDFDB _Global . started ) ? class {
2020-09-19 20:49:33 +02:00
getName ( ) { return config . info . name ; }
getAuthor ( ) { return config . info . author ; }
getVersion ( ) { return config . info . version ; }
getDescription ( ) { return config . info . description ; }
2020-05-22 21:17:02 +02:00
2020-10-09 21:09:35 +02:00
load ( ) {
2020-11-19 16:51:14 +01:00
if ( ! window . BDFDB _Global || ! Array . isArray ( window . BDFDB _Global . pluginQueue ) ) window . BDFDB _Global = Object . assign ( { } , window . BDFDB _Global , { pluginQueue : [ ] } ) ;
2020-09-19 20:49:33 +02:00
if ( ! window . BDFDB _Global . downloadModal ) {
window . BDFDB _Global . downloadModal = true ;
BdApi . showConfirmationModal ( "Library Missing" , ` The library plugin needed for ${ config . info . name } is missing. Please click "Download Now" to install it. ` , {
confirmText : "Download Now" ,
cancelText : "Cancel" ,
onCancel : _ => { delete window . BDFDB _Global . downloadModal ; } ,
2020-09-20 08:15:13 +02:00
onConfirm : _ => {
delete window . BDFDB _Global . downloadModal ;
require ( "request" ) . get ( "https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js" , ( e , r , b ) => {
2020-10-20 23:25:34 +02:00
if ( ! e && b && b . indexOf ( ` * @name BDFDB ` ) > - 1 ) require ( "fs" ) . writeFile ( require ( "path" ) . join ( BdApi . Plugins . folder , "0BDFDB.plugin.js" ) , b , _ => { } ) ;
2020-09-20 08:15:13 +02:00
else BdApi . alert ( "Error" , "Could not download BDFDB library plugin, try again some time later." ) ;
} ) ;
}
2020-09-19 20:49:33 +02:00
} ) ;
2020-03-28 07:55:39 +01:00
}
2020-09-19 20:49:33 +02:00
if ( ! window . BDFDB _Global . pluginQueue . includes ( config . info . name ) ) window . BDFDB _Global . pluginQueue . push ( config . info . name ) ;
2020-10-09 21:09:35 +02:00
}
start ( ) { this . load ( ) ; }
stop ( ) { }
2020-11-28 23:12:09 +01:00
getSettingsPanel ( ) {
let template = document . createElement ( "template" ) ;
template . innerHTML = ` <div style="color: var(--header-primary); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The library plugin needed for ${ config . info . name } is missing. \n Please click <a style="font-weight: 500;">Download Now</a> to install it.</div> ` ;
template . content . firstElementChild . querySelector ( "a" ) . addEventListener ( "click" , _ => {
require ( "request" ) . get ( "https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js" , ( e , r , b ) => {
if ( ! e && b && b . indexOf ( ` * @name BDFDB ` ) > - 1 ) require ( "fs" ) . writeFile ( require ( "path" ) . join ( BdApi . Plugins . folder , "0BDFDB.plugin.js" ) , b , _ => { } ) ;
else BdApi . alert ( "Error" , "Could not download BDFDB library plugin, try again some time later." ) ;
} ) ;
} ) ;
return template . content . firstElementChild ;
}
2020-10-09 21:09:35 +02:00
} : ( ( [ Plugin , BDFDB ] ) => {
2020-11-12 14:30:33 +01:00
const isBeta = ! ( window . BdApi && ! Array . isArray ( BdApi . settings ) ) ;
2020-09-19 20:49:33 +02:00
var dir ;
2020-10-09 21:09:35 +02:00
return class ThemeSettings extends Plugin {
2020-09-19 20:49:33 +02:00
onLoad ( ) {
dir = BDFDB . BDUtils . getThemesFolder ( ) ;
}
onStart ( ) {
2020-05-22 21:17:02 +02:00
let cardObserver = ( new MutationObserver ( changes => { changes . forEach ( change => { if ( change . addedNodes ) { change . addedNodes . forEach ( node => {
if ( BDFDB . DOMUtils . containsClass ( node , BDFDB . disCN . _repocard ) ) this . appendSettingsButton ( node ) ;
2020-06-12 15:23:14 +02:00
if ( node . nodeType != Node . TEXT _NODE ) for ( let child of node . querySelectorAll ( BDFDB . dotCN . _repocard ) ) this . appendSettingsButton ( child ) ;
2020-05-22 21:17:02 +02:00
} ) ; } } ) ; } ) ) ;
2020-11-19 16:51:14 +01:00
BDFDB . ObserverUtils . connect ( this , document . querySelector ( ` ${ BDFDB . dotCN . layer } [aria-label=" ${ BDFDB . DiscordConstants . Layers . USER _SETTINGS } "] ` ) , { name : "cardObserver" , instance : cardObserver } , { childList : true , subtree : true } ) ;
BDFDB . ObserverUtils . connect ( this , BDFDB . dotCN . applayers , { name : "appLayerObserver" , instance : ( new MutationObserver ( changes => { changes . forEach ( change => { if ( change . addedNodes ) { change . addedNodes . forEach ( node => {
if ( node . nodeType != Node . TEXT _NODE && node . getAttribute ( "aria-label" ) == BDFDB . DiscordConstants . Layers . USER _SETTINGS ) BDFDB . ObserverUtils . connect ( this , node , { name : "cardObserver" , instance : cardObserver } , { childList : true , subtree : true } ) ;
2020-05-22 21:17:02 +02:00
} ) ; } } ) ; } ) ) } , { childList : true } ) ;
for ( let child of document . querySelectorAll ( BDFDB . dotCN . _repocard ) ) this . appendSettingsButton ( child ) ;
2020-03-28 07:55:39 +01:00
}
2020-09-19 20:49:33 +02:00
onStop ( ) {
2020-05-22 21:17:02 +02:00
BDFDB . DOMUtils . remove ( ".theme-settings-button" ) ;
2020-03-28 07:55:39 +01:00
}
2020-05-22 21:17:02 +02:00
2020-09-19 20:49:33 +02:00
appendSettingsButton ( card ) {
if ( card . querySelector ( ".theme-settings-button" ) ) return ;
let addon = BDFDB . ObjectUtils . get ( BDFDB . ReactUtils . getInstance ( card ) , "return.stateNode.props.addon" ) ;
2020-10-24 10:00:00 +02:00
if ( addon && ! addon . plugin && ! addon . instance && addon . css ) {
2020-09-19 20:49:33 +02:00
let vars = this . getThemeVars ( addon . css ) ;
if ( vars . length ) {
2020-11-23 17:52:58 +01:00
let open = _ => {
BDFDB . ModalUtils . open ( this , {
header : ` ${ addon . name } ${ BDFDB . LanguageUtils . LanguageStrings . SETTINGS } ` ,
subheader : "" ,
className : BDFDB . disCN . _repomodal ,
2020-11-23 20:19:58 +01:00
headerClassName : BDFDB . disCN . _repomodalheader ,
contentClassName : BDFDB . disCN . _repomodalsettings ,
footerClassName : BDFDB . disCN . _repomodalfooter ,
2020-11-23 17:52:58 +01:00
size : "MEDIUM" ,
children : this . createThemeVarInputs ( addon , vars ) ,
2020-12-02 20:32:13 +01:00
buttons : [ { contents : BDFDB . LanguageUtils . LanguageStrings . SAVE , color : "GREEN" , click : modal => { this . updateTheme ( modal , addon ) ; } } ]
2020-11-23 17:52:58 +01:00
} ) ;
} ;
2020-11-12 14:30:33 +01:00
if ( isBeta ) {
let controls = card . querySelector ( "." + BDFDB . disCN . _repofooter . split ( " " ) [ 0 ] + " " + BDFDB . dotCN . _repocontrols ) ;
let settingsButton = document . createElement ( "button" ) ;
2020-11-06 16:32:34 +01:00
settingsButton . className = BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . _repobutton , BDFDB . disCN . _repocontrolsbutton , "theme-settings-button" ) ;
2020-11-06 16:14:31 +01:00
settingsButton . appendChild ( BDFDB . DOMUtils . create ( ` <svg viewBox="0 0 20 20" style="width: 20px; height: 20px;">
< path fill = "none" d = "M0 0h20v20H0V0z" > < / p a t h >
< path d = "M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z" > < / p a t h >
< / s v g > ` ) ) ;
controls . insertBefore ( settingsButton , controls . firstElementChild ) ;
2020-11-23 17:52:58 +01:00
settingsButton . addEventListener ( "click" , open ) ;
2020-11-06 16:14:31 +01:00
}
else {
2020-11-12 17:23:45 +01:00
let footer = card . querySelector ( "." + BDFDB . disCN . _repofooter . split ( " " ) . join ( ",." ) ) ;
2020-11-12 14:30:33 +01:00
if ( ! footer ) {
footer = document . createElement ( "div" ) ;
footer . className = BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . _repofooter ) ;
let links = document . createElement ( "span" ) ;
links . className = BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . _repolinks ) ;
footer . appendChild ( links ) ;
card . appendChild ( footer ) ;
}
let settingsButton = document . createElement ( "button" ) ;
2020-11-06 16:28:34 +01:00
settingsButton . className = BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . _reposettingsbutton , "theme-settings-button" ) ;
2020-11-06 16:14:31 +01:00
settingsButton . innerText = "Settings" ;
footer . appendChild ( settingsButton ) ;
2020-11-23 17:52:58 +01:00
settingsButton . addEventListener ( "click" , open ) ;
2020-11-06 16:14:31 +01:00
}
2020-09-19 20:49:33 +02:00
}
2020-03-28 07:55:39 +01:00
}
2018-12-11 19:43:51 +01:00
}
2020-11-06 16:14:31 +01:00
2020-11-06 16:46:50 +01:00
updateTheme ( card , addon ) {
2020-11-06 16:14:31 +01:00
let path = BDFDB . LibraryRequires . path . join ( dir , addon . filename ) ;
let css = BDFDB . LibraryRequires . fs . readFileSync ( path ) . toString ( ) ;
if ( css ) {
let amount = 0 ;
2020-11-06 16:46:50 +01:00
for ( let input of card . querySelectorAll ( BDFDB . dotCN . input ) ) {
2020-11-06 16:14:31 +01:00
let oldValue = input . getAttribute ( "placeholder" ) ;
let newValue = input . value ;
if ( newValue && newValue . trim ( ) && newValue != oldValue ) {
let varName = input . getAttribute ( "varName" ) ;
2020-11-19 16:51:14 +01:00
css = css . replace ( new RegExp ( ` -- ${ BDFDB . StringUtils . regEscape ( varName ) } ( \\ s*):( \\ s*) ${ BDFDB . StringUtils . regEscape ( oldValue ) } ` , "g" ) , ` -- ${ varName } $ 1: $ 2 ${ newValue } ` ) ;
2020-11-06 16:14:31 +01:00
input . setAttribute ( "placeholder" , newValue ) ;
amount ++ ;
}
}
if ( amount > 0 ) {
BDFDB . LibraryRequires . fs . writeFileSync ( path , css ) ;
2020-11-19 16:51:14 +01:00
BDFDB . NotificationUtils . toast ( ` Updated ${ amount } variable ${ amount == 1 ? "" : "s" } in ${ addon . filename } ` , { type : "success" } ) ;
2020-11-06 16:14:31 +01:00
}
2020-11-19 16:51:14 +01:00
else BDFDB . NotificationUtils . toast ( ` There are no changed variables to be updated in ${ addon . filename } ` , { type : "warning" } ) ;
2020-11-06 16:14:31 +01:00
}
2020-11-19 16:51:14 +01:00
else BDFDB . NotificationUtils . toast ( ` Could not find themefile: ${ addon . filename } ` , { type : "error" } ) ;
2020-11-06 16:14:31 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
getThemeVars ( css ) {
let vars = css . split ( ":root" ) ;
if ( vars . length > 1 ) {
vars = vars [ 1 ] . replace ( /\t\(/g , " (" ) . replace ( /\r|\t| {2,}/g , "" ) . replace ( /\/\*\n*((?!\/\*|\*\/).|\n)*\n+((?!\/\*|\*\/).|\n)*\n*\*\//g , "" ) . replace ( /\n\/\*.*?\*\//g , "" ) . replace ( /\n/g , "" ) ;
vars = vars . split ( "{" ) ;
vars . shift ( ) ;
vars = vars . join ( "{" ) . replace ( /\s*(:|;|--|\*)\s*/g , "$1" ) ;
vars = vars . split ( "}" ) [ 0 ] ;
return vars . slice ( 2 ) . split ( /;--|\*\/--/ ) ;
}
return [ ] ;
2020-03-28 07:55:39 +01:00
}
2019-01-26 22:45:19 +01:00
2020-11-23 19:20:23 +01:00
createThemeVarInputs ( theme , vars ) {
2020-12-02 20:57:32 +01:00
let settingsItems = [ ] ;
for ( let varStr of vars ) {
varStr = varStr . split ( ":" ) ;
let varName = varStr . shift ( ) . trim ( ) ;
varStr = varStr . join ( ":" ) . split ( /;[^A-z0-9]|\/\*/ ) ;
let varValue = varStr . shift ( ) . trim ( ) ;
if ( varValue ) {
let childType = "text" , childMode = "" ;
let isColor = BDFDB . ColorUtils . getType ( varValue ) ;
let isComp = ! isColor && /^[0-9 ]+,[0-9 ]+,[0-9 ]+$/g . test ( varValue ) ;
if ( isColor || isComp ) {
childType = "color" ;
childMode = isComp && "comp" ;
}
else {
let isUrlFile = /url\(.+\)/gi . test ( varValue ) ;
let isFile = ! isUrlFile && /(http(s)?):\/\/[(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/ . test ( varValue ) ;
if ( isFile || isUrlFile ) {
childType = "file" ;
childMode = isUrlFile && "url" ;
2020-09-19 20:49:33 +02:00
}
2020-03-28 07:55:39 +01:00
}
2020-12-02 20:57:32 +01:00
let varDescription = varStr . join ( "" ) . replace ( /\*\/|\/\*/g , "" ) . replace ( /:/g , ": " ) . replace ( /: \//g , ":/" ) . replace ( /--/g , " --" ) . replace ( /\( --/g , "(--" ) . trim ( ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "TextInput" ,
margin : 20 ,
dividerBottom : vars [ vars . length - 1 ] != varStr ,
childProps : {
type : childType ,
mode : childMode ,
filter : childType == "file" && "image"
} ,
label : varName [ 0 ] . toUpperCase ( ) + varName . slice ( 1 ) ,
note : varDescription && varDescription . indexOf ( "*" ) == 0 ? varDescription . slice ( 1 ) : varDescription ,
basis : "70%" ,
varName : varName ,
value : varValue ,
placeholder : varValue
} ) ) ;
2018-12-12 12:08:53 +01:00
}
2020-11-22 18:33:22 +01:00
} ;
2020-09-19 20:49:33 +02:00
2020-12-02 20:57:32 +01:00
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanel , {
addon : theme ,
children : settingsItems
} ) ;
2019-01-15 20:26:33 +01:00
}
2020-09-19 20:49:33 +02:00
} ;
2020-10-09 21:09:35 +02:00
} ) ( window . BDFDB _Global . PluginUtils . buildPlugin ( config ) ) ;
2020-09-19 20:49:33 +02:00
} ) ( ) ;