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>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
ea6914b5f4
commit
fffc3d5baf
@@ -318,4 +318,93 @@ class Fixtures {
|
||||
|
||||
static Map<String, dynamic> quickLink(int index) =>
|
||||
Map<String, dynamic>.from(quickLinks[index]);
|
||||
|
||||
// ============================================================
|
||||
// Environment Data
|
||||
// ============================================================
|
||||
|
||||
static const environment = {
|
||||
'weather': {
|
||||
'temperature': 8.5,
|
||||
'feels_like': 5.0,
|
||||
'conditions': 'Partly Cloudy',
|
||||
'humidity': 72,
|
||||
'wind_speed': 18.5,
|
||||
'wind_direction': 'SW',
|
||||
'location': 'Rotterdam, NL',
|
||||
'icon': '03d',
|
||||
},
|
||||
'forecast': [
|
||||
{
|
||||
'date': '2026-01-06',
|
||||
'high': 10.0,
|
||||
'low': 4.0,
|
||||
'conditions': 'Cloudy',
|
||||
'precipitation_chance': 20,
|
||||
},
|
||||
{
|
||||
'date': '2026-01-07',
|
||||
'high': 12.0,
|
||||
'low': 5.0,
|
||||
'conditions': 'Partly Cloudy',
|
||||
'precipitation_chance': 10,
|
||||
},
|
||||
{
|
||||
'date': '2026-01-08',
|
||||
'high': 9.0,
|
||||
'low': 3.0,
|
||||
'conditions': 'Rain',
|
||||
'precipitation_chance': 80,
|
||||
},
|
||||
{
|
||||
'date': '2026-01-09',
|
||||
'high': 11.0,
|
||||
'low': 6.0,
|
||||
'conditions': 'Sunny',
|
||||
'precipitation_chance': 0,
|
||||
},
|
||||
],
|
||||
'sun_times': {
|
||||
'sunrise': '2026-01-06T08:45:00Z',
|
||||
'sunset': '2026-01-06T16:50:00Z',
|
||||
'daylight_minutes': 485,
|
||||
'solar_noon': '2026-01-06T12:47:30Z',
|
||||
},
|
||||
'air_quality': {
|
||||
'aqi': 42,
|
||||
'quality': 'Good',
|
||||
'pm25': 8.5,
|
||||
'pm10': 15.0,
|
||||
'o3': 32.0,
|
||||
},
|
||||
'updated_at': '2026-01-06T10:30:00Z',
|
||||
'user': 'default',
|
||||
};
|
||||
|
||||
/// Environment data without air quality (for conditional rendering test).
|
||||
static const environmentNoAirQuality = {
|
||||
'weather': {
|
||||
'temperature': 8.5,
|
||||
'conditions': 'Partly Cloudy',
|
||||
'humidity': 72,
|
||||
'wind_speed': 18.5,
|
||||
'location': 'Rotterdam, NL',
|
||||
},
|
||||
'forecast': [
|
||||
{
|
||||
'date': '2026-01-06',
|
||||
'high': 10.0,
|
||||
'low': 4.0,
|
||||
'conditions': 'Cloudy',
|
||||
},
|
||||
],
|
||||
'sun_times': {
|
||||
'sunrise': '2026-01-06T08:45:00Z',
|
||||
'sunset': '2026-01-06T16:50:00Z',
|
||||
'daylight_minutes': 485,
|
||||
},
|
||||
'air_quality': null,
|
||||
'updated_at': '2026-01-06T10:30:00Z',
|
||||
'user': 'default',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -172,6 +172,16 @@ class TestHarness {
|
||||
api.whenGet('/tools/system/stats', stats ?? Fixtures.systemStats);
|
||||
}
|
||||
|
||||
/// Set up mock environment response.
|
||||
void givenEnvironment([Map<String, dynamic>? environment]) {
|
||||
api.whenGet('/tools/environment', environment ?? Fixtures.environment);
|
||||
}
|
||||
|
||||
/// Set up mock environment response without air quality.
|
||||
void givenEnvironmentNoAirQuality() {
|
||||
api.whenGet('/tools/environment', Fixtures.environmentNoAirQuality);
|
||||
}
|
||||
|
||||
/// Set up theme mode.
|
||||
void givenThemeMode(ThemeMode mode) {
|
||||
_themeMode = mode;
|
||||
|
||||
Reference in New Issue
Block a user