So, in order to decrease waiting times on my app, I decided to create the turbines in the shell and inherit from the shell in my ChrgeStationPage, and now I don't see anything
interface
public interface ITurbineService
{
Task InitializeAsync();
Task<ObservableCollection<TurbinePin>> GetTurbinePinsForUI(ICommand pinClickedCommand);
}
Service
private const string collectionName = "turbines";
private static Timer? _timer;
private FirestoreDb? _firestoreDb;
public ObservableCollection<TurbinePin> TurbinePins { get; set; } = [];
public async Task InitializeAsync()
{
bool isInitialized = await firestoreService.InitializeFirestoreAsync();
if (isInitialized)
{
_firestoreDb = firestoreService.GetFirestoreDb();
if (_firestoreDb != null)
{
await LoadOrInitializeTurbineAsync();
//InitializeTimer();
}
}
}
private async Task LoadOrInitializeTurbineAsync()
{
var turbinesRef = _firestoreDb!.Collection(collectionName);
var snapshot = await turbinesRef.GetSnapshotAsync();
if (snapshot.Count == 0)
{
var turbine = new Turbine
{
Id = "EC-G-SB",
Country = "Ecuador",
Name = "Estación Ciudadela Simón Bolívar",
Address = "Av. de las Américas, Guayaquil 090513, Ecuador",
Latitude = -2.151993,
Longitude = -79.886109,
InstalationDateTime = new DateTime(2024, 8, 2, 0, 0, 0,
DateTimeKind.Utc),
ImagesURLs = [],
};
turbine.RemovedCo2Kilograms = Math.Round(
turbine.EnergyProduced * turbine.Co2EmissionOffset, 5);
await AddTurbineImagesAsync(turbine);
var turbineDocRef = turbinesRef.Document(turbine.Id);
await turbineDocRef.SetAsync(turbine);
AddToCollection(turbine);
}
else
{
foreach (var document in snapshot.Documents)
{
var turbine = document.ConvertTo<Turbine>();
turbine.Id = document.Id;
await AddTurbineImagesAsync(turbine);
AddToCollection(turbine);
}
}
}
private async Task AddTurbineImagesAsync(Turbine turbine)
{
turbine.ImagesURLs = (await blobService.GetImagessFromBlob(turbine.Country!)).ToList();
}
private void AddToCollection(Turbine turbine)
{
TurbinePins.Add(new TurbinePin { Turbine = turbine });
}
public Task<ObservableCollection<TurbinePin>> GetTurbinePinsForUI(ICommand pinClickedCommand)
{
foreach (var pin in TurbinePins)
{
pin.PinClickedCommand = pinClickedCommand;
}
return Task.FromResult(TurbinePins);
}
shellViewModel
public partial class AppShellViewModel: ObservableObject
{
private AppShell? _shell;
private readonly IServiceProvider _serviceProvider;
private readonly ITurbineService _turbineService;
private readonly IAppService _appService;
public ObservableCollection<TurbinePin> TurbinePins { get; private set; }
public const string FLYOUT_KEY = "flyouy_key";
public const string SWITCH_KEY = "switch_key";
public AppShellViewModel(ITurbineService turbineService, IAppService appService,
IServiceProvider serviceProvider)
{
_turbineService = turbineService;
_appService = appService;
_serviceProvider = serviceProvider;
InitializeAsync().ConfigureAwait(false);
}
private async Task InitializeAsync()
{
await _turbineService.InitializeAsync().ConfigureAwait(false);
TurbinePins = await _turbineService.GetTurbinePinsForUI(PinMarkerClickedCommand);
}
[ObservableProperty]
bool isCompactMode;
[ObservableProperty]
bool isMenuPopUpOen;
[RelayCommand]
void Appearing(AppShell appShell)
{
_shell = appShell;
}
[RelayCommand]
void OpenMenu()
{
IsMenuPopUpOen = true;
}
[RelayCommand]
void ToogleSwitch()
{
if (IsCompactMode)
{
_shell!.FlyoutWidth = 65;
}
else
{
_shell!.FlyoutWidth = 300;
}
IsMenuPopUpOen = false;
}
[RelayCommand]
async void PinMarkerClicked(TurbinePin turbine)
chargingStationage
<ContentPage
x:Class="METROWIND.Views.ChargingStationsMapPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:constant="clr-namespace:METROWIND.Constants"
xmlns:controls="clr-namespace:METROWIND.Controls"
xmlns:expander="clr-namespace:Syncfusion.Maui.Expander;assembly=Syncfusion.Maui.Expander"
xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:model="clr-namespace:METROWIND.Models"
xmlns:popup="clr-namespace:Syncfusion.Maui.Popup;assembly=Syncfusion.Maui.Popup"
xmlns:rex="clr-namespace:METROWIND.Resources"
xmlns:vm="clr-namespace:METROWIND.ViewModel"
x:Name="stationsMapPage"
x:DataType="vm:ChargingStationsMapPageViewModel">
<Grid>
<Border
x:Name="MobileContent"
Style="{x:StaticResource ChargeStationBorderStyle}">
<expander:SfExpander
AnimationDuration="200"
IsExpanded="{x:Binding IsExpanded}">
<expander:SfExpander.Header>
<Grid RowDefinitions="48">
<Label Style="{x:StaticResource ChooseStationLabelStyle}" />
</Grid>
</expander:SfExpander.Header>
<expander:SfExpander.Content>
<Grid
Padding="10,0,0,0"
RowDefinitions="Auto">
<CollectionView ItemsSource="{x:Binding TurbinePins}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:TurbinePin">
<Border Stroke="Transparent">
<HorizontalStackLayout Spacing="10">
<Label Style="{x:StaticResource ElectricBoltLabelStyle}" />
<Label
Style="{x:StaticResource AddressLabelStyle}"
Text="{x:Binding Turbine.Name}" />
</HorizontalStackLayout>
<Border.Behaviors>
<mct:TouchBehavior
DefaultBackgroundColor="White"
PressedBackgroundColor="CornflowerBlue" />
</Border.Behaviors>
<Border.GestureRecognizers>
<TapGestureRecognizer
Command="{x:Binding Source={x:Reference stationsMapPage},
Path=BindingContext.ItemSelectedCommand}"
CommandParameter="{x:Binding Turbine}" />
</Border.GestureRecognizers>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</expander:SfExpander.Content>
</expander:SfExpander>
</Border>
<maps:Map
x:Name="ChargingStationMap"
ItemsSource="{x:Binding TurbinePins}"
VerticalOptions="FillAndExpand">
<maps:Map.ItemTemplate>
<DataTemplate x:DataType="model:TurbinePin">
<controls:CustomMapPin
Address="{x:Binding Turbine.Address}"
Images="{x:Binding Turbine.ImagesURLs}"
Label="{x:Binding Turbine.Name}"
Location="{x:Binding Turbine.Location}"
MarkerClickedCommand="{x:Binding PinClickedCommand}"
MarkerClickedCommandParameter="{x:Binding}" />
</DataTemplate>
</maps:Map.ItemTemplate>
</maps:Map>