TryInvokeAsync catches every exception and returns null, which is fine
for read-only calls but hid real HubException reasons behind a generic
"offline" message for the 7 mutating call sites (RestoreDefaultAgents,
UpsertPrimeSchedule, AddDailyNote, CleanupFinishedWorktrees,
ResetAllWorktrees, ForceRemoveWorktree, BuildPlanningIntegrationBranch)
— the same bug class fixed for ApproveReview in e1807fd. Each of the 22
TryInvokeAsync call sites was audited; the 15 read-only ones are left
unchanged (empty/offline is the right display). For the 7 switched to
a direct hub invoke, every caller was checked and, where it had no
catch, one was added so the exception surfaces (StatusMessage,
ShowErrorAsync/CombinedWarning) instead of crashing.
91 lines
2.7 KiB
C#
91 lines
2.7 KiB
C#
using System.Collections.ObjectModel;
|
|
using ClaudeDo.Ui.Services.Interfaces;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
namespace ClaudeDo.Ui.ViewModels.Islands;
|
|
|
|
public sealed partial class NoteBulletViewModel : ViewModelBase
|
|
{
|
|
public string Id { get; }
|
|
|
|
[ObservableProperty] private string _text;
|
|
|
|
public NoteBulletViewModel(string id, string text)
|
|
{
|
|
Id = id;
|
|
_text = text;
|
|
}
|
|
}
|
|
|
|
public sealed partial class NotesEditorViewModel : ViewModelBase
|
|
{
|
|
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<string>? ErrorReported;
|
|
|
|
public ObservableCollection<NoteBulletViewModel> Bullets { get; } = new();
|
|
|
|
[ObservableProperty] private DateOnly _currentDay = DateOnly.FromDateTime(DateTime.Today);
|
|
[ObservableProperty] private string _newBulletText = "";
|
|
|
|
public DateTime CurrentDate
|
|
{
|
|
get => CurrentDay.ToDateTime(TimeOnly.MinValue);
|
|
set { var d = DateOnly.FromDateTime(value); if (d != CurrentDay) _ = LoadDayAsync(d); }
|
|
}
|
|
|
|
public string CurrentDayLabel => CurrentDay.ToString("dddd, dd.MM.yyyy");
|
|
|
|
public async Task LoadDayAsync(DateOnly day)
|
|
{
|
|
CurrentDay = day;
|
|
OnPropertyChanged(nameof(CurrentDate));
|
|
OnPropertyChanged(nameof(CurrentDayLabel));
|
|
Bullets.Clear();
|
|
foreach (var dto in await _api.ListAsync(day))
|
|
Bullets.Add(MakeBullet(dto.Id, dto.Text));
|
|
}
|
|
|
|
private NoteBulletViewModel MakeBullet(string id, string text) =>
|
|
new(id, text);
|
|
|
|
[RelayCommand]
|
|
private async Task AddBullet()
|
|
{
|
|
var text = NewBulletText.Trim();
|
|
if (text.Length == 0) return;
|
|
try
|
|
{
|
|
var dto = await _api.AddAsync(CurrentDay, text);
|
|
if (dto is not null) Bullets.Add(MakeBullet(dto.Id, dto.Text));
|
|
NewBulletText = "";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorReported?.Invoke(ex.Message);
|
|
}
|
|
}
|
|
|
|
[RelayCommand] private Task PrevDay() => LoadDayAsync(CurrentDay.AddDays(-1));
|
|
[RelayCommand] private Task NextDay() => LoadDayAsync(CurrentDay.AddDays(1));
|
|
[RelayCommand] private Task Today() => LoadDayAsync(DateOnly.FromDateTime(DateTime.Today));
|
|
|
|
[RelayCommand]
|
|
private async Task CommitBullet(NoteBulletViewModel? b)
|
|
{
|
|
if (b is null) return;
|
|
var text = b.Text?.Trim() ?? "";
|
|
if (text.Length == 0)
|
|
{
|
|
await _api.DeleteAsync(b.Id);
|
|
Bullets.Remove(b);
|
|
return;
|
|
}
|
|
await _api.UpdateAsync(b.Id, text);
|
|
}
|
|
}
|