2018-03-07 14:28:48 +01:00
|
|
|
'use strict'
|
|
|
|
|
2018-03-12 17:00:19 +01:00
|
|
|
import { app, ipcMain, BrowserWindow, shell, Menu } from 'electron'
|
2018-03-08 15:08:33 +01:00
|
|
|
import Datastore from 'nedb'
|
|
|
|
import empty from 'is-empty'
|
|
|
|
|
2018-03-08 09:41:39 +01:00
|
|
|
import Authentication from './auth'
|
2018-03-09 09:08:27 +01:00
|
|
|
import Account from './account'
|
2018-03-12 08:42:05 +01:00
|
|
|
import Streaming from './streaming'
|
2018-03-07 14:28:48 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set `__static` path to static files in production
|
|
|
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
|
|
|
*/
|
|
|
|
if (process.env.NODE_ENV !== 'development') {
|
|
|
|
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
|
|
|
}
|
|
|
|
|
|
|
|
let mainWindow
|
|
|
|
const winURL = process.env.NODE_ENV === 'development'
|
|
|
|
? `http://localhost:9080`
|
|
|
|
: `file://${__dirname}/index.html`
|
|
|
|
|
2018-03-08 15:08:33 +01:00
|
|
|
let db = new Datastore({
|
|
|
|
filename: 'whalebird.db',
|
|
|
|
autoload: true
|
|
|
|
})
|
|
|
|
|
2018-03-21 04:22:45 +01:00
|
|
|
async function listAccounts () {
|
|
|
|
try {
|
|
|
|
const account = new Account(db)
|
|
|
|
const accounts = await account.listAccounts()
|
|
|
|
return accounts
|
|
|
|
} catch (err) {
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-07 14:28:48 +01:00
|
|
|
function createWindow () {
|
2018-03-12 17:00:19 +01:00
|
|
|
/**
|
2018-03-21 04:22:45 +01:00
|
|
|
* List accounts
|
2018-03-12 17:00:19 +01:00
|
|
|
*/
|
2018-03-21 04:22:45 +01:00
|
|
|
listAccounts()
|
|
|
|
.then((accounts) => {
|
|
|
|
const accountsChange = accounts.map((a, index) => {
|
|
|
|
return {
|
|
|
|
label: a.domain,
|
|
|
|
accelerator: `CmdOrCtrl+${index + 1}`,
|
2018-03-12 17:00:19 +01:00
|
|
|
click: () => {
|
2018-03-21 04:22:45 +01:00
|
|
|
mainWindow.webContents.send('change-account', Object.assign(a, { index: index }))
|
2018-03-12 17:00:19 +01:00
|
|
|
}
|
|
|
|
}
|
2018-03-21 04:22:45 +01:00
|
|
|
})
|
|
|
|
/**
|
|
|
|
* Set menu
|
|
|
|
*/
|
|
|
|
const template = [
|
2018-03-13 08:08:17 +01:00
|
|
|
{
|
2018-03-21 04:22:45 +01:00
|
|
|
label: 'Whalebird',
|
|
|
|
submenu: [
|
|
|
|
{
|
|
|
|
label: 'About Whalebird',
|
|
|
|
role: 'about'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'separator'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Quit',
|
|
|
|
accelerator: 'CmdOrCtrl+Q',
|
|
|
|
role: 'quit'
|
|
|
|
}
|
|
|
|
]
|
2018-03-13 08:08:17 +01:00
|
|
|
},
|
|
|
|
{
|
2018-03-21 04:22:45 +01:00
|
|
|
label: 'Toot',
|
|
|
|
submenu: [
|
|
|
|
{
|
|
|
|
label: 'New Toot',
|
|
|
|
accelerator: 'CmdOrCtrl+N',
|
|
|
|
click: () => {
|
|
|
|
mainWindow.webContents.send('CmdOrCtrl+N')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
2018-03-13 08:08:17 +01:00
|
|
|
},
|
|
|
|
{
|
2018-03-21 04:22:45 +01:00
|
|
|
label: 'Edit',
|
|
|
|
submenu: [
|
|
|
|
{
|
|
|
|
label: 'Undo',
|
|
|
|
accelerator: 'CmdOrCtrl+Z',
|
|
|
|
role: 'undo'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Redo',
|
|
|
|
accelerator: 'Shift+CmdOrCtrl+Z',
|
|
|
|
role: 'redo'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'separator'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Cut',
|
|
|
|
accelerator: 'CmdOrCtrl+X',
|
|
|
|
role: 'cut'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Copy',
|
|
|
|
accelerator: 'CmdOrCtrl+C',
|
|
|
|
role: 'copy'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Paste',
|
|
|
|
accelerator: 'CmdOrCtrl+V',
|
|
|
|
role: 'paste'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Select All',
|
|
|
|
accelerator: 'CmdOrCtrl+A',
|
|
|
|
role: 'selectall'
|
|
|
|
}
|
|
|
|
]
|
2018-03-13 08:08:17 +01:00
|
|
|
},
|
|
|
|
{
|
2018-03-21 04:22:45 +01:00
|
|
|
label: 'Window',
|
|
|
|
submenu: [
|
|
|
|
{
|
|
|
|
label: 'Close Window',
|
|
|
|
role: 'close'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Minimize',
|
|
|
|
role: 'minimize'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'separator'
|
|
|
|
}
|
|
|
|
].concat(accountsChange)
|
2018-03-21 07:24:07 +01:00
|
|
|
.concat([
|
|
|
|
{
|
|
|
|
type: 'separator'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Jump to',
|
|
|
|
accelerator: 'CmdOrCtrl+K',
|
|
|
|
click: () => {
|
|
|
|
mainWindow.webContents.send('CmdOrCtrl+K')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
])
|
2018-03-13 08:08:17 +01:00
|
|
|
}
|
|
|
|
]
|
2018-03-12 17:00:19 +01:00
|
|
|
|
2018-03-21 04:22:45 +01:00
|
|
|
const menu = Menu.buildFromTemplate(template)
|
|
|
|
Menu.setApplicationMenu(menu)
|
2018-03-12 17:00:19 +01:00
|
|
|
|
2018-03-21 04:22:45 +01:00
|
|
|
/**
|
|
|
|
* Initial window options
|
|
|
|
*/
|
|
|
|
mainWindow = new BrowserWindow({
|
|
|
|
height: 563,
|
|
|
|
useContentSize: true,
|
|
|
|
width: 1000
|
|
|
|
})
|
2018-03-07 14:28:48 +01:00
|
|
|
|
2018-03-21 04:22:45 +01:00
|
|
|
mainWindow.loadURL(winURL)
|
2018-03-07 14:28:48 +01:00
|
|
|
|
2018-03-21 04:22:45 +01:00
|
|
|
mainWindow.on('closed', () => {
|
|
|
|
mainWindow = null
|
|
|
|
})
|
|
|
|
})
|
2018-03-07 14:28:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
app.on('ready', createWindow)
|
|
|
|
|
|
|
|
app.on('window-all-closed', () => {
|
|
|
|
if (process.platform !== 'darwin') {
|
|
|
|
app.quit()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
app.on('activate', () => {
|
|
|
|
if (mainWindow === null) {
|
|
|
|
createWindow()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2018-03-08 15:08:33 +01:00
|
|
|
let auth = new Authentication(db)
|
2018-03-08 09:41:39 +01:00
|
|
|
|
2018-03-09 09:08:27 +01:00
|
|
|
ipcMain.on('get-auth-url', (event, domain) => {
|
2018-03-10 16:48:40 +01:00
|
|
|
auth.getAuthorizationUrl(domain)
|
2018-03-09 09:08:27 +01:00
|
|
|
.catch((err) => {
|
|
|
|
console.error(err)
|
|
|
|
event.sender.send('error-get-auth-url', err)
|
|
|
|
})
|
2018-03-08 09:41:39 +01:00
|
|
|
.then((url) => {
|
|
|
|
console.log(url)
|
2018-03-09 09:08:27 +01:00
|
|
|
event.sender.send('response-get-auth-url', url)
|
2018-03-10 15:28:55 +01:00
|
|
|
// Open authorize url in default browser.
|
2018-03-08 09:41:39 +01:00
|
|
|
shell.openExternal(url)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
ipcMain.on('get-access-token', (event, code) => {
|
|
|
|
auth.getAccessToken(code)
|
2018-03-09 09:08:27 +01:00
|
|
|
.catch((err) => {
|
|
|
|
console.error(err)
|
|
|
|
event.sender.send('error-get-access-token', err)
|
|
|
|
})
|
2018-03-08 16:24:18 +01:00
|
|
|
.then((token) => {
|
|
|
|
db.findOne({
|
|
|
|
accessToken: token
|
|
|
|
}, (err, doc) => {
|
2018-03-09 09:08:27 +01:00
|
|
|
if (err) return event.sender.send('error-get-access-token', err)
|
|
|
|
if (empty(doc)) return event.sender.send('error-get-access-token', 'error document is empty')
|
|
|
|
event.sender.send('response-get-access-token', doc._id)
|
2018-03-08 16:24:18 +01:00
|
|
|
})
|
|
|
|
})
|
2018-03-08 09:41:39 +01:00
|
|
|
})
|
|
|
|
|
2018-03-13 07:09:54 +01:00
|
|
|
// environments
|
2018-03-09 09:08:27 +01:00
|
|
|
ipcMain.on('get-social-token', (event, _) => {
|
2018-03-13 07:09:54 +01:00
|
|
|
const token = process.env.SOCIAL_TOKEN
|
|
|
|
if (empty(token)) {
|
|
|
|
return event.sender.send('error-get-social-token', new EmptyTokenError())
|
|
|
|
}
|
|
|
|
event.sender.send('response-get-social-token', token)
|
2018-03-08 10:36:09 +01:00
|
|
|
})
|
|
|
|
|
2018-03-09 09:08:27 +01:00
|
|
|
// nedb
|
2018-03-10 15:21:09 +01:00
|
|
|
ipcMain.on('list-accounts', (event, _) => {
|
2018-03-09 09:08:27 +01:00
|
|
|
const account = new Account(db)
|
2018-03-10 15:21:09 +01:00
|
|
|
account.listAccounts()
|
2018-03-08 15:08:33 +01:00
|
|
|
.catch((err) => {
|
|
|
|
console.error(err)
|
2018-03-10 15:21:09 +01:00
|
|
|
event.sender.send('error-list-accounts', err)
|
2018-03-08 15:08:33 +01:00
|
|
|
})
|
2018-03-10 15:21:09 +01:00
|
|
|
.then((accounts) => {
|
|
|
|
event.sender.send('response-list-accounts', accounts)
|
2018-03-08 15:08:33 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2018-03-09 09:36:57 +01:00
|
|
|
ipcMain.on('get-local-account', (event, id) => {
|
|
|
|
const account = new Account(db)
|
|
|
|
account.getAccount(id)
|
|
|
|
.catch((err) => {
|
|
|
|
event.sender.send('error-get-local-account', err)
|
|
|
|
})
|
2018-03-10 17:51:35 +01:00
|
|
|
.then((account) => {
|
|
|
|
event.sender.send('response-get-local-account', account)
|
2018-03-09 09:36:57 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2018-03-12 08:42:05 +01:00
|
|
|
// streaming
|
2018-03-12 08:47:27 +01:00
|
|
|
let userStreaming = null
|
|
|
|
|
2018-03-12 08:42:05 +01:00
|
|
|
ipcMain.on('start-user-streaming', (event, ac) => {
|
|
|
|
const account = new Account(db)
|
|
|
|
account.getAccount(ac._id)
|
|
|
|
.catch((err) => {
|
|
|
|
event.sender.send('error-start-user-streaming', err)
|
|
|
|
})
|
|
|
|
.then((account) => {
|
2018-03-12 15:30:55 +01:00
|
|
|
// Stop old user streaming
|
|
|
|
if (userStreaming !== null) {
|
|
|
|
userStreaming.stop()
|
|
|
|
userStreaming = null
|
|
|
|
}
|
|
|
|
|
2018-03-12 08:47:27 +01:00
|
|
|
userStreaming = new Streaming(account)
|
|
|
|
userStreaming.startUserStreaming(
|
2018-03-12 08:42:05 +01:00
|
|
|
(update) => {
|
|
|
|
event.sender.send('update-start-user-streaming', update)
|
|
|
|
},
|
|
|
|
(notification) => {
|
|
|
|
event.sender.send('notification-start-user-streaming', notification)
|
|
|
|
},
|
|
|
|
(err) => {
|
|
|
|
event.sender.send('error-start-user-streaming', err)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
2018-03-12 08:47:27 +01:00
|
|
|
|
|
|
|
ipcMain.on('stop-user-streaming', (event, _) => {
|
|
|
|
userStreaming.stop()
|
|
|
|
userStreaming = null
|
|
|
|
})
|
|
|
|
|
2018-03-14 04:24:54 +01:00
|
|
|
let localStreaming = null
|
|
|
|
|
|
|
|
ipcMain.on('start-local-streaming', (event, ac) => {
|
|
|
|
const account = new Account(db)
|
|
|
|
account.getAccount(ac._id)
|
|
|
|
.catch((err) => {
|
|
|
|
event.sender.send('error-start-local-streaming', err)
|
|
|
|
})
|
|
|
|
.then((account) => {
|
|
|
|
// Stop old local streaming
|
|
|
|
if (localStreaming !== null) {
|
|
|
|
localStreaming.stop()
|
|
|
|
localStreaming = null
|
|
|
|
}
|
|
|
|
|
|
|
|
localStreaming = new Streaming(account)
|
|
|
|
localStreaming.start(
|
|
|
|
'/streaming/public/local',
|
|
|
|
(update) => {
|
|
|
|
event.sender.send('update-start-local-streaming', update)
|
|
|
|
},
|
|
|
|
(err) => {
|
|
|
|
event.sender.send('error-start-local-streaming', err)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
ipcMain.on('stop-local-streaming', (event, _) => {
|
|
|
|
localStreaming.stop()
|
|
|
|
localStreaming = null
|
|
|
|
})
|
|
|
|
|
2018-03-14 06:54:20 +01:00
|
|
|
let publicStreaming = null
|
|
|
|
|
|
|
|
ipcMain.on('start-public-streaming', (event, ac) => {
|
|
|
|
const account = new Account(db)
|
|
|
|
account.getAccount(ac._id)
|
|
|
|
.catch((err) => {
|
|
|
|
event.sender.send('error-start-public-streaming', err)
|
|
|
|
})
|
|
|
|
.then((account) => {
|
|
|
|
// Stop old public streaming
|
|
|
|
if (publicStreaming !== null) {
|
|
|
|
publicStreaming.stop()
|
|
|
|
publicStreaming = null
|
|
|
|
}
|
|
|
|
|
|
|
|
publicStreaming = new Streaming(account)
|
|
|
|
publicStreaming.start(
|
|
|
|
'/streaming/public',
|
|
|
|
(update) => {
|
|
|
|
event.sender.send('update-start-public-streaming', update)
|
|
|
|
},
|
|
|
|
(err) => {
|
|
|
|
event.sender.send('error-start-public-streaming', err)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
ipcMain.on('stop-public-streaming', (event, _) => {
|
|
|
|
publicStreaming.stop()
|
|
|
|
publicStreaming = null
|
|
|
|
})
|
|
|
|
|
2018-03-07 14:28:48 +01:00
|
|
|
/**
|
|
|
|
* Auto Updater
|
|
|
|
*
|
|
|
|
* Uncomment the following code below and install `electron-updater` to
|
|
|
|
* support auto updating. Code Signing with a valid certificate is required.
|
|
|
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
import { autoUpdater } from 'electron-updater'
|
|
|
|
|
|
|
|
autoUpdater.on('update-downloaded', () => {
|
|
|
|
autoUpdater.quitAndInstall()
|
|
|
|
})
|
|
|
|
|
|
|
|
app.on('ready', () => {
|
|
|
|
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
|
|
|
|
})
|
|
|
|
*/
|
2018-03-13 07:09:54 +01:00
|
|
|
|
|
|
|
class EmptyTokenError {}
|