From 4a9e7463a597a817edda69020273942f8483f9b7 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 19 Feb 2026 10:03:10 +0100 Subject: [PATCH 01/22] update .NET --- .github/workflows/build_pipeline.yml | 14 +++++------ .github/workflows/run_tests.yml | 16 ++++++------ .../AudioCuesheetEditor.End2EndTests.csproj | 2 +- .../AudioCuesheetEditor.Tests.csproj | 4 +-- .../AudioCuesheetEditor.csproj | 10 ++++---- AudioCuesheetEditor/Program.cs | 25 +------------------ 6 files changed, 24 insertions(+), 47 deletions(-) diff --git a/.github/workflows/build_pipeline.yml b/.github/workflows/build_pipeline.yml index f6948c68..9cc55ee8 100644 --- a/.github/workflows/build_pipeline.yml +++ b/.github/workflows/build_pipeline.yml @@ -15,22 +15,22 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - # version can be found here https://dotnet.microsoft.com/en-us/download/dotnet/9.0 + # version can be found here https://dotnet.microsoft.com/en-us/download/dotnet/10.0 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install wasm-tools - run: dotnet workload install wasm-tools-net9 + run: dotnet workload install wasm-tools - name: Build release run: dotnet publish AudioCuesheetEditor --configuration Release --output release - name: Upload Build Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: AudioCuesheetEditor-Release path: ./release @@ -45,7 +45,7 @@ jobs: }} steps: - name: Download Build Artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 with: name: AudioCuesheetEditor-Release - name: Deploy to Netlify diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 0bab000c..03c1fa8f 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -9,25 +9,25 @@ jobs: run-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v6 - name: Set timestamp variable id: timestamp run: echo "datetime=$(date +'%Y-%m-%d_%H-%M-%S')" >> $GITHUB_OUTPUT - # version can be found here https://dotnet.microsoft.com/en-us/download/dotnet/9.0 + # version can be found here https://dotnet.microsoft.com/en-us/download/dotnet/10.0 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install wasm-tools - run: dotnet workload install wasm-tools-net9 + run: dotnet workload install wasm-tools - name: Build & Install run: dotnet build - name: Ensure browsers are installed - run: pwsh AudioCuesheetEditor.End2EndTests/bin/Debug/net9.0/playwright.ps1 install --with-deps + run: pwsh AudioCuesheetEditor.End2EndTests/bin/Debug/net10.0/playwright.ps1 install --with-deps - name: Start App run: dotnet run --project AudioCuesheetEditor & @@ -59,8 +59,8 @@ jobs: - name: Upload traces if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: playwright-traces-${{ steps.timestamp.outputs.datetime }} - path: AudioCuesheetEditor.End2EndTests/bin/Debug/net9.0/playwright-traces/ + path: AudioCuesheetEditor.End2EndTests/bin/Debug/net10.0/playwright-traces/ if-no-files-found: ignore diff --git a/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj b/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj index 4c5c4ccd..85d73e01 100644 --- a/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj +++ b/AudioCuesheetEditor.End2EndTests/AudioCuesheetEditor.End2EndTests.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 latest enable enable diff --git a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj index 0e10bc14..dc6ac4ec 100644 --- a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj +++ b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj @@ -1,9 +1,9 @@ - net9.0 + net10.0 latest - enable + enable false true Exe diff --git a/AudioCuesheetEditor/AudioCuesheetEditor.csproj b/AudioCuesheetEditor/AudioCuesheetEditor.csproj index ec6a9afa..efe02493 100644 --- a/AudioCuesheetEditor/AudioCuesheetEditor.csproj +++ b/AudioCuesheetEditor/AudioCuesheetEditor.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 true enable enable @@ -22,13 +22,13 @@ - - + + - - + + diff --git a/AudioCuesheetEditor/Program.cs b/AudioCuesheetEditor/Program.cs index dc5ef590..ce09002c 100644 --- a/AudioCuesheetEditor/Program.cs +++ b/AudioCuesheetEditor/Program.cs @@ -27,8 +27,6 @@ using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using MudBlazor.Services; -using System.Globalization; -using System.Reflection; using Toolbelt.Blazor.Extensions.DependencyInjection; var builder = WebAssemblyHostBuilder.CreateDefault(args); @@ -73,29 +71,8 @@ builder.Services.AddHotKeys2(); -// TODO: Remove this when https://github.com/dotnet/aspnetcore/issues/56824 is fixed - -// Get current localization culture -var currentCulture = CultureInfo.DefaultThreadCurrentCulture; - -// Get WASM culture provider via reflection -var type = Assembly.GetAssembly(typeof(WebAssemblyHost))!.GetType("Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyCultureProvider"); -var instance = type - !.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static) - ?.GetValue(null); - -// Swap out the "current culture" for the UI (localization) culture -CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE"); -// Load the satellite assemblies -await (ValueTask)instance! - .GetType() - .GetMethod("LoadCurrentCultureResourcesAsync", BindingFlags.Public | BindingFlags.Instance)! - .Invoke(instance, [])!; -// Swap the culture back -CultureInfo.DefaultThreadCurrentCulture = currentCulture; - var host = builder.Build(); await host.SetCultureFromConfigurationAsync(); -await host.RunAsync(); +await host.RunAsync(); \ No newline at end of file From 150db2eaff3b0fc8c2fa6c48da236040088f8023 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:18:28 +0100 Subject: [PATCH 02/22] fix null reference --- .../Services/IO/FileInputManager.cs | 8 +++++++- .../Services/IO/ImportManager.cs | 20 +++++++++++++++---- .../Shared/TrackList/ArtistColumn.razor | 2 +- .../Shared/TrackList/TitleColumn.razor | 2 +- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/AudioCuesheetEditor/Services/IO/FileInputManager.cs b/AudioCuesheetEditor/Services/IO/FileInputManager.cs index 78154ac4..afcc6854 100644 --- a/AudioCuesheetEditor/Services/IO/FileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/FileInputManager.cs @@ -17,6 +17,7 @@ using AudioCuesheetEditor.Model.IO; using AudioCuesheetEditor.Model.IO.Audio; using Microsoft.AspNetCore.Components.Forms; +using Microsoft.AspNetCore.Components.WebAssembly.Http; using Microsoft.JSInterop; namespace AudioCuesheetEditor.Services.IO @@ -93,7 +94,12 @@ public Boolean CheckFileMimeType(IBrowserFile file, String mimeType, IEnumerable audiofile = new Audiofile(browserFile.Name, audioFileObjectURL, codec); if (String.IsNullOrEmpty(audioFileObjectURL) == false) { - var loadContentStreamTask = _httpClient.GetStreamAsync(audioFileObjectURL) + var request = new HttpRequestMessage(HttpMethod.Get, audioFileObjectURL); + //TODO: Enable when https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/issues/524 gets done + request.SetBrowserRequestStreamingEnabled(false); + + var response = await _httpClient.SendAsync(request); + var loadContentStreamTask = response.Content.ReadAsStreamAsync() .ContinueWith(x => audiofile.ContentStream = x.Result); if (afterContentStreamLoaded != null) { diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs index 0d1a8745..15a32fb3 100644 --- a/AudioCuesheetEditor/Services/IO/ImportManager.cs +++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs @@ -52,7 +52,10 @@ public void ImportData(String? data) FileType = ImportFileType.Textfile }; stopwatch.Stop(); - _logger.LogDebug("ImportData duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug("ImportData duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + } } public async Task AnalyseImportfile() @@ -94,7 +97,10 @@ public async Task AnalyseImportfile() } } stopwatch.Stop(); - _logger.LogDebug("ImportTextAsync duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug("ImportTextAsync duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + } } public void ImportCuesheet() @@ -109,7 +115,10 @@ public void ImportCuesheet() } _sessionStateContainer.ResetImport(); stopwatch.Stop(); - _logger.LogDebug("ImportCuesheet duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug("ImportCuesheet duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + } } public async Task UploadFilesAsync(IEnumerable files, String? fileInputId = null) @@ -175,7 +184,10 @@ public async Task UploadFilesAsync(IEnumerable files, String? file } UploadFilesFinished?.Invoke(this, invalidFiles); stopwatch.Stop(); - _logger.LogDebug("UploadFilesAsync duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug("UploadFilesAsync duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + } } private static async Task ReadFileContentAsync(IBrowserFile file) diff --git a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor index b82322b0..d5e36555 100644 --- a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - diff --git a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor index ccb84295..d97e43ab 100644 --- a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - From ef5be4857a691e7c1268927fd65064adefe90ed5 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:57:44 +0100 Subject: [PATCH 03/22] Update EditTrackModal.razor --- AudioCuesheetEditor/Shared/Dialogs/EditTrackModal.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Dialogs/EditTrackModal.razor b/AudioCuesheetEditor/Shared/Dialogs/EditTrackModal.razor index 14886c52..721e7fe9 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/EditTrackModal.razor +++ b/AudioCuesheetEditor/Shared/Dialogs/EditTrackModal.razor @@ -38,7 +38,7 @@ along with Foobar. If not, see Name = EditedTrack.Artist }; } - @@ -57,7 +57,7 @@ along with Foobar. If not, see Title = EditedTrack.Title }; } - From ec92f9ad3b674f205865bc3441f6d788c32a94cc Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:57:58 +0100 Subject: [PATCH 04/22] Update FileInputManager.cs --- AudioCuesheetEditor/Services/IO/FileInputManager.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor/Services/IO/FileInputManager.cs b/AudioCuesheetEditor/Services/IO/FileInputManager.cs index afcc6854..a47eb4f5 100644 --- a/AudioCuesheetEditor/Services/IO/FileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/FileInputManager.cs @@ -55,7 +55,10 @@ public bool IsValidAudiofile(IBrowserFile browserFile) public Boolean CheckFileMimeType(IBrowserFile file, String mimeType, IEnumerable fileExtensions) { - _logger.LogDebug("CheckFileMimeType called with file: file.Name: '{FileName}', file.ContentType: '{ContentType}', mimeType: '{MimeType}', fileExtensions: '{fileExtensions}'", file.Name, file.ContentType, mimeType, fileExtensions); + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug("CheckFileMimeType called with file: file.Name: '{FileName}', file.ContentType: '{ContentType}', mimeType: '{MimeType}', fileExtensions: '{fileExtensions}'", file.Name, file.ContentType, mimeType, fileExtensions); + } Boolean fileMimeTypeMatches = false; if ((file != null) && (String.IsNullOrEmpty(mimeType) == false)) { @@ -63,7 +66,7 @@ public Boolean CheckFileMimeType(IBrowserFile file, String mimeType, IEnumerable { if (mimeType.EndsWith("/*")) { - var mainType = mimeType.Substring(0, mimeType.Length - 1); + var mainType = mimeType[..^1]; fileMimeTypeMatches = file.ContentType.StartsWith(mainType, StringComparison.CurrentCultureIgnoreCase); } else From 469e460955fdca4ce9d6a27362e4881dbe1b3ba2 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:03:15 +0100 Subject: [PATCH 05/22] Update AddTrack.razor --- AudioCuesheetEditor/Shared/Record/AddTrack.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Record/AddTrack.razor b/AudioCuesheetEditor/Shared/Record/AddTrack.razor index ba00b751..102317a2 100644 --- a/AudioCuesheetEditor/Shared/Record/AddTrack.razor +++ b/AudioCuesheetEditor/Shared/Record/AddTrack.razor @@ -31,7 +31,7 @@ along with Foobar. If not, see Name = currentRecordingTrack.Artist }; } - @@ -53,7 +53,7 @@ along with Foobar. If not, see Title = currentRecordingTrack.Title }; } - From a10a4d2bfb96cdfbc5f9c52beae1bfa101df5097 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:08:34 +0100 Subject: [PATCH 06/22] Update .editorconfig --- .editorconfig | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.editorconfig b/.editorconfig index 9d73dbfd..d735b55b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,7 +1 @@ -[*.cs] - -# IDE0016: throw-Ausdruck verwenden -csharp_style_throw_expression = false:suggestion - -# IDE0057: Bereichsoperator verwenden -csharp_style_prefer_range_operator = false:suggestion +[*.cs] \ No newline at end of file From b28d73de218bf356c460a573438a76e333aa7a8a Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:11:04 +0100 Subject: [PATCH 07/22] Update index.html --- AudioCuesheetEditor/wwwroot/index.html | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/AudioCuesheetEditor/wwwroot/index.html b/AudioCuesheetEditor/wwwroot/index.html index 0f4b486f..9edfd235 100644 --- a/AudioCuesheetEditor/wwwroot/index.html +++ b/AudioCuesheetEditor/wwwroot/index.html @@ -1,9 +1,9 @@ - + - + AudioCuesheetEditor @@ -32,14 +32,13 @@ position: relative; } -
- +

