import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:anyway/modules/landmark_card.dart'; import 'package:anyway/structs/landmark.dart'; import 'package:anyway/structs/trip.dart'; class LandmarksOverview extends StatefulWidget { final Trip? trip; const LandmarksOverview({super.key, this.trip}); @override State createState() => _LandmarksOverviewState(); } class _LandmarksOverviewState extends State { @override Widget build(BuildContext context) { return ListenableBuilder( listenable: widget.trip!, builder: (BuildContext context, Widget? child) { Trip trip = widget.trip!; log("Trip ${trip.uuid} ${trip.landmarks.length} landmarks"); List children; if (trip.uuid != 'pending' && trip.uuid != 'error') { log("Trip ${trip.uuid} ${trip.landmarks.length} landmarks"); if (trip.landmarks.length <= 1) { children = [ const Text("No landmarks in this trip"), ]; } else { children = [ landmarksWithSteps(), saveButton(), ]; } } else if(trip.uuid == 'pending') { // the trip is still being fetched from the api children = [Center(child: CircularProgressIndicator())]; } else { // trip.uuid == 'error' // show the error raised by the api // String error = children = [ const Icon( Icons.error_outline, color: Colors.red, size: 60, ), Padding( padding: const EdgeInsets.only(top: 16), child: Text('Error: ${trip.errorDescription}'), ), ]; } return Column( children: children, ); }, ); } Widget saveButton() => ElevatedButton( onPressed: () async { Trip? trip = await widget.trip; SharedPreferences prefs = await SharedPreferences.getInstance(); trip?.toPrefs(prefs); }, child: const Text('Save'), ); Widget landmarksWithSteps() { return ListenableBuilder( listenable: widget.trip!, builder: (BuildContext context, Widget? child) { List children = []; for (Landmark landmark in widget.trip!.landmarks) { children.add( Dismissible( key: ValueKey(landmark.hashCode), child: LandmarkCard(landmark), dismissThresholds: {DismissDirection.endToStart: 0.6}, onDismissed: (direction) { // Remove the item from the data source. log(landmark.name); setState(() { widget.trip!.removeLandmark(landmark); }); // Then show a snackbar. ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text("We won't show ${landmark.name} again"))); }, background: Container(color: Colors.red), secondaryBackground: Container( color: Colors.red, child: Icon( Icons.delete, color: Colors.white, ), padding: EdgeInsets.all(15), alignment: Alignment.centerRight, ), ) ); if (landmark.next != null) { Widget step = stepBetweenLandmarks(landmark, landmark.next!); children.add(step); } } return Column( children: children ); }, ); } } Widget stepBetweenLandmarks(Landmark current, Landmark next) { int timeRounded = 5 * (current.tripTime?.inMinutes ?? 0) ~/ 5; // ~/ is integer division (rounding) return Container( margin: EdgeInsets.all(10), padding: EdgeInsets.all(10), decoration: BoxDecoration( border: Border( left: BorderSide(width: 3.0, color: Colors.black), ), // gradient: LinearGradient( // begin: Alignment.topLeft, // end: Alignment.bottomRight, // colors: [Colors.grey, Colors.white, Colors.white], // ), ), child: Row( children: [ Column( children: [ Icon(Icons.directions_walk), Text("~$timeRounded min", style: TextStyle(fontSize: 10)), ], ), Spacer(), ElevatedButton( onPressed: () { // Open navigation instructions }, child: Row( children: [ Icon(Icons.directions), Text("Directions"), ], ), ) ], ), ); }