//META{"name":"RepoControls"}*// class RepoControls { getName () {return "RepoControls";} getVersion () {return "1.2.5";} getAuthor () {return "DevilBro";} getDescription () {return "Lets you sort and filter your list of downloaded Themes and Plugins.";} 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"} } }; } getSettingsPanel () { if (!global.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; let settings = BDFDB.getAllData(this, "settings"); let settingshtml = `
${this.name}
`; for (let key in settings) { settingshtml += `

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

`; } settingshtml += `
`; let settingspanel = BDFDB.htmlToElement(settingshtml); BDFDB.initElements(settingspanel, this); return settingspanel; } //legacy load () {} start () { var libraryScript = document.querySelector('head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]'); if (!libraryScript || performance.now() - libraryScript.getAttribute("date") > 600000) { if (libraryScript) libraryScript.remove(); libraryScript = document.createElement("script"); libraryScript.setAttribute("type", "text/javascript"); libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"); libraryScript.setAttribute("date", performance.now()); libraryScript.addEventListener("load", () => {if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize();}); document.head.appendChild(libraryScript); } else if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize(); this.startTimeout = setTimeout(() => {this.initialize();}, 30000); } initialize () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { if (this.started) return; 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(`%c[${this.name}]%c`, 'color: #3a71c1; font-weight: 700;', '', 'Fatal Error: Could not load BD functions!'); } } stop () { if (global.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { 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"); var checkbox = li.querySelector(BDFDB.dotCN._repocheckbox); if (checkbox) checkbox.removeEventListener("change", checkbox.changeRepoControlsListener); } } BDFDB.unloadMessage(this); } } // begin of own functions 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 = BDFDB.htmlToElement(this.deleteButtonMarkup); 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 = BDFDB.htmlToElement(this.repoControlsMarkup); BDFDB.initElements(repocontrols, this); container.parentElement.insertBefore(repocontrols, container); let sortfilter = repocontrols.querySelector(".sort-filter " + BDFDB.dotCN.quickselectvalue); sortfilter.setAttribute("option", sortings.sort); sortfilter.innerText = this.sortings.sort[sortings.sort]; let orderfilter = repocontrols.querySelector(".order-filter " + BDFDB.dotCN.quickselectvalue); orderfilter.setAttribute("option", sortings.order); orderfilter.innerText = this.sortings.order[sortings.order]; BDFDB.addChildEventListener(repocontrols, "keyup", BDFDB.dotCN.searchbarinput, () => { clearTimeout(repocontrols.searchTimeout); repocontrols.searchTimeout = setTimeout(() => {this.sortEntries(container, repocontrols);},1000); }); BDFDB.addChildEventListener(repocontrols, "click", BDFDB.dotCN.searchbarclear + BDFDB.dotCN.searchbarvisible, () => { this.sortEntries(container, repocontrols); }); BDFDB.addChildEventListener(repocontrols, "click", ".btn-enableall", e => { this.toggleAll(type, container, true); }); BDFDB.addChildEventListener(repocontrols, "click", ".btn-disableall", e => { this.toggleAll(type, container, false); }); BDFDB.addChildEventListener(repocontrols, "click", ".sort-filter", e => { BDFDB.createSortPopout(e.currentTarget, this.sortPopoutMarkup, () => { BDFDB.saveData("sort", sortfilter.getAttribute("option"), this, "sortings"); this.sortEntries(container, repocontrols); }); }); BDFDB.addChildEventListener(repocontrols, "click", ".order-filter", e => { BDFDB.createSortPopout(e.currentTarget, this.orderPopoutMarkup, () => { BDFDB.saveData("order", orderfilter.getAttribute("option"), this, "sortings"); this.sortEntries(container, repocontrols); }); }); BDFDB.addClass(container, "repocontrols-added"); container.entries = {}; for (let li of container.children) { if (li.querySelector(BDFDB.dotCN._reponame)) { 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.querySelector(BDFDB.dotCN.searchbarinput).value.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.setProperty("order", pos, "important"); var checkbox = li.querySelector(BDFDB.dotCN._repocheckbox); if (checkbox) { checkbox.removeEventListener("change", checkbox.changeRepoControlsListener); checkbox.changeRepoControlsListener = () => {entries[name].enabled = checkbox.checked ? 0 : 1}; checkbox.addEventListener("change", checkbox.changeRepoControlsListener); } } else li.style.removeProperty("order"); BDFDB.toggleEles(li, pos > -1) } } 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 (BDFDB.containsClass(ele, BDFDB.disCN._repodescription)) { ele.style.display = "block"; if (searchstring && searchstring.length > 2) ele.innerHTML = BDFDB.highlightText(ele.innerText, searchstring); else ele.innerHTML = ele.innerText; } else if (searchstring && searchstring.length > 2 || ele.querySelector(BDFDB.dotCN.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.name.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 (BDFDB.containsClass(switchinner, BDFDB.disCN._repocheckboxchecked) && !enable) switchinput.click(); else if (!BDFDB.containsClass(switchinner, BDFDB.disCN._repocheckboxchecked) && enable) switchinput.click(); } } } } }); } }