Skip to content

Commit

Permalink
add extra dialog to prevent user from aborting a new sync chain
Browse files Browse the repository at this point in the history
  • Loading branch information
cezaraugusto committed Jan 3, 2019
1 parent 24867f7 commit ae6a7ee
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 11 deletions.
2 changes: 2 additions & 0 deletions browser/ui/webui/brave_webui_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ void CustomizeWebUIHTMLSource(const std::string &name, content::WebUIDataSource*
{ "wordCount", IDS_BRAVE_SYNC_SHARED_WORD_COUNT_TEXT },
{ "ok", IDS_BRAVE_SYNC_SHARED_OK_BUTTON },
{ "cancel", IDS_BRAVE_SYNC_SHARED_CANCEL_BUTTON },
{ "cancelDeviceSyncing", IDS_BRAVE_SYNC_SHARED_CANCEL_SYNCING_TITLE },
{ "cancelDeviceSyncingButton", IDS_BRAVE_SYNC_SHARED_CANCEL_SYNCING_BUTTON },
{ "thisSyncChain", IDS_BRAVE_SYNC_SHARED_FROM_THIS_CHAIN_PARTIAL },
{ "lookingForDevice", IDS_BRAVE_SYNC_SCAN_CODE_LOOKING_FOR_DEVICE_BUTTON },
{ "viewSyncCode", IDS_BRAVE_SYNC_ENABLED_VIEW_CODE_BUTTON },
Expand Down
1 change: 1 addition & 0 deletions components/brave_sync/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ transpile_web_ui("ui") {
inputs = [
"actions/sync_actions.ts",
"components/commonDialogs/areYouSure.tsx",
"components/commonDialogs/cancelDeviceSyncing.tsx",
"components/modals/deviceType.tsx",
"components/modals/enterSyncCode.tsx",
"components/modals/removeDevice.tsx",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* 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, Paragraph } from 'brave-ui/features/sync'

// Utils
import { getLocale } from '../../../../common/locale'

interface Props {
onClickOk: () => void
onClickCancel: () => void
}

export default class AreYouSure extends React.PureComponent<Props, {}> {
render () {
const { onClickOk, onClickCancel } = this.props
return (
<AlertBox
okString={getLocale('cancelDeviceSyncingButton')}
onClickOk={onClickOk}
cancelString={getLocale('cancel')}
onClickCancel={onClickCancel}
>
<Title level={1}>{getLocale('areYouSure')}</Title>
<Paragraph>{getLocale('cancelDeviceSyncing')}</Paragraph>
</AlertBox>
)
}
}
2 changes: 1 addition & 1 deletion components/brave_sync/ui/components/modals/deviceType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default class DeviceTypeModal extends React.PureComponent<Props, State> {
}
}

componentWillMount () {
componentDidMount () {
// once the screen is rendered, create a sync chain.
// this allow us to request the qr code and sync words immediately
const { thisDeviceName } = this.props.syncData
Expand Down
42 changes: 37 additions & 5 deletions components/brave_sync/ui/components/modals/scanCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import {
// Modals
import ViewSyncCode from './viewSyncCode'

// Dialogs
import CancelDeviceSyncingDialog from '../commonDialogs/cancelDeviceSyncing'

// Utils
import { getLocale } from '../../../../common/locale'

Expand All @@ -33,30 +36,54 @@ interface Props {
actions: any
onClose: () => void
}

interface State {
viewSyncCode: boolean
willCancelScanCode: boolean
}

export default class ScanCodeModal extends React.PureComponent<Props, State> {
constructor (props: Props) {
super(props)
this.state = {
viewSyncCode: false
viewSyncCode: false,
willCancelScanCode: false
}
}

onClickEnterCodeWordsInstead = () => {
this.setState({ viewSyncCode: !this.state.viewSyncCode })
}

onCancel = (event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault()
onDismissModal = () => {
const { devices, isSyncConfigured } = this.props.syncData
// if user is still trying to build a sync chain,
// open the confirmation modal. otherwise close it
isSyncConfigured && devices.length < 2
? this.setState({ willCancelScanCode: true })
: this.props.onClose()
}

onDismissDialog = () => {
this.setState({ willCancelScanCode: false })
}

onConfirmDismissModal = () => {
const { devices, isSyncConfigured } = this.props.syncData
// sync is enabled when at least 2 devices are in the chain.
// this modal works both with sync enabled and disabled states.
// in case user opens it in the enabled content screen,
// check there are 2 devices in chain before reset
if (isSyncConfigured && devices.length < 2) {
this.props.actions.onSyncReset()
}
this.setState({ willCancelScanCode: false })
this.props.onClose()
}

render () {
const { onClose, syncData, actions } = this.props
const { viewSyncCode } = this.state
const { viewSyncCode, willCancelScanCode } = this.state

return (
<Modal id='scanCodeModal' displayCloseButton={false} size='small'>
Expand All @@ -65,6 +92,11 @@ export default class ScanCodeModal extends React.PureComponent<Props, State> {
? <ViewSyncCode syncData={syncData} actions={actions} onClose={this.onClickEnterCodeWordsInstead} />
: null
}
{
willCancelScanCode
? <CancelDeviceSyncingDialog onClickCancel={this.onDismissDialog} onClickOk={this.onConfirmDismissModal} />
: null
}
<ModalHeader>
<div>
<Title level={1}>{getLocale('scanThisCode')}</Title>
Expand All @@ -83,7 +115,7 @@ export default class ScanCodeModal extends React.PureComponent<Props, State> {
</ScanGrid>
<ThreeColumnButtonGrid>
<div>
<Link onClick={this.onCancel}>{getLocale('cancel')}</Link>
<Link onClick={this.onDismissModal}>{getLocale('cancel')}</Link>
</div>
<div>
<Button
Expand Down
41 changes: 36 additions & 5 deletions components/brave_sync/ui/components/modals/viewSyncCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import {
// Modals
import ScanCode from './scanCode'

// Dialogs
import CancelDeviceSyncingDialog from '../commonDialogs/cancelDeviceSyncing'

// Utils
import { getLocale } from '../../../../common/locale'

Expand All @@ -32,28 +35,51 @@ interface Props {

interface State {
useCameraInstead: boolean
willCancelViewCode: boolean
}

export default class ViewSyncCodeModal extends React.PureComponent<Props, State> {
constructor (props: Props) {
super(props)
this.state = {
useCameraInstead: false
useCameraInstead: false,
willCancelViewCode: false
}
}

onClickUseCameraInsteadButton = () => {
this.setState({ useCameraInstead: !this.state.useCameraInstead })
}

onCancel = (event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault()
onDismissModal = () => {
const { devices, isSyncConfigured } = this.props.syncData
// if user is still trying to build a sync chain,
// open the confirmation modal. otherwise close it
isSyncConfigured && devices.length < 2
? this.setState({ willCancelViewCode: true })
: this.props.onClose()
}

onDismissDialog = () => {
this.setState({ willCancelViewCode: false })
}

onConfirmDismissModal = () => {
const { devices, isSyncConfigured } = this.props.syncData
// sync is enabled when at least 2 devices are in the chain.
// this modal works both with sync enabled and disabled states.
// in case user opens it in the enabled content screen,
// check there are 2 devices in chain before reset
if (isSyncConfigured && devices.length < 2) {
this.props.actions.onSyncReset()
}
this.setState({ willCancelViewCode: false })
this.props.onClose()
}

render () {
const { onClose, actions, syncData } = this.props
const { useCameraInstead } = this.state
const { useCameraInstead, willCancelViewCode } = this.state

return (
<Modal id='viewSyncCodeModal' displayCloseButton={false} size='small'>
Expand All @@ -62,6 +88,11 @@ export default class ViewSyncCodeModal extends React.PureComponent<Props, State>
? <ScanCode syncData={syncData} actions={actions} onClose={this.onClickUseCameraInsteadButton} />
: null
}
{
willCancelViewCode
? <CancelDeviceSyncingDialog onClickCancel={this.onDismissDialog} onClickOk={this.onConfirmDismissModal} />
: null
}
<ModalHeader>
<div>
<Title level={1}>{getLocale('chainCode')}</Title>
Expand All @@ -84,7 +115,7 @@ export default class ViewSyncCodeModal extends React.PureComponent<Props, State>
}
<ThreeColumnButtonGrid>
<div>
<Link onClick={this.onCancel}>{getLocale('cancel')}</Link>
<Link onClick={this.onDismissModal}>{getLocale('cancel')}</Link>
</div>
<div>
<Button
Expand Down
2 changes: 2 additions & 0 deletions components/resources/brave_components_strings.grd
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,8 @@
<message name="IDS_BRAVE_SYNC_SHARED_WORD_COUNT_TEXT" desc="The Sync `word count` phrase that shows how many words are in a textarea field">Word Count:</message>
<message name="IDS_BRAVE_SYNC_SHARED_OK_BUTTON" desc="The Sync `ok` button that indicates user is aware of what is being written">Ok</message>
<message name="IDS_BRAVE_SYNC_SHARED_CANCEL_BUTTON" desc="The Sync `cancel` button that closes the current modal">Cancel</message>
<message name="IDS_BRAVE_SYNC_SHARED_CANCEL_SYNCING_TITLE" desc="The Sync phrase for when the user is about to reset sync by closing the `view code` or `scan code` modal">Exiting this modal early will delete the current chain and the devices looking for this code will not be able to sync. This modal will exit automatically when a successful sync connection is made.</message>
<message name="IDS_BRAVE_SYNC_SHARED_CANCEL_SYNCING_BUTTON" desc="The Sync button label for when the user is about to reset sync by closing the `view code` or `scan code` modal">Exit Modal</message>
<message name="IDS_BRAVE_SYNC_SHARED_FROM_THIS_CHAIN_PARTIAL" desc="The Sync partial phrase included in `remove X from this sync chain` where X is the user's device name">from this sync chain</message>
<message name="IDS_BRAVE_SYNC_SHARED_VIEW_CODE_BUTTON" desc="The Sync button to enter code words instead of scanning the current code">View Code Words</message>
<message name="IDS_BRAVE_SYNC_SCAN_CODE_LOOKING_FOR_DEVICE_BUTTON" desc="The Sync temporary button that holds while a device is not found yet">Looking for device</message>
Expand Down

0 comments on commit ae6a7ee

Please sign in to comment.