Skip to content

Commit

Permalink
Dynamic weather view
Browse files Browse the repository at this point in the history
  • Loading branch information
Kendi J authored and Kendi J committed Oct 11, 2023
1 parent a666b6f commit 6ef4f88
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 77 deletions.
37 changes: 35 additions & 2 deletions lib/presentation/cubit/weather_forecast_cubit_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:bloc/bloc.dart';
import 'package:intl/intl.dart';
import 'package:meta/meta.dart';
import 'package:weather_app/domain/model/forecast_responce.dart';
import 'package:weather_app/domain/api/weather_service.dart';
Expand All @@ -13,18 +14,50 @@ class WeatherForecastCubitCubit extends Cubit<WeatherForecastCubitState> {
ForecastResponse forecastResponse =
await WeatherApi().fetchWeatherForecast('Nairobi');
if (forecastResponse.list.isNotEmpty) {
final temperature = forecastResponse.list.first.main.temp;
final weather = forecastResponse.list.first.weather.first.main.name;
List<ListElement> dataToBeReturned = [];

Map<DateTime, ListElement> mappedResponse = { for (var item in forecastResponse.list) item.dtTxt : item };

final currentDate = DateTime.now();
//final formattedCurrentDate = _getFormattedDate(currentDate);
final formattedCurrentHour = _getFormattedHour(currentDate);
int hourOfWeatherToBeDisplayed = 0;

final listOfHours = [0, 3, 6, 9, 12, 15, 18, 21, 24];
for (int h in listOfHours) {
if(h - int.parse(formattedCurrentHour) > 0 && h - int.parse(formattedCurrentHour) < 3) {
hourOfWeatherToBeDisplayed = h;
}
}

mappedResponse.forEach((key, value) {
if(key.hour == hourOfWeatherToBeDisplayed) {
print(key);
dataToBeReturned.add(value);
}
});

final temperature = dataToBeReturned.first.main.temp;
final weather = dataToBeReturned.first.weather.first;
final tempCurrent = dataToBeReturned.first.main.temp;
final tempMin = dataToBeReturned.first.main.tempMin;
final tempMax = dataToBeReturned.first.main.tempMax;
emit(WeatherForecastCubitSuccess(
tempCurrent: tempCurrent,
tempMin: tempMin,
tempMax: tempMax,
forecastRes: forecastResponse,
temperature: temperature,
weatherList: dataToBeReturned.sublist(0, dataToBeReturned.length),
weather: weather));

} else {
emit(WeatherForecastCubitFail(error: "Weather not found"));
}
} catch (e) {
emit(WeatherForecastCubitFail(error: e.toString()));
}
}

String _getFormattedHour(DateTime date) => DateFormat.H().format(date);
}
16 changes: 13 additions & 3 deletions lib/presentation/cubit/weather_forecast_cubit_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,20 @@ final class WeatherForecastCubitLoading extends WeatherForecastCubitState {}
final class WeatherForecastCubitSuccess extends WeatherForecastCubitState {
final ForecastResponse forecastRes;
final double temperature;
final String weather;
final Weather weather;
final double tempCurrent;
final double tempMin;
final double tempMax;
final List<ListElement> weatherList;

WeatherForecastCubitSuccess(
{required this.forecastRes, required this.temperature, required this.weather,});
WeatherForecastCubitSuccess({required this.forecastRes,
required this.temperature,
required this.weather,
required this.weatherList,
required this.tempCurrent,
required this.tempMax,
required this.tempMin
});
}

final class WeatherForecastCubitFail extends WeatherForecastCubitState {
Expand Down
97 changes: 44 additions & 53 deletions lib/presentation/views/days_weather_view.dart
Original file line number Diff line number Diff line change
@@ -1,64 +1,28 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:weather_app/domain/model/forecast_responce.dart';
import 'package:weather_app/presentation/cubit/weather_forecast_cubit_cubit.dart';
import 'package:weather_app/presentation/views/weather_home_view.dart';

class DaysWeatherView extends StatelessWidget {
const DaysWeatherView({super.key});
final WeatherForecastCubitSuccess weatherForecastCubitSuccess;
const DaysWeatherView({super.key, required this.weatherForecastCubitSuccess});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// title
const Row(
children: [
// min
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"10°",
style: TextStyle(color: Colors.white),
),
Text(
"min",
style: TextStyle(color: Colors.white),
),
],
)),
//curent
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"19°",
style: TextStyle(color: Colors.white),
),
Text(
"current",
style: TextStyle(color: Colors.white),
),
],
)),
// max
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"19°",
style: TextStyle(color: Colors.white),
),
Text(
"max",
style: TextStyle(color: Colors.white),
),
],
))
],
),
const Divider(color: Colors.white),
...<DayWeather>[
...weatherForecastCubitSuccess.weatherList.map<Widget>((weatherData) {
return _weatherListTile(
DayWeather(
day: DateFormat.E().format(weatherData.dtTxt),
weather: weatherData.weather.first.main,
temperature: weatherData.main.temp
)
);
}).toList(),
/*...<DayWeather>[
DayWeather(day: "Monday", temperature: 23),
DayWeather(day: "Tuesday", temperature: 23),
DayWeather(day: "Wednesday", temperature: 23),
Expand Down Expand Up @@ -92,8 +56,35 @@ class DaysWeatherView extends StatelessWidget {
),
),
)
.toList(),
.toList(),*/
],
);
}
}

