From 8429327f563078b65764dbfd3fd62dc1b534ce70 Mon Sep 17 00:00:00 2001 From: meriadec Date: Mon, 15 Jan 2018 18:36:17 +0100 Subject: [PATCH] Create UpdateNotifier and connect it to updates statuses --- src/components/UpdateNotifier.js | 36 ++++++++++++++++++++++++++ src/components/Wrapper.js | 4 +++ src/reducers/devices.js | 13 +++++----- src/reducers/index.js | 15 +++++++++++ src/reducers/modals.js | 9 ++++++- src/reducers/update.js | 44 ++++++++++++++++++++++++++++++++ src/renderer/initEvents.js | 25 +++++------------- 7 files changed, 121 insertions(+), 25 deletions(-) create mode 100644 src/components/UpdateNotifier.js create mode 100644 src/reducers/update.js diff --git a/src/components/UpdateNotifier.js b/src/components/UpdateNotifier.js new file mode 100644 index 00000000..30213719 --- /dev/null +++ b/src/components/UpdateNotifier.js @@ -0,0 +1,36 @@ +// @flow + +import React, { PureComponent } from 'react' +import { connect } from 'react-redux' +import type { MapStateToProps } from 'react-redux' +import styled from 'styled-components' + +import { getUpdateStatus } from 'reducers/update' +import type { State } from 'reducers' +import type { UpdateStatus } from 'reducers/update' + +type Props = { + updateStatus: UpdateStatus, +} + +const mapStateToProps: MapStateToProps<*, *, *> = (state: State) => ({ + updateStatus: getUpdateStatus(state), +}) + +const Container = styled.div` + position: fixed; + bottom: 0; + left: 0; + right: 0; + display: flex; + justify-content: center; +` + +class UpdateNotifier extends PureComponent { + render() { + const { updateStatus } = this.props + return {updateStatus} + } +} + +export default connect(mapStateToProps, null)(UpdateNotifier) diff --git a/src/components/Wrapper.js b/src/components/Wrapper.js index 533fd292..c417f2f5 100644 --- a/src/components/Wrapper.js +++ b/src/components/Wrapper.js @@ -11,6 +11,7 @@ import SettingsPage from 'components/SettingsPage' import AccountPage from 'components/AccountPage' import SendModal from 'components/SendModal' import ReceiveModal from 'components/ReceiveModal' +import UpdateNotifier from 'components/UpdateNotifier' import SideBar from 'components/SideBar' import TopBar from 'components/TopBar' @@ -24,8 +25,11 @@ const Wrapper = () => ( + + + ) diff --git a/src/reducers/devices.js b/src/reducers/devices.js index d74c0c17..97385d21 100644 --- a/src/reducers/devices.js +++ b/src/reducers/devices.js @@ -4,11 +4,12 @@ import { handleActions } from 'redux-actions' import type { Device, Devices } from 'types/common' -type stateType = { +export type DevicesState = { currentDevice: Device | null, devices: Devices, } -const state = { + +const state: DevicesState = { currentDevice: null, devices: [], } @@ -21,19 +22,19 @@ function setCurrentDevice(state) { } const handlers: Object = { - DEVICES_UPDATE: (state: stateType, { payload: devices }: { payload: Devices }) => + DEVICES_UPDATE: (state: DevicesState, { payload: devices }: { payload: Devices }) => setCurrentDevice({ ...state, devices, }), - DEVICE_ADD: (state: stateType, { payload: device }: { payload: Device }) => + DEVICE_ADD: (state: DevicesState, { payload: device }: { payload: Device }) => setCurrentDevice({ ...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 }) => ({ + DEVICE_REMOVE: (state: DevicesState, { payload: device }: { payload: Device }) => ({ ...state, currentDevice: state.currentDevice !== null && state.currentDevice.path === device.path @@ -41,7 +42,7 @@ const handlers: Object = { : state.currentDevice, devices: state.devices.filter(d => d.path !== device.path), }), - DEVICE_CHOOSE: (state: stateType, { payload: currentDevice }: { payload: Device }) => ({ + DEVICE_CHOOSE: (state: DevicesState, { payload: currentDevice }: { payload: Device }) => ({ ...state, currentDevice, }), diff --git a/src/reducers/index.js b/src/reducers/index.js index a7586fe4..30b572fc 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -3,11 +3,26 @@ import { combineReducers } from 'redux' import { routerReducer as router } from 'react-router-redux' +import type { LocationShape } from 'react-router' + import devices from './devices' import modals from './modals' +import update from './update' + +import type { DevicesState } from './devices' +import type { ModalsState } from './modals' +import type { UpdateState } from './update' + +export type State = { + router: LocationShape, + devices: DevicesState, + modals: ModalsState, + update: UpdateState, +} export default combineReducers({ router, devices, modals, + update, }) diff --git a/src/reducers/modals.js b/src/reducers/modals.js index a41e460f..271afee0 100644 --- a/src/reducers/modals.js +++ b/src/reducers/modals.js @@ -2,7 +2,14 @@ import { handleActions, createAction } from 'redux-actions' -const state = {} +export type ModalsState = { + [key: string]: { + isOpened: boolean, + data?: Object | null, + }, +} + +const state: ModalsState = {} type OpenPayload = { name: string, diff --git a/src/reducers/update.js b/src/reducers/update.js new file mode 100644 index 00000000..1e88e7f6 --- /dev/null +++ b/src/reducers/update.js @@ -0,0 +1,44 @@ +// @flow + +import { handleActions, createAction } from 'redux-actions' + +export type UpdateStatus = + | 'idle' + | 'checking' + | 'available' + | 'progress' + | 'unavailable' + | 'error' + | 'downloaded' + +export type UpdateState = { + status: UpdateStatus, + data?: Object, +} + +const state: UpdateState = { + status: 'idle', + data: {}, +} + +const handlers = { + UPDATE_SET_STATUS: (state: UpdateState, { payload }: { payload: UpdateState }): UpdateState => + payload, +} + +// Actions + +export const setUpdateStatus = createAction( + 'UPDATE_SET_STATUS', + (status: UpdateStatus, data?: Object): UpdateState => ({ status, data }), +) + +// Selectors + +export function getUpdateStatus(state: { update: UpdateState }): UpdateStatus { + return state.update.status +} + +// Default export + +export default handleActions(handlers, state) diff --git a/src/renderer/initEvents.js b/src/renderer/initEvents.js index 3fd19bd2..3deea3e6 100644 --- a/src/renderer/initEvents.js +++ b/src/renderer/initEvents.js @@ -4,6 +4,7 @@ import { ipcRenderer } from 'electron' // eslint-disable-line import/no-extraneo import objectPath from 'object-path' import { devicesUpdate, deviceAdd, deviceRemove } from 'actions/devices' +import { setUpdateStatus } from 'reducers/update' type MsgPayload = { type: string, @@ -48,24 +49,12 @@ export default (store: Object) => { }, }, updater: { - checking: () => { - console.log('[UPDATER] checking for updates') - }, - updateAvailable: info => { - console.log('[UPDATER] update available', info) - }, - updateNotAvailable: () => { - console.log('[UPDATER] no update available') - }, - error: err => { - console.log('[UPDATER] update error', err) - }, - downloadProgress: progress => { - console.log('[UPDATER] download in progress...', progress.percent) - }, - downloaded: () => { - console.log('[UPDATER] update downloaded') - }, + checking: () => store.dispatch(setUpdateStatus('checking')), + updateAvailable: info => store.dispatch(setUpdateStatus('available', info)), + updateNotAvailable: () => store.dispatch(setUpdateStatus('unavailable')), + error: err => store.dispatch(setUpdateStatus('error', err)), + downloadProgress: progress => store.dispatch(setUpdateStatus('progress', progress)), + downloaded: () => store.dispatch(setUpdateStatus('downloaded')), }, }