Three causes behind the stuck indicator: - OperationStatus.End did not retire the generation, so tick work posted while the dispatcher was blocked drained afterwards and set ShowIndicator back to true on a finished operation. - The startup update check ran in Task.Run; OperationStatus writes its observable properties on the calling thread, so the final ShowIndicator=false never reached the binding. - OperationIndicator overwrote its own DataContext from the Status property, which re-targeted the call-site binding. It now scopes the DataContext to an inner panel and collapses itself when Status is null; every call site switched from DataContext= to Status=. Also gates the footer connection pill in the command body instead of CanExecute (a disabled command greyed out the ONLINE chip), and extends OperationTiming: pid per line, 4 MB rollover, fast successes dropped (failures always kept), and DetailsIsland.BindAsync now carries the selection trigger via TasksIslandViewModel.SelectFrom.
43 lines
1.6 KiB
C#
43 lines
1.6 KiB
C#
using System.Collections.Specialized;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using ClaudeDo.Ui.ViewModels;
|
|
|
|
namespace ClaudeDo.Ui.Views;
|
|
|
|
internal static class JumpToTaskHelper
|
|
{
|
|
// Selects the list, then waits for the matching task row to appear in Tasks.Items.
|
|
// Listens to CollectionChanged so it works regardless of how long LoadForListAsync takes;
|
|
// bounded by a hard timeout so we never hang if the task is filtered out.
|
|
public static async Task SelectAsync(IslandsShellViewModel s, string listId, string taskId)
|
|
{
|
|
if (s.Lists is null || s.Tasks is null) return;
|
|
var item = s.Lists.UserLists.FirstOrDefault(l => l.Id == $"user:{listId}");
|
|
if (item is null) return;
|
|
s.Lists.SelectedList = item;
|
|
|
|
var existing = s.Tasks.Items.FirstOrDefault(r => r.Id == taskId);
|
|
if (existing is not null) { s.Tasks.SelectFrom(existing, "jump-to-task"); return; }
|
|
|
|
var tcs = new TaskCompletionSource<bool>();
|
|
void OnChanged(object? _, NotifyCollectionChangedEventArgs __)
|
|
{
|
|
var row = s.Tasks!.Items.FirstOrDefault(r => r.Id == taskId);
|
|
if (row is not null) tcs.TrySetResult(true);
|
|
}
|
|
|
|
s.Tasks.Items.CollectionChanged += OnChanged;
|
|
try
|
|
{
|
|
await Task.WhenAny(tcs.Task, Task.Delay(5000));
|
|
var row = s.Tasks.Items.FirstOrDefault(r => r.Id == taskId);
|
|
if (row is not null) s.Tasks.SelectFrom(row, "jump-to-task");
|
|
}
|
|
finally
|
|
{
|
|
s.Tasks.Items.CollectionChanged -= OnChanged;
|
|
}
|
|
}
|
|
}
|