2020-12-12 11:56:28 +01:00
"use strict" ;
2020-05-16 23:24:51 +02:00
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports . getMainWindowId = getMainWindowId ;
exports . webContentsSend = webContentsSend ;
exports . init = init ;
2020-12-12 11:56:28 +01:00
exports . handleOpenUrl = handleOpenUrl ;
2020-05-16 23:24:51 +02:00
exports . setMainWindowVisible = setMainWindowVisible ;
2020-09-06 12:50:52 +02:00
exports . setBlurType = setBlurType
exports . setVibrancy = setVibrancy
2020-12-12 11:56:28 +01:00
const events = exports . events = new ( require ( "events" ) . EventEmitter ) ( )
2020-09-06 12:50:52 +02:00
const VIBRANCY _TYPES = [
"titlebar" ,
"selection" ,
"menu" ,
"popover" ,
"sidebar" ,
"header" ,
"sheet" ,
"window" ,
"hud" ,
"fullscreen-ui" ,
"tooltip" ,
"content" ,
"under-window" ,
"under-page" ,
"none"
]
const BLUR _TYPES = [ "blurbehind" , "acrylic" , "transparent" ]
2020-05-16 23:24:51 +02:00
2020-05-20 21:37:39 +02:00
var glasstron = require ( "glasstron" )
2020-12-12 11:56:28 +01:00
var _electron = require ( "electron" ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _fs = _interopRequireDefault ( require ( "fs" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _path = _interopRequireDefault ( require ( "path" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _url = _interopRequireDefault ( require ( "url" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _Backoff = _interopRequireDefault ( require ( "../common/Backoff" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _securityUtils = require ( "../common/securityUtils" ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var appBadge = _interopRequireWildcard ( require ( "./appBadge" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var appConfig = _interopRequireWildcard ( require ( "./appConfig" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _appSettings = require ( "./appSettings" ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _buildInfo = _interopRequireDefault ( require ( "./buildInfo" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _ipcMain = _interopRequireDefault ( require ( "./ipcMain" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var legacyModuleUpdater = _interopRequireWildcard ( require ( "./moduleUpdater" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _updater = _interopRequireDefault ( require ( "./updater" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var notificationScreen = _interopRequireWildcard ( require ( "./notificationScreen" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var paths = _interopRequireWildcard ( require ( "./paths" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var popoutWindows = _interopRequireWildcard ( require ( "./popoutWindows" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var splashScreen = _interopRequireWildcard ( require ( "./splashScreen" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var systemTray = _interopRequireWildcard ( require ( "./systemTray" ) ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
var _Constants = require ( "./Constants" ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
function _getRequireWildcardCache ( ) { if ( typeof WeakMap !== "function" ) return null ; var cache = new WeakMap ( ) ; _getRequireWildcardCache = function ( ) { return cache ; } ; return cache ; }
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
function _interopRequireWildcard ( obj ) { if ( obj && obj . _ _esModule ) { return obj ; } if ( obj === null || typeof obj !== "object" && typeof obj !== "function" ) { return { default : obj } ; } var cache = _getRequireWildcardCache ( ) ; if ( cache && cache . has ( obj ) ) { return cache . get ( obj ) ; } var newObj = { } ; var hasPropertyDescriptor = Object . defineProperty && Object . getOwnPropertyDescriptor ; for ( var key in obj ) { if ( Object . prototype . hasOwnProperty . call ( obj , key ) ) { var desc = hasPropertyDescriptor ? Object . getOwnPropertyDescriptor ( obj , key ) : null ; if ( desc && ( desc . get || desc . set ) ) { Object . defineProperty ( newObj , key , desc ) ; } else { newObj [ key ] = obj [ key ] ; } } } newObj . default = obj ; if ( cache ) { cache . set ( obj , newObj ) ; } return newObj ; }
2020-05-16 23:24:51 +02:00
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
2020-12-12 11:56:28 +01:00
const settings = ( 0 , _appSettings . getSettings ) ( ) ;
const connectionBackoff = new _Backoff . default ( 1000 , 20000 ) ;
2020-05-16 23:24:51 +02:00
const DISCORD _NAMESPACE = 'DISCORD_' ;
2020-07-06 19:16:21 +02:00
let isTabs = false
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
const getWebappEndpoint = ( ) => {
2020-07-06 19:16:21 +02:00
isTabs = settings . get ( "isTabs" , false )
2020-07-06 15:14:08 +02:00
if ( ! isTabs ) {
let endpoint = settings . get ( 'WEBAPP_ENDPOINT' ) ;
if ( ! endpoint ) {
2020-12-12 11:56:28 +01:00
if ( _buildInfo . default . releaseChannel === 'stable' ) {
2020-07-06 15:14:08 +02:00
endpoint = 'https://discord.com' ;
2020-12-12 11:56:28 +01:00
} else if ( _buildInfo . default . releaseChannel === 'development' ) {
endpoint = 'https://canary.discord.com' ;
2020-07-06 15:14:08 +02:00
} else {
2020-12-12 11:56:28 +01:00
endpoint = ` https:// ${ _buildInfo . default . releaseChannel } .discord.com ` ;
2020-07-06 15:14:08 +02:00
}
2020-05-16 23:24:51 +02:00
}
2020-07-06 15:14:08 +02:00
return endpoint ;
} else {
2020-12-12 11:56:28 +01:00
return "file://" + _path . default . join ( _ _dirname , "tabs" , "index.html" )
2020-05-16 23:24:51 +02:00
}
} ;
const WEBAPP _ENDPOINT = getWebappEndpoint ( ) ;
2020-12-12 11:56:28 +01:00
function checkUrlOriginMatches ( urlA , urlB ) {
let parsedUrlA ;
let parsedUrlB ;
try {
parsedUrlA = _url . default . parse ( urlA ) ;
parsedUrlB = _url . default . parse ( urlB ) ;
} catch ( _ ) {
return false ;
}
return parsedUrlA . protocol === parsedUrlB . protocol && parsedUrlA . slashes === parsedUrlB . slashes && parsedUrlA . host === parsedUrlB . host ;
}
2020-05-16 23:24:51 +02:00
function getSanitizedPath ( path ) {
// using the whatwg URL api, get a sanitized pathname from given path
// this is because url.parse's `path` may not always have a slash
// in front of it
2020-12-12 11:56:28 +01:00
return new _url . default . URL ( path , WEBAPP _ENDPOINT ) . pathname ;
2020-05-16 23:24:51 +02:00
}
2020-12-12 11:56:28 +01:00
function getSanitizedProtocolPath ( url _ ) {
try {
const parsedURL = _url . default . parse ( url _ ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
if ( parsedURL . protocol === 'discord:' ) {
return getSanitizedPath ( parsedURL . path ) ;
}
} catch ( _ ) { } // protect against URIError: URI malformed
return null ;
} // TODO: These should probably be thrown in constants.
const WEBAPP _PATH = settings . get ( 'WEBAPP_PATH' , ` /app?_= ${ Date . now ( ) } ` ) ;
const URL _TO _LOAD = ` ${ WEBAPP _ENDPOINT } ${ WEBAPP _PATH } ` ;
2020-05-16 23:24:51 +02:00
const MIN _WIDTH = settings . get ( 'MIN_WIDTH' , 940 ) ;
const MIN _HEIGHT = settings . get ( 'MIN_HEIGHT' , 500 ) ;
const DEFAULT _WIDTH = 1280 ;
2020-12-12 11:56:28 +01:00
const DEFAULT _HEIGHT = 720 ; // TODO: document this var's purpose
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
const MIN _VISIBLE _ON _SCREEN = 32 ;
2020-05-16 23:24:51 +02:00
let mainWindow = null ;
let mainWindowId = _Constants . DEFAULT _MAIN _WINDOW _ID ;
2020-12-12 11:56:28 +01:00
let mainWindowInitialPath = null ;
let mainWindowDidFinishLoad = false ; // whether we are in an intermediate auth process outside of our normal login screen (for e.g. internal builds)
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
let insideAuthFlow = false ; // last time the main app renderer has crashed ('crashed' event)
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
let lastCrashed = 0 ; // whether we failed to load a page outside of the intermediate auth flow
2020-05-16 23:24:51 +02:00
// used to reload the page after a delay
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
let lastPageLoadFailed = false ;
function getMainWindowId ( ) {
return mainWindowId ;
}
function webContentsSend ( ... args ) {
if ( mainWindow != null && mainWindow . webContents != null ) {
const [ event , ... options ] = args ;
mainWindow . webContents . send ( ` ${ DISCORD _NAMESPACE } ${ event } ` , ... options ) ;
}
}
function saveWindowConfig ( browserWindow ) {
try {
if ( ! browserWindow ) {
return ;
}
2020-08-04 13:43:22 +02:00
if ( settings . get ( "NO_WINDOWS_BOUND" ) ) return
2020-05-16 23:24:51 +02:00
settings . set ( 'IS_MAXIMIZED' , browserWindow . isMaximized ( ) ) ;
settings . set ( 'IS_MINIMIZED' , browserWindow . isMinimized ( ) ) ;
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
if ( ! settings . get ( 'IS_MAXIMIZED' ) && ! settings . get ( 'IS_MINIMIZED' ) ) {
settings . set ( 'WINDOW_BOUNDS' , browserWindow . getBounds ( ) ) ;
}
settings . save ( ) ;
} catch ( e ) {
console . error ( e ) ;
}
}
2020-09-06 12:50:52 +02:00
function setBlur ( blur ) {
if ( ! mainWindow ) return
if ( typeof blur !== "boolean" ) throw new TypeError ( "INVALID ARGUMENT: blur" )
mainWindow . setBlur ( blur )
}
function setVibrancy ( vibrancy ) {
if ( ! mainWindow ) return
if ( ! VIBRANCY _TYPES . includes ( vibrancy ) ) throw new TypeError ( "INVALID ARGUMENT: vibrancy" )
mainWindow . setVibrancy ( vibrancy )
settings . set ( "GLASSTRON_VIBRANCY" , vibrancy )
}
function setBlurType ( blurType ) {
if ( ! mainWindow ) return
if ( ! BLUR _TYPES . includes ( blurType ) ) throw new TypeError ( "INVALID ARGUMENT: blurType" )
mainWindow . blurType = blurType
settings . set ( "GLASSTRON_BLUR" , blurType )
}
function setDefaultBlur ( ) {
if ( ! mainWindow ) return
let blurType = settings . get ( "GLASSTRON_BLUR" , "blurbehind" )
if ( ! BLUR _TYPES . includes ( blurType ) ) {
blurType = "blurbehind"
settings . set ( "GLASSTRON_BLUR" , blurType )
}
setBlurType ( blurType )
let vibrancy = settings . get ( "GLASSTRON_VIBRANCY" , "fullscreen-ui" )
if ( ! VIBRANCY _TYPES . includes ( vibrancy ) ) {
vibrancy = "fullscreen-ui"
settings . set ( "GLASSTRON_VIBRANCY" , vibrancy )
}
setVibrancy ( vibrancy )
setBlur ( true )
}
2020-05-16 23:24:51 +02:00
function setWindowVisible ( isVisible , andUnminimize ) {
if ( mainWindow == null ) {
return ;
}
if ( isVisible ) {
if ( andUnminimize || ! mainWindow . isMinimized ( ) ) {
mainWindow . show ( ) ;
webContentsSend ( 'MAIN_WINDOW_FOCUS' ) ;
}
} else {
webContentsSend ( 'MAIN_WINDOW_BLUR' ) ;
2020-12-12 11:56:28 +01:00
mainWindow . hide ( ) ;
2020-05-16 23:24:51 +02:00
if ( systemTray . hasInit ) {
systemTray . displayHowToCloseHint ( ) ;
}
}
mainWindow . setSkipTaskbar ( ! isVisible ) ;
}
function doAABBsOverlap ( a , b ) {
const ax1 = a . x + a . width ;
const bx1 = b . x + b . width ;
const ay1 = a . y + a . height ;
2020-12-12 11:56:28 +01:00
const by1 = b . y + b . height ; // clamp a to b, see if it is non-empty
2020-05-16 23:24:51 +02:00
const cx0 = a . x < b . x ? b . x : a . x ;
const cx1 = ax1 < bx1 ? ax1 : bx1 ;
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
if ( cx1 - cx0 > 0 ) {
const cy0 = a . y < b . y ? b . y : a . y ;
const cy1 = ay1 < by1 ? ay1 : by1 ;
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
if ( cy1 - cy0 > 0 ) {
return true ;
}
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
return false ;
}
function applyWindowBoundsToConfig ( mainWindowOptions ) {
2020-12-12 11:56:28 +01:00
if ( ! settings . get ( 'WINDOW_BOUNDS' ) ) {
2020-05-16 23:24:51 +02:00
mainWindowOptions . center = true ;
return ;
}
2020-12-12 11:56:28 +01:00
const bounds = settings . get ( 'WINDOW_BOUNDS' ) ;
bounds . width = Math . max ( MIN _WIDTH , bounds . width ) ;
bounds . height = Math . max ( MIN _HEIGHT , bounds . height ) ;
2020-05-16 23:24:51 +02:00
let isVisibleOnAnyScreen = false ;
2020-12-12 11:56:28 +01:00
const displays = _electron . screen . getAllDisplays ( ) ;
2020-05-16 23:24:51 +02:00
displays . forEach ( display => {
if ( isVisibleOnAnyScreen ) {
return ;
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
const displayBound = display . workArea ;
displayBound . x += MIN _VISIBLE _ON _SCREEN ;
displayBound . y += MIN _VISIBLE _ON _SCREEN ;
displayBound . width -= 2 * MIN _VISIBLE _ON _SCREEN ;
displayBound . height -= 2 * MIN _VISIBLE _ON _SCREEN ;
isVisibleOnAnyScreen = doAABBsOverlap ( bounds , displayBound ) ;
} ) ;
if ( isVisibleOnAnyScreen ) {
mainWindowOptions . width = bounds . width ;
mainWindowOptions . height = bounds . height ;
mainWindowOptions . x = bounds . x ;
mainWindowOptions . y = bounds . y ;
} else {
mainWindowOptions . center = true ;
}
2020-12-12 11:56:28 +01:00
} // this can be called multiple times (due to recreating the main app window),
2020-05-16 23:24:51 +02:00
// so we only want to update existing if we already initialized it
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
function setupNotificationScreen ( mainWindow ) {
if ( ! notificationScreen . hasInit ) {
notificationScreen . init ( {
mainWindow ,
title : 'Lightcord Notifications' ,
maxVisible : 5 ,
screenPosition : 'bottom'
} ) ;
notificationScreen . events . on ( notificationScreen . NOTIFICATION _CLICK , ( ) => {
setWindowVisible ( true , true ) ;
} ) ;
} else {
notificationScreen . setMainWindow ( mainWindow ) ;
}
2020-12-12 11:56:28 +01:00
} // this can be called multiple times (due to recreating the main app window),
2020-05-16 23:24:51 +02:00
// so we only want to update existing if we already initialized it
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
function setupSystemTray ( ) {
if ( ! systemTray . hasInit ) {
systemTray . init ( {
2020-12-12 11:56:28 +01:00
onCheckForUpdates : ( ) => {
const updater = _updater . default === null || _updater . default === void 0 ? void 0 : _updater . default . getUpdater ( ) ;
if ( updater != null ) {
checkForUpdatesWithUpdater ( updater ) ;
} else {
legacyModuleUpdater . checkForUpdates ( ) ;
}
} ,
2020-05-16 23:24:51 +02:00
onTrayClicked : ( ) => setWindowVisible ( true , true ) ,
onOpenVoiceSettings : openVoiceSettings ,
onToggleMute : toggleMute ,
onToggleDeafen : toggleDeafen ,
onLaunchApplication : launchApplication
} ) ;
}
2020-12-12 11:56:28 +01:00
} // this can be called multiple times (due to recreating the main app window),
2020-05-16 23:24:51 +02:00
// so we only want to update existing if we already initialized it
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
function setupAppBadge ( ) {
if ( ! appBadge . hasInit ) {
appBadge . init ( ) ;
}
2020-12-12 11:56:28 +01:00
} // this can be called multiple times (due to recreating the main app window),
2020-05-16 23:24:51 +02:00
// so we only want to update existing if we already initialized it
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
function setupAppConfig ( ) {
if ( ! appConfig . hasInit ) {
appConfig . init ( ) ;
}
2020-12-12 11:56:28 +01:00
} // this can be called multiple times (due to recreating the main app window),
2020-05-16 23:24:51 +02:00
// so we only want to update existing if we already initialized it
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
function setupPopouts ( ) {
if ( ! popoutWindows . hasInit ) {
popoutWindows . init ( ) ;
}
}
function openVoiceSettings ( ) {
setWindowVisible ( true , true ) ;
webContentsSend ( 'SYSTEM_TRAY_OPEN_VOICE_SETTINGS' ) ;
}
function toggleMute ( ) {
webContentsSend ( 'SYSTEM_TRAY_TOGGLE_MUTE' ) ;
}
function toggleDeafen ( ) {
webContentsSend ( 'SYSTEM_TRAY_TOGGLE_DEAFEN' ) ;
}
function launchApplication ( applicationId ) {
webContentsSend ( 'LAUNCH_APPLICATION' , applicationId ) ;
}
const loadMainPage = ( ) => {
lastPageLoadFailed = false ;
mainWindow . loadURL ( URL _TO _LOAD ) ;
} ;
const DEFAULT _BACKGROUND _COLOR = '#2f3136' ;
const BACKGROUND _COLOR _KEY = 'BACKGROUND_COLOR' ;
function getBackgroundColor ( ) {
return settings . get ( BACKGROUND _COLOR _KEY , DEFAULT _BACKGROUND _COLOR ) ;
}
function setBackgroundColor ( color ) {
settings . set ( BACKGROUND _COLOR _KEY , color ) ;
2020-07-28 13:16:32 +02:00
//mainWindow.setBackgroundColor(color);
2020-05-16 23:24:51 +02:00
settings . save ( ) ;
2020-12-12 11:56:28 +01:00
} // launch main app window; could be called multiple times for various reasons
2020-05-16 23:24:51 +02:00
function launchMainAppWindow ( isVisible ) {
if ( mainWindow ) {
// TODO: message here?
mainWindow . destroy ( ) ;
}
const mainWindowOptions = {
title : 'Lightcord' ,
width : DEFAULT _WIDTH ,
height : DEFAULT _HEIGHT ,
minWidth : MIN _WIDTH ,
minHeight : MIN _HEIGHT ,
2020-05-22 18:43:33 +02:00
transparent : false ,
2020-05-16 23:24:51 +02:00
frame : false ,
resizable : true ,
show : isVisible ,
webPreferences : {
blinkFeatures : 'EnumerateDevices,AudioOutputDevices' ,
2020-06-06 01:21:03 +02:00
nativeWindowOpen : true ,
2020-07-06 15:14:08 +02:00
enableRemoteModule : true ,
2020-07-28 13:16:32 +02:00
spellcheck : true ,
2020-12-12 11:56:28 +01:00
contextIsolation : false ,
2020-07-06 15:14:08 +02:00
... ( isTabs ? {
nodeIntegration : true ,
webviewTag : true
} : {
nodeIntegration : false ,
webviewTag : false ,
2021-03-09 19:59:22 +01:00
contextIsolation : false ,
2020-12-12 11:56:28 +01:00
preload : _path . default . join ( _ _dirname , 'mainScreenPreload.js' )
} ) ,
// NB: this is required in order to give popouts (or any child window opened via window.open w/ nativeWindowOpen)
// a chance at a node environment (i.e. they run the preload, have an isolated context, etc.) when
// `app.allowRendererProcessReuse === false` (default in Electron 7).
additionalArguments : [ '--enable-node-leakage-in-renderers' ]
2020-05-16 23:24:51 +02:00
} ,
2020-12-12 11:56:28 +01:00
icon : _path . default . join ( _ _dirname , "images" , 'discord.png' )
2020-05-16 23:24:51 +02:00
} ;
if ( process . platform === 'linux' ) {
mainWindowOptions . frame = true ;
}
2020-07-10 01:44:40 +02:00
if ( ! settings . get ( "NO_WINDOWS_BOUND" , false ) ) applyWindowBoundsToConfig ( mainWindowOptions ) ;
2020-05-16 23:24:51 +02:00
2020-09-06 12:50:52 +02:00
const useGlasstron = settings . get ( "GLASSTRON" , true )
2020-12-12 11:56:28 +01:00
const BrowserWindow = useGlasstron ? glasstron . BrowserWindow : _electron . BrowserWindow
2020-09-06 12:50:52 +02:00
mainWindow = new BrowserWindow ( mainWindowOptions ) ;
2020-05-16 23:24:51 +02:00
mainWindowId = mainWindow . id ;
global . mainWindowId = mainWindowId ;
2020-09-06 12:50:52 +02:00
if ( useGlasstron ) setDefaultBlur ( )
2020-05-16 23:24:51 +02:00
mainWindow . webContents . session . webRequest . onHeadersReceived ( function ( details , callback ) {
if ( ! details . responseHeaders [ "content-security-policy-report-only" ] && ! details . responseHeaders [ "content-security-policy" ] ) return callback ( { cancel : false } ) ;
delete details . responseHeaders [ "content-security-policy-report-only" ] ;
delete details . responseHeaders [ "content-security-policy" ] ;
callback ( { cancel : false , responseHeaders : details . responseHeaders } ) ;
} ) ;
mainWindow . setMenuBarVisibility ( false ) ;
2020-07-10 01:44:40 +02:00
if ( ! settings . get ( "NO_WINDOWS_BOUND" , false ) ) {
if ( settings . get ( 'IS_MAXIMIZED' ) ) {
mainWindow . maximize ( ) ;
}
if ( settings . get ( 'IS_MINIMIZED' ) ) {
mainWindow . minimize ( ) ;
}
2020-05-16 23:24:51 +02:00
}
mainWindow . webContents . on ( 'new-window' , ( e , windowURL , frameName , disposition , options ) => {
e . preventDefault ( ) ;
2020-12-12 11:56:28 +01:00
2021-03-09 19:59:22 +01:00
if ( frameName . startsWith ( DISCORD _NAMESPACE ) && checkUrlOriginMatches ( windowURL , WEBAPP _ENDPOINT ) && getSanitizedPath ( windowURL ) === '/popout' ) {
2020-05-16 23:24:51 +02:00
popoutWindows . openOrFocusWindow ( e , windowURL , frameName , options ) ;
2020-12-12 11:56:28 +01:00
return ;
2020-05-16 23:24:51 +02:00
}
2020-12-12 11:56:28 +01:00
( 0 , _securityUtils . saferShellOpenExternal ) ( windowURL ) ;
} ) ;
2020-05-16 23:24:51 +02:00
mainWindow . webContents . on ( 'did-fail-load' , ( e , errCode , errDesc , validatedUrl ) => {
if ( insideAuthFlow ) {
return ;
}
if ( validatedUrl !== URL _TO _LOAD ) {
return ;
2020-12-12 11:56:28 +01:00
} // -3 (ABORTED) means we are reloading the page before it has finished loading
2020-05-16 23:24:51 +02:00
// 0 (???) seems to also mean the same thing
2020-12-12 11:56:28 +01:00
if ( errCode === - 3 || errCode === 0 ) return ;
2020-05-16 23:24:51 +02:00
lastPageLoadFailed = true ;
console . error ( '[WebContents] did-fail-load' , errCode , errDesc , ` retry in ${ connectionBackoff . current } ms ` ) ;
connectionBackoff . fail ( ( ) => {
console . log ( '[WebContents] retrying load' , URL _TO _LOAD ) ;
loadMainPage ( ) ;
} ) ;
} ) ;
mainWindow . webContents . on ( 'did-finish-load' , ( ) => {
2020-12-12 11:56:28 +01:00
if ( insideAuthFlow && mainWindow . webContents && checkUrlOriginMatches ( mainWindow . webContents . getURL ( ) , WEBAPP _ENDPOINT ) ) {
2020-05-16 23:24:51 +02:00
insideAuthFlow = false ;
}
2020-12-12 11:56:28 +01:00
mainWindowDidFinishLoad = true ; // if this is a first open and there's an initial path, direct user to that path
if ( mainWindowInitialPath != null ) {
webContentsSend ( 'MAIN_WINDOW_PATH' , mainWindowInitialPath ) ;
mainWindowInitialPath = null ;
}
2020-05-16 23:24:51 +02:00
webContentsSend ( mainWindow != null && mainWindow . isFocused ( ) ? 'MAIN_WINDOW_FOCUS' : 'MAIN_WINDOW_BLUR' ) ;
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
if ( ! lastPageLoadFailed ) {
connectionBackoff . succeed ( ) ;
}
events . emit ( "ready" )
} ) ;
mainWindow . webContents . on ( 'crashed' , ( e , killed ) => {
if ( killed ) {
2020-12-12 11:56:28 +01:00
_electron . app . quit ( ) ;
2020-05-16 23:24:51 +02:00
return ;
2020-12-12 11:56:28 +01:00
} // if we just crashed under 5 seconds ago, we are probably in a loop, so just die.
2020-05-16 23:24:51 +02:00
const crashTime = Date . now ( ) ;
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
if ( crashTime - lastCrashed < 5 * 1000 ) {
console . error ( '[WebContents] double crashed... RIP =(' ) ;
2020-12-12 11:56:28 +01:00
_electron . app . quit ( ) ;
2020-05-16 23:24:51 +02:00
return ;
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
lastCrashed = crashTime ;
console . error ( '[WebContents] crashed... reloading' ) ;
launchMainAppWindow ( true ) ;
2020-12-12 11:56:28 +01:00
} ) ; // Prevent navigation when links or files are dropping into the app, turning it into a browser.
2020-07-28 13:16:32 +02:00
// https://github.com/discord/discord/pull/278
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
mainWindow . webContents . on ( 'will-navigate' , ( evt , url ) => {
2020-12-12 11:56:28 +01:00
if ( ! insideAuthFlow && ! checkUrlOriginMatches ( url , WEBAPP _ENDPOINT ) ) {
2020-05-16 23:24:51 +02:00
evt . preventDefault ( ) ;
}
2020-12-12 11:56:28 +01:00
} ) ; // track intermediate auth flow
2020-05-16 23:24:51 +02:00
mainWindow . webContents . on ( 'did-get-redirect-request' , ( event , oldUrl , newUrl ) => {
2020-12-12 11:56:28 +01:00
if ( checkUrlOriginMatches ( oldUrl , WEBAPP _ENDPOINT ) && checkUrlOriginMatches ( newUrl , 'https://accounts.google.com/' ) ) {
2020-05-16 23:24:51 +02:00
insideAuthFlow = true ;
}
} ) ;
2020-07-28 13:16:32 +02:00
mainWindow . webContents . on ( 'context-menu' , ( _ , params ) => {
webContentsSend ( 'SPELLCHECK_RESULT' , params . misspelledWord , params . dictionarySuggestions ) ;
} ) ;
mainWindow . webContents . on ( 'devtools-opened' , ( ) => {
webContentsSend ( 'WINDOW_DEVTOOLS_OPENED' ) ;
} ) ;
mainWindow . webContents . on ( 'devtools-closed' , ( ) => {
webContentsSend ( 'WINDOW_DEVTOOLS_CLOSED' ) ;
} ) ;
2020-05-16 23:24:51 +02:00
mainWindow . on ( 'focus' , ( ) => {
webContentsSend ( 'MAIN_WINDOW_FOCUS' ) ;
} ) ;
mainWindow . on ( 'blur' , ( ) => {
webContentsSend ( 'MAIN_WINDOW_BLUR' ) ;
} ) ;
mainWindow . on ( 'page-title-updated' , ( e , title ) => {
if ( mainWindow === null ) {
return ;
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
e . preventDefault ( ) ;
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
if ( ! title . endsWith ( 'Lightcord' ) ) {
title += ' - Lightcord' ;
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
mainWindow . setTitle ( title ) ;
} ) ;
mainWindow . on ( 'leave-html-full-screen' , ( ) => {
// fixes a bug wherein embedded videos returning from full screen cause our menu to be visible.
mainWindow . setMenuBarVisibility ( false ) ;
} ) ;
2020-12-12 11:56:28 +01:00
mainWindow . webContents . on ( 'did-navigate-in-page' , ( _ , eventUrl ) => {
let parsedUrl ;
try {
parsedUrl = _url . default . parse ( eventUrl ) ;
} catch ( _ ) {
return ;
} // Prevent back navigation from revisting the login page after logging in,
// or being able to navigate back after signing out.
if ( parsedUrl && parsedUrl . pathname === '/login' ) {
mainWindow . webContents . clearHistory ( ) ;
}
} ) ; // 'swipe' only works if the classic 3 finger swipe style is enabled in
// 'System Preferences > Trackpad > More Gestures.' The more modern 2 finger
// gesture should be added when Electron adds support.
mainWindow . on ( 'swipe' , ( _ , direction ) => {
switch ( direction ) {
case 'left' :
webContentsSend ( 'NAVIGATE_BACK' , 'SWIPE' ) ;
break ;
case 'right' :
webContentsSend ( 'NAVIGATE_FORWARD' , 'SWIPE' ) ;
break ;
}
} ) ; // Windows/Linux media keys and 4th/5th mouse buttons.
mainWindow . on ( 'app-command' , ( _ , cmd ) => {
switch ( cmd ) {
case 'browser-backward' :
webContentsSend ( 'NAVIGATE_BACK' , 'BROWSER' ) ;
break ;
case 'browser-forward' :
webContentsSend ( 'NAVIGATE_FORWARD' , 'BROWSER' ) ;
break ;
}
} ) ;
2020-05-16 23:24:51 +02:00
if ( process . platform === 'win32' ) {
setupNotificationScreen ( mainWindow ) ;
}
setupSystemTray ( ) ;
setupAppBadge ( ) ;
setupAppConfig ( ) ;
setupPopouts ( ) ;
if ( process . platform === 'linux' || process . platform === 'win32' ) {
systemTray . show ( ) ;
mainWindow . on ( 'close' , e => {
if ( mainWindow === null ) {
// this means we're quitting
popoutWindows . closePopouts ( ) ;
return ;
}
2020-12-12 11:56:28 +01:00
webContentsSend ( 'MAIN_WINDOW_BLUR' ) ; // Save our app settings
saveWindowConfig ( mainWindow ) ; // Quit app if that's the setting
2020-05-16 23:24:51 +02:00
if ( ! settings . get ( 'MINIMIZE_TO_TRAY' , true ) ) {
2020-12-12 11:56:28 +01:00
_electron . app . quit ( ) ;
2020-05-16 23:24:51 +02:00
return ;
2020-12-12 11:56:28 +01:00
} // Else, minimize to tray
2020-05-16 23:24:51 +02:00
setWindowVisible ( false ) ;
e . preventDefault ( ) ;
} ) ;
}
loadMainPage ( ) ;
}
let updaterState = _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ;
function handleModuleUpdateCheckFinished ( succeeded , updateCount , manualRequired ) {
if ( ! succeeded ) {
updaterState = _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ;
webContentsSend ( _Constants . UpdaterEvents . UPDATE _ERROR ) ;
return ;
}
if ( updateCount === 0 ) {
updaterState = _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ;
} else if ( manualRequired ) {
updaterState = _Constants . UpdaterEvents . UPDATE _MANUALLY ;
} else {
updaterState = _Constants . UpdaterEvents . UPDATE _AVAILABLE ;
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
webContentsSend ( updaterState ) ;
}
function handleModuleUpdateDownloadProgress ( name , progress ) {
if ( mainWindow ) {
mainWindow . setProgressBar ( progress ) ;
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
webContentsSend ( _Constants . UpdaterEvents . MODULE _INSTALL _PROGRESS , name , progress ) ;
}
function handleModuleUpdateDownloadsFinished ( succeeded , failed ) {
if ( mainWindow ) {
mainWindow . setProgressBar ( - 1 ) ;
}
if ( updaterState === _Constants . UpdaterEvents . UPDATE _AVAILABLE ) {
if ( failed > 0 ) {
updaterState = _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ;
webContentsSend ( _Constants . UpdaterEvents . UPDATE _ERROR ) ;
} else {
updaterState = _Constants . UpdaterEvents . UPDATE _DOWNLOADED ;
webContentsSend ( updaterState ) ;
}
}
}
function handleModuleUpdateInstalledModule ( name , current , total , succeeded ) {
if ( mainWindow ) {
mainWindow . setProgressBar ( - 1 ) ;
}
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
webContentsSend ( _Constants . UpdaterEvents . MODULE _INSTALLED , name , succeeded ) ;
}
2020-12-12 11:56:28 +01:00
function setUpdaterState ( newUpdaterState ) {
updaterState = newUpdaterState ;
webContentsSend ( updaterState ) ;
}
async function checkForUpdatesWithUpdater ( updater ) {
if ( updaterState === _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ) {
setUpdaterState ( _Constants . UpdaterEvents . CHECKING _FOR _UPDATES ) ;
try {
let installedAnything = false ;
await updater . updateToLatest ( progress => {
const task = progress . task . HostInstall || progress . task . ModuleInstall ;
if ( task != null && progress . state === 'Complete' ) {
if ( ! installedAnything ) {
installedAnything = true ;
setUpdaterState ( _Constants . UpdaterEvents . UPDATE _AVAILABLE ) ;
}
}
} ) ;
setUpdaterState ( installedAnything ? _Constants . UpdaterEvents . UPDATE _DOWNLOADED : _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ) ;
} catch ( e ) {
console . error ( 'Update to latest failed: ' , e ) ;
updaterState = _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ;
webContentsSend ( _Constants . UpdaterEvents . UPDATE _FAILED ) ;
}
} else {
webContentsSend ( updaterState ) ;
}
} // Setup handling of events related to updates using the new updater.
function setupUpdaterEventsWithUpdater ( updater ) {
_electron . app . on ( _Constants . MenuEvents . CHECK _FOR _UPDATES , ( ) => checkForUpdatesWithUpdater ( ) ) ;
_ipcMain . default . on ( _Constants . UpdaterEvents . CHECK _FOR _UPDATES , ( ) => {
return checkForUpdatesWithUpdater ( updater ) ;
} ) ;
_ipcMain . default . on ( _Constants . UpdaterEvents . QUIT _AND _INSTALL , ( ) => {
saveWindowConfig ( mainWindow ) ;
mainWindow = null ; // TODO(eiz): This is a workaround for old Linux host versions whose host
// updater did not have a quitAndInstall() method, which causes the module
// updater to crash if a host update is available and we try to restart to
// install modules. Remove when all hosts are updated.
try {
legacyModuleUpdater . quitAndInstallUpdates ( ) ;
} catch ( e ) {
_electron . app . relaunch ( ) ;
_electron . app . quit ( ) ;
}
} ) ;
_ipcMain . default . on ( _Constants . UpdaterEvents . UPDATER _HISTORY _QUERY _AND _TRUNCATE , ( ) => {
if ( updater . queryAndTruncateHistory != null ) {
webContentsSend ( _Constants . UpdaterEvents . UPDATER _HISTORY _RESPONSE , updater . queryAndTruncateHistory ( ) ) ;
} else {
webContentsSend ( _Constants . UpdaterEvents . UPDATER _HISTORY _RESPONSE , [ ] ) ;
}
} ) ;
} // Setup events related to updates using the old module updater.
//
2020-05-16 23:24:51 +02:00
// sets up event listeners between the browser window and the app to send
// and listen to update-related events
2020-12-12 11:56:28 +01:00
function setupLegacyUpdaterEvents ( ) {
_electron . app . on ( _Constants . MenuEvents . CHECK _FOR _UPDATES , ( ) => legacyModuleUpdater . checkForUpdates ( ) ) ;
legacyModuleUpdater . events . on ( legacyModuleUpdater . CHECKING _FOR _UPDATES , ( ) => {
2020-05-16 23:24:51 +02:00
updaterState = _Constants . UpdaterEvents . CHECKING _FOR _UPDATES ;
webContentsSend ( updaterState ) ;
2020-12-12 11:56:28 +01:00
} ) ; // TODO(eiz): We currently still need to handle the old style non-object-based
2020-05-16 23:24:51 +02:00
// updater events to allow discord_desktop_core to be newer than the host asar,
// which contains the updater itself.
//
// Once all clients have updated to a sufficiently new host, we can delete this.
2020-12-12 11:56:28 +01:00
if ( legacyModuleUpdater . supportsEventObjects ) {
legacyModuleUpdater . events . on ( legacyModuleUpdater . UPDATE _CHECK _FINISHED , ( {
succeeded ,
updateCount ,
manualRequired
} ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateCheckFinished ( succeeded , updateCount , manualRequired ) ;
} ) ;
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . events . on ( legacyModuleUpdater . DOWNLOADING _MODULE _PROGRESS , ( {
name ,
progress
} ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateDownloadProgress ( name , progress ) ;
} ) ;
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . events . on ( legacyModuleUpdater . DOWNLOADING _MODULES _FINISHED , ( {
succeeded ,
failed
} ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateDownloadsFinished ( succeeded , failed ) ;
} ) ;
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . events . on ( legacyModuleUpdater . INSTALLED _MODULE , ( {
name ,
current ,
total ,
succeeded
} ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateInstalledModule ( name , current , total , succeeded ) ;
} ) ;
} else {
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . events . on ( legacyModuleUpdater . UPDATE _CHECK _FINISHED , ( succeeded , updateCount , manualRequired ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateCheckFinished ( succeeded , updateCount , manualRequired ) ;
} ) ;
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . events . on ( legacyModuleUpdater . DOWNLOADING _MODULE _PROGRESS , ( name , progress ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateDownloadProgress ( name , progress ) ;
} ) ;
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . events . on ( legacyModuleUpdater . DOWNLOADING _MODULES _FINISHED , ( succeeded , failed ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateDownloadsFinished ( succeeded , failed ) ;
} ) ;
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . events . on ( legacyModuleUpdater . INSTALLED _MODULE , ( name , current , total , succeeded ) => {
2020-05-16 23:24:51 +02:00
handleModuleUpdateInstalledModule ( name , current , total , succeeded ) ;
} ) ;
}
2020-12-12 11:56:28 +01:00
_ipcMain . default . on ( _Constants . UpdaterEvents . CHECK _FOR _UPDATES , ( ) => {
2020-05-16 23:24:51 +02:00
if ( updaterState === _Constants . UpdaterEvents . UPDATE _NOT _AVAILABLE ) {
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . checkForUpdates ( ) ;
2020-05-16 23:24:51 +02:00
} else {
webContentsSend ( updaterState ) ;
}
} ) ;
2020-12-12 11:56:28 +01:00
_ipcMain . default . on ( _Constants . UpdaterEvents . QUIT _AND _INSTALL , ( ) => {
2020-05-16 23:24:51 +02:00
saveWindowConfig ( mainWindow ) ;
2020-12-12 11:56:28 +01:00
mainWindow = null ; // TODO(eiz): This is a workaround for old Linux host versions whose host
2020-05-16 23:24:51 +02:00
// updater did not have a quitAndInstall() method, which causes the module
// updater to crash if a host update is available and we try to restart to
// install modules. Remove when all hosts are updated.
2020-12-12 11:56:28 +01:00
2020-05-16 23:24:51 +02:00
try {
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . quitAndInstallUpdates ( ) ;
2020-05-16 23:24:51 +02:00
} catch ( e ) {
2020-12-12 11:56:28 +01:00
_electron . app . relaunch ( ) ;
_electron . app . quit ( ) ;
2020-05-16 23:24:51 +02:00
}
} ) ;
2020-12-12 11:56:28 +01:00
_ipcMain . default . on ( _Constants . UpdaterEvents . MODULE _INSTALL , ( _event , name ) => {
2020-05-16 23:24:51 +02:00
// NOTE: do NOT allow options to be passed in, as this enables a client to downgrade its modules to potentially
// insecure versions.
2020-12-12 11:56:28 +01:00
legacyModuleUpdater . install ( name , false ) ;
2020-05-16 23:24:51 +02:00
} ) ;
2020-12-12 11:56:28 +01:00
_ipcMain . default . on ( _Constants . UpdaterEvents . MODULE _QUERY , ( _event , name ) => {
webContentsSend ( _Constants . UpdaterEvents . MODULE _INSTALLED , name , legacyModuleUpdater . isInstalled ( name ) ) ;
2020-05-16 23:24:51 +02:00
} ) ;
2020-12-12 11:56:28 +01:00
_ipcMain . default . on ( _Constants . UpdaterEvents . UPDATER _HISTORY _QUERY _AND _TRUNCATE , ( ) => {
webContentsSend ( _Constants . UpdaterEvents . UPDATER _HISTORY _RESPONSE , legacyModuleUpdater . events . history ) ;
legacyModuleUpdater . events . history = [ ] ;
2020-05-16 23:24:51 +02:00
} ) ;
}
function init ( ) {
// electron default behavior is to app.quit here, so long as there are no other listeners. we handle quitting
// or minimizing to system tray ourselves via mainWindow.on('closed') so this is simply to disable the electron
// default behavior.
2020-12-12 11:56:28 +01:00
_electron . app . on ( 'window-all-closed' , ( ) => { } ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
_electron . app . on ( 'before-quit' , ( ) => {
2020-05-16 23:24:51 +02:00
saveWindowConfig ( mainWindow ) ;
mainWindow = null ;
notificationScreen . close ( ) ;
2020-12-12 11:56:28 +01:00
} ) ; // TODO: move this to main startup
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
_electron . app . on ( 'gpu-process-crashed' , ( e , killed ) => {
2020-05-16 23:24:51 +02:00
if ( killed ) {
2020-12-12 11:56:28 +01:00
_electron . app . quit ( ) ;
2020-05-16 23:24:51 +02:00
}
} ) ;
2020-12-12 11:56:28 +01:00
_electron . app . on ( 'accessibility-support-changed' , ( _event , accessibilitySupportEnabled ) => webContentsSend ( 'ACCESSIBILITY_SUPPORT_CHANGED' , accessibilitySupportEnabled ) ) ;
_electron . app . on ( _Constants . MenuEvents . OPEN _HELP , ( ) => webContentsSend ( 'HELP_OPEN' ) ) ;
_electron . app . on ( _Constants . MenuEvents . OPEN _SETTINGS , ( ) => webContentsSend ( 'USER_SETTINGS_OPEN' ) ) ; // TODO: this hotpatches an issue with focusing the app from background.
// delete this after next stable electron release.
_electron . app . on ( 'second-instance' , ( _event , args ) => {
// if the second instance is the uninstaller, the bootstrap listener will quit the running app
if ( args != null && args . indexOf ( '--squirrel-uninstall' ) > - 1 ) {
return ;
} // if the current instance is multi instance, we want to leave the window alone
if ( process . argv != null && process . argv . slice ( 1 ) . includes ( '--multi-instance' ) ) {
return ;
}
if ( mainWindow == null ) {
return ;
}
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
setWindowVisible ( true , false ) ;
mainWindow . focus ( ) ;
} ) ;
2020-05-16 23:24:51 +02:00
2020-12-12 11:56:28 +01:00
_ipcMain . default . on ( 'SETTINGS_UPDATE_BACKGROUND_COLOR' , ( _event , backgroundColor ) => {
2020-05-16 23:24:51 +02:00
if ( getBackgroundColor ( ) !== backgroundColor ) {
setBackgroundColor ( backgroundColor ) ;
}
} ) ;
2020-12-12 11:56:28 +01:00
const updater = _updater . default === null || _updater . default === void 0 ? void 0 : _updater . default . getUpdater ( ) ;
if ( updater != null ) {
setupUpdaterEventsWithUpdater ( updater ) ;
} else {
setupLegacyUpdaterEvents ( ) ;
}
2020-05-16 23:24:51 +02:00
launchMainAppWindow ( false ) ;
}
2020-12-12 11:56:28 +01:00
function handleOpenUrl ( url ) {
const path = getSanitizedProtocolPath ( url ) ;
if ( path != null ) {
if ( ! mainWindowDidFinishLoad ) {
mainWindowInitialPath = path ;
2020-05-16 23:24:51 +02:00
}
2020-12-12 11:56:28 +01:00
webContentsSend ( 'MAIN_WINDOW_PATH' , path ) ;
}
if ( mainWindow == null ) {
return ;
2020-05-16 23:24:51 +02:00
}
2020-12-12 11:56:28 +01:00
setWindowVisible ( true , false ) ;
mainWindow . focus ( ) ;
2020-05-16 23:24:51 +02:00
}
function setMainWindowVisible ( visible ) {
setWindowVisible ( visible , false ) ;
}