[frontend/components] Update NoteDetails to use PaginationWrapper
This commit is contained in:
parent
9cd2f4f530
commit
fb0586ecba
3 changed files with 133 additions and 39 deletions
|
@ -8,7 +8,7 @@
|
||||||
@if (State is State.Loaded)
|
@if (State is State.Loaded)
|
||||||
{
|
{
|
||||||
<div class="likes">
|
<div class="likes">
|
||||||
@if (LikedBy != null) @foreach (var el in LikedBy)
|
@foreach (var el in LikedBy)
|
||||||
{
|
{
|
||||||
<div @onclick="() => OpenProfile(el.Username, el.Host)" class="like-entry">
|
<div @onclick="() => OpenProfile(el.Username, el.Host)" class="like-entry">
|
||||||
<img class="icon" src="@el.AvatarUrl"/>
|
<img class="icon" src="@el.AvatarUrl"/>
|
||||||
|
@ -18,6 +18,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@if (EndReached == false)
|
||||||
|
{
|
||||||
|
<ScrollEnd IntersectionChange="LoadMore" ManualLoad="LoadMore"/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (State is State.Loading)
|
@if (State is State.Loading)
|
||||||
|
@ -33,13 +37,25 @@
|
||||||
@code {
|
@code {
|
||||||
[Parameter, EditorRequired] public required string NoteId { get; set; }
|
[Parameter, EditorRequired] public required string NoteId { get; set; }
|
||||||
private State State { get; set; }
|
private State State { get; set; }
|
||||||
private List<UserResponse>? LikedBy { get; set; } = [];
|
private List<UserResponse> LikedBy { get; set; } = [];
|
||||||
|
private PaginationData Pd { get; set; } = null!;
|
||||||
|
private bool EndReached { get; set; } = false;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LikedBy = await Api.Notes.GetNoteLikes(NoteId);
|
var pq = new PaginationQuery { Limit = 20 };
|
||||||
|
var res = await Api.Notes.GetNoteLikes(NoteId, pq);
|
||||||
|
if (res is null)
|
||||||
|
{
|
||||||
|
State = State.NotFound;
|
||||||
|
Logger.LogWarning($"Likes for '{NoteId}' not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.Links.Next is null) EndReached = true;
|
||||||
|
LikedBy = res.Data;
|
||||||
State = State.Loaded;
|
State = State.Loaded;
|
||||||
}
|
}
|
||||||
catch (ApiException e)
|
catch (ApiException e)
|
||||||
|
@ -49,6 +65,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<PaginationWrapper<List<UserResponse>>?> FetchMore(PaginationData data)
|
||||||
|
{
|
||||||
|
if (data.Next is null) return null;
|
||||||
|
var pq = new PaginationQuery { MaxId = data.Next?.Split('=')[1], Limit = 20 };
|
||||||
|
var res = await Api.Notes.GetNoteLikes(NoteId, pq);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadMore()
|
||||||
|
{
|
||||||
|
if (EndReached) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var res = await FetchMore(Pd);
|
||||||
|
if (res is null)
|
||||||
|
{
|
||||||
|
EndReached = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pd = res.Links;
|
||||||
|
LikedBy.AddRange(res.Data);
|
||||||
|
}
|
||||||
|
catch (ApiException e)
|
||||||
|
{
|
||||||
|
Logger.LogError(e, $"Failed to load likes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OpenProfile(string username, string? host)
|
private void OpenProfile(string username, string? host)
|
||||||
{
|
{
|
||||||
var path = $"@{username}";
|
var path = $"@{username}";
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<Note NoteResponse="el"/>
|
<Note NoteResponse="el"/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (_end is false)
|
@if (EndReached is false)
|
||||||
{
|
{
|
||||||
<ScrollEnd ManualLoad="LoadMore" IntersectionChange="LoadMore"/>
|
<ScrollEnd ManualLoad="LoadMore" IntersectionChange="LoadMore"/>
|
||||||
}
|
}
|
||||||
|
@ -26,27 +26,24 @@
|
||||||
[Parameter, EditorRequired] public required string NoteId { get; set; }
|
[Parameter, EditorRequired] public required string NoteId { get; set; }
|
||||||
private State State { get; set; }
|
private State State { get; set; }
|
||||||
private List<NoteResponse> Quotes { get; set; } = [];
|
private List<NoteResponse> Quotes { get; set; } = [];
|
||||||
private string? _minId;
|
private PaginationData Pd { get; set; } = null!;
|
||||||
private string? _maxId;
|
private bool EndReached { get; set; } = false;
|
||||||
private bool _end = false;
|
|
||||||
private int _limit = 40;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var res = await Api.Notes.GetQuotes(NoteId, new PaginationQuery { Limit = _limit });
|
var res = await Api.Notes.GetQuotes(NoteId, new PaginationQuery { Limit = 20 });
|
||||||
if (res is not null && res.Count > 0)
|
if (res is null)
|
||||||
{
|
{
|
||||||
Quotes = res;
|
State = State.NotFound;
|
||||||
_minId = Quotes.Last().Id;
|
Logger.LogWarning($"Quotes for '{NoteId}' not found.");
|
||||||
_maxId = Quotes.First().Id;
|
return;
|
||||||
if (res.Count < _limit)
|
|
||||||
{
|
|
||||||
_end = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.Links.Next is null) EndReached = true;
|
||||||
|
Quotes = res.Data;
|
||||||
|
Pd = res.Links;
|
||||||
State = State.Loaded;
|
State = State.Loaded;
|
||||||
}
|
}
|
||||||
catch (ApiException e)
|
catch (ApiException e)
|
||||||
|
@ -56,26 +53,32 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void LoadMore()
|
private async Task<PaginationWrapper<List<NoteResponse>>?> FetchMore(PaginationData data)
|
||||||
{
|
{
|
||||||
var pq = new PaginationQuery { MaxId = _minId, Limit = 40 };
|
if (data.Next is null) return null;
|
||||||
|
var pq = new PaginationQuery { MaxId = data.Next?.Split('=')[1], Limit = 20 };
|
||||||
|
var res = await Api.Notes.GetQuotes(NoteId, pq);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadMore()
|
||||||
|
{
|
||||||
|
if (EndReached) return;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var res = await Api.Notes.GetQuotes(NoteId, pq);
|
var res = await FetchMore(Pd);
|
||||||
if (res is null) return; // If server returns null here, the note was likely deleted.
|
if (res is null)
|
||||||
if (res.Count < 1)
|
|
||||||
{
|
{
|
||||||
_end = true;
|
EndReached = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.Count < _limit) _end = true;
|
Pd = res.Links;
|
||||||
_minId = res.Last().Id;
|
Quotes.AddRange(res.Data);
|
||||||
Quotes.AddRange(res);
|
|
||||||
}
|
}
|
||||||
catch (ApiException e)
|
catch (ApiException e)
|
||||||
{
|
{
|
||||||
Logger.LogError(e, "Failed to load more quotes");
|
Logger.LogError(e, "Failed to load Quotes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
@if (State is State.Loaded)
|
@if (State is State.Loaded)
|
||||||
{
|
{
|
||||||
<div class="renotes">
|
<div class="renotes">
|
||||||
@if (RenotedBy != null) @foreach (var el in RenotedBy)
|
@foreach (var el in RenotedBy)
|
||||||
{
|
{
|
||||||
<div @onclick="() => OpenProfile(el.Username, el.Host)" class="renote-entry">
|
<div @onclick="() => OpenProfile(el.Username, el.Host)" class="renote-entry">
|
||||||
<img class="icon" src="@el.AvatarUrl"/>
|
<img class="icon" src="@el.AvatarUrl"/>
|
||||||
|
@ -18,6 +18,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@if (EndReached == false)
|
||||||
|
{
|
||||||
|
<ScrollEnd IntersectionChange="LoadMore" ManualLoad="LoadMore"/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (State is State.Loading)
|
@if (State is State.Loading)
|
||||||
|
@ -33,13 +37,26 @@
|
||||||
@code {
|
@code {
|
||||||
[Parameter, EditorRequired] public required string NoteId { get; set; }
|
[Parameter, EditorRequired] public required string NoteId { get; set; }
|
||||||
private State State { get; set; }
|
private State State { get; set; }
|
||||||
private List<UserResponse>? RenotedBy { get; set; } = [];
|
private List<UserResponse> RenotedBy { get; set; } = [];
|
||||||
|
private PaginationData Pd { get; set; } = null!;
|
||||||
|
private bool EndReached { get; set; }
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RenotedBy = await Api.Notes.GetRenotes(NoteId);
|
var pq = new PaginationQuery { Limit = 20 };
|
||||||
|
var res = await Api.Notes.GetRenotes(NoteId, pq);
|
||||||
|
if (res is null)
|
||||||
|
{
|
||||||
|
State = State.NotFound;
|
||||||
|
Logger.LogWarning($"Renotes for '{NoteId}' not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.Links.Next is null) EndReached = true;
|
||||||
|
RenotedBy = res.Data;
|
||||||
|
Pd = res.Links;
|
||||||
State = State.Loaded;
|
State = State.Loaded;
|
||||||
}
|
}
|
||||||
catch (ApiException e)
|
catch (ApiException e)
|
||||||
|
@ -49,6 +66,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<PaginationWrapper<List<UserResponse>>?> FetchMore(PaginationData data)
|
||||||
|
{
|
||||||
|
if (data.Next is null) return null;
|
||||||
|
var pq = new PaginationQuery { MaxId = data.Next?.Split('=')[1], Limit = 20 };
|
||||||
|
var res = await Api.Notes.GetRenotes(NoteId, pq);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadMore()
|
||||||
|
{
|
||||||
|
if (EndReached) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var res = await FetchMore(Pd);
|
||||||
|
if (res is null)
|
||||||
|
{
|
||||||
|
EndReached = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pd = res.Links;
|
||||||
|
RenotedBy.AddRange(res.Data);
|
||||||
|
}
|
||||||
|
catch (ApiException e)
|
||||||
|
{
|
||||||
|
Logger.LogError(e, "Failed to load renotes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OpenProfile(string username, string? host)
|
private void OpenProfile(string username, string? host)
|
||||||
{
|
{
|
||||||
var path = $"@{username}";
|
var path = $"@{username}";
|
||||||
|
|
Loading…
Add table
Reference in a new issue