Serializing all necessary place information
Avoids places service calls on every search result
Change-Id: I15092468fa627291263b0fb89013153f39fbf83f
diff --git a/src/components/timeline-client.js b/src/components/timeline-client.js
index fe5ced4..3b7e0f6 100644
--- a/src/components/timeline-client.js
+++ b/src/components/timeline-client.js
@@ -11,7 +11,7 @@
var self = this;
return this.outer.service.getDestinationPlace(this.outer.context, this.id)
.then(function(place) {
- return ifcx.toPlace(self.outer.dependencies, place);
+ return ifcx.toPlace(self.outer.maps, place);
});
},
@@ -67,7 +67,7 @@
},
remove: function(i) {
- return this.service.get(this.context, ifcx.box(i))
+ return this.service.remove(this.context, ifcx.box(i))
.then(this.getDestination);
},
@@ -123,17 +123,15 @@
this.bindEvent('onFocus', 'onDestinationFocus');
this.bindEvent('onPlaceChange', 'onDestinationPlaceChange',
function(e) {
- return Promise.all([
- ifcx.toPlace(self.outer.dependencies, e.place),
- ifcx.toPlace(self.outer.dependencies, e.previous)
- ]);
+ return [
+ ifcx.toPlace(self.outer.maps, e.place),
+ ifcx.toPlace(self.outer.maps, e.previous)
+ ];
});
this.bindEvent('onSearch', 'onDestinationSearch', function(e) {
- return Promise.all(e.places.map(function(place) {
- return ifcx.toPlace(self.outer.dependencies, place);
- })).then(function(places) {
- return [places];
- });
+ return [e.places.map(function(place) {
+ return ifcx.toPlace(self.outer.maps, place);
+ })];
});
this.bindEvent('onSubmit', 'onDestinationSubmit', function(e) {
return [e.value];
@@ -176,12 +174,12 @@
onError: 'memory'
},
- init: function(context, service, dependencies) {
+ init: function(context, service, maps) {
var self = this;
this.context = context;
this.service = service;
- this.dependencies = dependencies;
+ this.maps = maps;
this.destinations = {};
this.bindEvent('onAddClick');
diff --git a/src/components/timeline-server.js b/src/components/timeline-server.js
index 638baf1..56c9435 100644
--- a/src/components/timeline-server.js
+++ b/src/components/timeline-server.js
@@ -63,11 +63,11 @@
* function, and we'd have to new Function each one to preserve that.
*
* @param timeline the timeline control to serve.
- * @param dependencies {placesService, maps}
+ * @param maps
*/
-function TimelineService(timeline, dependencies) {
+function TimelineService(timeline, maps) {
this.timeline = timeline;
- this.dependencies = dependencies;
+ this.maps = maps;
this.destinations = {};
this.destinationIds = new Map();
@@ -118,7 +118,7 @@
setDestinationPlace: function(ctx, serverCall, id, place) {
var destination = this.destinations[id];
- return ifcx.toPlace(this.dependencies, place).then(destination.setPlace);
+ return destination.setPlace(ifcx.toPlace(this.maps, place));
},
setDestinationPlaceholder: function(ctx, serverCall, id, placeholder) {
@@ -127,7 +127,7 @@
setDestinationSearchBounds: function(ctx, serverCall, id, bounds) {
this.destinations[id].setSearchBounds(
- ifcx.toLatLngBounds(this.dependencies.maps, bounds));
+ ifcx.toLatLngBounds(this.maps, bounds));
},
getDestinationValue: function(ctx, serverCall, id) {
@@ -175,7 +175,7 @@
setSearchBounds: function(ctx, serverCall, bounds) {
this.timeline.setSearchBounds(
- ifcx.toLatLngBounds(this.dependencies.maps, bounds));
+ ifcx.toLatLngBounds(this.maps, bounds));
},
onAddClick: event('onAddClick',
diff --git a/src/ifc/conversions.js b/src/ifc/conversions.js
index 6cc210d..f83c60c 100644
--- a/src/ifc/conversions.js
+++ b/src/ifc/conversions.js
@@ -8,7 +8,7 @@
var Place = require('../place');
-module.exports = {
+var x = {
box: function(i) {
return i === undefined || i === null? i : new vdlTravel.Int16({ value: i });
},
@@ -17,35 +17,58 @@
return ifc && ifc.value;
},
- toPlace: function(dependencies, ifc) {
- return ifc? Place.fromObject(dependencies, ifc) : Promise.resolve();
+ toPlace: function(maps, ifc) {
+ return ifc && new Place({
+ 'place_id': ifc.placeId,
+ geometry: {
+ location: x.toLatLng(maps, ifc.location),
+ viewport: x.toLatLngBounds(maps, ifc.viewport)
+ },
+ 'formatted_address': ifc.formattedAddress,
+ name: ifc.name
+ });
},
fromPlace: function(place) {
- return place && new vdlTravel.Place(place.toObject());
+ if (!place) {
+ return place;
+ }
+
+ var placeObj = place.getPlaceObject();
+ var details = place.getDetails();
+ return new vdlTravel.Place({
+ placeId: placeObj.placeId,
+ location: x.fromLatLng(place.getLocation()),
+ viewport: place.getGeometry().viewport,
+ formattedAddress: details && details['formatted_address'] ||
+ placeObj.query,
+ name: details && details.name
+ });
},
toLatLng: function(maps, ifc) {
- return new maps.LatLng(ifc.lat, ifc.lng);
+ return ifc && new maps.LatLng(ifc.lat, ifc.lng);
},
fromLatLng: function(latlng) {
- return new vdlTravel.LatLng({
+ return latlng && new vdlTravel.LatLng({
lat: latlng.lat(),
lng: latlng.lng()
});
},
toLatLngBounds: function(maps, ifc) {
- return new maps.LatLngBounds(
- module.exports.toLatLng(maps, ifc.sw),
- module.exports.toLatLng(maps, ifc.ne));
+ return ifc && new maps.LatLngBounds(
+ x.toLatLng(maps, ifc.sw),
+ x.toLatLng(maps, ifc.ne));
},
fromLatLngBounds: function(bounds) {
- return new vdlTravel.LatLngBounds({
- sw: module.exports.fromLatLng(bounds.getSouthWest()),
- ne: module.exports.fromLatLng(bounds.getNorthEast())
+ return bounds && new vdlTravel.LatLngBounds({
+ sw: x.fromLatLng(bounds.getSouthWest()),
+ ne: x.fromLatLng(bounds.getNorthEast())
});
}
-};
\ No newline at end of file
+};
+
+module.exports = x;
\ No newline at end of file
diff --git a/src/ifc/types.vdl b/src/ifc/types.vdl
index b171441..506d826 100644
--- a/src/ifc/types.vdl
+++ b/src/ifc/types.vdl
@@ -34,6 +34,12 @@
type Place struct {
PlaceId Id
+
+ Location LatLng
+ Viewport ?LatLngBounds
+
+ FormattedAddress string
+ Name string
}
type Event struct {
diff --git a/src/travel.js b/src/travel.js
index 820bab1..9ddbbdb 100644
--- a/src/travel.js
+++ b/src/travel.js
@@ -140,8 +140,17 @@
/* Since these controls are 1:1 with destinations, we don't want to stay
* in a state where the control has invalid text but the destination is
* still valid; that would be confusing to the user (e.g. abandoned
- * query string "restaurants" for destination 4 Privet Drive.) */
- control.onPlaceChange.add(destination.setPlace);
+ * query string "restaurants" for destination 4 Privet Drive.)
+ *
+ * However, if the place is valid, don't bother updating the
+ * destination. The destination is authoritative, and any disparity will
+ * be due to update lag (especially bad for remote components), which
+ * will result in oscillation. */
+ control.onPlaceChange.add(function(place) {
+ if (!place) {
+ destination.setPlace(place);
+ }
+ });
}
asyncs.push(updateOrdinalAsync());
@@ -434,7 +443,7 @@
targetOwner, targetDeviceName, 'timeline');
return args.vanadiumWrapper.client(endpoint).then(function(ts) {
var tc = new TimelineClient(args.vanadiumWrapper.context(),
- ts, self.dependencies);
+ ts, self.map.maps);
tc.onError.add(self.error);
return self.adoptTimeline(tc);
});
@@ -444,7 +453,7 @@
receiveTimelineCast: function() {
var self = this;
var timeline = new Timeline(this.map.maps);
- var ts = new TimelineService(timeline, this.dependencies);
+ var ts = new TimelineService(timeline, this.map.maps);
this.vanadiumStartup.then(function(args) {
return args.vanadiumWrapper.server(
@@ -574,13 +583,13 @@
sbName = '/localhost:' + sbName;
}
- this.dependencies = {
+ var dependencies = {
maps: maps,
placesService: map.createPlacesService()
};
var sync = this.sync = new TravelSync(
- vanadiumStartup, this.dependencies, sbName);
+ vanadiumStartup, dependencies, sbName);
sync.bindDestinations(destinations);
this.info(strings['Connecting...'], sync.startup