Neighbourhood.omg.lol/Components/PicList.razor

74 lines
No EOL
2 KiB
Text

@inject IJSRuntime JS
@inject State State
@implements IDisposable
@if (Editable) {
<EditPicDialog @ref="Dialog" id="EditPicModal"></EditPicDialog>
}
@if (pics != null) foreach (Pic pic in pics) {
<PicCard Pic="pic" Editable="Editable" Dialog="Dialog"></PicCard>
}
<LoadingCard id="pics-loading" icon="fa-solid fa-images"></LoadingCard>
@code {
[Parameter]
public Func<bool, Task<List<Pic>?>> PicsFunc { get; set; }
[Parameter]
public bool Editable { get; set; } = false;
public EditPicDialog? Dialog { get; set; }
private List<Pic>? pics;
private int count { get; set; } = 0;
private int pageSize { get; } = 10;
// TODO: There is a noticable rendering delay between the pics loading and the page rendering
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
State.PropertyChanged += StateChanged;
State.CanRefresh = true;
if (pics == null || pics.Count == 0) await LoadNext();
await JS.InvokeVoidAsync("removeElementById", "pics-loading");
}
public async Task<bool> PullUp() {
int countBefore = count;
await LoadNext();
return (count != countBefore);
}
public async Task LoadNext(bool forceRefresh = false) {
if (pics == null) pics = new List<Pic>();
if (forceRefresh) {
count = 0;
pics.Clear();
}
var allPics = await PicsFunc(forceRefresh);
if(allPics != null && count < allPics.Count) {
pics.AddRange(allPics.Skip(count).Take(pageSize));
count = pics.Count;
}
await InvokeAsync(StateHasChanged);
}
private async void StateChanged(object? sender, PropertyChangedEventArgs e) {
if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) {
await LoadNext(true);
State.IsRefreshing = false;
}
if (e.PropertyName == nameof(State.AtBottom) && State.AtBottom) {
await LoadNext();
}
}
public void Dispose() {
State.PropertyChanged -= StateChanged;
State.CanRefresh = false;
}
}