Skip to content
Browse files

Code cleanup. Dynamic title. Added configurations. Support for geoloc…

…ation.
  • Loading branch information...
1 parent 0df5579 commit e51e533a20cd93464675dba4a693dfc03ccf2eb5 @st3fan committed Mar 30, 2013
Showing with 179 additions and 108 deletions.
  1. +50 −51 resources/public/index.html
  2. +129 −57 resources/public/index.js
View
101 resources/public/index.html
@@ -18,33 +18,32 @@
}
#header {
- width: 100%;
- background: url("assets/wallpaper.png") repeat center top, -webkit-linear-gradient(top, rgba(30,30,30,1) 0%, rgba(0,0,0,1) 100%);
- background: url("assets/wallpaper.png") repeat center top, -moz-linear-gradient(top, rgba(30,30,30,1) 0%, rgba(0,0,0,1) 100%);
- border-bottom: 4px solid #a52118;
- box-shadow: 0px 20px 0px rgba(0,0,0,0.05);
+ width: 100%;
+ background: url("assets/wallpaper.png") repeat center top, -webkit-linear-gradient(top, rgba(30,30,30,1) 0%, rgba(0,0,0,1) 100%);
+ background: url("assets/wallpaper.png") repeat center top, -moz-linear-gradient(top, rgba(30,30,30,1) 0%, rgba(0,0,0,1) 100%);
+ border-bottom: 4px solid #a52118;
+ box-shadow: 0px 20px 0px rgba(0,0,0,0.05);
}
#header p {
- font-family: 'Montserrat', sans-serif;
- font-weight: 400;
- font-size: 42px;
- color: #ffffff;
- text-transform: uppercase;0
- text-align: center;
- letter-spacing: 2px;
- padding: 20px;
+ font-family: 'Montserrat', sans-serif;
+ font-weight: 400;
+ font-size: 42px;
+ color: #ffffff;
+ text-transform: uppercase;0
+ text-align: center;
+ letter-spacing: 2px;
+ padding: 20px;
}
.logo {
- float: right;
- color: #fff;
- font-size: 42px;
- margin-top: -80px;
- margin-right: 20px;
+ float: right;
+ color: #fff;
+ font-size: 42px;
+ margin-top: -80px;
+ margin-right: 20px;
}
-
-
+
.prediction {
height: 50px;
width: 100%;
@@ -59,12 +58,12 @@
}
.prediction h1 {
- padding-left: 14px;
- font-family: 'Montserrat', sans-serif;
- font-weight: 400;
- letter-spacing: 2px;
- font-size: 42px;
- color: #333;
+ padding-left: 14px;
+ font-family: 'Montserrat', sans-serif;
+ font-weight: 400;
+ letter-spacing: 2px;
+ font-size: 42px;
+ color: #333;
}
.route {
@@ -92,46 +91,46 @@
}
.stop {
- text-transform: uppercase;
- font-size: 200%;
- color: #333;
+ text-transform: uppercase;
+ font-size: 200%;
+ color: #333;
}
.name {
- float: left;
- margin-left: 20px;
- padding-top: 2px;
- height: 50px;
- text-transform: uppercase;
- font-size: 30%;
- color: #a52118;
+ float: left;
+ margin-left: 20px;
+ padding-top: 2px;
+ height: 50px;
+ text-transform: uppercase;
+ font-size: 30%;
+ color: #a52118;
}
.timelist {
- float: right;
- padding-right: 14px;
+ float: right;
+ padding-right: 14px;
}
.timelist li {
- font-family: 'Montserrat', sans-serif;
- font-weight: 400;
- width: 48px;
- font-size: 36px;
- display: inline;
- float: left;
- list-style-type: none;
- margin-right: 20px;
- padding: 0px 6px;
- height: 70px;
- border-left: 1px solid rgba(0,0,0,0.1);
- text-align: center;
+ font-family: 'Montserrat', sans-serif;
+ font-weight: 400;
+ width: 48px;
+ font-size: 36px;
+ display: inline;
+ float: left;
+ list-style-type: none;
+ margin-right: 20px;
+ padding: 0px 6px;
+ height: 70px;
+ border-left: 1px solid rgba(0,0,0,0.1);
+ text-align: center;
}
</style>
</head>
<body ng-controller="PredictionsController">
- <div id="header"><p>Mozilla Toronto Transit Board</p></div>
+ <div id="header"><p>{{title}}</p></div>
<div ng-show="focus">
<timer progress="{{progress}}"></timer>
View
186 resources/public/index.js
@@ -1,3 +1,33 @@
+
+// Configuration: predefined locations. You can specify these in the
+// url like http://127.0.0.1:8080/#hacklabto If no location is
+// specified then the app defaults to your current geo location and
+// shows all stops near you within a 200 meter radius
+
+var locations = {
+ "hacklabto": {
+ title: "Hacklab.TO Transit Board",
+ agency: "ttc",
+ routes: [
+ {route: "510", stop: "3159", stopName: "Spadina & Nassau"}, // 510 South: Spadina Ave At Nassau St South Side
+ {route: "510", stop: "6577", stopName: "Spadina & Nassau"} // 510 North: Spadina Ave at Nassau St
+ ]
+ },
+ "mozilla-toronto": {
+ title: "Mozilla Toronto Transit Board",
+ agency: "ttc",
+ routes: [
+ {route: "501", stop: "7060", stopName: "Queen & Peter"}, // 501 East: Queen & Peter St
+ {route: "501", stop: "1653", stopName: "Queen & Spadina"}, // 501 West: Queen & Spadina Ave
+ {route: "504", stop: "436", stopName: "King & Spadina"}, // 504 West: King St West & Spadina Ave
+ {route: "508", stop: "436", stopName: "King & Spadina"}, // 508 West: King St West & Spadina Ave
+ {route: "510", stop: "5275", stopName: "King & Spadina"} // 510 North: Spadina Ave & King St West North Side
+ ]
+ }
+};
+
+// Below here is all app code.
+
var app = angular.module('predictions', []);
app.directive('timer', function () {
@@ -15,87 +45,117 @@ app.controller('PredictionsController', function ($scope, $http, $timeout) {
$scope.progress = 0;
$scope.lines = [];
$scope.focus = true;
+ $scope.title = "";
+
+ $scope.loadPredictions = function(location) {
- if (false) {
- window.onfocus = function() {
- $scope.focus = true;
- $scope.progress = 0;
- $scope.seconds = 0;
+ var stopsForLocation = function(name) {
+ var stops = [];
+ for (var i = 0; i < locations[name].routes.length; i++) {
+ stops.push(locations[name].routes[i].stop);
+ }
+ return stops;
};
-
- window.onblur = function() {
- $scope.focus = false;
- $scope.lines = [];
+
+ var simplifyDirectionName = function(name) {
+ name = name.replace("Station", "stn");
+ var i = name.indexOf("towards");
+ if (i != -1) {
+ return "T" + name.substring(i+1);
+ } else {
+ return name;
+ }
};
- }
- //
+ var request = {method: "GET"};
+ if (location.position) {
+ request.url = "/api/predictions-for-position";
+ request.params = {latitude: location.position.latitude, longitude: location.position.longitude, radius: 0.25};
+ } else if (location.name) {
+ request.url = "/api/predictions-for-stops";
+ request.params = {stops: stopsForLocation(location.name).join(",")};
+ }
- $scope.loadPredictions = function() {
- $http({method: "GET", url: "/api/predictions-for-stops", params: {stops: "7060,1653,436,5275"}})
+ $http(request)
.success(function(data) {
- // TODO Ideally all this moves to the server side so that we only have to fetch data here
- var routesOfInterest = [
- {route: "501", stop: "7060", stopName: "Queen & Peter"}, // 501 East: Queen & Peter St
- {route: "501", stop: "1653", stopName: "Queen & Spadina"}, // 501 West: Queen & Spadina Ave
- {route: "504", stop: "436", stopName: "King & Spadina"}, // 504 West: King St West & Spadina Ave
- {route: "508", stop: "436", stopName: "King & Spadina"}, // 508 West: King St West & Spadina Ave
- {route: "510", stop: "5275", stopName: "King & Spadina"} // 510 North: Spadina Ave & King St West North Side
- ];
-
- var isPredictionOfInterest = function(prediction) {
- for (var i = 0; i < routesOfInterest.length; i++) {
- if (routesOfInterest[i].route === prediction.route.tag && routesOfInterest[i].stop === prediction.stop.tag) {
- return true;
+
+ var lines = [];
+
+ if (location.name)
+ {
+ var isPredictionOfInterest = function(name, prediction) {
+ for (var i = 0; i < locations[name].routes.length; i++) {
+ if (locations[name].routes[i].route === prediction.route.tag && locations[name].routes[i].stop === prediction.stop.tag) {
+ return true;
+ }
}
- }
- return false;
- };
-
- var simplifyDirectionName = function(name) {
- var i = name.indexOf("towards");
- if (i != -1) {
- return "T" + name.substring(i+1);
- } else {
- return name;
- }
- };
+ return false;
+ };
- var getStopName = function(tag) {
- for (var i = 0; i < routesOfInterest.length; i++) {
- if (tag === routesOfInterest[i].stop) {
- return routesOfInterest[i].stopName;
- }
+ var getStopName = function(name, tag) {
+ for (var i = 0; i < locations[name].routes.length; i++) {
+ if (tag === locations[name].routes[i].stop) {
+ return locations[name].routes[i].stopName;
+ }
+ }
+ return "";
}
- return "";
+
+ _.each(data.predictions, function (prediction) {
+ if (isPredictionOfInterest(location.name, prediction)) {
+ _.each(prediction.directions, function (direction) {
+ var line = {route: prediction.route.tag,
+ direction: direction.title[0],
+ stopName: simplifyDirectionName(direction.title),
+ times: [],
+ name: getStopName(location.name, prediction.stop.tag) };
+ _.each(direction.predictions, function(prediction) {
+ if (prediction.minutes > 1) {
+ line.times.push(prediction.minutes);
+ }
+ });
+ lines.push(line);
+ });
+ }
+ });
}
- var lines = [];
- _.each(data.predictions, function (prediction) {
- if (isPredictionOfInterest(prediction)) {
+ else if (location.position)
+ {
+ _.each(data.predictions, function (prediction) {
_.each(prediction.directions, function (direction) {
- var line = {route: prediction.route.tag, direction: direction.title[0],
- name: simplifyDirectionName(direction.title), times: [], stopName: getStopName(prediction.stop.tag) };
+ var line = {route: prediction.route.tag,
+ direction: direction.title[0],
+ stopName: simplifyDirectionName(direction.title),
+ times: [],
+ name: prediction.stop.title };
_.each(direction.predictions, function(prediction) {
- if (prediction.minutes > 1) {
+ if (prediction.minutes > 0) {
line.times.push(prediction.minutes);
}
});
lines.push(line);
- });
- }
- });
+ });
+ });
+ }
- $scope.lines = lines;
+ // Sort by direction, then line
+ var directions = ['E', 'W', 'N', 'S'];
+ $scope.lines = _.sortBy(lines, function(line) { return "" + directions.indexOf(line.direction) + line.route; });
})
.error(function(/*data, status, headers, config*/){
});
};
+ // If we are called with a location name (in the hash) then we load those stops. Otherwise
+ // we figure out where we are and just show stops near us.
+
+ var location = {};
+
$scope.onTimeout = function() {
if ($scope.focus) {
if ($scope.seconds == 0) {
- $scope.loadPredictions();
+ $scope.loadPredictions(location);
}
$scope.seconds++;
@@ -108,6 +168,18 @@ app.controller('PredictionsController', function ($scope, $http, $timeout) {
refreshTimeout = $timeout($scope.onTimeout, 1000);
};
- $scope.loadPredictions();
- var refreshTimeout = $timeout($scope.onTimeout, 1000);
+ if (window.location.hash === "") {
+ $scope.title = "Departures"
+ navigator.geolocation.getCurrentPosition(function (position) {
+ location = {position: {latitude: position.coords.latitude, longitude: position.coords.longitude}};
+ $scope.loadPredictions(location);
+ var refreshTimeout = $timeout($scope.onTimeout, 1000);
+ });
+ } else {
+ var name = window.location.hash.substr(1);
+ $scope.title = locations[name].title;
+ location = {name: name};
+ $scope.loadPredictions(location);
+ var refreshTimeout = $timeout($scope.onTimeout, 1000);
+ }
});

0 comments on commit e51e533

Please sign in to comment.
Something went wrong with that request. Please try again.