import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_applicationdemo/BottomNavPage.dart'; import 'package:flutter_applicationdemo/ListViewPage.dart'; import 'package:flutter_applicationdemo/WeatherData.dart'; import 'package:flutter_applicationdemo/WebScraper.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:google_fonts/google_fonts.dart'; import 'dart:async'; import 'login/User.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:flutter_google_places/flutter_google_places.dart'; import 'package:google_api_headers/google_api_headers.dart'; import 'package:http/http.dart' as http; import 'package:http/retry.dart'; import 'package:intl/number_symbols.dart'; import 'package:location/location.dart'; import 'package:geolocator/geolocator.dart'; import 'package:intl/intl.dart'; import 'package:flutter_applicationdemo/login/User.dart'; import 'SettingsPage.dart'; import 'WeatherData.dart'; import 'venuePage.dart'; import 'Venue.dart'; import 'globals.dart' as globals; import 'package:syncfusion_flutter_sliders/sliders.dart'; import 'globals.dart' as globals; import 'HomePage.dart'; import 'SettingsPage.dart'; import 'Venue.dart'; import 'globals.dart' as globals; import 'FeedbackPage.dart'; import 'login/CreateAccountPage.dart'; import 'login/signInPage.dart'; class Map extends StatefulWidget { @override State createState() => MapState(); } const kGoogleApiKey = "AIzaSyAUmhd6Xxud8SwgDxJ4LlYlcntm01FGoSk"; final homeSacffoldKey = GlobalKey(); class MapState extends State { bool _bottomSheetIsOpen = false; /* Future getMerkerData() async { var url = Uri.parse( 'https://openstreetgs.stockholm.se/geoservice/api/b8e20fd7-5654-465e-8976-35b4de902b41/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=od_gis:Markupplatelse&srsName=EPSG:4326&outputFormat=json'); var response = await http.get(url); print('Response status: ${response.statusCode}'); // print('Response body: ${response.body.toString()}'); var jsonData = jsonDecode(response.body); }*/ final Completer _controller = Completer(); bool? _barFilterValue = true; bool? _restaurantFilterValue = true; bool? _cafeFilterValue = true; dynamic _priceFilterValue = 3; LocationData? _currentPosition; final TextEditingController _searchController = TextEditingController(); static const CameraPosition _stockholmCity = CameraPosition( target: LatLng(59.325027, 18.068516), zoom: 14.4746, ); List markersList = []; @override void initState() { initialize(); //_getUserLocation(); super.initState(); } initialize() { List allVenues = globals.VENUES; for (var venue in allVenues) { Marker marker = Marker( markerId: MarkerId(venue.venueID.toString()), position: venue.position, /*infoWindow: InfoWindow( title: venue.venueName, snippet: venue.venueAddress, ),*/ // onTap: () => createBottomSheet(venue.venueName), onTap: () => createBottomDrawer(venue), icon: venue.drawIconColor(), ); markersList.add(marker); } } void createBottomSheet(String venueName) async { var webScraper = WebScraper(); await webScraper.getWebsiteData(venueName); Scaffold.of(context).showBottomSheet(((context) { return Container( height: 420, color: Colors.white, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ /*const Text('BottomSheet'), ElevatedButton( child: const Text('Close BottomSheet'), onPressed: () {Navigator.pop(context);})*/ Container( child: Text(webScraper.openingHoursThisWeek.length.toString()), ), ], )), ); })); } Future _getLocationPermission() async { Location location = Location(); bool _serviceEnabled; PermissionStatus _permissionGranted; LocationData _locationData; _serviceEnabled = await location.serviceEnabled(); if (!_serviceEnabled) { _serviceEnabled = await location.requestService(); if (!_serviceEnabled) { return Future.error('Service not enable'); } } _permissionGranted = await location.hasPermission(); if (_permissionGranted == PermissionStatus.denied) { _permissionGranted = await location.requestPermission(); if (_permissionGranted != PermissionStatus.granted) { return Future.error('Permission Denied'); } } _locationData = await location.getLocation(); return _locationData; } _getUserLocation() async { _currentPosition = await _getLocationPermission(); _goToCurrentPosition( LatLng(_currentPosition!.latitude!, _currentPosition!.longitude!)); } late GoogleMapController googleMapController; final Mode _mode = Mode.fullscreen; int currentIndex = 0; final screens = [ Map(), ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: const Text("Sun chasers"), key: homeSacffoldKey, //leading: IconButton(icon: Icon(Icons.search), onPressed:() {},), /*actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () {}, ), ],*/ /*title: TextFormField( controller: _searchController, textCapitalization: TextCapitalization.words, decoration: const InputDecoration(hintText: 'Find your place'), onChanged: (value) { print(value); }, ),*/ actions: [createFilterMenuButton()], backgroundColor: const Color.fromARGB(255, 190, 146, 160), ), drawer : Drawer( child: Container( child: globals.LOGGED_IN_USER.userID == 0 ? buildDrawerSignedOut(context) : buildDrawerSignedIn(context), ), ), body: Stack( children: [ GoogleMap( mapType: MapType.normal, myLocationEnabled: true, initialCameraPosition: _stockholmCity, markers: markersList.map((e) => e).toSet(), onMapCreated: (GoogleMapController controller) { _controller.complete(controller); }, onTap: (LatLng) { closeBottomSheetIfOpen(); }, ), // ElevatedButton(onPressed: () {} //_handelPressButton // ,child: const Text("Search Placses")) ], ), floatingActionButton: Padding( padding: const EdgeInsets.only(top: 100.0), child: FloatingActionButton( onPressed: () { Navigator.push(context, MaterialPageRoute(builder: (context) => const SettingsPage())); }, backgroundColor: Colors.purple, child: const Icon(Icons.filter_alt), ), ), floatingActionButtonLocation: FloatingActionButtonLocation.endTop, ); } PopupMenuButton createFilterMenuButton() { return PopupMenuButton( icon: Icon(Icons.filter_list), iconSize: 40, itemBuilder: (context) => [ const PopupMenuItem( child: Text( "Filters", style: TextStyle( fontSize: 20, ), ), padding: EdgeInsets.only(left: 60), ), createCheckBoxes(), createPriceSlider(), PopupMenuItem( child: ButtonBar( alignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: null, // TODO: Fixa så att kartan filtreras när man klickar på 'Apply Filters' child: Text( "Apply Filters", style: TextStyle(color: Colors.black), ), style: ButtonStyle( backgroundColor: MaterialStateProperty.all( globals.BUTTONCOLOR)), ), ], )) ]); } // Creates the checkboxes for the filter menu PopupMenuItem createCheckBoxes() { return PopupMenuItem( child: Padding( padding: const EdgeInsets.all(8), child: Expanded( child: Column( children: [ Divider( color: Colors.black, ), StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return CheckboxListTile( value: _barFilterValue, onChanged: (bool? newValue) { setState(() { _barFilterValue = newValue; }); }, title: const Icon( Icons.sports_bar, color: Colors.orange, )); }), StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return CheckboxListTile( value: _restaurantFilterValue, onChanged: (bool? newValue) { setState(() { _restaurantFilterValue = newValue; }); }, title: Icon( Icons.restaurant, color: Colors.blueGrey[200], ), ); }), //Cafe checkbox StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return CheckboxListTile( value: _cafeFilterValue, onChanged: (bool? newValue) { setState(() => _cafeFilterValue = newValue); }, title: Icon( Icons.coffee, color: Colors.brown[400], )); }), ], /*floatingActionButton: Padding( padding: const EdgeInsets.only(top: 100.0), child: FloatingActionButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SettingsPage())); }, backgroundColor: Colors.purple, child: const Icon(Icons.filter_alt), ), ), floatingActionButtonLocation: FloatingActionButtonLocation .endTop,*/ ), ))); } PopupMenuItem createPriceSlider() { return PopupMenuItem( child: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return SfSlider( value: _priceFilterValue, onChanged: (dynamic newValue) { setState((() => _priceFilterValue = newValue)); }, min: 1, max: 3, showTicks: true, interval: 1, activeColor: Colors.blue, showLabels: true, stepSize: 1.0, labelFormatterCallback: (dynamic value, String formattedText) { switch (value) { case 1: return '\$'; case 2: return '\$\$'; case 3: return '\$\$\$'; } return value.toString(); }); }), ); } Future _gotoLocation(double lat, double lng) async { final GoogleMapController controller = await _controller.future; controller.animateCamera(CameraUpdate.newCameraPosition( CameraPosition(target: LatLng(lat, lng), zoom: 15))); } Widget _boxes(double lat, double lng, String resturantName) { return GestureDetector( onTap: () { _gotoLocation(lat, lng); }, child: Container( child: FittedBox( child: Material( color: Colors.white, elevation: 14.0, borderRadius: BorderRadius.circular(24.0), shadowColor: Color(0x802196F3), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: 250, height: 200, child: ClipRRect( borderRadius: new BorderRadius.circular(24.0), child: const Image(image: AssetImage('assets/images/bild.png')), ), ), Container( child: Padding( padding: const EdgeInsets.all(8.0), child: Text(resturantName), ), ) ], ), ), )), ); } Future _goToCurrentPosition(LatLng latlng) async { final GoogleMapController controller = await _controller.future; controller.animateCamera(CameraUpdate.newCameraPosition(CameraPosition( bearing: 0, target: LatLng(latlng.latitude, latlng.longitude), //tilt: 59.440717697143555, zoom: 14.4746))); } createBottomDrawer(Venue venue) async { // Position? position = await Geolocator.getLastKnownPosition(); // double bar = Geolocator.bearingBetween(position != null? position.latitude : 0, position != null? position.longitude : 0, venue.position.latitude, venue.position.longitude); _bottomSheetIsOpen = true; Scaffold.of(context).showBottomSheet(((context) { return InkWell( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (context) => VenuePage(venue)), ); }, child: Container( height: 250, color: const Color(0xFFF5F5F5), child: Center( child: Column( // mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( margin: const EdgeInsets.all(8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, // mainAxisSize: MainAxisSize.min, children: [ columnCoveringNameAndAddress(venue), columnCoveringRating(), ], ), ), columnHandlingCloseButton(context), Container( padding: const EdgeInsets.all(16.0), child: Column( children: [ Row( children: [ const Text('Weather: \t\t'), globals.forecast.getCurrentWeatherIcon(), ], ), Row( children: [ Text('– ' + globals.forecast.getCurrentWeatherStatus()), ], ), Row( children: [ const Text('Distance:'), ], ) ], ), ) ], ), ), ), ); })); } Column columnHandlingCloseButton(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.all(8), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ ElevatedButton( child: const Text('Close'), onPressed: () { Navigator.pop(context); _bottomSheetIsOpen = false; }), ElevatedButton( child: const Text('ListView'), onPressed: () { Navigator.push(context, MaterialPageRoute(builder: (context) => ListViewPage())); }, ), ], ), ), ], ); } Column columnCoveringRating() { return Column( children: [ Text( 'Rating', style: GoogleFonts.robotoCondensed( textStyle: const TextStyle( color: Colors.black87, fontSize: 20, fontWeight: FontWeight.bold, ), ), ), ], ); } Column columnCoveringNameAndAddress(Venue venue) { return Column( children: [ Text( venue.venueName, style: GoogleFonts.roboto( textStyle: const TextStyle( color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 24, )), ), Text( venue.venueAddress + ' ' + venue.venueStreetNo, style: GoogleFonts.roboto( textStyle: const TextStyle( color: Colors.black, fontWeight: FontWeight.w300, fontSize: 18, )), ) ], ); } closeBottomSheetIfOpen() { print(_bottomSheetIsOpen); if (_bottomSheetIsOpen) { Navigator.pop(context); } } /* Future _handelPressButton() async { Prediction? p = await PlacesAutocomplete.show( context: context, apiKey: kGoogleApiKey, mode: _mode, // Mode.fullscreen language: "en", strictbounds: false, decoration: InputDecoration( hintText:'serach', focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(20), borderSide: BorderSide(color: Colors.white)) ), types: [""], components: [Component(Component.country, "se")]); if (p != null) { displayPrediction(p,homeSacffoldKey.currentState); } } Future displayPrediction(Prediction p, ScaffoldState? currentState) async { GoogleMapsPlaces places = GoogleMapsPlaces( apiKey: kGoogleApiKey, apiHeaders: await const GoogleApiHeaders().getHeaders() ); PlacesDetailsResponse detail = await places.getDetailsByPlaceId(p.placeId!); final lat = detail.result.geometry!.location.lat; final lng = detail.result.geometry!.location.lng; markersList.clear(); markersList.add(Marker(markerId: const MarkerId("0"), position: LatLng(lat, lng), infoWindow: InfoWindow(title: detail.result.name))); setState(() {}); googleMapController.animateCamera(CameraUpdate.newLatLngZoom(LatLng(lat,lng), 14.0)); }*/ } Widget buildDrawerSignedIn(BuildContext context) { return Drawer( child: ListView( padding: EdgeInsets.zero, children: [ DrawerHeader( decoration: const BoxDecoration(color: Color.fromARGB(255, 190, 146, 160)), child: Column( children: const [ Text( 'Sun Chaser', style: TextStyle(fontSize: 32), ), SizedBox(height: 30), Icon(Icons.account_box_rounded), ], ), ), ListTile( leading: Icon(Icons.logout), title: Text('Sign out'), onTap: () { globals.LOGGED_IN_USER = User(0, "", ""); Navigator.push( context, MaterialPageRoute(builder: (context) => BottomNavPage()), //Replace Container() with call to Map-page. ); }, ), ListTile( leading: Icon(Icons.thumb_up_alt), title: Text('Give feedback'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => FormForFeedback(), ), ); }, ), ListTile( leading: Icon(Icons.settings), title: Text('Settings'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SettingsPage(), ), ); }, ), ], ), ); } Widget buildDrawerSignedOut(BuildContext context) { return Drawer( child: ListView( padding: EdgeInsets.zero, children: [ DrawerHeader( decoration: const BoxDecoration(color: Color.fromARGB(255, 190, 146, 160)), child: Column( children: const [ Text( 'Sun Chaser', style: TextStyle(fontSize: 32), ), SizedBox(height: 30), ], ), ), ListTile( leading: Icon(Icons.account_box_rounded), title: Text('Create account'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => CreateAccountPage(), ), ); }, ), ListTile( leading: Icon(Icons.login), title: Text('Sign in'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SignInPage(), ), ); }, ), ListTile( leading: Icon(Icons.thumb_up_alt), title: Text('Give feedback'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => FormForFeedback(), ), ); }, ), ListTile( leading: Icon(Icons.settings), title: Text('Settings'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SettingsPage(), ), ); }, ), ], ), ); } class _Marker { var Plats_1; var Gatunr_1; var coordinates; _Marker(this.Plats_1, this.Gatunr_1, this.coordinates); }