hub manager, start page manager, adding to settings

This commit is contained in:
Andy Pack 2023-01-28 14:41:03 +00:00
parent 95e1c66adf
commit e986f32058
Signed by: sarsoo
GPG Key ID: A55BA3536A5E0ED7
15 changed files with 293 additions and 95 deletions

View File

@ -0,0 +1,10 @@
using System;
namespace Selector.MAUI
{
public static class Constants
{
public const string JwtPrefKey = "last_jwt_key";
public const string StartPagePrefKey = "start_page";
}
}

View File

@ -0,0 +1,21 @@
using System;
using Selector.MAUI.Services;
using Selector.SignalR;
namespace Selector.MAUI.Extensions;
public static class ServiceExtensions
{
public static IServiceCollection AddHubs(this IServiceCollection services)
{
services.AddSingleton<NowHubClient>()
.AddSingleton<NowHubCache>();
services.AddSingleton<PastHubClient>();
services.AddSingleton<HubManager>();
return services;
}
}

View File

@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
using Selector.MAUI.Data; using Selector.MAUI.Data;
using Selector.MAUI.Services; using Selector.MAUI.Services;
using Selector.SignalR; using Selector.SignalR;
using Selector.MAUI.Extensions;
namespace Selector.MAUI; namespace Selector.MAUI;
@ -31,12 +32,10 @@ public static class MauiProgram
builder.Services.AddHttpClient() builder.Services.AddHttpClient()
.AddTransient<ISelectorNetClient, SelectorNetClient>(); .AddTransient<ISelectorNetClient, SelectorNetClient>();
builder.Services.AddSingleton<SessionManager>(); builder.Services.AddSingleton<SessionManager>()
.AddTransient<StartPageManager>();
builder.Services.AddSingleton<NowHubClient>() builder.Services.AddHubs();
.AddSingleton<NowHubCache>();
builder.Services.AddSingleton<PastHubClient>();
return builder.Build(); return builder.Build();
} }

View File

@ -1,8 +1,6 @@
@page "/app" @page "/app"
@using Selector.SignalR @using Selector.SignalR
@inject NowHubClient nowClient @inject HubManager hubManager
@inject NowHubCache nowCache
@inject PastHubClient pastClient
@inject ILogger<Index> logger @inject ILogger<Index> logger
<h1>run that</h1> <h1>run that</h1>
@ -11,16 +9,6 @@
protected async override Task OnInitializedAsync() protected async override Task OnInitializedAsync()
{ {
await hubManager.EnsureConnected();
if (nowClient.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Disconnected)
{
logger.LogInformation("Starting now hub connection");
await nowClient.StartAsync();
await pastClient.StartAsync();
nowCache.BindClient();
await nowClient.OnConnected();
}
} }
} }

View File

