From 5adf9d7c716a47e403b75ae99a3eec66e47b83ab Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 15:06:03 +0200 Subject: [PATCH 01/12] Fix empty state text for add account --- src/components/modals/AddAccounts/steps/03-step-import.js | 2 +- static/i18n/en/app.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/modals/AddAccounts/steps/03-step-import.js b/src/components/modals/AddAccounts/steps/03-step-import.js index 4573e6a8..e148a7ab 100644 --- a/src/components/modals/AddAccounts/steps/03-step-import.js +++ b/src/components/modals/AddAccounts/steps/03-step-import.js @@ -161,7 +161,7 @@ class StepImport extends PureComponent { }) const importableAccountsEmpty = t('app:addAccounts.noAccountToImport', { - currencyName: currency ? ` ${currency.name}}` : '', + currencyName: currency ? ` ${currency.name}` : '', }) return ( diff --git a/static/i18n/en/app.yml b/static/i18n/en/app.yml index 293005ae..f45ddfe1 100644 --- a/static/i18n/en/app.yml +++ b/static/i18n/en/app.yml @@ -138,7 +138,7 @@ addAccounts: editName: Edit name newAccount: New account legacyAccount: '{{accountName}} (legacy)' - noAccountToImport: We didnt find any {{currencyName}}} account to import. + noAccountToImport: We didnt find any {{currencyName}} account to import. success: Great success! createNewAccount: title: Create new account From 28feb3ead2b3a02bb95eb23faa8e499aef8f4a9a Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 15:10:03 +0200 Subject: [PATCH 02/12] Hide top bar vertical bar when no accounts --- src/components/TopBar/ActivityIndicator.js | 55 +++++++++------------- src/components/TopBar/index.js | 17 +++++-- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/components/TopBar/ActivityIndicator.js b/src/components/TopBar/ActivityIndicator.js index a2c9ff31..fb7b1e58 100644 --- a/src/components/TopBar/ActivityIndicator.js +++ b/src/components/TopBar/ActivityIndicator.js @@ -10,7 +10,6 @@ import type { T } from 'types/common' import type { AsyncState } from 'reducers/bridgeSync' import { globalSyncStateSelector } from 'reducers/bridgeSync' -import { hasAccountsSelector } from 'reducers/accounts' import { BridgeSyncConsumer } from 'bridge/BridgeSyncContext' import CounterValues from 'helpers/countervalues' @@ -23,7 +22,6 @@ import ItemContainer from './ItemContainer' const mapStateToProps = createStructuredSelector({ globalSyncState: globalSyncStateSelector, - hasAccounts: hasAccountsSelector, }) type Props = { @@ -128,37 +126,28 @@ class ActivityIndicatorInner extends PureComponent { } } -const ActivityIndicator = ({ - globalSyncState, - hasAccounts, - t, -}: { - globalSyncState: AsyncState, - hasAccounts: boolean, - t: T, -}) => - !hasAccounts ? null : ( - - {setSyncBehavior => ( - - {cvPolling => { - const isPending = cvPolling.pending || globalSyncState.pending - const isError = cvPolling.error || globalSyncState.error - return ( - - ) - }} - - )} - - ) +const ActivityIndicator = ({ globalSyncState, t }: { globalSyncState: AsyncState, t: T }) => ( + + {setSyncBehavior => ( + + {cvPolling => { + const isPending = cvPolling.pending || globalSyncState.pending + const isError = cvPolling.error || globalSyncState.error + return ( + + ) + }} + + )} + +) export default compose( translate(), diff --git a/src/components/TopBar/index.js b/src/components/TopBar/index.js index 11b4bd1c..13d88557 100644 --- a/src/components/TopBar/index.js +++ b/src/components/TopBar/index.js @@ -12,6 +12,7 @@ import type { T } from 'types/common' import { lock } from 'reducers/application' import { hasPassword } from 'reducers/settings' +import { hasAccountsSelector } from 'reducers/accounts' import { openModal } from 'reducers/modals' import IconLock from 'icons/Lock' @@ -54,6 +55,7 @@ const Bar = styled.div` const mapStateToProps = state => ({ hasPassword: hasPassword(state), + hasAccounts: hasAccountsSelector(state), }) const mapDispatchToProps = { @@ -63,6 +65,7 @@ const mapDispatchToProps = { type Props = { hasPassword: boolean, + hasAccounts: boolean, history: RouterHistory, location: Location, lock: Function, @@ -91,17 +94,21 @@ class TopBar extends PureComponent { } } render() { - const { hasPassword, t } = this.props + const { hasPassword, hasAccounts, t } = this.props return ( - - - - + {hasAccounts && ( + + + + + + + )} t('app:settings.title')}> From 01a913aadee4384e07c4817bb95588fa8bd3d13d Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 15:42:15 +0200 Subject: [PATCH 03/12] Adjust the Selects empty option texts --- src/components/SelectAccount/index.js | 3 +++ src/components/SelectCurrency/index.js | 3 +++ src/components/SelectExchange.js | 4 ++++ src/components/SettingsPage/sections/Display.js | 2 +- static/i18n/en/app.yml | 4 ++++ 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/components/SelectAccount/index.js b/src/components/SelectAccount/index.js index 3c1fe001..7e683cd9 100644 --- a/src/components/SelectAccount/index.js +++ b/src/components/SelectAccount/index.js @@ -69,6 +69,9 @@ const RawSelectAccount = ({ accounts, onChange, value, t, ...props }: Props) => renderValue={renderOption} renderOption={renderOption} placeholder={t('app:common.selectAccount')} + noOptionsMessage={({ inputValue }) => + t('app:common.selectAccountNoOption', { accountName: inputValue }) + } onChange={onChange} /> ) diff --git a/src/components/SelectCurrency/index.js b/src/components/SelectCurrency/index.js index 3d23dd91..6c7d9a54 100644 --- a/src/components/SelectCurrency/index.js +++ b/src/components/SelectCurrency/index.js @@ -40,6 +40,9 @@ const SelectCurrency = ({ onChange, value, t, placeholder, currencies, ...props renderValue={renderOption} options={options} placeholder={placeholder || t('app:common.selectCurrency')} + noOptionsMessage={({ inputValue }: { inputValue: string }) => + t('app:common.selectCurrencyNoOption', { currencyName: inputValue }) + } onChange={item => onChange(item ? item.currency : null)} {...props} /> diff --git a/src/components/SelectExchange.js b/src/components/SelectExchange.js index 168d509e..93c76db9 100644 --- a/src/components/SelectExchange.js +++ b/src/components/SelectExchange.js @@ -93,6 +93,10 @@ class SelectExchange extends Component< options={options} onChange={onChange} isLoading={options.length === 0} + placeholder={t('app:common.selectExchange')} + noOptionsMessage={({ inputValue }) => + t('app:common.selectExchangeNoOption', { exchangeName: inputValue }) + } {...props} /> ) diff --git a/src/components/SettingsPage/sections/Display.js b/src/components/SettingsPage/sections/Display.js index 1b3bd457..0a19b62a 100644 --- a/src/components/SettingsPage/sections/Display.js +++ b/src/components/SettingsPage/sections/Display.js @@ -169,7 +169,7 @@ class TabProfile extends PureComponent { to={counterValueCurrency} exchangeId={counterValueExchange} onChange={this.handleChangeExchange} - minWidth={150} + minWidth={200} /> diff --git a/static/i18n/en/app.yml b/static/i18n/en/app.yml index f45ddfe1..000c43a3 100644 --- a/static/i18n/en/app.yml +++ b/static/i18n/en/app.yml @@ -11,7 +11,11 @@ common: chooseWalletPlaceholder: Choose a wallet... currency: Currency selectAccount: Select an account + selectAccountNoOption: 'No account matching "{{accountName}}"' selectCurrency: Select a currency + selectCurrencyNoOption: 'No currency matching "{{currencyName}}"' + selectExchange: Select an exchange + selectExchangeNoOption: 'No exchange matching "{{exchangeName}}"' sortBy: Sort by search: Search save: Save From 74fb9d0db18f052b127f187e25e328378f7901a2 Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 16:06:41 +0200 Subject: [PATCH 04/12] Cleanify the AccountPage settings button --- src/components/AccountPage/index.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/AccountPage/index.js b/src/components/AccountPage/index.js index 5aadb530..469ea436 100644 --- a/src/components/AccountPage/index.js +++ b/src/components/AccountPage/index.js @@ -129,11 +129,9 @@ class AccountPage extends PureComponent { )} t('app:account.settings.title')}> openModal(MODAL_SETTINGS_ACCOUNT, { account })}> - + + + From d2fe8c5ff2fc37992c6a08a9e85c62ec7a9aeef4 Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 16:37:33 +0200 Subject: [PATCH 05/12] Ability to import accounts even if sync is not finished yet --- src/components/modals/AddAccounts/steps/03-step-import.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/modals/AddAccounts/steps/03-step-import.js b/src/components/modals/AddAccounts/steps/03-step-import.js index e148a7ab..3823acad 100644 --- a/src/components/modals/AddAccounts/steps/03-step-import.js +++ b/src/components/modals/AddAccounts/steps/03-step-import.js @@ -246,11 +246,12 @@ export const StepImportFooter = ({ const willClose = !willCreateAccount && !willAddAccounts const onClick = willClose ? onCloseModal : onClickAdd + const hasCheckedAccounts = !!checkedAccountsIds.length return ( {currency && } - From 5cc2c8ae51fd4337ca5abc081048d33e8123e6f9 Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 17:33:10 +0200 Subject: [PATCH 06/12] Ability to cancel sync when adding accounts --- .../AddAccounts/steps/03-step-import.js | 42 +++++++++++++++---- static/i18n/en/app.yml | 2 + 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/components/modals/AddAccounts/steps/03-step-import.js b/src/components/modals/AddAccounts/steps/03-step-import.js index 3823acad..bc411a96 100644 --- a/src/components/modals/AddAccounts/steps/03-step-import.js +++ b/src/components/modals/AddAccounts/steps/03-step-import.js @@ -8,6 +8,7 @@ import uniq from 'lodash/uniq' import { getBridgeForCurrency } from 'bridge' import Box from 'components/base/Box' +import FakeLink from 'components/base/FakeLink' import CurrencyBadge from 'components/base/CurrencyBadge' import Button from 'components/base/Button' import AccountsList from 'components/base/AccountsList' @@ -20,13 +21,26 @@ class StepImport extends PureComponent { this.startScanAccountsDevice() } - componentWillUnmount() { - if (this.scanSubscription) { - this.scanSubscription.unsubscribe() + componentDidUpdate(prevProps: StepProps) { + // handle case when we click on stop sync + if (prevProps.scanStatus !== 'finished' && this.props.scanStatus === 'finished') { + this.unsub() } } + componentWillUnmount() { + this.unsub() + } + scanSubscription = null + _unsubscribed = false + + unsub = () => { + if (this.scanSubscription && !this._unsubscribed) { + this.scanSubscription.unsubscribe() + this._unsubscribed = true + } + } translateName(account: Account) { const { t } = this.props @@ -142,6 +156,8 @@ class StepImport extends PureComponent { t, } = this.props + const currencyName = currency ? currency.name : '' + const importableAccounts = scannedAccounts.filter(acc => { if (acc.operations.length <= 0) { return false @@ -160,9 +176,8 @@ class StepImport extends PureComponent { count: importableAccounts.length, }) - const importableAccountsEmpty = t('app:addAccounts.noAccountToImport', { - currencyName: currency ? ` ${currency.name}` : '', - }) + const importableAccountsEmpty = t('app:addAccounts.noAccountToImport', { currencyName }) + const hasAlreadyEmptyAccount = scannedAccounts.some(a => a.operations.length === 0) return ( @@ -180,7 +195,11 @@ class StepImport extends PureComponent { /> { export default StepImport export const StepImportFooter = ({ + setState, scanStatus, onClickAdd, onCloseModal, @@ -246,12 +266,16 @@ export const StepImportFooter = ({ const willClose = !willCreateAccount && !willAddAccounts const onClick = willClose ? onCloseModal : onClickAdd - const hasCheckedAccounts = !!checkedAccountsIds.length return ( {currency && } - diff --git a/static/i18n/en/app.yml b/static/i18n/en/app.yml index 000c43a3..b190b2be 100644 --- a/static/i18n/en/app.yml +++ b/static/i18n/en/app.yml @@ -143,10 +143,12 @@ addAccounts: newAccount: New account legacyAccount: '{{accountName}} (legacy)' noAccountToImport: We didnt find any {{currencyName}} account to import. + cancelSync: Stop synchronization success: Great success! createNewAccount: title: Create new account noOperationOnLastAccount: You cannot create a new account because your last account has no operations + noAccountToCreate: We didnt find any {{currencyName}} account to create. retrySync: Retry sync cta: create: 'Create account' From b74a40b9c1f820c4289e8127be3fb512e11d1ced Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 18:25:48 +0200 Subject: [PATCH 07/12] Update default button hover & active styles --- src/components/base/Button/index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/base/Button/index.js b/src/components/base/Button/index.js index dc7f2515..8953eb31 100644 --- a/src/components/base/Button/index.js +++ b/src/components/base/Button/index.js @@ -16,8 +16,12 @@ type Style = any // FIXME const buttonStyles: { [_: string]: Style } = { default: { default: noop, - active: noop, - hover: noop, + active: p => ` + background: ${rgba(p.theme.colors.fog, 0.3)}; + `, + hover: p => ` + background: ${rgba(p.theme.colors.fog, 0.2)}; + `, focus: () => ` box-shadow: ${focusedShadowStyle}; `, From 4a9912281cc3922b705f446b5266e3a926a43e62 Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 18:30:05 +0200 Subject: [PATCH 08/12] Refactor retry on add account fail --- .../AddAccounts/steps/03-step-import.js | 66 ++++++++++++++----- static/i18n/en/app.yml | 2 +- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/components/modals/AddAccounts/steps/03-step-import.js b/src/components/modals/AddAccounts/steps/03-step-import.js index bc411a96..bf894775 100644 --- a/src/components/modals/AddAccounts/steps/03-step-import.js +++ b/src/components/modals/AddAccounts/steps/03-step-import.js @@ -8,11 +8,10 @@ import uniq from 'lodash/uniq' import { getBridgeForCurrency } from 'bridge' import Box from 'components/base/Box' -import FakeLink from 'components/base/FakeLink' import CurrencyBadge from 'components/base/CurrencyBadge' import Button from 'components/base/Button' import AccountsList from 'components/base/AccountsList' -import IconExchange from 'icons/Exchange' +import IconExclamationCircleThin from 'icons/ExclamationCircleThin' import type { StepProps } from '../index' @@ -26,6 +25,11 @@ class StepImport extends PureComponent { if (prevProps.scanStatus !== 'finished' && this.props.scanStatus === 'finished') { this.unsub() } + + // handle case when we click on retry sync + if (prevProps.scanStatus !== 'scanning' && this.props.scanStatus === 'scanning') { + this.startScanAccountsDevice() + } } componentWillUnmount() { @@ -71,8 +75,12 @@ class StepImport extends PureComponent { setState({ scanStatus: 'scanning' }) + this._unsubscribed = false this.scanSubscription = bridge.scanAccountsOnDevice(currency, devicePath, { next: account => { + // FIXME: this is called even if we unsubscribed + if (this._unsubscribed) return + const { scannedAccounts, checkedAccountsIds, existingAccounts } = this.props const hasAlreadyBeenScanned = !!scannedAccounts.find(a => account.id === a.id) const hasAlreadyBeenImported = !!existingAccounts.find(a => account.id === a.id) @@ -87,8 +95,16 @@ class StepImport extends PureComponent { }) } }, - complete: () => setState({ scanStatus: 'finished' }), - error: err => setState({ scanStatus: 'error', err }), + complete: () => { + // FIXME: this is called even if we unsubscribed + if (this._unsubscribed) return + setState({ scanStatus: 'finished' }) + }, + error: err => { + // FIXME: this is called even if we unsubscribed + if (this._unsubscribed) return + setState({ scanStatus: 'error', err }) + }, }) } catch (err) { setState({ scanStatus: 'error', err }) @@ -145,6 +161,17 @@ class StepImport extends PureComponent { handleUnselectAll = () => this.props.setState({ checkedAccountsIds: [] }) + renderError() { + const { err, t } = this.props + invariant(err, 'Trying to render inexisting error') + return ( + + + {t('app:addAccounts.somethingWentWrong')} + + ) + } + render() { const { scanStatus, @@ -156,6 +183,10 @@ class StepImport extends PureComponent { t, } = this.props + if (err) { + return this.renderError() + } + const currencyName = currency ? currency.name : '' const importableAccounts = scannedAccounts.filter(acc => { @@ -208,17 +239,7 @@ class StepImport extends PureComponent { /> - {err && ( - - {err.message} - - - )} + {err && {err.message}} ) } @@ -270,12 +291,21 @@ export const StepImportFooter = ({ return ( {currency && } + {scanStatus === 'error' && ( + + )} {scanStatus === 'scanning' && ( - setState({ scanStatus: 'finished' })}> + )} - diff --git a/static/i18n/en/app.yml b/static/i18n/en/app.yml index b190b2be..3fab9aaa 100644 --- a/static/i18n/en/app.yml +++ b/static/i18n/en/app.yml @@ -149,7 +149,7 @@ addAccounts: title: Create new account noOperationOnLastAccount: You cannot create a new account because your last account has no operations noAccountToCreate: We didnt find any {{currencyName}} account to create. - retrySync: Retry sync + somethingWentWrong: Something went wrong during synchronization. cta: create: 'Create account' import: 'Import account' From 009f74725a0a6838ed0264d4f92f3bab82f01e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Tue, 19 Jun 2018 18:34:17 +0200 Subject: [PATCH 09/12] add busy indicators --- src/components/DeviceBusyIndicator.js | 38 ++++++++++++++++++++++++++ src/components/LibcoreBusyIndicator.js | 37 +++++++++++++++++++++++++ src/components/layout/Default.js | 5 ++++ src/config/constants.js | 1 + src/helpers/deviceAccess.js | 19 +++++++++++-- src/helpers/withLibcore.js | 20 ++++++++++++-- src/main/bridge.js | 21 ++++++++------ src/renderer/events.js | 16 +++++++++-- 8 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 src/components/DeviceBusyIndicator.js create mode 100644 src/components/LibcoreBusyIndicator.js diff --git a/src/components/DeviceBusyIndicator.js b/src/components/DeviceBusyIndicator.js new file mode 100644 index 00000000..b77523bc --- /dev/null +++ b/src/components/DeviceBusyIndicator.js @@ -0,0 +1,38 @@ +import React, { PureComponent } from 'react' +import styled from 'styled-components' + +const Indicator = styled.div` + opacity: ${p => (p.busy ? 0.2 : 0)}; + width: 6px; + height: 6px; + border-radius: 3px; + background-color: black; + position: fixed; + bottom: 4px; + right: 4px; + z-index: 999; +` + +// NB this is done like this to be extremely performant. we don't want redux for this.. +const perPaths = {} +const instances = [] +export const onSetDeviceBusy = (path, busy) => { + perPaths[path] = busy + instances.forEach(i => i.forceUpdate()) +} + +class DeviceBusyIndicator extends PureComponent<{}> { + componentDidMount() { + instances.push(this) + } + componentWillUnmount() { + const i = instances.indexOf(this) + instances.splice(i, 1) + } + render() { + const busy = Object.values(perPaths).reduce((busy, b) => busy || b, false) + return + } +} + +export default DeviceBusyIndicator diff --git a/src/components/LibcoreBusyIndicator.js b/src/components/LibcoreBusyIndicator.js new file mode 100644 index 00000000..251f955b --- /dev/null +++ b/src/components/LibcoreBusyIndicator.js @@ -0,0 +1,37 @@ +import React, { PureComponent } from 'react' +import styled from 'styled-components' + +const Indicator = styled.div` + opacity: ${p => (p.busy ? 0.2 : 0)}; + width: 6px; + height: 6px; + border-radius: 3px; + background-color: black; + position: fixed; + bottom: 4px; + right: 4px; + z-index: 999; +` + +// NB this is done like this to be extremely performant. we don't want redux for this.. +let busy = false +const instances = [] +export const onSetLibcoreBusy = b => { + busy = b + instances.forEach(i => i.forceUpdate()) +} + +class LibcoreBusyIndicator extends PureComponent<{}> { + componentDidMount() { + instances.push(this) + } + componentWillUnmount() { + const i = instances.indexOf(this) + instances.splice(i, 1) + } + render() { + return + } +} + +export default LibcoreBusyIndicator diff --git a/src/components/layout/Default.js b/src/components/layout/Default.js index e7286fa0..c9a16c8c 100644 --- a/src/components/layout/Default.js +++ b/src/components/layout/Default.js @@ -17,6 +17,8 @@ import DashboardPage from 'components/DashboardPage' import ManagerPage from 'components/ManagerPage' import ExchangePage from 'components/ExchangePage' import SettingsPage from 'components/SettingsPage' +import LibcoreBusyIndicator from 'components/LibcoreBusyIndicator' +import DeviceBusyIndicator from 'components/DeviceBusyIndicator' import AppRegionDrag from 'components/AppRegionDrag' import IsUnlocked from 'components/IsUnlocked' @@ -96,6 +98,9 @@ class Default extends Component { + + + ) diff --git a/src/config/constants.js b/src/config/constants.js index 74ca72ef..473559a4 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -59,6 +59,7 @@ export const SKIP_GENUINE = boolFromEnv('SKIP_GENUINE') export const SKIP_ONBOARDING = boolFromEnv('SKIP_ONBOARDING') export const SHOW_LEGACY_NEW_ACCOUNT = boolFromEnv('SHOW_LEGACY_NEW_ACCOUNT') export const HIGHLIGHT_I18N = boolFromEnv('HIGHLIGHT_I18N') +export const DISABLE_ACTIVITY_INDICATORS = boolFromEnv('DISABLE_ACTIVITY_INDICATORS') // Other constants diff --git a/src/helpers/deviceAccess.js b/src/helpers/deviceAccess.js index 34aa3499..c380fe0c 100644 --- a/src/helpers/deviceAccess.js +++ b/src/helpers/deviceAccess.js @@ -18,7 +18,7 @@ export const withDevice: WithDevice = devicePath => { semaphorePerDevice[devicePath] || (semaphorePerDevice[devicePath] = createSemaphore(1)) return job => - takeSemaphorePromise(sem, async () => { + takeSemaphorePromise(sem, devicePath, async () => { const t = await retry(() => TransportNodeHid.open(devicePath), { maxRetry: 1 }) if (DEBUG_DEVICE) t.setDebugMode(true) @@ -32,17 +32,32 @@ export const withDevice: WithDevice = devicePath => { }) } -function takeSemaphorePromise(sem, f: () => Promise): Promise { +function takeSemaphorePromise(sem, devicePath, f: () => Promise): Promise { return new Promise((resolve, reject) => { sem.take(() => { + process.send({ + type: 'setDeviceBusy', + busy: true, + devicePath, + }) f().then( r => { sem.leave() resolve(r) + process.send({ + type: 'setDeviceBusy', + busy: false, + devicePath, + }) }, e => { sem.leave() reject(e) + process.send({ + type: 'setDeviceBusy', + busy: false, + devicePath, + }) }, ) }) diff --git a/src/helpers/withLibcore.js b/src/helpers/withLibcore.js index e2d42054..f1fe3fd4 100644 --- a/src/helpers/withLibcore.js +++ b/src/helpers/withLibcore.js @@ -3,8 +3,24 @@ // TODO: `core` should be typed type Job = Object => Promise -export default function withLibcore(job: Job): Promise { +let counter = 0 +export default async function withLibcore(job: Job): Promise { const core = require('./init-libcore').default core.getPoolInstance() - return job(core) + try { + if (counter++ === 0) { + process.send({ + type: 'setLibcoreBusy', + busy: true, + }) + } + return job(core) + } finally { + if (--counter === 0) { + process.send({ + type: 'setLibcoreBusy', + busy: false, + }) + } + } } diff --git a/src/main/bridge.js b/src/main/bridge.js index 2b71fcd1..79323d2e 100644 --- a/src/main/bridge.js +++ b/src/main/bridge.js @@ -97,16 +97,19 @@ ipcMainListenReceiveCommands({ }) function handleGlobalInternalMessage(payload) { - if (payload.type === 'executeHttpQueryOnRenderer') { - const win = getMainWindow && getMainWindow() - if (!win) { - logger.warn("can't executeHttpQueryOnRenderer because no renderer") - return + switch (payload.type) { + case 'setLibcoreBusy': + case 'setDeviceBusy': + case 'executeHttpQueryOnRenderer': { + const win = getMainWindow && getMainWindow() + if (!win) { + logger.warn(`can't ${payload.type} because no renderer`) + return + } + win.webContents.send(payload.type, payload) + break } - win.webContents.send('executeHttpQuery', { - id: payload.id, - networkArg: payload.networkArg, - }) + default: } } diff --git a/src/renderer/events.js b/src/renderer/events.js index bb106f27..63d266f2 100644 --- a/src/renderer/events.js +++ b/src/renderer/events.js @@ -15,7 +15,9 @@ import network from 'api/network' import { ipcRenderer } from 'electron' import debug from 'debug' -import { CHECK_UPDATE_DELAY } from 'config/constants' +import { CHECK_UPDATE_DELAY, DISABLE_ACTIVITY_INDICATORS } from 'config/constants' +import { onSetDeviceBusy } from 'components/DeviceBusyIndicator' +import { onSetLibcoreBusy } from 'components/LibcoreBusyIndicator' import { hasPassword } from 'reducers/settings' import { lock } from 'reducers/application' @@ -87,7 +89,7 @@ export default ({ store }: { store: Object }) => { } }) - ipcRenderer.on('executeHttpQuery', (event: any, { networkArg, id }) => { + ipcRenderer.on('executeHttpQueryOnRenderer', (event: any, { networkArg, id }) => { network(networkArg).then( result => { ipcRenderer.send('executeHttpQueryPayload', { type: 'success', id, result }) @@ -98,6 +100,16 @@ export default ({ store }: { store: Object }) => { ) }) + if (!DISABLE_ACTIVITY_INDICATORS) { + ipcRenderer.on('setLibcoreBusy', (event: any, { busy }) => { + onSetLibcoreBusy(busy) + }) + + ipcRenderer.on('setDeviceBusy', (event: any, { busy, devicePath }) => { + onSetDeviceBusy(devicePath, busy) + }) + } + if (__PROD__) { // TODO move this to "command" pattern const updaterHandlers = { From cc8dbb82ba353db3127a39a61290590109f0765f Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 18:38:12 +0200 Subject: [PATCH 10/12] Fix un-aligned back button & chevron, that was triggering me so much --- src/components/base/Modal/ModalTitle.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/base/Modal/ModalTitle.js b/src/components/base/Modal/ModalTitle.js index c4f4c7ed..cc812853 100644 --- a/src/components/base/Modal/ModalTitle.js +++ b/src/components/base/Modal/ModalTitle.js @@ -30,6 +30,7 @@ const Back = styled(Box).attrs({ })` cursor: pointer; position: absolute; + line-height: 1; top: 0; left: 0; From d5994a3a904c3256040b0cbb4e5aa40e28f92634 Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 19 Jun 2018 18:53:56 +0200 Subject: [PATCH 11/12] Wording update --- src/components/modals/AddAccounts/steps/03-step-import.js | 2 +- static/i18n/en/app.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/modals/AddAccounts/steps/03-step-import.js b/src/components/modals/AddAccounts/steps/03-step-import.js index bf894775..b95885c3 100644 --- a/src/components/modals/AddAccounts/steps/03-step-import.js +++ b/src/components/modals/AddAccounts/steps/03-step-import.js @@ -298,7 +298,7 @@ export const StepImportFooter = ({ )} {scanStatus === 'scanning' && ( )}