Expo / RN - Get face landmarks - javascript

I have a working code based on simple examples from the official documentation:
https://docs.expo.io/versions/latest/sdk/camera and https://docs.expo.io/versions/latest/sdk/facedetector.
It is said "While detecting faces, FaceDetector will emit object events of the following shape..."
But I don't understand how I can access the values of these objects. Tried all possible combinations - no success. What I am doing wrong? Can somebody help please?
The function "handleFacesDetected" is invoked while a face is detected but can't access the data.
This is the code:
import React from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { Camera, Permissions, FaceDetector } from 'expo';
export default class CameraExample extends React.Component {
state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
};
async componentWillMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === 'granted' });
}
handleFacesDetected(){
// it gets here while the face is detected. how to access the data?
}
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
} else {
return (
<View style={{ flex: 1 }}>
<Camera
style={{ flex: 1 }}
type={this.state.type}
onFacesDetected={this.handleFacesDetected}
faceDetectorSettings={{
mode: FaceDetector.Constants.Mode.accurate,
detectLandmarks: FaceDetector.Constants.Mode.all,
runClassifications: FaceDetector.Constants.Mode.all,
}}
>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
this.setState({
type: this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
});
}}>
<Text
style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
{' '}Flip{' '}
</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
}
}

Use this
handleFacesDetected = async ({ faces }) => {
if(faces.length === 1){
this.setState({ face: true });
}
}

Related

Issue with react-native-purchases and revenueCat

