[google_maps_flutter] Add onPoiTap callback to GoogleMap#10963
[google_maps_flutter] Add onPoiTap callback to GoogleMap#10963AsimRoyChowdhury wants to merge 48 commits intoflutter:mainfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the onPoiTap callback to the GoogleMap widget, allowing developers to handle user taps on points of interest on the map. The feature is implemented across the platform interface, Android, and iOS, with corresponding updates to the example application and tests. The changes involve adding new event types, updating platform-specific listeners, and exposing the new callback in the app-facing widget. My review includes suggestions for improving code clarity, test robustness, and fixing a critical dependency issue.
| flutter: | ||
| sdk: flutter | ||
| google_maps_flutter_platform_interface: ^2.13.0 | ||
| google_maps_flutter_platform_interface: ^2.14.0 |
There was a problem hiding this comment.
The google_maps_flutter_platform_interface version should be ^2.15.0 to match the version in which onPoiTap support was added. The current version ^2.14.0 will cause dependency conflicts or build failures since this package uses types introduced in 2.15.0.
google_maps_flutter_platform_interface: ^2.15.0
packages/google_maps_flutter/google_maps_flutter/example/lib/place_poi.dart
Outdated
Show resolved
Hide resolved
| import 'package:google_maps_flutter_android/google_maps_flutter_android.dart'; | ||
| import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; | ||
|
|
||
| import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; |
| Log.e("POI_TEST", "Native POI Click Detected: " + poi.name); | ||
| Log.e("POI_TEST", "Native Tap! Sending to Channel ID: " + id); |
| public void onPoiClick_SendsMethodCall() { | ||
| PointOfInterest poi = new PointOfInterest(new LatLng(1.0, 2.0), "placeId", "name"); | ||
|
|
||
| // controller is the instance of GoogleMapController in your test file | ||
| controller.onPoiClick(poi); | ||
|
|
||
| // Verify the messenger sent the message to the correct channel | ||
| verify(binaryMessenger).send( | ||
| eq("plugins.flutter.io/google_maps_0"), | ||
| any(ByteBuffer.class), | ||
| any(BinaryMessenger.BinaryReply.class)); | ||
| } |
There was a problem hiding this comment.
This test only verifies that a message is sent on the binary messenger, but it doesn't check the content of the message. A more robust test would be to use a mock MapsCallbackApi and verify that onPoiTap is called with the correct data. This ensures that the data is correctly constructed and passed to the Pigeon API.
Here's an example of how you could improve it:
@Test
public void onPoiClick_sendsCorrectData() {
// Assuming 'controller' and 'flutterApi' are set up as in other tests.
PointOfInterest poi = new PointOfInterest(new LatLng(1.0, 2.0), "placeId", "name");
controller.onPoiClick(poi);
ArgumentCaptor<Messages.PlatformPointOfInterest> poiCaptor = ArgumentCaptor.forClass(Messages.PlatformPointOfInterest.class);
verify(flutterApi).onPoiTap(poiCaptor.capture(), any(Messages.VoidResult.class));
Messages.PlatformPointOfInterest capturedPoi = poiCaptor.getValue();
assertEquals("name", capturedPoi.getName());
assertEquals("placeId", capturedPoi.getPlaceId());
assertEquals(1.0, capturedPoi.getPosition().getLatitude(), 1e-6);
assertEquals(2.0, capturedPoi.getPosition().getLongitude(), 1e-6);
}| /// Callback method for when a [PointOfInterest] is tapped. | ||
| typedef POIClickCallback = void Function(PointOfInterest poi); |
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Thanks for the contribution!
- I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
This needs to follow our documented process for changing federated plugins, so that CI works.
Please also be sure to review the feedback on the previous PR, especially this comment, and update accordingly. Even if this PR doesn't include web support (although it would be preferable if it did, especially since there is a previous PR to draw on), it does need to be designed in such a way as to not cause this problem for web later.
| ), | ||
| ); | ||
|
|
||
| // 🔥 IMPORTANT: Wait for the map initialization (onMapCreated) to complete |
There was a problem hiding this comment.
Please follow our standard commenting style. Sentences should be properly punctuated, and we don't use emoji in comments.
| ); | ||
|
|
||
| // 🔥 IMPORTANT: Wait for the map initialization (onMapCreated) to complete | ||
| await tester.pumpAndSettle(); |
There was a problem hiding this comment.
pumpAndSettle is for waiting for rendering to complete, not for arbitrary specific tasks. The way to wait for onMapCreated to complete is to have a future that completes when onMapCreated is called, and then wait for that. It is important that tests not be flaky because they are using delays as a proxy for waiting for specific conditions.
There was a problem hiding this comment.
Please review the package again. I have done the following works:
- Revamped the code as per the review of @stuartmorgan-g and @gemini_code_assist
- Added Support for flutter web for onPoiTap Callback
- Added Integration test for onPoiTap
- Updated Version for the google_maps_flutter_web package
There was a problem hiding this comment.
Thank you for addressing the feedback regarding the pumpAndSettle usage. The updated test now correctly waits for onMapCreated to complete using a Completer, which is a much more robust approach.
…ssage content being passed rather than the detecting if a binary message is being sent
…imRoyChowdhury/packages into feature/google-maps-poi-click
4512a35 to
3079afc
Compare
stuartmorgan-g
left a comment
There was a problem hiding this comment.
I've left some initial feedback.
This is not the first time I've had to point out that previous feedback has not been addressed. Please ensure that you either address feedback, or ask for clarification if necessary, before requesting review again.
There was a problem hiding this comment.
Generated files should never be patched or reconciled in merges, they should be regenerated from the source. These files should absolutely not be part of the PR, but the fact that they existed locally suggests that you haven't ensured up-to-date generated output.
| final Set<ClusterManager> clusterManagers; | ||
|
|
||
| /// Callback for Point of Interests tap | ||
| final ArgumentCallback<PointOfInterest>? onPoiTap; |
There was a problem hiding this comment.
This needs to be grouped with, and following the same comment style as, all the other callbacks.
There was a problem hiding this comment.
This change should have corresponding native unit tests.
|
|
||
| /// A [PointOfInterest] has been tapped. | ||
| Stream<MapPoiTapEvent> onPoiTap({required int mapId}) { | ||
| throw UnimplementedError('onPoiTap() has not been implemented.'); |
There was a problem hiding this comment.
This should return an empty stream, not throw, to avoid breaking existing implementations.
| final Set<ClusterManager> clusterManagers; | ||
|
|
||
| /// Callback for Point of Interests tap | ||
| final ArgumentCallback<PointOfInterest>? onPoiTap; |
There was a problem hiding this comment.
My previous comment has not been addressed. This is still returning an inflated POI rather than an ID.
There was a problem hiding this comment.
Code Review
This pull request introduces onPoiTap support for the GoogleMap widget, enabling tap detection on Points of Interest across Android, iOS, and web. The changes are well-implemented, touching the platform interface, all three platform implementations, and adding a new example page with tests. My review includes a minor code simplification suggestion and points out several patch-related artifact files that should be removed to maintain repository cleanliness. Overall, this is a great feature addition.
| @@ -0,0 +1,11 @@ | |||
| --- packages/google_maps_flutter/google_maps_flutter_android/example/lib/example_google_map.dart | |||
| @@ -0,0 +1,1574 @@ | |||
| --- packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart | |||
| @@ -0,0 +1,901 @@ | |||
| // Copyright 2013 The Flutter Authors | |||
| @@ -0,0 +1,807 @@ | |||
| --- packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/google_maps_flutter_pigeon_messages.g.h | |||
| @@ -0,0 +1,1496 @@ | |||
| --- packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart | |||
| if (widget.onPoiTap != null) { | ||
| widget.onPoiTap!(poi); | ||
| } |
There was a problem hiding this comment.
@stuartmorgan-g can you please see the code changes again. I have removed the name param from the onPoiTap. As you said that it sent inflated POI values in the web version. In the web version the name is not there in the native implementation which is why the inflated values were returned that's why I have removed the name param from all platform implementations and kept only the placeId and position.
As the unimplemented error was thrown which would have resulted in a breaking change so I have changed it to return an empty string instead of throwing.
I also applied the make-deps-path-based tooling but it was resulting in blank dependency overrides so I had to add the dependency overrides manually. Please help me in understanding this if I am using the tool incorrectly.
Above all thank you for your constant valuable feedback on the errors I was doing continuously, it would be great if you explain more about the errors if those happen again, and I have read the documentation regarding the federated plugin change and did all what I understood, please guide me if I have left something unaddressed.
There was a problem hiding this comment.
I have removed the name param from the onPoiTap.
It appears that you have removed the name from the PointOfInterest class, which would make it impossible to have the method discussed in the linked comment thread that would query for POI information.
The issue is not that POI doesn't have a name on web, it's that the tap event callback doesn't return a POI on web. That can't be fixed by removing information from POI itself. It needs to be solved by having the tap handler receive something that is not the POI class.
…s, formatting and removed name from PointOfInterest Model
… resolved syntax error
This PR adds support for detecting taps on the base map's Points of Interest.
Issue: Fixes flutter/flutter#60695
Changes:
Fixes: N/A - This is a new feature.
Pre-Review Checklist
[shared_preferences]pubspec.yamlwith an appropriate new version according to the [pub versioning philosophy], or I have commented below to indicate which [version change exemption] this PR falls under[^1].CHANGELOG.mdto add a description of the change, [following repository CHANGELOG style], or I have commented below to indicate which [CHANGELOG exemption] this PR falls under[^1].///).