81 lines
2.4 KiB
Dart
81 lines
2.4 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'models/weather_models.dart';
|
|
import 'repositories/weather_repository.dart';
|
|
import 'services/wallpaper_service.dart';
|
|
import 'providers/city_provider.dart';
|
|
|
|
// 仓库 Provider
|
|
final weatherRepositoryProvider = Provider<WeatherRepository>((ref) {
|
|
return WeatherRepository(client: http.Client());
|
|
});
|
|
|
|
// 天气状态 Notifier
|
|
final weatherProvider = AsyncNotifierProvider<WeatherNotifier, WeatherModel>(
|
|
() {
|
|
return WeatherNotifier();
|
|
},
|
|
);
|
|
|
|
class WeatherNotifier extends AsyncNotifier<WeatherModel> {
|
|
@override
|
|
Future<WeatherModel> build() async {
|
|
// 从城市管理获取当前城市
|
|
final cityListNotifier = ref.read(cityListProvider.notifier);
|
|
final currentCity = await cityListNotifier.getCurrentCity();
|
|
|
|
// 监听当前城市变化
|
|
ref.listen(currentCityProvider, (previous, next) {
|
|
next.whenData((city) {
|
|
if (previous?.value != city) {
|
|
refetchWeather(city);
|
|
}
|
|
});
|
|
});
|
|
|
|
return _fetchWeather(currentCity);
|
|
}
|
|
|
|
Future<WeatherModel> _fetchWeather(String city) async {
|
|
final repository = ref.read(weatherRepositoryProvider);
|
|
return await repository.fetchWeather(city);
|
|
}
|
|
|
|
Future<void> refetchWeather(String city) async {
|
|
state = const AsyncValue.loading();
|
|
try {
|
|
final weather = await _fetchWeather(city);
|
|
state = AsyncValue.data(weather);
|
|
} catch (e, s) {
|
|
state = AsyncValue.error(e, s);
|
|
}
|
|
}
|
|
|
|
// 切换城市并刷新天气
|
|
Future<void> switchCity(String city) async {
|
|
final cityListNotifier = ref.read(cityListProvider.notifier);
|
|
await cityListNotifier.setCurrentCity(city);
|
|
await refetchWeather(city);
|
|
}
|
|
}
|
|
|
|
// 壁纸服务 Provider
|
|
final wallpaperServiceProvider = Provider<WallpaperService>((ref) {
|
|
return WallpaperService();
|
|
});
|
|
|
|
// 动态壁纸路径 Provider
|
|
final dynamicWallpaperProvider = Provider<String>((ref) {
|
|
final weatherAsync = ref.watch(weatherProvider);
|
|
final wallpaperService = ref.watch(wallpaperServiceProvider);
|
|
return weatherAsync.when(
|
|
data: (weather) {
|
|
final code = weather.current.condition.code;
|
|
final isDay = weather.current.isDay == 1;
|
|
return wallpaperService.getWallpaper(code, isDay);
|
|
},
|
|
loading: () => wallpaperService.getWallpaper(1000, true),
|
|
error: (e, s) => wallpaperService.getWallpaper(1000, true),
|
|
);
|
|
});
|