From 4d30530ef0d9e1c0bfa207931e0bda6f9a53d2fa Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 15 Nov 2025 16:00:19 +0000 Subject: [PATCH] Add logo to company detail page. --- Marechai.App/App.xaml.cs | 1 + .../ViewModels/CompanyDetailViewModel.cs | 69 ++++++++++++++----- .../Presentation/Views/CompanyDetailPage.xaml | 10 +++ 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/Marechai.App/App.xaml.cs b/Marechai.App/App.xaml.cs index 75abab11..1c69d133 100644 --- a/Marechai.App/App.xaml.cs +++ b/Marechai.App/App.xaml.cs @@ -108,6 +108,7 @@ public partial class App : Application { // Register application services services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/Marechai.App/Presentation/ViewModels/CompanyDetailViewModel.cs b/Marechai.App/Presentation/ViewModels/CompanyDetailViewModel.cs index 0d5cb479..9b11b698 100644 --- a/Marechai.App/Presentation/ViewModels/CompanyDetailViewModel.cs +++ b/Marechai.App/Presentation/ViewModels/CompanyDetailViewModel.cs @@ -14,7 +14,6 @@ using Marechai.App.Services.Caching; using Marechai.Data; using Microsoft.UI.Xaml.Media.Imaging; using Uno.Extensions.Navigation; -using Windows.Storage.Streams; namespace Marechai.App.Presentation.ViewModels; @@ -24,6 +23,7 @@ public partial class CompanyDetailViewModel : ObservableObject private readonly FlagCache _flagCache; private readonly IStringLocalizer _localizer; private readonly ILogger _logger; + private readonly CompanyLogoCache _logoCache; private readonly INavigator _navigator; [ObservableProperty] @@ -53,6 +53,9 @@ public partial class CompanyDetailViewModel : ObservableObject [ObservableProperty] private ObservableCollection _filteredConsoles = []; + [ObservableProperty] + private SvgImageSource? _flagImageSource; + [ObservableProperty] private bool _hasError; @@ -63,19 +66,18 @@ public partial class CompanyDetailViewModel : ObservableObject private bool _isLoading; [ObservableProperty] - private SvgImageSource? _flagImageSource; + private SvgImageSource? _logoImageSource; [ObservableProperty] private CompanyDto? _soldToCompany; - public CompanyDetailViewModel(CompanyDetailService companyDetailService, - FlagCache flagCache, - IStringLocalizer localizer, - ILogger logger, - INavigator navigator) + public CompanyDetailViewModel(CompanyDetailService companyDetailService, FlagCache flagCache, + CompanyLogoCache logoCache, IStringLocalizer localizer, + ILogger logger, INavigator navigator) { _companyDetailService = companyDetailService; _flagCache = flagCache; + _logoCache = logoCache; _localizer = localizer; _logger = logger; _navigator = navigator; @@ -99,6 +101,11 @@ public partial class CompanyDetailViewModel : ObservableObject /// public bool HasFlagContent => FlagImageSource != null; + /// + /// Gets whether logo content is available + /// + public bool HasLogoContent => LogoImageSource != null; + public IAsyncRelayCommand LoadData { get; } public ICommand GoBackCommand { get; } public IAsyncRelayCommand NavigateToMachineCommand { get; } @@ -117,6 +124,12 @@ public partial class CompanyDetailViewModel : ObservableObject OnPropertyChanged(nameof(HasFlagContent)); } + partial void OnLogoImageSourceChanged(SvgImageSource? oldValue, SvgImageSource? newValue) + { + // Notify that HasLogoContent has changed + OnPropertyChanged(nameof(HasLogoContent)); + } + partial void OnComputersFilterTextChanged(string value) { FilterComputers(value); @@ -305,11 +318,12 @@ public partial class CompanyDetailViewModel : ObservableObject { try { - IsLoading = true; - ErrorMessage = string.Empty; - HasError = false; - IsDataLoaded = false; + IsLoading = true; + ErrorMessage = string.Empty; + HasError = false; + IsDataLoaded = false; FlagImageSource = null; + LogoImageSource = null; if(CompanyId <= 0) { @@ -335,29 +349,52 @@ public partial class CompanyDetailViewModel : ObservableObject { try { - short countryCode = (short)UntypedNodeExtractor.ExtractInt(Company.CountryId); - var flagStream = await _flagCache.GetFlagAsync(countryCode); + var countryCode = (short)UntypedNodeExtractor.ExtractInt(Company.CountryId); + Stream? flagStream = await _flagCache.GetFlagAsync(countryCode); var flagSource = new SvgImageSource(); await flagSource.SetSourceAsync(flagStream.AsRandomAccessStream()); FlagImageSource = flagSource; - _logger.LogInformation("Successfully loaded flag for country code {CountryCode}", - countryCode); + _logger.LogInformation("Successfully loaded flag for country code {CountryCode}", countryCode); } catch(Exception ex) { _logger.LogError("Failed to load flag for country {CountryId}: {Exception}", - Company.CountryId, ex.Message); + Company.CountryId, + ex.Message); + // Continue without flag if loading fails } } + if(Company.SoldToId != null) { int soldToId = UntypedNodeExtractor.ExtractInt(Company.SoldToId); if(soldToId > 0) SoldToCompany = await _companyDetailService.GetSoldToCompanyAsync(soldToId); } + // Load logo if available + if(Company.LastLogo.HasValue) + { + try + { + Stream? logoStream = await _logoCache.GetFlagAsync(Company.LastLogo.Value); + + var logoSource = new SvgImageSource(); + await logoSource.SetSourceAsync(logoStream.AsRandomAccessStream()); + LogoImageSource = logoSource; + + _logger.LogInformation("Successfully loaded logo for company {CompanyId}", CompanyId); + } + catch(Exception ex) + { + _logger.LogError("Failed to load logo for company {CompanyId}: {Exception}", CompanyId, ex.Message); + + // Continue without logo if loading fails + } + } + // Load computers and consoles made by this company List machines = await _companyDetailService.GetComputersByCompanyAsync(CompanyId); Computers.Clear(); diff --git a/Marechai.App/Presentation/Views/CompanyDetailPage.xaml b/Marechai.App/Presentation/Views/CompanyDetailPage.xaml index 4ac597e0..bd2c9a14 100644 --- a/Marechai.App/Presentation/Views/CompanyDetailPage.xaml +++ b/Marechai.App/Presentation/Views/CompanyDetailPage.xaml @@ -32,6 +32,16 @@ + + +