2021-09-01 20:48:05 +00:00
import electron , { BrowserWindow , MenuItemConstructorOptions } from 'electron' ;
2017-05-03 17:48:23 +00:00
import fs from 'fs' ;
2021-07-22 23:04:56 +00:00
import { Curl } from 'node-libcurl' ;
import * as os from 'os' ;
import path from 'path' ;
2018-06-25 17:42:50 +00:00
import {
2020-04-26 20:33:39 +00:00
changelogUrl ,
2018-06-25 17:42:50 +00:00
getAppLongName ,
getAppName ,
2020-08-12 20:59:30 +00:00
getAppReleaseDate ,
2020-05-14 22:54:07 +00:00
getAppVersion ,
2018-06-25 17:42:50 +00:00
isDevelopment ,
2020-08-12 20:59:30 +00:00
isLinux ,
2018-12-12 17:36:11 +00:00
isMac ,
2020-04-26 20:33:39 +00:00
MNEMONIC_SYM ,
2018-06-25 17:42:50 +00:00
} from '../common/constants' ;
2021-07-22 23:04:56 +00:00
import { docsBase } from '../common/documentation' ;
2021-05-12 20:20:52 +00:00
import { clickLink , getDataDirectory , restartApp } from '../common/electron-helpers' ;
2020-10-20 11:01:47 +00:00
import * as log from '../common/log' ;
2021-07-22 23:04:56 +00:00
import LocalStorage from './local-storage' ;
2017-05-03 17:48:23 +00:00
2021-10-12 15:21:45 +00:00
const { app , Menu , shell , dialog , clipboard } = electron ;
2020-07-28 05:18:26 +00:00
// So we can use native modules in renderer
2021-09-01 20:48:05 +00:00
// NOTE: This was (deprecated in Electron 10)[https://github.com/electron/electron/issues/18397] and (removed in Electron 14)[https://github.com/electron/electron/pull/26874]
2020-07-28 05:18:26 +00:00
app . allowRendererProcessReuse = false ;
2020-04-26 20:33:39 +00:00
const DEFAULT_WIDTH = 1280 ;
const DEFAULT_HEIGHT = 700 ;
2017-06-22 19:37:24 +00:00
const MINIMUM_WIDTH = 500 ;
const MINIMUM_HEIGHT = 400 ;
2021-05-12 06:35:00 +00:00
let mainWindow : BrowserWindow | null = null ;
let localStorage : LocalStorage | null = null ;
interface Bounds {
height? : number ;
width? : number ;
x? : number ;
y? : number ;
}
2017-05-03 17:48:23 +00:00
2018-06-25 17:42:50 +00:00
export function init() {
2017-05-24 16:25:22 +00:00
initLocalStorage ( ) ;
initContextMenus ( ) ;
}
2018-06-25 17:42:50 +00:00
export function createWindow() {
2017-05-03 17:48:23 +00:00
const zoomFactor = getZoomFactor ( ) ;
2018-06-25 17:42:50 +00:00
const { bounds , fullscreen , maximize } = getBounds ( ) ;
const { x , y , width , height } = bounds ;
2017-05-03 17:48:23 +00:00
2021-05-12 06:35:00 +00:00
const appLogo = 'static/insomnia-core-logo_16x.png' ;
2019-10-07 19:37:16 +00:00
let isVisibleOnAnyDisplay = true ;
2021-05-12 06:35:00 +00:00
2017-05-03 17:48:23 +00:00
for ( const d of electron . screen . getAllDisplays ( ) ) {
2019-10-07 19:37:16 +00:00
const isVisibleOnDisplay =
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION genuine error
2019-10-07 19:37:16 +00:00
x >= d . bounds . x &&
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION genuine error
2019-10-07 19:37:16 +00:00
y >= d . bounds . y &&
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION genuine error
2019-10-07 19:37:16 +00:00
x + width <= d . bounds . x + d . bounds . width &&
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION genuine error
2019-10-07 19:37:16 +00:00
y + height <= d . bounds . y + d . bounds . height ;
if ( ! isVisibleOnDisplay ) {
isVisibleOnAnyDisplay = false ;
}
2017-05-03 17:48:23 +00:00
}
2019-08-21 17:43:54 +00:00
2017-05-03 17:48:23 +00:00
mainWindow = new BrowserWindow ( {
// Make sure we don't initialize the window outside the bounds
2019-10-07 19:37:16 +00:00
x : isVisibleOnAnyDisplay ? x : undefined ,
y : isVisibleOnAnyDisplay ? y : undefined ,
// Other options
2021-04-20 01:33:46 +00:00
backgroundColor : '#2C2C2C' ,
2017-05-03 17:48:23 +00:00
fullscreen : fullscreen ,
fullscreenable : true ,
title : getAppName ( ) ,
2017-06-22 19:37:24 +00:00
width : width || DEFAULT_WIDTH ,
height : height || DEFAULT_HEIGHT ,
2017-06-26 19:12:18 +00:00
minHeight : MINIMUM_HEIGHT ,
minWidth : MINIMUM_WIDTH ,
2017-05-03 17:48:23 +00:00
acceptFirstMouse : true ,
2020-10-22 20:43:00 +00:00
icon : path.resolve ( __dirname , appLogo ) ,
2017-05-03 17:48:23 +00:00
webPreferences : {
2018-12-12 17:36:11 +00:00
zoomFactor : zoomFactor ,
2020-07-28 05:18:26 +00:00
nodeIntegration : true ,
webviewTag : true ,
enableRemoteModule : true ,
2021-07-16 20:35:32 +00:00
// TODO: enable context isolation
contextIsolation : false ,
2021-08-10 09:28:12 +00:00
disableBlinkFeatures : 'Auxclick' ,
2018-12-12 17:36:11 +00:00
} ,
2017-05-03 17:48:23 +00:00
} ) ;
2017-06-29 17:39:09 +00:00
// BrowserWindow doesn't have an option for this, so we have to do it manually :(
if ( maximize ) {
2021-05-12 06:35:00 +00:00
mainWindow ? . maximize ( ) ;
2017-06-29 17:39:09 +00:00
}
2021-05-12 06:35:00 +00:00
mainWindow ? . on ( 'resize' , ( ) = > saveBounds ( ) ) ;
mainWindow ? . on ( 'maximize' , ( ) = > saveBounds ( ) ) ;
mainWindow ? . on ( 'unmaximize' , ( ) = > saveBounds ( ) ) ;
mainWindow ? . on ( 'move' , ( ) = > saveBounds ( ) ) ;
mainWindow ? . on ( 'unresponsive' , ( ) = > {
2017-05-03 17:48:23 +00:00
showUnresponsiveModal ( ) ;
} ) ;
2021-09-20 09:53:05 +00:00
2019-05-08 20:13:26 +00:00
// Open generic links (<a .../>) in default browser
2021-05-12 06:35:00 +00:00
mainWindow ? . webContents . on ( 'will-navigate' , ( e , url ) = > {
2019-05-08 20:32:28 +00:00
if ( url === appUrl ) {
return ;
}
console . log ( '[app] Navigate to ' + url ) ;
2019-05-08 20:13:26 +00:00
e . preventDefault ( ) ;
2021-05-12 20:20:52 +00:00
clickLink ( url ) ;
2019-05-08 20:13:26 +00:00
} ) ;
2021-08-10 09:28:12 +00:00
mainWindow ? . webContents . on ( 'new-window' , e = > {
e . preventDefault ( ) ;
} ) ;
2017-11-24 01:39:53 +00:00
// Load the html of the app.
2018-03-30 16:46:01 +00:00
const url = process . env . APP_RENDER_URL ;
const appUrl = url || ` file:// ${ app . getAppPath ( ) } /renderer.html ` ;
console . log ( ` [main] Loading ${ appUrl } ` ) ;
2021-05-12 06:35:00 +00:00
mainWindow ? . loadURL ( appUrl ) ;
2017-05-03 17:48:23 +00:00
// Emitted when the window is closed.
2021-05-12 06:35:00 +00:00
mainWindow ? . on ( 'closed' , ( ) = > {
2017-05-03 17:48:23 +00:00
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null ;
} ) ;
2021-05-12 06:35:00 +00:00
const applicationMenu : MenuItemConstructorOptions = {
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Application ` ,
2017-05-03 17:48:23 +00:00
submenu : [
{
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Preferences ` ,
2021-05-12 06:35:00 +00:00
click : function ( _menuItem , window ) {
2017-05-03 17:48:23 +00:00
if ( ! window || ! window . webContents ) {
return ;
}
2021-05-12 06:35:00 +00:00
2017-05-03 17:48:23 +00:00
window . webContents . send ( 'toggle-preferences' ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-05-03 17:48:23 +00:00
} ,
{
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Changelog ` ,
2021-05-12 06:35:00 +00:00
click : function ( _menuItem , window ) {
2017-05-03 17:48:23 +00:00
if ( ! window || ! window . webContents ) {
return ;
}
2021-05-12 06:35:00 +00:00
clickLink ( changelogUrl ( ) ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-05-03 17:48:23 +00:00
} ,
2021-05-12 06:35:00 +00:00
{
type : 'separator' ,
} ,
{
role : 'hide' ,
} ,
{
// @ts-expect-error -- TSCONVERSION appears to be a genuine error
role : 'hideothers' ,
} ,
{
type : 'separator' ,
} ,
{
label : ` ${ MNEMONIC_SYM } Quit ` ,
accelerator : 'CmdOrCtrl+Q' ,
click : ( ) = > app . quit ( ) ,
} ,
2018-12-12 17:36:11 +00:00
] ,
2017-05-03 17:48:23 +00:00
} ;
2021-05-12 06:35:00 +00:00
const editMenu : MenuItemConstructorOptions = {
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Edit ` ,
2017-05-03 17:48:23 +00:00
submenu : [
2021-05-12 06:35:00 +00:00
{
label : ` ${ MNEMONIC_SYM } Undo ` ,
accelerator : 'CmdOrCtrl+Z' ,
selector : 'undo:' ,
} ,
{
label : ` ${ MNEMONIC_SYM } Redo ` ,
accelerator : 'Shift+CmdOrCtrl+Z' ,
selector : 'redo:' ,
} ,
{
type : 'separator' ,
} ,
{
label : ` Cu ${ MNEMONIC_SYM } t ` ,
accelerator : 'CmdOrCtrl+X' ,
selector : 'cut:' ,
} ,
{
label : ` ${ MNEMONIC_SYM } Copy ` ,
accelerator : 'CmdOrCtrl+C' ,
selector : 'copy:' ,
} ,
{
label : ` ${ MNEMONIC_SYM } Paste ` ,
accelerator : 'CmdOrCtrl+V' ,
selector : 'paste:' ,
} ,
2018-06-25 17:42:50 +00:00
{
2018-12-11 23:11:54 +00:00
label : ` Select ${ MNEMONIC_SYM } All ` ,
2018-06-25 17:42:50 +00:00
accelerator : 'CmdOrCtrl+A' ,
2018-12-12 17:36:11 +00:00
selector : 'selectAll:' ,
} ,
] ,
2017-05-03 17:48:23 +00:00
} ;
2021-05-12 06:35:00 +00:00
const viewMenu : MenuItemConstructorOptions = {
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } View ` ,
2017-05-03 17:48:23 +00:00
submenu : [
2021-05-12 06:35:00 +00:00
{
label : ` Toggle ${ MNEMONIC_SYM } Full Screen ` ,
role : 'togglefullscreen' ,
} ,
2017-05-03 17:48:23 +00:00
{
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Actual Size ` ,
2017-05-03 17:48:23 +00:00
accelerator : 'CmdOrCtrl+0' ,
click : ( ) = > {
2019-04-18 00:50:03 +00:00
const w = BrowserWindow . getFocusedWindow ( ) ;
2021-05-12 06:35:00 +00:00
2019-04-18 00:50:03 +00:00
if ( ! w || ! w . webContents ) {
2017-05-03 17:48:23 +00:00
return ;
}
const zoomFactor = 1 ;
2019-04-18 00:50:03 +00:00
w . webContents . setZoomFactor ( zoomFactor ) ;
2017-05-03 17:48:23 +00:00
saveZoomFactor ( zoomFactor ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-05-03 17:48:23 +00:00
} ,
{
2018-12-11 23:11:54 +00:00
label : ` Zoom ${ MNEMONIC_SYM } In ` ,
2019-04-18 00:50:03 +00:00
accelerator : 'CmdOrCtrl+=' ,
2017-05-03 17:48:23 +00:00
click : ( ) = > {
2019-04-18 00:50:03 +00:00
const w = BrowserWindow . getFocusedWindow ( ) ;
2021-05-12 06:35:00 +00:00
2019-04-18 00:50:03 +00:00
if ( ! w || ! w . webContents ) {
2017-05-03 17:48:23 +00:00
return ;
}
const zoomFactor = Math . min ( 1.8 , getZoomFactor ( ) + 0.05 ) ;
2019-04-18 00:50:03 +00:00
w . webContents . setZoomFactor ( zoomFactor ) ;
2017-05-03 17:48:23 +00:00
saveZoomFactor ( zoomFactor ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-05-03 17:48:23 +00:00
} ,
{
2018-12-11 23:11:54 +00:00
label : ` Zoom ${ MNEMONIC_SYM } Out ` ,
2017-05-03 17:48:23 +00:00
accelerator : 'CmdOrCtrl+-' ,
click : ( ) = > {
2019-04-18 00:50:03 +00:00
const w = BrowserWindow . getFocusedWindow ( ) ;
2021-05-12 06:35:00 +00:00
2019-04-18 00:50:03 +00:00
if ( ! w || ! w . webContents ) {
2017-05-03 17:48:23 +00:00
return ;
}
const zoomFactor = Math . max ( 0.5 , getZoomFactor ( ) - 0.05 ) ;
2019-04-18 00:50:03 +00:00
w . webContents . setZoomFactor ( zoomFactor ) ;
2017-05-03 17:48:23 +00:00
saveZoomFactor ( zoomFactor ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-05-03 17:48:23 +00:00
} ,
2021-07-11 07:28:35 +00:00
{
type : 'separator' ,
} ,
2019-08-05 18:38:19 +00:00
{
label : 'Toggle Sidebar' ,
click : ( ) = > {
const w = BrowserWindow . getFocusedWindow ( ) ;
2021-05-12 06:35:00 +00:00
2019-08-05 18:38:19 +00:00
if ( ! w || ! w . webContents ) {
return ;
}
w . webContents . send ( 'toggle-sidebar' ) ;
} ,
} ,
2017-09-17 14:25:31 +00:00
{
2018-12-11 23:11:54 +00:00
label : ` Toggle ${ MNEMONIC_SYM } DevTools ` ,
2020-06-30 21:00:58 +00:00
accelerator : 'Alt+CmdOrCtrl+I' ,
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION needs global module augmentation
click : ( ) = > mainWindow ? . toggleDevTools ( ) ,
2018-12-12 17:36:11 +00:00
} ,
] ,
2017-05-03 17:48:23 +00:00
} ;
2021-05-12 06:35:00 +00:00
const windowMenu : MenuItemConstructorOptions = {
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Window ` ,
2017-05-03 17:48:23 +00:00
role : 'window' ,
2018-12-11 23:11:54 +00:00
submenu : [
2021-05-12 06:35:00 +00:00
{
label : ` ${ MNEMONIC_SYM } Minimize ` ,
role : 'minimize' ,
} ,
// @ts-expect-error -- TSCONVERSION missing in official electron types
. . . ( isMac ( ) ? [
2021-05-27 18:00:32 +00:00
{
label : ` ${ MNEMONIC_SYM } Close ` ,
role : 'close' ,
} ,
]
2021-05-12 06:35:00 +00:00
: [ ] ) ,
2018-12-12 17:36:11 +00:00
] ,
2017-05-03 17:48:23 +00:00
} ;
2021-05-12 06:35:00 +00:00
const helpMenu : MenuItemConstructorOptions = {
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Help ` ,
2017-05-03 17:48:23 +00:00
role : 'help' ,
id : 'help' ,
submenu : [
{
2020-04-26 20:33:39 +00:00
label : ` ${ MNEMONIC_SYM } Help and Support ` ,
2021-09-01 20:48:05 +00:00
. . . ( isMac ( ) ? { } : { accelerator : 'F1' } ) ,
2017-05-03 17:48:23 +00:00
click : ( ) = > {
2021-05-12 20:20:52 +00:00
clickLink ( docsBase ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-05-03 17:48:23 +00:00
} ,
2017-08-04 16:54:11 +00:00
{
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Keyboard Shortcuts ` ,
accelerator : 'CmdOrCtrl+Shift+?' ,
2021-05-12 06:35:00 +00:00
click : ( _menuItem , w ) = > {
2019-04-18 00:50:03 +00:00
if ( ! w || ! w . webContents ) {
2017-08-04 16:54:11 +00:00
return ;
}
2021-05-12 06:35:00 +00:00
2019-04-18 00:50:03 +00:00
w . webContents . send ( 'toggle-preferences-shortcuts' ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-08-04 16:54:11 +00:00
} ,
2021-07-11 07:28:35 +00:00
{
type : 'separator' ,
} ,
2017-10-10 16:47:49 +00:00
{
2018-12-11 23:11:54 +00:00
label : ` Show App ${ MNEMONIC_SYM } Data Folder ` ,
2021-05-12 06:35:00 +00:00
click : ( ) = > {
const directory = getDataDirectory ( ) ;
2017-10-10 16:47:49 +00:00
shell . showItemInFolder ( directory ) ;
2018-12-12 17:36:11 +00:00
} ,
2017-10-10 16:47:49 +00:00
} ,
2020-10-20 11:01:47 +00:00
{
label : ` Show App ${ MNEMONIC_SYM } Logs Folder ` ,
2021-05-12 06:35:00 +00:00
click : ( ) = > {
2020-10-20 11:01:47 +00:00
const directory = log . getLogDirectory ( ) ;
shell . showItemInFolder ( directory ) ;
} ,
} ,
2021-07-11 07:28:35 +00:00
{
type : 'separator' ,
} ,
2020-02-06 13:41:56 +00:00
{
label : 'Show Open Source Licenses' ,
2021-05-12 06:35:00 +00:00
click : ( ) = > {
2020-02-06 13:41:56 +00:00
const licensePath = path . resolve ( app . getAppPath ( ) , '../opensource-licenses.txt' ) ;
2020-07-28 05:18:26 +00:00
shell . openPath ( licensePath ) ;
2020-02-06 13:41:56 +00:00
} ,
} ,
2020-03-12 22:57:46 +00:00
{
label : 'Show Software License' ,
click : ( ) = > {
2021-05-12 20:20:52 +00:00
clickLink ( 'https://insomnia.rest/license' ) ;
2020-03-12 22:57:46 +00:00
} ,
} ,
2018-12-12 17:36:11 +00:00
] ,
2017-05-03 17:48:23 +00:00
} ;
2020-08-12 20:59:30 +00:00
const aboutMenuClickHandler = async ( ) = > {
const copy = 'Copy' ;
const ok = 'OK' ;
const buttons = isLinux ( ) ? [ copy , ok ] : [ ok , copy ] ;
const detail = [
` Version: ${ getAppLongName ( ) } ${ getAppVersion ( ) } ` ,
` Release date: ${ getAppReleaseDate ( ) } ` ,
` OS: ${ os . type ( ) } ${ os . arch ( ) } ${ os . release ( ) } ` ,
` Electron: ${ process . versions . electron } ` ,
` Node: ${ process . versions . node } ` ,
` V8: ${ process . versions . v8 } ` ,
` Architecture: ${ process . arch } ` ,
` node-libcurl: ${ Curl . getVersion ( ) } ` ,
] . join ( '\n' ) ;
const msgBox = await dialog . showMessageBox ( {
type : 'info' ,
title : getAppName ( ) ,
message : getAppLongName ( ) ,
detail ,
buttons ,
defaultId : buttons.indexOf ( ok ) ,
cancelId : buttons.indexOf ( ok ) ,
noLink : true ,
} ) ;
if ( msgBox . response === buttons . indexOf ( copy ) ) {
clipboard . writeText ( detail ) ;
}
2020-08-10 21:14:11 +00:00
} ;
if ( isMac ( ) ) {
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION type splitting
applicationMenu . submenu ? . unshift (
2020-08-10 21:14:11 +00:00
{
label : ` A ${ MNEMONIC_SYM } bout ${ getAppName ( ) } ` ,
2020-08-12 20:59:30 +00:00
click : aboutMenuClickHandler ,
2020-08-10 21:14:11 +00:00
} ,
2021-05-12 06:35:00 +00:00
{
type : 'separator' ,
} ,
2020-08-10 21:14:11 +00:00
) ;
} else {
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION type splitting
helpMenu . submenu ? . push ( {
2021-07-11 07:28:35 +00:00
type : 'separator' ,
} ,
{
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } About ` ,
2020-08-12 20:59:30 +00:00
click : aboutMenuClickHandler ,
2018-03-30 16:46:01 +00:00
} ) ;
}
2021-05-12 06:35:00 +00:00
const developerMenu : MenuItemConstructorOptions = {
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Developer ` ,
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION missing in official electron types
2017-05-03 17:48:23 +00:00
position : 'before=help' ,
2018-06-25 17:42:50 +00:00
submenu : [
{
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Reload ` ,
2018-06-25 17:42:50 +00:00
accelerator : 'Shift+F5' ,
2021-05-12 06:35:00 +00:00
click : ( ) = > mainWindow ? . reload ( ) ,
2018-06-25 17:42:50 +00:00
} ,
{
2018-12-11 23:11:54 +00:00
label : ` Resize to Defaul ${ MNEMONIC_SYM } t ` ,
2018-06-25 17:42:50 +00:00
click : ( ) = >
2021-05-12 06:35:00 +00:00
mainWindow ? . setBounds ( {
2018-06-25 17:42:50 +00:00
x : 100 ,
y : 100 ,
width : DEFAULT_WIDTH ,
2018-12-12 17:36:11 +00:00
height : DEFAULT_HEIGHT ,
} ) ,
2018-06-25 17:42:50 +00:00
} ,
{
2018-12-11 23:11:54 +00:00
label : ` Take ${ MNEMONIC_SYM } Screenshot ` ,
2018-06-25 17:42:50 +00:00
click : function ( ) {
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION not accounted for in the electron types to provide a function
mainWindow ? . capturePage ( image = > {
2018-06-25 17:42:50 +00:00
const buffer = image . toPNG ( ) ;
const dir = app . getPath ( 'desktop' ) ;
2018-10-17 16:42:33 +00:00
fs . writeFileSync ( path . join ( dir , ` Screenshot- ${ new Date ( ) } .png ` ) , buffer ) ;
2018-06-25 17:42:50 +00:00
} ) ;
2018-12-12 17:36:11 +00:00
} ,
} ,
2021-02-25 20:13:37 +00:00
{
2021-07-22 12:21:41 +00:00
label : ` ${ MNEMONIC_SYM } Clear a model ` ,
click : function ( _menuItem , window ) {
window ? . webContents ? . send ( 'clear-model' ) ;
} ,
} ,
{
label : ` Clear ${ MNEMONIC_SYM } all models ` ,
click : function ( _menuItem , window ) {
window ? . webContents ? . send ( 'clear-all-models' ) ;
} ,
} ,
{
label : ` R ${ MNEMONIC_SYM } estart ` ,
2021-05-12 20:20:52 +00:00
click : restartApp ,
2021-02-25 20:13:37 +00:00
} ,
2018-12-12 17:36:11 +00:00
] ,
2017-05-03 17:48:23 +00:00
} ;
2021-05-12 06:35:00 +00:00
const toolsMenu : MenuItemConstructorOptions = {
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Tools ` ,
2018-06-25 17:42:50 +00:00
submenu : [
{
2018-12-11 23:11:54 +00:00
label : ` ${ MNEMONIC_SYM } Reload Plugins ` ,
2018-06-25 17:42:50 +00:00
click : ( ) = > {
2019-04-18 00:50:03 +00:00
const w = BrowserWindow . getFocusedWindow ( ) ;
2021-05-12 06:35:00 +00:00
2019-04-18 00:50:03 +00:00
if ( ! w || ! w . webContents ) {
2018-06-25 17:42:50 +00:00
return ;
}
2017-11-01 14:54:57 +00:00
2019-04-18 00:50:03 +00:00
w . webContents . send ( 'reload-plugins' ) ;
2018-12-12 17:36:11 +00:00
} ,
} ,
] ,
2017-11-01 14:54:57 +00:00
} ;
2021-05-18 20:32:18 +00:00
const template : MenuItemConstructorOptions [ ] = [ ] ;
2017-05-03 17:48:23 +00:00
template . push ( applicationMenu ) ;
template . push ( editMenu ) ;
template . push ( viewMenu ) ;
template . push ( windowMenu ) ;
2017-11-01 14:54:57 +00:00
template . push ( toolsMenu ) ;
2017-05-03 17:48:23 +00:00
template . push ( helpMenu ) ;
if ( isDevelopment ( ) || process . env . INSOMNIA_FORCE_DEBUG ) {
template . push ( developerMenu ) ;
}
Menu . setApplicationMenu ( Menu . buildFromTemplate ( template ) ) ;
return mainWindow ;
}
2020-07-28 05:18:26 +00:00
async function showUnresponsiveModal() {
const id = await dialog . showMessageBox ( {
type : 'info' ,
buttons : [ 'Cancel' , 'Reload' ] ,
defaultId : 1 ,
cancelId : 0 ,
title : 'Unresponsive' ,
message : 'Insomnia has become unresponsive. Do you want to reload?' ,
} ) ;
2021-05-12 06:35:00 +00:00
// @ts-expect-error -- TSCONVERSION appears to be a genuine error
2020-07-28 05:18:26 +00:00
if ( id === 1 ) {
2021-05-12 06:35:00 +00:00
mainWindow ? . destroy ( ) ;
2020-07-28 05:18:26 +00:00
createWindow ( ) ;
}
2017-05-03 17:48:23 +00:00
}
2018-06-25 17:42:50 +00:00
function saveBounds() {
2017-05-03 17:48:23 +00:00
if ( ! mainWindow ) {
return ;
}
2021-05-12 06:35:00 +00:00
const fullscreen = mainWindow ? . isFullScreen ( ) ;
2017-05-03 17:48:23 +00:00
// Only save the size if we're not in fullscreen
if ( ! fullscreen ) {
2021-05-12 06:35:00 +00:00
localStorage ? . setItem ( 'bounds' , mainWindow ? . getBounds ( ) ) ;
localStorage ? . setItem ( 'maximize' , mainWindow ? . isMaximized ( ) ) ;
localStorage ? . setItem ( 'fullscreen' , false ) ;
2017-05-03 17:48:23 +00:00
} else {
2021-05-12 06:35:00 +00:00
localStorage ? . setItem ( 'fullscreen' , true ) ;
2017-05-03 17:48:23 +00:00
}
}
2018-06-25 17:42:50 +00:00
function getBounds() {
2021-05-12 06:35:00 +00:00
let bounds : Bounds = { } ;
2017-05-03 17:48:23 +00:00
let fullscreen = false ;
2017-06-29 17:39:09 +00:00
let maximize = false ;
2021-05-12 06:35:00 +00:00
2017-05-03 17:48:23 +00:00
try {
2021-05-12 06:35:00 +00:00
bounds = localStorage ? . getItem ( 'bounds' , { } ) ;
fullscreen = localStorage ? . getItem ( 'fullscreen' , false ) ;
maximize = localStorage ? . getItem ( 'maximize' , false ) ;
2017-05-03 17:48:23 +00:00
} catch ( e ) {
// This should never happen, but if it does...!
console . error ( 'Failed to parse window bounds' , e ) ;
}
2021-05-12 06:35:00 +00:00
return {
bounds ,
fullscreen ,
maximize ,
} ;
2017-05-03 17:48:23 +00:00
}
2018-06-25 17:42:50 +00:00
function saveZoomFactor ( zoomFactor ) {
2021-05-12 06:35:00 +00:00
localStorage ? . setItem ( 'zoomFactor' , zoomFactor ) ;
2017-05-03 17:48:23 +00:00
}
2018-06-25 17:42:50 +00:00
function getZoomFactor() {
2017-05-03 17:48:23 +00:00
let zoomFactor = 1 ;
2021-05-12 06:35:00 +00:00
2017-05-03 17:48:23 +00:00
try {
2021-05-12 06:35:00 +00:00
zoomFactor = localStorage ? . getItem ( 'zoomFactor' , 1 ) ;
2017-05-03 17:48:23 +00:00
} catch ( e ) {
// This should never happen, but if it does...!
console . error ( 'Failed to parse zoomFactor' , e ) ;
}
return zoomFactor ;
}
2018-06-25 17:42:50 +00:00
function initLocalStorage() {
2021-05-12 06:35:00 +00:00
const localStoragePath = path . join ( getDataDirectory ( ) , 'localStorage' ) ;
2017-05-03 17:48:23 +00:00
localStorage = new LocalStorage ( localStoragePath ) ;
}
2018-06-25 17:42:50 +00:00
function initContextMenus() {
2021-05-12 06:35:00 +00:00
// eslint-disable-next-line @typescript-eslint/no-var-requires
2017-05-24 16:25:22 +00:00
require ( 'electron-context-menu' ) ( { } ) ;
}