Desktop: virtualise the transfer queue and the import lists

This commit is contained in:
jaap-jan committed 2026-10-02 15:14:34 +02:00
1 parent 7b072bcded
commit 8759b12d47
4 files changed
+108 -16

No files matched your search

@@ -1386,6 +1386,48 @@ public sealed class ScreenLayoutTests : IAsyncLifetime
await MeasureTransfersAsync(faults => faults.ShouldBeEmpty());
}
/// <remarks>
/// A folder download queues a row per file. The queue was a plain stack inside an outer scroller, which
/// measured and drew every row however deep — so the number of rows built here is the claim, not the
/// layout: a few screens' worth out of two thousand.
/// </remarks>
[Fact]
public async Task ADeepQueue_BuildsOnlyTheRowsOnScreen()
{
transfers.IsConnected = true;
for (var file = 0; file < 2000; file++)
{
Enqueue(TransferDirection.Download, $"asset-{file:0000}.png", 4096, 0, TransferState.Queued);
}
await LayoutHarness.OnTheUiThreadAsync(
() =>
{
var screen = new TransfersScreen { DataContext = transfers };
var window = LayoutHarness.HostAtMinimumSize(
screen,
LayoutHarness.SessionScreenWidth(transfers.IsConnected),
LayoutHarness.SessionScreenHeight);
try
{
var built = screen.GetVisualDescendants()
.OfType<ProgressBar>()
.Count(bar => bar.Classes.Contains("transferbar"));
built.ShouldBeGreaterThan(0, "the rows on screen are still drawn");
built.ShouldBeLessThan(200, "the rest of the two thousand are not");
}
finally
{
window.Close();
}
},
Token);
}
/// <remarks>
/// The edit strip, which shares the questions' Grid row and is the tallest thing that can be in it: a
/// heading, a path, a scrolling log of saves, the conflict card and a button. Its log is bounded for the
@@ -1632,11 +1674,24 @@ public sealed class ScreenLayoutTests : IAsyncLifetime
try
{
var words = screen.GetVisualDescendants()
.OfType<TextBlock>()
.Where(text => text.Classes.Contains("transferstatus"))
.Select(text => text.Text ?? string.Empty)
.ToList();
// Row by row, scrolled to: the queue is virtualised, so a row off the bottom of the strip is
// not built until it is scrolled to — see ADeepQueue_BuildsOnlyTheRowsOnScreen.
var queue = screen.GetVisualDescendants().OfType<ItemsControl>()
.First(control => ReferenceEquals(control.ItemsSource, transfers.Transfers));
var words = new List<string>();
for (var row = 0; row < expected.Length; row++)
{
queue.ScrollIntoView(row);
window.UpdateLayout();
words.Add(queue.ContainerFromIndex(row).ShouldNotBeNull()
.GetVisualDescendants()
.OfType<TextBlock>()
.Single(text => text.Classes.Contains("transferstatus"))
.Text ?? string.Empty);
}
words.ShouldBe(expected);
}