import 'dart:async'; import 'dart:convert'; import 'dart:developer'; import 'package:assessment/services/database_helper.dart'; import 'package:assessment/services/weather_api_client.dart'; import 'package:assessment/views/additional_information.dart'; import 'package:assessment/views/current_weather.dart'; import 'package:assessment/views/current_weather_daily.dart'; import 'package:assessment/widgets/nav_drawer.dart'; import 'package:assessment/widgets/search_place.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:geolocator/geolocator.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'model/weather_forecast_model.dart'; import 'model/weather_model.dart'; import 'package:intl/intl.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const MyApp()); } class Test { String tempUnit = "Celsius"; String tempSymbol = 'C'; bool tempBool = true; double? locLat; double? locLng; String? locationQuery; } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); static final ValueNotifier themeNotifier = ValueNotifier(ThemeMode.light); @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); return Provider( create: (_) => Test(), child: ValueListenableBuilder( valueListenable: themeNotifier, builder: (_, ThemeMode currentMode, __) { return MaterialApp( // Remove the debug banner debugShowCheckedModeBanner: false, title: 'WeatherApp', theme: ThemeData(primarySwatch: Colors.amber), darkTheme: ThemeData.dark(), themeMode: currentMode, home: HomePage(), ); }, ), ); } } class HomePage extends StatefulWidget { const HomePage({Key? key, String? locationName}) : super(key: key); @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State { late WeatherApiClient client = WeatherApiClient(); late WeatherForecast? data = WeatherForecast(); late WeatherForecast? searchedData = WeatherForecast(); late SharedPreferences sharedPreferences; var currentLat; var currentLng; Future getCurrentLocation(BuildContext context) async { sharedPreferences = await SharedPreferences.getInstance(); //Permission LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) { Geolocator.requestPermission(); } else { Position currentPosition = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.best); currentLat = currentPosition.latitude; currentLng = currentPosition.longitude; String? locationQuery = sharedPreferences.getString("test"); bool? isRefreshCurrentLoc = sharedPreferences.getBool("isRefreshUserLoc"); if (locationQuery != null && isRefreshCurrentLoc == false) { searchedData = await client.getCurrentWeather(locationQuery); return searchedData; } else { sharedPreferences.setBool("isRefreshCurrentLoc", false); sharedPreferences.setDouble("currentLat", currentLat); sharedPreferences.setDouble("currentLng", currentLng); data = await client.getCurrentWeatherLocation(currentLat, currentLng); return data; } } } Future getUserLocation(BuildContext context) async { sharedPreferences = await SharedPreferences.getInstance(); //Permission LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) { Geolocator.requestPermission(); } else { Position currentPosition = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.best); currentLat = currentPosition.latitude; currentLng = currentPosition.longitude; sharedPreferences.setDouble("currentLat", currentLat); sharedPreferences.setDouble("currentLng", currentLng); data = await client.getCurrentWeatherLocation(currentLat, currentLng); return data; } } Future getSearchedPlaceData(String locationName) async { searchedData = await client.getCurrentWeather(locationName); return searchedData; } @override Widget build(BuildContext context) { // TODO: implement build var status = false; final test = Provider.of(context); final test2 = context.watch(); return Scaffold( appBar: AppBar( elevation: 0.0, title: Text( "Weather App", ), centerTitle: true, // leading: IconButton( // onPressed: () {}, // icon: Icon(Icons.menu), // color: Colors.yellow, // ), actions: [ IconButton( icon: Icon(Icons.search), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SearchPlace()), ); }, ), IconButton( icon: Icon(MyApp.themeNotifier.value == ThemeMode.light ? Icons.dark_mode : Icons.light_mode), onPressed: () { MyApp.themeNotifier.value = MyApp.themeNotifier.value == ThemeMode.light ? ThemeMode.dark : ThemeMode.light; }, ), ], ), drawer: NavDrawer(), body: FutureBuilder( future: getCurrentLocation(context), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.data == null) { return const Center( child: Text('no data'), ); } else { return Container( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ currentWeather( snapshot.data!.list![0].weather![0].icon as String, snapshot.data!.list![0].main!.temp as double, snapshot.data!.city!.name as String, test2.tempSymbol, ), SizedBox(height: 20.0), FloatingActionButton( onPressed: () { setState(() { DatabaseHelper.instance.createItem( snapshot.data!.list![0].dt, snapshot.data!.list![0].main!.temp, snapshot.data!.list![0].wind!.speed, snapshot.data!.list![0].main!.humidity as int, snapshot.data!.list![0].main!.pressure as int, snapshot.data!.list![0].main!.feelsLike, snapshot.data!.city!.name.toString(), snapshot.data!.list![0].weather![0].icon as String, test2.tempSymbol); }); }, child: const Icon(Icons.favorite), backgroundColor: Colors.green, ), SizedBox( height: 60.0, ), Expanded( child: ListView.builder( shrinkWrap: true, itemCount: 5, itemBuilder: (context, index) { if (snapshot.data!.list!.isNotEmpty) { return ListTile( title: // Text(convertUnixToReadable(data!.list![index].dt)), currentWeatherDaily( snapshot.data!.list![index *= 8].dt as int, snapshot.data!.list![index].weather![0] .icon as String, snapshot.data!.list![index].main!.temp as double, test.tempSymbol), subtitle: additionalInformation( snapshot.data!.list![index].wind!.speed as double, snapshot.data!.list![index].main!.humidity as int, snapshot.data!.list![index].main!.pressure as int, snapshot.data!.list![index].main!.feelsLike as double), ); } else { return CircularProgressIndicator(); } }, ), ), FloatingActionButton( onPressed: () { setState(() { sharedPreferences.setBool("isRefreshUserLoc", true); getUserLocation(context); }); }, child: const Icon(Icons.refresh), backgroundColor: Colors.green, ), ], ), ); } // } } else if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } return Container(); }, ), ); } String convertUnixToReadable(timestamp) { var converted_timestamp = timestamp * 1000; var date = new DateTime.fromMillisecondsSinceEpoch(converted_timestamp); String dateFormat = 'MM/dd/yy mm:hh:ss'; final DateTime docDateTime = DateTime.parse(date.toString()); var formatted_date = DateFormat(dateFormat).format(docDateTime); var formmated_date_day = DateFormat('EEEE').format(docDateTime); return formmated_date_day + "\n " + formatted_date; } }