I am having an issue with my code for my in-app purchases. The use is allowed to buy 'emblems' which should be added to the user through asyncStorage. However this is not the case. Below is all my code and I hope that someone can find a fix. I am currently testing Android only, and the code below is not a final code, but testing code I've been using. They are one time purchases.
This is where I set my API key
const APIKeys = {
google: "*myapikey*",
};
function App() {
useEffect(() => {
Purchases.setDebugLogsEnabled(true);
if (Platform.OS == "android") {
Purchases.configure({ apiKey: APIKeys.google });
}
}, []);
This is the page where everything is supposed to happen:
import * as React from 'react';
import { Button, View, Text, StyleSheet, Image, ScrollView, ImageBackground, TouchableOpacity, Alert} from 'react-native';
import BuyBox from '../components/BuyBox';
import TopBar from '../components/TopBar';
import AsyncStorage from '#react-native-async-storage/async-storage';
import { MaterialIcons } from '#expo/vector-icons';
import Purchases from 'react-native-purchases';
class PremiumScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
offerings: null,
items: null,
emblems: null,
firstCheckpoint: null,
secondCheckpoint: null,
thirdCheckpoint: null,
fourthCheckpoint: null,
fifthCheckpoint: null
};
}
render() {
let outerSize = 0;
let innerSize = 0;
return (
<ImageBackground style={styles.MB} source={require('../../assets/Backgrounds/MainBackground.png')}>
<View style={{flex: 1}}>
<ScrollView contentContainerStyle={{justifyContent: 'center', alignContent: 'center', alignItems: 'center', width: '100%'}}>
<View style={{flexDirection: 'row-reverse', width: '100%', marginHorizontal: 10, right: 8}}>
<TouchableOpacity onPress={() => Alert.alert("Help", "Emblems can be exchanged for three things: First, emblem for a premium trip. Second, two emblems for another save slot. Lastly, one emblem for a cooldown reset")}>
<TopBar />
</TouchableOpacity>
</View>
<Text style={styles.TitleText} onPress={() => console.log(this.state.offerings.emblems.availablePackages)} >Welcome to the Embassy!</Text>
<Text style={styles.SubTitle}>This is where you can purchase Emblems for Premium Trips!</Text>
<View style={{marginVertical: 10}}/>
<View style={{width: 450, height: 450}}>
<ScrollView contentContainerStyle={{justifyContent: 'center', alignContent: 'center', alignItems: 'center'}} horizontal disableIntervalMomentum pagingEnabled>
<BuyBox Price='$0.99' EN='1 Emblems' onPress={async () => {
const products = await Purchases.getProducts(["ispy_1_emblem"]);
const pkg = products.find(product => product.identifier === "ispy_1_emblem");
await Purchases.purchaseProduct(pkg.identifier);
AsyncStorage.getItem('emblems').then(value => {
if (value == null){
AsyncStorage.setItem('emblems', '1');
} else {
AsyncStorage.setItem('emblems', (Number(value) + 1).toString());
}
})
}}/>
<BuyBox Price='$3.99' EN='5 Emblems' onPress={async () => {
const products = await Purchases.getProducts(["ispy_5_emblem"]);
const pkg = products.find(product => product.identifier === "ispy_5_emblem");
await Purchases.purchaseProduct(pkg.identifier);
AsyncStorage.getItem('emblems').then(value => {
if (value == null){
AsyncStorage.setItem('emblems', '5');
} else {
AsyncStorage.setItem('emblems', (Number(value) + 5).toString());
}
})
}}/>
<BuyBox Price='$6.99' EN='10 Emblems' onPress={async () => {
const products = await Purchases.getProducts(["ispy_10_emblem"]);
const pkg = products.availablePackages.find(product => product.identifier === "ispy_10_emblem");
await Purchases.purchaseProduct(pkg.identifier);
AsyncStorage.getItem('emblems').then(value => {
if (value == null){
AsyncStorage.setItem('emblems', '10');
} else {
AsyncStorage.setItem('emblems', (Number(value) + 10).toString());
}
})
}}/>
<BuyBox Price='$12.99' EN='20 Emblems' onPress={async () => {
const products = await Purchases.getProducts(["ispy_20_emblem"]);
const pkg = products.availablePackages.find(product => product.identifier === "ispy_20_emblem");
await Purchases.purchaseProduct(pkg);
AsyncStorage.getItem('emblems').then(value => {
if (value == null){
AsyncStorage.setItem('emblems', '20');
} else {
AsyncStorage.setItem('emblems', (Number(value) + 20).toString());
}
})
}} />
<BuyBox Price='$24.99' EN='40 Emblems' onPress={async () => {
const products = await Purchases.getProducts();
const pkg = products.availablePackages.find(product => product.identifier === "ispy_20_emblem");
await Purchases.purchaseProduct(pkg);
AsyncStorage.getItem('emblems').then(value => {
if (value == null){
AsyncStorage.setItem('emblems', '20');
} else {
AsyncStorage.setItem('emblems', (Number(value) + 20).toString());
}
})
}}/>
<BuyBox Price='$48.99' EN='80 Emblems' onPress={async () => {
}}/>
</ScrollView>
</View>
<View style={{justifyContent: 'center', alignContent: "center", alignItems: "center", alignSelf: 'center'}}>
<MaterialIcons name="swipe" size={54} color="black" />
</View>
<View style={{margin: '5%'}}/>
<View style={{justifyContent: 'center', alignContent: 'center', alignItems: 'center'}}>
<Text style={styles.SubMain}>Want more information?</Text>
<TouchableOpacity style={{alignContent: 'center', alignItems: 'center', justifyContent: 'center', marginHorizontal: 5}} onPress={() => this.props.navigation.navigate('PrEinfo')}>
<Text style={styles.SubMain2}>Click Here!</Text>
</TouchableOpacity>
</View>
<Text>{this.state.firstCheckpoint}</Text>
<Text>{this.state.secondCheckpoint}</Text>
<Text>{this.state.thirdCheckpoint}</Text>
<Text>{this.state.fourthCheckpoint}</Text>
<Text>{this.state.fifthCheckpoint}</Text>
</ScrollView>
</View>
</ImageBackground>
)
}
}
const styles = StyleSheet.create({
MB: {
flex: 1,
alignContent: 'center',
alignItems: 'center',
justifyContent: 'flex-start',
padding: 5,
paddingTop: 42.5
},
Row:{
flexDirection: 'row',
margin: 10,
marginBottom: 0,
},
TitleText:{
fontSize: 28,
fontWeight: 'bold',
textAlign: 'center'
},
SubTitle:{
fontSize: 16,
textAlign: 'center',
fontWeight: '300'
},
SubMain:{
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center'
},
SubMain2:{
fontSize: 22,
fontWeight: 'bold',
color: 'dodgerblue',
textAlign: 'center'
}
})
export default PremiumScreen;
And this is everything from play console and revenue cat:
Currently, the code on the premiumScreen doesn't work; it doesn't do anything. The onpress does nothing, you see the effect occur, and know the onpress has run however nothing happens. It doesn't crash either.
Some key things to not are that I am testing not an emulator but through the internal testing via the play console. This means I have to do eas build for every change and I cannot see console.logs or try catch. I do have some states I used as checkpoints that are visible at the bottom but when I generally try to set a state to an error, it will normally just crash the app. Any help is appreciated :D

