aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Damani <kumar.damani@mail.utoronto.ca>2019-04-23 18:36:36 +0000
committerKumar Damani <kumar.damani@mail.utoronto.ca>2019-04-23 18:36:36 +0000
commit0380ba5ea5c134f3b7c79efae4daa1034d405daf (patch)
tree63c8b95e5b88738c7562b2c22766f7c90f01778e
parent8808175e3aa8ffc4022e58c9f926abfd28ce62c4 (diff)
parent8135fe42bfa36df72c427e8d567aad2182e14372 (diff)
Merge branch 'master' into qa
-rw-r--r--mobile/.expo/packager-info.json12
-rw-r--r--mobile/App.js13
-rw-r--r--mobile/components/FormPage.js20
-rw-r--r--mobile/screens/GreetingPage.js (renamed from mobile/components/GreetingPage.js)0
-rw-r--r--mobile/screens/HomeScreen.js188
-rw-r--r--mobile/screens/LinksScreen.js27
-rw-r--r--mobile/screens/MapPage.js154
-rw-r--r--mobile/screens/SettingsScreen.js14
-rw-r--r--web/app.js20
-rw-r--r--web/models/mockpoints.js34
-rw-r--r--web/models/points.js58
-rw-r--r--web/public/javascripts/map.js369
-rw-r--r--web/routes/index.js120
13 files changed, 391 insertions, 638 deletions
diff --git a/mobile/.expo/packager-info.json b/mobile/.expo/packager-info.json
index 7391ba7..606e044 100644
--- a/mobile/.expo/packager-info.json
+++ b/mobile/.expo/packager-info.json
@@ -1,9 +1,9 @@
{
"devToolsPort": 19002,
- "expoServerPort": null,
- "packagerPort": null,
- "packagerPid": null,
- "expoServerNgrokUrl": null,
- "packagerNgrokUrl": null,
- "ngrokPid": null
+ "expoServerPort": 19000,
+ "packagerPort": 19001,
+ "packagerPid": 29021,
+ "expoServerNgrokUrl": "https://h6-m98.csc301dreamteam.mobile.exp.direct",
+ "packagerNgrokUrl": "https://packager.h6-m98.csc301dreamteam.mobile.exp.direct",
+ "ngrokPid": 29069
} \ No newline at end of file
diff --git a/mobile/App.js b/mobile/App.js
index 703c6eb..a1f3bc4 100644
--- a/mobile/App.js
+++ b/mobile/App.js
@@ -3,15 +3,20 @@ import { Text, View, Alert, StyleSheet, Button, AppRegistry, Navigator, Touchabl
import { Ionicons } from '@expo/vector-icons';
import { createStackNavigator, createAppContainer } from 'react-navigation';
-import GreetingPage from './components/GreetingPage';
+import GreetingPage from './screens/GreetingPage';
import FormPage from './screens/Form1';
import MapPage from './screens/MapPage';
-const RootStack = createStackNavigator( {GreetingPage: GreetingPage, FormPage: FormPage, MapPage: MapPage},
- {headerMode: 'none'})
+const RootStack = createStackNavigator(
+ {
+ GreetingPage: GreetingPage,
+ FormPage: FormPage,
+ MapPage: MapPage
+ },
+ { headerMode: 'none' }
+)
const App = createAppContainer(RootStack)
export default App;
-
diff --git a/mobile/components/FormPage.js b/mobile/components/FormPage.js
deleted file mode 100644
index 9ea3dce..0000000
--- a/mobile/components/FormPage.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import React, { Component } from 'react';
-import { Text, View, Alert, StyleSheet, Button, AppRegistry, Navigator, TouchableHighlight} from 'react-native';
-import { Ionicons } from '@expo/vector-icons';
-import { createStackNavigator, createAppContainer } from 'react-navigation';
-
-export default class FormPage extends Component {
- render() {
- return (
- <View marginTop = {50}>
- <Text>
- Put the form stuff here
- </Text>
- <Button
- onPress={() => this.props.navigation.navigate('GreetingPage')}
- title='Go Back'
- />
- </View>
- );
- }
-}
diff --git a/mobile/components/GreetingPage.js b/mobile/screens/GreetingPage.js
index 18c202f..18c202f 100644
--- a/mobile/components/GreetingPage.js
+++ b/mobile/screens/GreetingPage.js
diff --git a/mobile/screens/HomeScreen.js b/mobile/screens/HomeScreen.js
deleted file mode 100644
index 0d3548e..0000000
--- a/mobile/screens/HomeScreen.js
+++ /dev/null
@@ -1,188 +0,0 @@
-import React from 'react';
-import {
- Image,
- Platform,
- ScrollView,
- StyleSheet,
- Text,
- TouchableOpacity,
- View,
-} from 'react-native';
-import { WebBrowser } from 'expo';
-
-import { MonoText } from '../components/StyledText';
-
-export default class HomeScreen extends React.Component {
- static navigationOptions = {
- header: null,
- };
-
- render() {
- return (
- <View style={styles.container}>
- <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
- <View style={styles.welcomeContainer}>
- <Image
- source={
- __DEV__
- ? require('../assets/images/robot-dev.png')
- : require('../assets/images/robot-prod.png')
- }
- style={styles.welcomeImage}
- />
- </View>
-
- <View style={styles.getStartedContainer}>
- {this._maybeRenderDevelopmentModeWarning()}
-
- <Text style={styles.getStartedText}>Get started by opening</Text>
-
- <View style={[styles.codeHighlightContainer, styles.homeScreenFilename]}>
- <MonoText style={styles.codeHighlightText}>screens/HomeScreen.js</MonoText>
- </View>
-
- <Text style={styles.getStartedText}>
- Change this text and your app will automatically reload.
- </Text>
- </View>
-
- <View style={styles.helpContainer}>
- <TouchableOpacity onPress={this._handleHelpPress} style={styles.helpLink}>
- <Text style={styles.helpLinkText}>Help, it didn’t automatically reload!</Text>
- </TouchableOpacity>
- </View>
- </ScrollView>
-
- <View style={styles.tabBarInfoContainer}>
- <Text style={styles.tabBarInfoText}>This is a tab bar. You can edit it in:</Text>
-
- <View style={[styles.codeHighlightContainer, styles.navigationFilename]}>
- <MonoText style={styles.codeHighlightText}>navigation/MainTabNavigator.js</MonoText>
- </View>
- </View>
- </View>
- );
- }
-
- _maybeRenderDevelopmentModeWarning() {
- if (__DEV__) {
- const learnMoreButton = (
- <Text onPress={this._handleLearnMorePress} style={styles.helpLinkText}>
- Learn more
- </Text>
- );
-
- return (
- <Text style={styles.developmentModeText}>
- Development mode is enabled, your app will be slower but you can use useful development
- tools. {learnMoreButton}
- </Text>
- );
- } else {
- return (
- <Text style={styles.developmentModeText}>
- You are not in development mode, your app will run at full speed.
- </Text>
- );
- }
- }
-
- _handleLearnMorePress = () => {
- WebBrowser.openBrowserAsync('https://docs.expo.io/versions/latest/guides/development-mode');
- };
-
- _handleHelpPress = () => {
- WebBrowser.openBrowserAsync(
- 'https://docs.expo.io/versions/latest/guides/up-and-running.html#can-t-see-your-changes'
- );
- };
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: '#fff',
- },
- developmentModeText: {
- marginBottom: 20,
- color: 'rgba(0,0,0,0.4)',
- fontSize: 14,
- lineHeight: 19,
- textAlign: 'center',
- },
- contentContainer: {
- paddingTop: 30,
- },
- welcomeContainer: {
- alignItems: 'center',
- marginTop: 10,
- marginBottom: 20,
- },
- welcomeImage: {
- width: 100,
- height: 80,
- resizeMode: 'contain',
- marginTop: 3,
- marginLeft: -10,
- },
- getStartedContainer: {
- alignItems: 'center',
- marginHorizontal: 50,
- },
- homeScreenFilename: {
- marginVertical: 7,
- },
- codeHighlightText: {
- color: 'rgba(96,100,109, 0.8)',
- },
- codeHighlightContainer: {
- backgroundColor: 'rgba(0,0,0,0.05)',
- borderRadius: 3,
- paddingHorizontal: 4,
- },
- getStartedText: {
- fontSize: 17,
- color: 'rgba(96,100,109, 1)',
- lineHeight: 24,
- textAlign: 'center',
- },
- tabBarInfoContainer: {
- position: 'absolute',
- bottom: 0,
- left: 0,
- right: 0,
- ...Platform.select({
- ios: {
- shadowColor: 'black',
- shadowOffset: { height: -3 },
- shadowOpacity: 0.1,
- shadowRadius: 3,
- },
- android: {
- elevation: 20,
- },
- }),
- alignItems: 'center',
- backgroundColor: '#fbfbfb',
- paddingVertical: 20,
- },
- tabBarInfoText: {
- fontSize: 17,
- color: 'rgba(96,100,109, 1)',
- textAlign: 'center',
- },
- navigationFilename: {
- marginTop: 5,
- },
- helpContainer: {
- marginTop: 15,
- alignItems: 'center',
- },
- helpLink: {
- paddingVertical: 15,
- },
- helpLinkText: {
- fontSize: 14,
- color: '#2e78b7',
- },
-});
diff --git a/mobile/screens/LinksScreen.js b/mobile/screens/LinksScreen.js
deleted file mode 100644
index 7bb4a62..0000000
--- a/mobile/screens/LinksScreen.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import React from 'react';
-import { ScrollView, StyleSheet } from 'react-native';
-import { ExpoLinksView } from '@expo/samples';
-
-export default class LinksScreen extends React.Component {
- static navigationOptions = {
- title: 'Links',
- };
-
- render() {
- return (
- <ScrollView style={styles.container}>
- {/* Go ahead and delete ExpoLinksView and replace it with your
- * content, we just wanted to provide you with some helpful links */}
- <ExpoLinksView />
- </ScrollView>
- );
- }
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- paddingTop: 15,
- backgroundColor: '#fff',
- },
-});
diff --git a/mobile/screens/MapPage.js b/mobile/screens/MapPage.js
index f8e2a79..7cdb873 100644
--- a/mobile/screens/MapPage.js
+++ b/mobile/screens/MapPage.js
@@ -14,86 +14,84 @@ import {MapView} from 'expo';
export default class Form1 extends Component {
- constructor(props) {
- super(props);
- this.state = {
- initial_region_coordinates: [-79.3832, 43.6532],
- markers: [],
- canProceed: false,
- }
- }
-
- addMarker(e) {
- this.setState(
- { markers : [{ latlng: e.nativeEvent.coordinate}], canProceed: true}
- );
- }
- deleteMarker() {
- this.setState(
- { markers : [], canProceed: false}
- );
- }
- moveToFormPage = () => {
- if(this.state.canProceed === false) {
- alert("Please press on the map to drop a pin");
- return;
- }
- this.props.navigation.navigate('FormPage',
- {coordinates : [
- this.state.markers[0].latlng.longitude,
- this.state.markers[0].latlng.latitude]
- });
- };
- moveToGreetingPage = () => {
- this.props.navigation.navigate('GreetingPage');
- }
+ constructor(props) {
+ super(props);
+ this.state = {
+ initial_region_coordinates: [-79.3832, 43.6532],
+ markers: [],
+ canProceed: false,
+ }
+ }
+ addMarker(e) {
+ this.setState(
+ { markers : [{ latlng: e.nativeEvent.coordinate}], canProceed: true}
+ );
+ }
+ deleteMarker() {
+ this.setState(
+ { markers : [], canProceed: false}
+ );
+ }
+ moveToFormPage = () => {
+ if(this.state.canProceed === false) {
+ alert("Please press on the map to drop a pin");
+ return;
+ }
+ this.props.navigation.navigate('FormPage',
+ {coordinates : [
+ this.state.markers[0].latlng.longitude,
+ this.state.markers[0].latlng.latitude]
+ });
+ };
+ moveToGreetingPage = () => {
+ this.props.navigation.navigate('GreetingPage');
+ }
- render() {
- return (
- <View style={{flex:1,}}>
- <View style={{flex:3}}>
- <MapView
- style={{ flex: 1 }}
- initialRegion={{
- latitude: this.state.initial_region_coordinates[1],
- longitude: this.state.initial_region_coordinates[0],
- latitudeDelta: 0.0922,
- longitudeDelta: 0.0421,
- }}
- onPress={this.addMarker.bind(this)}
- >
+ render() {
+ return (
+ <View style={{flex:1,}}>
+ <View style={{flex:3}}>
+ <MapView
+ style={{ flex: 1 }}
+ initialRegion={{
+ latitude: this.state.initial_region_coordinates[1],
+ longitude: this.state.initial_region_coordinates[0],
+ latitudeDelta: 0.0922,
+ longitudeDelta: 0.0421,
+ }}
+ onPress={this.addMarker.bind(this)}
+ >
- {
- this.state.markers.map((marker, i) => (<MapView.Marker key={i} coordinate={marker.latlng}
- onPress={(e) => {e.stopPropagation(); this.deleteMarker(i)}} />))
- }
- </MapView>
- </View>
+ {
+ this.state.markers.map((marker, i) => (<MapView.Marker key={i} coordinate={marker.latlng}
+ onPress={(e) => {e.stopPropagation(); this.deleteMarker(i)}} />))
+ }
+ </MapView>
+ </View>
- <TouchableHighlight
- style={styles.first_button_container}
- onPress={() => { this.moveToFormPage() }}>
- <Text style={styles.proceed_title}>
- Proceed
- </Text>
- </TouchableHighlight>
- <TouchableHighlight
- style={styles.second_button_container}
- onPress={() => { this.moveToGreetingPage() }}>
- <Text style={styles.proceed_title}>
- Back
- </Text>
- </TouchableHighlight>
- </View>
- );
+ <TouchableHighlight
+ style={styles.first_button_container}
+ onPress={() => { this.moveToFormPage() }}>
+ <Text style={styles.proceed_title}>
+ Proceed
+ </Text>
+ </TouchableHighlight>
+ <TouchableHighlight
+ style={styles.second_button_container}
+ onPress={() => { this.moveToGreetingPage() }}>
+ <Text style={styles.proceed_title}>
+ Back
+ </Text>
+ </TouchableHighlight>
+ </View>
+ );
}
-
}
const styles = StyleSheet.create( {
- first_button_container: {
- width: '100%',
- flex: 1,
- position: 'absolute',
+ first_button_container: {
+ width: '100%',
+ flex: 1,
+ position: 'absolute',
bottom:60,
backgroundColor: '#c0392b',
flexDirection: 'row',
@@ -101,9 +99,9 @@ const styles = StyleSheet.create( {
alignItems: 'stretch'
},
second_button_container: {
- width: '100%',
- flex: 1,
- position: 'absolute',
+ width: '100%',
+ flex: 1,
+ position: 'absolute',
bottom:0,
backgroundColor: '#535c68',
flexDirection: 'row',
@@ -118,4 +116,4 @@ const styles = StyleSheet.create( {
opacity: 0.9,
fontSize: 20
}
-}) \ No newline at end of file
+})
diff --git a/mobile/screens/SettingsScreen.js b/mobile/screens/SettingsScreen.js
deleted file mode 100644
index 6957dcb..0000000
--- a/mobile/screens/SettingsScreen.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import { ExpoConfigView } from '@expo/samples';
-
-export default class SettingsScreen extends React.Component {
- static navigationOptions = {
- title: 'app.json',
- };
-
- render() {
- /* Go ahead and delete ExpoConfigView and replace it with your
- * content, we just wanted to give you a quick view of your config */
- return <ExpoConfigView />;
- }
-}
diff --git a/web/app.js b/web/app.js
index d2831a9..fc2da3c 100644
--- a/web/app.js
+++ b/web/app.js
@@ -24,21 +24,21 @@ app.use(require('./routes/sse'));
var env = process.env.NODE_ENV || 'development';
var uri;
if (env === 'development') {
- uri = 'mongodb://localhost:27017/helpthehome'
+ uri = 'mongodb://localhost:27017/helpthehome'
} else {
- // for qa and production set it on heroku config vars
- uri = process.env.MONGODB_URI
+ // for qa and production set it on heroku config vars
+ uri = process.env.MONGODB_URI
}
// Mongoose connection to MongoDB
mongoose.connect(uri, { useNewUrlParser: true }, function (error) {
- if (error) {
- console.log(error);
- console.log("App was not able to connect to the mongo server!");
- console.log("... double check that the mongo server is running locally");
- } else {
- console.log(`connected to ${uri}`);
- }
+ if (error) {
+ console.log(error);
+ console.log("App was not able to connect to the mongo server!");
+ console.log("... double check that the mongo server is running locally");
+ } else {
+ console.log(`connected to ${uri}`);
+ }
});
app.use('/', indexRouter);
diff --git a/web/models/mockpoints.js b/web/models/mockpoints.js
index 51bd422..05e9f18 100644
--- a/web/models/mockpoints.js
+++ b/web/models/mockpoints.js
@@ -3,15 +3,15 @@ var mongoose = require('mongoose');
// Mongoose Schema definition
var Schema = mongoose.Schema;
var dumbJsonSchema = new Schema({
- type: String,
- coordinates: Array,
- gender: String,
- age: String,
- race: String,
- longhair: Boolean,
- longbeard: Boolean,
- extra: String,
- status: String
+ type: String,
+ coordinates: Array,
+ gender: String,
+ age: String,
+ race: String,
+ longhair: Boolean,
+ longbeard: Boolean,
+ extra: String,
+ status: String
});
// Mongoose Model definition
@@ -20,16 +20,16 @@ var dumbJson = mongoose.model('dumbJstring', dumbJsonSchema, 'dumbpointscollecti
// this function gets ALL the points from the db
// returns the entire document without modifications
exports.get_points = function(callback) {
- dumbJson.find({}).exec(function(err, docs) {
- if (err) callback(err, null);
- callback(null, docs);
- });
+ dumbJson.find({}).exec(function(err, docs) {
+ if (err) callback(err, null);
+ callback(null, docs);
+ });
}
// this function stores A user report into the db
exports.save_request = function(data, callback) {
- dumbJson.create(data, function(err, result) {
- if (err) callback(err, null);
- callback(null, result);
- });
+ dumbJson.create(data, function(err, result) {
+ if (err) callback(err, null);
+ callback(null, result);
+ });
}
diff --git a/web/models/points.js b/web/models/points.js
index e8c181e..d506900 100644
--- a/web/models/points.js
+++ b/web/models/points.js
@@ -3,15 +3,15 @@ var mongoose = require('mongoose');
// Mongoose Schema definition
var Schema = mongoose.Schema;
var JsonSchema = new Schema({
- type: String,
- coordinates: Array,
- gender: String,
- age: String,
- race: String,
- longhair: Boolean,
- longbeard: Boolean,
- extra: String,
- status: String
+ type: String,
+ coordinates: Array,
+ gender: String,
+ age: String,
+ race: String,
+ longhair: Boolean,
+ longbeard: Boolean,
+ extra: String,
+ status: String
});
// Mongoose Model definition
@@ -20,34 +20,34 @@ var Json = mongoose.model('Jstring', JsonSchema, 'pointscollection');
// this function gets ALL the points from the db
// returns the entire document without modifications
exports.get_points = function(callback) {
- Json.find({}).exec(function(err, docs) {
- if (err) callback(err, null);
- callback(null, docs);
- });
+ Json.find({}).exec(function(err, docs) {
+ if (err) callback(err, null);
+ callback(null, docs);
+ });
}
exports.get_all_active_points = function(callback) {
- var activeStatusTypes = ["new", "pending"];
- Json.find({ status: { $in: activeStatusTypes } }).exec(function(err, docs) {
- if (err) callback(err, null);
- callback(null, docs);
- });
+ var activeStatusTypes = ["new", "pending"];
+ Json.find({ status: { $in: activeStatusTypes } }).exec(function(err, docs) {
+ if (err) callback(err, null);
+ callback(null, docs);
+ });
}
// this function stores A user report into the db
exports.save_request = function(data, callback) {
- Json.create(data, function(err, result) {
- if (err) callback(err, null);
- callback(null, result);
- });
+ Json.create(data, function(err, result) {
+ if (err) callback(err, null);
+ callback(null, result);
+ });
}
exports.update_point_status = function(id, newStatus, callback) {
- Json.findByIdAndUpdate(id, {status: newStatus}, {new: true},
- function(err, result) {
- if (err) callback(err, null);
- // result contains the updated point document
- callback(null, result);
- }
- );
+ Json.findByIdAndUpdate(id, {status: newStatus}, {new: true},
+ function(err, result) {
+ if (err) callback(err, null);
+ // result contains the updated point document
+ callback(null, result);
+ }
+ );
}
diff --git a/web/public/javascripts/map.js b/web/public/javascripts/map.js
index a3d2fb3..5ee9219 100644
--- a/web/public/javascripts/map.js
+++ b/web/public/javascripts/map.js
@@ -5,198 +5,197 @@
let currPoint;
const Races = {
- "White" : "European or White",
- "eAsian" : "East Asian",
- "sAsian" : "South Asian",
- "Black" : "Black or African American",
- "Aboriginal": "Aboriginal",
- "Other" : "Other",
+ "White" : "European or White",
+ "eAsian" : "East Asian",
+ "sAsian" : "South Asian",
+ "Black" : "Black or African American",
+ "Aboriginal": "Aboriginal",
+ "Other" : "Other",
};
const PendingIcon = new L.Icon({
- iconAnchor: [ 12, 41 ],
- iconUrl: "../images/orange-icon.png",
- iconSize: [ 25, 41 ],
- popupAnchor: [ 1, -34 ],
- shadowSize: [ 41, 41 ],
- shadowUrl: "../images/marker-shadow.png",
- tooltipAnchor: [ 16, -28 ]
+ iconAnchor: [ 12, 41 ],
+ iconUrl: "../images/orange-icon.png",
+ iconSize: [ 25, 41 ],
+ popupAnchor: [ 1, -34 ],
+ shadowSize: [ 41, 41 ],
+ shadowUrl: "../images/marker-shadow.png",
+ tooltipAnchor: [ 16, -28 ]
});
function plotPointsOnMap(points) {
- L.geoJson(points, {
- pointToLayer: function (feature, latlng) {
- //return L.circleMarker(latlng);
- latlngbounds.extend(latlng);
- if (feature.status === "pending") {
- return L.marker(latlng, {icon: PendingIcon});
- }
- return L.marker(latlng);
- }
- }).on('click', showDetails).addTo(map);
-
- // rezoom the map so that all the markers fit in the view, add 20% padding so
- // that marker dont cut off
- console.log(latlngbounds)
- map.fitBounds(latlngbounds.pad(0.20));
+ L.geoJson(points, {
+ pointToLayer: function (feature, latlng) {
+ //return L.circleMarker(latlng);
+ latlngbounds.extend(latlng);
+ if (feature.status === "pending") {
+ return L.marker(latlng, {icon: PendingIcon});
+ }
+ return L.marker(latlng);
+ }
+ }).on('click', showDetails).addTo(map);
+
+ // rezoom the map so that all the markers fit in the view, add 20% padding so
+ // that marker dont cut off
+ map.fitBounds(latlngbounds.pad(0.20));
}
// show details about point
// e is the event info
function showDetails(e) {
- if(currPoint !== undefined) {
- if (currPoint.feature.geometry.status === "new") {
- currPoint._icon.src = '../images/blue-icon.png';
- }
- else if (currPoint.feature.geometry.status === "pending") {
- currPoint._icon.src = '../images/orange-icon.png';
- }
- }
-
- // layer.feature.geometry gives you access to all the fields
- let layer = e.layer;
- currPoint = layer;
-
- if (currPoint.feature.geometry.status === "new") {
- currPoint._icon.src = '../images/blue-icon-focused.png';
- }
- else if (currPoint.feature.geometry.status === "pending") {
- currPoint._icon.src = '../images/orange-icon-focused.png';
- }
-
- const pointBounds = [currPoint.getLatLng()];
- map.fitBounds(pointBounds);
-
- let sideBar = document.getElementById('sidebar');
-
- if (getComputedStyle(sideBar).visibility === 'hidden') {
- sideBar.style.visibility = 'visible';
- }
-
- // remove the previous report text
- let report = document.getElementById('report');
- let prevUserInputs = report.getElementsByClassName('user-input');
- for (let i=0; i < prevUserInputs.length; i++) {
- prevUserInputs[i].innerHTML = "";
- }
-
- // put gender of the person
- let genderTextSpan = document.getElementById('report-gender');
- genderTextSpan.className = 'user-input';
- let genderText = document.createTextNode(layer.feature.geometry['gender']);
- genderTextSpan.appendChild(genderText);
-
- // put age range of person
- let ageRangeTextSpan = document.getElementById('report-age-range');
- ageRangeTextSpan.className = 'user-input';
- let ageRangeText = document.createTextNode(
- " ~ " + layer.feature.geometry['age'] + " years");
- ageRangeTextSpan.appendChild(ageRangeText);
-
- // put race of person
- let raceTextSpan = document.getElementById('report-race');
- raceTextSpan.className = 'user-input';
- let raceText = document.createTextNode(
- Races[layer.feature.geometry['race']]
- );
- raceTextSpan.appendChild(raceText);
-
- // put other attributes
- let otherAttrTextSpan = document.getElementById('report-other');
- otherAttrTextSpan.className = 'user-input';
- otherAttrTextSpan.innerHTML =
- "Long hair? " + (layer.feature.geometry['longhair'] ? "Yes" : "No") +
- "<br>" +
- "Long beard? " + (layer.feature.geometry['longbeard'] ? "Yes" : "No");
-
- // put extra info
- let extraTextSpan = document.getElementById('report-distinctive');
- extraTextSpan.className = 'user-input';
- let extraText = document.createTextNode(layer.feature.geometry['extra']);
- extraTextSpan.appendChild(extraText);
-
- let pendingBtn = document.getElementById('pending-btn');
- pendingBtn.addEventListener('click', markAsPending);
-
- let completedBtn = document.getElementById('completed-btn');
- completedBtn.addEventListener('click', markAsCompleted);
-
- let closeBtn = document.getElementById('close-btn');
- closeBtn.addEventListener('click', closeDetails);
+ if(currPoint !== undefined) {
+ if (currPoint.feature.geometry.status === "new") {
+ currPoint._icon.src = '../images/blue-icon.png';
+ }
+ else if (currPoint.feature.geometry.status === "pending") {
+ currPoint._icon.src = '../images/orange-icon.png';
+ }
+ }
+
+ // layer.feature.geometry gives you access to all the fields
+ let layer = e.layer;
+ currPoint = layer;
+
+ if (currPoint.feature.geometry.status === "new") {
+ currPoint._icon.src = '../images/blue-icon-focused.png';
+ }
+ else if (currPoint.feature.geometry.status === "pending") {
+ currPoint._icon.src = '../images/orange-icon-focused.png';
+ }
+
+ const pointBounds = [currPoint.getLatLng()];
+ map.fitBounds(pointBounds);
+
+ let sideBar = document.getElementById('sidebar');
+
+ if (getComputedStyle(sideBar).visibility === 'hidden') {
+ sideBar.style.visibility = 'visible';
+ }
+
+ // remove the previous report text
+ let report = document.getElementById('report');
+ let prevUserInputs = report.getElementsByClassName('user-input');
+ for (let i=0; i < prevUserInputs.length; i++) {
+ prevUserInputs[i].innerHTML = "";
+ }
+
+ // put gender of the person
+ let genderTextSpan = document.getElementById('report-gender');
+ genderTextSpan.className = 'user-input';
+ let genderText = document.createTextNode(layer.feature.geometry['gender']);
+ genderTextSpan.appendChild(genderText);
+
+ // put age range of person
+ let ageRangeTextSpan = document.getElementById('report-age-range');
+ ageRangeTextSpan.className = 'user-input';
+ let ageRangeText = document.createTextNode(
+ " ~ " + layer.feature.geometry['age'] + " years");
+ ageRangeTextSpan.appendChild(ageRangeText);
+
+ // put race of person
+ let raceTextSpan = document.getElementById('report-race');
+ raceTextSpan.className = 'user-input';
+ let raceText = document.createTextNode(
+ Races[layer.feature.geometry['race']]
+ );
+ raceTextSpan.appendChild(raceText);
+
+ // put other attributes
+ let otherAttrTextSpan = document.getElementById('report-other');
+ otherAttrTextSpan.className = 'user-input';
+ otherAttrTextSpan.innerHTML =
+ "Long hair? " + (layer.feature.geometry['longhair'] ? "Yes" : "No") +
+ "<br>" +
+ "Long beard? " + (layer.feature.geometry['longbeard'] ? "Yes" : "No");
+
+ // put extra info
+ let extraTextSpan = document.getElementById('report-distinctive');
+ extraTextSpan.className = 'user-input';
+ let extraText = document.createTextNode(layer.feature.geometry['extra']);
+ extraTextSpan.appendChild(extraText);
+
+ let pendingBtn = document.getElementById('pending-btn');
+ pendingBtn.addEventListener('click', markAsPending);
+
+ let completedBtn = document.getElementById('completed-btn');
+ completedBtn.addEventListener('click', markAsCompleted);
+
+ let closeBtn = document.getElementById('close-btn');
+ closeBtn.addEventListener('click', closeDetails);
}
function markAsPending(e) {
- let currPointDetails = currPoint.feature.geometry;
- let currPointId = currPointDetails._id;
- if (currPointDetails.status === "pending") return;
-
- currPoint._icon.src = '../images/orange-icon-focused.png';
- currPointDetails.status = "pending";
-
- updatePointStatusInDb(currPointId, "pending")
- .then(function(responseJson) {
- alert("Your change has been saved.");
- currPoint._icon.src = '../images/orange-icon-focused.png';
- })
- .catch(function(error) {
- alert(error);
- });
+ let currPointDetails = currPoint.feature.geometry;
+ let currPointId = currPointDetails._id;
+ if (currPointDetails.status === "pending") return;
+
+ currPoint._icon.src = '../images/orange-icon-focused.png';
+ currPointDetails.status = "pending";
+
+ updatePointStatusInDb(currPointId, "pending")
+ .then(function(responseJson) {
+ alert("Your change has been saved.");
+ currPoint._icon.src = '../images/orange-icon-focused.png';
+ })
+ .catch(function(error) {
+ alert(error);
+ });
}
function markAsCompleted(e) {
- let currPointDetails = currPoint.feature.geometry;
- let currPointId = currPointDetails._id;
- if (currPointDetails.status === "complete") return;
-
- updatePointStatusInDb(currPointId, "complete")
- .then(function(responseJson) {
- alert("Your change has been saved.");
- map.removeLayer(currPoint);
- currPoint = undefined;
- })
- .catch(function(error) {
- alert(error);
- });
- closeDetails();
+ let currPointDetails = currPoint.feature.geometry;
+ let currPointId = currPointDetails._id;
+ if (currPointDetails.status === "complete") return;
+
+ updatePointStatusInDb(currPointId, "complete")
+ .then(function(responseJson) {
+ alert("Your change has been saved.");
+ map.removeLayer(currPoint);
+ currPoint = undefined;
+ })
+ .catch(function(error) {
+ alert(error);
+ });
+ closeDetails();
}
function closeDetails(e) {
- let details = document.getElementById('sidebar')
- details.style.visibility = 'hidden';
-
- if (currPoint.feature.geometry.status === "pending") {
- currPoint._icon.src = '../images/orange-icon.png';
- }
- else if (currPoint.feature.geometry.status === "new") {
- currPoint._icon.src = '../images/blue-icon.png';
- }
- map.fitBounds(latlngbounds.pad(0.20));
+ let details = document.getElementById('sidebar')
+ details.style.visibility = 'hidden';
+
+ if (currPoint.feature.geometry.status === "pending") {
+ currPoint._icon.src = '../images/orange-icon.png';
+ }
+ else if (currPoint.feature.geometry.status === "new") {
+ currPoint._icon.src = '../images/blue-icon.png';
+ }
+ map.fitBounds(latlngbounds.pad(0.20));
}
// returns a Promise object
function updatePointStatusInDb(pointId, pointStatus) {
- return fetch('/savestatus/' + pointStatus, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({id: pointId}),
- })
- .then(function(response) {
- if (response.ok) {
- return response.json();
- }
- throw new Error("We were unable to save your changes.");
- });
+ return fetch('/savestatus/' + pointStatus, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({id: pointId}),
+ })
+ .then(function(response) {
+ if (response.ok) {
+ return response.json();
+ }
+ throw new Error("We were unable to save your changes.");
+ });
}
// different basemap
L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}.{ext}', {
- attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
- subdomains: 'abcd',
- minZoom: 0,
- maxZoom: 18,
- ext: 'png'
+ attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
+ subdomains: 'abcd',
+ minZoom: 0,
+ maxZoom: 18,
+ ext: 'png'
}).addTo(map);
// keep track of the boundary of the markers so that we can update the
@@ -204,29 +203,29 @@ L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}
var latlngbounds = new L.latLngBounds();
if (points.length) {
- plotPointsOnMap(points);
+ plotPointsOnMap(points);
}
// setup live updates
if (window.EventSource) {
- var source = new EventSource('/stream');
-
- source.addEventListener('message', function(e) {
- var data = JSON.parse(e.data);
- if (data.coordinates) {
- points.push(data);
- plotPointsOnMap(data);
- }
- }, false)
-
- source.addEventListener('open', function(e) {
- console.log("Connection was opened")
- }, false)
-
- source.addEventListener('error', function(e) {
- if (e.readyState == EventSource.CLOSED) {
- console.log("Connection was closed")
- }
- }, false)
+ var source = new EventSource('/stream');
+
+ source.addEventListener('message', function(e) {
+ var data = JSON.parse(e.data);
+ if (data.coordinates) {
+ points.push(data);
+ plotPointsOnMap(data);
+ }
+ }, false)
+
+ source.addEventListener('open', function(e) {
+ console.log("Connection was opened")
+ }, false)
+
+ source.addEventListener('error', function(e) {
+ if (e.readyState == EventSource.CLOSED) {
+ console.log("Connection was closed")
+ }
+ }, false)
} else {
- console.log("sse not supported.");
+ console.log("sse not supported.");
}
diff --git a/web/routes/index.js b/web/routes/index.js
index 05df4d4..24fa334 100644
--- a/web/routes/index.js
+++ b/web/routes/index.js
@@ -11,82 +11,82 @@ const glookup = new GeoJsonGeometriesLookup(torontoNeighbourhoords);
/* GET home page. */
router.get('/', function(req, res, next) {
- // for now just redirect to /map
- //res.redirect('/map');
- res.render('index');
+ // for now just redirect to /map
+ //res.redirect('/map');
+ res.render('index');
});
/* GET Map page. */
router.get('/map', function(req,res) {
- Points.get_all_active_points(function(err, points){
- res.render('map', {
- lat : 43.665234,
- lng : -79.383370,
- points: points
- });
- });
+ Points.get_all_active_points(function(err, points){
+ res.render('map', {
+ lat : 43.665234,
+ lng : -79.383370,
+ points: points
+ });
+ });
});
router.post('/mobilerequest', function(req, res) {
- var point = req.body;
+ var point = req.body;
- if (!point.coordinates.length) {
- var errMssg = "Coordinates field must not be empty in a request.";
- return res.status(422).send({ error: errMssg });
- }
+ if (!point.coordinates.length) {
+ var errMssg = "Coordinates field must not be empty in a request.";
+ return res.status(422).send({ error: errMssg });
+ }
- if (!glookup.hasContainers(point)) {
- var errMssg = "Sorry, we currently only support locations strictly within the City of Toronto.";
- return res.status(422).send({ error: errMssg });
- }
+ if (!glookup.hasContainers(point)) {
+ var errMssg = "Sorry, we currently only support locations strictly within the City of Toronto.";
+ return res.status(422).send({ error: errMssg });
+ }
- // here we are guaranteed to have a valid point in Toronto
- Points.save_request(point, function(err, result) {
- if (err) {
- console.log(`err inserting mobile request into db: ${err}`);
- res.status(500).send({ error: "Sorry, something failed on our end." });
- } else {
- // send event to all connections
- for(var i = 0; i < connections.length; i++) {
- connections[i].sseSend(result);
- }
- console.log(result);
- res.status(201).send({'status': 'success'});
- }
- });
+ // here we are guaranteed to have a valid point in Toronto
+ Points.save_request(point, function(err, result) {
+ if (err) {
+ console.log(`err inserting mobile request into db: ${err}`);
+ res.status(500).send({ error: "Sorry, something failed on our end." });
+ } else {
+ // send event to all connections
+ for(var i = 0; i < connections.length; i++) {
+ connections[i].sseSend(result);
+ }
+ console.log(result);
+ res.status(201).send({'status': 'success'});
+ }
+ });
});
router.post('/savestatus/:status', function(req, res) {
- var data = req.body;
- var pointId = data.id;
- var setStatus = req.params.status;
- if (
- setStatus !== "new" &&
- setStatus !== "pending" &&
- setStatus !== "complete"
- ) {
- console.log("Invalid status supplied.");
- return res.status(422).send({error: "Error: Status must be one of 'new', 'pending', or 'complete'"});
- }
+ var data = req.body;
+ var pointId = data.id;
+ var setStatus = req.params.status;
+ if (
+ setStatus !== "new" &&
+ setStatus !== "pending" &&
+ setStatus !== "complete"
+ ) {
+ console.log("Invalid status supplied.");
+ return res.status(422).send({error: "Error: Status must be one of 'new', 'pending', or 'complete'"});
+ }
- // here we are guaranteed to be able to do the query
- Points.update_point_status(pointId, setStatus, function(err, result) {
- if (err) {
- console.log(`err updating point status in db: ${err}`);
- res.status(500).send({ error: "Oops. Something went wrong on our end." });
- } else {
- console.log(result);
- res.status(200).send({'status': 'success'});
- }
- });
+ // here we are guaranteed to be able to do the query
+ Points.update_point_status(pointId, setStatus, function(err, result) {
+ if (err) {
+ console.log(`err updating point status in db: ${err}`);
+ res.status(500).send({ error: "Oops. Something went wrong on our end." });
+ } else {
+ console.log(result);
+ res.status(200).send({'status': 'success'});
+ }
+ });
});
router.get('/stream', function(req, res){
- // set up server side event (communication line between front end and server)
- res.sseSetup();
- // send an event to the front end to open the connection
- res.sseSend('ok');
- // push connection to connection array
- connections.push(res);
+ // set up server side event (communication line between front end and server)
+ res.sseSetup();
+ // send an event to the front end to open the connection
+ res.sseSend('ok');
+ // push connection to connection array
+ connections.push(res);
});
module.exports = router;