//META{"name":"ThemeSettings","website":"https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ThemeSettings","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/ThemeSettings/ThemeSettings.plugin.js"}*// class ThemeSettings { getName () {return "ThemeSettings";} getVersion () {return "1.1.5";} getAuthor () {return "DevilBro";} getDescription () {return "Allows you to change Theme Variables within BetterDiscord. Adds a Settings button (similar to Plugins) to customizable Themes in your Themes Page.";} constructor () { this.changelog = { "improved":[["Colorpicker & Filenavigator","The plugin now tries to guess if whether an input is used as a colorinput or a fileinput and adds elements to more easily change them"]] }; this.patchModules = { "V2C_ThemeCard":"componentDidMount" }; } //legacy load () {} start () { if (!global.BDFDB) global.BDFDB = {myPlugins:{}}; if (global.BDFDB && global.BDFDB.myPlugins && typeof global.BDFDB.myPlugins == "object") global.BDFDB.myPlugins[this.getName()] = this; var libraryScript = document.querySelector('head script#BDFDBLibraryScript'); if (!libraryScript || (performance.now() - libraryScript.getAttribute("date")) > 600000) { if (libraryScript) libraryScript.remove(); libraryScript = document.createElement("script"); libraryScript.setAttribute("id", "BDFDBLibraryScript"); libraryScript.setAttribute("type", "text/javascript"); libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js"); libraryScript.setAttribute("date", performance.now()); libraryScript.addEventListener("load", () => {this.initialize();}); document.head.appendChild(libraryScript); } else if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize(); this.startTimeout = setTimeout(() => { try {return this.initialize();} catch (err) {console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not initiate plugin! " + err);} }, 30000); } initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { if (this.started) return; BDFDB.PluginUtils.init(this); this.dir = BDFDB.BDUtils.getThemesFolder(); BDFDB.ModuleUtils.forceAllUpdates(this); } else console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not load BD functions!"); } stop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { this.stopping = true; BDFDB.DOMUtils.remove(".themes-settings-button",".themes-settings-footer"); BDFDB.PluginUtils.clear(this); } } // begin of own functions processV2CThemeCard (instance, wrapper) { if (instance.props && instance.props.theme && !wrapper.querySelector(BDFDB.dotCN._reposettingsbutton + ".themes-settings-button")) { let vars = this.getThemeVars(instance.props.theme.css); if (vars.length) { let footer = wrapper.querySelector(BDFDB.dotCN._repofooter); if (!footer) { footer = document.createElement("div"); footer.className = BDFDB.disCNS._repofooter + "themes-settings-footer"; wrapper.appendChild(footer); } let button = document.createElement("button"); button.className = BDFDB.disCNS._reposettingsbutton + "themes-settings-button"; button.innerText = "Settings"; footer.appendChild(button); button.addEventListener("click", () => { BDFDB.DOMUtils.addClass(wrapper, BDFDB.disCN._reposettingsopen); BDFDB.DOMUtils.removeClass(wrapper, BDFDB.disCN._reposettingsclosed); let children = []; while (wrapper.childElementCount) { children.push(wrapper.firstChild); wrapper.firstChild.remove(); } let closebutton = BDFDB.DOMUtils.create(`
`); wrapper.appendChild(closebutton); closebutton.addEventListener("click", () => { BDFDB.DOMUtils.removeClass(wrapper, BDFDB.disCN._reposettingsopen); BDFDB.DOMUtils.addClass(wrapper, BDFDB.disCN._reposettingsclosed); while (wrapper.childElementCount) wrapper.firstChild.remove(); while (children.length) wrapper.appendChild(children.shift()); }) this.createThemeSettings(wrapper, instance.props.theme, vars); }); } } } 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 []; } createThemeSettings (wrapper, theme, vars) { if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; var settingshtml = `
${BDFDB.StringUtils.htmlEscape(theme.name)}

Update all variables

