diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/BasicTest.cs b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/BasicTest.cs index 26ca4f12..e0e507d3 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/BasicTest.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/BasicTest.cs @@ -68,7 +68,6 @@ public async Task ChangeLanguage_ShouldSwitchLanguage_WhenGermanIsSelected() var detailView = new DetailView(TestPage); await detailView.GotoAsync(); await bar.ChangeLanguageAsync("German (Germany)"); - await Expect(TestPage.GetByRole(AriaRole.Heading, new() { Name = "Abschnitte" })).ToBeVisibleAsync(); await Expect(TestPage.GetByRole(AriaRole.Heading, new() { Name = "Allgemeine Informationen" })).ToBeVisibleAsync(); await Expect(TestPage.GetByText("Aufnahmeansicht")).ToBeVisibleAsync(); await Expect(TestPage.GetByRole(AriaRole.Heading, new() { Name = "Titel" })).ToBeVisibleAsync(); @@ -79,7 +78,7 @@ public async Task ChangeLanguage_ShouldSwitchLanguage_WhenGermanIsSelected() await Expect(TestPage.Locator("#app")).ToMatchAriaSnapshotAsync("- paragraph: Künstler\n- paragraph: Titel\n- paragraph: Audiodatei\n- paragraph: CDTextdatei\n- paragraph: Katalognummer\n- paragraph: Datum\n- paragraph: Datum & Uhrzeit\n- paragraph: Uhrzeit"); await TestPage.GetByText("CDTextdatei").ClickAsync(); await exportDialog.OpenSchemeMenuAsync("Schema Titel"); - await Expect(TestPage.Locator("#app")).ToMatchAriaSnapshotAsync("- paragraph: Position\n- paragraph: Künstler\n- paragraph: Titel\n- paragraph: Beginn\n- paragraph: Ende\n- paragraph: Länge\n- paragraph: Markierungen\n- paragraph: Vorlücke\n- paragraph: Nachlücke"); + await Expect(TestPage.GetByTestId("menu-wrapper")).ToMatchAriaSnapshotAsync("- paragraph: Position\n- paragraph: Künstler\n- paragraph: Titel\n- paragraph: Begin\n- paragraph: End\n- paragraph: Länge\n- paragraph: Markierungen\n- paragraph: Vorlücke\n- paragraph: Nachlücke"); } [TestMethod] diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs index e2cb6937..8e856f81 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs @@ -68,7 +68,7 @@ public async Task DownloadProject_GeneratesProjectFile_WhenCuesheetIsValidAsync( using var stream = await download.CreateReadStreamAsync(); using var reader = new StreamReader(stream); var content = await reader.ReadToEndAsync(TestContext.CancellationToken); - Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}},\"Sections\":[]}", content); + Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48.0608330\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48.0608330\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}}}", content); } [TestMethod] diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/BasicTestSmartphone.cs b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/BasicTestSmartphone.cs index 92a725ed..6c87dc81 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/BasicTestSmartphone.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/BasicTestSmartphone.cs @@ -70,7 +70,6 @@ public async Task ChangeLanguage_ShouldSwitchLanguage_WhenGermanIsSelected() var detailView = new DetailView(TestPage); await detailView.GotoAsync(); await bar.ChangeLanguageAsync("German (Germany)"); - await Expect(TestPage.GetByRole(AriaRole.Heading, new() { Name = "Abschnitte" })).ToBeVisibleAsync(); await Expect(TestPage.GetByRole(AriaRole.Heading, new() { Name = "Allgemeine Informationen" })).ToBeVisibleAsync(); await Expect(TestPage.GetByText("Aufnahmeansicht")).ToBeVisibleAsync(); await Expect(TestPage.GetByRole(AriaRole.Heading, new() { Name = "Titel" })).ToBeVisibleAsync(); @@ -81,7 +80,7 @@ public async Task ChangeLanguage_ShouldSwitchLanguage_WhenGermanIsSelected() await Expect(TestPage.Locator("#app")).ToMatchAriaSnapshotAsync("- paragraph: Künstler\n- paragraph: Titel\n- paragraph: Audiodatei\n- paragraph: CDTextdatei\n- paragraph: Katalognummer\n- paragraph: Datum\n- paragraph: Datum & Uhrzeit\n- paragraph: Uhrzeit"); await TestPage.GetByText("CDTextdatei").ClickAsync(); await exportDialog.OpenSchemeMenuAsync("Schema Titel"); - await Expect(TestPage.Locator("#app")).ToMatchAriaSnapshotAsync("- paragraph: Position\n- paragraph: Künstler\n- paragraph: Titel\n- paragraph: Beginn\n- paragraph: Ende\n- paragraph: Länge\n- paragraph: Markierungen\n- paragraph: Vorlücke\n- paragraph: Nachlücke"); + await Expect(TestPage.GetByTestId("menu-wrapper")).ToMatchAriaSnapshotAsync("- paragraph: Position\n- paragraph: Künstler\n- paragraph: Titel\n- paragraph: Begin\n- paragraph: End\n- paragraph: Länge\n- paragraph: Markierungen\n- paragraph: Vorlücke\n- paragraph: Nachlücke"); } [TestMethod] diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs index 61cdc3fd..22865d9b 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs @@ -68,7 +68,7 @@ public async Task DownloadProject_GeneratesProjectFile_WhenCuesheetIsValidAsync( using var stream = await download.CreateReadStreamAsync(); using var reader = new StreamReader(stream); var content = await reader.ReadToEndAsync(TestContext.CancellationToken); - Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}},\"Sections\":[]}", content); + Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48.0608330\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48.0608330\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}}}", content); } [TestMethod] diff --git a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj index dc6ac4ec..0651db7f 100644 --- a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj +++ b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs b/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs index aaeea1fb..0db99667 100644 --- a/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs +++ b/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs @@ -16,7 +16,6 @@ using AudioCuesheetEditor.Model.AudioCuesheet; using AudioCuesheetEditor.Model.Entity; using AudioCuesheetEditor.Model.IO.Audio; -using AudioCuesheetEditor.Model.IO.Export; using AudioCuesheetEditor.Tests.Utility; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -414,96 +413,6 @@ public void IsRecordingPossible_WhenNoErrors_ReturnsEmpty() Assert.IsEmpty(errors); } - [TestMethod] - public void AddSection_WithValidData_FiresEvents() - { - // Arrange - var cuesheet = new Cuesheet(); - bool eventFired = false; - cuesheet.TraceablePropertyChanged += (sender, args) => - { - if (args.TraceableChange.PropertyName == nameof(Cuesheet.Sections)) - { - eventFired = true; - } - }; - - // Act - var section = cuesheet.AddSection(); - - // Assert - Assert.IsTrue(eventFired); - Assert.IsNotNull(section); - Assert.HasCount(1, cuesheet.Sections); - Assert.AreEqual(cuesheet, section.Cuesheet); - } - - [TestMethod()] - public void RemoveSections_RemovesSpecifiedSections() - { - // Arrange - var cuesheet = new Cuesheet(); - var section1 = cuesheet.AddSection(); - var section2 = cuesheet.AddSection(); - var section3 = cuesheet.AddSection(); - var sectionsToRemove = new List { section1, section3 }; - bool eventFired = false; - cuesheet.TraceablePropertyChanged += (sender, args) => - { - if (args.TraceableChange.PropertyName == nameof(Cuesheet.Sections)) - { - eventFired = true; - } - }; - - // Act - cuesheet.RemoveSections(sectionsToRemove); - - // Assert - Assert.IsTrue(eventFired); - Assert.HasCount(1, cuesheet.Sections); - Assert.IsTrue(cuesheet.Sections.Contains(section2)); - Assert.IsFalse(cuesheet.Sections.Contains(section1)); - Assert.IsFalse(cuesheet.Sections.Contains(section3)); - } - - [TestMethod()] - public void GetSection_ReturnsCorrectSection() - { - // Arrange - var cuesheet = new Cuesheet(); - var section1 = cuesheet.AddSection(); - section1.Begin = TimeSpan.Zero; - section1.End = TimeSpan.FromSeconds(120); - cuesheet.AddSection(); - var track = new Track { Begin = TimeSpan.Zero, End = TimeSpan.FromSeconds(83) }; - cuesheet.AddTrack(track); - - // Act - var result = cuesheet.GetSection(track); - - // Assert - Assert.AreEqual(section1, result); - } - - [TestMethod()] - public void GetSection_ReturnsNullIfNoMatchingSection() - { - // Arrange - var cuesheet = new Cuesheet(); - var section1 = cuesheet.AddSection(); - section1.Begin = TimeSpan.Zero; - section1.End = TimeSpan.FromHours(1.5); - var track = new Track { Begin = section1.End + TimeSpan.FromSeconds(1), End = section1.End + TimeSpan.FromSeconds(2) }; - cuesheet.AddTrack(track); - - // Act - var result = cuesheet.GetSection(track); - - // Assert - Assert.IsNull(result); - } - [TestMethod] public void MoveTracksPossible_ShouldReturnFalse_WhenNoTracksToMove() { @@ -764,12 +673,9 @@ public void StartRecording_WithAudiofile_ShouldStartRecording() public void RecalculateLastTrackEnd_SingleTrackWithAudiofile_EndSetToAudiofileDuration() { // Arrange - var audiofileMock = new Mock(); - audiofileMock.SetupGet(a => a.Duration).Returns(TimeSpan.FromMinutes(5)); - var cuesheet = new Cuesheet { - Audiofile = audiofileMock.Object + Audiofile = new("Test.mp3", nameof(RecalculateLastTrackEnd_SingleTrackWithAudiofile_EndSetToAudiofileDuration), new AudioCodec("audio/mpeg", ".mp3", "AudioCodec MP3"), TimeSpan.FromMinutes(5)) }; var track = new Track { Position = 1, Begin = TimeSpan.Zero }; cuesheet.AddTrack(track); @@ -803,12 +709,9 @@ public void RecalculateLastTrackEnd_MultipleTracks_EndSetCorrectly() public void RecalculateLastTrackEnd_MultipleTracksWithAudiofile_LastTrackEndSetToAudiofileDuration() { // Arrange - var audiofileMock = new Mock(); - audiofileMock.SetupGet(a => a.Duration).Returns(TimeSpan.FromMinutes(5)); - var cuesheet = new Cuesheet { - Audiofile = audiofileMock.Object + Audiofile = new("Test.mp3", nameof(RecalculateLastTrackEnd_SingleTrackWithAudiofile_EndSetToAudiofileDuration), new AudioCodec("audio/mpeg", ".mp3", "AudioCodec MP3"), TimeSpan.FromMinutes(5)) }; var track1 = new Track { Position = 1, Begin = TimeSpan.Zero, End = TimeSpan.FromMinutes(2) }; var track2 = new Track { Position = 2, Begin = TimeSpan.FromMinutes(2) }; diff --git a/AudioCuesheetEditor.Tests/Model/IO/Audio/AudiofileTests.cs b/AudioCuesheetEditor.Tests/Model/IO/Audio/AudiofileTests.cs deleted file mode 100644 index 7779ba5a..00000000 --- a/AudioCuesheetEditor.Tests/Model/IO/Audio/AudiofileTests.cs +++ /dev/null @@ -1,48 +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.Model.IO.Audio; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Linq; - -namespace AudioCuesheetEditor.Tests.Model.IO.Audio -{ - [TestClass()] - public class AudiofileTests - { - [TestMethod()] - public void AudioFileTest() - { - var audioFile = new Audiofile("test.mp3"); - Assert.IsNull(audioFile.ContentStream); - Assert.IsFalse(audioFile.IsContentStreamLoaded); - Assert.IsNotNull(audioFile.Name); - Assert.AreEqual("MP3", audioFile.AudioFileType); - audioFile = new Audiofile("Test"); - Assert.AreEqual(audioFile.AudioFileType, string.Empty); - Assert.IsNotNull(audioFile.Name); - var codec = Audiofile.AudioCodecs.Single(x => x.FileExtension == ".ogg"); - audioFile = new Audiofile("test", "TestobjectURL", codec); - Assert.IsNotNull(audioFile.Name); - Assert.AreEqual("test.ogg", audioFile.Name); - Assert.AreEqual("OGG", audioFile.AudioFileType); - Assert.IsNotNull(audioFile.ObjectURL); - Assert.IsTrue(audioFile.PlaybackPossible); - codec = Audiofile.AudioCodecs.Single(x => x.FileExtension == ".mp3"); - var audioFile2 = new Audiofile(audioFile.Name, "TestObjectURL2", codec); - Assert.AreEqual("test.mp3", audioFile2.Name); - } - } -} \ No newline at end of file diff --git a/AudioCuesheetEditor.Tests/Model/IO/Export/CuesheetSectionTests.cs b/AudioCuesheetEditor.Tests/Model/IO/Export/CuesheetSectionTests.cs deleted file mode 100644 index e752c314..00000000 --- a/AudioCuesheetEditor.Tests/Model/IO/Export/CuesheetSectionTests.cs +++ /dev/null @@ -1,175 +0,0 @@ -using AudioCuesheetEditor.Model.AudioCuesheet; -using AudioCuesheetEditor.Model.Entity; -using AudioCuesheetEditor.Model.IO.Export; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; - -namespace AudioCuesheetEditor.Tests.Model.IO.Export -{ - [TestClass()] - public class CuesheetSectionTests - { - [TestMethod()] - public void ValidationTest() - { - var cuesheet = new Cuesheet(); - var section = new CuesheetSection(cuesheet); - Assert.IsNull(section.Begin); - var beginValidationResult = section.Validate(nameof(CuesheetSection.Begin)); - var endValidationResult = section.Validate(nameof(CuesheetSection.End)); - Assert.AreEqual(ValidationStatus.Error, beginValidationResult.Status); - Assert.AreEqual(ValidationStatus.Error, endValidationResult.Status); - section.Begin = new TimeSpan(0, 0, 0); - beginValidationResult = section.Validate(nameof(CuesheetSection.Begin)); - endValidationResult = section.Validate(nameof(CuesheetSection.End)); - Assert.AreEqual(ValidationStatus.Success, beginValidationResult.Status); - Assert.AreEqual(ValidationStatus.Error, endValidationResult.Status); - cuesheet.AddTrack(new Track() { Position = 1, Begin = new TimeSpan(0, 0, 10) }); - cuesheet.AddTrack(new Track() { Position = 2, Begin = new TimeSpan(0, 8, 43), End = new TimeSpan(0, 15, 43) }); - beginValidationResult = section.Validate(nameof(CuesheetSection.Begin)); - endValidationResult = section.Validate(nameof(CuesheetSection.End)); - Assert.AreEqual(ValidationStatus.Error, beginValidationResult.Status); - Assert.AreEqual(ValidationStatus.Error, endValidationResult.Status); - section.Begin = new TimeSpan(0, 0, 10); - beginValidationResult = section.Validate(nameof(CuesheetSection.Begin)); - endValidationResult = section.Validate(nameof(CuesheetSection.End)); - Assert.AreEqual(ValidationStatus.Success, beginValidationResult.Status); - Assert.AreEqual(ValidationStatus.Error, endValidationResult.Status); - section.Begin = new TimeSpan(0, 10, 0); - section.End = new TimeSpan(0, 5, 0); - beginValidationResult = section.Validate(nameof(CuesheetSection.Begin)); - endValidationResult = section.Validate(nameof(CuesheetSection.End)); - Assert.AreEqual(ValidationStatus.Error, beginValidationResult.Status); - Assert.AreEqual(ValidationStatus.Error, endValidationResult.Status); - section.Begin = new TimeSpan(0, 10, 0); - section.End = new TimeSpan(0, 15, 0); - beginValidationResult = section.Validate(nameof(CuesheetSection.Begin)); - endValidationResult = section.Validate(nameof(CuesheetSection.End)); - Assert.AreEqual(ValidationStatus.Success, beginValidationResult.Status); - Assert.AreEqual(ValidationStatus.Success, endValidationResult.Status); - } - - [TestMethod()] - public void Begin_FirstSection_ReturnsTimespanZero() - { - // Arrange - var cuesheet = new Cuesheet(); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 4, 43) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 9, 23) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 14, 12) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 18, 53) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 22, 01) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 25, 56) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 31, 12) - }); - // Act - var section = cuesheet.AddSection(); - // Assert - Assert.AreEqual(TimeSpan.Zero, section.Begin); - } - - [TestMethod()] - public void Begin_SecondSection_ReturnsFirstSectionEnd() - { - // Arrange - var cuesheet = new Cuesheet(); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 4, 43) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 9, 23) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 14, 12) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 18, 53) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 22, 01) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 25, 56) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 31, 12) - }); - var section1 = cuesheet.AddSection(); - section1.End = new TimeSpan(0, 30, 0); - // Act - var section2 = cuesheet.AddSection(); - // Assert - Assert.AreEqual(section1.End, section2.Begin); - } - - [TestMethod()] - public void Begin_ThirdSection_ReturnsSecondSectionEnd() - { - // Arrange - var cuesheet = new Cuesheet(); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 4, 43) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 9, 23) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 14, 12) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 18, 53) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 22, 01) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 25, 56) - }); - cuesheet.AddTrack(new Track() - { - End = new TimeSpan(0, 31, 12) - }); - var section1 = cuesheet.AddSection(); - section1.End = new TimeSpan(0, 15, 0); - var section2 = cuesheet.AddSection(); - section2.End = new TimeSpan(0, 30, 0); - // Act - var section3 = cuesheet.AddSection(); - // Assert - Assert.AreEqual(section2.End, section3.Begin); - } - } -} \ No newline at end of file diff --git a/AudioCuesheetEditor.Tests/Model/IO/ProjectfileTests.cs b/AudioCuesheetEditor.Tests/Model/IO/ProjectfileTests.cs index f8f6cd0d..37848f93 100644 --- a/AudioCuesheetEditor.Tests/Model/IO/ProjectfileTests.cs +++ b/AudioCuesheetEditor.Tests/Model/IO/ProjectfileTests.cs @@ -21,7 +21,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Text.Json; namespace AudioCuesheetEditor.Tests.Model.IO @@ -76,57 +75,6 @@ public void GenerateFile_WithoutSections_GeneratesOneFile() File.Delete(fileName); } - [TestMethod()] - public void GenerateFile_WithSections_GeneratesOneFile() - { - // Arrange - var cuesheet = new Cuesheet - { - Artist = "CuesheetArtist", - Title = "CuesheetTitle", - Audiofile = new Audiofile("AudioFile.mp3"), - CDTextfile = new CDTextfile("CDTextfile.cdt"), - Cataloguenumber = "A123" - }; - var begin = TimeSpan.Zero; - for (int i = 1; i <= 10; i++) - { - var track = new Track - { - Position = (uint)i, - Artist = string.Format("Artist {0}", i), - Title = string.Format("Title {0}", i), - Begin = begin - }; - var rand = new Random(); - var flagsToAdd = rand.Next(1, 3); - var flags = new List(); - for (int x = 0; x < flagsToAdd; x++) - { - flags.Add(Flag.AvailableFlags.ElementAt(x)); - } - track.Flags = flags; - begin = begin.Add(new TimeSpan(0, i, i)); - track.End = begin; - cuesheet.AddTrack(track); - } - var section = cuesheet.AddSection(); - section.Begin = new TimeSpan(0, 30, 0); - section = cuesheet.AddSection(); - section.Begin = new TimeSpan(1, 0, 0); - var projectFile = new Projectfile(cuesheet); - // Act - var generatedFile = projectFile.GenerateFile(); - // Assert - Assert.IsNotNull(generatedFile); - var fileName = Path.GetTempFileName(); - File.WriteAllBytes(fileName, generatedFile); - var fileContent = File.ReadAllLines(fileName); - var json = JsonSerializer.Serialize(cuesheet, Projectfile.Options); - Assert.AreEqual(json, fileContent.FirstOrDefault()); - File.Delete(fileName); - } - [TestMethod()] public void ImportFile_ValidProjectfile_ShouldImportFile() { @@ -175,9 +123,10 @@ public void ImportFile_ValidProjectfileWithSections_ShouldImportFile() Assert.IsTrue(ReferenceEquals(cuesheet.Tracks.First(), cuesheet.GetPreviousLinkedTrack(cuesheet.Tracks.ElementAt(1)))); Assert.AreEqual(cuesheet.Tracks.First(), cuesheet.GetPreviousLinkedTrack(cuesheet.Tracks.ElementAt(1))); Assert.AreEqual((uint)10, cuesheet.Tracks.Last().Position); - Assert.HasCount(2, cuesheet.Sections); - Assert.AreEqual(new TimeSpan(0, 30, 0), cuesheet.Sections.First().Begin); - Assert.AreEqual(new TimeSpan(1, 0, 0), cuesheet.Sections.Last().Begin); + //TODOD + //Assert.HasCount(2, cuesheet.Sections); + //Assert.AreEqual(new TimeSpan(0, 30, 0), cuesheet.Sections.First().Begin); + //Assert.AreEqual(new TimeSpan(1, 0, 0), cuesheet.Sections.Last().Begin); } } } \ No newline at end of file diff --git a/AudioCuesheetEditor.Tests/Services/IO/CuesheetExportServiceTests.cs b/AudioCuesheetEditor.Tests/Services/IO/CuesheetExportServiceTests.cs index bfa05bc5..bcfd701d 100644 --- a/AudioCuesheetEditor.Tests/Services/IO/CuesheetExportServiceTests.cs +++ b/AudioCuesheetEditor.Tests/Services/IO/CuesheetExportServiceTests.cs @@ -14,46 +14,49 @@ //along with Foobar. If not, see //. using AudioCuesheetEditor.Model.AudioCuesheet; +using AudioCuesheetEditor.Model.Entity; using AudioCuesheetEditor.Model.IO.Audio; -using AudioCuesheetEditor.Model.IO.Export; using AudioCuesheetEditor.Services.IO; using AudioCuesheetEditor.Services.UI; +using Microsoft.Extensions.Localization; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System; -using System.Linq; -using System.Text; namespace AudioCuesheetEditor.Tests.Services.IO { [TestClass()] public class CuesheetExportServiceTests { - private readonly Mock sessionStateContainerMock; - private readonly CuesheetExportService cuesheetExportService; + private readonly Mock _sessionStateContainerMock; + private readonly Mock> _localizerMock; + private readonly CuesheetExportService _cuesheetExportService; public CuesheetExportServiceTests() { - sessionStateContainerMock = new Mock(); - cuesheetExportService = new CuesheetExportService(sessionStateContainerMock.Object); + _sessionStateContainerMock = new Mock(); + _localizerMock = new Mock>(); + _cuesheetExportService = new CuesheetExportService(_sessionStateContainerMock.Object, _localizerMock.Object); } [TestMethod] - public void CanGenerateExportfiles_InvalidExtension_ReturnsValidationMessage() + public void CanGenerateExportfile_InvalidExtension_ReturnsValidationMessage() { // Arrange string invalidFilename = "test.txt"; - sessionStateContainerMock.SetupProperty(x => x.Cuesheet, new Cuesheet()); + _sessionStateContainerMock.SetupProperty(x => x.Cuesheet, new Cuesheet()); + _localizerMock.Setup(x => x["File extension is not '{0}'", It.IsAny()]).Returns(new LocalizedString("File extension is not '{0}'", "File extension is not '{0}'")); // Act - var result = cuesheetExportService.CanGenerateExportfiles(invalidFilename); + var result = _cuesheetExportService.CanGenerateExportfile(invalidFilename); // Assert - Assert.Contains(vm => vm.Message.Contains("File extension is not"), result); + Assert.IsFalse(result.IsSuccess); + Assert.IsTrue(result.Error?.Message.Contains("File extension is not")); } [TestMethod] - public void CanGenerateExportfiles_ValidExtension_ReturnsEmpty() + public void CanGenerateExportfiles_ValidExtension_ReturnsSuccess() { // Arrange var cuesheet = new Cuesheet() @@ -68,13 +71,13 @@ public void CanGenerateExportfiles_ValidExtension_ReturnsEmpty() Begin = TimeSpan.Zero, End = new TimeSpan(0, 3, 43) }); - sessionStateContainerMock.SetupProperty(x => x.Cuesheet, cuesheet); + _sessionStateContainerMock.SetupProperty(x => x.Cuesheet, cuesheet); // Act - var result = cuesheetExportService.CanGenerateExportfiles("test.cue"); + var result = _cuesheetExportService.CanGenerateExportfile("test.cue"); // Assert - Assert.AreEqual(0, result.Count()); + Assert.IsTrue(result.IsSuccess); } [TestMethod] @@ -103,17 +106,15 @@ public void GenerateExportfiles_WithoutSections_ReturnsExportFile() End = new TimeSpan(0, 8, 32), Position = 2 }); - sessionStateContainerMock.SetupProperty(x => x.Cuesheet, cuesheet); + _sessionStateContainerMock.SetupProperty(x => x.Cuesheet, cuesheet); // Act - var result = cuesheetExportService.GenerateExportfiles(filename); + var result = _cuesheetExportService.GenerateExportfile(filename); // Assert - Assert.HasCount(1, result); - Assert.AreEqual(filename, result.First().Name); - Assert.AreEqual(TimeSpan.Zero, result.First().Begin); - Assert.AreEqual(new TimeSpan(0, 8, 32), result.First().End); - var content = result.First().Content; + Assert.IsTrue(result.IsSuccess); + Assert.AreEqual(filename, result.Value!.Name); + var content = result.Value!.Content; Assert.IsNotNull(content); Assert.AreEqual(@"TITLE ""Test title cuesheet"" PERFORMER ""Test artist cuesheet"" @@ -130,103 +131,7 @@ TRACK 02 AUDIO } [TestMethod] - public void GenerateExportfiles_WithSections_ReturnsExportFiles() - { - // Arrange - var filename = "Test valid Filename.cue"; - var exportProfile = new Exportprofile - { - Name = "TestProfile", - SchemeHead = "%Cuesheet.Artist% - %Cuesheet.Title%", - SchemeTracks = "%Track.Position% %Track.Artist% - %Track.Title%", - Filename = "TestExport.txt" - }; - var cuesheet = new Cuesheet() - { - Artist = "Test artist cuesheet", - Title = "Test title cuesheet", - Audiofile = new Audiofile("Test audiofile.mp3") - }; - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 1", - Title = "Test title 1", - Begin = TimeSpan.Zero, - End = new TimeSpan(0, 4, 12), - Position = 1 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 2", - Title = "Test title 2", - End = new TimeSpan(0, 8, 32), - Position = 2 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 3", - Title = "Test title 3", - End = new TimeSpan(0, 12, 31), - Position = 3 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 4", - Title = "Test title 4", - End = new TimeSpan(0, 16, 8), - Position = 4 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 5", - Title = "Test title 5", - End = new TimeSpan(0, 21, 54), - Position = 5 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 6", - Title = "Test title 6", - End = new TimeSpan(0, 31, 32), - Position = 6 - }); - var section1 = cuesheet.AddSection(); - section1.Begin = TimeSpan.Zero; - section1.End = new TimeSpan(0, 10, 0); - var section2 = cuesheet.AddSection(); - section2.Begin = section1.End; - section2.End = new TimeSpan(0, 20, 0); - var section3 = cuesheet.AddSection(); - section3.Begin = section2.End; - section3.End = new TimeSpan(0, 30, 0); - sessionStateContainerMock.SetupProperty(x => x.Cuesheet, cuesheet); - - // Act - var result = cuesheetExportService.GenerateExportfiles(filename); - - // Assert - Assert.HasCount(3, result); - Assert.AreEqual("Test valid Filename(3).cue", result.Last().Name); - Assert.AreEqual(section3.Begin, result.Last().Begin); - Assert.AreEqual(section3.End, result.Last().End); - var content = result.Last().Content; - Assert.IsNotNull(content); - Assert.AreEqual(@"TITLE ""Test title cuesheet"" -PERFORMER ""Test artist cuesheet"" -FILE ""Test audiofile.mp3"" MP3 - TRACK 01 AUDIO - TITLE ""Test title 5"" - PERFORMER ""Test artist 5"" - INDEX 01 00:00:00 - TRACK 02 AUDIO - TITLE ""Test title 6"" - PERFORMER ""Test artist 6"" - INDEX 01 01:54:00 -", content); - } - - [TestMethod] - public void GenerateExportfiles_WithInvalidTracks_ReturnsEmpty() + public void GenerateExportfiles_WithInvalidTracks_ReturnsFailure() { // Arrange var cuesheet = new Cuesheet() @@ -246,13 +151,13 @@ public void GenerateExportfiles_WithInvalidTracks_ReturnsEmpty() }; cuesheet.AddTrack(track1); cuesheet.AddTrack(track2); - sessionStateContainerMock.SetupProperty(x => x.Cuesheet, cuesheet); + _sessionStateContainerMock.SetupProperty(x => x.Cuesheet, cuesheet); // Act - var result = cuesheetExportService.GenerateExportfiles("test.cue"); + var result = _cuesheetExportService.GenerateExportfile("test.cue"); // Assert - Assert.HasCount(0, result); + Assert.IsFalse(result.IsSuccess); } } } \ No newline at end of file diff --git a/AudioCuesheetEditor.Tests/Services/IO/ExportfileGeneratorTests.cs b/AudioCuesheetEditor.Tests/Services/IO/ExportfileGeneratorTests.cs index 98246d33..2b57cc83 100644 --- a/AudioCuesheetEditor.Tests/Services/IO/ExportfileGeneratorTests.cs +++ b/AudioCuesheetEditor.Tests/Services/IO/ExportfileGeneratorTests.cs @@ -14,28 +14,29 @@ //along with Foobar. If not, see //. using AudioCuesheetEditor.Model.AudioCuesheet; +using AudioCuesheetEditor.Model.Entity; using AudioCuesheetEditor.Model.IO.Audio; using AudioCuesheetEditor.Model.IO.Export; using AudioCuesheetEditor.Services.IO; using AudioCuesheetEditor.Services.UI; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Localization; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System; -using System.Linq; namespace AudioCuesheetEditor.Tests.Services.IO { [TestClass] public class ExportfileGeneratorTests { - private readonly Mock mockSessionStateContainer; - private readonly ExportfileGenerator exportfileGenerator; + private readonly Mock _mockSessionStateContainer; + private readonly ExportfileGenerator _exportfileGenerator; public ExportfileGeneratorTests() { - mockSessionStateContainer = new Mock(); - exportfileGenerator = new ExportfileGenerator(mockSessionStateContainer.Object); + _mockSessionStateContainer = new Mock(); + var mockLocalizer = new Mock>(); + _exportfileGenerator = new ExportfileGenerator(_mockSessionStateContainer.Object, mockLocalizer.Object); } [TestMethod] @@ -70,112 +71,19 @@ public void GenerateExportFile_ShouldGenerateExportfile_WithoutSections() End = new TimeSpan(0, 8, 32), Position = 2 }); - mockSessionStateContainer.SetupProperty(x => x.Cuesheet, cuesheet); + _mockSessionStateContainer.SetupProperty(x => x.Cuesheet, cuesheet); // Act - var result = exportfileGenerator.GenerateExportfiles(exportProfile); - + var result = _exportfileGenerator.GenerateExportfile(exportProfile); // Assert - Assert.IsNotNull(result); - Assert.HasCount(1, result); - Assert.AreEqual(exportProfile.Filename, result.First().Name); - Assert.AreEqual(TimeSpan.Zero, result.First().Begin); - Assert.AreEqual(new TimeSpan(0, 8, 32), result.First().End); - var content = result.First().Content; + Assert.IsTrue(result.IsSuccess); + Assert.AreEqual(exportProfile.Filename, result.Value!.Name); + var content = result.Value!.Content; Assert.IsNotNull(content); Assert.AreEqual(@"Test artist cuesheet - Test title cuesheet 1 Test artist 1 - Test title 1 2 Test artist 2 - Test title 2 -", content); - } - - [TestMethod] - public void GenerateExportFile_ShouldGenerateExportfiles_WithSections() - { - // Arrange - var exportProfile = new Exportprofile - { - Name = "TestProfile", - SchemeHead = "%Cuesheet.Artist% - %Cuesheet.Title%", - SchemeTracks = "%Track.Position% %Track.Artist% - %Track.Title%", - Filename = "TestExport.txt" - }; - var cuesheet = new Cuesheet() - { - Artist = "Test artist cuesheet", - Title = "Test title cuesheet", - Audiofile = new Audiofile("Test audiofile.mp3") - }; - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 1", - Title = "Test title 1", - Begin = TimeSpan.Zero, - End = new TimeSpan(0, 4, 12), - Position = 1 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 2", - Title = "Test title 2", - End = new TimeSpan(0, 8, 32), - Position = 2 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 3", - Title = "Test title 3", - End = new TimeSpan(0, 12, 31), - Position = 3 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 4", - Title = "Test title 4", - End = new TimeSpan(0, 16, 8), - Position = 4 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 5", - Title = "Test title 5", - End = new TimeSpan(0, 21, 54), - Position = 5 - }); - cuesheet.AddTrack(new Track() - { - Artist = "Test artist 6", - Title = "Test title 6", - End = new TimeSpan(0, 31, 32), - Position = 6 - }); - var section1 = cuesheet.AddSection(); - section1.Begin = TimeSpan.Zero; - section1.End = new TimeSpan(0, 10, 0); - var section2 = cuesheet.AddSection(); - section2.Begin = section1.End; - section2.End = new TimeSpan(0, 20, 0); - var section3 = cuesheet.AddSection(); - section3.Begin = section2.End; - section3.End = new TimeSpan(0, 30, 0); - mockSessionStateContainer.SetupProperty(x => x.Cuesheet, cuesheet); - - // Act - var result = exportfileGenerator.GenerateExportfiles(exportProfile); - - // Assert - Assert.IsNotNull(result); - Assert.HasCount(3, result); - Assert.AreEqual("TestExport(3).txt", result.Last().Name); - Assert.AreEqual(section3.Begin, result.Last().Begin); - Assert.AreEqual(section3.End, result.Last().End); - var content = result.Last().Content; - Assert.IsNotNull(content); - Assert.AreEqual(@"Test artist cuesheet - Test title cuesheet -1 Test artist 5 - Test title 5 -2 Test artist 6 - Test title 6 - ", content); } @@ -205,18 +113,15 @@ public void GenerateExportFile_ShouldHandleEmptyProfile() End = new TimeSpan(0, 8, 32), Position = 2 }); - mockSessionStateContainer.SetupProperty(x => x.Cuesheet, cuesheet); + _mockSessionStateContainer.SetupProperty(x => x.Cuesheet, cuesheet); // Act - var result = exportfileGenerator.GenerateExportfiles(exportProfile); + var result = _exportfileGenerator.GenerateExportfile(exportProfile); // Assert - Assert.IsNotNull(result); - Assert.HasCount(1, result); - Assert.AreEqual(Exportprofile.DefaultFileName, result.First().Name); - Assert.AreEqual(TimeSpan.Zero, result.First().Begin); - Assert.AreEqual(new TimeSpan(0, 8, 32), result.First().End); - Assert.IsNotNull(result.First().Content); + Assert.IsTrue(result.IsSuccess); + Assert.AreEqual(Exportprofile.DefaultFileName, result.Value!.Name); + Assert.IsNotNull(result.Value!.Content); } [TestMethod] @@ -249,13 +154,13 @@ public void GenerateExportFile_ReturnsEmpty_WithInvalidTracks() Title = "Test title 2", Position = 2 }); - mockSessionStateContainer.SetupProperty(x => x.Cuesheet, cuesheet); + _mockSessionStateContainer.SetupProperty(x => x.Cuesheet, cuesheet); // Act - var result = exportfileGenerator.GenerateExportfiles(exportProfile); + var result = _exportfileGenerator.GenerateExportfile(exportProfile); // Assert - Assert.HasCount(0, result); + Assert.IsFalse(result.IsSuccess); } } } \ No newline at end of file diff --git a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs index 5b6b2ec9..875a900b 100644 --- a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs +++ b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs @@ -288,7 +288,7 @@ public async Task UploadFilesAsync_WithAudiofile_ImportsCorrectly() _fileInputManagerMock.Setup(f => f.CheckFileMimeType(file.ContentType, file.Name, FileMimeTypes.Cuesheet, It.IsAny>())).Returns(false); _fileInputManagerMock.Setup(f => f.IsValidForImportView(file.ContentType, file.Name)).Returns(false); _fileInputManagerMock.Setup(f => f.IsValidAudiofile(file.ContentType, file.Name)).Returns(true); - _fileInputManagerMock.Setup(f => f.CreateAudiofileAsync(It.IsAny(), It.IsAny>?>())).ReturnsAsync(new AudioCuesheetEditor.Model.IO.Audio.Audiofile(file.Name)); + _fileInputManagerMock.Setup(f => f.CreateAudiofileAsync(It.IsAny())).ReturnsAsync(new Audiofile(file.Name)); IImportfile? sessionStateContainerImportfile = null; _sessionStateContainerMock.SetupSet(x => x.Importfile = It.IsAny()).Callback(x => sessionStateContainerImportfile = x); diff --git a/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs b/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs index 5eda87dc..195cbcb3 100644 --- a/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs +++ b/AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs @@ -367,7 +367,7 @@ public void RemoveTracedChanges_RemovesChanges_WhenChangesAvailable() cuesheet1.Artist = "Test Artist Cuesheet 1"; cuesheet1.Title = "Test Title Cuesheet 1"; cuesheet2.CDTextfile = new("CD Testfile.cdt"); - cuesheet2.AddSection(); + cuesheet2.Title = "Test Title Cuesheet 2"; var tracedObjectHistoryChangedFired = false; manager.TracedObjectHistoryChanged += delegate { @@ -393,7 +393,7 @@ public void RemoveTracedChanges_RemovesNoChanges_WhenNoChangesAvailable() manager.TraceChanges(cuesheet1); manager.TraceChanges(cuesheet2); cuesheet2.CDTextfile = new("CD Testfile.cdt"); - cuesheet2.AddSection(); + cuesheet2.Title = "Test Title Cuesheet 2"; var tracedObjectHistoryChangedFired = false; manager.TracedObjectHistoryChanged += delegate { diff --git a/AudioCuesheetEditor/AudioCuesheetEditor.csproj b/AudioCuesheetEditor/AudioCuesheetEditor.csproj index 9dd43125..171d7120 100644 --- a/AudioCuesheetEditor/AudioCuesheetEditor.csproj +++ b/AudioCuesheetEditor/AudioCuesheetEditor.csproj @@ -7,7 +7,7 @@ enable https://github.com/NeoCoderMatrix86/AudioCuesheetEditor 3.0 - 11.0.0 + 12.0.0 false true true @@ -22,16 +22,15 @@ - - + + - - - - + + + + - diff --git a/AudioCuesheetEditor/Extensions/InterfaceConverter.cs b/AudioCuesheetEditor/Extensions/InterfaceConverter.cs deleted file mode 100644 index f5ab2bfb..00000000 --- a/AudioCuesheetEditor/Extensions/InterfaceConverter.cs +++ /dev/null @@ -1,40 +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 System.Text.Json.Serialization; -using System.Text.Json; - -namespace AudioCuesheetEditor.Extensions -{ - public class InterfaceConverter : JsonConverter where TImplementation : TInterface - { - public override TInterface? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return JsonSerializer.Deserialize(ref reader, options); - } - - public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options) - { - if (value != null) - { - JsonSerializer.Serialize(writer, (TImplementation)value, options); - } - else - { - writer.WriteNullValue(); - } - } - } -} diff --git a/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs b/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs index c0501fdf..65ea5d96 100644 --- a/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs +++ b/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs @@ -15,7 +15,6 @@ //. using AudioCuesheetEditor.Model.Entity; using AudioCuesheetEditor.Model.IO.Audio; -using AudioCuesheetEditor.Model.IO.Export; using AudioCuesheetEditor.Model.UI; using System.Text.Json.Serialization; @@ -39,11 +38,10 @@ public class Cuesheet() : Validateable, ITraceable, ICuesheet private List tracks = []; private String? artist; private String? title; - private IAudiofile? audiofile; + private Audiofile? audiofile; private CDTextfile? cDTextfile; private String? catalogueNumber; private readonly List> currentlyHandlingLinkedTrackPropertyChange = []; - private List sections = []; public event EventHandler? TraceablePropertyChanged; public event EventHandler? IsRecordingChanged; @@ -91,7 +89,7 @@ public String? Title FireEvents(previousValue, propertyName: nameof(Title)); } } - public IAudiofile? Audiofile + public Audiofile? Audiofile { get => audiofile; set @@ -151,42 +149,6 @@ public IEnumerable IsRecordingPossible [JsonIgnore] public Boolean IsImporting { get; set; } - - [JsonInclude] - public IReadOnlyCollection Sections - { - get => sections; - private set - { - foreach(var section in value.Where(x => x.Cuesheet != this)) - { - section.Cuesheet = this; - } - sections = [.. value]; - } - } - - public CuesheetSection AddSection() - { - var previousValue = new List(sections); - var section = new CuesheetSection(this); - sections.Add(section); - OnTraceablePropertyChanged(previousValue, nameof(Sections)); - return section; - } - - public void RemoveSections(IEnumerable sectionsToRemove) - { - var previousValue = new List(sections); - var intersection = sections.Intersect(sectionsToRemove); - sections = [.. sections.Except(intersection)]; - OnTraceablePropertyChanged(previousValue, nameof(Sections)); - } - - public CuesheetSection? GetSection(Track track) - { - return Sections?.FirstOrDefault(x => track.Begin <= x.Begin && track.End >= x.Begin); - } /// /// Get the previous linked track of a track object @@ -484,7 +446,7 @@ public override ValidationResult Validate(string property) private void RecalculateTrackProperties(Track trackToCalculate) { - if ((Audiofile != null) && (Audiofile.Duration.HasValue) && (trackToCalculate.End.HasValue == false)) + if ((Audiofile?.Duration.HasValue == true) && (trackToCalculate.End.HasValue == false)) { trackToCalculate.End = Audiofile.Duration; } diff --git a/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs b/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs index c61e7a63..ebee7f8d 100644 --- a/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs +++ b/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs @@ -18,7 +18,7 @@ namespace AudioCuesheetEditor.Model.IO.Audio { [method: JsonConstructor] - public class Audiofile(String name) : IDisposable, IAudiofile + public class Audiofile(String name) { public static readonly AudioCodec AudioCodecWEBM = new("audio/webm", ".webm", "AudioCodec WEBM"); @@ -35,13 +35,9 @@ public class Audiofile(String name) : IDisposable, IAudiofile ]; private AudioCodec? audioCodec; - private Stream? contentStream; private String name = name; - private bool disposedValue; - public event EventHandler? ContentStreamLoaded; - - public Audiofile(String name, String objectURL, AudioCodec? audioCodec) : this(name) + public Audiofile(String name, String objectURL, AudioCodec? audioCodec, TimeSpan? duration = null) : this(name) { if (String.IsNullOrEmpty(objectURL)) { @@ -49,6 +45,7 @@ public Audiofile(String name, String objectURL, AudioCodec? audioCodec) : this(n } ObjectURL = objectURL; AudioCodec = audioCodec; + Duration = duration; } public String Name @@ -71,32 +68,6 @@ public String Name [JsonIgnore] public String? ObjectURL { get; private set; } /// - /// Boolean indicating if the stream has fully been loaded - /// - [JsonIgnore] - public Boolean IsContentStreamLoaded - { - get { return ContentStream != null; } - } - /// - /// File content stream. Be carefully, this stream is loaded asynchronously. Connect to the StreamLoaded for checking if loading has already been done! - /// - [JsonIgnore] - public Stream? ContentStream - { - get => contentStream; - set - { - contentStream = value; - if ((ContentStream != null) && (AudioCodec != null)) - { - var track = new ATL.Track(ContentStream, AudioCodec.MimeType); - Duration = new TimeSpan(0, 0, track.Duration); - ContentStreamLoaded?.Invoke(this, EventArgs.Empty); - } - } - } - /// /// Duration of the audio file /// public TimeSpan? Duration { get; private set; } @@ -144,30 +115,5 @@ public Boolean PlaybackPossible return playbackPossible; } } - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - if (ContentStream != null) - { - ContentStream.Close(); - ContentStream.Dispose(); - ContentStream = null; - } - } - - 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/Model/IO/Audio/IAudiofile.cs b/AudioCuesheetEditor/Model/IO/Audio/IAudiofile.cs deleted file mode 100644 index 456fd475..00000000 --- a/AudioCuesheetEditor/Model/IO/Audio/IAudiofile.cs +++ /dev/null @@ -1,31 +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 -//. -namespace AudioCuesheetEditor.Model.IO.Audio -{ - public interface IAudiofile - { - AudioCodec? AudioCodec { get; } - string? AudioFileType { get; } - Stream? ContentStream { get; set; } - TimeSpan? Duration { get; } - bool IsContentStreamLoaded { get; } - string Name { get; set; } - string? ObjectURL { get; } - bool PlaybackPossible { get; } - - event EventHandler? ContentStreamLoaded; - } -} \ No newline at end of file diff --git a/AudioCuesheetEditor/Model/IO/Export/CuesheetSection.cs b/AudioCuesheetEditor/Model/IO/Export/CuesheetSection.cs deleted file mode 100644 index 534b65d3..00000000 --- a/AudioCuesheetEditor/Model/IO/Export/CuesheetSection.cs +++ /dev/null @@ -1,217 +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.Model.AudioCuesheet; -using AudioCuesheetEditor.Model.Entity; -using AudioCuesheetEditor.Model.UI; -using System.Text.Json.Serialization; - -namespace AudioCuesheetEditor.Model.IO.Export -{ - public class CuesheetSection : Validateable, ITraceable - { - private Cuesheet? cuesheet; - private TimeSpan? begin; - private TimeSpan? end; - private String? artist; - private String? title; - private String? audiofileName; - - public event EventHandler? TraceablePropertyChanged; - - public CuesheetSection(Cuesheet cuesheet) - { - Cuesheet = cuesheet; - artist = Cuesheet.Artist; - title = Cuesheet.Title; - audiofileName = Cuesheet.Audiofile?.Name; - //Try to set begin - begin = Cuesheet.Sections?.LastOrDefault()?.End; - if (Begin.HasValue == false) - { - begin = Cuesheet.Tracks.Min(x => x.Begin); - } - end = Cuesheet.Tracks.Max(x => x.End); - } - - [JsonConstructor] - public CuesheetSection() { } - public Cuesheet? Cuesheet - { - get => cuesheet; - set - { - if (cuesheet == null) - { - cuesheet = value; - } - else - { - throw new InvalidOperationException(); - } - } - } - - public String? Artist - { - get => artist; - set - { - var previousValue = artist; - artist = value; - OnValidateablePropertyChanged(nameof(Artist)); - OnTraceablePropertyChanged(previousValue, nameof(Artist)); - } - } - - public String? Title - { - get => title; - set - { - var previousValue = title; - title = value; - OnValidateablePropertyChanged(nameof(Title)); - OnTraceablePropertyChanged(previousValue, nameof(Title)); - } - } - - public TimeSpan? Begin - { - get => begin; - set - { - var previousValue = begin; - begin = value; - OnValidateablePropertyChanged(nameof(Begin)); - OnTraceablePropertyChanged(previousValue, nameof(Begin)); - } - } - - public TimeSpan? End - { - get => end; - set - { - var previousValue = end; - end = value; - OnValidateablePropertyChanged(nameof(End)); - OnTraceablePropertyChanged(previousValue, nameof(End)); - } - } - - public String? AudiofileName - { - get => audiofileName; - set - { - var previousValue = audiofileName; - audiofileName = value; - OnValidateablePropertyChanged(nameof(AudiofileName)); - OnTraceablePropertyChanged(previousValue, nameof(AudiofileName)); - } - } - - public void CopyValues(CuesheetSection splitPoint) - { - Artist = splitPoint.Artist; - Title = splitPoint.Title; - Begin = splitPoint.Begin; - } - - public override ValidationResult Validate(string property) - { - ValidationStatus validationStatus = ValidationStatus.NoValidation; - List? validationMessages = null; - switch (property) - { - case nameof(Begin): - validationStatus = ValidationStatus.Success; - if (Begin == null) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} has no value!", nameof(Begin))); - } - else - { - var minBegin = Cuesheet?.Tracks.Min(x => x.Begin); - if (Begin < minBegin) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} should be greater than or equal '{1}'!", nameof(Begin), minBegin)); - } - if (Begin > End) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} should be less than or equal '{1}'!", nameof(Begin), End)); - } - } - break; - case nameof(End): - validationStatus = ValidationStatus.Success; - if (End == null) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} has no value!", nameof(End))); - } - else - { - var maxEnd = Cuesheet?.Tracks.Max(x => x.End); - if (End > maxEnd) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} should be less than or equal '{1}'!", nameof(End), maxEnd)); - } - if (End < Begin) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} should be greater than or equal '{1}'!", nameof(End), Begin)); - } - } - break; - case nameof(Artist): - validationStatus = ValidationStatus.Success; - if (String.IsNullOrEmpty(Artist)) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} has no value!", nameof(Artist))); - } - break; - case nameof(Title): - validationStatus = ValidationStatus.Success; - if (String.IsNullOrEmpty(Title)) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} has no value!", nameof(Title))); - } - break; - case nameof(AudiofileName): - validationStatus = ValidationStatus.Success; - if (String.IsNullOrEmpty(AudiofileName)) - { - validationMessages ??= []; - validationMessages.Add(new ValidationMessage("{0} has no value!", nameof(AudiofileName))); - } - break; - } - return ValidationResult.Create(validationStatus, validationMessages); - } - - private void OnTraceablePropertyChanged(object? previousValue, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = "") - { - TraceablePropertyChanged?.Invoke(this, new TraceablePropertiesChangedEventArgs(new TraceableChange(previousValue, propertyName))); - } - } -} diff --git a/AudioCuesheetEditor/Model/IO/Export/Exportfile.cs b/AudioCuesheetEditor/Model/IO/Export/Exportfile.cs index e2c7baf5..c056e572 100644 --- a/AudioCuesheetEditor/Model/IO/Export/Exportfile.cs +++ b/AudioCuesheetEditor/Model/IO/Export/Exportfile.cs @@ -21,7 +21,5 @@ public class Exportfile public static readonly string DefaultCuesheetFilename = "Cuesheet.cue"; public string Name { get; set; } = String.Empty; public string? Content { get; set; } - public TimeSpan? Begin { get; set; } - public TimeSpan? End { get; set; } } } diff --git a/AudioCuesheetEditor/Model/IO/Projectfile.cs b/AudioCuesheetEditor/Model/IO/Projectfile.cs index c54dace0..c6d2617e 100644 --- a/AudioCuesheetEditor/Model/IO/Projectfile.cs +++ b/AudioCuesheetEditor/Model/IO/Projectfile.cs @@ -13,9 +13,7 @@ //You should have received a copy of the GNU General Public License //along with Foobar. If not, see //. -using AudioCuesheetEditor.Extensions; using AudioCuesheetEditor.Model.AudioCuesheet; -using AudioCuesheetEditor.Model.IO.Audio; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -32,8 +30,7 @@ public class Projectfile(Cuesheet cuesheet) ReferenceHandler = ReferenceHandler.IgnoreCycles, Converters = { - new JsonStringEnumConverter(), - new InterfaceConverter() // Add a custom converter for IAudiofile + new JsonStringEnumConverter() } }; diff --git a/AudioCuesheetEditor/Model/Options/ExportOptions.cs b/AudioCuesheetEditor/Model/Options/ExportOptions.cs index dfa267a2..3f8457ac 100644 --- a/AudioCuesheetEditor/Model/Options/ExportOptions.cs +++ b/AudioCuesheetEditor/Model/Options/ExportOptions.cs @@ -60,7 +60,7 @@ public ExportOptions() public ExportOptions(ICollection exportProfiles, Guid? selectedProfileId = null) { ExportProfiles = exportProfiles; - SelectedProfileId = selectedProfileId ?? ExportProfiles.First().Id; + SelectedProfileId = selectedProfileId ?? ExportProfiles.FirstOrDefault()?.Id; } public ICollection ExportProfiles { get; set; } [JsonIgnore] diff --git a/AudioCuesheetEditor/Services/Audio/PlaybackService.cs b/AudioCuesheetEditor/Services/Audio/PlaybackService.cs index 89f90592..b451800e 100644 --- a/AudioCuesheetEditor/Services/Audio/PlaybackService.cs +++ b/AudioCuesheetEditor/Services/Audio/PlaybackService.cs @@ -26,7 +26,7 @@ public class PlaybackService : IDisposable private readonly IHowl _howl; private int? soundId; - private IAudiofile? currentlyPlayingAudiofile; + private Audiofile? currentlyPlayingAudiofile; private Timer? updateTimer; private bool disposedValue; private readonly Lock timerLock = new(); @@ -71,7 +71,7 @@ public PlaybackService(ISessionStateContainer sessionStateContainer, IHowl howl) public async Task PlayOrPauseAsync() { //Reset if the last played audiofile is not the current one - if (currentlyPlayingAudiofile !=cuesheet.Audiofile) + if (currentlyPlayingAudiofile != cuesheet.Audiofile) { soundId = null; } diff --git a/AudioCuesheetEditor/Services/IO/CuesheetExportService.cs b/AudioCuesheetEditor/Services/IO/CuesheetExportService.cs index 835cad77..2c34ee94 100644 --- a/AudioCuesheetEditor/Services/IO/CuesheetExportService.cs +++ b/AudioCuesheetEditor/Services/IO/CuesheetExportService.cs @@ -18,15 +18,17 @@ using AudioCuesheetEditor.Model.IO; using AudioCuesheetEditor.Model.IO.Export; using AudioCuesheetEditor.Services.UI; +using Microsoft.Extensions.Localization; using System.Text; namespace AudioCuesheetEditor.Services.IO { - public class CuesheetExportService(ISessionStateContainer sessionStateContainer) + public class CuesheetExportService(ISessionStateContainer sessionStateContainer, IStringLocalizer localizer) { private readonly ISessionStateContainer _sessionStateContainer = sessionStateContainer; + private readonly IStringLocalizer _localizer = localizer; - public IEnumerable CanGenerateExportfiles(string? filename) + public Result CanGenerateExportfile(string? filename) { List validationMessages = []; var extension = Path.GetExtension(filename); @@ -37,52 +39,34 @@ public IEnumerable CanGenerateExportfiles(string? filename) } validationMessages.AddRange(_sessionStateContainer.Cuesheet.Validate().ValidationMessages); validationMessages.AddRange(_sessionStateContainer.Cuesheet.Tracks.Select(x => x.Validate()).SelectMany(x => x.ValidationMessages)); - return validationMessages; + if (validationMessages.Count != 0) + { + return Result.Failure(new Error(ErrorType.ValidationFailed, string.Join(Environment.NewLine, validationMessages.Select(x => x.GetMessageLocalized(_localizer))))); + } + return Result.Success(); } - public IReadOnlyCollection GenerateExportfiles(string? filename) + public Result GenerateExportfile(string? filename) { - List exportfiles = []; - if (!CanGenerateExportfiles(filename).Any()) + var validationResult = CanGenerateExportfile(filename); + if (validationResult.IsSuccess == false) { - if (_sessionStateContainer.Cuesheet.Sections.Count != 0) - { - var counter = 1; - string? content = null; - string? audioFileName = null; - foreach (var section in _sessionStateContainer.Cuesheet.Sections.OrderBy(x => x.Begin)) - { - audioFileName = section.AudiofileName; - if (section.Validate().Status == ValidationStatus.Success) - { - content = WriteCuesheet(audioFileName, section); - var name = string.Format("{0}({1}){2}", Path.GetFileNameWithoutExtension(filename), counter, FileExtensions.Cuesheet); - exportfiles.Add(new Exportfile() { Name = name, Content = content, Begin = section.Begin, End = section.End }); - counter++; - } - } - } - else - { - string? content = null; - var extension = Path.GetExtension(filename); - if (extension?.Equals(FileExtensions.Cuesheet, StringComparison.OrdinalIgnoreCase) == false) - { - filename = $"{filename}{FileExtensions.Cuesheet}"; - } - if (_sessionStateContainer.Cuesheet.Audiofile != null) - { - content = WriteCuesheet(_sessionStateContainer.Cuesheet.Audiofile.Name); - } - var begin = _sessionStateContainer.Cuesheet.Tracks.Min(x => x.Begin); - var end = _sessionStateContainer.Cuesheet.Tracks.Max(x => x.End); - exportfiles.Add(new Exportfile() { Name = filename!, Content = content, Begin = begin, End = end }); - } + return Result.Failure(new Error(ErrorType.ValidationFailed, validationResult.Error!.Message)); + } + string? content = null; + var extension = Path.GetExtension(filename); + if (extension?.Equals(FileExtensions.Cuesheet, StringComparison.OrdinalIgnoreCase) == false) + { + filename = $"{filename}{FileExtensions.Cuesheet}"; + } + if (_sessionStateContainer.Cuesheet.Audiofile != null) + { + content = WriteCuesheet(_sessionStateContainer.Cuesheet.Audiofile.Name); } - return exportfiles; + return Result.Success(new Exportfile() { Name = filename!, Content = content }); } - private string WriteCuesheet(string? audiofileName, CuesheetSection? section = null) + private string WriteCuesheet(string? audiofileName) { var builder = new StringBuilder(); if (string.IsNullOrEmpty(_sessionStateContainer.Cuesheet.Cataloguenumber) == false) @@ -93,14 +77,10 @@ private string WriteCuesheet(string? audiofileName, CuesheetSection? section = n { builder.AppendLine(string.Format("{0} \"{1}\"", CuesheetConstants.CuesheetCDTextfile, _sessionStateContainer.Cuesheet.CDTextfile.Name)); } - builder.AppendLine(string.Format("{0} \"{1}\"", CuesheetConstants.CuesheetTitle, section != null ? section.Title : _sessionStateContainer.Cuesheet.Title)); - builder.AppendLine(string.Format("{0} \"{1}\"", CuesheetConstants.CuesheetArtist, section != null ? section.Artist : _sessionStateContainer.Cuesheet.Artist)); + builder.AppendLine(string.Format("{0} \"{1}\"", CuesheetConstants.CuesheetTitle, _sessionStateContainer.Cuesheet.Title)); + builder.AppendLine(string.Format("{0} \"{1}\"", CuesheetConstants.CuesheetArtist, _sessionStateContainer.Cuesheet.Artist)); builder.AppendLine(string.Format("{0} \"{1}\" {2}", CuesheetConstants.CuesheetFileName, audiofileName, _sessionStateContainer.Cuesheet.Audiofile?.AudioFileType)); IEnumerable tracks = _sessionStateContainer.Cuesheet.Tracks.OrderBy(x => x.Position); - if (section != null) - { - tracks = _sessionStateContainer.Cuesheet.Tracks.Where(x => x.Begin <= section.End && x.End >= section.Begin).OrderBy(x => x.Position); - } if (tracks.Any()) { //Position and begin should always start from 0 even with splitpoints @@ -121,17 +101,6 @@ private string WriteCuesheet(string? audiofileName, CuesheetSection? section = n if (track.Begin.HasValue) { var begin = track.Begin.Value; - if (section != null && section.Begin.HasValue) - { - if (section.Begin >= track.Begin) - { - begin = TimeSpan.Zero; - } - else - { - begin = track.Begin.Value - section.Begin.Value; - } - } builder.AppendLine(string.Format("{0}{1}{2} {3:00}:{4:00}:{5:00}", CuesheetConstants.Tab, CuesheetConstants.Tab, CuesheetConstants.TrackIndex01, Math.Floor(begin.TotalMinutes), begin.Seconds, begin.Milliseconds * 75 / 1000)); } else diff --git a/AudioCuesheetEditor/Services/IO/ExportfileGenerator.cs b/AudioCuesheetEditor/Services/IO/ExportfileGenerator.cs index b6f3656b..4b1e3464 100644 --- a/AudioCuesheetEditor/Services/IO/ExportfileGenerator.cs +++ b/AudioCuesheetEditor/Services/IO/ExportfileGenerator.cs @@ -17,77 +17,53 @@ using AudioCuesheetEditor.Model.Entity; using AudioCuesheetEditor.Model.IO.Export; using AudioCuesheetEditor.Services.UI; +using Microsoft.Extensions.Localization; using System.Data; using System.Text; namespace AudioCuesheetEditor.Services.IO { - public class ExportfileGenerator(ISessionStateContainer sessionStateContainer) + public class ExportfileGenerator(ISessionStateContainer sessionStateContainer, IStringLocalizer localizer) { private readonly ISessionStateContainer _sessionStateContainer = sessionStateContainer; + private readonly IStringLocalizer _localizer = localizer; - public IEnumerable CanGenerateExportfiles(Exportprofile? exportprofile) + public Result CanGenerateExportfile(Exportprofile exportprofile) { List validationMessages = []; - if (exportprofile != null) - { - validationMessages.AddRange(exportprofile.Validate().ValidationMessages); - } - else - { - validationMessages.Add(new ValidationMessage("No exportprofile selected!")); - } + validationMessages.AddRange(exportprofile.Validate().ValidationMessages); validationMessages.AddRange(_sessionStateContainer.Cuesheet.Validate().ValidationMessages); validationMessages.AddRange(_sessionStateContainer.Cuesheet.Tracks.Select(x => x.Validate()).SelectMany(x => x.ValidationMessages)); - return validationMessages; + if (validationMessages.Count != 0) + { + return Result.Failure(new Error(ErrorType.ValidationFailed, string.Join(Environment.NewLine, validationMessages.Select(x => x.GetMessageLocalized(_localizer))))); + } + return Result.Success(); } - public IReadOnlyCollection GenerateExportfiles(Exportprofile? exportprofile) + public Result GenerateExportfile(Exportprofile exportprofile) { - List exportfiles = []; - if ((!CanGenerateExportfiles(exportprofile).Any()) && (exportprofile != null)) + var validationResult = CanGenerateExportfile(exportprofile); + if (validationResult.IsSuccess == false) { - if (_sessionStateContainer.Cuesheet.Sections.Count != 0) - { - var counter = 1; - string? content = null; - string filename = string.Empty; - string? audioFileName = null; - foreach (var section in _sessionStateContainer.Cuesheet.Sections.OrderBy(x => x.Begin)) - { - audioFileName = section.AudiofileName; - if (section.Validate().Status == ValidationStatus.Success) - { - content = WriteExport(exportprofile, audioFileName, section); - filename = string.Format("{0}({1}){2}", Path.GetFileNameWithoutExtension(exportprofile.Filename), counter, Path.GetExtension(exportprofile.Filename)); - exportfiles.Add(new Exportfile() { Name = filename, Content = content, Begin = section.Begin, End = section.End }); - counter++; - } - } - } - else - { - string? content = null; - if (_sessionStateContainer.Cuesheet.Audiofile != null) - { - content = WriteExport(exportprofile, _sessionStateContainer.Cuesheet.Audiofile.Name); - } - var begin = _sessionStateContainer.Cuesheet.Tracks.Min(x => x.Begin); - var end = _sessionStateContainer.Cuesheet.Tracks.Max(x => x.End); - exportfiles.Add(new Exportfile() { Name = exportprofile.Filename, Content = content, Begin = begin, End = end }); - } + return Result.Failure(new Error(ErrorType.ValidationFailed, validationResult.Error!.Message)); + } + string? content = null; + if (_sessionStateContainer.Cuesheet.Audiofile != null) + { + content = WriteExport(exportprofile, _sessionStateContainer.Cuesheet.Audiofile.Name); } - return exportfiles; + return Result.Success(new Exportfile() { Name = exportprofile.Filename, Content = content}); } - private string WriteExport(Exportprofile exportprofile, string? audiofileName, CuesheetSection? section = null) + private string WriteExport(Exportprofile exportprofile, string? audiofileName) { var builder = new StringBuilder(); if (exportprofile != null) { var header = exportprofile.SchemeHead - .Replace(Exportprofile.SchemeCuesheetArtist, section != null ? section.Artist : _sessionStateContainer.Cuesheet.Artist) - .Replace(Exportprofile.SchemeCuesheetTitle, section != null ? section.Title : _sessionStateContainer.Cuesheet.Title) + .Replace(Exportprofile.SchemeCuesheetArtist, _sessionStateContainer.Cuesheet.Artist) + .Replace(Exportprofile.SchemeCuesheetTitle, _sessionStateContainer.Cuesheet.Title) .Replace(Exportprofile.SchemeCuesheetAudiofile, audiofileName) .Replace(Exportprofile.SchemeCuesheetCDTextfile, _sessionStateContainer.Cuesheet.CDTextfile?.Name) .Replace(Exportprofile.SchemeCuesheetCatalogueNumber, _sessionStateContainer.Cuesheet.Cataloguenumber) @@ -96,10 +72,6 @@ private string WriteExport(Exportprofile exportprofile, string? audiofileName, C .Replace(Exportprofile.SchemeTime, DateTime.Now.ToLongTimeString()); builder.AppendLine(header); IEnumerable tracks = _sessionStateContainer.Cuesheet.Tracks.OrderBy(x => x.Position); - if (section != null) - { - tracks = _sessionStateContainer.Cuesheet.Tracks.Where(x => x.Begin <= section.End && x.End >= section.Begin).OrderBy(x => x.Position); - } if (tracks.Any()) { //Position, Begin and End should always start from 0 even with splitpoints @@ -111,18 +83,6 @@ private string WriteExport(Exportprofile exportprofile, string? audiofileName, C if (track.Begin.HasValue) { begin = track.Begin.Value; - if (section?.Begin != null) - { - if (section.Begin >= track.Begin) - { - begin = TimeSpan.Zero; - } - else - { - begin = track.Begin.Value - section.Begin.Value; - } - end = track.End - section.Begin.Value; - } } else { @@ -145,8 +105,8 @@ private string WriteExport(Exportprofile exportprofile, string? audiofileName, C } } var footer = exportprofile.SchemeFooter - .Replace(Exportprofile.SchemeCuesheetArtist, section != null ? section.Artist : _sessionStateContainer.Cuesheet.Artist) - .Replace(Exportprofile.SchemeCuesheetTitle, section != null ? section.Title : _sessionStateContainer.Cuesheet.Title) + .Replace(Exportprofile.SchemeCuesheetArtist, _sessionStateContainer.Cuesheet.Artist) + .Replace(Exportprofile.SchemeCuesheetTitle, _sessionStateContainer.Cuesheet.Title) .Replace(Exportprofile.SchemeCuesheetAudiofile, audiofileName) .Replace(Exportprofile.SchemeCuesheetCDTextfile, _sessionStateContainer.Cuesheet.CDTextfile?.Name) .Replace(Exportprofile.SchemeCuesheetCatalogueNumber, _sessionStateContainer.Cuesheet.Cataloguenumber) diff --git a/AudioCuesheetEditor/Services/IO/FileInputManager.cs b/AudioCuesheetEditor/Services/IO/FileInputManager.cs index 61cef4db..32836dc8 100644 --- a/AudioCuesheetEditor/Services/IO/FileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/FileInputManager.cs @@ -17,7 +17,6 @@ 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 @@ -83,7 +82,7 @@ public bool CheckFileMimeType(string? fileContentType, string fileName, string m return fileMimeTypeMatches; } - public async Task CreateAudiofileAsync(FileUpload fileUpload, Action>? afterContentStreamLoaded = null) + public async Task CreateAudiofileAsync(FileUpload fileUpload) { Audiofile? audiofile = null; if (fileUpload.ObjectUrl != null) @@ -92,22 +91,13 @@ public bool CheckFileMimeType(string? fileContentType, string fileName, string m var codec = GetAudioCodec(fileUpload.ContentType, fileUpload.Name); if (codec != null) { - audiofile = new Audiofile(fileUpload.Name, fileUpload.ObjectUrl, codec); + TimeSpan? duration = null; if (String.IsNullOrEmpty(fileUpload.ObjectUrl) == false) { - var request = new HttpRequestMessage(HttpMethod.Get, fileUpload.ObjectUrl); - //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) - { - _ = loadContentStreamTask - .ContinueWith(afterContentStreamLoaded); - } + var durationSeconds = await _jsRuntime.InvokeAsync("getAudioDurationFromFile", fileUpload.ObjectUrl); + duration = TimeSpan.FromSeconds(durationSeconds); } + audiofile = new Audiofile(fileUpload.Name, fileUpload.ObjectUrl, codec, duration); } else { diff --git a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs index 026ed5d4..f79f88a0 100644 --- a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs @@ -34,7 +34,7 @@ public interface IFileInputManager /// /// bool CheckFileMimeType(string? fileContentType, string fileName, string mimeType, IEnumerable fileExtensions); - Task CreateAudiofileAsync(FileUpload fileUpload, Action>? afterContentStreamLoaded = null); + Task CreateAudiofileAsync(FileUpload fileUpload); CDTextfile? CreateCDTextfile(string? fileContentType, string fileName); /// /// Checks if the file can be used for the import view diff --git a/AudioCuesheetEditor/Services/IO/ImportManager.cs b/AudioCuesheetEditor/Services/IO/ImportManager.cs index 6817670f..adeabb5e 100644 --- a/AudioCuesheetEditor/Services/IO/ImportManager.cs +++ b/AudioCuesheetEditor/Services/IO/ImportManager.cs @@ -19,7 +19,6 @@ using AudioCuesheetEditor.Model.IO.Audio; using AudioCuesheetEditor.Model.IO.Import; using AudioCuesheetEditor.Services.UI; -using Microsoft.AspNetCore.Components.Forms; using System.Diagnostics; namespace AudioCuesheetEditor.Services.IO @@ -188,12 +187,6 @@ private static void CopyCuesheet(Cuesheet target, ICuesheet cuesheetToCopy) if (cuesheetToCopy is Cuesheet originCuesheet) { tracks = originCuesheet.Tracks; - // Copy sections - foreach (var section in originCuesheet.Sections) - { - var newSplitPoint = target.AddSection(); - newSplitPoint.CopyValues(section); - } target.Audiofile = originCuesheet.Audiofile; target.CDTextfile = originCuesheet.CDTextfile; target.Cataloguenumber = originCuesheet.Cataloguenumber; diff --git a/AudioCuesheetEditor/Services/Result.cs b/AudioCuesheetEditor/Services/Result.cs new file mode 100644 index 00000000..da870084 --- /dev/null +++ b/AudioCuesheetEditor/Services/Result.cs @@ -0,0 +1,117 @@ +//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 +//. +namespace AudioCuesheetEditor.Services +{ + /// + /// Defines types of errors + /// + public enum ErrorType + { + /// + /// Validation failed with error + /// + ValidationFailed + } + + /// + /// Represents an error of an service + /// + public class Error(ErrorType type, string message) + { + /// + /// Type of error + /// + public ErrorType Type { get; } = type; + /// + /// The error message + /// + public string Message { get; } = message; + } + + /// + /// Indicates a service result + /// + public class Result + { + /// + /// Indicates if the result was successful + /// + public bool IsSuccess { get; } + /// + /// The error if one occurred + /// + public Error? Error { get; } + + /// + /// Private constructor + /// + protected Result() + { + IsSuccess = true; + } + + /// + /// Private constructor + /// + protected Result(Error error) + { + IsSuccess = false; + Error = error; + } + /// + /// Creates a success result + /// + /// + public static Result Success() => new(); + /// + /// Creates a failure result + /// + /// + /// + public static Result Failure(Error error) => new(error); + } + + /// + /// Represent the result of a service + /// + /// + public class Result : Result + { + /// + /// The result value + /// + public T? Value { get; } + + private Result(T value) : base() + { + Value = value; + } + + private Result(Error error) : base(error) { } + /// + /// Creates a success result + /// + /// + /// + public static Result Success(T value) => new(value); + /// + /// Creates a failure result + /// + /// + /// + public static new Result Failure(Error error) => new(error); + } +} diff --git a/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor b/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor index 61605a5a..cc0cf4eb 100644 --- a/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor +++ b/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor @@ -114,14 +114,11 @@ along with Foobar. If not, see if (browserFile != null) { var fileUpload = await _fileInputManager.CreateFileUploadsAsync([browserFile], fileInputAudiofileId); - Cuesheet.Audiofile = await _fileInputManager.CreateAudiofileAsync(fileUpload.Single(), x => + Cuesheet.Audiofile = await _fileInputManager.CreateAudiofileAsync(fileUpload.Single()); + if (Cuesheet.RecalculateLastTrackEnd()) { - if (Cuesheet.RecalculateLastTrackEnd()) - { - TraceChangeManager.MergeLastEditWithEdit(x => x.Changes.All(y => y.TraceableObject == Cuesheet && y.TraceableChange.PropertyName == nameof(Audiofile))); - } - StateHasChanged(); - }); + TraceChangeManager.MergeLastEditWithEdit(x => x.Changes.All(y => y.TraceableObject == Cuesheet && y.TraceableChange.PropertyName == nameof(Audiofile))); + } } else { diff --git a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.de.resx b/AudioCuesheetEditor/Shared/Cuesheet/EditSections.de.resx deleted file mode 100644 index e7321fc5..00000000 --- a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.de.resx +++ /dev/null @@ -1,150 +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 - - - Neue Sektion hinzufügen - - - Sind Sie sicher, dass Sie alle Abschnitte entfernen möchten? - - - Audiodatei - - - Start - - - Bestätigen - - - Cuesheet Künstler - - - Cuesheet Titel - - - Alle Abschnitte löschen - - - Ausgewählte Abschnitte löschen - - - Ende - - \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor b/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor deleted file mode 100644 index 2c998de5..00000000 --- a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.razor +++ /dev/null @@ -1,154 +0,0 @@ - -@inherits BaseLocalizedComponent - -@inject IStringLocalizer _localizer -@inject ApplicationOptionsTimeSpanParser _applicationOptionsTimeSpanParser -@inject ValidationService _validationService -@inject IDialogService _dialogService -@inject IFileInputManager _fileInputManager -@inject ISessionStateContainer _sessionStateContainer - - - - - - - - @_localizer["Delete selected sections"] - - - - - - - - @_localizer["Delete all sections"] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - x.MimeType))" - DisplayMenu="false" /> - - - - - -@code { - HashSet selectedSections = new(); - - [CascadingParameter] - public ViewMode CurrentViewMode { get; set; } - - public Cuesheet? Cuesheet - { - get - { - if (CurrentViewMode == ViewMode.ImportView) - { - return _sessionStateContainer.ImportCuesheet; - } - return _sessionStateContainer.Cuesheet; - } - } - - void AddSectionClicked() - { - if (Cuesheet != null) - { - var section = Cuesheet.AddSection(); - TraceChangeManager.TraceChanges(section); - } - } - - String? GetValidationErrorMessage(object model, string propertyName) - { - String? validationErrorMessage = null; - var validationMessages = _validationService.Validate(model, propertyName); - if (validationMessages.Count() > 0) - { - validationErrorMessage = String.Join(Environment.NewLine, validationMessages); - } - return validationErrorMessage; - } - - void DeleteSelectedSections() - { - Cuesheet?.RemoveSections(selectedSections); - selectedSections.Clear(); - } - - async Task DeleteAllSections() - { - var parameters = new DialogParameters - { - { x => x.ConfirmText, _localizer["Are you sure you want to remove all sections?"] }, - }; - var dialog = await _dialogService.ShowAsync(_localizer["Confirm"], parameters); - var result = await dialog.Result; - if (result?.Canceled == false) - { - Cuesheet?.RemoveSections(Cuesheet.Sections); - selectedSections.Clear(); - } - } - - void AudiofileSelected(CuesheetSection section, IBrowserFile? browserFile) - { - if ((browserFile != null) && (_fileInputManager.IsValidAudiofile(browserFile.ContentType, browserFile.Name) == true)) - { - section.AudiofileName = browserFile?.Name; - } - else - { - section.AudiofileName = null; - } - } -} diff --git a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.resx b/AudioCuesheetEditor/Shared/Cuesheet/EditSections.resx deleted file mode 100644 index c8ddb59e..00000000 --- a/AudioCuesheetEditor/Shared/Cuesheet/EditSections.resx +++ /dev/null @@ -1,150 +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 - - - Add new section - - - Are you sure you want to remove all sections? - - - Audio file - - - Begin - - - Confirm - - - Cuesheet artist - - - Cuesheet title - - - Delete all sections - - - Delete selected sections - - - End - - \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.de.resx b/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.de.resx index be1422e4..a8dca8e8 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.de.resx +++ b/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.de.resx @@ -126,12 +126,6 @@ Name - - Beginn - - - Ende - Inhalt diff --git a/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.razor b/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.razor index bf701eee..374ef511 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.razor +++ b/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.razor @@ -18,7 +18,6 @@ along with Foobar. If not, see @inherits BaseLocalizedComponent @inject IStringLocalizer _localizer -@inject IStringLocalizer _validationMessageLocalizer @inject ValidationService _validationService @inject IBlazorDownloadFileService _blazorDownloadFileService @inject CuesheetExportService _cuesheetExportService @@ -32,20 +31,16 @@ along with Foobar. If not, see @((MarkupString)GetGenerationValidationMessages()!) } -
- + @_localizer["Name"] - @_localizer["Begin"] - @_localizer["End"] @_localizer["Content"] @context.Name - @context.Begin - @context.End @{ var ariaLabel = $"Download-{context.Name}"; @@ -57,15 +52,21 @@ along with Foobar. If not, see @code { - IEnumerable exportfiles = []; - DownloadOptions? options; + //TODO: Get validation messages only once during rendering and use the reference for better performance + //TODO: Will be a single file when #548 gets done + IEnumerable _exportfiles = []; + DownloadOptions? _options; protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - options = await base.LocalStorageOptionsProvider.GetOptionsAsync(); + _options = await base.LocalStorageOptionsProvider.GetOptionsAsync(); base.LocalStorageOptionsProvider.OptionSaved += LocalStorageOptionsProvider_OptionSaved; - exportfiles = _cuesheetExportService.GenerateExportfiles(options?.CuesheetFilename); + var result = _cuesheetExportService.GenerateExportfile(_options?.CuesheetFilename); + if (result.IsSuccess) + { + _exportfiles = [result.Value!]; + } } protected override void Dispose(bool disposing) @@ -77,9 +78,9 @@ along with Foobar. If not, see String? GetValidationErrorMessage() { String? validationErrorMessage = null; - if (options != null) + if (_options != null) { - var validationMessages = _validationService.Validate(options, nameof(DownloadOptions.CuesheetFilename)); + var validationMessages = _validationService.Validate(_options, nameof(DownloadOptions.CuesheetFilename)); if (validationMessages.Count() > 0) { validationErrorMessage = String.Join(Environment.NewLine, validationMessages); @@ -91,10 +92,10 @@ along with Foobar. If not, see String? GetGenerationValidationMessages() { String? validationErrorMessage = null; - var messages = _cuesheetExportService.CanGenerateExportfiles(options?.CuesheetFilename); - if (messages.Count() > 0) + var result = _cuesheetExportService.CanGenerateExportfile(_options?.CuesheetFilename); + if (result.IsSuccess == false) { - validationErrorMessage = String.Join("
", messages.Select(x => x.GetMessageLocalized(_validationMessageLocalizer))); + validationErrorMessage = result.Error?.Message.Replace(Environment.NewLine, "
"); } return validationErrorMessage; } @@ -102,14 +103,18 @@ along with Foobar. If not, see async Task CuesheetFilenameChanged(string newFilename) { await LocalStorageOptionsProvider.SaveOptionsValueAsync(x => x.CuesheetFilename, newFilename); - exportfiles = _cuesheetExportService.GenerateExportfiles(options?.CuesheetFilename); + var result = _cuesheetExportService.GenerateExportfile(_options?.CuesheetFilename); + if (result.IsSuccess) + { + _exportfiles = [result.Value!]; + } } void LocalStorageOptionsProvider_OptionSaved(object? sender, IOptions option) { if (option is DownloadOptions downloadOptions) { - options = downloadOptions; + _options = downloadOptions; StateHasChanged(); } } diff --git a/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.resx b/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.resx index fd4c9fa2..15cfd0b9 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.resx +++ b/AudioCuesheetEditor/Shared/Dialogs/GenerateCuesheetDialog.resx @@ -126,12 +126,6 @@ Name - - Begin - - - End - Content diff --git a/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.de.resx b/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.de.resx index 29747256..13c2296c 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.de.resx +++ b/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.de.resx @@ -132,9 +132,6 @@ Ausgewähltes Exportprofil löschen - - Name - Geben Sie hier den Namen für dieses Profil ein @@ -168,15 +165,6 @@ Export herunterladen - - Beginn - - - Ende - - - Inhalt - Künstler @@ -216,7 +204,7 @@ Nachlücke - - Inhalt anzeigen + + Kein Exportprofil ausgewählt! \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.razor b/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.razor index c8d8da7f..7444765e 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.razor +++ b/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.razor @@ -18,7 +18,6 @@ along with Foobar. If not, see @inherits BaseLocalizedComponent @inject IStringLocalizer _localizer -@inject IStringLocalizer _validationMessageLocalizer @inject ValidationService _validationService @inject ExportfileGenerator _exportfileGenerator @inject IBlazorDownloadFileService _blazorDownloadFileService @@ -121,42 +120,7 @@ along with Foobar. If not, see - @if (_exportFiles.Count() == 1) - { - var exportFile = _exportFiles.Single(); - - } - else - { - - - @_localizer["Name"] - @_localizer["Begin"] - @_localizer["End"] - @_localizer["Content"] - - - @context.Name - @context.Begin - @context.End - @{ - var ariaLabelDownload = $"Download-{context.Name}"; - var ariaLabelDialog = $"Dialog-{context.Name}"; - var dialogVisible = _displayContentDialogVisible.GetValueOrDefault(context); - - @_localizer["Display content"] - - - - - - - - - } - - - } + @@ -165,7 +129,7 @@ along with Foobar. If not, see @code { ExportOptions? _exportOptions; - IEnumerable _exportFiles = []; + Exportfile? _exportFile; Boolean _configureExportCompleted = false; MudMenu? _schemeHeadMenu, _schemeTracksMenu, _schemeFooterMenu; Dictionary _displayContentDialogVisible = new(); @@ -218,10 +182,18 @@ along with Foobar. If not, see String? GetGenerationValidationMessages() { String? validationErrorMessage = null; - var messages = _exportfileGenerator.CanGenerateExportfiles(_exportOptions?.SelectedExportProfile); - if (messages.Count() > 0) + var selectedExportProfile = _exportOptions?.SelectedExportProfile; + if (selectedExportProfile != null) + { + var result = _exportfileGenerator.CanGenerateExportfile(selectedExportProfile); + if (result.IsSuccess == false) + { + validationErrorMessage = result.Error?.Message.Replace(Environment.NewLine, "
"); + } + } + else { - validationErrorMessage = String.Join("
", messages.Select(x => x.GetMessageLocalized(_validationMessageLocalizer))); + validationErrorMessage = _localizer["No export profile selected!"]; } return validationErrorMessage; } @@ -237,10 +209,15 @@ along with Foobar. If not, see void ActiveIndexChanged(int newIndex) { - if (newIndex == 1) + if (newIndex == 1) { - _exportFiles = _exportfileGenerator.GenerateExportfiles(_exportOptions?.SelectedExportProfile); - _configureExportCompleted = _exportFiles.Any(); + var selectedExportProfile = _exportOptions?.SelectedExportProfile; + if (selectedExportProfile != null) + { + var result = _exportfileGenerator.GenerateExportfile(selectedExportProfile); + _exportFile = result.Value; + _configureExportCompleted = result.IsSuccess; + } } } diff --git a/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.resx b/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.resx index b44b5523..d3274d80 100644 --- a/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.resx +++ b/AudioCuesheetEditor/Shared/Dialogs/GenerateExportDialog.resx @@ -132,9 +132,6 @@ Delete selected export profile - - Name - Enter the name for this profile here @@ -168,15 +165,6 @@ Download export - - Begin - - - End - - - Content - Artist @@ -216,7 +204,7 @@ PostGap - - Display content + + No export profile selected! \ No newline at end of file diff --git a/AudioCuesheetEditor/Shared/TrackList/TrackList.de.resx b/AudioCuesheetEditor/Shared/TrackList/TrackList.de.resx index c780f878..241c5171 100644 --- a/AudioCuesheetEditor/Shared/TrackList/TrackList.de.resx +++ b/AudioCuesheetEditor/Shared/TrackList/TrackList.de.resx @@ -138,9 +138,6 @@ Länge - - Ein Abschnitt beginnt innerhalb dieses Titels - Wiedergabe dieses Titel starten @@ -156,9 +153,6 @@ Status - - Abschnitt - Track von vorherigem abkoppeln diff --git a/AudioCuesheetEditor/Shared/TrackList/TrackList.razor b/AudioCuesheetEditor/Shared/TrackList/TrackList.razor index a445f42b..912fc315 100644 --- a/AudioCuesheetEditor/Shared/TrackList/TrackList.razor +++ b/AudioCuesheetEditor/Shared/TrackList/TrackList.razor @@ -110,12 +110,6 @@ along with Foobar. If not, see