Commit 4cbea335 authored by Milan John Paul Digiuseppe's avatar Milan John Paul Digiuseppe

Merge branch 'milan/onboarding' into 'master'

Onboarding

See merge request !17
parents 6501f24d ecb84bd6
......@@ -2,20 +2,40 @@
import React from 'react';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import { initializeAuth } from './src/store/auth/AuthActions';
import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
import Firebase from 'firebase';
import { firebaseAuthStateChanged } from './src/store/auth/AuthActions';
import RootReducer from './src/store/RootReducer';
import AppContainer from './src/AppContainer';
import RootNavigator from './src/navigation/RootNavigator';
import theme from './src/theme';
import AppLoader from './src/AppLoader';
import firebaseConfig from './firebaseconfig.json';
const NavTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: theme.colors.white,
},
};
const store = configureStore({
reducer: RootReducer,
});
store.dispatch(initializeAuth())
// Prevent reinitialization on hot reload
if (Firebase.apps.length === 0) {
Firebase.initializeApp(firebaseConfig);
}
Firebase.auth().onAuthStateChanged((user) => store.dispatch(firebaseAuthStateChanged(user)));
const App = () => (
<Provider store={store}>
<AppContainer />
<AppLoader>
<NavigationContainer theme={NavTheme}>
<RootNavigator />
</NavigationContainer>
</AppLoader>
</Provider>
);
......
......@@ -4,14 +4,10 @@
"slug": "geo",
"privacy": "public",
"sdkVersion": "36.0.0",
"platforms": [
"ios",
"android",
"web"
],
"platforms": ["ios", "android", "web"],
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"icon": "./assets/icon-ios-1024@1x.png",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
......@@ -20,12 +16,10 @@
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"facebookScheme" : "fb710462976370982",
"facebookAppId" : "710462976370982",
"facebookDisplayName" : "GeoCache-",
"assetBundlePatterns": ["**/*"],
"facebookScheme": "fb710462976370982",
"facebookAppId": "710462976370982",
"facebookDisplayName": "GeoCache-",
"ios": {
"bundleIdentifier": "com.gamergroup.geo",
"buildNumber": "1.0.0",
......@@ -39,4 +33,4 @@
"versionCode": 1
}
}
}
\ No newline at end of file
}
assets/splash.png

11.2 KB | W: | H:

assets/splash.png

6.34 KB | W: | H:

