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

[google_maps_flutter_web] Add "My Location" Widget #6868

Closed
wants to merge 43 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5f861c5
Add my location button
nploi Dec 12, 2022
d9a4fa6
Move to current location when click
nploi Dec 13, 2022
1450b75
Add blue dot
nploi Dec 14, 2022
03ed666
Update my location icon
nploi Dec 14, 2022
72b6553
Add blue dot
nploi Dec 14, 2022
ea3dd73
Add animation
nploi Dec 19, 2022
64668d0
Update my location element
nploi Dec 19, 2022
e2a5a24
Update my location element
nploi Dec 19, 2022
1ae5172
Update my location element
nploi Dec 19, 2022
9abc526
Add blue dot
nploi Dec 19, 2022
b986d65
Add blue dot icon
nploi Dec 20, 2022
c358fe8
Format code
nploi Dec 20, 2022
278b043
Update UI
nploi Dec 20, 2022
a72e0a1
Update types
nploi Dec 20, 2022
7ad54b5
Revert code
nploi Dec 20, 2022
e0c6c3d
Revert code
nploi Dec 20, 2022
ea4cdef
Add integration test
nploi Dec 24, 2022
1cdce7a
Revert code
nploi Dec 24, 2022
58c74ec
Fix test fail
nploi Dec 25, 2022
7bd8aa4
Fix test fail
nploi Dec 25, 2022
1b62e8c
Add more test & fix test fail
nploi Dec 25, 2022
4d6ba54
Revert code
nploi Dec 25, 2022
9d40e2e
Fix spelling
nploi Dec 25, 2022
f3a8fc9
Updated version & changelog
nploi Dec 25, 2022
77414ec
Updated version & changelog
nploi Dec 25, 2022
6668606
Updated version & changelog
nploi Dec 25, 2022
1b4b0bb
Move code to separate file, update logic, add mylocation-sprite-2x to…
nploi Dec 28, 2022
241f69d
Update logic watch position and check permission
nploi Dec 31, 2022
c0fff06
Rename method
nploi Dec 31, 2022
1747092
Revert code
nploi Dec 31, 2022
dd51548
Fix unit-test & fix logic
nploi Jan 1, 2023
c99c506
Update blue dot icon & add todo me
nploi Jan 1, 2023
6c0aecd
Fix lint
nploi Jan 1, 2023
cbc6bc2
Add unit-test for location permission
nploi Jan 1, 2023
766d690
Add author
nploi Jan 1, 2023
d85e6b8
Fix error syntax
nploi Jan 1, 2023
f99bce4
Revert code
nploi Jan 1, 2023
9755380
Fix lint
nploi Jan 1, 2023
65630ef
Merge branch 'main' of https://github.com/nploi/plugins into impl-my-…
nploi Jan 11, 2023
42e307a
Fix linter
nploi Jan 11, 2023
0090120
Merge branch 'main' of https://github.com/nploi/plugins into impl-my-…
nploi Jan 23, 2023
3db8113
Merge branch 'main' into impl-my-location
nploi Jan 25, 2023
9270247
Fix linter
nploi Jan 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy <[email protected]>
Anton Borries <[email protected]>
Alex Li <[email protected]>
Rahul Raj <[email protected]>
Nguyễn Phúc Lợi <[email protected]>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 0.4.1

* Add "My Location" Widget. Issue [#64073](https://github.com/flutter/flutter/issues/64073)
* Updates minimum Flutter version to 3.0.

## 0.4.0+5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const double _acceptableDelta = 0.0000000001;
MockSpec<PolygonsController>(onMissingStub: OnMissingStub.returnDefault),
MockSpec<PolylinesController>(onMissingStub: OnMissingStub.returnDefault),
MockSpec<MarkersController>(onMissingStub: OnMissingStub.returnDefault),
MockSpec<html.Geolocation>(onMissingStub: OnMissingStub.returnDefault),
MockSpec<html.Geoposition>(onMissingStub: OnMissingStub.returnDefault),
MockSpec<html.Coordinates>(onMissingStub: OnMissingStub.returnDefault),
])

/// Test Google Map Controller
Expand All @@ -35,7 +38,6 @@ void main() {
const int mapId = 33930;
late GoogleMapController controller;
late StreamController<MapEvent<Object?>> stream;

// Creates a controller with the default mapId and stream controller, and any `options` needed.
GoogleMapController createController({
CameraPosition initialCameraPosition =
Expand Down Expand Up @@ -485,6 +487,153 @@ void main() {
expect(controller.trafficLayer, isNotNull);
});
});

