//META{"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"}*// var ThemeSettings = (_ => { return class ThemeSettings { getName () {return "ThemeSettings";} getVersion () {return "1.1.8";} 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.patchedModules = { after: { V2C_ThemeCard: "render" } }; } // Legacy load () {} start () { if (!window.BDFDB) window.BDFDB = {myPlugins:{}}; if (window.BDFDB && window.BDFDB.myPlugins && typeof window.BDFDB.myPlugins == "object") window.BDFDB.myPlugins[this.getName()] = this; let 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 (window.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 (window.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 (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { this.stopping = true; BDFDB.ModuleUtils.forceAllUpdates(this); BDFDB.PluginUtils.clear(this); } } // Begin of own functions processV2CThemeCard (e) { if (e.instance.props.addon && e.instance.props.addon.css && !e.instance.state.settings) { let vars = this.getThemeVars(e.instance.props.addon.css); if (vars.length) { let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {props: [["className", BDFDB.disCN._repofooter]]}); if (index == -1) { let footer = BDFDB.ReactUtils.createElement("div", {className: BDFDB.disCN._repofooter, children: []}); e.returnvalue.props.children.push(footer); children = footer.props.children; } else { children[index].props.children = [children[index].props.children].flat(); children = children[index].props.children; } children.push(BDFDB.ReactUtils.createElement("button", { className: BDFDB.disCNS._reposettingsbutton, children: "Settings", onClick: event => { let wrapper = BDFDB.DOMUtils.getParent(BDFDB.dotCN._reposettingsclosed, event.currentTarget); 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, e.instance.props.addon, 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 (!window.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; let settingsItems = []; settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, { type: "Button", className: BDFDB.disCN.marginbottom8, color: BDFDB.LibraryComponents.Button.Colors.GREEN, label: "Update all variables", onClick: _ => { 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 wrapper.querySelectorAll(BDFDB.dotCN.input)) { let oldvalue = input.getAttribute("placeholder"); let newvalue = input.value; if (newvalue && newvalue.trim() && newvalue != oldvalue) { let varName = input.getAttribute("varName"); 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"}); }, children: "Update" })); 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"; } } let varDescription = varStr.join("").replace(/\*\/|\/\*/g, "").replace(/:/g, ": ").replace(/: \//g, ":/").replace(/--/g, " --").replace(/\( --/g, "(--").trim(); settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, { className: BDFDB.disCN.marginbottom20, dividerbottom: vars[vars.length-1] != varStr, type: "TextInput", 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 })); } } wrapper.appendChild(BDFDB.PluginUtils.createSettingsPanel(theme, settingsItems)); } } })();