Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Wallet] Prompt users with connectivity issues to switch to forno #2526

Merged
merged 20 commits into from
Jan 24, 2020
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions packages/mobile/locales/en-US/accountScreen10.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
"sendIssueReport": "Send an Issue Report",
"analytics": "Analytics",
"shareAnalytics": "Share Analytics",
"shareAnalytics_detail":
"We collect anonymized data about how you use Celo to help improve the application for everyone.",
"shareAnalytics_detail": "We collect anonymized data about how you use Celo to help improve the application for everyone.",
"dataSaver": "Data Saver",
"enableDataSaver": "Enable Data Saver",
"dataSaverDetail":
"Data Saver mode allows you to communicate with the Celo Network through a trusted node. You can always change this mode in app settings.",
"dataSaverDetail": "Data Saver mode allows you to communicate with the Celo Network through a trusted node. You can always change this mode in app settings.",
"restartModalSwitchOff": {
"header": "Restart To Switch Off Data Saver",
"body": "To switch Data Saver on and off repeatedly, you will need to restart the app.",
Expand All @@ -23,6 +21,11 @@
"body": "In case of incorrect PIN, you will need to restart the app.",
"understand": "I understand"
},
"promptZeroSyncModal": {
"header": "Switch Connection Mode?",
"body": "We’ve noticed you’re having some trouble connecting. We recommend enabling Data Saver mode to allow you to keep using the Celo Wallet with intermittent connection.",
"switchToDataSaver": "Switch To Data Saver"
},
"testFaqLink": "Celo Wallet FAQ",
"termsOfServiceLink": "Terms of service",
"editProfile": "Edit Profile",
Expand Down
5 changes: 5 additions & 0 deletions packages/mobile/locales/es-419/accountScreen10.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
"body": "En caso de ingresar un PIN incorrecto, la aplicación se reiniciará.",
"understand": "Entendido"
},
"promptZeroSyncModal": {
"header": "Cambiar modo de conexión?",
"body": "Hemos notado que tienes problemas para conectarte. Recomendamos habilitar el modo de ahorro de datos para que pueda seguir usando Celo Wallet con una conexión intermitente.",
"switchToDataSaver": "Habilitar Ahorro de Datos"
},
"testFaqLink": "Las Preguntas Frecuentes del Monedero Celo",
"termsOfServiceLink": "Las Condiciones de Servicio",
"editProfile": "Editar perfil",
Expand Down
3 changes: 2 additions & 1 deletion packages/mobile/src/account/DataSaver.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { Provider } from 'react-redux'
import * as renderer from 'react-test-renderer'
import DataSaver from 'src/account/DataSaver'
import { createMockStore } from 'test/utils'
import { mockNavigation } from 'test/values'

describe('DataSaver', () => {
it('renders correctly', () => {
const tree = renderer.create(
<Provider store={createMockStore({})}>
<DataSaver />
<DataSaver navigation={mockNavigation} />
</Provider>
)
expect(tree).toMatchSnapshot()
Expand Down
34 changes: 33 additions & 1 deletion packages/mobile/src/account/DataSaver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import * as React from 'react'
import { WithTranslation } from 'react-i18next'
import { ScrollView, StyleSheet, Text, View } from 'react-native'
import Modal from 'react-native-modal'
import { NavigationInjectedProps } from 'react-navigation'
import { connect } from 'react-redux'
import i18n, { Namespaces, withTranslation } from 'src/i18n'
import { headerWithBackButton } from 'src/navigator/Headers'
import { navigateBack } from 'src/navigator/NavigationService'
import { RootState } from 'src/redux/reducers'
import { toggleZeroSyncMode } from 'src/web3/actions'

Expand All @@ -21,7 +23,7 @@ interface DispatchProps {
toggleZeroSyncMode: typeof toggleZeroSyncMode
}

type Props = StateProps & DispatchProps & WithTranslation
type Props = StateProps & DispatchProps & WithTranslation & NavigationInjectedProps

const mapDispatchToProps = {
toggleZeroSyncMode,
Expand All @@ -37,6 +39,7 @@ const mapStateToProps = (state: RootState): StateProps => {
interface State {
switchOffModalVisible: boolean
switchOnModalVisible: boolean
promptModalVisible: boolean
}

interface ModalProps {
Expand Down Expand Up @@ -85,6 +88,16 @@ export class DataSaver extends React.Component<Props, State> {
state = {
switchOffModalVisible: false,
switchOnModalVisible: false,
promptModalVisible: false,
}

componentDidMount() {
const promptModalVisible = this.props.navigation.getParam('promptModalVisible')
if (promptModalVisible) {
this.setState({
promptModalVisible,
})
}
}

showSwitchOffModal = () => {
Expand Down Expand Up @@ -113,6 +126,16 @@ export class DataSaver extends React.Component<Props, State> {
this.hideSwitchOnModal()
}

onPressPromptModal = () => {
this.props.toggleZeroSyncMode(true)
navigateBack()
}

hidePromptModal = () => {
this.props.toggleZeroSyncMode(false)
navigateBack()
}

handleZeroSyncToggle = (zeroSyncMode: boolean) => {
if (!zeroSyncMode && this.props.gethStartedThisSession) {
// Starting geth a second time this app session which will
Expand All @@ -136,6 +159,15 @@ export class DataSaver extends React.Component<Props, State> {
>
<Text style={fontStyles.body}>{t('enableDataSaver')}</Text>
</SettingsSwitchItem>
<WarningModal
isVisible={this.state.promptModalVisible}
header={t('promptZeroSyncModal.header')}
body={t('promptZeroSyncModal.body')}
continueTitle={t('promptZeroSyncModal.switchToDataSaver')}
cancelTitle={t('global:goBack')}
onCancel={this.hidePromptModal}
onContinue={this.onPressPromptModal}
/>
<WarningModal
isVisible={this.state.switchOffModalVisible}
header={t('restartModalSwitchOff.header')}
Expand Down
205 changes: 205 additions & 0 deletions packages/mobile/src/account/__snapshots__/DataSaver.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,211 @@ exports[`DataSaver renders correctly 1`] = `
</Text>
</View>
</View>
<Modal
animationType="none"
hardwareAccelerated={false}
hideModalContentWhileAnimating={false}
onModalHide={[Function]}
onModalWillHide={[Function]}
onModalWillShow={[Function]}
onRequestClose={[Function]}
scrollHorizontal={false}
scrollOffset={0}
scrollOffsetMax={0}
scrollTo={null}
supportedOrientations={
Array [
"portrait",
"landscape",
]
}
swipeThreshold={100}
transparent={true}
visible={true}
>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"backgroundColor": "black",
"bottom": 0,
"height": 1334,
"left": 0,
"opacity": 0,
"position": "absolute",
"right": 0,
"top": 0,
"width": 750,
}
}
/>
<View
hideModalContentWhileAnimating={false}
onModalHide={[Function]}
onModalWillHide={[Function]}
onModalWillShow={[Function]}
pointerEvents="box-none"
scrollHorizontal={false}
scrollOffset={0}
scrollOffsetMax={0}
scrollTo={null}
style={
Object {
"flex": 1,
"justifyContent": "center",
"margin": 37.5,
"transform": Array [
Object {
"translateY": 1334,
},
],
}
}
supportedOrientations={
Array [
"portrait",
"landscape",
]
}
swipeThreshold={100}
>
<View
style={
Object {
"backgroundColor": "#FFFFFF",
"borderRadius": 4,
"marginHorizontal": 10,
"padding": 20,
}
}
>
<Text
style={
Object {
"color": "#2E3338",
"fontFamily": "Hind-Bold",
"fontSize": 18,
"marginVertical": 15,
"textAlign": "center",
}
}
>
promptZeroSyncModal.header
</Text>
<Text
style={
Object {
"color": "#2E3338",
"fontFamily": "Hind-Regular",
"fontSize": 16,
"lineHeight": 24,
}
}
>
promptZeroSyncModal.body
</Text>
<View
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"justifyContent": "space-evenly",
"marginTop": 25,
}
}
>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
nativeBackgroundAndroid={
Object {
"attribute": "selectableItemBackgroundBorderless",
"type": "ThemeAttrAndroid",
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
>
<Text
style={
Array [
Object {
"color": "#42D689",
"fontFamily": "Hind-SemiBold",
"fontSize": 14,
"lineHeight": 18,
},
Object {
"color": "#2E3338",
"fontFamily": "Hind-SemiBold",
"fontSize": 16,
"lineHeight": 24,
"paddingRight": 20,
},
]
}
>
global:goBack
</Text>
</View>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
nativeBackgroundAndroid={
Object {
"attribute": "selectableItemBackgroundBorderless",
"type": "ThemeAttrAndroid",
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
>
<Text
style={
Array [
Object {
"color": "#42D689",
"fontFamily": "Hind-SemiBold",
"fontSize": 14,
"lineHeight": 18,
},
Object {
"color": "#42D689",
"fontFamily": "Hind-SemiBold",
"fontSize": 16,
"lineHeight": 24,
"paddingLeft": 20,
},
]
}
>
promptZeroSyncModal.switchToDataSaver
</Text>
</View>
</View>
</View>
</View>
</Modal>
<Modal
animationType="none"
hardwareAccelerated={false}
Expand Down
26 changes: 21 additions & 5 deletions packages/mobile/src/geth/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,42 @@ import { InitializationState } from 'src/geth/reducer'
export enum Actions {
SET_INIT_STATE = 'GETH/SET_INIT_STATE',
SET_GETH_CONNECTED = 'GETH/SET_GETH_CONNECTED',
CANCEL_GETH_SAGA = 'GETH/CANCEL_GETH_SAGA',
SET_PROMPT_ZERO_SYNC = 'GETH/SET_PROMPT_ZERO_SYNC',
}

interface SetInitState {
interface SetInitStateAction {
type: Actions.SET_INIT_STATE
state: InitializationState
}

export const setInitState = (state: InitializationState): SetInitState => ({
export const setInitState = (state: InitializationState): SetInitStateAction => ({
type: Actions.SET_INIT_STATE,
state,
})

interface SetGethConnected {
export const cancelGethSaga = () => ({
type: Actions.CANCEL_GETH_SAGA,
})

interface SetPromptZeroSyncAction {
type: Actions.SET_PROMPT_ZERO_SYNC
promptIfNeeded: boolean
}

export const setPromptZeroSync = (promptIfNeeded: boolean): SetPromptZeroSyncAction => ({
type: Actions.SET_PROMPT_ZERO_SYNC,
promptIfNeeded,
})

interface SetGethConnectedAction {
type: Actions.SET_GETH_CONNECTED
connected: boolean
}

export const setGethConnected = (connected: boolean): SetGethConnected => ({
export const setGethConnected = (connected: boolean): SetGethConnectedAction => ({
type: Actions.SET_GETH_CONNECTED,
connected,
})

export type ActionTypes = SetInitState | SetGethConnected
export type ActionTypes = SetInitStateAction | SetGethConnectedAction | SetPromptZeroSyncAction
Loading