`; let settingspanel = BDFDB.DOMUtils.create(settingshtml); var settingspanelinner = settingspanel.querySelector(".BDFDB-settings-inner"); var maxwidth = BDFDB.DOMUtils.getRects(wrapper).width - 80; 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 vardescription = varstr.join("").replace(/\*\/|\/\*/g, "").replace(/:/g, ": ").replace(/: \//g, ":/").replace(/--/g, " --").replace(/\( --/g, "(--").trim(); vardescription = vardescription && vardescription.indexOf("*") == 0 ? vardescription.slice(1) : vardescription; let varcontainer = BDFDB.DOMUtils.create(`

${varname[0].toUpperCase() + varname.slice(1)}

${vardescription ? `
${BDFDB.StringUtils.htmlEscape(vardescription)}
` : ""}${vars[vars.length-1] == varstr ? '' : `
`}
`); let varinput = varcontainer.querySelector(BDFDB.dotCN.input); varinput.value = varvalue; varinput.setAttribute("placeholder", varvalue); let swatch = varcontainer.querySelector(".single-swatch"); let navigator = varcontainer.querySelector(".file-navigator"); let iscolor = BDFDB.ColorUtils.getType(varvalue); let iscomp = !iscolor && /[0-9 ]+,[0-9 ]+,[0-9 ]+/g.test(varvalue); let isurlfile = !iscolor && !iscolor && /url\(.+\)/gi.test(varvalue); let isfile = !iscolor && !iscolor && !isurlfile && /(http(s)?):\/\/[(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.test(varvalue); if (iscolor || iscomp) { let color = iscomp ? BDFDB.ColorUtils.convert(varvalue.split(","), "RGB") : varvalue; swatch.style.setProperty("background-color", color, "important"); swatch.addEventListener("click", e => { BDFDB.ColorUtils.openPicker(varcontainer, e.currentTarget, color, {gradient:false, comp:iscomp, alpha:iscolor}); }); } else BDFDB.DOMUtils.remove(swatch); if (isurlfile || isfile) { navigator.addEventListener("change", e => { let file = navigator.querySelector("input").files[0]; if (file && file.type.indexOf("image") == 0) varinput.value = `${isurlfile ? "url('" : ""}data:${file.type};base64,${BDFDB.LibraryRequires.fs.readFileSync(file.path).toString("base64")}${isurlfile ? "')" : ""}`; else varinput.value = varvalue; }); } else BDFDB.DOMUtils.remove(navigator); settingspanelinner.appendChild(varcontainer); } } BDFDB.initElements(settingspanel, this); BDFDB.ListenerUtils.add(this, settingspanel, "click", ".update-button", () => { let path = BDFDB.LibraryRequires.path.join(this.dir, theme.filename); let css = BDFDB.LibraryRequires.fs.readFileSync(path).toString(); if (css) { let amount = 0; for (let input of settingspanel.querySelectorAll(BDFDB.dotCN.input)) { let oldvalue = input.getAttribute("placeholder"); let newvalue = input.value; if (newvalue && newvalue.trim() && newvalue != oldvalue) { let varname = input.getAttribute("option"); css = css.replace(new RegExp(`--${BDFDB.StringUtils.regEscape(varname)}(\\s*):(\\s*)${BDFDB.StringUtils.regEscape(oldvalue)}`,"g"),`--${varname}$1:$2${newvalue}`); amount++; } } if (amount > 0) { BDFDB.LibraryRequires.fs.writeFileSync(path, css); BDFDB.NotificationUtils.toast(`Updated ${amount} variable${amount == 1 ? "" : "s"} in ${theme.filename}`, {type:"success"}); } else BDFDB.NotificationUtils.toast(`There are no changed variables to be updated in ${theme.filename}`, {type:"warning"}); } else BDFDB.NotificationUtils.toast(`Could not find themefile: ${theme.filename}`, {type:"error"}); }); wrapper.appendChild(settingspanel); } }