BetterDiscordAddons/Plugins/ThemeSettings/ThemeSettings.plugin.js

196 lines
12 KiB
JavaScript
Raw Normal View History

2019-09-20 22:32:52 +02:00
//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"}*//
2018-12-11 19:43:51 +01:00
class ThemeSettings {
getName () {return "ThemeSettings";}
2019-09-27 13:10:10 +02:00
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.";}
2019-01-26 22:45:19 +01:00
2019-09-04 12:34:02 +02:00
constructor () {
2019-09-11 12:14:43 +02:00
this.changelog = {
2019-09-25 17:35:00 +02:00
"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"]]
2019-09-11 12:14:43 +02:00
};
this.patchModules = {
"V2C_ThemeCard":"componentDidMount"
};
}
2018-12-11 19:43:51 +01:00
//legacy
load () {}
start () {
2019-02-04 09:13:15 +01:00
if (!global.BDFDB) global.BDFDB = {myPlugins:{}};
if (global.BDFDB && global.BDFDB.myPlugins && typeof global.BDFDB.myPlugins == "object") global.BDFDB.myPlugins[this.getName()] = this;
2019-05-26 13:55:26 +02:00
var libraryScript = document.querySelector('head script#BDFDBLibraryScript');
if (!libraryScript || (performance.now() - libraryScript.getAttribute("date")) > 600000) {
2018-12-11 19:43:51 +01:00
if (libraryScript) libraryScript.remove();
libraryScript = document.createElement("script");
2019-05-26 13:55:26 +02:00
libraryScript.setAttribute("id", "BDFDBLibraryScript");
2018-12-11 19:43:51 +01:00
libraryScript.setAttribute("type", "text/javascript");
2019-10-18 10:56:41 +02:00
libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js");
2019-01-17 23:48:29 +01:00
libraryScript.setAttribute("date", performance.now());
2019-05-26 13:55:26 +02:00
libraryScript.addEventListener("load", () => {this.initialize();});
2018-12-11 19:43:51 +01:00
document.head.appendChild(libraryScript);
}
2019-01-17 23:48:29 +01:00
else if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize();
2019-11-01 10:27:07 +01:00
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);
2018-12-11 19:43:51 +01:00
}
initialize () {
2019-01-17 23:48:29 +01:00
if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
2019-01-22 11:05:54 +01:00
if (this.started) return;
2019-10-22 18:55:25 +02:00
BDFDB.PluginUtils.init(this);
2019-09-11 12:14:43 +02:00
2019-10-23 11:10:01 +02:00
this.dir = BDFDB.BDUtils.getThemesFolder();
2019-01-26 22:45:19 +01:00
2019-10-22 18:55:25 +02:00
BDFDB.ModuleUtils.forceAllUpdates(this);
2018-12-11 19:43:51 +01:00
}
2019-11-01 10:14:50 +01:00
else console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not load BD functions!");
2018-12-11 19:43:51 +01:00
}
stop () {
2019-01-17 23:48:29 +01:00
if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
2019-10-22 11:37:23 +02:00
this.stopping = true;
2019-10-23 11:10:01 +02:00
BDFDB.DOMUtils.remove(".themes-settings-button",".themes-settings-footer");
2019-10-22 18:55:25 +02:00
BDFDB.PluginUtils.clear(this);
2018-12-11 19:43:51 +01:00
}
}
2019-01-26 22:45:19 +01:00
2018-12-11 19:43:51 +01:00
// begin of own functions
2019-01-26 22:45:19 +01:00
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);
2018-12-11 19:43:51 +01:00
}
let button = document.createElement("button");
button.className = BDFDB.disCNS._reposettingsbutton + "themes-settings-button";
button.innerText = "Settings";
footer.appendChild(button);
button.addEventListener("click", () => {
2019-10-23 11:10:01 +02:00
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();
2018-12-11 19:43:51 +01:00
}
2019-10-23 11:10:01 +02:00
let closebutton = BDFDB.DOMUtils.create(`<div style="float: right; cursor: pointer;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" style="width: 18px; height: 18px;"><g class="background" fill="none" fill-rule="evenodd"><path d="M0 0h12v12H0"></path><path class="fill" fill="#dcddde" d="M9.5 3.205L8.795 2.5 6 5.295 3.205 2.5l-.705.705L5.295 6 2.5 8.795l.705.705L6 6.705 8.795 9.5l.705-.705L6.705 6"></path></g></svg></div>`);
wrapper.appendChild(closebutton);
closebutton.addEventListener("click", () => {
2019-10-23 11:10:01 +02:00
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);
});
2018-12-11 19:43:51 +01:00
}
}
}
2019-01-26 22:45:19 +01:00
2018-12-11 19:43:51 +01:00
getThemeVars (css) {
let vars = css.split(":root");
if (vars.length > 1) {
2019-09-27 13:10:10 +02:00
vars = vars[1].replace(/\t\(/g, " (").replace(/\r|\t| {2,}/g, "").replace(/\/\*\n*((?!\/\*|\*\/).|\n)*\n+((?!\/\*|\*\/).|\n)*\n*\*\//g, "").replace(/\n\/\*.*?\*\//g, "").replace(/\n/g, "");
2018-12-11 19:43:51 +01:00
vars = vars.split("{");
vars.shift();
2019-09-24 13:49:14 +02:00
vars = vars.join("{").replace(/\s*(:|;|--|\*)\s*/g, "$1");
2018-12-11 21:36:15 +01:00
vars = vars.split("}")[0];
return vars.slice(2).split(/;--|\*\/--/);
2018-12-11 19:43:51 +01:00
}
return [];
}
2019-01-26 22:45:19 +01:00
createThemeSettings (wrapper, theme, vars) {
2019-01-22 11:28:32 +01:00
if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return;
2019-10-23 11:10:01 +02:00
var settingshtml = `<div class="theme-settings" id="theme-settings-${theme.name}"><div class="${theme.name}-settings BDFDB-settings"><div class="${BDFDB.disCNS.titledefault + BDFDB.disCNS.titlesize18 + BDFDB.disCNS.height24 + BDFDB.disCNS.weightnormal + BDFDB.disCN.marginbottom8}">${BDFDB.StringUtils.htmlEscape(theme.name)}</div><div class="BDFDB-settings-inner"><div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCNS.nowrap + BDFDB.disCN.marginbottom8}" style="flex: 0 0 auto;"><h3 class="${BDFDB.disCNS.titledefault + BDFDB.disCNS.marginreset + BDFDB.disCNS.weightmedium + BDFDB.disCNS.titlesize16 + BDFDB.disCNS.height24 + BDFDB.disCN.flexchild}" style="flex: 1 1 auto;">Update all variables</h3><button type="button" class="${BDFDB.disCNS.flexchild + BDFDB.disCNS.button + BDFDB.disCNS.buttonlookfilled + BDFDB.disCNS.buttoncolorgreen + BDFDB.disCNS.buttonsizemedium + BDFDB.disCN.buttongrow} update-button" style="flex: 0 0 auto;"><div class="${BDFDB.disCN.buttoncontents}">Update</div></button></div></div></div>`;
2019-01-26 22:45:19 +01:00
2019-10-23 11:10:01 +02:00
let settingspanel = BDFDB.DOMUtils.create(settingshtml);
2019-04-18 09:28:20 +02:00
var settingspanelinner = settingspanel.querySelector(".BDFDB-settings-inner");
2019-01-26 22:45:19 +01:00
2019-10-23 11:10:01 +02:00
var maxwidth = BDFDB.DOMUtils.getRects(wrapper).width - 80;
2019-01-26 22:45:19 +01:00
2018-12-11 19:43:51 +01:00
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();
2019-09-24 13:49:14 +02:00
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;
2019-10-23 11:10:01 +02:00
let varcontainer = BDFDB.DOMUtils.create(`<div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.directioncolumn + BDFDB.disCNS.justifystart + BDFDB.disCNS.alignstretch + BDFDB.disCNS.nowrap + BDFDB.disCN.marginbottom20} varcontainer" style="flex: 1 1 auto;"><div class="${BDFDB.disCNS.flex + BDFDB.disCNS.horizontal + BDFDB.disCNS.justifystart + BDFDB.disCNS.aligncenter + BDFDB.disCN.nowrap}" style="flex: 1 1 auto;"><h3 class="${BDFDB.disCNS.titledefault + BDFDB.disCNS.weightmedium + BDFDB.disCNS.titlesize16 + BDFDB.disCN.flexchild} BDFDB-textscrollwrapper" style="flex: 0 0 30%;"><div class="BDFDB-textscroll">${varname[0].toUpperCase() + varname.slice(1)}</div></h3><div class="${BDFDB.disCNS.inputwrapper + BDFDB.disCNS.vertical + BDFDB.disCNS.flex2 + BDFDB.disCN.directioncolumn}" style="flex: 1 1 auto;"><input type="text" option="${varname}" class="${BDFDB.disCNS.inputdefault + BDFDB.disCNS.input + BDFDB.disCN.titlesize16} varinput"></div><button type="button" class="${BDFDB.disCN.colorpickerswatch} single-swatch" style="background-color: black;"></button><button type="button" class="${BDFDB.disCNS.flexchild + BDFDB.disCNS.button + BDFDB.disCNS.buttonlookfilled + BDFDB.disCNS.buttoncolorbrand + BDFDB.disCNS.buttonsizemedium + BDFDB.disCN.buttongrow} file-navigator" style="flex: 0 0 auto;"><div class="${BDFDB.disCN.buttoncontents}"></div><input type="file" accept="image/*" style="display:none!important;"></button></div>${vardescription ? `<div class="${BDFDB.disCNS.description + BDFDB.disCNS.note + BDFDB.disCN.primary} BDFDB-textscrollwrapper" style="flex: 1 1 auto; max-width: ${maxwidth}px !important;"><div class="BDFDB-textscroll">${BDFDB.StringUtils.htmlEscape(vardescription)}</div></div>` : ""}${vars[vars.length-1] == varstr ? '' : `<div class="${BDFDB.disCNS.divider + BDFDB.disCN.dividerdefault}"></div>`}</div>`);
2019-09-24 13:49:14 +02:00
let varinput = varcontainer.querySelector(BDFDB.dotCN.input);
2019-09-25 17:35:00 +02:00
varinput.value = varvalue;
varinput.setAttribute("placeholder", varvalue);
let swatch = varcontainer.querySelector(".single-swatch");
let navigator = varcontainer.querySelector(".file-navigator");
2019-10-23 10:03:33 +02:00
let iscolor = BDFDB.ColorUtils.getType(varvalue);
2019-09-25 17:35:00 +02:00
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) {
2019-10-23 10:03:33 +02:00
let color = iscomp ? BDFDB.ColorUtils.convert(varvalue.split(","), "RGB") : varvalue;
2019-09-25 17:35:00 +02:00
swatch.style.setProperty("background-color", color, "important");
swatch.addEventListener("click", e => {
2019-10-23 11:10:01 +02:00
BDFDB.ColorUtils.openPicker(varcontainer, e.currentTarget, color, {gradient:false, comp:iscomp, alpha:iscolor});
2019-09-25 17:35:00 +02:00
});
}
2019-10-23 11:10:01 +02:00
else BDFDB.DOMUtils.remove(swatch);
2019-09-25 17:35:00 +02:00
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;
});
}
2019-10-23 11:10:01 +02:00
else BDFDB.DOMUtils.remove(navigator);
2019-09-25 17:35:00 +02:00
2019-09-24 13:49:14 +02:00
settingspanelinner.appendChild(varcontainer);
}
2018-12-12 12:13:27 +01:00
}
2019-01-26 22:45:19 +01:00
BDFDB.initElements(settingspanel, this);
2018-12-11 19:43:51 +01:00
2019-10-22 18:55:25 +02:00
BDFDB.ListenerUtils.add(this, settingspanel, "click", ".update-button", () => {
2019-09-11 12:14:43 +02:00
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");
2019-10-23 11:10:01 +02:00
css = css.replace(new RegExp(`--${BDFDB.StringUtils.regEscape(varname)}(\\s*):(\\s*)${BDFDB.StringUtils.regEscape(oldvalue)}`,"g"),`--${varname}$1:$2${newvalue}`);
amount++;
}
2018-12-11 19:43:51 +01:00
}
if (amount > 0) {
2019-09-11 12:14:43 +02:00
BDFDB.LibraryRequires.fs.writeFileSync(path, css);
2019-10-22 18:55:25 +02:00
BDFDB.NotificationUtils.toast(`Updated ${amount} variable${amount == 1 ? "" : "s"} in ${theme.filename}`, {type:"success"});
}
2019-10-22 18:55:25 +02:00
else BDFDB.NotificationUtils.toast(`There are no changed variables to be updated in ${theme.filename}`, {type:"warning"});
}
2019-10-22 18:55:25 +02:00
else BDFDB.NotificationUtils.toast(`Could not find themefile: ${theme.filename}`, {type:"error"});
});
2019-01-26 22:45:19 +01:00
wrapper.appendChild(settingspanel);
2018-12-11 19:43:51 +01:00
}
}