[frontend/components] Hide virtual scroller ScrollEnd buttons when not needed

This commit is contained in:
Lilian 2025-02-09 22:30:05 +01:00
parent cd1973e000
commit 13495a692a
No known key found for this signature in database
3 changed files with 54 additions and 9 deletions

View file

@ -2,7 +2,7 @@
@using Ljbc1994.Blazor.IntersectionObserver.Components
@using Iceshrimp.Assets.PhosphorIcons
<IntersectionObserve OnChange="entry => OnChange(entry)">
<div @ref="context.Ref.Current" class="@Class" style="@Style">
<div @ref="context.Ref.Current" class="@Class @(Hide ? "hidden" : "")" style="@Style">
@if (_state is State.Loading or State.Init)
{
<LoadingSpinner />
@ -20,12 +20,15 @@
[Parameter] public string? Class { get; set; }
[Parameter] public bool RequireReset { get; init; }
[Parameter] public string? Style { get; set; }
[Parameter] public bool Hide { get; set; } = false;
public bool Visible { get; private set; }
private State _state;
private async Task OnChange(IntersectionObserverEntry entry)
{
if (entry.IsIntersecting)
{
Visible = true;
switch (_state)
{
case State.Loading:
@ -40,6 +43,9 @@
{
_state = State.Waiting;
}
} else if (entry.IsIntersecting == false)
{
Visible = false;
}
}

View file

@ -40,6 +40,7 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
private bool _setScroll = false;
private bool _shouldRender = false;
private bool _initialized = false;
private bool _hideBefore = true;
private IDisposable? _locationChangeHandlerDisposable;
@ -111,7 +112,8 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
builder.AddComponentParameter(3, "ManualLoad", new EventCallback(this, CallbackBeforeAsync));
builder.AddComponentParameter(4, "RequireReset", true);
builder.AddComponentParameter(5, "Class", "virtual-scroller-button");
builder.AddComponentReferenceCapture(6,
builder.AddComponentParameter(6, "Hide", _hideBefore);
builder.AddComponentReferenceCapture(7,
reference =>
Before = reference as ScrollEnd
?? throw new InvalidOperationException());
@ -166,9 +168,20 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
Before.Reset();
return;
}
var heightBefore = _module.Invoke<float>("GetDocumentHeight");
var res = await ItemProvider(DirectionEnum.Newer, Items.First().Value);
var resTask = ItemProvider(DirectionEnum.Newer, Items.First().Value);
// Only show the spinner if ItemProvider takes more than 500ms to load, and the spinner is actually visible on screen.
await Task.WhenAny(Task.Delay(TimeSpan.FromMilliseconds(500)), resTask);
if (resTask.IsCompleted == false)
{
if (Before.Visible)
{
_hideBefore = false;
ReRender();
}
}
var res = await resTask;
if (res is not null && res.Count > 0)
{
foreach (var el in res)
@ -183,6 +196,12 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
var scroll = _module.Invoke<float>("GetScrollY");
_module.InvokeVoid("SetScrollY", scroll + diff);
}
else if (res?.Count == 0)
{
_hideBefore = true;
Logger.LogInformation("Hiding before");
ReRender();
}
Before.Reset();
}
@ -195,6 +214,7 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
var add = Items.TryAdd(item.Id, item);
if (add is false) Logger.LogError($"Duplicate notification: {item.Id}");
}
ReRender();
}

View file

@ -23,7 +23,7 @@
--notice-color: #92c1ff;
--font-color: #e7edff;
--link: #9E9EFF;
overscroll-behavior-y: none;
}
@ -115,6 +115,7 @@ button {
padding-inline: 1em;
align-items: center;
}
.button:hover {
background-color: var(--hover-color);
}
@ -127,7 +128,7 @@ button {
input, textarea, select {
display: block;
background-color: var(--foreground-color);
border: solid var(--highlight-color) 0.05rem ;
border: solid var(--highlight-color) 0.05rem;
outline: none;
max-width: 50em;
border-radius: 0.5em;
@ -286,7 +287,7 @@ code {
padding: 0.1em;
}
pre:has(code){
pre:has(code) {
background-color: #050507;
color: #fff9e7;
padding: 0.5rem;
@ -304,8 +305,25 @@ pre:has(code){
flex-direction: column;
align-items: center;
height: 3rem;
transition: height ease-out 250ms;
}
.virtual-scroller-button.hidden {
height: 0;
overflow: clip;
/*transition: height ease-out 250ms;*/
opacity: 0;
}
/*@Is supported in all browsers*/
/*noinspection CssInvalidAtRule*/
@starting-style {
.virtual-scroller-button {
height: 0;
}
}
@keyframes spinner {
0% {
rotate: 0deg;
@ -322,7 +340,7 @@ pre:has(code){
animation: 3s spinner infinite;
}
.lazy-component-target-internal.visible{
.lazy-component-target-internal.visible {
transition: min-height 1s ease-in;
min-height: 0;
}
@ -330,10 +348,11 @@ pre:has(code){
.lazy-component-target-internal {
min-height: var(--height);
}
/*@Is supported in all browsers*/
/*noinspection CssInvalidAtRule*/
@starting-style {
.lazy-component-target-internal.visible{
.lazy-component-target-internal.visible {
--height: 0px;
min-height: var(--height);
}