From bc93ecf4126707995b97e64b1ccb404cd4ef6723 Mon Sep 17 00:00:00 2001 From: Mirco Wittrien Date: Mon, 10 Feb 2020 15:05:58 +0100 Subject: [PATCH] Update PluginRepo.plugin.js --- Plugins/PluginRepo/PluginRepo.plugin.js | 1700 +++++++++++------------ 1 file changed, 847 insertions(+), 853 deletions(-) diff --git a/Plugins/PluginRepo/PluginRepo.plugin.js b/Plugins/PluginRepo/PluginRepo.plugin.js index bd952727e0..5356437475 100644 --- a/Plugins/PluginRepo/PluginRepo.plugin.js +++ b/Plugins/PluginRepo/PluginRepo.plugin.js @@ -1,889 +1,883 @@ //META{"name":"PluginRepo","website":"https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/PluginRepo","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/PluginRepo/PluginRepo.plugin.js"}*// -class PluginRepo { - getName () {return "PluginRepo";} - - getVersion () {return "1.8.8";} - - getAuthor () {return "DevilBro";} - - getDescription () {return "Allows you to look at all plugins from the plugin repo and download them on the fly. Repo button is in the plugins settings.";} - - constructor () { - this.changelog = { - "improved":[["Promise Error","Fixed issue where PluginRepo wouldnt load when an installed plugin has no getAuthor"]] - }; - - this.patchedModules = { - after: { - "V2C_List":"componentDidMount" - } - }; - } - - initConstructor () { - this.sortings = { - sort: { - name: "Name", - author: "Author", - version: "Version", - description: "Description", - state: "Update State", - fav: "Favorites", - new: "New Plugins" - }, - order: { - asc: "Ascending", - desc: "Descending" - } - }; - - this.loading = {is:false, timeout:null, amount:0}; - - this.cachedPlugins = []; - this.grabbedPlugins = []; - this.foundPlugins = []; - this.loadedPlugins = {}; - - this.updateInterval; - - this.pluginRepoIconMarkup = - ` - - - `; - - this.frameMarkup = - ``; - - this.pluginEntryMarkup = - `
  • -
    - - v by - -
    -
    - -
    - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - - - - - -
    -
  • `; - - this.pluginRepoModalMarkup = - ` -
    -
    -
    -
    -
    -
    -

    Plugin Repository

    -
    -
    - -
    -
    -
    -
    Plugins
    -
    Settings
    -
    -
    -
    Sort by:
    -
    -
    ${this.sortings.sort[Object.keys(this.sortings.sort)[0]]}
    -
    -
    -
    -
    -
    Order:
    -
    -
    ${this.sortings.order[Object.keys(this.sortings.order)[0]]}
    -
    -
    -
    -
    -
    -
    -
      -
      -
      -
      -
      -

      To experience PluginRepo 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.

      -
      -
      -

      Hide updated Plugins.

      -
      - -
      -
      -
      -

      Hide outdated Plugins.

      -
      - -
      -
      -
      -

      Hide downloadable Plugins.

      -
      - -
      -
      -
      -

      Start Plugin after Download (Automatic Loading needed)

      -
      - -
      -
      -
      -
      -
      -
      -
      `; - - 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.defaults = { - settings: { - useChromium: {value:false, description:"Use an inbuilt browser window instead of opening your default browser"}, - notifyOutdated: {value:true, description:"Notifies you when one of your Plugins is outdated."}, - notifyNewentries: {value:true, description:"Notifies you when there are new entries in the Repo."} - } - }; - - this.css = ` - ${BDFDB.dotCN.app} > .repo-loadingwrapper { - position: absolute; - bottom: 0; - right: 0; - z-index: 1000; - animation: repo-loadingwrapper-fade 3s infinite ease; - } - ${BDFDB.dotCN.app} > .repo-loadingwrapper > * { - margin: 0 5px; - } - @keyframes repo-loadingwrapper-fade { - from {opacity: 0.1;} - 50% {opacity: 0.9;} - to {opacity: 0.1;} - } - .${this.name}-modal.Repo-modal ${BDFDB.dotCN.modalinner} { - min-height: 100%; - min-width: 800px; - width: 50%; - } - .${this.name}-modal .pluginEntry ${BDFDB.dotCN._repocontrols} > * { - margin-right: 5px !important; - } - .${this.name}-modal .pluginEntry svg[fill="currentColor"], - .${this.name}-modal .pluginEntry ${BDFDB.dotCN.giffavoritebutton} { - cursor: pointer; - } - .${this.name}-modal .pluginEntry svg[fill="currentColor"], - .${this.name}-modal .pluginEntry ${BDFDB.dotCN.giffavoritebutton + BDFDB.notCN.giffavoriteselected} { - color: #72767d !important; - } - ${BDFDB.dotCN.themedark} .${this.name}-modal .pluginEntry svg[fill="currentColor"], - ${BDFDB.dotCN.themedark} .${this.name}-modal .pluginEntry ${BDFDB.dotCN.giffavoritebutton + BDFDB.notCN.giffavoriteselected} { - color: #dcddde !important; - } - .${this.name}-modal .pluginEntry.downloadable .trashIcon { - opacity: 0 !important; - pointer-events: none !important; - }`; - } - - getSettingsPanel () { - if (!window.BDFDB || typeof BDFDB != "object" || !BDFDB.loaded || !this.started) return; - var settings = BDFDB.DataUtils.get(this, "settings"); - var settingshtml = `
      ${this.name}
      `; - for (let key in settings) { - settingshtml += `

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

      `; - } - settingshtml += `

      Add Plugin:

      `; - settingshtml += `

      Your additional Plugin List:

      `; - var ownlist = BDFDB.DataUtils.load(this, "ownlist", "ownlist") || []; - for (let url of ownlist) { - settingshtml += `
      ${url}
      `; - } - settingshtml += `
      `; - settingshtml += `

      Force all Plugins to be fetched again.

      `; - settingshtml += `

      Remove all added Plugins from your own list.

      `; - settingshtml += `
      `; - - let settingspanel = BDFDB.DOMUtils.create(settingshtml); - - BDFDB.initElements(settingspanel, this); - - BDFDB.ListenerUtils.add(this, settingspanel, "click", ".btn-addplugin", _ => {this.addPluginToOwnList(settingspanel);}); - BDFDB.ListenerUtils.add(this, settingspanel, "click", "#input-pluginurl", e => {if (e.which == 13) this.addPluginToOwnList(settingspanel);}); - BDFDB.ListenerUtils.add(this, settingspanel, "click", ".remove-plugin", e => {this.removePluginFromOwnList(e);}); - BDFDB.ListenerUtils.add(this, settingspanel, "click", ".remove-all", _ => {this.removeAllFromOwnList(settingspanel);}); - BDFDB.ListenerUtils.add(this, settingspanel, "click", ".refresh-button", _ => { - this.loading = {is:false, timeout:null, amount:0}; - this.loadPlugins(); - }); - - return settingspanel; - } - - //legacy - load () {} - - start () { - if (!window.BDFDB) window.BDFDB = {myPlugins:{}}; - if (window.BDFDB && window.BDFDB.myPlugins && typeof window.BDFDB.myPlugins == "object") window.BDFDB.myPlugins[this.getName()] = this; - let libraryScript = document.querySelector("head script#BDFDBLibraryScript"); - if (!libraryScript || (performance.now() - libraryScript.getAttribute("date")) > 600000) { - if (libraryScript) libraryScript.remove(); - libraryScript = document.createElement("script"); - libraryScript.setAttribute("id", "BDFDBLibraryScript"); - libraryScript.setAttribute("type", "text/javascript"); - libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js"); - libraryScript.setAttribute("date", performance.now()); - libraryScript.addEventListener("load", _ => {this.initialize();}); - document.head.appendChild(libraryScript); - } - else if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize(); - this.startTimeout = setTimeout(_ => { - try {return this.initialize();} - catch (err) {console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not initiate plugin! " + err);} - }, 30000); - } - - initialize () { - if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - if (this.started) return; - BDFDB.PluginUtils.init(this); - - this.loadPlugins(); - - this.updateInterval = BDFDB.TimeUtils.interval(_ => {this.checkForNewPlugins();},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!"); - } - - - stop () { - if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { - this.stopping = true; - - BDFDB.TimeUtils.clear(this.updateInterval); - BDFDB.TimeUtils.clear(this.loading.timeout); - - BDFDB.DOMUtils.remove(".pluginrepo-notice",".bd-pluginrepobutton",".pluginrepo-loadingicon",BDFDB.dotCN.app + " > .repo-loadingwrapper:empty"); - - var frame = document.querySelector("iframe.discordSandbox"); - if (frame) { - window.removeEventListener("message", frame.messageReceived); - frame.remove(); - } - - BDFDB.PluginUtils.clear(this); - } - } - - - // begin of own functions - - onUserSettingsCogContextMenu (e) { - BDFDB.TimeUtils.timeout(_ => {for (let child of e.returnvalue.props.children) if (child && child.props && child.props.label == "BandagedBD" && Array.isArray(child.props.render)) { - child.props.render.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ContextMenuItems.Item, { - label: "Plugin Repo", - action: _ => { - if (!this.loading.is) BDFDB.ContextMenuUtils.close(e.instance); - this.openPluginRepoModal(); - } - })); - break; - }}); - } - - processV2CList (instance, wrapper, returnvalue) { - if (!document.querySelector(".bd-pluginrepobutton") && window.PluginUpdates && window.PluginUpdates.plugins && instance._reactInternalFiber.key && instance._reactInternalFiber.key.split("-")[0] == "plugin") { - var folderbutton = document.querySelector(BDFDB.dotCN._repofolderbutton); - if (folderbutton) { - var repoButton = BDFDB.DOMUtils.create(``); - repoButton.addEventListener("click", _ => { - this.openPluginRepoModal(); - }); - repoButton.addEventListener("mouseenter", _ => { - BDFDB.TooltipUtils.create(repoButton, "Open Plugin Repo", {type:"top",selector:"pluginrepo-button-tooltip"}); - }); - folderbutton.parentElement.insertBefore(repoButton, folderbutton.nextSibling); - } +var PluginRepo = (_ => { + var loading, cachedPlugins, grabbedPlugins, foundPlugins, loadedPlugins, updateInterval, currentSearchString, selectedSortKey, selectedOrderKey; + + const pluginStates = { + UPDATED: 0, + OUTDATED: 1, + DOWNLOADABLE: 2 + }; + const buttonData = { + UPDATED: { + colorClass: "GREEN", + backgroundColor: "STATUS_GREEN", + text: "Updated" + }, + OUTDATED: { + colorClass: "RED", + backgroundColor: "STATUS_RED", + text: "Outdated" + }, + DOWNLOADABLE: { + colorClass: "BRAND", + backgroundColor: "BRAND", + text: "Download" } }; - - addPluginToOwnList (settingspanel) { - var pluginUrlInput = settingspanel.querySelector("#input-pluginurl"); - var pluginList = settingspanel.querySelector(".plugin-list"); - if (pluginUrlInput && pluginList) { - var url = pluginUrlInput.value; - pluginUrlInput.value = null; - var ownlist = BDFDB.DataUtils.load(this, "ownlist", "ownlist") || []; - if (!ownlist.includes(url)) { - ownlist.push(url); - BDFDB.DataUtils.save(ownlist, this, "ownlist", "ownlist"); - let entry = BDFDB.DOMUtils.create(`
      ${url}
      `); - BDFDB.ListenerUtils.addToChildren(entry, "click", ".remove-plugin", e => {this.removePluginFromOwnList(e);}); - pluginList.appendChild(entry); - } + const favStates = { + FAVORIZED: 0, + NOT_FAVORIZED: 1 + }; + const newStates = { + NEW: 0, + NOT_NEW: 1 + }; + const sortKeys = { + NAME: "Name", + AUTHOR: "Author", + VERSION: "Version", + DESCRIPTION: "Description", + STATE: "Update State", + FAV: "Favorites", + NEW: "New Plugins" + }; + const orderKeys = { + ASC: "Ascending", + DESC: "Descending" + }; + + const pluginRepoIcon = ``; + const gitHubIcon = ``; + + const repoListComponent = class PluginList extends BdApi.React.Component { + render() { + let list = BDFDB.ReactUtils.createElement("ul", { + 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, Object.assign({}, entry, { + + }))) + }); + BDFDB.ReactUtils.forceStyle(list, ["display", "flex-direction", "margin", "width"]); + return list; } - } + }; + + return class PluginRepo { + getName () {return "PluginRepo";} - removePluginFromOwnList (e) { - var entry = e.currentTarget.parentElement; - var url = entry.querySelector(".entryurl").textContent; - entry.remove(); - var ownlist = BDFDB.DataUtils.load(this, "ownlist", "ownlist") || []; - BDFDB.ArrayUtils.remove(ownlist, url); - BDFDB.DataUtils.save(ownlist, this, "ownlist", "ownlist"); - } + getVersion () {return "1.8.9";} - removeAllFromOwnList (settingspanel) { - BDFDB.ModalUtils.confirm(this, "Are you sure you want to remove all added Plugins from your own list?", _ => { - BDFDB.DataUtils.save([], this, "ownlist", "ownlist"); - BDFDB.DOMUtils.remove(settingspanel.querySelector(BDFDB.dotCN.hovercard)); - }); - } + getAuthor () {return "DevilBro";} - openPluginRepoModal (options = {}) { - if (this.loading.is) { - BDFDB.NotificationUtils.toast(`Plugins are still being fetched. Try again in some seconds.`, {type:"danger"}); - return; - } + getDescription () {return "Allows you to look at all plugins from the plugin repo and download them on the fly. Repo button is in the plugins settings.";} - var pluginRepoModal = BDFDB.DOMUtils.create(this.pluginRepoModalMarkup); - var tabbar = pluginRepoModal.querySelector(BDFDB.dotCN.tabbar); - tabbar.parentElement.insertBefore(BDFDB.createSearchBar("small"), tabbar.nextElementSibling); - var hiddenSettings = BDFDB.DataUtils.load(this, "hidden"); - pluginRepoModal.querySelector("#input-hideupdated").checked = hiddenSettings.updated || options.showOnlyOutdated; - pluginRepoModal.querySelector("#input-hideoutdated").checked = hiddenSettings.outdated && !options.showOnlyOutdated; - pluginRepoModal.querySelector("#input-hidedownloadable").checked = hiddenSettings.downloadable || options.showOnlyOutdated; - if (!BDFDB.BDUtils.isAutoLoadEnabled()) pluginRepoModal.querySelector("#RNMoption").remove(); - else pluginRepoModal.querySelector("#input-rnmstart").checked = BDFDB.DataUtils.load(this, "RNMstart", "RNMstart"); - - if (options.forcedSort && this.sortings.sort[options.forcedSort]) { - var sortinput = pluginRepoModal.querySelector(".sort-filter " + BDFDB.dotCN.quickselectvalue); - sortinput.innerText = this.sortings.sort[options.forcedSort]; - sortinput.setAttribute('option', options.forcedSort); - } - if (options.forcedOrder && this.sortings.order[options.forcedOrder]) { - var orderinput = pluginRepoModal.querySelector(".order-filter " + BDFDB.dotCN.quickselectvalue); - orderinput.innerText = this.sortings.order[options.forcedOrder]; - orderinput.setAttribute('option', options.forcedOrder); - } - - BDFDB.ListenerUtils.addToChildren(pluginRepoModal, "keyup", BDFDB.dotCN.searchbarinput, _ => { - BDFDB.TimeUtils.clear(pluginRepoModal.searchTimeout); - pluginRepoModal.searchTimeout = BDFDB.TimeUtils.timeout(_ => {this.sortEntries(pluginRepoModal);},1000); - }); - BDFDB.ListenerUtils.addToChildren(pluginRepoModal, "click", BDFDB.dotCN.searchbarclear, _ => { - BDFDB.TimeUtils.clear(pluginRepoModal.searchTimeout); - pluginRepoModal.searchTimeout = BDFDB.TimeUtils.timeout(_ => {this.sortEntries(pluginRepoModal);},1000); - }); - BDFDB.ListenerUtils.addToChildren(pluginRepoModal, "change", ".hide-checkbox", e => { - pluginRepoModal.updateHidden = true; - BDFDB.DataUtils.save(e.currentTarget.checked, this, "hidden", e.currentTarget.value); - }); - BDFDB.ListenerUtils.addToChildren(pluginRepoModal, "change", "#input-rnmstart", e => { - BDFDB.DataUtils.save(e.currentTarget.checked, this, "RNMstart", "RNMstart"); - }); - BDFDB.ListenerUtils.addToChildren(pluginRepoModal, "click", ".sort-filter", e => { - BDFDB.createSortPopout(e.currentTarget, this.sortPopoutMarkup, _ => {this.sortEntries(pluginRepoModal);}); - }); - BDFDB.ListenerUtils.addToChildren(pluginRepoModal, "click", ".order-filter", e => { - BDFDB.createSortPopout(e.currentTarget, this.orderPopoutMarkup, _ => {this.sortEntries(pluginRepoModal);}); - }); - BDFDB.ListenerUtils.addToChildren(pluginRepoModal, "click", BDFDB.dotCN.tabbaritem + "[tab=plugins]", e => { - if (!BDFDB.DOMUtils.containsClass(e.currentTarget, BDFDB.disCN.settingsitemselected) && pluginRepoModal.updateHidden) { - delete pluginRepoModal.updateHidden; - this.sortEntries(pluginRepoModal); - } - }); - - let favorites = BDFDB.DataUtils.load(this, "favorites"); - let container = pluginRepoModal.querySelector(".plugins"); - pluginRepoModal.entries = {}; - for (let url in this.loadedPlugins) { - let plugin = this.loadedPlugins[url]; - let instPlugin = BDFDB.BDUtils.getPlugin(plugin.getName); - if (instPlugin && typeof instPlugin.getAuthor == "function" && this.getString(instPlugin.getAuthor()).toUpperCase() == plugin.getAuthor.toUpperCase()) plugin.getState = this.getString(instPlugin.getVersion()) != plugin.getVersion ? 1 : 0; - else plugin.getState = 2; - let data = { - url: plugin.url, - search: (plugin.getName + " " + plugin.getVersion + " " + plugin.getAuthor + " " + plugin.getDescription).toUpperCase(), - name: plugin.getName, - version: plugin.getVersion, - author: plugin.getAuthor, - description: plugin.getDescription ? plugin.getDescription : "No Description found.", - fav: favorites[url] ? 0 : 1, - new: !this.cachedPlugins.includes(url) ? 0 : 1, - state: plugin.getState + constructor () { + this.changelog = { + "improved":[["New Library Structure & React","Restructured my Library and switched to React rendering instead of DOM manipulation"]] }; - pluginRepoModal.entries[url] = data; - this.addEntry(pluginRepoModal, container, data); - } - this.sortEntries(pluginRepoModal); - BDFDB.appendModal(pluginRepoModal); - - pluginRepoModal.querySelector(BDFDB.dotCN.searchbarinput).focus(); - } - - addEntry (pluginRepoModal, container, data) { - if (!pluginRepoModal || !container || !data) return; - let entry = BDFDB.DOMUtils.create(this.pluginEntryMarkup); - setEntryState(data.state); - entry.setAttribute("data-name", data.name); - entry.setAttribute("data-version", data.version); - entry.setAttribute("data-url", data.url); - entry.querySelector(BDFDB.dotCN._reponame).innerHTML = data.name; - entry.querySelector(BDFDB.dotCN._repoversion).innerHTML = data.version; - entry.querySelector(BDFDB.dotCN._repoauthor).innerHTML = data.author; - entry.querySelector(BDFDB.dotCN._repodescription).innerHTML = data.description; - if (data.new == 0) entry.querySelector(BDFDB.dotCN._repoheadertitle).appendChild(BDFDB.DOMUtils.create(`NEW`)); - let favbutton = entry.querySelector(BDFDB.dotCN.giffavoritebutton); - BDFDB.DOMUtils.toggleClass(favbutton, BDFDB.disCN.giffavoriteselected, data.fav == 0); - favbutton.addEventListener("click", e => { - let favorize = data.fav == 1; - data.fav = favorize ? 0 : 1; - if (favorize) BDFDB.DataUtils.save(true, this, "favorites", data.url); - else BDFDB.DataUtils.remove(this, "favorites", data.url); - pluginRepoModal.entries[data.url] = data; - }); - let gitbutton = entry.querySelector(".gitIcon"); - gitbutton.addEventListener("click", e => { - var giturl = null; - if (data.url.indexOf("https://raw.githubusercontent.com") == 0) { - var temp = data.url.replace("//raw.githubusercontent", "//github").split("/"); - temp.splice(5, 0, "blob"); - giturl = temp.join("/"); - } - else if (data.url.indexOf("https://gist.githubusercontent.com/") == 0) { - giturl = data.url.replace("//gist.githubusercontent", "//gist.github").split("/raw/")[0]; - } - if (giturl) BDFDB.DiscordUtils.openLink(giturl, BDFDB.DataUtils.get(this, "settings", "useChromium")); - }); - gitbutton.addEventListener("mouseenter", e => { - BDFDB.TooltipUtils.create(gitbutton, "Go to Git", {type:"top",selector:"pluginrepo-giticon-tooltip"}); - }); - let trashbutton = entry.querySelector(".trashIcon"); - trashbutton.addEventListener("click", e => { - if (BDFDB.DOMUtils.containsClass(entry, "outdated", "updated", false)) { - setEntryState(2); - this.deletePluginFile(data); - if (!BDFDB.BDUtils.isAutoLoadEnabled()) this.stopPlugin(data); - } - }); - trashbutton.addEventListener("mouseenter", e => { - BDFDB.TooltipUtils.create(trashbutton, "Delete Pluginfile", {type:"top",selector:"pluginrepo-trashicon-tooltip"}); - }); - entry.querySelector(".btn-download").addEventListener("click", e => { - setEntryState(0); - this.downloadPlugin(data); - if (pluginRepoModal.querySelector("#input-rnmstart").checked) BDFDB.TimeUtils.timeout(_ => {this.startPlugin(data);},3000); - }); - - container.appendChild(entry); - - function setEntryState (state) { - data.state = state; - BDFDB.DOMUtils.toggleClass(entry, "downloadable", state > 1); - BDFDB.DOMUtils.toggleClass(entry, "outdated", state == 1); - BDFDB.DOMUtils.toggleClass(entry, "updated", state < 1); - let downloadbutton = entry.querySelector(".btn-download"); - downloadbutton.innerText = state < 1 ? "Updated" : (state > 1 ? "Download" : "Outdated"); - downloadbutton.style.setProperty("background-color", "rgb(" + (state < 1 ? "67,181,129" : (state > 1 ? "114,137,218" : "241,71,71")) + ")", state > 1 ? "" : "important"); - pluginRepoModal.entries[data.url] = data; - }; - } - - sortEntries (pluginRepoModal) { - if (!pluginRepoModal || typeof pluginRepoModal.entries != "object") return; - - let container = pluginRepoModal.querySelector(".plugins"); - if (!container) return; - - let searchstring = pluginRepoModal.querySelector(BDFDB.dotCN.searchbarinput).value.replace(/[<|>]/g, "").toUpperCase(); - - let entries = pluginRepoModal.entries; - if (pluginRepoModal.querySelector("#input-hideupdated").checked) entries = BDFDB.ObjectUtils.filter(entries, entry => {return entry.state < 1 ? null : entry;}); - if (pluginRepoModal.querySelector("#input-hideoutdated").checked) entries = BDFDB.ObjectUtils.filter(entries, entry => {return entry.state == 1 ? null : entry;}); - if (pluginRepoModal.querySelector("#input-hidedownloadable").checked) entries = BDFDB.ObjectUtils.filter(entries, entry => {return entry.state > 1 ? null : entry;}); - entries = BDFDB.ObjectUtils.filter(entries, entry => {return entry.search.indexOf(searchstring) > -1 ? entry : null;}); - - let sortfilter = pluginRepoModal.querySelector(".sort-filter " + BDFDB.dotCN.quickselectvalue).getAttribute("option"); - entries = BDFDB.ObjectUtils.sort(entries, sortfilter == "new" && !pluginRepoModal.querySelector(".newentries-tag") ? "name" : sortfilter); - if (pluginRepoModal.querySelector(".order-filter " + BDFDB.dotCN.quickselectvalue).getAttribute("option") == "desc") entries = BDFDB.ObjectUtils.reverse(entries); - - let entrypositions = Object.keys(entries); - - pluginRepoModal.querySelector(".pluginAmount").innerText = "PluginRepo Repository " + entrypositions.length + "/" + Object.keys(this.loadedPlugins).length + " Plugins"; - - for (let li of container.children) { - let pos = entrypositions.indexOf(li.getAttribute("data-url")); - if (pos > -1) { - li.querySelectorAll(BDFDB.dotCNC._reponame + BDFDB.dotCNC._repoversion + BDFDB.dotCNC._repoauthor + BDFDB.dotCN._repodescription).forEach(ele => { - if (searchstring && searchstring.length > 2 || ele.querySelector(BDFDB.dotCN.highlight)) ele.innerHTML = BDFDB.highlightText(ele.innerText, searchstring); - }); - li.style.setProperty("order", pos, "important"); - } - else li.style.removeProperty("order"); - BDFDB.DOMUtils.toggle(li, pos > -1); - } - } - - loadPlugins () { - BDFDB.DOMUtils.remove("iframe.discordSandbox",".pluginrepo-loadingicon"); - let settings = BDFDB.DataUtils.load(this, "settings"); - var getPluginInfo, createFrame, runInFrame; - var frame, framerunning = false, framequeue = [], outdated = 0, newentries = 0, i = 0; - var tags = ["getName", "getVersion", "getAuthor", "getDescription"]; - var seps = ["\"", "\'", "\`"]; - var newentriesdata = BDFDB.DataUtils.load(this, "newentriesdata"), ownlist = BDFDB.DataUtils.load(this, "ownlist", "ownlist") || []; - this.cachedPlugins = (newentriesdata.urlbase64 ? atob(newentriesdata.urlbase64).split("\n") : []).concat(ownlist); - BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/PluginRepo/res/PluginList.txt", (error, response, result) => { - if (!error && result) { - result = result.replace(/[\r\t]/g, ""); - BDFDB.DataUtils.save(btoa(result), this, "newentriesdata", "urlbase64"); - this.loadedPlugins = {}; - this.grabbedPlugins = result.split("\n").filter(n => n); - this.foundPlugins = this.grabbedPlugins.concat(ownlist); - this.loading = {is:true, timeout:BDFDB.TimeUtils.timeout(_ => { - BDFDB.TimeUtils.clear(this.loading.timeout); - if (this.started) { - if (this.loading.is && this.loading.amount < 4) BDFDB.TimeUtils.timeout(_ => {this.loadPlugins();},10000); - this.loading = {is: false, timeout:null, amount:this.loading.amount}; - } - },1200000), amount:this.loading.amount+1}; - var loadingiconwrapper = document.querySelector(BDFDB.dotCN.app + "> .repo-loadingwrapper"); - if (!loadingiconwrapper) { - loadingiconwrapper = BDFDB.DOMUtils.create(`
      `); - document.querySelector(BDFDB.dotCN.app).appendChild(loadingiconwrapper); + this.patchedModules = { + after: { + V2C_ContentColumn: "render" } - var loadingicon = BDFDB.DOMUtils.create(this.pluginRepoIconMarkup); - BDFDB.DOMUtils.addClass(loadingicon, "pluginrepo-loadingicon"); - loadingicon.addEventListener("mouseenter", _ => { - BDFDB.TooltipUtils.create(loadingicon, this.getLoadingTooltipText(), {type:"left", delay:500, style:"max-width:unset;", selector:"pluginrepo-loading-tooltip"}); - }); - loadingiconwrapper.appendChild(loadingicon); + }; + } - createFrame().then(_ => { - getPluginInfo(_ => { - if (!this.started) { - BDFDB.TimeUtils.clear(this.loading.timeout); - BDFDB.DOMUtils.remove(frame); - if (frame && frame.messageReceived) window.removeEventListener("message", frame.messageReceived); - return; + initConstructor () { + loading = {is:false, timeout:null, amount:0}; + + cachedPlugins = []; + grabbedPlugins = []; + foundPlugins = []; + loadedPlugins = {}; + + this.defaults = { + settings: { + useChromium: {value:false, description:"Use an inbuilt browser window instead of opening your default browser"}, + notifyOutdated: {value:true, description:"Notifies you when one of your Plugins is outdated"}, + notifyNewentries: {value:true, description:"Notifies you when there are new entries in the Repo"} + }, + modalSettings: { + updated: {value:true, modify:true, description:"Show updated Plugins",}, + outdated: {value:true, modify:true, description:"Show outdated Plugins"}, + downloadable: {value:true, modify:true, description:"Show downloadable Plugins"}, + rnmStart: {value:true, modify:false, description:"Start Plugin after Download"} + } + }; + + this.css = ` + .${this.name}-modal.repo-modal { + max-width: 800px; + min-height: 90vh; + max-height: 90vh; + } + `; + } + + 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 settingspanel, settingsitems = []; + + settingsitems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, { + title: "Settings", + collapseStates: collapseStates, + children: Object.keys(settings).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, { + className: BDFDB.disCN.marginbottom8, + type: "Switch", + plugin: this, + keys: ["settings", key], + label: this.defaults.settings[key].description, + value: settings[key] + })) + })); + settingsitems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, { + title: "Custom Plugins", + collapseStates: collapseStates, + dividertop: true, + children: [ + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, { + title: "Add Plugin:", + tag: BDFDB.LibraryComponents.FormComponents.FormTitleTags.H3, + className: BDFDB.disCNS.margintop4 + BDFDB.disCN.marginbottom8, + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, { + align: BDFDB.LibraryComponents.Flex.Align.CENTER, + children: [ + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, { + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, { + placeholder: customUrl, + placeholder: "Insert Raw Github Link of Plugin (https://raw.githubusercontent.com/...)", + onChange: value => {customUrl = value.trim();} + }) + }), + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, { + onClick: _ => { + if (customUrl) { + customList.push(customUrl); + BDFDB.DataUtils.save(BDFDB.ArrayUtils.removeCopies(customList), this, "custom"); + BDFDB.PluginUtils.refreshSettingsPanel(this, settingspanel, collapseStates); + } + }, + children: BDFDB.LanguageUtils.LanguageStrings.ADD + }) + ] + }) + }), + customList.length ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsPanelInner, { + title: "Custom Plugin List:", + className: BDFDB.disCNS.margintop8 + BDFDB.disCN.marginbottom20, + first: true, + last: true, + children: customList.map(url => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Card, { + children: url, + onRemove: _ => { + BDFDB.ArrayUtils.remove(customList, url, true); + BDFDB.DataUtils.save(customList, this, "custom"); + BDFDB.PluginUtils.refreshSettingsPanel(this, settingspanel, collapseStates); + } + })) + }) : null, + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, { + type: "Button", + color: BDFDB.LibraryComponents.Button.Colors.RED, + label: "Remove all custom added Plugins", + onClick: _ => { + BDFDB.ModalUtils.confirm(this, "Are you sure you want to remove all added Plugins from your own list", _ => { + BDFDB.DataUtils.save([], this, "custom"); + BDFDB.PluginUtils.refreshSettingsPanel(this, settingspanel, collapseStates); + }); + }, + children: BDFDB.LanguageUtils.LanguageStrings.REMOVE + }) + ].flat(10).filter(n => n) + })); + settingsitems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, { + title: "Refetch All", + collapseStates: collapseStates, + dividertop: true, + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, { + type: "Button", + label: "Force all Plugins to be fetched again", + onClick: _ => { + loading = {is:false, timeout:null, amount:0}; + this.loadPlugins(); + }, + children: BDFDB.LanguageUtils.LanguageStrings.ERRORS_RELOAD + }) + })); + + return settingspanel = BDFDB.PluginUtils.createSettingsPanel(this, settingsitems); + } + + //legacy + load () {} + + start () { + if (!window.BDFDB) window.BDFDB = {myPlugins:{}}; + if (window.BDFDB && window.BDFDB.myPlugins && typeof window.BDFDB.myPlugins == "object") window.BDFDB.myPlugins[this.getName()] = this; + let libraryScript = document.querySelector("head script#BDFDBLibraryScript"); + if (!libraryScript || (performance.now() - libraryScript.getAttribute("date")) > 600000) { + if (libraryScript) libraryScript.remove(); + libraryScript = document.createElement("script"); + libraryScript.setAttribute("id", "BDFDBLibraryScript"); + libraryScript.setAttribute("type", "text/javascript"); + libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js"); + libraryScript.setAttribute("date", performance.now()); + libraryScript.addEventListener("load", _ => {this.initialize();}); + document.head.appendChild(libraryScript); + } + else if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) this.initialize(); + this.startTimeout = setTimeout(_ => { + try {return this.initialize();} + catch (err) {console.error(`%c[${this.getName()}]%c`, "color: #3a71c1; font-weight: 700;", "", "Fatal Error: Could not initiate plugin! " + err);} + }, 30000); + } + + initialize () { + if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + if (this.started) return; + BDFDB.PluginUtils.init(this); + + // REMOVE 18.01.2020 + let olddata = BDFDB.DataUtils.load(this, "ownlist", "ownlist"); + if (olddata) { + BDFDB.DataUtils.save(olddata, this, "custom"); + BDFDB.DataUtils.remove(this, "ownlist"); + } + + this.loadPlugins(); + + updateInterval = BDFDB.TimeUtils.interval(_ => {this.checkForNewPlugins();},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!"); + } + + + stop () { + if (window.BDFDB && typeof BDFDB === "object" && BDFDB.loaded) { + this.stopping = true; + + BDFDB.TimeUtils.clear(updateInterval); + BDFDB.TimeUtils.clear(loading.timeout); + + BDFDB.ModuleUtils.forceAllUpdates(this); + + BDFDB.DOMUtils.remove(".bd-pluginrepobutton", ".pluginrepo-notice", ".pluginrepo-loadingicon"); + + let frame = document.querySelector("iframe.discordSandbox"); + if (frame) { + window.removeEventListener("message", frame.messageReceived); + BDFDB.DOMUtils.remove(frame); + } + + BDFDB.PluginUtils.clear(this); + } + } + + + // begin of own functions + + onUserSettingsCogContextMenu (e) { + BDFDB.TimeUtils.timeout(_ => { + let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {props: [["label", "BandagedBD"]]}); + if (index > -1) children[index].props.render.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ContextMenuItems.Item, { + label: "Plugin Repo", + action: _ => { + if (!loading.is) BDFDB.ContextMenuUtils.close(e.instance); + this.openPluginRepoModal(); + } + })); + }); + } + + processV2CContentColumn (e) { + if (e.instance.props.title == "Plugins") { + let [children, index] = BDFDB.ReactUtils.findChildren(e.returnvalue, {key: "folder-button"}); + if (index > -1) children.splice(index + 1, 0, BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, { + text: "Open Plugin Repo", + children: BDFDB.ReactUtils.createElement("button", { + className: `${BDFDB.disCN._repofolderbutton} bd-pluginrepobutton`, + onClick: _ => {this.openPluginRepoModal();}, + children: "PluginRepo" + }) + })); + } + } + + getCustomList () { + let customlist = BDFDB.DataUtils.load(this, "custom"); + return BDFDB.ArrayUtils.is(customlist) ? customlist : []; + } + + + openPluginRepoModal (options = {}) { + if (loading.is) BDFDB.NotificationUtils.toast(`Plugins are still being fetched. Try again in some seconds.`, {type:"danger"}); + else { + currentSearchString = ""; + selectedSortKey = options.forcedSort || Object.keys(sortKeys)[0]; + selectedOrderKey = options.forcedOrder || Object.keys(orderKeys)[0]; + let searchTimeout; + let modalSettings = BDFDB.DataUtils.get(this, "modalSettings"), automaticLoading = BDFDB.BDUtils.isAutoLoadEnabled(); + let entries = this.createEntries(); + BDFDB.ModalUtils.open(this, { + className: "repo-modal", + size: "LARGE", + header: "Plugin Repository", + subheader: BDFDB.ReactUtils.createElement(class RepoAmount extends BDFDB.ReactUtils.Component { + render () {return `${this.props.entries.length}/${Object.keys(loadedPlugins).length} Plugins`} + }, {entries}), + tabBarChildren: [ + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, { + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SearchBar, { + autoFocus: true, + onChange: (value, instance) => { + BDFDB.TimeUtils.clear(searchTimeout); + searchTimeout = BDFDB.TimeUtils.timeout(_ => { + currentSearchString = value.replace(/[<|>]/g, "").toUpperCase(); + this.updateList(instance); + }, 1000); + }, + onClear: instance => { + currentSearchString = ""; + this.updateList(instance); + } + }) + }), + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, { + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, { + label: "Sort by:", + value: { + label: sortKeys[selectedSortKey], + value: selectedSortKey + }, + options: Object.keys(sortKeys).map(key => {return { + label: sortKeys[key], + value: key + };}), + onChange: (key, instance) => { + selectedSortKey = key; + this.updateList(instance); + } + }) + }), + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, { + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.QuickSelect, { + label: "Order:", + value: { + label: orderKeys[selectedOrderKey], + value: selectedOrderKey + }, + options: Object.keys(orderKeys).map(key => {return { + label: orderKeys[key], + value: key + };}), + onChange: (key, instance) => { + selectedOrderKey = key; + this.updateList(instance); + } + }) + }) + ], + children: [ + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, { + tab: "Plugins", + children: BDFDB.ReactUtils.createElement(repoListComponent, { + key: "repo-list", + plugin: this, + entries: entries + }) + }), + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ModalComponents.ModalTabContent, { + tab: BDFDB.LanguageUtils.LanguageStrings.SETTINGS, + children: [ + !automaticLoading && 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: "To experience PluginRepo 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." + }) + }), + 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: modalSettings[key] && (key != "outdated" || !options.showOnlyOutdated) || (this.defaults.modalSettings[key].modify && options.showOnlyOutdated), + onChange: (value, instance) => { + this.updateList(instance); + } + })) + ].flat(10).filter(n => n) + }) + ] + }); + } + } + + updateList (instance) { + let modalIns = BDFDB.ReactUtils.findOwner(instance, {name:"BDFDB_Modal", up:true}); + if (modalIns) { + let listIns = BDFDB.ReactUtils.findOwner(modalIns, {key:"repo-list"}); + let amountIns = BDFDB.ReactUtils.findOwner(modalIns, {name:"RepoAmount"}); + if (listIns && amountIns) { + let entries = this.createEntries(); + listIns.props.entries = entries; + amountIns.props.entries = entries; + BDFDB.ReactUtils.forceUpdate(listIns, amountIns); + } + } + } + + createEntries () { + let favorites = BDFDB.DataUtils.load(this, "favorites"); + let modalSettings = BDFDB.DataUtils.get(this, "modalSettings"); + let plugins = Object.keys(loadedPlugins).map(url => { + let plugin = loadedPlugins[url]; + let instPlugin = BDFDB.BDUtils.getPlugin(plugin.getName); + if (instPlugin && typeof instPlugin.getAuthor == "function" && this.getString(instPlugin.getAuthor()).toUpperCase() == plugin.getAuthor.toUpperCase()) plugin.getState = this.getString(instPlugin.getVersion()) != plugin.getVersion ? pluginStates.OUTDATED : pluginStates.UPDATED; + else plugin.getState = pluginStates.DOWNLOADABLE; + return { + url: plugin.url, + search: (plugin.getName + " " + plugin.getVersion + " " + plugin.getAuthor + " " + plugin.getDescription).toUpperCase(), + name: plugin.getName, + version: plugin.getVersion, + author: plugin.getAuthor, + description: plugin.getDescription ? plugin.getDescription : "No Description found.", + fav: favorites[url] ? favStates.FAVORIZED : favStates.NOT_FAVORIZED, + new: !cachedPlugins.includes(url) ? newStates.NEW : newStates.NOT_NEW, + state: plugin.getState + }; + }); + if (!modalSettings.updated) plugins = plugins.filter(plugin => plugin.state == pluginStates.UPDATED); + if (!modalSettings.outdated) plugins = plugins.filter(plugin => plugin.state == pluginStates.OUTDATED); + if (!modalSettings.downloadable) plugins = plugins.filter(plugin => plugin.state == pluginStates.DOWNLOADABLE); + if (currentSearchString) plugins = plugins.filter(plugin => plugin.search.indexOf(currentSearchString) > -1).map(plugin => Object.assign({}, plugin, { + name: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(plugin.name, currentSearchString))) || plugin.name, + version: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(plugin.version, currentSearchString))) || plugin.version, + author: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(plugin.author, currentSearchString))) || plugin.author, + description: BDFDB.ReactUtils.elementToReact(BDFDB.DOMUtils.create(BDFDB.StringUtils.highlight(plugin.description, currentSearchString))) || plugin.description + })); + + BDFDB.ArrayUtils.keySort(plugins, (selectedSortKey == "NEW" && !plugins.some(plugin => plugin.new == newStates.NEW) ? Object.keys(sortKeys)[0] : selectedSortKey).toLowerCase()); + if (selectedOrderKey == "DESC") plugins.reverse(); + return plugins.map(plugin => { + let buttonConfig = buttonData[(Object.entries(pluginStates).find(n => n[1] == plugin.state) || [])[0]] + return buttonConfig && { + data: plugin, + controls: [ + plugin.new == newStates.NEW && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.BadgeComponents.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.disCNS._repoentryiconwrapper + BDFDB.disCN.cursorpointer, + isFavorite: plugin.fav == favStates.FAVORIZED, + onClick: value => { + plugin.fav = value ? favStates.FAVORIZED : favStates.NOT_FAVORIZED; + if (value) BDFDB.DataUtils.save(true, this, "favorites", plugin.url); + else BDFDB.DataUtils.remove(this, "favorites", plugin.url); + } + }), + BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, { + text: "Go to Source", + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, { + className: BDFDB.disCNS._repoentryiconwrapper, + onClick: _ => { + let giturl = null; + if (plugin.url.indexOf("https://raw.githubusercontent.com") == 0) { + let temp = plugin.url.replace("//raw.githubusercontent", "//github").split("/"); + temp.splice(5, 0, "blob"); + giturl = temp.join("/"); + } + else if (plugin.url.indexOf("https://gist.githubusercontent.com/") == 0) { + giturl = plugin.url.replace("//gist.githubusercontent", "//gist.github").split("/raw/")[0]; + } + if (giturl) BDFDB.DiscordUtils.openLink(giturl, BDFDB.DataUtils.get(this, "settings", "useChromium")); + }, + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, { + iconSVG: gitHubIcon + }) + }) + }) + ], + buttons: [ + plugin.state != pluginStates.DOWNLOADABLE && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, { + text: "Delete Pluginfile", + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, { + className: BDFDB.disCN._repoentryiconwrapper, + children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, { + className: BDFDB.disCN.svgicon, + name: BDFDB.LibraryComponents.SvgIcon.Names.NOVA_TRASH + }), + onClick: (e, instance) => { + this.deletePluginFile(plugin); + BDFDB.TimeUtils.timeout(_ => { + this.updateList(instance); + if (!BDFDB.BDUtils.isAutoLoadEnabled()) this.stopPlugin(plugin); + }, 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.downloadPlugin(plugin); + BDFDB.TimeUtils.timeout(_ => { + this.updateList(instance); + if (modalSettings.rnmStart) this.startPlugin(plugin); + }, 3000); + } + }) + ] + }; + }).filter(n => n); + } + + loadPlugins () { + BDFDB.DOMUtils.remove("iframe.discordSandbox", ".pluginrepo-loadingicon"); + let settings = BDFDB.DataUtils.load(this, "settings"); + let getPluginInfo, createFrame, runInFrame; + let frame, framerunning = false, framequeue = [], outdated = 0, newentries = 0, i = 0; + let tags = ["getName", "getVersion", "getAuthor", "getDescription"]; + let seps = ["\"", "\'", "\`"]; + let newentriesdata = BDFDB.DataUtils.load(this, "newentriesdata"), customList = this.getCustomList(); + cachedPlugins = (newentriesdata.urlbase64 ? atob(newentriesdata.urlbase64).split("\n") : []).concat(customList); + BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/PluginRepo/res/PluginList.txt", (error, response, result) => { + if (!error && result) { + result = result.replace(/[\r\t]/g, ""); + BDFDB.DataUtils.save(btoa(result), this, "newentriesdata", "urlbase64"); + + loadedPlugins = {}; + grabbedPlugins = result.split("\n").filter(n => n); + foundPlugins = grabbedPlugins.concat(customList); + + loading = {is:true, timeout:BDFDB.TimeUtils.timeout(_ => { + BDFDB.TimeUtils.clear(loading.timeout); + if (this.started) { + if (loading.is && loading.amount < 4) BDFDB.TimeUtils.timeout(_ => {this.loadPlugins();},10000); + loading = {is: false, timeout:null, amount:loading.amount}; } - var finishCounter = 0, finishInterval = BDFDB.TimeUtils.interval(_ => { - if ((framequeue.length == 0 && !framerunning) || finishCounter > 300 || !this.loading.is) { - BDFDB.TimeUtils.clear(finishInterval); - BDFDB.DOMUtils.remove(frame, loadingicon, ".pluginrepo-loadingicon"); + },1200000), amount:loading.amount+1}; + + let loadingicon = BDFDB.DOMUtils.create(pluginRepoIcon); + BDFDB.DOMUtils.addClass(loadingicon, "pluginrepo-loadingicon"); + loadingicon.addEventListener("mouseenter", _ => { + BDFDB.TooltipUtils.create(loadingicon, this.getLoadingTooltipText(), { + type: "left", + delay: 500, + style: "max-width: unset;", + selector: "pluginrepo-loading-tooltip" + }); + }); + BDFDB.PluginUtils.addLoadingIcon(loadingicon); + + createFrame().then(_ => { + getPluginInfo(_ => { + if (!this.started) { + BDFDB.TimeUtils.clear(loading.timeout); + BDFDB.DOMUtils.remove(frame); if (frame && frame.messageReceived) window.removeEventListener("message", frame.messageReceived); - if (!loadingiconwrapper.firstChild) BDFDB.DOMUtils.remove(loadingiconwrapper); - BDFDB.TimeUtils.clear(this.loading.timeout); - this.loading = {is:false, timeout:null, amount:this.loading.amount}; - console.log(`%c[${this.name}]%c`, "color: #3a71c1; font-weight: 700;", "", "Finished fetching Plugins."); - if (document.querySelector(".bd-pluginrepobutton")) BDFDB.NotificationUtils.toast(`Finished fetching Plugins.`, {type:"success"}); - if ((settings.notifyOutdated || settings.notifyOutdated == undefined) && outdated > 0) { - var oldbarbutton = document.querySelector(".pluginrepo-outdate-notice " + BDFDB.dotCN.noticedismiss); - if (oldbarbutton) oldbarbutton.click(); - var bar = BDFDB.NotificationUtils.notice(`${outdated} of your Plugins ${outdated == 1 ? "is" : "are"} outdated. Check:`,{type:"danger",btn:"PluginRepo",selector:"pluginrepo-notice pluginrepo-outdate-notice", customicon:this.pluginRepoIconMarkup.replace(/#7289da/gi,"#FFF").replace(/#7f8186/gi,"#B9BBBE")}); - bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", e => { - this.openPluginRepoModal({showOnlyOutdated:true}); - bar.querySelector(BDFDB.dotCN.noticedismiss).click(); - }); - } - if ((settings.notifyNewentries || settings.notifyNewentries == undefined) && newentries > 0) { - var oldbarbutton = document.querySelector(".pluginrepo-newentries-notice " + BDFDB.dotCN.noticedismiss); - if (oldbarbutton) oldbarbutton.click(); - var bar = BDFDB.NotificationUtils.notice(`There ${newentries == 1 ? "is" : "are"} ${newentries} new Plugin${newentries == 1 ? "" : "s"} in the Repo. Check:`,{type:"success",btn:"PluginRepo",selector:"pluginrepo-notice pluginrepo-newentries-notice", customicon:this.pluginRepoIconMarkup.replace(/#7289da/gi,"#FFF").replace(/#7f8186/gi,"#B9BBBE")}); - bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", e => { - this.openPluginRepoModal({forcedSort:"new",forcedOrder:"asc"}); - bar.querySelector(BDFDB.dotCN.noticedismiss).click(); - }); - } - if (BDFDB.UserUtils.me.id == "278543574059057154") { - let wrongUrls = []; - for (let url of this.foundPlugins) if (url && !this.loadedPlugins[url] && !wrongUrls.includes(url)) wrongUrls.push(url); - if (wrongUrls.length > 0) { - var bar = BDFDB.NotificationUtils.notice(`PluginRepo: ${wrongUrls.length} Plugin${wrongUrls.length > 1 ? "s" : ""} could not be loaded.`, {type:"danger",btn:"List",selector:"pluginrepo-notice pluginrepo-fail-notice", customicon:this.pluginRepoIconMarkup.replace(/#7289da/gi,"#FFF").replace(/#7f8186/gi,"#B9BBBE")}); - bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", e => { - var toast = BDFDB.NotificationUtils.toast(wrongUrls.join("\n"),{type:"error"}); - toast.style.overflow = "hidden"; - console.log(wrongUrls.length == 1 ? wrongUrls[0] : wrongUrls); + return; + } + let finishCounter = 0, finishInterval = BDFDB.TimeUtils.interval(_ => { + if ((framequeue.length == 0 && !framerunning) || finishCounter > 300 || !loading.is) { + BDFDB.TimeUtils.clear(loading.timeout); + BDFDB.TimeUtils.clear(finishInterval); + BDFDB.DOMUtils.remove(frame, loadingicon, ".pluginrepo-loadingicon"); + if (frame && frame.messageReceived) window.removeEventListener("message", frame.messageReceived); + loading = {is:false, timeout:null, amount:loading.amount}; + + BDFDB.LogUtils.log("Finished fetching Plugins.", this.name); + if (document.querySelector(".bd-pluginrepobutton")) BDFDB.NotificationUtils.toast(`Finished fetching Plugins.`, {type:"success"}); + + if ((settings.notifyOutdated || settings.notifyOutdated == undefined) && outdated > 0) { + let oldbarbutton = document.querySelector(".pluginrepo-outdate-notice " + BDFDB.dotCN.noticedismiss); + if (oldbarbutton) oldbarbutton.click(); + let bar = BDFDB.NotificationUtils.notice(`${outdated} of your Plugins ${outdated == 1 ? "is" : "are"} outdated. Check:`, { + type: "danger", + btn: "PluginRepo", + selector: "pluginrepo-notice pluginrepo-outdate-notice", + customicon: pluginRepoIcon.replace(/#7289da/gi, "#FFF").replace(/#7f8186/gi, "#B9BBBE") }); + bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", _ => { + this.openPluginRepoModal({showOnlyOutdated:true}); + bar.querySelector(BDFDB.dotCN.noticedismiss).click(); + }); + } + + if ((settings.notifyNewentries || settings.notifyNewentries == undefined) && newentries > 0) { + let oldbarbutton = document.querySelector(".pluginrepo-newentries-notice " + BDFDB.dotCN.noticedismiss); + if (oldbarbutton) oldbarbutton.click(); + let single = newentries == 1; + let bar = BDFDB.NotificationUtils.notice(`There ${single ? "is" : "are"} ${newentries} new Plugin${single ? "" : "s"} in the Repo. Check:`, { + type: "success", + btn: "PluginRepo", + selector: "pluginrepo-notice pluginrepo-newentries-notice", + customicon: pluginRepoIcon.replace(/#7289da/gi, "#FFF").replace(/#7f8186/gi, "#B9BBBE") + }); + bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", _ => { + this.openPluginRepoModal({forcedSort:"NEW", forcedOrder:"ASC"}); + bar.querySelector(BDFDB.dotCN.noticedismiss).click(); + }); + } + + if (BDFDB.UserUtils.me.id == "278543574059057154") { + let wrongUrls = []; + for (let url of foundPlugins) if (url && !loadedPlugins[url] && !wrongUrls.includes(url)) wrongUrls.push(url); + if (wrongUrls.length) { + let bar = BDFDB.NotificationUtils.notice(`PluginRepo: ${wrongUrls.length} Plugin${wrongUrls.length > 1 ? "s" : ""} could not be loaded.`, { + type: "danger", + btn: "List", + selector: "pluginrepo-notice pluginrepo-fail-notice", + customicon: pluginRepoIcon.replace(/#7289da/gi, "#FFF").replace(/#7f8186/gi, "#B9BBBE") + }); + bar.querySelector(BDFDB.dotCN.noticebutton).addEventListener("click", e => { + let toast = BDFDB.NotificationUtils.toast(wrongUrls.join("\n"), {type: "error"}); + toast.style.setProperty("overflow", "hidden"); + for (let url of wrongUrls) console.log(url); + }); + } + } + } + else finishCounter++; + },1000); + }); + }); + } + }); + + getPluginInfo = (callback) => { + if (i >= foundPlugins.length || !this.started || !loading.is) { + callback(); + return; + } + let url = foundPlugins[i]; + BDFDB.LibraryRequires.request(url, (error, response, body) => { + if (!response) { + if (url && BDFDB.ArrayUtils.getAllIndexes(foundPlugins, url).length < 2) foundPlugins.push(url); + } + else if (body && body.indexOf("404: Not Found") != 0 && response.statusCode == 200) { + let plugin = {}; + let bodycopy = body; + if (body.length / body.split("\n").length > 1000) { + /* code is minified -> add newlines */ + bodycopy = body.replace(/}/g, "}\n"); + } + let configreg = /(module\.exports|config)\s*=\s*\{\n*\r*\t*["'`]*info["'`]*\s*:\s*/i.exec(bodycopy); + if (url != "https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/PluginRepo/PluginRepo.plugin.js" && configreg) { + try { + let config = JSON.parse('{"info":' + bodycopy.substring(configreg.index).split(configreg[0])[1].split("};")[0] + '}'); + plugin.getName = config.info.name.charAt(0).toUpperCase() + config.info.name.slice(1); + plugin.getDescription = config.info.description.charAt(0).toUpperCase() + config.info.description.slice(1); + plugin.getVersion = config.info.version; + plugin.getAuthor = ""; + if (typeof config.info.author == "string") plugin.getAuthor = config.info.author.charAt(0).toUpperCase() + config.info.author.slice(1); + else if (typeof config.info.authors == "string") plugin.getAuthor = config.info.authors.charAt(0).toUpperCase() + config.info.authors.slice(1); + else if (Array.isArray(config.info.authors)) for (let author of config.info.authors) { + plugin.getAuthor += (plugin.getAuthor + (plugin.getAuthor ? ", " : "") + (typeof author == "string" ? author : author.name)); + } + } + catch (err) {} + } + else { + for (let tag of tags) { + let result = new RegExp(tag + "[\\s|\\t|\\n|\\r|=|>|_|:|function|\(|\)|\{|return]*([\"|\'|\`]).*\\1","gi").exec(bodycopy); + if (!result) result = new RegExp("get " + tag.replace("get", "").toLowerCase() + "[\\s|\\t|\\n|\\r|=|>|_|:|function|\(|\)|\{|return]*([\"|\'|\`]).*\\1","gi").exec(bodycopy); + if (result) { + let separator = result[1]; + result = result[0].replace(new RegExp("\\\\" + separator, "g"), separator).split(separator); + if (result.length > 2) { + result = result.slice(1, -1).join(separator).replace(/\\n/g, "
      ").replace(/\\/g, ""); + result = tag != "getVersion" ? result.charAt(0).toUpperCase() + result.slice(1) : result; + plugin[tag] = result ? result.trim() : result; } } } - else finishCounter++; - },1000); - }); + } + + if (!tags.some(tag => !plugin[tag] || plugin[tag].length > 10000)) { + plugin.url = url; + loadedPlugins[url] = plugin; + let instPlugin = BDFDB.BDUtils.getPlugin(plugin.getName); + if (instPlugin && typeof instPlugin.getAuthor == "function" && this.getString(instPlugin.getAuthor()).toUpperCase() == plugin.getAuthor.toUpperCase() && this.getString(instPlugin.getVersion()) != plugin.getVersion && PluginUpdates && PluginUpdates.plugins && !PluginUpdates.plugins[url]) outdated++; + if (!cachedPlugins.includes(url)) newentries++; + } + else if (frame && frame.contentWindow) { + framequeue.push({body, url}); + runInFrame(); + } + } + i++; + + let loadingtooltip = document.querySelector(".pluginrepo-loading-tooltip"); + if (loadingtooltip) { + BDFDB.DOMUtils.setText(loadingtooltip, this.getLoadingTooltipText()); + BDFDB.TooltipUtils.update(loadingtooltip); + } + + getPluginInfo(callback); }); } - }); - getPluginInfo = (callback) => { - if (i >= this.foundPlugins.length || !this.started || !this.loading.is) { - callback(); - return; + createFrame = _ => { + return new Promise(callback => { + frame = BDFDB.DOMUtils.create(``); + frame.startTimeout = BDFDB.TimeUtils.timeout(_ => { + callback(); + },600000); + frame.messageReceived = e => { + if (!document.contains(frame)) { + window.removeEventListener("message", frame.messageReceived); + } + else if (typeof e.data === "object" && e.data.origin == "DiscordPreview") { + switch (e.data.reason) { + case "OnLoad": + frame.contentWindow.postMessage({ + origin: "PluginRepo", + reason: "OnLoad", + classes: JSON.stringify(BDFDB.DiscordClasses), + classmodules: JSON.stringify(BDFDB.DiscordClassModules) + }, "*"); + callback(); + break; + } + } + }; + window.addEventListener("message", frame.messageReceived); + + document.body.appendChild(frame); + }); } - let url = this.foundPlugins[i]; - BDFDB.LibraryRequires.request(url, (error, response, body) => { - if (!response) { - if (url && BDFDB.ArrayUtils.getAllIndexes(this.foundPlugins, url).length < 2) this.foundPlugins.push(url); - } - else if (body && body.indexOf("404: Not Found") != 0 && response.statusCode == 200) { - let plugin = {}; - let bodycopy = body; - if (body.length / body.split("\n").length > 1000) { - /* code is minified -> add newlines */ - bodycopy = body.replace(/}/g, "}\n"); - } - let configreg = /(module\.exports|config)\s*=\s*\{\n*\r*\t*["'`]*info["'`]*\s*:\s*/i.exec(bodycopy); - if (url != "https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/PluginRepo/PluginRepo.plugin.js" && configreg) { - try { - let config = JSON.parse('{"info":' + bodycopy.substring(configreg.index).split(configreg[0])[1].split("};")[0] + '}'); - plugin.getName = config.info.name.charAt(0).toUpperCase() + config.info.name.slice(1); - plugin.getDescription = config.info.description.charAt(0).toUpperCase() + config.info.description.slice(1); - plugin.getVersion = config.info.version; - plugin.getAuthor = ""; - if (typeof config.info.author == "string") plugin.getAuthor = config.info.author.charAt(0).toUpperCase() + config.info.author.slice(1); - else if (typeof config.info.authors == "string") plugin.getAuthor = config.info.authors.charAt(0).toUpperCase() + config.info.authors.slice(1); - else if (Array.isArray(config.info.authors)) for (let author of config.info.authors) { - plugin.getAuthor += (plugin.getAuthor + (plugin.getAuthor ? ", " : "") + (typeof author == "string" ? author : author.name)); - } + + runInFrame = _ => { + if (framerunning) return; + let framedata = framequeue.shift(); + if (!framedata) return; + framerunning = true; + let {body, url} = framedata; + let name = body.replace(/\s*:\s*/g, ":").split('"name":"'); + if (name.length > 1) { + name = name[1].split('"')[0]; + let processResult = plugin => { + if (BDFDB.ObjectUtils.is(plugin)) { + plugin.url = url; + loadedPlugins[url] = plugin; + let instPlugin = BDFDB.BDUtils.getPlugin(plugin.getName); + if (instPlugin && typeof instPlugin.getAuthor == "function" && this.getString(instPlugin.getAuthor()).toUpperCase() == plugin.getAuthor.toUpperCase() && this.getString(instPlugin.getVersion()) != plugin.getVersion) outdated++; + if (!cachedPlugins.includes(url)) newentries++; } - catch (err) {} - } - else { - for (let tag of tags) { - let result = new RegExp(tag + "[\\s|\\t|\\n|\\r|=|>|_|:|function|\(|\)|\{|return]*([\"|\'|\`]).*\\1","gi").exec(bodycopy); - if (!result) result = new RegExp("get " + tag.replace("get", "").toLowerCase() + "[\\s|\\t|\\n|\\r|=|>|_|:|function|\(|\)|\{|return]*([\"|\'|\`]).*\\1","gi").exec(bodycopy); - if (result) { - let separator = result[1]; - result = result[0].replace(new RegExp("\\\\" + separator, "g"), separator).split(separator); - if (result.length > 2) { - result = result.slice(1, -1).join(separator).replace(/\\n/g, "
      ").replace(/\\/g, ""); - result = tag != "getVersion" ? result.charAt(0).toUpperCase() + result.slice(1) : result; - plugin[tag] = result ? result.trim() : result; - } - } - } - } - let valid = true; - for (let tag of tags) if (!plugin[tag] || plugin[tag].length > 10000) valid = false; - if (valid) { - plugin.url = url; - this.loadedPlugins[url] = plugin; - let instPlugin = BDFDB.BDUtils.getPlugin(plugin.getName); - if (instPlugin && typeof instPlugin.getAuthor == "function" && this.getString(instPlugin.getAuthor()).toUpperCase() == plugin.getAuthor.toUpperCase() && this.getString(instPlugin.getVersion()) != plugin.getVersion && PluginUpdates && PluginUpdates.plugins && !PluginUpdates.plugins[url]) outdated++; - if (!this.cachedPlugins.includes(url)) newentries++; - } - else if (frame && frame.contentWindow) { - framequeue.push({body, url}); + framerunning = false; runInFrame(); - } + }; + let evalResultReceived = e => { + if (typeof e.data === "object" && e.data.origin == "DiscordPreview") { + switch (e.data.reason) { + case "EvalResult": + window.removeEventListener("message", evalResultReceived); + processResult(e.data.result); + break; + } + } + }; + window.addEventListener("message", evalResultReceived); + frame.contentWindow.postMessage({origin:"PluginRepo",reason:"Eval",jsstring:` + try { + ${body} + var p = new ${name}(); + var data = { + "getName":getString(p.getName()), + "getAuthor":getString(p.getAuthor()), + "getVersion":getString(p.getVersion()), + "getDescription":getString(p.getDescription()) + }; + window.evalResult = data; + } + catch (err) { + window.evalResult = null; + }` + },"*"); } - i++; - var loadingtooltip = document.querySelector(".pluginrepo-loading-tooltip"); - if (loadingtooltip) { - BDFDB.DOMUtils.setText(loadingtooltip, this.getLoadingTooltipText()); - BDFDB.TooltipUtils.update(loadingtooltip); + } + } + + getLoadingTooltipText () { + return `Loading PluginRepo - [${Object.keys(loadedPlugins).length}/${Object.keys(grabbedPlugins).length}]`; + } + + getString (obj) { + let string = ""; + if (typeof obj == "string") string = obj; + else if (obj && obj.props) { + if (typeof obj.props.children == "string") string = obj.props.children; + else if (Array.isArray(obj.props.children)) for (let c of obj.props.children) string += typeof c == "string" ? c : this.getString(c); + } + return string; + } + + checkForNewPlugins () { + BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/PluginRepo/res/PluginList.txt", (error, response, result) => { + if (response && !BDFDB.equals(result.replace(/\t|\r/g, "").split("\n").filter(n => n), grabbedPlugins)) { + loading = {is:false, timeout:null, amount:0}; + this.loadPlugins(); } - getPluginInfo(callback); }); } - createFrame = _ => { - var markup = this.frameMarkup; - return new Promise(function(callback) { - frame = BDFDB.DOMUtils.create(markup); - frame.startTimeout = BDFDB.TimeUtils.timeout(_ => { - callback(); - },600000); - frame.messageReceived = e => { - if (!document.contains(frame)) { - window.removeEventListener("message", frame.messageReceived); - } - else if (typeof e.data === "object" && e.data.origin == "DiscordPreview") { - switch (e.data.reason) { - case "OnLoad": - frame.contentWindow.postMessage({origin:"PluginRepo",reason:"OnLoad",classes:JSON.stringify(BDFDB.DiscordClasses),classmodules:JSON.stringify(BDFDB.DiscordClassModules)},"*"); - callback(); - break; - } - } - }; - window.addEventListener("message", frame.messageReceived); - - document.body.appendChild(frame); + downloadPlugin (data) { + BDFDB.LibraryRequires.request(data.url, (error, response, body) => { + if (error) BDFDB.NotificationUtils.toast(`Unable to download Plugin "${plugin.getName}".`, {type:"danger"}); + else this.createPluginFile(data.url.split("/").pop(), body); }); } - runInFrame = _ => { - if (framerunning) return; - let framedata = framequeue.shift(); - if (!framedata) return; - framerunning = true; - let {body, url} = framedata; - let name = body.replace(/\s*:\s*/g, ":").split('"name":"'); - if (name.length > 1) { - name = name[1].split('"')[0]; - var processResult = plugin => { - if (BDFDB.ObjectUtils.is(plugin)) { - plugin.url = url; - this.loadedPlugins[url] = plugin; - let instPlugin = BDFDB.BDUtils.getPlugin(plugin.getName); - if (instPlugin && typeof instPlugin.getAuthor == "function" && this.getString(instPlugin.getAuthor()).toUpperCase() == plugin.getAuthor.toUpperCase() && this.getString(instPlugin.getVersion()) != plugin.getVersion) outdated++; - if (!this.cachedPlugins.includes(url)) newentries++; - } - framerunning = false; - runInFrame(); - }; - var evalResultReceived = e => { - if (typeof e.data === "object" && e.data.origin == "DiscordPreview") { - switch (e.data.reason) { - case "EvalResult": - window.removeEventListener("message", evalResultReceived); - processResult(e.data.result); - break; - } - } - }; - window.addEventListener("message", evalResultReceived); - frame.contentWindow.postMessage({origin:"PluginRepo",reason:"Eval",jsstring:` - try { - ${body} - var p = new ${name}(); - var data = { - "getName":getString(p.getName()), - "getAuthor":getString(p.getAuthor()), - "getVersion":getString(p.getVersion()), - "getDescription":getString(p.getDescription()) - }; - window.evalResult = data; - } - catch (err) { - window.evalResult = null; - }` - },"*"); + createPluginFile (filename, content) { + BDFDB.LibraryRequires.fs.writeFile(BDFDB.LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), filename), content, (error) => { + if (error) BDFDB.NotificationUtils.toast(`Unable to save Plugin "${filename}".`, {type:"danger"}); + else BDFDB.NotificationUtils.toast(`Successfully saved Plugin "${filename}".`, {type:"success"}); + }); + } + + startPlugin (data) { + if (BDFDB.BDUtils.isPluginEnabled(data.name) == false) { + window.pluginModule.startPlugin(data.name); + BDFDB.LogUtils.log(`Started Plugin ${data.name}.`, this.name); + } + } + + deletePluginFile (data) { + let filename = data.url.split("/").pop(); + BDFDB.LibraryRequires.fs.unlink(BDFDB.LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), filename), (error) => { + if (error) BDFDB.NotificationUtils.toast(`Unable to delete Plugin "${filename}".`, {type:"danger"}); + else BDFDB.NotificationUtils.toast(`Successfully deleted Plugin "${filename}".`); + }); + } + + stopPlugin (data) { + if (BDFDB.BDUtils.isPluginEnabled(data.name) == true) { + window.pluginModule.stopPlugin(data.name); + BDFDB.LogUtils.log(`Stopped Plugin ${data.name}.`, this.name); } } } - - getLoadingTooltipText () { - return `Loading PluginRepo - [${Object.keys(this.loadedPlugins).length}/${Object.keys(this.grabbedPlugins).length}]`; - } - - getString (obj) { - var string = ""; - if (typeof obj == "string") string = obj; - else if (obj && obj.props) { - if (typeof obj.props.children == "string") string = obj.props.children; - else if (Array.isArray(obj.props.children)) for (let c of obj.props.children) string += typeof c == "string" ? c : this.getString(c); - } - return string; - } - - checkForNewPlugins () { - BDFDB.LibraryRequires.request("https://mwittrien.github.io/BetterDiscordAddons/Plugins/PluginRepo/res/PluginList.txt", (error, response, result) => { - if (response && !BDFDB.equals(result.replace(/\t|\r/g, "").split("\n").filter(n => n), this.grabbedPlugins)) { - this.loading = {is:false, timeout:null, amount:0}; - this.loadPlugins(); - } - }); - } - - downloadPlugin (data) { - BDFDB.LibraryRequires.request(data.url, (error, response, body) => { - if (error) BDFDB.NotificationUtils.toast(`Unable to download Plugin "${plugin.getName}".`, {type:"danger"}); - else this.createPluginFile(data.url.split("/").pop(), body); - }); - } - - createPluginFile (filename, content) { - BDFDB.LibraryRequires.fs.writeFile(BDFDB.LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), filename), content, (error) => { - if (error) BDFDB.NotificationUtils.toast(`Unable to save Plugin "${filename}".`, {type:"danger"}); - else BDFDB.NotificationUtils.toast(`Successfully saved Plugin "${filename}".`, {type:"success"}); - }); - } - - startPlugin (data) { - if (BDFDB.BDUtils.isPluginEnabled(data.name) == false) { - window.pluginModule.startPlugin(data.name); - console.log(`%c[${this.name}]%c`, "color: #3a71c1; font-weight: 700;", "", "Started Plugin " + data.name + "."); - } - } - - deletePluginFile (data) { - let filename = data.url.split("/").pop(); - BDFDB.LibraryRequires.fs.unlink(BDFDB.LibraryRequires.path.join(BDFDB.BDUtils.getPluginsFolder(), filename), (error) => { - if (error) BDFDB.NotificationUtils.toast(`Unable to delete Plugin "${filename}".`, {type:"danger"}); - else BDFDB.NotificationUtils.toast(`Successfully deleted Plugin "${filename}".`); - }); - } - - stopPlugin (data) { - if (BDFDB.BDUtils.isPluginEnabled(data.name) == true) { - window.pluginModule.stopPlugin(data.name); - console.log(`%c[${this.name}]%c`, "color: #3a71c1; font-weight: 700;", "", "Stopped Plugin " + data.name + "."); - } - } -} +})(); \ No newline at end of file