Skip to content

Commit 90d7185

Browse files
committed
Merge pull request codeforokc#33 from codeforokc/current_location
Merging so we can move forward, will discuss the frontend js stuff a permanent solution when we start getting a build system put together.
2 parents 6250814 + f64d4b7 commit 90d7185

File tree

11 files changed

+214
-28
lines changed

11 files changed

+214
-28
lines changed

school-finder-frontend/README.md

+12
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,22 @@ Gulp is used as a task runner.
1212

1313
npm is used to keep track of dependencies.
1414

15+
#### Folders
16+
17+
- app - holds the final application code
18+
- services = where services are located
19+
- css - where stylesheets are located
20+
- scripts - where external scripts are located
21+
- tests - where tests are located
22+
1523
## Building the app
1624

25+
**As of right now you don't need to do any building, though in the future this will probably change**
26+
1727
* Install node/npm
1828
* Install global dependencies - `npm install -g gulp-cli`
1929
* Install npm dependencies - `npm install`
2030
* Run tests - `gulp test` -- or -- `npm test`
2131
* Build the app - TBD
32+
33+
##

school-finder-frontend/app/app.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
var SCHOOL_FINDER = (function(){
2+
3+
function init() {
4+
console.debug("Started initting app");
5+
6+
// create module
7+
var sfApp = angular.module('sfApp', []);
8+
9+
// register services
10+
sfApp.service("currentLocationService", SCHOOL_FINDER_CLS.CurrentLocationService);
11+
12+
13+
console.debug("Finished initting app");
14+
}
15+
16+
return {
17+
init: init
18+
};
19+
}());
20+
21+
SCHOOL_FINDER.init();

school-finder-frontend/app/css/.gitkeep

Whitespace-only changes.

school-finder-frontend/app/index.html

+30-26
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,37 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<title>School Finder</title>
5-
<!-- Currently using CDN until we decide how we want to handle this -->
6-
<script src='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.js'></script>
7-
<link href='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.css' rel='stylesheet'/>
8-
<script src="../node_modules/angular/angular.js"></script>
9-
<style>
10-
body {
11-
margin: 0;
12-
padding: 0;
13-
}
4+
<title>School Finder</title>
5+
<link rel="stylesheet" href="../node_modules/angular/angular-csp.css" />
6+
<link href='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.css' rel='stylesheet'/>
7+
<style>
8+
body {
9+
margin: 0;
10+
padding: 0;
11+
}
1412

15-
#map {
16-
position: absolute;
17-
top: 0;
18-
bottom: 0;
19-
width: 100%;
20-
}
21-
</style>
13+
#map {
14+
position: absolute;
15+
top: 0;
16+
bottom: 0;
17+
width: 100%;
18+
}
19+
</style>
2220
</head>
23-
<body>
24-
<div id='map'></div>
25-
<script>
26-
// Currently using a personal access token, so feel free to update to an account created for Code for OKC
27-
L.mapbox.accessToken = 'pk.eyJ1IjoibWJvY2t1cyIsImEiOiJGSVhxeUJzIn0.dFVS1mpYRCuR8fn_l0FWew';
28-
// instantiate the map to show okc
29-
var map = L.mapbox.map('map', 'examples.map-i86nkdio')
30-
.setView([35.4826479, -97.4791974], 10);
31-
</script>
21+
<body ng-app="sfApp" ng-strict-di="">
22+
23+
<div id='map'></div>
24+
25+
<script src="../node_modules/angular/angular.js"></script>
26+
<script src="services/currentLocationService.js"></script>
27+
<script src="app.js"></script>
28+
<script src='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.js'></script>
29+
<script>
30+
// Currently using a personal access token, so feel free to update to an account created for Code for OKC
31+
L.mapbox.accessToken = 'pk.eyJ1IjoibWJvY2t1cyIsImEiOiJGSVhxeUJzIn0.dFVS1mpYRCuR8fn_l0FWew';
32+
// instantiate the map to show okc
33+
var map = L.mapbox.map('map', 'examples.map-i86nkdio')
34+
.setView([35.4826479, -97.4791974], 10);
35+
</script>
3236
</body>
3337
</html>

school-finder-frontend/app/scripts/.gitkeep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
(function(exports){
2+
3+
/*
4+
* This is an angular service definition
5+
*/
6+
function CLS() {/*noop*/}
7+
8+
function onError(callback, err) {
9+
return setTimeout(callback.bind(null, err), 0);
10+
}
11+
12+
function onSuccess(callback, position) {
13+
var coordinates = position.coords;
14+
return setTimeout(callback.bind(null, null, coordinates), 1000);
15+
}
16+
17+
/*
18+
* Get the current location from the user
19+
*
20+
* @param geolocation : navigator.geolocation
21+
* @param options : https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions
22+
* @param callback(err, coordinates) : https://developer.mozilla.org/en-US/docs/Web/API/Coordinates
23+
*
24+
*/
25+
CLS.prototype.getCurrentLocation = function(geolocation, options, callback) {
26+
if (!geolocation) {
27+
return setTimeout(callback.bind(null, new Error("Geolocation not available")), 0);
28+
}
29+
geolocation.getCurrentPosition(onSuccess.bind(null, callback),
30+
onError.bind(null, callback),
31+
options);
32+
}
33+
34+
exports.CurrentLocationService = CLS;
35+
}(typeof exports === 'undefined' ? this['SCHOOL_FINDER_CLS']={}: exports));

