TimeTracker/lib/pages/MapPage.dart
2025-07-22 12:17:11 -07:00

215 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:libacflutter/Constants.dart';
import 'package:timetrack/data.dart';
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
class MapPage extends StatefulWidget {
const MapPage({super.key});
@override
State<StatefulWidget> createState() {
return _MapPage();
}
}
class _MapPage extends State<MapPage> {
MapController controller = MapController();
LatLng initialPosition = LatLng(0, 0);
List<LatLng> PointMap = [];
List<Marker> Markers = [];
bool autorefresh = true;
late FMTCTileProvider _tileProvider;
@override
void initState() {
SessionData.Calls.MapCallback = call;
super.initState();
}
void call() {
if (autorefresh) {
didChangeDependencies();
}
setState(() {});
}
@override
void didChangeDependencies() {
if (!SessionData.isWeb) {
_tileProvider = FMTCTileProvider(
stores: const {'mapStore': BrowseStoreStrategy.readUpdateCreate},
);
}
PointMap = [];
Markers = [];
var firstPos = SessionData.positions[0];
initialPosition = LatLng(firstPos.latitude, firstPos.longitude);
for (var position in SessionData.positions) {
PointMap.add(LatLng(position.latitude, position.longitude));
}
print("Total trips: ${SessionData.Trips.length}");
for (var trip in SessionData.Trips) {
for (var dropOff in trip.DropOffLocations) {
Markers.add(
Marker(
point: LatLng(dropOff.latitude, dropOff.longitude),
child: Stack(
children: GetDropOffWidgets(
dropOff,
trip.DropOffLocations.indexOf(dropOff) + 1,
SessionData.Trips.indexOf(trip) + 1,
),
),
),
);
}
for (var dropOff in trip.deliveries) {
if (dropOff.endLocation == null) continue;
Markers.add(
Marker(
point: LatLng(
dropOff.endLocation!.latitude,
dropOff.endLocation!.longitude,
),
child: Stack(
children: GetDropOffWidgets(
dropOff.endLocation!,
trip.deliveries.indexOf(dropOff) + 1,
SessionData.Trips.indexOf(trip) + 1,
),
),
),
);
print("Marker added");
}
if (SessionData.IsOnTheClock) {
Markers.add(
Marker(
point: GetCurrentPosition(),
child: Stack(
children: [
Icon(Icons.circle_outlined, color: Colors.lightBlue, size: 28),
Icon(Icons.circle, color: Colors.blue, size: 24),
],
),
),
);
}
}
setState(() {});
super.didChangeDependencies();
}
LatLng GetCurrentPosition() {
SmallPosition pos = SessionData.positions.last;
return LatLng(pos.latitude, pos.longitude);
}
List<Widget> GetDropOffWidgets(
SmallPosition pos,
int dropOffNumber,
int tripNumber,
) {
return [
IconButton(
onPressed: () {
showDialog(
context: context,
builder: (builder) {
return AlertDialog(
title: Text("Trip #${tripNumber}; DropOff #${dropOffNumber}"),
);
},
);
},
icon: Icon(Icons.location_on_rounded, size: 24, color: Colors.red),
),
];
}
@override
void dispose() {
SessionData.Calls.MapCallback = null;
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Time Tracker - Map View"),
backgroundColor: LibACFlutterConstants.TITLEBAR_COLOR,
actions: [
IconButton(
onPressed: () async {
didChangeDependencies();
},
icon: Icon(Icons.refresh),
),
IconButton(
onPressed: () {
autorefresh = !autorefresh;
},
icon:
autorefresh
? Icon(Icons.play_disabled)
: Icon(Icons.play_circle),
),
],
),
body: GestureDetector(
onTap: FocusScope.of(context).unfocus,
child: SafeArea(
child: FlutterMap(
mapController: controller,
options: MapOptions(
minZoom: 1,
maxZoom: 30,
initialZoom: 15,
initialCenter:
SessionData.IsOnTheClock
? GetCurrentPosition()
: initialPosition,
keepAlive: false,
),
children: [
TileLayer(
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
userAgentPackageName: "dev.zontreck.timetrack",
tileProvider: SessionData.isWeb ? null : _tileProvider,
),
PolylineLayer(
polylines: [
Polyline(
points: PointMap,
color: Colors.blue,
borderStrokeWidth: 8,
borderColor: Colors.blue,
),
],
),
MarkerLayer(markers: Markers),
RichAttributionWidget(
attributions: [
TextSourceAttribution('OpenStreetMap contributors'),
],
),
],
),
),
),
);
}
}