Files
wheres-my-sign/lib/main.dart

231 lines
6.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:wheres_my_sign/models/property.dart';
import 'package:wheres_my_sign/widgets/custom_dialog_box.dart';
Future<void> main() async {
await dotenv.load(fileName: ".env");
runApp(SignLocatorApp());
}
class SignLocatorApp extends StatelessWidget {
const SignLocatorApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sign Locator',
theme: ThemeData(primarySwatch: Colors.blue),
home: SignMapScreen(),
);
}
}
class SignMapScreen extends StatefulWidget {
const SignMapScreen({super.key});
@override
SignMapScreenState createState() => SignMapScreenState();
}
class SignMapScreenState extends State<SignMapScreen> {
GoogleMapController? mapController;
Set<Marker> markers = {};
LatLng _initialPosition = const LatLng(37.7749, -122.4194); // Default: SF
BitmapDescriptor customIcon = BitmapDescriptor.defaultMarker;
void customMarker() {
BitmapDescriptor.asset(
ImageConfiguration(),
'assets/icons/sign_marker.png',
).then((icon) {
setState(() {
customIcon = icon;
});
});
}
@override
void initState() {
super.initState();
_requestPermissions();
customMarker();
}
Future<void> _requestPermissions() async {
await Permission.locationWhenInUse.request();
_goToUserLocation();
}
Future<void> _goToUserLocation() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) return;
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied ||
permission == LocationPermission.deniedForever) {
permission = await Geolocator.requestPermission();
}
Position position = await Geolocator.getCurrentPosition();
_initialPosition = LatLng(position.latitude, position.longitude);
mapController?.animateCamera(CameraUpdate.newLatLng(_initialPosition));
}
void _addMarker() async {
Position position = await Geolocator.getCurrentPosition();
final markerId = MarkerId(DateTime.now().toString());
final newMarker = Marker(
markerId: markerId,
position: LatLng(position.latitude, position.longitude),
infoWindow: InfoWindow(title: 'Sign Location'),
icon: customIcon,
);
setState(() {
markers.add(newMarker);
});
}
// return something like this:
// Property {
// address: "1234 Smith St",
// latitude: 37.7749,
// longitude: -122.4194,
// signLocations: [LatLng(37.77, -122.42), LatLng(37.775, -122.41)],
// }
void _addProperty() async {
final Property? newProperty = await showDialog<Property>(
context: context,
builder: (BuildContext context) {
return CustomDialogBox(
title: "Show A Property",
descriptions: "Let's show a new property!",
text: "Yes",
);
},
);
if (newProperty != null) {
setState(() {
// 🟢 Main property marker
markers.add(
Marker(
markerId: MarkerId(
'property_${newProperty.latitude}_${newProperty.longitude}',
),
position: LatLng(newProperty.latitude, newProperty.longitude),
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueGreen,
),
infoWindow: InfoWindow(title: newProperty.address),
),
);
// 🔴 Sign location markers
for (int i = 0; i < newProperty.signLocations.length; i++) {
final LatLng signLocation = newProperty.signLocations[i];
markers.add(
Marker(
markerId: MarkerId('sign_$i'),
position: signLocation,
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueRed,
),
infoWindow: InfoWindow(title: 'Sign ${i + 1}'),
),
);
}
});
// Optionally: Move camera to property location
mapController?.animateCamera(
CameraUpdate.newLatLngZoom(
LatLng(newProperty.latitude, newProperty.longitude),
14.0,
),
);
}
}
// void _addProperty() async {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return CustomDialogBox(
// title: "Show A Property",
// descriptions: "Let's show a new property!",
// text: "Yes",
// );
// },
// );
// }
void _clearMarkers() {
setState(() {
markers.clear();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: SizedBox(
width: MediaQuery.of(context).size.width,
child: Image.asset(
'assets/app_title.png', // Replace with your image path
fit: BoxFit.contain, // Adjust the height as needed
),
),
),
body: GoogleMap(
zoomGesturesEnabled: true,
scrollGesturesEnabled: true,
tiltGesturesEnabled: true,
rotateGesturesEnabled: true,
myLocationButtonEnabled: true,
compassEnabled: true,
mapType: MapType.normal,
onMapCreated: (controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 14,
),
myLocationEnabled: true,
markers: markers,
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _addProperty,
backgroundColor: Colors.green,
tooltip: 'Add new property',
child: Icon(Icons.add_home),
),
SizedBox(height: 12),
FloatingActionButton(
onPressed: _addMarker,
tooltip: 'Drop Pin',
child: Icon(Icons.add_location),
),
SizedBox(height: 12),
FloatingActionButton(
onPressed: _clearMarkers,
backgroundColor: Colors.red,
tooltip: 'Clear Pins',
child: Icon(Icons.clear),
),
],
),
);
}
}