import * as pathlib from "path" ; import { app , ipcMain , IpcMainInvokeEvent } from "electron" ; import { enforceMacOSAppLocation } from 'electron-util' ; import { EventEmitter } from "events" ; import Main from "./windows/main" ; import Window from "./windows/window" ; import { MainIpc_FileHandlers , MainIpc_TagHandlers , MainIpc_DialogHandlers , MainIpc_LifecycleHandlers , MainIpc_ThemeHandlers , MainIpc_ShellHandlers , MainIpcHandlers , MainIpcChannel , MainIpc_OutlineHandlers , MainIpc_MetadataHandlers , MainIpc_NavigationHandlers } from "./MainIPC" ; import { FSAL } from "./fsal/fsal" ; import { invokerFor , FunctionPropertyNames } from "@common/ipc" ; import { IDirEntryMeta } from "@common/files" ; import { AppEvents , IpcEvents } from "@common/events" ; import { RendererIpcHandlers } from "@renderer/RendererIPC" ; import { WorkspaceService , WorkspaceEvent } from "./workspace/workspace-service" ; import { ThemeService , ThemeEvent } from "./theme/theme-service" ; import { PluginService } from "./plugins/plugin-service" ; export default class NoteworthyApp extends EventEmitter { window : Window | undefined ; /** proxy for SENDING events to the render process */ _renderProxy : null | RendererIpcHandlers ; /** handlers for events RECEIVED from the render process */ _eventHandlers : MainIpcHandlers ; constructor ( /** file system abstraction layer */ private _fsal , private _workspaceService , private _pluginService , private _themeService ) { super ( ) ; this . _renderProxy = null ; this . _eventHandlers = this . makeHandlers ( ) ; this . handleFileTreeChanged = this . handleFileTreeChanged . bind ( this ) ; this . handleThemeChanged = this . handleThemeChanged . bind ( this ) ; this . init ( ) ; this . attachEvents ( ) ; } init ( ) { ipcMain . handle ( "command" , < T extends MainIpcChannel > ( evt , channel , key , data ) => { console . log ( `MainIPC :: handling event :: ${ channel } ${ key }` ) ; return this . handle ( channel , key , data ) ; } ) ; } todo makeHandlers ( ) { let lifecycleHandlers = new MainIpc_LifecycleHandlers ( this ) ; let shellHandlers = new MainIpc_ShellHandlers ( ) ; let fileHandlers = new MainIpc_FileHandlers ( this , this . _fsal , this . _workspaceService , this . _pluginService ) ; let tagHandlers = new MainIpc_TagHandlers ( this , this . _workspaceService , this . _pluginService , fileHandlers ) ; let navigationHandlers = new MainIpc_NavigationHandlers ( this , this . _workspaceService , this . _pluginService , fileHandlers , tagHandlers ) ; let dialogHandlers = new MainIpc_DialogHandlers ( this , this . _fsal , this . _workspaceService ) ; let outlineHandlers = new MainIpc_OutlineHandlers ( this . _pluginService ) ; let themeHandlers = new MainIpc_ThemeHandlers ( this . _themeService ) ; let metadataHandlers = new MainIpc_MetadataHandlers ( this . _pluginService ) ; return { lifecycle : lifecycleHandlers , file : fileHandlers , theme : themeHandlers , shell : shellHandlers , dialog : dialogHandlers , tag : tagHandlers , outline : outlineHandlers , metadata : metadataHandlers , navigation : navigationHandlers , } ; } caution quit ( ) { global . isQuitting = true ; todo this . detach__beforeQuit ( ) ; this . _workspaceService . closeWorkspace ( ) ; this . _fsal . close ( ) ; app . quit ( ) ; } load ( ) { if ( this . window ) { } console . log ( "app :: load" ) ; this . window = new Main ( "main" , this ) ; this . window . init ( ) ; this . _renderProxy = invokerFor < RendererIpcHandlers > ( this . window , IpcEvents . RENDERER_INVOKE , "main->render" ) ; } returns param fileExt param fileName getDefaultFileContents ( fileExt , fileName ) { todo todo if ( fileExt == ".md" || fileExt == ".txt" ) { let name = pathlib . basename ( fileName , fileExt ) ; return `# ${ name }` ; } else { return "" ; } } todo async handle < S extends MainIpcChannel , T extends FunctionPropertyNames < MainIpcHandlers [ S ] > > ( channel , name , todo data ? ) { remark return this . _eventHandlers [ channel ] [ name ] ( data as any ) ; } async handleFileTreeChanged ( fileTree ) { await this . _renderProxy ?. fileTreeChanged ( fileTree ) ; } async handleThemeChanged ( cssString ) { await this . _renderProxy ?. applyThemeCss ( cssString ) ; } attachEvents ( ) { this . attachWindowEvents ( ) ; todo this . _workspaceService . on ( WorkspaceEvent . FILETREE_CHANGED , this . handleFileTreeChanged ) ; this . _themeService . on ( ThemeEvent . THEME_CHANGED , this . handleThemeChanged ) ; } detachEvents ( ) { this . _workspaceService . off ( WorkspaceEvent . FILETREE_CHANGED , this . handleFileTreeChanged ) ; this . _themeService . off ( ThemeEvent . THEME_CHANGED , this . handleThemeChanged ) ; this . detachWindowEvents ( ) ; } todo attachWindowEvents ( ) { this . attach__windowAllClosed ( ) ; this . attach__activate ( ) ; this . attach__beforeQuit ( ) ; this . attach__forceQuit ( ) ; this . attach__ready ( ) ; this . attach__cwdChanged ( ) ; this . attach__updaterCheck ( ) ; } detachWindowEvents ( ) { } attach__windowAllClosed = ( ) => { app . on ( "window-all-closed" , this . __windowAllClosed ) ; } ; attach__activate = ( ) => { app . on ( "activate" , this . __activate ) ; } ; attach__beforeQuit = ( ) => { app . on ( "before-quit" , this . __beforeQuit ) ; } ; detach__beforeQuit = ( ) => { app . removeListener ( "before-quit" , this . __beforeQuit ) ; } ; attach__forceQuit = ( ) => { ipcMain . on ( "force-quit" , this . __forceQuit ) ; } ; attach__ready = ( ) => { app . on ( "ready" , this . __ready ) ; } ; attach__cwdChanged = ( ) => { ipcMain . on ( "cwd-changed" , this . __cwdChanged ) ; } ; attach__updaterCheck = ( ) => { ipcMain . on ( "updater-check" , this . __updaterCheck ) ; } ; __windowAllClosed = ( ) => { console . log ( "app :: __windowAllClosed" ) ; todo this . quit ( ) ; } ; __activate = ( ) => { console . log ( "app :: __activate" ) ; if ( this . window && this . window . window ) return ; this . load ( ) ; } ; __beforeQuit = ( ) => { console . log ( "app :: __beforeQuit" ) ; if ( ! this . window || ! this . window . window ) { return ; } this . window . window . webContents . send ( AppEvents . APP_QUIT ) ; } ; __forceQuit = ( ) => { console . log ( "app :: __forceQuit" ) ; this . quit ( ) ; } ; __ready = ( ) => { enforceMacOSAppLocation ( ) ; this . load ( ) ; } ; __cwdChanged = ( ) => { if ( this . window && this . window . window ) { this . window . window . once ( "closed" , this . load . bind ( this ) ) ; this . window . window . close ( ) ; } else { this . load ( ) ; } } ; __updaterCheck = ( ) => { } ; }