From 24867f792bd9b48a4479bbf258913f6b7e5aa06d Mon Sep 17 00:00:00 2001 From: Cezar Augusto Date: Wed, 2 Jan 2019 06:17:07 -0200 Subject: [PATCH] add a loading state for adding, removing and reseting sync fix brave/brave-browser#2567 fix brave/brave-browser#2629 --- components/brave_sync/ui/BUILD.gn | 1 + .../components/commonDialogs/areYouSure.tsx | 35 ++++++++++ .../ui/components/enabledContent.tsx | 11 ++- .../ui/components/modals/enterSyncCode.tsx | 44 ++++++++++-- .../ui/components/modals/removeDevice.tsx | 63 ++++++++++++++--- .../ui/components/modals/resetSync.tsx | 70 +++++++++++++------ 6 files changed, 183 insertions(+), 41 deletions(-) create mode 100644 components/brave_sync/ui/components/commonDialogs/areYouSure.tsx diff --git a/components/brave_sync/ui/BUILD.gn b/components/brave_sync/ui/BUILD.gn index 15c775f09dee..d1efc97c0fad 100644 --- a/components/brave_sync/ui/BUILD.gn +++ b/components/brave_sync/ui/BUILD.gn @@ -3,6 +3,7 @@ import("//brave/components/common/typescript.gni") transpile_web_ui("ui") { inputs = [ "actions/sync_actions.ts", + "components/commonDialogs/areYouSure.tsx", "components/modals/deviceType.tsx", "components/modals/enterSyncCode.tsx", "components/modals/removeDevice.tsx", diff --git a/components/brave_sync/ui/components/commonDialogs/areYouSure.tsx b/components/brave_sync/ui/components/commonDialogs/areYouSure.tsx new file mode 100644 index 000000000000..80472e443a4d --- /dev/null +++ b/components/brave_sync/ui/components/commonDialogs/areYouSure.tsx @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' + +// Components +import { AlertBox } from 'brave-ui' + +// Feature-specific components +import { Title } from 'brave-ui/features/sync' + +// Utils +import { getLocale } from '../../../../common/locale' + +interface Props { + onClickOk: () => void + onClickCancel: () => void +} + +export default class AreYouSure extends React.PureComponent { + render () { + const { onClickOk, onClickCancel } = this.props + return ( + + {getLocale('areYouSure')} + + ) + } +} diff --git a/components/brave_sync/ui/components/enabledContent.tsx b/components/brave_sync/ui/components/enabledContent.tsx index 070ec5ddb3c4..10cdf3a2e778 100644 --- a/components/brave_sync/ui/components/enabledContent.tsx +++ b/components/brave_sync/ui/components/enabledContent.tsx @@ -137,10 +137,14 @@ export default class SyncEnabledContent extends React.PureComponent { + this.setState({ removeDevice: !this.state.removeDevice }) + } + onUserNoticedError = () => { this.props.actions.resetSyncSetupError() } @@ -199,10 +203,11 @@ export default class SyncEnabledContent extends React.PureComponent ) : null diff --git a/components/brave_sync/ui/components/modals/enterSyncCode.tsx b/components/brave_sync/ui/components/modals/enterSyncCode.tsx index 4e7e9f734e49..4cd06ff88392 100644 --- a/components/brave_sync/ui/components/modals/enterSyncCode.tsx +++ b/components/brave_sync/ui/components/modals/enterSyncCode.tsx @@ -19,6 +19,9 @@ import { SubTitle } from 'brave-ui/features/sync' +// Icons +import { LoaderIcon } from 'brave-ui/components/icons' + // Utils import { getLocale } from '../../../../common/locale' @@ -29,13 +32,33 @@ interface Props { } interface State { passphrase: string + willCreateNewSyncChainFromCode: boolean } export default class EnterSyncCodeModal extends React.PureComponent { constructor (props: Props) { super(props) this.state = { - passphrase: '' + passphrase: '', + willCreateNewSyncChainFromCode: false + } + } + + componentDidUpdate (prevProps: Props) { + // when component updates with a different config, disable the + // loading state and unfreeze the modal. at this point the component + // auto refresh and lead the user to the enabledContent view + if ( + this.props.syncData.error !== undefined || + ( + this.state.willCreateNewSyncChainFromCode && + prevProps.syncData.isSyncConfigured !== + this.props.syncData.isSyncConfigured && + this.props.syncData.devices.length > 1 + ) + ) { + this.setState({ willCreateNewSyncChainFromCode: false }) + this.props.onClose() } } @@ -47,19 +70,26 @@ export default class EnterSyncCodeModal extends React.PureComponent { + this.props.onClose() + } + onClickConfirmSyncCode = () => { const { error, thisDeviceName } = this.props.syncData if (thisDeviceName !== '' || error) { return } const { passphrase } = this.state + this.setState({ willCreateNewSyncChainFromCode: true }) this.props.actions.onSetupSyncHaveCode(passphrase, '') } render () { - const { onClose, syncData } = this.props + const { syncData } = this.props + const { willCreateNewSyncChainFromCode } = this.state + return ( - + { syncData.error === 'ERR_SYNC_WRONG_WORDS' ? @@ -110,7 +140,8 @@ export default class EnterSyncCodeModal extends React.PureComponent @@ -120,6 +151,11 @@ export default class EnterSyncCodeModal extends React.PureComponent + }} /> diff --git a/components/brave_sync/ui/components/modals/removeDevice.tsx b/components/brave_sync/ui/components/modals/removeDevice.tsx index 2a445893a9da..f9312f522c64 100644 --- a/components/brave_sync/ui/components/modals/removeDevice.tsx +++ b/components/brave_sync/ui/components/modals/removeDevice.tsx @@ -17,35 +17,70 @@ import { OneColumnButtonGrid } from 'brave-ui/features/sync' +// Icons +import { LoaderIcon } from 'brave-ui/components/icons' + // Utils import { getLocale } from '../../../../common/locale' interface Props { + syncData: Sync.State onClose: (event?: React.MouseEvent) => void actions: any deviceName: string | undefined - deviceId: number | undefined + deviceId: string | undefined +} + +interface State { + willRemoveDevice: boolean } -export default class RemoveMainDeviceModal extends React.PureComponent { +export default class RemoveMainDeviceModal extends React.PureComponent { + constructor (props: Props) { + super(props) + this.state = { willRemoveDevice: false } + } + + componentDidUpdate (prevProps: Props) { + // if devices lengh is different it means that sync + // computed the device removal. in this case, cancel + // the loading state and close the modal + if ( + prevProps.syncData.devices.length !== + this.props.syncData.devices.length + ) { + this.setState({ willRemoveDevice: false }) + this.props.onClose() + } + } + + onDismissModal = () => { + this.props.onClose() + } + onClickConfirmRemoveDeviceButton = () => { - const { deviceName, deviceId } = this.props + const { syncData, deviceName, deviceId } = this.props + // if there aren't enough devices, reset sync + if (syncData.devices.length < 2) { + this.props.actions.onSyncReset() + return + } this.props.actions.onRemoveDevice(Number(deviceId), deviceName) - this.props.onClose() + this.setState({ willRemoveDevice: true }) } render () { - const { onClose, deviceName, deviceId } = this.props + const { syncData, deviceName, deviceId } = this.props + const { willRemoveDevice } = this.state return ( - + {getLocale('remove')} “{deviceName}” {getLocale('thisSyncChain')}? { - // zero is always the this device - deviceId === 0 + deviceId === syncData.thisDeviceId ?
{getLocale('thisDeviceRemovalDescription')} {getLocale('joinSyncChain')} @@ -57,18 +92,24 @@ export default class RemoveMainDeviceModal extends React.PureComponent