livia-test/Livia/ViewModels/PagingControlViewModel.cs
2025-03-28 14:31:53 +08:00

100 lines
2.5 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using Livia.Utility;
namespace Livia.ViewModels;
public interface IPagingControlRecipient
{
public Task<bool> Refresh();
}
public class PagingControlViewModel : ObservableObject
{
public int Offset => (CurrentPage - 1) * ItemPerPage;
public int PageCount { get => _pageCount; private set => SetProperty(ref _pageCount, value); }
public int TotalCount { get => _totalCount; private set => SetProperty(ref _totalCount, value); }
//TODO::Bind to string instead. Currently empty space will trigger error.
public int CurrentPage
{
get => _currentPage;
set
{
int newValue = Math.Clamp(value, 1, PageCount);
SetProperty(ref _currentPage, newValue);
}
}
public bool Processing { get => _processing; private set => SetProperty(ref _processing, value); }
private bool _processing;
private int _pageCount = 1;
private int _totalCount;
private int _currentPage = 1;
private IPagingControlRecipient? _recipient;
private readonly DebounceHelper _updateServerJobListBounceHelper = new(TimeSpan.FromSeconds(0.5));
//default to 8
public const int ItemPerPage = 8;
public void SetRecipient(IPagingControlRecipient recipient)
{
_recipient = recipient;
}
public void SetItemNumber(int n)
{
PageCount = Math.Max(1, 1 + (n - 1) / ItemPerPage);
TotalCount = n;
}
private async Task TryJumpTo(int n)
{
if (!_updateServerJobListBounceHelper.TryFire())
return;
Processing = true;
int oldValue = CurrentPage;
CurrentPage = n;
if (_recipient != null && !await _recipient.Refresh().ConfigureAwait(false))
{
CurrentPage = oldValue;
}
Processing = false;
}
public Task First()
{
return TryJumpTo(1);
}
public Task Previous()
{
return TryJumpTo(CurrentPage - 1);
}
public Task Next()
{
return TryJumpTo(CurrentPage + 1);
}
public Task Last()
{
return TryJumpTo(PageCount);
}
public Task Refresh()
{
return TryJumpTo(CurrentPage);
}
public void RefreshCurrentPage()
{
int deletePageCount = TotalCount - 1; // delete after page count
int maxPage = Math.Max(1, 1 + (deletePageCount - 1) / ItemPerPage); // delete after max page
if (this.CurrentPage > maxPage)
{
this.CurrentPage = maxPage;
}
}
}