Cleanup & Bug Fixes
- WebAssembly fix (missing app.Run) - API comms cleanup
This commit is contained in:
@@ -1,9 +1,6 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Terminal.Gui;
|
using Terminal.Gui;
|
||||||
using DeepDrftWeb.Services.Repositories;
|
|
||||||
using DeepDrftContent.Services;
|
|
||||||
using DeepDrftModels.Entities;
|
using DeepDrftModels.Entities;
|
||||||
using NetBlocks.Models;
|
|
||||||
|
|
||||||
namespace DeepDrftCli.Services;
|
namespace DeepDrftCli.Services;
|
||||||
|
|
||||||
@@ -13,7 +10,6 @@ namespace DeepDrftCli.Services;
|
|||||||
public class GuiService
|
public class GuiService
|
||||||
{
|
{
|
||||||
private readonly ILogger<GuiService> _logger;
|
private readonly ILogger<GuiService> _logger;
|
||||||
private readonly TrackRepository _trackRepository;
|
|
||||||
private readonly DeepDrftWeb.Services.TrackService _webTrackService;
|
private readonly DeepDrftWeb.Services.TrackService _webTrackService;
|
||||||
private readonly DeepDrftContent.Services.TrackService _contentTrackService;
|
private readonly DeepDrftContent.Services.TrackService _contentTrackService;
|
||||||
|
|
||||||
@@ -27,12 +23,10 @@ public class GuiService
|
|||||||
|
|
||||||
public GuiService(
|
public GuiService(
|
||||||
ILogger<GuiService> logger,
|
ILogger<GuiService> logger,
|
||||||
TrackRepository trackRepository,
|
|
||||||
DeepDrftWeb.Services.TrackService webTrackService,
|
DeepDrftWeb.Services.TrackService webTrackService,
|
||||||
DeepDrftContent.Services.TrackService contentTrackService)
|
DeepDrftContent.Services.TrackService contentTrackService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_trackRepository = trackRepository;
|
|
||||||
_webTrackService = webTrackService;
|
_webTrackService = webTrackService;
|
||||||
_contentTrackService = contentTrackService;
|
_contentTrackService = contentTrackService;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,15 +55,6 @@ if (app.Environment.IsDevelopment())
|
|||||||
{
|
{
|
||||||
app.MapOpenApi();
|
app.MapOpenApi();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Only use HTTPS redirection if not behind a reverse proxy
|
|
||||||
var forwardedProto = app.Services.GetService<IConfiguration>()?["ForwardedHeaders:DisableHttpsRedirection"];
|
|
||||||
if (string.IsNullOrEmpty(forwardedProto) || !bool.Parse(forwardedProto))
|
|
||||||
{
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseCors("ContentApiPolicy");
|
app.UseCors("ContentApiPolicy");
|
||||||
app.UseApiKeyAuthentication(apiKeySettings.ApiKey);
|
app.UseApiKeyAuthentication(apiKeySettings.ApiKey);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@page "/tracks"
|
@page "/tracks"
|
||||||
|
@rendermode @(new InteractiveAutoRenderMode(prerender: false))
|
||||||
|
|
||||||
@using DeepDrftWeb.Client.Controls
|
@using DeepDrftWeb.Client.Controls
|
||||||
|
|
||||||
@@ -19,6 +20,16 @@
|
|||||||
SelectedChanged="@SetPage"
|
SelectedChanged="@SetPage"
|
||||||
BoundaryCount="2"
|
BoundaryCount="2"
|
||||||
MiddleCount="3"/>
|
MiddleCount="3"/>
|
||||||
|
|
||||||
|
<div class="interactivity-test mt-4">
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="TestInteractivity">
|
||||||
|
Test Interactivity (@_clickCount)
|
||||||
|
</MudButton>
|
||||||
|
<MudText Typo="Typo.body2" Class="mt-2">
|
||||||
|
Lifecycle Status: @_lifecycleStatus
|
||||||
|
</MudText>
|
||||||
|
</div>
|
||||||
|
|
||||||
<AudioPlayerBar AudioPlaybackEngine="AudioPlaybackEngine" />
|
<AudioPlayerBar AudioPlaybackEngine="AudioPlaybackEngine" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using DeepDrftModels.Entities;
|
using DeepDrftModels.Entities;
|
||||||
using DeepDrftModels.Models;
|
using DeepDrftModels.Models;
|
||||||
using DeepDrftWeb.Client.Services;
|
using DeepDrftWeb.Client.Services;
|
||||||
using DeepDrftWeb.Client.ViewModels;
|
using DeepDrftWeb.Client.ViewModels;
|
||||||
@@ -12,13 +12,29 @@ public partial class TracksView : ComponentBase
|
|||||||
[Inject] public required AudioPlaybackEngine AudioPlaybackEngine { get; set; }
|
[Inject] public required AudioPlaybackEngine AudioPlaybackEngine { get; set; }
|
||||||
|
|
||||||
private TrackEntity? _selectedTrack = null;
|
private TrackEntity? _selectedTrack = null;
|
||||||
|
private int _clickCount = 0;
|
||||||
|
private string _lifecycleStatus = "Not initialized";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
_lifecycleStatus = "OnInitializedAsync called";
|
||||||
await SetPage(1);
|
await SetPage(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (!RendererInfo.IsInteractive) return;
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
await AudioPlaybackEngine.InitializeAudioPlayer();
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
_lifecycleStatus = "OnAfterRenderAsync called - WebAssembly is active!";
|
||||||
|
await AudioPlaybackEngine.InitializeAudioPlayer();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestInteractivity()
|
||||||
|
{
|
||||||
|
_clickCount++;
|
||||||
|
_lifecycleStatus = $"Button clicked {_clickCount} times - Interactivity working!";
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SetPage(int newPage)
|
private async Task SetPage(int newPage)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using DeepDrftWeb.Client;
|
using DeepDrftWeb.Client;
|
||||||
using DeepDrftWeb.Client.Services;
|
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
using MudBlazor.Services;
|
using MudBlazor.Services;
|
||||||
|
|
||||||
@@ -16,3 +15,5 @@ Startup.ConfigureContentServices(builder.Services, contentApiUrl);
|
|||||||
Startup.ConfigureDomainServices(builder.Services);
|
Startup.ConfigureDomainServices(builder.Services);
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
await app.RunAsync();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<Router AppAssembly="typeof(Program).Assembly">
|
<Router AppAssembly="typeof(_Imports).Assembly">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
|
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
|
||||||
<FocusOnNavigate RouteData="routeData" Selector="h1" />
|
|
||||||
</Found>
|
</Found>
|
||||||
</Router>
|
</Router>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class AudioPlaybackEngine : IAsyncDisposable
|
|||||||
public required AudioInteropService AudioInterop { get; set; }
|
public required AudioInteropService AudioInterop { get; set; }
|
||||||
|
|
||||||
public string PlayerId { get; private set; } = Guid.NewGuid().ToString();
|
public string PlayerId { get; private set; } = Guid.NewGuid().ToString();
|
||||||
|
public bool IsInitialized { get; private set; } = false;
|
||||||
public bool IsLoaded { get; private set; } = false;
|
public bool IsLoaded { get; private set; } = false;
|
||||||
public bool IsPlaying { get; private set; } = false;
|
public bool IsPlaying { get; private set; } = false;
|
||||||
public bool IsPaused { get; private set; } = false;
|
public bool IsPaused { get; private set; } = false;
|
||||||
@@ -30,6 +31,8 @@ public class AudioPlaybackEngine : IAsyncDisposable
|
|||||||
|
|
||||||
public async Task InitializeAudioPlayer()
|
public async Task InitializeAudioPlayer()
|
||||||
{
|
{
|
||||||
|
if (IsInitialized) return;
|
||||||
|
|
||||||
var result = await AudioInterop.CreatePlayerAsync(PlayerId);
|
var result = await AudioInterop.CreatePlayerAsync(PlayerId);
|
||||||
if (!result.Success)
|
if (!result.Success)
|
||||||
{
|
{
|
||||||
@@ -42,6 +45,8 @@ public class AudioPlaybackEngine : IAsyncDisposable
|
|||||||
await AudioInterop.SetOnLoadProgressCallbackAsync(PlayerId, OnLoadProgress);
|
await AudioInterop.SetOnLoadProgressCallbackAsync(PlayerId, OnLoadProgress);
|
||||||
|
|
||||||
await AudioInterop.SetVolumeAsync(PlayerId, Volume);
|
await AudioInterop.SetVolumeAsync(PlayerId, Volume);
|
||||||
|
|
||||||
|
IsInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task LoadTrack(TrackEntity track)
|
public async Task LoadTrack(TrackEntity track)
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using DeepDrftWeb.Client.Clients;
|
using DeepDrftWeb.Client.Clients;
|
||||||
using DeepDrftWeb.Client.Services;
|
using DeepDrftWeb.Client.Services;
|
||||||
using DeepDrftWeb.Client.ViewModels;
|
using DeepDrftWeb.Client.ViewModels;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
|
||||||
using NetBlocks.Models;
|
|
||||||
|
|
||||||
namespace DeepDrftWeb.Client;
|
namespace DeepDrftWeb.Client;
|
||||||
|
|
||||||
@@ -31,6 +29,6 @@ public static class Startup
|
|||||||
});
|
});
|
||||||
services.AddScoped<TrackMediaClient>();
|
services.AddScoped<TrackMediaClient>();
|
||||||
services.AddScoped<AudioInteropService>();
|
services.AddScoped<AudioInteropService>();
|
||||||
services.AddScoped<AudioPlaybackEngine>();
|
services.AddTransient<AudioPlaybackEngine>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ApiUrls": {
|
"ApiUrls": {
|
||||||
"ContentApi": "https://localhost:54493/api"
|
"ContentApi": "http://localhost:54493/api/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ApiUrls": {
|
"ApiUrls": {
|
||||||
"ContentApi": "https://media.deepdrft.com/api"
|
"ContentApi": "https://media.deepdrft.com/api/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-2
@@ -12,8 +12,8 @@ builder.Services.AddMudServices();
|
|||||||
// Add AudioInteropService for both server and client rendering
|
// Add AudioInteropService for both server and client rendering
|
||||||
builder.Services.AddScoped<AudioInteropService>();
|
builder.Services.AddScoped<AudioInteropService>();
|
||||||
|
|
||||||
var baseUrl = Startup.GetKestrelUrl(builder);
|
var baseUrl = builder.GetKestrelUrl();
|
||||||
var contentApiUrl = builder.Configuration["ApiUrls:ContentApi"] ?? "https://localhost:7001";
|
var contentApiUrl = builder.Configuration["ApiUrls:ContentApi"] ?? throw new Exception("Content API URL is not configured");
|
||||||
|
|
||||||
Startup.ConfigureDomainServices(builder);
|
Startup.ConfigureDomainServices(builder);
|
||||||
|
|
||||||
@@ -28,6 +28,17 @@ builder.Services.AddRazorComponents()
|
|||||||
.AddInteractiveServerComponents()
|
.AddInteractiveServerComponents()
|
||||||
.AddInteractiveWebAssemblyComponents();
|
.AddInteractiveWebAssemblyComponents();
|
||||||
|
|
||||||
|
// Configure SignalR for better circuit cleanup
|
||||||
|
builder.Services.AddSignalR(options =>
|
||||||
|
{
|
||||||
|
if (builder.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
options.EnableDetailedErrors = true;
|
||||||
|
options.KeepAliveInterval = TimeSpan.FromSeconds(10);
|
||||||
|
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Configure forwarded headers for reverse proxy support
|
// Configure forwarded headers for reverse proxy support
|
||||||
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
||||||
{
|
{
|
||||||
@@ -63,6 +74,22 @@ else
|
|||||||
|
|
||||||
app.UseAntiforgery();
|
app.UseAntiforgery();
|
||||||
|
|
||||||
|
// Configure cache headers for Blazor WebAssembly assets
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.Use(async (context, next) =>
|
||||||
|
{
|
||||||
|
if (context.Request.Path.StartsWithSegments("/_framework") ||
|
||||||
|
context.Request.Path.StartsWithSegments("/_content"))
|
||||||
|
{
|
||||||
|
context.Response.Headers.CacheControl = "no-cache, no-store, must-revalidate";
|
||||||
|
context.Response.Headers.Pragma = "no-cache";
|
||||||
|
context.Response.Headers.Expires = "0";
|
||||||
|
}
|
||||||
|
await next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
app.MapStaticAssets();
|
app.MapStaticAssets();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
app.MapRazorComponents<App>()
|
app.MapRazorComponents<App>()
|
||||||
@@ -70,4 +97,5 @@ app.MapRazorComponents<App>()
|
|||||||
.AddInteractiveWebAssemblyRenderMode()
|
.AddInteractiveWebAssemblyRenderMode()
|
||||||
.AddAdditionalAssemblies(typeof(DeepDrftWeb.Client._Imports).Assembly);
|
.AddAdditionalAssemblies(typeof(DeepDrftWeb.Client._Imports).Assembly);
|
||||||
|
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
},
|
},
|
||||||
"DetailedErrors": true,
|
"DetailedErrors": true,
|
||||||
"ApiUrls": {
|
"ApiUrls": {
|
||||||
"ContentApi": "https://localhost:54493/api"
|
"ContentApi": "http://localhost:54493/api/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"DefaultConnection": "Data Source=../Database/deepdrft.db"
|
"DefaultConnection": "Data Source=../Database/deepdrft.db"
|
||||||
},
|
},
|
||||||
"ApiUrls": {
|
"ApiUrls": {
|
||||||
"ContentApi": "https://localhost:12777/api"
|
"ContentApi": "http://localhost:12777/api/"
|
||||||
},
|
},
|
||||||
"ForwardedHeaders": {
|
"ForwardedHeaders": {
|
||||||
"DisableHttpsRedirection": "true"
|
"DisableHttpsRedirection": "true"
|
||||||
|
|||||||
Reference in New Issue
Block a user