From 566e9b35f74fd8d4fbcf2b9e3aebd7f86e0e105d Mon Sep 17 00:00:00 2001 From: Yuval Haspel Date: Thu, 30 May 2019 15:46:43 +0300 Subject: [PATCH] Desktop Notifications (#97) * desktop notification - initial commit * notification open on app hidden * notification click action: nav to local node page regardless of tab selected when app is closed * launch notification on app blurred * quit app on quit selection on close main window * code review changes * code review changes and merged with develop * code review changes * code review changes --- app/assets/icons/app_icon.png | Bin 0 -> 64445 bytes app/components/localNode/LeftPane.js | 3 +- app/components/localNode/LocalNodeLog.js | 9 ++--- app/infra/httpService/httpService.js | 5 ++- app/infra/notificationsService/index.js | 1 + .../notificationsService.js | 34 ++++++++++++++++++ app/redux/localNode/reducer.js | 3 +- app/screens/main/Main.js | 21 +++++++++-- app/vars/ipcConsts.js | 3 ++ desktop/eventListners.js | 10 ++++++ desktop/main.dev.js | 32 +++++++++++++---- 11 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 app/assets/icons/app_icon.png create mode 100644 app/infra/notificationsService/index.js create mode 100644 app/infra/notificationsService/notificationsService.js diff --git a/app/assets/icons/app_icon.png b/app/assets/icons/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f52c1a7aab473503e4417198cf254e1e7024f30e GIT binary patch literal 64445 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 { componentDidMount() { const { getLocalNodeSetupProgress } = this.props; this.checkInitStatus(); + getLocalNodeSetupProgress(); this.timer = setInterval(() => { getLocalNodeSetupProgress(); - }, 10000); + }, 30000); } componentDidUpdate() { diff --git a/app/components/localNode/LocalNodeLog.js b/app/components/localNode/LocalNodeLog.js index 0d157d985..e5c3e6540 100644 --- a/app/components/localNode/LocalNodeLog.js +++ b/app/components/localNode/LocalNodeLog.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import styled from 'styled-components'; import { smColors } from '/vars'; -// TODO: remove stab +// TODO: remove stub const getRandomNumber = (maxValue: number) => Math.floor(Math.random() * Math.floor(maxValue)); const getTimestamp = () => new Date().toUTCString(); const generateLogEntry = (i: number) => { @@ -56,6 +56,7 @@ const LogRow = styled.div` align-items: center; `; +// $FlowStyledIssue const LogEntry = styled.div` font-size: 16px; line-height: 30px; @@ -87,12 +88,12 @@ class LocalNodeLog extends Component<{}, { log: LogRecord[] }> { ); } - // TODO: remove stab + // TODO: remove stub componentDidMount() { this.generateLog(); } - // TODO: remove stab + // TODO: remove stub componentWillUnmount() { this.timer && clearInterval(this.timer); } @@ -104,7 +105,7 @@ class LocalNodeLog extends Component<{}, { log: LogRecord[] }> { )); - // TODO: remove stab + // TODO: remove stub generateLog = () => { let i = 0; this.timer = setInterval(() => { diff --git a/app/infra/httpService/httpService.js b/app/infra/httpService/httpService.js index e0fd2ff9e..89997cf94 100644 --- a/app/infra/httpService/httpService.js +++ b/app/infra/httpService/httpService.js @@ -29,7 +29,10 @@ class HttpService { ipcRenderer.send(ipcConsts.GET_INIT_PROGRESS); return new Promise((resolve: Function, reject: Function) => { ipcRenderer.once(ipcConsts.GET_INIT_PROGRESS_SUCCESS, (event, response) => { - resolve(response); + const timer = setTimeout(() => { + resolve(response); + clearTimeout(timer); + }, 10000); }); ipcRenderer.once(ipcConsts.GET_INIT_PROGRESS_FAILURE, (event, args) => { reject(args); diff --git a/app/infra/notificationsService/index.js b/app/infra/notificationsService/index.js new file mode 100644 index 000000000..61f3156db --- /dev/null +++ b/app/infra/notificationsService/index.js @@ -0,0 +1 @@ +export { default as notificationsService } from './notificationsService'; // eslint-disable-line import/prefer-default-export diff --git a/app/infra/notificationsService/notificationsService.js b/app/infra/notificationsService/notificationsService.js new file mode 100644 index 000000000..a09faba6c --- /dev/null +++ b/app/infra/notificationsService/notificationsService.js @@ -0,0 +1,34 @@ +import path from 'path'; +import { ipcRenderer } from 'electron'; +import { ipcConsts } from '/vars'; + +// @flow +class NotificationsService { + static notify = ({ title, notification, callback }: { title: string, notification: string, callback: () => void }) => { + NotificationsService.getNotificationAllowedStatus().then(({ isNotificationAllowed }: { isNotificationAllowed: boolean }) => { + if (isNotificationAllowed) { + const notificationOptions: any = { + body: notification, + icon: path.join(__dirname, '..', 'app', 'assets', 'icons', 'app_icon.png') + }; + const desktopNotification = new Notification(title || 'Alert', notificationOptions); + desktopNotification.onclick = () => { + ipcRenderer.send(ipcConsts.NOTIFICATION_CLICK); + callback && callback(); + }; + } + }); + }; + + static getNotificationAllowedStatus = async () => { + const isPermitted = await Notification.requestPermission(); + ipcRenderer.send(ipcConsts.CAN_NOTIFY); + return new Promise((resolve) => { + ipcRenderer.once(ipcConsts.CAN_NOTIFY_SUCCESS, (event, isInFocus) => { + resolve({ isNotificationAllowed: isPermitted && !isInFocus }); + }); + }); + }; +} + +export default NotificationsService; diff --git a/app/redux/localNode/reducer.js b/app/redux/localNode/reducer.js index 93d07d0de..df5edae0b 100644 --- a/app/redux/localNode/reducer.js +++ b/app/redux/localNode/reducer.js @@ -21,7 +21,8 @@ const initialState = { progress: null, totalEarnings: null, upcomingEarnings: null, - awardsAddress: null + awardsAddress: null, + pathToLocalNode: null }; const reducer = (state: any = initialState, action: Action) => { diff --git a/app/screens/main/Main.js b/app/screens/main/Main.js index a1e99737c..9cbad7da8 100644 --- a/app/screens/main/Main.js +++ b/app/screens/main/Main.js @@ -10,6 +10,9 @@ import type { SideMenuItem } from '/basicComponents'; import { menu1, menu2, menu3, menu4, menu5, menu6, menu7 } from '/assets/images'; import routes from '/routes'; import type { Account, Action } from '/types'; +import { notificationsService } from '/infra/notificationsService'; + +const completeValue = 80; // TODO: change to actual complete value const sideMenuItems: SideMenuItem[] = [ { @@ -73,7 +76,9 @@ type Props = { location: { pathname: string, hash: string }, accounts: Account[], resetNodeSettings: Action, - logout: Action + logout: Action, + // pathToLocalNode: string, + progress: number }; type State = { @@ -109,6 +114,17 @@ class Main extends Component { ); } + componentDidUpdate(prevProps: Props) { + const { progress, history } = this.props; + if (prevProps.progress !== progress && progress === completeValue) { + notificationsService.notify({ + title: 'Local Node', + notification: 'Your full node setup is complete! You are now participating in the Spacemesh network!', + callback: () => this.handleSideMenuPress({ index: 0 }) + }); + } + } + handleSideMenuPress = ({ index }: { index: number }) => { const { history, accounts, location } = this.props; const newPath: ?string = sideMenuItems[index].path; @@ -133,7 +149,8 @@ class Main extends Component { } const mapStateToProps = (state) => ({ - accounts: state.wallet.accounts + accounts: state.wallet.accounts, + progress: state.localNode.progress }); const mapDispatchToProps = { diff --git a/app/vars/ipcConsts.js b/app/vars/ipcConsts.js index 71e1491bc..39bb40258 100644 --- a/app/vars/ipcConsts.js +++ b/app/vars/ipcConsts.js @@ -28,6 +28,9 @@ const ipcConsts = { SET_NODE_IP: 'SET_NODE_IP', SET_NODE_IP_SUCCESS: 'SET_NODE_IP_SUCCESS', SET_NODE_IP_FAILURE: 'SET_NODE_IP_FAILURE', + CAN_NOTIFY: 'CAN_NOTIFY', + CAN_NOTIFY_SUCCESS: 'CAN_NOTIFY_SUCCESS', + NOTIFICATION_CLICK: 'NOTIFICATION_CLICK', // gRPC calls GET_BALANCE: 'GET_BALANCE', GET_BALANCE_SUCCESS: 'GET_BALANCE_SUCCESS', diff --git a/desktop/eventListners.js b/desktop/eventListners.js index 2840bbf39..bb169024a 100644 --- a/desktop/eventListners.js +++ b/desktop/eventListners.js @@ -84,6 +84,16 @@ const subscribeToEventListeners = ({ mainWindow }) => { ipcMain.on(ipcConsts.SET_NODE_IP, async (event, request) => { netService.setNodeIpAddress({ event, ...request }); }); + + ipcMain.on(ipcConsts.NOTIFICATION_CLICK, () => { + mainWindow.show(); + mainWindow.focus(); + }); + + ipcMain.on(ipcConsts.CAN_NOTIFY, (event) => { + const isInFocus = mainWindow.isFocused(); + event.sender.send(ipcConsts.CAN_NOTIFY_SUCCESS, isInFocus); + }); }; export { subscribeToEventListeners }; // eslint-disable-line import/prefer-default-export diff --git a/desktop/main.dev.js b/desktop/main.dev.js index 7e7a58770..af92de4fd 100644 --- a/desktop/main.dev.js +++ b/desktop/main.dev.js @@ -8,7 +8,7 @@ * When running `npm run build` or `npm run build-main`, this file is compiled to * `./desktop/main.prod.js` using webpack. This gives us some performance wins. */ -import { app, BrowserWindow } from 'electron'; +import { app, BrowserWindow, dialog } from 'electron'; import { autoUpdater } from 'electron-updater'; import log from 'electron-log'; import MenuBuilder from './menu'; @@ -41,9 +41,6 @@ const installExtensions = async () => { return Promise.all(extensions.map((name) => installer.default(installer[name], forceDownload))).catch(console.error); // eslint-disable-line no-console }; -// Add event listeners. -subscribeToEventListeners({ mainWindow }); - app.on('window-all-closed', () => { // Respect the OSX convention of having the application in memory even // after all windows have been closed @@ -64,6 +61,8 @@ const createWindow = () => { nodeIntegration: true } }); + // Add event listeners. + subscribeToEventListeners({ mainWindow }); }; app.on('ready', async () => { @@ -83,8 +82,26 @@ app.on('ready', async () => { mainWindow.focus(); }); - mainWindow.on('closed', () => { - mainWindow = null; + mainWindow.on('close', (event) => { + event.preventDefault(); + const options = { + title: 'Spacemesh', + message: 'Quit app or keep in background?', + buttons: ['Keep running in background', 'Quit'] + }; + dialog.showMessageBox(mainWindow, options, (response) => { + if (response === 0) { + mainWindow.hide(); + } + if (response === 1) { + mainWindow.destroy(); + mainWindow = null; + app.quit(); + } + if (process.platform !== 'darwin') { + app.dock.hide(); + } + }); }); const menuBuilder = new MenuBuilder(mainWindow); @@ -98,5 +115,8 @@ app.on('ready', async () => { app.on('activate', () => { if (mainWindow === null) { createWindow(); + } else if (mainWindow) { + mainWindow.show(); + mainWindow.focus(); } });