Skip to content

Commit

Permalink
Merge pull request #1472 from Emurgo/tos
Browse files Browse the repository at this point in the history
move tos, redux -> component state
  • Loading branch information
vsubhuman committed Jul 24, 2021
2 parents 1ffc9f4 + 9a7f3b8 commit 59df809
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 119 deletions.
13 changes: 1 addition & 12 deletions src/actions/language.js
@@ -1,6 +1,6 @@
// @flow

import {writeAppSettings, APP_SETTINGS_KEYS, loadTOS} from '../helpers/appSettings'
import {writeAppSettings, APP_SETTINGS_KEYS} from '../helpers/appSettings'

import {type Dispatch} from 'redux'

Expand All @@ -16,20 +16,9 @@ export const changeLanguage = (languageCode: string) => (dispatch: Dispatch<any>
})
}

export const changeTOSLanguage = (tos: string) => (dispatch: Dispatch<any>) => {
dispatch({
path: ['tos'],
payload: tos,
reducer: (state, tos) => tos,
type: 'CHANGE_TOS_LANGUAGE',
})
}

export const changeAndSaveLanguage = (languageCode: string) => async (dispatch: Dispatch<any>) => {
await writeAppSettings(APP_SETTINGS_KEYS.LANG, languageCode)
const tos = await loadTOS(languageCode)

dispatch(changeTOSLanguage(tos))
dispatch(changeLanguage(languageCode))
}

Expand Down
27 changes: 12 additions & 15 deletions src/components/Common/TermsOfService.js
@@ -1,24 +1,21 @@
// @flow

import React from 'react'
import {connect} from 'react-redux'
import {compose} from 'redux'
import {useSelector} from 'react-redux'
import Markdown from 'react-native-easy-markdown'
import {loadTOS} from '../../helpers/appSettings'
import {ActivityIndicator} from 'react-native'
import {languageSelector} from '../../selectors'

