293 lines
11 KiB
C#
293 lines
11 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Text.RegularExpressions;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using OF_DL.Models.Config;
|
|
using Serilog;
|
|
|
|
namespace OF_DL.Gui.ViewModels;
|
|
|
|
public partial class CreatorConfigModalViewModel : ViewModelBase
|
|
{
|
|
private static readonly Regex s_fileNameVariableRegex = new(@"\{([^{}]+)\}", RegexOptions.Compiled);
|
|
|
|
private static readonly string[] s_postFileNameVariables = ["id", "postedAt", "mediaId", "mediaCreatedAt", "filename", "username", "text"];
|
|
private static readonly string[] s_messageFileNameVariables = ["id", "createdAt", "mediaId", "mediaCreatedAt", "filename", "username", "text"];
|
|
|
|
private readonly Action<bool> _onClose;
|
|
private readonly Func<bool> _isUsernameDuplicate;
|
|
|
|
[ObservableProperty] private bool _isOpen;
|
|
[ObservableProperty] private bool _isEditMode;
|
|
[ObservableProperty] private string _originalUsername = string.Empty;
|
|
[ObservableProperty] private string _username = string.Empty;
|
|
[ObservableProperty] private string _usernameError = string.Empty;
|
|
[ObservableProperty] private string _paidPostFileNameFormat = string.Empty;
|
|
[ObservableProperty] private string _postFileNameFormat = string.Empty;
|
|
[ObservableProperty] private string _paidMessageFileNameFormat = string.Empty;
|
|
[ObservableProperty] private string _messageFileNameFormat = string.Empty;
|
|
[ObservableProperty] private string _selectedPaidPostVariable = string.Empty;
|
|
[ObservableProperty] private string _selectedPostVariable = string.Empty;
|
|
[ObservableProperty] private string _selectedPaidMessageVariable = string.Empty;
|
|
[ObservableProperty] private string _selectedMessageVariable = string.Empty;
|
|
[ObservableProperty] private string _unknownPaidPostVariablesMessage = string.Empty;
|
|
[ObservableProperty] private string _unknownPostVariablesMessage = string.Empty;
|
|
[ObservableProperty] private string _unknownPaidMessageVariablesMessage = string.Empty;
|
|
[ObservableProperty] private string _unknownMessageVariablesMessage = string.Empty;
|
|
|
|
public ObservableCollection<string> AvailableUsers { get; }
|
|
public ObservableCollection<string> PaidPostVariables { get; } = [];
|
|
public ObservableCollection<string> PostVariables { get; } = [];
|
|
public ObservableCollection<string> PaidMessageVariables { get; } = [];
|
|
public ObservableCollection<string> MessageVariables { get; } = [];
|
|
public ObservableCollection<FileNameFormatSegmentViewModel> PaidPostSegments { get; } = [];
|
|
public ObservableCollection<FileNameFormatSegmentViewModel> PostSegments { get; } = [];
|
|
public ObservableCollection<FileNameFormatSegmentViewModel> PaidMessageSegments { get; } = [];
|
|
public ObservableCollection<FileNameFormatSegmentViewModel> MessageSegments { get; } = [];
|
|
|
|
public bool HasUsernameError => !string.IsNullOrWhiteSpace(UsernameError);
|
|
public bool HasUnknownPaidPostVariables => !string.IsNullOrWhiteSpace(UnknownPaidPostVariablesMessage);
|
|
public bool HasUnknownPostVariables => !string.IsNullOrWhiteSpace(UnknownPostVariablesMessage);
|
|
public bool HasUnknownPaidMessageVariables => !string.IsNullOrWhiteSpace(UnknownPaidMessageVariablesMessage);
|
|
public bool HasUnknownMessageVariables => !string.IsNullOrWhiteSpace(UnknownMessageVariablesMessage);
|
|
|
|
public string DialogTitle => IsEditMode ? "Edit Creator Config" : "Add Creator Config";
|
|
|
|
public CreatorConfigModalViewModel(IEnumerable<string> availableUsers, Action<bool> onClose, Func<bool> isUsernameDuplicate)
|
|
{
|
|
AvailableUsers = new ObservableCollection<string>(availableUsers);
|
|
_onClose = onClose;
|
|
_isUsernameDuplicate = isUsernameDuplicate;
|
|
|
|
foreach (string variable in s_postFileNameVariables)
|
|
{
|
|
PaidPostVariables.Add(variable);
|
|
PostVariables.Add(variable);
|
|
}
|
|
|
|
foreach (string variable in s_messageFileNameVariables)
|
|
{
|
|
PaidMessageVariables.Add(variable);
|
|
MessageVariables.Add(variable);
|
|
}
|
|
|
|
SelectedPaidPostVariable = PaidPostVariables.FirstOrDefault() ?? string.Empty;
|
|
SelectedPostVariable = PostVariables.FirstOrDefault() ?? string.Empty;
|
|
SelectedPaidMessageVariable = PaidMessageVariables.FirstOrDefault() ?? string.Empty;
|
|
SelectedMessageVariable = MessageVariables.FirstOrDefault() ?? string.Empty;
|
|
}
|
|
|
|
public void OpenForAdd()
|
|
{
|
|
Log.Information("=== OpenForAdd called ===");
|
|
IsEditMode = false;
|
|
OriginalUsername = string.Empty;
|
|
Username = string.Empty;
|
|
UsernameError = string.Empty;
|
|
PaidPostFileNameFormat = string.Empty;
|
|
PostFileNameFormat = string.Empty;
|
|
PaidMessageFileNameFormat = string.Empty;
|
|
MessageFileNameFormat = string.Empty;
|
|
ClearAllPreviews();
|
|
Log.Information("About to set IsOpen = true");
|
|
IsOpen = true;
|
|
Log.Information("=== OpenForAdd: IsOpen is now {IsOpen} ===", IsOpen);
|
|
}
|
|
|
|
public void OpenForEdit(string username, CreatorConfig config)
|
|
{
|
|
IsEditMode = true;
|
|
OriginalUsername = username;
|
|
Username = username;
|
|
UsernameError = string.Empty;
|
|
PaidPostFileNameFormat = config.PaidPostFileNameFormat ?? string.Empty;
|
|
PostFileNameFormat = config.PostFileNameFormat ?? string.Empty;
|
|
PaidMessageFileNameFormat = config.PaidMessageFileNameFormat ?? string.Empty;
|
|
MessageFileNameFormat = config.MessageFileNameFormat ?? string.Empty;
|
|
UpdateAllPreviews();
|
|
IsOpen = true;
|
|
}
|
|
|
|
public (string Username, CreatorConfig Config)? GetResult()
|
|
{
|
|
if (!Validate())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
CreatorConfig config = new()
|
|
{
|
|
PaidPostFileNameFormat = string.IsNullOrWhiteSpace(PaidPostFileNameFormat) ? null : PaidPostFileNameFormat,
|
|
PostFileNameFormat = string.IsNullOrWhiteSpace(PostFileNameFormat) ? null : PostFileNameFormat,
|
|
PaidMessageFileNameFormat = string.IsNullOrWhiteSpace(PaidMessageFileNameFormat) ? null : PaidMessageFileNameFormat,
|
|
MessageFileNameFormat = string.IsNullOrWhiteSpace(MessageFileNameFormat) ? null : MessageFileNameFormat
|
|
};
|
|
|
|
return (Username.Trim(), config);
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void InsertPaidPostVariable()
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(SelectedPaidPostVariable))
|
|
{
|
|
PaidPostFileNameFormat += $"{{{SelectedPaidPostVariable}}}";
|
|
}
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void InsertPostVariable()
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(SelectedPostVariable))
|
|
{
|
|
PostFileNameFormat += $"{{{SelectedPostVariable}}}";
|
|
}
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void InsertPaidMessageVariable()
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(SelectedPaidMessageVariable))
|
|
{
|
|
PaidMessageFileNameFormat += $"{{{SelectedPaidMessageVariable}}}";
|
|
}
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void InsertMessageVariable()
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(SelectedMessageVariable))
|
|
{
|
|
MessageFileNameFormat += $"{{{SelectedMessageVariable}}}";
|
|
}
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void Confirm()
|
|
{
|
|
if (Validate())
|
|
{
|
|
_onClose(true);
|
|
}
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void Cancel()
|
|
{
|
|
_onClose(false);
|
|
}
|
|
|
|
partial void OnIsOpenChanged(bool value)
|
|
{
|
|
Log.Information("*** IsOpen property changed to: {Value} ***", value);
|
|
}
|
|
|
|
partial void OnPaidPostFileNameFormatChanged(string value) => UpdatePaidPostPreview();
|
|
partial void OnPostFileNameFormatChanged(string value) => UpdatePostPreview();
|
|
partial void OnPaidMessageFileNameFormatChanged(string value) => UpdatePaidMessagePreview();
|
|
partial void OnMessageFileNameFormatChanged(string value) => UpdateMessagePreview();
|
|
|
|
private bool Validate()
|
|
{
|
|
UsernameError = string.Empty;
|
|
|
|
if (string.IsNullOrWhiteSpace(Username))
|
|
{
|
|
UsernameError = "Username is required.";
|
|
return false;
|
|
}
|
|
|
|
string trimmedUsername = Username.Trim();
|
|
if (!IsEditMode || trimmedUsername != OriginalUsername)
|
|
{
|
|
if (_isUsernameDuplicate())
|
|
{
|
|
UsernameError = "A config for this username already exists.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void ClearAllPreviews()
|
|
{
|
|
PaidPostSegments.Clear();
|
|
PostSegments.Clear();
|
|
PaidMessageSegments.Clear();
|
|
MessageSegments.Clear();
|
|
UnknownPaidPostVariablesMessage = string.Empty;
|
|
UnknownPostVariablesMessage = string.Empty;
|
|
UnknownPaidMessageVariablesMessage = string.Empty;
|
|
UnknownMessageVariablesMessage = string.Empty;
|
|
}
|
|
|
|
private void UpdateAllPreviews()
|
|
{
|
|
UpdatePaidPostPreview();
|
|
UpdatePostPreview();
|
|
UpdatePaidMessagePreview();
|
|
UpdateMessagePreview();
|
|
}
|
|
|
|
private void UpdatePaidPostPreview() =>
|
|
UpdateFileNamePreview(PaidPostFileNameFormat, PaidPostSegments, s_postFileNameVariables, msg => UnknownPaidPostVariablesMessage = msg);
|
|
|
|
private void UpdatePostPreview() =>
|
|
UpdateFileNamePreview(PostFileNameFormat, PostSegments, s_postFileNameVariables, msg => UnknownPostVariablesMessage = msg);
|
|
|
|
private void UpdatePaidMessagePreview() =>
|
|
UpdateFileNamePreview(PaidMessageFileNameFormat, PaidMessageSegments, s_messageFileNameVariables, msg => UnknownPaidMessageVariablesMessage = msg);
|
|
|
|
private void UpdateMessagePreview() =>
|
|
UpdateFileNamePreview(MessageFileNameFormat, MessageSegments, s_messageFileNameVariables, msg => UnknownMessageVariablesMessage = msg);
|
|
|
|
private void UpdateFileNamePreview(string format, ObservableCollection<FileNameFormatSegmentViewModel> segments, string[] allowedVariables, Action<string> setUnknownMessage)
|
|
{
|
|
segments.Clear();
|
|
setUnknownMessage(string.Empty);
|
|
|
|
if (string.IsNullOrEmpty(format))
|
|
{
|
|
return;
|
|
}
|
|
|
|
HashSet<string> allowedSet = new(allowedVariables, StringComparer.OrdinalIgnoreCase);
|
|
HashSet<string> unknownVariables = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
MatchCollection matches = s_fileNameVariableRegex.Matches(format);
|
|
int currentIndex = 0;
|
|
foreach (Match match in matches)
|
|
{
|
|
if (match.Index > currentIndex)
|
|
{
|
|
string plainText = format[currentIndex..match.Index];
|
|
segments.Add(new FileNameFormatSegmentViewModel(plainText, "#1F2A44"));
|
|
}
|
|
|
|
string variableName = match.Groups[1].Value;
|
|
bool isAllowed = allowedSet.Contains(variableName);
|
|
segments.Add(new FileNameFormatSegmentViewModel(match.Value, isAllowed ? "#2E6EEA" : "#D84E4E"));
|
|
|
|
if (!isAllowed)
|
|
{
|
|
unknownVariables.Add(variableName);
|
|
}
|
|
|
|
currentIndex = match.Index + match.Length;
|
|
}
|
|
|
|
if (currentIndex < format.Length)
|
|
{
|
|
string trailingText = format[currentIndex..];
|
|
segments.Add(new FileNameFormatSegmentViewModel(trailingText, "#1F2A44"));
|
|
}
|
|
|
|
if (unknownVariables.Count > 0)
|
|
{
|
|
string tokens = string.Join(", ", unknownVariables.Select(v => $"{{{v}}}"));
|
|
setUnknownMessage($"Unknown variable(s): {tokens}");
|
|
}
|
|
}
|
|
}
|