diff --git a/package.json b/package.json index c3e493d..d4fd589 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "cordova-android": "^8.0.0", "cordova-plugin-app-version": "^0.1.9", + "cordova-plugin-geolocation": "^4.0.1", "cordova-plugin-headercolor": "^1.0.0", "cordova-plugin-inappbrowser": "^3.0.0", "cordova-plugin-statusbar": "^2.4.2", @@ -27,7 +28,8 @@ "cordova-plugin-inappbrowser": {}, "phonegap-plugin-barcodescanner": { "ANDROID_SUPPORT_V4_VERSION": "27.+" - } + }, + "cordova-plugin-geolocation": {} }, "platforms": [ "android" diff --git a/www/js/api.js b/www/js/api.js index 99912b4..3bb1eab 100644 --- a/www/js/api.js +++ b/www/js/api.js @@ -4,6 +4,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/** + * Get the API endpoint URL for an action + * @param {String} action + * @return {String} + */ +function getActionUrl(action) { + return SETTINGS["server"] + "/" + action; +} + /** * Call an API function on the server. * @param {string} action @@ -16,19 +25,66 @@ function callAPI(action, data, success, failure) { return $.ajax({ type: 'POST', dataType: 'json', - url: SETTINGS["server"] + "/" + action, + url: getActionUrl(action), data: data, timeout: 5000, success: function (data, textStatus) { if (data.status === "OK") { success(data); - } else if (data.status === "ERROR") { + return; + } + if (typeof failure != 'function') { + return; + } + if (data.status === "ERROR") { failure(data.msg); } else { failure("The server sent an invalid response."); } }, error: function (xhr, textStatus, errorThrown) { + if (typeof failure != 'function') { + return; + } + switch (textStatus) { + case "timeout": + failure("Couldn't connect to the server (timeout)."); + break; + case "error": + failure("Couldn't connect to the server (error)."); + break; + case "parseerror": + failure("The server sent a malformed response."); + break; + default: + failure("Couldn't connect to the server."); + } + } + }); +} + +/** + * Call an API function on the server. Makes fewer assumptions about what + * constitutes a success response. + * @param {string} action + * @param {array} data key: value array of arguments for the server. + * @param {function} success Called with the JSON response object. + * @param {function} failure Called with an error message string. + * @return {undefined} + */ +function callAPIRawResponse(action, data, success, failure) { + return $.ajax({ + type: 'POST', + url: getActionUrl(action), + data: data, + timeout: 5000, + success: function (data, textStatus) { + success(data); + }, + error: function (xhr, textStatus, errorThrown) { + if (typeof failure != 'function') { + return; + } switch (textStatus) { case "timeout": failure("Couldn't connect to the server (timeout)."); diff --git a/www/js/home.js b/www/js/home.js index 218d261..1f82bff 100644 --- a/www/js/home.js +++ b/www/js/home.js @@ -18,7 +18,7 @@ $(".view-main").on("card:open", ".card-expandable", function () { }); $(".view-main").on("card:closed", "#map-card", function () { - leafletgllayer._glMap.setPitch(0); + //leafletgllayer._glMap.setPitch(0); leafletmap.invalidateSize(); }); @@ -46,7 +46,7 @@ function loadBalance(callback) { } function openMapCard() { - leafletgllayer._glMap.setPitch(40); + //leafletgllayer._glMap.setPitch(40); leafletmap.invalidateSize(); } diff --git a/www/js/map.js b/www/js/map.js index 5b03078..0027c78 100644 --- a/www/js/map.js +++ b/www/js/map.js @@ -4,12 +4,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +var userPositionIsReal = false; +var userposition = { + coords: { + latitude: 46.595, + longitude: -112.019, + accuracy: 10000 + } +}; var leafletmap = L.map('map', { minZoom: 12, maxZoom: 20 }); -leafletmap.setView([46.595, -112.019], 13); + leafletmap.attributionControl.setPrefix(""); var leafletgllayer = L.mapboxGL({ attribution: "© OpenMapTiles © OpenStreetMap contributors", @@ -18,4 +26,108 @@ var leafletgllayer = L.mapboxGL({ pitch: 0 }); -leafletgllayer.addTo(leafletmap); \ No newline at end of file +leafletgllayer.addTo(leafletmap); + +L.control.scale().addTo(leafletmap); + +var leafletpeoplelayer = L.geoJson( + { + name: "Nearby People", + type: "FeatureCollection", + features: [ + { + type: "Feature", + geometry: { + type: "Point", + coordinates: [0, 0] + }, + properties: { + id: "", + name: "", + username: "", + verified: false + } + } + ] + }, + { + onEachFeature: function (feature, layer) { + if (feature.properties && feature.properties.popupContent) { + layer.bindPopup(feature.properties.popupContent); + } + }, + pointToLayer: function (feature, latlng) { + return L.marker(latlng); +// return L.circleMarker(latlng, { +// radius: 14, +// fillColor: "#f00", +// color: "#000", +// weight: 1, +// opacity: 1, +// fillOpacity: 0.6 +// }); + } + } +); + +function updateMap() { + var diagonalMeters = leafletmap.getBounds().getNorthWest().distanceTo(leafletmap.getBounds().getSouthEast()); + var radius = (diagonalMeters / 2.0) / 1609.344; + callAPIRawResponse("getnearby", { + key: localStorage.getItem("key"), + latitude: leafletmap.getCenter().lat, + longitude: leafletmap.getCenter().lng, + radius: radius, + format: "geojson" + }, function (data) { + if (data.type == "FeatureCollection") { + leafletpeoplelayer.clearLayers(); + data.features.forEach(function (item) { + item.properties.popupContent = " " + item.properties.name + "

Send Money"; + leafletpeoplelayer.addData(item); + }); + leafletmap.addLayer(leafletpeoplelayer); + } + }); +} + +function recenterMapPosition() { + var zoom = 13; + if (userposition.coords.accuracy < 100) { + zoom = 15; + } + if (userposition.coords.accuracy < 50) { + zoom = 16; + } + leafletmap.setView([userposition.coords.latitude, userposition.coords.longitude], zoom); +} + +function recenterMapToUserPosition() { + if (userPositionIsReal == false) { + getLocation(function (position) { + userposition = position; + userPositionIsReal = true; + recenterMapPosition(); + }); + } else { + recenterMapPosition(); + } +} + +// Attempt to get user location +watchLocation(function (position) { + userposition = position; + if (userPositionIsReal == false) { + recenterMapPosition(); + userPositionIsReal = true; + } +}); + +// Set map to default position +recenterMapPosition(); +// Load nearby people +updateMap(); +// Watch for map moving +leafletmap.on("moveend", function () { + updateMap(); +}); \ No newline at end of file diff --git a/www/js/platform.js b/www/js/platform.js index a6b58da..5efc5b4 100644 --- a/www/js/platform.js +++ b/www/js/platform.js @@ -14,6 +14,38 @@ var openBrowser = function (url) { } +var getLocation = function (success, error) { + if ("geolocation" in navigator) { + navigator.geolocation.getCurrentPosition(function (position) { + success(position); + }, function (err) { + error(err.message); + }, { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0 + }); + } else { + error("Location is unavailable."); + } +} + +var watchLocation = function (success, error) { + if ("geolocation" in navigator) { + navigator.geolocation.watchPosition(function (position) { + success(position); + }, function (err) { + error(err.message); + }, { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0 + }); + } else { + error("Location is unavailable."); + } +} + function initCordova() { platform_type = "cordova"; diff --git a/www/pages/home.html b/www/pages/home.html index e1a0020..44c9866 100644 --- a/www/pages/home.html +++ b/www/pages/home.html @@ -84,17 +84,25 @@
-
- -
- Nearby +
+
Nearby
+
+ + my_location +
+
+ +