React Native module fails to load because of a single function that is not even invoked. Error : 'AppRegistry.registerComponent'

So I'm having some bundling problem with a single function that is not even invoked. const { status } = await BarCodeScanner.requestPermissionsAsync(); The function should be invoked when the QR code is scanned and the string information gets parsed and saved to a SQLite database. There is something wrong with bundling the app. I tried to set a setTimeOut at the root but to no avail. Here is the error That I'm getting:
ERROR TypeError: undefined is not an object (evaluating '_Splash.default.TABLE_REFERENCE')
LOG Running "main" with {"rootTag":91,"initialProps":{}}
ERROR Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.
Here is the actual screen. nothing fancy really.
import { StackScreenProps } from "#react-navigation/stack";
import { BarCodeScanner, BarCodeScannerResult } from "expo-barcode-scanner";
import AsyncStorage from "#react-native-async-storage/async-storage";
import React, { useEffect, useState } from "react";
import {
Alert,
StyleSheet,
Text,
useWindowDimensions,
View,
ScrollView,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { BackBar } from "../../components/BackBar";
import { useDispatch } from "react-redux";
import {
IntroScreen,
IntroStackParamList,
} from "../../navigation/intro/StackUtil";
import { EnumFonts } from "../../types/enums/fonts.enum";
import addSplashUriToDatabase from "../../database/addSplashUriToDatabase";
import { setStarter } from "../../store/starter/actions";
import { Camera } from "expo-camera";
interface Props
extends StackScreenProps<IntroStackParamList, IntroScreen.ScanQR> {}
const ScanQRScreen: React.FC<Props> = (props) => {
const [hasPermissions, setHasPermissions] = useState(false);
const [scanned, setScanned] = useState(false);
const [processing, setProcessing] = useState(false);
const { width, height } = useWindowDimensions();
const dispatch = useDispatch();
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermissions(status === "granted");
})();
}, []);
const handleBarCodeScanned = async ({ type, data }: BarCodeScannerResult) => {
setScanned(true);
console.log(
`Bar code with type ${type} and data ${data} has been scanned!`
);
try {
const success = await addSplashUriToDatabase(data);
if (success) {
// Navigate to other screen
dispatch(setStarter(false));
try {
const value = await AsyncStorage.setItem("#starter", "true");
if (value !== null) {
// value previously stored
// setStarter("false");
}
} catch (e) {
// error reading value
}
}
} catch (error) {
console.error(error);
Alert.alert(
"Fail to scan QR code",
"Please let us know, this could caused by invalid participant names.",
[
{
text: "OK",
},
// {text: 'Report Bug', onPress: failOnScan},
],
{ cancelable: true }
);
}
};
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView style={{ flex: 1, padding: "5%" }}>
<BackBar goBackFunction={props.navigation.goBack} />
<View
style={{ flex: 0.3, justifyContent: "space-evenly", marginTop: 30 }}
>
<Text
style={{
fontFamily: EnumFonts.BOLD,
fontSize: 30,
marginVertical: 10,
}}
>
Scan a Splash code
</Text>
<Text
style={{
fontFamily: EnumFonts.REGULAR,
fontSize: 20,
marginVertical: 10,
}}
>
Line up the Splash code in the red square. Ensure the other phone
has its screen brightness at maximum setting.
</Text>
</View>
<View style={{ flex: 0.6, justifyContent: "space-around" }}>
{hasPermissions && (
<>
<View
style={{
width: width * 0.8,
borderWidth: 5,
borderColor: scanned ? "green" : "red",
backgroundColor: "black",
alignSelf: "center",
}}
>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{
width: "100%",
height: height * 0.45,
borderWidth: 1,
borderColor: "red",
}}
/>
</View>
<Text
style={{
fontFamily: EnumFonts.REGULAR,
fontSize: 18,
textAlign: "center",
marginTop: 15,
}}
>
The square will turn green to indicate a successful scan
position
</Text>
</>
)}
{!hasPermissions && (
<Text
style={{
fontFamily: EnumFonts.MEDIUM,
fontSize: 20,
textAlign: "justify",
}}
>
Please allow us to use camera to scan qr
</Text>
)}
</View>
</ScrollView>
</SafeAreaView>
);
};
export default ScanQRScreen;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
});

