commit fe3018ce373967df8c4dfd3ab42caadc0318b818 Author: Henry Hiles Date: Wed Jun 15 11:35:53 2022 -0400 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c85333 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Powercord Plugin/Theme Downloader + +A package for the [kernel client mod](https://github.com/kernel-mod/) to download plugins and themes from the #plugin-links and #theme-links channels (on the powercord discord server) with a single click. (Compatible with openasar) + +![button](https://i.imgur.com/qrE0xA3.png) + +## Prerequisites + +### [Webpack Package](https://github.com/strencher-kernel/webpack) + +### [PC-Compat Package](https://github.com/strencher-kernel/pc-compat) + +To install the prerequisites, you can either [use my package downloader](https://github.com/Henry-Hiles/kernel-package-downloader) or run these: + +1. `cd ` +2. `git clone https://github.com/strencher-kernel/webpack` +3. `git clone https://github.com/strencher-kernel/pc-compat` +4. `cd pc-compat` +5. `pnpm i --production` + +Then restart Discord with `Ctrl+R` + +## Installation + +**Before you follow this make sure you have the prerequisites.** +To install the prerequisites, you can either [use my package downloader](https://github.com/Henry-Hiles/kernel-package-downloader) or run these: + +1. `cd ` +2. `git clone https://github.com/Henry-Hiles/kernel-powercord-plugin-downloader` + +Then restart Discord with `Ctrl+R` + +Huge thank you to the kernel devs and helper team for making this possible. diff --git a/index.json b/index.json new file mode 100644 index 0000000..6797458 --- /dev/null +++ b/index.json @@ -0,0 +1,6 @@ +{ + "name": "Powercord Plugin/Theme Downloader", + "id": "powercord-plugin-downloader", + "description": "A powercord plugin and theme downloader for kernel. (pc-compat required)", + "dependencies": ["strencher.webpack", "strencher.pc-compat"] +} diff --git a/preload.js b/preload.js new file mode 100644 index 0000000..765e52f --- /dev/null +++ b/preload.js @@ -0,0 +1,21 @@ +const { contextBridge } = require("electron") +const { resolve, join } = require("path") + +const exec = require("util").promisify(require("child_process").exec) + +contextBridge.exposeInMainWorld("download", async (link, plugin) => { + const pluginsPath = join( + resolve(__dirname, "..", ".."), + "powercord", + plugin ? "plugins" : "themes" + ) + try { + await exec(`git clone ${link[0]}`, { + cwd: pluginsPath, + }) + + return { reloadMessage: "Please reload discord with Ctrl+R" } + } catch (error) { + return { error } + } +}) diff --git a/renderer.js b/renderer.js new file mode 100644 index 0000000..e0f69c9 --- /dev/null +++ b/renderer.js @@ -0,0 +1,135 @@ +/// + +export default new (class PluginDownloader { + async start() { + const pluginLog = (msg, logFunc = console.info) => + logFunc(`%c[${this.constructor.name}] `, "color:#14bbaa", msg) + + pluginLog("Started successfully") + + await Webpack.whenReady + const { React } = Webpack.common + const MiniPopover = Webpack.findByDisplayName("MiniPopover", { + default: true, + }) + const Toasts = Object.assign( + {}, + ...Webpack.getByProps("showToast", "createToast", { + bulk: true, + }) + ) + const Tooltip = Webpack.findByDisplayName("Tooltip") + const funcCopy = MiniPopover.default + + MiniPopover.default = (...args) => { + const props = args[0].children.at?.(-1) + ? args[0].children.at(-1).props + : null + + const isPluginChannel = props.channel.id == "755005584322854972" + const isThemeChannel = props.channel.id == "755005710323941386" + + const Button = () => { + const [disabled, setDisabled] = React.useState(false) + + const gitURL = props.message.content.match( + /((git@|http(s)?:\/\/)([\w\.@]+)(\/|:))([\w,\-,\_]+)\/([\w,\-,\_]+)(.git){0,1}((\/){0,1})/ + ) + + return [ + React.createElement( + Tooltip, + { + position: "top", + text: isPluginChannel + ? "Install Plugin" + : "Install Theme", + }, + (args) => + React.createElement( + MiniPopover.Button, + { + ...args, + disabled: disabled, + onClick: async () => { + setDisabled(true) + + const { reloadMessage, error } = + await window.download( + gitURL, + isPluginChannel + ) + + if (reloadMessage) { + Toasts.showToast( + Toasts.createToast( + `Successfully installed plugin/theme! ${ + reloadMessage + ? `${reloadMessage}.` + : "" + }`, + Toasts.ToastType.SUCCESS + ) + ) + pluginLog( + `Successfully installed plugin/theme! ${ + reloadMessage + ? `${reloadMessage}.` + : "" + }` + ) + } else { + Toasts.showToast( + Toasts.createToast( + "Failed to install plugin/theme, check console for error.", + Toasts.ToastType.ERROR + ) + ) + pluginLog( + `Plugin/theme installation failed: ${error}`, + console.error + ) + setDisabled(false) + } + }, + }, + React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "16", + height: "16", + fill: "currentColor", + class: "bi bi-arrow-down-circle-fill", + viewBox: "0 0 16 16", + }, + React.createElement("path", { + d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z", + }) + ) + ) + ), + React.createElement(MiniPopover.Separator), + ] + } + + if ( + props?.message && + props.channel && + (isPluginChannel || isThemeChannel) + ) + args[0].children.unshift(React.createElement(Button)) + + return funcCopy.apply(this, args) + } + + Object.assign(MiniPopover.default, funcCopy) + + pluginLog("Patched, ready to download plugins!") + + this.stop = () => { + MiniPopover.default = funcCopy + pluginLog("Stopped successfully") + } + } +})()