Skip to content

Instantly share code, notes, and snippets.

@kendhia
Created January 3, 2020 14:24
Show Gist options
  • Save kendhia/5bd708346565451e76e30cc78e38039d to your computer and use it in GitHub Desktop.
Save kendhia/5bd708346565451e76e30cc78e38039d to your computer and use it in GitHub Desktop.
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
Image,
Dimensions,
TouchableOpacity,
} from 'react-native';
import {LoginManager, AccessToken} from 'react-native-fbsdk';
import {
GoogleSignin,
GoogleSigninButton,
statusCodes,
} from '@react-native-community/google-signin';
import {TapGestureHandler, State} from 'react-native-gesture-handler';
const {width, height} = Dimensions.get('window');
import Animated, {Easing} from 'react-native-reanimated';
const {
Value,
event,
block,
cond,
eq,
set,
Clock,
startClock,
stopClock,
debug,
timing,
clockRunning,
interpolate,
Extrapolate,
} = Animated;
function runTiming(clock, value, dest) {
const state = {
finished: new Value(0),
position: new Value(0),
time: new Value(0),
frameTime: new Value(0),
};
const config = {
duration: 1000,
toValue: new Value(0),
easing: Easing.inOut(Easing.ease),
};
return block([
cond(clockRunning(clock), 0, [
set(state.finished, 0),
set(state.time, 0),
set(state.position, value),
set(state.frameTime, 0),
set(config.toValue, dest),
startClock(clock),
]),
timing(clock, state, config),
cond(state.finished, debug('stop clock', stopClock(clock))),
state.position,
]);
}
class LoginScreen extends Component {
constructor() {
super();
this.state = {user: {email: ''}, gUser: {email: ''}};
this.buttonOpacity = new Value(1);
this.onStateChange = event([
{
nativeEvent: ({state}) =>
block([
cond(
eq(state, State.END),
set(this.buttonOpacity, runTiming(new Clock(), 1, 0)),
),
]),
},
]);
this.buttonY = interpolate(this.buttonOpacity, {
inputRange: [0, 1],
outputRange: [100, 0],
extrapolate: Extrapolate.CLAMP,
});
this.bgY = interpolate(this.buttonOpacity, {
inputRange: [0, 1],
outputRange: [-height / 3, 0],
extrapolate: Extrapolate.CLAMP,
});
GoogleSignin.configure();
}
signIn = async () => {
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
this.setState({gUser: userInfo.user});
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
// user cancelled the login flow
} else if (error.code === statusCodes.IN_PROGRESS) {
// operation (e.g. sign in) is in progress already
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
// play services not available or outdated
} else {
// some other error happened
}
}
};
isSignedIn = async () => {
const isSignedIn = await GoogleSignin.isSignedIn();
this.setState({isLoginScreenPresented: !isSignedIn});
};
getCurrentUser = async () => {
const currentUser = await GoogleSignin.getCurrentUser();
this.setState({currentUser});
};
tryLogin = () => {
LoginManager.logInWithPermissions(['public_profile', 'email']).then(
result => {
if (result.isCancelled) {
console.log('Login cancelled');
} else {
console.log(
'Login success with permissions: ' +
result.grantedPermissions.toString(),
);
AccessToken.getCurrentAccessToken().then(data => {
console.log(data.accessToken.toString());
this.initUser(data.accessToken.toString());
});
}
},
function(error) {
console.log('Login fail with error: ' + error);
},
);
};
initUser(token) {
fetch(
'https://graph.facebook.com/v2.5/me?fields=email,name,friends&access_token=' +
token,
)
.then(response => response.json())
.then(json => {
// Some user object has been set up somewhere, build that user here
const user = {};
user.name = json.name;
user.id = json.id;
user.user_friends = json.friends;
user.email = json.email;
user.username = json.name;
user.loading = false;
user.loggedIn = true;
this.setState({user: user});
})
.catch(() => {
// reject('ERROR GETTING DATA FROM FACEBOOK');
});
}
render() {
return (
<View
style={{
flex: 1,
backgroundColor: 'white',
justifyContent: 'flex-end',
}}>
<Animated.View
style={{
...StyleSheet.absoluteFill,
transform: [{translateY: this.bgY}],
}}>
<Image
source={require('../assets/bg_1.png')}
style={{flex: 1, height: null, width: null}}
/>
</Animated.View>
<View style={{height: height / 2.5, justifyContent: 'center'}}>
<TapGestureHandler onHandlerStateChange={this.onStateChange}>
<Animated.View
style={{
...styles.button,
opacity: this.buttonOpacity,
transform: [{translateY: this.buttonY}],
}}>
<Text style={{fontSize: 20, fontWeight: 'bold'}}>SIGN IN</Text>
</Animated.View>
</TapGestureHandler>
<Animated.View
style={{
...styles.button,
backgroundColor: '#2E71DC',
opacity: this.buttonOpacity,
transform: [{translateY: this.buttonY}],
}}>
<TouchableOpacity
style={{
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
onPress={this.tryLogin}>
<Text style={{fontSize: 20, fontWeight: 'bold', color: 'white'}}>
{this.state.user.email.length > 0
? this.state.user.email
: 'Sign In with Facebook'}
</Text>
</TouchableOpacity>
</Animated.View>
<Animated.View
style={{
...styles.button,
backgroundColor: 'red',
opacity: this.buttonOpacity,
transform: [{translateY: this.buttonY}],
}}>
<TouchableOpacity
style={{
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
onPress={this.signIn}>
<Text style={{fontSize: 20, fontWeight: 'bold', color: 'white'}}>
{this.state.gUser.email.length > 0
? this.state.gUser.email
: 'Sign In with Google'}
</Text>
</TouchableOpacity>
</Animated.View>
</View>
</View>
);
}
}
export default LoginScreen;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
button: {
backgroundColor: 'white',
height: 70,
marginHorizontal: 20,
borderRadius: 35,
alignItems: 'center',
justifyContent: 'center',
marginVertical: 5,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment