Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #11

Merged
merged 24 commits into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
053e29a
MVP for home screen
ahardy42 Mar 23, 2020
36a30c0
map page is pretty weak but it works and markers are loaded when a po…
ahardy42 Mar 24, 2020
a7f4153
Merge pull request #1 from ahardy42/feature/map-page
ahardy42 Mar 24, 2020
1cb9764
added difficulty options and styled buttons
ahardy42 Mar 24, 2020
30ea207
Merge pull request #2 from ahardy42/feature/main-options
ahardy42 Mar 24, 2020
2b29105
added a start modal
ahardy42 Mar 24, 2020
3cead56
Merge pull request #3 from ahardy42/feature/start-modal
ahardy42 Mar 24, 2020
d1d5bde
updated marker
ahardy42 Mar 24, 2020
c98ef6a
snapping markers roughly to roads
ahardy42 Mar 25, 2020
2c0c5e1
Merge pull request #4 from ahardy42/feature/marker-fix
ahardy42 Mar 25, 2020
19d346f
updated bbox creation
ahardy42 Mar 25, 2020
adca8a7
added bbox creation screen to select polygon for play
ahardy42 Mar 25, 2020
9817376
Merge pull request #5 from ahardy42/feature/create-bbox
ahardy42 Mar 25, 2020
579e10a
difficulty settings means something now
ahardy42 Mar 25, 2020
dd5bf17
Merge pull request #6 from ahardy42/feature/difficulty
ahardy42 Mar 25, 2020
73bf265
create different lengths and a home button
ahardy42 Mar 26, 2020
9d2a8af
Merge pull request #7 from ahardy42/feature/length
ahardy42 Mar 26, 2020
201ede2
created a timer for the game
ahardy42 Mar 26, 2020
87baf5c
Merge pull request #8 from ahardy42/feature/timer
ahardy42 Mar 26, 2020
11ebfa6
made some styling changes
ahardy42 Mar 26, 2020
89cf829
created game over situation
ahardy42 Mar 26, 2020
54acc5e
Merge pull request #9 from ahardy42/feature/game-over
ahardy42 Mar 26, 2020
74a00ea
Merge pull request #10 from ahardy42/feature/stylin
ahardy42 Mar 26, 2020
7648868
updating some simple things
ahardy42 Mar 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import MapScreen from './screens/MapScreen';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { FormProvider } from './context/FormContext';
import { MarkerProvider } from './context/MarkerContext';
import { RegionProvider } from './context/RegionContext';
import BboxCreateScreen from './screens/BboxCreateScreen';

export type RootStackParamList = {
Home: undefined,
Bbox: undefined,
Map: undefined
}

Expand All @@ -16,10 +20,15 @@ export default function App() {
return (
<NavigationContainer>
<FormProvider>
<Stack.Navigator initialRouteName='Home'>
<Stack.Screen name='Home' component={HomeScreen}/>
<Stack.Screen name='Map' component={MapScreen}/>
</Stack.Navigator>
<MarkerProvider>
<RegionProvider>
<Stack.Navigator initialRouteName='Home'>
<Stack.Screen name='Home' component={HomeScreen}/>
<Stack.Screen options={{headerShown: false}} name='Bbox' component={BboxCreateScreen}/>
<Stack.Screen options={{headerShown: false}} name='Map' component={MapScreen}/>
</Stack.Navigator>
</RegionProvider>
</MarkerProvider>
</FormProvider>
</NavigationContainer>
);
Expand Down
30 changes: 30 additions & 0 deletions components/Instructions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

type InstructionsProps = {
coordsLen: number
}

export default function Instructions({ coordsLen }: InstructionsProps) {
let instructions = coordsLen < 1 ? 'Click on the map to start drawing a game Boundary' :
coordsLen < 2 ? 'Now keep clicking to create a box' : 'When finished, press the button at the bottom of the screen'
return (
<View style={styles.container}>
<Text style={styles.text}>{instructions}</Text>
</View>
);
}

const styles = StyleSheet.create({
container: {
position: 'absolute',
top: 35,
left: 0,
width: '100%'
},
text: {
fontSize: 30,
textAlign: 'center',
color: '#fff'
}
})
3 changes: 2 additions & 1 deletion components/MarkerList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { Marker, LatLng } from 'react-native-maps';
import { Text } from 'react-native';
import { Marker } from 'react-native-maps';
import Svg, { Path } from 'react-native-svg';
import { Feature, Point } from '@turf/turf';

Expand Down
14 changes: 7 additions & 7 deletions components/PointsTally.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Card } from 'react-native-material-ui';
import { useMarkerContext } from '../context/MarkerContext';

