UNPKG

skypager-project-types-electron-app

Version:

skypager electron app project type

377 lines (305 loc) 8.8 kB
/** * @method appWillQuit * @method appIsQuitting * @method appIsDuplicate * @method prepareApplication * @method applicationWillLaunch * @method applicationDidLaunch * @method handlePanelMessage * @method secondInstanceWasLaunched * @method appDidQuit * @method prepareTray * @method userOpenedFiles * @method userSavedFiles */ import Helper from 'skypager-helper' import { Tray, dialog, Menu, protocol, BrowserWindow, app } from 'electron' import { join } from 'path' export class Application extends Helper { static attach(project) { return Helper.attach(project, Application, { registryProp: 'applications', lookupProp: 'application', registry: Helper.createContextRegistry('applications', { context: require.context('./applications', false, /\.js$/), dirname: __dirname, filename: __filename, }) }) } info(...args) { return this.project.info(...args) } debug(...args) { return this.project.debug(...args) } error(...args) { return this.project.error(...args) } initialize() { this.applyMixin(this.provider, this.context, this) this.lazy('defaultPanelOptions', () => this.tryResult('panelDefaults', {})) this.debug('Initializing Application with Panel Options', { panelOptions: this.defaultPanelOptions }) if (this.tryResult('launchImmediately') !== false) { if (app.isReady()) { this.debug('App is already ready. Launching.') this.launch() .then(() => { this.isLaunched = true this.isLaunching = false }) .catch((error) => { this.isLaunched = true this.isLaunching = false this.launchError = error }) } else { app.once('ready', () => this.launch().then(() => this.isLaunched = true).catch(error => { this.debug('App became ready. Launching.') this.isLaunched = true this.isLaunching = false this.launchError = error })) } } app.on('before-quit', this._beforeQuit.bind(this)) app.on('will-quit', this._willQuit.bind(this)) app.on('quit', this._onQuit.bind(this)) this.lazy('storage', () => { this.debug('Initializing storage') return require('../runtime/storage') }) this.hide('activePanels', {}) /* protocol.registerBufferProtocol('skypager', (request, callback) => { const { url, uploadData, method = 'GET', referrer = '' } = request callback({ mimeType: 'text/html', data: new Buffer(`Hi`) }) }) */ } _willQuit(event) { this.debug('App is quitting', event) if (this.appIsQuitting) { this.appIsQuitting(event) } } _beforeQuit(event) { this.debug('App will quit', event) if (this.appWillQuit) { this.appWillQuit(event) } } getPath(...args) { return app.getPath(...args) } get appPath() { return this.get('options.appPath', this.get('project.paths.output', app.getAppPath())) } setApplicationMenu(...args) { return this.Menu.setApplicationMenu(...args) } setAboutPanel(options = {}) { return this.app.setAboutPanelOptions({ applicationName: this.tryResult('appName', this.project.getEither('manifest.productName', 'manifest.appName', 'manifest.name')), applicationVersion: this.tryResult('appVersion', this.project.getEither('manifest.appVersion', 'manifest.version')), ...options, }) } async open(options = {}) { const result = await new Promise((resolve, reject) => { dialog.showOpenDialog(options, (files) => { resolve({ files, options }) }) }) if (this.userOpenedFiles) { await this.userOpenedFiles(result) } return result } async save(options = {}) { const result = await new Promise((resolve, reject) => { dialog.showSaveDialog(options, (file) => { resolve({ file, options }) }) }) if (this.userSavedFiles) { await this.userSavedFiles(result) } return result } get dock() { return this.get('app.dock', app.dock) } get tmpdir() { return this.getPath('temp') } get storagePath() { return join(this.userDataPath, 'storage') } get userDataPath() { return this.getPath('userData') } get userHomePath() { return this.getPath('home') } findPanelForWindow(windowId) { const browserWindow = this.get('browserWindows').find(b => b.windowId === windowId) if (browserWindow) { return browserWindow.getPanel() } } async askPanel(id, payload, ...args) { const response = this.panel(id).askPanel(payload, ...args) return response } async tellPanel(id, payload, ...args) { const response = this.panel(id).tellPanel(payload, ...args) return response } panel(id, options = {}) { const instanceId = options.instanceId || id if (!options.fresh && this.get(['activePanels', instanceId])) { return this.get(['activePanels', instanceId]) } const object = this.project.panel(id, { ...this.get('defaultPanelOptions', {}), ...this.get(`panelOptions.${id}`, {}), cacheHelper: !options.fresh, ...options, }, { appInstance: this }) this.set(['activePanels', instanceId], object) return object } get panelOptions() { return this.tryGet('panels', {}) } async launch() { this.debug('App launch') if (this.isSecondInstance) { this.debug('App launched as second instance') if (this.applicationIsDuplicate) { this.debug('applicationIsDuplicate hook being called') try { await this.applicationIsDuplicate() } catch(error) { this.app.quit(0) } } } if (this.isLaunched) { this.isLaunching = false return this } this.isLaunching = true this.debug('prepareSystem') try { await this.prepareSystem() } catch(error) { this.error('Error in prepareSystem', error) } this.debug('prepareApplication') if (this.prepareApplication) { try { await this.prepareApplication() this.debug('prepareApplication custom hook was called') } catch(error) { this.error('prepareApplication Error', error) } } this.debug('applicationWillLaunch') if (this.applicationWillLaunch) { try { await this.applicationWillLaunch() this.debug('applicationWillLaunch custom hook was called') } catch(error) { this.error('applicationWillLaunch', error) } } if (this.prepareTray) { try { this.debug('prepareTray') this.prepareTray() } catch(error) { this.error('prepareTray Error', error) } } if (this.applicationDidLaunch) { try { await this.applicationDidLaunch() this.debug('applicationDidLaunch custom hook was called') } catch(error) { this.error('applicationDidLaunch Error', error) } } this.isLaunching = false return this } async receivePanelMessage({channel, panel, payload} = {}) { if (this.handlePanelMessage) { return this.handlePanelMessage({channel, panel, payload}).then((r) => r) } return payload } async prepareSystem() { await this.prepareStorage() await this.prepareLogging() } async prepareLogging() { } async prepareStorage() { await this.project.mkdirpAsync(this.storagePath) } get app() { return app } get browserWindows() { return this.BrowserWindow.getAllWindows() } get BrowserWindow() { return this.tryGet('BrowserWindow', BrowserWindow) } get Menu() { return this.tryGet('Menu', Menu) } get dialog() { return this.tryGet('dialog', dialog) } get protocol() { return this.tryGet('protocol', protocol) } get Tray() { return this.tryGet('Tray', Tray) } get ipcStream() { return this.tryGet('ipcStream', require('./stream')) } get isSecondInstance() { return app.makeSingleInstance((commandLine, workingDirectory) => { this._secondInstance(commandLine, workingDirectory) }) } createTray(trayIcon) { return new Tray(trayIcon) } /** * Returns true if the application can only be a single instance */ get singleInstance() { return this.tryGet('singleInstance', false) } _secondInstance(...args) { if (this.secondInstanceWasLaunched) { return this.secondInstanceWasLaunched(...args) } } _onQuit(...args) { if (this.appDidQuit) { return this.appDidQuit(...args) } } } export default Application export const attach = Application.attach