//META{"name":"RepoControls"}*// class RepoControls { initConstructor () { this.patchModules = { "V2C_List":"componentDidMount", "V2C_PluginCard": ["componentDidMount","componentDidUpdate"], "V2C_ThemeCard": ["componentDidMount","componentDidUpdate"] }; 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 .trashIcon { margin-right: 5px; cursor: pointer; vertical-align: top; color: #72767d; } ${BDFDB.dotCN.themedark} #bd-settingspane-container .trashIcon { color: #dcddde; }`; 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.2.4";} getAuthor () {return "DevilBro";} getSettingsPanel () { if (!this.started || typeof BDFDB !== "object") return; let settings = BDFDB.getAllData(this, "settings"); let settingshtml = `
${this.getName()}
`; for (let key in settings) { settingshtml += `

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

`; } settingshtml += `
`; let settingspanel = $(settingshtml)[0]; BDFDB.initElements(settingspanel); $(settingspanel) .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}); return settingspanel; } //legacy load () {} start () { let 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.fs = require("fs"); this.path = require("path"); this.dirs = {theme: BDFDB.getThemesFolder(), plugin: BDFDB.getPluginsFolder()}; BDFDB.WebModules.forceAllUpdates(this); } else { console.error(this.getName() + ": Fatal Error: Could not load BD functions!"); } } stop () { if (typeof BDFDB === "object") { BDFDB.removeEles(".repo-controls","#bd-settingspane-container .trashIcon"); BDFDB.removeClasses("repocontrols-added"); for (let list of document.querySelectorAll(BDFDB.dotCNS._repolist)) { list.style.removeProperty("display"); list.style.removeProperty("flex-direction"); for (let li of list.querySelectorAll("li")) { li.style.removeProperty("display"); li.style.removeProperty("order"); } } BDFDB.unloadMessage(this); } } // begin of own functions updateSettings (settingspanel) { let settings = {}; for (let input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { settings[input.value] = input.checked; } BDFDB.saveAllData(settings, this, "settings"); } processV2CList (instance, container) { if (instance._reactInternalFiber.key) this.addControls(instance._reactInternalFiber.key.split("-")[0], container); } processV2CPluginCard (instance, wrapper, methodnames) { if (wrapper.querySelector(BDFDB.dotCN._reponame)) { if (instance.props && BDFDB.getData("addDeleteButton", this, "settings")) this.addDeleteButton("plugin", wrapper); if (methodnames.includes("componentDidUpdate")) this.changeTextToHTML(wrapper, ""); } } processV2CThemeCard (instance, wrapper, methodnames) { if (wrapper.querySelector(BDFDB.dotCN._reponame)) { if (instance.props && BDFDB.getData("addDeleteButton", this, "settings")) this.addDeleteButton("theme", wrapper); if (methodnames.includes("componentDidUpdate")) this.changeTextToHTML(wrapper, ""); } } addDeleteButton (type, wrapper) { if (!type || !wrapper || wrapper.querySelector(".trashIcon")) return; let name = wrapper.getAttribute("data-name"); if (!name) return; let path = global[`bd${type}s`] && global[`bd${type}s`][name] ? this.path.join(this.dirs[type], global[`bd${type}s`][name].filename) : null; if (!path) return; let button = $(this.deleteButtonMarkup)[0]; button.addEventListener("click", () => { let deleteFile = () => { this.fs.unlink(path, (error) => { if (error) BDFDB.showToast(`Unable to delete ${type} "${name}".`, {type:"danger"}); else BDFDB.showToast(`Successfully deleted ${type} "${name}".`, {type:"success"}); }); }; if (!BDFDB.getData("confirmDelete", this, "settings")) deleteFile(); else BDFDB.openConfirmModal(this, `Are you sure you want to delete the ${type} "${name}"?`, () => { deleteFile(); }); }); button.addEventListener("mouseenter", (e) => { BDFDB.createTooltip(`Delete ${type[0].toUpperCase() + type.slice(1)}`, e.currentTarget, {type:"top",selector:"repocontrols-trashicon-tooltip"}); }); let controls = wrapper.querySelector(BDFDB.dotCN._repocontrols); if (controls) controls.insertBefore(button, controls.firstElementChild); } addControls (type, container) { if (!type || !container) return; BDFDB.removeEles(".repo-controls"); container.style.setProperty("display","flex","important"); container.style.setProperty("flex-direction","column","important"); let sortings = BDFDB.getAllData(this, "sortings"); let repoControls = $(this.repoControlsMarkup); 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.sortEntries(container, repoControls);},1000); }) .on("click." + this.getName(), BDFDB.dotCN.searchbarclear + BDFDB.dotCN.searchbarvisible, () => { this.sortEntries(container, repoControls); }) .on("click." + this.getName(), ".btn-enableall", (e) => { this.toggleAll(type, container, true); }) .on("click." + this.getName(), ".btn-disableall", (e) => { this.toggleAll(type, 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.classList.add("repocontrols-added"); container.entries = {}; for (let li of container.children) { let name = li.querySelector(BDFDB.dotCN._reponame).textContent; let version = li.querySelector(BDFDB.dotCN._repoversion).textContent; let author = li.querySelector(BDFDB.dotCN._repoauthor).textContent; let description = li.querySelector(BDFDB.dotCN._repodescription).textContent; let enabled = li.querySelector(BDFDB.dotCN._repocheckbox).checked; let path = global[`bd${type}s`] && global[`bd${type}s`][name] ? this.path.join(this.dirs[type], global[`bd${type}s`][name].filename) : null; let stats = path ? this.fs.statSync(path) : null; container.entries[name] = { search: (name + " " + version + " " + author + " " + description).toUpperCase(), origName: name, name: (name).toUpperCase(), version: (version).toUpperCase(), author: (author).toUpperCase(), description: (description).toUpperCase(), type: type, path: path, adddate: stats ? stats.atime.getTime() : null, moddate: stats ? stats.mtime.getTime() : null, enabled: enabled ? 0 : 1 }; } this.sortEntries(container, repoControls); } sortEntries (container, repoControls) { if (typeof container.entries != "object") return; let searchstring = repoControls.find(BDFDB.dotCN.searchbarinput).val().replace(/[<|>]/g, "").toUpperCase(); let sortings = BDFDB.getAllData(this, "sortings"); let entries = BDFDB.filterObject(container.entries, entry => {return entry.search.indexOf(searchstring) > -1 ? entry : null;}); entries = BDFDB.sortObject(entries, sortings.sort); if (sortings.order == "desc") entries = BDFDB.reverseObject(entries); let entrypositions = Object.keys(entries); for (let li of container.children) { let name = li.getAttribute("data-name"); let pos = entrypositions.indexOf(name); if (pos > -1) { this.changeTextToHTML(li, searchstring); li.style.removeProperty("display"); li.style.setProperty("order", pos, "important"); $(li) .find(BDFDB.dotCN._repocheckbox) .off("change." + this.getName()) .on("change." + this.getName(), (e) => { entries[name].enabled = e.checked ? 0 : 1 }); } else { li.style.setProperty("display", "none", "important"); li.style.removeProperty("order"); } } } changeTextToHTML (wrapper, searchstring) { if (!wrapper || !wrapper.tagName) return; for (let ele of wrapper.querySelectorAll(BDFDB.dotCNC._reponame + BDFDB.dotCNC._repoversion + BDFDB.dotCNC._repoauthor + BDFDB.dotCN._repodescription)) { if (ele.classList.contains(BDFDB.disCN._repodescription)) { ele.style.display = "block"; ele.innerHTML = BDFDB.highlightText(ele.innerText, searchstring); } else if (searchstring || ele.querySelector(".highlight")) ele.innerHTML = BDFDB.highlightText(ele.innerText, searchstring); } } toggleAll (type, container, enable) { BDFDB.openConfirmModal(this, `Are you sure you want to ${enable ? "enable" : "disable"} all ${type[0].toUpperCase() + type.slice(1)}s?`, () => { for (let header of container.querySelectorAll(BDFDB.dotCN._repoheader)) { if (header.querySelector(BDFDB.dotCN._reponame).textContent.toLowerCase().indexOf(this.getName().toLowerCase()) != 0) { let switchwrap = header.querySelector(BDFDB.dotCN._repocheckboxwrap); if (switchwrap) { let switchinner = switchwrap.querySelector(BDFDB.dotCN._repocheckboxinner); let switchinput = switchwrap.querySelector(BDFDB.dotCN._repocheckbox); if (switchinner && switchinput) { if (switchinner.classList.contains("checked") && !enable) switchinput.click(); else if (!switchinner.classList.contains("checked") && enable) switchinput.click(); } } } } }); } openSortPopout (e, markup, container, repoControls) { let wrapper = e.currentTarget; if (wrapper.classList.contains("popout-open")) return; wrapper.classList.add("popout-open"); let value = $(wrapper).find(BDFDB.dotCN.quickselectvalue); let popout = $(markup); $(BDFDB.dotCN.popouts).append(popout) .off("click", BDFDB.dotCN.contextmenuitem) .on("click", BDFDB.dotCN.contextmenuitem, (e2) => { let 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.sortEntries(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); } }); } }