school-finder-frontend/gulpfile.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
var gulp = require('gulp');
2+
var serve = require('gulp-serve');
3+
var mocha = require('gulp-mocha');
24

35
gulp.task('default', function() {
46

57
});
68

7-
gulp.task('test', function() {
9+
gulp.task('serve', serve(['tests', 'app']));
810

11+
gulp.task('test', function() {
12+
return gulp.src('tests/**/*_spec.js', {read: false})
13+
.pipe(mocha({reporter: 'nyan'}));
914
});

school-finder-frontend/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
"author": "Code for OKC",
99
"license": "MIT",
1010
"devDependencies": {
11-
"gulp": "^3.8.10"
11+
"chai": "^1.10.0",
12+
"gulp": "^3.8.10",
13+
"gulp-mocha": "^2.0.0",
14+
"mocha": "^2.1.0"
1215
},
1316
"dependencies": {
1417
"angular": "^1.3.11",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Test of geolocation service
2+
3+
Just a simple angular app that pulls in the location service and binds a button to call into it.
4+
5+
**Note** you must run this in a browser that has geolocation enabled. By default chrome does not
6+
allow geolocation access to local files so a good choice would be safari or firefox.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var CLS = require('../../app/services/currentLocationService');
2+
3+
var mocha = require('mocha');
4+
var expect = require('chai').expect;
5+
6+
describe("current location service", function(){
7+
describe("getCurrentLocation", function(){
8+
it("should return error if no geolocation available", function(done){
9+
new CLS.CurrentLocationService().getCurrentLocation(undefined, {}, function(err){
10+
expect(err).to.exist;
11+
done();
12+
});
13+
});
14+
});
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>School Finder</title>
5+
</head>
6+
<body ng-app="testApp" ng-strict-di="">
7+
8+
<div ng-controller="LocationController">
9+
<span async-button-disable
10+
default-text="Get Location"
11+
working-text="Getting Location"
12+
watch-value="updatingLocation"
13+
call-function="updateLocation()"></span>
14+
<p ng-cloak ng-hide="location === undefined">
15+
My location is {{ location.latitude }} {{ location.longitude }}
16+
</p>
17+
<p ng-cloak ng-hide="locationError === undefined">
18+
{{ locationError }}
19+
</p>
20+
</div>
21+
22+
<script src="../../node_modules/angular/angular.js"></script>
23+
<script src="../../app/services/currentLocationService.js"></script>
24+
<script>
25+
// create module
26+
var sfApp = angular.module('testApp', []);
27+
28+
// register services
29+
sfApp.service("currentLocationService", SCHOOL_FINDER_CLS.CurrentLocationService);
30+
31+
sfApp.controller("LocationController", [
32+
"$scope",
33+
"currentLocationService",
34+
function($scope, cls) {
35+
$scope.updatingLocation = false;
36+
$scope.location = undefined;
37+
$scope.locationError = undefined;
38+
$scope.updateLocation = function() {
39+
if ($scope.updatingLocation) {
40+
return;
41+
}
42+
$scope.updatingLocation = true;
43+
$scope.location = undefined;
44+
$scope.locationError = undefined;
45+
cls.getCurrentLocation(navigator.geolocation, {timeout: 5000}, function(err, coordinates){
46+
$scope.updatingLocation = false;
47+
if (err) {
48+
console.log(err);
49+
$scope.location = undefined;
50+
$scope.locationError = err;
51+
} else {
52+
console.log("Got coordinates");
53+
$scope.location = coordinates;
54+
}
55+
$scope.$apply(); // trigger angular digest
56+
});
57+
}
58+
}]);
59+
60+
sfApp.directive("asyncButtonDisable", function(){
61+
return {
62+
link: function(scope, el, attrs) {
63+
var button = document.createElement("button");
64+
button.innerHTML = attrs.defaultText;
65+
button.disabled = false;
66+
button.onclick = function(){
67+
scope.$apply(attrs.callFunction);
68+
};
69+
el[0].appendChild(button);
70+
scope.$watch(attrs.watchValue, function(newValue, oldValue){
71+
if (newValue) {
72+
button.innerHTML = attrs.workingText;
73+
button.disabled = true;
74+
} else {
75+
button.innerHTML = attrs.defaultText;
76+
button.disabled = false;
77+
}
78+
});
79+
}
80+
};
81+
});
82+
83+
</script>
84+
</body>
85+
</html>

0 commit comments

Comments
 (0)