using System.Collections.ObjectModel;
using ClaudeDo.Ui.Localization;
using ClaudeDo.Ui.Services;
using ClaudeDo.Ui.Services.Interfaces;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace ClaudeDo.Ui.ViewModels.Islands;
/// Date separator between the note groups. Rows carry these inline (like the task list's
/// HeaderRow) so one ItemsControl renders today and the history without a nested control per day.
public sealed class NoteDayHeaderViewModel
{
public DateOnly Day { get; }
public string Label { get; }
public bool IsToday { get; }
public NoteDayHeaderViewModel(DateOnly day, DateOnly today)
{
Day = day;
IsToday = day == today;
Label = day == today ? Loc.T("notes.today")
: day == today.AddDays(-1) ? Loc.T("notes.yesterday")
: day.ToString("dddd, dd.MM.");
}
}
public sealed partial class NoteBulletViewModel : ViewModelBase
{
/// Empty until the note is persisted — a row the user started but hasn't typed into
/// yet exists only in the list, so an abandoned Enter leaves nothing behind in the database.
public string Id { get; set; }
public DateOnly Day { get; }
public bool FromAgent { get; }
public bool IsNew => Id.Length == 0;
[ObservableProperty] private string _text;
public NoteBulletViewModel(string id, DateOnly day, string text, bool fromAgent = false)
{
Id = id;
Day = day;
_text = text;
FromAgent = fromAgent;
}
}
public sealed partial class NotesEditorViewModel : ViewModelBase
{
/// How far the history scrolls back. Older notes stay in the database and in the week
/// report; they are simply not worth the round trip in a day log.
public const int HistoryDays = 14;
private readonly INotesApi _api;
public NotesEditorViewModel(INotesApi api) => _api = api;
// Raised when a worker call fails so the host VM can surface it (e.g. via ShowErrorAsync).
public event Action? ErrorReported;
/// Raised after a row is inserted so the view can move the caret into it.
public event Action? FocusRequested;
/// NoteDayHeaderViewModel | NoteBulletViewModel, newest day first.
public ObservableCollection