Add initial pass at core updater
- Fix duplicate file regex - Add core updater - Unify versions - Add sanity for plugin/theme folder
This commit is contained in:
parent
66d8d7a069
commit
5b1900fe3d
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"name": "betterdiscord-renderer",
|
||||
"version": "1.0.0",
|
||||
"description": "Renderer portion of the BetterDiscord application.",
|
||||
"private": true,
|
||||
"main": "src/index.js",
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
export default {
|
||||
local: false,
|
||||
localPath: "",
|
||||
minified: true,
|
||||
branch: "stable",
|
||||
repo: "rauenzi",
|
||||
minSupportedVersion: "0.3.0",
|
||||
bdVersion: "1.0.0",
|
||||
version: process.env.__VERSION__,
|
||||
|
||||
// Get from main process
|
||||
version: "0.6.0",
|
||||
path: "",
|
||||
appPath: "",
|
||||
userData: ""
|
||||
|
|
|
@ -287,7 +287,6 @@ export default {
|
|||
},
|
||||
Startup: {
|
||||
notSupported: "Not Supported",
|
||||
versionMismatch: "BetterDiscord Injector v{{injector}} is not supported by the latest remote (v{{remote}}).\n\nPlease download the latest version from [GitHub](https://github.com/rauenzi/BetterDiscordApp/releases/latest)",
|
||||
incompatibleApp: "BetterDiscord does not work with {{app}}. Please uninstall one of them.",
|
||||
updateNow: "Update Now",
|
||||
maybeLater: "Maybe Later",
|
||||
|
|
|
@ -45,21 +45,18 @@ export default new class ComponentPatcher {
|
|||
children[children.length - 2].type = newOne;
|
||||
}
|
||||
|
||||
const injector = DiscordModules.React.createElement("div", {className: "colorMuted-HdFt4q size12-3cLvbJ"}, `Injector ${Config.version}`);
|
||||
const versionHash = `(${Config.hash ? Config.hash.substring(0, 7) : Config.branch})`;
|
||||
const additional = DiscordModules.React.createElement("div", {className: "colorMuted-HdFt4q size12-3cLvbJ"}, `BD ${Config.bdVersion} `, DiscordModules.React.createElement("span", {className: "versionHash-2gXjIB da-versionHash"}, versionHash));
|
||||
|
||||
const additional = DiscordModules.React.createElement("div", {className: "colorMuted-HdFt4q size12-3cLvbJ"}, `BetterDiscord ${Config.version}`);
|
||||
|
||||
|
||||
const originalVersions = children[children.length - 1].type;
|
||||
children[children.length - 1].type = function() {
|
||||
const returnVal = originalVersions(...arguments);
|
||||
returnVal.props.children.splice(returnVal.props.children.length - 1, 0, injector);
|
||||
returnVal.props.children.splice(1, 0, additional);
|
||||
return returnVal;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
patchGuildListItems() {
|
||||
if (this.guildListItemsPatch) return;
|
||||
|
@ -158,7 +155,7 @@ export default new class ComponentPatcher {
|
|||
|
||||
// Tropical's notes
|
||||
|
||||
/*
|
||||
/*
|
||||
html [maximized | bd | stable | canary | ptb]
|
||||
.iconWrapper-2OrFZ1 [type]
|
||||
.sidebar-2K8pFh [guild-id]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const path = require("path");
|
||||
import LocaleManager from "./localemanager";
|
||||
|
||||
import Logger from "common/logger";
|
||||
|
@ -13,6 +14,7 @@ import DataStore from "./datastore";
|
|||
import DiscordModules from "./discordmodules";
|
||||
import ComponentPatcher from "./componentpatcher";
|
||||
import Strings from "./strings";
|
||||
import IPC from "./ipc";
|
||||
import LoadingIcon from "../loadingicon";
|
||||
import Styles from "../styles/index.css";
|
||||
|
||||
|
@ -39,7 +41,7 @@ export default new class Core {
|
|||
// console.error = toFile(window.oce);
|
||||
// console.exception = toFile(window.ocx);
|
||||
// })();
|
||||
|
||||
|
||||
Config.appPath = process.env.DISCORD_APP_PATH;
|
||||
Config.userData = process.env.DISCORD_USER_DATA;
|
||||
Config.dataPath = process.env.BETTERDISCORD_DATA_PATH;
|
||||
|
@ -55,7 +57,6 @@ export default new class Core {
|
|||
await LocaleManager.initialize();
|
||||
|
||||
Logger.log("Startup", "Performing incompatibility checks");
|
||||
if (Config.version < Config.minSupportedVersion) return Modals.alert(Strings.Startup.notSupported, Strings.Startup.versionMismatch.format({injector: Config.version, remote: Config.bdVersion}));
|
||||
if (window.ED) return Modals.alert(Strings.Startup.notSupported, Strings.Startup.incompatibleApp.format({app: "EnhancedDiscord"}));
|
||||
if (window.WebSocket && window.WebSocket.name && window.WebSocket.name.includes("Patched")) return Modals.alert(Strings.Startup.notSupported, Strings.Startup.incompatibleApp.format({app: "Powercord"}));
|
||||
|
||||
|
@ -97,10 +98,12 @@ export default new class Core {
|
|||
Modals.showAddonErrors({plugins: pluginErrors, themes: themeErrors});
|
||||
|
||||
const previousVersion = DataStore.getBDData("version");
|
||||
if (Config.bdVersion > previousVersion) {
|
||||
if (Config.version > previousVersion) {
|
||||
Modals.showChangelogModal(Changelog);
|
||||
DataStore.setBDData("version", Config.bdVersion);
|
||||
DataStore.setBDData("version", Config.version);
|
||||
}
|
||||
|
||||
this.checkForUpdate();
|
||||
}
|
||||
|
||||
waitForGuilds() {
|
||||
|
@ -112,12 +115,64 @@ export default new class Core {
|
|||
const wrapper = GuildClasses.wrapper.split(" ")[0];
|
||||
const guild = GuildClasses.listItem.split(" ")[0];
|
||||
const blob = GuildClasses.blobContainer.split(" ")[0];
|
||||
if (document.querySelectorAll(`.${wrapper} .${guild} .${blob}`).length > 0) return resolve(Config.deferLoaded = true);
|
||||
// else if (timesChecked >= 50) return resolve(Config.deferLoaded = true);
|
||||
if (document.querySelectorAll(`.${wrapper} .${guild} .${blob}`).length > 0) return resolve();
|
||||
// else if (timesChecked >= 50) return resolve();
|
||||
setTimeout(checkForGuilds, 100);
|
||||
};
|
||||
|
||||
checkForGuilds();
|
||||
});
|
||||
}
|
||||
|
||||
async checkForUpdate() {
|
||||
const resp = await fetch(`https://api.github.com/repos/rauenzi/BetterDiscordApp/releases/latest`,{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "BetterDiscord Updater"
|
||||
}
|
||||
});
|
||||
|
||||
const data = await resp.json();
|
||||
const remoteVersion = data.tag_name.startsWith("v") ? data.tag_name.slice(1) : data.tag_name;
|
||||
const hasUpdate = remoteVersion > Config.version;
|
||||
if (!hasUpdate) return;
|
||||
|
||||
Modals.showConfirmationModal("Update", "There is an update, would you like to update now?", {
|
||||
confirmText: "Update",
|
||||
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": "BD 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");
|
||||
console.log(asarPath);
|
||||
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) {
|
||||
console.error(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: ""
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
|
@ -29,6 +29,12 @@ export default new class DataStore {
|
|||
const bdFolderExists = fs.existsSync(Config.dataPath);
|
||||
if (!bdFolderExists) fs.mkdirSync(Config.dataPath);
|
||||
|
||||
const pluginFolderExists = fs.existsSync(this.pluginFolder);
|
||||
if (!pluginFolderExists) fs.mkdirSync(this.pluginFolder);
|
||||
|
||||
const themeFolderExists = fs.existsSync(this.themeFolder);
|
||||
if (!themeFolderExists) fs.mkdirSync(this.themeFolder);
|
||||
|
||||
const newStorageExists = fs.existsSync(this.baseFolder);
|
||||
if (!newStorageExists) fs.mkdirSync(this.baseFolder);
|
||||
|
||||
|
@ -101,6 +107,8 @@ export default new class DataStore {
|
|||
return this._injectionPath = realLocation;
|
||||
}
|
||||
|
||||
get pluginFolder() {return this._pluginFolder || (this._pluginFolder = path.resolve(Config.dataPath, "plugins"));}
|
||||
get themeFolder() {return this._themeFolder || (this._themeFolder = path.resolve(Config.dataPath, "themes"));}
|
||||
get customCSS() {return this._customCSS || (this._customCSS = path.resolve(this.dataFolder, "custom.css"));}
|
||||
get baseFolder() {return this._baseFolder || (this._baseFolder = path.resolve(Config.dataPath, "data"));}
|
||||
get dataFolder() {return this._dataFolder || (this._dataFolder = path.resolve(this.baseFolder, `${releaseChannel}`));}
|
||||
|
|
|
@ -22,7 +22,7 @@ export default new class PluginManager extends AddonManager {
|
|||
get name() {return "PluginManager";}
|
||||
get moduleExtension() {return ".js";}
|
||||
get extension() {return ".plugin.js";}
|
||||
get duplicatePattern() {return /\.plugin\([0-9]+\)\.js/;}
|
||||
get duplicatePattern() {return /\.plugin\s?\([0-9]+\)\.js/;}
|
||||
get addonFolder() {return path.resolve(Config.dataPath, "plugins");}
|
||||
get prefix() {return "plugin";}
|
||||
get language() {return "javascript";}
|
||||
|
|
|
@ -14,7 +14,7 @@ export default new class ThemeManager extends AddonManager {
|
|||
get name() {return "ThemeManager";}
|
||||
get moduleExtension() {return ".css";}
|
||||
get extension() {return ".theme.css";}
|
||||
get duplicatePattern() {return /\.theme\([0-9]+\)\.css/;}
|
||||
get duplicatePattern() {return /\.theme\s?\([0-9]+\)\.css/;}
|
||||
get addonFolder() {return path.resolve(Config.dataPath, "themes");}
|
||||
get prefix() {return "theme";}
|
||||
get language() {return "css";}
|
||||
|
|
|
@ -78,7 +78,7 @@ export default class Modals {
|
|||
|
||||
const emptyFunction = () => {};
|
||||
const {onConfirm = emptyFunction, onCancel = emptyFunction, confirmText = Strings.Modals.okay, cancelText = Strings.Modals.cancel, danger = false, key = undefined} = options;
|
||||
|
||||
|
||||
if (!Array.isArray(content)) content = [content];
|
||||
content = content.map(c => typeof(c) === "string" ? React.createElement(Markdown, null, c) : c);
|
||||
|
||||
|
@ -180,8 +180,8 @@ export default class Modals {
|
|||
const Changelog = WebpackModules.getModule(m => m.defaultProps && m.defaultProps.selectable == false);
|
||||
const MarkdownParser = WebpackModules.getByProps("defaultRules", "parse");
|
||||
if (!Changelog || !ModalStack || !ChangelogClasses || !TextElement || !FlexChild || !Titles || !MarkdownParser) return Logger.warn("Modals", "showChangelogModal missing modules");
|
||||
|
||||
const {image = "https://i.imgur.com/8sctUVV.png", description = "", changes = [], title = "BetterDiscord", subtitle = `v${Config.bdVersion}`, footer} = options;
|
||||
|
||||
const {image = "https://i.imgur.com/8sctUVV.png", description = "", changes = [], title = "BetterDiscord", subtitle = `v${Config.version}`, footer} = options;
|
||||
const ce = React.createElement;
|
||||
const changelogItems = [options.video ? ce("video", {src: options.video, poster: options.poster, controls: true, className: ChangelogClasses.video}) : ce("img", {src: image})];
|
||||
if (description) changelogItems.push(ce("p", null, MarkdownParser.parse(description)));
|
||||
|
@ -199,7 +199,7 @@ export default class Modals {
|
|||
ce(TextElement, {size: TextElement.Sizes.SMALL, color: TextElement.Colors.STANDARD, className: ChangelogClasses.date}, subtitle)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const renderFooter = () => {
|
||||
const Anchor = WebpackModules.getModule(m => m.displayName == "Anchor");
|
||||
const AnchorClasses = WebpackModules.getByProps("anchorUnderlineOnHover") || {anchor: "anchor-3Z-8Bb", anchorUnderlineOnHover: "anchorUnderlineOnHover-2ESHQB"};
|
||||
|
@ -228,7 +228,7 @@ export default class Modals {
|
|||
renderFooter: renderFooter,
|
||||
}, props), changelogItems);
|
||||
});
|
||||
|
||||
|
||||
const closeModal = ModalActions.closeModal;
|
||||
ModalActions.closeModal = function(k) {
|
||||
Reflect.apply(closeModal, this, arguments);
|
||||
|
@ -248,7 +248,7 @@ export default class Modals {
|
|||
this.elementRef = React.createRef();
|
||||
this.element = panel;
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
if (this.element instanceof Node) this.elementRef.current.appendChild(this.element);
|
||||
// if (typeof(this.element) === "string") this.elementRef.current.appendChild(this.element);
|
||||
|
@ -268,15 +268,15 @@ export default class Modals {
|
|||
|
||||
const mc = this.ModalComponents;
|
||||
const modal = props => {
|
||||
return React.createElement(mc.ModalRoot, Object.assign({size: mc.ModalSize.MEDIUM, className: "bd-addon-modal"}, props),
|
||||
return React.createElement(mc.ModalRoot, Object.assign({size: mc.ModalSize.MEDIUM, className: "bd-addon-modal"}, props),
|
||||
React.createElement(mc.ModalHeader, {separator: false, className: "bd-addon-modal-header"},
|
||||
React.createElement(this.FormTitle, {tag: "h4"}, `${name} Settings`),
|
||||
React.createElement(this.FlexElements.Child, {grow: 0},
|
||||
React.createElement(mc.ModalCloseButton, {className: "bd-modal-close", onClick: props.onClose})
|
||||
)
|
||||
),
|
||||
React.createElement(mc.ModalContent, {className: "bd-addon-modal-settings"},
|
||||
React.createElement(ErrorBoundary, {}, child)
|
||||
React.createElement(mc.ModalContent, {className: "bd-addon-modal-settings"},
|
||||
React.createElement(ErrorBoundary, {}, child)
|
||||
),
|
||||
React.createElement(mc.ModalFooter, {className: "bd-addon-modal-footer"},
|
||||
React.createElement(this.Buttons.default, {onClick: props.onClose, className: "bd-button"}, Strings.Modals.done)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const CircularDependencyPlugin = require("circular-dependency-plugin");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const basePkg = require("../package.json");
|
||||
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
|
@ -14,6 +16,7 @@ module.exports = {
|
|||
externals: {
|
||||
electron: `require("electron")`,
|
||||
fs: `require("fs")`,
|
||||
"original-fs": `require("original-fs")`,
|
||||
path: `require("path")`,
|
||||
request: `require("request")`,
|
||||
events: `require("events")`,
|
||||
|
@ -40,7 +43,7 @@ module.exports = {
|
|||
presets: [["@babel/env", {
|
||||
targets: {
|
||||
node: "12.14.1",
|
||||
chrome: "80"
|
||||
chrome: "83"
|
||||
}
|
||||
}], "@babel/react"]
|
||||
}
|
||||
|
@ -55,6 +58,9 @@ module.exports = {
|
|||
new CircularDependencyPlugin({
|
||||
exclude: /node_modules/,
|
||||
cwd: process.cwd(),
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
"process.env.__VERSION__": JSON.stringify(basePkg.version)
|
||||
})
|
||||
],
|
||||
optimization: {
|
||||
|
|
Loading…
Reference in New Issue