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 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+ Text="Download Media Types" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ToolTip.Tip="{Binding HelpText}" />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ IsChecked="{Binding DownloadOnlySpecificDatesField.BoolValue, FallbackValue=False}" />
+ IsEnabled="{Binding DownloadOnlySpecificDatesField.BoolValue, FallbackValue=False}"
+ ItemsSource="{Binding DownloadDateSelectionField.EnumOptions, FallbackValue={x:Null}}"
+ SelectedItem="{Binding DownloadDateSelectionField.EnumValue, FallbackValue={x:Null}}" />
-
-
-
-
-
-
-
-
+ IsEnabled="{Binding DownloadOnlySpecificDatesField.BoolValue, FallbackValue=False}"
+ SelectedDate="{Binding CustomDateField.DateValue, FallbackValue={x:Null}}" />
+
+
+
+
+
+
+
+
+ IsChecked="{Binding LimitDownloadRateField.BoolValue, FallbackValue=False}" />
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ IsChecked="{Binding FolderPerPaidPostField.BoolValue, FallbackValue=False}" />
+ IsChecked="{Binding FolderPerPostField.BoolValue, FallbackValue=False}" />
+ IsChecked="{Binding FolderPerPaidMessageField.BoolValue, FallbackValue=False}" />
+ IsChecked="{Binding FolderPerMessageField.BoolValue, FallbackValue=False}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OF DL.Gui/Views/MainWindow.axaml.cs b/OF DL.Gui/Views/MainWindow.axaml.cs
index 236253d..ba9789e 100644
--- a/OF DL.Gui/Views/MainWindow.axaml.cs
+++ b/OF DL.Gui/Views/MainWindow.axaml.cs
@@ -11,6 +11,7 @@ namespace OF_DL.Gui.Views;
public partial class MainWindow : Window
{
private bool _hasInitialized;
+ public MainWindowViewModel? ViewModel => DataContext as MainWindowViewModel;
public MainWindow()
{