Make updater responsive

This commit is contained in:
Zack Rauen 2022-10-10 02:32:57 -04:00
parent a984bf08b0
commit 9c0a8747f3
6 changed files with 46 additions and 72 deletions

View File

@ -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();

View File

@ -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;
}

View File

@ -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
});
}
}
};

View File

@ -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) {

View File

@ -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");
export const PluginUpdater = new AddonUpdater("plugin");
export const ThemeUpdater = new AddonUpdater("theme");

View File

@ -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() {