AtmoSphere/lib/providers.dart
2026-01-16 18:22:32 +08:00

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),
);
});