From 6138c693bfd76eaf06d26862ef1b459e2c66634e Mon Sep 17 00:00:00 2001 From: Alex <15199219+muskit@users.noreply.github.com> Date: Thu, 28 Aug 2025 22:54:00 -0700 Subject: [PATCH] refine functionality of UI so far --- src/Data/Song/Song.cs | 4 +- src/ExportOperation/Exporter.cs | 2 +- src/UI/Views/Export/Export.axaml.cs | 61 +++++++++++++++++------------ 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/Data/Song/Song.cs b/src/Data/Song/Song.cs index 20d8f95..01ae2d6 100644 --- a/src/Data/Song/Song.cs +++ b/src/Data/Song/Song.cs @@ -76,8 +76,8 @@ public class Song e.Reading = Rubi; e.Artist = Artist; e.BpmMessage = BpmMessage; - e.PreviewBegin = PreviewTime; - e.PreviewLength = PreviewLen; + e.PreviewBegin = PreviewTime*1000f; + e.PreviewLength = PreviewLen*1000f; e.ClearThreshold = clearThreshold; e.Difficulty = diff; e.Level = l.Value.Item1; diff --git a/src/ExportOperation/Exporter.cs b/src/ExportOperation/Exporter.cs index 78fc5d8..c965bbc 100644 --- a/src/ExportOperation/Exporter.cs +++ b/src/ExportOperation/Exporter.cs @@ -88,7 +88,7 @@ public class Exporter /// JACKET /// if (song.Jacket != null) - File.Copy(song.Jacket, Path.Combine(exportSongPath, "jacket.png")); + File.Copy(song.Jacket, Path.Combine(exportSongPath, "jacket.png"), true); return new ExportResult { status = ExportResult.Status.Failed, message = "Unimplemented" }; } diff --git a/src/UI/Views/Export/Export.axaml.cs b/src/UI/Views/Export/Export.axaml.cs index 80eaabb..867704c 100644 --- a/src/UI/Views/Export/Export.axaml.cs +++ b/src/UI/Views/Export/Export.axaml.cs @@ -30,7 +30,6 @@ public partial class ExportRow : ObservableObject { private static Dictionary StatusImgs = new() { - { ExportStatus.NotStarted, null }, { ExportStatus.Working, new Bitmap(Utils.AssetPath("imgs/status/indeterminate_spinner.png")) }, { ExportStatus.Error, new Bitmap(Utils.AssetPath("imgs/status/task_error.png")) }, { ExportStatus.Finished, new Bitmap(Utils.AssetPath("imgs/status/task_complete.png")) }, @@ -40,16 +39,31 @@ public partial class ExportRow : ObservableObject [ObservableProperty] private IImage? statusImg = null; public required Song Song { get; set; } - public void SetStatus(ExportStatus status) - { - StatusImg = StatusImgs[status]; - } + public ExportStatus Status { set => StatusImg = StatusImgs.GetValueOrDefault(value, null); } } public partial class Export : Panel { public ObservableCollection Rows { get; } = new(); + private bool _exporting = false; + private bool Exporting + { + get => _exporting; + set + { + _exporting = value; + Dispatcher.UIThread.Invoke(() => + { + BtnExport.IsEnabled = !value; + ExportOptionsPane.IsEnabled = !value; + MainWindow.Instance!.TabSelection.IsEnabled = !value; + ExportSelectionPane.IsEnabled = !value; + }); + } + } + + public Export() { InitializeComponent(); @@ -98,6 +112,8 @@ public partial class Export : Panel private void UpdateRows() { + if (Exporting) return; + Console.WriteLine("Updating rows!"); Rows.Clear(); @@ -118,6 +134,8 @@ public partial class Export : Panel /// private void UpdateUIConditions() { + if (Exporting) return; + ListSelectAudioConvertFormat.IsEnabled = (bool)RadioShouldAudioConvert.IsChecked!; BtnExport.IsEnabled = @@ -134,7 +152,6 @@ public partial class Export : Panel ); var ffmpegAvail = Utils.IsFFMpegAvailable(); - Console.WriteLine($"FFMpeg available: {ffmpegAvail}"); if (!ffmpegAvail) RadioLeaveAudioWAV.IsChecked = true; RadioLeaveAudioWAV.IsEnabled = ffmpegAvail; @@ -142,25 +159,13 @@ public partial class Export : Panel NoFFMpegMessage.IsVisible = !ffmpegAvail; } - private void UIExportingMode(bool isExporting) - { - Dispatcher.UIThread.Invoke(() => - { - BtnExport.IsEnabled = !isExporting; - ExportOptionsPane.IsEnabled = !isExporting; - MainWindow.Instance!.TabSelection.IsEnabled = !isExporting; - ExportSelectionPane.IsEnabled = !isExporting; - }); - } - private async void ExportFlow() { - UIExportingMode(true); - + Exporting = true; var path = await Utils.BeginDirSelection("Choose your export path...", Settings.I!.ExportPath); if (string.IsNullOrEmpty(path)) { - UIExportingMode(false); + Exporting = false; return; } Settings.I!.ExportPath = path; @@ -182,18 +187,24 @@ public partial class Export : Panel }; }); + // Reset statuses + Dispatcher.UIThread.Invoke(() => Rows.ToList().ForEach(row => row.Status = ExportStatus.NotStarted)); + // process each song in parallel (for audio conversion) - Parallel.ForEach( + // TODO: cancellable? + await Parallel.ForEachAsync( Rows, new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Settings.I!.ConcurrentExports) }, - async row => + async (row, cancelToken) => { - await Dispatcher.UIThread.InvokeAsync(() => row.SetStatus(ExportStatus.Working)); + if (cancelToken.IsCancellationRequested) return; + + await Dispatcher.UIThread.InvokeAsync(() => row.Status = ExportStatus.Working); Exporter.Run(path, row.Song, options); - await Dispatcher.UIThread.InvokeAsync(() => row.SetStatus(ExportStatus.Finished)); + await Dispatcher.UIThread.InvokeAsync(() => row.Status = ExportStatus.Finished); } ); - UIExportingMode(false); + Exporting = false; } } \ No newline at end of file