Skip to content

Commit

Permalink
Make it nice
Browse files Browse the repository at this point in the history
  • Loading branch information
albyrock87 committed Feb 7, 2025
1 parent 8ea4d59 commit a82de62
Show file tree
Hide file tree
Showing 28 changed files with 745 additions and 227 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Nalu.Maui.Weather.Converters;

using System;
using System.Globalization;
using Microsoft.Maui.Controls;

public class WeatherCodeToImageConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is int weatherCode && WeatherData.WeatherCodes.TryGetValue(weatherCode, out var weatherInfo))
{
return weatherInfo.Image;
}

return WeatherData.WeatherCodes[0].Image; // Default to clear sky
}

public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotImplementedException(); // One-way binding, no need for ConvertBack
}

58 changes: 29 additions & 29 deletions Samples/Nalu.Maui.Weather/Converters/WeatherData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,36 @@ namespace Nalu.Maui.Weather.Converters;

public static class WeatherData
{
public static readonly Dictionary<int, (string Description, string Icon)> WeatherCodes = new()
public static readonly Dictionary<int, (string Description, string Icon, string Image)> WeatherCodes = new()
{
{ 0, ("Clear sky", "\ue430") },
{ 1, ("Mainly clear", "\ue430") },
{ 2, ("Partly cloudy", "\ue42d") },
{ 3, ("Overcast", "\ue3dd") },
{ 45, ("Fog", "\uf029") },
{ 48, ("Depositing rime fog", "\uf029") },
{ 51, ("Drizzle: Light intensity", "\ue3ea") },
{ 53, ("Drizzle: Moderate intensity", "\ue3ea") },
{ 55, ("Drizzle: Dense intensity", "\ue3ea") },
{ 56, ("Freezing Drizzle: Light intensity", "\ue798") },
{ 57, ("Freezing Drizzle: Dense intensity", "\ue798") },
{ 61, ("Rain: Slight intensity", "\uf1ad") },
{ 63, ("Rain: Moderate intensity", "\uf1ad") },
{ 65, ("Rain: Heavy intensity", "\uf1ad") },
{ 66, ("Freezing Rain: Light intensity", "\ueb3b") },
{ 67, ("Freezing Rain: Heavy intensity", "\ueb3b") },
{ 71, ("Snow fall: Slight intensity", "\uebd3") },
{ 73, ("Snow fall: Moderate intensity", "\uebd3") },
{ 75, ("Snow fall: Heavy intensity", "\uebd3") },
{ 77, ("Snow grains", "\uebd3") },
{ 80, ("Rain showers: Slight", "\uf061") },
{ 81, ("Rain showers: Moderate", "\uf061") },
{ 82, ("Rain showers: Violent", "\uebdb") },
{ 85, ("Snow showers: Slight", "\uebd3") },
{ 86, ("Snow showers: Heavy", "\uebd3") },
{ 95, ("Thunderstorm: Slight or moderate", "\uebdb") },
{ 96, ("Thunderstorm with slight hail", "\uebdb") },
{ 99, ("Thunderstorm with heavy hail", "\uebdb") }
{ 0, ("Clear sky", "\ue430", "https://images.unsplash.com/photo-1601297183305-6df142704ea2?ixlib=rb-4.0.3&q=75&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=ritam-baishya-ROVBDer29PQ-unsplash.jpg") },
{ 1, ("Mainly clear", "\ue430", "https://images.unsplash.com/photo-1601297183305-6df142704ea2?ixlib=rb-4.0.3&q=75&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=ritam-baishya-ROVBDer29PQ-unsplash.jpg") },
{ 2, ("Partly cloudy", "\ue42d", "https://images.unsplash.com/photo-1601297183305-6df142704ea2?ixlib=rb-4.0.3&q=75&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=ritam-baishya-ROVBDer29PQ-unsplash.jpg") },
{ 3, ("Overcast", "\ue3dd", "https://images.unsplash.com/photo-1499956827185-0d63ee78a910?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=barry-simon-4C6Rp23RjnE-unsplash.jpg") },
{ 45, ("Fog", "\uf029", "https://images.unsplash.com/photo-1512923927402-a9867a68180e?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=chris-lawton-6tfO1M8_gas-unsplash.jpg") },
{ 48, ("Depositing rime fog", "\uf029", "https://images.unsplash.com/photo-1512923927402-a9867a68180e?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=chris-lawton-6tfO1M8_gas-unsplash.jpg") },
{ 51, ("Drizzle: Light intensity", "\ue3ea", "https://images.unsplash.com/photo-1556485689-33e55ab56127?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=roman-synkevych-qPvBmSvmohs-unsplash.jpg") },
{ 53, ("Drizzle: Moderate intensity", "\ue3ea", "https://images.unsplash.com/photo-1556485689-33e55ab56127?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=roman-synkevych-qPvBmSvmohs-unsplash.jpg") },
{ 55, ("Drizzle: Dense intensity", "\ue3ea", "https://images.unsplash.com/photo-1556485689-33e55ab56127?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=roman-synkevych-qPvBmSvmohs-unsplash.jpg") },
{ 56, ("Freezing Drizzle: Light intensity", "\ue798", "https://images.unsplash.com/photo-1505404919723-002ecad81b92?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=philippe-tarbouriech-rWwj4zcOcIs-unsplash.jpg") },
{ 57, ("Freezing Drizzle: Dense intensity", "\ue798", "https://images.unsplash.com/photo-1505404919723-002ecad81b92?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=philippe-tarbouriech-rWwj4zcOcIs-unsplash.jpg") },
{ 61, ("Rain: Slight intensity", "\uf1ad", "https://images.unsplash.com/photo-1519692933481-e162a57d6721?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=osman-rana-GXEZuWo5m4I-unsplash.jpg") },
{ 63, ("Rain: Moderate intensity", "\uf1ad", "https://images.unsplash.com/photo-1519692933481-e162a57d6721?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=osman-rana-GXEZuWo5m4I-unsplash.jpg") },
{ 65, ("Rain: Heavy intensity", "\uf1ad", "https://images.unsplash.com/photo-1519692933481-e162a57d6721?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=osman-rana-GXEZuWo5m4I-unsplash.jpg") },
{ 66, ("Freezing Rain: Light intensity", "\ueb3b", "https://images.unsplash.com/photo-1645221986876-8e3255ba006c?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=benjamin-lehman-jHpqNFSOSA0-unsplash.jpg") },
{ 67, ("Freezing Rain: Heavy intensity", "\ueb3b", "https://images.unsplash.com/photo-1645221986876-8e3255ba006c?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=benjamin-lehman-jHpqNFSOSA0-unsplash.jpg") },
{ 71, ("Snow fall: Slight intensity", "\uebd3", "https://images.unsplash.com/photo-1627854879776-c6eab3d4b7a6?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=martina-de-marchena-HJ2Ayo5yOFE-unsplash.jpg") },
{ 73, ("Snow fall: Moderate intensity", "\uebd3", "https://images.unsplash.com/photo-1627854879776-c6eab3d4b7a6?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=martina-de-marchena-HJ2Ayo5yOFE-unsplash.jpg") },
{ 75, ("Snow fall: Heavy intensity", "\uebd3", "https://images.unsplash.com/photo-1627854879776-c6eab3d4b7a6?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=martina-de-marchena-HJ2Ayo5yOFE-unsplash.jpg") },
{ 77, ("Snow grains", "\uebd3", "https://images.unsplash.com/photo-1627854879776-c6eab3d4b7a6?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=martina-de-marchena-HJ2Ayo5yOFE-unsplash.jpg") },
{ 80, ("Rain showers: Slight", "\uf061", "https://images.unsplash.com/photo-1496034663057-6245f11be793?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=liv-bruce-8yt8kBuEqok-unsplash.jpg") },
{ 81, ("Rain showers: Moderate", "\uf061", "https://images.unsplash.com/photo-1496034663057-6245f11be793?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=liv-bruce-8yt8kBuEqok-unsplash.jpg") },
{ 82, ("Rain showers: Violent", "\uebdb", "https://images.unsplash.com/photo-1496034663057-6245f11be793?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=liv-bruce-8yt8kBuEqok-unsplash.jpg") },
{ 85, ("Snow showers: Slight", "\uebd3", "https://images.unsplash.com/photo-1496034663057-6245f11be793?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=liv-bruce-8yt8kBuEqok-unsplash.jpg") },
{ 86, ("Snow showers: Heavy", "\uebd3", "https://images.unsplash.com/photo-1496034663057-6245f11be793?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=liv-bruce-8yt8kBuEqok-unsplash.jpg") },
{ 95, ("Thunderstorm: Slight or moderate", "\uebdb", "https://images.unsplash.com/photo-1605727216801-e27ce1d0cc28?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=tasos-mansour-_hGPdpyMV-8-unsplash.jpg") },
{ 96, ("Thunderstorm with slight hail", "\uebdb", "https://images.unsplash.com/photo-1605727216801-e27ce1d0cc28?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=tasos-mansour-_hGPdpyMV-8-unsplash.jpg") },
{ 99, ("Thunderstorm with heavy hail", "\uebdb", "https://images.unsplash.com/photo-1605727216801-e27ce1d0cc28?ixlib=rb-4.0.3&q=80&fm=jpg&w=1200&auto=format&fit=crop&cs=srgb&dl=tasos-mansour-_hGPdpyMV-8-unsplash.jpg") }
};
}

