diff --git a/DeepDrftCli/Services/GuiService.cs b/DeepDrftCli/Services/GuiService.cs index 908bfe9..233d6ef 100644 --- a/DeepDrftCli/Services/GuiService.cs +++ b/DeepDrftCli/Services/GuiService.cs @@ -1,9 +1,6 @@ using Microsoft.Extensions.Logging; using Terminal.Gui; -using DeepDrftWeb.Services.Repositories; -using DeepDrftContent.Services; using DeepDrftModels.Entities; -using NetBlocks.Models; namespace DeepDrftCli.Services; @@ -13,7 +10,6 @@ namespace DeepDrftCli.Services; public class GuiService { private readonly ILogger _logger; - private readonly TrackRepository _trackRepository; private readonly DeepDrftWeb.Services.TrackService _webTrackService; private readonly DeepDrftContent.Services.TrackService _contentTrackService; @@ -27,12 +23,10 @@ public class GuiService public GuiService( ILogger logger, - TrackRepository trackRepository, DeepDrftWeb.Services.TrackService webTrackService, DeepDrftContent.Services.TrackService contentTrackService) { _logger = logger; - _trackRepository = trackRepository; _webTrackService = webTrackService; _contentTrackService = contentTrackService; } diff --git a/DeepDrftContent/Program.cs b/DeepDrftContent/Program.cs index b4ef3ed..bd50496 100644 --- a/DeepDrftContent/Program.cs +++ b/DeepDrftContent/Program.cs @@ -55,15 +55,6 @@ if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } -else -{ - // Only use HTTPS redirection if not behind a reverse proxy - var forwardedProto = app.Services.GetService()?["ForwardedHeaders:DisableHttpsRedirection"]; - if (string.IsNullOrEmpty(forwardedProto) || !bool.Parse(forwardedProto)) - { - app.UseHttpsRedirection(); - } -} app.UseCors("ContentApiPolicy"); app.UseApiKeyAuthentication(apiKeySettings.ApiKey); diff --git a/DeepDrftWeb.Client/Pages/TracksView.razor b/DeepDrftWeb.Client/Pages/TracksView.razor index b16c1a5..60d9fdd 100644 --- a/DeepDrftWeb.Client/Pages/TracksView.razor +++ b/DeepDrftWeb.Client/Pages/TracksView.razor @@ -1,4 +1,5 @@ -@page "/tracks" +@page "/tracks" +@rendermode @(new InteractiveAutoRenderMode(prerender: false)) @using DeepDrftWeb.Client.Controls @@ -19,6 +20,16 @@ SelectedChanged="@SetPage" BoundaryCount="2" MiddleCount="3"/> + +
+ + Test Interactivity (@_clickCount) + + + Lifecycle Status: @_lifecycleStatus + +
+ } diff --git a/DeepDrftWeb.Client/Pages/TracksView.razor.cs b/DeepDrftWeb.Client/Pages/TracksView.razor.cs index 9dc3a01..2bf84a0 100644 --- a/DeepDrftWeb.Client/Pages/TracksView.razor.cs +++ b/DeepDrftWeb.Client/Pages/TracksView.razor.cs @@ -1,4 +1,4 @@ -using DeepDrftModels.Entities; +using DeepDrftModels.Entities; using DeepDrftModels.Models; using DeepDrftWeb.Client.Services; using DeepDrftWeb.Client.ViewModels; @@ -12,13 +12,29 @@ public partial class TracksView : ComponentBase [Inject] public required AudioPlaybackEngine AudioPlaybackEngine { get; set; } private TrackEntity? _selectedTrack = null; + private int _clickCount = 0; + private string _lifecycleStatus = "Not initialized"; protected override async Task OnInitializedAsync() { + _lifecycleStatus = "OnInitializedAsync called"; await SetPage(1); - - if (!RendererInfo.IsInteractive) return; - await AudioPlaybackEngine.InitializeAudioPlayer(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + 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) diff --git a/DeepDrftWeb.Client/Program.cs b/DeepDrftWeb.Client/Program.cs index 4343915..3075f84 100644 --- a/DeepDrftWeb.Client/Program.cs +++ b/DeepDrftWeb.Client/Program.cs @@ -1,5 +1,4 @@ using DeepDrftWeb.Client; -using DeepDrftWeb.Client.Services; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using MudBlazor.Services; @@ -16,3 +15,5 @@ Startup.ConfigureContentServices(builder.Services, contentApiUrl); Startup.ConfigureDomainServices(builder.Services); var app = builder.Build(); + +await app.RunAsync(); diff --git a/DeepDrftWeb.Client/Routes.razor b/DeepDrftWeb.Client/Routes.razor index f756e19..cba3397 100644 --- a/DeepDrftWeb.Client/Routes.razor +++ b/DeepDrftWeb.Client/Routes.razor @@ -1,6 +1,5 @@ - + - diff --git a/DeepDrftWeb.Client/Services/AudioPlaybackEngine.cs b/DeepDrftWeb.Client/Services/AudioPlaybackEngine.cs index f5f8c7e..040ac47 100644 --- a/DeepDrftWeb.Client/Services/AudioPlaybackEngine.cs +++ b/DeepDrftWeb.Client/Services/AudioPlaybackEngine.cs @@ -13,6 +13,7 @@ public class AudioPlaybackEngine : IAsyncDisposable public required AudioInteropService AudioInterop { get; set; } 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 IsPlaying { get; private set; } = false; public bool IsPaused { get; private set; } = false; @@ -30,6 +31,8 @@ public class AudioPlaybackEngine : IAsyncDisposable public async Task InitializeAudioPlayer() { + if (IsInitialized) return; + var result = await AudioInterop.CreatePlayerAsync(PlayerId); if (!result.Success) { @@ -42,6 +45,8 @@ public class AudioPlaybackEngine : IAsyncDisposable await AudioInterop.SetOnLoadProgressCallbackAsync(PlayerId, OnLoadProgress); await AudioInterop.SetVolumeAsync(PlayerId, Volume); + + IsInitialized = true; } public async Task LoadTrack(TrackEntity track) diff --git a/DeepDrftWeb.Client/Startup.cs b/DeepDrftWeb.Client/Startup.cs index e8eddea..d3b8971 100644 --- a/DeepDrftWeb.Client/Startup.cs +++ b/DeepDrftWeb.Client/Startup.cs @@ -1,8 +1,6 @@ using DeepDrftWeb.Client.Clients; using DeepDrftWeb.Client.Services; using DeepDrftWeb.Client.ViewModels; -using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using NetBlocks.Models; namespace DeepDrftWeb.Client; @@ -31,6 +29,6 @@ public static class Startup }); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddTransient(); } } \ No newline at end of file diff --git a/DeepDrftWeb.Client/wwwroot/appsettings.Development.json b/DeepDrftWeb.Client/wwwroot/appsettings.Development.json index ad99d23..53447bc 100644 --- a/DeepDrftWeb.Client/wwwroot/appsettings.Development.json +++ b/DeepDrftWeb.Client/wwwroot/appsettings.Development.json @@ -6,6 +6,6 @@ } }, "ApiUrls": { - "ContentApi": "https://localhost:54493/api" + "ContentApi": "http://localhost:54493/api/" } } diff --git a/DeepDrftWeb.Client/wwwroot/appsettings.json b/DeepDrftWeb.Client/wwwroot/appsettings.json index 84a67cf..8ec7c59 100644 --- a/DeepDrftWeb.Client/wwwroot/appsettings.json +++ b/DeepDrftWeb.Client/wwwroot/appsettings.json @@ -6,6 +6,6 @@ } }, "ApiUrls": { - "ContentApi": "https://media.deepdrft.com/api" + "ContentApi": "https://media.deepdrft.com/api/" } } diff --git a/DeepDrftWeb/Program.cs b/DeepDrftWeb/Program.cs index 5927f79..39fe4b2 100644 --- a/DeepDrftWeb/Program.cs +++ b/DeepDrftWeb/Program.cs @@ -12,8 +12,8 @@ builder.Services.AddMudServices(); // Add AudioInteropService for both server and client rendering builder.Services.AddScoped(); -var baseUrl = Startup.GetKestrelUrl(builder); -var contentApiUrl = builder.Configuration["ApiUrls:ContentApi"] ?? "https://localhost:7001"; +var baseUrl = builder.GetKestrelUrl(); +var contentApiUrl = builder.Configuration["ApiUrls:ContentApi"] ?? throw new Exception("Content API URL is not configured"); Startup.ConfigureDomainServices(builder); @@ -28,6 +28,17 @@ builder.Services.AddRazorComponents() .AddInteractiveServerComponents() .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 builder.Services.Configure(options => { @@ -63,6 +74,22 @@ else 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.MapControllers(); app.MapRazorComponents() @@ -70,4 +97,5 @@ app.MapRazorComponents() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(DeepDrftWeb.Client._Imports).Assembly); + app.Run(); diff --git a/DeepDrftWeb/appsettings.Development.json b/DeepDrftWeb/appsettings.Development.json index 2b4c7a6..7050dd0 100644 --- a/DeepDrftWeb/appsettings.Development.json +++ b/DeepDrftWeb/appsettings.Development.json @@ -7,6 +7,6 @@ }, "DetailedErrors": true, "ApiUrls": { - "ContentApi": "https://localhost:54493/api" + "ContentApi": "http://localhost:54493/api/" } } diff --git a/DeepDrftWeb/appsettings.json b/DeepDrftWeb/appsettings.json index 1dd1f8c..64d821d 100644 --- a/DeepDrftWeb/appsettings.json +++ b/DeepDrftWeb/appsettings.json @@ -10,7 +10,7 @@ "DefaultConnection": "Data Source=../Database/deepdrft.db" }, "ApiUrls": { - "ContentApi": "https://localhost:12777/api" + "ContentApi": "http://localhost:12777/api/" }, "ForwardedHeaders": { "DisableHttpsRedirection": "true"