// Automatic FlutterFlow imports
import '/backend/[Link]';
import '/backend/schema/structs/[Link]';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/[Link]'; // Imports other custom widgets
import '/custom_code/actions/[Link]'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/[Link]';
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'dart:html';
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui';
import 'package:google_maps_flutter/google_maps_flutter.dart' as google_maps_flutter;
import '/flutter_flow/lat_lng.dart' as latlng;
import 'package:location/[Link]';
export 'dart:async' show Completer;
export 'package:google_maps_flutter/google_maps_flutter.dart' hide LatLng;
export '/flutter_flow/lat_lng.dart' show LatLng;
class FirestoreMapNEW extends StatefulWidget {
const FirestoreMapNEW({
Key? key,
[Link],
[Link],
[Link], // Changed from places to mapdata
required [Link],
required [Link],
required [Link],
required [Link],
required [Link],
required [Link],
required [Link],
[Link],
}) : super(key: key);
final double? width;
final double? height;
final List<MapDataRecord>? mapdata; // Changed from PlaceRecord to MapDataRecord
final bool showLocation;
final bool showCompass;
final bool showMapToolbar;
final bool showTraffic;
final bool allowZoom;
final bool showZoomControls;
final double defaultZoom;
final Future Function(MapDataRecord? mapdataRow)? onClickMarker;
@override
State<FirestoreMapNEW> createState() => _FirestoreMapState();
}
class _FirestoreMapState extends State<FirestoreMapNEW> {
Completer<google_maps_flutter.GoogleMapController> _controller = Completer();
Map<String, google_maps_flutter.BitmapDescriptor> _customIcons = {};
Set<google_maps_flutter.Marker> _markers = {};
google_maps_flutter.LatLng? _center;
bool _showCustomInfoWindow = false;
MapDataRecord? _selectedData; // Changed from PlaceRecord to MapDataRecord
Offset _infoWindowOffset = [Link];
@override
void initState() {
[Link]();
_initializeLocation();
_loadMarkerIcons();
Future<void> _initializeLocation() async {
Location location = Location();
bool _serviceEnabled;
PermissionStatus _permissionGranted;
LocationData _locationData;
_serviceEnabled = await [Link]();
if (!_serviceEnabled) {
_serviceEnabled = await [Link]();
if (!_serviceEnabled) {
return;
_permissionGranted = await [Link]();
if (_permissionGranted == [Link]) {
_permissionGranted = await [Link]();
if (_permissionGranted != [Link]) {
return;
_locationData = await [Link]();
setState(() {
_center = google_maps_flutter.LatLng(
_locationData.latitude!, _locationData.longitude!);
});
_updateMarkers();
Future<void> _loadMarkerIcons() async {
Set<String?> uniqueIconPaths =
[Link]?.map((data) => [Link]).toSet() ?? {}; // Updated to mapdata
for (String? path in uniqueIconPaths) {
if (path != null && [Link]) {
if ([Link]("https")) {
Uint8List? imageData = await loadNetworkImage(path);
if (imageData != null) {
google_maps_flutter.BitmapDescriptor descriptor =
await google_maps_flutter.[Link](imageData);
_customIcons[path] = descriptor;
} else {
google_maps_flutter.BitmapDescriptor descriptor =
await google_maps_flutter.[Link](
const ImageConfiguration(devicePixelRatio: 2.5),
"assets/images/$path",
);
_customIcons[path] = descriptor;
_updateMarkers();
Future<Uint8List?> loadNetworkImage(String path) async {
final completer = Completer<ImageInfo>();
var image = NetworkImage(path);
[Link](const ImageConfiguration()).addListener(ImageStreamListener(
(ImageInfo info, bool _) => [Link](info)));
final imageInfo = await [Link];
final byteData =
await [Link](format: [Link]);
return byteData?.buffer.asUint8List();
void _updateMarkers() {
setState(() {
_markers = _createMarkers();
});
void _onMapCreated(google_maps_flutter.GoogleMapController controller) {
_controller.complete(controller);
Set<google_maps_flutter.Marker> _createMarkers() {
var tmp = <google_maps_flutter.Marker>{};
for (int i = 0; i < ([Link] ?? []).length; i++) { // Updated to mapdata
var data = [Link]?[i];
final [Link] coordinates =
[Link](data?.latitude ?? 0.0, data?.longitude ?? 0.0);
final google_maps_flutter.LatLng googleMapsLatLng =
google_maps_flutter.LatLng(
[Link], [Link]);
google_maps_flutter.BitmapDescriptor icon = _customIcons[data?.icon] ??
google_maps_flutter.[Link];
final google_maps_flutter.Marker marker = google_maps_flutter.Marker(
markerId:
google_maps_flutter.MarkerId('${data?.address ?? "Marker"}_$i'),
position: googleMapsLatLng,
icon: icon,
onTap: () async {
setState(() {
_selectedData = data;
_showCustomInfoWindow = true;
_infoWindowOffset = Offset(
[Link](context).[Link] / 2 - 100,
[Link](context).[Link] / 2 - 150,
);
});
final callback = [Link];
if (callback != null) {
await callback(data);
},
);
[Link](marker);
return tmp;
}
@override
Widget build(BuildContext context) {
return _center == null
? Center(child: CircularProgressIndicator())
: Stack(
children: [
google_maps_flutter.GoogleMap(
onMapCreated: _onMapCreated,
zoomGesturesEnabled: [Link],
zoomControlsEnabled: [Link],
myLocationEnabled: [Link],
compassEnabled: [Link],
mapToolbarEnabled: [Link],
trafficEnabled: [Link],
initialCameraPosition: google_maps_flutter.CameraPosition(
target: _center!,
zoom: [Link],
),
markers: _markers,
onTap: (position) {
final latLng = google_maps_flutter.LatLng(
[Link], [Link]);
setState(() {
_center = latLng; // Recenter the map based on tapped position
_showCustomInfoWindow = false; // Hide info window
});
},
),
if (_showCustomInfoWindow && _selectedData != null)
Positioned(
left: _infoWindowOffset.dx,
top: _infoWindowOffset.dy,
child: CustomInfoWindow(
data: _selectedData!,
onAddToRoute: (data) {
// Add your add-to-route logic here
print('Added to route: ${[Link]}');
},
),
),
],
);
class CustomInfoWindow extends StatelessWidget {
final MapDataRecord data; // Updated from PlaceRecord to MapDataRecord
final Function(MapDataRecord data) onAddToRoute;
CustomInfoWindow({required [Link], required [Link]});
@override
Widget build(BuildContext context) {
return Container(
width: 200,
padding: [Link](8.0),
decoration: BoxDecoration(
color: [Link],
borderRadius: [Link](8.0),
boxShadow: [
BoxShadow(
color: Colors.black26,
offset: Offset(0, 2),
blurRadius: 6.0,
),
],
),
child: Column(
mainAxisSize: [Link],
children: [
[Link] != null
? [Link]([Link]!, width: 180, height: 100, fit: [Link])
: Container(),
SizedBox(height: 8.0),
Text(
[Link] ?? '',
style: TextStyle(fontWeight: [Link]),
),
SizedBox(height: 4.0),
Text([Link] ?? ''),
SizedBox(height: 8.0),
ElevatedButton(
onPressed: () => onAddToRoute(data),
child: Text('Add to Route'),
),
],
),
);