//META{"name":"RepoControls"}*// class RepoControls { initConstructor () { this.sortings = { sort: { name: "Name", author: "Author", version: "Version", description: "Description", enabled: "Enabled", adddate: "Added", moddate: "Modified" }, order: { asc: "Ascending", desc: "Descending" } }; this.repoControlsMarkup = `
Sort by:
${this.sortings.sort[Object.keys(this.sortings.sort)[0]]}
Order:
${this.sortings.order[Object.keys(this.sortings.order)[0]]}
`; this.sortPopoutMarkup = `
${Object.keys(this.sortings.sort).map((key, i) => `
${this.sortings.sort[key]}
`).join("")}
`; this.orderPopoutMarkup = `
${Object.keys(this.sortings.order).map((key, i) => `
${this.sortings.order[key]}
`).join("")}
`; this.deleteButtonMarkup = ` `; this.css = ` #bd-settingspane-container .bda-description { display: block; } #bd-settingspane-container .bda-right .ui-switch-wrapper { right: 0; } #bd-settingspane-container .bda-right button { position: absolute; right: 0; top: 30px; } #bd-settingspane-container .bda-right, #bd-settingspane-container .bda-header { position: relative; } #bd-settingspane-container .trashIcon { display: none; } #bd-settingspane-container .bda-right .trashIcon, #bd-settingspane-container .bda-header .trashIcon { cursor: pointer; display: block; position: absolute; right: 50px; } #bd-settingspane-container .bda-right .trashIcon { top: 7px; }`; this.defaults = { settings: { addDeleteButton: {value:true, description:"Add a Delete Button to your Plugin and Theme List."}, confirmDelete: {value:true, description:"Ask for your confirmation before deleting a File."} }, sortings: { sort: {value:"name"}, order: {value:"asc"} } }; } getName () {return "RepoControls";} getDescription () {return "Lets you sort and filter your list of downloaded Themes and Plugins.";} getVersion () {return "1.1.9";} getAuthor () {return "DevilBro";} getSettingsPanel () { if (!this.started || typeof BDFDB !== "object") return; var settings = BDFDB.getAllData(this, "settings"); var settingshtml = `
${this.getName()}
`; for (let key in settings) { settingshtml += `

${this.defaults.settings[key].description}

