2021-04-05 07:43:30 +02:00
const path = require ( "path" ) ;
2021-03-06 09:30:16 +01:00
import LocaleManager from "./localemanager" ;
import Logger from "common/logger" ;
import { Config , Changelog } from "data" ;
import DOMManager from "./dommanager" ;
import PluginManager from "./pluginmanager" ;
import ThemeManager from "./thememanager" ;
import Settings from "./settingsmanager" ;
import * as Builtins from "builtins" ;
import Modals from "../ui/modals" ;
import ReactComponents from "./reactcomponents" ;
import DataStore from "./datastore" ;
import DiscordModules from "./discordmodules" ;
import ComponentPatcher from "./componentpatcher" ;
import Strings from "./strings" ;
2021-04-05 07:43:30 +02:00
import IPC from "./ipc" ;
2021-03-06 09:30:16 +01:00
import LoadingIcon from "../loadingicon" ;
import Styles from "../styles/index.css" ;
2021-07-27 15:41:51 +02:00
import Editor from "./editor" ;
2021-03-06 09:30:16 +01:00
export default new class Core {
async startup ( ) {
if ( this . hasStarted ) return ;
this . hasStarted = true ;
Config . appPath = process . env . DISCORD _APP _PATH ;
Config . userData = process . env . DISCORD _USER _DATA ;
Config . dataPath = process . env . BETTERDISCORD _DATA _PATH ;
// Load css early
Logger . log ( "Startup" , "Injecting BD Styles" ) ;
DOMManager . injectStyle ( "bd-stylesheet" , Styles . toString ( ) ) ;
Logger . log ( "Startup" , "Initializing DataStore" ) ;
DataStore . initialize ( ) ;
Logger . log ( "Startup" , "Initializing LocaleManager" ) ;
2021-04-08 02:31:02 +02:00
LocaleManager . initialize ( ) ;
2021-03-06 09:30:16 +01:00
Logger . log ( "Startup" , "Performing incompatibility checks" ) ;
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" } ) ) ;
2021-04-17 01:28:34 +02:00
Logger . log ( "Startup" , "Getting update information" ) ;
2021-04-08 02:31:02 +02:00
this . checkForUpdate ( ) ;
2021-03-06 09:30:16 +01:00
Logger . log ( "Startup" , "Initializing Settings" ) ;
Settings . initialize ( ) ;
Logger . log ( "Startup" , "Initializing DOMManager" ) ;
DOMManager . initialize ( ) ;
Logger . log ( "Startup" , "Waiting for guilds..." ) ;
await this . waitForGuilds ( ) ;
Logger . log ( "Startup" , "Initializing ReactComponents" ) ;
ReactComponents . initialize ( ) ;
Logger . log ( "Startup" , "Initializing ComponentPatcher" ) ;
ComponentPatcher . initialize ( ) ;
2021-07-27 15:41:51 +02:00
Logger . log ( "Startup" , "Initializing Editor" ) ;
await Editor . initialize ( ) ;
2021-03-06 09:30:16 +01:00
Logger . log ( "Startup" , "Initializing Builtins" ) ;
for ( const module in Builtins ) {
2021-07-27 15:41:51 +02:00
Builtins [ module ] . initialize ( ) ;
2021-03-06 09:30:16 +01:00
}
Logger . log ( "Startup" , "Loading Plugins" ) ;
// const pluginErrors = [];
const pluginErrors = PluginManager . initialize ( ) ;
Logger . log ( "Startup" , "Loading Themes" ) ;
// const themeErrors = [];
const themeErrors = ThemeManager . initialize ( ) ;
Logger . log ( "Startup" , "Removing Loading Icon" ) ;
LoadingIcon . hide ( ) ;
// Show loading errors
Logger . log ( "Startup" , "Collecting Startup Errors" ) ;
Modals . showAddonErrors ( { plugins : pluginErrors , themes : themeErrors } ) ;
const previousVersion = DataStore . getBDData ( "version" ) ;
2021-04-05 07:43:30 +02:00
if ( Config . version > previousVersion ) {
2021-03-06 09:30:16 +01:00
Modals . showChangelogModal ( Changelog ) ;
2021-04-05 07:43:30 +02:00
DataStore . setBDData ( "version" , Config . version ) ;
2021-03-06 09:30:16 +01:00
}
}
waitForGuilds ( ) {
2021-04-16 00:03:59 +02:00
// TODO: experiment with waiting for CONNECTION_OPEN event instead
const GuildClasses = DiscordModules . GuildClasses ;
2021-03-06 09:30:16 +01:00
return new Promise ( resolve => {
const checkForGuilds = function ( ) {
if ( document . readyState != "complete" ) setTimeout ( checkForGuilds , 100 ) ;
const wrapper = GuildClasses . wrapper . split ( " " ) [ 0 ] ;
const guild = GuildClasses . listItem . split ( " " ) [ 0 ] ;
2021-04-17 01:28:34 +02:00
if ( document . querySelectorAll ( ` . ${ wrapper } . ${ guild } ` ) . length > 0 ) return resolve ( ) ;
2021-03-06 09:30:16 +01:00
setTimeout ( checkForGuilds , 100 ) ;
} ;
checkForGuilds ( ) ;
} ) ;
}
2021-04-05 07:43:30 +02:00
async checkForUpdate ( ) {
2021-07-09 08:05:58 +02:00
const resp = await fetch ( ` https://api.github.com/repos/BetterDiscord/BetterDiscord/releases/latest ` , {
2021-04-05 07:43:30 +02:00
method : "GET" ,
headers : {
"Accept" : "application/json" ,
"Content-Type" : "application/json" ,
"User-Agent" : "BetterDiscord Updater"
}
} ) ;
const data = await resp . json ( ) ;
2021-04-08 02:31:02 +02:00
Object . assign ( Config . release , data ) ;
2021-04-05 07:43:30 +02:00
const remoteVersion = data . tag _name . startsWith ( "v" ) ? data . tag _name . slice ( 1 ) : data . tag _name ;
const hasUpdate = remoteVersion > Config . version ;
if ( ! hasUpdate ) return ;
2021-04-17 01:28:34 +02:00
// TODO: move to strings file when updater is complete.
2021-04-06 08:03:08 +02:00
Modals . showConfirmationModal ( "Update Available" , ` BetterDiscord ( ${ Config . version } ) has an available update available ( ${ remoteVersion } ). Would you like to update now? ` , {
2021-04-05 07:43:30 +02:00
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 ) =>
2021-04-06 08:03:08 +02:00
request ( asar . url , { encoding : null , headers : { "User-Agent" : "BetterDiscord Updater" , "Accept" : "application/octet-stream" } } , ( err , resp , body ) => {
2021-04-05 07:43:30 +02:00
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 ) {
2021-04-06 08:03:08 +02:00
Logger . stacktrace ( "Updater" , "Failed to update" , err ) ;
2021-04-05 07:43:30 +02:00
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." , {
2021-04-06 20:09:43 +02:00
cancelText : null
2021-04-05 07:43:30 +02:00
} ) ;
}
}
2021-03-06 09:30:16 +01:00
} ;