@@ -5,6 +5,7 @@ import 'package:intersperse/intersperse.dart';
55import 'package:neon_dashboard/l10n/localizations.dart' ;
66import 'package:neon_dashboard/src/blocs/dashboard.dart' ;
77import 'package:neon_dashboard/src/widgets/dry_intrinsic_height.dart' ;
8+ import 'package:neon_dashboard/src/widgets/set_weather_location_dialog.dart' ;
89import 'package:neon_dashboard/src/widgets/widget.dart' ;
910import 'package:neon_dashboard/src/widgets/widget_button.dart' ;
1011import 'package:neon_dashboard/src/widgets/widget_item.dart' ;
@@ -27,6 +28,7 @@ class DashboardMainPage extends StatelessWidget {
2728 final bloc = NeonProvider .of <DashboardBloc >(context);
2829 final accountsBloc = NeonProvider .of <AccountsBloc >(context);
2930 final userStatusBloc = accountsBloc.activeUserStatusBloc;
31+ final weatherStatusBloc = accountsBloc.activeWeatherStatusBloc;
3032
3133 return NeonCustomBackground (
3234 child: ResultBuilder .behaviorSubject (
@@ -36,6 +38,7 @@ class DashboardMainPage extends StatelessWidget {
3638 _buildStatuses (
3739 account: accountsBloc.activeAccount.value! ,
3840 userStatusBloc: userStatusBloc,
41+ weatherStatusBloc: weatherStatusBloc,
3942 ),
4043 ];
4144
@@ -109,6 +112,7 @@ class DashboardMainPage extends StatelessWidget {
109112 Widget _buildStatuses ({
110113 required Account account,
111114 required UserStatusBloc userStatusBloc,
115+ required WeatherStatusBloc weatherStatusBloc,
112116 }) =>
113117 Row (
114118 mainAxisAlignment: MainAxisAlignment .center,
@@ -152,6 +156,86 @@ class DashboardMainPage extends StatelessWidget {
152156 return const SizedBox .shrink ();
153157 },
154158 ),
159+ StreamBuilder (
160+ stream: weatherStatusBloc.isSupported,
161+ builder: (context, weatherStatusSupportedSnapshot) => ResultBuilder .behaviorSubject (
162+ subject: weatherStatusBloc.forecasts,
163+ builder: (context, forecastsResult) {
164+ if (weatherStatusSupportedSnapshot.data ?? false ) {
165+ Future <void > onWeatherStatusPressed () async {
166+ final location = await showDialog <String >(
167+ context: context,
168+ builder: (context) => DashboardSetWeatherLocationDialog (
169+ currentAddress: weatherStatusBloc.location.valueOrNull? .data? .address,
170+ ),
171+ );
172+ if (location != null ) {
173+ weatherStatusBloc.setLocation (location);
174+ }
175+ }
176+
177+ if (forecastsResult.hasData) {
178+ final weatherCode = forecastsResult.requireData.first.data.next1Hours.summary.symbolCode;
179+ final temperature = forecastsResult.requireData.first.data.instant.details.airTemperature;
180+ final description = switch (weatherCode.replaceAll (RegExp (r'_(day|night)$' ), '' )) {
181+ 'clearsky' => DashboardLocalizations .of (context).weatherClearSky,
182+ 'cloudy' => DashboardLocalizations .of (context).weatherCloudy,
183+ 'fair' => DashboardLocalizations .of (context).weatherFairWeather,
184+ 'partlycloudy' => DashboardLocalizations .of (context).weatherPartlyCloudy,
185+ 'fog' => DashboardLocalizations .of (context).weatherFoggy,
186+ 'rain' => DashboardLocalizations .of (context).weatherRainfall,
187+ 'lightrain' => DashboardLocalizations .of (context).weatherLightRainfall,
188+ 'heavyrain' => DashboardLocalizations .of (context).weatherHeavyRainfall,
189+ 'rainshowers' => DashboardLocalizations .of (context).weatherRainfallShowers,
190+ 'lightrainshowers' => DashboardLocalizations .of (context).weatherLightRainfallShowers,
191+ 'heavyrainshowers' => DashboardLocalizations .of (context).weatherHeavyRainfallShowers,
192+ _ => throw UnimplementedError ('Unknown weather code: $weatherCode ' ),
193+ };
194+
195+ final icon = switch (weatherCode) {
196+ 'clearsky_day' => 'sun' ,
197+ 'clearsky_night' => 'moon' ,
198+ 'cloudy' => 'cloud-cloud' ,
199+ 'fair_day' => 'sun-small-cloud' ,
200+ 'fair_night' => 'moon-small-cloud' ,
201+ 'partlycloudy_day' => 'sun-cloud' ,
202+ 'partlycloudy_night' => 'moon-cloud' ,
203+ 'fog' => 'fog' ,
204+ 'rain' => 'rain' ,
205+ 'lightrain' => 'light-rain' ,
206+ 'heavyrain' => 'heavy-rain' ,
207+ 'rainshowers_day' => 'sun-cloud-rain' ,
208+ 'rainshowers_night' => 'moon-cloud-rain' ,
209+ 'lightrainshowers_day' => 'sun-cloud-light-rain' ,
210+ 'lightrainshowers_night' => 'moon-cloud-light-rain' ,
211+ 'heavyrainshowers_day' => 'sun-cloud-heavy-rain' ,
212+ 'heavyrainshowers_night' => 'moon-cloud-heavy-rain' ,
213+ _ => throw UnimplementedError ('Unknown icon: $weatherCode ' ),
214+ };
215+
216+ return _buildStatus (
217+ context: context,
218+ icon: NeonServerIcon (
219+ icon: icon,
220+ ),
221+ label: Text ('$temperature °C $description ' ),
222+ onPressed: onWeatherStatusPressed,
223+ );
224+ } else {
225+ return _buildStatus (
226+ context: context,
227+ icon: const NeonServerIcon (
228+ icon: 'sun-small-cloud' ,
229+ ),
230+ label: Text (DashboardLocalizations .of (context).locationSet),
231+ onPressed: onWeatherStatusPressed,
232+ );
233+ }
234+ }
235+ return const SizedBox .shrink ();
236+ },
237+ ),
238+ ),
155239 ]
156240 .intersperse (
157241 const SizedBox (
0 commit comments