Usability and styling #24
| @@ -34,26 +34,19 @@ ThemeData APP_THEME = ThemeData( | ||||
|  | ||||
|  | ||||
|   textButtonTheme: TextButtonThemeData( | ||||
|      | ||||
|     style: TextButton.styleFrom( | ||||
|       backgroundColor: PRIMARY_COLOR, | ||||
|       textStyle: TextStyle( | ||||
|         color: Colors.black, | ||||
|       ), | ||||
|         color: Colors.red | ||||
|       ) | ||||
|     ), | ||||
|   ), | ||||
|  | ||||
|   iconButtonTheme: IconButtonThemeData( | ||||
|     style: ButtonStyle( | ||||
|       backgroundColor: MaterialStateProperty.all(PRIMARY_COLOR), | ||||
|     ) | ||||
|   ), | ||||
|    | ||||
|   buttonTheme: ButtonThemeData( | ||||
|     buttonColor: PRIMARY_COLOR, | ||||
|     textTheme: ButtonTextTheme.primary, | ||||
|   ), | ||||
|  | ||||
|    | ||||
| ); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,22 +6,23 @@ import 'package:flutter/material.dart'; | ||||
| import 'package:anyway/structs/landmark.dart'; | ||||
| import 'package:anyway/structs/trip.dart'; | ||||
| import 'package:google_maps_flutter/google_maps_flutter.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:widget_to_marker/widget_to_marker.dart'; | ||||
|  | ||||
|  | ||||
| class MapWidget extends StatefulWidget { | ||||
| class CurrentTripMap extends StatefulWidget { | ||||
|  | ||||
|   final Trip? trip; | ||||
|  | ||||
|   MapWidget({ | ||||
|   CurrentTripMap({ | ||||
|     this.trip | ||||
|   }); | ||||
|  | ||||
|   @override | ||||
|   State<MapWidget> createState() => _MapWidgetState(); | ||||
|   State<CurrentTripMap> createState() => _CurrentTripMapState(); | ||||
| } | ||||
|  | ||||
| class _MapWidgetState extends State<MapWidget> { | ||||
| class _CurrentTripMapState extends State<CurrentTripMap> { | ||||
|   late GoogleMapController mapController; | ||||
|  | ||||
|   CameraPosition _cameraPosition = CameraPosition( | ||||
| @@ -67,9 +68,27 @@ class _MapWidgetState extends State<MapWidget> { | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     widget.trip?.addListener(setMapMarkers); | ||||
|     Future<SharedPreferences> preferences = SharedPreferences.getInstance(); | ||||
|  | ||||
|     return FutureBuilder( | ||||
|       future: preferences, | ||||
|       builder: (context, snapshot) { | ||||
|         if (snapshot.hasData) { | ||||
|           SharedPreferences prefs = snapshot.data as SharedPreferences; | ||||
|           bool useLocation = prefs.getBool('useLocation') ?? true; | ||||
|           return _buildMap(useLocation); | ||||
|         } else { | ||||
|           return const CircularProgressIndicator(); | ||||
|         } | ||||
|       } | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Widget _buildMap(bool useLocation) { | ||||
|     return GoogleMap( | ||||
|       onMapCreated: _onMapCreated, | ||||
|       initialCameraPosition: _cameraPosition, | ||||
| @@ -79,7 +98,9 @@ class _MapWidgetState extends State<MapWidget> { | ||||
|       cloudMapId: MAP_ID, | ||||
|       mapToolbarEnabled: false, | ||||
|       zoomControlsEnabled: false, | ||||
|       myLocationEnabled: true, | ||||
|       myLocationEnabled: useLocation, | ||||
|       myLocationButtonEnabled: false, | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import 'package:anyway/structs/landmark.dart'; | ||||
| import 'package:anyway/structs/trip.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:google_maps_flutter/google_maps_flutter.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:widget_to_marker/widget_to_marker.dart'; | ||||
|  | ||||
|  | ||||
| @@ -72,6 +73,23 @@ class _NewTripMapState extends State<NewTripMap> { | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     widget.trip.addListener(updateTripDetails); | ||||
|     Future<SharedPreferences> preferences = SharedPreferences.getInstance(); | ||||
|  | ||||
|     return FutureBuilder( | ||||
|       future: preferences, | ||||
|       builder: (context, snapshot) { | ||||
|         if (snapshot.hasData) { | ||||
|           SharedPreferences prefs = snapshot.data as SharedPreferences; | ||||
|           bool useLocation = prefs.getBool('useLocation') ?? true; | ||||
|           return _buildMap(useLocation); | ||||
|         } else { | ||||
|           return const CircularProgressIndicator(); | ||||
|         } | ||||
|       } | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Widget _buildMap(bool useLocation) { | ||||
|     return GoogleMap( | ||||
|       onMapCreated: _onMapCreated, | ||||
|       initialCameraPosition: _cameraPosition, | ||||
| @@ -80,8 +98,8 @@ class _NewTripMapState extends State<NewTripMap> { | ||||
|       cloudMapId: MAP_ID, | ||||
|       mapToolbarEnabled: false, | ||||
|       zoomControlsEnabled: false, | ||||
|       // TODO: should be loaded from the sharedprefs | ||||
|       myLocationEnabled: true, | ||||
|       myLocationButtonEnabled: false, | ||||
|       myLocationEnabled: useLocation, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @@ -29,14 +29,14 @@ class _TripPageState extends State<TripPage> { | ||||
|     return SlidingUpPanel( | ||||
|         panelBuilder: (sc) => _panelFull(sc), | ||||
|         // collapsed: _floatingCollapsed(), | ||||
|         body: MapWidget(trip: widget.trip), | ||||
|         body: CurrentTripMap(trip: widget.trip), | ||||
|         // renderPanelSheet: false, | ||||
|         // backdropEnabled: true, | ||||
|         maxHeight: MediaQuery.of(context).size.height * 0.8, | ||||
|         padding: EdgeInsets.only(left: 10, right: 10, top: 25, bottom: 10), | ||||
|         // panelSnapping: false, | ||||
|         borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), | ||||
|         boxShadow: [ | ||||
|         boxShadow: const [ | ||||
|           BoxShadow( | ||||
|             blurRadius: 20.0, | ||||
|             color: Colors.black, | ||||
|   | ||||
| @@ -84,6 +84,8 @@ class _NewTripPreferencesPageState extends State<NewTripPreferencesPage> { | ||||
|       for (SinglePreference pref in prefs) { | ||||
|       sliders.add( | ||||
|         Card( | ||||
|           margin: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 0), | ||||
|           shadowColor: Colors.grey, | ||||
|           child: ListTile( | ||||
|             leading: pref.icon, | ||||
|             title: Text(pref.name), | ||||
| @@ -100,8 +102,6 @@ class _NewTripPreferencesPageState extends State<NewTripPreferencesPage> { | ||||
|               }, | ||||
|             ) | ||||
|           ), | ||||
|           margin: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 0), | ||||
|           shadowColor: Colors.grey, | ||||
|         ) | ||||
|       ); | ||||
|     } | ||||
|   | ||||
| @@ -7,7 +7,6 @@ import 'package:url_launcher/url_launcher.dart'; | ||||
|  | ||||
|  | ||||
| bool debugMode = false; | ||||
| bool useLocation = false; | ||||
|  | ||||
| class SettingsPage extends StatefulWidget { | ||||
|   @override | ||||
| @@ -15,7 +14,6 @@ class SettingsPage extends StatefulWidget { | ||||
| } | ||||
|  | ||||
| class _SettingsPageState extends State<SettingsPage> { | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return ListView( | ||||
| @@ -90,6 +88,7 @@ class _SettingsPageState extends State<SettingsPage> { | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Widget darkMode() { | ||||
|     return Row( | ||||
|       children: [ | ||||
| @@ -115,46 +114,58 @@ class _SettingsPageState extends State<SettingsPage> { | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Widget setLocationUsage() { | ||||
|     Future<SharedPreferences> preferences = SharedPreferences.getInstance(); | ||||
|     return Row( | ||||
|       children: [ | ||||
|         Text('Use location services'), | ||||
|         // white space | ||||
|         Spacer(), | ||||
|         Switch( | ||||
|           value: useLocation, | ||||
|           onChanged: (bool? newValue) async { | ||||
|             await Permission.locationWhenInUse | ||||
|               .onDeniedCallback(() { | ||||
|                 rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|                   SnackBar(content: Text('Location services are required for this feature')) | ||||
|                 ); | ||||
|               }) | ||||
|               .onGrantedCallback(() { | ||||
|                 rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|                   SnackBar(content: Text('Location services are now enabled')) | ||||
|                 ); | ||||
|                 setState(() { | ||||
|                   useLocation = newValue!; | ||||
|                 }); | ||||
|                 SharedPreferences.getInstance().then( | ||||
|                   (SharedPreferences prefs) { | ||||
|                     prefs.setBool('useLocation', useLocation); | ||||
|                   } | ||||
|                 ); | ||||
|               }) | ||||
|               .onPermanentlyDeniedCallback(() { | ||||
|                 rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|                   SnackBar(content: Text('Location services are required for this feature')) | ||||
|                 ); | ||||
|               })   | ||||
|             .request(); | ||||
|         FutureBuilder( | ||||
|           future: preferences, | ||||
|           builder: (context, snapshot) { | ||||
|             if (snapshot.hasData) { | ||||
|               bool useLocation = snapshot.data!.getBool('useLocation') ?? false; | ||||
|               return Switch( | ||||
|                 value: useLocation, | ||||
|                 onChanged: setUseLocation, | ||||
|               ); | ||||
|             } else { | ||||
|               return CircularProgressIndicator(); | ||||
|             } | ||||
|           } | ||||
|         ) | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   void setUseLocation(bool newValue) async { | ||||
|     await Permission.locationWhenInUse | ||||
|       .onDeniedCallback(() { | ||||
|         rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|           SnackBar(content: Text('Location services are required for this feature')) | ||||
|         ); | ||||
|       }) | ||||
|       .onGrantedCallback(() { | ||||
|         rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|           SnackBar(content: Text('Location services are now enabled')) | ||||
|         ); | ||||
|         SharedPreferences.getInstance().then( | ||||
|           (SharedPreferences prefs) { | ||||
|             setState(() { | ||||
|               prefs.setBool('useLocation', newValue); | ||||
|             }); | ||||
|           } | ||||
|         ); | ||||
|       }) | ||||
|       .onPermanentlyDeniedCallback(() { | ||||
|         rootScaffoldMessengerKey.currentState!.showSnackBar( | ||||
|           SnackBar(content: Text('Location services are required for this feature')) | ||||
|         ); | ||||
|       })   | ||||
|     .request(); | ||||
|   } | ||||
|  | ||||
|   Widget privacyInfo() { | ||||
|     return Center( | ||||
| @@ -163,8 +174,8 @@ class _SettingsPageState extends State<SettingsPage> { | ||||
|           Text('Our privacy policy is available under:'), | ||||
|            | ||||
|           TextButton.icon( | ||||
|             icon: Icon(Icons.info), | ||||
|             label: Text(PRIVACY_URL), | ||||
|             icon: Icon(Icons.info, color: Colors.white), | ||||
|             label: Text(PRIVACY_URL, style: TextStyle(color: Colors.white)), | ||||
|             onPressed: () async{ | ||||
|               await launchUrl(Uri.parse(PRIVACY_URL)); | ||||
|             } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user