Strange borders on production build in react native, but not in develope mode

In my App I have a screen that normally looks like this
but when I build for production the title wrapper gets pushed down a few pixels, which results in some strange formatting:
I don't really understand why the app looks different when build for release vs when I develop it.
I also tested it on multiple devices but I have the same error on all of them.
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';
import BottomBar from './component/BottomBar';
export default function ScanScreen({ navigation }) {
const [hasPermission, setHasPermission] = useState(null);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
navigation.navigate("Shelf", { shelfID: data.toString() })
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
<View style={styles.contentContainer}>
<View style={styles.titleWrapper}>
<Text style={styles.text}> Shelf Scanner </Text>
</View>
<View style={{flex: 1}}>
<BarCodeScanner
onBarCodeScanned={handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
</View>
</View>
<BottomBar navigation={navigation} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
flexDirection: 'row',
},
titleWrapper: {
width: '100%',
top: 30,
height: 50,
alignSelf: 'center',
alignItems: 'center',
backgroundColor: '#A2F5AA',
},
text: {
fontSize: 15,
justifyContent: 'center',
fontWeight: 'bold',
flex: 1,
marginTop: 10,
},
contentContainer: {
flex: 1
},
});
I fixed it by removing top: 30, from titleWrapper. The title is now offset in develop mode, but it at least looks correct in the production build

E-commerce like feature for selecting product sizes or color

