diff --git a/OF DL.Core/Services/ApiService.cs b/OF DL.Core/Services/ApiService.cs index 499e18e..219d4ac 100644 --- a/OF DL.Core/Services/ApiService.cs +++ b/OF DL.Core/Services/ApiService.cs @@ -159,6 +159,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// Retrieves user information from the API. /// /// The user endpoint. + /// /// The user entity when available. public async Task GetUserInfo(string endpoint, CancellationToken cancellationToken = default) { @@ -413,6 +414,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The endpoint to query. /// Optional username context. /// The creator folder path. + /// /// A mediaId-to-URL map. public async Task?> GetMedia(MediaType mediatype, string endpoint, @@ -650,6 +652,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The creator username. /// A list to collect paid media IDs. /// Status reporter. + /// /// A paid post collection. public async Task GetPaidPosts(string endpoint, string folder, string username, @@ -832,6 +835,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The creator folder path. /// Paid post media IDs to skip. /// Status reporter. + /// /// A post collection. public async Task GetPosts(string endpoint, string folder, List paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) @@ -1021,6 +1025,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// /// The post endpoint. /// The creator folder path. + /// /// A single post collection. public async Task GetPost(string endpoint, string folder, CancellationToken cancellationToken = default) { @@ -1169,6 +1174,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The creator folder path. /// Paid post media IDs to skip. /// Status reporter. + /// /// A streams collection. public async Task GetStreams(string endpoint, string folder, List paidPostIds, @@ -1321,6 +1327,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The archived posts endpoint. /// The creator folder path. /// Status reporter. + /// /// An archived collection. public async Task GetArchived(string endpoint, string folder, IStatusReporter statusReporter, CancellationToken cancellationToken = default) @@ -1475,6 +1482,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The messages endpoint. /// The creator folder path. /// Status reporter. + /// /// A message collection. public async Task GetMessages(string endpoint, string folder, IStatusReporter statusReporter, CancellationToken cancellationToken = default) @@ -1664,6 +1672,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// /// The paid message endpoint. /// The creator folder path. + /// /// A single paid message collection. public async Task GetPaidMessage(string endpoint, string folder, CancellationToken cancellationToken = default) { @@ -1810,6 +1819,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The creator folder path. /// The creator username. /// Status reporter. + /// /// A paid message collection. public async Task GetPaidMessages(string endpoint, string folder, string username, @@ -2034,6 +2044,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// /// The purchased tab endpoint. /// Known users map. + /// /// A username-to-userId map. public async Task> GetPurchasedTabUsers(string endpoint, Dictionary users, CancellationToken cancellationToken = default) { @@ -2202,6 +2213,7 @@ public class ApiService(IAuthService authService, IConfigService configService, /// The purchased tab endpoint. /// The base download folder. /// Known users map. + /// /// A list of purchased tab collections. public async Task> GetPurchasedTab(string endpoint, string folder, Dictionary users, CancellationToken cancellationToken = default) diff --git a/OF DL.Gui/Services/AvaloniaDownloadEventHandler.cs b/OF DL.Gui/Services/AvaloniaDownloadEventHandler.cs index d0df032..8b48314 100644 --- a/OF DL.Gui/Services/AvaloniaDownloadEventHandler.cs +++ b/OF DL.Gui/Services/AvaloniaDownloadEventHandler.cs @@ -36,7 +36,7 @@ internal sealed class AvaloniaDownloadEventHandler( progressStart(description, maxValue, showSize); try { - AvaloniaProgressReporter reporter = new(progressIncrement, isCancellationRequested, cancellationToken); + AvaloniaProgressReporter reporter = new(progressIncrement, isCancellationRequested, CancellationToken); return await work(reporter); } finally diff --git a/OF DL.Gui/ViewModels/CreatorConfigEditorViewModel.cs b/OF DL.Gui/ViewModels/CreatorConfigEditorViewModel.cs index 9c6a2f4..cd30bd4 100644 --- a/OF DL.Gui/ViewModels/CreatorConfigEditorViewModel.cs +++ b/OF DL.Gui/ViewModels/CreatorConfigEditorViewModel.cs @@ -24,7 +24,8 @@ public partial class CreatorConfigEditorViewModel : ViewModelBase public void LoadFromConfig(Dictionary configs) { Rows.Clear(); - foreach (KeyValuePair kvp in configs.OrderBy(c => c.Key, StringComparer.OrdinalIgnoreCase)) + foreach (KeyValuePair kvp in configs.OrderBy(c => c.Key, + StringComparer.OrdinalIgnoreCase)) { Rows.Add(new CreatorConfigRowViewModel(kvp.Key, kvp.Value, OnDeleteRow, OnEditRow)); } @@ -37,6 +38,7 @@ public partial class CreatorConfigEditorViewModel : ViewModelBase { result[row.Username] = row.Config; } + return result; } @@ -53,24 +55,11 @@ public partial class CreatorConfigEditorViewModel : ViewModelBase private void AddCreator() { Log.Information("AddCreator command executed"); - Log.Information("ModalViewModel is null: {IsNull}", ModalViewModel == null); _editingRow = null; - if (ModalViewModel != null) - { - Log.Information("Calling ModalViewModel.OpenForAdd()"); - ModalViewModel.OpenForAdd(); - Log.Information("After OpenForAdd - Modal IsOpen: {IsOpen}", ModalViewModel.IsOpen); - } - else - { - Log.Error("ModalViewModel is null, cannot open modal"); - } + ModalViewModel.OpenForAdd(); } - private void OnDeleteRow(CreatorConfigRowViewModel row) - { - Rows.Remove(row); - } + private void OnDeleteRow(CreatorConfigRowViewModel row) => Rows.Remove(row); private void OnEditRow(CreatorConfigRowViewModel row) { diff --git a/OF DL.Gui/ViewModels/MainWindowViewModel.cs b/OF DL.Gui/ViewModels/MainWindowViewModel.cs index b03b581..5ac9b96 100644 --- a/OF DL.Gui/ViewModels/MainWindowViewModel.cs +++ b/OF DL.Gui/ViewModels/MainWindowViewModel.cs @@ -131,9 +131,9 @@ public partial class MainWindowViewModel( private AppScreen _configReturnScreen = AppScreen.Loading; private bool _isApplyingListSelection; - public ObservableCollection ConfigFields { get; } = []; + private ObservableCollection ConfigFields { get; } = []; - public ObservableCollection ConfigCategories { get; } = []; + private static ObservableCollection ConfigCategories => []; public ObservableCollection ConfigCategoriesLeft { get; } = []; @@ -224,9 +224,12 @@ public partial class MainWindowViewModel( public bool HasMediaSourcesError => !string.IsNullOrWhiteSpace(MediaSourcesError); - public string FfmpegPathDisplay => HidePrivateInfo && !string.IsNullOrWhiteSpace(FfmpegPath) ? "[Hidden for Privacy]" : FfmpegPath; + public string FfmpegPathDisplay => + HidePrivateInfo && !string.IsNullOrWhiteSpace(FfmpegPath) ? "[Hidden for Privacy]" : FfmpegPath; - public string DownloadPathDisplay => HidePrivateInfo && !string.IsNullOrWhiteSpace(DownloadPath) ? "[Hidden for Privacy]" : DownloadPath; + public string DownloadPathDisplay => HidePrivateInfo && !string.IsNullOrWhiteSpace(DownloadPath) + ? "[Hidden for Privacy]" + : DownloadPath; public string FfmpegPathHelpText => GetConfigHelpText(nameof(Config.FFmpegPath)); @@ -310,7 +313,9 @@ public partial class MainWindowViewModel( { string normalizedPath = NormalizePathForDisplay(path); _actualFfmpegPath = normalizedPath; - FfmpegPath = HidePrivateInfo && !string.IsNullOrWhiteSpace(normalizedPath) ? "[Hidden for Privacy]" : normalizedPath; + FfmpegPath = HidePrivateInfo && !string.IsNullOrWhiteSpace(normalizedPath) + ? "[Hidden for Privacy]" + : normalizedPath; FfmpegPathError = string.Empty; } @@ -318,7 +323,9 @@ public partial class MainWindowViewModel( { string normalizedPath = NormalizePathForDisplay(path); _actualDownloadPath = normalizedPath; - DownloadPath = HidePrivateInfo && !string.IsNullOrWhiteSpace(normalizedPath) ? "[Hidden for Privacy]" : normalizedPath; + DownloadPath = HidePrivateInfo && !string.IsNullOrWhiteSpace(normalizedPath) + ? "[Hidden for Privacy]" + : normalizedPath; DownloadPathError = string.Empty; } @@ -475,21 +482,7 @@ public partial class MainWindowViewModel( private void AddCreatorConfig() { Log.Information("=== AddCreatorConfig command called ==="); - Log.Information("CreatorConfigEditor is null: {IsNull}", CreatorConfigEditor == null); - if (CreatorConfigEditor != null) - { - Log.Information("CreatorConfigEditor.AddCreatorCommand is null: {IsNull}", CreatorConfigEditor.AddCreatorCommand == null); - Log.Information("ModalViewModel is null: {IsNull}", CreatorConfigEditor.ModalViewModel == null); - if (CreatorConfigEditor.ModalViewModel != null) - { - Log.Information("ModalViewModel.IsOpen before: {IsOpen}", CreatorConfigEditor.ModalViewModel.IsOpen); - } - CreatorConfigEditor.AddCreatorCommand.Execute(null); - if (CreatorConfigEditor.ModalViewModel != null) - { - Log.Information("ModalViewModel.IsOpen after: {IsOpen}", CreatorConfigEditor.ModalViewModel.IsOpen); - } - } + CreatorConfigEditor.AddCreatorCommand.Execute(null); } [RelayCommand] @@ -625,14 +618,15 @@ public partial class MainWindowViewModel( 0, false); + CancellationTokenSource cancellationSource = _workCancellationSource; AvaloniaDownloadEventHandler eventHandler = new( AppendLog, UpdateProgressStatus, StartDownloadProgress, IncrementDownloadProgress, StopDownloadProgress, - () => _workCancellationSource?.IsCancellationRequested == true, - _workCancellationSource.Token); + () => cancellationSource.IsCancellationRequested, + cancellationSource.Token); try { @@ -762,6 +756,7 @@ public partial class MainWindowViewModel( { _actualFfmpegPath = value; } + FfmpegPathError = string.Empty; } @@ -771,6 +766,7 @@ public partial class MainWindowViewModel( { _actualDownloadPath = value; } + DownloadPathError = string.Empty; } @@ -936,7 +932,7 @@ public partial class MainWindowViewModel( UpdateUserListsCollection(); UpdateIgnoredUsersListFieldOptions(); - CreatorConfigEditor?.UpdateAvailableUsers(_allUsers.Keys); + CreatorConfigEditor.UpdateAvailableUsers(_allUsers.Keys); SelectedListName = null; @@ -1100,8 +1096,8 @@ public partial class MainWindowViewModel( private void UpdateIgnoredUsersListFieldOptions() { - IEnumerable listNames = _allLists.Keys - .OrderBy(listName => listName, StringComparer.OrdinalIgnoreCase); + List listNames = _allLists.Keys + .OrderBy(listName => listName, StringComparer.OrdinalIgnoreCase).ToList(); foreach (ConfigFieldViewModel field in ConfigFields.Where(field => field.IsIgnoredUsersListField)) { @@ -1128,7 +1124,9 @@ public partial class MainWindowViewModel( string downloadPath = ResolveDownloadPathForDisplay(config.DownloadPath); _actualDownloadPath = downloadPath; - DownloadPath = HidePrivateInfo && !string.IsNullOrWhiteSpace(downloadPath) ? "[Hidden for Privacy]" : downloadPath; + DownloadPath = HidePrivateInfo && !string.IsNullOrWhiteSpace(downloadPath) + ? "[Hidden for Privacy]" + : downloadPath; ClearSpecialConfigErrors(); diff --git a/OF DL.Gui/Views/MainWindow.axaml b/OF DL.Gui/Views/MainWindow.axaml index c1928fd..230d1ee 100644 --- a/OF DL.Gui/Views/MainWindow.axaml +++ b/OF DL.Gui/Views/MainWindow.axaml @@ -3,6 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="using:OF_DL.Gui.ViewModels" + xmlns:views="using:OF_DL.Gui.Views" x:Class="OF_DL.Gui.Views.MainWindow" x:DataType="vm:MainWindowViewModel" Width="1320" @@ -85,767 +86,782 @@ - - - - - + + + + + - - - + + + - - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + +