2022-01-30 19:48:32 +00:00
// To allow seamless switching between custom titlebar and native os titlebar,
// I had to add most of the window creation code here to split both into seperete functions
// WHY? Because I can't use the same code for both due to annoying bug with value `frame` not responding to variables
// I'm sorry for this mess but I'm not sure how to fix it.
2022-06-16 21:09:41 +00:00
import { BrowserWindow , shell , app , dialog } from "electron" ;
2022-01-30 19:48:32 +00:00
import path from "path" ;
2022-07-11 19:42:35 +00:00
import { checkIfConfigIsBroken , firstRun , getConfig , contentPath , setConfig , setLang , setWindowState } from "./utils" ;
2022-06-16 21:09:41 +00:00
import { registerIpc } from "./ipc" ;
2022-07-14 15:25:59 +00:00
import { setMenu } from "./menu" ;
2022-06-16 21:09:41 +00:00
import * as fs from "fs" ;
2022-05-22 11:52:26 +00:00
import startServer from "./socket" ;
2022-02-26 21:26:16 +00:00
import contextMenu from "electron-context-menu" ;
2022-05-14 17:55:06 +00:00
import os from "os" ;
2022-04-21 16:20:58 +00:00
export var icon : string ;
2022-01-30 19:48:32 +00:00
export let mainWindow : BrowserWindow ;
2022-04-19 13:56:04 +00:00
export let inviteWindow : BrowserWindow ;
2022-06-03 16:05:28 +00:00
var osType = os . type ( )
2022-05-14 17:55:06 +00:00
2022-02-26 21:26:16 +00:00
contextMenu ( {
2022-03-04 17:53:18 +00:00
showSaveImageAs : true ,
showCopyImageAddress : true ,
showSearchWithGoogle : true
2022-02-26 21:26:16 +00:00
} ) ;
2022-01-30 19:48:32 +00:00
2022-04-19 17:59:52 +00:00
async function doAfterDefiningTheWindow() {
2022-06-03 13:18:36 +00:00
var ignoreProtocolWarning = await getConfig ( "ignoreProtocolWarning" ) ;
2022-04-18 10:06:17 +00:00
checkIfConfigIsBroken ( ) ;
2022-03-04 17:53:18 +00:00
registerIpc ( ) ;
2022-07-11 17:13:52 +00:00
if ( await getConfig ( "mobileMode" ) ) {
mainWindow . webContents . userAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.149 Mobile Safari/537.36"
} else {
// A little sloppy but it works :p
if ( osType == 'Windows_NT' ) {
osType = "Windows " + os . release ( ) . split ( '.' ) [ 0 ] + " (" + os . release ( ) + ")" ;
}
mainWindow . webContents . userAgent = ` Mozilla/5.0 (X11; ${ osType } ${ os . arch ( ) } ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 ` ; //fake useragent for screenshare to work
2022-06-03 16:05:28 +00:00
}
2022-07-11 17:13:52 +00:00
2022-06-16 21:09:41 +00:00
mainWindow . webContents . setWindowOpenHandler ( ( { url } ) = > {
2022-06-03 13:18:36 +00:00
if ( url . startsWith ( "https:" || url . startsWith ( "http:" ) || url . startsWith ( "mailto:" ) ) ) {
shell . openExternal ( url ) ;
} else {
if ( ignoreProtocolWarning ) {
shell . openExternal ( url ) ;
} else {
const options = {
type : "question" ,
buttons : [ "Yes, please" , "No, I don't" ] ,
defaultId : 1 ,
title : url ,
message : ` Do you want to open ${ url } ? ` ,
detail : "This url was detected to not use normal browser protocols. It could mean that this url leads to a local program on your computer. Please check if you recognise it, before proceeding!" ,
checkboxLabel : "Remember my answer and ignore this warning for future sessions" ,
checkboxChecked : false
} ;
2022-06-16 21:09:41 +00:00
dialog . showMessageBox ( mainWindow , options ) . then ( ( { response , checkboxChecked } ) = > {
2022-06-03 13:18:36 +00:00
console . log ( response , checkboxChecked ) ;
if ( checkboxChecked ) {
if ( response == 0 ) {
setConfig ( "ignoreProtocolWarning" , true ) ;
} else {
setConfig ( "ignoreProtocolWarning" , false ) ;
}
}
if ( response == 0 ) {
shell . openExternal ( url ) ;
} else {
return ;
}
} ) ;
}
}
2022-06-16 21:09:41 +00:00
return { action : "deny" } ;
2022-03-04 17:53:18 +00:00
} ) ;
mainWindow . webContents . session . webRequest . onBeforeRequest ( ( details , callback ) = > {
2022-06-16 21:09:41 +00:00
if ( /api\/v\d\/science$/g . test ( details . url ) ) return callback ( { cancel : true } ) ;
2022-03-04 17:53:18 +00:00
return callback ( { } ) ;
} ) ;
2022-06-16 21:09:41 +00:00
const userDataPath = app . getPath ( "userData" ) ;
const themesFolder = userDataPath + "/themes/" ;
if ( ! fs . existsSync ( themesFolder ) ) {
fs . mkdirSync ( themesFolder ) ;
console . log ( "Created missing theme folder" ) ;
}
mainWindow . webContents . on ( 'did-finish-load' , ( ) = > {
fs . readdirSync ( themesFolder ) . forEach ( ( file ) = > {
try {
const manifest = fs . readFileSync ( ` ${ themesFolder } / ${ file } /manifest.json ` , "utf8" ) ;
var themeFile = JSON . parse ( manifest ) ;
mainWindow . webContents . send ( "themeLoader" , fs . readFileSync ( ` ${ themesFolder } / ${ file } / ${ themeFile . theme } ` , "utf-8" ) )
console . log ( ` %cLoaded ${ themeFile . name } made by ${ themeFile . author } ` , "color:red" ) ;
} catch ( err ) {
console . error ( err ) ;
}
} ) ;
} ) ;
2022-07-14 15:25:59 +00:00
setMenu ( )
2022-03-04 17:53:18 +00:00
mainWindow . on ( "close" , async ( e ) = > {
2022-06-16 15:24:37 +00:00
let [ width , height ] = mainWindow . getSize ( )
setWindowState ( {
width : width ,
height : height ,
isMaximized : mainWindow.isMaximized ( )
} )
2022-04-18 10:25:10 +00:00
if ( await getConfig ( "minimizeToTray" ) ) {
2022-03-04 17:53:18 +00:00
e . preventDefault ( ) ;
mainWindow . hide ( ) ;
2022-04-18 10:25:10 +00:00
} else if ( ! ( await getConfig ( "minimizeToTray" ) ) ) {
2022-03-04 17:53:18 +00:00
e . preventDefault ( ) ;
app . quit ( ) ;
}
} ) ;
2022-06-16 21:09:41 +00:00
mainWindow . on ( 'maximize' , ( ) = > {
2022-06-14 14:30:18 +00:00
mainWindow . webContents . executeJavaScript ( ` document.body.setAttribute("isMaximized", ""); ` )
} )
2022-06-16 21:09:41 +00:00
mainWindow . on ( 'unmaximize' , ( ) = > {
2022-06-14 14:30:18 +00:00
mainWindow . webContents . executeJavaScript ( ` document.body.removeAttribute("isMaximized"); ` )
} )
2022-03-04 17:53:18 +00:00
console . log ( contentPath ) ;
2022-05-22 11:52:26 +00:00
if ( ( await getConfig ( "inviteWebsocket" ) ) == true ) {
2022-07-11 18:19:50 +00:00
await startServer ( ) ;
2022-04-19 17:59:52 +00:00
}
2022-07-11 18:19:50 +00:00
if ( firstRun ) {
await setLang ( Intl . DateTimeFormat ( ) . resolvedOptions ( ) . locale )
mainWindow . setSize ( 390 , 470 ) ;
await mainWindow . loadFile ( path . join ( __dirname , "/content/setup.html" ) ) ;
} else {
await mainWindow . loadFile ( path . join ( __dirname , "/content/splash.html" ) ) ;
2022-01-30 19:48:32 +00:00
}
}
export function createCustomWindow() {
2022-03-04 17:53:18 +00:00
mainWindow = new BrowserWindow ( {
2022-05-14 19:02:09 +00:00
width : 300 ,
height : 350 ,
2022-03-04 17:53:18 +00:00
title : "ArmCord" ,
darkTheme : true ,
2022-06-10 18:46:30 +00:00
icon : path.join ( __dirname , "../" , "/assets/ac_icon_transparent.png" ) ,
2022-03-04 17:53:18 +00:00
frame : false ,
autoHideMenuBar : true ,
webPreferences : {
preload : path.join ( __dirname , "preload/preload.js" ) ,
spellcheck : true
}
} ) ;
doAfterDefiningTheWindow ( ) ;
2022-01-30 19:48:32 +00:00
}
export function createNativeWindow() {
2022-03-04 17:53:18 +00:00
mainWindow = new BrowserWindow ( {
width : 300 ,
height : 350 ,
title : "ArmCord" ,
darkTheme : true ,
2022-06-10 18:46:30 +00:00
icon : path.join ( __dirname , "../" , "/assets/ac_icon_transparent.png" ) ,
2022-03-04 17:53:18 +00:00
frame : true ,
autoHideMenuBar : true ,
webPreferences : {
preload : path.join ( __dirname , "preload/preload.js" ) ,
spellcheck : true
}
} ) ;
doAfterDefiningTheWindow ( ) ;
2022-02-26 21:26:16 +00:00
}
2022-04-19 13:56:04 +00:00
export function createInviteWindow() {
inviteWindow = new BrowserWindow ( {
width : 800 ,
height : 600 ,
title : "ArmCord Invite Manager" ,
darkTheme : true ,
2022-06-10 18:46:30 +00:00
icon : path.join ( __dirname , "../" , "/assets/ac_icon_transparent.png" ) ,
2022-04-19 13:56:04 +00:00
frame : true ,
autoHideMenuBar : true ,
webPreferences : {
spellcheck : true
}
} ) ;
2022-05-22 11:52:26 +00:00
inviteWindow . hide ( ) ;
}