Browse Source

Add currentDevice in reducer devices

master
Loëck Vézien 7 years ago
parent
commit
797ceac6ba
No known key found for this signature in database GPG Key ID: CBCDCE384E853AC4
  1. 65
      src/actions/devices.js
  2. 16
      src/components/Home.js
  3. 31
      src/components/Wrapper.js
  4. 2
      src/i18n/en/translation.yml
  5. 2
      src/main/app.js
  6. 18
      src/main/ledger.js
  7. 43
      src/reducers/devices.js
  8. 5
      src/renderer/i18n.js
  9. 16
      src/renderer/initEvents.js
  10. 5
      src/types/common.js

65
src/actions/devices.js

@ -2,22 +2,59 @@
// eslint-disable import/prefer-default-export
import type { Device } from 'types/common'
import type { Dispatch } from 'redux'
type devicesUpdateType = (Array<Device>) => { type: string, payload: Array<Device> }
export const devicesUpdate: devicesUpdateType = payload => ({
type: 'DEVICES_UPDATE',
payload,
})
import { getDevices } from 'reducers/devices'
type devicesAddType = Device => { type: string, payload: Device }
export const deviceAdd: devicesAddType = payload => ({
type: 'DEVICE_ADD',
payload,
})
import type { Device, Devices } from 'types/common'
type devicesRemoveType = Device => { type: string, payload: Device }
export const deviceRemove: devicesRemoveType = payload => ({
type: 'DEVICE_REMOVE',
type deviceChooseType = (?Device) => { type: string, payload: ?Device }
export const deviceChoose: deviceChooseType = payload => ({
type: 'DEVICE_CHOOSE',
payload,
})
type deviceChooseFirstType = () => (Dispatch<any>, () => { devices: Devices }) => void
export const deviceChooseFirst: deviceChooseFirstType = () => (dispatch, getState) => {
const devices = getDevices(getState())
// If we detect only 1 device, we choose it
if (devices.length === 1) {
dispatch(deviceChoose(devices[0]))
}
}
type devicesAddType = Device => (Dispatch<any>) => void
export const deviceAdd: devicesAddType = payload => dispatch => {
dispatch({
type: 'DEVICE_ADD',
payload,
})
dispatch(deviceChooseFirst())
}
type devicesRemoveType = Device => (Dispatch<any>, () => { devices: Devices }) => void
export const deviceRemove: devicesRemoveType = payload => (dispatch, getState) => {
dispatch({
type: 'DEVICE_REMOVE',
payload,
})
const devices = getDevices(getState())
// If we don't detect any device we reset currentDevice
if (devices.length === 0) {
dispatch(deviceChoose(null))
}
}
type devicesUpdateType = Devices => (Dispatch<any>) => void
export const devicesUpdate: devicesUpdateType = payload => dispatch => {
dispatch({
type: 'DEVICES_UPDATE',
payload,
})
dispatch(deviceChooseFirst())
}

16
src/components/Home.js

@ -5,16 +5,26 @@ import { compose } from 'redux'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import type { MapStateToProps } from 'react-redux'
import type { Devices, T } from 'types/common'
import { getDevices } from 'reducers/devices'
type Props = {
devices: Array<Object>,
t: (string, ?Object) => string,
devices: Devices,
t: T,
}
const mapStateToProps: MapStateToProps<*, *, *> = state => ({
devices: getDevices(state),
})
class Home extends PureComponent<Props> {
render() {
const { devices, t } = this.props
return <div>{t('common.connectedDevices', { count: devices.length })}</div>
}
}
export default compose(connect(({ devices }: Props): Object => ({ devices })), translate())(Home)
export default compose(connect(mapStateToProps), translate())(Home)

31
src/components/Wrapper.js

@ -1,34 +1,23 @@
// @flow
import React, { Fragment } from 'react'
import { compose } from 'redux'
import { connect } from 'react-redux'
import React from 'react'
import { Route } from 'react-router'
import { translate } from 'react-i18next'
import Box from 'components/base/Box'
import Overlay from 'components/base/Overlay'
import Home from 'components/Home'
import SideBar from 'components/SideBar'
import TopBar from 'components/TopBar'
const Wrapper = ({ devices, t }: { devices: Array<Object>, t: string => string }) => (
<Fragment>
{devices.length === 0 ? (
<Overlay align="center" justify="center">
<Box color="white">{t('common.connectDevice')}</Box>
</Overlay>
) : (
<Box grow horizontal>
<SideBar />
<Box grow bg="cream">
<TopBar />
<Route path="/" component={Home} />
</Box>
</Box>
)}
</Fragment>
const Wrapper = () => (
<Box grow horizontal>
<SideBar />
<Box grow bg="cream">
<TopBar />
<Route path="/" component={Home} />
</Box>
</Box>
)
export default compose(connect(({ devices }): Object => ({ devices })), translate())(Wrapper)
export default translate()(Wrapper)

2
src/i18n/en/translation.yml

@ -1,6 +1,6 @@
common:
ok: Okay
cancel: Cancel
connectDevice: Please connect your device
connectedDevices: You have {{count}} device connected
connectedDevices_0: You don't have device connected
connectedDevices_plural: You have {{count}} devices connected

2
src/main/app.js

@ -35,7 +35,7 @@ function createMainWindow() {
return window
}
// dsq
// Quit application when all windows are closed
app.on('window-all-closed', () => {
// On macOS it is common for applications to stay open

18
src/main/ledger.js

@ -41,13 +41,17 @@ const handlers = {
},
all: send => send('devices.update', HID.devices().filter(isLedgerDevice)),
},
requestWalletInfos: async (send, { path, wallet }) => {
try {
const publicKey = await getWalletInfos(path, wallet)
send('receiveWalletInfos', { path, publicKey })
} catch (err) {
send('failWalletInfos', { path, err: err.stack })
}
wallet: {
infos: {
request: async (send, { path, wallet }) => {
try {
const publicKey = await getWalletInfos(path, wallet)
send('wallet.infos.success', { path, publicKey })
} catch (err) {
send('wallet.infos.fail', { path, err: err.stack || err })
}
},
},
},
}

43
src/reducers/devices.js

@ -2,13 +2,44 @@
import { handleActions } from 'redux-actions'
const state = []
import type { Device, Devices } from 'types/common'
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),
type stateType = {
currentDevice: ?Device,
devices: Devices,
}
const state = {
currentDevice: null,
devices: [],
}
const handlers: Object = {
DEVICES_UPDATE: (state: stateType, { payload: devices }: { payload: Devices }) => ({
...state,
devices,
}),
DEVICE_ADD: (state: stateType, { payload: device }: { payload: Device }) => ({
...state,
devices: [...state.devices, device].filter(
(v, i, s) => s.findIndex(t => t.path === v.path) === i,
),
}),
DEVICE_REMOVE: (state: stateType, { payload: device }: { payload: Device }) => ({
...state,
devices: state.devices.filter(d => d.path !== device.path),
}),
DEVICE_CHOOSE: (state: stateType, { payload: currentDevice }: { payload: Device }) => ({
...state,
currentDevice,
}),
}
export function getCurrentDevice(state: Object) {
return state.devices.currentDevice
}
export function getDevices(state: Object) {
return state.devices.devices
}
export default handleActions(handlers, state)

5
src/renderer/i18n.js

@ -16,4 +16,9 @@ i18n.use(Backend).init({
},
})
i18n.services.pluralResolver.addRule('en', {
numbers: [0, 1, 'plural'],
plurals: n => Number(n >= 2 ? 2 : n),
})
export default i18n

16
src/renderer/initEvents.js

@ -23,7 +23,7 @@ export default (store: Object) => {
update: devices => {
store.dispatch(devicesUpdate(devices))
if (devices.length) {
send('requestWalletInfos', {
send('wallet.infos.request', {
path: devices[0].path,
wallet: 'btc',
})
@ -34,11 +34,15 @@ export default (store: Object) => {
add: device => store.dispatch(deviceAdd(device)),
remove: device => store.dispatch(deviceRemove(device)),
},
receiveWalletInfos: ({ path, publicKey }) => {
console.log({ path, publicKey })
},
failWalletInfos: ({ path, err }) => {
console.log({ path, err })
wallet: {
infos: {
success: ({ path, publicKey }) => {
console.log({ path, publicKey })
},
fail: ({ path, err }) => {
console.log({ path, err })
},
},
},
}

5
src/types/common.js

@ -3,4 +3,9 @@
export type Device = {
vendorId: string,
productId: string,
path: string,
}
export type Devices = Array<Device>
export type T = (string, ?Object) => string

Loading…
Cancel
Save