diff --git a/renderer/src/modules/addonupdater.js b/renderer/src/modules/addonupdater.js index 147e6130..91114cf6 100644 --- a/renderer/src/modules/addonupdater.js +++ b/renderer/src/modules/addonupdater.js @@ -1,26 +1,22 @@ -import {Config} from "data"; -import fileSystem from "fs"; -import path from "path"; import request from "request"; +import fileSystem from "fs"; +import {Config} from "data"; +import path from "path"; import PluginManager from "./pluginmanager"; import ThemeManager from "./thememanager"; import Toasts from "../ui/toasts"; import Notices from "../ui/notices"; -import Logger from "../../../common/logger"; - +import Logger from "common/logger"; const base = "https://api.betterdiscord.app/v2/store/"; const route = r => `${base}${r}`; const redirect = addonId => `https://betterdiscord.app/gh-redirect?id=${addonId}`; -// const raceTimeout = (delay, reason) => new Promise((_, rej) => setTimeout(() => rej(reason), delay)); -// const timeout = (promise, delay, reason) => Promise.race([promise, raceTimeout(delay, reason)]); - const getJSON = url => { return new Promise(resolve => { - request(url, (error, response, body) => { + request(url, (error, _, body) => { if (error) return resolve([]); resolve(JSON.parse(body)); }); @@ -40,19 +36,15 @@ export default class AddonUpdater { this.shown = false; this.pending = []; - Logger.info("AddonUpdater", "Before get api"); const pluginData = await getJSON(route("plugins")); const themeData = await getJSON(route("themes")); - Logger.info("AddonUpdater", "After get api"); - - this.temp = {pluginData, themeData}; pluginData.reduce(reducer, this.cache); themeData.reduce(reducer, this.cache); - Logger.info("AddonUpdater", "going to check lists"); for (const addon of PluginManager.addonList) this.checkForUpdate(addon.filename, addon.version); for (const addon of ThemeManager.addonList) this.checkForUpdate(addon.filename, addon.version); + this.showUpdateNotice(); } @@ -61,7 +53,6 @@ export default class AddonUpdater { } static async checkForUpdate(filename, currentVersion) { - Logger.info("AddonUpdater", "checkForUpdate", filename, currentVersion); const info = this.cache[path.basename(filename)]; if (!info) return; const hasUpdate = info.version > currentVersion; @@ -71,22 +62,20 @@ export default class AddonUpdater { static async updatePlugin(filename) { const info = this.cache[filename]; - request(redirect(info.id), (err, response) => { - if (err) return; - if (!response.headers.location) return; // expected redirect - request(response.headers.location, (error, _, body) => { - if (error) return; - const file = path.join(path.resolve(Config.dataPath, info.type + "s"), filename); - fileSystem.writeFile(file, body.toString(), () => { - Toasts.success(`${info.name} has been updated to version ${info.version}!`); - }); - }); + request(redirect(info.id), (error, _, body) => { + if (error) { + Logger.stacktrace("AddonUpdater", `Failed to download body for ${info.id}:`, error); + return; + } + const file = path.join(path.resolve(Config.dataPath, info.type + "s"), filename); + fileSystem.writeFile(file, body.toString(), () => { + Toasts.success(`${info.name} has been updated to version ${info.version}!`); + }); }); } static showUpdateNotice() { - Logger.info("AddonUpdater", "showUpdateNotice", this.shown, this.pending); if (this.shown || !this.pending.length) return; this.shown = true; const close = Notices.info(`BetterDiscord has found updates for ${this.pending.length} of your plugins and themes!`, { @@ -105,5 +94,3 @@ export default class AddonUpdater { }); } } - -window.updater = AddonUpdater; \ No newline at end of file diff --git a/renderer/src/modules/pluginapi.js b/renderer/src/modules/pluginapi.js index e9583b51..0e6b6dc7 100644 --- a/renderer/src/modules/pluginapi.js +++ b/renderer/src/modules/pluginapi.js @@ -155,7 +155,7 @@ BdApi.showToast = function(content, options = {}) { * @param {object} options Options for the notice. * @param {string} [options.type="info" | "error" | "warning" | "success"] Type for the notice. Will affect the color. * @param {Array<{label: string, onClick: function}>} [options.buttons] Buttons that should be added next to the notice text. - * @param {number} [options.timeout=10000] Timeout until the notice is closed. Won't fire if it's set to 0; + * @param {number} [options.timeout=0] Timeout until the notice is closed. Won't fire if it's set to 0; * @returns {function} A callback for closing the notice. Passing `true` as first parameter closes immediately without transitioning out. */ BdApi.showNotice = function (content, options = {}) { @@ -681,4 +681,4 @@ Object.freeze(BdApi.Patcher); Object.freeze(BdApi.Webpack); Object.freeze(BdApi.Webpack.Filters); -export default BdApi; \ No newline at end of file +export default BdApi; diff --git a/renderer/src/styles/ui/addonlist.css b/renderer/src/styles/ui/addonlist.css index 8dfeb747..2ad67c29 100644 --- a/renderer/src/styles/ui/addonlist.css +++ b/renderer/src/styles/ui/addonlist.css @@ -112,9 +112,10 @@ .bd-description-wrap .banner { padding: 5px; - border-left: 5px solid gray; + border: 2px solid gray; background: #26191E; - color: #C13A3A; + color: #ffffff; + font-weight: 700px; border-radius: 5px; font-size: 16px; display: flex; @@ -122,19 +123,18 @@ } .banner.banner-danger { - border-left-color: #C13A3A; - background: #26191E; - color: #C13A3A; + border-color: #F04747; + background: #473C41; } .banner .bd-icon { - fill: red; + fill: #ffffff; margin-right: 5px; height: 16px !important; } .banner-danger .bd-icon { - fill: red; + fill: #F04747; } .bd-addon-list .bd-description { @@ -315,4 +315,4 @@ .bd-addon-list .bd-footer .bd-links .bd-addon-button { height: 24px; -} \ No newline at end of file +} diff --git a/renderer/src/ui/notices.js b/renderer/src/ui/notices.js index 3585d274..b914ceab 100644 --- a/renderer/src/ui/notices.js +++ b/renderer/src/ui/notices.js @@ -1,7 +1,8 @@ -import {WebpackModules} from "modules"; +import {Utilities, WebpackModules} from "modules"; export default class Notices { - static get baseClass() {return this.__baseClass || (this.__baseClass = WebpackModules.getByProps("container", "base")?.base);} + static get baseClass() {return this.__baseClass ??= WebpackModules.getByProps("container", "base")?.base;} + static get errorPageClass() {return this.__errorPageClass ??= WebpackModules.getByProps("errorPage")?.errorPage;} /** Shorthand for `type = "info"` for {@link module:Notices.show} */ static info(content, options = {}) {return this.show(content, Object.assign({}, options, {type: "info"}));} @@ -32,7 +33,7 @@ export default class Notices { * @param {object} options Options for the notice. * @param {string} [options.type="info" | "error" | "warning" | "success"] Type for the notice. Will affect the color. * @param {Array<{label: string, onClick: (immediately?: boolean = false) => void}>} [options.buttons] Buttons that should be added next to the notice text. - * @param {number} [options.timeout=10000] Timeout until the toast is closed. Won't fire if it's set to 0; + * @param {number} [options.timeout=0] Timeout until the toast is closed. Won't fire if it's set to 0; * @returns {(immediately?: boolean = false) => void} */ static show(content, options = {}) { @@ -83,6 +84,14 @@ export default class Notices { }); container.prepend(noticeContainer); + Utilities.onRemoved(container, async () => { + if (!this.errorPageClass) return; + + const element = await new Promise(res => Utilities.onAdded(`.${this.errorPageClass}`, res)); + + element.prepend(noticeContainer); + }); + return true; } -} \ No newline at end of file +}