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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
63bae2d1a6
commit
6c3202a0cf
@@ -243,6 +243,16 @@
|
|||||||
block-size: 100%;
|
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,
|
* 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.
|
* as it was typed — its line breaks kept and a long word or key wrapped rather than overflowing.
|
||||||
|
|||||||
@@ -94,25 +94,27 @@
|
|||||||
})"
|
})"
|
||||||
x-on:beforeunload.window="warnBeforeLeaving($event)"
|
x-on:beforeunload.window="warnBeforeLeaving($event)"
|
||||||
>
|
>
|
||||||
<x-list :label="__('Shared Files')">
|
<div class="share-file-list" data-test="share-file-list">
|
||||||
@foreach ($files as $file)
|
<x-list :label="__('Shared Files')">
|
||||||
<x-list-item
|
@foreach ($files as $file)
|
||||||
:title="$file->relative_path ?: $file->original_name"
|
<x-list-item
|
||||||
icon="description"
|
:title="$file->relative_path ?: $file->original_name"
|
||||||
wire:key="file-{{ $file->id }}"
|
icon="description"
|
||||||
>
|
wire:key="file-{{ $file->id }}"
|
||||||
<x-slot:description><span class="md-tabular">{{ Number::fileSize($file->file_size) }}</span></x-slot:description>
|
>
|
||||||
<x-slot:end>
|
<x-slot:description><span class="md-tabular">{{ Number::fileSize($file->file_size) }}</span></x-slot:description>
|
||||||
<x-row gap="space100">
|
<x-slot:end>
|
||||||
<span x-show="isDone({{ $file->id }})" x-cloak data-test="file-downloaded">
|
<x-row gap="space100">
|
||||||
<x-icon name="download_done" class="md-ink-success" :label="__('Downloaded')" />
|
<span x-show="isDone({{ $file->id }})" x-cloak data-test="file-downloaded">
|
||||||
</span>
|
<x-icon name="download_done" class="md-ink-success" :label="__('Downloaded')" />
|
||||||
<x-button icon="download" :link="route('share.download.file', [$share, $file])" no-wire-navigate :aria-label="__('Download :name', ['name' => $file->original_name])" x-on:click="downloaded = true; markDone({{ $file->id }})" />
|
</span>
|
||||||
</x-row>
|
<x-button icon="download" :link="route('share.download.file', [$share, $file])" no-wire-navigate :aria-label="__('Download :name', ['name' => $file->original_name])" x-on:click="downloaded = true; markDone({{ $file->id }})" />
|
||||||
</x-slot:end>
|
</x-row>
|
||||||
</x-list-item>
|
</x-slot:end>
|
||||||
@endforeach
|
</x-list-item>
|
||||||
</x-list>
|
@endforeach
|
||||||
|
</x-list>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div x-show="running || finished" x-cloak data-test="folder-download">
|
<div x-show="running || finished" x-cloak data-test="folder-download">
|
||||||
<x-stack gap="space100">
|
<x-stack gap="space100">
|
||||||
|
|||||||
@@ -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')
|
$page->assertSee('holiday/docs/notes.txt')
|
||||||
->assertNoJavaScriptErrors();
|
->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();
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user