Improve help text on config page

This commit is contained in:
whimsical-c4lic0 2026-02-26 19:10:52 -06:00
parent bb04e0518a
commit 2a727c7121
4 changed files with 62 additions and 107 deletions

View File

@ -5,6 +5,12 @@ namespace OF_DL.Gui.ViewModels;
public sealed class ConfigCategoryViewModel : ViewModelBase public sealed class ConfigCategoryViewModel : ViewModelBase
{ {
private const string SpecificDateFilterOptionHelpText =
"Downloads posts (does not apply to messages) before or after the chosen date.";
private const string FolderStructureOptionHelpText =
"Choose which content types get separate folders, including unlocked PPV posts and messages.";
public ConfigCategoryViewModel(string categoryName, IEnumerable<ConfigFieldViewModel> fields) public ConfigCategoryViewModel(string categoryName, IEnumerable<ConfigFieldViewModel> fields)
{ {
CategoryName = categoryName; CategoryName = categoryName;
@ -111,29 +117,7 @@ public sealed class ConfigCategoryViewModel : ViewModelBase
FolderPerPaidMessageField != null && FolderPerPaidMessageField != null &&
FolderPerMessageField != null; FolderPerMessageField != null;
public string SpecificDateFilterHelpText public string SpecificDateFilterHelpText => SpecificDateFilterOptionHelpText;
{
get
{
List<string> parts = [];
if (!string.IsNullOrWhiteSpace(DownloadOnlySpecificDatesField?.HelpText))
{
parts.Add(DownloadOnlySpecificDatesField.HelpText);
}
if (!string.IsNullOrWhiteSpace(DownloadDateSelectionField?.HelpText))
{
parts.Add(DownloadDateSelectionField.HelpText);
}
if (!string.IsNullOrWhiteSpace(CustomDateField?.HelpText))
{
parts.Add(CustomDateField.HelpText);
}
return string.Join(" ", parts.Distinct(StringComparer.Ordinal));
}
}
public string RateLimitHelpText public string RateLimitHelpText
{ {
@ -154,34 +138,7 @@ public sealed class ConfigCategoryViewModel : ViewModelBase
} }
} }
public string FolderStructureHelpText public string FolderStructureHelpText => FolderStructureOptionHelpText;
{
get
{
List<string> parts = [];
if (!string.IsNullOrWhiteSpace(FolderPerPaidPostField?.HelpText))
{
parts.Add(FolderPerPaidPostField.HelpText);
}
if (!string.IsNullOrWhiteSpace(FolderPerPostField?.HelpText))
{
parts.Add(FolderPerPostField.HelpText);
}
if (!string.IsNullOrWhiteSpace(FolderPerPaidMessageField?.HelpText))
{
parts.Add(FolderPerPaidMessageField.HelpText);
}
if (!string.IsNullOrWhiteSpace(FolderPerMessageField?.HelpText))
{
parts.Add(FolderPerMessageField.HelpText);
}
return string.Join(" ", parts.Distinct(StringComparer.Ordinal));
}
}
public bool HasSpecificDateFilterHelpText => !string.IsNullOrWhiteSpace(SpecificDateFilterHelpText); public bool HasSpecificDateFilterHelpText => !string.IsNullOrWhiteSpace(SpecificDateFilterHelpText);

View File

@ -99,10 +99,7 @@ public partial class ConfigFieldViewModel : ViewModelBase
} }
SelectedFileNameVariable = AvailableFileNameVariables.FirstOrDefault(); SelectedFileNameVariable = AvailableFileNameVariables.FirstOrDefault();
string availableVariables = const string fileNameHelpText = "Include {mediaId} or {filename} to avoid filename collisions.";
string.Join(", ", AvailableFileNameVariables.Select(variable => $"{{{variable}}}"));
string fileNameHelpText =
$"Available variables: {availableVariables}. Include {{mediaId}} or {{filename}} to avoid collisions.";
HelpText = string.IsNullOrWhiteSpace(HelpText) HelpText = string.IsNullOrWhiteSpace(HelpText)
? fileNameHelpText ? fileNameHelpText
: $"{HelpText} {fileNameHelpText}"; : $"{HelpText} {fileNameHelpText}";