assets/splash.png
assets/splash.png
assets/splash.png
assets/splash.png
  • 2-up
  • Swipe
  • Onion skin
{
"apiKey": "AIzaSyB7ueZ5fnM1SwpWwoUi88H5k3_tkLIoz5I",
"authDomain": "my-project-1569171242510.firebaseapp.com",
"databaseURL": "https://my-project-1569171242510.firebaseio.com",
"projectId": "my-project-1569171242510",
"storageBucket": "my-project-1569171242510.appspot.com",
"messagingSenderId": "834336886747",
"appId": "1:834336886747:web:db805542e470265dbc61fe",
"measurementId": "834336886747"
}
......@@ -1054,6 +1054,11 @@
"@types/hammerjs": "^2.0.36"
}
},
"@expo-google-fonts/nunito": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@expo-google-fonts/nunito/-/nunito-0.1.0.tgz",
"integrity": "sha512-9IQtlKj029h1XtSyhQck5yBi2nLJXHF3Uqmt2w7nxABTv99QYzCsIAaULmttxcZlJsyUMNMz3Fyor6UgfIV5cA=="
},
"@expo/vector-icons": {
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-10.2.0.tgz",
......@@ -2387,6 +2392,11 @@
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.15.0.tgz",
"integrity": "sha512-Zc6sowqlCWu3+V0bocZwdaPPXlRv14EHtYcQDCOghj9EdyKLMkAOODBh3HHAx5r7QRylDYCOaXa/b/edgBLDpA=="
},
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"bplist-creator": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz",
......@@ -2919,6 +2929,38 @@
"isobject": "^3.0.1"
}
},
"css-select": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
"integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^3.2.1",
"domutils": "^1.7.0",
"nth-check": "^1.0.2"
}
},
"css-tree": {
"version": "1.0.0-alpha.39",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz",
"integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==",
"requires": {
"mdn-data": "2.0.6",
"source-map": "^0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"css-what": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz",
"integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg=="
},
"csstype": {
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
......@@ -3059,11 +3101,41 @@
"esutils": "^2.0.2"
}
},
"dom-serializer": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
"requires": {
"domelementtype": "^2.0.1",
"entities": "^2.0.0"
},
"dependencies": {
"domelementtype": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
}
}
},
"dom-storage": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.1.0.tgz",
"integrity": "sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q=="
},
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
"requires": {
"dom-serializer": "0",
"domelementtype": "1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
......@@ -3101,6 +3173,11 @@
"once": "^1.4.0"
}
},
"entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
"integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
},
"envinfo": {
"version": "7.5.1",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.5.1.tgz",
......@@ -5593,6 +5670,11 @@
"buffer-alloc": "^1.1.0"
}
},
"mdn-data": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz",
"integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA=="
},
"mem": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
......@@ -6204,6 +6286,14 @@
"path-key": "^2.0.0"
}
},
"nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
"requires": {
"boolbase": "~1.0.0"
}
},
"nullthrows": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
......@@ -7279,11 +7369,28 @@
"resolved": "https://registry.npmjs.org/react-native-status-bar-height/-/react-native-status-bar-height-2.5.0.tgz",
"integrity": "sha512-sYBCPYA/NapBSHkdm/IVL4ID3LLlIuLqINi2FBDyMkc2BU9pfSGOtkz9yfxoK39mYJuTrlTOQ7mManARUsYDSA=="
},
"react-native-svg": {
"version": "9.13.3",
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-9.13.3.tgz",
"integrity": "sha512-H50b2m4jvrQ7KxKs8uYSuWecr6e5XC7BDfS7DaA96+0Owjh0C9DksI5l8SRyHnmE+emiYMPu6Qqfr9dCyKkaJQ==",
"requires": {
"css-select": "^2.0.2",
"css-tree": "^1.0.0-alpha.37"
}
},
"react-native-swipe-list-view": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/react-native-swipe-list-view/-/react-native-swipe-list-view-2.5.0.tgz",
"integrity": "sha512-HTsVaxA3an6myShlLroTyDZo/AOrZ6HJr+EwCaGRE2YuGdM/cFHoYfsuslOEEig5GenTw8DILUB8kqYWQ5lJtA=="
},
"react-native-swiper": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/react-native-swiper/-/react-native-swiper-1.6.0.tgz",
"integrity": "sha512-OnkTTZi+9uZUgy0uz1I9oYDhCU3z36lZn+LFsk9FXPRelxb/KeABzvPs3r3SrHWy1aA67KGtSFj0xNK2QD0NJQ==",
"requires": {
"prop-types": "^15.5.10"
}
},
"react-native-touchable-scale": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/react-native-touchable-scale/-/react-native-touchable-scale-2.1.1.tgz",
......
import React from 'react';
import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
import RootNavigator from './navigation/RootNavigator';
import theme from './theme';
const NavTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: theme.colors.white,
},
};
const AppContainer = () => (
<NavigationContainer theme={NavTheme}>
<RootNavigator />
</NavigationContainer>
);
export default AppContainer;
/* eslint-disable @typescript-eslint/camelcase */
import React from 'react';
import { AppLoading } from 'expo';
import {
useFonts,
// Nunito_200ExtraLight,
// Nunito_300Light,
Nunito_400Regular,
Nunito_600SemiBold,
Nunito_700Bold,
Nunito_800ExtraBold,
// Nunito_900Black,
// Nunito_200ExtraLight_Italic,
// Nunito_300Light_Italic,
// Nunito_400Regular_Italic,
// Nunito_600SemiBold_Italic,
// Nunito_700Bold_Italic,
// Nunito_800ExtraBold_Italic,
// Nunito_900Black_Italic,
} from '@expo-google-fonts/nunito';
import { View, StyleSheet } from 'react-native';
import { useSelector } from 'react-redux';
import { getAuthLoading } from './store/auth/AuthSelectors';
/**
* Renders loading screen until everything necessary for app is loaded:
* - fonts
* - auth token
*/
const AppLoader: React.FC = ({ children }) => {
const [fontsLoaded] = useFonts({
// Nunito_200ExtraLight,
// Nunito_300Light,
Nunito_400Regular,
Nunito_600SemiBold,
Nunito_700Bold,
Nunito_800ExtraBold,
// Nunito_900Black,
// Nunito_200ExtraLight_Italic,
// Nunito_300Light_Italic,
// Nunito_400Regular_Italic,
// Nunito_600SemiBold_Italic,
// Nunito_700Bold_Italic,
// Nunito_800ExtraBold_Italic,
// Nunito_900Black_Italic,
});
const authLoading = useSelector(getAuthLoading);
if (!fontsLoaded || authLoading) {
return <AppLoading />;
}
return (
<View style={StyleSheet.absoluteFill}>
{children}
</View>
);
};
export default AppLoader;
......@@ -15,7 +15,7 @@ export const sampleCaches: Cache[] = [
},
{
id: '1',
name: 'will.brown',
name: 'Will Brown',
message: 'Has anyone discovered the tunnels under UW? Where do they go? Do ghosts live in there?',
found: new Date(2019, 9, 20, 0, 0, 0, 0).valueOf(),
lat: 48.4211108,
......@@ -28,7 +28,7 @@ export const sampleCaches: Cache[] = [
},
{
id: '2',
name: 'jayson',
name: 'Jayson',
message: 'Geocaching is fun :) I\'m gonna tell all my friends',
found: new Date(2020, 1, 14, 0, 0, 0, 0).valueOf(),
lat: 40.7464687,
......@@ -43,7 +43,7 @@ export const sampleCaches: Cache[] = [
},
{
id: '3',
name: 'krisztian',
name: 'Krisztian',
message: 'Someone please give us $1 million for this app. We are starving students',
found: new Date(2020, 1, 8, 0, 0, 0, 0).valueOf(),
lat: 40.7464687,
......
......@@ -79,21 +79,23 @@ const CacheFoundModal: React.FC<Props> = ({
<View style={{ alignItems: 'center', flex: 1 }}>
<GeoText
variant={'formHeader'}
text={cache.name!}
variant={'title'}
style={{
marginTop: theme.spacing.xlarge,
marginBottom: theme.spacing.medium,
fontSize: 28,
}}
/>
>
{cache.name!}
</GeoText>
{cache.type === 'Game' && (
<TicTacToe boardState={ticTacToeState} onCellPress={onCellPress} />
)}
{cache.type === 'Message' && (
<View style={{ flex: 1, justifyContent: 'center', paddingHorizontal: theme.spacing.screenPadding }}>
<GeoText text={cache.message} style={{ textAlign: 'center', fontSize: 18, lineHeight: 24 }} />
<GeoText align={'center'}>
{cache.message}
</GeoText>
</View>
)}
</View>
......@@ -105,14 +107,14 @@ const CacheFoundModal: React.FC<Props> = ({
>
{cache.type === 'Game' && (
<GeoButton
title={'MAKE MOVE'}
title={'Make Move'}
onPress={onSave}
disabled={!moveMade}
/>
)}
{cache.type !== 'Game' && (
<GeoButton
title={'SAVE'}
title={'Save'}
onPress={onSave}
icon={'book'}
/>
......
......@@ -6,6 +6,7 @@ import theme from '../theme';
import { NavParams } from '../screens/CacheDetailScreen';
import { CacheType } from '../store/caches/CachesState';
import { cacheTypeToIconName, cacheTypeToColorGradient } from '../utils/CacheUtils';
import GeoText from './GeoText';
const IMG_SIZE = 50;
......@@ -59,12 +60,9 @@ const CacheListItem: React.FC<Props> = ({
reverse
/>
)}
title={name}
titleStyle={{ fontWeight: 'bold' }}
subtitle={`@ ${foundReverseGeocode}`}
subtitleStyle={{ fontSize: 12 }}
rightTitle={yourMove ? 'YOUR MOVE' : undefined}
rightTitleStyle={{ color: theme.colors.blue }}
title={<GeoText variant={'textBold'}>{name}</GeoText>}
subtitle={<GeoText variant={'secondaryText'}>{`@ ${foundReverseGeocode}`}</GeoText>}
rightTitle={<GeoText variant={'textBold'} color={'blue'}>{yourMove ? 'YOUR MOVE' : undefined}</GeoText>}
rightElement={imageUri ? (
<Image
style={styles.image}
......
......@@ -2,6 +2,7 @@ import React from 'react';
import { StyleSheet, ViewStyle, TextStyle } from 'react-native';
import { Button, Icon } from 'react-native-elements';
import theme from '../theme';
import { textStyles } from './GeoText';
const styles = StyleSheet.create({
button: {
......@@ -48,7 +49,7 @@ const GeoButton: React.FC<Props> = ({
iconContainerStyle={{ marginRight: theme.spacing.xlarge }}
onPress={onPress}
title={title}
titleStyle={titleStyle}
titleStyle={[titleStyle, textStyles.button]}
type={type}
/>
);
......
import React from 'react';
import { Input } from 'react-native-elements';
import { StyleSheet } from 'react-native';
import { textStyles } from './GeoText';
import theme from '../theme';
const styles = StyleSheet.create({
label: {
...textStyles.textBold,
color: theme.colors.black,
},
});
interface Props {
value: string;
onChangeText: (text: string) => void;
label?: string;
placeholder?: string;
errorMessage?: string;
}
const GeoInput: React.FC<Props> = ({
value,
onChangeText,
label,
placeholder,
errorMessage,
}) => (
<Input
value={value}
onChangeText={onChangeText}
label={label}
labelStyle={styles.label}
placeholder={placeholder}
errorMessage={errorMessage}
inputStyle={textStyles.text}
/>
);
export default GeoInput;
......@@ -8,7 +8,7 @@ import { StyleSheet, ViewStyle } from 'react-native';
import mapStyleDay from '../../map-styles/MapStyleDay.json';
import { geoSearch } from '../store/caches/CachesActions';
import { distanceBetweenCoordinates } from '../utils/Geography';
import { getAuthToken } from '../store/auth/AuthSelectors';
import { getIdToken } from '../store/auth/AuthSelectors';
const styles = StyleSheet.create({
hideGoogleLogo: {
......@@ -72,7 +72,7 @@ export const UserLocationProvider: React.FC = ({ children }) => {
export const GeoMapSearch: React.FC = ({ children }) => {
const dispatch = useDispatch();
const { userLocation } = useContext(UserLocationContext);
const idToken = useSelector(getAuthToken);
const idToken = useSelector(getIdToken);
const [lastGeosearch, setLastGeosearch] = useState<LatLng>();
// Call geosearch when user has moved 100m since last geosearch location
......
......@@ -83,11 +83,13 @@ const GeoMarker: React.FC<GeoMarkerProps> = ({
style={styles.callout}
>
<GeoText
text={message}
variant={'text'}
style={{ flex: 1, flexWrap: 'wrap' }}
numberOfLines={3}
/>
>
{message}
</GeoText>
</Callout>
)}
</Marker>
......
......@@ -4,57 +4,91 @@ import {
} from 'react-native';
import { Color, COLOR_MAP } from '../theme';
type Variant = 'header' | 'formHeader' | 'textBold' | 'text' | 'textWeak';
type Variant =
| 'title'
| 'blurb'
| 'text'
| 'textBold'
| 'secondaryText'
| 'screenHeader'
| 'formHeader'
| 'button';
const fontSizes = {
h1: 36,
h3: 20,
text: 16,
};
const fontWeights = {
bold: '700',
normal: '500',
weak: '200',
// These fonts are loaded in AppLoader
const fontFamilies = {
// extraLight: 'Nunito_200ExtraLight',
// light: 'Nunito_300Light',
regular: 'Nunito_400Regular',
semiBold: 'Nunito_600SemiBold',
bold: 'Nunito_700Bold',
extraBold: 'Nunito_800ExtraBold',
// black: 'Nunito_900Black',
} as const;
const styles = StyleSheet.create({
header: {
fontSize: fontSizes.h1,
export const textStyles = StyleSheet.create({
title: {
fontSize: 34,
fontFamily: fontFamilies.bold,
},
formHeader: {
fontSize: fontSizes.h3,
fontWeight: fontWeights.bold,
blurb: {
fontSize: 21,
fontFamily: fontFamilies.semiBold,
},
text: {
fontSize: 17,
fontFamily: fontFamilies.regular,
},
textBold: {
fontSize: fontSizes.text,
fontWeight: fontWeights.bold,
fontSize: 17,
fontFamily: fontFamilies.bold,
},
text: {
fontSize: fontSizes.text,
fontWeight: fontWeights.normal,
secondaryText: {
fontSize: 15,
fontFamily: fontFamilies.regular,
lineHeight: 18,
},
screenHeader: {
fontSize: 17,
fontFamily: fontFamilies.extraBold,
},
formHeader: {
fontSize: 21,
fontFamily: fontFamilies.bold,
textTransform: 'uppercase',
},
textWeak: {
fontSize: fontSizes.text,