@ -3,6 +3,8 @@
@inject ILogger<Login> logger; @inject ILogger<Login> logger;
@inject NavigationManager NavManager; @inject NavigationManager NavManager;
@inject SessionManager sessionManager; @inject SessionManager sessionManager;
@inject HubManager hubManager;
@inject StartPageManager startManager;
<h1>Loading...</h1> <h1>Loading...</h1>
@ -15,8 +17,11 @@
if (sessionManager.IsLoggedIn) if (sessionManager.IsLoggedIn)
{ {
await hubManager.EnsureConnected();
logger.LogInformation("User logged in, navigating to main app"); logger.LogInformation("User logged in, navigating to main app");
NavManager.NavigateTo("/app");
startManager.NavigateToStartPage();
} }
else else
{ {

View File

@ -1,7 +1,5 @@
@page "/past" @page "/past"
@using Selector.SignalR; @using Selector.SignalR;
@using System.Linq;
@implements IDisposable
<h1>Past</h1> <h1>Past</h1>

View File

@ -1,8 +1,23 @@
@page "/settings" @page "/settings"
<h1>Settings</h1> <div class="form-container">
<h1>Settings</h1>
<button @onclick="@SignOut">Sign Out</button> <div class="row">
<RadzenCard>
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Start Page</RadzenText>
<RadzenDropDown AllowClear="true" TValue="string" Class="w-100"
Data=@startManager.StartPages
@bind-Value="currentStartPage"
Change=@OnStartPageChange />
</RadzenCard>
</div>
<div class="row">
<RadzenButton Click=@(_ => SignOut()) Text="Sign Out" ButtonStyle="ButtonStyle.Danger" />
</div>
<SignatureImage/>
</div>
@code { @code {
@ -10,10 +25,19 @@
private SessionManager sessionManager { get; set; } private SessionManager sessionManager { get; set; }
[Inject] [Inject]
private NavigationManager navigationManager { get; set; } private NavigationManager navigationManager { get; set; }
[Inject]
private StartPageManager startManager { get; set; }
private string currentStartPage { get; set; }
protected async override Task OnInitializedAsync() protected async override Task OnInitializedAsync()
{ {
currentStartPage = startManager.GetStartPage();
}
private void OnStartPageChange(object value)
{
startManager.SetStartPage((string) value);
} }
private void SignOut() private void SignOut()

View File

@ -0,0 +1,20 @@
body {
}
.form-container {
max-width: 300px;
margin: auto;
}
.row {
padding-top: 5px;
padding-bottom: 5px;
}
::deep h3 {
text-align: left;
}
h1 {
padding-bottom: 20px;
}

View File

@ -98,10 +98,12 @@
<None Remove="Microsoft.AspNetCore.SignalR.Client" /> <None Remove="Microsoft.AspNetCore.SignalR.Client" />
<None Remove="Microsoft.AspNetCore.Components.Forms" /> <None Remove="Microsoft.AspNetCore.Components.Forms" />
<None Remove="Radzen.Blazor" /> <None Remove="Radzen.Blazor" />
<None Remove="Extensions\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Services\" /> <Folder Include="Services\" />
<Folder Include="Models\" /> <Folder Include="Models\" />
<Folder Include="Extensions\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Selector\Selector.csproj" /> <ProjectReference Include="..\Selector\Selector.csproj" />

View File

@ -0,0 +1,43 @@
using System;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Logging;
using Selector.SignalR;
namespace Selector.MAUI.Services;
public class HubManager
{
private readonly NowHubClient nowClient;
private readonly NowHubCache nowCache;
private readonly PastHubClient pastClient;
private readonly ILogger<HubManager> logger;
public HubManager(NowHubClient nowClient, NowHubCache nowCache, PastHubClient pastClient, ILogger<HubManager> logger)
{
this.nowClient = nowClient;
this.nowCache = nowCache;
this.pastClient = pastClient;
this.logger = logger;
}
public async Task EnsureConnected()
{
if (nowClient.State == HubConnectionState.Disconnected)
{
logger.LogInformation("Starting now hub connection");
await nowClient.StartAsync();
nowCache.BindClient();
await nowClient.OnConnected();
}
if (pastClient.State == HubConnectionState.Disconnected)
{
logger.LogInformation("Starting past hub connection");
await pastClient.StartAsync();
await pastClient.OnConnected();
}
}
}

View File

@ -5,8 +5,6 @@ namespace Selector.MAUI.Services;
public class SessionManager public class SessionManager
{ {
private const string jwt_keychain_key = "last_jwt_key";
private string lastStoredKey; private string lastStoredKey;
private DateTime lastRefresh; private DateTime lastRefresh;
private readonly ISelectorNetClient _selectorNetClient; private readonly ISelectorNetClient _selectorNetClient;
@ -23,7 +21,7 @@ public class SessionManager
public async Task LoadUserFromDisk() public async Task LoadUserFromDisk()
{ {
//var lastToken = await SecureStorage.Default.GetAsync(jwt_keychain_key); //var lastToken = await SecureStorage.Default.GetAsync(jwt_keychain_key);
var lastToken = Preferences.Default.Get(jwt_keychain_key, string.Empty); var lastToken = Preferences.Default.Get(Constants.JwtPrefKey, string.Empty);
lastStoredKey = lastToken; lastStoredKey = lastToken;
@ -62,7 +60,7 @@ public class SessionManager
//await SecureStorage.Default.SetAsync(jwt_keychain_key, lastStoredKey); //await SecureStorage.Default.SetAsync(jwt_keychain_key, lastStoredKey);
// I know, but I can't get secure storage to work // I know, but I can't get secure storage to work
Preferences.Default.Set(jwt_keychain_key, lastStoredKey); Preferences.Default.Set(Constants.JwtPrefKey, lastStoredKey);
break; break;
case SelectorNetClient.TokenResponseStatus.Malformed: case SelectorNetClient.TokenResponseStatus.Malformed:

View File

@ -0,0 +1,62 @@
using System;
using Microsoft.AspNetCore.Components;
namespace Selector.MAUI.Services;
public class StartPageManager
{
private readonly NavigationManager navManager;
public string[] StartPages { get; } = new[]
{
Home, Now, Past
};
public const string Home = "Home";
public const string Now = "Now";
public const string Past = "Past";
public StartPageManager(NavigationManager navManager)
{
this.navManager = navManager;
}
public string GetStartPage()
{
var savedStartPage = Preferences.Default.Get(Constants.StartPagePrefKey, string.Empty);
if (!string.IsNullOrWhiteSpace(savedStartPage))
{
return savedStartPage;
}
else
{
return Home;
}
}
public void NavigateToStartPage()
{
var startPage = GetStartPage();
switch (startPage)
{
case Now:
navManager.NavigateTo("/now");
break;
case Past:
navManager.NavigateTo("/past");
break;
case Home:
default:
navManager.NavigateTo("/app");
break;
}
}
public void SetStartPage(string value)
{
Preferences.Default.Set(Constants.StartPagePrefKey, value);
}
}

View File

@ -0,0 +1,16 @@
<div style="text-align: center">
<a href="https://sarsoo.xyz/about/" style="display: inline-block">
<img src="/andy.png"
alt="AP"
width="120px"
style="display: block;
margin-left: auto;
margin-right: auto;
padding: 8px">
</a>
</div>
@code {
}

View File

@ -11,7 +11,7 @@
<link href="css/link.css" rel="stylesheet" /> <link href="css/link.css" rel="stylesheet" />
<link href="css/input.css" rel="stylesheet" /> <link href="css/input.css" rel="stylesheet" />
<link href="Selector.MAUI.styles.css" rel="stylesheet" /> <link href="Selector.MAUI.styles.css" rel="stylesheet" />
<link rel="stylesheet" href="_content/Radzen.Blazor/css/material-base.css"> <link rel="stylesheet" href="_content/Radzen.Blazor/css/dark-base.css">
</head> </head>
<body> <body>

View File

@ -13,6 +13,9 @@ public class NowHubCache
public List<ICard> LastCards { get; private set; } = new(); public List<ICard> LastCards { get; private set; } = new();
private readonly object updateLock = new(); private readonly object updateLock = new();
private readonly object bindingLock = new();
private bool isBound = false;
public PlayCount LastPlayCount { get; private set; } public PlayCount LastPlayCount { get; private set; }
public CurrentlyPlayingDTO LastPlaying { get; private set; } public CurrentlyPlayingDTO LastPlaying { get; private set; }
@ -28,6 +31,10 @@ public class NowHubCache
} }
public void BindClient() public void BindClient()
{
lock(bindingLock)
{
if(!isBound)
{ {
_connection.OnNewAudioFeature(af => _connection.OnNewAudioFeature(af =>
{ {
@ -41,7 +48,7 @@ public class NowHubCache
_connection.OnNewCard(c => _connection.OnNewCard(c =>
{ {
lock(updateLock) lock (updateLock)
{ {
logger.LogInformation("New card received: {0}", c); logger.LogInformation("New card received: {0}", c);
LastCards.Add(c); LastCards.Add(c);
@ -92,11 +99,16 @@ public class NowHubCache
LastPlaying.Track.Album?.Artists.FirstOrDefault()?.Name LastPlaying.Track.Album?.Artists.FirstOrDefault()?.Name
); );
} }
}catch(Exception e) }
catch (Exception e)
{ {
logger.LogError(e, "Error while handling new now playing"); logger.LogError(e, "Error while handling new now playing");
} }
}); });
isBound = true;
}
}
} }
} }