4 changes: 4 additions & 0 deletions Samples/Nalu.Maui.Weather/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
namespace Nalu.Maui.Weather;

#if DEBUG
using Microsoft.Extensions.Logging;
#endif

using CommunityToolkit.Maui;
using FFImageLoading.Maui;
using Services;
using ViewModels;

Expand All @@ -23,6 +26,7 @@ public static MauiApp CreateMauiApp()
.UseNaluLayouts()
.UseMauiCommunityToolkit()
.UseOpenMeteo()
.UseFFImageLoading()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "Regular");
Expand Down
10 changes: 0 additions & 10 deletions Samples/Nalu.Maui.Weather/Models/AirQualityModel.cs

This file was deleted.

18 changes: 18 additions & 0 deletions Samples/Nalu.Maui.Weather/Models/DailyWeatherModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Nalu.Maui.Weather.Models;

public class DailyWeatherModel
{
public DateTime Time { get; set; }
public float WindSpeed { get; set; }
public float WindDirection { get; set; }
public float TemperatureMin { get; set; }
public float TemperatureMax { get; set; }
public float RainSum { get; set; }
public int WeatherCode { get; set; }
public string DayName => Time.ToString("dddd");
public string Date => Time.ToString("M");
public string TemperatureMinDegrees => $"{TemperatureMin:N0}°";
public string TemperatureMaxDegrees => $"{TemperatureMax:N0}°";
public string RainSumMm => $"{RainSum:N1}mm";
public string WindSpeedKmh => $"{WindSpeed:N0}km/h {WindDirection}°";
}
122 changes: 122 additions & 0 deletions Samples/Nalu.Maui.Weather/Models/HourlyAirQualityModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
namespace Nalu.Maui.Weather.Models;

