diff --git a/renderer/src/builtins/general/publicservers.js b/renderer/src/builtins/general/publicservers.js index 86fd66e3..3f7c9ae1 100644 --- a/renderer/src/builtins/general/publicservers.js +++ b/renderer/src/builtins/general/publicservers.js @@ -92,6 +92,10 @@ export default new class PublicServers extends Builtin { aSlot.href = ""; aSlot.dataset.listItemId = "public-servers"; + // Remove any badges + const badge = newButton.querySelector(`[class*="premiumTrial"]`); + badge?.remove?.(); + // Render our icon in the avatar slot const avatarSlot = newButton.querySelector(`[class*="avatar-"]`); avatarSlot.replaceChildren(); diff --git a/renderer/src/modules/addonmanager.js b/renderer/src/modules/addonmanager.js index ae3c514c..245c0a76 100644 --- a/renderer/src/modules/addonmanager.js +++ b/renderer/src/modules/addonmanager.js @@ -206,7 +206,7 @@ export default class AddonManager { if (partialAddon) { partialAddon.partial = true; this.state[partialAddon.id] = false; - this.emit("loaded", partialAddon.id); + this.emit("loaded", partialAddon); } return e; } @@ -216,12 +216,12 @@ export default class AddonManager { if (error) { this.state[addon.id] = false; addon.partial = true; - this.emit("loaded", addon.id); + this.emit("loaded", addon); return error; } if (shouldToast) Toasts.success(`${addon.name} v${addon.version} was loaded.`); - this.emit("loaded", addon.id); + this.emit("loaded", addon); if (!this.state[addon.id]) return this.state[addon.id] = false; return this.startAddon(addon); @@ -234,7 +234,7 @@ export default class AddonManager { if (this.state[addon.id]) isReload ? this.stopAddon(addon) : this.disableAddon(addon); this.addonList.splice(this.addonList.indexOf(addon), 1); - this.emit("unloaded", addon.id); + this.emit("unloaded", addon); if (shouldToast) Toasts.success(`${addon.name} was unloaded.`); return true; } diff --git a/renderer/src/modules/core.js b/renderer/src/modules/core.js index e784f270..411e028d 100644 --- a/renderer/src/modules/core.js +++ b/renderer/src/modules/core.js @@ -1,4 +1,3 @@ -const path = require("path"); import LocaleManager from "./localemanager"; import Logger from "common/logger"; @@ -11,8 +10,6 @@ import * as Builtins from "builtins"; import Modals from "../ui/modals"; import DataStore from "./datastore"; import DiscordModules from "./discordmodules"; -import Strings from "./strings"; -import IPC from "./ipc"; import LoadingIcon from "../loadingicon"; import Styles from "../styles/index.css"; import Editor from "./editor"; @@ -37,9 +34,6 @@ export default new class Core { Logger.log("Startup", "Initializing LocaleManager"); LocaleManager.initialize(); - Logger.log("Startup", "Getting update information"); - this.checkForUpdate(); - Logger.log("Startup", "Initializing Settings"); Settings.initialize(); @@ -78,7 +72,7 @@ export default new class Core { Modals.showAddonErrors({plugins: pluginErrors, themes: themeErrors}); const previousVersion = DataStore.getBDData("version"); - if (Config.version > previousVersion) { + if (Config.version !== previousVersion) { Modals.showChangelogModal(Changelog); DataStore.setBDData("version", Config.version); } @@ -90,57 +84,4 @@ export default new class Core { DiscordModules.Dispatcher.subscribe("CONNECTION_OPEN", done); }); } - - async checkForUpdate() { - const resp = await fetch(`https://api.github.com/repos/BetterDiscord/BetterDiscord/releases/latest`,{ - method: "GET", - headers: { - "Accept": "application/json", - "Content-Type": "application/json", - "User-Agent": "BetterDiscord Updater" - } - }); - - const data = await resp.json(); - Object.assign(Config.release, data); - const remoteVersion = data.tag_name.startsWith("v") ? data.tag_name.slice(1) : data.tag_name; - const hasUpdate = remoteVersion > Config.version; - if (!hasUpdate) return; - - // TODO: move to strings file when updater is complete. - Modals.showConfirmationModal("Update Available", `BetterDiscord (v${Config.version}) has an update available (v${remoteVersion}). Would you like to update now?`, { - confirmText: "Update Now!", - cancelText: "Skip", - onConfirm: () => this.update(data) - }); - } - - async update(releaseInfo) { - try { - const asar = releaseInfo.assets.find(a => a.name === "betterdiscord.asar"); - const request = require("request"); - const buff = await new Promise((resolve, reject) => - request(asar.url, {encoding: null, headers: {"User-Agent": "BetterDiscord Updater", "Accept": "application/octet-stream"}}, (err, resp, body) => { - if (err || resp.statusCode != 200) return reject(err || `${resp.statusCode} ${resp.statusMessage}`); - return resolve(body); - })); - - const asarPath = path.join(DataStore.baseFolder, "betterdiscord.asar"); - const fs = require("original-fs"); - fs.writeFileSync(asarPath, buff); - - Modals.showConfirmationModal("Update Successful!", "BetterDiscord updated successfully. Discord needs to restart in order for it to take effect. Do you want to do this now?", { - confirmText: Strings.Modals.restartNow, - cancelText: Strings.Modals.restartLater, - danger: true, - onConfirm: () => IPC.relaunch() - }); - } - catch (err) { - Logger.stacktrace("Updater", "Failed to update", err); - Modals.showConfirmationModal("Update Failed", "BetterDiscord failed to update. Please download the latest version of the installer from GitHub (https://github.com/BetterDiscord/Installer/releases/latest) and reinstall.", { - cancelText: null - }); - } - } }; diff --git a/renderer/src/modules/localemanager.js b/renderer/src/modules/localemanager.js index 87a86300..77439b5f 100644 --- a/renderer/src/modules/localemanager.js +++ b/renderer/src/modules/localemanager.js @@ -3,7 +3,7 @@ import DiscordModules from "./discordmodules"; import Utilities from "./utilities"; import Events from "./emitter"; -const {Dispatcher, LocaleStore} = DiscordModules; +const {LocaleStore} = DiscordModules; export default new class LocaleManager { get discordLocale() {return LocaleStore?.locale ?? this.defaultLocale;} @@ -16,7 +16,7 @@ export default new class LocaleManager { initialize() { this.setLocale(this.discordLocale); - Dispatcher.subscribe("USER_SETTINGS_UPDATE", (newLocale) => this.setLocale(newLocale)); + LocaleStore?.addChangeListener((newLocale) => this.setLocale(newLocale)); } setLocale(newLocale) { diff --git a/renderer/src/modules/updater.js b/renderer/src/modules/updater.js index b550d5ec..0b7775cb 100644 --- a/renderer/src/modules/updater.js +++ b/renderer/src/modules/updater.js @@ -5,6 +5,7 @@ import path from "path"; import Logger from "common/logger"; +import Events from "./emitter"; import IPC from "./ipc"; import Strings from "./strings"; import DataStore from "./datastore"; @@ -25,7 +26,7 @@ const React = DiscordModules.React; const UserSettingsWindow = WebpackModules.getByProps("updateAccount"); const base = "https://api.betterdiscord.app/v2/store/"; -const route = r => `${base}${r}`; +const route = r => `${base}${r}s`; const redirect = addonId => `https://betterdiscord.app/gh-redirect?id=${addonId}`; const getJSON = url => { @@ -137,7 +138,7 @@ export class CoreUpdater { class AddonUpdater { constructor(type) { - this.manager = type === "plugins" ? PluginManager : ThemeManager; + this.manager = type === "plugin" ? PluginManager : ThemeManager; this.type = type; this.cache = {}; this.pending = []; @@ -146,6 +147,14 @@ class AddonUpdater { async initialize() { await this.updateCache(); this.checkAll(); + Events.on(`${this.type}-loaded`, addon => { + this.checkForUpdate(addon.filename, addon.version); + }); + + Events.on(`${this.type}-unloaded`, addon => { + const index = this.pending.indexOf(addon.filename); + if (index >= 0) this.pending.splice(index, 1); + }); } async updateCache() { @@ -190,7 +199,7 @@ class AddonUpdater { showUpdateNotice() { if (!this.pending.length) return; - const close = Notices.info(`BetterDiscord has found updates for ${this.pending.length} of your ${this.type}!`, { + const close = Notices.info(`BetterDiscord has found updates for ${this.pending.length} of your ${this.type}s!`, { buttons: [{ label: "More Info", onClick: () => { @@ -202,5 +211,5 @@ class AddonUpdater { } } -export const PluginUpdater = new AddonUpdater("plugins"); -export const ThemeUpdater = new AddonUpdater("themes"); \ No newline at end of file +export const PluginUpdater = new AddonUpdater("plugin"); +export const ThemeUpdater = new AddonUpdater("theme"); \ No newline at end of file diff --git a/renderer/src/ui/updater.jsx b/renderer/src/ui/updater.jsx index 5c64e495..f26f67de 100644 --- a/renderer/src/ui/updater.jsx +++ b/renderer/src/ui/updater.jsx @@ -1,5 +1,5 @@ import {Config} from "data"; -import {React} from "modules"; +import {React, Events} from "modules"; import Drawer from "./settings/drawer"; import SettingItem from "./settings/components/item"; import SettingsTitle from "./settings/title"; @@ -56,6 +56,26 @@ export default class UpdaterPanel extends React.Component { this.checkForUpdates = this.checkForUpdates.bind(this); this.updateAddon = this.updateAddon.bind(this); this.updateAllAddons = this.updateAllAddons.bind(this); + this.update = this.update.bind(this); + } + + update() { + this.checkAddons("plugins"); + this.checkAddons("themes"); + } + + componentDidMount() { + Events.on(`plugin-loaded`, this.update); + Events.on(`plugin-unloaded`, this.update); + Events.on(`theme-loaded`, this.update); + Events.on(`theme-unloaded`, this.update); + } + + componentWillUnmount() { + Events.off(`plugin-loaded`, this.update); + Events.off(`plugin-unloaded`, this.update); + Events.off(`theme-loaded`, this.update); + Events.off(`theme-unloaded`, this.update); } async checkForUpdates() {