Browse code

POST to strava Ok, oauth to do on webviewclose

Louis authored on20/10/2022 00:00:26
Showing5 changed files
... ...
@@ -1,27 +1,13 @@
1 1
 /*STRAVA_API
2 2
 
3
-{
4
-  "file": /path/to/file.txt, // {File} The uploaded file.
5
-  "name": name_example, // {String} The desired name of the resulting activity.
6
-  "description": description_example, // {String} The desired description of the resulting activity.
7
-  "trainer": trainer_example, // {String} Whether the resulting activity should be marked as having been performed on a trainer.
8
-  "commute": commute_example, // {String} Whether the resulting activity should be tagged as a commute.
9
-  "dataType": dataType_example, // {String} The format of the uploaded file.
10
-  "externalId": externalId_example // {String} The desired external identifier of the resulting activity.
11
-}
12
-
13
-
14
-https://resmedglobal.atlassian.net/secure/CreateIssue.jspa?issuetype=2&pid=ISMS2
15
-https://resmedglobal.atlassian.net/secure/CreateIssue.jspa?issuetype=3&pid=ISMS2
16
-
17 3
 OAuth2.0 strava / pebble
18 4
 
19 5
 1 - get activity:write authorization (once and for all)
20 6
     GET https://www.strava.com/oauth/authorize?client_id=94880&response_type=code&redirect_uri=http://strava.jonget.fr&approval_prompt=force&state=bike_companion&scope=activity:write
21 7
     monitor state, code and scope (as upload can be unchecked)!
22 8
     code is short lived and one time usage
23
-2 - get tokens in exchange of code
24
-    POST https://www.strava.com/oauth/token?client_id=94880&client_secret=08dc170f0fe38f39dd327bea82a28db4400e6f00&code=e0aeb60ea9f508d25974bb56ccb551be56b91470&grant_type=authorization_code
9
+2 - get tokens in exchange of code (make it done by jonget.fr because of secret ? )
10
+    POST https://www.strava.com/oauth/token?client_id=94880&client_secret=08dc170f0fe38f39dd327bea82a28db4400e6f00&code=db896b06f89804997a8088320fba755e6299c0d6&grant_type=authorization_code
25 11
     refresh & access tokens + expiry of access token (6hours) retrieved
26 12
 
27 13
 3 - test if access token expired
... ...
@@ -29,55 +15,6 @@ OAuth2.0 strava / pebble
29 15
 4a- if not, API call
30 16
     GET https://www.strava.com/api/v3/athlete with "Authorization" header ="Bearer XXXXX"  XXXXX=access token
31 17
 
32
-4b- if yes refresh access token with refresh token get in 2
18
+4b- if yes refresh access token with refresh token get in 2  (make it done by jonget.fr because of secret ? )
33 19
     POST https://www.strava.com/oauth/token?client_id=94880&client_secret=8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58&refresh_token=c313d612768db4b12af2782372aa1d9349c265cb&grant_type=refresh_token
34 20
 */
35
-
36
-gpxfile = b.getGpx(!0) // returned gpxfile is string
37
-upload(gpxfile)
38
-
39
-function getGpx(t) {
40
-    if (0 == points.length) return "";
41
-    if (creator = "Ventoo SE", gpxfile = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" creator="' + creator + '" version="1.1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd  http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd" xmlns:pb10="http://www.pebblebike.com/GPX/1/0/">\n', itemId = -1, trackNumber = 1, points.length > 0) {
42
-        for (gpxfile += "<trk>\n<name>Track #1</name>\n<trkseg>\n", prevTime = -1, i = 0; i < points.length; i++) prevTime > 0 && points[i].t - prevTime > 43200 ? (trackNumber++, gpxfile += "</trkseg>\n</trk>\n<trk>\n<name>Track #" + trackNumber + "</name>\n<trkseg>\n") : prevTime > 0 && points[i].t - prevTime > 7200 && (gpxfile += "</trkseg>\n<trkseg>\n"), d = new Date(1e3 * points[i].t), ti = d.toISOString(), gpxfile += '<trkpt lat="' + points[i].la + '" lon="' + points[i].lo + '">\n  <ele>' + points[i].a + "</ele><time>" + ti + "</time>\n", !t && points[i].h || (gpxfile += "  <extensions>", t && (gpxfile += "<pb10:accuracy>" + points[i].ac + "</pb10:accuracy>"), points[i].h && (gpxfile += "<gpxtpx:TrackPointExtension>", gpxfile += "<gpxtpx:hr>" + points[i].h + "</gpxtpx:hr>", gpxfile += "</gpxtpx:TrackPointExtension>\n"), gpxfile += "</extensions>\n"), gpxfile += "</trkpt>\n", prevTime = points[i].t;
43
-        gpxfile += "</trkseg>\n</trk>\n"
44
-    }
45
-    return gpxfile += "</gpx>\n", gpxfile
46
-}
47
-
48
-function upload(gpxfile) {
49
-    params = {
50
-            url: s,
51
-            method: "POST",
52
-            data: { description: "desc", data_type: "gpx" },
53
-            files: { file: gpxfile },
54
-        authorization: "Bearer " + c,
55
-            callback: function() {
56
-                var z = "";
57
-                if (r && console.log(e.status + " - " + e.txt), 201 == e.status) z = "Your activity has been created";
58
-                else if (400 == e.status) z = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
59
-                else if (401 == e.status) z = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
60
-                else try { response_json = JSON.parse(e.txt), response_json.error ? (r && console.log("error:" + response_json.error), z = response_json.error, o.setAccessToken("")) : response_json.status && (r && console.log("status:" + response_json.status), z = response_json.status) } catch (z) { console.log("Error log, " + z) }
61
-                z && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", z)
62
-            }
63
-        }
64
-        //e[0] = params
65
-    var XHR = new XMLHttpRequest
66
-    console.log(e[0].url)
67
-    XHR.open(e[0].method, e[0].url, !0)
68
-    var r = Math.random().toString().substr(2);
69
-    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + r)
70
-    e[0].authorization && XHR.setRequestHeader("Authorization", e[0].authorization);
71
-    for (var i in e[0].data) o += "--" + r + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + e[0].data[i] + "\r\n";
72
-    for (var i in e[0].files) o += "--" + r + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + e[0].files[i] + "\r\n";
73
-    o += "--" + r + "--\r\n"
74
-
75
-    XHR.onreadystatechange = function() {
76
-        try {
77
-            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, e[0].callback && e[0].callback())
78
-        } catch (t) {
79
-            console.error("Error2 loading, ", t)
80
-        }
81
-    }
82
-    XHR.send(o)
83
-}
84 21
\ No newline at end of file
85 22
Binary files a/build/bike_companion.pbw and b/build/bike_companion.pbw differ
... ...
@@ -11,7 +11,7 @@ const uint32_t outbox_size = 64;
11 11
 static uint32_t size ;
