Skip to content
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.

Commit

Permalink
Add form UI (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
pandananta authored Aug 22, 2018
1 parent dcdc5d2 commit d874206
Show file tree
Hide file tree
Showing 20 changed files with 8,100 additions and 423 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file added expo_project/.DS_Store
Binary file not shown.
69 changes: 40 additions & 29 deletions expo_project/App.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import React, { Component } from "react";
import { Button, Platform, StatusBar, StyleSheet, Text, View } from "react-native";
import {
Button,
Platform,
StatusBar,
StyleSheet,
Text,
View
} from "react-native";
import { AppLoading, Asset, Font, Icon } from "expo";
import AppNavigator from "./navigation/AppNavigator";

import * as firebase from "firebase";

const firebaseConfig = {
apiKey: 'AIzaSyD_6-qVGk9CiFyhv6wmGp-PWb1b8-sCytc',
authDomain: 'gehl-921be.firebaseapp.com',
projectId: 'gehl-921be'
apiKey: "AIzaSyD_6-qVGk9CiFyhv6wmGp-PWb1b8-sCytc",
authDomain: "gehl-921be.firebaseapp.com",
projectId: "gehl-921be"
};

firebase.initializeApp(firebaseConfig);
Expand All @@ -23,33 +30,35 @@ export default class App extends React.Component {
// https://github.com/hasura/react-native-auth-boilerplate/issues/11
_signIn = async () => {
try {
console.log('start the log ing');
const { type, idToken, user} = await Expo.Google.logInAsync({
iosClientId: '8677857213-j9dn9ebe425td60q8c9tc20gomjbojip.apps.googleusercontent.com',
scopes: ['profile', 'email']
console.log("start the log ing");
const { type, idToken, user } = await Expo.Google.logInAsync({
iosClientId:
"8677857213-j9dn9ebe425td60q8c9tc20gomjbojip.apps.googleusercontent.com",
scopes: ["profile", "email"]
});

if (type === "success") {
this.setState({
userIsAuthenticated: true,
name: user.name,
photoUrl: user.photoUrl
})
});
// Build Firebase credential with the access token.
const credential = firebase.auth.GoogleAuthProvider.credential(idToken);
console.log(`credential: ${credential}`)
console.log(`credential: ${credential}`);

// Sign in with credential from the Facebook user.
const firebaseSignInResult = await firebase.auth().signInAndRetrieveDataWithCredential(credential);
const firebaseSignInResult = await firebase
.auth()
.signInAndRetrieveDataWithCredential(credential);
console.log(`sign in result: ${firebaseSignInResult}`);
} else {
console.log("cancelled")
console.log("cancelled");
}

} catch (e) {
console.log("error", e)
console.log("error", e);
}
}
};

render() {
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
Expand All @@ -62,19 +71,21 @@ export default class App extends React.Component {
);
} else {
return (
<View style={styles.container}>
{this.state.userIsAuthenticated ? (
<View style={styles.container}>
{Platform.OS === "ios" && <StatusBar barStyle="default" />}
<AppNavigator />
</View>
) : (<Button
onPress={this._signIn}
title="Log In"
color="#841584"
accessibilityLabel='sign in'
/>)}
</View>
<View style={styles.container}>
{this.state.userIsAuthenticated ? (
<View style={styles.container}>
{Platform.OS === "ios" && <StatusBar barStyle="light-content" />}
<AppNavigator />
</View>
) : (
<Button
onPress={this._signIn}
title="Log In"
color="#841584"
accessibilityLabel="sign in"
/>
)}
</View>
);
}
}
Expand All @@ -83,7 +94,7 @@ export default class App extends React.Component {
// This is from the boilerplate. We might not need it
return Font.loadAsync({
...Icon.Ionicons.font,
"space-mono": require("./assets/fonts/SpaceMono-Regular.ttf")
monaco: require("./assets/fonts/monaco.ttf")
});
};

Expand Down
Binary file removed expo_project/assets/fonts/SpaceMono-Regular.ttf
Binary file not shown.
Binary file added expo_project/assets/fonts/monaco.ttf
Binary file not shown.
35 changes: 35 additions & 0 deletions expo_project/components/ColoredButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import PropTypes from "prop-types";
import React from "react";

import { StyleSheet, Text, TouchableOpacity } from "react-native";

class ColoredButton extends React.Component {
render() {
const { backgroundColor, color, onPress, label } = this.props;
return (
<TouchableOpacity
style={[styles.button, { backgroundColor }]}
onPress={onPress}
>
<Text style={[styles.text, { color }]}>{label}</Text>
</TouchableOpacity>
);
}
}

const styles = StyleSheet.create({
button: {
backgroundColor: "#5B93D9",
padding: 12,
marginVertical: 20,
justifyContent: "center",
alignItems: "center"
},
text: { fontWeight: "bold" }
});

ColoredButton.propTypes = {
color: PropTypes.string.isRequired
};

export default ColoredButton;
82 changes: 82 additions & 0 deletions expo_project/components/MapWithMarkers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import PropTypes from "prop-types";
import React from "react";
import { StyleSheet } from "react-native";
import { MapView } from "expo";
import PersonIcon from "./PersonIcon";

