Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[google_maps_flutter_web] Fix getScreenCoordinate, Circle zIndex #4298

Merged
merged 17 commits into from Sep 11, 2021

Conversation

ditman
Copy link
Member

@ditman ditman commented Sep 2, 2021

This PR passes the zIndex attribute to Circle 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 inverse getLatLng(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 first onTilesloaded 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

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Note that unlike the flutter/flutter repo, the flutter/plugins repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@@ -305,11 +308,16 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform {
polylines: polylines,
circles: circles,
mapOptions: mapOptions,
);
)..init(); // Initialize the controller
Copy link
Member Author

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!');
Copy link
Member Author

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) {
Copy link
Member Author

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
Copy link
Contributor

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?)

Copy link
Member Author

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 :/).

@ditman ditman changed the title [google_maps_flutter_web] Fix getScreenCoordinate method [google_maps_flutter_web] Fix getScreenCoordinate, Circle zIndex Sep 10, 2021
@ditman ditman requested review from stuartmorgan and removed request for cyanglaz September 10, 2021 01:41
Copy link
Contributor

@stuartmorgan stuartmorgan left a 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

@ditman ditman added waiting for tree to go green (Use "autosubmit") This PR is approved and tested, but waiting for the tree to be green to land. and removed waiting for tree to go green (Use "autosubmit") This PR is approved and tested, but waiting for the tree to be green to land. labels Sep 11, 2021
@ditman
Copy link
Member Author

ditman commented Sep 11, 2021

I'll manually squash and merge when master recovers, I want to have a proper commit message for this one.

@ditman ditman merged commit 70c314c into flutter:master Sep 11, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Sep 11, 2021
fluttergithubbot pushed a commit to flutter/flutter that referenced this pull request Sep 11, 2021
fotiDim pushed a commit to fotiDim/plugins that referenced this pull request Sep 13, 2021
…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).
@ditman ditman deleted the maps-get-screen-coordinate branch September 13, 2021 16:20
amantoux pushed a commit to amantoux/plugins that referenced this pull request Sep 27, 2021
…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).
KyleFin pushed a commit to KyleFin/plugins that referenced this pull request Dec 21, 2021
…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).
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants