From f31967aa3ef6d6c4948f8bfd6407d8a88dd0c0ca Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Thu, 8 Jan 2026 19:10:24 +0100 Subject: [PATCH] feat: bottom-aligned widgets and wind direction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - All environment widgets align content from bottom for visual harmony - Wind chip now shows direction (e.g., "SE 14 km/h") 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- CHANGELOG.md | 12 ++++++++++++ lib/shared/widgets/air_quality_widget.dart | 9 ++++----- lib/shared/widgets/forecast_widget.dart | 9 +++++---- lib/shared/widgets/weather_widget.dart | 17 ++++++++++------- pubspec.yaml | 2 +- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef7a6f8..5add9e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.5.8] - 2026-01-08 + +### Changed + +- **Bottom-aligned widget content** - All environment widgets now align content from the bottom + - Creates consistent visual baseline across Sun Position, Weather, Air Quality, and Forecast cards + - Footers (weather details, pollutants) sit at the same level across cards + +### Added + +- **Wind direction in Weather** - Wind chip now shows direction (e.g., "SE 14 km/h") + ## [1.5.7] - 2026-01-08 ### Fixed diff --git a/lib/shared/widgets/air_quality_widget.dart b/lib/shared/widgets/air_quality_widget.dart index bf11640..c80c122 100644 --- a/lib/shared/widgets/air_quality_widget.dart +++ b/lib/shared/widgets/air_quality_widget.dart @@ -69,14 +69,13 @@ class AirQualityWidget extends StatelessWidget { ), const SizedBox(height: 8), - // Content area with minimum height to match other widgets - ConstrainedBox( - constraints: const BoxConstraints(minHeight: 170), + // Content area with fixed height, content aligned to bottom + SizedBox( + height: 170, child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, children: [ - const SizedBox(height: 8), // AQI Display Row( children: [ diff --git a/lib/shared/widgets/forecast_widget.dart b/lib/shared/widgets/forecast_widget.dart index 0eaa8c5..dc66d54 100644 --- a/lib/shared/widgets/forecast_widget.dart +++ b/lib/shared/widgets/forecast_widget.dart @@ -108,10 +108,11 @@ class ForecastWidget extends StatelessWidget { ), const SizedBox(height: 8), - // Content area with minimum height to match other widgets - ConstrainedBox( - constraints: const BoxConstraints(minHeight: 170), - child: Center( + // Content area with fixed height, content aligned to bottom + SizedBox( + height: 170, + child: Align( + alignment: Alignment.bottomCenter, child: SizedBox( height: 110, child: ListView.separated( diff --git a/lib/shared/widgets/weather_widget.dart b/lib/shared/widgets/weather_widget.dart index 7cec80f..63836ca 100644 --- a/lib/shared/widgets/weather_widget.dart +++ b/lib/shared/widgets/weather_widget.dart @@ -71,14 +71,13 @@ class WeatherWidget extends StatelessWidget { ), const SizedBox(height: 8), - // Content area with minimum height to match other widgets - ConstrainedBox( - constraints: const BoxConstraints(minHeight: 170), + // Content area with fixed height, content aligned to bottom + SizedBox( + height: 170, child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, children: [ - const SizedBox(height: 8), // Main weather display (matching AQI layout) Row( children: [ @@ -167,8 +166,9 @@ class WeatherWidget extends StatelessWidget { if (weather.windSpeed != null) _DetailChip( label: 'Wind', - value: - '${weather.windSpeed!.round()} ${weather.windUnit}', + value: weather.windDirection != null + ? '${weather.windDirection} ${weather.windSpeed!.round()} ${weather.windUnit}' + : '${weather.windSpeed!.round()} ${weather.windUnit}', ), if (weather.feelsLike != null) _DetailChip( @@ -341,6 +341,7 @@ WeatherData _fromApiData(api.WeatherData data) { icon: _getWeatherIcon(data.conditions, data.icon), humidity: data.humidity, windSpeed: data.windSpeed, + windDirection: data.windDirection, feelsLike: data.feelsLike, iconColor: _getWeatherColor(data.conditions), ); @@ -405,6 +406,7 @@ class WeatherData { this.unit = TemperatureUnit.celsius, this.humidity, this.windSpeed, + this.windDirection, this.windUnit = 'km/h', this.feelsLike, this.iconColor, @@ -417,6 +419,7 @@ class WeatherData { final TemperatureUnit unit; final int? humidity; final double? windSpeed; + final String? windDirection; final String windUnit; final double? feelsLike; final Color? iconColor; diff --git a/pubspec.yaml b/pubspec.yaml index 969a9ce..14fb5e4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.5.7+1 +version: 1.5.8+1 environment: sdk: ^3.10.4