I have searched the whole web to the best of my ability on how to create an interface for selecting products just like the ones implemented in most of the major e-commerce apps(amazon,taobao,shopify..).The goal is to highlight or change the styles of the selected item in the list by simultaneously removing the styles of the previously selected item. I am trying to use react-native to clone such a feature. Any references or guides on how to do this will be highly appreciated!
import React, { Component } from 'react';
import { View, Text ,StyleSheet, TouchableOpacity, } from 'react-native';
class Selections extends Component {
state={
highlighted: false,
id: null
}
// The purpose of this function is to set the state to the target index on press
indexStateHandler = (i) =>{
if(this.state.id === null){
this.setState({
id: i
})
}else{
this.setState({
id:i
})
}
console.log("index: "+i)
console.log("state: "+this.state.id)
}
//The purpose of this function is to set styles for the targeted index
highlightStateHandler = (i) =>{
if(this.state.id === i){
if(!this.state.highlighted){
this.setState({
highlighted:true
})
}
else{
this.setState({
highlighted:false
})
}
}
}
highlightHandler = (i) =>{
// console.log(i)
this.indexStateHandler(i)
this.highlightStateHandler(i)
}
render() {
return (
<View style={styles.selectionWrapper}>
<View style={styles.label}><Text style={{color: "black"}}>{this.props.label}</Text></View>
<View style={styles.listContainer}>
{this.props.options.map((options, i) => (
<TouchableOpacity onPress={()=>this.highlightHandler(i)} key={i}>
<View style={this.state.highlighted&&this.state.id == i?styles.highlighted:styles.options} > <Text style={styles.text}>{options}</Text> </View>
</TouchableOpacity>
)
)}
</View>
</View>
);
}
}
const styles= StyleSheet.create({
selectionWrapper:{
width: '100%',
height: 100,
borderWidth: 1,
borderColor: 'red',
},
label:{
flex: 1,
}
,
listContainer:{
flex: 3,
flexDirection: "row",
justifyContent: "space-around",
alignItems: 'center',
// backgroundColor: "#7fffd4"
},
options:{
borderRadius: 10,
padding: 5,
borderWidth: 1,
borderColor: "#d0b783",
// backgroundColor: ""
},
text:{
color: 'black',
textAlign: 'center'
},
highlighted:{
borderRadius: 10,
padding: 5,
borderWidth: 1,
// borderColor: "#d0b783",
backgroundColor: "#d0b783"
}
})
export default Selections
.....
.....
.....
<TouchableOpacity
style={[styles.buttonStyle,{
backgroundColor : item.id === this.state.selectedItem.id ? "red" : "blue"
}]}
>
{
...
...
}
</TouchableOpacity>
.....
.....
.....
Have a look on TouchableOpacity and TouchableHighlight and try to run examples to see how they work. Also you can combine them to changing visual changes by changing styles.
import React, { Component } from 'react' import { AppRegistry, StyleSheet, TouchableOpacity, Text, View, } from 'react-native'
export default class App extends React.Component { constructor(props) {
super(props)
this.state = {
itemEn1: true,
itemEn2: false,
itemEn3: false,
} }
onPress1 = () => {
this.setState({
itemEn1: true,
itemEn2: false,
itemEn3: false,
}) }
onPress2 = () => {
this.setState({
itemEn1: false,
itemEn2: true,
itemEn3: false,
}) }
onPress3 = () => {
this.setState({
itemEn1: false,
itemEn2: false,
itemEn3: true,
}) }
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={this.state.itemEn1 ? styles.buttonEnabled : styles.buttonDisabled}
onPress={this.onPress1}>
<Text> Item 1 </Text>
</TouchableOpacity>
<TouchableOpacity
style={this.state.itemEn2 ? styles.buttonEnabled : styles.buttonDisabled}
onPress={this.onPress2}>
<Text> Item 2 </Text>
</TouchableOpacity>
<TouchableOpacity
style={this.state.itemEn3 ? styles.buttonEnabled : styles.buttonDisabled}
onPress={this.onPress3}>
<Text> Item 3 </Text>
</TouchableOpacity>
</View>
) } }
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 10
},
buttonDisabled: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
marginTop: 20
},
buttonEnabled: {
alignItems: 'center',
backgroundColor: 'green',
padding: 10,
marginTop: 20
},
countContainer: {
alignItems: 'center',
padding: 10
},
})
this is by map function:
export default class DataCollector extends React.Component {
constructor(props) {
super(props);
this.SendBack = this.SendBack.bind(this);
}
SendBack(info) {
console.log("Key is :", info);
this.props.callback(info);
}
render() {
let testData = this.props.data.map(function (articleData, index) {
return (
<View key={index}>
<TouchableOpacity
activeOpacity={0.6}
key={index}
onPress={() => this.callBack([articleData.id, articleData.name])}>
</TouchableOpacity>
</View>
)
}, this);
return (
<View>
{testData}
</View>
);
}
}
so now you have access to the clicked item and can use it for enable/disable etc..

React Native Navigator - screen always blank

