feat: add dynamic environment widgets Add live weather, sun position, and forecast widgets to Front Hall dashboard, powered by data from the Qdrant volatile collection via core-api. New widgets: - SunPositionWidget: Animated arc showing sun/moon position with gradient colors - ForecastWidget: Multi-day weather outlook - Updated WeatherWidget and AirQualityWidget to accept API data Infrastructure: - Environment datasource calling GET /tools/environment - Environment provider with 5-minute auto-refresh - Freezed models for environment data Tests: - 12 widget tests for environment section - Updated existing tests with givenEnvironment() harness method 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
28 lines
973 B
Dart
28 lines
973 B
Dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:tatlock_ui/features/front_hall/data/datasources/environment_datasource.dart';
|
|
import 'package:tatlock_ui/features/front_hall/data/models/environment_model.dart';
|
|
|
|
part 'environment_provider.g.dart';
|
|
|
|
/// Fetches environment data (weather, forecast, sun times) from Core API.
|
|
///
|
|
/// Auto-invalidates every 5 minutes to keep data fresh.
|
|
/// Weather data in Qdrant has 1-hour TTL, so 5-minute refresh is reasonable.
|
|
@riverpod
|
|
Future<EnvironmentData> environment(Ref ref) async {
|
|
final datasource = ref.watch(environmentDatasourceProvider);
|
|
return datasource.getEnvironment();
|
|
}
|
|
|
|
/// Provides whether air quality data is available.
|
|
///
|
|
/// Used for conditional rendering of AirQualityWidget.
|
|
@riverpod
|
|
bool hasAirQuality(Ref ref) {
|
|
final asyncValue = ref.watch(environmentProvider);
|
|
return asyncValue.maybeWhen(
|
|
data: (data) => data.airQuality != null,
|
|
orElse: () => false,
|
|
);
|
|
}
|