Loading application, please stand by ...

@@ -55,7 +54,7 @@ 🗙
- + From 749553b5c502877b14c43fe70a2c612ae18738ba Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:18:36 +0100 Subject: [PATCH 08/22] use culture for switching culture --- .../Services/UI/LocalizationService.cs | 16 ++++++++-------- AudioCuesheetEditor/Shared/AppBar.razor | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/AudioCuesheetEditor/Services/UI/LocalizationService.cs b/AudioCuesheetEditor/Services/UI/LocalizationService.cs index c48c8588..96934225 100644 --- a/AudioCuesheetEditor/Services/UI/LocalizationService.cs +++ b/AudioCuesheetEditor/Services/UI/LocalizationService.cs @@ -46,27 +46,27 @@ public async Task SetCultureFromConfigurationAsync() { var options = await _localStorageOptionsProvider.GetOptionsAsync(); - ChangeLanguage(options.Culture.Name); + ChangeLanguage(options.Culture); } - public async Task ChangeLanguageAsync(string name) + public async Task ChangeLanguageAsync(CultureInfo culture) { - if (ChangeLanguage(name)) + if (ChangeLanguage(culture)) { - await _localStorageOptionsProvider.SaveOptionsValueAsync(x => x.CultureName!, name); + await _localStorageOptionsProvider.SaveOptionsValueAsync(x => x.CultureName!, culture.Name); LocalizationChanged?.Invoke(this, new EventArgs()); } } - private static Boolean ChangeLanguage(string name) + private static Boolean ChangeLanguage(CultureInfo newCulture) { - var newCulture = AvailableCultures.SingleOrDefault(c => c.Name == name); - if (newCulture != null) + var contains = AvailableCultures.Contains(newCulture); + if (contains) { CultureInfo.DefaultThreadCurrentUICulture = newCulture; CultureInfo.CurrentUICulture = newCulture; } - return newCulture != null; + return contains; } } } diff --git a/AudioCuesheetEditor/Shared/AppBar.razor b/AudioCuesheetEditor/Shared/AppBar.razor index 9631153d..4fbda6c8 100644 --- a/AudioCuesheetEditor/Shared/AppBar.razor +++ b/AudioCuesheetEditor/Shared/AppBar.razor @@ -59,7 +59,7 @@ along with Foobar. If not, see @foreach (var culture in LocalizationService.AvailableCultures) { - @IsoCountryCodeToFlagEmoji(culture) @culture.DisplayName + @IsoCountryCodeToFlagEmoji(culture) @culture.DisplayName } @@ -115,9 +115,9 @@ along with Foobar. If not, see [Parameter] public Boolean DisplayReset { get; set; } - async Task SelectedCultureChanged(string name) + async Task SelectedCultureChanged(CultureInfo culture) { - await base.LocalizationService.ChangeLanguageAsync(name); + await base.LocalizationService.ChangeLanguageAsync(culture); } String GetStyle(CultureInfo cultureInfo) From a45051ba1fde408a7468fd4096eebd01c7849956 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:00:21 +0100 Subject: [PATCH 09/22] reload after switching language --- .../Services/UI/LocalizationService.cs | 13 ++-- AudioCuesheetEditor/Shared/AppBar.razor | 10 +++- .../Shared/BaseLocalizedComponent.cs | 7 --- .../BaseLocalizedLayoutComponentBase.cs | 59 ------------------- .../Shared/Layouts/MainLayout.razor | 5 +- .../Layouts/MainLayoutWithoutMenu.razor | 3 +- 6 files changed, 19 insertions(+), 78 deletions(-) delete mode 100644 AudioCuesheetEditor/Shared/Layouts/BaseLocalizedLayoutComponentBase.cs diff --git a/AudioCuesheetEditor/Services/UI/LocalizationService.cs b/AudioCuesheetEditor/Services/UI/LocalizationService.cs index 96934225..f158f979 100644 --- a/AudioCuesheetEditor/Services/UI/LocalizationService.cs +++ b/AudioCuesheetEditor/Services/UI/LocalizationService.cs @@ -15,13 +15,17 @@ //. using AudioCuesheetEditor.Data.Options; using AudioCuesheetEditor.Model.Options; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; using System.Globalization; namespace AudioCuesheetEditor.Services.UI { - public class LocalizationService(ILocalStorageOptionsProvider localStorageOptionsProvider) + public class LocalizationService(ILocalStorageOptionsProvider localStorageOptionsProvider, NavigationManager navigationManager, IJSRuntime jsRuntime) { private readonly ILocalStorageOptionsProvider _localStorageOptionsProvider = localStorageOptionsProvider; + private readonly NavigationManager _navigationManager = navigationManager; + private readonly IJSRuntime _jsRuntime = jsRuntime; public const String DefaultCulture = "en-US"; @@ -38,8 +42,6 @@ public static IReadOnlyCollection AvailableCultures } } - public event EventHandler? LocalizationChanged; - public static CultureInfo SelectedCulture => CultureInfo.DefaultThreadCurrentUICulture ?? CultureInfo.CurrentUICulture; public async Task SetCultureFromConfigurationAsync() @@ -54,7 +56,8 @@ public async Task ChangeLanguageAsync(CultureInfo culture) if (ChangeLanguage(culture)) { await _localStorageOptionsProvider.SaveOptionsValueAsync(x => x.CultureName!, culture.Name); - LocalizationChanged?.Invoke(this, new EventArgs()); + await _jsRuntime.InvokeVoidAsync("removeBeforeunload"); + _navigationManager.NavigateTo(_navigationManager.Uri, true); } } @@ -64,7 +67,7 @@ private static Boolean ChangeLanguage(CultureInfo newCulture) if (contains) { CultureInfo.DefaultThreadCurrentUICulture = newCulture; - CultureInfo.CurrentUICulture = newCulture; + CultureInfo.DefaultThreadCurrentCulture = newCulture; } return contains; } diff --git a/AudioCuesheetEditor/Shared/AppBar.razor b/AudioCuesheetEditor/Shared/AppBar.razor index 4fbda6c8..771d40f1 100644 --- a/AudioCuesheetEditor/Shared/AppBar.razor +++ b/AudioCuesheetEditor/Shared/AppBar.razor @@ -69,7 +69,10 @@ along with Foobar. If not, see } @_localizer["Help"] @_localizer["About"] - @_localizer["Hotkeys"] + @if (DisplayHotkeys) + { + @_localizer["Hotkeys"] + } @_localizer["Preview environment"] @if (DisplayReset) { @@ -115,6 +118,9 @@ along with Foobar. If not, see [Parameter] public Boolean DisplayReset { get; set; } + [Parameter] + public Boolean DisplayHotkeys { get; set; } + async Task SelectedCultureChanged(CultureInfo culture) { await base.LocalizationService.ChangeLanguageAsync(culture); @@ -223,7 +229,7 @@ along with Foobar. If not, see await _importManager.UploadFilesAsync([file]); } - async Task DisplayHotkeys() + async Task ShowHotkeysDialog() { var options = new DialogOptions() { BackdropClick = false, CloseOnEscapeKey = true, CloseButton = true, FullWidth = true, MaxWidth = MaxWidth.Large }; await _dialogService.ShowAsync(_localizer["Hotkeys"], options); diff --git a/AudioCuesheetEditor/Shared/BaseLocalizedComponent.cs b/AudioCuesheetEditor/Shared/BaseLocalizedComponent.cs index 5a31acad..ddb56da7 100644 --- a/AudioCuesheetEditor/Shared/BaseLocalizedComponent.cs +++ b/AudioCuesheetEditor/Shared/BaseLocalizedComponent.cs @@ -33,7 +33,6 @@ public abstract class BaseLocalizedComponent : ComponentBase, IDisposable protected override void OnInitialized() { base.OnInitialized(); - LocalizationService.LocalizationChanged += LocalizationService_LocalizationChanged; TraceChangeManager.TracedObjectHistoryChanged += TraceChangeManager_TracedObjectHistoryChanged; TraceChangeManager.UndoDone += TraceChangeManager_UndoDone; TraceChangeManager.RedoDone += TraceChangeManager_RedoDone; @@ -54,18 +53,12 @@ void TraceChangeManager_TracedObjectHistoryChanged(object? sender, EventArgs e) StateHasChanged(); } - void LocalizationService_LocalizationChanged(object? sender, EventArgs args) - { - StateHasChanged(); - } - protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { - LocalizationService.LocalizationChanged -= LocalizationService_LocalizationChanged; TraceChangeManager.TracedObjectHistoryChanged -= TraceChangeManager_TracedObjectHistoryChanged; TraceChangeManager.UndoDone -= TraceChangeManager_UndoDone; TraceChangeManager.RedoDone -= TraceChangeManager_RedoDone; diff --git a/AudioCuesheetEditor/Shared/Layouts/BaseLocalizedLayoutComponentBase.cs b/AudioCuesheetEditor/Shared/Layouts/BaseLocalizedLayoutComponentBase.cs deleted file mode 100644 index 63470c21..00000000 --- a/AudioCuesheetEditor/Shared/Layouts/BaseLocalizedLayoutComponentBase.cs +++ /dev/null @@ -1,59 +0,0 @@ -//This file is part of AudioCuesheetEditor. - -//AudioCuesheetEditor is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//AudioCuesheetEditor is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with Foobar. If not, see -//. -using AudioCuesheetEditor.Services.UI; -using Microsoft.AspNetCore.Components; - -namespace AudioCuesheetEditor.Shared.Layouts -{ - public class BaseLocalizedLayoutComponentBase: LayoutComponentBase, IDisposable - { - private bool disposedValue; - - [Inject] - protected LocalizationService LocalizationService { get; set; } = default!; - - protected override void OnInitialized() - { - base.OnInitialized(); - LocalizationService.LocalizationChanged += LocalizationService_LocalizationChanged; - } - - void LocalizationService_LocalizationChanged(object? sender, EventArgs args) - { - StateHasChanged(); - } - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - LocalizationService.LocalizationChanged -= LocalizationService_LocalizationChanged; - } - - disposedValue = true; - } - } - - public void Dispose() - { - // Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in der Methode "Dispose(bool disposing)" ein. - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - } -} diff --git a/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor b/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor index ba89985e..2a9a319d 100644 --- a/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor +++ b/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor @@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License along with Foobar. If not, see . --> - -@inherits BaseLocalizedLayoutComponentBase +@inherits LayoutComponentBase @inject NavigationManager _navigationManager @inject IStringLocalizer _localizer @@ -26,7 +25,7 @@ along with Foobar. If not, see - + @Body diff --git a/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor b/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor index 8791ef1c..1fa5d25d 100644 --- a/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor +++ b/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor @@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License along with Foobar. If not, see . --> - -@inherits BaseLocalizedLayoutComponentBase +@inherits LayoutComponentBase @inject NavigationManager _navigationManager @inject IStringLocalizer _localizer From 7d5a6be892c36c38f2d9fb50b0da26407fdabd1c Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:03:20 +0100 Subject: [PATCH 10/22] Update AppBar.cs --- AudioCuesheetEditor.End2EndTests/Models/AppBar.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs b/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs index 6129ffd9..69bd206c 100644 --- a/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs +++ b/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs @@ -48,6 +48,8 @@ internal async Task ChangeLanguageAsync(string language) { await _page.GetByRole(AriaRole.Button, new() { Name = "Change language" }).ClickAsync(); await _page.GetByText(language).ClickAsync(); + await _page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await _page.WaitForFunctionAsync(@"() => window.Blazor !== undefined"); } internal async Task UndoAsync() From ab4f9b5624b5d87bc843894ea00281594915a5f1 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:45:49 +0100 Subject: [PATCH 11/22] fix tracks table --- AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor | 3 ++- AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor index d5e36555..3ad6d073 100644 --- a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - @@ -34,6 +34,7 @@ along with Foobar. If not, see @code { + //TODO: Check if ToStringFunc really gets a nullable or not [Parameter] [EditorRequired] public Track Track { get; set; } = default!; diff --git a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor index d97e43ab..0e8d5261 100644 --- a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - @@ -34,6 +34,7 @@ along with Foobar. If not, see @code { + //TODO: Check if ToStringFunc really gets a nullable or not [Parameter] [EditorRequired] public Track Track { get; set; } = default!; From a6143a6231ee1afb8a121930f7f14cfad0ca3412 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 27 Feb 2026 13:04:06 +0100 Subject: [PATCH 12/22] Update Track.cs --- AudioCuesheetEditor/Model/AudioCuesheet/Track.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/Model/AudioCuesheet/Track.cs b/AudioCuesheetEditor/Model/AudioCuesheet/Track.cs index 60e42688..09b511b7 100644 --- a/AudioCuesheetEditor/Model/AudioCuesheet/Track.cs +++ b/AudioCuesheetEditor/Model/AudioCuesheet/Track.cs @@ -60,7 +60,7 @@ public Track() { } /// Create object with copied values from input /// /// Object to copy values from - /// /// Copy cuesheet reference from track also? + /// Copy cuesheet reference from track also? public Track(ITrack track, Boolean copyCuesheetReference = true) : this() { CopyValues(track, copyCuesheetReference); From 74326626a4b8a6de11c9b271477ba600bd41f9b9 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 27 Feb 2026 15:03:04 +0100 Subject: [PATCH 13/22] fix tests --- AudioCuesheetEditor.End2EndTests/MSTestSettings.cs | 2 +- AudioCuesheetEditor.Tests/MSTestSettings.cs | 2 +- AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor | 3 +-- AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs b/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs index aaf278c8..2492be6d 100644 --- a/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs +++ b/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs @@ -1 +1 @@ -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] +[assembly: Parallelize()] diff --git a/AudioCuesheetEditor.Tests/MSTestSettings.cs b/AudioCuesheetEditor.Tests/MSTestSettings.cs index e466aa12..8a30f591 100644 --- a/AudioCuesheetEditor.Tests/MSTestSettings.cs +++ b/AudioCuesheetEditor.Tests/MSTestSettings.cs @@ -1,3 +1,3 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] +[assembly: Parallelize()] diff --git a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor index 3ad6d073..154acdbd 100644 --- a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - @@ -34,7 +34,6 @@ along with Foobar. If not, see @code { - //TODO: Check if ToStringFunc really gets a nullable or not [Parameter] [EditorRequired] public Track Track { get; set; } = default!; diff --git a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor index 0e8d5261..4d787e9c 100644 --- a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - @@ -34,7 +34,6 @@ along with Foobar. If not, see @code { - //TODO: Check if ToStringFunc really gets a nullable or not [Parameter] [EditorRequired] public Track Track { get; set; } = default!; From f5f4ad67354d00633052bf33a68283082dc4b513 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 27 Feb 2026 15:11:19 +0100 Subject: [PATCH 14/22] reset to method level parlellization --- AudioCuesheetEditor.End2EndTests/MSTestSettings.cs | 2 +- AudioCuesheetEditor.Tests/MSTestSettings.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs b/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs index 2492be6d..aaf278c8 100644 --- a/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs +++ b/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs @@ -1 +1 @@ -[assembly: Parallelize()] +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/AudioCuesheetEditor.Tests/MSTestSettings.cs b/AudioCuesheetEditor.Tests/MSTestSettings.cs index 8a30f591..e466aa12 100644 --- a/AudioCuesheetEditor.Tests/MSTestSettings.cs +++ b/AudioCuesheetEditor.Tests/MSTestSettings.cs @@ -1,3 +1,3 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -[assembly: Parallelize()] +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] From fba8d10267a9a27d9d0ae84f0365f243ec968cf8 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:19:21 +0100 Subject: [PATCH 15/22] Update MSTestSettings.cs --- AudioCuesheetEditor.End2EndTests/MSTestSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs b/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs index aaf278c8..2492be6d 100644 --- a/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs +++ b/AudioCuesheetEditor.End2EndTests/MSTestSettings.cs @@ -1 +1 @@ -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] +[assembly: Parallelize()] From f05f0ee1688243f949508c5a372dff2484de2180 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 3 Mar 2026 14:41:28 +0100 Subject: [PATCH 16/22] Update ArtistColumn.razor --- AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor index 154acdbd..b82322b0 100644 --- a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - From ae3f9fdc8182e8fd487ea38ec73ced31d6ba4135 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 3 Mar 2026 15:07:43 +0100 Subject: [PATCH 17/22] Update ArtistColumn.razor --- AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor index b82322b0..154acdbd 100644 --- a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - From 8130f2a59e051e40fbf30c6c85f0691e54bfd5c9 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 3 Mar 2026 15:31:47 +0100 Subject: [PATCH 18/22] fix autocomplete handling --- .../Shared/TrackList/ArtistColumn.razor | 48 +++++++----- .../Shared/TrackList/TitleColumn.razor | 74 +++++++++++-------- 2 files changed, 71 insertions(+), 51 deletions(-) diff --git a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor index 154acdbd..6e949688 100644 --- a/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/ArtistColumn.razor @@ -20,9 +20,9 @@ along with Foobar. If not, see @inject AutocompleteManager _autocompleteManager @inject ValidationService _validationService - + @context.Name @if (context.Disambiguation != null) @@ -38,39 +38,49 @@ along with Foobar. If not, see [EditorRequired] public Track Track { get; set; } = default!; - MusicBrainzArtist? autocompleteArtist; - string? artist; - Timer? debounceTimer; + MusicBrainzArtist? _autocompleteArtist; + string? _artist; + CancellationTokenSource? _cancellationTokenSource; protected override void OnParametersSet() { base.OnParametersSet(); - autocompleteArtist = new() { Name = Track.Artist }; - artist = autocompleteArtist.Name; + SetComponentValues(new() { Name = Track.Artist }); } - void ValueChanged(MusicBrainzArtist? newValue) + void SetComponentValues(MusicBrainzArtist? newValue) { - autocompleteArtist = newValue; - artist = autocompleteArtist?.Name; - StartChangeTimer(); + if (newValue?.Name != _autocompleteArtist?.Name) + { + _autocompleteArtist = newValue; + _artist = _autocompleteArtist?.Name; + } } - void OnBlur(FocusEventArgs args) + void ValueChanged(MusicBrainzArtist? newValue) { + SetComponentValues(newValue); StartChangeTimer(); } void StartChangeTimer() { - debounceTimer = new Timer(100); - debounceTimer.Elapsed += ChangeArtist; - debounceTimer.AutoReset = false; - debounceTimer.Start(); + _cancellationTokenSource?.Cancel(); + _cancellationTokenSource = new CancellationTokenSource(); + + _ = DebounceAsync(_cancellationTokenSource.Token); } - void ChangeArtist(object? sender, System.Timers.ElapsedEventArgs e) + async Task DebounceAsync(CancellationToken token) { - Track.Artist = artist; + try + { + await Task.Delay(100, token); + Track.Artist = _artist; + } + catch (TaskCanceledException) + { + //Nothing to do here + } } } diff --git a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor index 4d787e9c..68b190ff 100644 --- a/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor +++ b/AudioCuesheetEditor/Shared/TrackList/TitleColumn.razor @@ -21,8 +21,8 @@ along with Foobar. If not, see @inject ValidationService _validationService + @bind-Text="_title" Value="_autocompleteTrack" ValueChanged="TitleSelected" ResetValueOnEmptyText Clearable ShowProgressIndicator + Validation="(string? newTitle) => _validationService.Validate(Track, nameof(Track.Title))" MaxItems="null" CoerceText="false" OnBlur="() => StartChangeTimer()"> @autocompleteContext.Title @if (autocompleteContext.Disambiguation != null) @@ -42,55 +42,65 @@ along with Foobar. If not, see [EditorRequired] public ViewMode CurrentViewMode { get; set; } - MusicBrainzTrack? autocompleteTrack; - string? title; - Timer? debounceTimer; + MusicBrainzTrack? _autocompleteTrack; + string? _title; + CancellationTokenSource? _cancellationTokenSource; protected override void OnParametersSet() { base.OnParametersSet(); - autocompleteTrack = new() { Artist = Track.Artist, Title = Track.Title }; - title = autocompleteTrack?.Title; + SetComponentValues(new() { Artist = Track.Artist, Title = Track.Title }); } - void TitleSelected(MusicBrainzTrack? newValue) + void SetComponentValues(MusicBrainzTrack? newValue) { - autocompleteTrack = newValue; - title = autocompleteTrack?.Title; - StartChangeTimer(); + if ((newValue?.Artist != _autocompleteTrack?.Artist) || (newValue?.Title != _autocompleteTrack?.Title)) + { + _autocompleteTrack = newValue; + _title = _autocompleteTrack?.Title; + } } - void OnBlur(FocusEventArgs args) + void TitleSelected(MusicBrainzTrack? newValue) { + SetComponentValues(newValue); StartChangeTimer(); } void StartChangeTimer() { - debounceTimer = new Timer(100); - debounceTimer.Elapsed += ChangeTitle; - debounceTimer.AutoReset = false; - debounceTimer.Start(); + _cancellationTokenSource?.Cancel(); + _cancellationTokenSource = new CancellationTokenSource(); + + _ = DebounceAsync(_cancellationTokenSource.Token); } - void ChangeTitle(object? sender, System.Timers.ElapsedEventArgs e) + async Task DebounceAsync(CancellationToken token) { - base.TraceChangeManager.BulkEdit = true; - Track.Title = title; - switch (CurrentViewMode) + try + { + await Task.Delay(100, token); + base.TraceChangeManager.BulkEdit = true; + Track.Title = _title; + switch (CurrentViewMode) + { + case ViewMode.DetailView: + case ViewMode.ImportView: + if ((String.IsNullOrEmpty(Track.Artist)) && (String.IsNullOrEmpty(_autocompleteTrack?.Artist) == false)) + { + Track.Artist = _autocompleteTrack.Artist; + } + if ((Track.Length.HasValue == false) && (_autocompleteTrack?.Length.HasValue == true)) + { + Track.Length = _autocompleteTrack?.Length; + } + break; + } + base.TraceChangeManager.BulkEdit = false; + } + catch (TaskCanceledException) { - case ViewMode.DetailView: - case ViewMode.ImportView: - if ((String.IsNullOrEmpty(Track.Artist)) && (String.IsNullOrEmpty(autocompleteTrack?.Artist) == false)) - { - Track.Artist = autocompleteTrack.Artist; - } - if ((Track.Length.HasValue == false) && (autocompleteTrack?.Length.HasValue == true)) - { - Track.Length = autocompleteTrack?.Length; - } - break; + //Nothing to do here } - base.TraceChangeManager.BulkEdit = false; } } From 40f1b6744342fe21f9670733748fc12322b31aa0 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 4 Mar 2026 09:12:30 +0100 Subject: [PATCH 19/22] fix browser issues --- .../Models/AppBar.cs | 16 +++++----------- .../Tests/Desktop/ExportTest.cs | 2 +- .../Tests/Smartphone/ExportTestSmartphone.cs | 2 +- AudioCuesheetEditor/Shared/AppBar.razor | 2 +- .../Shared/Audio/AudioPlayer.razor | 10 +++++----- .../Shared/Cuesheet/EditSections.razor | 2 +- .../Shared/Dialogs/ConfirmationDialog.razor | 4 ++-- .../Shared/Inputs/FileInput.razor | 10 +++++----- 8 files changed, 21 insertions(+), 27 deletions(-) diff --git a/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs b/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs index 69bd206c..ee614bf3 100644 --- a/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs +++ b/AudioCuesheetEditor.End2EndTests/Models/AppBar.cs @@ -18,13 +18,13 @@ namespace AudioCuesheetEditor.End2EndTests.Models { - partial class AppBar + partial class AppBar(IPage page) { [GeneratedRegex("^Open$")] private static partial Regex OpenRegex(); - private readonly IPage _page; - private readonly ILocator _menuButton; + private readonly IPage _page = page; + internal ILocator MenuButton => _page.GetByRole(AriaRole.Toolbar).GetByRole(AriaRole.Button, new() { Name = "More" }); internal ILocator UndoButton => _page.GetByRole(AriaRole.Button, new() { Name = "undo" }); @@ -32,15 +32,9 @@ partial class AppBar internal ILocator HomeButton => _page.Locator(".mud-button-root").First; - internal AppBar(IPage page) - { - _page = page; - _menuButton = _page.GetByRole(AriaRole.Button, new() { Name = "More" }); - } - internal async Task OpenSettingsAsync() { - await _menuButton.ClickAsync(); + await MenuButton.ClickAsync(); await _page.GetByText("Settings").ClickAsync(); } @@ -83,7 +77,7 @@ internal async Task OpenExportDialogAsync(string exportType, string fileMenuName internal async Task OpenDisplayHotkeysAsync() { - await _page.GetByRole(AriaRole.Button, new() { Name = "More" }).ClickAsync(); + await MenuButton.ClickAsync(); await _page.GetByText("Hotkeys").ClickAsync(); } } diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs index 85555e5b..58d53768 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs @@ -83,7 +83,7 @@ public async Task DownloadText_GeneratesTextFile_WhenCuesheetIsValidAsync() await detailView.AudiofileInput.SetInputFilesAsync("Kalimba.mp3"); await detailView.EditTrackAsync("Track Artist 1", "Track Title 1"); await bar.OpenExportDialogAsync("Textfile"); - await TestPage.GetByRole(AriaRole.Button, new() { Name = "Next" }).ClickAsync(); + await TestPage.GetByRole(AriaRole.Button, new() { Name = "Next", Exact = true }).ClickAsync(); var downloadTask = TestPage.WaitForDownloadAsync(); await TestPage.GetByRole(AriaRole.Button, new() { Name = "Download-YouTube.txt" }).ClickAsync(); var download = await downloadTask; diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs index 385e3aa3..6bee002f 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs @@ -83,7 +83,7 @@ public async Task DownloadText_GeneratesTextFile_WhenCuesheetIsValidAsync() await detailView.AudiofileInput.SetInputFilesAsync("Kalimba.mp3"); await detailView.EditTrackAsync("Track Artist 1", "Track Title 1"); await bar.OpenExportDialogAsync("Textfile"); - await TestPage.GetByRole(AriaRole.Button, new() { Name = "Next" }).ClickAsync(); + await TestPage.GetByRole(AriaRole.Button, new() { Name = "Next", Exact = true }).ClickAsync(); var downloadTask = TestPage.WaitForDownloadAsync(); await TestPage.GetByRole(AriaRole.Button, new() { Name = "Download-YouTube.txt" }).ClickAsync(); var download = await downloadTask; diff --git a/AudioCuesheetEditor/Shared/AppBar.razor b/AudioCuesheetEditor/Shared/AppBar.razor index 771d40f1..746f5c60 100644 --- a/AudioCuesheetEditor/Shared/AppBar.razor +++ b/AudioCuesheetEditor/Shared/AppBar.razor @@ -27,7 +27,7 @@ along with Foobar. If not, see @inject ImportManager _importManager - + AudioCuesheetEditor diff --git a/AudioCuesheetEditor/Shared/Audio/AudioPlayer.razor b/AudioCuesheetEditor/Shared/Audio/AudioPlayer.razor index 11224223..5533938b 100644 --- a/AudioCuesheetEditor/Shared/Audio/AudioPlayer.razor +++ b/AudioCuesheetEditor/Shared/Audio/AudioPlayer.razor @@ -38,7 +38,7 @@ along with Foobar. If not, see { @String.Format("--{0}--{1}--", CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator, CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator) } - + @GetSliderTimeValue() @@ -54,17 +54,17 @@ along with Foobar. If not, see - + - + - + - + diff --git a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor b/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor index fa21e07c..d1abd5cb 100644 --- a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor +++ b/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor @@ -26,7 +26,7 @@ along with Foobar. If not, see - + diff --git a/AudioCuesheetEditor/Shared/Dialogs/ConfirmationDialog.razor b/AudioCuesheetEditor/Shared/Dialogs/ConfirmationDialog.razor index 4aafb337..98b7d01a 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/ConfirmationDialog.razor +++ b/AudioCuesheetEditor/Shared/Dialogs/ConfirmationDialog.razor @@ -24,8 +24,8 @@ along with Foobar. If not, see @ConfirmText - @_localizer["Yes"] - @_localizer["No"] + @_localizer["Yes"] + @_localizer["No"] diff --git a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor index 91ebeb91..65769f6c 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor @@ -21,19 +21,19 @@ along with Foobar. If not, see - @_localizer["Search"] + @_localizer["Search"] - + @if (DisplayMenu) { - - @_localizer["Rename file"] + + @_localizer["Rename file"] } From fbb3a92aebcbc83cd3d93d1758fcbb7b793e16fd Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:29:41 +0100 Subject: [PATCH 20/22] Update Readme.md --- Readme.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Readme.md b/Readme.md index 23511888..2a69f968 100644 --- a/Readme.md +++ b/Readme.md @@ -1,36 +1,40 @@ -## Introduction +# Introduction -### What is AudioCuesheetEditor? +## What is AudioCuesheetEditor? AudioCuesheetEditor is a Blazor based web port of AudioCuesheetEditor (https://sourceforge.net/projects/audiocuesheet/). Basically it is a program for handling audio cuesheet files and everything around. -### Description +## Description AudioCuesheetEditor is a Blazor based web application for writing audio cuesheets. There is much validation that helps the user to write a valid cuesheet. You can import external data (like text files, xml files, etc.) and analyse them directly in GUI. There are also much export variations like CSV, but you can customize export freely. -## Usage +# Usage Simply open the link https://audiocuesheeteditor.netlify.app/ on any browser -## Environments +# Environments -### Production +## Production [![Build & Deploy](https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/actions/workflows/build_pipeline.yml/badge.svg?branch=master)](https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/actions/workflows/build_pipeline.yml) The current stable version can be found here: https://audiocuesheeteditor.netlify.app/ -### Preview +## Preview [![Build & Deploy](https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/actions/workflows/build_pipeline.yml/badge.svg?branch=development)](https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/actions/workflows/build_pipeline.yml) The next release candidate version can be found here: https://preview-audiocuesheeteditor.netlify.app/ -## Contributing +# Contributing You can contribute to the project by opening up issues or adding feature requests. To do so, you simply open https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/issues and add a new issue. If you want, you can also contribute by developing a feature or fixing a bug. More can be found here: https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/blob/master/CONTRIBUTING.md -## License +## Requirements + +This application is build using Blazor WASM Standalone and needs .NET 10 to run. Tests are running using MSTest and Playwright. + +# License GNU GENERAL PUBLIC LICENSE Version 3 From d535581cb21b08dde4a6321dc3ae7a558fdb6321 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:33:43 +0100 Subject: [PATCH 21/22] Update AudioCuesheetEditor.csproj --- AudioCuesheetEditor/AudioCuesheetEditor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/AudioCuesheetEditor.csproj b/AudioCuesheetEditor/AudioCuesheetEditor.csproj index efe02493..d1d88f83 100644 --- a/AudioCuesheetEditor/AudioCuesheetEditor.csproj +++ b/AudioCuesheetEditor/AudioCuesheetEditor.csproj @@ -7,7 +7,7 @@ enable https://github.com/NeoCoderMatrix86/AudioCuesheetEditor 3.0 - 10.4.0 + 11.0.0 false true true From 5ca3079512645c8a277fb59457b3ade106db08ec Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:40:00 +0100 Subject: [PATCH 22/22] Update AudioCuesheetEditor.csproj --- AudioCuesheetEditor/AudioCuesheetEditor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/AudioCuesheetEditor.csproj b/AudioCuesheetEditor/AudioCuesheetEditor.csproj index d1d88f83..d7bb3822 100644 --- a/AudioCuesheetEditor/AudioCuesheetEditor.csproj +++ b/AudioCuesheetEditor/AudioCuesheetEditor.csproj @@ -26,7 +26,7 @@ - +