import type {ComponentType} from 'react'
const TermsOfService = () => {
const [tos, setTos] = React.useState()
const languageCode = useSelector(languageSelector)

type Props = {
tos: string,
}
React.useEffect(() => {
loadTOS(languageCode).then(setTos)
}, [languageCode])

const TermsOfService = ({tos}: Props) => {
return <Markdown>{tos}</Markdown>
return tos ? <Markdown>{tos}</Markdown> : <ActivityIndicator size={'large'} color={'black'} />
}

export default (compose(
connect((state) => {
return {
tos: state.tos,
}
}),
)(TermsOfService): ComponentType<any>)
export default TermsOfService
160 changes: 74 additions & 86 deletions src/components/FirstRun/AcceptTermsOfServiceScreen.js
@@ -1,24 +1,23 @@
// @flow

import React from 'react'
import {connect} from 'react-redux'
import {compose} from 'redux'
import {useDispatch} from 'react-redux'
import {SafeAreaView} from 'react-native-safe-area-context'
import {withStateHandlers, withHandlers} from 'recompose'
import {ScrollView, Platform} from 'react-native'
import {ScrollView, Platform, View} from 'react-native'
import {injectIntl, defineMessages, type IntlShape} from 'react-intl'

import TermsOfService from '../Common/TermsOfService'
import {Checkbox, Button, StatusBar, PleaseWaitModal} from '../UiKit'
import {FIRST_RUN_ROUTES} from '../../RoutesList'
import {isSystemAuthEnabledSelector} from '../../selectors'
import {acceptAndSaveTos, setSystemAuth, signin} from '../../actions'
import {canBiometricEncryptionBeEnabled} from '../../helpers/deviceSettings'
import {CONFIG} from '../../config/config'

import styles from './styles/AcceptTermsOfServiceScreen.styles'
import globalMessages from '../../i18n/global-messages'

import type {Navigation} from '../../types/navigation'

const messages = defineMessages({
aggreeClause: {
id: 'components.firstrun.acepttermsofservicescreen.aggreeClause',
Expand All @@ -36,86 +35,75 @@ const messages = defineMessages({

type Props = {
intl: IntlShape,
acceptedTos: boolean,
setAcceptedTos: (accepted: boolean) => any,
handleAccepted: () => any,
savingConsent: boolean,
navigation: Navigation,
}

const AcceptTermsOfServiceScreen = ({intl, navigation}: Props) => {
const [acceptedTos, setAcceptedTos] = React.useState(false)
const [savingConsent, setSavingConsent] = React.useState(false)

const dispatch = useDispatch()
const handleAccepted = async () => {
setSavingConsent(true)
await dispatch(acceptAndSaveTos())

const canSystemAuthBeEnabled = await canBiometricEncryptionBeEnabled()

// temporary disable biometric auth for Android SDK >= 29
// TODO(v-almonacid): re-enable for Android SDK >= 29 once the module
// is updated
const shouldNotEnableBiometricAuth =
Platform.OS === 'android' && CONFIG.ANDROID_BIO_AUTH_EXCLUDED_SDK.includes(Platform.Version)

if (canSystemAuthBeEnabled && !shouldNotEnableBiometricAuth) {
await dispatch(setSystemAuth(true))
// note(v-almonacid) here we don't setSavingConsent(false)
// because signin() will likely unmount the component before the
// update is dispatched
dispatch(signin())
} else {
setSavingConsent(false)
navigation.navigate(FIRST_RUN_ROUTES.CUSTOM_PIN)
}
}

return (
<SafeAreaView edges={['left', 'right', 'bottom']} style={styles.safeAreaView}>
<StatusBar type="dark" />

<ScrollView contentContainerStyle={styles.contentContainer}>
<TermsOfService />
</ScrollView>

<Spacer />

<Footer>
<Checkbox
checked={acceptedTos}
text={intl.formatMessage(messages.aggreeClause)}
onChange={setAcceptedTos}
testID="acceptTosCheckbox"
/>

<Spacer />

<Button
onPress={handleAccepted}
disabled={!acceptedTos}
title={intl.formatMessage(messages.continueButton)}
testID="acceptTosButton"
/>
</Footer>

<PleaseWaitModal
title={intl.formatMessage(messages.savingConsentModalTitle)}
spinnerText={intl.formatMessage(globalMessages.pleaseWait)}
visible={savingConsent}
/>
</SafeAreaView>
)
}
export default injectIntl(AcceptTermsOfServiceScreen)

const AcceptTermsOfServiceScreen = ({intl, acceptedTos, setAcceptedTos, handleAccepted, savingConsent}: Props) => (
<SafeAreaView style={styles.safeAreaView}>
<StatusBar type="dark" />

<ScrollView>
<TermsOfService />
</ScrollView>

<Checkbox
style={styles.checkbox}
checked={acceptedTos}
text={intl.formatMessage(messages.aggreeClause)}
onChange={setAcceptedTos}
testID="acceptTosCheckbox"
/>
<Button
onPress={handleAccepted}
disabled={!acceptedTos}
title={intl.formatMessage(messages.continueButton)}
testID="acceptTosButton"
/>

<PleaseWaitModal
title={intl.formatMessage(messages.savingConsentModalTitle)}
spinnerText={intl.formatMessage(globalMessages.pleaseWait)}
visible={savingConsent}
/>
</SafeAreaView>
)

export default injectIntl(
compose(
connect(
(state) => ({
isSystemAuthEnabled: isSystemAuthEnabledSelector(state),
}),
{acceptAndSaveTos, setSystemAuth, signin},
),
withStateHandlers(
{
acceptedTos: false,
savingConsent: false,
},
{
setAcceptedTos: () => (acceptedTos) => ({acceptedTos}),
setSavingConsent: () => (savingConsent) => ({savingConsent}),
},
),
withHandlers({
handleAccepted:
({navigation, acceptAndSaveTos, setSystemAuth, setSavingConsent, signin}) =>
async () => {
setSavingConsent(true)
await acceptAndSaveTos()

const canSystemAuthBeEnabled = await canBiometricEncryptionBeEnabled()

// temporary disable biometric auth for Android SDK >= 29
// TODO(v-almonacid): re-enable for Android SDK >= 29 once the module
// is updated
const shouldNotEnableBiometricAuth =
Platform.OS === 'android' && CONFIG.ANDROID_BIO_AUTH_EXCLUDED_SDK.includes(Platform.Version)

if (canSystemAuthBeEnabled && !shouldNotEnableBiometricAuth) {
await setSystemAuth(true)
// note(v-almonacid) here we don't setSavingConsent(false)
// because signin() will likely unmount the component before the
// update is dispatched
signin()
} else {
setSavingConsent(false)
navigation.navigate(FIRST_RUN_ROUTES.CUSTOM_PIN)
}
},
}),
)(AcceptTermsOfServiceScreen),
)
const Footer = ({children}: {children: React$Node}) => <View style={styles.footer}>{children}</View>
const Spacer = () => <View style={styles.spacer} />
Expand Up @@ -6,9 +6,14 @@ export default StyleSheet.create({
safeAreaView: {
backgroundColor: '#fff',
flex: 1,
},
contentContainer: {
padding: 16,
},
checkbox: {
marginVertical: 15,
footer: {
paddingHorizontal: 16,
},
spacer: {
height: 16,
},
})
4 changes: 2 additions & 2 deletions src/components/Settings/TermsOfServiceScreen.js
Expand Up @@ -10,10 +10,10 @@ import TermsOfService from '../Common/TermsOfService'
import styles from './styles/TermsOfServiceScreen.styles'

const TermsOfServiceScreen = () => (
<SafeAreaView style={styles.safeAreaView}>
<SafeAreaView edges={['left', 'right', 'bottom']} style={styles.safeAreaView}>
<StatusBar type="dark" />

<ScrollView>
<ScrollView contentContainerStyle={styles.contentContainer}>
<TermsOfService />
</ScrollView>
</SafeAreaView>
Expand Down
18 changes: 18 additions & 0 deletions src/components/Settings/TermsOfServiceScreen.stories.js
@@ -0,0 +1,18 @@
// @flow

import React from 'react'
import {StyleSheet, View} from 'react-native'

import {storiesOf} from '@storybook/react-native'

import TermsOfServiceScreen from './TermsOfServiceScreen'

const styles = StyleSheet.create({
termsOfServiceScreen: {
flex: 1,
},
})

storiesOf('TermsOfServiceScreen', module)
.addDecorator((getStory) => <View style={styles.termsOfServiceScreen}>{getStory()}</View>)
.add('Default', () => <TermsOfServiceScreen />)
2 changes: 2 additions & 0 deletions src/components/Settings/styles/TermsOfServiceScreen.styles.js
Expand Up @@ -6,6 +6,8 @@ export default StyleSheet.create({
safeAreaView: {
backgroundColor: '#fff',
flex: 1,
},
contentContainer: {
padding: 16,
},
})
2 changes: 0 additions & 2 deletions src/state.js
Expand Up @@ -81,7 +81,6 @@ export type State = {
isAppInitialized: boolean,
isAuthenticated: boolean,
isKeyboardOpen: boolean,
tos: string,
appSettings: {
acceptedTos: boolean,
installationId: ?string,
Expand Down Expand Up @@ -159,7 +158,6 @@ export const getInitialState = (): State => ({
isAppInitialized: false,
isAuthenticated: false,
isKeyboardOpen: false,
tos: '',
appSettings: {
acceptedTos: false,
languageCode: 'en-US',
Expand Down

0 comments on commit 59df809

Please sign in to comment.