using System; using System.Linq; using System.Net.Http; using System.Reactive; using System.Reactive.Disposables; using System.Threading; using System.Threading.Tasks; using Artemis.UI.Shared; using Artemis.UI.Shared.Routing; using Artemis.UI.Shared.Services; using Artemis.WebClient.Workshop; using Artemis.WebClient.Workshop.Services; using Avalonia.Media.Imaging; using FluentAvalonia.UI.Controls; using PropertyChanged.SourceGenerator; using ReactiveUI; using Serilog; namespace Artemis.UI.Screens.Workshop.CurrentUser; public partial class CurrentUserViewModel : ActivatableViewModelBase { private readonly IAuthenticationService _authenticationService; private readonly ObservableAsPropertyHelper _isAnonymous; private readonly ILogger _logger; private readonly IWindowService _windowService; private readonly IRouter _router; [Notify] private bool _allowLogout = true; [Notify(Setter.Private)] private Bitmap? _avatar; [Notify(Setter.Private)] private string? _email; [Notify(Setter.Private)] private bool _loading = true; [Notify(Setter.Private)] private string? _name; [Notify(Setter.Private)] private string? _userId; [Notify(Setter.Private)] private string? _avatarUrl; public CurrentUserViewModel(ILogger logger, IAuthenticationService authenticationService, IWindowService windowService, IRouter router) { _logger = logger; _authenticationService = authenticationService; _windowService = windowService; _router = router; Login = ReactiveCommand.CreateFromTask(ExecuteLogin); _isAnonymous = this.WhenAnyValue(vm => vm.Loading, vm => vm.Name, (l, n) => l || n == null).ToProperty(this, vm => vm.IsAnonymous); this.WhenActivated(d => { Task.Run(AutoLogin); _authenticationService.IsLoggedIn.Subscribe(_ => LoadCurrentUser()).DisposeWith(d); }); } public bool IsAnonymous => _isAnonymous.Value; public ReactiveCommand Login { get; } public void Logout() { if (AllowLogout) _authenticationService.Logout(); } private async Task ExecuteLogin(CancellationToken cancellationToken) { ContentDialogResult result = await _windowService.CreateContentDialog() .WithViewModel(out WorkshopLoginViewModel _) .WithTitle("Workshop login") .ShowAsync(); if (result == ContentDialogResult.Primary) LoadCurrentUser(); } private async Task AutoLogin() { try { await _authenticationService.AutoLogin(); LoadCurrentUser(); } catch (Exception e) { _logger.Warning(e, "Failed to load the current user"); } finally { Loading = false; } } private void LoadCurrentUser() { UserId = _authenticationService.Claims.FirstOrDefault(c => c.Type == "sub")?.Value; Name = _authenticationService.Claims.FirstOrDefault(c => c.Type == "name")?.Value; Email = _authenticationService.Claims.FirstOrDefault(c => c.Type == "email")?.Value; AvatarUrl = $"{WorkshopConstants.AUTHORITY_URL}/user/avatar/{UserId}"; } public void ManageAccount() { _router.Navigate("settings/account"); } }