Desktop: build only the host cards near the view, with a virtualising wrap panel for the board
ci / build and test (push) Successful in 3m39s
ci / android head (push) Successful in 3m59s
ci / api image (push) Successful in 5s
ci / desktop nightly (push) Failing after 37s

This commit is contained in:
jaap-jan committed 2026-10-02 16:20:51 +02:00
1 parent 41f368ae75
commit 656a33b4b1
3 files changed
+448 -1

No files matched your search

@@ -567,6 +567,69 @@ public sealed class HostGridTests : IAsyncLifetime
});
}
/// <remarks>
/// <para>
/// The board was a plain wrap panel, which built every card on it whether it was in view or not — some
/// twenty-five controls a card, so three hundred hosts took seconds to open and to redraw after a filter
/// was cleared. It builds the rows near the view now; see <c>VirtualizingWrapPanel</c>.
/// </para>
/// <para>
/// And the arrows still go everywhere, which is the half a virtualising panel can quietly break: Down
/// steps a whole row, and End reaches the last card although nothing had built it.
/// </para>
/// </remarks>
[Fact]
public async Task ADeepBoard_BuildsTheCardsInView_AndTheArrowsStillReachTheRest()
{
for (var host = 0; host < 120; host++)
{
vault.NewHostCommand.Execute(null);
vault.EditorLabel = $"zz-host-{host:000}";
vault.EditorHostname = $"zz-host-{host:000}.internal";
vault.EditorUsername = "deploy";
await vault.SaveHostCommand.ExecuteAsync(null);
}
await vault.LoadAsync(Token);
// Nothing selected, so the board opens at the top: a selected card is scrolled into view, and the last
// host saved is the one the editor left selected.
vault.SelectedHost = null;
await OnTheBoardAsync((screen, window) =>
{
var built = screen.GetVisualDescendants().OfType<ListBoxItem>().Count(card => card.IsVisible);
var total = vault.HostBoardOrder.Count();
total.ShouldBe(122);
built.ShouldBeGreaterThan(0);
built.ShouldBeLessThan(total / 2, "only the rows near the view are built");
var order = vault.HostBoardOrder.ToList();
var first = order[0];
Click(CardFor(screen, first), window);
vault.SelectedHost.ShouldBeSameAs(first);
var columns = CardFor(screen, first).GetVisualParent().ShouldBeOfType<VirtualizingWrapPanel>()
.GetVisualChildren().OfType<ListBoxItem>()
.Where(card => card.IsVisible)
.Count(card => Math.Abs(card.Bounds.Top - CardFor(screen, first).Bounds.Top) < 0.5);
window.KeyPressQwerty(PhysicalKey.ArrowDown, RawInputModifiers.None);
Dispatcher.UIThread.RunJobs();
vault.SelectedHost.ShouldBeSameAs(order[columns], "Down steps one whole row of cards");
window.KeyPressQwerty(PhysicalKey.End, RawInputModifiers.None);
Dispatcher.UIThread.RunJobs();
vault.SelectedHost.ShouldBeSameAs(order[^1], "the last card, built on the way there");
});
}
// ---- Helpers ----
private static void RightClick(Visual card, Visual window)