using CommunityToolkit.Mvvm.ComponentModel;
using Resources;

public class HourlyAirQualityModel
{
public required DateTime Time { get; set; }
public required float? Pm25 { get; set; }
public required float? Pm10 { get; set; }
public required float? O3 { get; set; }
public required float? Co { get; set; }

public string Icon
{
get
{
if (Pm25 is > 50 || Pm10 is > 50 || Co is > 1000)
{
return "\ue99a";
}

if (Pm25 is > 25 || Pm10 is > 25 || Co is > 600)
{
return "\uf083";
}

return "\ue1d5";
}
}

public Color IconColor
{
get
{
if (Pm25 is > 50 || Pm10 is > 50 || Co is > 1000)
{
return Colors.Red;
}

if (Pm25 is > 25 || Pm10 is > 25 || Co is > 600)
{
return Colors.Orange;
}

return Colors.Green;
}
}

public string DangerousUnit
{
get
{
var pm25Danger = Pm25.HasValue ? Pm25.Value / 50 : 0;
var pm10Danger = Pm10.HasValue ? Pm10.Value / 50 : 0;
var o3Danger = O3.HasValue ? O3.Value / 180 : 0;
var coDanger = Co.HasValue ? Co.Value / 1000 : 0;

var maxDanger = new[] { pm25Danger, pm10Danger, o3Danger, coDanger }.Max();

if (maxDanger == pm25Danger)
{
return Texts.PM25;
}

if (maxDanger == pm10Danger)
{
return Texts.PM10;
}

return maxDanger == o3Danger ? "O3" : "CO";
}
}

public string DangerousValue
{
get
{
var dangerousUnit = DangerousUnit;
if (dangerousUnit == Texts.PM25)
{
return Pm25Value;
}

if (dangerousUnit == Texts.PM10)
{
return Pm10Value;
}

if (dangerousUnit == "O3")
{
return O3Value;
}

return CoValue;
}
}

public string DangerousLevel
{
get
{
if (Pm25 is > 50 || Pm10 is > 50 || Co is > 1000)
{
return "Dangerous";
}

if (Pm25 is > 25 || Pm10 is > 25 || Co is > 600)
{
return "Unhealthy";
}

return "Good";
}
}

public string Hour => Time.ToString("HH:mm");
public string Pm25Value => $"{Pm25 ?? 0:N0} μg/m³";
public string Pm10Value => $"{Pm10 ?? 0:N0} μg/m³";
public string O3Value => $"{O3 ?? 0:N0} μg/m³";
public string CoValue => $"{Co ?? 0:N1} mg/m³";
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Nalu.Maui.Weather.Models;

public class WeatherModel
public class HourlyWeatherModel
{
public required DateTime Time { get; set; }
public required float? Temperature { get; set; }
Expand All @@ -10,4 +10,6 @@ public class WeatherModel
public required float? WindSpeed { get; set; }
public required float? WindDirection { get; set; }
public required int? WeatherCode { get; set; }
public string Hour => Time.ToString("HH:mm");
public string TemperatureDegrees => $"{Temperature ?? 0:N0}°";
}
15 changes: 15 additions & 0 deletions Samples/Nalu.Maui.Weather/Nalu.Maui.Weather.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="11.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="FFImageLoading.Maui" Version="1.2.7" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.30"/>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0"/>
Expand All @@ -83,6 +84,12 @@
<MauiXaml Update="Resources\Styles\KeyedStyles.xaml">
<SubType>Designer</SubType>
</MauiXaml>
<MauiXaml Update="Views\ForecastCard.xaml">
<SubType>Designer</SubType>
</MauiXaml>
<MauiXaml Update="Views\AirQualityCard.xaml">
<SubType>Designer</SubType>
</MauiXaml>
</ItemGroup>

<ItemGroup>
Expand All @@ -99,6 +106,14 @@
<DependentUpon>HomePage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\ForecastCard.xaml.cs">
<DependentUpon>ForecastCard.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\AirQualityCard.xaml.cs">
<DependentUpon>AirQualityCard.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>

<ItemGroup>
Expand Down
28 changes: 21 additions & 7 deletions Samples/Nalu.Maui.Weather/PageModels/InitializationPageModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,25 @@ public async ValueTask OnAppearingAsync(StartupIntent intent)
weatherState.Location = location;

var time = timeProvider.GetLocalNow();
var start = time.Date;
var end = start.AddDays(1);
var today = time.Date;
var forecastEnd = today.AddDays(14);

Message = Texts.LoadingIQ;
var iq = await weatherService.GetAirQualityAsync((float)location.Latitude, (float)location.Longitude, start, end);
var hourlyAirQualityModels = await weatherService.GetHourlyAirQualityAsync(
(float)location.Latitude, (float)location.Longitude, today, today);

Message = Texts.LoadingWeatherForecast;
var forecast = await weatherService.GetWeatherAsync((float)location.Latitude, (float)location.Longitude, start, end);

weatherState.WeatherData.AddRange(forecast);
weatherState.AirQualityData.AddRange(iq);
var hourlyWeatherModels = await weatherService.GetHourlyWeatherAsync(
(float)location.Latitude, (float)location.Longitude, today, today);
var dailyWeatherModels = await weatherService.GetDailyWeatherAsync(
(float)location.Latitude, (float)location.Longitude, today, forecastEnd);

weatherState.TodayWeather = dailyWeatherModels.First();
weatherState.TodayHourlyWeatherData.AddRange(hourlyWeatherModels);
weatherState.TodayHourlyAirQualityData.AddRange(hourlyAirQualityModels.Take(24));
weatherState.DailyWeatherData.AddRange(dailyWeatherModels.Skip(1));
weatherState.UpdateCurrent();

Message = string.Empty;

Expand All @@ -58,7 +66,13 @@ public async ValueTask OnAppearingAsync(StartupIntent intent)
}

[RelayCommand]
private Task NavigateToHomePage() => navigationService.GoToAsync(Navigation.Absolute().ShellContent<HomePageModel>());
private Task NavigateToHomePage()
{
var navigation = Navigation
.Absolute(NavigationBehavior.Immediate | NavigationBehavior.PopAllPagesOnItemChange)
.ShellContent<HomePageModel>();
return navigationService.GoToAsync(navigation);
}

private async Task<Location> GetGeoLocationAsync()
{
Expand Down
Loading

0 comments on commit a82de62

Please sign in to comment.