class MapWithMarkers extends React.Component {
constructor(props) {
super(props);
}

render() {
const {
markers,
activeMarkerId,
onMarkerDragEnd,
onMarkerPress,
onMapPress,
onMapLongPress
} = this.props;
return (
<MapView
style={styles.mapStyle}
onPress={onMapPress}
onLongPress={onMapLongPress}
showsUserLocation
followsUserLocation
zoomEnabled
rotateEnabled
pitchEnabled={false}
>
{markers.map(marker => {
const selected = marker.id === activeMarkerId;
// Update the key when selected or delected, so the marker re renders and centers itself based on the new child size
const key = marker.id + (selected ? "-selected" : "");
return (
<MapView.Marker
coordinate={marker.coordinate}
key={key}
identifier={marker.id}
stopPropagation
draggable
onDragEnd={onMarkerDragEnd}
onPress={() => onMarkerPress(marker.id)}
anchor={{ x: 0, y: 0 }}
calloutAnchor={{ x: 0, y: 0 }}
>
<PersonIcon
backgroundColor={marker.color}
size={selected ? 24 : 16}
shadow
/>
</MapView.Marker>
);
})}
</MapView>
);
}
}

const styles = StyleSheet.create({
mapStyle: { flex: 1 }
});

MapWithMarkers.propTypes = {
markers: PropTypes.arrayOf(
PropTypes.shape({
coordinate: PropTypes.any,
color: PropTypes.string,
title: PropTypes.string,
dateLabel: PropTypes.string,
id: PropTypes.string
})
).isRequired,
activeMarkerId: PropTypes.string,
onMarkerDragEnd: PropTypes.func.isRequired,
onMarkerPress: PropTypes.func.isRequired,
onMapPress: PropTypes.func.isRequired,
onMapLongPress: PropTypes.func.isRequired
};

export default MapWithMarkers;
132 changes: 132 additions & 0 deletions expo_project/components/MarkerCarousel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import PropTypes from "prop-types";
import React from "react";

import PersonIcon from "./PersonIcon";

import { FlatList, StyleSheet, TouchableOpacity } from "react-native";

import * as _ from "lodash";

const CAROUSEL_ICON_SIZE = 50;
const CAROUSEL_ITEM_PADDING = 12;
const CAROUSEL_ITEM_LENGTH = CAROUSEL_ICON_SIZE + 2 * CAROUSEL_ITEM_PADDING;

const VIEWABILITY_CONFIG = { itemVisiblePercentThreshold: 100 };

class MarkerCarousel extends React.Component {
constructor(props) {
super(props);

this.state = {
viewableIndices: []
};
this.onViewableItemsChanged = this.onViewableItemsChanged.bind(this);
}

onViewableItemsChanged({ viewableItems }) {
const viewableIndices = _.map(viewableItems, "index");
this.setState({ viewableIndices });
}

componentDidUpdate(prevProps, prevState) {
// If user selects a marker, and it's not visible, scroll to it
// Note that Adding / removing markers trigger their own animation (see: onContentSizeChange)
// Therefore we stop if props.markers has changed
if (
this.props.markers === prevProps.markers &&
this.props.activeMarkerId !== prevProps.activeMarkerId
) {
const index = _.findIndex(this.props.markers, {
id: this.props.activeMarkerId
});
if (index > -1) {
// Only scroll if the new selection isn't already visible
if (!_.includes(this.state.viewableIndices, index)) {
this.flatList.scrollToIndex({
index,
viewPosition: 0.5,
animated: true
});
}
}
}
}

render() {
const { activeMarkerId, markers, onMarkerPress } = this.props;
return (
<FlatList
style={styles.container}
data={markers}
keyExtractor={item => item.id}
extraData={activeMarkerId}
horizontal
removeClippedSubviews
showsHorizontalScrollIndicator={false}
ref={ref => (this.flatList = ref)}
onContentSizeChange={(contentWidth, contentHeight) => {
if (markers.length > 1) {
// This is janky sometimes when there's only one item for some reason ...
this.flatList.scrollToEnd({ animated: true });
}
}}
getItemLayout={(data, index) => ({
length: CAROUSEL_ITEM_LENGTH,
offset: CAROUSEL_ITEM_LENGTH * index,
index
})}
onViewableItemsChanged={this.onViewableItemsChanged}
viewabilityConfig={VIEWABILITY_CONFIG}
renderItem={({ item, index }) => {
const selected = item.id === activeMarkerId;
return (
<TouchableOpacity
Index={index}
style={[
styles.cell,
selected && { borderBottomColor: item.color }
]}
onPress={() => onMarkerPress(item.id)}
>
<PersonIcon
backgroundColor={item.color}
size={CAROUSEL_ICON_SIZE}
/>
</TouchableOpacity>
);
}}
/>
);
}
}

const styles = StyleSheet.create({
container: {
borderBottomColor: "rgba(0, 0, 0, 0.12)",
borderBottomWidth: 1
},
cell: {
padding: CAROUSEL_ITEM_PADDING,
// there's a border on selected cells, so put an inivisble border on all cells to keep cell height consistent
borderBottomColor: "transparent",
borderBottomWidth: 4,
justifyContent: "center",
alignItems: "center"
}
});

MarkerCarousel.propTypes = {
markers: PropTypes.arrayOf(
PropTypes.shape({
coordinate: PropTypes.any,
color: PropTypes.string,
title: PropTypes.string,
dateLabel: PropTypes.string,
id: PropTypes.string
})
).isRequired,
activeMarkerId: PropTypes.string,
onMarkerPress: PropTypes.func.isRequired
};

export default MarkerCarousel;
Loading

0 comments on commit d874206

Please sign in to comment.