`; } settingshtml += `
`; var settingspanel = $(settingshtml)[0]; BDFDB.initElements(settingspanel); $(settingspanel) .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}); return settingspanel; } //legacy load () {} start () { var libraryScript = null; if (typeof BDFDB !== "object" || BDFDB.isLibraryOutdated()) { if (typeof BDFDB === "object") BDFDB = ""; 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") this.initialize(); else libraryScript.addEventListener("load", () => {this.initialize();}); } initialize () { if (typeof BDFDB === "object") { BDFDB.loadMessage(this); var observer = null; observer = new MutationObserver((changes, _) => { changes.forEach( (change, j) => { if (change.addedNodes) { change.addedNodes.forEach((node) => { if (this.getSettingsPageType(node)) { this.addControls(node.querySelector(".bda-slist")); if (node && node.tagName && node.querySelector(".ui-switch")) { var entry = this.getEntry($(".repo-controls"), $("li").has(node)[0]); if (entry) { if (BDFDB.getData("addDeleteButton", this, "settings")) this.addDeleteButton(entry); this.changeTextToHTML(entry.div); } } } }); } } ); }); 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 && node.tagName && node.getAttribute("layer-id") == "user-settings") { BDFDB.addObserver(this, node, {name:"innerSettingsWindowObserver"}, {childList:true,subtree:true}); if (this.getSettingsPageType(node)) this.addControls(node.querySelector(".bda-slist")); } }); }); } } ); }); BDFDB.addObserver(this, BDFDB.dotCN.layers, {name:"settingsWindowObserver",instance:observer}, {childList:true}); var settingswindow = document.querySelector(BDFDB.dotCN.layer + "[layer-id='user-settings']"); if (settingswindow && this.getSettingsPageType(settingswindow)) this.addControls(settingswindow.querySelector(".bda-slist")); } else { console.error(this.getName() + ": Fatal Error: Could not load BD functions!"); } } stop () { if (typeof BDFDB === "object") { $(".repo-controls, #bd-settingspane-container .trashIcon").remove(); $(".repocontrols-added").removeClass(".repocontrols-added"); BDFDB.unloadMessage(this); } } // begin of own functions updateSettings (settingspanel) { var settings = {}; for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { settings[input.value] = input.checked; } BDFDB.saveAllData(settings, this, "settings"); } getSettingsPageType (container) { if (typeof container === "undefined") container = document.querySelector(BDFDB.dotCN.layer + "[layer-id='user-settings']"); 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) { var headerText = header.innerText.toUpperCase(); if (headerText === "PLUGINS" || headerText === "THEMES") { return headerText[0] + headerText.slice(1).toLowerCase(); } } } } } return null; } addControls (container) { if (!container || document.querySelector(".repo-controls")) return; var sortings = BDFDB.getAllData(this, "sortings"); var repoControls = $(this.repoControlsMarkup); repoControls.Plugins = {}; repoControls.Themes = {}; var fs = require("fs"), folder = BDFDB.getPluginsFolder(), ending = ".plugin.js"; for (var plugin of fs.readdirSync(folder)) { if (plugin.indexOf(ending) == plugin.length - ending.length) { let path = folder + "/" + plugin; let body = fs.readFileSync(path).toString(); let result = new RegExp("getName[\\s|\\t|\\n|\\r|=|>|_|:|function|\(|\)|\{|return]*([\"|\'|\`]).*\\1","gi").exec(body); if (result) { repoControls.Plugins[result[0].split(result[1])[1]] = {path, stats: fs.statSync(path)}; } } } folder = BDFDB.getThemesFolder(), ending = ".theme.css"; for (var theme of fs.readdirSync(folder)) { if (theme.indexOf(ending) == theme.length - ending.length) { let path = folder + "/" + theme; let body = fs.readFileSync(path).toString(); if (body.split("*//").length > 1 && body.split("\n").length > 1) { let result = body.replace(new RegExp("\\s*\:\\s*", "g"), ":").replace(new RegExp("\\s*\}\\s*", "g"), "}").split('"name":"'); result = result.length > 1 ? result[1].split('",')[0].split('"}')[0] : null; if (result) { repoControls.Themes[result] = {path, stats: fs.statSync(path)};; } } } } BDFDB.initElements(repoControls); repoControls.find(".sort-filter " + BDFDB.dotCN.quickselectvalue).attr("option", sortings.sort).text(this.sortings.sort[sortings.sort]); repoControls.find(".order-filter " + BDFDB.dotCN.quickselectvalue).attr("option", sortings.order).text(this.sortings.order[sortings.order]); repoControls .on("keyup." + this.getName(), BDFDB.dotCN.searchbarinput, () => { clearTimeout(repoControls.searchTimeout); repoControls.searchTimeout = setTimeout(() => {this.addEntries(container, repoControls);},1000); }) .on("click." + this.getName(), BDFDB.dotCN.searchbarclear + BDFDB.dotCN.searchbarvisible, () => { this.addEntries(container, repoControls); }) .on("click." + this.getName(), ".btn-enableall", (e) => { this.toggleAll(container, true); }) .on("click." + this.getName(), ".btn-disableall", (e) => { this.toggleAll(container, false); }) .on("click." + this.getName(), ".sort-filter", (e) => { this.openSortPopout(e, this.sortPopoutMarkup, container, repoControls); }) .on("click." + this.getName(), ".order-filter", (e) => { this.openSortPopout(e, this.orderPopoutMarkup, container, repoControls); }) .insertBefore(container); $(container).addClass("repocontrols-added").on("click." + this.getName(), "div[style='float: right; cursor: pointer;']", (e) => { setImmediate(() => { var entry = this.getEntry(repoControls, $("li").has(e.currentTarget)[0]); if (entry) { if (BDFDB.getData("addDeleteButton", this, "settings")) this.addDeleteButton(entry); this.changeTextToHTML(entry.div); } }); }); container.entries = []; for (let li of container.querySelectorAll("li")) { container.entries.push(this.getEntry(repoControls, li)); } this.addEntries(container, repoControls); } getEntry (repoControls, li) { if (!repoControls || !li || !li.tagName || !li.querySelector(".bda-name")) return null; let name, version, author, description, enabled; if (BDFDB.zacksFork()) { name = li.querySelector(".bda-name").textContent; version = li.querySelector(".bda-version").textContent; author = li.querySelector(".bda-author").textContent; description = li.querySelector(".bda-description").textContent; enabled = li.querySelector(".ui-switch-checkbox").checked; } else { let namestring = li.querySelector(".bda-name").textContent; name = namestring.split(" v")[0]; version = namestring.split(" v")[1].split(" by ")[0]; author = namestring.split(" by ")[1]; description = li.querySelector(".bda-description").textContent; enabled = li.querySelector(".ui-switch-checkbox").checked; } let type = this.getSettingsPageType(); let pathstatscache = type ? repoControls[type][name] : null; return { div: li, search: (name + " " + version + " " + author + " " + description).toUpperCase(), origName: name, name: (name).toUpperCase(), version: (version).toUpperCase(), author: (author).toUpperCase(), description: (description).toUpperCase(), type: type, path: pathstatscache ? pathstatscache.path : null, adddate: pathstatscache ? pathstatscache.stats.atime.getTime() : null, moddate: pathstatscache ? pathstatscache.stats.mtime.getTime() : null, enabled: enabled ? 0 : 1 }; } addEntries (container, repoControls) { $(container).find(".trashIcon, li").remove(); var searchstring = repoControls.find(BDFDB.dotCN.searchbarinput).val().replace(/[<|>]/g, "").toUpperCase(); var entries = container.entries; var sortings = BDFDB.getAllData(this, "sortings"); entries = entries.filter((entry) => {return entry.search.indexOf(searchstring) > -1 ? entry : null;}); BDFDB.sortArrayByKey(entries, sortings.sort); if (sortings.order == "desc") entries.reverse(); var settings = BDFDB.getAllData(this, "settings"); for (let entry of entries) { container.appendChild(entry.div); if (settings.addDeleteButton) this.addDeleteButton(entry); this.changeTextToHTML(entry.div, searchstring); $(entry.div).find(".ui-switch-checkbox") .off("change." + this.getName()) .on("change." + this.getName(), (e) => { entry.enabled = e.checked ? 0 : 1 }); } } addDeleteButton (entry) { if (!entry || !entry.div || !entry.div.tagName || entry.div.querySelector(".trashIcon")) return; $(this.deleteButtonMarkup) .on("click." + this.getName(), () => { var container = document.querySelector(".bda-slist"); let type = entry.type ? entry.type.slice(0, -1) : "File"; if (container && (!BDFDB.getData("confirmDelete", this, "settings") || confirm(`Are you sure you want to delete this ${type}?`))) { require("fs").unlink(entry.path, (error) => { if (error) { BDFDB.showToast(`Unable to delete ${type} "${entry.origName}". Filename might not be the same as ${type}name.`, {type:"danger"}); } else { BDFDB.showToast(`Successfully deleted ${type} "${entry.origName}".`, {type:"success"}); BDFDB.removeFromArray(container.entries, entry); entry.div.remove(); } }); } }) .on("mouseenter." + this.getName(), (e) => { BDFDB.createTooltip("Delete File", e.currentTarget, {type:"top",selector:"repocontrols-trashicon-tooltip"}); }) .insertAfter(entry.div.querySelector(".ui-switch-wrapper")); } toggleAll (container, enable) { if (confirm(`Are you sure you want to ${enable ? "enable" : "disable"} everything?`)) { for (let header of container.querySelectorAll(".bda-header")) { if (header.querySelector(".bda-name").textContent.toLowerCase().indexOf(this.getName().toLowerCase()) != 0) { let switchwrap = header.querySelector(".ui-switch-wrapper"); if (switchwrap) { let switchinner = switchwrap.querySelector(".ui-switch"); let switchinput = switchwrap.querySelector(".ui-switch-checkbox"); if (switchinner && switchinput) { if (switchinner.classList.contains("checked") && !enable) { switchinput.click(); } else if (!switchinner.classList.contains("checked") && enable) { switchinput.click(); } } } } } } } changeTextToHTML (container, searchstring) { if (!container || !container.tagName) return; if (typeof searchstring === "undefined") { var searchinput = document.querySelector(".repo-controls " + BDFDB.dotCN.searchbarinput); searchstring = searchinput ? searchinput.value : ""; } container.querySelectorAll(".bda-name, .bda-version, .bda-author, .bda-description").forEach(ele => { if (ele.classList.contains("bda-description")) ele.style.display = "block"; ele.innerHTML = BDFDB.highlightText(ele.innerText, searchstring); }); } openSortPopout (e, markup, container, repoControls) { 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) => { var option = $(e2.currentTarget).attr("option"); value.text($(e2.currentTarget).text()); value.attr("option", option); $(document).off("mousedown.sortpopout" + this.getName()); popout.remove(); BDFDB.saveData(popout.attr("option"), option, this, "sortings"); this.addEntries(container, repoControls); 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); } }); } }