diff --git a/examples/simple-map/.meteor/versions b/examples/simple-map/.meteor/versions index 94beaa1..a3298b7 100644 --- a/examples/simple-map/.meteor/versions +++ b/examples/simple-map/.meteor/versions @@ -25,7 +25,7 @@ jquery@1.0.1 json@1.0.1 livedata@1.0.11 logging@1.0.4 -mdg:geolocation@1.0.2 +mdg:geolocation@1.0.3 meteor-platform@1.1.2 meteor@1.1.2 minifiers@1.1.1 diff --git a/examples/simple-map/map.html b/examples/simple-map/map.html index 4116445..43d111b 100644 --- a/examples/simple-map/map.html +++ b/examples/simple-map/map.html @@ -7,7 +7,12 @@

Where am I?

+ + {{#if error}}

Error: {{error.message}}

{{/if}} - \ No newline at end of file + diff --git a/examples/simple-map/map.js b/examples/simple-map/map.js index 6e27d4b..e106741 100644 --- a/examples/simple-map/map.js +++ b/examples/simple-map/map.js @@ -1,9 +1,22 @@ if (Meteor.isClient) { + Template.body.events({ + "change .high-accuracy input": function (event) { + Session.set("highAccuracy", event.target.checked); + } + }); Template.body.helpers({ loc: function () { + // options is *optional*. We're including it in this demo + // to show how it is reactive. + var options = { + enableHighAccuracy: !!Session.get("highAccuracy") + }; // return 0, 0 if the location isn't ready - return Geolocation.latLng() || { lat: 0, lng: 0 }; + return Geolocation.latLng(options) || { lat: 0, lng: 0 }; }, - error: Geolocation.error + error: Geolocation.error, + highAccuracy: function() { + return Session.get("highAccuracy"); + } }); -} \ No newline at end of file +} diff --git a/packages/mdg:geolocation/README.md b/packages/mdg:geolocation/README.md index d586d61..ca487b5 100644 --- a/packages/mdg:geolocation/README.md +++ b/packages/mdg:geolocation/README.md @@ -10,10 +10,22 @@ There are currently no options to set. Every method is reactive using [Tracker]( Returns the [position error](https://developer.mozilla.org/en-US/docs/Web/API/PositionError) that is currently preventing position updates. -### Geolocation.currentLocation() +### Geolocation.currentLocation(options) Returns the [position](https://developer.mozilla.org/en-US/docs/Web/API/Position) that is reported by the device, or null if no position is available. -### Geolocation.latLng() +The `options` parameter is optional; if provided it as if `Geolocation.setOptions` was called before returning the position. -A simple shorthand for currentLocation() when all you need is the latitude and longitude. Returns an object that has `lat` and `lng` keys. \ No newline at end of file +### Geolocation.latLng(options) + +A simple shorthand for currentLocation() when all you need is the latitude and longitude. Returns an object that has `lat` and `lng` keys. + +The `options` parameter is optional; if provided it as if `Geolocation.setOptions` was called before returning the position. + +### Geolocation.setOptions(options) + +Provide [PositionOptions](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions) to manage power consumption on mobile devices. The options can be reactive. + +### Geolocation.setPaused(boolean) + +If the parameter is `true`, temporarily halts reactive position updates to reduce power consumption. diff --git a/packages/mdg:geolocation/geolocation.js b/packages/mdg:geolocation/geolocation.js index 87616a6..8ee7643 100644 --- a/packages/mdg:geolocation/geolocation.js +++ b/packages/mdg:geolocation/geolocation.js @@ -8,24 +8,53 @@ var location = new ReactiveVar(null); var error = new ReactiveVar(null); // options for watchPosition -var options = { +var options = new ReactiveVar({ enableHighAccuracy: true, maximumAge: 0 -}; +}, function(a, b) { + // Reject attempts to set this to a non-object. + if (a == null || b == null || typeof a !== 'object' || typeof b !=='object') { + return true; + } + return ( + a.enableHighAccuracy === b.enableHighAccuracy && + a.maximumAge === b.maximumAge && + a.timeout === b.timeout + ); +}); + +// pause geolocation updates +var paused = new ReactiveVar(false); var onError = function (newError) { error.set(newError); + Tracker.afterFlush(checkDependents); }; var onPosition = function (newLocation) { location.set(newLocation); error.set(null); + Tracker.afterFlush(checkDependents); +}; + +var checkDependents = function() { + if (location.dep.hasDependents() || error.dep.hasDependents()) { + return; + } + watchingPosition.stop(); + watchingPosition = false; }; var startWatchingPosition = function () { - if (! watchingPosition && navigator.geolocation) { - navigator.geolocation.watchPosition(onPosition, onError, options); - watchingPosition = true; + if (watchingPosition === false && navigator.geolocation) { + watchingPosition = Tracker.autorun(function() { + if (paused.get()) { return; } + var watchId = + navigator.geolocation.watchPosition(onPosition, onError, options.get()); + Tracker.onInvalidate(function() { + navigator.geolocation.clearWatch(watchId); + }); + }); } }; @@ -43,29 +72,37 @@ Geolocation = { * that is currently preventing position updates. */ error: function () { - startWatchingPosition(); + Tracker.nonreactive(startWatchingPosition); return error.get(); }, /** * @summary Get the current location + * @param {PositionOptions} options Optional geolocation options + * @param {Boolean} options.enableHighAccuracy + * @param {Number} options.maximumAge + * @param {Number} options.timeout * @return {Position | null} The * [position](https://developer.mozilla.org/en-US/docs/Web/API/Position) * that is reported by the device, or null if no position is available. */ - currentLocation: function () { - startWatchingPosition(); + currentLocation: function (_options) { + if (_options != null) { + Geolocation.setOptions(_options); + } + Tracker.nonreactive(startWatchingPosition); return location.get(); }, + // simple version of location; just lat and lng - + /** * @summary Get the current latitude and longitude * @return {Object | null} An object with `lat` and `lng` properties, * or null if no position is available. */ - latLng: function () { - var loc = Geolocation.currentLocation(); + latLng: function (options) { + var loc = Geolocation.currentLocation(options); if (loc) { return { @@ -75,5 +112,20 @@ Geolocation = { } return null; + }, + + /** + * @summary Set the PositionOptions used for geolocation. + */ + setOptions: function(_options) { + options.set(_options); + }, + + /** + * @summary Allow temporarily halting reactive updates to position. + */ + setPaused: function(_paused) { + paused.set(_paused); } -}; \ No newline at end of file + +}; diff --git a/packages/mdg:geolocation/package.js b/packages/mdg:geolocation/package.js index 66294d8..cce8811 100644 --- a/packages/mdg:geolocation/package.js +++ b/packages/mdg:geolocation/package.js @@ -1,7 +1,7 @@ Package.describe({ name: "mdg:geolocation", summary: "Provides reactive geolocation on desktop and mobile.", - version: "1.0.2", + version: "1.0.3", git: "https://github.com/meteor/mobile-packages" }); @@ -14,4 +14,4 @@ Package.on_use(function (api) { api.versionsFrom("METEOR@0.9.2"); api.add_files(["geolocation.js"], "client"); api.export("Geolocation", "client"); -}); \ No newline at end of file +});