//META{"name":"ThemeRepo"}*//
class ThemeRepo {
initConstructor () {
this.sortings = {
sort: {
name: "Name",
author: "Author",
version: "Version",
description: "Description",
state: "Update State",
fav: "Favorites"
},
order: {
asc: "Ascending",
desc: "Descending"
}
};
this.loading = false;
this.grabbedThemes = [];
this.foundThemes = [];
this.loadedThemes = {};
this.updateInterval;
this.themeFixerCSS = `#friends, .noChannel-Z1DQK7, .activityFeed-HeiGwL, .lfg-3xoFkI, .app, .layers-3iHuyZ, .layer-3QrUeG, .container-2lgZY8, .content-region, .guilds-wrapper, .search-l1Wz-Q .search-bar, .chat .inner-zqa7da, .search-results-wrap, .search-results-wrap .search-header, .search-results-wrap .search-result-message.hit, .sidebar-region, .ui-standard-sidebar-view, .channels-Ie2l6A, .container-2Thooq {background: rgba(0,0,0,0.3) !important;} .search-results-wrap .search-result-message.hit {box-shadow:none !important;} .titleBar-AC4pGV::after {content:""; position:absolute; z-index:-1; top:0; left:0; right:0; width:100%; height:22px; background: rgba(0,0,0,0.8) !important;} #friends .friends-table, .members-1998pB, .loading-316uYQ, .chat .content, .chat form, .chat, .content .flex-spacer, .messages-wrapper, .typing-2GQL18, .container-PNkimc, .headerBar-UHpsPw, .titleBar-AC4pGV, .titleWrapper-1l0xT9 .title-3qD0b-, .search-results-wrap .search-result::before, .search-results-wrap .search-result::after, .search-results-wrap .channel-name {background: transparent !important;} ::-webkit-scrollbar-thumb {border-color: transparent !important; background: rgba(0,0,0,0.8) !important;} ::-webkit-scrollbar, ::-webkit-scrollbar-track-piece {border-color: transparent !important; background: transparent !important;} ::-webkit-scrollbar-corner {display: none !important;}`;
this.themeRepoButtonMarkup =
``;
this.settingsContextEntryMarkup =
`
`;
this.themeRepoLoadingIconMarkup =
``;
this.frameMarkup =
``;
this.themeEntryMarkup =
`
`;
this.themeRepoModalMarkup =
`
You can toggle this menu with the "Ctrl" key to take a better look at the preview.
Download ThemeFixer
`;
this.sortPopoutMarkup =
``;
this.orderPopoutMarkup =
``;
this.css = `
${BDFDB.dotCN.app} > .repo-loadingwrapper {
position: absolute;
bottom: 0;
right: 0;
z-index: 1000;
animation: repo-loadingwrapper-fade 3s infinite ease;
}
@keyframes repo-loadingwrapper-fade {
from {opacity: 0.1;}
50% {opacity: 0.9;}
to {opacity: 0.1;}
}
.discordPreview {
width: 100vw !important;
height: 100vh !important;
position: absolute !important;
z-index: 3400 !important;
}
.discordPreview ~ ${BDFDB.dotCN.appmount} {
position: absolute !important;
top: 0 !important;
}
.themerepo-sort-popout,
.themerepo-order-popout,
.themerepo-favicon-tooltip,
.themerepo-giticon-tooltip {
z-index: 3600 !important;
}
.themerepo-modal {
position: relative !important;
z-index: 3500 !important;
}
.themerepo-modal ${BDFDB.dotCN.modalinner} {
min-height: 100%;
}
.themerepo-modal .themeEntry {
overflow: visible !important;
}
.themerepo-modal .themeEntry .gitIcon,
.themerepo-modal .themeEntry .favIcon,
.themerepo-modal .themeEntry .trashIcon {
margin-right: 5px;
cursor: pointer;
}
.themerepo-modal .themeEntry .trashIcon,
.themerepo-modal .themeEntry .favIcon {
margin-left: auto;
}
.themerepo-modal .themeEntry .favIcon path {
stroke: yellow;
fill: none;
}
.themerepo-modal .themeEntry .favIcon.favorized path {
stroke: yellow;
fill: yellow;
}
.themerepo-modal .themeEntry.downloadable .trashIcon {
display: none;
}
.themerepo-modal .themeEntry.downloadable .btn-download {
background-color: rgb(114, 137, 218) !important;
margin-left: auto !important;
}
.themerepo-modal .themeEntry.outdated .btn-download {
background-color: rgb(240, 71, 71) !important;
margin-left: 0 !important;
}
.themerepo-modal .themeEntry.updated .btn-download {
background-color: rgb(67, 181, 129) !important;
margin-left: 0 !important;
}
.themerepo-trashicon-tooltip{
z-index: 3500!important;
}
.themerepo-modal .themeEntry.jiiks .bda-right {
flex: 1 1 auto;
}
.themerepo-modal .themeEntry.jiiks .bda-header,
.themerepo-modal .themeEntry.jiiks .bda-footer {
display: flex;
align-items: center;
margin: 0 !important;
}
.themerepo-modal .themeEntry.jiiks .bda-footer {
margin-top: 33% !important;
}
.themerepo-modal .themeEntry.jiiks .previewCheckboxWrapper {
margin-right: 5px;
}`;
}
getName () {return "ThemeRepo";}
getDescription () {return "Allows you to preview all themes from the theme repo and download them on the fly. Repo button is in the theme settings.";}
getVersion () {return "1.5.8";}
getAuthor () {return "DevilBro";}
getSettingsPanel () {
if (!this.started || typeof BDFDB !== "object") return;
var settingshtml = `${this.getName()}
`;
settingshtml += `
`;
settingshtml += `
Your additional Theme List:
`;
var ownlist = BDFDB.loadData("ownlist", this, "ownlist") || [];
if (ownlist) for (let url of ownlist) {
settingshtml += `
`;
}
settingshtml += `
`;
settingshtml += `
Force all Themes to be fetched again.
`;
settingshtml += `
Remove all added Themes from your own list.
`;
settingshtml += `
`;
var settingspanel = $(settingshtml)[0];
BDFDB.initElements(settingspanel);
$(settingspanel)
.on("click", ".btn-addtheme", () => {this.addThemeToOwnList(settingspanel);})
.on("keyup", "#input-themeurl", (e) => {if (e.which == 13) this.addThemeToOwnList(settingspanel);})
.on("click", ".remove-theme", (e) => {this.removeThemeFromOwnList(e);})
.on("click", ".remove-all", () => {this.removeAllFromOwnList(settingspanel);})
.on("click", ".refresh-button", () => {this.loadThemes();});
return settingspanel;
}
//legacy
load () {}
start () {
var libraryScript = null;
if (typeof BDFDB !== "object" || typeof BDFDB.isLibraryOutdated !== "function" || BDFDB.isLibraryOutdated()) {
libraryScript = document.querySelector('head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]');
if (libraryScript) libraryScript.remove();
libraryScript = document.createElement("script");
libraryScript.setAttribute("type", "text/javascript");
libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js");
document.head.appendChild(libraryScript);
}
this.startTimeout = setTimeout(() => {this.initialize();}, 30000);
if (typeof BDFDB === "object" && typeof BDFDB.isLibraryOutdated === "function") this.initialize();
else libraryScript.addEventListener("load", () => {this.initialize();});
}
initialize () {
if (typeof BDFDB === "object") {
BDFDB.loadMessage(this);
this.UserUtils = BDFDB.WebModules.findByProperties(["getUsers"]);
this.IconUtils = BDFDB.WebModules.findByProperties(["getUserAvatarURL"]);
var observer = null;
observer = new MutationObserver((changes, _) => {
changes.forEach(
(change, j) => {
if (change.addedNodes) {
change.addedNodes.forEach((node) => {
this.checkIfThemesPage(node);
});
}
}
);
});
BDFDB.addObserver(this, BDFDB.dotCN.layer + "[layer-id='user-settings']", {name:"innerSettingsWindowObserver",instance:observer}, {childList:true,subtree:true});
observer = new MutationObserver((changes, _) => {
changes.forEach(
(change, i) => {
if (change.addedNodes) {
change.addedNodes.forEach((node) => {
setImmediate(() => {
if (node.tagName && node.getAttribute("layer-id") == "user-settings") {
BDFDB.addObserver(this, node, {name:"innerSettingsWindowObserver"}, {childList:true,subtree:true});
this.checkIfThemesPage(node);
}
});
});
}
}
);
});
BDFDB.addObserver(this, BDFDB.dotCN.layers, {name:"settingsWindowObserver",instance:observer}, {childList:true});
observer = new MutationObserver((changes, _) => {
changes.forEach(
(change, i) => {
if (change.addedNodes) {
change.addedNodes.forEach((node) => {
if (node && node.nodeType == 1 && node.className.includes(BDFDB.disCN.contextmenu)) {
this.onContextMenu(node);
}
});
}
}
);
});
BDFDB.addObserver(this, BDFDB.dotCN.appmount, {name:"settingsContextObserver",instance:observer}, {childList: true});
var settingswindow = document.querySelector(BDFDB.dotCN.layer + "[layer-id='user-settings']");
if (settingswindow) this.checkIfThemesPage(settingswindow);
this.loadThemes();
this.updateInterval = setInterval(() => {this.checkForNewThemes();},1000*60*30);
}
else {
console.error(this.getName() + ": Fatal Error: Could not load BD functions!");
}
}
stop () {
if (typeof BDFDB === "object") {
clearInterval(this.updateInterval);
$(".discordPreview, .themerepo-modal, .bd-themerepobutton, .themerepo-loadingicon").remove();
$(BDFDB.dotCN.app + " > .repo-loadingwrapper:empty").remove();
BDFDB.unloadMessage(this);
}
}
// begin of own functions
onContextMenu (context) {
if (!context || !context.tagName || !context.parentElement) return;
for (let entry of context.querySelectorAll(BDFDB.dotCN.contextmenuitem)) {
if (entry.textContent == "BetterDiscord") {
let innerObserver = new MutationObserver((changes, _) => {
changes.forEach(
(change, i) => {
if (change.addedNodes) {
change.addedNodes.forEach((node) => {
if (node && node.nodeType == 1 && node.className.includes(BDFDB.disCN.contextmenu) && !node.querySelector(".themerepo-item")) {
var innerEntries = node.querySelectorAll(BDFDB.dotCN.contextmenuitem);
$(this.settingsContextEntryMarkup)
.on("click", () => {
if (!this.loading) $(context).hide();
this.openThemeRepoModal();
})
.insertAfter(innerEntries[innerEntries.length-1]);
$(node).css("top", $(context).css("top").replace("px","") - $(node).outerHeight() + $(context).outerHeight());
}
});
}
}
);
});
innerObserver.observe(entry, {childList: true});
break;
}
}
}
addThemeToOwnList (settingspanel) {
var themeUrlInput = settingspanel.querySelector("#input-themeurl");
var themeList = settingspanel.querySelector(".theme-list");
if (themeUrlInput && themeList) {
var url = themeUrlInput.value;
themeUrlInput.value = null;
var ownlist = BDFDB.loadData("ownlist", this, "ownlist") || [];
if (!ownlist.includes(url)) {
ownlist.push(url);
BDFDB.saveData("ownlist", ownlist, this, "ownlist");
$(``).appendTo(themeList);
}
}
}
removeThemeFromOwnList (e) {
var entry = e.currentTarget.parentElement;
var url = entry.querySelector(".entryurl").textContent;
entry.remove();
var ownlist = BDFDB.loadData("ownlist", this, "ownlist") || [];
BDFDB.removeFromArray(ownlist, url);
BDFDB.saveData("ownlist", ownlist, this, "ownlist");
}
removeAllFromOwnList (settingspanel) {
if (confirm("Are you sure you want to remove all added Themes from your own list?")) {
BDFDB.saveData("ownlist", [], this, "ownlist");
settingspanel.querySelectorAll(BDFDB.dotCN.hovercard).forEach(ele => {ele.remove();});
}
}
checkIfThemesPage (container) {
if (container && container.tagName) {
var folderbutton = container.querySelector(".bd-pfbtn");
if (folderbutton) {
var buttonbar = folderbutton.parentElement;
if (buttonbar && buttonbar.tagName) {
var header = buttonbar.querySelector("h2");
if (header && header.innerText.toUpperCase() === "THEMES") {
this.addThemeRepoButton(buttonbar);
}
}
}
}
}
addThemeRepoButton (container) {
if (container && !container.querySelector(".bd-themerepobutton")) {
$(container).find(".bda-description").css("display", "block");
$(this.themeRepoButtonMarkup)
.insertAfter(container.querySelector(".bd-pfbtn"))
.on("click", () => {
this.openThemeRepoModal();
})
.on("mouseenter", (e) => {
BDFDB.createTooltip("Open Theme Repo", e.currentTarget, {type:"top",selector:"themerepo-button-tooltip"});
});
}
}
openThemeRepoModal (showOnlyOutdated = false) {
if (this.loading) {
BDFDB.showToast(`Themes are still being fetched. Try again in some seconds.`, {type:"danger"});
return;
}
var frame = $(this.frameMarkup)[0];
var lightTheme = BDFDB.getDiscordTheme() == "theme-light";
var themeRepoModal = $(this.themeRepoModalMarkup);
themeRepoModal.updateModal = true;
themeRepoModal.enableSearch = false;
var hiddenSettings = BDFDB.loadAllData(this, "hidden");
themeRepoModal.find("#input-darklight").prop("checked", lightTheme);
themeRepoModal.find("#input-customcss").prop("checked", false);
themeRepoModal.find("#input-themefixer").prop("checked", false);
themeRepoModal.find("#input-hideupdated").prop("checked", hiddenSettings.updated || showOnlyOutdated);
themeRepoModal.find("#input-hideoutdated").prop("checked", hiddenSettings.outdated && !showOnlyOutdated);
themeRepoModal.find("#input-hidedownloadable").prop("checked", hiddenSettings.downloadable || showOnlyOutdated);
if (!BDFDB.isRestartNoMoreEnabled()) themeRepoModal.find("#RNMoption").remove();
else themeRepoModal.find("#input-rnmstart").prop("checked", BDFDB.loadData("RNMstart", this, "settings"));
themeRepoModal
.on("keyup." + this.getName(), BDFDB.dotCN.searchbarinput, () => {
clearTimeout(themeRepoModal.searchTimeout);
themeRepoModal.searchTimeout = setTimeout(() => {this.addThemeEntries(themeRepoModal, frame);},1000);
})
.on("click." + this.getName(), BDFDB.dotCN.searchbarclear + BDFDB.dotCN.searchbarvisible, () => {
clearTimeout(themeRepoModal.searchTimeout);
themeRepoModal.searchTimeout = setTimeout(() => {this.addThemeEntries(themeRepoModal, frame);},1000);
})
.on("click." + this.getName(), BDFDB.dotCNC.modalclose + BDFDB.dotCN.backdrop, () => {
frame.remove();
$(document).off("keyup." + this.getName());
$(window).off("message." + this.getName());
})
.on("click." + this.getName(), ".sort-filter", (e) => {
this.openSortPopout(e, this.sortPopoutMarkup, themeRepoModal, frame);
})
.on("click." + this.getName(), ".order-filter", (e) => {
this.openSortPopout(e, this.orderPopoutMarkup, themeRepoModal, frame);
})
.on("change." + this.getName(), "#input-darklight", (e) => {
frame.contentWindow.postMessage({origin:"ThemeRepo",reason:"DarkLight",checked:$(e.target).prop("checked")},"*");
})
.on("change." + this.getName(), "#input-customcss", (e) => {
var customCSS = document.querySelector("style#customcss");
if (customCSS && customCSS.innerText.length > 0)
frame.contentWindow.postMessage({origin:"ThemeRepo",reason:"CustomCSS",checked:$(e.target).prop("checked"),css:customCSS.innerText},"*");
})
.on("change." + this.getName(), "#input-themefixer", (e) => {
frame.contentWindow.postMessage({origin:"ThemeRepo",reason:"ThemeFixer",checked:$(e.target).prop("checked"),css:this.themeFixerCSS},"*");
})
.on("click." + this.getName(), "#download-themefixer", (e) => {
this.createThemeFile("ThemeFixer.theme.css", `//META{"name":"ThemeFixer","description":"ThemeFixerCSS for transparent themes","author":"DevilBro","version":"1.0.1"}*//\n\n` + this.themeFixerCSS);
})
.on("change." + this.getName(), ".hide-checkbox", (e) => {
var hideButton = $(e.currentTarget);
hiddenSettings[hideButton.val()] = hideButton.prop("checked");
BDFDB.saveAllData(hiddenSettings, this, "hidden");
})
.on("change." + this.getName(), "#input-rnmstart", (e) => {
BDFDB.saveData("RNMstart", $(e.currentTarget).prop("checked"), this, "settings");
})
.on("click." + this.getName(), ".tab[tab=themes]:not(.selected)", (e) => {
this.addThemeEntries(themeRepoModal, frame);
});
$(document).off("keyup." + this.getName())
.on("keyup." + this.getName(), (e) => {
keyPressed(e.which);
});
$(window).off("message." + this.getName())
.on("message." + this.getName(), (e) => {
e = e.originalEvent;
if (typeof e.data === "object" && e.data.origin == "DiscordPreview") {
switch (e.data.reason) {
case "OnLoad":
var user = this.UserUtils.getCurrentUser();
if (!user) return;
var username = user.username;
var id = user.id;
var avatar = "url(" + (((user.avatar ? "" : "https://discordapp.com") + this.IconUtils.getUserAvatarURL(user)).split("?size")[0]) + ");";
var discriminator = user.discriminator;
var nativecss = document.querySelector("head link[rel='stylesheet'][integrity]");
nativecss = nativecss && nativecss.href ? nativecss.href : null;
frame.contentWindow.postMessage({origin:"ThemeRepo",reason:"OnLoad",username,id,avatar,discriminator,nativecss},"*");
frame.contentWindow.postMessage({origin:"ThemeRepo",reason:"DarkLight",checked:lightTheme},"*");
break;
case "KeyUp":
keyPressed(e.data.key);
break;
}
}
});
this.createThemeEntries(themeRepoModal, frame);
BDFDB.appendModal(themeRepoModal);
$(frame).insertBefore(BDFDB.dotCN.appmount);
function keyPressed (key) {
if (key == 17 && !themeRepoModal.find(BDFDB.dotCN.searchbarinput).is(":focus")) themeRepoModal.toggle();
if (key == 27) frame.remove();
}
}
openSortPopout (e, markup, modal, frame) {
var wrapper = e.currentTarget;
if (wrapper.classList.contains("popout-open")) return;
wrapper.classList.add("popout-open");
var value = $(wrapper).find(BDFDB.dotCN.quickselectvalue);
var popout = $(markup);
$(BDFDB.dotCN.popouts).append(popout)
.off("click", BDFDB.dotCN.contextmenuitem)
.on("click", BDFDB.dotCN.contextmenuitem, (e2) => {
value.text($(e2.currentTarget).text());
value.attr("option", $(e2.currentTarget).attr("option"));
$(document).off("mousedown.sortpopout" + this.getName());
popout.remove();
this.addThemeEntries(modal, frame);
setTimeout(() => {wrapper.classList.remove("popout-open");},300);
});
popout
.css("left", $(wrapper).offset().left + $(wrapper).outerWidth() + "px")
.css("top", $(wrapper).offset().top + value.outerHeight() + "px")
.find(BDFDB.dotCN.contextmenu).addClass(BDFDB.getDiscordTheme());
$(document).on("mousedown.sortpopout" + this.getName(), (e2) => {
if (popout.has(e2.target).length == 0) {
$(document).off("mousedown.sortpopout" + this.getName());
popout.remove();
setTimeout(() => {wrapper.classList.remove("popout-open");},300);
}
});
}
createThemeEntries (modal, frame) {
var favorites = BDFDB.loadAllData(this, "favorites");
modal.entries = [];
for (let url in this.loadedThemes) {
let theme = this.loadedThemes[url];
let div = $(this.themeEntryMarkup);
var installedTheme = window.bdthemes[this.loadedThemes[url].name];
if (installedTheme && installedTheme.author.toUpperCase() == theme.author.toUpperCase()) {
if (installedTheme.version != theme.version) {
theme.state = 1;
div.addClass("outdated")
.find(".btn-download").text("Outdated");
}
else {
theme.state = 0;
div.addClass("updated")
.find(".btn-download").text("Updated");
}
}
else {
theme.state = 2;
div.addClass("downloadable")
.find(".btn-download").text("Download");
}
if (favorites[url]) {
theme.fav = 0;
div.find(".favIcon")[0].classList.add("favorized");
}
else {
theme.fav = 1;
div.find(".favIcon")[0].classList.remove("favorized");
}
modal.entries.push({
div: div,
url: theme.url,
search: (theme.name + " " + theme.version + " " + theme.author + " " + theme.description).toUpperCase(),
name: theme.name,
version: theme.version,
author: theme.author,
description: theme.description,
fav: theme.fav,
state: theme.state,
css: theme.css
});
}
this.addThemeEntries(modal, frame);
}
addThemeEntries (modal, frame) {
if (typeof modal.entries != "object") return;
modal.find(".themeEntry").remove();
var searchstring = modal.find(BDFDB.dotCN.searchbarinput).val().replace(/[<|>]/g, "").toUpperCase();
var entries = modal.entries;
if (modal.find("#input-hideupdated").prop("checked")) entries = entries.filter((entry) => {return entry.state != 0 ? entry : null;});
if (modal.find("#input-hideoutdated").prop("checked")) entries = entries.filter((entry) => {return entry.state != 1 ? entry : null;});
if (modal.find("#input-hidedownloadable").prop("checked")) entries = entries.filter((entry) => {return entry.state != 2 ? entry : null;});
entries = entries.filter((entry) => {return entry.search.indexOf(searchstring) > -1 ? entry : null;});
BDFDB.sortArrayByKey(entries, modal.find(".sort-filter " + BDFDB.dotCN.quickselectvalue).attr("option"));
if (modal.find(".order-filter " + BDFDB.dotCN.quickselectvalue).attr("option") == "desc") entries.reverse();
modal.find(".themeAmount").text("Theme Repository " + entries.length + "/" + Object.keys(this.loadedThemes).length + " Themes");
var container = modal.find(".themes");
entries.forEach((entry) => {
var div = entry.div;
var values = [entry.name, entry.version, entry.author, entry.description];
if (searchstring.length > 0) {
for (let i in values) values[i] = BDFDB.highlightText(values[i], searchstring);
}
div.find(".bda-name").html(values[0]);
div.find(".bda-version").html(values[1]);
div.find(".bda-author").html(values[2]);
div.find(".bda-description").html(values[3]);
div
.on("change." + this.getName(), ".previewCheckbox", (e) => {
modal.find(".previewCheckbox").not(e.target).prop("checked", false);
modal.find(".previewCheckbox").each((_, checkBox) => {
$(checkBox.parentElement)
.toggleClass("valueChecked-3Bzkbm", $(checkBox).prop("checked"))
.toggleClass("valueUnchecked-XR6AOk", $(checkBox).prop("checked"));
});
frame.contentWindow.postMessage({origin:"ThemeRepo",reason:"NewTheme",checked:$(e.target).prop("checked"),css:entry.css},"*");
})
.on("click." + this.getName(), ".favIcon", (e) => {
e.currentTarget.classList.toggle("favorized");
if (e.currentTarget.classList.contains("favorized")) {
entry.fav = 0;
BDFDB.saveData(entry.url, true, this, "favorites");
}
else {
entry.fav = 1;
BDFDB.removeData(entry.url, this, "favorites");
}
})
.on("click." + this.getName(), ".gitIcon", (e) => {
var giturl = null;
if (entry.url.indexOf("https://raw.githubusercontent.com") == 0) {
var temp = entry.url.replace("//raw.githubusercontent", "//github").split("/");
temp.splice(5, 0, "blob");
giturl = temp.join("/");
}
else if (entry.url.indexOf("https://gist.githubusercontent.com/") == 0) {
giturl = entry.url.replace("//gist.githubusercontent", "//gist.github").split("/raw/")[0];
}
if (giturl) {
window.open(giturl, "_blank");
}
})
.on("click." + this.getName(), ".trashIcon", () => {
if (div.hasClass("outdated") || div.hasClass("updated")) {
entry.state = 2;
div.removeClass("outdated").removeClass("updated").addClass("downloadable")
.find(".btn-download").text("Download");
this.deleteThemeFile(entry);
if (!BDFDB.isRestartNoMoreEnabled()) this.removeTheme(entry);
}
})
.on("mouseenter." + this.getName(), ".favIcon", (e) => {
BDFDB.createTooltip("Favorize", e.currentTarget, {type:"top",selector:"themerepo-favicon-tooltip"});
})
.on("mouseenter." + this.getName(), ".gitIcon", (e) => {
BDFDB.createTooltip("Go to Git", e.currentTarget, {type:"top",selector:"themerepo-giticon-tooltip"});
})
.on("mouseenter." + this.getName(), ".trashIcon", (e) => {
BDFDB.createTooltip("Delete Themefile", e.currentTarget, {type:"top",selector:"themerepo-trashicon-tooltip"});
})
.on("click." + this.getName(), ".btn-download", () => {
entry.state = 0;
this.downloadTheme(entry);
div.removeClass("downloadable").removeClass("outdated").addClass("updated")
.find(".btn-download").text("Updated");
if (modal.find("#input-rnmstart").prop("checked")) setTimeout(() => {this.applyTheme(entry);},3000);
});
container.append(div);
});
}
loadThemes () {
var getThemeInfo, outdated = 0, i = 0;
var tags = ["name","description","author","version"];
let request = require("request");
request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/ThemeList.txt", (error, response, result) => {
if (response) {
this.loadedThemes = {};
this.grabbedThemes = result.split("\n");
this.foundThemes = this.grabbedThemes.concat(BDFDB.loadData("ownlist", this, "ownlist") || []);
this.loading = true;
var loadingiconwrapper = document.querySelector(BDFDB.dotCN.app + "> .repo-loadingwrapper");
if (!loadingiconwrapper) {
loadingiconwrapper = document.createElement("div");
loadingiconwrapper.className = "repo-loadingwrapper";
document.querySelector(BDFDB.dotCN.app).appendChild(loadingiconwrapper);
}
$(this.themeRepoLoadingIconMarkup)
.on("mouseenter." + this.getName(), (e) => {BDFDB.createTooltip("Loading ThemeRepo",e.currentTarget,{type:"left",delay:500});})
.appendTo(loadingiconwrapper);
getThemeInfo(() => {
if (!this.started) return;
this.loading = false;
$(".themerepo-loadingicon").remove();
if (!loadingiconwrapper.firstChild) loadingiconwrapper.remove();
console.log("ThemeRepo: Finished fetching Themes.");
if (document.querySelector(".bd-themerepobutton")) BDFDB.showToast(`Finished fetching Themes.`, {type:"success"});
if (outdated > 0) {
var text = `${outdated} of your Themes ${outdated == 1 ? "is" : "are"} outdated. Check:`;
var bar = BDFDB.createNotificationsBar(text,{type:"danger",btn:"ThemeRepo",selector:"themerepo-notice"});
$(bar).on("click." + this.getName(), BDFDB.dotCN.noticebutton, (e) => {
this.openThemeRepoModal(true);
e.delegateTarget.querySelector(BDFDB.dotCN.noticedismiss).click();
});
}
if (BDFDB.myData.id == "278543574059057154") {
let wrongUrls = [];
for (let url of this.foundThemes) if (url && !this.loadedThemes[url] && !wrongUrls.includes(url)) wrongUrls.push(url);
if (wrongUrls.length > 0) {
var bar = BDFDB.createNotificationsBar(`ThemeRepo: ${wrongUrls.length} Theme${wrongUrls.length > 1 ? "s" : ""} could not be loaded.`, {type:"danger",btn:"List"});
$(bar).on("click." + this.getName(), BDFDB.dotCN.noticebutton, (e) => {
var toast = BDFDB.showToast(wrongUrls.join("\n"),{type:"error"});
toast.style.overflow = "hidden";
console.log(wrongUrls.length == 1 ? wrongUrls[0] : wrongUrls);
});
}
}
});
}
});
getThemeInfo = (callback) => {
if (i >= this.foundThemes.length || !this.started) {
callback();
return;
}
let url = this.foundThemes[i].replace(new RegExp("[\\r|\\n|\\t]", "g"), "");
this.foundThemes[i] = url;
request(url, (error, response, body) => {
if (!response) {
if (url && BDFDB.getAllIndexes(this.foundThemes, url).length < 2) this.foundThemes.push(url);
}
else {
let theme = {};
let text = body;
if (text.split("*//").length > 1 && text.split("\n").length > 1) {
for (let tag of tags) {
let result = text.replace(new RegExp("\\s*\:\\s*", "g"), ":").replace(new RegExp("\\s*\}\\s*", "g"), "}").split('"' + tag + '":"');
result = result.length > 1 ? result[1].split('",')[0].split('"}')[0] : null;
result = result && tag != "version" ? result.charAt(0).toUpperCase() + result.slice(1) : result;
theme[tag] = result;
}
let valid = true;
for (let tag of tags) {
if (theme[tag] === null) valid = false;
}
if (valid) {
theme.css = text.split("\n").slice(1).join("\n").replace(new RegExp("[\\r|\\n|\\t]", "g"), "");
theme.url = url;
this.loadedThemes[url] = theme;
var installedTheme = window.bdthemes[theme.name];
if (installedTheme && installedTheme.author.toUpperCase() == theme.author.toUpperCase() && installedTheme.version != theme.version) outdated++;
}
}
}
i++;
getThemeInfo(callback);
});
}
}
checkForNewThemes () {
let request = require("request");
request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/ThemeRepo/res/ThemeList.txt", (error, response, result) => {
if (response && !BDFDB.equals(result.split("\n"), this.grabbedThemes)) this.loadThemes();
});
}
downloadTheme (entry) {
let request = require("request");
request(entry.url, (error, response, body) => {
if (error) {
BDFDB.showToast(`Unable to download Theme "${entry.name}".`, {type:"danger"});
}
else {
let filename = entry.url.split("/");
this.createThemeFile(filename[filename.length - 1], body);
}
});
}
createThemeFile (filename, content) {
let fileSystem = require("fs");
let path = require("path");
var file = path.join(BDFDB.getThemesFolder(), filename);
fileSystem.writeFile(file, content, (error) => {
if (error) {
BDFDB.showToast(`Unable to save Theme "${filename}".`, {type:"danger"});
}
else {
BDFDB.showToast(`Successfully saved Theme "${filename}".`, {type:"success"});
}
});
}
applyTheme (entry) {
var name = entry.name;
if (BDFDB.isThemeEnabled(name) == false) {
$(`style#${name}`).remove();
$("head").append(``);
themeCookie[name] = true;
themeModule.saveThemeData();
console.log("ThemeRepo: applied Theme " + name);
}
}
deleteThemeFile (entry) {
let fileSystem = require("fs");
let path = require("path");
let filename = entry.url.split("/");
filename = filename[filename.length - 1];
var file = path.join(BDFDB.getThemesFolder(), filename);
fileSystem.unlink(file, (error) => {
if (error) {
BDFDB.showToast(`Unable to delete Theme "${filename}".`, {type:"danger"});
}
else {
BDFDB.showToast(`Successfully deleted Theme "${filename}".`, {type:"success"});
}
});
}
removeTheme (entry) {
var name = entry.name;
if (BDFDB.isThemeEnabled(name) == true) {
$(`style#${name}`).remove();
themeCookie[name] = false;
delete bdthemes[name];
themeModule.saveThemeData();
console.log("ThemeRepo: removed Theme " + name);
}
}
}