[frontend/components] Hide virtual scroller ScrollEnd buttons when not needed
This commit is contained in:
parent
cd1973e000
commit
13495a692a
3 changed files with 54 additions and 9 deletions
|
@ -2,7 +2,7 @@
|
||||||
@using Ljbc1994.Blazor.IntersectionObserver.Components
|
@using Ljbc1994.Blazor.IntersectionObserver.Components
|
||||||
@using Iceshrimp.Assets.PhosphorIcons
|
@using Iceshrimp.Assets.PhosphorIcons
|
||||||
<IntersectionObserve OnChange="entry => OnChange(entry)">
|
<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)
|
@if (_state is State.Loading or State.Init)
|
||||||
{
|
{
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
|
@ -20,12 +20,15 @@
|
||||||
[Parameter] public string? Class { get; set; }
|
[Parameter] public string? Class { get; set; }
|
||||||
[Parameter] public bool RequireReset { get; init; }
|
[Parameter] public bool RequireReset { get; init; }
|
||||||
[Parameter] public string? Style { get; set; }
|
[Parameter] public string? Style { get; set; }
|
||||||
|
[Parameter] public bool Hide { get; set; } = false;
|
||||||
|
public bool Visible { get; private set; }
|
||||||
private State _state;
|
private State _state;
|
||||||
|
|
||||||
private async Task OnChange(IntersectionObserverEntry entry)
|
private async Task OnChange(IntersectionObserverEntry entry)
|
||||||
{
|
{
|
||||||
if (entry.IsIntersecting)
|
if (entry.IsIntersecting)
|
||||||
{
|
{
|
||||||
|
Visible = true;
|
||||||
switch (_state)
|
switch (_state)
|
||||||
{
|
{
|
||||||
case State.Loading:
|
case State.Loading:
|
||||||
|
@ -40,6 +43,9 @@
|
||||||
{
|
{
|
||||||
_state = State.Waiting;
|
_state = State.Waiting;
|
||||||
}
|
}
|
||||||
|
} else if (entry.IsIntersecting == false)
|
||||||
|
{
|
||||||
|
Visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
|
||||||
private bool _setScroll = false;
|
private bool _setScroll = false;
|
||||||
private bool _shouldRender = false;
|
private bool _shouldRender = false;
|
||||||
private bool _initialized = false;
|
private bool _initialized = false;
|
||||||
|
private bool _hideBefore = true;
|
||||||
|
|
||||||
private IDisposable? _locationChangeHandlerDisposable;
|
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(3, "ManualLoad", new EventCallback(this, CallbackBeforeAsync));
|
||||||
builder.AddComponentParameter(4, "RequireReset", true);
|
builder.AddComponentParameter(4, "RequireReset", true);
|
||||||
builder.AddComponentParameter(5, "Class", "virtual-scroller-button");
|
builder.AddComponentParameter(5, "Class", "virtual-scroller-button");
|
||||||
builder.AddComponentReferenceCapture(6,
|
builder.AddComponentParameter(6, "Hide", _hideBefore);
|
||||||
|
builder.AddComponentReferenceCapture(7,
|
||||||
reference =>
|
reference =>
|
||||||
Before = reference as ScrollEnd
|
Before = reference as ScrollEnd
|
||||||
?? throw new InvalidOperationException());
|
?? throw new InvalidOperationException());
|
||||||
|
@ -168,7 +170,18 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
|
||||||
}
|
}
|
||||||
|
|
||||||
var heightBefore = _module.Invoke<float>("GetDocumentHeight");
|
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)
|
if (res is not null && res.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var el in res)
|
foreach (var el in res)
|
||||||
|
@ -183,6 +196,12 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
|
||||||
var scroll = _module.Invoke<float>("GetScrollY");
|
var scroll = _module.Invoke<float>("GetScrollY");
|
||||||
_module.InvokeVoid("SetScrollY", scroll + diff);
|
_module.InvokeVoid("SetScrollY", scroll + diff);
|
||||||
}
|
}
|
||||||
|
else if (res?.Count == 0)
|
||||||
|
{
|
||||||
|
_hideBefore = true;
|
||||||
|
Logger.LogInformation("Hiding before");
|
||||||
|
ReRender();
|
||||||
|
}
|
||||||
|
|
||||||
Before.Reset();
|
Before.Reset();
|
||||||
}
|
}
|
||||||
|
@ -195,6 +214,7 @@ public class VirtualScroller<T> : ComponentBase, IDisposable where T : IIdentifi
|
||||||
var add = Items.TryAdd(item.Id, item);
|
var add = Items.TryAdd(item.Id, item);
|
||||||
if (add is false) Logger.LogError($"Duplicate notification: {item.Id}");
|
if (add is false) Logger.LogError($"Duplicate notification: {item.Id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
ReRender();
|
ReRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ button {
|
||||||
padding-inline: 1em;
|
padding-inline: 1em;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
.button:hover {
|
||||||
background-color: var(--hover-color);
|
background-color: var(--hover-color);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +128,7 @@ button {
|
||||||
input, textarea, select {
|
input, textarea, select {
|
||||||
display: block;
|
display: block;
|
||||||
background-color: var(--foreground-color);
|
background-color: var(--foreground-color);
|
||||||
border: solid var(--highlight-color) 0.05rem ;
|
border: solid var(--highlight-color) 0.05rem;
|
||||||
outline: none;
|
outline: none;
|
||||||
max-width: 50em;
|
max-width: 50em;
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
|
@ -286,7 +287,7 @@ code {
|
||||||
padding: 0.1em;
|
padding: 0.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre:has(code){
|
pre:has(code) {
|
||||||
background-color: #050507;
|
background-color: #050507;
|
||||||
color: #fff9e7;
|
color: #fff9e7;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
@ -304,8 +305,25 @@ pre:has(code){
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 3rem;
|
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 {
|
@keyframes spinner {
|
||||||
0% {
|
0% {
|
||||||
rotate: 0deg;
|
rotate: 0deg;
|
||||||
|
@ -322,7 +340,7 @@ pre:has(code){
|
||||||
animation: 3s spinner infinite;
|
animation: 3s spinner infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lazy-component-target-internal.visible{
|
.lazy-component-target-internal.visible {
|
||||||
transition: min-height 1s ease-in;
|
transition: min-height 1s ease-in;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
@ -330,10 +348,11 @@ pre:has(code){
|
||||||
.lazy-component-target-internal {
|
.lazy-component-target-internal {
|
||||||
min-height: var(--height);
|
min-height: var(--height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@Is supported in all browsers*/
|
/*@Is supported in all browsers*/
|
||||||
/*noinspection CssInvalidAtRule*/
|
/*noinspection CssInvalidAtRule*/
|
||||||
@starting-style {
|
@starting-style {
|
||||||
.lazy-component-target-internal.visible{
|
.lazy-component-target-internal.visible {
|
||||||
--height: 0px;
|
--height: 0px;
|
||||||
min-height: var(--height);
|
min-height: var(--height);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue