1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

Refactor main process and add exception handler for Socket server

This commit is contained in:
Dick Choi
2015-12-19 00:54:11 +09:00
parent be3c519a57
commit 16bcd86792
5 changed files with 275 additions and 116 deletions

View File

@@ -6,7 +6,7 @@ const app = electron.app
const ipcMain = electron.ipcMain const ipcMain = electron.ipcMain
const Tray = electron.Tray const Tray = electron.Tray
const path = require('path') const path = require('path')
const nodeIpc = require('node-ipc') const nodeIpc = require('@rokt33r/node-ipc')
var isFinderLoaded = false var isFinderLoaded = false
@@ -18,6 +18,13 @@ nodeIpc.connectTo(
'main', 'main',
path.join(app.getPath('userData'), 'boost.service'), path.join(app.getPath('userData'), 'boost.service'),
function () { function () {
nodeIpc.of.main.on(
'error',
function (err) {
nodeIpc.log('<< ## err ##'.rainbow, nodeIpc.config.delay)
nodeIpc.log(err)
}
)
nodeIpc.of.main.on( nodeIpc.of.main.on(
'connect', 'connect',
function () { function () {

View File

@@ -1,4 +1,5 @@
const electron = require('electron') const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow const BrowserWindow = electron.BrowserWindow
const path = require('path') const path = require('path')
@@ -20,4 +21,9 @@ mainWindow.webContents.on('new-window', function (e) {
e.preventDefault() e.preventDefault()
}) })
app.on('activate', function () {
if (mainWindow == null) return null
mainWindow.show()
})
module.exports = mainWindow module.exports = mainWindow

62
hotkey.js Normal file
View File

@@ -0,0 +1,62 @@
const electron = require('electron')
const app = electron.app
const Menu = electron.Menu
const ipc = electron.ipcMain
const globalShortcut = electron.globalShortcut
const jetpack = require('fs-jetpack')
const path = require('path')
const mainWindow = require('./atom-lib/main-window')
const nodeIpc = require('@rokt33r/node-ipc')
var userDataPath = app.getPath('userData')
if (!jetpack.cwd(userDataPath).exists('keymap.json')) {
jetpack.cwd(userDataPath).file('keymap.json', {content: '{}'})
}
try {
global.keymap = JSON.parse(jetpack.cwd(userDataPath).read('keymap.json', 'utf-8'))
} catch (err) {
jetpack.cwd(userDataPath).file('keymap.json', {content: '{}'})
global.keymap = {}
}
if (global.keymap.toggleFinder == null) global.keymap.toggleFinder = 'ctrl+tab+shift'
var toggleFinderKey = global.keymap.toggleFinder
try {
globalShortcut.register(toggleFinderKey, function () {
emitToFinder('open-finder')
mainWindow.webContents.send('open-finder', {})
})
} catch (err) {
console.log(err.name)
}
ipc.on('hotkeyUpdated', function (event, newKeymap) {
console.log('got new keymap')
console.log(newKeymap)
globalShortcut.unregisterAll()
global.keymap = newKeymap
jetpack.cwd(userDataPath).file('keymap.json', {content: JSON.stringify(global.keymap)})
var toggleFinderKey = global.keymap.toggleFinder != null ? global.keymap.toggleFinder : 'ctrl+tab+shift'
try {
globalShortcut.register(toggleFinderKey, function () {
emitToFinder('open-finder')
mainWindow.webContents.send('open-finder', {})
})
mainWindow.webContents.send('APP_SETTING_DONE', {})
} catch (err) {
console.error(err)
mainWindow.webContents.send('APP_SETTING_ERROR', {
message: 'Failed to apply hotkey: Invalid format'
})
}
})
function emitToFinder (type, data) {
var payload = {
type: type,
data: data
}
nodeIpc.server.broadcast('message', payload)
}

310
main.js
View File

@@ -2,22 +2,99 @@ const electron = require('electron')
const app = electron.app const app = electron.app
const Menu = electron.Menu const Menu = electron.Menu
const ipc = electron.ipcMain const ipc = electron.ipcMain
const globalShortcut = electron.globalShortcut
const autoUpdater = electron.autoUpdater const autoUpdater = electron.autoUpdater
const jetpack = require('fs-jetpack')
const path = require('path') const path = require('path')
const ChildProcess = require('child_process') const ChildProcess = require('child_process')
const _ = require('lodash') const _ = require('lodash')
// electron.crashReporter.start() // electron.crashReporter.start()
var mainWindow = null var mainWindow = null
var finderProcess var finderProcess = null
var finderWindow = null
var update = null var update = null
// app.on('window-all-closed', function () { // app.on('window-all-closed', function () {
// if (process.platform !== 'darwin') app.quit() // if (process.platform !== 'darwin') app.quit()
// }) // })
const appRootPath = path.join(process.execPath, '../..')
const updateDotExePath = path.join(appRootPath, 'Update.exe')
const exeName = path.basename(process.execPath)
function spawnUpdate (args, cb) {
var stdout = ''
var updateProcess = null
try {
updateProcess = ChildProcess.spawn(updateDotExePath, args)
} catch (e) {
process.nextTick(function () {
cb(e)
})
}
updateProcess.stdout.on('data', function (data) {
stdout += data
})
error = null
updateProcess.on('error', function (_error) {
error = _error
})
updateProcess.on('close', function (code, signal) {
if (code !== 0) {
error = new Error("Command failed: #{signal ? code}")
error.code = code
error.stdout = stdout
}
cb(error, stdout)
})
}
var handleStartupEvent = function () {
if (process.platform !== 'win32') {
return false
}
var squirrelCommand = process.argv[1];
switch (squirrelCommand) {
case '--squirrel-install':
spawnUpdate(['--createShortcut', exeName], function (err) {
quitApp()
})
return true
case '--squirrel-updated':
quitApp()
return true
case '--squirrel-uninstall':
spawnUpdate(['--removeShortcut', exeName], function (err) {
quitApp()
})
quitApp()
return true
case '--squirrel-obsolete':
quitApp()
return true
}
}
if (handleStartupEvent()) {
return
}
var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
return true
})
if (shouldQuit) {
app.quit()
return
}
var appQuit = false var appQuit = false
var version = app.getVersion() var version = app.getVersion()
@@ -33,46 +110,83 @@ function notify (title, body) {
} }
} }
autoUpdater var isUpdateReady = false
.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) { if (process.platform === 'darwin') {
update = quitAndUpdate autoUpdater.setFeedURL('https://orbital.b00st.io/rokt33r/boost-app/latest?version=' + version)
autoUpdater
.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
update = quitAndUpdate
if (mainWindow != null) {
notify('Ready to Update! ' + releaseName, 'Click update button on Main window.')
mainWindow.webContents.send('update-available', 'Update available!')
}
})
.on('error', function (err, message) {
console.error('error')
console.error(err)
if (!versionNotified) {
notify('Updater error!', message)
}
})
.on('update-available', function () {
notify('Update is available!', 'Download started.. wait for the update ready.')
})
.on('update-not-available', function () {
if (!versionNotified) {
versionNotified = true
notify('Latest Build!! ' + versionText, 'Hope you to enjoy our app :D')
}
})
} else if (process.platform === 'win32') {
var GhReleases = require('electron-gh-releases')
var ghReleasesOpts = {
repo: 'BoostIO/boost-releases',
currentVersion: app.getVersion()
}
const updater = new GhReleases(ghReleasesOpts)
// Check for updates
// `status` returns true if there is a new update available
function checkUpdate () {
updater.check((err, status) => {
if (err) {
console.error(err)
if (!versionNotified) notify('Updater error!', message)
}
if (!err) {
if (status) {
notify('Update is available!', 'Download started.. wait for the update ready.')
updater.download()
} else {
if (!versionNotified) {
versionNotified = true
notify('Latest Build!! ' + versionText, 'Hope you to enjoy our app :D')
}
}
}
})
}
updater.on('update-downloaded', (info) => {
if (mainWindow != null) { if (mainWindow != null) {
notify('Ready to Update! ' + releaseName, 'Click update button on Main window.') notify('Ready to Update! ' + releaseName, 'Click update button on Main window.')
mainWindow.webContents.send('update-available', 'Update available!') mainWindow.webContents.send('update-available', 'Update available!')
isUpdateReady = true
} }
}) })
.on('error', function (err, message) { }
console.error(err)
if (!versionNotified) {
notify('Updater error!', message)
}
})
// .on('checking-for-update', function () {
// // Connecting
// console.log('checking...')
// })
.on('update-available', function () {
notify('Update is available!', 'Download started.. wait for the update ready.')
})
.on('update-not-available', function () {
if (mainWindow != null && !versionNotified) {
versionNotified = true
notify('Latest Build!! ' + versionText, 'Hope you to enjoy our app :D')
}
})
const nodeIpc = require('@rokt33r/node-ipc')
const nodeIpc = require('node-ipc')
var isNodeIpcReady = false
nodeIpc.config.id = 'node' nodeIpc.config.id = 'node'
nodeIpc.config.retry = 1500 nodeIpc.config.retry = 1500
nodeIpc.config.silent = true // nodeIpc.config.silent = true
nodeIpc.serve( nodeIpc.serve(
path.join(app.getPath('userData'), 'boost.service'), path.join(app.getPath('userData'), 'boost.service'),
function(){ function () {
isNodeIpcReady = true
nodeIpc.server.on( nodeIpc.server.on(
'message', 'message',
function (data, socket) { function (data, socket) {
@@ -80,6 +194,12 @@ nodeIpc.serve(
format(data) format(data)
} }
) )
nodeIpc.server.on(
'error',
function (err) {
console.log('>>', err)
}
)
} }
) )
@@ -93,37 +213,61 @@ function format (payload) {
mainWindow.webContents.send('copy-finder') mainWindow.webContents.send('copy-finder')
break break
case 'quit-app': case 'quit-app':
appQuit = true quitApp()
app.quit()
break break
} }
} }
function quitApp () {
appQuit = true
if (finderProcess) finderProcess.kill()
app.quit()
}
app.on('ready', function () { app.on('ready', function () {
app.on('before-quit', function () { app.on('before-quit', function () {
if (finderProcess) finderProcess.kill() if (finderProcess) finderProcess.kill()
appQuit = true appQuit = true
}) })
autoUpdater.setFeedURL('https://orbital.b00st.io/rokt33r/boost-app/latest?version=' + version)
var template = require('./atom-lib/menu-template') var template = require('./atom-lib/menu-template')
var menu = Menu.buildFromTemplate(template) var menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu) Menu.setApplicationMenu(menu)
setInterval(function () { if (process.platform === 'darwin') {
if (update == null) autoUpdater.checkForUpdates() setInterval(function () {
}, 1000 * 60 * 60 * 24) if (update == null) autoUpdater.checkForUpdates()
}, 1000 * 60 * 60 * 24)
ipc.on('check-update', function (event, msg) { ipc.on('check-update', function (event, msg) {
if (update == null) autoUpdater.checkForUpdates() if (update == null) autoUpdater.checkForUpdates()
}) })
ipc.on('update-app', function (event, msg) { ipc.on('update-app', function (event, msg) {
if (update != null) { if (update != null) {
appQuit = true appQuit = true
update() update()
} }
}) })
autoUpdater.checkForUpdates()
} else if (process.platform === 'win32') {
setInterval(function () {
checkUpdate()
}, 1000 * 60 * 60 * 24)
ipc.on('check-update', function (event, msg) {
if (update == null) checkUpdate()
})
ipc.on('update-app', function (event, msg) {
if (isUpdateReady) {
appQuit = true
update.install()
}
})
checkUpdate()
}
mainWindow = require('./atom-lib/main-window') mainWindow = require('./atom-lib/main-window')
mainWindow.on('close', function (e) { mainWindow.on('close', function (e) {
@@ -132,25 +276,12 @@ app.on('ready', function () {
mainWindow.hide() mainWindow.hide()
}) })
function emitToFinder (type, data) {
if (!isNodeIpcReady) {
console.log('server is not ready')
}
var payload = {
type: type,
data: data
}
nodeIpc.server.broadcast('message', payload)
}
mainWindow.webContents.on('did-finish-load', function () { mainWindow.webContents.on('did-finish-load', function () {
if (finderProcess == null && process.platform === 'darwin') { if (finderProcess == null && process.platform === 'darwin') {
var finderArgv = [path.join(__dirname, 'finder.js'), '--finder'] var finderArgv = [path.join(__dirname, 'finder.js'), '--finder']
if (_.find(process.argv, a => a === '--hot')) finderArgv.push('--hot') if (_.find(process.argv, a => a === '--hot')) finderArgv.push('--hot')
finderProcess = ChildProcess finderProcess = ChildProcess
.execFile(process.execPath, finderArgv) .execFile(process.execPath, finderArgv)
nodeIpc.server.start()
} else { } else {
finderWindow = require('./atom-lib/finder-window') finderWindow = require('./atom-lib/finder-window')
@@ -159,63 +290,16 @@ app.on('ready', function () {
e.preventDefault() e.preventDefault()
finderWindow.hide() finderWindow.hide()
}) })
nodeIpc.server.start()
} }
if (update != null) { nodeIpc.server.start(function (err) {
mainWindow.webContents.send('update-available', 'whoooooooh!') if (err.code === 'EADDRINUSE') {
} else { notify('Error occurs!', 'You have to kill other Boostnote processes.')
autoUpdater.checkForUpdates() quitApp()
} }
})
app.on('activate', function () {
if (mainWindow == null) return null
mainWindow.show()
})
var userDataPath = app.getPath('userData')
if (!jetpack.cwd(userDataPath).exists('keymap.json')) {
jetpack.cwd(userDataPath).file('keymap.json', {content: '{}'})
}
try {
global.keymap = JSON.parse(jetpack.cwd(userDataPath).read('keymap.json', 'utf-8'))
} catch (err) {
jetpack.cwd(userDataPath).file('keymap.json', {content: '{}'})
global.keymap = {}
}
if (global.keymap.toggleFinder == null) global.keymap.toggleFinder = 'ctrl+tab+shift'
var toggleFinderKey = global.keymap.toggleFinder
try {
globalShortcut.register(toggleFinderKey, function () {
emitToFinder('open-finder')
mainWindow.webContents.send('open-finder', {})
}) })
} catch (err) {
console.log(err.name)
}
ipc.on('hotkeyUpdated', function (event, newKeymap) {
console.log('got new keymap')
console.log(newKeymap)
globalShortcut.unregisterAll()
global.keymap = newKeymap
jetpack.cwd(userDataPath).file('keymap.json', {content: JSON.stringify(global.keymap)})
var toggleFinderKey = global.keymap.toggleFinder != null ? global.keymap.toggleFinder : 'ctrl+tab+shift'
try {
globalShortcut.register(toggleFinderKey, function () {
emitToFinder('open-finder')
mainWindow.webContents.send('open-finder', {})
})
mainWindow.webContents.send('APP_SETTING_DONE', {})
} catch (err) {
console.error(err)
mainWindow.webContents.send('APP_SETTING_ERROR', {
message: 'Failed to apply hotkey: Invalid format'
})
}
}) })
require('./hotkey')
}) })

