--- a/src/main/resources/scripts/tracker.js Wed Aug 24 17:52:18 2011 -0400
+++ b/src/main/resources/scripts/tracker.js Wed Aug 24 17:54:23 2011 -0400
@@ -1,40 +1,58 @@
var Const = {
- distance : { km : 1,
- mile : 0.621371192,
- toString : function(propertyValue) {
- var arr = Object.getOwnPropertyNames(this);
- for (var i = 0; i < arr.length; i++) {
- if (this[arr[i]] === propertyValue) return arr[i];
- }
- return "";
- }
- },
+ distance : { km : 1, mile : 0.621371192 },
+ height : { cm : 1, inch : 0.393700787 },
+ weight : { kg : 1, lb : 2.20462262 },
// wait for at least 2 consecutive GPS data before declaring the GPS ready
- gps_max_errors : 2,
+ gps_max_errors : 2
+
+
};
var user = (function () {
- function dummyuser() {
- this.name = "dummy";
- this.weight = 73;
- this.height = 180;
- this.distance = Const.distance.km;
- this.prefs = { weight : "kg", height : "cm", distance : Const.distance.toString(Const.distance.km) };
+ var n = null;
+ try {
+ var n = Util.store.get("track_gps_user");
+ if (n === null) {
+ Util.log("Creating dummy user");
+ n = {
+ name : "dummy@example.com",
+ weight : 73,
+ height : 180,
+ prefs : {
+ weight : Util.getPropertyString(Const.weight, Const.weight.kg),
+ height : Util.getPropertyString(Const.height, Const.height.cm),
+ distance : Util.getPropertyString(Const.distance, Const.distance.km)
+ }
+ };
+ } else {
+ Util.log("Found user " + n.name);
}
- var n = Util.store.get("track_gps_user");
- if (n === null) n = new dummyuser();
n.getPostRunURI = function() { return "/user/" + this.name + "/run"; }
n.getProfileURI = function() { return "/user/" + this.name + "/profile"; }
- n.setDistance = function(propertyString) { this.distance = Const.distance[propertyString]; this.prefs.distance = propertyString; }
+
n.save = function() {
- Util.store.set("track_gps_user", this);
+ if (Util.store.set("track_gps_user", this)) {
+ Util.log("Saved user preferences");
+ } else {
+ Util.log("Failed to save preferences");
+ }
+
};
-
+ } catch (e) { Util.log("[ERROR] user " + e); }
return n;
})();
+function Activity(type) {
+ this.activity = type;
+ this.time = 0;
+ this.distance = 0;
+ this.duration = 0;
+ this.userAgent = navigator.userAgent;
+ this.events = [];
+}
+
var app = {
// identifier for geolocation watch operation
@@ -45,6 +63,7 @@
// total real time duration
duration : 0,
+
// start_time since start or pause
start_time : 0,
@@ -61,8 +80,7 @@
locations : 0,
// this will store all the geolocation data and pause
- currentActivity : { activity: "http://dbpedia.org/resource/Running", events: []},
-
+ currentActivity : new Activity("http://dbpedia.org/resource/Running")
};
// add a geolocation position into the current activity
@@ -77,11 +95,12 @@
var events = activity.events;
events[events.length] = { t:Date.now(), s: [ "pause" ] };
}
+
// simply refresh the current screen data
app.repaint = function () {
if (document.visibilityState && app.inActivity) {
document.getElementById("locations").textContent = String(app.locations);
- var d = Util.geo.calculateDistanceCoordinates(app.currentActivity.events) * user.distance;
+ var d = Util.geo.calculateDistanceCoordinates(app.currentActivity.events) * Const.distance[user.prefs.distance];
var t = app.duration + (Date.now() - app.start_time);
document.getElementById("distance").textContent = String(Math.round(d*100)/100);
if (t != 0 && d != 0) {
@@ -181,17 +200,21 @@
if (!app.inActivity) {
// start an activity
app.inActivity = true;
- app.start_time = Date.now();
+ var now = Date.now();
+ app.start_time = now;
app.intervalId = setInterval(app.timer, 1000);
document.getElementById("stop").disabled = false;
document.getElementById("start").textContent = "Pause";
+ if (app.currentActivity.time === 0) {
+ app.currentActivity.time = now;
+ }
} else {
// pause an activity
app.inActivity = false;
clearInterval(app.intervalId);
app.duration += (Date.now() - app.start_time);
document.getElementById("start").textContent = "Restart";
- app.pause_event(app.activity);
+ app.pause_event(app.currentActivity);
document.getElementById("gps_text").style.display = "inline";
document.getElementById("gps_data").style.display = "none";
}
@@ -202,22 +225,24 @@
app.inActivity = false;
navigator.geolocation.clearWatch(app.watchId);
clearInterval(app.intervalId);
+ app.currentActivity.duration += (Date.now() - app.currentActivity.time);
+ app.currentActivity.distance = Util.geo.calculateDistanceCoordinates(app.currentActivity.events);
app.got_error = 0;
app.locations = 0;
app.discarded = 0;
- app.duration = 0;
+ app.duration = 0;
document.getElementById("start").textContent = "Start";
document.getElementById("stop").disabled = true;
- Util.log("");
if (!Util.postNewResourceAsJSON(user.getPostRunURI(),app.currentActivity)) {
if (!Util.store.set("track_gps_app", app.currentActivity)) {
Util.log("[ERROR] Can't store the value " + e.code);
}
}
- app.currentActivity.events = [];
+ app.currentActivity = new Activity("http://dbpedia.org/resource/Running");
}
-app.init = function () {
+app.init = function () {
+
if (!!document.visibilityState)
document.addEventListener("visibilitychange", app.repaint, false);
else
@@ -227,17 +252,18 @@
// return false;
// @@ in the future, make sure this is empty
- if (Util.store.set("track_gps_app", "")) {
- app.setUnit();
- } else {
- Util.log("[ERROR] no local storage");
- }
- if (!!navigator.geolocation) {
- app.watchId = navigator.geolocation.watchPosition(app.handleSuccess, app.handleError, {enableHighAccuracy:true, maximumAge:0, timeout:1000});
- } else {
- document.getElementById("gps_text").textContent = "not supported";
- document.getElementById("start").disabled = true;
- }
+ if (!Util.store.enabled) {
+ Util.log("[ERROR] no local storage");
+ }
+ app.setPrefs();
+
+ if (!!navigator.geolocation) {
+ app.watchId = navigator.geolocation.watchPosition(app.handleSuccess, app.handleError, {enableHighAccuracy:true, maximumAge:0, timeout:1000});
+ } else {
+ Util.log("[ERROR] no geolocation support");
+ document.getElementById("gps_text").textContent = "not supported";
+ document.getElementById("start").disabled = true;
+ }
}
@@ -247,22 +273,79 @@
var node = firstElementChild(document.getElementById("select_distance"));
do {
if (node.selected) {
- user.setDistance(node.getAttribute("value"));
+ user.prefs.distance = node.getAttribute("value");
}
} while ((node=nextElementSibling(node)) != null);
- app.setUnit();
+ app.setPrefs();
app.repaint();
user.save();
}
-app.setUnit = function () {
- var nodes = document.getElementsByClassName("distance_unit");
+app.changeWeightUnit = function () {
+ var node = firstElementChild(document.getElementById("select_weight"));
+ do {
+ if (node.selected) {
+ user.prefs.weight = node.getAttribute("value");
+ }
+ } while ((node=nextElementSibling(node)) != null);
+ app.setPrefs();
+ app.repaint();
+ user.save();
+}
+
+app.changeHeightUnit = function () {
+ var node = firstElementChild(document.getElementById("select_height"));
+ do {
+ if (node.selected) {
+ user.prefs.height = node.getAttribute("value");
+ }
+ } while ((node=nextElementSibling(node)) != null);
+ app.setPrefs();
+ app.repaint();
+ user.save();
+}
+
+app.setPrefs = function () {
+ var nodes = null, node = null;
+
+ document.getElementById("user_input").value = user.name;
+
+ nodes = document.getElementsByClassName("distance_unit");
i = 0;
do {
nodes[i].textContent = user.prefs.distance;
} while (++i < nodes.length);
- var node = firstElementChild(document.getElementById("select_distance"));
+ node = firstElementChild(document.getElementById("select_distance"));
do {
if (node.getAttribute("value")===user.prefs.distance) node.selected = true;
} while ((node=nextElementSibling(node)) != null);
+
+ nodes = document.getElementsByClassName("weight_unit");
+ i = 0;
+ do {
+ nodes[i].textContent = user.prefs.weight;
+ } while (++i < nodes.length);
+ node = firstElementChild(document.getElementById("select_weight"));
+ do {
+ if (node.getAttribute("value")===user.prefs.weight) node.selected = true;
+ } while ((node=nextElementSibling(node)) != null);
+ document.getElementById("weight_input").value = user.weight;
+
+ nodes = document.getElementsByClassName("height_unit");
+ i = 0;
+ do {
+ nodes[i].textContent = user.prefs.height;
+ } while (++i < nodes.length);
+ node = firstElementChild(document.getElementById("select_height"));
+ do {
+ if (node.getAttribute("value")===user.prefs.height) node.selected = true;
+ } while ((node=nextElementSibling(node)) != null);
+ document.getElementById("height_input").value = user.height;
}
+
+app.save = function () {
+ user.name = document.getElementById("user_input").value;
+ user.weight = parseInt(document.getElementById("weight_input").value);
+ user.height = parseInt(document.getElementById("height_input").value);
+ user.save();
+}
\ No newline at end of file
--- a/src/main/resources/styles/tracker.css Wed Aug 24 17:52:18 2011 -0400
+++ b/src/main/resources/styles/tracker.css Wed Aug 24 17:54:23 2011 -0400
@@ -17,17 +17,19 @@
h1 { text-align: right; padding-right: 1ex; font-family: cursive; margin: 0;}
#gps_data { display: none }
+a { text-decoration: none; }
+
nav #atab0 { color: #ccc; cursor: default; }
#vtab0:target ~ #tab0 { display: block }
#vtab0:target ~ #tab1 { display: none }
+#vtab0:target ~ nav #atab0 { color: #ccc; cursor: default; }
#vtab0:target ~ nav #atab1 { color: #6699ff; cursor: pointer; }
-#vtab0:target ~ nav #atab0 { color: #ccc; cursor: default; }
#tab1 { display: none; }
-#vtab1:target ~ #tab0 { display: none }
#vtab1:target ~ #tab1 { display: block }
+#vtab1:target ~ #tab0 { display: none }
+#vtab1:target ~ nav #atab1 { color: #ccc; cursor: default; }
#vtab1:target ~ nav #atab0 { color: #6699ff; cursor: pointer; }
-#vtab1:target ~ nav #atab1 { color: #ccc; cursor: default; }
section.tab_anchor { display: none; }
--- a/src/main/resources/templates/geolocation.ssp Wed Aug 24 17:52:18 2011 -0400
+++ b/src/main/resources/templates/geolocation.ssp Wed Aug 24 17:54:23 2011 -0400
@@ -47,7 +47,7 @@
<nav>
<a id='atab0' href='#vtab0'>Tracker</a>
-<a id='atab1' href='#vtab1'>Settings</a>
+<a id='atab1' href='#vtab1'>Profile</a>
</nav>
@@ -88,16 +88,73 @@
<section id='tab1'>
-<p>
-<label for='select_distance'>Current unit:</label>
+<table>
+<tbody>
+<tr>
+<th><label for='user_input'>Email:</label></th>
+<td>
+<input id='user_input' type="email" size='20' autocomplete='on'/>
+</td>
+</tr>
+<tr>
+<th><label for='weight_input'>Weight:</label></th>
+<td>
+<input id='weight_input' type="number" size='5' style='display: inline'/> <span class='weight_unit'>kg</span>
+</td>
+</tr>
+<tr>
+<th><label for='height_input'>Height:</label></th>
+<td>
+<input id='height_input' type="number" size='5' /> <span class='height_unit'>cm</span>
+</td>
+</tr>
+</tbody>
+</table>
+
+<table>
+<tbody>
+<tr>
+<th><label for='select_distance'>Distance unit:</label></th>
+<td>
<select id='select_distance' onchange='app.changeDistanceUnit()'>
<option value='km'>KM</option>
<option value='mile'>MILE</option>
</select>
+</td>
+</tr>
+<tr>
+<th><label for='select_weight'>Weight unit:</label></th>
+<td>
+<select id='select_weight' onchange='app.changeWeightUnit()'>
+
+<option value='kg'>KG</option>
+
+<option value='lb'>LB</option>
+</select>
+</td>
+</tr>
+<tr>
+<th><label for='select_height'>Height unit:</label></th>
+<td>
+<select id='select_height' onchange='app.changeHeightUnit()'>
+
+<option value='cm'>CM</option>
+
+<option value='inch'>INCH</option>
+</select>
+</td>
+</tr>
+</tbody>
+</table>
+
+<p>
+<button type='button' id='save'
+ onclick='app.save()'>Save</button>
</p>
+
</section>
<p id='log'>