revamp new trip flow
This commit is contained in:
		| @@ -32,7 +32,6 @@ List<Widget> landmarksList(Trip trip) { | ||||
|         onDismissed: (direction) { | ||||
|           log('Removing ${landmark.name}'); | ||||
|           trip.removeLandmark(landmark); | ||||
|           // Then show a snackbar | ||||
|  | ||||
|           rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|             SnackBar(content: Text("We won't show ${landmark.name} again")) | ||||
|   | ||||
| @@ -79,7 +79,7 @@ class _MapWidgetState extends State<MapWidget> { | ||||
|       cloudMapId: MAP_ID, | ||||
|       mapToolbarEnabled: false, | ||||
|       zoomControlsEnabled: false, | ||||
|  | ||||
|       myLocationEnabled: true, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -18,10 +18,6 @@ class _LandmarkCardState extends State<LandmarkCard> { | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     ThemeData theme = Theme.of(context); | ||||
|     ButtonStyle buttonStyle = TextButton.styleFrom( | ||||
|       backgroundColor: Colors.orange, | ||||
|       fixedSize: Size.fromHeight(20) | ||||
|     ); | ||||
|     return Container( | ||||
|       height: 160, | ||||
|       child: Card( | ||||
| @@ -88,21 +84,21 @@ class _LandmarkCardState extends State<LandmarkCard> { | ||||
|                         // show the type, the website, and the wikipedia link as buttons/labels in a row | ||||
|                         children: [ | ||||
|                           TextButton.icon( | ||||
|                             style: buttonStyle, | ||||
|                             style: theme.iconButtonTheme.style, | ||||
|                             onPressed: () {}, | ||||
|                             icon: widget.landmark.type.icon, | ||||
|                             label: Text(widget.landmark.type.name), | ||||
|                           ), | ||||
|                           if (widget.landmark.duration != null && widget.landmark.duration!.inMinutes > 0) | ||||
|                             TextButton.icon( | ||||
|                               style: buttonStyle, | ||||
|                               style: theme.iconButtonTheme.style, | ||||
|                               onPressed: () {}, | ||||
|                               icon: Icon(Icons.hourglass_bottom), | ||||
|                               label: Text('${widget.landmark.duration!.inMinutes} minutes'), | ||||
|                             ), | ||||
|                           if (widget.landmark.websiteURL != null) | ||||
|                             TextButton.icon( | ||||
|                               style: buttonStyle, | ||||
|                               style: theme.iconButtonTheme.style, | ||||
|                               onPressed: () async { | ||||
|                                 // open a browser with the website link | ||||
|                                 await launchUrl(Uri.parse(widget.landmark.websiteURL!)); | ||||
| @@ -112,7 +108,7 @@ class _LandmarkCardState extends State<LandmarkCard> { | ||||
|                             ), | ||||
|                           if (widget.landmark.wikipediaURL != null) | ||||
|                             TextButton.icon( | ||||
|                               style: buttonStyle, | ||||
|                               style: theme.iconButtonTheme.style, | ||||
|                               onPressed: () async { | ||||
|                                 // open a browser with the wikipedia link | ||||
|                                 await launchUrl(Uri.parse(widget.landmark.wikipediaURL!)); | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import 'package:anyway/layout.dart'; | ||||
| import 'package:anyway/main.dart'; | ||||
| import 'package:anyway/structs/preferences.dart'; | ||||
| import 'package:anyway/structs/trip.dart'; | ||||
| import 'package:anyway/utils/fetch_trip.dart'; | ||||
| @@ -8,8 +9,12 @@ import 'package:flutter/material.dart'; | ||||
|  | ||||
| class NewTripButton extends StatefulWidget { | ||||
|   final Trip trip; | ||||
|   final UserPreferences preferences; | ||||
|  | ||||
|   const NewTripButton({required this.trip}); | ||||
|   const NewTripButton({ | ||||
|     required this.trip, | ||||
|     required this.preferences, | ||||
|     }); | ||||
|  | ||||
|   @override | ||||
|   State<NewTripButton> createState() => _NewTripButtonState(); | ||||
| @@ -23,42 +28,39 @@ class _NewTripButtonState extends State<NewTripButton> { | ||||
|       listenable: widget.trip, | ||||
|       builder: (BuildContext context, Widget? child) { | ||||
|         if (widget.trip.landmarks.isEmpty){ | ||||
|           // Fallback if the trip setup is lagging behind | ||||
|           // This should in theory never happen | ||||
|           return Container(); | ||||
|         } | ||||
|         return FloatingActionButton.extended( | ||||
|           onPressed: () async { | ||||
|             Future<UserPreferences> preferences = loadUserPreferences(); | ||||
|             Trip trip = widget.trip; | ||||
|             fetchTrip(trip, preferences); | ||||
|             Navigator.of(context).push( | ||||
|               MaterialPageRoute( | ||||
|                 builder: (context) => BasePage(mainScreen: "map", trip: trip) | ||||
|               ) | ||||
|             ); | ||||
|           }, | ||||
|           icon: Icon(Icons.add), | ||||
|           label: FutureBuilder( | ||||
|             future: widget.trip.cityName, | ||||
|             builder: (context, snapshot) { | ||||
|               if (snapshot.connectionState == ConnectionState.done) { | ||||
|                 return AutoSizeText( | ||||
|                   'New trip to ${snapshot.data.toString()}', | ||||
|                   style: TextStyle(fontSize: 18), | ||||
|                   maxLines: 2, | ||||
|                 ); | ||||
|               } else { | ||||
|                 return AutoSizeText( | ||||
|                   'New trip to ...', | ||||
|                   style: TextStyle(fontSize: 18), | ||||
|                   maxLines: 2, | ||||
|                 ); | ||||
|               } | ||||
|             }, | ||||
|           ) | ||||
|         ); | ||||
|          | ||||
|       }  | ||||
|           onPressed: onPressed, | ||||
|           icon: const Icon(Icons.add), | ||||
|           label: AutoSizeText('Start planning!'), | ||||
|         );  | ||||
|       } | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   void onPressed() async { | ||||
|     // Check that the preferences are valid | ||||
|     UserPreferences preferences = widget.preferences; | ||||
|     if (preferences.nature.value == 0 && preferences.shopping.value == 0 && preferences.sightseeing.value == 0){ | ||||
|       rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|         SnackBar(content: Text("Please specify at least one preference")) | ||||
|       ); | ||||
|     } else if (preferences.maxTime.value == 0){ | ||||
|       rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|         SnackBar(content: Text("Please choose a longer duration")) | ||||
|       ); | ||||
|     } else { | ||||
|       Trip trip = widget.trip; | ||||
|       fetchTrip(trip, widget.preferences); | ||||
|       Navigator.of(context).push( | ||||
|         MaterialPageRoute( | ||||
|           builder: (context) => BasePage(mainScreen: "map", trip: trip) | ||||
|         ) | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,9 +6,12 @@ import 'dart:developer'; | ||||
|  | ||||
| import 'package:anyway/structs/trip.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
|  | ||||
| class NewTripLocationSearch extends StatefulWidget { | ||||
|   Future<SharedPreferences> prefs = SharedPreferences.getInstance(); | ||||
|   Trip trip; | ||||
|    | ||||
|   NewTripLocationSearch( | ||||
|     this.trip, | ||||
|   ); | ||||
| @@ -45,20 +48,51 @@ class _NewTripLocationSearchState extends State<NewTripLocationSearch> { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return SearchBar( | ||||
|       hintText: 'Enter a city name or long press on the map.', | ||||
|       onSubmitted: setTripLocation, | ||||
|       controller: _controller, | ||||
|       leading: Icon(Icons.search), | ||||
|       trailing: [ElevatedButton( | ||||
|   late Widget locationSearchBar = SearchBar( | ||||
|     hintText: 'Enter a city name or long press on the map.', | ||||
|     onSubmitted: setTripLocation, | ||||
|     controller: _controller, | ||||
|     leading: Icon(Icons.search), | ||||
|     trailing: [ | ||||
|       ElevatedButton( | ||||
|         onPressed: () { | ||||
|           setTripLocation(_controller.text); | ||||
|         }, | ||||
|         child: Text('Search'), | ||||
|       ),] | ||||
|       ) | ||||
|     ] | ||||
|   ); | ||||
|  | ||||
|  | ||||
|   late Widget useCurrentLocationButton = ElevatedButton( | ||||
|     onPressed: () { | ||||
|       // setTripLocation(location); | ||||
|       // TODO: get current location | ||||
|     }, | ||||
|     child: Text('Use current location'), | ||||
|   ); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return FutureBuilder( | ||||
|       future: widget.prefs, | ||||
|       builder: (context, snapshot) { | ||||
|         if (snapshot.hasData) { | ||||
|           final useLocation = snapshot.data!.getBool('useLocation') ?? false; | ||||
|           if (useLocation) { | ||||
|             return Column( | ||||
|               children: [ | ||||
|                 locationSearchBar, | ||||
|                 useCurrentLocationButton, | ||||
|               ], | ||||
|             ); | ||||
|           } else { | ||||
|             return locationSearchBar; | ||||
|           } | ||||
|         } else { | ||||
|           return locationSearchBar; | ||||
|         } | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| // A map that allows the user to select a location for a new trip. | ||||
| import 'dart:developer'; | ||||
|  | ||||
| @@ -22,7 +21,7 @@ class NewTripMap extends StatefulWidget { | ||||
| } | ||||
|  | ||||
| class _NewTripMapState extends State<NewTripMap> { | ||||
|   final CameraPosition _cameraPosition = CameraPosition( | ||||
|   final CameraPosition _cameraPosition = const CameraPosition( | ||||
|     target: LatLng(48.8566, 2.3522), | ||||
|     zoom: 11.0, | ||||
|   ); | ||||
| @@ -70,7 +69,6 @@ class _NewTripMapState extends State<NewTripMap> { | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     widget.trip.addListener(updateTripDetails); | ||||
| @@ -82,6 +80,8 @@ class _NewTripMapState extends State<NewTripMap> { | ||||
|       cloudMapId: MAP_ID, | ||||
|       mapToolbarEnabled: false, | ||||
|       zoomControlsEnabled: false, | ||||
|       // TODO: should be loaded from the sharedprefs | ||||
|       myLocationEnabled: true, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										41
									
								
								frontend/lib/modules/new_trip_options_button.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								frontend/lib/modules/new_trip_options_button.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| import 'package:anyway/pages/new_trip_preferences.dart'; | ||||
| import 'package:anyway/structs/trip.dart'; | ||||
| import 'package:auto_size_text/auto_size_text.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
|  | ||||
|  | ||||
| class NewTripOptionsButton extends StatefulWidget { | ||||
|   final Trip trip; | ||||
|  | ||||
|   const NewTripOptionsButton({required this.trip}); | ||||
|  | ||||
|   @override | ||||
|   State<NewTripOptionsButton> createState() => _NewTripOptionsButtonState(); | ||||
| } | ||||
|  | ||||
| class _NewTripOptionsButtonState extends State<NewTripOptionsButton> { | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return ListenableBuilder( | ||||
|       listenable: widget.trip, | ||||
|       builder: (BuildContext context, Widget? child) { | ||||
|         if (widget.trip.landmarks.isEmpty){ | ||||
|           return Container(); | ||||
|         } | ||||
|         return FloatingActionButton.extended( | ||||
|           onPressed: () async { | ||||
|             Navigator.of(context).push( | ||||
|               MaterialPageRoute( | ||||
|                 builder: (context) => NewTripPreferencesPage(trip: widget.trip) | ||||
|               ) | ||||
|             ); | ||||
|           }, | ||||
|           icon: const Icon(Icons.add), | ||||
|           label: const AutoSizeText('Set preferences') | ||||
|         );  | ||||
|       } | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -16,20 +16,23 @@ class OnboardingCard extends StatelessWidget { | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     Color baseColor = Theme.of(context).primaryColor; | ||||
|     Color baseColor = Theme.of(context).colorScheme.secondary; | ||||
|     // have a different color for each card, incrementing the hue | ||||
|     Color currentColor = baseColor.withAlpha(baseColor.alpha - index * 30); | ||||
|     return Container( | ||||
|       color: currentColor, | ||||
|       alignment: Alignment.center, | ||||
|       child: Padding( | ||||
|         padding: EdgeInsets.all(20), | ||||
|         child: Column( | ||||
|           mainAxisAlignment: MainAxisAlignment.center, | ||||
|           children: [ | ||||
|             Text( | ||||
|               title, | ||||
|               style: TextStyle( | ||||
|                 fontSize: 24, | ||||
|                 fontWeight: FontWeight.bold, | ||||
|                 color: Colors.white, | ||||
|               ), | ||||
|             ), | ||||
|             Padding(padding: EdgeInsets.only(top: 20)), | ||||
| @@ -44,7 +47,8 @@ class OnboardingCard extends StatelessWidget { | ||||
|                 fontSize: 16, | ||||
|               ), | ||||
|             ), | ||||
|           ], | ||||
|  | ||||
|           ] | ||||
|         ), | ||||
|       ) | ||||
|     ); | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import 'package:anyway/constants.dart'; | ||||
| import 'package:anyway/structs/landmark.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
|  | ||||
| @@ -51,9 +52,7 @@ class ThemedMarker extends StatelessWidget { | ||||
|         children: [ | ||||
|           Container( | ||||
|             decoration: BoxDecoration( | ||||
|               gradient: LinearGradient( | ||||
|                 colors: [Colors.red, Colors.yellow] | ||||
|               ), | ||||
|               gradient: APP_GRADIENT, | ||||
|               shape: BoxShape.circle, | ||||
|               border: Border.all(color: Colors.black, width: 5), | ||||
|             ), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user