View File

@@ -34,13 +34,14 @@
"short code" "short code"
], ],
"author": "Dick Choi <fluke8259@gmail.com> (http://kazup.co)", "author": "Dick Choi <fluke8259@gmail.com> (http://kazup.co)",
"license": "No License",
"bugs": { "bugs": {
"url": "https://github.com/Rokt33r/codexen-app/issues" "url": "https://github.com/Rokt33r/codexen-app/issues"
}, },
"homepage": "https://github.com/Rokt33r/codexen-app#readme", "homepage": "https://github.com/Rokt33r/codexen-app#readme",
"dependencies": { "dependencies": {
"@rokt33r/node-ipc": "^5.0.4",
"devicon": "^2.0.0", "devicon": "^2.0.0",
"electron-gh-releases": "^2.0.2",
"font-awesome": "^4.3.0", "font-awesome": "^4.3.0",
"fs-jetpack": "^0.7.0", "fs-jetpack": "^0.7.0",
"highlight.js": "^8.9.1", "highlight.js": "^8.9.1",
@@ -49,7 +50,6 @@
"markdown-it-emoji": "^1.1.0", "markdown-it-emoji": "^1.1.0",
"md5": "^2.0.0", "md5": "^2.0.0",
"moment": "^2.10.3", "moment": "^2.10.3",
"node-ipc": "^5.0.0",
"socket.io-client": "^1.3.6", "socket.io-client": "^1.3.6",
"superagent": "^1.2.0", "superagent": "^1.2.0",
"superagent-promise": "^1.0.3" "superagent-promise": "^1.0.3"