Files
lunchpick/lib/presentation/providers/weather_provider.dart
2025-11-19 16:36:39 +09:00

95 lines
2.8 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lunchpick/domain/entities/weather_info.dart';
import 'package:lunchpick/domain/repositories/weather_repository.dart';
import 'package:lunchpick/presentation/providers/di_providers.dart';
import 'package:lunchpick/presentation/providers/location_provider.dart';
/// 현재 날씨 Provider
final weatherProvider = FutureProvider<WeatherInfo>((ref) async {
final repository = ref.watch(weatherRepositoryProvider);
final location = await ref.watch(currentLocationProvider.future);
if (location == null) {
throw Exception('위치 정보를 가져올 수 없습니다');
}
// 캐시된 날씨 정보 확인
final cached = await repository.getCachedWeather();
if (cached != null) {
return cached;
}
// 새로운 날씨 정보 가져오기
return repository.getCurrentWeather(
latitude: location.latitude,
longitude: location.longitude,
);
});
/// 날씨 업데이트 필요 여부 Provider
final isWeatherUpdateNeededProvider = FutureProvider<bool>((ref) async {
final repository = ref.watch(weatherRepositoryProvider);
return repository.isWeatherUpdateNeeded();
});
/// 날씨 관리 StateNotifier
class WeatherNotifier extends StateNotifier<AsyncValue<WeatherInfo>> {
final WeatherRepository _repository;
final Ref _ref;
WeatherNotifier(this._repository, this._ref)
: super(const AsyncValue.loading());
/// 날씨 정보 새로고침
Future<void> refreshWeather() async {
state = const AsyncValue.loading();
try {
final location = await _ref.read(currentLocationProvider.future);
if (location == null) {
throw Exception('위치 정보를 가져올 수 없습니다');
}
final weather = await _repository.getCurrentWeather(
latitude: location.latitude,
longitude: location.longitude,
);
state = AsyncValue.data(weather);
} catch (e, stack) {
state = AsyncValue.error(e, stack);
}
}
/// 캐시에서 날씨 정보 로드
Future<void> loadCachedWeather() async {
try {
final cached = await _repository.getCachedWeather();
if (cached != null) {
state = AsyncValue.data(cached);
} else {
// 캐시가 없으면 새로 가져오기
await refreshWeather();
}
} catch (e, stack) {
state = AsyncValue.error(e, stack);
}
}
/// 날씨 캐시 삭제
Future<void> clearCache() async {
try {
await _repository.clearWeatherCache();
} catch (e, stack) {
state = AsyncValue.error(e, stack);
}
}
}
/// WeatherNotifier Provider
final weatherNotifierProvider =
StateNotifierProvider<WeatherNotifier, AsyncValue<WeatherInfo>>((ref) {
final repository = ref.watch(weatherRepositoryProvider);
return WeatherNotifier(repository, ref);
});