type PointsTallyProps = {
markerListLen: number,
initialLen: number
}
export default function PointsTally() {

const [markerState] = useMarkerContext();

export default function PointsTally({ markerListLen, initialLen }) {
const { markerListlen, numHit } = markerState;
return (
<View style={styles.container}>
<Card >
<View>
<Text style={styles.text}>Points: {(initialLen - markerListLen) * 10}</Text>
<Text style={styles.text}>Markers: {markerListLen}</Text>
<Text style={styles.text}>Points: {numHit * 10}</Text>
<Text style={styles.text}>Markers: {markerListlen}</Text>
</View>
</Card>
</View>
Expand Down
35 changes: 35 additions & 0 deletions components/PolyBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { Polygon, MapEvent, LatLng, Point, Polyline, Circle, } from 'react-native-maps';

// hook to emit polygon / editing state
export const usePolygonCreator: () => [LatLng[], (e: any) => void] = () => {

const [coords, setCoords] = React.useState<LatLng[]>([]);

const addToPolygon: (e: any) => void = e => {
e.persist();
setCoords(prevState => [...prevState, e.nativeEvent.coordinate])
}

return [coords, addToPolygon]
}

// PolyBoundary Component
type PolyProps = {
coords: LatLng[],
}

export function PolyBoundary({ coords }: PolyProps) {

return (
<>
{coords.length < 2 && <Circle center={coords[0]} radius={5} strokeWidth={5} strokeColor='green'/>}
{coords.length < 3 && <Polyline coordinates={coords} strokeWidth={5} strokeColor='green'/>}
<Polygon
coordinates={coords}
strokeColor='green'
strokeWidth={5}
/>
</>
);
}
46 changes: 46 additions & 0 deletions components/PolyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import {LatLng} from 'react-native-maps';

type ButtonProps = {
coordsLen: number,
setBoundary: React.Dispatch<React.SetStateAction<LatLng[]>>
}

export default function PolyButton({ coordsLen, coords, setBoundary }) {

const handlePress: () => void = () => {
if (coordsLen < 3) return;
setBoundary(coords);
}

return (
<TouchableOpacity onPress={handlePress} style={styles.button}>
<Text style={styles.text}>Set Boundary</Text>
</TouchableOpacity>
);
}

const styles = StyleSheet.create({
button: {
position: 'absolute',
backgroundColor: '#fff',
bottom: 50,
left: '50%',
marginLeft: -50,
padding: 10,
borderRadius: 5,
shadowColor: '#000',
shadowOpacity: 0.6,
shadowRadius: 3,
shadowOffset: {
width: 2,
height: 2
},
zIndex: 500
},
text: {
fontSize: 15,
textAlign: 'center'
}
})
2 changes: 1 addition & 1 deletion components/StartModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const styles = StyleSheet.create({
width: '100%'
},
wrapper: {
backgroundColor: 'rgba(0, 0, 0, 0.2)',
backgroundColor: 'rgba(255, 255, 255, 0.4)',
height: '70%',
width: '70%',
borderRadius: 10,
Expand Down
57 changes: 57 additions & 0 deletions context/MarkerContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { createContext, useContext, useReducer } from 'react';
import { Feature, Point } from '@turf/turf';

type ProviderProps = {
children: any
}

type MarkerState = {
markers: Feature<Point>[],
markerListlen: number,
numHit: number
}

type MarkerActions =
| { type: 'SET_LIST', payload: Feature<Point>[] }
| { type: 'DELETE_MARKER', payload: Feature<Point> }
| { type: 'RESET_STATE' }

const initialState = {
markers: [],
markerListlen: 0,
numHit: 0
}

const reducer = (state: MarkerState, action: MarkerActions) => {
switch (action.type) {
case 'SET_LIST':
return { markers: action.payload, markerListlen: action.payload.length, numHit: 0 };
case 'DELETE_MARKER':
let updatedMarkers = state.markers.filter(marker => marker.id !== action.payload.id);
let updatedNum = state.numHit + 1;
return { ...state, markers: updatedMarkers, numHit: updatedNum };
case 'RESET_STATE':
return initialState;
default:
return state;
}
}

export const MarkerContext = createContext(null);

export const MarkerProvider = ({ children }: ProviderProps) => {

const [markerState, markerDispatch] = useReducer(reducer, initialState);

React.useEffect(() => {
console.log('marker state:', markerState)
}, [markerState]);

return (
<MarkerContext.Provider value={[markerState, markerDispatch]}>
{children}
</MarkerContext.Provider>
);
}

export const useMarkerContext: () => [MarkerState, React.Dispatch<MarkerActions>] = () => useContext(MarkerContext);
14 changes: 14 additions & 0 deletions context/RegionContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, {createContext, useContext, useState} from 'react';
import { Region } from 'react-native-maps';

export const RegionContext = createContext(null);

export function RegionProvider({ children }) {
return (
<RegionContext.Provider value={useState<Region>(null)}>
{children}
</RegionContext.Provider>
);
}

export const useRegionContext: () => [Region, React.Dispatch<React.SetStateAction<Region>>] = () => useContext(RegionContext);
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@types/react-native-material-ui": "^1.32.0",
"expo": "~36.0.0",
"expo-location": "~8.0.0",
"random-points-on-polygon": "^0.0.4",
"react": "~16.9.0",
"react-dom": "~16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz",
Expand Down
101 changes: 101 additions & 0 deletions screens/BboxCreateScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import { RootStackParamList } from '../App';
import { StackNavigationProp } from '@react-navigation/stack';
import { LocationData, Accuracy } from 'expo-location';
// utilties
import { useFormContext } from '../context/FormContext';
import { useMarkerContext } from '../context/MarkerContext';
import { initMarkerList, initSnappedMarkerList } from '../utils/markers';
//comonents
import { usePolygonCreator, PolyBoundary } from '../components/PolyBoundary';
import PolyButton from '../components/PolyButton';
import MapView, { Region, LatLng } from 'react-native-maps';
import Instructions from '../components/Instructions';
import { StackActions } from '@react-navigation/native';
import { useRegionContext } from '../context/RegionContext';

type ProfileScreenNavigationProp = StackNavigationProp<
RootStackParamList,
'Bbox'
>;

type BboxCreateProps = {
navigation: ProfileScreenNavigationProp
}

export default function BboxCreateScreen({ navigation }: BboxCreateProps) {

const initialRegion = {
latitude: 39.8333333,
longitude: -98.585522,
latitudeDelta: 50,
longitudeDelta: 50
}

const [boundary, setBoundary] = React.useState<LatLng[]>([]);
const [formState] = useFormContext();
const [coords, addToPolygon] = usePolygonCreator();
const [markerState, markerDispatch] = useMarkerContext();
const [isFollowingUser, setFollowing] = React.useState<boolean>(true);
const [finalRegion, setRegion] = useRegionContext();

React.useEffect(() => {
if (boundary.length) {
// init markers
if (formState.activity === 'on-road') {
initSnappedMarkerList(boundary, 10)
.then(list => {
markerDispatch({type: 'SET_LIST', payload: list})
})
.catch(e => {
console.log(e);
})
} else {
let list = initMarkerList(boundary, 10);
console.log('list is', list)
markerDispatch({type: 'SET_LIST', payload: list})
}
}
}, [boundary])

React.useEffect(() => {
if (markerState.markers.length) {
navigation.navigate('Map');
}
}, [markerState.markers])


return (
<View style={styles.container}>
<MapView
style={styles.mapStyle}
mapType='hybrid'
initialRegion={initialRegion}
onPress={addToPolygon}
onPanDrag={() => setFollowing(false)}
onRegionChange={e => {setRegion(e)}}
showsUserLocation
followsUserLocation={isFollowingUser}
onUserLocationChange={e => console.log(e.nativeEvent)}
>
<PolyBoundary coords={coords}/>
</MapView>
<Instructions coordsLen={coords.length}/>
<PolyButton coordsLen={coords.length} coords={coords} setBoundary={setBoundary}/>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
mapStyle: {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
});
2 changes: 1 addition & 1 deletion screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) {

if (!formState.activity || !formState.distance) return;

navigation.navigate('Map');
navigation.navigate('Bbox');

}

Expand Down
Loading