Skip to content
This repository has been archived by the owner on Jun 11, 2019. It is now read-only.

#419 Upload Profile Picture Button Styles #432

Merged
merged 15 commits into from
Jan 11, 2019
42 changes: 33 additions & 9 deletions src/Accounts/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {Text, View, Image, TextInput, ScrollView, TouchableHighlight} from 'reac
import SharedStyles from '../styles/shared/sharedStyles'
import AccountStyles from '../styles/account/accountStyles'
import TicketWalletStyles from '../styles/tickets/ticketWalletStyles'
import avatarPlaceholder from '../../assets/avatar-female.png'
import {autotrim} from '../string'
import {accessCameraRoll, selectCameraRollImage} from '../image'
import {uploadImageToCloudinary} from '../cloudinary'

const styles = SharedStyles.createStyles()
const accountStyles = AccountStyles.createStyles()
Expand All @@ -19,15 +20,29 @@ export default class AccountDetails extends Component {
}
}

updateUser = (attr) => (value) => {
_updateUser(attr, value) {
const user = {...this.state.user}

user[attr] = value
this.setState({user})
}

updateUser = (attr) => (value) => this._updateUser(attr, value)

async prepareUserChanges() {
const {user, newProfilePic} = this.state
const changes = {...user}

if (newProfilePic) {
changes.profile_pic_url = await uploadImageToCloudinary(newProfilePic)
}

return changes
}

saveChanges = async () => {
const result = await this.props.screenProps.auth.updateCurrentUser(this.state.user)
const changes = await this.prepareUserChanges()
const result = await this.props.screenProps.auth.updateCurrentUser(changes)

if (result.error) {
this.onSaveChangesError(result)
Expand All @@ -49,6 +64,18 @@ export default class AccountDetails extends Component {
alert(`There was a problem:\n\n${msg}`)
}

onPressPictureButton = async () => {
if (await accessCameraRoll()) {
this.setState({newProfilePic: await selectCameraRollImage()})
}
}

get profilePicSourceToDisplay() {
const uri = this.state.newProfilePic || this.state.user.profile_pic_url

return uri ? {uri} : null
}

render() {
const {
props: {
Expand All @@ -57,28 +84,25 @@ export default class AccountDetails extends Component {
},
state: {
user,
}
},
} = this

return (
<ScrollView showsVerticalScrollIndicator={false} style={styles.containerDark}>
<View style={styles.paddingVerticalMedium}>

{false && // TODO: Re-enable when functionality is implemented.
<View style={accountStyles.rowContainer}>
<View style={accountStyles.row}>
<View style={[ticketWalletStyles.avatarContainer, accountStyles.avatarContainer]}>
<Image
style={ticketWalletStyles.avatar}
source={avatarPlaceholder}
source={this.profilePicSourceToDisplay}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this show a placeholder if profilePicSourceToDisplay returns null?

/>
</View>
<TouchableHighlight style={styles.flexColumnCenter}>
<Text style={styles.buttonSecondaryText} onPress={() => navigate('ChangePhoto')}>Change Profile Photo</Text>
<Text style={styles.buttonSecondaryText} onPress={this.onPressPictureButton}>Change Profile Photo</Text>
</TouchableHighlight>
</View>
</View>
}

<View style={accountStyles.inputContainer}>
<View style={accountStyles.row}>
Expand Down
13 changes: 0 additions & 13 deletions src/Accounts/changePhoto.js

This file was deleted.

3 changes: 2 additions & 1 deletion src/Accounts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ModalStyles from '../styles/shared/modalStyles'
import coverPhotoPlaceholder from '../../assets/account-placeholder-bkgd.png'
import qrCodePlaceholder from '../../assets/qr-code-placeholder.png'
import qrCodeIcon from '../../assets/qr-code-small.png'
import {username} from '../string'

const styles = SharedStyles.createStyles()
const accountStyles = AccountStyles.createStyles()
Expand Down Expand Up @@ -110,7 +111,7 @@ export default class Account extends Component {

<View style={accountStyles.accountHeaderWrapper}>
<View>
<Text style={accountStyles.accountEmailHeader}>{user.first_name} {user.last_name}</Text>
<Text style={accountStyles.accountEmailHeader}>{username(user)}</Text>
<View style={accountStyles.emailWrapper}>
<Icon style={accountStyles.emailIcon} name="mail" />
<Text style={accountStyles.accountEmail}>{user.email}</Text>
Expand Down
7 changes: 0 additions & 7 deletions src/Accounts/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Notifications from './notifications'
import Billing from './billing'
import OrderHistory from './orderHistory'
import SignedOut from './signedOut'
import ChangePhoto from './changePhoto'
import EventManager from './eventManager'
import EventScanner from './eventScanner'
import Icon from 'react-native-vector-icons/MaterialIcons'
Expand Down Expand Up @@ -44,12 +43,6 @@ const ROUTES = {
screen: AccountDetails,
navigationOptions: ({navigation}) => (defaultNavOptions('Account', navigation)),
},
ChangePhoto: {
screen: ChangePhoto,
navigationOptions: {
title: 'Change Photo',
},
},
SignedOut: {
screen: SignedOut,
navigationOptions: {
Expand Down
15 changes: 10 additions & 5 deletions src/Auth/AuthLoadingScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import {Subscribe} from 'unstated'
import {AuthContainer} from '../state/authStateProvider'
import {retrieveTokens} from '../constants/Server'

function shouldDoNextSignUpStep({first_name: first, last_name: last}) {
return !(first || last)
}

class AuthStore extends Component {
static propTypes = {
navigation: PropTypes.object.isRequired,
Expand All @@ -26,13 +30,14 @@ class AuthStore extends Component {
const {userToken, refreshToken} = await retrieveTokens()

if (userToken && refreshToken) {
const {state: {currentUser}} = auth

if (Object.keys(currentUser).length === 0) {
if (!auth.state.currentUser.user) {
await auth.getCurrentUser(navigate, userToken, refreshToken)
}

navigate('App')
if (!shouldDoNextSignUpStep(auth.state.currentUser.user)) {
navigate('App')
} else {
navigate('SignUpNext')
}
} else {
navigate('Auth')
}
Expand Down
2 changes: 0 additions & 2 deletions src/Auth/LogIn.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,12 @@ export default class LogIn extends Component {
keyboardType="email-address"
style={formStyles.input}
placeholder="Email Address"
searchIcon={{size: 24}}
underlineColorAndroid="transparent"
onChangeText={autotrim((email) => this.setState({email}))}
/>
<TextInput
style={formStyles.input}
placeholder="Password"
searchIcon={{size: 24}}
underlineColorAndroid="transparent"
secureTextEntry
onChangeText={(password) => this.setState({password})}
Expand Down
61 changes: 25 additions & 36 deletions src/Auth/SignUp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {View, KeyboardAvoidingView, ScrollView, Text, TextInput, TouchableHighlight} from 'react-native'
import Icon from 'react-native-vector-icons/MaterialIcons'
import {Feather} from '@expo/vector-icons'
import {LinearGradient} from 'expo'
import SharedStyles from '../styles/shared/sharedStyles'
import FormStyles from '../styles/shared/formStyles'
import LoginStyles from '../styles/login/loginStyles'
import { Constants, WebBrowser } from 'expo';
import { autotrim } from '../string';
import {accessCameraRoll, selectCameraRollImage} from '../image'
import {uploadImageToCloudinary} from '../cloudinary'

const styles = SharedStyles.createStyles()
const formStyles = FormStyles.createStyles()
Expand Down Expand Up @@ -39,39 +42,28 @@ export default class SignUp extends Component {
this.state = {
email: '',
password: '',
first_name: '',
last_name: '',
}
}

signUp = async () => {
const {screenProps: {auth}, navigation: {navigate}} = this.props
const {email, password, first_name, last_name} = this.state
const {email, password} = this.state

// Should register & login on success
await auth.signUp({email, password, first_name, last_name}, navigate)
await auth.signUp({email, password}, navigate)
}

render() {
return (
<KeyboardAvoidingView style={loginStyles.container} behavior="padding" enabled>
<ScrollView showsVerticalScrollIndicator={false}>
<View>
<Text style={loginStyles.smallText}>
Secure your experiences
</Text>
<Text style={[styles.headerSecondary, styles.textCenter, styles.paddingBottomJumbo]}>
Create your account
</Text>
<TextInput
style={formStyles.input}
placeholder="First Name"
underlineColorAndroid="transparent"
onChangeText={autotrim((first_name) => this.setState({first_name}))}
/>
<TextInput
style={formStyles.input}
placeholder="Last Name"
underlineColorAndroid="transparent"
onChangeText={autotrim((last_name) => this.setState({last_name}))}
/>
<TextInput
keyboardType="email-address"
style={formStyles.input}
Expand All @@ -86,6 +78,7 @@ export default class SignUp extends Component {
underlineColorAndroid="transparent"
onChangeText={(password) => this.setState({password})}
/>

<TouchableHighlight style={loginStyles.buttonContainer} onPress={this.signUp}>
<LinearGradient
start={{x: 0, y: 0}}
Expand All @@ -98,27 +91,23 @@ export default class SignUp extends Component {
</TouchableHighlight>
</View>

<View>
<View style={loginStyles.disclaimerWrapper}>
<Text style={[loginStyles.mutedText, styles.textCenter]}>By signing up you agree to our</Text>
<View
style={{flexDirection: 'row',justifyContent: 'center'}}
>
<TouchableHighlight
style={{flexDirection:'column'}}
onPress={ () => {
WebBrowser.openBrowserAsync('https://www.bigneon.com/terms.html')
}}>
<Text style={[loginStyles.mutedText, styles.textCenter, styles.textUnderline]}>Terms of Service</Text>
</TouchableHighlight>
<Text style={{flexDirection:'column'}}> &amp; </Text>
<TouchableHighlight
style={{flexDirection:'column'}}
onPress={ () => {
WebBrowser.openBrowserAsync('https://www.bigneon.com/privacy.html')
}}
>
<Text style={[loginStyles.mutedText, styles.textCenter, styles.textUnderline]}>Privacy Policy</Text>
</TouchableHighlight>
<View style={{flexDirection: 'row',justifyContent: 'center'}}>
<TouchableHighlight
onPress={ () => {
WebBrowser.openBrowserAsync('https://www.bigneon.com/terms.html')
}}>
<Text style={[loginStyles.mutedText, styles.textCenter, styles.textUnderline]}>Terms of Service</Text>
</TouchableHighlight>
<Text style={loginStyles.mutedText}> &amp; </Text>
<TouchableHighlight
onPress={ () => {
WebBrowser.openBrowserAsync('https://www.bigneon.com/privacy.html')
}}
>
<Text style={[loginStyles.mutedText, styles.textCenter, styles.textUnderline]}>Privacy Policy</Text>
</TouchableHighlight>
</View>
</View>
</ScrollView>
Expand Down
Loading