Files
tatlock-ui/lib/features/front_hall/data/models/environment_model.dart
T
Jeroen SchweitzerandClaude Opus 4.5 fffc3d5baf
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 3m12s
chore: release v1.5.0
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>
2026-01-06 23:05:24 +01:00

92 lines
2.5 KiB
Dart

import 'package:freezed_annotation/freezed_annotation.dart';
part 'environment_model.freezed.dart';
part 'environment_model.g.dart';
/// Environment data response from Core API.
/// Contains weather, forecast, sun times, and optionally air quality.
@freezed
sealed class EnvironmentData with _$EnvironmentData {
const factory EnvironmentData({
WeatherData? weather,
List<ForecastDay>? forecast,
@JsonKey(name: 'sun_times') SunTimesData? sunTimes,
@JsonKey(name: 'air_quality') AirQualityData? airQuality,
@JsonKey(name: 'updated_at') required DateTime updatedAt,
String? user,
}) = _EnvironmentData;
factory EnvironmentData.fromJson(Map<String, dynamic> json) =>
_$EnvironmentDataFromJson(json);
}
/// Current weather conditions.
@freezed
sealed class WeatherData with _$WeatherData {
const factory WeatherData({
double? temperature,
@JsonKey(name: 'feels_like') double? feelsLike,
String? conditions,
int? humidity,
@JsonKey(name: 'wind_speed') double? windSpeed,
@JsonKey(name: 'wind_direction') String? windDirection,
double? pressure,
double? visibility,
@JsonKey(name: 'uv_index') double? uvIndex,
String? location,
String? icon,
}) = _WeatherData;
factory WeatherData.fromJson(Map<String, dynamic> json) =>
_$WeatherDataFromJson(json);
}
/// Single day forecast data.
@freezed
sealed class ForecastDay with _$ForecastDay {
const factory ForecastDay({
required String date,
double? high,
double? low,
String? conditions,
@JsonKey(name: 'precipitation_chance') int? precipitationChance,
String? icon,
}) = _ForecastDay;
factory ForecastDay.fromJson(Map<String, dynamic> json) =>
_$ForecastDayFromJson(json);
}
/// Sunrise and sunset times.
@freezed
sealed class SunTimesData with _$SunTimesData {
const factory SunTimesData({
DateTime? sunrise,
DateTime? sunset,
@JsonKey(name: 'daylight_minutes') int? daylightMinutes,
@JsonKey(name: 'solar_noon') DateTime? solarNoon,
DateTime? dawn,
DateTime? dusk,
}) = _SunTimesData;
factory SunTimesData.fromJson(Map<String, dynamic> json) =>
_$SunTimesDataFromJson(json);
}
/// Air quality information.
@freezed
sealed class AirQualityData with _$AirQualityData {
const factory AirQualityData({
int? aqi,
String? quality,
double? pm25,
double? pm10,
double? o3,
double? no2,
String? location,
}) = _AirQualityData;
factory AirQualityData.fromJson(Map<String, dynamic> json) =>
_$AirQualityDataFromJson(json);
}