View File

@ -78,88 +78,88 @@ public partial class MainWindowViewModel(
private static readonly Dictionary<string, string> s_configHelpTextByProperty = new(StringComparer.Ordinal) private static readonly Dictionary<string, string> s_configHelpTextByProperty = new(StringComparer.Ordinal)
{ {
[nameof(Config.FFmpegPath)] = [nameof(Config.FFmpegPath)] =
"Path to the FFmpeg executable. If blank, OF-DL will try the app directory and PATH.", "Path to the FFmpeg executable. Leave blank to auto-detect from the app folder or PATH.",
[nameof(Config.FFprobePath)] = [nameof(Config.FFprobePath)] =
"Path to the FFprobe executable. If blank, OF-DL will try FFmpeg's directory, the app directory, and PATH.", "Path to the FFprobe executable. Leave blank to auto-detect from FFmpeg's folder, the app folder, or PATH.",
[nameof(Config.DownloadPath)] = [nameof(Config.DownloadPath)] =
"Base download folder. If blank, OF-DL uses __user_data__/sites/OnlyFans/{username}.", "Base download folder. Leave blank to use __user_data__/sites/OnlyFans/{username}.",
[nameof(Config.DrmVideoDurationMatchThreshold)] = [nameof(Config.DrmVideoDurationMatchThreshold)] =
"Minimum DRM video duration match threshold. Higher values are stricter. 100% requires an exact duration match. 98% is the recommended value.", "Minimum DRM duration match required. 98% is recommended; 100% requires an exact match.",
[nameof(Config.DownloadVideos)] = "Download video media when enabled.", [nameof(Config.DownloadVideos)] = "Include videos in downloads.",
[nameof(Config.DownloadImages)] = "Download image media when enabled.", [nameof(Config.DownloadImages)] = "Include images in downloads.",
[nameof(Config.DownloadAudios)] = "Download audio media when enabled.", [nameof(Config.DownloadAudios)] = "Include audio files in downloads.",
[nameof(Config.DownloadAvatarHeaderPhoto)] = [nameof(Config.DownloadAvatarHeaderPhoto)] =
"Download creator avatar and header images when enabled.", "Include creator avatar and header images.",
[nameof(Config.DownloadPosts)] = "Download free posts when enabled.", [nameof(Config.DownloadPosts)] = "Include free posts.",
[nameof(Config.DownloadPaidPosts)] = "Download paid posts when enabled.", [nameof(Config.DownloadPaidPosts)] = "Include unlocked PPV posts.",
[nameof(Config.DownloadArchived)] = "Download archived posts when enabled.", [nameof(Config.DownloadArchived)] = "Include archived posts.",
[nameof(Config.DownloadStreams)] = "Download posts from the Streams tab when enabled.", [nameof(Config.DownloadStreams)] = "Include stream posts from the Streams tab.",
[nameof(Config.DownloadStories)] = "Download stories when enabled.", [nameof(Config.DownloadStories)] = "Include stories.",
[nameof(Config.DownloadHighlights)] = "Download highlights when enabled.", [nameof(Config.DownloadHighlights)] = "Include highlights.",
[nameof(Config.DownloadMessages)] = [nameof(Config.DownloadMessages)] =
"Download free media from messages (including paid-message previews) when enabled.", "Include free message media and paid-message preview media.",
[nameof(Config.DownloadPaidMessages)] = [nameof(Config.DownloadPaidMessages)] =
"Download paid media from messages (excluding preview media) when enabled.", "Include unlocked PPV message media (excluding preview media).",
[nameof(Config.IgnoreOwnMessages)] = [nameof(Config.IgnoreOwnMessages)] =
"Ignore your own sent messages and do not download media sent by your account.", "Skip messages sent by your account and any media attached to them.",
[nameof(Config.DownloadPostsIncrementally)] = [nameof(Config.DownloadPostsIncrementally)] =
"Only download new posts after the latest downloaded post in metadata DB.", "Only fetch posts newer than the latest saved post in metadata.",
[nameof(Config.BypassContentForCreatorsWhoNoLongerExist)] = [nameof(Config.BypassContentForCreatorsWhoNoLongerExist)] =
"Allow downloading accessible purchased content for deleted creators.", "Try downloading accessible purchased content even when a creator account no longer exists.",
[nameof(Config.DownloadDuplicatedMedia)] = [nameof(Config.DownloadDuplicatedMedia)] =
"When enabled, duplicate media can be downloaded instead of being skipped.", "Allow duplicate media to be downloaded instead of skipped.",
[nameof(Config.SkipAds)] = [nameof(Config.SkipAds)] =
"Skip posts/messages containing #ad or free-trial links when enabled.", "Skip posts and messages that contain #ad or free-trial links.",
[nameof(Config.DownloadOnlySpecificDates)] = [nameof(Config.DownloadOnlySpecificDates)] =
"Limit downloads by date using DownloadDateSelection and CustomDate.", "Enable post date filtering using Date Selection and Custom Date.",
[nameof(Config.DownloadDateSelection)] = [nameof(Config.DownloadDateSelection)] =
"Choose whether date filtering uses content before or after CustomDate.", "Choose whether post filtering uses content before or after Custom Date.",
[nameof(Config.CustomDate)] = [nameof(Config.CustomDate)] =
"Date used for date-filtered downloads (yyyy-MM-dd).", "Date used for post filtering (yyyy-MM-dd).",
[nameof(Config.ShowScrapeSize)] = [nameof(Config.ShowScrapeSize)] =
"Show total byte size instead of item counts during download progress.", "Show estimated total bytes instead of item counts while preparing downloads.",
[nameof(Config.DisableTextSanitization)] = [nameof(Config.DisableTextSanitization)] =
"Store post/message text as-is without XML stripping.", "Store post and message text as-is without XML stripping.",
[nameof(Config.DownloadVideoResolution)] = [nameof(Config.DownloadVideoResolution)] =
"Choose preferred video resolution (source, 240, or 720 when available).", "Preferred video resolution when alternatives are available.",
[nameof(Config.PaidPostFileNameFormat)] = [nameof(Config.PaidPostFileNameFormat)] =
"Custom filename format for paid posts. See custom filename formats docs.", "Filename pattern for unlocked PPV posts.",
[nameof(Config.PostFileNameFormat)] = [nameof(Config.PostFileNameFormat)] =
"Custom filename format for free posts/archived/streams. See custom filename formats docs.", "Filename pattern for free posts, archived posts, and streams.",
[nameof(Config.PaidMessageFileNameFormat)] = [nameof(Config.PaidMessageFileNameFormat)] =
"Custom filename format for paid messages. See custom filename formats docs.", "Filename pattern for unlocked PPV message media.",
[nameof(Config.MessageFileNameFormat)] = [nameof(Config.MessageFileNameFormat)] =
"Custom filename format for free messages. See custom filename formats docs.", "Filename pattern for free message media.",
[nameof(Config.RenameExistingFilesWhenCustomFormatIsSelected)] = [nameof(Config.RenameExistingFilesWhenCustomFormatIsSelected)] =
"Rename previously downloaded files when custom filename format is enabled.", "Rename existing downloaded files to match current custom filename formats.",
[nameof(Config.CreatorConfigs)] = [nameof(Config.CreatorConfigs)] =
"Per-creator filename format overrides. Values here override global filename formats.", "Per-creator filename format overrides in JSON. These override global formats.",
[nameof(Config.FolderPerPaidPost)] = [nameof(Config.FolderPerPaidPost)] =
"Create a separate folder per paid post when enabled.", "Create a separate folder for each unlocked PPV post.",
[nameof(Config.FolderPerPost)] = [nameof(Config.FolderPerPost)] =
"Create a separate folder per free post when enabled.", "Create a separate folder for each free post.",
[nameof(Config.FolderPerPaidMessage)] = [nameof(Config.FolderPerPaidMessage)] =
"Create a separate folder per paid message when enabled.", "Create a separate folder for each unlocked PPV message.",
[nameof(Config.FolderPerMessage)] = [nameof(Config.FolderPerMessage)] =
"Create a separate folder per free message when enabled.", "Create a separate folder for each free message.",
[nameof(Config.IncludeExpiredSubscriptions)] = [nameof(Config.IncludeExpiredSubscriptions)] =
"Include expired subscriptions in user selection.", "Show expired subscriptions in creator selection.",
[nameof(Config.IncludeRestrictedSubscriptions)] = [nameof(Config.IncludeRestrictedSubscriptions)] =
"Include restricted creators in scraping and download flow.", "Include restricted creators during scraping and downloads.",
[nameof(Config.IgnoredUsersListName)] = [nameof(Config.IgnoredUsersListName)] =
"Users in this list are ignored during scraping. Empty means no users are ignored.", "Skip creators that belong to this OnlyFans list.",
[nameof(Config.Timeout)] = [nameof(Config.Timeout)] =
"HTTP timeout override in seconds (-1 uses default behavior).", "HTTP timeout in seconds. Use -1 for default behavior.",
[nameof(Config.LimitDownloadRate)] = [nameof(Config.LimitDownloadRate)] =
"Enable download speed limiting.", "Enable download speed limiting.",
[nameof(Config.DownloadLimitInMbPerSec)] = [nameof(Config.DownloadLimitInMbPerSec)] =
"Download rate limit in MB/s when rate limiting is enabled.", "Maximum download speed in MB/s when rate limiting is enabled.",
[nameof(Config.Theme)] = [nameof(Config.Theme)] =
"GUI theme for the configuration and download screens.", "Choose the GUI theme.",
[nameof(Config.HideMissingCdmKeysWarning)] = [nameof(Config.HideMissingCdmKeysWarning)] =
"Hide the missing CDM keys warning before downloads start.", "Skip the missing CDM keys confirmation before downloads start.",
[nameof(Config.LoggingLevel)] = [nameof(Config.LoggingLevel)] =
"Log verbosity written to logs/OFDL.txt." "Minimum log level written to logs/OFDL.txt."
}; };
private static readonly Dictionary<string, string> s_lightThemeBrushes = new(StringComparer.Ordinal) private static readonly Dictionary<string, string> s_lightThemeBrushes = new(StringComparer.Ordinal)

View File

@ -765,7 +765,8 @@
Spacing="8"> Spacing="8">
<CheckBox IsChecked="{Binding BoolValue}" <CheckBox IsChecked="{Binding BoolValue}"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
<TextBlock IsVisible="{Binding IsHideMissingCdmKeysWarningField}" <TextBlock
IsVisible="{Binding IsHideMissingCdmKeysWarningField}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{Binding ViewModel.HideMissingCdmKeysWarningStatusText, RelativeSource={RelativeSource AncestorType=views:MainWindow}, FallbackValue=''}" Text="{Binding ViewModel.HideMissingCdmKeysWarningStatusText, RelativeSource={RelativeSource AncestorType=views:MainWindow}, FallbackValue=''}"
Foreground="{Binding ViewModel.HideMissingCdmKeysWarningStatusBrush, RelativeSource={RelativeSource AncestorType=views:MainWindow}}" /> Foreground="{Binding ViewModel.HideMissingCdmKeysWarningStatusBrush, RelativeSource={RelativeSource AncestorType=views:MainWindow}}" />