12 12
 //static char * msg;
13 13
 
14
-static char s_status[3];
14
+static char s_status[4];
15 15
 
16 16
 //restricting long and lat to 13 char : 0-1 for the sign, 1-3 for integer, 1 for the point, 7-10 for decimal, 1 for \0
17 17
 static char s_longitude[13];
... ...
@@ -76,7 +76,7 @@ static void prv_up_click_handler(ClickRecognizerRef recognizer, void *context) {
76 76
 
77 77
 static void prv_down_click_handler(ClickRecognizerRef recognizer, void *context) {
78 78
   //text_layer_set_text(s_other_text_layer, "Down");
79
-  //send_message("exit");
79
+  send_message("exit");
80 80
 }
81 81
 
82 82
 static void prv_back_click_handler(ClickRecognizerRef recognizer, void *context) {
... ...
@@ -260,7 +260,7 @@ static void inbox_received_callback(DictionaryIterator *iter, void *context) {
260 260
 
261 261
   if(status_tuple) {
262 262
     memset(s_status,'\0',sizeof(s_status));
263
-    strncpy(s_status, status_tuple->value->cstring, 2);
263
+    strncpy(s_status, status_tuple->value->cstring, 4);
264 264
     /*if (strcmp(s_status,"KO")== 0){
265 265
       //find a way to exit 
266 266
     }else{*/
... ...
@@ -333,7 +333,7 @@ static void prv_init(void) {
333 333
 }
334 334
 
335 335
 static void prv_deinit(void) {
336
-  send_message("exit");
336
+  //send_message("exit");
337 337
   window_destroy(s_window);
338 338
 }
339 339
 
... ...
@@ -1,53 +1,90 @@
1
-module.exports = [
2
-  {
3
-    "type": "heading",
4
-    "defaultValue": "Bike Companion Configuration"
5
-  },
6
-  {
7
-    "type": "text",
8
-    "defaultValue": "This is not used for now, no action will be executed with these info."
9
-  },
10
-  {
11
-  "type": "section",
12
-    "items":
13
-    [
14
-      {
15
-        "type": "heading",
16
-        "defaultValue": "Your synology account"
17
-      },
18
-      {
19
-        "type": "input",
20
-        "messageKey": "username",
21
-        "label": "Your DSM Username",
22
-        "attributes":
23
-        {
24
-           "maxlength":40
25
-        }
26
-      },
27
-      {
28
-        "type": "input",
29
-        "messageKey": "password",
30
-        "label": "Your DSM Password",
31
-        "attributes":
32
-        {
33
-          "type": "password",
34
-          "maxlength":40
35
-        }
36
-      },
37
-      {
38
-        "type": "input",
39
-        "messageKey": "server",
40
-        "label": "Your DSM Server",
41
-        "attributes":
42
-        {
43
-          "type": "url",
44
-          "maxlength":255
45
-        }
46
-      }
47
-    ]
48
-  },
49
-  {
50
-    "type": "submit",
51
-    "defaultValue": "Save Settings"
52
-  }
53
-];
1
+module.exports = [{
2
+        type: "section",
3
+        items: [{
4
+                type: "heading",
5
+                defaultValue: "Locate Me"
6
+            },
7
+            {
8
+                type: "toggle",
9
+                messageKey: "ping_location_enable",
10
+                label: "Locate me on another server"
11
+            },
12
+            {
13
+                type: "text",
14
+                messageKey: "ping_location_url",
15
+                label: "full URL of server getting the location"
16
+            },
17
+            {
18
+                type: "input",
19
+                messageKey: "ping_location_login",
20
+                label: "Login (unused)"
21
+            },
22
+            {
23
+                type: "input",
24
+                messageKey: "ping_location_password",
25
+                label: "Password (unused)",
26
+                attributes: { type: "password" }
27
+            }
28
+        ]
29
+    }, {
30
+        type: "section",
31
+        items: [{
32
+                type: "heading",
33
+                defaultValue: "Send GPX to another server"
34
+            },
35
+            {
36
+                type: "toggle",
37
+                messageKey: "gpx_web_enable",
38
+                label: "Send GPX to another server"
39
+            },
40
+            {
41
+                type: "text",
42
+                messageKey: "gpx_web_url",
43
+                label: "full URL of server getting the GPX"
44
+            },
45
+            {
46
+                type: "input",
47
+                messageKey: "gpx_web_login",
48
+                label: "Login (unused)"
49
+            },
50
+            {
51
+                type: "input",
52
+                messageKey: "gpx_web_password",
53
+                label: "Password (unused)",
54
+                attributes: { type: "password" }
55
+            }
56
+        ]
57
+    },
58
+    {
59
+        type: "section",
60
+        items: [{
61
+                type: "heading",
62
+                defaultValue: "strava"
63
+            },
64
+            {
65
+                type: "text",
66
+                defaultValue: "Grant this application access to upload to Strava<br/><a onclick='return confirm(&quot;Have you saved your changes? They would be lost if you continue.&quot;)' href='https://www.strava.com/oauth/authorize?client_id=94880&response_type=code&redirect_uri=http://strava.jonget.fr&approval_prompt=force&state=bike_companion&scope=activity:write'><img src='data:image/png;base64,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'/></a>"
67
+            },
68
+            {
69
+                type: "toggle",
70
+                messageKey: "strava_upload",
71
+                label: "strava_upload"
72
+            },
73
+            {
74
+                type: "toggle",
75
+                messageKey: "strava_automatic_upload",
76
+                label: "Automatic upload at the end of the track"
77
+            }
78
+        ]
79
+    },
80
+    {
81
+        type: "toggle",
82
+        messageKey: "debug",
83
+        label: "Debug"
84
+    },
85
+    {
86
+        type: "submit",
87
+        id: "submitButton",
88
+        defaultValue: "Save"
89
+    }
90
+];
54 91
\ No newline at end of file
... ...
@@ -1,511 +1,477 @@
1 1
 var Clay = require('pebble-clay');
2 2
 var clayConfig = require('./config');
3
-var clay = new Clay(clayConfig);
3
+var clay = new Clay(clayConfig, null, { autoHandleEvents: false });
4
+var messageKeys = require('message_keys');
4 5
 
6
+Pebble.addEventListener('showConfiguration', function(e) {
7
+
8
+    // This is an example of how you might load a different config based on platform.
9
+    var platform = clay.meta.activeWatchInfo.platform || 'aplite';
10
+    if (platform === 'aplite') {
11
+        clay.config = clayConfigAplite;
12
+    }
13
+
14
+    Pebble.openURL(clay.generateUrl());
15
+});
16
+
17
+Pebble.addEventListener('webviewclosed', function(e) {
18
+    if (!t || t.response) {
19
+        try {
20
+            if (data = JSON.parse(t.response), data.strava) {
21
+                //data.strava will be like this :
22
+                // {"code":"db896b06f89804997a8088320fba755e6299c0d6","scope":"read,activity:write","state":"bike_companion"}
23
+                // so need to parse it correctly
24
+                //console.log("strava temp code to exchange to access token : " + data.code)
25
+                // placeholder to get token from code from php
26
+                return token
27
+            }
28
+        } catch (t) {
29
+            i && console.error("Parsing error:", t)
30
+        }
31
+        var dict = clay.getSettings(t.response);
32
+
33
+        /* assess if needed to send setting to watch as already in phone (done with "getsettings")
34
+        m.live_mmt_enable = dict[p.live_mmt_enable]
35
+        m.live_mmt_login = dict[p.live_mmt_login]
36
+        m.live_mmt_password = dict[p.live_mmt_password]
37
+        m.live_jayps_enable = dict[p.live_jayps_enable]
38
+        m.live_jayps_login = dict[p.live_jayps_login]
39
+        m.live_jayps_password = dict[p.live_jayps_password]
40
+        m.strava_automatic_upload = dict[p.strava_automatic_upload]
41
+    
42
+        i = dict[p.debug]
43
+        console.log("debug:" + i)
44
+        g.setDebug(i)
45
+        h.setDebug(i)
46
+        b.setDebug(i)
47
+        y.setDebug(i)
48
+        m.setDebug(i)
49
+    
50
+        m.save()
51
+        // Assess if needed to send settings values to watch side
52
+        /*
53
+        Pebble.sendAppMessage(dict, function(e) {
54
+            console.log('Sent config data to Pebble');
55
+        }, function(e) {
56
+            console.log('Failed to send config data!');
57
+            console.log(JSON.stringify(e));
58
+        });*/
59
+    }
60
+});
5 61
 
6
-var messageKeys = require('message_keys');
7 62
 
8 63
 var message;
9
-var gpx_to_strava = false;
10
-var gpx_to_web = true;
64
+var gpx_to_strava
65
+var gpx_to_web
66
+var locate_me
11 67
 
12 68
 var locationInterval;
69
+var instantLocationInterval;
13 70
 
14 71
 var firstlocationOptions = {
15
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
16
-  'timeout': 60000, //60s timeout to get a good signal
17
-  'maximumAge': 5 // no cache
72
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
73
+    'timeout': 60000, //60s timeout to get a first good signal
74
+    'maximumAge': 0 // no cache
18 75
 };
19 76
 var locationOptions = {
20
-  'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
21
-  'timeout': 5000, //5s timeout to get a good signal
22
-  'maximumAge': 5 // no cache
77
+    'enableHighAccuracy': true, // default = false (quick and dirty mode), can be true (more accurate but need more power and time)
78
+    'timeout': 5000, //5s timeout to get a good signal
79
+    'maximumAge': 0 // no cache
23 80
 };
24 81
 var geoloc_id;
25 82
 
26 83
 // Store location in Pebble app local storage
27 84
 //
28 85
 function storeLocation(position) {
29
-  var latitude = position.coords.latitude;
30
-  var longitude = position.coords.longitude;
31
-  var timestamp = position.timestamp;
32
-  localStorage.setItem("latitude", latitude);
33
-  localStorage.setItem("longitude", longitude);
34
-  localStorage.setItem("timestamp", timestamp);
35
-  // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
86
+    var latitude = position.coords.latitude;
87
+    var longitude = position.coords.longitude;
88
+    var timestamp = position.timestamp;
89
+    localStorage.setItem("latitude", latitude);
90
+    localStorage.setItem("longitude", longitude);
91
+    localStorage.setItem("timestamp", timestamp);
92
+    // console.log("Stored location " + position.coords.latitude + ',' + position.coords.longitude);
36 93
 }
37 94
 
38 95
 // Get location from Pebble app local storage
39 96
 //
40 97
 function getLocation() {
41
-  if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
42
-    var la = localStorage.getItem("latitude");
43
-    var lo = localStorage.getItem("longitude");
44
-    var ti = localStorage.getItem("timestamp");
45
-    var co = { "latitude": la, "longitude": lo };
46
-    var pos = { "coords": co, "timestamp": ti };
47
-    // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
48
-    return pos;
49
-  } else {
50
-    return null;
51
-  }
52
-}
53
-
54
-// Calculate the distance from 2 geoloc in degrees.
55
-// IMPORTANT : this is a calculation from 2D projection, altitude is not involved
56
-//
57
-function distance_on_geoid(lat1, lon1, lat2, lon2) {
58
-  // Convert degrees to radians
59
-  lat1 = lat1 * Math.PI / 180.0;
60
-  lon1 = lon1 * Math.PI / 180.0;
61
-  lat2 = lat2 * Math.PI / 180.0;
62
-  lon2 = lon2 * Math.PI / 180.0;
63
-  // radius of earth in metres
64
-  r = 6378100;
65
-  // P
66
-  rho1 = r * Math.cos(lat1);
67
-  z1 = r * Math.sin(lat1);
68
-  x1 = rho1 * Math.cos(lon1);
69
-  y1 = rho1 * Math.sin(lon1);
70
-  // Q
71
-  rho2 = r * Math.cos(lat2);
72
-  z2 = r * Math.sin(lat2);
73
-  x2 = rho2 * Math.cos(lon2);
74
-  y2 = rho2 * Math.sin(lon2);
75
-  // Dot product
76
-  dot = (x1 * x2 + y1 * y2 + z1 * z2);
77
-  cos_theta = dot / (r * r);
78
-  theta = Math.acos(cos_theta);
79
-  // Distance in Metres
80
-  return r * theta;
81
-}
82
-
83
-// Calculate speed from 2 geoloc point arrays (with lat,long,timestamp)
84
-//
85
-function speed_from_distance_and_time(p1, p2) {
86
-  dist = distance_on_geoid(p1.coords.latitude, p1.coords.longitude, p2.coords.latitude, p2.coords.longitude);
87
-  // timestamp is in milliseconds
88
-  time_s = (p2.timestamp - p1.timestamp) / 1000.0;
89
-  speed_mps = dist / time_s;
90
-  speed_kph = (speed_mps * 3600.0) / 1000.0;
91
-  return speed_kph;
98
+    if (localStorage.getItem("latitude") || localStorage.getItem("longitude") || localStorage.getItem("timestamp")) {
99
+        var la = localStorage.getItem("latitude");
100
+        var lo = localStorage.getItem("longitude");
101
+        var ti = localStorage.getItem("timestamp");
102
+        var co = { "latitude": la, "longitude": lo };
103
+        var pos = { "coords": co, "timestamp": ti };
104
+        // console.log("Stored location " + pos.co.la + ',' + pos.co.lo);
105
+        return pos;
106
+    } else {
107
+        return null;
108
+    }
92 109
 }
93 110
 
94 111
 // Get max speed of the run
95 112
 //
96 113
 function getMaxSpeed(lastSpeed) {
97
-  oldmax = localStorage.getItem("maxSpeed") || -1;
98
-  if (oldmax < lastSpeed) {
99
-    maxSpeed = lastSpeed
100
-  } else if (oldmax > lastSpeed) {
101
-    maxSpeed = oldmax
102
-  } else {
103
-    maxSpeed = oldmax
104
-  }
105
-  localStorage.setItem("maxSpeed", maxSpeed);
106
-  return maxSpeed
114
+    oldmax = localStorage.getItem("maxSpeed") || -1;
115
+    if (oldmax < lastSpeed) {
116
+        maxSpeed = lastSpeed
117
+    } else if (oldmax > lastSpeed) {
118
+        maxSpeed = oldmax
119
+    } else {
120
+        maxSpeed = oldmax
121
+    }
122
+    localStorage.setItem("maxSpeed", maxSpeed);
123
+    return maxSpeed
107 124
 }
108 125
 
109 126
 // split float number into an array of int (null returned instead of 0 for decimal)
110 127
 //
111 128
 function splitFloatNumber(num) {
112
-  const intStr = num.toString().split('.')[0];
113
-  const decimalStr = num.toString().split('.')[1];
114
-  return [Number(intStr), Number(decimalStr)];
129
+    const intStr = num.toString().split('.')[0];
130
+    const decimalStr = num.toString().split('.')[1];
131
+    return [Number(intStr), Number(decimalStr)];
115 132
 
116 133
 }
117 134
 
118 135
 // Build GPX headers
119 136
 //
120 137
 function GPXHeadersBuilder(timestamp, name, type) {
121
-  var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
122
-  var ret = localStorage.setItem("GPX", headers);
123
-  return true;
138
+    var headers = '<?xml version="1.0" encoding="UTF-8"?><gpx creator="Pebble with barometer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"><metadata><time>' + timestamp + '</time></metadata><trk><name>' + name + '</name><type>' + type + '</type><trkseg>';
139
+    var ret = localStorage.setItem("GPX", headers);
140
+    return true;
124 141
 }
125 142
 
126 143
 // Build GPX footer
127 144
 //
128 145
 function GPXtrkptBuilder(lat, lon, ele, timestamp) {
129
-  var GPX = localStorage.getItem("GPX");
130
-  var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
131
-  localStorage.setItem("GPX", GPX + trkpt);
132
-  return true;
146
+    var GPX = localStorage.getItem("GPX");
147
+    var trkpt = '<trkpt lat="' + lat + '" lon="' + lon + '"><ele>' + ele + '</ele><time>' + timestamp + '</time></trkpt>';
148
+    localStorage.setItem("GPX", GPX + trkpt);
149
+    return true;
133 150
 }
134 151
 
135 152
 // Build GPX footer
136 153
 //
137 154
 function GPXfooterBuilder() {
138
-  var GPX = localStorage.getItem("GPX");
139
-  var footer = '</trkseg></trk></gpx>';
140
-  var ret = localStorage.setItem("GPX", GPX + footer);
141
-  //console.log("GPX closed : " + GPX + footer);
142
-  return ret;
155
+    var GPX = localStorage.getItem("GPX");
156
+    var footer = '</trkseg></trk></gpx>';
157
+    var ret = localStorage.setItem("GPX", GPX + footer);
158
+    //console.log("GPX closed : " + GPX + footer);
159
+    return ret;
143 160
 }
144 161
 
145 162
 
146 163
 // Send GPX to Strava profile
147 164
 // TODO : get authentication creds from settings
148 165
 function SendToStrava() {
149
-  console.log('--- GPX upload to strava');
150
-  var gpxfile = localStorage.getItem("GPX");
151
-  // need to automate oAUTH
152
-  var bearer = "8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58"
153
-  params = {
154
-    url: "https://www.strava.com/api/v3/uploads",
155
-    method: "POST",
156
-    data: { description: "desc", data_type: "gpx" },
157
-    files: { file: gpxfile },
158
-    authorization: "Bearer " + bearer,
159
-    callback: function () {
160
-      var message = "";
161
-      // what is 'r'
162
-      // what is 'e'
163
-      // what is 'o'
164
-      // what is 'z'
165
-      if (r && console.log(e.status + " - " + e.txt), 201 == e.status) {
166
-        message = "Your activity has been created";
167
-      } else if (400 == e.status) {
168
-        message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
169
-      } else if (401 == e.status) {
170
-        message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
171
-      } else {
166
+    console.log('--- GPX upload to strava');
167
+    var gpxfile = localStorage.getItem("GPX");
168
+    // need to automate oAUTH
169
+    var bearer = "09f93068353f11f09d22059f1e8e42ef526949a5"
170
+    params = {
171
+        url: "https://www.strava.com/api/v3/uploads",
172
+        method: "POST",
173
+        data: { description: "desc", data_type: "gpx" },
174
+        files: { file: gpxfile },
175
+        authorization: "Bearer " + bearer,
176
+        callback: function(e) {
177
+            var message = "";
178
+            // what is 'r'
179
+            // what is 'e'
180
+            // what is 'o'
181
+            // what is 'z'
182
+            if (console.log(e.status + " - " + e.txt), 201 == e.status) {
183
+                message = "Your activity has been created";
184
+            } else if (400 == e.status) {
185
+                message = "An error has occurred. If you've already uploaded the current activity, please delete it in Strava.";
186
+            } else if (401 == e.status) {
187
+                message = "Error - Unauthorized. Please check your credentials in the settings.", o.setAccessToken("");
188
+            } else {
189
+                try {
190
+                    response_json = JSON.parse(e.txt)
191
+                    response_json.error ? (console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (console.log("status:" + response_json.status), z = response_json.status)
192
+                } catch (e) {
193
+                    console.log("Error log, " + e)
194
+                }
195
+            }
196
+            message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
197
+        }
198
+    }
199
+    var XHR = new XMLHttpRequest;
200
+    var n = this;
201
+    console.log(params.url);
202
+    XHR.open(params.method, params.url, !0);
203
+    var body = "";
204
+    var boundary = Math.random().toString().substring(2);
205
+    XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
206
+    XHR.setRequestHeader("Authorization", params.authorization);
207
+    for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
208
+    for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
209
+    body += "--" + boundary + "--\r\n"
210
+
211
+    XHR.onreadystatechange = function() {
212
+        // what is 'n'
172 213
         try {
173
-          response_json = JSON.parse(e.txt)
174
-          response_json.error ? (r && console.log("error:" + response_json.error), message = response_json.error, o.setAccessToken("")) : response_json.status && (r && console.log("status:" + response_json.status), z = response_json.status)
214
+            4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback(n))
175 215
         } catch (e) {
176
-          console.log("Error log, " + e)
216
+            console.error("Error2 loading, ", e)
177 217
         }
178
-      }
179
-      message && Pebble.showSimpleNotificationOnPebble("Ventoo SE - Strava", message)
180
-    }
181
-  }
182
-  var XHR = new XMLHttpRequest;
183
-  console.log(params.url);
184
-  XHR.open(params.method, params.url, !0);
185
-  var body = "";
186
-  var boundary = Math.random().toString().substring(2);
187
-  XHR.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary)
188
-  XHR.setRequestHeader("Authorization", params.authorization);
189
-  for (var i in params.data) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '"\r\n\r\n' + params.data[i] + "\r\n";
190
-  for (var i in params.files) body += "--" + boundary + '\r\nContent-Disposition: form-data; name="' + i + '" ; filename=test.gpx\r\n\r\n' + params.files[i] + "\r\n";
191
-  body += "--" + boundary + "--\r\n"
192
-
193
-  XHR.onreadystatechange = function () {
194
-    // what is 'n'
195
-    try {
196
-      4 == XHR.readyState && (n.status = XHR.status, n.txt = XHR.responseText, n.xml = XHR.responseXML, params.callback && params.callback())
197
-    } catch (e) {
198
-      console.error("Error2 loading, ", e)
199 218
     }
200
-  }
201
-  XHR.send(body)
202
-
203
-
204
-
205
-  // fetch or Blob or Formdata are not implemented in pebblekitJS
206
-  /*fetch('data:application/gpx+xml;base64,'.btoa(GPX))
207
-      .then(function(value) { return value.blob() })
208
-      .then(
209
-          function(value) {
210
-  var data = new FormData();
211
-  data.append("name", "test");
212
-  data.append("description", "description");
213
-  data.append("data_type", "gpx");
214
-  data.append("file", value, "blob.gpx");
215
-
216
-  var xhr = new XMLHttpRequest();
217
-  var url = "https://www.strava.com/api/v3/uploads";
218
-  xhr.withCredentials = true;
219
-  xhr.timeout = 10000; // time in milliseconds
220
-
221
-  xhr.open("POST", url, false);
222
-  xhr.setRequestHeader("Authorization", "Bearer 8a68d5b79f2fb3e00ad3eaa5025253990fbd6a58");
223
-
224
-  console.log('------GPX / xhr opened with authorization')
225
-  console.log('------array for blob: ' + [GPX])
226
-  xhr.onload = function() {
227
-      console.log('------xhr onload')
228
-      if (xhr.readyState === 4) {
229
-          console.log('------xhr request returned with ' + xhr.status);
230
-          console.log(this.responseText);
231
-          if (xhr.status == 200) {
232
-              //console.log('--> HTTP 200');
233
-              return true;
234
-          } else {
235
-              //console.log('--> HTTP ' + xhr.status);
236
-              return false;
237
-          }
238
-      }
239
-  };
240
-
241
-  xhr.send(data);
242
-  },
243
-          function(error) {
244
-              console.log('error')
245
-          }
246
-      )*/
247
-  /* -------------------- */
248
-
249
-
219
+    XHR.send(body)
250 220
 }
251 221
 
252 222
 
253
-// Build CSV
254
-function CSV(pos) {
255
-  var CSV = localStorage.getItem("CSV");
256
-  var datapoint = pos.timestamp + "," + pos.coords.latitude + "," + pos.coords.longitude + "," + pos.coords.altitude + "," + pos.coords.accuracy + "," + pos.coords.altitudeAccuracy + "," + pos.coords.heading + "," + pos.coords.speed + "\n";
257
-
258
-  localStorage.setItem("CSV", CSV + datapoint);
259
-
260
-}
261
-// Send CSV to web server (need configuration on serverside)
223
+// Send GPX to web server (need configuration on serverside)
262 224
 // TODO : secure it ?
263 225
 function PostToWeb() {
264
-  console.log('--- GPX upload to custom web server');
265
-  var GPX = localStorage.getItem("GPX");
266
-
267
-  var url = "https://jonget.fr/strava/upload.php?name=pebblegpx&type=application/gpx+xml";
268
-  var xhr = new XMLHttpRequest();
269
-  xhr.timeout = 10000; // time in milliseconds
270
-
271
-  xhr.open("POST", url, false);
272
-
273
-  //console.log('------ CSV / xhr opened')
274
-  xhr.onload = function () {
275
-    //console.log('------xhr onload')
276
-    if (xhr.readyState === 4) {
277
-      //console.log('------xhr request returned with ' + xhr.status);
278
-      //console.log(this.responseText);
279
-      if (xhr.status == 200) {
280
-        //console.log('--> HTTP 200');
281
-        return true;
282
-      } else {
283
-        //console.log('--> HTTP ' + xhr.status);
284
-        return false;
285
-      }
286
-    }
287
-  };
226
+    console.log('--- GPX upload to custom web server');
227
+    var GPX = localStorage.getItem("GPX");
228
+    var url = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_url + "?name=pebblegpx&type=application/gpx+xml";
229
+    var xhr = new XMLHttpRequest();
230
+    xhr.timeout = 10000; // time in milliseconds
231
+
232
+    xhr.open("POST", url, false);
233
+
234
+    //console.log('------ CSV / xhr opened')
235
+    xhr.onload = function() {
236
+        //console.log('------xhr onload')
237
+        if (xhr.readyState === 4) {
238
+            //console.log('------xhr request returned with ' + xhr.status);
239
+            //console.log(this.responseText);
240
+            if (xhr.status == 200) {
241
+                //console.log('--> HTTP 200');
242
+                return true;
243
+            } else {
244
+                //console.log('--> HTTP ' + xhr.status);
245
+                return false;
246
+            }
247
+        }
248
+    };
288 249
 
289
-  //send CSV in body
290
-  xhr.send(GPX);
250
+    //send CSV in body
251
+    xhr.send(GPX);
291 252
 
292 253
 }
293 254
 
294
-// Send location to web server for instant location (no tracking)
255
+// Send location to web server for instant location (no live tracking)
295 256
 // TODO : secure it ?
296 257
 function instantLocationUpdate(pos) {
297
-  console.log('--- Instant location update');
298
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
299
-
300
-  var url = "https://jonget.fr/find_me/update.php?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
301
-  var xhr = new XMLHttpRequest();
302
-  xhr.timeout = 10000; // time in milliseconds
303
-
304
-  xhr.open("POST", url);
305
-
306
-  //console.log('------ instant / xhr opened')
307
-  xhr.onload = function () {
308
-    //console.log('------xhr onload')
309
-    if (xhr.readyState === 4) {
310
-      //console.log('------xhr request returned with ' + xhr.status);
311
-      //console.log(this.responseText);
312
-      if (xhr.status == 200) {
313
-        //console.log('--> HTTP 200');
314
-        return true;
315
-      } else {
316
-        //console.log('--> HTTP ' + xhr.status);
317
-        return false;
318
-      }
319
-    }
320
-  };
321
-
322
-  //send without body
323
-  xhr.send();
324
-
325
-}
258
+    console.log('--- Instant location update');
259
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
260
+
261
+    var url = JSON.parse(localStorage.getItem('clay-settings')).ping_location_url + "?lat=" + pos.coords.latitude + "&long=" + pos.coords.longitude + "&acc=" + pos.coords.accuracy + "&timestamp=" + pos.timestamp;
262
+    var xhr = new XMLHttpRequest();
263
+    xhr.timeout = 10000; // time in milliseconds
264
+
265
+    xhr.open("POST", url);
266
+
267
+    //console.log('------ instant / xhr opened')
268
+    xhr.onload = function() {
269
+        //console.log('------xhr onload')
270
+        if (xhr.readyState === 4) {
271
+            //console.log('------xhr request returned with ' + xhr.status);
272
+            //console.log(this.responseText);
273
+            if (xhr.status == 200) {
274
+                //console.log('--> HTTP 200');
275
+                return true;
276
+            } else {
277
+                //console.log('--> HTTP ' + xhr.status);
278
+                return false;
279
+            }
280
+        }
281
+    };
326 282
 
283
+    //send without body
284
+    xhr.send();
327 285
 
328
-// Adding leading characters to string for nice displays
329
-//
330
-function padStart(string, max_length, padding) {
331
-  if (string.length > max_length) {
332
-    return string;
333
-  } else {
334
-    var new_str = string;
335
-    for (index = string.length; index < max_length; index++) {
336
-      new_str = "0" + new_str;
337
-    }
338
-    return new_str;
339
-  }
340 286
 }
341 287
 
342 288
 // called in case of successful geoloc gathering and sends the coordinate to watch
343 289
 //
344 290
 function locationSuccess(new_pos) {
345
-  console.log('--- locationSuccess');
346
-  // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
291
+    console.log('--- locationSuccess');
292
+    // console.log(" location is " + new_pos.coords.latitude + ',' + new_pos.coords.longitude + ' , acc. ' + new_pos.coords.accuracy);
347 293
 
348
-  var prev_pos = getLocation();
349
-  storeLocation(new_pos);
350
-  if (prev_pos === null) {
351
-    console.log('--- start building gpx');
294
+    var prev_pos = getLocation();
295
+    storeLocation(new_pos);
296
+    if (prev_pos === null) {
297
+        console.log('--- start building gpx');
352 298
 
353
-    if (gpx_to_strava || gpx_to_web) {
354
-      // Start the GPX file
355
-      GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
356
-    }
357
-  } else {
358
-    //clear watch of new position to avoid overlap
359
-    //navigator.geolocation.clearWatch(geoloc_id);
360
-    //console.log('--- watch geoloc cleared');
361
-    //var speed = speed_from_distance_and_time(prev_pos, new_pos);
362
-
363
-    //get speed from geoloc API isntead of calculate it
364
-    // speed is initially in m/s, get it at km/h
365
-    if (new_pos.coords.speed === null) {
366
-      var speed = 0;
299
+        if (gpx_to_strava || gpx_to_web) {
300
+            // Start the GPX file
301
+            GPXHeadersBuilder(new Date(new_pos.timestamp).toISOString(), "test", "18");
302
+        }
367 303
     } else {
368
-      var speed = new_pos.coords.speed * 3.6;
369
-    }
304
+        //clear watch of new position to avoid overlap
305
+        //navigator.geolocation.clearWatch(geoloc_id);
306
+        //console.log('--- watch geoloc cleared');
307
+        //var speed = speed_from_distance_and_time(prev_pos, new_pos);
308
+
309
+        //get speed from geoloc API isntead of calculate it
310
+        // speed is initially in m/s, get it at km/h
311
+        if (new_pos.coords.speed === null) {
312
+            var speed = 0;
313
+        } else {
314
+            var speed = new_pos.coords.speed * 3.6;
315
+        }
370 316
 
371
-    // Prepare display on watch
372
-    // now it's only raw data
373
-    // init strings
374
-    var latitudeString = "";
375
-    var longitudeString = "";
376
-    var accuracyString = "";
377
-    var altitudeString = "";
378
-    var speedString = "";
379
-
380
-    //formating for precision and max size
381
-    latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
382
-    longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
383
-    accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
384
-    //console.log("split num : " + new_pos.coords.altitude);
385
-    altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
386
-    timestampISO = new Date(new_pos.timestamp).toISOString();
387
-    //console.log("split num : " + speed);
388
-    speedString = splitFloatNumber(speed)[0].toString().substring(0, 3); //+ "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
389
-
390
-    //console.log("split num : " + getMaxSpeed(speed));
391
-    maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 4);
392
-
393
-    if (speedString == "NaN") {
394
-      speedString = "---";
395
-    }
317
+        // Prepare display on watch
318
+        // now it's only raw data
319
+        // init strings
320
+        var latitudeString = "";
321
+        var longitudeString = "";
322
+        var accuracyString = "";
323
+        var altitudeString = "";
324
+        var speedString = "";
325
+
326
+        //formating for precision and max size
327
+        latitudeString = new_pos.coords.latitude.toString().substring(0, 12);
328
+        longitudeString = new_pos.coords.longitude.toString().substring(0, 12);
329
+        accuracyString = new_pos.coords.accuracy.toString().substring(0, 4);
330
+        //console.log("split num : " + new_pos.coords.altitude);
331
+        altitudeString = splitFloatNumber(new_pos.coords.altitude)[0].toString().substring(0, 5);
332
+        timestampISO = new Date(new_pos.timestamp).toISOString();
333
+        //console.log("split num : " + speed);
334
+        if (isNaN(speed)) {
335
+            speedString = "---";
336
+        } else {
337
+            speedString = splitFloatNumber(speed)[0].toString().substring(0, 3) + "." + splitFloatNumber(speed)[1].toString().substring(0, 1);
338
+            if (speedString == "0.N") {
339
+                speedString = "0.0";
340
+            }
341
+
342
+            //console.log("split num : " + getMaxSpeed(speed));
343
+            maxSpeedString = splitFloatNumber(getMaxSpeed(speed))[0].toString().substring(0, 3);
344
+        }
396 345
 
397
-    if (gpx_to_strava || gpx_to_web) {
398
-      //add a new datapoint to GPX file
399
-      GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
346
+        if (gpx_to_strava || gpx_to_web) {
347
+            //add a new datapoint to GPX file
348
+            GPXtrkptBuilder(latitudeString, longitudeString, altitudeString, timestampISO);
400 349
 
401
-    }
402
-
403
-    // Build message
404
-    message = "OK";
405
-    var dict = {
406
-      'accuracy': accuracyString,
407
-      'altitude': altitudeString,
408
-      'speed': speedString,
409
-      'max_speed': maxSpeedString,
410
-      'status': message
411
-    };
350
+        }
412 351
 
413
-    // Send the message
414
-    Pebble.sendAppMessage(dict, function () {
415
-      console.log('Message sent successfully: ' + JSON.stringify(dict));
416
-    }, function (e) {
417
-      console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
418
-    });
419
-  }
352
+        // Build message
353
+        message = "OK";
354
+        var dict = {
355
+            'accuracy': accuracyString,
356
+            'altitude': altitudeString,
357
+            'speed': speedString,
358
+            'max_speed': maxSpeedString,
359
+            'status': message
360
+        };
361
+
362
+        // Send the message
363
+        Pebble.sendAppMessage(dict, function() {
364
+            console.log('Message sent successfully: ' + JSON.stringify(dict));
365
+        }, function(e) {
366
+            console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
367
+        });
368
+    }
420 369
 
421 370
 }
422 371
 
423 372
 function locationError(err) {
424 373
 
425
-  console.warn('location error (' + err.code + '): ' + err.message);
426
-  /*
427
-  if (gpx_to_web) {
428
-
429
-      var CSV = localStorage.getItem("CSV");
430
-      var datapoint = Date.now() + ",location error," + err.code + "," + err.message + ",,,,";
431
-
432
-      localStorage.setItem("CSV", CSV + datapoint);
433
-  }*/
374
+    console.warn('location error (' + err.code + '): ' + err.message);
434 375
 
435 376
 }
436 377
 
437 378
 
438 379
 function get_coordinate() {
439
-  console.log('--- Starting regular getCurrentPosition loop using setInterval at 5 sec');
380
+    console.log('--- Starting regular getCurrentPosition loop using setInterval at 1 sec');
440 381
 
441
-  navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
382
+    locationInterval = setInterval(function() {
383
+        navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
384
+    }, 1000);
442 385
 
443
-  locationInterval = setInterval(function () {
444
-    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions);
445
-  }, 1000);
446
-
447
-  instantLocationInterval = setInterval(function () {
448
-    navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
449
-  }, 60000);
386
+    if (locate_me) {
387
+        instantLocationInterval = setInterval(function() {
388
+            navigator.geolocation.getCurrentPosition(instantLocationUpdate, locationError, locationOptions);
389
+        }, 60000);
390
+    }
450 391
 
451 392
 }
452 393
 
453 394
 function init() {
454
-  // local storage init,
455
-  // todo : clear only temporary values, not clay config (and do it on exit ?)
456
-  localStorage.clear();
457
-  localStorage.setItem("CSV", "");
458
-  // clear any other var to do
459
-  clearInterval(locationInterval);
395
+    // local storage init
396
+    gpx_to_strava = JSON.parse(localStorage.getItem('clay-settings')).strava_upload;
397
+    gpx_to_web = JSON.parse(localStorage.getItem('clay-settings')).gpx_web_enable;
398
+    locate_me = JSON.parse(localStorage.getItem('clay-settings')).ping_location_enable;
399
+
400
+    var ce = gpx_to_web;
401
+    var cu = localStorage.getItem("custom_enabled");
402
+    var se = gpx_to_strava;
403
+    var su = localStorage.getItem("strava_enabled");
404
+
405
+    if ((se && !su) || (ce && !cu)) {
406
+        //posting any missed XHR from previous ride session
407
+        if (ce) {
408
+            PostToWeb();
409
+        }
410
+        if (se) {
411
+            SendToStrava();
412
+        }
413
+    } else {
414
+        localStorage.setItem("GPX", "");
415
+        localStorage.setItem("maxSpeed", "");
416
+        localStorage.setItem("latitude", "");
417
+        localStorage.setItem("longitude", "");
418
+        localStorage.setItem("timestamp", "");
419
+        localStorage.setItem("custom_uploaded", false);
420
+        localStorage.setItem("strava_uploaded", false);
421
+    }
422
+    // clear any other var to do
423
+    clearInterval(locationInterval);
424
+    clearInterval(instantLocationInterval);
425
+    navigator.geolocation.getCurrentPosition(locationSuccess, locationError, firstlocationOptions);
460 426
 
461 427
 }
462 428
 
463 429
 // Get JS readiness events
464
-Pebble.addEventListener('ready', function (e) {
465
-  console.log('PebbleKit JS is ready');
466
-  // Update Watch on this
467
-  Pebble.sendAppMessage({ 'JSReady': 1 });
430
+Pebble.addEventListener('ready', function(e) {
431
+    console.log('PebbleKit JS is ready');
432
+    // Update Watch on this
433
+    Pebble.sendAppMessage({ 'JSReady': 1 });
468 434
 
469
-  init();
435
+    init();
470 436
 });
471 437
 
472 438
 // Get AppMessage events
473
-Pebble.addEventListener('appmessage', function (e) {
474
-  // Get the dictionary from the message
475
-  var dict = e.payload;
476
-  //console.log(dict[0].toString());
477
-  switch (dict[0]) {
478
-    case 'get':
479
-      get_coordinate();
480
-      break;
481
-    case 'exit':
482
-      clearInterval(instantLocationInterval);
483
-      clearInterval(locationInterval);
484
-      if (gpx_to_strava || gpx_to_web) {
485
-        //End GPX file
486
-        GPXfooterBuilder();
487
-        if (gpx_to_strava) {
488
-          //send to strava through API
489
-          SendToStrava();
490
-        }
491
-        if (gpx_to_web) {
492
-          // send CSV to web server through API
493
-          PostToWeb();
494
-        }
495
-      }
496
-      // Send the message
497
-      var dict = {
498
-        'status': "KO"
499
-      };
500
-      Pebble.sendAppMessage(dict, function () {
501
-        console.log('Message sent successfully: ' + JSON.stringify(dict));
502
-      }, function (e) {
503
-        console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
504
-      });
505
-
506
-      break;
507
-    default:
508
-      console.log('Sorry. I don\'t understand your request :' + dict[0]);
509
-  }
439
+Pebble.addEventListener('appmessage', function(e) {
440
+    // Get the dictionary from the message
441
+    var dict = e.payload;
442
+    //console.log(dict[0].toString());
443
+    switch (dict[0]) {
444
+        case 'get':
445
+            get_coordinate();
446
+            break;
447
+        case 'exit':
448
+            clearInterval(instantLocationInterval);
449
+            clearInterval(locationInterval);
450
+            if (gpx_to_strava || gpx_to_web) {
451
+                //End GPX file
452
+                GPXfooterBuilder();
453
+                if (gpx_to_strava) {
454
+                    //send to strava through API
455
+                    SendToStrava();
456
+                }
457
+                if (gpx_to_web) {
458
+                    // send CSV to web server through API
459
+                    PostToWeb();
460
+                }
461
+            }
462
+            // Send the message
463
+            var dict = {
464
+                'status': "EXIT"
465
+            };
466
+            Pebble.sendAppMessage(dict, function() {
467
+                console.log('Message sent successfully: ' + JSON.stringify(dict));
468
+            }, function(e) {
469
+                console.log('Message (' + JSON.stringify(dict) + ') failed: ' + JSON.stringify(e));
470
+            });
471
+
472
+            break;
473
+        default:
474
+            console.log('Sorry. I don\'t understand your request :' + dict[0]);
475
+    }
510 476
 
511 477
 });
512 478
\ No newline at end of file