mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Added basic login
This commit is contained in:
1 parent
bde4e861c2
commit
4224875fb0
14 files changed
+524
-5
No files matched your search
@@ -0,0 +1,59 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:currentUser="clr-namespace:Artemis.UI.Screens.Workshop.CurrentUser"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.CurrentUser.CurrentUserView"
|
||||
x:DataType="currentUser:CurrentUserViewModel">
|
||||
|
||||
<Panel>
|
||||
<!-- Signed out -->
|
||||
<Ellipse Height="28" Width="28" IsVisible="{CompiledBinding !IsLoggedIn}">
|
||||
<Ellipse.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Login" Command="{CompiledBinding Login}">
|
||||
<MenuItem.Icon>
|
||||
<avalonia:MaterialIcon Kind="Login" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuFlyout>
|
||||
</Ellipse.ContextFlyout>
|
||||
<Ellipse.Fill>
|
||||
<ImageBrush Source="/Assets/Images/avatar-placeholder.png" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
|
||||
<!-- Signed in -->
|
||||
<Ellipse Height="28" Width="28" IsVisible="{CompiledBinding IsLoggedIn}" Name="UserMenu">
|
||||
<Ellipse.ContextFlyout>
|
||||
<Flyout>
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="*,*,*" MinWidth="300">
|
||||
<Ellipse Grid.Column="0" Grid.RowSpan="3" Height="50" Width="50" Margin="0 0 8 0" VerticalAlignment="Top">
|
||||
<Ellipse.Fill>
|
||||
<ImageBrush Source="{CompiledBinding Avatar}" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Name}" Margin="0 4 0 0"></TextBlock>
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Text="{CompiledBinding Email}"></TextBlock>
|
||||
<controls:HyperlinkButton
|
||||
Grid.Column="1"
|
||||
Grid.Row="2"
|
||||
Margin="-8 0 0 0"
|
||||
Padding="6 4"
|
||||
Click="Button_OnClick">
|
||||
Sign out
|
||||
</controls:HyperlinkButton>
|
||||
</Grid>
|
||||
</Flyout>
|
||||
</Ellipse.ContextFlyout>
|
||||
<Ellipse.Fill>
|
||||
<ImageBrush Source="{CompiledBinding Avatar}" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
</Panel>
|
||||
|
||||
|
||||
</UserControl>
|
||||
@@ -0,0 +1,21 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.CurrentUser;
|
||||
|
||||
public partial class CurrentUserView : ReactiveUserControl<CurrentUserViewModel>
|
||||
{
|
||||
public CurrentUserView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Button_OnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
UserMenu.ContextFlyout?.Hide();
|
||||
ViewModel?.Logout();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.WebClient.Workshop.Services;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Flurl.Http;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.CurrentUser;
|
||||
|
||||
public class CurrentUserViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly IAuthenticationService _authenticationService;
|
||||
private ObservableAsPropertyHelper<bool>? _isLoggedIn;
|
||||
|
||||
private string? _userId;
|
||||
private string? _name;
|
||||
private string? _email;
|
||||
private Bitmap? _avatar;
|
||||
|
||||
public CurrentUserViewModel(IAuthenticationService authenticationService)
|
||||
{
|
||||
_authenticationService = authenticationService;
|
||||
Login = ReactiveCommand.CreateFromTask(ExecuteLogin);
|
||||
|
||||
this.WhenActivated(d => _isLoggedIn = _authenticationService.WhenAnyValue(s => s.IsLoggedIn).ToProperty(this, vm => vm.IsLoggedIn).DisposeWith(d));
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await _authenticationService.AutoLogin();
|
||||
await LoadCurrentUser();
|
||||
}).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public void Logout()
|
||||
{
|
||||
_authenticationService.Logout();
|
||||
}
|
||||
|
||||
public string? UserId
|
||||
{
|
||||
get => _userId;
|
||||
set => RaiseAndSetIfChanged(ref _userId, value);
|
||||
}
|
||||
|
||||
public string? Name
|
||||
{
|
||||
get => _name;
|
||||
set => RaiseAndSetIfChanged(ref _name, value);
|
||||
}
|
||||
|
||||
public string? Email
|
||||
{
|
||||
get => _email;
|
||||
set => RaiseAndSetIfChanged(ref _email, value);
|
||||
}
|
||||
|
||||
public Bitmap? Avatar
|
||||
{
|
||||
get => _avatar;
|
||||
set => RaiseAndSetIfChanged(ref _avatar, value);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> Login { get; }
|
||||
public bool IsLoggedIn => _isLoggedIn?.Value ?? false;
|
||||
|
||||
private async Task ExecuteLogin(CancellationToken cancellationToken)
|
||||
{
|
||||
await _authenticationService.Login();
|
||||
await LoadCurrentUser();
|
||||
Console.WriteLine(_authenticationService.Claims);
|
||||
}
|
||||
|
||||
private async Task LoadCurrentUser()
|
||||
{
|
||||
if (!IsLoggedIn)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
if (UserId != null)
|
||||
await LoadAvatar(UserId);
|
||||
}
|
||||
|
||||
private async Task LoadAvatar(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Avatar = new Bitmap(await $"{IAuthenticationService.AUTHORITY}/user/avatar/{userId}".GetStreamAsync());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<ContentControl Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Right" Content="{CompiledBinding CurrentUserViewModel}" Margin="8"></ContentControl>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -4,6 +4,7 @@ using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Screens.Workshop.CurrentUser;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.UI.Shared.Services.Builders;
|
||||
using Artemis.WebClient.Workshop;
|
||||
@@ -18,8 +19,9 @@ public class WorkshopViewModel : MainScreenViewModel
|
||||
{
|
||||
private readonly IWorkshopClient _workshopClient;
|
||||
|
||||
public WorkshopViewModel(IScreen hostScreen, IWorkshopClient workshopClient) : base(hostScreen, "workshop")
|
||||
public WorkshopViewModel(IScreen hostScreen, IWorkshopClient workshopClient, CurrentUserViewModel currentUserViewModel) : base(hostScreen, "workshop")
|
||||
{
|
||||
CurrentUserViewModel = currentUserViewModel;
|
||||
_workshopClient = workshopClient;
|
||||
DisplayName = "Workshop";
|
||||
|
||||
@@ -27,7 +29,8 @@ public class WorkshopViewModel : MainScreenViewModel
|
||||
}
|
||||
|
||||
public ObservableCollection<IGetEntries_Entries_Nodes> Test { get; set; } = new();
|
||||
|
||||
public CurrentUserViewModel CurrentUserViewModel { get; set; }
|
||||
|
||||
private async Task GetEntries()
|
||||
{
|
||||
|
||||
|
||||
Reference in new issue
Block a user