Skip to content

Commit

Permalink
feat: onboarding screen with notification permission
Browse files Browse the repository at this point in the history
  • Loading branch information
Guillaume Louvigny authored and 90dy committed Jan 22, 2019
1 parent f2fb899 commit c80d7d7
Show file tree
Hide file tree
Showing 16 changed files with 344 additions and 8 deletions.
6 changes: 5 additions & 1 deletion client/react-native/common/components/App.js
Expand Up @@ -110,8 +110,11 @@ export default class App extends PureComponent {
this.setState({ deepLink: null })
}

setDeepLink (deepLink) {
this.setState({ deepLink })
}

render () {
console.log(this.onAnimationFinished)
const { loading, deepLink, hide, progress } = this.state
return (
<I18nextProvider i18n={i18n}>
Expand All @@ -138,6 +141,7 @@ export default class App extends PureComponent {
}}
screenProps={{
deepLink,
setDeepLink: (deepLink) => this.setDeepLink(deepLink),
clearDeepLink: () => this.clearDeepLink(),
}}
/> : null }
Expand Down
11 changes: 8 additions & 3 deletions client/react-native/common/components/Screens/Accounts/Auth.js
Expand Up @@ -63,7 +63,9 @@ class Auth extends PureComponent {
}
}

open = async nickname => {
open = async (nickname, options) => {
let { firstLaunch } = options || {}

if (nickname == null) {
await this.init()
const list = await this.list()
Expand All @@ -78,7 +80,10 @@ class Auth extends PureComponent {
nickname = list[0]
}
await this.start(nickname)
this.props.navigation.navigate('accounts/current')

this.props.navigation.navigate('accounts/current', {
firstLaunch,
})
}

async componentDidMount () {
Expand Down Expand Up @@ -147,7 +152,7 @@ class Auth extends PureComponent {
value={this.state.nickname}
/>
<TouchableOpacity
onPress={() => this.open(this.state.nickname)}
onPress={() => this.open(this.state.nickname, { firstLaunch: true })}
disabled={this.state.nickname.length === 0}
>
<Text
Expand Down
Expand Up @@ -111,6 +111,7 @@ class Current extends PureComponent {
...this.props.screenProps,
context,
availableUpdate,
firstLaunch: this.props.navigation.getParam('firstLaunch', false),
}}
/>
</RelayContext.Provider>
Expand Down
@@ -0,0 +1,22 @@
import React from 'react'
import { ScrollView, Text, View } from 'react-native'
import { Flex } from '../../../Library'
import { withNavigation } from 'react-navigation'
import * as onboardingStyle from './style'
import { NextButton, SkipButton } from './Button'
import { withNamespaces } from 'react-i18next'

const Backup = ({ navigation, t }) => <ScrollView alwaysBounceVertical={false}>
<Flex.Rows style={onboardingStyle.view}>
<Text style={onboardingStyle.title}>{t('onboarding.backup.title')}</Text>
<Text style={onboardingStyle.help}>{t('onboarding.backup.help')}</Text>
<Text style={onboardingStyle.disclaimer}>{t('onboarding.backup.disclaimer')}</Text>
<View style={{ height: 60, flexDirection: 'row' }}>
<SkipButton
onPress={() => navigation.navigate('onboarding/ready')}>{t('skip')}</SkipButton>
<NextButton>{t('onboarding.backup.action')}</NextButton>
</View>
</Flex.Rows>
</ScrollView>

export default withNamespaces()(withNavigation(Backup))
@@ -0,0 +1,7 @@
import React from 'react'
import { Button } from '../../../Library'
import colors from '../../../../constants/colors'

export const SkipButton = props => <Button {...props} left color={colors.darkGrey} margin padding small rounded />

export const NextButton = props => <Button {...props} color={colors.inputGrey} background={colors.blue} small margin padding center rounded />
@@ -0,0 +1,29 @@
import React from 'react'
import { Text, View, ScrollView } from 'react-native'
import { Flex } from '../../../Library'
import { withNavigation } from 'react-navigation'
import * as onboardingStyle from './style'
import { NextButton, SkipButton } from './Button'
import { withNamespaces } from 'react-i18next'
import { withCurrentUser } from '../../../../utils/contact'
import { extractPublicKeyFromId, shareLinkSelf } from '../../../../helpers/contacts'

const Contacts = ({ navigation, currentUser, t }) => <ScrollView alwaysBounceVertical={false}>
<Flex.Rows style={onboardingStyle.view}>
<Text style={onboardingStyle.title}>{t('onboarding.contacts.title')}</Text>
<Text style={onboardingStyle.help}>{t('onboarding.contacts.link-help')}</Text>
<Text style={onboardingStyle.disclaimer}>{t('onboarding.contacts.link-disclaimer')}</Text>
<View style={{ height: 60, flexDirection: 'row' }}>
<SkipButton>{' '}</SkipButton>
<NextButton onPress={() => shareLinkSelf({ id: extractPublicKeyFromId(currentUser.id), displayName: currentUser.displayName })}>{t('onboarding.contacts.link-share')}</NextButton>
</View>
<Text style={onboardingStyle.help}>{t('onboarding.contacts.phone-help')}</Text>
<Text style={onboardingStyle.disclaimer}>{t('onboarding.contacts.phone-disclaimer')}</Text>
<View style={{ height: 60, flexDirection: 'row' }}>
<SkipButton onPress={() => navigation.navigate('onboarding/backup')}>{t('skip')}</SkipButton>
<NextButton>{t('onboarding.contacts.phone-link')}</NextButton>
</View>
</Flex.Rows>
</ScrollView>

export default withCurrentUser(withNamespaces()(withNavigation(Contacts)), { showOnlyLoaded: true })
@@ -0,0 +1,32 @@
import React from 'react'
import { Text, Platform, View, ScrollView } from 'react-native'
import { Flex } from '../../../Library'
import { withNavigation } from 'react-navigation'
import * as onboardingStyle from './style'
import { NextButton, SkipButton } from './Button'
import { enableNativeNotifications } from '../../../../helpers/notifications'
import { withNamespaces } from 'react-i18next'
import { RelayContext } from '../../../../relay'

const Notifications = ({ navigation, t }) =>
<RelayContext.Consumer>{context =>
<ScrollView alwaysBounceVertical={false}>
<Flex.Rows style={onboardingStyle.view}>
<Text style={onboardingStyle.title}>{t('onboarding.notifications.title')}</Text>
<Text style={onboardingStyle.help}>{t('onboarding.notifications.help')}</Text>
<Text style={onboardingStyle.disclaimer}>
{Platform.OS === 'ios' && t('onboarding.notifications.disclaimer-apple')}
{Platform.OS === 'android' && t('onboarding.notifications.disclaimer-google')}
</Text>
<View style={{ height: 60, flexDirection: 'row' }}>
<SkipButton
onPress={() => navigation.navigate('onboarding/contacts')}>{t('skip')}</SkipButton>
<NextButton onPress={async () => {
await enableNativeNotifications({ context })
navigation.navigate('onboarding/contacts')
}}>{t('onboarding.notifications.enable')}</NextButton>
</View>
</Flex.Rows>
</ScrollView>
}</RelayContext.Consumer>
export default withNamespaces()(withNavigation(Notifications))
@@ -0,0 +1,20 @@
import React from 'react'
import { ScrollView, Text, View } from 'react-native'
import { Flex } from '../../../Library'
import { withNavigation } from 'react-navigation'
import * as onboardingStyle from './style'
import { NextButton } from './Button'
import { withNamespaces } from 'react-i18next'

const Ready = ({ navigation, t }) =>
<ScrollView alwaysBounceVertical={false}>
<Flex.Rows style={onboardingStyle.view}>
<Text style={onboardingStyle.title}>{t('onboarding.ready.title')}</Text>
<View style={{ height: 60, flexDirection: 'row' }}>
<NextButton
onPress={() => navigation.navigate('switch/main')}>{t('close')}</NextButton>
</View>
</Flex.Rows>
</ScrollView>

export default withNamespaces()(withNavigation(Ready))
@@ -0,0 +1,27 @@
import React from 'react'
import { View, Text, ScrollView } from 'react-native'
import { Flex } from '../../../Library'
import { withNavigation } from 'react-navigation'
import * as onboardingStyle from './style'
import { NextButton, SkipButton } from './Button'
import { withNamespaces } from 'react-i18next'

const Welcome = ({ navigation, t }) =>
<ScrollView alwaysBounceVertical={false}>
<Flex.Rows style={onboardingStyle.view}>
<Text style={onboardingStyle.title}>{t('onboarding.welcome.title')}</Text>
<Text style={onboardingStyle.help}>{t('onboarding.welcome.help-1')}</Text>
<Text style={onboardingStyle.help}>{t('onboarding.welcome.help-2')}</Text>
<Text style={onboardingStyle.disclaimer}>{t('onboarding.welcome.disclaimer')}</Text>
<View style={{ height: 60, flexDirection: 'row' }}>
<SkipButton
onPress={() => navigation.navigate('onboarding/ready')}
style={onboardingStyle.skipButton}>{t('onboarding.welcome.skip-everything')}</SkipButton>
<NextButton
onPress={() => navigation.navigate('onboarding/notifications')}
style={onboardingStyle.nextButton}>{t('next')}</NextButton>
</View>
</Flex.Rows>
</ScrollView>

export default withNamespaces()(withNavigation(Welcome))
@@ -0,0 +1,52 @@
import { createMaterialTopTabNavigator } from 'react-navigation'
import Welcome from './Welcome'
import Notifications from './Notifications'
import Contacts from './Contacts'
import Backup from './Backup'
import Ready from './Ready'
import { tabIcon } from '../../../../helpers/views'
import { tabNavigatorOptions } from '../../../../constants/styling'

export default createMaterialTopTabNavigator(
{
'onboarding/welcome': {
screen: Welcome,
navigationOptions: () => ({
title: '',
tabBarIcon: tabIcon('lock'),
}),
},
'onboarding/notifications': {
screen: Notifications,
navigationOptions: () => ({
title: '',
tabBarIcon: tabIcon('bell'),
}),
},
'onboarding/contacts': {
screen: Contacts,
navigationOptions: () => ({
title: '',
tabBarIcon: tabIcon('users'),
}),
},
'onboarding/backup': {
screen: Backup,
navigationOptions: () => ({
title: '',
tabBarIcon: tabIcon('archive'),
}),
},
'onboarding/ready': {
screen: Ready,
navigationOptions: () => ({
title: '',
tabBarIcon: tabIcon('check-circle'),
}),
},
},
{
initialRouteName: 'onboarding/welcome',
...tabNavigatorOptions,
},
)
@@ -0,0 +1,30 @@
import colors from '../../../../constants/colors'

export const title = {
fontSize: 24,
color: colors.blue,
marginBottom: 20,
marginTop: 20,
textAlign: 'center',
}

export const help = {
fontSize: 16,
color: colors.fakeBlack,
marginBottom: 12,
}

export const disclaimer = {
fontSize: 12,
color: colors.darkGrey,
marginBottom: 6,
}

export const view = {
backgroundColor: colors.white,
marginLeft: 'auto',
marginRight: 'auto',
paddingLeft: 10,
paddingRight: 10,
maxWidth: 400,
}
34 changes: 31 additions & 3 deletions client/react-native/common/components/Screens/Main.js
@@ -1,5 +1,9 @@
import { Animated, Easing, Platform } from 'react-native'
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation'
import { Animated, Easing, Platform, View } from 'react-native'
import {
createStackNavigator,
createBottomTabNavigator,
createSwitchNavigator,
} from 'react-navigation'
import React from 'react'

import { EventListFilterModal } from './Settings/Devtools/EventList'
Expand All @@ -11,6 +15,7 @@ import Settings from './Settings'
import ContactCardModal from './Contacts/ContactCardModal'
import { ViewExportComponent } from '../../helpers/saveViewToCamera'
import I18n from 'i18next'
import Onboarding from './Accounts/Onboarding'

const TabBarIcon = (tintColor, routeName, badgeValue) => {
let iconName = {
Expand Down Expand Up @@ -96,10 +101,27 @@ export const tabs = createBottomTabNavigator(
}
)

class Picker extends React.Component {
constructor (props) {
super(props)

this.props.navigation.navigate(
this.props.screenProps.firstLaunch
? 'switch/onboarding'
: 'switch/main'
)
}

render () {
return <View />
}
}

// Navigator handling modals
export default createStackNavigator(
const Main = createStackNavigator(
{
tabs: tabs,
'main/onboarding': Onboarding,
'modal/devtools/event/list/filters': {
screen: EventListFilterModal,
},
Expand Down Expand Up @@ -143,3 +165,9 @@ export default createStackNavigator(
}),
}
)

export default createSwitchNavigator({
'switch/picker': Picker,
'switch/onboarding': Onboarding,
'switch/main': Main,
})
Expand Up @@ -300,6 +300,11 @@ export default class List extends PureComponent {
title={'Notifications'}
onPress={() => navigation.navigate('devtools/notifications')}
/>
<Menu.Item
icon='sunrise'
title='Show onboarding'
onPress={() => navigation.navigate('switch/onboarding')}
/>
<Menu.Item
icon='check-circle'
title='Integration tests'
Expand Down
Expand Up @@ -2,7 +2,7 @@ import { graphql } from 'react-relay'

import { subscriber } from '../../relay'

const CommitLogStream = graphql`
export const CommitLogStream = graphql`
subscription CommitLogStreamSubscription {
CommitLogStream(T: true) {
operation
Expand Down

0 comments on commit c80d7d7

Please sign in to comment.