#nullable enable using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading.Tasks; using Marechai.App.Presentation.Models; using Marechai.App.Services; using Uno.Extensions.Navigation; namespace Marechai.App.Presentation.ViewModels; public partial class SoundSynthsListViewModel : ObservableObject { private readonly ILogger _logger; private readonly INavigator _navigator; private readonly SoundSynthsService _soundSynthsService; [ObservableProperty] private string _errorMessage = string.Empty; [ObservableProperty] private bool _hasError; [ObservableProperty] private bool _isDataLoaded; [ObservableProperty] private bool _isLoading = true; [ObservableProperty] private ObservableCollection _soundSynths = []; public SoundSynthsListViewModel(SoundSynthsService soundSynthsService, INavigator navigator, ILogger logger) { _soundSynthsService = soundSynthsService; _navigator = navigator; _logger = logger; LoadData = new AsyncRelayCommand(LoadDataAsync); NavigateToSoundSynthCommand = new AsyncRelayCommand(NavigateToSoundSynthAsync); } public IAsyncRelayCommand LoadData { get; } public IAsyncRelayCommand NavigateToSoundSynthCommand { get; } private async Task LoadDataAsync() { try { IsLoading = true; IsDataLoaded = false; HasError = false; ErrorMessage = string.Empty; List soundSynths = await _soundSynthsService.GetAllSoundSynthsAsync(); // Separate special sound synths from regular ones var specialSoundSynths = new List(); var regularSoundSynths = new List(); foreach(SoundSynthDto ss in soundSynths) { string displayName = ss.Name ?? "Unknown"; // Replace special database name if(displayName == "DB_SOFTWARE") displayName = "Software"; var soundSynthItem = new SoundSynthListItem { Id = ss.Id ?? 0, Name = displayName, Company = ss.Company ?? "Unknown", IsSpecial = ss.Name == "DB_SOFTWARE" }; if(soundSynthItem.IsSpecial) specialSoundSynths.Add(soundSynthItem); else regularSoundSynths.Add(soundSynthItem); _logger.LogInformation("Sound Synth: {Name}, Company: {Company}, ID: {Id}, IsSpecial: {IsSpecial}", displayName, ss.Company, ss.Id, soundSynthItem.IsSpecial); } // Sort regular sound synths alphabetically by name regularSoundSynths.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); // Add special sound synths first (Software), then regular sound synths SoundSynths.Clear(); foreach(SoundSynthListItem ss in specialSoundSynths) SoundSynths.Add(ss); foreach(SoundSynthListItem ss in regularSoundSynths) SoundSynths.Add(ss); _logger.LogInformation("Successfully loaded {Count} Sound Synthesizers", SoundSynths.Count); IsDataLoaded = true; } catch(Exception ex) { _logger.LogError(ex, "Error loading Sound Synthesizers"); ErrorMessage = "Failed to load Sound Synthesizers. Please try again later."; HasError = true; } finally { IsLoading = false; } } private async Task NavigateToSoundSynthAsync(SoundSynthListItem? item) { if(item == null) return; _logger.LogInformation("Navigating to Sound Synthesizer {SoundSynthId}", item.Id); await _navigator.NavigateViewModelAsync(this, data: new SoundSynthDetailNavigationParameter { SoundSynthId = item.Id, NavigationSource = this }); } public class SoundSynthListItem { public int Id { get; set; } public string Name { get; set; } = string.Empty; public string? Company { get; set; } public bool IsSpecial { get; set; } } }