Widget _weatherListTile(final DayWeather dayWeather) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: Text(
dayWeather.day,
style: const TextStyle(color: Colors.white),
)),
Expanded(
flex: 2,
child: Icon(
dayWeather.weather == MainEnum.CLEAR ? Icons.sunny : dayWeather.weather == MainEnum.RAIN ? Icons.shower : Icons.cloud,
color: Colors.white,
),
),
const SizedBox(width: 60),
Text(
"${dayWeather.temperature.toStringAsFixed(2)}°",
style: const TextStyle(color: Colors.white),
),
],
),
);
}
87 changes: 73 additions & 14 deletions lib/presentation/views/image_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@

import 'package:flutter/material.dart';
import 'package:weather_app/domain/model/forecast_responce.dart';
import 'package:weather_app/presentation/cubit/weather_forecast_cubit_cubit.dart';

class ImageWidget extends StatelessWidget {
final ForecastResponse response;
final String weather;
final double temperature;
final WeatherForecastCubitSuccess weatherForecastCubitSuccess;
const ImageWidget(
{super.key,
required this.response,
required this.weather,
required this.temperature});
required this.weatherForecastCubitSuccess});

@override
Widget build(BuildContext context) {
Expand All @@ -20,33 +17,95 @@ class ImageWidget extends StatelessWidget {
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(response.list[0].weather[0].main == "Clouds"
? 'assets/images/forest_sunny.png'
: response.list[0].weather[0].main == "Rainy"
? 'assets/images/forest_rainy.png'
: 'assets/images/forest_cloudy.png'),
image: AssetImage(_getWeatherBanner(weatherForecastCubitSuccess.weather.main)),
fit: BoxFit.fitHeight),
),
child: Column(
mainAxisSize: MainAxisSize.min,
//mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Spacer(),
Text(
temperature.toString(),
weatherForecastCubitSuccess.temperature.toString(),
style: const TextStyle(
fontSize: 60, fontWeight: FontWeight.bold, color: Colors.white),
),
Text(
weather,
weatherForecastCubitSuccess.weather.main.name,
style: const TextStyle(
fontSize: 32,
fontWeight: FontWeight.normal,
color: Colors.white),
),
const Spacer(),
///
Row(
children: [
// min
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"${weatherForecastCubitSuccess.tempMin}°",
style: const TextStyle(color: Colors.white),
),
const Text(
"min",
style: TextStyle(color: Colors.white),
),
],
)),
//curent
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"${weatherForecastCubitSuccess.tempCurrent}°",
style: const TextStyle(color: Colors.white),
),
const Text(
"current",
style: TextStyle(color: Colors.white),
),
],
)),
// max
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"${weatherForecastCubitSuccess.tempMax}°",
style: const TextStyle(color: Colors.white),
),
const Text(
"max",
style: TextStyle(color: Colors.white),
),
],
))
],
),
const Divider(color: Colors.white),
// Text(state.forecastResponce.city.name),
],
),
);
}
}

String _getWeatherBanner(MainEnum weatherType) {
switch(weatherType) {
case MainEnum.CLOUDS:
return "assets/images/forest_cloudy.png";
case MainEnum.RAIN:
return "assets/images/forest_rainy.png";
case MainEnum.CLEAR:
return "assets/images/forest_sunny.png";
default:
return "";
}
}
12 changes: 7 additions & 5 deletions lib/presentation/views/weather_home_view.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ignore_for_file: unrelated_type_equality_checks

import 'package:flutter/material.dart';
import 'package:weather_app/domain/model/forecast_responce.dart';
import 'package:weather_app/presentation/views/days_weather_view.dart';
import 'package:weather_app/presentation/views/image_widget.dart';
import 'package:weather_app/presentation/widgets/consts/theme.dart';
Expand Down Expand Up @@ -33,11 +34,11 @@ class _RainyView extends State<RainyView> {
children: [
// Text(state.forecastRes.city.name),
ImageWidget(
response: state.forecastRes,
weather: state.weather,
temperature: state.temperature,
weatherForecastCubitSuccess: state,
),
const Expanded(child: DaysWeatherView())
Expanded(child: DaysWeatherView(
weatherForecastCubitSuccess: state
))
],
);
} else {
Expand All @@ -53,9 +54,10 @@ class _RainyView extends State<RainyView> {
class DayWeather {
final String day;
final num temperature;
final MainEnum weather;

DayWeather({
required this.day,
required this.temperature,
required this.temperature, required this.weather,
});
}
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
intl:
dependency: "direct main"
description:
name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.1"
js:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies:
bloc: ^8.1.2
meta: ^1.9.1
geolocator: ^10.1.0
intl: ^0.18.1

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 6ef4f88

Please sign in to comment.