From 5f861c58563a8d4382a445e44b307b9997f0f497 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 13 Dec 2022 00:47:26 +0700 Subject: [PATCH 01/40] Add my location button --- .../example/lib/main.dart | 109 ++++++++++++++++-- .../example/web/index.html | 2 +- .../lib/src/google_maps_controller.dart | 31 +++++ 3 files changed, 130 insertions(+), 12 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index e93a60e19906..c2e935ee538f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -1,25 +1,112 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - +import 'dart:async'; +import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; void main() { runApp(const MyApp()); } -/// App for testing -class MyApp extends StatefulWidget { - /// Constructor with key - const MyApp({Key? key}) : super(key: key); +class MyApp extends StatelessWidget { + const MyApp({key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Welcome to Flutter', + home: Scaffold( + body: Page1(), + ), + ); + } +} +class Page1 extends StatefulWidget { @override - State createState() => _MyAppState(); + _Page1State createState() => _Page1State(); } -class _MyAppState extends State { +class _Page1State extends State { + @override + void initState() { + Timer time = Timer.periodic(Duration(seconds: 3), (Timer t) => timer()); + super.initState(); + } + + LatLng _kMapCenter1 = LatLng(19.0182, 72.8479); + LatLng _kMapCenter2 = LatLng(19.0183, 72.8480); + bool toggle = false; + + Future timer() async { + if (toggle) { + setState(() { + _kMapCenter1 = LatLng(19.0181, 72.8478); + _kMapCenter2 = LatLng(19.0184, 72.8481); + }); + toggle = !toggle; + } else { + setState(() { + _kMapCenter1 = LatLng(19.0182, 72.8479); + _kMapCenter2 = LatLng(19.0183, 72.8480); + }); + toggle = !toggle; + } + + print(_kMapCenter1.longitude); + } + + Completer _controller = Completer(); + + static final CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + + static final CameraPosition _kLake = CameraPosition( + bearing: 192.8334901395799, + target: LatLng(19.01825595, 72.84793854), + tilt: 59.440717697143555, + zoom: 19.151926040649414); + @override Widget build(BuildContext context) { - return const Text('Testing... Look at the console output for results!'); + return Scaffold( + body: GoogleMap( + markers: Set.of(_createMarker()), + mapType: MapType.hybrid, + initialCameraPosition: _kGooglePlex, + onMapCreated: (GoogleMapController controller) { + _controller.complete(controller); + }, + myLocationButtonEnabled: true, + myLocationEnabled: true, + ), + floatingActionButton: FloatingActionButton.extended( + onPressed: _goToTheLake, + label: Text('To the lake!'), + icon: Icon(Icons.directions_boat), + ), + ); + } + + //ทำ marker + Set _createMarker() { + print(5555); + return { + Marker( + markerId: MarkerId("marker_1"), + position: _kMapCenter1, + infoWindow: InfoWindow(title: 'Marker 1'), + rotation: 90), + Marker( + markerId: MarkerId("marker_2"), + position: _kMapCenter2, + ), + }; + } + + Future _goToTheLake() async { + final GoogleMapController controller = await _controller.future; + controller.animateCamera(CameraUpdate.newCameraPosition(_kLake)); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index 3121d189b913..d1d27adb4a57 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,7 +6,7 @@ Browser Tests - + diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index a659fb218803..6f18bd96e843 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -160,9 +160,11 @@ class GoogleMapController { _lastMapConfiguration, _lastStyles); // Initial position can only to be set here! options = _applyInitialPosition(_initialCameraPosition, options); + var button = _addMyLocationButton(); // Create the map... final gmaps.GMap map = _createMap(_div, options); + map.controls![gmaps.ControlPosition.TOP_CENTER as int]?.push(button); _googleMap = map; _attachMapEvents(map); @@ -179,6 +181,35 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); } + HtmlElement _addMyLocationButton() { + final controlButton = document.createElement('myLocationButton'); + + // // Set CSS for the control. + controlButton.style.backgroundColor = "#fff"; + controlButton.style.border = "2px solid #fff"; + controlButton.style.borderRadius = "3px"; + controlButton.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)"; + controlButton.style.color = "rgb(25,25,25)"; + controlButton.style.cursor = "pointer"; + controlButton.style.fontFamily = "Roboto,Arial,sans-serif"; + controlButton.style.fontSize = "16px"; + controlButton.style.lineHeight = "38px"; + controlButton.style.margin = "8px 0 22px"; + controlButton.style.padding = "0 5px"; + controlButton.style.textAlign = "center"; + + controlButton.innerHtml = "Center Map"; + controlButton.title = "Click to recenter the map"; + // controlButton. = "button"; + // Setup the click event listeners: simply set the map to Chicago. + controlButton.addEventListener("click", ((event) => {})); + // final centerControlDiv = document.createElement("div"); + // Create the control. + // Append the control to the DIV. + // centerControlDiv.append(controlButton); + return controlButton as HtmlElement; + } + // Funnels map gmap events into the plugin's stream controller. void _attachMapEvents(gmaps.GMap map) { map.onTilesloaded.first.then((void _) { From d9a4fa654b5bc15082c28ae70fa7e8f4808d13f6 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 13 Dec 2022 21:44:30 +0700 Subject: [PATCH 02/40] Move to current location when click --- .../lib/src/google_maps_controller.dart | 27 ++++++++++++++----- .../google_maps_flutter_web/lib/src/test.html | 11 ++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 6f18bd96e843..689e7260ee37 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -160,11 +160,13 @@ class GoogleMapController { _lastMapConfiguration, _lastStyles); // Initial position can only to be set here! options = _applyInitialPosition(_initialCameraPosition, options); - var button = _addMyLocationButton(); // Create the map... final gmaps.GMap map = _createMap(_div, options); - map.controls![gmaps.ControlPosition.TOP_CENTER as int]?.push(button); + if (_lastMapConfiguration.myLocationButtonEnabled!) { + final button = _addMyLocationButton(); + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int]?.push(button); + } _googleMap = map; _attachMapEvents(map); @@ -182,10 +184,9 @@ class GoogleMapController { } HtmlElement _addMyLocationButton() { - final controlButton = document.createElement('myLocationButton'); + final controlButton = document.createElement('button'); // // Set CSS for the control. - controlButton.style.backgroundColor = "#fff"; controlButton.style.border = "2px solid #fff"; controlButton.style.borderRadius = "3px"; controlButton.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)"; @@ -197,12 +198,24 @@ class GoogleMapController { controlButton.style.margin = "8px 0 22px"; controlButton.style.padding = "0 5px"; controlButton.style.textAlign = "center"; - - controlButton.innerHtml = "Center Map"; + // controlButton.innerHtml = ""; + controlButton.text = "My Location"; controlButton.title = "Click to recenter the map"; // controlButton. = "button"; // Setup the click event listeners: simply set the map to Chicago. - controlButton.addEventListener("click", ((event) => {})); + controlButton.addEventListener("click", ((event) { + window.navigator.geolocation.getCurrentPosition().then((value) { + moveCamera( + CameraUpdate.newLatLng(LatLng( + value.coords!.latitude!.toDouble(), + value.coords!.longitude!.toDouble(), + )), + ); + }); + })); +// if (window.navigator.geolocation) { +// navigator.geolocation.getCurrentPosition(showPosition); +// } // final centerControlDiv = document.createElement("div"); // Create the control. // Append the control to the DIV. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html new file mode 100644 index 000000000000..785abab10793 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html @@ -0,0 +1,11 @@ + \ No newline at end of file From 1450b756fbdb18dc8bb0d5bd8a7bdf3d95381943 Mon Sep 17 00:00:00 2001 From: nploi Date: Wed, 14 Dec 2022 22:20:10 +0700 Subject: [PATCH 03/40] Add blue dot --- .../example/lib/main.dart | 24 ----- .../lib/src/google_maps_controller.dart | 100 ++++++++++++------ .../google_maps_flutter_web/lib/src/test.html | 11 -- 3 files changed, 65 insertions(+), 70 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index c2e935ee538f..6175f1c10da7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -29,7 +29,6 @@ class Page1 extends StatefulWidget { class _Page1State extends State { @override void initState() { - Timer time = Timer.periodic(Duration(seconds: 3), (Timer t) => timer()); super.initState(); } @@ -37,24 +36,6 @@ class _Page1State extends State { LatLng _kMapCenter2 = LatLng(19.0183, 72.8480); bool toggle = false; - Future timer() async { - if (toggle) { - setState(() { - _kMapCenter1 = LatLng(19.0181, 72.8478); - _kMapCenter2 = LatLng(19.0184, 72.8481); - }); - toggle = !toggle; - } else { - setState(() { - _kMapCenter1 = LatLng(19.0182, 72.8479); - _kMapCenter2 = LatLng(19.0183, 72.8480); - }); - toggle = !toggle; - } - - print(_kMapCenter1.longitude); - } - Completer _controller = Completer(); static final CameraPosition _kGooglePlex = CameraPosition( @@ -81,11 +62,6 @@ class _Page1State extends State { myLocationButtonEnabled: true, myLocationEnabled: true, ), - floatingActionButton: FloatingActionButton.extended( - onPressed: _goToTheLake, - label: Text('To the lake!'), - icon: Icon(Icons.directions_boat), - ), ); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 689e7260ee37..baf023fd6702 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -163,9 +163,10 @@ class GoogleMapController { // Create the map... final gmaps.GMap map = _createMap(_div, options); - if (_lastMapConfiguration.myLocationButtonEnabled!) { - final button = _addMyLocationButton(); - map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int]?.push(button); + if (_lastMapConfiguration.myLocationButtonEnabled! && + _lastMapConfiguration.myLocationEnabled!) { + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] + ?.push(_addMyLocationButton()); } _googleMap = map; @@ -181,48 +182,77 @@ class GoogleMapController { ); _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); + + if (_lastMapConfiguration.myLocationEnabled!) { + _watchPositionAndAddBlueDot(); + _moveToCurrentLocation(); + } } HtmlElement _addMyLocationButton() { final controlButton = document.createElement('button'); - // // Set CSS for the control. - controlButton.style.border = "2px solid #fff"; - controlButton.style.borderRadius = "3px"; - controlButton.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)"; - controlButton.style.color = "rgb(25,25,25)"; - controlButton.style.cursor = "pointer"; - controlButton.style.fontFamily = "Roboto,Arial,sans-serif"; - controlButton.style.fontSize = "16px"; - controlButton.style.lineHeight = "38px"; - controlButton.style.margin = "8px 0 22px"; - controlButton.style.padding = "0 5px"; - controlButton.style.textAlign = "center"; - // controlButton.innerHtml = ""; - controlButton.text = "My Location"; - controlButton.title = "Click to recenter the map"; - // controlButton. = "button"; - // Setup the click event listeners: simply set the map to Chicago. + // controlButton.style.border = "2px solid #fff"; + // controlButton.style.borderRadius = "3px"; + // controlButton.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)"; + // controlButton.style.color = "rgb(25,25,25)"; + // controlButton.style.cursor = "pointer"; + // controlButton.style.fontFamily = "Roboto,Arial,sans-serif"; + // controlButton.style.fontSize = "16px"; + // controlButton.style.lineHeight = "38px"; + // controlButton.style.margin = "8px 0 22px"; + // controlButton.style.padding = "0 5px"; + // controlButton.style.textAlign = "center"; + controlButton.className = "gm-control-active"; + controlButton.innerHtml = ""; + // controlButton.title = "Click to recenter the map"; controlButton.addEventListener("click", ((event) { - window.navigator.geolocation.getCurrentPosition().then((value) { - moveCamera( - CameraUpdate.newLatLng(LatLng( - value.coords!.latitude!.toDouble(), - value.coords!.longitude!.toDouble(), - )), - ); - }); + _moveToCurrentLocation(); })); -// if (window.navigator.geolocation) { -// navigator.geolocation.getCurrentPosition(showPosition); -// } - // final centerControlDiv = document.createElement("div"); - // Create the control. - // Append the control to the DIV. - // centerControlDiv.append(controlButton); return controlButton as HtmlElement; } + void _moveToCurrentLocation() { + window.navigator.geolocation.getCurrentPosition().then((location) { + moveCamera( + CameraUpdate.newLatLng(LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + )), + ); + }); + } + + void _watchPositionAndAddBlueDot() { + window.navigator.geolocation + .watchPosition() + .listen((Geoposition geolocation) { + _addBlueDot(geolocation); + }); + } + + void _addBlueDot(Geoposition geolocation) { + print('add blue dot'); + assert( + _markersController != null, 'Cannot update circles after dispose().'); + _circlesController?._addCircle(Circle( + circleId: CircleId('my_location_blue_dot'), + // scale: 10, + // fillOpacity: 1, + strokeWidth: 2, + radius: 50, + center: LatLng( + geolocation.coords!.latitude!.toDouble(), + geolocation.coords!.longitude!.toDouble(), + ), + + // strokeWidth: 2, + fillColor: Colors.blue, + strokeColor: Colors.white, + zIndex: -1, + )); + } + // Funnels map gmap events into the plugin's stream controller. void _attachMapEvents(gmaps.GMap map) { map.onTilesloaded.first.then((void _) { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html deleted file mode 100644 index 785abab10793..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/test.html +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file From 03ed666d8085e28680651276402a45c20864c461 Mon Sep 17 00:00:00 2001 From: nploi Date: Thu, 15 Dec 2022 01:16:22 +0700 Subject: [PATCH 04/40] Update my location icon --- .../lib/src/google_maps_controller.dart | 86 +++++++++++-------- 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index baf023fd6702..c1e012a2eabd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -165,8 +165,7 @@ class GoogleMapController { final gmaps.GMap map = _createMap(_div, options); if (_lastMapConfiguration.myLocationButtonEnabled! && _lastMapConfiguration.myLocationEnabled!) { - map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(_addMyLocationButton()); + _addMyLocationButton(map); } _googleMap = map; @@ -184,36 +183,54 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); if (_lastMapConfiguration.myLocationEnabled!) { - _watchPositionAndAddBlueDot(); + // _watchPositionAndAddBlueDot(); _moveToCurrentLocation(); } } - HtmlElement _addMyLocationButton() { - final controlButton = document.createElement('button'); - // // Set CSS for the control. - // controlButton.style.border = "2px solid #fff"; - // controlButton.style.borderRadius = "3px"; - // controlButton.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)"; - // controlButton.style.color = "rgb(25,25,25)"; - // controlButton.style.cursor = "pointer"; - // controlButton.style.fontFamily = "Roboto,Arial,sans-serif"; - // controlButton.style.fontSize = "16px"; - // controlButton.style.lineHeight = "38px"; - // controlButton.style.margin = "8px 0 22px"; - // controlButton.style.padding = "0 5px"; - // controlButton.style.textAlign = "center"; - controlButton.className = "gm-control-active"; - controlButton.innerHtml = ""; - // controlButton.title = "Click to recenter the map"; - controlButton.addEventListener("click", ((event) { + void _addMyLocationButton(gmaps.GMap map) { + final controlDiv = document.createElement('div'); + var firstChild = document.createElement('button'); + firstChild.style.backgroundColor = '#fff'; + firstChild.style.border = 'none'; + firstChild.style.outline = 'none'; + firstChild.style.width = '40px'; + firstChild.style.height = '40px'; + firstChild.style.borderRadius = '2px'; + firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; + firstChild.style.cursor = 'pointer'; + firstChild.style.marginRight = '10px'; + firstChild.style.padding = '0px'; + firstChild.title = 'Your Location'; + firstChild.className = 'gm-control-active"'; + controlDiv.append(firstChild); + + var secondChild = document.createElement('div'); //class="gm-control-active" + + secondChild.style.margin = '5px'; + secondChild.style.width = '30px'; + secondChild.style.height = '30px'; + secondChild.style.backgroundImage = + 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-2x.png)'; + secondChild.style.backgroundSize = '300px 30px'; + secondChild.style.backgroundPosition = '0px 0px'; + secondChild.style.backgroundRepeat = 'no-repeat'; + secondChild.id = 'you_location_img'; + firstChild.append(secondChild); + + firstChild.addEventListener("click", ((event) { _moveToCurrentLocation(); })); - return controlButton as HtmlElement; + + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] + ?.push(controlDiv as HtmlElement); } void _moveToCurrentLocation() { - window.navigator.geolocation.getCurrentPosition().then((location) { + window.navigator.geolocation + .getCurrentPosition(enableHighAccuracy: true) + .then((location) { + print('_moveToCurrentLocation'); moveCamera( CameraUpdate.newLatLng(LatLng( location.coords!.latitude!.toDouble(), @@ -227,7 +244,7 @@ class GoogleMapController { window.navigator.geolocation .watchPosition() .listen((Geoposition geolocation) { - _addBlueDot(geolocation); + // _addBlueDot(geolocation); }); } @@ -235,21 +252,22 @@ class GoogleMapController { print('add blue dot'); assert( _markersController != null, 'Cannot update circles after dispose().'); - _circlesController?._addCircle(Circle( - circleId: CircleId('my_location_blue_dot'), + _markersController?._addMarker(Marker( + markerId: MarkerId('my_location_blue_dot'), // scale: 10, // fillOpacity: 1, - strokeWidth: 2, - radius: 50, - center: LatLng( + // strokeWidth: 2, + // radius: 50, + // icon: value, + position: LatLng( geolocation.coords!.latitude!.toDouble(), geolocation.coords!.longitude!.toDouble(), ), - - // strokeWidth: 2, - fillColor: Colors.blue, - strokeColor: Colors.white, - zIndex: -1, + + // // strokeWidth: 2, + // fillColor: Colors.blue, + // strokeColor: Colors.white, + // zIndex: -1, )); } From 72b6553528719de7639fd08c699bd443ef2a9666 Mon Sep 17 00:00:00 2001 From: nploi Date: Thu, 15 Dec 2022 01:24:50 +0700 Subject: [PATCH 05/40] Add blue dot --- .../lib/src/google_maps_controller.dart | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index c1e012a2eabd..0ab73140c0f4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -183,7 +183,7 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); if (_lastMapConfiguration.myLocationEnabled!) { - // _watchPositionAndAddBlueDot(); + _watchPositionAndAddBlueDot(); _moveToCurrentLocation(); } } @@ -244,7 +244,7 @@ class GoogleMapController { window.navigator.geolocation .watchPosition() .listen((Geoposition geolocation) { - // _addBlueDot(geolocation); + _addBlueDot(geolocation); }); } @@ -252,22 +252,16 @@ class GoogleMapController { print('add blue dot'); assert( _markersController != null, 'Cannot update circles after dispose().'); + final Uint8List bytes = base64.decode( + 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAF96VFh0UmF3IHByb2ZpbGUgdHlwZSBBUFAxAABo3uNKT81LLcpMVigoyk/LzEnlUgADYxMuE0sTS6NEAwMDCwMIMDQwMDYEkkZAtjlUKNEABZgamFmaGZsZmgMxiM8FAEi2FMnxHlGkAAADqElEQVRo3t1aTWgTQRQOiuDPQfHs38GDogc1BwVtQxM9xIMexIN4EWw9iAehuQdq0zb+IYhglFovClXQU+uhIuqh3hQll3iwpyjG38Zkt5uffc4XnHaSbpLZ3dnEZOBB2H3z3jeZN+9vx+fzYPgTtCoQpdVHrtA6EH7jme+/HFFawQBu6BnWNwdGjB2BWH5P32jeb0V4B54KL5uDuW3D7Y/S2uCwvrUR4GaEuZABWS0FHhhd2O4UdN3FMJneLoRtN7Y+GMvvUw2eE2RDh3LTOnCd1vQN5XZ5BXwZMV3QqQT84TFa3zuU39sy8P8IOqHb3T8fpY1emoyMSQGDI/Bwc+0ELy6i4nLtepp2mE0jc5L3UAhMsdxut0rPJfRDN2eMY1enF8Inbmj7XbtZhunkI1rZFD/cmFMlr1PFi1/nzSdGkT5RzcAzvAOPU/kVF9s0ujqw+9mP5QgDmCbJAV7McXIeGpqS3Qg7OVs4lTfMD1Yg9QLR518mZbImFcvWC8FcyLAbsev++3YETb0tn2XAvouAvjGwd14YdCahUTCWW6QQIzzDO/CIAzKm3pf77ei23AUkVbICHr8pnDZNynMQJfYPT7wyKBzPVQG3IvCAtyTsCmRBprQpMawWnkc+q2Rbn+TK/+gmRR7qTYHXEuZkdVM0p6SdLLYqX0LItnFgBxe3v0R04b5mGzwnzIUMPiBbFkdVmhGIa5tkJ4reZvyl4Rg8p3tMBh+FEqUduVRUSTKTnieL58UDG76cc70AyMgIBxs6pMyIYV5agKT9f/ltTnJFOIhuwXOCLD6gQ/oc8AJcdtuYb09xRQN3NWULgCwhfqSk3SkaBZViRTK3EYNUSBF4Hic0Y8mM+if0HhlMlaIHbQ8Z5lszxnGuIP2zrAw8J8jkA7pkMAG79AKuPTOOcgWZeVP5AsSDjAxWegGyJoSUWAj/FBpRa0JiviSbfldMqOMPcce7UVeBLK4gkMVVBLI2phLjKlIJm8lcxMNkLuIomXOTTmc1kwYf2E+nMQdzlaTTKgoaZJWyBQ141RY0DkrK6XflAQbih1geZnhJeXu5WeEZ3mVqSkrIgCzXJaXqoh65TUuLerdtFXgQ2bYKeD1pq6hobLE86SlztXMWvaA5vPO0sYWB9p2K1iJS4ra0Fju/udsN7fWu+MDRFZ+YuuIjX1d8Zu2OD92WC9G3ub1qABktBV7vssfBMX1L7yVjZ7PLHuABb9svezS7boNDyK/b4LdX123+Au+jOmNxrkG0AAAAAElFTkSuQmCC'); _markersController?._addMarker(Marker( - markerId: MarkerId('my_location_blue_dot'), - // scale: 10, - // fillOpacity: 1, - // strokeWidth: 2, - // radius: 50, - // icon: value, + markerId: const MarkerId('my_location_blue_dot'), + icon: BitmapDescriptor.fromBytes(bytes, size: Size(20, 20)), position: LatLng( geolocation.coords!.latitude!.toDouble(), geolocation.coords!.longitude!.toDouble(), ), - - // // strokeWidth: 2, - // fillColor: Colors.blue, - // strokeColor: Colors.white, - // zIndex: -1, + zIndex: 0.5, )); } From ea3dd73c7503a01eae4b89ecc920b3c341ee1484 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 20 Dec 2022 00:24:07 +0700 Subject: [PATCH 06/40] Add animation --- .../lib/src/google_maps_controller.dart | 67 +++++++------------ 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 0ab73140c0f4..52b209a69be8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -183,7 +183,6 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); if (_lastMapConfiguration.myLocationEnabled!) { - _watchPositionAndAddBlueDot(); _moveToCurrentLocation(); } } @@ -202,11 +201,9 @@ class GoogleMapController { firstChild.style.marginRight = '10px'; firstChild.style.padding = '0px'; firstChild.title = 'Your Location'; - firstChild.className = 'gm-control-active"'; controlDiv.append(firstChild); - var secondChild = document.createElement('div'); //class="gm-control-active" - + var secondChild = document.createElement('div'); secondChild.style.margin = '5px'; secondChild.style.width = '30px'; secondChild.style.height = '30px'; @@ -219,50 +216,36 @@ class GoogleMapController { firstChild.append(secondChild); firstChild.addEventListener("click", ((event) { - _moveToCurrentLocation(); + String imgX = '0'; + final timer = Timer.periodic(const Duration(milliseconds: 500), (_) { + imgX = (imgX == '-30') ? '0' : '-30'; + document.getElementById('you_location_img')?.style.backgroundPosition = + '${imgX}px 0px'; + }); + _moveToCurrentLocation().then((_) { + timer.cancel(); + document.getElementById('you_location_img')?.style.backgroundPosition = + '-270px 0px'; + }); })); - map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(controlDiv as HtmlElement); - } - - void _moveToCurrentLocation() { - window.navigator.geolocation - .getCurrentPosition(enableHighAccuracy: true) - .then((location) { - print('_moveToCurrentLocation'); - moveCamera( - CameraUpdate.newLatLng(LatLng( - location.coords!.latitude!.toDouble(), - location.coords!.longitude!.toDouble(), - )), - ); + map.addListener('dragend', () { + document.getElementById('you_location_img')?.style.backgroundPosition = + '0px 0px'; }); - } - void _watchPositionAndAddBlueDot() { - window.navigator.geolocation - .watchPosition() - .listen((Geoposition geolocation) { - _addBlueDot(geolocation); - }); + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] + ?.push(controlDiv as HtmlElement); } - void _addBlueDot(Geoposition geolocation) { - print('add blue dot'); - assert( - _markersController != null, 'Cannot update circles after dispose().'); - final Uint8List bytes = base64.decode( - 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAF96VFh0UmF3IHByb2ZpbGUgdHlwZSBBUFAxAABo3uNKT81LLcpMVigoyk/LzEnlUgADYxMuE0sTS6NEAwMDCwMIMDQwMDYEkkZAtjlUKNEABZgamFmaGZsZmgMxiM8FAEi2FMnxHlGkAAADqElEQVRo3t1aTWgTQRQOiuDPQfHs38GDogc1BwVtQxM9xIMexIN4EWw9iAehuQdq0zb+IYhglFovClXQU+uhIuqh3hQll3iwpyjG38Zkt5uffc4XnHaSbpLZ3dnEZOBB2H3z3jeZN+9vx+fzYPgTtCoQpdVHrtA6EH7jme+/HFFawQBu6BnWNwdGjB2BWH5P32jeb0V4B54KL5uDuW3D7Y/S2uCwvrUR4GaEuZABWS0FHhhd2O4UdN3FMJneLoRtN7Y+GMvvUw2eE2RDh3LTOnCd1vQN5XZ5BXwZMV3QqQT84TFa3zuU39sy8P8IOqHb3T8fpY1emoyMSQGDI/Bwc+0ELy6i4nLtepp2mE0jc5L3UAhMsdxut0rPJfRDN2eMY1enF8Inbmj7XbtZhunkI1rZFD/cmFMlr1PFi1/nzSdGkT5RzcAzvAOPU/kVF9s0ujqw+9mP5QgDmCbJAV7McXIeGpqS3Qg7OVs4lTfMD1Yg9QLR518mZbImFcvWC8FcyLAbsev++3YETb0tn2XAvouAvjGwd14YdCahUTCWW6QQIzzDO/CIAzKm3pf77ei23AUkVbICHr8pnDZNynMQJfYPT7wyKBzPVQG3IvCAtyTsCmRBprQpMawWnkc+q2Rbn+TK/+gmRR7qTYHXEuZkdVM0p6SdLLYqX0LItnFgBxe3v0R04b5mGzwnzIUMPiBbFkdVmhGIa5tkJ4reZvyl4Rg8p3tMBh+FEqUduVRUSTKTnieL58UDG76cc70AyMgIBxs6pMyIYV5agKT9f/ltTnJFOIhuwXOCLD6gQ/oc8AJcdtuYb09xRQN3NWULgCwhfqSk3SkaBZViRTK3EYNUSBF4Hic0Y8mM+if0HhlMlaIHbQ8Z5lszxnGuIP2zrAw8J8jkA7pkMAG79AKuPTOOcgWZeVP5AsSDjAxWegGyJoSUWAj/FBpRa0JiviSbfldMqOMPcce7UVeBLK4gkMVVBLI2phLjKlIJm8lcxMNkLuIomXOTTmc1kwYf2E+nMQdzlaTTKgoaZJWyBQ141RY0DkrK6XflAQbih1geZnhJeXu5WeEZ3mVqSkrIgCzXJaXqoh65TUuLerdtFXgQ2bYKeD1pq6hobLE86SlztXMWvaA5vPO0sYWB9p2K1iJS4ra0Fju/udsN7fWu+MDRFZ+YuuIjX1d8Zu2OD92WC9G3ub1qABktBV7vssfBMX1L7yVjZ7PLHuABb9svezS7boNDyK/b4LdX123+Au+jOmNxrkG0AAAAAElFTkSuQmCC'); - _markersController?._addMarker(Marker( - markerId: const MarkerId('my_location_blue_dot'), - icon: BitmapDescriptor.fromBytes(bytes, size: Size(20, 20)), - position: LatLng( - geolocation.coords!.latitude!.toDouble(), - geolocation.coords!.longitude!.toDouble(), - ), - zIndex: 0.5, - )); + Future _moveToCurrentLocation() async { + final location = await window.navigator.geolocation.getCurrentPosition(); + await moveCamera( + CameraUpdate.newLatLng(LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + )), + ); } // Funnels map gmap events into the plugin's stream controller. From 64668d02648a2f533935e29320e2de1ad3ed06f8 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 20 Dec 2022 00:45:13 +0700 Subject: [PATCH 07/40] Update my location element --- .../lib/src/google_maps_controller.dart | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 52b209a69be8..231faf2561d7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -187,57 +187,6 @@ class GoogleMapController { } } - void _addMyLocationButton(gmaps.GMap map) { - final controlDiv = document.createElement('div'); - var firstChild = document.createElement('button'); - firstChild.style.backgroundColor = '#fff'; - firstChild.style.border = 'none'; - firstChild.style.outline = 'none'; - firstChild.style.width = '40px'; - firstChild.style.height = '40px'; - firstChild.style.borderRadius = '2px'; - firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; - firstChild.style.cursor = 'pointer'; - firstChild.style.marginRight = '10px'; - firstChild.style.padding = '0px'; - firstChild.title = 'Your Location'; - controlDiv.append(firstChild); - - var secondChild = document.createElement('div'); - secondChild.style.margin = '5px'; - secondChild.style.width = '30px'; - secondChild.style.height = '30px'; - secondChild.style.backgroundImage = - 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-2x.png)'; - secondChild.style.backgroundSize = '300px 30px'; - secondChild.style.backgroundPosition = '0px 0px'; - secondChild.style.backgroundRepeat = 'no-repeat'; - secondChild.id = 'you_location_img'; - firstChild.append(secondChild); - - firstChild.addEventListener("click", ((event) { - String imgX = '0'; - final timer = Timer.periodic(const Duration(milliseconds: 500), (_) { - imgX = (imgX == '-30') ? '0' : '-30'; - document.getElementById('you_location_img')?.style.backgroundPosition = - '${imgX}px 0px'; - }); - _moveToCurrentLocation().then((_) { - timer.cancel(); - document.getElementById('you_location_img')?.style.backgroundPosition = - '-270px 0px'; - }); - })); - - map.addListener('dragend', () { - document.getElementById('you_location_img')?.style.backgroundPosition = - '0px 0px'; - }); - - map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(controlDiv as HtmlElement); - } - Future _moveToCurrentLocation() async { final location = await window.navigator.geolocation.getCurrentPosition(); await moveCamera( @@ -482,6 +431,57 @@ class GoogleMapController { return _markersController?.isInfoWindowShown(markerId) ?? false; } + void _addMyLocationButton(gmaps.GMap map) { + final controlDiv = document.createElement('button'); + controlDiv.style.backgroundColor = '#fff'; + controlDiv.style.border = 'none'; + controlDiv.style.outline = 'none'; + controlDiv.style.width = '40px'; + controlDiv.style.height = '40px'; + controlDiv.style.borderRadius = '2px'; + controlDiv.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; + controlDiv.style.cursor = 'pointer'; + controlDiv.style.marginRight = '10px'; + controlDiv.style.padding = '0px'; + + final secondChild = document.createElement('div'); + secondChild.style.margin = '5px'; + secondChild.style.width = '30px'; + secondChild.style.height = '30px'; + secondChild.style.backgroundImage = + 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-2x.png)'; + secondChild.style.backgroundSize = '300px 30px'; + secondChild.style.backgroundPosition = '0px 0px'; + secondChild.style.backgroundRepeat = 'no-repeat'; + secondChild.id = 'you_location_img'; + controlDiv.append(secondChild); + + // ignore: unnecessary_parenthesis + controlDiv.addEventListener("click", ((_) { + String imgX = '0'; + final Timer timer = + Timer.periodic(const Duration(milliseconds: 500), (_) { + imgX = (imgX == '-30') ? '0' : '-30'; + document.getElementById('you_location_img')?.style.backgroundPosition = + '${imgX}px 0px'; + }); + _moveToCurrentLocation().then((_) { + timer.cancel(); + imgX = '-270'; + document.getElementById('you_location_img')?.style.backgroundPosition = + '-270px 0px'; + }); + })); + + map.addListener('dragend', () { + document.getElementById('you_location_img')?.style.backgroundPosition = + '0px 0px'; + }); + + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] + ?.push(controlDiv as HtmlElement); + } + // Cleanup /// Disposes of this controller and its resources. From e2a5a2491b3a023b2854bf9012b1f4834e0e9d81 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 20 Dec 2022 01:04:27 +0700 Subject: [PATCH 08/40] Update my location element --- .../lib/src/google_maps_controller.dart | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 231faf2561d7..e3473d9026a6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -432,44 +432,44 @@ class GoogleMapController { } void _addMyLocationButton(gmaps.GMap map) { - final controlDiv = document.createElement('button'); - controlDiv.style.backgroundColor = '#fff'; - controlDiv.style.border = 'none'; - controlDiv.style.outline = 'none'; - controlDiv.style.width = '40px'; - controlDiv.style.height = '40px'; - controlDiv.style.borderRadius = '2px'; - controlDiv.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; - controlDiv.style.cursor = 'pointer'; - controlDiv.style.marginRight = '10px'; - controlDiv.style.padding = '0px'; + final controlDiv = document.createElement('div'); + final firstChild = document.createElement('button'); + firstChild.style.backgroundColor = '#fff'; + firstChild.style.border = 'none'; + firstChild.style.outline = 'none'; + firstChild.style.width = '40px'; + firstChild.style.height = '40px'; + firstChild.style.borderRadius = '2px'; + firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; + firstChild.style.cursor = 'pointer'; + firstChild.style.marginRight = '10px'; + controlDiv.append(firstChild); final secondChild = document.createElement('div'); - secondChild.style.margin = '5px'; - secondChild.style.width = '30px'; - secondChild.style.height = '30px'; + secondChild.style.margin = '3px'; + secondChild.style.width = '24px'; + secondChild.style.height = '24px'; secondChild.style.backgroundImage = 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-2x.png)'; - secondChild.style.backgroundSize = '300px 30px'; + secondChild.style.backgroundSize = '240px 24px'; secondChild.style.backgroundPosition = '0px 0px'; secondChild.style.backgroundRepeat = 'no-repeat'; secondChild.id = 'you_location_img'; - controlDiv.append(secondChild); + firstChild.append(secondChild); // ignore: unnecessary_parenthesis - controlDiv.addEventListener("click", ((_) { + firstChild.addEventListener("click", ((_) { String imgX = '0'; final Timer timer = Timer.periodic(const Duration(milliseconds: 500), (_) { - imgX = (imgX == '-30') ? '0' : '-30'; + imgX = (imgX == '-24') ? '0' : '-24'; document.getElementById('you_location_img')?.style.backgroundPosition = '${imgX}px 0px'; }); _moveToCurrentLocation().then((_) { timer.cancel(); - imgX = '-270'; document.getElementById('you_location_img')?.style.backgroundPosition = - '-270px 0px'; + '-192px 0px'; }); })); From 1ae5172d01ed5433be7b5092778a371b90825d52 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 20 Dec 2022 01:13:59 +0700 Subject: [PATCH 09/40] Update my location element --- .../lib/src/google_maps_controller.dart | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index e3473d9026a6..522825422532 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -187,16 +187,6 @@ class GoogleMapController { } } - Future _moveToCurrentLocation() async { - final location = await window.navigator.geolocation.getCurrentPosition(); - await moveCamera( - CameraUpdate.newLatLng(LatLng( - location.coords!.latitude!.toDouble(), - location.coords!.longitude!.toDouble(), - )), - ); - } - // Funnels map gmap events into the plugin's stream controller. void _attachMapEvents(gmaps.GMap map) { map.onTilesloaded.first.then((void _) { @@ -468,8 +458,6 @@ class GoogleMapController { }); _moveToCurrentLocation().then((_) { timer.cancel(); - document.getElementById('you_location_img')?.style.backgroundPosition = - '-192px 0px'; }); })); @@ -482,6 +470,19 @@ class GoogleMapController { ?.push(controlDiv as HtmlElement); } + Future _moveToCurrentLocation() async { + final location = await window.navigator.geolocation.getCurrentPosition(); + await moveCamera( + CameraUpdate.newLatLng(LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + )), + ); + + document.getElementById('you_location_img')?.style.backgroundPosition = + '-192px 0px'; + } + // Cleanup /// Disposes of this controller and its resources. From 9abc5264e732b8c6ee922d33e6544a5bb105683a Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 20 Dec 2022 01:35:23 +0700 Subject: [PATCH 10/40] Add blue dot --- .../lib/src/google_maps_controller.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 522825422532..63ff8cb6eba4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -481,6 +481,24 @@ class GoogleMapController { document.getElementById('you_location_img')?.style.backgroundPosition = '-192px 0px'; + _addBlueDot(location); + } + + void _addBlueDot(Geoposition geolocation) { + print('add blue dot'); + assert( + _markersController != null, 'Cannot update markers after dispose().'); + final Uint8List bytes = base64.decode( + 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAF96VFh0UmF3IHByb2ZpbGUgdHlwZSBBUFAxAABo3uNKT81LLcpMVigoyk/LzEnlUgADYxMuE0sTS6NEAwMDCwMIMDQwMDYEkkZAtjlUKNEABZgamFmaGZsZmgMxiM8FAEi2FMnxHlGkAAADqElEQVRo3t1aTWgTQRQOiuDPQfHs38GDogc1BwVtQxM9xIMexIN4EWw9iAehuQdq0zb+IYhglFovClXQU+uhIuqh3hQll3iwpyjG38Zkt5uffc4XnHaSbpLZ3dnEZOBB2H3z3jeZN+9vx+fzYPgTtCoQpdVHrtA6EH7jme+/HFFawQBu6BnWNwdGjB2BWH5P32jeb0V4B54KL5uDuW3D7Y/S2uCwvrUR4GaEuZABWS0FHhhd2O4UdN3FMJneLoRtN7Y+GMvvUw2eE2RDh3LTOnCd1vQN5XZ5BXwZMV3QqQT84TFa3zuU39sy8P8IOqHb3T8fpY1emoyMSQGDI/Bwc+0ELy6i4nLtepp2mE0jc5L3UAhMsdxut0rPJfRDN2eMY1enF8Inbmj7XbtZhunkI1rZFD/cmFMlr1PFi1/nzSdGkT5RzcAzvAOPU/kVF9s0ujqw+9mP5QgDmCbJAV7McXIeGpqS3Qg7OVs4lTfMD1Yg9QLR518mZbImFcvWC8FcyLAbsev++3YETb0tn2XAvouAvjGwd14YdCahUTCWW6QQIzzDO/CIAzKm3pf77ei23AUkVbICHr8pnDZNynMQJfYPT7wyKBzPVQG3IvCAtyTsCmRBprQpMawWnkc+q2Rbn+TK/+gmRR7qTYHXEuZkdVM0p6SdLLYqX0LItnFgBxe3v0R04b5mGzwnzIUMPiBbFkdVmhGIa5tkJ4reZvyl4Rg8p3tMBh+FEqUduVRUSTKTnieL58UDG76cc70AyMgIBxs6pMyIYV5agKT9f/ltTnJFOIhuwXOCLD6gQ/oc8AJcdtuYb09xRQN3NWULgCwhfqSk3SkaBZViRTK3EYNUSBF4Hic0Y8mM+if0HhlMlaIHbQ8Z5lszxnGuIP2zrAw8J8jkA7pkMAG79AKuPTOOcgWZeVP5AsSDjAxWegGyJoSUWAj/FBpRa0JiviSbfldMqOMPcce7UVeBLK4gkMVVBLI2phLjKlIJm8lcxMNkLuIomXOTTmc1kwYf2E+nMQdzlaTTKgoaZJWyBQ141RY0DkrK6XflAQbih1geZnhJeXu5WeEZ3mVqSkrIgCzXJaXqoh65TUuLerdtFXgQ2bYKeD1pq6hobLE86SlztXMWvaA5vPO0sYWB9p2K1iJS4ra0Fju/udsN7fWu+MDRFZ+YuuIjX1d8Zu2OD92WC9G3ub1qABktBV7vssfBMX1L7yVjZ7PLHuABb9svezS7boNDyK/b4LdX123+Au+jOmNxrkG0AAAAAElFTkSuQmCC'); + _markersController?._addMarker(Marker( + markerId: const MarkerId('my_location_blue_dot'), + icon: BitmapDescriptor.fromBytes(bytes, size: Size(20, 20)), + position: LatLng( + geolocation.coords!.latitude!.toDouble(), + geolocation.coords!.longitude!.toDouble(), + ), + zIndex: 0.5, + )); } // Cleanup From b986d6576b0ed8a20af131b41b7536fe926c4a14 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 20 Dec 2022 23:26:46 +0700 Subject: [PATCH 11/40] Add blue dot icon --- .../icons/blue-dot.png | Bin 0 -> 1116 bytes .../lib/src/google_maps_controller.dart | 25 ++++++++++-------- .../google_maps_flutter_web/pubspec.yaml | 3 ++- 3 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/icons/blue-dot.png diff --git a/packages/google_maps_flutter/google_maps_flutter_web/icons/blue-dot.png b/packages/google_maps_flutter/google_maps_flutter_web/icons/blue-dot.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f31c1f399053c4b11efe649b326c23537211e1 GIT binary patch literal 1116 zcmV-i1f%aB^>EX>4U6ba`-PAVE-2F#rH)-s4J7%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~m>QT_ni-oJngcP2&jkQT zwiLidS*7ObKc6kMS88KbZsRaDtF0AMwZm7)i24;kiLGsbbQ zApNtf3_K^u%osQENhCz9gG| zS4^nm4{^u4QCER1t{{-bRRpp&rV`^SQVE;MT*Sj38J;2I7ZU9%gt+d3(88;Thg#YD!ATfGpP~rRt&{xlK!p zdbe#Aco5mP3V1zftEgyfu{`N1bG368y`VX~^R%&rf%ct>)*@2kwzL*Izq#8D?e(ts zz|j?-n7ZO4Usrr)?T!!KmJ89hxxH!t87&1~@3P0iF?~z#C1Yo^%O2nXZ`&_>G`ntt iL&&e&;I~)TZT Date: Tue, 20 Dec 2022 23:28:05 +0700 Subject: [PATCH 12/40] Format code --- .../lib/src/google_maps_controller.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 54eeed5f76d0..c01e7d899d19 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -489,9 +489,10 @@ class GoogleMapController { assert( _markersController != null, 'Cannot update markers after dispose().'); BitmapDescriptor.fromAssetImage( - const ImageConfiguration(size: Size(24, 24)), 'icons/blue-dot.png', - package: 'google_maps_flutter_web') - .then((BitmapDescriptor icon) { + const ImageConfiguration(size: Size(24, 24)), + 'icons/blue-dot.png', + package: 'google_maps_flutter_web', + ).then((BitmapDescriptor icon) { _markersController?._addMarker(Marker( markerId: const MarkerId('my_location_blue_dot'), icon: icon, From 278b043607ddcdcd22278158c02a6c844ffb83b5 Mon Sep 17 00:00:00 2001 From: nploi Date: Tue, 20 Dec 2022 23:37:02 +0700 Subject: [PATCH 13/40] Update UI --- .../lib/src/google_maps_controller.dart | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index c01e7d899d19..883e09d4e7b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -422,8 +422,13 @@ class GoogleMapController { } void _addMyLocationButton(gmaps.GMap map) { + // ignore: always_specify_types final controlDiv = document.createElement('div'); + controlDiv.style.marginRight = '10px'; + + // ignore: always_specify_types final firstChild = document.createElement('button'); + firstChild.className = 'gm-control-active'; firstChild.style.backgroundColor = '#fff'; firstChild.style.border = 'none'; firstChild.style.outline = 'none'; @@ -432,11 +437,11 @@ class GoogleMapController { firstChild.style.borderRadius = '2px'; firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; firstChild.style.cursor = 'pointer'; - firstChild.style.marginRight = '10px'; + firstChild.style.padding = '8px'; controlDiv.append(firstChild); + // ignore: always_specify_types final secondChild = document.createElement('div'); - secondChild.style.margin = '3px'; secondChild.style.width = '24px'; secondChild.style.height = '24px'; secondChild.style.backgroundImage = @@ -471,7 +476,8 @@ class GoogleMapController { } Future _moveToCurrentLocation() async { - final location = await window.navigator.geolocation.getCurrentPosition(); + final Geoposition location = + await window.navigator.geolocation.getCurrentPosition(); await moveCamera( CameraUpdate.newLatLng(LatLng( location.coords!.latitude!.toDouble(), @@ -484,12 +490,12 @@ class GoogleMapController { _addBlueDot(location); } - void _addBlueDot(Geoposition geolocation) { + void _addBlueDot(Geoposition location) { print('add blue dot'); assert( _markersController != null, 'Cannot update markers after dispose().'); BitmapDescriptor.fromAssetImage( - const ImageConfiguration(size: Size(24, 24)), + const ImageConfiguration(size: Size(18, 18)), 'icons/blue-dot.png', package: 'google_maps_flutter_web', ).then((BitmapDescriptor icon) { @@ -497,8 +503,8 @@ class GoogleMapController { markerId: const MarkerId('my_location_blue_dot'), icon: icon, position: LatLng( - geolocation.coords!.latitude!.toDouble(), - geolocation.coords!.longitude!.toDouble(), + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), ), zIndex: 0.5, )); From a72e0a199a2846b3164cac2dd984ee4881723c10 Mon Sep 17 00:00:00 2001 From: nploi Date: Wed, 21 Dec 2022 00:22:20 +0700 Subject: [PATCH 14/40] Update types --- .../example/lib/main.dart | 2 +- .../lib/src/google_maps_controller.dart | 61 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index 6175f1c10da7..de200b5493fc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -59,7 +59,7 @@ class _Page1State extends State { onMapCreated: (GoogleMapController controller) { _controller.complete(controller); }, - myLocationButtonEnabled: true, + myLocationButtonEnabled: false, myLocationEnabled: true, ), ); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 883e09d4e7b7..376a833029ae 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -163,10 +163,7 @@ class GoogleMapController { // Create the map... final gmaps.GMap map = _createMap(_div, options); - if (_lastMapConfiguration.myLocationButtonEnabled! && - _lastMapConfiguration.myLocationEnabled!) { - _addMyLocationButton(map); - } + _googleMap = map; _attachMapEvents(map); @@ -181,7 +178,10 @@ class GoogleMapController { ); _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); - + if (_lastMapConfiguration.myLocationEnabled! && + _lastMapConfiguration.myLocationButtonEnabled!) { + _addMyLocationButton(map); + } if (_lastMapConfiguration.myLocationEnabled!) { _moveToCurrentLocation(); } @@ -421,13 +421,12 @@ class GoogleMapController { return _markersController?.isInfoWindowShown(markerId) ?? false; } + // Add My Location widget to right bottom void _addMyLocationButton(gmaps.GMap map) { - // ignore: always_specify_types - final controlDiv = document.createElement('div'); + final HtmlElement controlDiv = DivElement(); controlDiv.style.marginRight = '10px'; - // ignore: always_specify_types - final firstChild = document.createElement('button'); + final HtmlElement firstChild = ButtonElement(); firstChild.className = 'gm-control-active'; firstChild.style.backgroundColor = '#fff'; firstChild.style.border = 'none'; @@ -440,8 +439,7 @@ class GoogleMapController { firstChild.style.padding = '8px'; controlDiv.append(firstChild); - // ignore: always_specify_types - final secondChild = document.createElement('div'); + final HtmlElement secondChild = DivElement(); secondChild.style.width = '24px'; secondChild.style.height = '24px'; secondChild.style.backgroundImage = @@ -452,29 +450,32 @@ class GoogleMapController { secondChild.id = 'you_location_img'; firstChild.append(secondChild); - // ignore: unnecessary_parenthesis - firstChild.addEventListener("click", ((_) { + firstChild.addEventListener('click', (_) { String imgX = '0'; + // Add animation when find current location final Timer timer = Timer.periodic(const Duration(milliseconds: 500), (_) { imgX = (imgX == '-24') ? '0' : '-24'; document.getElementById('you_location_img')?.style.backgroundPosition = '${imgX}px 0px'; }); + // Find and move to current location _moveToCurrentLocation().then((_) { timer.cancel(); + document.getElementById('you_location_img')?.style.backgroundPosition = + '-192px 0px'; }); - })); + }); map.addListener('dragend', () { document.getElementById('you_location_img')?.style.backgroundPosition = '0px 0px'; }); - map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(controlDiv as HtmlElement); + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int]?.push(controlDiv); } + // Find and move to current location Future _moveToCurrentLocation() async { final Geoposition location = await window.navigator.geolocation.getCurrentPosition(); @@ -485,30 +486,28 @@ class GoogleMapController { )), ); - document.getElementById('you_location_img')?.style.backgroundPosition = - '-192px 0px'; _addBlueDot(location); } - void _addBlueDot(Geoposition location) { + // Add blue dot for current location + Future _addBlueDot(Geoposition location) async { print('add blue dot'); assert( _markersController != null, 'Cannot update markers after dispose().'); - BitmapDescriptor.fromAssetImage( + final BitmapDescriptor icon = await BitmapDescriptor.fromAssetImage( const ImageConfiguration(size: Size(18, 18)), 'icons/blue-dot.png', package: 'google_maps_flutter_web', - ).then((BitmapDescriptor icon) { - _markersController?._addMarker(Marker( - markerId: const MarkerId('my_location_blue_dot'), - icon: icon, - position: LatLng( - location.coords!.latitude!.toDouble(), - location.coords!.longitude!.toDouble(), - ), - zIndex: 0.5, - )); - }); + ); + _markersController?._addMarker(Marker( + markerId: const MarkerId('my_location_blue_dot'), + icon: icon, + position: LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + ), + zIndex: 0.5, + )); } // Cleanup From 7ad54b50c075561ec6251f1941424ac46ba9ba6c Mon Sep 17 00:00:00 2001 From: nploi Date: Wed, 21 Dec 2022 00:30:03 +0700 Subject: [PATCH 15/40] Revert code --- .../example/lib/main.dart | 87 +++---------------- 1 file changed, 12 insertions(+), 75 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index de200b5493fc..291ca40336ba 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -1,88 +1,25 @@ -import 'dart:async'; -import 'dart:math'; +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'package:flutter/material.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; void main() { runApp(const MyApp()); } -class MyApp extends StatelessWidget { - const MyApp({key}); +/// App for testing +class MyApp extends StatefulWidget { + /// Constructor with key + const MyApp({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Welcome to Flutter', - home: Scaffold( - body: Page1(), - ), - ); - } + State createState() => _MyAppState(); } -class Page1 extends StatefulWidget { - @override - _Page1State createState() => _Page1State(); -} - -class _Page1State extends State { - @override - void initState() { - super.initState(); - } - - LatLng _kMapCenter1 = LatLng(19.0182, 72.8479); - LatLng _kMapCenter2 = LatLng(19.0183, 72.8480); - bool toggle = false; - - Completer _controller = Completer(); - - static final CameraPosition _kGooglePlex = CameraPosition( - target: LatLng(37.42796133580664, -122.085749655962), - zoom: 14.4746, - ); - - static final CameraPosition _kLake = CameraPosition( - bearing: 192.8334901395799, - target: LatLng(19.01825595, 72.84793854), - tilt: 59.440717697143555, - zoom: 19.151926040649414); - +class _MyAppState extends State { @override Widget build(BuildContext context) { - return Scaffold( - body: GoogleMap( - markers: Set.of(_createMarker()), - mapType: MapType.hybrid, - initialCameraPosition: _kGooglePlex, - onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); - }, - myLocationButtonEnabled: false, - myLocationEnabled: true, - ), - ); + return const Text('Testing... Look at the console output for results!'); } - - //ทำ marker - Set _createMarker() { - print(5555); - return { - Marker( - markerId: MarkerId("marker_1"), - position: _kMapCenter1, - infoWindow: InfoWindow(title: 'Marker 1'), - rotation: 90), - Marker( - markerId: MarkerId("marker_2"), - position: _kMapCenter2, - ), - }; - } - - Future _goToTheLake() async { - final GoogleMapController controller = await _controller.future; - controller.animateCamera(CameraUpdate.newCameraPosition(_kLake)); - } -} +} \ No newline at end of file From e0c6c3df5ecd7866ecbe6007e2fc7f531cc39244 Mon Sep 17 00:00:00 2001 From: nploi Date: Wed, 21 Dec 2022 00:30:54 +0700 Subject: [PATCH 16/40] Revert code --- .../google_maps_flutter_web/example/lib/main.dart | 2 +- .../google_maps_flutter_web/example/web/index.html | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index 291ca40336ba..e93a60e19906 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -22,4 +22,4 @@ class _MyAppState extends State { Widget build(BuildContext context) { return const Text('Testing... Look at the console output for results!'); } -} \ No newline at end of file +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index d1d27adb4a57..3a1b16b3a4a0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,8 +6,7 @@ Browser Tests - - + From ea4cdef7beb14e706f5c10e3bc6643fa2622181d Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 02:16:08 +0700 Subject: [PATCH 17/40] Add integration test --- .../google_maps_controller_test.dart | 19 ++++++ .../google_maps_plugin_test.mocks.dart | 2 + .../example/web/index.html | 3 +- .../lib/src/google_maps_controller.dart | 67 ++++++++++++++----- 4 files changed, 72 insertions(+), 19 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 0226234ea97a..f72725faf34e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -485,6 +485,25 @@ void main() { expect(controller.trafficLayer, isNotNull); }); }); + + group('My Location button', () { + testWidgets('by default is disabled', (WidgetTester tester) async { + controller = createController(); + controller.init(); + expect(controller.myLocationButton, isNull); + }); + + testWidgets('initializes with my location button', + (WidgetTester tester) async { + controller = createController( + mapConfiguration: const MapConfiguration( + myLocationEnabled: true, + )); + controller.debugSetOverrides(createMap: (_, __) => map); + controller.init(); + expect(controller.myLocationButton, isNotNull); + }); + }); }); // These are the methods that are delegated to the gmaps.GMap object, that we can mock... diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart index a85bce31e20f..17b6946a4254 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart @@ -101,6 +101,7 @@ class MockGoogleMapController extends _i1.Mock _i4.CirclesController? circles, _i4.PolygonsController? polygons, _i4.PolylinesController? polylines, + _i4.DebugGetCurrentLocation? getCurrentLocation, }) => super.noSuchMethod( Invocation.method( @@ -112,6 +113,7 @@ class MockGoogleMapController extends _i1.Mock #circles: circles, #polygons: polygons, #polylines: polylines, + #getCurrentLocation: getCurrentLocation, }, ), returnValueForMissingStub: null, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index 3a1b16b3a4a0..d1d27adb4a57 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,7 +6,8 @@ Browser Tests - + + diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 376a833029ae..384986735313 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -9,6 +9,10 @@ part of google_maps_flutter_web; typedef DebugCreateMapFunction = gmaps.GMap Function( HtmlElement div, gmaps.MapOptions options); +/// Type used when passing an override to the _getCurrentLocation function. +@visibleForTesting +typedef DebugGetCurrentLocation = Future Function(); + /// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered. class GoogleMapController { /// Initializes the GMap, and the sub-controllers related to it. Wires events. @@ -64,6 +68,7 @@ class GoogleMapController { // The Flutter widget that contains the rendered Map. HtmlElementView? _widget; late HtmlElement _div; + late HtmlElement _myLocationButton; /// The Flutter widget that will contain the rendered Map. Used for caching. Widget? get widget { @@ -75,6 +80,10 @@ class GoogleMapController { return _widget; } + /// A getter for the my location button + @visibleForTesting + HtmlElement? get myLocationButton => _myLocationButton; + // The currently-enabled traffic layer. gmaps.TrafficLayer? _trafficLayer; @@ -114,14 +123,19 @@ class GoogleMapController { CirclesController? circles, PolygonsController? polygons, PolylinesController? polylines, + DebugGetCurrentLocation? getCurrentLocation, }) { _overrideCreateMap = createMap; _markersController = markers ?? _markersController; _circlesController = circles ?? _circlesController; _polygonsController = polygons ?? _polygonsController; _polylinesController = polylines ?? _polylinesController; + _overrideGetCurrentLocation = getCurrentLocation; } + // Get current location + DebugGetCurrentLocation? _overrideGetCurrentLocation; + DebugCreateMapFunction? _overrideCreateMap; gmaps.GMap _createMap(HtmlElement div, gmaps.MapOptions options) { @@ -178,6 +192,7 @@ class GoogleMapController { ); _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); + if (_lastMapConfiguration.myLocationEnabled! && _lastMapConfiguration.myLocationButtonEnabled!) { _addMyLocationButton(map); @@ -422,7 +437,7 @@ class GoogleMapController { } // Add My Location widget to right bottom - void _addMyLocationButton(gmaps.GMap map) { + HtmlElement _createMyLocationButton() { final HtmlElement controlDiv = DivElement(); controlDiv.style.marginRight = '10px'; @@ -467,31 +482,50 @@ class GoogleMapController { }); }); - map.addListener('dragend', () { - document.getElementById('you_location_img')?.style.backgroundPosition = - '0px 0px'; - }); + return controlDiv; + } - map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int]?.push(controlDiv); + // Get current location + Future _getCurrentLocation() async { + final Geoposition location = + await window.navigator.geolocation.getCurrentPosition(); + return LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + ); } // Find and move to current location Future _moveToCurrentLocation() async { - final Geoposition location = - await window.navigator.geolocation.getCurrentPosition(); + LatLng location; + if (_overrideGetCurrentLocation != null) { + location = await _overrideGetCurrentLocation!.call(); + } else { + location = await _getCurrentLocation(); + } + await moveCamera( - CameraUpdate.newLatLng(LatLng( - location.coords!.latitude!.toDouble(), - location.coords!.longitude!.toDouble(), - )), + CameraUpdate.newLatLng(location), ); _addBlueDot(location); } + // Add my location to map + void _addMyLocationButton(gmaps.GMap map) { + _myLocationButton = _createMyLocationButton(); + + map.addListener('dragend', () { + document.getElementById('you_location_img')?.style.backgroundPosition = + '0px 0px'; + }); + + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] + ?.push(_myLocationButton); + } + // Add blue dot for current location - Future _addBlueDot(Geoposition location) async { - print('add blue dot'); + Future _addBlueDot(LatLng location) async { assert( _markersController != null, 'Cannot update markers after dispose().'); final BitmapDescriptor icon = await BitmapDescriptor.fromAssetImage( @@ -502,10 +536,7 @@ class GoogleMapController { _markersController?._addMarker(Marker( markerId: const MarkerId('my_location_blue_dot'), icon: icon, - position: LatLng( - location.coords!.latitude!.toDouble(), - location.coords!.longitude!.toDouble(), - ), + position: location, zIndex: 0.5, )); } From 1cdce7a452e20c723272592ea070ef476fdd7889 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 02:17:24 +0700 Subject: [PATCH 18/40] Revert code --- .../google_maps_flutter_web/example/web/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index d1d27adb4a57..cac2f0579833 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,7 +6,7 @@ Browser Tests - + From 58c74ecb3120a8983273b02fee61b020f1f6ac70 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 15:27:36 +0700 Subject: [PATCH 19/40] Fix test fail --- .../example/integration_test/google_maps_plugin_test.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index 9bd1a68c6207..c6d57fc4786d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -86,6 +86,10 @@ void main() { initialCameraPosition: initialCameraPosition, textDirection: TextDirection.ltr, ), + mapConfiguration: const MapConfiguration( + myLocationButtonEnabled: false, + myLocationEnabled: false, + ), ); expect(widget, isA()); From 7bd8aa4e93d1f6115eeef361338595207d215219 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 15:29:36 +0700 Subject: [PATCH 20/40] Fix test fail --- .../example/integration_test/google_maps_plugin_test.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index c6d57fc4786d..ea76a8543349 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -128,6 +128,10 @@ void main() { initialCameraPosition: initialCameraPosition, textDirection: TextDirection.ltr, ), + mapConfiguration: const MapConfiguration( + myLocationButtonEnabled: false, + myLocationEnabled: false, + ), ); expect(widget, equals(expected)); @@ -147,6 +151,10 @@ void main() { initialCameraPosition: initialCameraPosition, textDirection: TextDirection.ltr, ), + mapConfiguration: const MapConfiguration( + myLocationButtonEnabled: false, + myLocationEnabled: false, + ), ); // Simulate Google Maps JS SDK being "ready" From 1b62e8c4fd4198cfce78cefd3910258407264de0 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 16:46:23 +0700 Subject: [PATCH 21/40] Add more test & fix test fail --- .../google_maps_controller_test.dart | 55 ++++++++++++++++++- .../google_maps_plugin_test.dart | 12 ---- .../lib/src/google_maps_controller.dart | 26 +++++---- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index f72725faf34e..40a366a78701 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -486,22 +486,71 @@ void main() { }); }); - group('My Location button', () { + group('My Location', () { testWidgets('by default is disabled', (WidgetTester tester) async { controller = createController(); controller.init(); expect(controller.myLocationButton, isNull); }); - testWidgets('initializes with my location button', + testWidgets('initializes with my location with my location button', (WidgetTester tester) async { + const LatLng currentLocation = LatLng(10.8231, 106.6297); controller = createController( mapConfiguration: const MapConfiguration( myLocationEnabled: true, + myLocationButtonEnabled: true, )); - controller.debugSetOverrides(createMap: (_, __) => map); + controller.debugSetOverrides( + createMap: (_, __) => map, + markers: markers, + getCurrentLocation: () => Future.value(currentLocation), + ); controller.init(); + + await Future.delayed(const Duration(milliseconds: 50)); + + final Set capturedMarkers = + verify(markers.addMarkers(captureAny)).captured[1] as Set; + + 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 without my location button', + (WidgetTester tester) async { + const LatLng currentLocation = LatLng(10.8231, 106.6297); + controller = createController( + mapConfiguration: const MapConfiguration( + myLocationEnabled: true, + myLocationButtonEnabled: false, + )); + controller.debugSetOverrides( + createMap: (_, __) => map, + markers: markers, + getCurrentLocation: () => Future.value(currentLocation), + ); + controller.init(); + + await Future.delayed(const Duration(milliseconds: 50)); + + final Set capturedMarkers = + verify(markers.addMarkers(captureAny)).captured[1] as Set; + + 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); }); }); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index ea76a8543349..9bd1a68c6207 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -86,10 +86,6 @@ void main() { initialCameraPosition: initialCameraPosition, textDirection: TextDirection.ltr, ), - mapConfiguration: const MapConfiguration( - myLocationButtonEnabled: false, - myLocationEnabled: false, - ), ); expect(widget, isA()); @@ -128,10 +124,6 @@ void main() { initialCameraPosition: initialCameraPosition, textDirection: TextDirection.ltr, ), - mapConfiguration: const MapConfiguration( - myLocationButtonEnabled: false, - myLocationEnabled: false, - ), ); expect(widget, equals(expected)); @@ -151,10 +143,6 @@ void main() { initialCameraPosition: initialCameraPosition, textDirection: TextDirection.ltr, ), - mapConfiguration: const MapConfiguration( - myLocationButtonEnabled: false, - myLocationEnabled: false, - ), ); // Simulate Google Maps JS SDK being "ready" diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 384986735313..5ca546454696 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -68,7 +68,7 @@ class GoogleMapController { // The Flutter widget that contains the rendered Map. HtmlElementView? _widget; late HtmlElement _div; - late HtmlElement _myLocationButton; + HtmlElement? _myLocationButton; /// The Flutter widget that will contain the rendered Map. Used for caching. Widget? get widget { @@ -193,11 +193,11 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); - if (_lastMapConfiguration.myLocationEnabled! && - _lastMapConfiguration.myLocationButtonEnabled!) { + if ((_lastMapConfiguration.myLocationEnabled ?? false) && + (_lastMapConfiguration.myLocationButtonEnabled ?? false)) { _addMyLocationButton(map); } - if (_lastMapConfiguration.myLocationEnabled!) { + if (_lastMapConfiguration.myLocationEnabled ?? false) { _moveToCurrentLocation(); } } @@ -508,7 +508,7 @@ class GoogleMapController { CameraUpdate.newLatLng(location), ); - _addBlueDot(location); + _addBlueDotMarker(location); } // Add my location to map @@ -525,7 +525,7 @@ class GoogleMapController { } // Add blue dot for current location - Future _addBlueDot(LatLng location) async { + Future _addBlueDotMarker(LatLng location) async { assert( _markersController != null, 'Cannot update markers after dispose().'); final BitmapDescriptor icon = await BitmapDescriptor.fromAssetImage( @@ -533,12 +533,14 @@ class GoogleMapController { 'icons/blue-dot.png', package: 'google_maps_flutter_web', ); - _markersController?._addMarker(Marker( - markerId: const MarkerId('my_location_blue_dot'), - icon: icon, - position: location, - zIndex: 0.5, - )); + _markersController?.addMarkers({ + Marker( + markerId: const MarkerId('my_location_blue_dot'), + icon: icon, + position: location, + zIndex: 0.5, + ) + }); } // Cleanup From 4d6ba5408bb4ba244a876aca088e4bde1d1d817f Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 16:49:07 +0700 Subject: [PATCH 22/40] Revert code --- .../google_maps_flutter_web/example/web/index.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index cac2f0579833..3a1b16b3a4a0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,8 +6,7 @@ Browser Tests - - + From 9d40e2e0298d08e770c9febe2a05e50722d670bb Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 16:52:15 +0700 Subject: [PATCH 23/40] Fix spelling --- .../google_maps_flutter_web/lib/src/convert.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 2b09950cc00d..e0d9a0396aae 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -41,7 +41,7 @@ double _getCssOpacity(Color color) { // myLocationEnabled needs to be built through dart:html navigator.geolocation // See: https://api.dart.dev/stable/2.8.4/dart-html/Geolocation-class.html // trafficEnabled is handled when creating the GMap object, since it needs to be added as a layer. -// trackCameraPosition is just a boolan value that indicates if the map has an onCameraMove handler. +// trackCameraPosition is just a boolean value that indicates if the map has an onCameraMove handler. // indoorViewEnabled seems to not have an equivalent in web // buildingsEnabled seems to not have an equivalent in web // padding seems to behave differently in web than mobile. You can't move UI elements in web. From f3a8fc9dbf41134a295052567c2484dde6a484d0 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 16:55:48 +0700 Subject: [PATCH 24/40] Updated version & changelog --- .../google_maps_flutter/google_maps_flutter_web/CHANGELOG.md | 4 ++++ .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 2333f7d16028..86f9b34e0f3c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -2,6 +2,10 @@ * Updates code for `no_leading_underscores_for_local_identifiers` lint. +## 0.4.0+4 + +* Add "My Location" Widget. Issue [#64073](https://github.com/flutter/flutter/issues/64073) + ## 0.4.0+3 * Updates imports for `prefer_relative_imports`. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 43f35e335e1c..6a97431839a2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.4.0+3 +version: 0.4.0+4 environment: sdk: ">=2.12.0 <3.0.0" From 77414ec09d89fd9949f8b4f113a21d2f0b073d87 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 18:00:22 +0700 Subject: [PATCH 25/40] Updated version & changelog --- .../google_maps_flutter/google_maps_flutter_web/CHANGELOG.md | 5 +---- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 86f9b34e0f3c..cb8bd585a4e1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,10 +1,7 @@ ## NEXT -* Updates code for `no_leading_underscores_for_local_identifiers` lint. - -## 0.4.0+4 - * Add "My Location" Widget. Issue [#64073](https://github.com/flutter/flutter/issues/64073) +* Updates code for `no_leading_underscores_for_local_identifiers` lint. ## 0.4.0+3 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 6a97431839a2..43f35e335e1c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.4.0+4 +version: 0.4.0+3 environment: sdk: ">=2.12.0 <3.0.0" From 6668606824b91860aa84dcf4edc412ffe602bc8a Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 25 Dec 2022 18:06:49 +0700 Subject: [PATCH 26/40] Updated version & changelog --- .../google_maps_flutter/google_maps_flutter_web/CHANGELOG.md | 2 +- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index cb8bd585a4e1..9a0134219be5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,4 +1,4 @@ -## NEXT +## 0.4.0+4 * Add "My Location" Widget. Issue [#64073](https://github.com/flutter/flutter/issues/64073) * Updates code for `no_leading_underscores_for_local_identifiers` lint. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 43f35e335e1c..6a97431839a2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.4.0+3 +version: 0.4.0+4 environment: sdk: ">=2.12.0 <3.0.0" From 1b4b0bbeba6253275acbde4d432b192e9a1fd900 Mon Sep 17 00:00:00 2001 From: nploi Date: Thu, 29 Dec 2022 01:57:01 +0700 Subject: [PATCH 27/40] Move code to separate file, update logic, add mylocation-sprite-2x to assets folder --- .../example/lib/main.dart | 85 ++++++++++-- .../example/web/index.html | 3 +- .../icons/mylocation-sprite-2x.png | Bin 0 -> 1582 bytes .../lib/google_maps_flutter_web.dart | 1 + .../lib/src/google_maps_controller.dart | 121 +----------------- .../lib/src/my_location.dart | 118 +++++++++++++++++ 6 files changed, 199 insertions(+), 129 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/icons/mylocation-sprite-2x.png create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index e93a60e19906..6175f1c10da7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -1,25 +1,88 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - +import 'dart:async'; +import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; void main() { runApp(const MyApp()); } -/// App for testing -class MyApp extends StatefulWidget { - /// Constructor with key - const MyApp({Key? key}) : super(key: key); +class MyApp extends StatelessWidget { + const MyApp({key}); @override - State createState() => _MyAppState(); + Widget build(BuildContext context) { + return MaterialApp( + title: 'Welcome to Flutter', + home: Scaffold( + body: Page1(), + ), + ); + } } -class _MyAppState extends State { +class Page1 extends StatefulWidget { + @override + _Page1State createState() => _Page1State(); +} + +class _Page1State extends State { + @override + void initState() { + super.initState(); + } + + LatLng _kMapCenter1 = LatLng(19.0182, 72.8479); + LatLng _kMapCenter2 = LatLng(19.0183, 72.8480); + bool toggle = false; + + Completer _controller = Completer(); + + static final CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + + static final CameraPosition _kLake = CameraPosition( + bearing: 192.8334901395799, + target: LatLng(19.01825595, 72.84793854), + tilt: 59.440717697143555, + zoom: 19.151926040649414); + @override Widget build(BuildContext context) { - return const Text('Testing... Look at the console output for results!'); + return Scaffold( + body: GoogleMap( + markers: Set.of(_createMarker()), + mapType: MapType.hybrid, + initialCameraPosition: _kGooglePlex, + onMapCreated: (GoogleMapController controller) { + _controller.complete(controller); + }, + myLocationButtonEnabled: true, + myLocationEnabled: true, + ), + ); + } + + //ทำ marker + Set _createMarker() { + print(5555); + return { + Marker( + markerId: MarkerId("marker_1"), + position: _kMapCenter1, + infoWindow: InfoWindow(title: 'Marker 1'), + rotation: 90), + Marker( + markerId: MarkerId("marker_2"), + position: _kMapCenter2, + ), + }; + } + + Future _goToTheLake() async { + final GoogleMapController controller = await _controller.future; + controller.animateCamera(CameraUpdate.newCameraPosition(_kLake)); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index 3a1b16b3a4a0..d1d27adb4a57 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,7 +6,8 @@ Browser Tests - + + diff --git a/packages/google_maps_flutter/google_maps_flutter_web/icons/mylocation-sprite-2x.png b/packages/google_maps_flutter/google_maps_flutter_web/icons/mylocation-sprite-2x.png new file mode 100644 index 0000000000000000000000000000000000000000..546b97a245d9bd4964a726de96352c8b0619fbb8 GIT binary patch literal 1582 zcmaKteNYou5WqwEQZfV!PJ%Jw*by>{$S4JjIZ9P5Mko=jLPq?eAoYtct6U&s6iPFw z0VGOvj7NuR1*Jig5m1tffQhG=AXO8$q*Y8M&fj6=Y54hewHN&`(t1_B1lP5R(i8dx|%`4MPOMUr(@7s;q8Dv zTOCtn6-PF&Fer6F?lL#G`rSr1M*4y{in)GjIs8R(ZOK!BP6ucaKm!M7t87C^gv)w8 zM{VsNy-9i3bfY6zsoS=oFUNfMe|CJbm+?y4{)b3?)`E8u?roq@NRR)-hD)bb8JlEd z)F-T@4&EGCn~_d$HMV5@$F-#m&yC4-#N=~Jdym2Kf64tyI)c%-lr|L@K^M46zQq zge5Iyqm+e38LS8_WJ}b613@x@^k~m;Q34)?6#)o9C0eZZMLDd?t|Qil(vM`A;DYA9 zCa`_GV+%QdV-*jjr(Qoc1`pb@0`?r8zWPfWgX^qR#$33oeKDGITG*Gej&RCp(j_W? zq}PGyLw`eNo@@bidmYp*1Jtbm)Gc+74vl)C5M2A2Po=-H?`5@#%-<5$`So=xcOy!? zPm)L^k}vy^`T%4Y|L#Vi*0m_B$G(bz+;9CgU~l}Uj}Ai`()i+l?1qW74R!lc*Fay+ z{BtLa>%O`;sV5s83`gMl$Ac#Cdsc=WxBggaywY2|h!=SM%>IzJxUzJpj#l1}z-o~^;2ZOYPyLdHQBA(K4y#zlPIUu{t#I0G}$%4MgIIpG~~I1ro0% zR`MuTgu?mi>hV%&%`T6rC8(eJ@&gf=}JNN5_Z;SNmlkGFzR<&)P-wA@Tf` zXquml@bF$S$MgU?es;epD?JTF^cX}$;(>@LAfnGFYU~kjk8vz76Cbnj)Q*@(w@3YJ zMUj9rw^%x)5+NG)-rwq8w9iR8h=zeunN#FlA- Function(); - /// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered. class GoogleMapController { /// Initializes the GMap, and the sub-controllers related to it. Wires events. @@ -68,7 +64,6 @@ class GoogleMapController { // The Flutter widget that contains the rendered Map. HtmlElementView? _widget; late HtmlElement _div; - HtmlElement? _myLocationButton; /// The Flutter widget that will contain the rendered Map. Used for caching. Widget? get widget { @@ -193,12 +188,11 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); - if ((_lastMapConfiguration.myLocationEnabled ?? false) && - (_lastMapConfiguration.myLocationButtonEnabled ?? false)) { - _addMyLocationButton(map); - } if (_lastMapConfiguration.myLocationEnabled ?? false) { - _moveToCurrentLocation(); + if (_lastMapConfiguration.myLocationButtonEnabled ?? false) { + _addMyLocationButton(map, this); + } + _displayAndCenterMyCurrentLocation(this); } } @@ -436,113 +430,6 @@ class GoogleMapController { return _markersController?.isInfoWindowShown(markerId) ?? false; } - // Add My Location widget to right bottom - HtmlElement _createMyLocationButton() { - final HtmlElement controlDiv = DivElement(); - controlDiv.style.marginRight = '10px'; - - final HtmlElement firstChild = ButtonElement(); - firstChild.className = 'gm-control-active'; - firstChild.style.backgroundColor = '#fff'; - firstChild.style.border = 'none'; - firstChild.style.outline = 'none'; - firstChild.style.width = '40px'; - firstChild.style.height = '40px'; - firstChild.style.borderRadius = '2px'; - firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; - firstChild.style.cursor = 'pointer'; - firstChild.style.padding = '8px'; - controlDiv.append(firstChild); - - final HtmlElement secondChild = DivElement(); - secondChild.style.width = '24px'; - secondChild.style.height = '24px'; - secondChild.style.backgroundImage = - 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-2x.png)'; - secondChild.style.backgroundSize = '240px 24px'; - secondChild.style.backgroundPosition = '0px 0px'; - secondChild.style.backgroundRepeat = 'no-repeat'; - secondChild.id = 'you_location_img'; - firstChild.append(secondChild); - - firstChild.addEventListener('click', (_) { - String imgX = '0'; - // Add animation when find current location - final Timer timer = - Timer.periodic(const Duration(milliseconds: 500), (_) { - imgX = (imgX == '-24') ? '0' : '-24'; - document.getElementById('you_location_img')?.style.backgroundPosition = - '${imgX}px 0px'; - }); - // Find and move to current location - _moveToCurrentLocation().then((_) { - timer.cancel(); - document.getElementById('you_location_img')?.style.backgroundPosition = - '-192px 0px'; - }); - }); - - return controlDiv; - } - - // Get current location - Future _getCurrentLocation() async { - final Geoposition location = - await window.navigator.geolocation.getCurrentPosition(); - return LatLng( - location.coords!.latitude!.toDouble(), - location.coords!.longitude!.toDouble(), - ); - } - - // Find and move to current location - Future _moveToCurrentLocation() async { - LatLng location; - if (_overrideGetCurrentLocation != null) { - location = await _overrideGetCurrentLocation!.call(); - } else { - location = await _getCurrentLocation(); - } - - await moveCamera( - CameraUpdate.newLatLng(location), - ); - - _addBlueDotMarker(location); - } - - // Add my location to map - void _addMyLocationButton(gmaps.GMap map) { - _myLocationButton = _createMyLocationButton(); - - map.addListener('dragend', () { - document.getElementById('you_location_img')?.style.backgroundPosition = - '0px 0px'; - }); - - map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(_myLocationButton); - } - - // Add blue dot for current location - Future _addBlueDotMarker(LatLng location) async { - assert( - _markersController != null, 'Cannot update markers after dispose().'); - final BitmapDescriptor icon = await BitmapDescriptor.fromAssetImage( - const ImageConfiguration(size: Size(18, 18)), - 'icons/blue-dot.png', - package: 'google_maps_flutter_web', - ); - _markersController?.addMarkers({ - Marker( - markerId: const MarkerId('my_location_blue_dot'), - icon: icon, - position: location, - zIndex: 0.5, - ) - }); - } - // Cleanup /// Disposes of this controller and its resources. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart new file mode 100644 index 000000000000..0dd4561c4d1c --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart @@ -0,0 +1,118 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of google_maps_flutter_web; + +/// Type used when passing an override to the _getCurrentLocation function. +@visibleForTesting +typedef DebugGetCurrentLocation = Future Function(); +HtmlElement? _myLocationButton; + +// Get current location +Future _getCurrentLocation() async { + final Geoposition location = + await window.navigator.geolocation.getCurrentPosition(); + return LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + ); +} + +// Find and move to current location +Future _displayAndCenterMyCurrentLocation( + GoogleMapController controller, +) async { + LatLng location; + if (controller._overrideGetCurrentLocation != null) { + location = await controller._overrideGetCurrentLocation!.call(); + } else { + location = await _getCurrentLocation(); + } + _addBlueDotMarker(controller._markersController, location); + + await controller.moveCamera( + CameraUpdate.newLatLng(location), + ); +} + +// Add my location to map +void _addMyLocationButton(gmaps.GMap map, GoogleMapController controller) { + _myLocationButton = _createMyLocationButton(controller); + + map.addListener('dragend', () { + document.getElementById('you_location_img')?.style.backgroundPosition = + '0px 0px'; + }); + + map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] + ?.push(_myLocationButton); +} + +// Add blue dot for current location +Future _addBlueDotMarker( + MarkersController? markersController, LatLng location) async { + assert(markersController != null, 'Cannot update markers after dispose().'); + + final BitmapDescriptor icon = await BitmapDescriptor.fromAssetImage( + const ImageConfiguration(size: Size(18, 18)), + 'icons/blue-dot.png', + package: 'google_maps_flutter_web', + ); + markersController?.addMarkers({ + Marker( + markerId: const MarkerId('my_location_blue_dot'), + icon: icon, + position: location, + zIndex: 0.5, + ) + }); +} + +// Add My Location widget to right bottom +HtmlElement _createMyLocationButton(GoogleMapController controller) { + final HtmlElement controlDiv = DivElement(); + controlDiv.style.marginRight = '10px'; + + final HtmlElement firstChild = ButtonElement(); + firstChild.className = 'gm-control-active'; + firstChild.style.backgroundColor = '#fff'; + firstChild.style.border = 'none'; + firstChild.style.outline = 'none'; + firstChild.style.width = '40px'; + firstChild.style.height = '40px'; + firstChild.style.borderRadius = '2px'; + firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; + firstChild.style.cursor = 'pointer'; + firstChild.style.padding = '8px'; + controlDiv.append(firstChild); + + final HtmlElement secondChild = DivElement(); + secondChild.style.width = '24px'; + secondChild.style.height = '24px'; + secondChild.style.backgroundImage = + 'url(${window.location.href.replaceAll('/#', '')}/assets/packages/google_maps_flutter_web/icons/mylocation-sprite-2x.png)'; + secondChild.style.backgroundSize = '240px 24px'; + secondChild.style.backgroundPosition = '0px 0px'; + secondChild.style.backgroundRepeat = 'no-repeat'; + secondChild.id = 'you_location_img'; + firstChild.append(secondChild); + + firstChild.addEventListener('click', (_) { + String imgX = '0'; + // Add animation when find current location + final Timer timer = Timer.periodic(const Duration(milliseconds: 500), (_) { + imgX = (imgX == '-24') ? '0' : '-24'; + document.getElementById('you_location_img')?.style.backgroundPosition = + '${imgX}px 0px'; + }); + // Find and move to current location + _displayAndCenterMyCurrentLocation(controller).then((_) { + timer.cancel(); + document.getElementById('you_location_img')?.style.backgroundPosition = + '-192px 0px'; + }); + }); + + return controlDiv; +} From 241f69d9839384981f2051c61574095a1d279494 Mon Sep 17 00:00:00 2001 From: nploi Date: Sat, 31 Dec 2022 18:49:23 +0700 Subject: [PATCH 28/40] Update logic watch position and check permission --- .../google_maps_flutter_web/CHANGELOG.md | 2 +- .../example/lib/main.dart | 85 +------ .../lib/src/google_maps_controller.dart | 15 +- .../lib/src/my_location.dart | 217 ++++++++++++------ .../google_maps_flutter_web/pubspec.yaml | 2 +- 5 files changed, 165 insertions(+), 156 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 9a0134219be5..963738d44b37 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.4.0+4 +## 0.4.1 * Add "My Location" Widget. Issue [#64073](https://github.com/flutter/flutter/issues/64073) * Updates code for `no_leading_underscores_for_local_identifiers` lint. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index 6175f1c10da7..e93a60e19906 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -1,88 +1,25 @@ -import 'dart:async'; -import 'dart:math'; +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'package:flutter/material.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; void main() { runApp(const MyApp()); } -class MyApp extends StatelessWidget { - const MyApp({key}); +/// App for testing +class MyApp extends StatefulWidget { + /// Constructor with key + const MyApp({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Welcome to Flutter', - home: Scaffold( - body: Page1(), - ), - ); - } + State createState() => _MyAppState(); } -class Page1 extends StatefulWidget { - @override - _Page1State createState() => _Page1State(); -} - -class _Page1State extends State { - @override - void initState() { - super.initState(); - } - - LatLng _kMapCenter1 = LatLng(19.0182, 72.8479); - LatLng _kMapCenter2 = LatLng(19.0183, 72.8480); - bool toggle = false; - - Completer _controller = Completer(); - - static final CameraPosition _kGooglePlex = CameraPosition( - target: LatLng(37.42796133580664, -122.085749655962), - zoom: 14.4746, - ); - - static final CameraPosition _kLake = CameraPosition( - bearing: 192.8334901395799, - target: LatLng(19.01825595, 72.84793854), - tilt: 59.440717697143555, - zoom: 19.151926040649414); - +class _MyAppState extends State { @override Widget build(BuildContext context) { - return Scaffold( - body: GoogleMap( - markers: Set.of(_createMarker()), - mapType: MapType.hybrid, - initialCameraPosition: _kGooglePlex, - onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); - }, - myLocationButtonEnabled: true, - myLocationEnabled: true, - ), - ); - } - - //ทำ marker - Set _createMarker() { - print(5555); - return { - Marker( - markerId: MarkerId("marker_1"), - position: _kMapCenter1, - infoWindow: InfoWindow(title: 'Marker 1'), - rotation: 90), - Marker( - markerId: MarkerId("marker_2"), - position: _kMapCenter2, - ), - }; - } - - Future _goToTheLake() async { - final GoogleMapController controller = await _controller.future; - controller.animateCamera(CameraUpdate.newCameraPosition(_kLake)); + return const Text('Testing... Look at the console output for results!'); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index a15455971e71..af22c3752c2f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -77,7 +77,7 @@ class GoogleMapController { /// A getter for the my location button @visibleForTesting - HtmlElement? get myLocationButton => _myLocationButton; + _MyLocationButton? get myLocationButton => _myLocationButton; // The currently-enabled traffic layer. gmaps.TrafficLayer? _trafficLayer; @@ -128,9 +128,6 @@ class GoogleMapController { _overrideGetCurrentLocation = getCurrentLocation; } - // Get current location - DebugGetCurrentLocation? _overrideGetCurrentLocation; - DebugCreateMapFunction? _overrideCreateMap; gmaps.GMap _createMap(HtmlElement div, gmaps.MapOptions options) { @@ -188,11 +185,17 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); + _renderMyLocation(map); + } + + // Render my location + Future _renderMyLocation(gmaps.GMap map) async { if (_lastMapConfiguration.myLocationEnabled ?? false) { if (_lastMapConfiguration.myLocationButtonEnabled ?? false) { - _addMyLocationButton(map, this); + _renderMyLocationButton(map, this); } - _displayAndCenterMyCurrentLocation(this); + _watchLocationAndUpdateBlueDot(this); + _centerMyCurrentLocation(this); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart index 0dd4561c4d1c..6ad7f85d737e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart @@ -7,7 +7,24 @@ part of google_maps_flutter_web; /// Type used when passing an override to the _getCurrentLocation function. @visibleForTesting typedef DebugGetCurrentLocation = Future Function(); -HtmlElement? _myLocationButton; + +DebugGetCurrentLocation? _overrideGetCurrentLocation; + +// Get current location +_MyLocationButton? _myLocationButton; + +// Watch current location and update blue dot +void _watchLocationAndUpdateBlueDot(GoogleMapController controller) { + window.navigator.geolocation + .watchPosition() + .listen((Geoposition location) async { + final Marker blueDot = await _createBlueDotMarker(LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + )); + controller._markersController?.addMarkers({blueDot}); + }); +} // Get current location Future _getCurrentLocation() async { @@ -20,99 +37,151 @@ Future _getCurrentLocation() async { } // Find and move to current location -Future _displayAndCenterMyCurrentLocation( +Future _centerMyCurrentLocation( GoogleMapController controller, ) async { - LatLng location; - if (controller._overrideGetCurrentLocation != null) { - location = await controller._overrideGetCurrentLocation!.call(); - } else { - location = await _getCurrentLocation(); + try { + LatLng location; + if (_overrideGetCurrentLocation != null) { + location = await _overrideGetCurrentLocation!.call(); + } else { + location = await _getCurrentLocation(); + } + await controller.moveCamera( + CameraUpdate.newLatLng(location), + ); + _myLocationButton?.doneAnimation(); + } catch (e) { + _myLocationButton?.disable(); } - _addBlueDotMarker(controller._markersController, location); - - await controller.moveCamera( - CameraUpdate.newLatLng(location), - ); } // Add my location to map -void _addMyLocationButton(gmaps.GMap map, GoogleMapController controller) { - _myLocationButton = _createMyLocationButton(controller); +void _renderMyLocationButton(gmaps.GMap map, GoogleMapController controller) { + _myLocationButton = _MyLocationButton(); + + _myLocationButton?.addClickListener( + () async { + _myLocationButton?.startAnimation(); + await _centerMyCurrentLocation(controller); + }, + ); map.addListener('dragend', () { - document.getElementById('you_location_img')?.style.backgroundPosition = - '0px 0px'; + _myLocationButton?.resetAnimation(); }); map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(_myLocationButton); + ?.push(_myLocationButton?.getButtonElement); } -// Add blue dot for current location -Future _addBlueDotMarker( - MarkersController? markersController, LatLng location) async { - assert(markersController != null, 'Cannot update markers after dispose().'); - +// Create blue dot marker with current location +Future _createBlueDotMarker(LatLng location) async { final BitmapDescriptor icon = await BitmapDescriptor.fromAssetImage( const ImageConfiguration(size: Size(18, 18)), 'icons/blue-dot.png', package: 'google_maps_flutter_web', ); - markersController?.addMarkers({ - Marker( - markerId: const MarkerId('my_location_blue_dot'), - icon: icon, - position: location, - zIndex: 0.5, - ) - }); + return Marker( + markerId: const MarkerId('my_location_blue_dot'), + icon: icon, + position: location, + zIndex: 0.5, + ); } -// Add My Location widget to right bottom -HtmlElement _createMyLocationButton(GoogleMapController controller) { - final HtmlElement controlDiv = DivElement(); - controlDiv.style.marginRight = '10px'; - - final HtmlElement firstChild = ButtonElement(); - firstChild.className = 'gm-control-active'; - firstChild.style.backgroundColor = '#fff'; - firstChild.style.border = 'none'; - firstChild.style.outline = 'none'; - firstChild.style.width = '40px'; - firstChild.style.height = '40px'; - firstChild.style.borderRadius = '2px'; - firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; - firstChild.style.cursor = 'pointer'; - firstChild.style.padding = '8px'; - controlDiv.append(firstChild); - - final HtmlElement secondChild = DivElement(); - secondChild.style.width = '24px'; - secondChild.style.height = '24px'; - secondChild.style.backgroundImage = - 'url(${window.location.href.replaceAll('/#', '')}/assets/packages/google_maps_flutter_web/icons/mylocation-sprite-2x.png)'; - secondChild.style.backgroundSize = '240px 24px'; - secondChild.style.backgroundPosition = '0px 0px'; - secondChild.style.backgroundRepeat = 'no-repeat'; - secondChild.id = 'you_location_img'; - firstChild.append(secondChild); - - firstChild.addEventListener('click', (_) { - String imgX = '0'; - // Add animation when find current location - final Timer timer = Timer.periodic(const Duration(milliseconds: 500), (_) { - imgX = (imgX == '-24') ? '0' : '-24'; - document.getElementById('you_location_img')?.style.backgroundPosition = - '${imgX}px 0px'; - }); - // Find and move to current location - _displayAndCenterMyCurrentLocation(controller).then((_) { - timer.cancel(); - document.getElementById('you_location_img')?.style.backgroundPosition = - '-192px 0px'; +class _MyLocationButton { + _MyLocationButton() { + _addCss(); + _createButton(); + } + + late ButtonElement _firstChild; + late DivElement _secondChild; + late DivElement _controlDiv; + bool isAnimating = false; + // Add animation css + void _addCss() { + final StyleElement styleElement = StyleElement(); + document.head?.append(styleElement); + final CssStyleSheet sheet = styleElement.sheet as CssStyleSheet; + String rule = + '.waiting { animation: 1000ms infinite step-end blink-position-icon;}'; + sheet.insertRule(rule); + rule = + '@keyframes blink-position-icon {0% {background-position: -24px 0px;} ' + '50% {background-position: 0px 0px;}}'; + sheet.insertRule(rule); + } + + // Add My Location widget to right bottom + void _createButton() { + _controlDiv = DivElement(); + + _controlDiv.style.marginRight = '10px'; + + _firstChild = ButtonElement(); + _firstChild.className = 'gm-control-active'; + _firstChild.style.backgroundColor = '#fff'; + _firstChild.style.border = 'none'; + _firstChild.style.outline = 'none'; + _firstChild.style.width = '40px'; + _firstChild.style.height = '40px'; + _firstChild.style.borderRadius = '2px'; + _firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; + _firstChild.style.cursor = 'pointer'; + _firstChild.style.padding = '8px'; + _controlDiv.append(_firstChild); + + _secondChild = DivElement(); + _secondChild.style.width = '24px'; + _secondChild.style.height = '24px'; + _secondChild.style.backgroundImage = + 'url(${window.location.href.replaceAll('/#', '')}/assets/packages/google_maps_flutter_web/icons/mylocation-sprite-2x.png)'; + _secondChild.style.backgroundSize = '240px 24px'; + _secondChild.style.backgroundPosition = '0px 0px'; + _secondChild.style.backgroundRepeat = 'no-repeat'; + _secondChild.id = 'my_location_btn'; + _firstChild.append(_secondChild); + } + + HtmlElement get getButtonElement => _controlDiv; + + void addClickListener(Function onLick) { + _firstChild.addEventListener('click', (_) { + onLick(); }); - }); + } - return controlDiv; + void resetAnimation() { + if (_firstChild.disabled) { + _secondChild.style.backgroundPosition = '-24px 0px'; + } else { + _secondChild.style.backgroundPosition = '0px 0px'; + } + } + + void startAnimation() { + if (_firstChild.disabled && !isAnimating) { + return; + } + _secondChild.classes.add('waiting'); + } + + void doneAnimation() { + if (_firstChild.disabled) { + return; + } + _secondChild.classes.remove('waiting'); + _secondChild.style.backgroundPosition = '-192px 0px'; + } + + void disable() { + _firstChild.disabled = true; + _secondChild.style.backgroundPosition = '-24px 0px'; + } + + void enable() { + _firstChild.disabled = false; + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 6a97431839a2..090788f6257a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.4.0+4 +version: 0.4.1 environment: sdk: ">=2.12.0 <3.0.0" From c0fff065a451d5a2b8fd99f939036d593a9f3e9a Mon Sep 17 00:00:00 2001 From: nploi Date: Sat, 31 Dec 2022 21:22:57 +0700 Subject: [PATCH 29/40] Rename method --- .../example/lib/main.dart | 85 +++++++++++-- .../lib/src/google_maps_controller.dart | 4 +- .../lib/src/my_location.dart | 113 +++++++++--------- 3 files changed, 132 insertions(+), 70 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index e93a60e19906..6175f1c10da7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -1,25 +1,88 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - +import 'dart:async'; +import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; void main() { runApp(const MyApp()); } -/// App for testing -class MyApp extends StatefulWidget { - /// Constructor with key - const MyApp({Key? key}) : super(key: key); +class MyApp extends StatelessWidget { + const MyApp({key}); @override - State createState() => _MyAppState(); + Widget build(BuildContext context) { + return MaterialApp( + title: 'Welcome to Flutter', + home: Scaffold( + body: Page1(), + ), + ); + } } -class _MyAppState extends State { +class Page1 extends StatefulWidget { + @override + _Page1State createState() => _Page1State(); +} + +class _Page1State extends State { + @override + void initState() { + super.initState(); + } + + LatLng _kMapCenter1 = LatLng(19.0182, 72.8479); + LatLng _kMapCenter2 = LatLng(19.0183, 72.8480); + bool toggle = false; + + Completer _controller = Completer(); + + static final CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(37.42796133580664, -122.085749655962), + zoom: 14.4746, + ); + + static final CameraPosition _kLake = CameraPosition( + bearing: 192.8334901395799, + target: LatLng(19.01825595, 72.84793854), + tilt: 59.440717697143555, + zoom: 19.151926040649414); + @override Widget build(BuildContext context) { - return const Text('Testing... Look at the console output for results!'); + return Scaffold( + body: GoogleMap( + markers: Set.of(_createMarker()), + mapType: MapType.hybrid, + initialCameraPosition: _kGooglePlex, + onMapCreated: (GoogleMapController controller) { + _controller.complete(controller); + }, + myLocationButtonEnabled: true, + myLocationEnabled: true, + ), + ); + } + + //ทำ marker + Set _createMarker() { + print(5555); + return { + Marker( + markerId: MarkerId("marker_1"), + position: _kMapCenter1, + infoWindow: InfoWindow(title: 'Marker 1'), + rotation: 90), + Marker( + markerId: MarkerId("marker_2"), + position: _kMapCenter2, + ), + }; + } + + Future _goToTheLake() async { + final GoogleMapController controller = await _controller.future; + controller.animateCamera(CameraUpdate.newCameraPosition(_kLake)); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index af22c3752c2f..8d80d716609a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -192,9 +192,9 @@ class GoogleMapController { Future _renderMyLocation(gmaps.GMap map) async { if (_lastMapConfiguration.myLocationEnabled ?? false) { if (_lastMapConfiguration.myLocationButtonEnabled ?? false) { - _renderMyLocationButton(map, this); + _addMyLocationButton(map, this); } - _watchLocationAndUpdateBlueDot(this); + _displayAndWatchMyLocation(_markersController!); _centerMyCurrentLocation(this); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart index 6ad7f85d737e..88cfa36502ac 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart @@ -14,22 +14,25 @@ DebugGetCurrentLocation? _overrideGetCurrentLocation; _MyLocationButton? _myLocationButton; // Watch current location and update blue dot -void _watchLocationAndUpdateBlueDot(GoogleMapController controller) { +Future _displayAndWatchMyLocation(MarkersController controller) async { + final Marker marker = await _createBlueDotMarker(); window.navigator.geolocation .watchPosition() .listen((Geoposition location) async { - final Marker blueDot = await _createBlueDotMarker(LatLng( - location.coords!.latitude!.toDouble(), - location.coords!.longitude!.toDouble(), - )); - controller._markersController?.addMarkers({blueDot}); + controller.addMarkers({ + marker.copyWith( + positionParam: LatLng( + location.coords!.latitude!.toDouble(), + location.coords!.longitude!.toDouble(), + )) + }); }); } // Get current location Future _getCurrentLocation() async { - final Geoposition location = - await window.navigator.geolocation.getCurrentPosition(); + final Geoposition location = await window.navigator.geolocation + .getCurrentPosition(timeout: const Duration(seconds: 30)); return LatLng( location.coords!.latitude!.toDouble(), location.coords!.longitude!.toDouble(), @@ -52,14 +55,13 @@ Future _centerMyCurrentLocation( ); _myLocationButton?.doneAnimation(); } catch (e) { - _myLocationButton?.disable(); + _myLocationButton?.disableBtn(); } } // Add my location to map -void _renderMyLocationButton(gmaps.GMap map, GoogleMapController controller) { +void _addMyLocationButton(gmaps.GMap map, GoogleMapController controller) { _myLocationButton = _MyLocationButton(); - _myLocationButton?.addClickListener( () async { _myLocationButton?.startAnimation(); @@ -72,11 +74,11 @@ void _renderMyLocationButton(gmaps.GMap map, GoogleMapController controller) { }); map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(_myLocationButton?.getButtonElement); + ?.push(_myLocationButton?.getButton); } -// Create blue dot marker with current location -Future _createBlueDotMarker(LatLng location) async { +// Create blue dot marker +Future _createBlueDotMarker() async { final BitmapDescriptor icon = await BitmapDescriptor.fromAssetImage( const ImageConfiguration(size: Size(18, 18)), 'icons/blue-dot.png', @@ -85,25 +87,26 @@ Future _createBlueDotMarker(LatLng location) async { return Marker( markerId: const MarkerId('my_location_blue_dot'), icon: icon, - position: location, zIndex: 0.5, ); } +// This class support create my location button & handle animation class _MyLocationButton { _MyLocationButton() { _addCss(); _createButton(); } - late ButtonElement _firstChild; - late DivElement _secondChild; + late ButtonElement _btnChild; + late DivElement _imageChild; late DivElement _controlDiv; - bool isAnimating = false; + // Add animation css void _addCss() { final StyleElement styleElement = StyleElement(); document.head?.append(styleElement); + // ignore: cast_nullable_to_non_nullable final CssStyleSheet sheet = styleElement.sheet as CssStyleSheet; String rule = '.waiting { animation: 1000ms infinite step-end blink-position-icon;}'; @@ -120,68 +123,64 @@ class _MyLocationButton { _controlDiv.style.marginRight = '10px'; - _firstChild = ButtonElement(); - _firstChild.className = 'gm-control-active'; - _firstChild.style.backgroundColor = '#fff'; - _firstChild.style.border = 'none'; - _firstChild.style.outline = 'none'; - _firstChild.style.width = '40px'; - _firstChild.style.height = '40px'; - _firstChild.style.borderRadius = '2px'; - _firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; - _firstChild.style.cursor = 'pointer'; - _firstChild.style.padding = '8px'; - _controlDiv.append(_firstChild); - - _secondChild = DivElement(); - _secondChild.style.width = '24px'; - _secondChild.style.height = '24px'; - _secondChild.style.backgroundImage = + _btnChild = ButtonElement(); + _btnChild.className = 'gm-control-active'; + _btnChild.style.backgroundColor = '#fff'; + _btnChild.style.border = 'none'; + _btnChild.style.outline = 'none'; + _btnChild.style.width = '40px'; + _btnChild.style.height = '40px'; + _btnChild.style.borderRadius = '2px'; + _btnChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'; + _btnChild.style.cursor = 'pointer'; + _btnChild.style.padding = '8px'; + _controlDiv.append(_btnChild); + + _imageChild = DivElement(); + _imageChild.style.width = '24px'; + _imageChild.style.height = '24px'; + _imageChild.style.backgroundImage = 'url(${window.location.href.replaceAll('/#', '')}/assets/packages/google_maps_flutter_web/icons/mylocation-sprite-2x.png)'; - _secondChild.style.backgroundSize = '240px 24px'; - _secondChild.style.backgroundPosition = '0px 0px'; - _secondChild.style.backgroundRepeat = 'no-repeat'; - _secondChild.id = 'my_location_btn'; - _firstChild.append(_secondChild); + _imageChild.style.backgroundSize = '240px 24px'; + _imageChild.style.backgroundPosition = '0px 0px'; + _imageChild.style.backgroundRepeat = 'no-repeat'; + _imageChild.id = 'my_location_btn'; + _btnChild.append(_imageChild); } - HtmlElement get getButtonElement => _controlDiv; + HtmlElement get getButton => _controlDiv; void addClickListener(Function onLick) { - _firstChild.addEventListener('click', (_) { + _btnChild.addEventListener('click', (_) { onLick(); }); } void resetAnimation() { - if (_firstChild.disabled) { - _secondChild.style.backgroundPosition = '-24px 0px'; + if (_btnChild.disabled) { + _imageChild.style.backgroundPosition = '-24px 0px'; } else { - _secondChild.style.backgroundPosition = '0px 0px'; + _imageChild.style.backgroundPosition = '0px 0px'; } } void startAnimation() { - if (_firstChild.disabled && !isAnimating) { + if (_btnChild.disabled) { return; } - _secondChild.classes.add('waiting'); + _imageChild.classes.add('waiting'); } void doneAnimation() { - if (_firstChild.disabled) { + if (_btnChild.disabled) { return; } - _secondChild.classes.remove('waiting'); - _secondChild.style.backgroundPosition = '-192px 0px'; - } - - void disable() { - _firstChild.disabled = true; - _secondChild.style.backgroundPosition = '-24px 0px'; + _imageChild.classes.remove('waiting'); + _imageChild.style.backgroundPosition = '-192px 0px'; } - void enable() { - _firstChild.disabled = false; + void disableBtn() { + _btnChild.disabled = true; + _imageChild.style.backgroundPosition = '-24px 0px'; } } From 17470929e87607966ed26e092e0436fd1e3957d3 Mon Sep 17 00:00:00 2001 From: nploi Date: Sat, 31 Dec 2022 21:23:16 +0700 Subject: [PATCH 30/40] Revert code --- .../example/lib/main.dart | 85 +++---------------- 1 file changed, 11 insertions(+), 74 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index 6175f1c10da7..e93a60e19906 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -1,88 +1,25 @@ -import 'dart:async'; -import 'dart:math'; +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'package:flutter/material.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; void main() { runApp(const MyApp()); } -class MyApp extends StatelessWidget { - const MyApp({key}); +/// App for testing +class MyApp extends StatefulWidget { + /// Constructor with key + const MyApp({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Welcome to Flutter', - home: Scaffold( - body: Page1(), - ), - ); - } + State createState() => _MyAppState(); } -class Page1 extends StatefulWidget { - @override - _Page1State createState() => _Page1State(); -} - -class _Page1State extends State { - @override - void initState() { - super.initState(); - } - - LatLng _kMapCenter1 = LatLng(19.0182, 72.8479); - LatLng _kMapCenter2 = LatLng(19.0183, 72.8480); - bool toggle = false; - - Completer _controller = Completer(); - - static final CameraPosition _kGooglePlex = CameraPosition( - target: LatLng(37.42796133580664, -122.085749655962), - zoom: 14.4746, - ); - - static final CameraPosition _kLake = CameraPosition( - bearing: 192.8334901395799, - target: LatLng(19.01825595, 72.84793854), - tilt: 59.440717697143555, - zoom: 19.151926040649414); - +class _MyAppState extends State { @override Widget build(BuildContext context) { - return Scaffold( - body: GoogleMap( - markers: Set.of(_createMarker()), - mapType: MapType.hybrid, - initialCameraPosition: _kGooglePlex, - onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); - }, - myLocationButtonEnabled: true, - myLocationEnabled: true, - ), - ); - } - - //ทำ marker - Set _createMarker() { - print(5555); - return { - Marker( - markerId: MarkerId("marker_1"), - position: _kMapCenter1, - infoWindow: InfoWindow(title: 'Marker 1'), - rotation: 90), - Marker( - markerId: MarkerId("marker_2"), - position: _kMapCenter2, - ), - }; - } - - Future _goToTheLake() async { - final GoogleMapController controller = await _controller.future; - controller.animateCamera(CameraUpdate.newCameraPosition(_kLake)); + return const Text('Testing... Look at the console output for results!'); } } From dd5154812ad0858580c85d2fbd4321cc1dbc1c1a Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 16:46:17 +0700 Subject: [PATCH 31/40] Fix unit-test & fix logic --- .../google_maps_controller_test.dart | 56 +++++- .../google_maps_controller_test.mocks.dart | 164 ++++++++++++++---- .../google_maps_plugin_test.dart | 1 + .../google_maps_plugin_test.mocks.dart | 9 +- .../lib/src/google_maps_controller.dart | 19 +- .../lib/src/my_location.dart | 53 +++--- 6 files changed, 218 insertions(+), 84 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 40a366a78701..3e27272ce50e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -25,6 +25,9 @@ const double _acceptableDelta = 0.0000000001; MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec(onMissingStub: OnMissingStub.returnDefault), + MockSpec(onMissingStub: OnMissingStub.returnDefault), + MockSpec(onMissingStub: OnMissingStub.returnDefault), + MockSpec(onMissingStub: OnMissingStub.returnDefault), ]) /// Test Google Map Controller @@ -35,7 +38,6 @@ void main() { const int mapId = 33930; late GoogleMapController controller; late StreamController> stream; - // Creates a controller with the default mapId and stream controller, and any `options` needed. GoogleMapController createController({ CameraPosition initialCameraPosition = @@ -493,9 +495,13 @@ void main() { expect(controller.myLocationButton, isNull); }); - testWidgets('initializes with my location with my location button', + 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, @@ -504,11 +510,27 @@ void main() { controller.debugSetOverrides( createMap: (_, __) => map, markers: markers, - getCurrentLocation: () => Future.value(currentLocation), + 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.fromIterable( + [mockGeoposition]); + }); + controller.init(); - await Future.delayed(const Duration(milliseconds: 50)); + await Future.delayed(const Duration(seconds: 1)); final Set capturedMarkers = verify(markers.addMarkers(captureAny)).captured[1] as Set; @@ -523,9 +545,13 @@ void main() { expect(gmCenter.lng, currentLocation.longitude); }); - testWidgets('initializes with my location without my location button', + 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, @@ -534,11 +560,27 @@ void main() { controller.debugSetOverrides( createMap: (_, __) => map, markers: markers, - getCurrentLocation: () => Future.value(currentLocation), + 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.fromIterable( + [mockGeoposition]); + }); + controller.init(); - await Future.delayed(const Duration(milliseconds: 50)); + await Future.delayed(const Duration(seconds: 1)); final Set capturedMarkers = verify(markers.addMarkers(captureAny)).captured[1] as Set; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart index efde66459327..9bae50540ad8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart @@ -3,10 +3,13 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i6; +import 'dart:html' as _i3; + import 'package:google_maps/google_maps.dart' as _i2; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart' - as _i4; -import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i3; + as _i5; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i4; import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint @@ -30,16 +33,26 @@ class _FakeGMap_0 extends _i1.SmartFake implements _i2.GMap { ); } +class _FakeGeoposition_1 extends _i1.SmartFake implements _i3.Geoposition { + _FakeGeoposition_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [CirclesController]. /// /// See the documentation for Mockito's code generation for more information. -class MockCirclesController extends _i1.Mock implements _i3.CirclesController { +class MockCirclesController extends _i1.Mock implements _i4.CirclesController { @override - Map<_i4.CircleId, _i3.CircleController> get circles => (super.noSuchMethod( + Map<_i5.CircleId, _i4.CircleController> get circles => (super.noSuchMethod( Invocation.getter(#circles), - returnValue: <_i4.CircleId, _i3.CircleController>{}, - returnValueForMissingStub: <_i4.CircleId, _i3.CircleController>{}, - ) as Map<_i4.CircleId, _i3.CircleController>); + returnValue: <_i5.CircleId, _i4.CircleController>{}, + returnValueForMissingStub: <_i5.CircleId, _i4.CircleController>{}, + ) as Map<_i5.CircleId, _i4.CircleController>); @override _i2.GMap get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), @@ -75,7 +88,7 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { returnValueForMissingStub: null, ); @override - void addCircles(Set<_i4.Circle>? circlesToAdd) => super.noSuchMethod( + void addCircles(Set<_i5.Circle>? circlesToAdd) => super.noSuchMethod( Invocation.method( #addCircles, [circlesToAdd], @@ -83,7 +96,7 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { returnValueForMissingStub: null, ); @override - void changeCircles(Set<_i4.Circle>? circlesToChange) => super.noSuchMethod( + void changeCircles(Set<_i5.Circle>? circlesToChange) => super.noSuchMethod( Invocation.method( #changeCircles, [circlesToChange], @@ -91,7 +104,7 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { returnValueForMissingStub: null, ); @override - void removeCircles(Set<_i4.CircleId>? circleIdsToRemove) => + void removeCircles(Set<_i5.CircleId>? circleIdsToRemove) => super.noSuchMethod( Invocation.method( #removeCircles, @@ -120,13 +133,13 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { /// /// See the documentation for Mockito's code generation for more information. class MockPolygonsController extends _i1.Mock - implements _i3.PolygonsController { + implements _i4.PolygonsController { @override - Map<_i4.PolygonId, _i3.PolygonController> get polygons => (super.noSuchMethod( + Map<_i5.PolygonId, _i4.PolygonController> get polygons => (super.noSuchMethod( Invocation.getter(#polygons), - returnValue: <_i4.PolygonId, _i3.PolygonController>{}, - returnValueForMissingStub: <_i4.PolygonId, _i3.PolygonController>{}, - ) as Map<_i4.PolygonId, _i3.PolygonController>); + returnValue: <_i5.PolygonId, _i4.PolygonController>{}, + returnValueForMissingStub: <_i5.PolygonId, _i4.PolygonController>{}, + ) as Map<_i5.PolygonId, _i4.PolygonController>); @override _i2.GMap get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), @@ -162,7 +175,7 @@ class MockPolygonsController extends _i1.Mock returnValueForMissingStub: null, ); @override - void addPolygons(Set<_i4.Polygon>? polygonsToAdd) => super.noSuchMethod( + void addPolygons(Set<_i5.Polygon>? polygonsToAdd) => super.noSuchMethod( Invocation.method( #addPolygons, [polygonsToAdd], @@ -170,7 +183,7 @@ class MockPolygonsController extends _i1.Mock returnValueForMissingStub: null, ); @override - void changePolygons(Set<_i4.Polygon>? polygonsToChange) => super.noSuchMethod( + void changePolygons(Set<_i5.Polygon>? polygonsToChange) => super.noSuchMethod( Invocation.method( #changePolygons, [polygonsToChange], @@ -178,7 +191,7 @@ class MockPolygonsController extends _i1.Mock returnValueForMissingStub: null, ); @override - void removePolygons(Set<_i4.PolygonId>? polygonIdsToRemove) => + void removePolygons(Set<_i5.PolygonId>? polygonIdsToRemove) => super.noSuchMethod( Invocation.method( #removePolygons, @@ -207,13 +220,13 @@ class MockPolygonsController extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockPolylinesController extends _i1.Mock - implements _i3.PolylinesController { + implements _i4.PolylinesController { @override - Map<_i4.PolylineId, _i3.PolylineController> get lines => (super.noSuchMethod( + Map<_i5.PolylineId, _i4.PolylineController> get lines => (super.noSuchMethod( Invocation.getter(#lines), - returnValue: <_i4.PolylineId, _i3.PolylineController>{}, - returnValueForMissingStub: <_i4.PolylineId, _i3.PolylineController>{}, - ) as Map<_i4.PolylineId, _i3.PolylineController>); + returnValue: <_i5.PolylineId, _i4.PolylineController>{}, + returnValueForMissingStub: <_i5.PolylineId, _i4.PolylineController>{}, + ) as Map<_i5.PolylineId, _i4.PolylineController>); @override _i2.GMap get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), @@ -249,7 +262,7 @@ class MockPolylinesController extends _i1.Mock returnValueForMissingStub: null, ); @override - void addPolylines(Set<_i4.Polyline>? polylinesToAdd) => super.noSuchMethod( + void addPolylines(Set<_i5.Polyline>? polylinesToAdd) => super.noSuchMethod( Invocation.method( #addPolylines, [polylinesToAdd], @@ -257,7 +270,7 @@ class MockPolylinesController extends _i1.Mock returnValueForMissingStub: null, ); @override - void changePolylines(Set<_i4.Polyline>? polylinesToChange) => + void changePolylines(Set<_i5.Polyline>? polylinesToChange) => super.noSuchMethod( Invocation.method( #changePolylines, @@ -266,7 +279,7 @@ class MockPolylinesController extends _i1.Mock returnValueForMissingStub: null, ); @override - void removePolylines(Set<_i4.PolylineId>? polylineIdsToRemove) => + void removePolylines(Set<_i5.PolylineId>? polylineIdsToRemove) => super.noSuchMethod( Invocation.method( #removePolylines, @@ -294,13 +307,13 @@ class MockPolylinesController extends _i1.Mock /// A class which mocks [MarkersController]. /// /// See the documentation for Mockito's code generation for more information. -class MockMarkersController extends _i1.Mock implements _i3.MarkersController { +class MockMarkersController extends _i1.Mock implements _i4.MarkersController { @override - Map<_i4.MarkerId, _i3.MarkerController> get markers => (super.noSuchMethod( + Map<_i5.MarkerId, _i4.MarkerController> get markers => (super.noSuchMethod( Invocation.getter(#markers), - returnValue: <_i4.MarkerId, _i3.MarkerController>{}, - returnValueForMissingStub: <_i4.MarkerId, _i3.MarkerController>{}, - ) as Map<_i4.MarkerId, _i3.MarkerController>); + returnValue: <_i5.MarkerId, _i4.MarkerController>{}, + returnValueForMissingStub: <_i5.MarkerId, _i4.MarkerController>{}, + ) as Map<_i5.MarkerId, _i4.MarkerController>); @override _i2.GMap get googleMap => (super.noSuchMethod( Invocation.getter(#googleMap), @@ -336,7 +349,7 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValueForMissingStub: null, ); @override - void addMarkers(Set<_i4.Marker>? markersToAdd) => super.noSuchMethod( + void addMarkers(Set<_i5.Marker>? markersToAdd) => super.noSuchMethod( Invocation.method( #addMarkers, [markersToAdd], @@ -344,7 +357,7 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValueForMissingStub: null, ); @override - void changeMarkers(Set<_i4.Marker>? markersToChange) => super.noSuchMethod( + void changeMarkers(Set<_i5.Marker>? markersToChange) => super.noSuchMethod( Invocation.method( #changeMarkers, [markersToChange], @@ -352,7 +365,7 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValueForMissingStub: null, ); @override - void removeMarkers(Set<_i4.MarkerId>? markerIdsToRemove) => + void removeMarkers(Set<_i5.MarkerId>? markerIdsToRemove) => super.noSuchMethod( Invocation.method( #removeMarkers, @@ -361,7 +374,7 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValueForMissingStub: null, ); @override - void showMarkerInfoWindow(_i4.MarkerId? markerId) => super.noSuchMethod( + void showMarkerInfoWindow(_i5.MarkerId? markerId) => super.noSuchMethod( Invocation.method( #showMarkerInfoWindow, [markerId], @@ -369,7 +382,7 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValueForMissingStub: null, ); @override - void hideMarkerInfoWindow(_i4.MarkerId? markerId) => super.noSuchMethod( + void hideMarkerInfoWindow(_i5.MarkerId? markerId) => super.noSuchMethod( Invocation.method( #hideMarkerInfoWindow, [markerId], @@ -377,7 +390,7 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValueForMissingStub: null, ); @override - bool isInfoWindowShown(_i4.MarkerId? markerId) => (super.noSuchMethod( + bool isInfoWindowShown(_i5.MarkerId? markerId) => (super.noSuchMethod( Invocation.method( #isInfoWindowShown, [markerId], @@ -401,3 +414,80 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { returnValueForMissingStub: null, ); } + +/// A class which mocks [Geolocation]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGeolocation extends _i1.Mock implements _i3.Geolocation { + @override + _i6.Future<_i3.Geoposition> getCurrentPosition({ + bool? enableHighAccuracy, + Duration? timeout, + Duration? maximumAge, + }) => + (super.noSuchMethod( + Invocation.method( + #getCurrentPosition, + [], + { + #enableHighAccuracy: enableHighAccuracy, + #timeout: timeout, + #maximumAge: maximumAge, + }, + ), + returnValue: _i6.Future<_i3.Geoposition>.value(_FakeGeoposition_1( + this, + Invocation.method( + #getCurrentPosition, + [], + { + #enableHighAccuracy: enableHighAccuracy, + #timeout: timeout, + #maximumAge: maximumAge, + }, + ), + )), + returnValueForMissingStub: + _i6.Future<_i3.Geoposition>.value(_FakeGeoposition_1( + this, + Invocation.method( + #getCurrentPosition, + [], + { + #enableHighAccuracy: enableHighAccuracy, + #timeout: timeout, + #maximumAge: maximumAge, + }, + ), + )), + ) as _i6.Future<_i3.Geoposition>); + @override + _i6.Stream<_i3.Geoposition> watchPosition({ + bool? enableHighAccuracy, + Duration? timeout, + Duration? maximumAge, + }) => + (super.noSuchMethod( + Invocation.method( + #watchPosition, + [], + { + #enableHighAccuracy: enableHighAccuracy, + #timeout: timeout, + #maximumAge: maximumAge, + }, + ), + returnValue: _i6.Stream<_i3.Geoposition>.empty(), + returnValueForMissingStub: _i6.Stream<_i3.Geoposition>.empty(), + ) as _i6.Stream<_i3.Geoposition>); +} + +/// A class which mocks [Geoposition]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGeoposition extends _i1.Mock implements _i3.Geoposition {} + +/// A class which mocks [Coordinates]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCoordinates extends _i1.Mock implements _i3.Coordinates {} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index 9bd1a68c6207..916e8eb08fd2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -26,6 +26,7 @@ void main() { group('GoogleMapsPlugin', () { late MockGoogleMapController controller; + late GoogleMapsPlugin plugin; late Completer reportedMapIdCompleter; int numberOnPlatformViewCreatedCalls = 0; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart index 17b6946a4254..d6653e815246 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart @@ -4,8 +4,9 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i2; +import 'dart:html' as _i5; -import 'package:google_maps/google_maps.dart' as _i5; +import 'package:google_maps/google_maps.dart' as _i6; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart' as _i3; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i4; @@ -101,7 +102,7 @@ class MockGoogleMapController extends _i1.Mock _i4.CirclesController? circles, _i4.PolygonsController? polygons, _i4.PolylinesController? polylines, - _i4.DebugGetCurrentLocation? getCurrentLocation, + _i5.Geolocation? geolocation, }) => super.noSuchMethod( Invocation.method( @@ -113,7 +114,7 @@ class MockGoogleMapController extends _i1.Mock #circles: circles, #polygons: polygons, #polylines: polylines, - #getCurrentLocation: getCurrentLocation, + #geolocation: geolocation, }, ), returnValueForMissingStub: null, @@ -136,7 +137,7 @@ class MockGoogleMapController extends _i1.Mock returnValueForMissingStub: null, ); @override - void updateStyles(List<_i5.MapTypeStyle>? styles) => super.noSuchMethod( + void updateStyles(List<_i6.MapTypeStyle>? styles) => super.noSuchMethod( Invocation.method( #updateStyles, [styles], diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 8d80d716609a..aa0a7f4ab95d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -75,9 +75,12 @@ class GoogleMapController { return _widget; } + // Get current location + MyLocationButton? _myLocationButton; + /// A getter for the my location button @visibleForTesting - _MyLocationButton? get myLocationButton => _myLocationButton; + MyLocationButton? get myLocationButton => _myLocationButton; // The currently-enabled traffic layer. gmaps.TrafficLayer? _trafficLayer; @@ -118,14 +121,14 @@ class GoogleMapController { CirclesController? circles, PolygonsController? polygons, PolylinesController? polylines, - DebugGetCurrentLocation? getCurrentLocation, + Geolocation? geolocation, }) { _overrideCreateMap = createMap; _markersController = markers ?? _markersController; _circlesController = circles ?? _circlesController; _polygonsController = polygons ?? _polygonsController; _polylinesController = polylines ?? _polylinesController; - _overrideGetCurrentLocation = getCurrentLocation; + _geolocation = geolocation ?? _geolocation; } DebugCreateMapFunction? _overrideCreateMap; @@ -185,13 +188,14 @@ class GoogleMapController { _setTrafficLayer(map, _lastMapConfiguration.trafficEnabled ?? false); - _renderMyLocation(map); + _renderMyLocation(map, _lastMapConfiguration); } // Render my location - Future _renderMyLocation(gmaps.GMap map) async { - if (_lastMapConfiguration.myLocationEnabled ?? false) { - if (_lastMapConfiguration.myLocationButtonEnabled ?? false) { + Future _renderMyLocation( + gmaps.GMap map, MapConfiguration mapConfiguration) async { + if (mapConfiguration.myLocationEnabled ?? false) { + if (mapConfiguration.myLocationButtonEnabled ?? false) { _addMyLocationButton(map, this); } _displayAndWatchMyLocation(_markersController!); @@ -446,6 +450,7 @@ class GoogleMapController { _polygonsController = null; _polylinesController = null; _markersController = null; + _myLocationButton = null; _streamController.close(); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart index 88cfa36502ac..f0da749e7acf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart @@ -4,21 +4,13 @@ part of google_maps_flutter_web; -/// Type used when passing an override to the _getCurrentLocation function. -@visibleForTesting -typedef DebugGetCurrentLocation = Future Function(); - -DebugGetCurrentLocation? _overrideGetCurrentLocation; - -// Get current location -_MyLocationButton? _myLocationButton; +// geolocation +Geolocation _geolocation = window.navigator.geolocation; // Watch current location and update blue dot Future _displayAndWatchMyLocation(MarkersController controller) async { final Marker marker = await _createBlueDotMarker(); - window.navigator.geolocation - .watchPosition() - .listen((Geoposition location) async { + _geolocation.watchPosition().listen((Geoposition location) async { controller.addMarkers({ marker.copyWith( positionParam: LatLng( @@ -31,8 +23,8 @@ Future _displayAndWatchMyLocation(MarkersController controller) async { // Get current location Future _getCurrentLocation() async { - final Geoposition location = await window.navigator.geolocation - .getCurrentPosition(timeout: const Duration(seconds: 30)); + final Geoposition location = await _geolocation.getCurrentPosition( + timeout: const Duration(seconds: 30)); return LatLng( location.coords!.latitude!.toDouble(), location.coords!.longitude!.toDouble(), @@ -44,37 +36,32 @@ Future _centerMyCurrentLocation( GoogleMapController controller, ) async { try { - LatLng location; - if (_overrideGetCurrentLocation != null) { - location = await _overrideGetCurrentLocation!.call(); - } else { - location = await _getCurrentLocation(); - } + final LatLng location = await _getCurrentLocation(); await controller.moveCamera( CameraUpdate.newLatLng(location), ); - _myLocationButton?.doneAnimation(); + controller._myLocationButton?.doneAnimation(); } catch (e) { - _myLocationButton?.disableBtn(); + controller._myLocationButton?.disableBtn(); } } // Add my location to map void _addMyLocationButton(gmaps.GMap map, GoogleMapController controller) { - _myLocationButton = _MyLocationButton(); - _myLocationButton?.addClickListener( + controller._myLocationButton = MyLocationButton(); + controller._myLocationButton?.addClickListener( () async { - _myLocationButton?.startAnimation(); + controller._myLocationButton?.startAnimation(); await _centerMyCurrentLocation(controller); }, ); map.addListener('dragend', () { - _myLocationButton?.resetAnimation(); + controller._myLocationButton?.resetAnimation(); }); map.controls![gmaps.ControlPosition.RIGHT_BOTTOM as int] - ?.push(_myLocationButton?.getButton); + ?.push(controller._myLocationButton?.getButton); } // Create blue dot marker @@ -91,9 +78,11 @@ Future _createBlueDotMarker() async { ); } -// This class support create my location button & handle animation -class _MyLocationButton { - _MyLocationButton() { +/// This class support create my location button & handle animation +@visibleForTesting +class MyLocationButton { + /// Add css and create my location button + MyLocationButton() { _addCss(); _createButton(); } @@ -148,14 +137,17 @@ class _MyLocationButton { _btnChild.append(_imageChild); } + /// Get button element HtmlElement get getButton => _controlDiv; + /// Add click listener void addClickListener(Function onLick) { _btnChild.addEventListener('click', (_) { onLick(); }); } + /// Reset animation void resetAnimation() { if (_btnChild.disabled) { _imageChild.style.backgroundPosition = '-24px 0px'; @@ -164,6 +156,7 @@ class _MyLocationButton { } } + /// Start animation void startAnimation() { if (_btnChild.disabled) { return; @@ -171,6 +164,7 @@ class _MyLocationButton { _imageChild.classes.add('waiting'); } + /// Done animation void doneAnimation() { if (_btnChild.disabled) { return; @@ -179,6 +173,7 @@ class _MyLocationButton { _imageChild.style.backgroundPosition = '-192px 0px'; } + /// Disable button void disableBtn() { _btnChild.disabled = true; _imageChild.style.backgroundPosition = '-24px 0px'; From c99c506c14a4498f52e750255461ddbe04280cf4 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 17:54:51 +0700 Subject: [PATCH 32/40] Update blue dot icon & add todo me --- .../icons/blue-dot.png | Bin 1116 -> 1754 bytes .../lib/src/my_location.dart | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/icons/blue-dot.png b/packages/google_maps_flutter/google_maps_flutter_web/icons/blue-dot.png index a7f31c1f399053c4b11efe649b326c23537211e1..77780f8ab4b78bdfec273c504a5104fbf134b054 100644 GIT binary patch literal 1754 zcmZ`&2{_bg82=oR5nXJQm2#HK7$oNyGn1KQ9_Mxl12BHWEsU5N%Jf zqH>gOA*oH$wM!`p!}!nf|Lr!3f*GYq*i&YY=D$1qZg zfRceZrc7;OV?>U?ry3(>P7}F8y9}XYDgxhsD`ADg6U|6=!;Dw%^uKP~pNl_?qfpP~ zZ}&^FuMQ07uBvW}gd%Kc3>}$3#ecnm8QE?9Bk9Kp^wbT6Svc*?5s*0o*rUE@wzlSu zNFv2b+YoxD0QxX9DMVQn!U-WNtA!)P670a4>A6|Otw>4h-(2WC!L=u|@L&h1LyM-N zKnIe7VBnx>1Pv(_<~JjMe3rt|P(%O6Uy+eC8rBy+-0?M-Jm0D4jm|S04Ao< zsB)n!2{FrH!?2-C$}E_M8v2m?9DP_gR|}W<^*$lCZjc)W5QFyyU28&t(p@Ln{apeYLFImfA z51r3jy>G{{B_pF?YgLJDxG1~ua#)u+pU=;euSDa((9?%v%{zp*lgpkwsV0`cF-W-! zbhbC{IjloYi_uky?93~F0FJ-!qr|e%2~CxUs*CD&X$Z!@C5$gK1|OJ}I7T3=$+$UHLf#p z(;e>zVwcj7%nvwYu$LV5y3Af+IC<90i@bloT9T>$e1EHek5>C?Mcn4PgvRYgL?d?N z3O51Qv^QPJy7NNM2H$r-wJmof+!}3>x3qXw+^jUYI9}Z5@ORu zHcmcgFj5}3M_mezP*#;D%w$+btjIA@R?^L(QnVHrAKBuA_L?E@#)yIz|x|DHH# zo9lheF_F*Dk{u;kb-2qu-h?&rgnZ2ts15z*{r=Gl$g5Jeh>s?me7PU~FMuJ7x}6mg z$O^R$jtqqc5by+x^>}kA-sX5)i%qt8D^on)7LQjsKnVCpLHMDNy9y8Ey_$*C@9KL%gjmTQUC*E6D|`=6HB8+0|NsK z0|+oQFfcX*l14zbIaDao00o#Dm|2<`n;Dt|F^JCv07$kJ$$#-4QKSF>1E@(vK~!ko z-C9j(6G0RXir~*d@$BEhgQ5pD2L)|I6FtO(9>jxq5o|q(2cfwKYST9UA&6ju6eX8s#)km(-I)4y;idS*7ObK zc6kMS88KbZsRaDtFEt6?*%UwAm{TRMQ^kv4 z=glWZkv>t)z%#r9k5l;-7uz(tI;C(81WmmypJl+li-5i{uyP>;y66R!eQ#7ZfoqsI0Dqlj#wsBww7q`Debm6{c8$2h> zg$zC*TNX!Enh}U=n`9@7-e&xz;TSxpdrSr&g%YJ5xl~k1GLxPsi|54y8@`-#y#UC_ z2nQQFq|At6URr>p{eSswPI5&!h;G4if-F9uL;4)>0$g_6m~T&UMFV#=Web2TA%3K! z-G3<>1(jk&GPeZm7)i24;kiLGsbbQApNtf3_K^u%osQENhCz9gG|S4^nm4{^u4QCER1 zt{{-bRRpp&rV`^SQVE;MT*SjYMpWok-F$bc-@C8g@39=T0Ri+ZpP0JhBTHXb zd}i&A58ajv(YLw1Y5*B61zzv6$H6guOYbFPXS2&5-~n&jFMBk*Zi7R}uiN0aSJ!R+ Y0`H?bV{xuQv;Y7A07*qoM6N<$f=aUNB>(^b diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart index f0da749e7acf..43a31ea52f6f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart @@ -4,13 +4,17 @@ part of google_maps_flutter_web; -// geolocation Geolocation _geolocation = window.navigator.geolocation; // Watch current location and update blue dot Future _displayAndWatchMyLocation(MarkersController controller) async { final Marker marker = await _createBlueDotMarker(); _geolocation.watchPosition().listen((Geoposition location) async { + // TODO(nploi): https://github.com/flutter/plugins/pull/6868#discussion_r1057898052 + // We're discarding a lot of information from coords, like its accuracy, heading and speed. Those can be used to: + // - Render a bigger "blue halo" around the current position marker when the accuracy is low. + // - Render the direction in which we're looking at with a small "cone" using the heading information. + // - Render the current position marker as an arrow when the current position is "moving" (speed > certain threshold), and the direction in which the arrow should point (again, with the heading information). controller.addMarkers({ marker.copyWith( positionParam: LatLng( From 6c0aecd8b7459498904e7fa6388fafad42d09b55 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 18:05:57 +0700 Subject: [PATCH 33/40] Fix lint --- .../example/integration_test/google_maps_plugin_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index 916e8eb08fd2..9bd1a68c6207 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -26,7 +26,6 @@ void main() { group('GoogleMapsPlugin', () { late MockGoogleMapController controller; - late GoogleMapsPlugin plugin; late Completer reportedMapIdCompleter; int numberOnPlatformViewCreatedCalls = 0; From cbc6bc22a0bc7df93b8dc5756ebf65a547a0adf2 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 18:54:42 +0700 Subject: [PATCH 34/40] Add unit-test for location permission --- .../google_maps_controller_test.dart | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 3e27272ce50e..60852d0cda01 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -530,7 +530,7 @@ void main() { controller.init(); - await Future.delayed(const Duration(seconds: 1)); + await Future.delayed(const Duration(milliseconds: 50)); final Set capturedMarkers = verify(markers.addMarkers(captureAny)).captured[1] as Set; @@ -580,7 +580,7 @@ void main() { controller.init(); - await Future.delayed(const Duration(seconds: 1)); + await Future.delayed(const Duration(milliseconds: 50)); final Set capturedMarkers = verify(markers.addMarkers(captureAny)).captured[1] as Set; @@ -595,6 +595,48 @@ void main() { 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(); + 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(mockGeolocation.getCurrentPosition( + timeout: const Duration(seconds: 30))) + .thenAnswer( + (_) async => throw 'permission denied', + ); + + when(mockGeolocation.watchPosition()).thenAnswer((_) { + return Stream.fromIterable([]); + }); + + controller.init(); + + await Future.delayed(const Duration(milliseconds: 50)); + + final Set capturedMarkers = + verify(markers.addMarkers(captureAny)).captured[0] as Set; + + 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... From 766d69051a3e814ee742dd12ee632b857ca74752 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 18:57:28 +0700 Subject: [PATCH 35/40] Add author --- packages/google_maps_flutter/google_maps_flutter_web/AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS b/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS index 493a0b4ef9c2..16db024a2168 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS +++ b/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy Anton Borries Alex Li Rahul Raj <64.rahulraj@gmail.com> +Nguyễn Phúc Lợi From d85e6b832fc20d4cc10b5b411208867b044e17d2 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 19:06:20 +0700 Subject: [PATCH 36/40] Fix error syntax --- .../google_maps_flutter_web/lib/src/my_location.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart index 43a31ea52f6f..41ea57b87556 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart @@ -182,4 +182,9 @@ class MyLocationButton { _btnChild.disabled = true; _imageChild.style.backgroundPosition = '-24px 0px'; } + + /// Check button disabled or enabled + bool isDisabled() { + return _btnChild.disabled; + } } From f99bce42ccc9f34da93c4eaa0c3c4172c42b0947 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 19:08:44 +0700 Subject: [PATCH 37/40] Revert code --- .../google_maps_flutter_web/example/web/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index d1d27adb4a57..3121d189b913 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -6,7 +6,7 @@ Browser Tests - + From 9755380dd1b2fbf2859f05085247e6bb5632ba3b Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 1 Jan 2023 19:15:24 +0700 Subject: [PATCH 38/40] Fix lint --- .../example/integration_test/google_maps_controller_test.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 60852d0cda01..a69dba56ae2a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -600,9 +600,6 @@ void main() { 'My location button should be disable when dont have permission access to location', (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( From 42e307a020344e77d7027910a83bbebb7262079d Mon Sep 17 00:00:00 2001 From: nploi Date: Wed, 11 Jan 2023 21:11:23 +0700 Subject: [PATCH 39/40] Fix linter --- .../google_maps_flutter_web/lib/src/my_location.dart | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart index 41ea57b87556..e776fb120181 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/my_location.dart @@ -54,9 +54,8 @@ Future _centerMyCurrentLocation( void _addMyLocationButton(gmaps.GMap map, GoogleMapController controller) { controller._myLocationButton = MyLocationButton(); controller._myLocationButton?.addClickListener( - () async { + (_) async { controller._myLocationButton?.startAnimation(); - await _centerMyCurrentLocation(controller); }, ); @@ -145,10 +144,8 @@ class MyLocationButton { HtmlElement get getButton => _controlDiv; /// Add click listener - void addClickListener(Function onLick) { - _btnChild.addEventListener('click', (_) { - onLick(); - }); + void addClickListener(EventListener? listener) { + _btnChild.addEventListener('click', listener); } /// Reset animation From 927024758a8352737c6c2bb234bf553184b805d0 Mon Sep 17 00:00:00 2001 From: nploi Date: Sun, 29 Jan 2023 00:02:34 +0700 Subject: [PATCH 40/40] Fix linter --- .../example/integration_test/google_maps_controller_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index a69dba56ae2a..038d1256dd5c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -616,7 +616,7 @@ void main() { when(mockGeolocation.getCurrentPosition( timeout: const Duration(seconds: 30))) .thenAnswer( - (_) async => throw 'permission denied', + (_) async => throw Exception('permission denied'), ); when(mockGeolocation.watchPosition()).thenAnswer((_) {