Skip to content

Review pending files in the viewer when no tray is running - #755

Merged
SimonCropp merged 1 commit into
mainfrom
pending-files-without-a-tray
Aug 14, 2026
Merged

Review pending files in the viewer when no tray is running#755
SimonCropp merged 1 commit into
mainfrom
pending-files-without-a-tray

Conversation

@SimonCropp

Copy link
Copy Markdown
Member

A pending move or delete used to be reported to nothing at all without a tray: DiffRunner checked DiffEngineTray.IsRunning and skipped the send, so a received file waiting to be promoted, or a verified file a passing test no longer produces, was pending in no surface whatsoever.

PendingFiles is now the router: the piper port when a tray is running, and the inline queue's owner when one is not. A delete starts a viewer if nothing owns the queue, because it has no second file to compare against and so no diff tool ever opens for it. A move does not, since DiffRunner has already opened one for that pair.

An owning viewer holds them as ordinary Move/Delete queue entries, the same ones an attached viewer already draws for the tray's, so the rows, the context menu, grouping and Accept all are unchanged. Only who applies them differs. A tray that owns the queue answers the new verbs too, which is load bearing rather than defensive: the tray check is cached at type init, so a test process that started first addresses the queue owner for good.

That surfaced a latent bug. Every inline transition rebuilds its half of the queue from InlineQueue, and the projection returned only inline entries, so accepting one snapshot would have dropped every file pending beside it. ViewerSession.Rebuild carries them across.

Also in this change, from auditing what the tray and the viewer do to the same item:

  • RemoteInlineHost decided applied versus failed from the wire's ok, which carries no apply status. An owner keeps a failed entry pending, so the tray reported a snapshot as accepted while the viewer still showed it, and the menu offered it again a scan later. It now re-reads the listing.
  • The tray menu's "Discard (n)" swept its dictionaries directly, leaving received files behind that the per item discard and the viewer's both delete. It goes through the same discard now, which in turn forced DisposeAsync to stop being a discard: exiting is not discarding.
  • Bulk and group accepts sweep tracked files, worded as the tray words its own, so "Accept all in ..." cannot quietly mean "the snapshots in ...".

TrayViewerSyncTest is the new coverage for all of it: a real tray and a real viewer session over a real socket, in both ownership arrangements, asserting that an accept, discard, sweep or settle from either surface leaves the other showing the same thing.

A pending move or delete used to be reported to nothing at all without a
tray: DiffRunner checked DiffEngineTray.IsRunning and skipped the send, so
a received file waiting to be promoted, or a verified file a passing test
no longer produces, was pending in no surface whatsoever.

PendingFiles is now the router: the piper port when a tray is running, and
the inline queue's owner when one is not. A delete starts a viewer if
nothing owns the queue, because it has no second file to compare against
and so no diff tool ever opens for it. A move does not, since DiffRunner
has already opened one for that pair.

An owning viewer holds them as ordinary Move/Delete queue entries, the same
ones an attached viewer already draws for the tray's, so the rows, the
context menu, grouping and Accept all are unchanged. Only who applies them
differs. A tray that owns the queue answers the new verbs too, which is
load bearing rather than defensive: the tray check is cached at type init,
so a test process that started first addresses the queue owner for good.

That surfaced a latent bug. Every inline transition rebuilds its half of
the queue from InlineQueue, and the projection returned only inline
entries, so accepting one snapshot would have dropped every file pending
beside it. ViewerSession.Rebuild carries them across.

Also in this change, from auditing what the tray and the viewer do to the
same item:

* RemoteInlineHost decided applied versus failed from the wire's ok, which
  carries no apply status. An owner keeps a failed entry pending, so the
  tray reported a snapshot as accepted while the viewer still showed it,
  and the menu offered it again a scan later. It now re-reads the listing.
* The tray menu's "Discard (n)" swept its dictionaries directly, leaving
  received files behind that the per item discard and the viewer's both
  delete. It goes through the same discard now, which in turn forced
  DisposeAsync to stop being a discard: exiting is not discarding.
* Bulk and group accepts sweep tracked files, worded as the tray words its
  own, so "Accept all in ..." cannot quietly mean "the snapshots in ...".

TrayViewerSyncTest is the new coverage for all of it: a real tray and a
real viewer session over a real socket, in both ownership arrangements,
asserting that an accept, discard, sweep or settle from either surface
leaves the other showing the same thing.
@SimonCropp
SimonCropp merged commit d057225 into main Aug 14, 2026
9 checks passed
@SimonCropp
SimonCropp deleted the pending-files-without-a-tray branch August 14, 2026 04:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant