From 6c3202a0cfa6e63b28a895e6a564b1bce35d8135 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Thu, 8 Oct 2026 22:40:34 +0200 Subject: [PATCH] Scroll a long file list on the download page on its own A share with hundreds of files made the download page as tall as its list, so the recipient scrolled far past the buttons. The list now sits in .share-file-list, capped at min(32rem, 60dvh) with its own scroll, as the upload page's selected-files list already is; the download buttons stay on the first screen. Co-Authored-By: Claude Opus 5.5 --- resources/css/app.css | 10 +++++ .../views/livewire/share-download.blade.php | 40 ++++++++++--------- tests/Browser/ShareFlowTest.php | 16 ++++++++ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/resources/css/app.css b/resources/css/app.css index 9115e00..569e7f8 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -243,6 +243,16 @@ block-size: 100%; } +/* + * resources/views/livewire/share-download.blade.php: a long file list scrolls on its own, as the + * upload page's does, so the download buttons stay near the top of the page. It is the page's main + * content, so it may take more of the window. + */ +.share-file-list { + max-block-size: min(32rem, 60dvh); + overflow-y: auto; +} + /* * resources/views/livewire/share-download.blade.php: the private text once the recipient shows it, * as it was typed — its line breaks kept and a long word or key wrapped rather than overflowing. diff --git a/resources/views/livewire/share-download.blade.php b/resources/views/livewire/share-download.blade.php index fb2fdd6..fdc1909 100644 --- a/resources/views/livewire/share-download.blade.php +++ b/resources/views/livewire/share-download.blade.php @@ -94,25 +94,27 @@ })" x-on:beforeunload.window="warnBeforeLeaving($event)" > - - @foreach ($files as $file) - - {{ Number::fileSize($file->file_size) }} - - - - - - - - - - @endforeach - +
diff --git a/tests/Browser/ShareFlowTest.php b/tests/Browser/ShareFlowTest.php index c2d7063..3e31a9e 100644 --- a/tests/Browser/ShareFlowTest.php +++ b/tests/Browser/ShareFlowTest.php @@ -297,3 +297,19 @@ test('Browse Folder picks a whole folder and keeps each file\'s path in it', fun $page->assertSee('holiday/docs/notes.txt') ->assertNoJavaScriptErrors(); }); + +test('a long file list scrolls on its own and keeps the download buttons on the first screen', function () { + $share = app(ShareService::class)->createShare(collect(range(1, 40))->map(fn (int $number): array => [ + 'file' => UploadedFile::fake()->createWithContent("file-{$number}.txt", "file {$number}"), + 'relativePath' => null, + ])->all()); + + $page = ready(visit(route('share.download', $share, false))->resize(1280, 800)); + + $page->assertScript("(() => { + const list = document.querySelector('[data-test=share-file-list]'); + return list.scrollHeight > list.clientHeight && getComputedStyle(list).overflowY === 'auto'; + })()") + ->assertScript("[...document.querySelectorAll('[data-md-button]')].filter((button) => button.offsetParent !== null && button.textContent.trim().toLowerCase().startsWith('download all')).every((button) => button.getBoundingClientRect().bottom <= window.innerHeight)") + ->assertNoJavaScriptErrors(); +});