group('My Location', () {
testWidgets('by default is disabled', (WidgetTester tester) async {
controller = createController();
controller.init();
expect(controller.myLocationButton, isNull);
});

testWidgets('initializes with my location & display my location button',
(WidgetTester tester) async {
late final MockGeolocation mockGeolocation = MockGeolocation();
late final MockGeoposition mockGeoposition = MockGeoposition();
late final MockCoordinates mockCoordinates = MockCoordinates();
const LatLng currentLocation = LatLng(10.8231, 106.6297);

controller = createController(
mapConfiguration: const MapConfiguration(
myLocationEnabled: true,
myLocationButtonEnabled: true,
));
controller.debugSetOverrides(
createMap: (_, __) => map,
markers: markers,
geolocation: mockGeolocation,
);

when(mockGeoposition.coords).thenReturn(mockCoordinates);

when(mockCoordinates.longitude).thenReturn(currentLocation.longitude);

when(mockCoordinates.latitude).thenReturn(currentLocation.latitude);

when(mockGeolocation.getCurrentPosition(
timeout: const Duration(seconds: 30)))
.thenAnswer((_) async => mockGeoposition);

when(mockGeolocation.watchPosition()).thenAnswer((_) {
return Stream<MockGeoposition>.fromIterable(
<MockGeoposition>[mockGeoposition]);
});

controller.init();

await Future<void>.delayed(const Duration(milliseconds: 50));

final Set<Marker> capturedMarkers =
verify(markers.addMarkers(captureAny)).captured[1] as Set<Marker>;

final gmaps.LatLng gmCenter = map.center!;

expect(controller.myLocationButton, isNotNull);
expect(capturedMarkers.length, 1);
expect(capturedMarkers.first.position, currentLocation);
expect(capturedMarkers.first.zIndex, 0.5);
expect(gmCenter.lat, currentLocation.latitude);
expect(gmCenter.lng, currentLocation.longitude);
});

testWidgets('initializes with my location only',
(WidgetTester tester) async {
late final MockGeolocation mockGeolocation = MockGeolocation();
late final MockGeoposition mockGeoposition = MockGeoposition();
late final MockCoordinates mockCoordinates = MockCoordinates();
const LatLng currentLocation = LatLng(10.8231, 106.6297);

controller = createController(
mapConfiguration: const MapConfiguration(
myLocationEnabled: true,
myLocationButtonEnabled: false,
));
controller.debugSetOverrides(
createMap: (_, __) => map,
markers: markers,
geolocation: mockGeolocation,
);

when(mockGeoposition.coords).thenReturn(mockCoordinates);

when(mockCoordinates.longitude).thenReturn(currentLocation.longitude);

when(mockCoordinates.latitude).thenReturn(currentLocation.latitude);

when(mockGeolocation.getCurrentPosition(
timeout: const Duration(seconds: 30)))
.thenAnswer((_) async => mockGeoposition);

when(mockGeolocation.watchPosition()).thenAnswer((_) {
return Stream<MockGeoposition>.fromIterable(
<MockGeoposition>[mockGeoposition]);
});

controller.init();

await Future<void>.delayed(const Duration(milliseconds: 50));

final Set<Marker> capturedMarkers =
verify(markers.addMarkers(captureAny)).captured[1] as Set<Marker>;

final gmaps.LatLng gmCenter = map.center!;

expect(controller.myLocationButton, isNull);
expect(capturedMarkers.length, 1);
expect(capturedMarkers.first.position, currentLocation);
expect(capturedMarkers.first.zIndex, 0.5);
expect(gmCenter.lat, currentLocation.latitude);
expect(gmCenter.lng, currentLocation.longitude);
});
});

testWidgets(
'My location button should be disable when dont have permission access to location',
(WidgetTester tester) async {
late final MockGeolocation mockGeolocation = MockGeolocation();

controller = createController(
mapConfiguration: const MapConfiguration(
myLocationEnabled: true,
myLocationButtonEnabled: true,
));

controller.debugSetOverrides(
createMap: (_, __) => map,
markers: markers,
geolocation: mockGeolocation,
);

when(mockGeolocation.getCurrentPosition(
timeout: const Duration(seconds: 30)))
.thenAnswer(
(_) async => throw Exception('permission denied'),
);

when(mockGeolocation.watchPosition()).thenAnswer((_) {
return Stream<MockGeoposition>.fromIterable(<MockGeoposition>[]);
});

controller.init();

await Future<void>.delayed(const Duration(milliseconds: 50));

final Set<Marker> capturedMarkers =
verify(markers.addMarkers(captureAny)).captured[0] as Set<Marker>;

expect(controller.myLocationButton, isNotNull);
expect(controller.myLocationButton?.isDisabled(), true);
expect(capturedMarkers.length, 0);
});
});

// These are the methods that are delegated to the gmaps.GMap object, that we can mock...
Expand Down
Loading