fix(ui): Reactivität — Description-Save-Race, UsageMonitor-Leak, Listen-Live-Refresh
Drei unabhängige Reactivity-Bugs aus dem Polish-Audit 2026-08-20: 1. Description-Autosave überschrieb den falschen Task, weil SaveDescriptionAsync Task.Id/EditableDescription erst nach dem 400ms-Debounce las statt Row+Wert an der Aufrufstelle zu capturen (wie SaveTitleAsync es schon tat). Bind() cancelt jetzt zusätzlich einen laufenden Title-/Description-Save der vorherigen Row. 2. UsageMonitorModalViewModel abonnierte UsageUpdatedEvent erst nach dem Erst-Load-Await — schloss man das Modal währenddessen, lief das Unsubscribe in Close() ins Leere und die VM hing für immer am WorkerClient. Ein _isClosed-Flag wird jetzt nach dem Await geprüft, bevor abonniert wird. 3. Per MCP erstellte Listen blieben unsichtbar: RefreshRowAsync hatte keinen Add-Zweig für unbekannte Ids und verglich zudem die falsche Id-Form (der Worker broadcastet die rohe DB-Id, nie die "user:"-prefixte Row-Id). Ein Reconnect lud zudem nur Counts statt der vollen Listen neu.
This commit is contained in:
@@ -13,6 +13,7 @@ public sealed partial class UsageMonitorModalViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IWorkerClient _worker;
|
||||
private bool _applyingRange;
|
||||
private bool _isClosed;
|
||||
|
||||
public UsageMonitorModalViewModel(IWorkerClient worker) => _worker = worker;
|
||||
|
||||
@@ -78,6 +79,7 @@ public sealed partial class UsageMonitorModalViewModel : ViewModelBase
|
||||
[RelayCommand]
|
||||
private void Close()
|
||||
{
|
||||
_isClosed = true;
|
||||
_worker.UsageUpdatedEvent -= OnUsageUpdated;
|
||||
CloseAction?.Invoke();
|
||||
}
|
||||
@@ -95,7 +97,11 @@ public sealed partial class UsageMonitorModalViewModel : ViewModelBase
|
||||
IsBusy = true;
|
||||
try
|
||||
{
|
||||
Snapshot = await _worker.GetUsageSnapshotAsync();
|
||||
var snapshot = await _worker.GetUsageSnapshotAsync();
|
||||
// The modal can be closed while the first-load scan is still running (see remarks
|
||||
// above) — subscribing after that would leak this VM onto the long-lived WorkerClient.
|
||||
if (_isClosed) return;
|
||||
Snapshot = snapshot;
|
||||
_worker.UsageUpdatedEvent -= OnUsageUpdated;
|
||||
_worker.UsageUpdatedEvent += OnUsageUpdated;
|
||||
ApplyPresetRange(SelectedPresetDays);
|
||||
|
||||
Reference in New Issue
Block a user