From 346c5d7c9b510e1cefd214108b454c364a72e244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Tue, 9 Jan 2018 13:39:46 +0100 Subject: [PATCH] Add reducer for devices list --- package.json | 13 +++++----- src/actions/devices.js | 19 ++++++++++++++ src/components/Home.js | 56 +++++++++++++++++++++++++---------------- src/main/app.js | 2 +- src/main/ledger.js | 24 +++++++++--------- src/reducers/devices.js | 14 +++++++++++ src/reducers/index.js | 3 +++ yarn.lock | 21 ++++++++++++++-- 8 files changed, 110 insertions(+), 42 deletions(-) create mode 100644 src/actions/devices.js create mode 100644 src/reducers/devices.js diff --git a/package.json b/package.json index cfbb7a8a..48d0079a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dist": "yarn compile && electron-builder", "dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null", "prettier": "prettier --write \"src/**/*.js\"", - "postinstall": "flow-typed install -s", + "postinstall": "electron-rebuild && flow-typed install -s", "flow": "flow", "lint": "eslint src" }, @@ -26,19 +26,20 @@ } }, "dependencies": { - "electron-devtools-installer": "^2.2.3", "electron": "1.7.9", + "electron-devtools-installer": "^2.2.3", "history": "^4.7.2", - "ledger-node-js-hid": "github:loeck/ledger-node-js-hid", + "ledger-node-js-hid": "github:loeck/ledger-node-js-hid#master", "ledgerco": "^1.2.1", + "react": "^16.2.0", "react-dom": "^16.2.0", "react-redux": "^5.0.6", + "react-router": "^4.2.0", "react-router-dom": "^4.2.2", "react-router-redux": "5.0.0-alpha.9", - "react-router": "^4.2.0", - "react": "^16.2.0", - "redux-thunk": "^2.2.0", "redux": "^3.7.2", + "redux-actions": "^2.2.1", + "redux-thunk": "^2.2.0", "source-map-support": "^0.5.0", "styled-components": "^2.2.4", "styled-system": "^1.1.1", diff --git a/src/actions/devices.js b/src/actions/devices.js new file mode 100644 index 00000000..9824ccdc --- /dev/null +++ b/src/actions/devices.js @@ -0,0 +1,19 @@ +// eslint-disable import/prefer-default-export + +export const devicesUpdate = payload => dispatch => + dispatch({ + type: 'DEVICES_UPDATE', + payload, + }) + +export const deviceAdd = payload => dispatch => + dispatch({ + type: 'DEVICE_ADD', + payload, + }) + +export const deviceRemove = payload => dispatch => + dispatch({ + type: 'DEVICE_REMOVE', + payload, + }) diff --git a/src/components/Home.js b/src/components/Home.js index a6b0577b..b51edb8c 100644 --- a/src/components/Home.js +++ b/src/components/Home.js @@ -1,34 +1,48 @@ -import React, { Component } from 'react' +// @flow + +import React, { PureComponent } from 'react' +import { connect } from 'react-redux' import { ipcRenderer } from 'electron' -class App extends Component { - state = { - devices: [], - } +import { devicesUpdate, deviceAdd, deviceRemove } from 'actions/devices' + +type Props = { + devicesUpdate: (devices: Object) => void, + deviceAdd: (device: Object) => void, + deviceRemove: (device: Object) => void, + devices: Object, +} - componentDidMount() { +class Home extends PureComponent { + componentWillMount() { + const { devicesUpdate, deviceAdd, deviceRemove } = this.props + + ipcRenderer.on('updateDevices', (e, devices) => devicesUpdate(devices)) + ipcRenderer.on('addDevice', (e, device) => deviceAdd(device)) + ipcRenderer.on('removeDevice', (e, device) => deviceRemove(device)) + + // First renderer, we get all devices + ipcRenderer.send('getDevices') + + // Start detection when we plug/unplug devices ipcRenderer.send('listenDevices') + } - ipcRenderer.on('addDevice', (e, device) => - this.setState(prev => ({ - devices: [...prev.devices, device].filter( - (v, i, s) => s.findIndex(t => t.path === v.path) === i, - ), - })), - ) - - ipcRenderer.on('removeDevice', (e, device) => - this.setState(prev => ({ - devices: prev.devices.filter(d => d.path !== device.path), - })), - ) + componentWillUnmount() { + ipcRenderer.removeAllListeners('updateDevices') + ipcRenderer.removeAllListeners('addDevice') + ipcRenderer.removeAllListeners('removeDevice') } render() { - const { devices } = this.state + const { devices } = this.props return
{devices.map(device => device.path)}
} } -export default App +export default connect(({ devices }) => ({ devices }), { + deviceAdd, + deviceRemove, + devicesUpdate, +})(Home) diff --git a/src/main/app.js b/src/main/app.js index 138765ea..3a8e84e8 100644 --- a/src/main/app.js +++ b/src/main/app.js @@ -1,6 +1,6 @@ // @flow -import { app, BrowserWindow } from 'electron' // eslint-disable-line import/no-extraneous-dependencies +import { app, BrowserWindow } from 'electron' // Global reference to mainWindow // Necessary to prevent win from being garbage collected diff --git a/src/main/ledger.js b/src/main/ledger.js index 4a3b9dfa..300c8853 100644 --- a/src/main/ledger.js +++ b/src/main/ledger.js @@ -6,17 +6,17 @@ import HID from 'ledger-node-js-hid' ipcMain.on('listenDevices', event => { HID.listenDevices.start() - HID.listenDevices.events.on('add', device => { - console.log('add', device, isLedgerDevice(device)) - if (isLedgerDevice(device)) { - event.sender.send('addDevice', device) - } - }) + HID.listenDevices.events.on( + 'add', + device => isLedgerDevice(device) && event.sender.send('addDevice', device), + ) - HID.listenDevices.events.on('remove', device => { - console.log('remove', device, isLedgerDevice(device)) - if (isLedgerDevice(device)) { - event.sender.send('removeDevice', device) - } - }) + HID.listenDevices.events.on( + 'remove', + device => isLedgerDevice(device) && event.sender.send('removeDevice', device), + ) }) + +ipcMain.on('getDevices', event => + event.sender.send('updateDevices', HID.devices().filter(isLedgerDevice)), +) diff --git a/src/reducers/devices.js b/src/reducers/devices.js new file mode 100644 index 00000000..817a21f3 --- /dev/null +++ b/src/reducers/devices.js @@ -0,0 +1,14 @@ +// @flow + +import { handleActions } from 'redux-actions' + +const state = [] + +const handlers = { + DEVICES_UPDATE: (state, { payload: devices }) => devices, + DEVICE_ADD: (state, { payload: device }) => + [...state, device].filter((v, i, s) => s.findIndex(t => t.path === v.path) === i), + DEVICE_REMOVE: (state, { payload: device }) => state.filter(d => d.path !== device.path), +} + +export default handleActions(handlers, state) diff --git a/src/reducers/index.js b/src/reducers/index.js index 201da084..c3063211 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -3,6 +3,9 @@ import { combineReducers } from 'redux' import { routerReducer as router } from 'react-router-redux' +import devices from './devices' + export default combineReducers({ router, + devices, }) diff --git a/yarn.lock b/yarn.lock index 070eac96..750d791d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4140,6 +4140,10 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +"ledger-node-js-hid@github:loeck/ledger-node-js-hid#master": + version "" + resolved "git+ssh://git@github.com/loeck/ledger-node-js-hid.git#e345337a26b417028e7c5514634a98cd98f499ad" + ledgerco@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ledgerco/-/ledgerco-1.2.1.tgz#a1fdefd7aaf5a8857bf9b47887f5465bdcdf0602" @@ -4201,7 +4205,7 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash-es@^4.2.0, lodash-es@^4.2.1: +lodash-es@^4.17.4, lodash-es@^4.2.0, lodash-es@^4.2.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" @@ -4233,7 +4237,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0: +lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -5695,6 +5699,19 @@ reduce-function-call@^1.0.1: dependencies: balanced-match "^0.4.2" +reduce-reducers@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.1.2.tgz#fa1b4718bc5292a71ddd1e5d839c9bea9770f14b" + +redux-actions@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/redux-actions/-/redux-actions-2.2.1.tgz#d64186b25649a13c05478547d7cd7537b892410d" + dependencies: + invariant "^2.2.1" + lodash "^4.13.1" + lodash-es "^4.17.4" + reduce-reducers "^0.1.0" + redux-thunk@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5"