I am trying to follow the example (https://github.com/facebook/react-native/tree/master/Examples/UIExplorer/Navigator) on the react native site to set up my navigator, but I can't seem to get it to work. No matter what I seem to do, the GoogSignIn scene always comes up blank although it does hit both of my console.log points in the file. I have tried switching the starting point to a different scene in my app, but the same thing always happens. I assume this is something I did wrong in index.ios.js with my navigator, but I'm not sure what. Any help is much appreciated.
index.ios.js
'use strict';
var React = require('react-native');
var DataEntry = require('./app/DataEntry');
var PasswordView = require('./app/PasswordView');
var GoogSignIn = require('./app/GoogSignIn');
var {
AppRegistry,
Image,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
} = React;
class PasswordRecovery extends React.Component {
render() {
return (
<Navigator
ref={this._setNavigatorRef}
style={styles.container}
initialRoute={{id: 'GoogSignIn', name: 'Index'}}
renderScene={this.renderScene}
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FloatFromRight;
}} />
);
}
renderScene(route, navigator) {
switch (route.id) {
case 'GoogSignIn':
return <GoogSignIn navigator={navigator} />;
case 'DataEntry':
return <DataEntry navigator={navigator} />;
case 'PasswordView':
return <PasswordView navigator={navigator} />;
default:
return this.noRoute(navigator);
}
noRoute(navigator) {
return (
<View style={{flex: 1, alignItems: 'stretch', justifyContent: 'center'}}>
<TouchableOpacity style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}
onPress={() => navigator.pop()}>
<Text style={{color: 'red', fontWeight: 'bold'}}>ERROR: NO ROUTE DETECTED</Text>
</TouchableOpacity>
</View>
);
}
_setNavigatorRef(navigator) {
if (navigator !== this._navigator) {
this._navigator = navigator;
if (navigator) {
var callback = (event) => {
console.log(
`TabBarExample: event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from the owner.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
}
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('PasswordRecovery', () => PasswordRecovery);
I am just trying to get this all setup so that I can display a Google Sign in scene and then navigate from there. The code for that scene so far is here:
GoogSignIn.js
'use strict';
var React = require('react-native');
var { NativeAppEventEmitter } = require('react-native');
var GoogleSignin = require('react-native-google-signin');
var cssVar = require('cssVar');
var { Icon } = require('react-native-icons');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
TouchableHighlight,
PixelRatio,
Navigator,
} = React;
var NavigationBarRouteMapper = {
LeftButton: function(route, navigator, index, navState) {
if (index === 0) {
return null;
}
var previousRoute = navState.routeStack[index - 1];
return (
<TouchableOpacity
onPress={() => navigator.pop()}
style={styles.navBarLeftButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
{previousRoute.title}
</Text>
</TouchableOpacity>
);
},
RightButton: function(route, navigator, index, navState) {
return (
null
);
},
Title: function(route, navigator, index, navState) {
return (
<Text style={[styles.navBarText, styles.navBarTitleText]}>
GOOGLE SIGN IN
</Text>
);
},
};
class GoogSignin extends React.Component {
constructor(props) {
super(props);
this.state = {
user: null
};
}
componentWillMount() {
var navigator = this.props.navigator;
var callback = (event) => {
console.log(
`NavigationBarSample : event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from this component.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
componentDidMount() {
this._configureOauth(
'105558473349-7usegucirv10bruohtogd0qtuul3kkhn.apps.googleusercontent.com'
);
}
renderScene(route, navigator) {
console.log("HERE");
return (
<View style={styles.container}>
<TouchableHighlight onPress={() => {this._signIn(); }}>
<View style={{backgroundColor: '#f44336', flexDirection: 'row'}}>
<View style={{padding: 12, borderWidth: 1/2, borderColor: 'transparent', borderRightColor: 'white'}}>
<Icon
name='ion|social-googleplus'
size={24}
color='white'
style={{width: 24, height: 24}}
/>
</View>
<Text style={{color: 'white', padding: 12, marginTop: 2, fontWeight: 'bold'}}>Sign in with Google</Text>
</View>
</TouchableHighlight>
</View>
);
}
render() {
return (
<Navigator
debugOverlay={false}
style={styles.container}
renderScene={this.renderScene}
navigationBar={
<Navigator.NavigationBar
routeMapper={NavigationBarRouteMapper}
style={styles.navBar}/>
}/>
);
}
_configureOauth(clientId, scopes=[]) {
console.log("WE HERE")
GoogleSignin.configure(clientId, scopes);
NativeAppEventEmitter.addListener('googleSignInError', (error) => {
console.log('ERROR signin in', error);
});
NativeAppEventEmitter.addListener('googleSignIn', (user) => {
console.log(user);
this.setState({user: user});
});
return true;
}
_signIn() {
GoogleSignin.signIn();
}
_signOut() {
GoogleSignin.signOut();
this.setState({user: null});
}
};
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
messageText: {
fontSize: 17,
fontWeight: '500',
padding: 15,
marginTop: 50,
marginLeft: 15,
},
button: {
backgroundColor: 'white',
padding: 15,
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
navBar: {
backgroundColor: 'white',
},
navBarText: {
fontSize: 16,
marginVertical: 10,
},
navBarTitleText: {
color: cssVar('fbui-bluegray-60'),
fontWeight: '500',
marginVertical: 9,
},
navBarLeftButton: {
paddingLeft: 10,
},
navBarRightButton: {
paddingRight: 10,
},
navBarButtonText: {
color: cssVar('fbui-accent-blue'),
},
scene: {
flex: 1,
paddingTop: 20,
backgroundColor: '#EAEAEA',
},
});
module.exports = GoogSignin;
edit: screenshots of inspector:
In your renderScene method, try doing something like this (this will also help you remove that big switch):
Component = route.id
<View style={styles.container}>
<Component navigator={navigator} route={route} />
</View>
styles = StyleSheet.create({
container:
flex: 1
})

Categories