2021-04-03 05:16:23 +02:00
import fs from "fs" ;
import path from "path" ;
import electron from "electron" ;
2021-03-06 09:30:16 +01:00
import ReactDevTools from "./reactdevtools" ;
import * as IPCEvents from "common/constants/ipcevents" ;
// Build info file only exists for non-linux (for current injection)
const appPath = electron . app . getAppPath ( ) ;
const buildInfoFile = path . resolve ( appPath , ".." , "build_info.json" ) ;
// Locate data path to find transparency settings
let dataPath = "" ;
2021-03-25 17:19:55 +01:00
if ( process . platform === "win32" || process . platform === "darwin" ) dataPath = path . join ( electron . app . getPath ( "userData" ) , ".." ) ;
else dataPath = process . env . XDG _CONFIG _HOME ? process . env . XDG _CONFIG _HOME : path . join ( process . env . HOME , ".config" ) ; // This will help with snap packages eventually
2021-03-06 09:30:16 +01:00
dataPath = path . join ( dataPath , "BetterDiscord" ) + "/" ;
2021-04-03 05:16:23 +02:00
let hasCrashed = false ;
2021-03-06 09:30:16 +01:00
export default class BetterDiscord {
static getWindowPrefs ( ) {
if ( ! fs . existsSync ( buildInfoFile ) ) return { } ;
const buildInfo = _ _non _webpack _require _ _ ( buildInfoFile ) ;
const prefsFile = path . resolve ( dataPath , "data" , buildInfo . releaseChannel , "windowprefs.json" ) ;
if ( ! fs . existsSync ( prefsFile ) ) return { } ;
return _ _non _webpack _require _ _ ( prefsFile ) ;
}
static getSetting ( category , key ) {
if ( this . _settings ) return this . _settings [ category ] ? . [ key ] ;
try {
const buildInfo = _ _non _webpack _require _ _ ( buildInfoFile ) ;
2021-04-03 05:16:23 +02:00
const settingsFile = path . resolve ( dataPath , "data" , buildInfo . releaseChannel , "settings.json" ) ;
2021-03-06 09:30:16 +01:00
this . _settings = _ _non _webpack _require _ _ ( settingsFile ) ? ? { } ;
return this . _settings [ category ] ? . [ key ] ;
}
catch ( _ ) {
this . _settings = { } ;
return this . _settings [ category ] ? . [ key ] ;
}
}
static ensureDirectories ( ) {
if ( ! fs . existsSync ( dataPath ) ) fs . mkdirSync ( dataPath ) ;
if ( ! fs . existsSync ( path . join ( dataPath , "plugins" ) ) ) fs . mkdirSync ( path . join ( dataPath , "plugins" ) ) ;
if ( ! fs . existsSync ( path . join ( dataPath , "themes" ) ) ) fs . mkdirSync ( path . join ( dataPath , "themes" ) ) ;
}
static async ensureWebpackModules ( browserWindow ) {
await browserWindow . webContents . executeJavaScript ( ` new Promise(resolve => {
const check = function ( ) {
if ( window . webpackJsonp && window . webpackJsonp . flat ( ) . flat ( ) . length >= 7000 ) return resolve ( ) ;
setTimeout ( check , 100 ) ;
} ;
check ( ) ;
} ) ; ` );
}
static async injectRenderer ( browserWindow ) {
const location = path . join ( _ _dirname , "renderer.js" ) ;
if ( ! fs . existsSync ( location ) ) return ; // TODO: cut a fatal log
const content = fs . readFileSync ( location ) . toString ( ) ;
const success = await browserWindow . webContents . executeJavaScript ( `
( ( ) => {
try {
$ { content }
return true ;
} catch {
return false ;
}
} ) ( ) ;
` );
if ( ! success ) return ; // TODO: cut a fatal log
}
static setup ( browserWindow ) {
2021-04-03 06:17:55 +02:00
2021-03-06 09:30:16 +01:00
// Setup some useful vars to avoid blocking IPC calls
2021-07-27 23:19:45 +02:00
try {
process . env . DISCORD _RELEASE _CHANNEL = _ _non _webpack _require _ _ ( buildInfoFile ) . releaseChannel ;
}
catch ( e ) {
process . env . DISCORD _RELEASE _CHANNEL = "stable" ;
}
2021-03-06 09:30:16 +01:00
process . env . DISCORD _PRELOAD = browserWindow . _ _originalPreload ;
process . env . DISCORD _APP _PATH = appPath ;
process . env . DISCORD _USER _DATA = electron . app . getPath ( "userData" ) ;
process . env . BETTERDISCORD _DATA _PATH = dataPath ;
// When DOM is available, pass the renderer over the wall
browserWindow . webContents . on ( "dom-ready" , ( ) => {
2021-03-18 22:50:47 +01:00
if ( ! hasCrashed ) return this . injectRenderer ( browserWindow ) ;
// If a previous crash was detected, show a message explaining why BD isn't there
electron . dialog . showMessageBox ( {
title : "BetterDiscord Crashed" ,
type : "warning" ,
message : "BetterDiscord seems to have crashed your Discord client." ,
detail : "BetterDiscord has automatically disabled itself temporarily. Try removing all your plugins then restarting Discord."
} ) ;
2021-03-31 22:28:43 +02:00
hasCrashed = false ;
2021-03-06 09:30:16 +01:00
} ) ;
// This is used to alert renderer code to onSwitch events
browserWindow . webContents . on ( "did-navigate-in-page" , ( ) => {
browserWindow . webContents . send ( IPCEvents . NAVIGATE ) ;
} ) ;
2021-03-18 22:50:47 +01:00
2021-04-12 07:07:00 +02:00
browserWindow . webContents . on ( "render-process-gone" , ( ) => {
2021-03-18 22:50:47 +01:00
hasCrashed = true ;
} ) ;
2021-03-06 09:30:16 +01:00
}
2022-01-24 06:15:55 +01:00
static disableMediaKeys ( ) {
if ( ! BetterDiscord . getSetting ( "general" , "mediaKeys" ) ) return ;
const originalDisable = electron . app . commandLine . getSwitchValue ( "disable-features" ) || "" ;
electron . app . commandLine . appendSwitch ( "disable-features" , ` ${ originalDisable ? "," : "" } HardwareMediaKeyHandling,MediaSessionService ` ) ;
}
2021-04-03 06:17:55 +02:00
}
2021-07-26 17:19:16 +02:00
if ( BetterDiscord . getSetting ( "developer" , "reactDevTools" ) ) {
electron . app . whenReady ( ) . then ( async ( ) => {
await ReactDevTools . install ( ) ;
} ) ;
}