diff --git a/src/Component/BlazorComponent/Components/InfiniteScroll/BInfiniteScroll.razor b/src/Component/BlazorComponent/Components/InfiniteScroll/BInfiniteScroll.razor deleted file mode 100644 index b84edb361..000000000 --- a/src/Component/BlazorComponent/Components/InfiniteScroll/BInfiniteScroll.razor +++ /dev/null @@ -1,61 +0,0 @@ -@namespace BlazorComponent -@inherits BDomComponentBase - -
- @if (ChildContent != null) - { - @ChildContent((_loadStatus, CreateEventCallback(DoLoadMore))) - } - else - { - if (_loadStatus == InfiniteScrollLoadStatus.Empty) - { - @if (EmptyContent != null) - { - @EmptyContent - } - else - { - @EmptyText - } - } - else if (_loadStatus == InfiniteScrollLoadStatus.Loading) - { - @if (LoadingContent != null) - { - @LoadingContent - } - else - { - @LoadingText - - } - } - else if (_loadStatus == InfiniteScrollLoadStatus.Error) - { - if (ErrorContent != null) - { - @ErrorContent.Invoke(DoLoadMore) - } - else - { - @ErrorText - - - $retry - - } - } - else - { - @if (LoadMoreContent != null) - { - @LoadMoreContent.Invoke(DoLoadMore) - } - else - { - @LoadMoreText - } - } - } -
diff --git a/src/Component/BlazorComponent/Components/InfiniteScroll/BInfiniteScroll.razor.cs b/src/Component/BlazorComponent/Components/InfiniteScroll/BInfiniteScroll.razor.cs deleted file mode 100644 index 42ff629a2..000000000 --- a/src/Component/BlazorComponent/Components/InfiniteScroll/BInfiniteScroll.razor.cs +++ /dev/null @@ -1,176 +0,0 @@ -using BlazorComponent.JSInterop; - -namespace BlazorComponent; - -public partial class BInfiniteScroll : BDomComponentBase, IAsyncDisposable -{ - [Parameter, EditorRequired] - public EventCallback OnLoad { get; set; } - - /// - /// The parent element that has overflow style. - /// - [Parameter, EditorRequired] - public OneOf? Parent { get; set; } - - [Parameter] - public string? Color { get; set; } - - [Parameter] - public bool Manual - { - get => GetValue(); - set => SetValue(value); - } - - [Parameter] - [MasaApiParameter(250)] - public StringNumber Threshold { get; set; } = 250; - - [Parameter] - public RenderFragment<(InfiniteScrollLoadStatus Status, EventCallback OnLoad)>? ChildContent { get; set; } - - [Parameter] - public string? EmptyText { get; set; } - - [Parameter] - public string? LoadingText { get; set; } - - [Parameter] - public string? LoadMoreText { get; set; } - - [Parameter] - public string? ErrorText { get; set; } - - [Parameter] - public RenderFragment? EmptyContent { get; set; } - - [Parameter] - public RenderFragment>? ErrorContent { get; set; } - - [Parameter] - public RenderFragment? LoadingContent { get; set; } - - [Parameter] - public RenderFragment>? LoadMoreContent { get; set; } - - private bool _isAttached; - private string? _parentSelector; - private InfiniteScrollLoadStatus _loadStatus; - - protected override void RegisterWatchers(PropertyWatcher watcher) - { - base.RegisterWatchers(watcher); - - watcher.Watch(nameof(Manual), ManualChangeCallback); - } - - private async void ManualChangeCallback(bool val) - { - if (val) - { - await AddScrollListener(); - } - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - await DoLoadMore(); - - NextTick(async () => { await AddScrollListener(); }); - StateHasChanged(); - } - } - - private async Task AddScrollListener() - { - if (!_isAttached && Parent is { Value: not null }) - { - string? selector = null; - - if (Parent.Value.IsT0 && Parent.Value.AsT0.Id is not null) - { - selector = Parent.Value.AsT0.GetSelector(); - } - else if (Parent.Value.IsT1) - { - selector = Parent.Value.AsT1; - } - - if (selector is null) - { - return; - } - - _isAttached = true; - _parentSelector = selector; - - await Js.AddHtmlElementEventListener(selector, "scroll", OnScroll, false, new EventListenerExtras(0, 100)); - } - } - - private async Task OnScroll() - { - if (_parentSelector is null || Manual || !OnLoad.HasDelegate || _loadStatus == InfiniteScrollLoadStatus.Empty) - { - return; - } - - if (_loadStatus is InfiniteScrollLoadStatus.Error or InfiniteScrollLoadStatus.Empty or InfiniteScrollLoadStatus.Loading) - { - return; - } - - // OPTIMIZE: Combine scroll event and the following js interop. - var exceeded = await JsInvokeAsync(JsInteropConstants.CheckIfThresholdIsExceededWhenScrolling, Ref, _parentSelector, - Threshold.ToDouble()); - if (!exceeded) - { - return; - } - - await DoLoadMore(); - StateHasChanged(); - } - - private async Task DoLoadMore() - { - _loadStatus = InfiniteScrollLoadStatus.Loading; - - var eventArgs = new InfiniteScrollLoadEventArgs(); - - try - { - await OnLoad.InvokeAsync(eventArgs); - _loadStatus = eventArgs.Status; - } - catch (Exception e) - { - _loadStatus = InfiniteScrollLoadStatus.Error; - - Logger.LogWarning(e, "Failed to load more"); - StateHasChanged(); - } - } - - async ValueTask IAsyncDisposable.DisposeAsync() - { - try - { - if (_parentSelector is null) - { - return; - } - - await Js.RemoveHtmlElementEventListener(_parentSelector, "scroll"); - } - catch (Exception) - { - // ignored - } - } -} diff --git a/src/Component/BlazorComponent/Components/InfiniteScroll/InfiniteScrollLoadEventArgs.cs b/src/Component/BlazorComponent/Components/InfiniteScroll/InfiniteScrollLoadEventArgs.cs deleted file mode 100644 index 90072412b..000000000 --- a/src/Component/BlazorComponent/Components/InfiniteScroll/InfiniteScrollLoadEventArgs.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace BlazorComponent; - -public class InfiniteScrollLoadEventArgs : EventArgs -{ - /// - /// The load status of infinite scroll. - /// - public InfiniteScrollLoadStatus Status { get; set; } -} - -public enum InfiniteScrollLoadStatus -{ - /// - /// Content was loaded successfully. - /// - Ok, - /// - /// Something went wrong when loading content. - /// - Error, - /// - /// There is no more content to load. - /// - Empty, - /// - /// Content is currently loading. - /// This status should only be set internally by the component. - /// - Loading -}