Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session/6 #19

Merged
merged 14 commits into from
Sep 5, 2023
37 changes: 37 additions & 0 deletions lib/model/weather_data.dart
mqkotoo marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:flutter_training/model/weather_condition.dart';
import 'package:flutter_training/utils/extention/enum.dart';

class WeatherData {
const WeatherData({
required this.weatherCondition,
required this.maxTemperature,
required this.minTemperature,
required this.date,
});

factory WeatherData.fromJson(Map<String, dynamic> json) {
final weatherCondition = WeatherCondition.values
.byNameOrNull(json['weather_condition'].toString());
if (weatherCondition == null) {
throw const FormatException('Invalid value for [WeatherCondition].');
}

final maxTemperature = int.parse(json['max_temperature'].toString());

final minTemperature = int.parse(json['min_temperature'].toString());

final date = DateTime.parse(json['date']?.toString() ?? '');

return WeatherData(
weatherCondition: weatherCondition,
maxTemperature: maxTemperature,
minTemperature: minTemperature,
date: date,
);
}

final WeatherCondition weatherCondition;
final int maxTemperature;
final int minTemperature;
final DateTime date;
}
13 changes: 13 additions & 0 deletions lib/model/weather_request.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class WeatherRequest {
WeatherRequest({required this.area, required this.date});

final String area;
final DateTime date;

Map<String, dynamic> toJson() {
return {
'area': area,
'date': date.toString(),
};
}
}
31 changes: 19 additions & 12 deletions lib/service/weather_service.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:flutter_training/model/weather_condition.dart';
import 'dart:convert';

import 'package:flutter_training/model/weather_data.dart';
import 'package:flutter_training/model/weather_request.dart';
import 'package:flutter_training/utils/api/result.dart';
import 'package:flutter_training/utils/extention/enum.dart';
import 'package:yumemi_weather/yumemi_weather.dart';

class WeatherService {
Expand All @@ -12,17 +14,22 @@ class WeatherService {
/// If successful, the value is stored in [Success],
/// if unsuccessful, the error message is stored in [Failure].

Result<WeatherCondition, String> fetchWeather() {
Result<WeatherData, String> fetchWeather(WeatherRequest request) {
try {
final condition = _client.fetchThrowsWeather('Aichi');
final weatherCondition = WeatherCondition.values.byNameOrNull(condition);
if (weatherCondition == null) {
return const Failure<WeatherCondition, String>('unknown');
}
return Success<WeatherCondition, String>(weatherCondition);
} on YumemiWeatherError catch (_) {
// 投げられるエラーは`YumemiWeatherError.unknown`だけ
return const Failure<WeatherCondition, String>('予期せぬエラーが発生しました。');
final jsonData = jsonEncode(request);
final resultJson = _client.fetchWeather(jsonData);
final weatherData = jsonDecode(resultJson) as Map<String, dynamic>;
final result = WeatherData.fromJson(weatherData);
return Success<WeatherData, String>(result);
} on YumemiWeatherError catch (e) {
return switch (e) {
YumemiWeatherError.invalidParameter =>
const Failure<WeatherData, String>('パラメータが有効ではありません。'),
YumemiWeatherError.unknown =>
const Failure<WeatherData, String>('予期せぬエラーが発生しました。')
};
} on FormatException {
mqkotoo marked this conversation as resolved.
Show resolved Hide resolved
return const Failure<WeatherData, String>('不適切なデータを取得しました。');
}
}
}
15 changes: 7 additions & 8 deletions lib/view/weather_view/component/weather_forecast.dart
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import 'package:flutter/material.dart';
import 'package:flutter_training/model/weather_condition.dart';
import 'package:flutter_training/model/weather_data.dart';

class WeatherForecast extends StatelessWidget {
const WeatherForecast({super.key, required this.weatherCondition});
const WeatherForecast({super.key, required this.weatherData});

final WeatherCondition? weatherCondition;
final WeatherData? weatherData;

@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Column(
children: [
//Placeholder
//Weather conditions
AspectRatio(
aspectRatio: 1,
child: weatherCondition == null
? const Placeholder()
: weatherCondition!.svgImage,
child: weatherData?.weatherCondition.svgImage ?? const Placeholder(),
),
const SizedBox(height: 16),
//Temperature
Row(
children: [
Expanded(
child: Text(
'** ℃',
'${weatherData?.minTemperature ?? '**'} ℃',
textAlign: TextAlign.center,
style: textTheme.labelLarge!.copyWith(
color: Colors.blue,
Expand All @@ -33,7 +32,7 @@ class WeatherForecast extends StatelessWidget {
),
Expanded(
child: Text(
'** ℃',
'${weatherData?.maxTemperature ?? '**'} ℃',
textAlign: TextAlign.center,
style: textTheme.labelLarge!.copyWith(
color: Colors.red,
Expand Down
12 changes: 7 additions & 5 deletions lib/view/weather_view/weather_page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_training/model/weather_condition.dart';
import 'package:flutter_training/model/weather_data.dart';
import 'package:flutter_training/model/weather_request.dart';
import 'package:flutter_training/service/weather_service.dart';
import 'package:flutter_training/utils/api/result.dart';
import 'package:flutter_training/view/weather_view/component/weather_forecast.dart';
Expand All @@ -13,13 +14,14 @@ class WeatherPage extends StatefulWidget {
}

class _WeatherPageState extends State<WeatherPage> {
WeatherCondition? weatherCondition;
WeatherData? weatherData;
final service = WeatherService(YumemiWeather());

void _onReloaded() {
//fetchWeatherの結果がSuccessかFailureかで処理を分ける
return switch (service.fetchWeather()) {
Success(value: final value) => setState(() => weatherCondition = value),
return switch (service
.fetchWeather(WeatherRequest(area: 'Aichi', date: DateTime.now()))) {
Success(value: final value) => setState(() => weatherData = value),
Failure(exception: final error) => showDialog<void>(
barrierDismissible: false,
context: context,
Expand All @@ -37,7 +39,7 @@ class _WeatherPageState extends State<WeatherPage> {
child: Column(
children: [
const Spacer(),
WeatherForecast(weatherCondition: weatherCondition),
WeatherForecast(weatherData: weatherData),
Flexible(
child: Column(
children: [
Expand Down
Loading