From ab9272678bf935d9c3fae9447436a1778ffd5981 Mon Sep 17 00:00:00 2001 From: NeoCoderMatrix86 <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:16:09 +0100 Subject: [PATCH 01/64] first step to new import view --- AudioCuesheetEditor/Pages/Index.razor | 4 ++- .../Shared/ViewModes/NewViewModeImport.razor | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor diff --git a/AudioCuesheetEditor/Pages/Index.razor b/AudioCuesheetEditor/Pages/Index.razor index 64a3150d..c0d510b7 100644 --- a/AudioCuesheetEditor/Pages/Index.razor +++ b/AudioCuesheetEditor/Pages/Index.razor @@ -31,12 +31,14 @@ along with Foobar. If not, see - + @* *@ + @code{ + //TODO: Move back to ViewModeImport ViewOptions? options; ViewMode currentViewmode = ViewMode.DetailView; diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor new file mode 100644 index 00000000..52fd6848 --- /dev/null +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -0,0 +1,33 @@ + +@inherits BaseLocalizedComponent + +@inject ILogger _logger +@inject IStringLocalizer _localizer + + + + + +@code { + //TODO: Make a new component for new import view, which starts with a text input area (respective file upload) + //TODO: Add a preview of parsed data + + private string? importText; +} From abbce37ed5ce63ecb6fbb98923c4169182de2148 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Mon, 12 Jan 2026 16:47:22 +0100 Subject: [PATCH 02/64] Update NewViewModeImport.razor --- AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor index 52fd6848..a66fdb18 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -22,7 +22,8 @@ along with Foobar. If not, see + Lines="15" @bind-Value="importText" FullWidth /> + @code { From 9061cfcea6ed12459d3388f35adb89eb3a04b4d6 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Mon, 12 Jan 2026 17:08:08 +0100 Subject: [PATCH 03/64] Update NewViewModeImport.razor --- .../Shared/ViewModes/NewViewModeImport.razor | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor index a66fdb18..ae941e2d 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -17,16 +17,25 @@ along with Foobar. If not, see --> @inherits BaseLocalizedComponent -@inject ILogger _logger -@inject IStringLocalizer _localizer - - - - - + + + + + + + Upload File + + + Import data + + + + + @code { + //TODO: Localization + //TODO: Arrange buttons on mudstack and make icon buttons, etc. //TODO: Make a new component for new import view, which starts with a text input area (respective file upload) //TODO: Add a preview of parsed data From c9f793bab275dfebbf3d09d4765c78cbb8f7fd76 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:39:48 +0100 Subject: [PATCH 04/64] Update ImportManager.cs --- AudioCuesheetEditor/Services/IO/ImportManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs index ba80e27c..d4796079 100644 --- a/AudioCuesheetEditor/Services/IO/ImportManager.cs +++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs @@ -18,7 +18,6 @@ using AudioCuesheetEditor.Model.IO; using AudioCuesheetEditor.Model.IO.Audio; using AudioCuesheetEditor.Model.IO.Import; -using AudioCuesheetEditor.Model.UI; using AudioCuesheetEditor.Services.UI; using Microsoft.AspNetCore.Components.Forms; using System.Diagnostics; From 707ea18948a969f8a133277fe863a77d1d25463f Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 13 Jan 2026 10:26:36 +0100 Subject: [PATCH 05/64] Update NewViewModeImport.razor --- .../Shared/ViewModes/NewViewModeImport.razor | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor index ae941e2d..a91fd3c6 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -19,25 +19,24 @@ along with Foobar. If not, see - - - - - Upload File - - - Import data - - - + + + + + Upload File + + + Analyse data + + + @code { //TODO: Localization - //TODO: Arrange buttons on mudstack and make icon buttons, etc. - //TODO: Make a new component for new import view, which starts with a text input area (respective file upload) + //TODO: Add selection of import profile //TODO: Add a preview of parsed data private string? importText; -} +} \ No newline at end of file From a09b1c1023e929b82be7c0a75c62bbca8921268f Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 13 Jan 2026 10:31:49 +0100 Subject: [PATCH 06/64] Update NewViewModeImport.razor --- AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor index a91fd3c6..2df2209c 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -35,6 +35,7 @@ along with Foobar. If not, see @code { //TODO: Localization + //TODO: Drag n Drop files //TODO: Add selection of import profile //TODO: Add a preview of parsed data From 9c0b3651766c3954126f3169a83ace3ce3c4f10b Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 13 Jan 2026 15:54:11 +0100 Subject: [PATCH 07/64] Update NewViewModeImport.razor --- .../Shared/ViewModes/NewViewModeImport.razor | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor index 2df2209c..320aea54 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -17,21 +17,30 @@ along with Foobar. If not, see --> @inherits BaseLocalizedComponent - - - + + + Upload File - - Analyse data - - - + + + Analyse data + + + + + +
+                TODO: Enter analyzed content here!
+            
+
+
+ @code { //TODO: Localization From 93caa2a3f93e33799c83d9ccce45d790334222bb Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:36:15 +0100 Subject: [PATCH 08/64] Update NewViewModeImport.razor --- .../Shared/ViewModes/NewViewModeImport.razor | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor index 320aea54..d4e4b936 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -17,28 +17,35 @@ along with Foobar. If not, see --> @inherits BaseLocalizedComponent - - - - - - - Upload File - - - - - - Analyse data - - + + + + + + + + Upload File + + + + + + Importprofile 1 + Importprofile 2 + + TODO: All profile related stuff + + + - +
                 TODO: Enter analyzed content here!
             
+ TODO: Here comes the analyzed cuesheet +
From 2791d4282527d9d1cdac31fc0eef3e628b8e5fec Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 14 Jan 2026 14:03:52 +0100 Subject: [PATCH 09/64] add new input TextField --- .../Shared/Inputs/TextField.razor | 41 +++++++++++++++++++ .../Shared/ViewModes/NewViewModeImport.razor | 9 +--- 2 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 AudioCuesheetEditor/Shared/Inputs/TextField.razor diff --git a/AudioCuesheetEditor/Shared/Inputs/TextField.razor b/AudioCuesheetEditor/Shared/Inputs/TextField.razor new file mode 100644 index 00000000..a33f4425 --- /dev/null +++ b/AudioCuesheetEditor/Shared/Inputs/TextField.razor @@ -0,0 +1,41 @@ + +@inherits BaseLocalizedComponent + +@inject IStringLocalizer _localizer + + + + + @_localizer["Upload file"] + + + +@code { + //TODO: Drag n drop files + //TODO: localization + + [Parameter] + public String? Placeholder { get; set; } + + [Parameter] + public String? Text { get; set; } + + [Parameter] + public EventCallback TextChanged { get; set; } +} diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor index d4e4b936..78d68283 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor @@ -20,14 +20,7 @@ along with Foobar. If not, see - - - - - Upload File - - - + Importprofile 1 From da7f1de9ab20fefefe22d8f27c28deaee522e486 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 14 Jan 2026 15:05:17 +0100 Subject: [PATCH 10/64] move new view to existing one --- AudioCuesheetEditor/Pages/Index.razor | 4 +- ...ent.resx => DisplayAnalyzedResult.de.resx} | 6 - ...tent.razor => DisplayAnalyzedResult.razor} | 33 ++--- ...ent.de.resx => DisplayAnalyzedResult.resx} | 6 - .../Shared/Import/SelectImportFiles.de.resx | 126 ---------------- .../Shared/Import/SelectImportFiles.razor | 94 ------------ .../Shared/Import/SelectImportFiles.resx | 126 ---------------- .../Shared/ViewModes/NewViewModeImport.razor | 52 ------- .../Shared/ViewModes/ViewModeImport.razor | 138 +++--------------- 9 files changed, 35 insertions(+), 550 deletions(-) rename AudioCuesheetEditor/Shared/Import/{ImportFileContent.resx => DisplayAnalyzedResult.de.resx} (96%) rename AudioCuesheetEditor/Shared/Import/{ImportFileContent.razor => DisplayAnalyzedResult.razor} (57%) rename AudioCuesheetEditor/Shared/Import/{ImportFileContent.de.resx => DisplayAnalyzedResult.resx} (96%) delete mode 100644 AudioCuesheetEditor/Shared/Import/SelectImportFiles.de.resx delete mode 100644 AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor delete mode 100644 AudioCuesheetEditor/Shared/Import/SelectImportFiles.resx delete mode 100644 AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor diff --git a/AudioCuesheetEditor/Pages/Index.razor b/AudioCuesheetEditor/Pages/Index.razor index c0d510b7..64a3150d 100644 --- a/AudioCuesheetEditor/Pages/Index.razor +++ b/AudioCuesheetEditor/Pages/Index.razor @@ -31,14 +31,12 @@ along with Foobar. If not, see - @* *@ - + @code{ - //TODO: Move back to ViewModeImport ViewOptions? options; ViewMode currentViewmode = ViewMode.DetailView; diff --git a/AudioCuesheetEditor/Shared/Import/ImportFileContent.resx b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.de.resx similarity index 96% rename from AudioCuesheetEditor/Shared/Import/ImportFileContent.resx rename to AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.de.resx index f861a443..1af7de15 100644 --- a/AudioCuesheetEditor/Shared/Import/ImportFileContent.resx +++ b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.de.resx @@ -117,10 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Analyzed file content - - - Edit - \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Import/ImportFileContent.razor b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor similarity index 57% rename from AudioCuesheetEditor/Shared/Import/ImportFileContent.razor rename to AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor index 894b9e15..21e1a464 100644 --- a/AudioCuesheetEditor/Shared/Import/ImportFileContent.razor +++ b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor @@ -17,35 +17,22 @@ along with Foobar. If not, see --> @inherits BaseLocalizedComponent -@inject IStringLocalizer _localizer +@inject IStringLocalizer _localizer @inject ISessionStateContainer _sessionStateContainer - - - -
-                @if (FileContentRecognized != null)
-                {
-                    @((MarkupString)SanitizeHTML(FileContentRecognized))
-                }
-            
-
-
- - - -
+ +
+        @if (FileContentRecognized != null)
+        {
+            @((MarkupString)SanitizeHTML(FileContentRecognized))
+        }
+    
+
@code { - [Parameter] - public EventCallback FileContentChanged { get; set; } + //TODO: Display analyze errors public String? FileContentRecognized => _sessionStateContainer.Importfile?.FileContentRecognized; - async Task FileContent_TextChangedAsync(string newFileContent) - { - await FileContentChanged.InvokeAsync(newFileContent); - } - string SanitizeHTML(string input) { var sanitizer = new HtmlSanitizer(); diff --git a/AudioCuesheetEditor/Shared/Import/ImportFileContent.de.resx b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.resx similarity index 96% rename from AudioCuesheetEditor/Shared/Import/ImportFileContent.de.resx rename to AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.resx index cb591bb2..1af7de15 100644 --- a/AudioCuesheetEditor/Shared/Import/ImportFileContent.de.resx +++ b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.resx @@ -117,10 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Analysierter Dateiinhalt - - - Bearbeiten - \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.de.resx b/AudioCuesheetEditor/Shared/Import/SelectImportFiles.de.resx deleted file mode 100644 index 4fbd4abb..00000000 --- a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.de.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Datei für Import auswählen - - - Sie haben eine ungültige Datei ({0}) hinzugefügt die nicht verarbeitet werden kann. - - \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor b/AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor deleted file mode 100644 index 4c1f617e..00000000 --- a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.razor +++ /dev/null @@ -1,94 +0,0 @@ - -@inherits BaseLocalizedComponent - -@inject IStringLocalizer _localizer -@inject ISessionStateContainer _sessionStateContainer -@inject ImportManager _importManager -@inject IFileInputManager _fileInputManager - - - - - @_localizer["Select files for import"] - - - - - @foreach (var invalidFileName in invalidDropFileNames) - { - - @String.Format(_localizer["You dropped an invalid file ({0}) that can not be processed."], invalidFileName) - - } - - - -@code { - string dropFileInputId = "dropFileInputId"; - List invalidDropFileNames = new(); - - [Parameter] - public EventCallback FilesImported { get; set; } - - [Parameter] - public EventCallback> InvalidFilesChanged { get; set; } - - async Task InputFilesChanged(IReadOnlyCollection files) - { - invalidDropFileNames.Clear(); - foreach (var file in files) - { - if ((_fileInputManager.IsValidForImportView(file) == false) - && (_fileInputManager.IsValidAudiofile(file) == false)) - { - invalidDropFileNames.Add(file.Name); - } - } - if (invalidDropFileNames.Count == 0) - { - await ImportFiles(files); - } - else - { - await InvalidFilesChanged.InvokeAsync(invalidDropFileNames); - } - } - - async Task ImportFiles(IReadOnlyCollection files) - { - _sessionStateContainer.ResetImport(); - await _importManager.ImportFilesAsync(files); - // Audio file is handled seperatly - foreach (var file in files) - { - if (_fileInputManager.IsValidAudiofile(file)) - { - var audiofile = await _fileInputManager.CreateAudiofileAsync(dropFileInputId, file); - _sessionStateContainer.ImportAudiofile = audiofile; - } - } - await FilesImported.InvokeAsync(); - } - - async Task CloseInvalidFileClicked(string invalidFile) - { - invalidDropFileNames.Remove(invalidFile); - await InvalidFilesChanged.InvokeAsync(invalidDropFileNames); - } -} diff --git a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.resx b/AudioCuesheetEditor/Shared/Import/SelectImportFiles.resx deleted file mode 100644 index 062757f8..00000000 --- a/AudioCuesheetEditor/Shared/Import/SelectImportFiles.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Select files for import - - - You dropped an invalid file ({0}) that can not be processed. - - \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor deleted file mode 100644 index 78d68283..00000000 --- a/AudioCuesheetEditor/Shared/ViewModes/NewViewModeImport.razor +++ /dev/null @@ -1,52 +0,0 @@ - -@inherits BaseLocalizedComponent - - - - - - - - Importprofile 1 - Importprofile 2 - - TODO: All profile related stuff - - - - - - -
-                TODO: Enter analyzed content here!
-            
-
- TODO: Here comes the analyzed cuesheet - -
-
- -@code { - //TODO: Localization - //TODO: Drag n Drop files - //TODO: Add selection of import profile - //TODO: Add a preview of parsed data - - private string? importText; -} \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index 96aba8df..c6ce78e0 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -17,33 +17,25 @@ along with Foobar. If not, see --> @inherits BaseLocalizedComponent -@inject ILogger _logger @inject IStringLocalizer _localizer -@inject ISessionStateContainer _sessionStateContainer -@inject ImportManager _importManager -@inject DialogManager _dialogManager - - - - - + + + + + + + Importprofile 1 + Importprofile 2 + + TODO: All profile related stuff + + + + + + - - - @_localizer["Filecontent"] - - - - - @if (_sessionStateContainer.Importfile?.AnalyseException != null) - { - - @_localizer["Error during textimport"] : @_sessionStateContainer.Importfile.AnalyseException.Message - - } - - @_localizer["Common data"] @@ -61,97 +53,15 @@ along with Foobar. If not, see - - + +
+
@code { - MudStepper? mudStepper; - int activeStepIndex; - Boolean fileContentExpanded = false, cuesheetDataExpanded = false, cuesheetTracksExpanded = false; - Boolean selectFilesStepCompleted = false, selectFilesStepError = false; - long? renderBegin; - - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - if (_sessionStateContainer.Importfile?.FileType == ImportFileType.Textfile) - { - await FilesImported(); - } - } - - protected override void OnAfterRender(bool firstRender) - { - if (renderBegin.HasValue) - { - var renderDuration = System.Diagnostics.Stopwatch.GetElapsedTime(renderBegin.Value); - _logger.LogDebug("ViewModeImport render duration: {renderDuration}", renderDuration); - } - base.OnAfterRender(firstRender); - } - - async Task ImportFileContent_FileContentChanged(string newFileContent) - { - _sessionStateContainer.Importfile!.FileContent = newFileContent; - await AnalyseImportfile(); - } - - async Task AnalyseImportfile() - { - await _importManager.AnalyseImportfile(); - renderBegin = System.Diagnostics.Stopwatch.GetTimestamp(); - } - - async Task FilesImported() - { - await _dialogManager.ShowLoadingDialogAsync(); - try - { - await AnalyseImportfile(); - } - finally - { - _dialogManager.HideLoadingDialog(); - } - fileContentExpanded = true; - cuesheetDataExpanded = true; - cuesheetTracksExpanded = true; - activeStepIndex = 1; - selectFilesStepCompleted = true; - selectFilesStepError = false; - renderBegin = System.Diagnostics.Stopwatch.GetTimestamp(); - } - - async Task CompleteImportAsync() - { - _importManager.ImportCuesheet(); - await ResetAsync(); - // Don't await since otherwise the rendering will stop and this view will not be reset - _ = LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ActiveTab, ViewMode.DetailView); - } - - Task PreviewInteraction(StepperInteractionEventArgs arg) - { - if (arg.StepIndex == 0) - { - arg.Cancel = (selectFilesStepCompleted == false) || (selectFilesStepError == true); - } - return Task.CompletedTask; - } - - void InvalidFilesDropped(List files) - { - selectFilesStepError = files.Any(); - } + //TODO: Localization + //TODO: Logic for import + //TODO: Preview of analyzed data - async Task ResetAsync() - { - activeStepIndex = 0; - selectFilesStepCompleted = false; - selectFilesStepError = false; - if (mudStepper != null) - { - await mudStepper.ResetAsync(true); - } - } + private string? importText; + Boolean cuesheetDataExpanded = true, cuesheetTracksExpanded = true; } From 7c497ab75c950007c6ba60d38d126caec5f34568 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 14 Jan 2026 15:26:52 +0100 Subject: [PATCH 11/64] add import profiles to import --- .../Shared/Import/Importprofiles.de.resx | 17 +++- .../Shared/Import/Importprofiles.razor | 95 +++++++++---------- .../Shared/Import/Importprofiles.resx | 15 ++- .../Shared/ViewModes/ViewModeImport.razor | 8 +- 4 files changed, 70 insertions(+), 65 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.de.resx b/AudioCuesheetEditor/Shared/Import/Importprofiles.de.resx index a7736980..56ba6509 100644 --- a/AudioCuesheetEditor/Shared/Import/Importprofiles.de.resx +++ b/AudioCuesheetEditor/Shared/Import/Importprofiles.de.resx @@ -141,6 +141,9 @@ Tage + + Ausgewähltes Profil löschen + Ende @@ -162,9 +165,6 @@ Stunden - - Import Profil - Länge @@ -189,8 +189,14 @@ Vorlücke + + Profildetails + - Profil Name + Profilname + + + Importprofile zurücksetzen Schema Allgemeine Informationen @@ -204,6 +210,9 @@ Sekunden + + Ausgewähltes Profil + Startzeitpunkt diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor index 57e6a842..742dc52a 100644 --- a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor +++ b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor @@ -24,7 +24,7 @@ along with Foobar. If not, see @if (importOptions != null) { - + @foreach (var profile in importOptions.ImportProfiles) { @profile.Name @@ -39,55 +39,55 @@ along with Foobar. If not, see - @_localizer["Reset import schemes"] + @_localizer["Reset import profiles"] - + - - - - - @foreach (var scheme in Importprofile.AvailableSchemeCuesheet) - { - @_localizer[scheme] - } - - - - @foreach (var scheme in Importprofile.AvailableSchemesTrack) - { - @_localizer[scheme] - } - - - - @foreach (var scheme in TimeSpanFormat.AvailableTimespanScheme) - { - @_localizer[scheme] - } - + + + + + + @foreach (var scheme in Importprofile.AvailableSchemeCuesheet) + { + @_localizer[scheme] + } + + + + @foreach (var scheme in Importprofile.AvailableSchemesTrack) + { + @_localizer[scheme] + } + + + + @foreach (var scheme in TimeSpanFormat.AvailableTimespanScheme) + { + @_localizer[scheme] + } + + + } @code { - [Parameter] - public EventCallback ImportprofileChanged { get; set; } - ImportOptions? importOptions; MudMenu? schemeCuesheetMenu, schemeTracksMenu, timeSpanFormatMenu; MudTextField? schemeCuesheetTextField, schemeTracksTextField, timeSpanFormatTextField; @@ -113,25 +113,21 @@ along with Foobar. If not, see async Task SelectedImportProfileChangedAsync(Importprofile? newSelectedProfile) { await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.SelectedImportProfile, newSelectedProfile); - await ImportprofileChanged.InvokeAsync(); } async Task UseRegularExpressionChangedAsync(Boolean? newValue) { await LocalStorageOptionsProvider.SaveNestedOptionValueAsync(x => x.SelectedImportProfile, x => x!.UseRegularExpression, newValue!.Value); - await ImportprofileChanged.InvokeAsync(); } async Task SchemeCuesheetChangedAsync(string newScheme) { await LocalStorageOptionsProvider.SaveNestedOptionValueAsync(x => x.SelectedImportProfile, x => x!.SchemeCuesheet, newScheme); - await ImportprofileChanged.InvokeAsync(); } async Task SchemeTracksChangedAsync(string newScheme) { await LocalStorageOptionsProvider.SaveNestedOptionValueAsync(x => x.SelectedImportProfile, x => x!.SchemeTracks, newScheme); - await ImportprofileChanged.InvokeAsync(); } async Task ImportTimeInputFormatChangedAsync(string newScheme) @@ -149,7 +145,6 @@ along with Foobar. If not, see format = new() { Scheme = newScheme }; } await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.SelectedImportProfile!.TimeSpanFormat, format); - await ImportprofileChanged.InvokeAsync(); } } @@ -167,7 +162,7 @@ along with Foobar. If not, see return validationErrorMessage; } - async Task ResetSchemes() + async Task ResetProfiles() { var parameters = new DialogParameters { @@ -180,7 +175,6 @@ along with Foobar. If not, see importOptions!.ImportProfiles = ImportOptions.DefaultImportprofiles; importOptions!.SelectedImportProfile = ImportOptions.DefaultSelectedImportprofile; await LocalStorageOptionsProvider.SaveOptionsAsync(importOptions); - await ImportprofileChanged.InvokeAsync(); } } @@ -202,7 +196,6 @@ along with Foobar. If not, see }; importOptions!.SelectedImportProfile = profile; await LocalStorageOptionsProvider.SaveOptionsAsync(importOptions); - await ImportprofileChanged.InvokeAsync(); } async Task DeleteImportprofileClick() diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.resx b/AudioCuesheetEditor/Shared/Import/Importprofiles.resx index 5bd62cc2..75f0fce7 100644 --- a/AudioCuesheetEditor/Shared/Import/Importprofiles.resx +++ b/AudioCuesheetEditor/Shared/Import/Importprofiles.resx @@ -141,6 +141,9 @@ Days + + Delete selected profile + End @@ -162,9 +165,6 @@ Hours - - Import profile - Length @@ -189,9 +189,15 @@ PreGap + + Profile details + Profile name + + Reset import profiles + Scheme common data @@ -204,6 +210,9 @@ Seconds + + Selected profile + StartDateTime diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index c6ce78e0..b45093e6 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -23,13 +23,7 @@ along with Foobar. If not, see - - - Importprofile 1 - Importprofile 2 - - TODO: All profile related stuff - + From 2ca9850258c416dde513cd87ccb8157226d21b64 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:26:08 +0100 Subject: [PATCH 12/64] implement import logic --- .../Services/IO/ImportManager.cs | 15 ++++++ .../Shared/ViewModes/ViewModeImport.razor | 47 +++++++++++++++++-- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs index d4796079..331caf9d 100644 --- a/AudioCuesheetEditor/Services/IO/ImportManager.cs +++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs @@ -71,6 +71,7 @@ public async Task ImportFilesAsync(IEnumerable files) FileType = ImportFileType.Cuesheet }; } + //TODO: Check if this is still needed, maybe we can use import for all kinds of data if (_fileInputManager.IsValidForImportView(file)) { var fileContent = await ReadFileContentAsync(file); @@ -88,6 +89,20 @@ public async Task ImportFilesAsync(IEnumerable files) stopwatch.Stop(); _logger.LogDebug("ImportFilesAsync duration: {stopwatch.Elapsed}", stopwatch.Elapsed); } + + public void ImportData(String? data) + { + //TODO: Test + var stopwatch = Stopwatch.StartNew(); + _sessionStateContainer.Importfile = new Importfile() + { + FileContent = data, + FileContentRecognized = data, + FileType = ImportFileType.Textfile + }; + stopwatch.Stop(); + _logger.LogDebug("ImportData duration: {stopwatch.Elapsed}", stopwatch.Elapsed); + } public async Task AnalyseImportfile() { diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index b45093e6..b0d6d3c2 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -18,14 +18,17 @@ along with Foobar. If not, see @inherits BaseLocalizedComponent @inject IStringLocalizer _localizer +@inject ImportManager _importManager +@inject DialogManager _dialogManager - + - + @@ -47,15 +50,49 @@ along with Foobar. If not, see - + @code { //TODO: Localization - //TODO: Logic for import - //TODO: Preview of analyzed data private string? importText; Boolean cuesheetDataExpanded = true, cuesheetTracksExpanded = true; + int activePanelIndex = 0; + + async Task Analyze() + { + await _dialogManager.ShowLoadingDialogAsync(); + try + { + await AnalyseImportfile(); + } + finally + { + _dialogManager.HideLoadingDialog(); + } + // Switch to analyzed data + activePanelIndex = 1; + } + + async Task AnalyseImportfile() + { + _importManager.ImportData(importText); + await _importManager.AnalyseImportfile(); + } + + void ImportData() + { + _importManager.ImportCuesheet(); + ResetAsync(); + // Don't await since otherwise the rendering will stop and this view will not be reset + _ = LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ActiveTab, ViewMode.DetailView); + } + + void ResetAsync() + { + activePanelIndex = 0; + } } From 86ebc36f7e24a64e30b5c9681aad66a6683852b7 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:49:25 +0100 Subject: [PATCH 13/64] Update ViewModeImport.razor --- AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index b0d6d3c2..90175550 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -57,6 +57,7 @@ along with Foobar. If not, see @code { //TODO: Localization + //TODO: Save state when switching to details or record view private string? importText; Boolean cuesheetDataExpanded = true, cuesheetTracksExpanded = true; From dfbe3d9e3ecaa6e31454644e615890a1d44c4baa Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:49:56 +0100 Subject: [PATCH 14/64] Update TextField.razor --- AudioCuesheetEditor/Shared/Inputs/TextField.razor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/Shared/Inputs/TextField.razor b/AudioCuesheetEditor/Shared/Inputs/TextField.razor index a33f4425..6cfa2c63 100644 --- a/AudioCuesheetEditor/Shared/Inputs/TextField.razor +++ b/AudioCuesheetEditor/Shared/Inputs/TextField.razor @@ -27,7 +27,8 @@ along with Foobar. If not, see @code { - //TODO: Drag n drop files + //TODO: Drag n drop file + //TODO: Upload file //TODO: localization [Parameter] From 579bc6b5b1e2237b1cf81eef050c6b2b62e733d6 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 15 Jan 2026 09:39:36 +0100 Subject: [PATCH 15/64] save import view state --- .../Model/Options/ViewOptions.cs | 24 ++++++++ .../Shared/ViewModes/ViewModeImport.razor | 60 +++++++++++++++---- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/AudioCuesheetEditor/Model/Options/ViewOptions.cs b/AudioCuesheetEditor/Model/Options/ViewOptions.cs index 3c1389e4..8b02c4dc 100644 --- a/AudioCuesheetEditor/Model/Options/ViewOptions.cs +++ b/AudioCuesheetEditor/Model/Options/ViewOptions.cs @@ -23,6 +23,11 @@ public enum ViewMode RecordView = 1, ImportView = 2 } + public enum ImportTab + { + Edit = 0, + Analyze = 1 + } public class ViewOptions : IOptions { [JsonIgnore] @@ -42,5 +47,24 @@ public String? ActiveTabName } } } + + [JsonIgnore] + public ImportTab ActiveImportTab { get; set; } + + public String? ActiveImportTabName + { + get => Enum.GetName(ActiveImportTab); + set + { + if (value != null) + { + ActiveImportTab = Enum.Parse(value); + } + else + { + throw new ArgumentNullException(nameof(value)); + } + } + } } } diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index 90175550..d6b7349f 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -20,11 +20,12 @@ along with Foobar. If not, see @inject IStringLocalizer _localizer @inject ImportManager _importManager @inject DialogManager _dialogManager +@inject ISessionStateContainer _sessionStateContainer - + - + (); + base.LocalStorageOptionsProvider.OptionSaved += LocalStorageOptionsProvider_OptionSaved; + activePanelIndex = (int)viewOptions.ActiveImportTab; + if (_sessionStateContainer.Importfile?.FileType == ImportFileType.Textfile) + { + importText = _sessionStateContainer.Importfile.FileContent; + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + base.LocalStorageOptionsProvider.OptionSaved -= LocalStorageOptionsProvider_OptionSaved; + } + + void ImportTextChanged(string? newImportText) + { + importText = newImportText; + _importManager.ImportData(importText); + } + + async Task ActiveTabIndexChanged(int tabIndex) + { + await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ActiveImportTab, (ImportTab)tabIndex); + } async Task Analyze() { @@ -75,25 +106,34 @@ along with Foobar. If not, see _dialogManager.HideLoadingDialog(); } // Switch to analyzed data - activePanelIndex = 1; + await ActiveTabIndexChanged(1); } async Task AnalyseImportfile() { - _importManager.ImportData(importText); await _importManager.AnalyseImportfile(); } - void ImportData() + async Task ImportData() { _importManager.ImportCuesheet(); - ResetAsync(); + await ResetAsync(); // Don't await since otherwise the rendering will stop and this view will not be reset _ = LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ActiveTab, ViewMode.DetailView); } - void ResetAsync() + async Task ResetAsync() { - activePanelIndex = 0; + await ActiveTabIndexChanged(0); + } + + void LocalStorageOptionsProvider_OptionSaved(object? sender, IOptions option) + { + if (option is ViewOptions newViewOptions) + { + viewOptions = newViewOptions; + activePanelIndex = (int)viewOptions.ActiveImportTab; + StateHasChanged(); + } } } From f1c93c9384177dc6da3d6a0535fba5fb0c8fde2a Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 15 Jan 2026 13:30:44 +0100 Subject: [PATCH 16/64] added file upload --- .../Services/IO/FileInputManager.cs | 8 ++++++++ .../Services/IO/IFileInputManager.cs | 6 ++++++ .../Shared/Inputs/TextField.razor | 17 +++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor/Services/IO/FileInputManager.cs b/AudioCuesheetEditor/Services/IO/FileInputManager.cs index 96129e13..918a990e 100644 --- a/AudioCuesheetEditor/Services/IO/FileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/FileInputManager.cs @@ -132,5 +132,13 @@ public bool IsValidForImportView(IBrowserFile browserFile) { return CheckFileMimeType(browserFile, FileMimeTypes.Text, [FileExtensions.Text, FileExtensions.HTML]); } + + /// + public async Task ReadFileContentAsync(IBrowserFile browserFile) + { + //TODO: Tests? + var fileContent = new StreamContent(browserFile.OpenReadStream()); + return await fileContent.ReadAsStringAsync(); + } } } diff --git a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs index 6bf15fef..e5d00d13 100644 --- a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs @@ -33,5 +33,11 @@ public interface IFileInputManager /// /// bool IsValidForImportView(IBrowserFile browserFile); + /// + /// Reads the browser file and gets the file content as string + /// + /// + /// + Task ReadFileContentAsync(IBrowserFile browserFile); } } \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Inputs/TextField.razor b/AudioCuesheetEditor/Shared/Inputs/TextField.razor index 6cfa2c63..7e4f1534 100644 --- a/AudioCuesheetEditor/Shared/Inputs/TextField.razor +++ b/AudioCuesheetEditor/Shared/Inputs/TextField.razor @@ -18,17 +18,21 @@ along with Foobar. If not, see @inherits BaseLocalizedComponent @inject IStringLocalizer _localizer +@inject IFileInputManager _fileInputManager - @_localizer["Upload file"] + + + @_localizer["Upload file"] + + @code { //TODO: Drag n drop file - //TODO: Upload file //TODO: localization [Parameter] @@ -39,4 +43,13 @@ along with Foobar. If not, see [Parameter] public EventCallback TextChanged { get; set; } + + async Task FileUploaded(InputFileChangeEventArgs e) + { + if (_fileInputManager.IsValidForImportView(e.File)) + { + var fileContent = await _fileInputManager.ReadFileContentAsync(e.File); + await TextChanged.InvokeAsync(fileContent); + } + } } From ca8782653893677262b6ad59b57bda5c6fb4fa20 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 15 Jan 2026 13:52:49 +0100 Subject: [PATCH 17/64] added display of import errors --- .../Shared/Import/DisplayAnalyzedResult.razor | 30 ++++++++++++++++++- .../Shared/ViewModes/ViewModeImport.razor | 27 +++-------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor index 21e1a464..02b2bc69 100644 --- a/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor +++ b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor @@ -28,9 +28,37 @@ along with Foobar. If not, see } +@if (_sessionStateContainer.Importfile?.AnalyseException != null) +{ + + @_localizer["Error during textimport"] : @_sessionStateContainer.Importfile.AnalyseException.Message + +} +else +{ + + + + @_localizer["Common data"] + + + + + + + + @_localizer["Tracks"] + + + + + + +} @code { - //TODO: Display analyze errors + Boolean cuesheetDataExpanded = true, cuesheetTracksExpanded = true; + public String? FileContentRecognized => _sessionStateContainer.Importfile?.FileContentRecognized; string SanitizeHTML(string input) diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index d6b7349f..c148c664 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -24,33 +24,14 @@ along with Foobar. If not, see - - - - + + - - - - @_localizer["Common data"] - - - - - - - - @_localizer["Tracks"] - - - - - - + @@ -59,9 +40,9 @@ along with Foobar. If not, see @code { //TODO: Localization //TODO: Maybe disable analyzed data tab when no analyze has been done? + //TODO: Reset tab when loading initially private string? importText; - Boolean cuesheetDataExpanded = true, cuesheetTracksExpanded = true; ViewOptions? viewOptions; int activePanelIndex; From f971c67c356689109f0ef049f35768d78fab6377 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 15 Jan 2026 14:01:54 +0100 Subject: [PATCH 18/64] moved saving of import tab to sessionstatecontainer --- .../Model/Options/ViewOptions.cs | 24 ----------- .../Services/UI/ISessionStateContainer.cs | 1 + .../Services/UI/SessionStateContainer.cs | 1 + .../Shared/ViewModes/ViewModeImport.razor | 41 +++++-------------- 4 files changed, 13 insertions(+), 54 deletions(-) diff --git a/AudioCuesheetEditor/Model/Options/ViewOptions.cs b/AudioCuesheetEditor/Model/Options/ViewOptions.cs index 8b02c4dc..3c1389e4 100644 --- a/AudioCuesheetEditor/Model/Options/ViewOptions.cs +++ b/AudioCuesheetEditor/Model/Options/ViewOptions.cs @@ -23,11 +23,6 @@ public enum ViewMode RecordView = 1, ImportView = 2 } - public enum ImportTab - { - Edit = 0, - Analyze = 1 - } public class ViewOptions : IOptions { [JsonIgnore] @@ -47,24 +42,5 @@ public String? ActiveTabName } } } - - [JsonIgnore] - public ImportTab ActiveImportTab { get; set; } - - public String? ActiveImportTabName - { - get => Enum.GetName(ActiveImportTab); - set - { - if (value != null) - { - ActiveImportTab = Enum.Parse(value); - } - else - { - throw new ArgumentNullException(nameof(value)); - } - } - } } } diff --git a/AudioCuesheetEditor/Services/UI/ISessionStateContainer.cs b/AudioCuesheetEditor/Services/UI/ISessionStateContainer.cs index 10796b37..4c469abf 100644 --- a/AudioCuesheetEditor/Services/UI/ISessionStateContainer.cs +++ b/AudioCuesheetEditor/Services/UI/ISessionStateContainer.cs @@ -28,5 +28,6 @@ public interface ISessionStateContainer public Audiofile? ImportAudiofile { get; set; } public IImportfile? Importfile { get; set; } public void ResetImport(); + public int ImportTabActiveTab { get; set; } } } diff --git a/AudioCuesheetEditor/Services/UI/SessionStateContainer.cs b/AudioCuesheetEditor/Services/UI/SessionStateContainer.cs index 494b234e..9f7c61db 100644 --- a/AudioCuesheetEditor/Services/UI/SessionStateContainer.cs +++ b/AudioCuesheetEditor/Services/UI/SessionStateContainer.cs @@ -77,6 +77,7 @@ public Audiofile? ImportAudiofile } public IImportfile? Importfile{ get; set; } + public int ImportTabActiveTab { get; set; } = 0; public void ResetImport() { diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index c148c664..284cd071 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -40,39 +40,30 @@ along with Foobar. If not, see @code { //TODO: Localization //TODO: Maybe disable analyzed data tab when no analyze has been done? - //TODO: Reset tab when loading initially private string? importText; - ViewOptions? viewOptions; int activePanelIndex; - protected override async Task OnInitializedAsync() + protected override void OnInitialized() { - await base.OnInitializedAsync(); - viewOptions = await base.LocalStorageOptionsProvider.GetOptionsAsync(); - base.LocalStorageOptionsProvider.OptionSaved += LocalStorageOptionsProvider_OptionSaved; - activePanelIndex = (int)viewOptions.ActiveImportTab; + base.OnInitialized(); + activePanelIndex = _sessionStateContainer.ImportTabActiveTab; if (_sessionStateContainer.Importfile?.FileType == ImportFileType.Textfile) { importText = _sessionStateContainer.Importfile.FileContent; } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - base.LocalStorageOptionsProvider.OptionSaved -= LocalStorageOptionsProvider_OptionSaved; - } - void ImportTextChanged(string? newImportText) { importText = newImportText; _importManager.ImportData(importText); } - async Task ActiveTabIndexChanged(int tabIndex) + void ActiveTabIndexChanged(int tabIndex) { - await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ActiveImportTab, (ImportTab)tabIndex); + _sessionStateContainer.ImportTabActiveTab = tabIndex; + activePanelIndex = tabIndex; } async Task Analyze() @@ -87,7 +78,7 @@ along with Foobar. If not, see _dialogManager.HideLoadingDialog(); } // Switch to analyzed data - await ActiveTabIndexChanged(1); + ActiveTabIndexChanged(1); } async Task AnalyseImportfile() @@ -95,26 +86,16 @@ along with Foobar. If not, see await _importManager.AnalyseImportfile(); } - async Task ImportData() + void ImportData() { _importManager.ImportCuesheet(); - await ResetAsync(); + ResetAsync(); // Don't await since otherwise the rendering will stop and this view will not be reset _ = LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ActiveTab, ViewMode.DetailView); } - async Task ResetAsync() - { - await ActiveTabIndexChanged(0); - } - - void LocalStorageOptionsProvider_OptionSaved(object? sender, IOptions option) + void ResetAsync() { - if (option is ViewOptions newViewOptions) - { - viewOptions = newViewOptions; - activePanelIndex = (int)viewOptions.ActiveImportTab; - StateHasChanged(); - } + ActiveTabIndexChanged(0); } } From d8ff8e24a6ee0964579ae42322d0d075a3f56fce Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 15 Jan 2026 14:03:53 +0100 Subject: [PATCH 19/64] Update DisplayAnalyzedResult.razor --- AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor index 02b2bc69..81de2de1 100644 --- a/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor +++ b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor @@ -57,6 +57,7 @@ else } @code { + //TODO: Localization Boolean cuesheetDataExpanded = true, cuesheetTracksExpanded = true; public String? FileContentRecognized => _sessionStateContainer.Importfile?.FileContentRecognized; From 87a099e8cdc92b91bd5ef838bd92e774c778f396 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 15 Jan 2026 16:55:03 +0100 Subject: [PATCH 20/64] fix styling --- .../Shared/Import/DisplayAnalyzedResult.razor | 2 +- AudioCuesheetEditor/Shared/Import/Importprofiles.razor | 7 ++++--- AudioCuesheetEditor/Shared/Inputs/TextField.razor | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor index 81de2de1..cd29776a 100644 --- a/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor +++ b/AudioCuesheetEditor/Shared/Import/DisplayAnalyzedResult.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject IStringLocalizer _localizer @inject ISessionStateContainer _sessionStateContainer - +
         @if (FileContentRecognized != null)
         {
diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor
index 742dc52a..5933864f 100644
--- a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor
+++ b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor
@@ -24,13 +24,14 @@ along with Foobar.  If not, see
 
 @if (importOptions != null)
 {
-    
+    
         @foreach (var profile in importOptions.ImportProfiles)
         {
             @profile.Name
         }
     
-    
+    
         
         
             @_localizer["Delete selected profile"]
@@ -45,7 +46,7 @@ along with Foobar.  If not, see
             
         
     
-    
+    
         
diff --git a/AudioCuesheetEditor/Shared/Inputs/TextField.razor b/AudioCuesheetEditor/Shared/Inputs/TextField.razor
index 7e4f1534..ee96b6f4 100644
--- a/AudioCuesheetEditor/Shared/Inputs/TextField.razor
+++ b/AudioCuesheetEditor/Shared/Inputs/TextField.razor
@@ -20,7 +20,7 @@ along with Foobar.  If not, see
 @inject IStringLocalizer _localizer
 @inject IFileInputManager _fileInputManager
 
-
+
     
     
         

From f6c1359b9a8f5717b945f98c9d13825973c8d0eb Mon Sep 17 00:00:00 2001
From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com>
Date: Mon, 19 Jan 2026 15:47:22 +0100
Subject: [PATCH 21/64] move basics to top razor

---
 AudioCuesheetEditor/App.razor                        | 12 +++++++++++-
 AudioCuesheetEditor/Shared/Layouts/MainLayout.razor  | 10 ----------
 .../Shared/Layouts/MainLayoutWithoutMenu.razor       | 10 ----------
 3 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/AudioCuesheetEditor/App.razor b/AudioCuesheetEditor/App.razor
index 6fd3ed1b..cc065a26 100644
--- a/AudioCuesheetEditor/App.razor
+++ b/AudioCuesheetEditor/App.razor
@@ -1,4 +1,14 @@
-
+@* Required *@
+
+
+
+@* Needed for dialogs *@
+
+
+@* Needed for snackbars *@
+
+
+
     
         
         
diff --git a/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor b/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor
index 41971df2..ba89985e 100644
--- a/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor
+++ b/AudioCuesheetEditor/Shared/Layouts/MainLayout.razor
@@ -22,16 +22,6 @@ along with Foobar.  If not, see
 @inject IStringLocalizer _localizer
 @inject IJSRuntime _jsRuntime
 
-@* Required *@
-
-
-
-@* Needed for dialogs *@
-
-
-@* Needed for snackbars *@
-
-
 
     
         
diff --git a/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor b/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor
index c3af3813..8791ef1c 100644
--- a/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor
+++ b/AudioCuesheetEditor/Shared/Layouts/MainLayoutWithoutMenu.razor
@@ -22,16 +22,6 @@ along with Foobar.  If not, see
 @inject IStringLocalizer _localizer
 @inject IJSRuntime _jsRuntime
 
-@* Required *@
-
-
-
-@* Needed for dialogs *@
-
-
-@* Needed for snackbars *@
-
-
 
     
         

From 2d68e7f1280c4a6ef929f0f1d77d7383bce727d2 Mon Sep 17 00:00:00 2001
From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com>
Date: Wed, 21 Jan 2026 10:04:44 +0100
Subject: [PATCH 22/64] add basic dropping of files

---
 AudioCuesheetEditor/App.razor                 |   4 +-
 .../Shared/Inputs/FileDropOverlay.razor       | 101 ++++++++++++++++++
 AudioCuesheetEditor/wwwroot/css/app.css       |  10 ++
 AudioCuesheetEditor/wwwroot/index.html        |   1 +
 .../wwwroot/scripts/globalFileDrag.js         |  70 ++++++++++++
 5 files changed, 185 insertions(+), 1 deletion(-)
 create mode 100644 AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor
 create mode 100644 AudioCuesheetEditor/wwwroot/scripts/globalFileDrag.js

diff --git a/AudioCuesheetEditor/App.razor b/AudioCuesheetEditor/App.razor
index cc065a26..9b89a2a6 100644
--- a/AudioCuesheetEditor/App.razor
+++ b/AudioCuesheetEditor/App.razor
@@ -8,6 +8,8 @@
 @* Needed for snackbars *@
 
 
+
+
 
     
         
@@ -19,4 +21,4 @@
             

Sorry, there's nothing at this address.

-
+
\ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor new file mode 100644 index 00000000..f9b3c432 --- /dev/null +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -0,0 +1,101 @@ + +@inherits BaseLocalizedComponent + +@implements IAsyncDisposable + +@inject IJSRuntime _jsRuntime +@inject IStringLocalizer _localizer + + + + + +@code { + //TODO: localization + + private DotNetObjectReference? _dotNetRef; + private bool _showOverlay; + private bool _disposed; + private const string DefaultDragClass = "d-flex align-center justify-center position-relative"; + private string _dragClass = DefaultDragClass; + + protected override async Task OnInitializedAsync() + { + _dotNetRef = DotNetObjectReference.Create(this); + await _jsRuntime.InvokeVoidAsync("globalFileDrag.register", _dotNetRef); + } + + [JSInvokable("OnGlobalDragEnter")] + public Task OnGlobalDragEnterAsync() + { + if (!_showOverlay) + { + _showOverlay = true; + StateHasChanged(); + } + return Task.CompletedTask; + } + + [JSInvokable("OnGlobalDragLeave")] + public Task OnGlobalDragLeaveAsync() + { + if (_showOverlay) + { + _showOverlay = false; + ClearDragClass(); + StateHasChanged(); + } + return Task.CompletedTask; + } + + async Task OnInputFileChanged(InputFileChangeEventArgs e) + { + //TODO: send files to a service or an event + + ClearDragClass(); + _showOverlay = false; + await _jsRuntime.InvokeVoidAsync("globalFileDrag.reset", _dotNetRef); + StateHasChanged(); + } + + void SetDragClass() => _dragClass = $"{DefaultDragClass} mud-border-primary"; + + void ClearDragClass() => _dragClass = DefaultDragClass; + + public async ValueTask DisposeAsync() + { + if (_disposed) + { + return; + } + + _disposed = true; + await _jsRuntime.InvokeVoidAsync("globalFileDrag.unregister"); + _dotNetRef?.Dispose(); + } +} diff --git a/AudioCuesheetEditor/wwwroot/css/app.css b/AudioCuesheetEditor/wwwroot/css/app.css index 33d6bb99..f72131ce 100644 --- a/AudioCuesheetEditor/wwwroot/css/app.css +++ b/AudioCuesheetEditor/wwwroot/css/app.css @@ -51,4 +51,14 @@ a, .btn-link { .blazor-error-boundary::after { content: "An error has occurred." +} + +.file-upload-input { + position: absolute; + inset: 0; + width: 100vw; + height: 100vh; + opacity: 0; + cursor: pointer; + z-index: 10; } \ No newline at end of file diff --git a/AudioCuesheetEditor/wwwroot/index.html b/AudioCuesheetEditor/wwwroot/index.html index 89c2fd6c..0f4b486f 100644 --- a/AudioCuesheetEditor/wwwroot/index.html +++ b/AudioCuesheetEditor/wwwroot/index.html @@ -57,6 +57,7 @@ + diff --git a/AudioCuesheetEditor/wwwroot/scripts/globalFileDrag.js b/AudioCuesheetEditor/wwwroot/scripts/globalFileDrag.js new file mode 100644 index 00000000..c781f82e --- /dev/null +++ b/AudioCuesheetEditor/wwwroot/scripts/globalFileDrag.js @@ -0,0 +1,70 @@ +window.globalFileDrag = (function () { + let dotnetRef = null; + let counter = 0; + let registered = false; + + function hasFiles(e) { + try { + const dt = e.dataTransfer || e; + if (!dt || !dt.types) return false; + for (let i = 0; i < dt.types.length; i++) { + if (dt.types[i] === "Files") return true; + } + } catch { } + return false; + } + + function safeInvoke(methodName) { + if (!registered || !dotnetRef || typeof dotnetRef.invokeMethodAsync !== "function") return; + + Promise.resolve() + .then(() => dotnetRef.invokeMethodAsync(methodName)) + .catch(function (err) { + console.debug("globalFileDrag: invokeMethodAsync rejected:", err && err.message ? err.message : err); + }); + } + + function onDragEnter(e) { + if (!hasFiles(e)) return; + counter++; + if (counter === 1) { + safeInvoke('OnGlobalDragEnter'); + } + } + + function onDragLeave(e) { + counter--; + if (counter <= 0) { + counter = 0; + safeInvoke('OnGlobalDragLeave'); + } + } + + function register(dotnetObject) { + dotnetRef = dotnetObject; + registered = true; + counter = 0; + + document.addEventListener('dragenter', onDragEnter, false); + document.addEventListener('dragleave', onDragLeave, false); + } + + function unregister() { + document.removeEventListener('dragenter', onDragEnter, false); + document.removeEventListener('dragleave', onDragLeave, false); + + registered = false; + dotnetRef = null; + counter = 0; + } + + function reset() { + counter = 0; + } + + return { + register: register, + unregister: unregister, + reset: reset + }; +})(); \ No newline at end of file From 9141dee54015bcbbd94cb00be5e0a9554bf10d26 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 21 Jan 2026 10:17:18 +0100 Subject: [PATCH 23/64] Update FileDropOverlay.razor --- AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor index f9b3c432..5f7482a2 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @implements IAsyncDisposable @inject IJSRuntime _jsRuntime -@inject IStringLocalizer _localizer +@inject IStringLocalizer _localizer
@code { - //TODO: Drag n drop file //TODO: localization [Parameter] From 35a194ee5f2a478894b52d69f07758457bbc2a32 Mon Sep 17 00:00:00 2001 From: NeoCoderMatrix86 <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:56:20 +0100 Subject: [PATCH 33/64] Update ImportManager.cs --- AudioCuesheetEditor/Services/IO/ImportManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs index 325cfd3f..1320f0e3 100644 --- a/AudioCuesheetEditor/Services/IO/ImportManager.cs +++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs @@ -113,7 +113,6 @@ public void ImportCuesheet() public async Task UploadFilesAsync(IEnumerable files) { - //TODO: Test? var stopwatch = Stopwatch.StartNew(); var invalidFiles = new List(); foreach (var file in files) From c35b3621c019a3280b3a3a1e0cc6e0d51b136f14 Mon Sep 17 00:00:00 2001 From: NeoCoderMatrix86 <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:59:32 +0100 Subject: [PATCH 34/64] Update FileInputManager.cs --- AudioCuesheetEditor/Services/IO/FileInputManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/AudioCuesheetEditor/Services/IO/FileInputManager.cs b/AudioCuesheetEditor/Services/IO/FileInputManager.cs index 918a990e..78154ac4 100644 --- a/AudioCuesheetEditor/Services/IO/FileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/FileInputManager.cs @@ -136,7 +136,6 @@ public bool IsValidForImportView(IBrowserFile browserFile) /// public async Task ReadFileContentAsync(IBrowserFile browserFile) { - //TODO: Tests? var fileContent = new StreamContent(browserFile.OpenReadStream()); return await fileContent.ReadAsStringAsync(); } From 96387c2e13458a2ccbdbcfef6f3d7e398e328b26 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 08:48:20 +0100 Subject: [PATCH 35/64] Update FileInput.razor --- AudioCuesheetEditor/Shared/Inputs/FileInput.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor index 495eda69..c036457a 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor @@ -44,6 +44,7 @@ along with Foobar. If not, see } @code { + //TODO: Remove dropping files [Parameter] [EditorRequired] public String? Label { get; set; } From 9d7392572c0a8e50161d4877f20f9bfccc1d0f4c Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:12:47 +0100 Subject: [PATCH 36/64] Update CuesheetData.razor --- AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor b/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor index 4d44b0a3..cafdf50c 100644 --- a/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor +++ b/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor @@ -104,6 +104,7 @@ along with Foobar. If not, see async Task OnAudiofileSelected(IBrowserFile? browserFile) { + //TODO: Move to importmanager if (Cuesheet == null) { return; From e241bae8ce2e9a5f3e77c0edaabb751967b43a24 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 11:05:14 +0100 Subject: [PATCH 37/64] Allow dropping of audiofiles --- .../Services/IO/ImportManagerTests.cs | 25 +++++++++++++ AudioCuesheetEditor/Pages/Index.razor | 17 +++++++++ .../Services/IO/ImportManager.cs | 11 ++++-- .../Shared/Inputs/FileDropOverlay.razor | 10 +++--- .../wwwroot/scripts/library.js | 36 ++++++++++--------- 5 files changed, 76 insertions(+), 23 deletions(-) diff --git a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs index ace94f8d..f5893914 100644 --- a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs +++ b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs @@ -208,6 +208,31 @@ public async Task UploadFilesAsync_TextFile_ImportsCorrectly() Assert.AreEqual(ImportFileType.Textfile, sessionStateContainer.Importfile.FileType); } + [TestMethod] + public async Task UploadFilesAsync_WithAudiofile_ImportsCorrectly() + { + // Arrange + var file = CreateBrowserFileMock("test.mp3"); + var traceChangeManager = new TraceChangeManager(TestHelper.CreateLogger()); + var sessionStateContainer = new SessionStateContainer(traceChangeManager); + var fileInputManagerMock = new Mock(); + var textImportServiceMock = new Mock(); + fileInputManagerMock.Setup(f => f.CheckFileMimeType(file, FileMimeTypes.Projectfile, It.IsAny>())).Returns(false); + fileInputManagerMock.Setup(f => f.CheckFileMimeType(file, FileMimeTypes.Cuesheet, It.IsAny>())).Returns(false); + fileInputManagerMock.Setup(f => f.IsValidForImportView(file)).Returns(false); + fileInputManagerMock.Setup(f => f.IsValidAudiofile(file)).Returns(true); + fileInputManagerMock.Setup(f => f.CreateAudiofileAsync(It.IsAny(), It.IsAny(), It.IsAny>?>())).ReturnsAsync(new AudioCuesheetEditor.Model.IO.Audio.Audiofile(file.Name)); + + var loggerMock = new Mock>(); + var importManager = new ImportManager(sessionStateContainer, traceChangeManager, fileInputManagerMock.Object, textImportServiceMock.Object, loggerMock.Object); + // Act + await importManager.UploadFilesAsync([file]); + + // Assert + Assert.IsNull(sessionStateContainer.Importfile); + Assert.IsNotNull(sessionStateContainer.ImportAudiofile); + } + [TestMethod] public void ImportCuesheet_WithImportCuesheetAvailable_ImportsCuesheetData() { diff --git a/AudioCuesheetEditor/Pages/Index.razor b/AudioCuesheetEditor/Pages/Index.razor index e392e7b4..86873040 100644 --- a/AudioCuesheetEditor/Pages/Index.razor +++ b/AudioCuesheetEditor/Pages/Index.razor @@ -44,6 +44,18 @@ along with Foobar. If not, see ViewOptions? options; ViewMode currentViewmode = ViewMode.DetailView; + public Cuesheet? Cuesheet + { + get + { + if (currentViewmode == ViewMode.ImportView) + { + return _sessionStateContainer.ImportCuesheet; + } + return _sessionStateContainer.Cuesheet; + } + } + protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); @@ -107,6 +119,11 @@ along with Foobar. If not, see await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.ActiveTab, ViewMode.ImportView); break; } + if ((Cuesheet != null) && (_sessionStateContainer.ImportAudiofile != null)) + { + Cuesheet.Audiofile = _sessionStateContainer.ImportAudiofile; + } + _sessionStateContainer.ResetImport(); } finally { diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs index 1320f0e3..a1323d13 100644 --- a/AudioCuesheetEditor/Services/IO/ImportManager.cs +++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs @@ -111,16 +111,16 @@ public void ImportCuesheet() _logger.LogDebug("ImportCuesheet duration: {stopwatch.Elapsed}", stopwatch.Elapsed); } - public async Task UploadFilesAsync(IEnumerable files) + public async Task UploadFilesAsync(IEnumerable files, String? fileInputId = null) { var stopwatch = Stopwatch.StartNew(); var invalidFiles = new List(); foreach (var file in files) { - //TODO: Add check for audio files if (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Projectfile, [FileExtensions.Projectfile]) || _fileInputManager.CheckFileMimeType(file, FileMimeTypes.Cuesheet, [FileExtensions.Cuesheet]) - || _fileInputManager.IsValidForImportView(file)) + || _fileInputManager.IsValidForImportView(file) + || _fileInputManager.IsValidAudiofile(file)) { if (_fileInputManager.CheckFileMimeType(file, FileMimeTypes.Projectfile, [FileExtensions.Projectfile])) { @@ -161,6 +161,11 @@ public async Task UploadFilesAsync(IEnumerable files) FileType = ImportFileType.Textfile }; } + if (_fileInputManager.IsValidAudiofile(file)) + { + var audioFile = await _fileInputManager.CreateAudiofileAsync(fileInputId, file); + _sessionStateContainer.ImportAudiofile = audioFile; + } } else { diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor index 730fb914..93ecbe4b 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -25,7 +25,7 @@ along with Foobar. If not, see @inject DialogManager _dialogManager -
@code { - //TODO: localization - [Parameter] public String? Placeholder { get; set; } diff --git a/AudioCuesheetEditor/Shared/Inputs/TextField.resx b/AudioCuesheetEditor/Shared/Inputs/TextField.resx new file mode 100644 index 00000000..386bbe36 --- /dev/null +++ b/AudioCuesheetEditor/Shared/Inputs/TextField.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Upload file + + \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.de.resx b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.de.resx index 9b5df825..11980259 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.de.resx +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.de.resx @@ -117,22 +117,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Allgemeine Informationen + + Analysiere - - Fehler während des Textimports + + Zurück - - Dateiinhalt + + Daten importieren - - Eingabedateien auswählen - - - Titel - - - Validieren + + Bitte Text eingeben oder eine Datei hochladen \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor index ad4e6f01..88a59ea3 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.razor @@ -26,7 +26,7 @@ along with Foobar. If not, see { - } else @@ -41,8 +41,6 @@ else } @code { - //TODO: Localization - private string? importText; public Boolean IsAnalyzed diff --git a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.resx b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.resx index 5561d972..dfb9e191 100644 --- a/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.resx +++ b/AudioCuesheetEditor/Shared/ViewModes/ViewModeImport.resx @@ -117,22 +117,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Common data + + Analyze - - Error during textimport + + Back - - Filecontent + + Import data - - Select inputfiles - - - Tracks - - - Validate + + Please enter text or upload a file for import \ No newline at end of file From 5ef244db82c780a0218380b77e5cc615d4bf2b96 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:47:39 +0100 Subject: [PATCH 45/64] Update FileDropOverlay.razor --- AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor | 2 -- 1 file changed, 2 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor index 93ecbe4b..8c2b06dd 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -38,8 +38,6 @@ along with Foobar. If not, see @code { - //TODO: localization - private DotNetObjectReference? _dotNetRef; private bool _showOverlay; private bool _disposed; From 800e584ecadd3fa6a69f255e04803ef5b98daf63 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:48:20 +0100 Subject: [PATCH 46/64] Update FileDropOverlay.razor --- AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor index 8c2b06dd..50a26bb3 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -38,6 +38,8 @@ along with Foobar. If not, see @code { + //TODO: Filedrop is visible if scrolled down (if you have already imported a cuesheet for example) + private DotNetObjectReference? _dotNetRef; private bool _showOverlay; private bool _disposed; From dc338b104538244863fccfe0c794db305443b357 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:50:45 +0100 Subject: [PATCH 47/64] Update Importprofiles.razor --- AudioCuesheetEditor/Shared/Import/Importprofiles.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor index 5933864f..3667803b 100644 --- a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor +++ b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor @@ -89,6 +89,7 @@ along with Foobar. If not, see } @code { + //TODO: Opening the selection of import profiles makes the drowdown wider than the viewport ImportOptions? importOptions; MudMenu? schemeCuesheetMenu, schemeTracksMenu, timeSpanFormatMenu; MudTextField? schemeCuesheetTextField, schemeTracksTextField, timeSpanFormatTextField; From c6ac88dd32070322615863fc5951567373e4a524 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:49:40 +0100 Subject: [PATCH 48/64] bugfix overflow --- AudioCuesheetEditor/Program.cs | 5 ++++- AudioCuesheetEditor/Shared/Import/Importprofiles.razor | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/AudioCuesheetEditor/Program.cs b/AudioCuesheetEditor/Program.cs index 8d470618..dc5ef590 100644 --- a/AudioCuesheetEditor/Program.cs +++ b/AudioCuesheetEditor/Program.cs @@ -37,7 +37,10 @@ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddLocalization(); -builder.Services.AddMudServices(); +builder.Services.AddMudServices(config => +{ + config.PopoverOptions.OverflowPadding = 0; +}); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor index 3667803b..5933864f 100644 --- a/AudioCuesheetEditor/Shared/Import/Importprofiles.razor +++ b/AudioCuesheetEditor/Shared/Import/Importprofiles.razor @@ -89,7 +89,6 @@ along with Foobar. If not, see } @code { - //TODO: Opening the selection of import profiles makes the drowdown wider than the viewport ImportOptions? importOptions; MudMenu? schemeCuesheetMenu, schemeTracksMenu, timeSpanFormatMenu; MudTextField? schemeCuesheetTextField, schemeTracksTextField, timeSpanFormatTextField; From 94839eceb191876bc327fc666d85b288a756d266 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:03:24 +0100 Subject: [PATCH 49/64] Update FileDropOverlay.razor --- AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor index 50a26bb3..90cbaf69 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -24,7 +24,7 @@ along with Foobar. If not, see @inject ImportManager _importManager @inject DialogManager _dialogManager - + @code { - //TODO: Filedrop is visible if scrolled down (if you have already imported a cuesheet for example) - private DotNetObjectReference? _dotNetRef; private bool _showOverlay; private bool _disposed; From 8606fe3e032ec03da1c621df456df5a7907a6229 Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 29 Jan 2026 08:39:16 +0100 Subject: [PATCH 51/64] added TODOs --- AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor | 1 + AudioCuesheetEditor/Shared/Inputs/FileInput.razor | 1 + 2 files changed, 2 insertions(+) diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor index 90a9ac37..45e4a983 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -38,6 +38,7 @@ along with Foobar. If not, see @code { + //TODO: FieldId can not be used, it is readonly private DotNetObjectReference? _dotNetRef; private bool _showOverlay; private bool _disposed; diff --git a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor index 6536de71..59a50a48 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor @@ -43,6 +43,7 @@ along with Foobar. If not, see } @code { + //TODO: FieldId can not be used, it is readonly [Parameter] [EditorRequired] public String? Label { get; set; } From 968b0cde520a6a86ed606fd8491a27f14b52888b Mon Sep 17 00:00:00 2001 From: Sven <40752681+NeoCoderMatrix86@users.noreply.github.com> Date: Thu, 29 Jan 2026 08:57:03 +0100 Subject: [PATCH 52/64] fix identifier --- AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor | 3 +-- AudioCuesheetEditor/Shared/Inputs/FileInput.razor | 3 +-- AudioCuesheetEditor/wwwroot/scripts/library.js | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor index 45e4a983..f36353d9 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileDropOverlay.razor @@ -25,7 +25,7 @@ along with Foobar. If not, see @inject DialogManager _dialogManager - @code { - //TODO: FieldId can not be used, it is readonly private DotNetObjectReference? _dotNetRef; private bool _showOverlay; private bool _disposed; diff --git a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor index 59a50a48..91ebeb91 100644 --- a/AudioCuesheetEditor/Shared/Inputs/FileInput.razor +++ b/AudioCuesheetEditor/Shared/Inputs/FileInput.razor @@ -20,7 +20,7 @@ along with Foobar. If not, see @inject IStringLocalizer _localizer -