[google_maps_flutter_web] Fix getScreenCoordinate, Circle zIndex #4298
Conversation
@@ -305,11 +308,16 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { | |||
polylines: polylines, | |||
circles: circles, | |||
mapOptions: mapOptions, | |||
); | |||
)..init(); // Initialize the controller |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the crux of the early initialization. Before the flow was:
buildView -> onPlatformViewCreated (plugin) -> init (plugin) -> init (controller) -> JS SDK
but now, it's:
buildView + init (controller) -> JS SDK -> onPlatformViewCreated (plugin) -> init (plugin, noop)
// The internal instance of our controller is initialized eagerly in `buildView`, | ||
// so we don't have to do anything in this method, which is left intentionally | ||
// blank. | ||
assert(_map(mapId) != null, 'Must call buildWidget before init!'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assertion is added to preserve some of the validation that happened before, mainly that calling init before buildWidget would cause quite a lot of breakage.
This method used to call init
in the controller, but no longer. We do that immediately after creating the controller in buildView.
@@ -163,6 +185,10 @@ class GoogleMapController { | |||
|
|||
// Funnels map gmap events into the plugin's stream controller. | |||
void _attachMapEvents(gmaps.GMap map) { | |||
map.onTilesloaded.first.then((event) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no map.onReady
event, so we synthesize it from the first onTilesloaded
event 🤷 (years of discussion)
build_runner: ^2.1.1 | ||
google_maps: ^5.2.0 | ||
google_maps_flutter: # Used for projection_test.dart | ||
path: ../../google_maps_flutter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels sketchy, but I don't have a better suggestion offhand :(
(Maybe long term some of the widgets should be in the interface package, not the app-facing package?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Maybe long term some of the widgets should be in the interface package, not the app-facing package?)
Yes, I'm not a fan of the current widget. There's a circular dependency in the code that didn't allow me to completely separate it from the GoogleMapsController that also lives in the core plugin, here (I'm not a fan of the controller accessing the map state directly, but never had the time to make it better :/).
packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart
Outdated
Show resolved
Hide resolved
a84a694
to
e2bc20b
Compare
e2bc20b
to
9bbdfa9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment nit and license format nit, but otherwise LGTM
packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart
Show resolved
Hide resolved
packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart
Outdated
Show resolved
Hide resolved
...utter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart
Show resolved
Hide resolved
I'll manually squash and merge when master recovers, I want to have a proper commit message for this one. |
…lutter#4298) This commit: * uses the zIndex attribute when converting Circle geometry objects. * ensures that the getScreenCoordinate method works as expected on the web platform. * adds tests that can use a fully-rendered Google Map (see projection_test.dart) * changes the initialization flow of the web Google Map, so the Controller is only returned to the main plugin when it's ready to work. In order to test the getScreenCoordinate method, the Controller of a fully-rendered map must be available on the test, so we can retrieve information from an actual map instance. While working on this, it was observed that the Controller was being sent to the programmer before it was truly ready (while the map was still initializing). Instead of littering the test with imprecise timeouts that may make these tests slower (and flakier) than needed, this PR also changes the initialization process of a GMap slightly so when its Controller is returned to the user of the plugin (onPlatformViewCreated method call), it is truly ready. For this: * Controller.init is immediately called after the controller is created, * The plugin waits for the first onTilesloaded event coming from the JS SDK, and then * The Controller is sent to the user This change happens within "private" sections of the plugin, so programmers using the plugin "normally" shouldn't notice any difference whatsoever (only that the GMap might load slightly faster, and the onPlatformViewCreated callback might be firing a few hundred milliseconds later).
…lutter#4298) This commit: * uses the zIndex attribute when converting Circle geometry objects. * ensures that the getScreenCoordinate method works as expected on the web platform. * adds tests that can use a fully-rendered Google Map (see projection_test.dart) * changes the initialization flow of the web Google Map, so the Controller is only returned to the main plugin when it's ready to work. In order to test the getScreenCoordinate method, the Controller of a fully-rendered map must be available on the test, so we can retrieve information from an actual map instance. While working on this, it was observed that the Controller was being sent to the programmer before it was truly ready (while the map was still initializing). Instead of littering the test with imprecise timeouts that may make these tests slower (and flakier) than needed, this PR also changes the initialization process of a GMap slightly so when its Controller is returned to the user of the plugin (onPlatformViewCreated method call), it is truly ready. For this: * Controller.init is immediately called after the controller is created, * The plugin waits for the first onTilesloaded event coming from the JS SDK, and then * The Controller is sent to the user This change happens within "private" sections of the plugin, so programmers using the plugin "normally" shouldn't notice any difference whatsoever (only that the GMap might load slightly faster, and the onPlatformViewCreated callback might be firing a few hundred milliseconds later).
…lutter#4298) This commit: * uses the zIndex attribute when converting Circle geometry objects. * ensures that the getScreenCoordinate method works as expected on the web platform. * adds tests that can use a fully-rendered Google Map (see projection_test.dart) * changes the initialization flow of the web Google Map, so the Controller is only returned to the main plugin when it's ready to work. In order to test the getScreenCoordinate method, the Controller of a fully-rendered map must be available on the test, so we can retrieve information from an actual map instance. While working on this, it was observed that the Controller was being sent to the programmer before it was truly ready (while the map was still initializing). Instead of littering the test with imprecise timeouts that may make these tests slower (and flakier) than needed, this PR also changes the initialization process of a GMap slightly so when its Controller is returned to the user of the plugin (onPlatformViewCreated method call), it is truly ready. For this: * Controller.init is immediately called after the controller is created, * The plugin waits for the first onTilesloaded event coming from the JS SDK, and then * The Controller is sent to the user This change happens within "private" sections of the plugin, so programmers using the plugin "normally" shouldn't notice any difference whatsoever (only that the GMap might load slightly faster, and the onPlatformViewCreated callback might be firing a few hundred milliseconds later).
This PR passes the
zIndex
attribute toCircle
geometry objects.Fixes flutter/flutter#89374 (simple)
This PR ensures that the
getScreenCoordinate
method works as expected on the web platform.Fixes flutter/flutter#80710
The
getScreenCoordinate(LatLng)
method (along with its inversegetLatLng(ScreenCoordinate)
require a fully rendered map to be tested, because they need the physical size in pixels, current center and zoom level of a map to work.So far, these two methods weren't tested, but this PR adds happy-case tests for both (see
projection_test.dart
)In order to test those methods, the
Controller
of the rendered map must be available on the test, so we can retrieve information from the map. While doing this, I noticed that the map Controller was being sent to the programmer before it was truly ready (while the map was still initializing).Instead of littering the test with imprecise timeouts that may make these tests slower (or flakier) than needed, this PR also changes the initialization process of a GMap slightly so when its Controller is returned to the user (
onPlatformViewCreated
method call), it is truly ready.For this, we now call
init
on the Controller immediately as it is created, then wait for the firstonTilesloaded
event coming from the JS SDK, and only then we return the Controller to the user.This change happens within "private" sections of the plugin, so programmers using the plugin "normally" shouldn't notice any difference whatsoever (only that the GMap might load slightly faster, and the
onPlatformViewCreated
callback might be firing a few hundred milliseconds later).(This PR also triggered changes in the mock files, that can be safely ignored, since those are auto-generated.)
Pre-launch Checklist
dart format
.)[shared_preferences]
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.