diff --git a/Plugins/PluginRepo/PluginRepo.plugin.js b/Plugins/PluginRepo/PluginRepo.plugin.js
index b9a7a3899e..5e2d9093ae 100644
--- a/Plugins/PluginRepo/PluginRepo.plugin.js
+++ b/Plugins/PluginRepo/PluginRepo.plugin.js
@@ -46,8 +46,8 @@ var PluginRepo = (_ => {
NEW: "New Plugins"
};
const orderKeys = {
- ASC: "Ascending",
- DESC: "Descending"
+ ASC: "ascending",
+ DESC: "descending"
};
const pluginRepoIcon = ``;
@@ -257,25 +257,14 @@ var PluginRepo = (_ => {
render() {
if (!this.props.tab) this.props.tab = "Plugins";
return [
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormTitle, {
- tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H2,
- className: BDFDB.disCN.marginbottom4,
- children: `Plugin Repo — ${loading.is ? 0 : this.props.amount || 0}/${loading.is ? 0 : Object.keys(loadedPlugins).length} Plugins`
- }),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
- className: BDFDB.disCNS.tabbarcontainer + BDFDB.disCN.tabbarcontainerbottom,
+ className: BDFDB.disCNS._repolistheader + BDFDB.disCN.marginbottom4,
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
children: [
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TabBar, {
- className: BDFDB.disCN.tabbar,
- itemClassName: BDFDB.disCN.tabbaritem,
- type: BDFDB.LibraryComponents.TabBar.Types.TOP,
- selectedItem: this.props.tab,
- items: [{value:"Plugins"}, {value:BDFDB.LanguageUtils.LanguageStrings.SETTINGS}],
- onItemSelect: (value, instance) => {
- this.props.tab = list.props.tab = value;
- BDFDB.ReactUtils.forceUpdate(list);
- }
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormTitle, {
+ tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H2,
+ className: BDFDB.disCN.marginreset,
+ children: `Plugin Repo — ${loading.is ? 0 : this.props.amount || 0}/${loading.is ? 0 : Object.keys(loadedPlugins).length}`
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SearchBar, {
@@ -293,10 +282,29 @@ var PluginRepo = (_ => {
BDFDB.ReactUtils.forceUpdate(this, list);
}
})
+ })
+ ]
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
+ className: BDFDB.disCNS.tabbarcontainer + BDFDB.disCN.tabbarcontainerbottom,
+ align: BDFDB.LibraryComponents.Flex.Align.CENTER,
+ children: [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TabBar, {
+ className: BDFDB.disCN.tabbar,
+ itemClassName: BDFDB.disCN.tabbaritem,
+ type: BDFDB.LibraryComponents.TabBar.Types.TOP,
+ selectedItem: this.props.tab,
+ items: [{value:"Plugins"}, {value:BDFDB.LanguageUtils.LanguageStrings.SETTINGS}],
+ onItemSelect: (value, instance) => {
+ this.props.tab = list.props.tab = value;
+ BDFDB.ReactUtils.forceUpdate(list);
+ }
+ })
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, {
- label: "Sort by:",
+ label: BDFDB.LanguageUtils.LibraryStrings.sort_by + ":",
value: {
label: sortKeys[this.props.sortKey],
value: this.props.sortKey
@@ -313,13 +321,13 @@ var PluginRepo = (_ => {
}),
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, {
- label: "Order:",
+ label: BDFDB.LanguageUtils.LibraryStrings.order + ":",
value: {
- label: orderKeys[this.props.orderKey],
+ label: BDFDB.LanguageUtils.LibraryStrings[orderKeys[this.props.orderKey]],
value: this.props.orderKey
},
options: Object.keys(orderKeys).map(key => ({
- label: orderKeys[key],
+ label: BDFDB.LanguageUtils.LibraryStrings[orderKeys[key]],
value: key
})),
onChange: (key, instance) => {
@@ -337,7 +345,7 @@ var PluginRepo = (_ => {
return class PluginRepo {
getName () {return "PluginRepo";}
- getVersion () {return "2.0.1";}
+ getVersion () {return "2.0.2";}
getAuthor () {return "DevilBro";}
diff --git a/Plugins/ThemeRepo/ThemeRepo.plugin.js b/Plugins/ThemeRepo/ThemeRepo.plugin.js
index 31fb2540cc..202c74dfda 100644
--- a/Plugins/ThemeRepo/ThemeRepo.plugin.js
+++ b/Plugins/ThemeRepo/ThemeRepo.plugin.js
@@ -3,6 +3,8 @@
var ThemeRepo = (_ => {
var _this;
var loading, cachedThemes, grabbedThemes, foundThemes, loadedThemes, generatorThemes, updateInterval;
+ var list, header, preview, searchTimeout, updateGeneratorTimeout, forceRerenderGenerator, forcedSort, forcedOrder, showOnlyOutdated;
+ var settings = {}, modalSettings = {}, favorites = [], customList = [];
const themeStates = {
UPDATED: 0,
@@ -44,89 +46,583 @@ var ThemeRepo = (_ => {
NEW: "New Themes"
};
const orderKeys = {
- ASC: "Ascending",
- DESC: "Descending"
+ ASC: "ascending",
+ DESC: "descending"
};
const themeRepoIcon = ``;
- const repoListComponent = class ThemeList extends BdApi.React.Component {
- render() {
- let list = BDFDB.ReactUtils.createElement("div", {
- className: BDFDB.disCN._repolist,
- style: {
- display: "flex",
- flexDirection: "column",
- margin: "unset",
- width: "unset"
- },
- children: [].concat(this.props.entries).filter(n => n).map(entry => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.AddonCard, entry))
+ const RepoListComponent = class ThemeList extends BdApi.React.Component {
+ componentDidMount() {
+ list = this;
+ BDFDB.TimeUtils.timeout(_ => {
+ forcedSort = null;
+ forcedOrder = null;
+ showOnlyOutdated = false;
+ }, 5000);
+ }
+ filterThemes() {
+ let themes = Object.keys(loadedThemes).map(url => {
+ let theme = loadedThemes[url];
+ let instTheme = BDFDB.BDUtils.getTheme(theme.name);
+ if (instTheme && instTheme.author.toUpperCase() == theme.author.toUpperCase()) theme.state = instTheme.version != theme.version ? themeStates.OUTDATED : themeStates.UPDATED;
+ else theme.state = themeStates.DOWNLOADABLE;
+ return {
+ url: theme.url,
+ requesturl: theme.requesturl,
+ search: (theme.name + " " + theme.version + " " + theme.author + " " + theme.description).toUpperCase(),
+ name: theme.name,
+ version: theme.version,
+ author: theme.author,
+ description: theme.description || "No Description found.",
+ fav: favorites.includes(url) ? favStates.FAVORIZED : favStates.NOT_FAVORIZED,
+ new: !cachedThemes.includes(url) ? newStates.NEW : newStates.NOT_NEW,
+ state: theme.state,
+ css: theme.css,
+ fullcss: theme.fullcss
+ };
});
- BDFDB.ReactUtils.forceStyle(list, ["display", "flex-direction", "margin", "width"]);
- return list;
+ if (!this.props.updated) themes = themes.filter(theme => theme.state != themeStates.UPDATED);
+ if (!this.props.outdated) themes = themes.filter(theme => theme.state != themeStates.OUTDATED);
+ if (!this.props.downloadable) themes = themes.filter(theme => theme.state != themeStates.DOWNLOADABLE);
+ if (this.props.searchString) {
+ let searchString = this.props.searchString.toUpperCase();
+ themes = themes.filter(theme => theme.search.indexOf(searchString) > -1).map(theme => Object.assign({}, theme, {
+ name: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.name, searchString))) || theme.name,
+ version: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.version, searchString))) || theme.version,
+ author: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.author, searchString))) || theme.author,
+ description: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.description, searchString))) || theme.description
+ }));
+ }
+
+ BDFDB.ArrayUtils.keySort(themes, (!this.props.sortKey || this.props.sortKey == "NEW" && !themes.some(theme => theme.new == newStates.NEW) ? Object.keys(sortKeys)[0] : this.props.sortKey).toLowerCase());
+ if (this.props.orderKey == "DESC") themes.reverse();
+ return themes;
+ }
+ openPreview() {
+ preview = BDFDB.WindowUtils.open(this, "https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/DiscordPreview.html", {
+ alwaysOnTop: settings.keepOnTop,
+ showOnReady: true,
+ frame: false,
+ onLoad: _ => {
+ let nativeCSS = document.querySelector("head link[rel='stylesheet'][integrity]");
+ let titleBar = document.querySelector(BDFDB.dotCN.titlebar);
+ preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "OnLoad",
+ username: ${JSON.stringify(BDFDB.UserUtils.me.username || "")},
+ id: ${JSON.stringify(BDFDB.UserUtils.me.id || "")},
+ discriminator: ${JSON.stringify(BDFDB.UserUtils.me.discriminator || "")},
+ avatar: ${JSON.stringify(BDFDB.UserUtils.getAvatar() || "")},
+ classes: ${JSON.stringify(JSON.stringify(BDFDB.DiscordClasses))},
+ classModules: ${JSON.stringify(JSON.stringify(BDFDB.DiscordClassModules))},
+ nativeCSS: ${JSON.stringify(nativeCSS && nativeCSS.href || "")},
+ htmlClassName: ${JSON.stringify(document.documentElement.className || "")},
+ titleBar: ${JSON.stringify(titleBar && titleBar.outerHTML || "")}
+ })`);
+ if (this.props.currentTheme) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "NewTheme",
+ checked: true,
+ css: ${JSON.stringify(this.props.currentTheme.css || "")}
+ })`);
+ if (this.props.currentGenerator) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "NewTheme",
+ checked: true,
+ css: ${JSON.stringify((loadedThemes[this.props.currentGenerator] || {}).fullcss || "")}
+ })`);
+ if (this.props.useLightMode) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "DarkLight",
+ checked: true
+ })`);
+ if (this.props.useNormalizer) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "Normalize",
+ checked: true
+ })`);
+ if (this.props.useCustomCSS) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "CustomCSS",
+ checked: true
+ })`);
+ if (this.props.useThemeFixer) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "ThemeFixer",
+ checked: true
+ })`);
+ },
+ onClose: _ => {
+ preview = null;
+ }
+ });
+ }
+ renderCard(theme) {
+ let buttonConfig = buttonData[(Object.entries(themeStates).find(n => n[1] == theme.state) || [])[0]];
+ return buttonConfig && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.AddonCard, {
+ data: theme,
+ controls: [
+ theme.new == newStates.NEW && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Badges.TextBadge, {
+ style: {
+ borderRadius: 3,
+ textTransform: "uppercase",
+ background: BDFDB.DiscordConstants.Colors.STATUS_YELLOW
+ },
+ text: BDFDB.LanguageUtils.LanguageStrings.NEW
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FavButton, {
+ className: BDFDB.disCN._repocontrolsbutton,
+ isFavorite: theme.fav == favStates.FAVORIZED,
+ onClick: value => {
+ theme.fav = value ? favStates.FAVORIZED : favStates.NOT_FAVORIZED;
+ if (value) favorites.push(theme.url);
+ else BDFDB.ArrayUtils.remove(favorites, theme.url, true);
+ BDFDB.DataUtils.save(favorites, _this, "favorites");
+ }
+ }),
+ BDFDB.ReactUtils.createElement("div", {
+ className: BDFDB.disCN._repocontrolsbutton,
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
+ text: "Go to Source",
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
+ name: BDFDB.LibraryComponents.SvgIcon.Names.GITHUB,
+ className: BDFDB.disCN._repoicon,
+ onClick: _ => {
+ let gitUrl = null;
+ if (theme.url.indexOf("https://raw.githubusercontent.com") == 0) {
+ let temp = theme.url.replace("//raw.githubusercontent", "//github").split("/");
+ temp.splice(5, 0, "blob");
+ gitUrl = temp.join("/");
+ }
+ else if (theme.url.indexOf("https://gist.githubusercontent.com/") == 0) {
+ gitUrl = theme.url.replace("//gist.githubusercontent", "//gist.github").split("/raw/")[0];
+ }
+ if (gitUrl) BDFDB.DiscordUtils.openLink(gitUrl, settings.useChromium);
+ }
+ })
+ })
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Switch, {
+ value: this.props.currentTheme && this.props.currentTheme.url == theme.url,
+ onChange: (value, instance) => {
+ if (value) this.props.currentTheme = theme;
+ else delete this.props.currentTheme;
+ delete this.props.currentGenerator;
+ delete this.props.generatorValues;
+ if (preview) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "NewTheme",
+ checked: ${value},
+ css: ${JSON.stringify(theme.css || "")}
+ })`);
+ else this.openPreview();
+ BDFDB.ReactUtils.forceUpdate(this);
+ }
+ })
+ ],
+ buttons: [
+ theme.state != themeStates.DOWNLOADABLE && BDFDB.ReactUtils.createElement("div", {
+ className: BDFDB.disCN._repocontrolsbutton,
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
+ text: "Delete Themefile",
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
+ name: BDFDB.LibraryComponents.SvgIcon.Names.NOVA_TRASH,
+ className: BDFDB.disCN._repoicon,
+ onClick: (e, instance) => {
+ _this.removeTheme(theme);
+ _this.deleteThemeFile(theme);
+ BDFDB.TimeUtils.timeout(_ => {
+ BDFDB.ReactUtils.forceUpdate(this);
+ }, 3000);
+ }
+ })
+ })
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
+ size: BDFDB.LibraryComponents.Button.Sizes.MIN,
+ color: BDFDB.LibraryComponents.Button.Colors[buttonConfig.colorClass],
+ style: {backgroundColor: BDFDB.DiscordConstants.Colors[buttonConfig.backgroundColor]},
+ children: buttonConfig.text,
+ onClick: (e, instance) => {
+ _this.downloadTheme(theme);
+ BDFDB.TimeUtils.timeout(_ => {
+ BDFDB.ReactUtils.forceUpdate(this);
+ if (this.props.rnmStart) _this.applyTheme(theme);
+ }, 3000);
+ }
+ })
+ ]
+ });
+ }
+ render() {
+ let automaticLoading = BDFDB.BDUtils.getSettings(BDFDB.BDUtils.settingsIds.automaticLoading);
+ if (!this.props.tab) this.props.tab = "Themes";
+ this.props.entries = (!loading.is && !BDFDB.ObjectUtils.isEmpty(loadedThemes) ? this.filterThemes() : []).map(theme => this.renderCard(theme)).filter(n => n);
+
+ BDFDB.TimeUtils.timeout(_ => {
+ if (!loading.is && header && this.props.entries.length != header.props.amount) {
+ header.props.amount = this.props.entries.length;
+ BDFDB.ReactUtils.forceUpdate(header);
+ }
+ });
+
+ if (forceRerenderGenerator && this.props.tab == "Generator") BDFDB.TimeUtils.timeout(_ => {
+ forceRerenderGenerator = false;
+ BDFDB.ReactUtils.forceUpdate(this);
+ });
+
+ return [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, {
+ tab: "Themes",
+ open: this.props.tab == "Themes",
+ render: false,
+ children: loading.is ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
+ direction: BDFDB.LibraryComponents.Flex.Direction.VERTICAL,
+ justify: BDFDB.LibraryComponents.Flex.Justify.CENTER,
+ style: {marginTop: "50%"},
+ children: [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Spinner, {
+ type: BDFDB.LibraryComponents.Spinner.Type.WANDERING_CUBES
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextElement, {
+ className: BDFDB.disCN.margintop20,
+ style: {textAlign: "center"},
+ children: "Themes are still being fetched. Please wait a moment."
+ })
+ ]
+ }) : BDFDB.ReactUtils.forceStyle(BDFDB.ReactUtils.createElement("div", {
+ className: BDFDB.disCN._repolist,
+ style: {
+ display: "flex",
+ flexDirection: "column",
+ margin: "unset",
+ width: "unset"
+ },
+ children: this.props.entries
+ }), ["display", "flex-direction", "margin", "width"])
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, {
+ tab: "Generator",
+ open: this.props.tab == "Generator",
+ render: false,
+ children: [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Select",
+ label: "Choose a Generator Theme",
+ basis: "60%",
+ value: this.props.currentGenerator || "-----",
+ options: ["-----"].concat(generatorThemes).map(url => ({value:url, label:(loadedThemes[url] || {}).name || "-----"})).sort((x, y) => (x.label < y.label ? -1 : x.label > y.label ? 1 : 0)),
+ searchable: true,
+ onChange: (value, instance) => {
+ if (loadedThemes[value.value]) {
+ if (this.props.currentGenerator) forceRerenderGenerator = true;
+ this.props.currentGenerator = value.value;
+ this.props.generatorValues = {};
+ }
+ else {
+ delete this.props.currentGenerator;
+ delete this.props.generatorValues;
+ }
+ delete this.props.currentTheme;
+ if (preview) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "NewTheme",
+ checked: true,
+ css: ${JSON.stringify((loadedThemes[value.value] || {}).fullcss || "")}
+ })`);
+ else this.openPreview();
+ BDFDB.ReactUtils.forceUpdate(this);
+ }
+ }),
+ !this.props.currentGenerator ? null : (forceRerenderGenerator ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
+ direction: BDFDB.LibraryComponents.Flex.Direction.VERTICAL,
+ justify: BDFDB.LibraryComponents.Flex.Justify.CENTER,
+ style: {marginTop: "50%"},
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Spinner, {
+ type: BDFDB.LibraryComponents.Spinner.Type.WANDERING_CUBES
+ })
+ }) : [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Button",
+ label: "Download generated Theme",
+ children: "Download",
+ onClick: _ => {
+ _this.createThemeFile(this.props.currentGenerator.name + ".theme.css", _this.generateTheme(this.props.currentGenerator, this.props.generatorValues));
+ }
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
+ className: BDFDB.disCN.marginbottom20
+ }),
+ (_ => {
+ let vars = loadedThemes[this.props.currentGenerator].fullcss.split(":root");
+ if (vars.length < 2) return null;
+ 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];
+ vars = vars.slice(2).split(/;--|\*\/--/);
+ let inputRefs = [];
+ for (let varStr of vars) {
+ varStr = varStr.split(":");
+ let varName = varStr.shift().trim();
+ varStr = varStr.join(":").split(/;[^A-z0-9]|\/\*/);
+ let oldValue = varStr.shift().trim();
+ if (oldValue) {
+ let childType = "text", childMode = "";
+ let isColor = BDFDB.ColorUtils.getType(oldValue);
+ let isComp = !isColor && /[0-9 ]+,[0-9 ]+,[0-9 ]+/g.test(oldValue);
+ if (isColor || isComp) {
+ childType = "color";
+ childMode = isComp && "comp";
+ }
+ else {
+ let isUrlFile = /url\(.+\)/gi.test(oldValue);
+ let isFile = !isUrlFile && /(http(s)?):\/\/[(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.test(oldValue);
+ if (isFile || isUrlFile) {
+ childType = "file";
+ childMode = isUrlFile && "url";
+ }
+ }
+ let varDescription = varStr.join("").replace(/\*\/|\/\*/g, "").replace(/:/g, ": ").replace(/: \//g, ":/").replace(/--/g, " --").replace(/\( --/g, "(--").trim();
+ this.props.generatorValues[varName] = {value:oldValue, oldValue};
+ inputRefs.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%",
+ value: oldValue,
+ placeholder: oldValue,
+ onChange: value => {
+ BDFDB.TimeUtils.clear(updateGeneratorTimeout);
+ updateGeneratorTimeout = BDFDB.TimeUtils.timeout(_ => {
+ this.props.generatorValues[varName] = {value, oldValue};
+ if (preview) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "NewTheme",
+ checked: true,
+ css: ${JSON.stringify(_this.generateTheme(loadedThemes[this.props.currentGenerator], this.props.generatorValues) || "")}
+ })`);
+ }, 1000);
+ }
+ }));
+ }
+ }
+ return inputRefs;
+ })()
+ ])
+ ].flat(10).filter(n => n)
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, {
+ tab: BDFDB.LanguageUtils.LanguageStrings.SETTINGS,
+ open: this.props.tab == BDFDB.LanguageUtils.LanguageStrings.SETTINGS,
+ render: false,
+ children: [
+ !automaticLoading && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
+ className: BDFDB.disCN.marginbottom20,
+ children: BDFDB.ReactUtils.createElement("div", {
+ className: BDFDB.disCNS.titledefault + BDFDB.disCN.cursordefault,
+ children: "To experience ThemeRepo in the best way. I would recommend you to enable BD intern reload function, that way all downloaded files are loaded into Discord without the need to reload."
+ })
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Switch",
+ label: "Preview in light mode",
+ value: this.props.useLightMode,
+ onChange: (value, instance) => {
+ this.props.useLightMode = value;
+ if (preview) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "DarkLight",
+ checked: ${this.props.useLightMode}
+ })`);
+ }
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Switch",
+ label: "Preview with useNormalizer classes",
+ value: this.props.useNormalizer,
+ onChange: (value, instance) => {
+ this.props.useNormalizer = value;
+ if (preview) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "Normalize",
+ checked: ${this.props.useNormalizer}
+ })`);
+ }
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Switch",
+ label: "Include Custom CSS in Preview",
+ value: this.props.useCustomCSS,
+ onChange: (value, instance) => {
+ this.props.useCustomCSS = value;
+ let customCSS = document.querySelector("style#customcss");
+ if (preview && customCSS && customCSS.innerText.length > 0) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "CustomCSS",
+ checked: ${this.props.useCustomCSS},
+ css: ${JSON.stringify(customCSS.innerText || "")}
+ })`);
+ }
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Switch",
+ label: "Include ThemeFixer CSS in Preview",
+ value: this.props.useThemeFixer,
+ onChange: (value, instance) => {
+ this.props.useThemeFixer = value;
+ BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/ThemeFixer.css", (error, response, body) => {
+ if (preview) preview.executeJavaScriptSafe(`window.onmessage({
+ origin: "ThemeRepo",
+ reason: "ThemeFixer",
+ checked: ${this.props.useThemeFixer},
+ css: ${JSON.stringify(_this.createFixerCSS(body) || "")}
+ })`);
+ });
+ }
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Button",
+ label: "Download ThemeFixer",
+ children: "Download",
+ onClick: _ => {
+ BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/ThemeFixer.css", (error, response, body) => {
+ _this.createThemeFile("ThemeFixer.theme.css", `//META{"name":"ThemeFixer","description":"ThemeFixerCSS for transparent themes","author":"DevilBro","version":"1.0.3","authorId":"278543574059057154","invite":"Jx3TjNS","donate":"https://www.paypal.me/MircoWittrien","patreon":"https://www.patreon.com/MircoWittrien"}*//\n\n` + _this.createFixerCSS(body));
+ });
+ }
+ }),
+ Object.keys(modalSettings).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
+ className: BDFDB.disCN.marginbottom20,
+ type: "Switch",
+ plugin: _this,
+ keys: ["modalSettings", key],
+ label: _this.defaults.modalSettings[key].description,
+ note: key == "rnmStart" && !automaticLoading && "Automatic Loading has to be enabled",
+ disabled: key == "rnmStart" && !automaticLoading,
+ value: this.props[key],
+ onChange: (value, instance) => {
+ this.props[key] = value;
+ BDFDB.ReactUtils.forceUpdate(this);
+ }
+ }))
+ ].flat(10).filter(n => n)
+ })
+ ];
}
};
- let forceRerenderGenerator;
- const generatorComponent = class ThemeGenerator extends BdApi.React.Component {
+ const RepoListHeaderComponent = class ThemeListHeader extends BdApi.React.Component {
+ componentDidMount() {
+ header = this;
+ }
render() {
- if (forceRerenderGenerator) {
- BDFDB.TimeUtils.timeout(_ => {
- forceRerenderGenerator = false;
- BDFDB.ReactUtils.forceUpdate(this);
- }, 500);
- }
- let theme = this.props.options && loadedThemes[this.props.options.currentGenerator];
- return !this.props.options || !this.props.options.preview ? null : [
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Select",
- label: "Choose a Generator Theme",
- basis: "70%",
- value: this.props.options.currentGenerator || "-----",
- options: ["-----"].concat(generatorThemes).map(url => {return {value:url, label:(loadedThemes[url] || {}).name || "-----"}}).sort((x, y) => (x.label < y.label ? -1 : x.label > y.label ? 1 : 0)),
- searchable: true,
- onChange: (value, instance) => {
- if (loadedThemes[value.value]) {
- if (this.props.options.currentGenerator) forceRerenderGenerator = true;
- this.props.options.currentGenerator = value.value;
- this.props.options.generatorValues = {};
- }
- else {
- delete this.props.options.currentGenerator;
- delete this.props.options.generatorValues;
- }
- delete this.props.options.currentTheme;
- _this.updateList(instance, this.props.options);
- this.props.options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "NewTheme",
- checked: true,
- css: ${JSON.stringify((loadedThemes[value.value] || {}).fullcss || "")}
- })`);
- }
+ if (!this.props.tab) this.props.tab = "Themes";
+ return [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
+ className: BDFDB.disCNS._repolistheader + BDFDB.disCN.marginbottom4,
+ align: BDFDB.LibraryComponents.Flex.Align.CENTER,
+ children: [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormTitle, {
+ tag: BDFDB.LibraryComponents.FormComponents.FormTitle.Tags.H2,
+ className: BDFDB.disCN.marginreset,
+ children: `Theme Repo — ${loading.is ? 0 : this.props.amount || 0}/${loading.is ? 0 : Object.keys(loadedThemes).length}`
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SearchBar, {
+ autoFocus: true,
+ query: this.props.searchString,
+ onChange: (value, instance) => {
+ BDFDB.TimeUtils.clear(searchTimeout);
+ searchTimeout = BDFDB.TimeUtils.timeout(_ => {
+ this.props.searchString = list.props.searchString = value.replace(/[<|>]/g, "");
+ BDFDB.ReactUtils.forceUpdate(this, list);
+ }, 1000);
+ },
+ onClear: instance => {
+ this.props.searchString = list.props.searchString = "";
+ BDFDB.ReactUtils.forceUpdate(this, list);
+ }
+ })
+ })
+ ]
}),
- theme && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Button",
- label: "Download generated Theme",
- children: "Download",
- onClick: _ => {
- _this.createThemeFile(theme.name + ".theme.css", _this.generateTheme(theme, this.props.options));
- }
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
- className: BDFDB.disCN.marginbottom20
- }),
- theme && !forceRerenderGenerator && _this.createGeneratorInputs(theme, this.props.options)
- ].flat(10).filter(n => n)
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
+ className: BDFDB.disCNS.tabbarcontainer + BDFDB.disCN.tabbarcontainerbottom,
+ align: BDFDB.LibraryComponents.Flex.Align.CENTER,
+ children: [
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TabBar, {
+ className: BDFDB.disCN.tabbar,
+ itemClassName: BDFDB.disCN.tabbaritem,
+ type: BDFDB.LibraryComponents.TabBar.Types.TOP,
+ selectedItem: this.props.tab,
+ items: [{value:"Themes"}, {value:"Generator"}, {value:BDFDB.LanguageUtils.LanguageStrings.SETTINGS}],
+ onItemSelect: (value, instance) => {
+ this.props.tab = list.props.tab = value;
+ BDFDB.ReactUtils.forceUpdate(list);
+ }
+ })
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, {
+ label: BDFDB.LanguageUtils.LibraryStrings.sort_by + ":",
+ value: {
+ label: sortKeys[this.props.sortKey],
+ value: this.props.sortKey
+ },
+ options: Object.keys(sortKeys).filter(n => n != "NEW" || Object.keys(loadedThemes).some(p => !cachedThemes.includes(p))).map(key => ({
+ label: sortKeys[key],
+ value: key
+ })),
+ onChange: (key, instance) => {
+ this.props.sortKey = list.props.sortKey = key;
+ BDFDB.ReactUtils.forceUpdate(this, list);
+ }
+ })
+ }),
+ BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
+ children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, {
+ label: BDFDB.LanguageUtils.LibraryStrings.order + ":",
+ value: {
+ label: BDFDB.LanguageUtils.LibraryStrings[orderKeys[this.props.orderKey]],
+ value: this.props.orderKey
+ },
+ options: Object.keys(orderKeys).map(key => ({
+ label: BDFDB.LanguageUtils.LibraryStrings[orderKeys[key]],
+ value: key
+ })),
+ onChange: (key, instance) => {
+ this.props.orderKey = list.props.orderKey = key;
+ BDFDB.ReactUtils.forceUpdate(this, list);
+ }
+ })
+ })
+ ]
+ })
+ ]
}
};
return class ThemeRepo {
getName () {return "ThemeRepo";}
- getVersion () {return "1.9.9";}
+ getVersion () {return "2.0.2";}
getAuthor () {return "DevilBro";}
@@ -134,12 +630,15 @@ var ThemeRepo = (_ => {
constructor () {
this.changelog = {
- "fixed":[["Moved repo button","Repo button is now an item in the settings sidebar instead of an extra button in the themes page"]]
+ "improved":[["Inbuilt Repo","The plugin repo no longer opens a modal to display the repo, instead the list is rendered in the settings window"]]
};
this.patchedModules = {
before: {
SettingsView: "render"
+ },
+ after: {
+ StandardSidebarView: "render"
}
};
}
@@ -181,8 +680,7 @@ var ThemeRepo = (_ => {
getSettingsPanel (collapseStates = {}) {
if (!window.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return;
- let settings = BDFDB.DataUtils.get(this, "settings");
- let customList = this.getCustomList(), customUrl = "";
+ let customUrl = "";
let settingsPanel, settingsItems = [];
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
@@ -300,12 +798,19 @@ var ThemeRepo = (_ => {
if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) {
if (this.started) return;
BDFDB.PluginUtils.init(this);
+
+ let oldfavorites = BDFDB.DataUtils.load(this, "favorites"); // REMOVE 26.07.2020
+ if (BDFDB.ObjectUtils.is(oldfavorites) && Object.keys(oldfavorites).length) {
+ let newfavorites = [];
+ for (let url of oldfavorites) if (oldfavorites[url]) newfavorites.push(url);
+ BDFDB.DataUtils.save(newfavorites, this, "favorites");
+ }
+
+ this.forceUpdateAll();
this.loadThemes();
updateInterval = BDFDB.TimeUtils.interval(_ => {this.checkForNewThemes();}, 1000*60*30);
-
- BDFDB.ModuleUtils.forceAllUpdates(this);
}
else console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not load BD functions!");
}
@@ -318,7 +823,7 @@ var ThemeRepo = (_ => {
BDFDB.TimeUtils.clear(updateInterval);
BDFDB.TimeUtils.clear(loading.timeout);
- BDFDB.ModuleUtils.forceAllUpdates(this);
+ this.forceUpdateAll();
BDFDB.DOMUtils.remove(".bd-themerepobutton", ".themerepo-notice", ".themerepo-loadingicon");
@@ -328,6 +833,24 @@ var ThemeRepo = (_ => {
// Begin of own functions
+
+ forceUpdateAll () {
+ settings = BDFDB.DataUtils.get(this, "settings");
+ modalSettings = BDFDB.DataUtils.get(this, "modalSettings");
+ favorites = BDFDB.DataUtils.load(this, "favorites");
+ favorites = BDFDB.ArrayUtils.is(favorites) ? favorites : [];
+ customList = BDFDB.DataUtils.load(this, "custom");
+ customList = BDFDB.ArrayUtils.is(customList) ? customList : [];
+
+ BDFDB.ModuleUtils.forceAllUpdates(this);
+ }
+
+ onSettingsClosed () {
+ if (this.SettingsUpdated) {
+ delete this.SettingsUpdated;
+ this.forceUpdateAll();
+ }
+ }
onUserSettingsCogContextMenu (e) {
BDFDB.TimeUtils.timeout(_ => {
@@ -336,8 +859,8 @@ var ThemeRepo = (_ => {
label: "Theme Repo",
id: BDFDB.ContextMenuUtils.createItemId(this.name, "repo"),
action: _ => {
- if (!loading.is) BDFDB.ContextMenuUtils.close(e.instance);
- this.openThemeRepoModal();
+ BDFDB.ContextMenuUtils.close(e.instance);
+ BDFDB.LibraryModules.UserSettingsUtils.open("themerepo");
}
}));
});
@@ -353,390 +876,44 @@ var ThemeRepo = (_ => {
e.instance.props.sections.splice(oldSettings ? index + 1 : index - 1, 0, {
label: "Theme Repo",
section: "themerepo",
- onClick: _ => {this.openThemeRepoModal();}
+ element: _ => {
+ let options = Object.assign({}, modalSettings);
+ options.updated = options.updated && !showOnlyOutdated;
+ options.outdated = options.outdated || showOnlyOutdated;
+ options.downloadable = options.downloadable && !showOnlyOutdated;
+ options.searchString = "";
+ options.sortKey = forcedSort || Object.keys(sortKeys)[0];
+ options.orderKey = forcedOrder || Object.keys(orderKeys)[0];
+ options.useLightMode = BDFDB.DiscordUtils.getTheme() == BDFDB.disCN.themelight;
+ options.useNormalizer = BDFDB.BDUtils.getSettings(BDFDB.BDUtils.settingsIds.normalizedClasses);
+ options.useThemeFixer = false;
+ options.useCustomCSS = false;
+
+ return BDFDB.ReactUtils.createElement(RepoListComponent, options);
+ }
});
if (oldSettings && !isPRinjected) e.instance.props.sections.splice(index + 1, 0, {section: "DIVIDER"});
}
}
}
- getCustomList () {
- let customList = BDFDB.DataUtils.load(this, "custom");
- return BDFDB.ArrayUtils.is(customList) ? customList : [];
- }
-
-
- openThemeRepoModal (options = {}) {
- if (loading.is) BDFDB.NotificationUtils.toast(`Themes are still being fetched. Try again in some seconds.`, {type:"danger"});
- else {
- let modalSettings = BDFDB.DataUtils.get(this, "modalSettings");
- let searchTimeout, automaticLoading = BDFDB.BDUtils.getSettings(BDFDB.BDUtils.settingsIds.automaticLoading);
- options = Object.assign(options, modalSettings);
- options.updated = options.updated && !options.showOnlyOutdated;
- options.outdated = options.updated || options.showOnlyOutdated;
- options.downloadable = options.downloadable && !options.showOnlyOutdated;
- options.searchString = "";
- options.sortKey = options.forcedSort || Object.keys(sortKeys)[0];
- options.orderKey = options.forcedOrder || Object.keys(orderKeys)[0];
-
- options.preview = BDFDB.WindowUtils.open(this, "https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/DiscordPreview.html", {
- alwaysOnTop: BDFDB.DataUtils.get(this, "settings", "keepOnTop"),
- showOnReady: true,
- frame: false,
- onLoad: _ => {
- let nativeCSS = document.querySelector("head link[rel='stylesheet'][integrity]");
- let titleBar = document.querySelector(BDFDB.dotCN.titlebar);
- options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "OnLoad",
- username: ${JSON.stringify(BDFDB.UserUtils.me.username || "")},
- id: ${JSON.stringify(BDFDB.UserUtils.me.id || "")},
- discriminator: ${JSON.stringify(BDFDB.UserUtils.me.discriminator || "")},
- avatar: ${JSON.stringify(BDFDB.UserUtils.getAvatar() || "")},
- classes: ${JSON.stringify(JSON.stringify(BDFDB.DiscordClasses))},
- classModules: ${JSON.stringify(JSON.stringify(BDFDB.DiscordClassModules))},
- nativeCSS: ${JSON.stringify(nativeCSS && nativeCSS.href || "")},
- htmlClassName: ${JSON.stringify(document.documentElement.className || "")},
- titleBar: ${JSON.stringify(titleBar && titleBar.outerHTML || "")}
- })`);
- options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "DarkLight",
- checked: ${BDFDB.DiscordUtils.getTheme() == BDFDB.disCN.themelight}
- })`);
- }
- });
-
- let entries = this.createEntries(options);
- BDFDB.ModalUtils.open(this, {
- className: "repo-modal",
- size: "LARGE",
- header: "Theme Repository",
- subheader: BDFDB.ReactUtils.createElement(class RepoAmount extends BDFDB.ReactUtils.Component {
- render () {return `${this.props.entries.length}/${Object.keys(loadedThemes).length} Themes`}
- }, {entries}),
- tabBarChildren: [
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
- children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SearchBar, {
- autoFocus: true,
- query: options.searchString,
- onChange: (value, instance) => {
- BDFDB.TimeUtils.clear(searchTimeout);
- searchTimeout = BDFDB.TimeUtils.timeout(_ => {
- options.searchString = value.replace(/[<|>]/g, "").toUpperCase();
- this.updateList(instance, options);
- }, 1000);
- },
- onClear: instance => {
- options.searchString = "";
- this.updateList(instance, options);
- }
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
- children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, {
- label: "Sort by:",
- value: {
- label: sortKeys[options.sortKey],
- value: options.sortKey
- },
- options: Object.keys(sortKeys).filter(n => n != "NEW" || Object.keys(loadedThemes).some(t => !cachedThemes.includes(t))).map(key => ({
- label: sortKeys[key],
- value: key
- })),
- onChange: (key, instance) => {
- options.sortKey = key;
- this.updateList(instance, options);
- }
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
- children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, {
- label: "Order:",
- value: {
- label: orderKeys[options.orderKey],
- value: options.orderKey
- },
- options: Object.keys(orderKeys).map(key => ({
- label: orderKeys[key],
- value: key
- })),
- onChange: (key, instance) => {
- options.orderKey = key;
- this.updateList(instance, options);
- }
- })
- })
- ],
- children: [
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, {
- tab: "Themes",
- children: BDFDB.ReactUtils.createElement(repoListComponent, {
- entries: entries
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, {
- tab: "Generator",
- children: BDFDB.ReactUtils.createElement(generatorComponent, {
- options: options
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, {
- tab: BDFDB.LanguageUtils.LanguageStrings.SETTINGS,
- children: [
- !automaticLoading && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
- className: BDFDB.disCN.marginbottom8,
- children: BDFDB.ReactUtils.createElement("div", {
- className: BDFDB.disCNS.titledefault + BDFDB.disCN.cursordefault,
- style: {maxWidth: 760},
- children: "To experience ThemeRepo in the best way. I would recommend you to enable BD intern reload function, that way all downloaded files are loaded into Discord without the need to reload."
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
- className: BDFDB.disCN.marginbottom20,
- children: BDFDB.ReactUtils.createElement("div", {
- className: BDFDB.disCNS.titledefault + BDFDB.disCN.cursordefault,
- style: {maxWidth: 760},
- children: "You can toggle this menu with the 'Ctrl' key to take a better look at the preview."
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Switch",
- label: "Preview in light mode",
- value: BDFDB.DiscordUtils.getTheme() == BDFDB.disCN.themelight,
- onChange: (value, instance) => {
- options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "DarkLight",
- checked: ${value}
- })`);
- }
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Switch",
- label: "Preview with normalized classes",
- value: BDFDB.BDUtils.getSettings(BDFDB.BDUtils.settingsIds.normalizedClasses),
- onChange: (value, instance) => {
- options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "Normalize",
- checked: ${value}
- })`);
- }
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Switch",
- label: "Include Custom CSS in Preview",
- value: false,
- onChange: (value, instance) => {
- let customCSS = document.querySelector("style#customcss");
- if (customCSS && customCSS.innerText.length > 0) options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "CustomCSS",
- checked: ${value},
- css: ${JSON.stringify(customCSS.innerText || "")}
- })`);
- }
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Switch",
- label: "Include ThemeFixer CSS in Preview",
- value: false,
- onChange: (value, instance) => {
- BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/ThemeFixer.css", (error, response, body) => {
- options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "ThemeFixer",
- checked: ${value},
- css: ${JSON.stringify(this.createFixerCSS(body) || "")}
- })`);
- });
- }
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Button",
- label: "Download ThemeFixer",
- children: "Download",
- onClick: _ => {
- BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/ThemeFixer.css", (error, response, body) => {
- this.createThemeFile("ThemeFixer.theme.css", `//META{"name":"ThemeFixer","description":"ThemeFixerCSS for transparent themes","author":"DevilBro","version":"1.0.3","authorId":"278543574059057154","invite":"Jx3TjNS","donate":"https://www.paypal.me/MircoWittrien","patreon":"https://www.patreon.com/MircoWittrien"}*//\n\n` + this.createFixerCSS(body));
- });
- }
- }),
- Object.keys(modalSettings).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
- className: BDFDB.disCN.marginbottom20,
- type: "Switch",
- plugin: this,
- keys: ["modalSettings", key],
- label: this.defaults.modalSettings[key].description,
- note: key == "rnmStart" && !automaticLoading && "Automatic Loading has to be enabled",
- disabled: key == "rnmStart" && !automaticLoading,
- value: options[key],
- onChange: (value, instance) => {
- options[key] = value;
- this.updateList(instance, options);
- }
- }))
- ].flat(10).filter(n => n)
- })
- ],
- onClose: (modal, instance) => {
- BDFDB.WindowUtils.close(options.preview);
- }
- });
- }
- }
-
- updateList (instance, options = {}) {
- let modalIns = BDFDB.ReactUtils.findOwner(instance, {name:"BDFDB_Modal", up:true});
- if (modalIns) {
- let amountIns = BDFDB.ReactUtils.findOwner(modalIns, {name:"RepoAmount"});
- let listIns = BDFDB.ReactUtils.findOwner(modalIns, {name:"ThemeList"});
- let genIns = BDFDB.ReactUtils.findOwner(modalIns, {name:"ThemeGenerator"});
- if (amountIns && listIns && genIns) {
- let entries = this.createEntries(options);
- amountIns.props.entries = entries;
- listIns.props.entries = entries;
- BDFDB.ReactUtils.forceUpdate(amountIns, listIns, genIns);
+ processStandardSidebarView (e) {
+ if (BDFDB.ReactUtils.getValue(e, "instance.props.content.props.section") == "themerepo") {
+ let content = BDFDB.ReactUtils.findChild(e.returnvalue, {props: [["className", BDFDB.disCN.settingswindowcontentregion]]});
+ if (content) content.props.className = BDFDB.DOMUtils.formatClassName(BDFDB.disCN._repolistwrapper, content.props.className);
+ let [children, index] = BDFDB.ReactUtils.findParent(e.returnvalue, {props: [["className", BDFDB.disCN.settingswindowcontentregionscroller]]});
+ if (index > -1) {
+ let options = {};
+ options.searchString = "";
+ options.sortKey = forcedSort || Object.keys(sortKeys)[0];
+ options.orderKey = forcedOrder || Object.keys(orderKeys)[0];
+ children[index] = [
+ BDFDB.ReactUtils.createElement(RepoListHeaderComponent, options),
+ children[index]
+ ];
}
}
}
-
- createEntries (options = {}) {
- let favorites = BDFDB.DataUtils.load(this, "favorites");
- let themes = Object.keys(loadedThemes).map(url => {
- let theme = loadedThemes[url];
- let instTheme = BDFDB.BDUtils.getTheme(theme.name);
- if (instTheme && instTheme.author.toUpperCase() == theme.author.toUpperCase()) theme.state = instTheme.version != theme.version ? themeStates.OUTDATED : themeStates.UPDATED;
- else theme.state = themeStates.DOWNLOADABLE;
- return {
- url: theme.url,
- requesturl: theme.requesturl,
- search: (theme.name + " " + theme.version + " " + theme.author + " " + theme.description).toUpperCase(),
- name: theme.name,
- version: theme.version,
- author: theme.author,
- description: theme.description || "No Description found.",
- fav: favorites[url] ? favStates.FAVORIZED : favStates.NOT_FAVORIZED,
- new: !cachedThemes.includes(url) ? newStates.NEW : newStates.NOT_NEW,
- state: theme.state,
- css: theme.css,
- fullcss: theme.fullcss
- };
- });
- if (!options.updated) themes = themes.filter(theme => theme.state != themeStates.UPDATED);
- if (!options.outdated) themes = themes.filter(theme => theme.state != themeStates.OUTDATED);
- if (!options.downloadable) themes = themes.filter(theme => theme.state != themeStates.DOWNLOADABLE);
- if (options.searchString) themes = themes.filter(theme => theme.search.indexOf(options.searchString) > -1).map(theme => Object.assign({}, theme, {
- name: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.name, options.searchString))) || theme.name,
- version: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.version, options.searchString))) || theme.version,
- author: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.author, options.searchString))) || theme.author,
- description: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(theme.description, options.searchString))) || theme.description
- }));
-
- BDFDB.ArrayUtils.keySort(themes, (options.sortKey == "NEW" && !themes.some(theme => theme.new == newStates.NEW) ? Object.keys(sortKeys)[0] : options.sortKey).toLowerCase());
- if (options.orderKey == "DESC") themes.reverse();
- return themes.map(theme => {
- let buttonConfig = buttonData[(Object.entries(themeStates).find(n => n[1] == theme.state) || [])[0]]
- return buttonConfig && {
- data: theme,
- controls: [
- theme.new == newStates.NEW && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Badges.TextBadge, {
- style: {
- borderRadius: 3,
- textTransform: "uppercase",
- background: BDFDB.DiscordConstants.Colors.STATUS_YELLOW
- },
- text: BDFDB.LanguageUtils.LanguageStrings.NEW
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FavButton, {
- className: BDFDB.disCN._repocontrolsbutton,
- isFavorite: theme.fav == favStates.FAVORIZED,
- onClick: value => {
- theme.fav = value ? favStates.FAVORIZED : favStates.NOT_FAVORIZED;
- if (value) BDFDB.DataUtils.save(true, this, "favorites", theme.url);
- else BDFDB.DataUtils.remove(this, "favorites", theme.url);
- }
- }),
- BDFDB.ReactUtils.createElement("div", {
- className: BDFDB.disCN._repocontrolsbutton,
- children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
- text: "Go to Source",
- children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
- name: BDFDB.LibraryComponents.SvgIcon.Names.GITHUB,
- className: BDFDB.disCN._repoicon,
- onClick: _ => {
- let gitUrl = null;
- if (theme.requesturl.indexOf("https://raw.githubusercontent.com") == 0) {
- let temp = theme.requesturl.replace("//raw.githubusercontent", "//github").split("/");
- temp.splice(5, 0, "blob");
- gitUrl = temp.join("/");
- }
- else if (theme.requesturl.indexOf("https://gist.githubusercontent.com/") == 0) {
- gitUrl = theme.requesturl.replace("//gist.githubusercontent", "//gist.github").split("/raw/")[0];
- }
- if (gitUrl) BDFDB.DiscordUtils.openLink(gitUrl, BDFDB.DataUtils.get(this, "settings", "useChromium"));
- }
- })
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Switch, {
- value: options.currentTheme == theme.url,
- onChange: (value, instance) => {
- if (value) options.currentTheme = theme.url;
- else delete options.currentTheme;
- delete options.currentGenerator;
- delete options.generatorValues;
- this.updateList(instance, options);
- options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "NewTheme",
- checked: ${value},
- css: ${JSON.stringify(theme.css || "")}
- })`);
- }
- })
- ],
- buttons: [
- theme.state != themeStates.DOWNLOADABLE && BDFDB.ReactUtils.createElement("div", {
- className: BDFDB.disCN._repocontrolsbutton,
- children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
- text: "Delete Themefile",
- children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
- name: BDFDB.LibraryComponents.SvgIcon.Names.NOVA_TRASH,
- className: BDFDB.disCN._repoicon,
- onClick: (e, instance) => {
- this.deleteThemeFile(theme);
- BDFDB.TimeUtils.timeout(_ => {
- this.updateList(instance, options);
- this.removeTheme(theme);
- }, 3000);
- }
- })
- })
- }),
- BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
- size: BDFDB.LibraryComponents.Button.Sizes.MIN,
- color: BDFDB.LibraryComponents.Button.Colors[buttonConfig.colorClass],
- style: {backgroundColor: BDFDB.DiscordConstants.Colors[buttonConfig.backgroundColor]},
- children: buttonConfig.text,
- onClick: (e, instance) => {
- this.downloadTheme(theme);
- BDFDB.TimeUtils.timeout(_ => {
- this.updateList(instance, options);
- if (options.rnmStart) this.applyTheme(theme);
- }, 3000);
- }
- })
- ]
- };
- }).filter(n => n);
- }
createFixerCSS (body) {
let oldcss = body.replace(/\n/g, "\\n").replace(/\t/g, "\\t").replace(/\r/g, "\\r").split("REPLACE_CLASS_");
@@ -748,86 +925,24 @@ var ThemeRepo = (_ => {
return newcss.replace(/\\n/g, "\n").replace(/\\t/g, "\t").replace(/\\r/g, "\r");
}
- createGeneratorInputs (theme, options = {}) {
- if (!options.preview || !BDFDB.ObjectUtils.is(options.generatorValues) || !BDFDB.ObjectUtils.is(theme) || !theme.fullcss) return null;
- let vars = theme.fullcss.split(":root");
- if (vars.length < 2) return null;
- 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];
- vars = vars.slice(2).split(/;--|\*\/--/);
- let inputRefs = [], updateTimeout;
- for (let varStr of vars) {
- varStr = varStr.split(":");
- let varName = varStr.shift().trim();
- varStr = varStr.join(":").split(/;[^A-z0-9]|\/\*/);
- let oldValue = varStr.shift().trim();
- if (oldValue) {
- let childType = "text", childMode = "";
- let isColor = BDFDB.ColorUtils.getType(oldValue);
- let isComp = !isColor && /[0-9 ]+,[0-9 ]+,[0-9 ]+/g.test(oldValue);
- if (isColor || isComp) {
- childType = "color";
- childMode = isComp && "comp";
- }
- else {
- let isUrlFile = /url\(.+\)/gi.test(oldValue);
- let isFile = !isUrlFile && /(http(s)?):\/\/[(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.test(oldValue);
- if (isFile || isUrlFile) {
- childType = "file";
- childMode = isUrlFile && "url";
- }
- }
- let varDescription = varStr.join("").replace(/\*\/|\/\*/g, "").replace(/:/g, ": ").replace(/: \//g, ":/").replace(/--/g, " --").replace(/\( --/g, "(--").trim();
- options.generatorValues[varName] = {value:oldValue, oldValue};
- inputRefs.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%",
- value: oldValue,
- placeholder: oldValue,
- onChange: value => {
- BDFDB.TimeUtils.clear(updateTimeout);
- updateTimeout = BDFDB.TimeUtils.timeout(_ => {
- options.generatorValues[varName] = {value, oldValue};
- options.preview.executeJavaScriptSafe(`window.onmessage({
- origin: "ThemeRepo",
- reason: "NewTheme",
- checked: true,
- css: ${JSON.stringify(this.generateTheme(theme, options) || "")}
- })`);
- }, 1000);
- }
- }));
- }
- }
+ createGeneratorInputs (theme, generatorValues) {
+ if (!BDFDB.ObjectUtils.is(theme) || !BDFDB.ObjectUtils.is(generatorValues) || !theme.fullcss) return null;
return inputRefs;
}
- generateTheme (theme, options = {}) {
- if (!BDFDB.ObjectUtils.is(theme) || !BDFDB.ObjectUtils.is(options) || !BDFDB.ObjectUtils.is(options.generatorValues)) return "";
+ generateTheme (theme, generatorValues) {
+ if (!BDFDB.ObjectUtils.is(theme) || !BDFDB.ObjectUtils.is(generatorValues)) return "";
let css = theme.fullcss;
- for (let inputId in options.generatorValues) if (options.generatorValues[inputId].value && options.generatorValues[inputId].value.trim() && options.generatorValues[inputId].value != options.generatorValues[inputId].oldValue) css = css.replace(new RegExp(`--${BDFDB.StringUtils.regEscape(inputId)}(\\s*):(\\s*)${BDFDB.StringUtils.regEscape(options.generatorValues[inputId].oldValue)}`,"g"),`--${inputId}$1:$2${options.generatorValues[inputId].value}`);
+ for (let inputId in generatorValues) if (generatorValues[inputId].value && generatorValues[inputId].value.trim() && generatorValues[inputId].value != generatorValues[inputId].oldValue) css = css.replace(new RegExp(`--${BDFDB.StringUtils.regEscape(inputId)}(\\s*):(\\s*)${BDFDB.StringUtils.regEscape(generatorValues[inputId].oldValue)}`,"g"),`--${inputId}$1:$2${generatorValues[inputId].value}`);
return css;
}
loadThemes () {
BDFDB.DOMUtils.remove(".themerepo-loadingicon");
- let settings = BDFDB.DataUtils.load(this, "settings");
- let getThemeInfo, outdated = 0, newentries = 0, i = 0, NFLDreplace = null;
+ let getThemeInfo, outdated = 0, newEntries = 0, i = 0, NFLDreplace = null;
let tags = ["name","description","author","version"];
- let newentriesdata = BDFDB.DataUtils.load(this, "newentriesdata"), customList = this.getCustomList();
- cachedThemes = (newentriesdata.urlbase64 ? atob(newentriesdata.urlbase64).split("\n") : []).concat(customList);
+ let newEntriesData = BDFDB.DataUtils.load(this, "newentriesdata");
+ cachedThemes = (newEntriesData.urlbase64 ? atob(newEntriesData.urlbase64).split("\n") : []).concat(customList);
BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/ThemeList.txt", (error, response, body) => {
if (!error && body) {
body = body.replace(/[\r\t]/g, "");
@@ -871,7 +986,7 @@ var ThemeRepo = (_ => {
loading = {is:false, timeout:null, amount:loading.amount};
BDFDB.LogUtils.log("Finished fetching Themes.", this.name);
- if (document.querySelector(".bd-themerepobutton")) BDFDB.NotificationUtils.toast(`Finished fetching Themes.`, {type:"success"});
+ if (list) BDFDB.ReactUtils.forceUpdate(list);
if ((settings.notifyOutdated || settings.notifyOutdated == undefined) && outdated > 0) {
let oldbarbutton = document.querySelector(".themerepo-outdate-notice " + BDFDB.dotCN.noticedismiss);
@@ -883,15 +998,16 @@ var ThemeRepo = (_ => {
customicon: themeRepoIcon.replace(/#7289da/gi, "#FFF").replace(/#7f8186/gi, "#B9BBBE")
});
bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", _ => {
- this.openThemeRepoModal({showOnlyOutdated:true});
+ showOnlyOutdated = true;
+ BDFDB.LibraryModules.UserSettingsUtils.open("themerepo");
bar.querySelector(BDFDB.dotCN.noticedismiss).click();
});
}
- if ((settings.notifyNewentries || settings.notifyNewentries == undefined) && newentries > 0) {
+ if (settings.notifyNewEntries && newEntries > 0) {
let oldbarbutton = document.querySelector(".themerepo-newentries-notice " + BDFDB.dotCN.noticedismiss);
if (oldbarbutton) oldbarbutton.click();
- let single = newentries == 1;
+ let single = newEntries == 1;
let bar = BDFDB.NotificationUtils.notice(`There ${single ? "is" : "are"} ${newentries} new Theme${single ? "" : "s"} in the Repo. Check:`, {
type: "success",
btn: "ThemeRepo",
@@ -899,7 +1015,9 @@ var ThemeRepo = (_ => {
customicon: themeRepoIcon.replace(/#7289da/gi, "#FFF").replace(/#7f8186/gi, "#B9BBBE")
});
bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", _ => {
- this.openThemeRepoModal({forcedSort:"new",forcedOrder:"asc"});
+ forcedSort = "NEW";
+ forcedOrder = "ASC";
+ BDFDB.LibraryModules.UserSettingsUtils.open("themerepo");
bar.querySelector(BDFDB.dotCN.noticedismiss).click();
});
}
@@ -1019,7 +1137,7 @@ var ThemeRepo = (_ => {
}
applyTheme (data) {
- if (BDFDB.BDUtils.isThemeEnabled(data.name) == false) {
+ if (data.name && BDFDB.BDUtils.isThemeEnabled(data.name) == false) {
let id = data.name.replace(/^[^a-z]+|[^\w-]+/gi, "-");
BDFDB.DOMUtils.remove(`style#${id}`);
document.head.appendChild(BDFDB.DOMUtils.create(``));
@@ -1037,7 +1155,7 @@ var ThemeRepo = (_ => {
}
removeTheme (data) {
- if (BDFDB.BDUtils.isThemeEnabled(data.name) == true) {
+ if (data.name && BDFDB.BDUtils.isThemeEnabled(data.name) == true) {
let id = data.name.replace(/^[^a-z]+|[^\w-]+/gi, "-");
BDFDB.DOMUtils.remove(`style#${id}`);
BDFDB.BDUtils.disableTheme(data.name, false);