Files
ClaudeDo/src/ClaudeDo.Ui/ViewModels/Modals/Settings/PrimeScheduleRowViewModel.cs
T

137 lines
4.6 KiB
C#

using System.Globalization;
using ClaudeDo.Data.Models;
using ClaudeDo.Ui.Localization;
using ClaudeDo.Ui.Services;
using CommunityToolkit.Mvvm.ComponentModel;
namespace ClaudeDo.Ui.ViewModels.Modals.Settings;
public sealed partial class PrimeScheduleRowViewModel : ViewModelBase
{
private const int Mon = 1, Tue = 2, Wed = 4, Thu = 8, Fri = 16, Sat = 32, Sun = 64;
public Guid Id { get; }
public bool IsExisting { get; }
[ObservableProperty] private bool _enabled;
[ObservableProperty] private bool _monday;
[ObservableProperty] private bool _tuesday;
[ObservableProperty] private bool _wednesday;
[ObservableProperty] private bool _thursday;
[ObservableProperty] private bool _friday;
[ObservableProperty] private bool _saturday;
[ObservableProperty] private bool _sunday;
[ObservableProperty] private TimeSpan _timeOfDay;
[ObservableProperty] private DateTimeOffset? _lastRunAt;
[ObservableProperty] private string? _promptOverride;
[ObservableProperty] private PrimeActionKind _kind;
public string LastRunLabel => LastRunAt is { } v ? v.LocalDateTime.ToString("g") : "—";
private static readonly string[] TimeFormats = { @"h\:mm", @"hh\:mm" };
public string TimeText
{
get => TimeOfDay.ToString(@"hh\:mm", CultureInfo.InvariantCulture);
set
{
if (TimeSpan.TryParseExact(value, TimeFormats, CultureInfo.InvariantCulture, out var t)
&& t >= TimeSpan.Zero && t < TimeSpan.FromDays(1))
{
TimeOfDay = t;
}
OnPropertyChanged(nameof(TimeText));
}
}
/// <summary>Per-row group name. A shared GroupName would make every schedule in the
/// ItemsControl share one selection.</summary>
public string RadioGroup => $"prime-kind-{Id}";
// One boolean per kind rather than an enum-to-bool converter: RadioButton.IsChecked binds
// TwoWay to a bool, and compiled bindings stay simple.
public bool IsPing
{
get => Kind == PrimeActionKind.Ping;
set { if (value) Kind = PrimeActionKind.Ping; }
}
public bool IsFillMyDay
{
get => Kind == PrimeActionKind.FillMyDay;
set { if (value) Kind = PrimeActionKind.FillMyDay; }
}
public bool IsCustom
{
get => Kind == PrimeActionKind.Custom;
set { if (value) Kind = PrimeActionKind.Custom; }
}
public bool IsImportTickets
{
get => Kind == PrimeActionKind.ImportTickets;
set { if (value) Kind = PrimeActionKind.ImportTickets; }
}
public bool ShowPrompt => Kind != PrimeActionKind.Ping;
public string PromptLabel => Kind == PrimeActionKind.Custom
? Loc.T("settings.prime.customPromptLabel")
: Loc.T("settings.prime.promptOverrideLabel");
public string PromptPlaceholder => Kind == PrimeActionKind.Custom
? Loc.T("settings.prime.customPromptPlaceholder")
: Loc.T("settings.prime.promptOverridePlaceholder");
partial void OnKindChanged(PrimeActionKind value)
{
OnPropertyChanged(nameof(IsPing));
OnPropertyChanged(nameof(IsFillMyDay));
OnPropertyChanged(nameof(IsCustom));
OnPropertyChanged(nameof(IsImportTickets));
OnPropertyChanged(nameof(ShowPrompt));
OnPropertyChanged(nameof(PromptLabel));
OnPropertyChanged(nameof(PromptPlaceholder));
}
partial void OnLastRunAtChanged(DateTimeOffset? value) => OnPropertyChanged(nameof(LastRunLabel));
partial void OnTimeOfDayChanged(TimeSpan value) => OnPropertyChanged(nameof(TimeText));
public PrimeScheduleRowViewModel(PrimeScheduleDto dto, bool isExisting)
{
Id = dto.Id;
IsExisting = isExisting;
Enabled = dto.Enabled;
Monday = (dto.Days & Mon) != 0;
Tuesday = (dto.Days & Tue) != 0;
Wednesday = (dto.Days & Wed) != 0;
Thursday = (dto.Days & Thu) != 0;
Friday = (dto.Days & Fri) != 0;
Saturday = (dto.Days & Sat) != 0;
Sunday = (dto.Days & Sun) != 0;
TimeOfDay = dto.TimeOfDay;
LastRunAt = dto.LastRunAt;
PromptOverride = dto.PromptOverride;
Kind = dto.Kind;
}
public int DaysMask()
{
int m = 0;
if (Monday) m |= Mon;
if (Tuesday) m |= Tue;
if (Wednesday) m |= Wed;
if (Thursday) m |= Thu;
if (Friday) m |= Fri;
if (Saturday) m |= Sat;
if (Sunday) m |= Sun;
return m;
}
public PrimeScheduleDto ToDto() =>
new(Id, DaysMask(), TimeOfDay, Enabled, LastRunAt,
string.IsNullOrWhiteSpace(PromptOverride) ? null : PromptOverride, Kind);
}