Iceshrimp.NET/Iceshrimp.Frontend/Components/ScrollEnd.razor
2025-02-17 23:32:45 +01:00

67 lines
No EOL
2 KiB
Text

@using Ljbc1994.Blazor.IntersectionObserver.API
@using Ljbc1994.Blazor.IntersectionObserver.Components
<IntersectionObserve OnChange="entry => OnChange(entry)">
<div @ref="context.Ref.Current" class="@Class @(Hide ? "hidden" : "")" style="@Style">
@if (_state is State.Loading or State.Init)
{
<LoadingSpinner />
}
else
{
<button class="button" @onclick="Manual">Load more</button>
}
</div>
</IntersectionObserve>
@code {
[Parameter] [EditorRequired] public EventCallback IntersectionChange { get; set; }
[Parameter] [EditorRequired] public EventCallback ManualLoad { get; set; }
[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:
return;
case State.Waiting or State.Init:
_state = State.Loading;
await IntersectionChange.InvokeAsync();
break;
}
if (!RequireReset)
{
_state = State.Waiting;
}
} else if (entry.IsIntersecting == false)
{
Visible = false;
}
}
private async Task Manual()
{
await ManualLoad.InvokeAsync();
}
private enum State
{
Init,
Loading,
Waiting
}
public void Reset()
{
_state = State.Waiting;
}
}