feat: start adding pagination

This commit is contained in:
Anna 2024-01-03 23:23:09 -05:00
parent e47710b7eb
commit 4e29c174fe
Signed by: anna
GPG Key ID: D0943384CD9F87D1
3 changed files with 90 additions and 16 deletions

View File

@ -2,6 +2,7 @@ using System.Collections;
using System.Net.Http.Headers;
using Dalamud.Game.ClientState.Objects.Enums;
using EorzeaVotes.Model;
using EorzeaVotes.Utilities;
using Newtonsoft.Json;
namespace EorzeaVotes;
@ -10,8 +11,9 @@ internal class QuestionManager : IDisposable, IReadOnlyList<IQuestion> {
private Plugin Plugin { get; }
private HttpClient Http { get; }
private List<IQuestion> _questions = new();
private QuestionsResponse _questions = new();
private Guid _lastSeenActive = Guid.Empty;
private int _page = 1;
internal QuestionManager(Plugin plugin) {
this.Plugin = plugin;
@ -29,12 +31,34 @@ internal class QuestionManager : IDisposable, IReadOnlyList<IQuestion> {
this.Http.Dispose();
}
public int Count => this._questions.Count;
internal IQuestion? Current => this._questions.Current;
public IQuestion this[int index] => this._questions[index];
internal bool HasNext => this._questions.HasNext;
internal bool Loading { get; private set; }
internal int Page {
get => this._page;
set {
if (this.Loading) {
return;
}
this._page = Math.Max(1, value);
Task.Run(async () => {
this.Loading = true;
using var notLoading = new OnDispose(() => this.Loading = false);
await this.Check();
});
}
}
public int Count => this._questions.Page.Count;
public IQuestion this[int index] => this._questions.Page[index];
public IEnumerator<IQuestion> GetEnumerator() {
return this._questions.GetEnumerator();
return this._questions.Page.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
@ -102,12 +126,23 @@ internal class QuestionManager : IDisposable, IReadOnlyList<IQuestion> {
this.Plugin.SaveConfig();
}
[Serializable]
private class QuestionsResponse {
internal IQuestion? Current { get; init; }
internal List<IQuestion> Page { get; init; }
internal bool HasNext { get; init; }
}
internal async Task Check() {
await this.RegisterIfNecessary();
var req = this.MakeMessage(HttpMethod.Get, "/questions");
var req = this.MakeMessage(HttpMethod.Get, $"/questions?v=2&page={this._page}");
var resp = await this.Http.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
var json = await resp.Content.ReadAsStringAsync();
this._questions = JsonConvert.DeserializeObject<List<IQuestion>>(json, Plugin.SerializerSettings) ?? new List<IQuestion>();
this._questions = JsonConvert.DeserializeObject<QuestionsResponse>(json, Plugin.SerializerSettings) ?? new QuestionsResponse {
Current = null,
Page = new(),
HasNext = false,
};
await this.OpenIfNew();
}

View File

@ -175,4 +175,16 @@ internal static class ImGuiHelper {
ImGui.SetNextItemWidth(-1);
return drawInput(label);
}
internal static bool IconButton(FontAwesomeIcon icon, string? id = null) {
ImGui.PushFont(UiBuilder.IconFont);
using var pop = new OnDispose(ImGui.PopFont);
var label = icon.ToIconString();
if (id != null) {
label += id;
}
return ImGui.Button(label);
}
}

View File

@ -1,4 +1,5 @@
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using EorzeaVotes.Model;
using EorzeaVotes.Utilities;
@ -21,14 +22,14 @@ internal class QuestionsTab {
using var endTabItem = new OnDispose(ImGui.EndTabItem);
if (this.Plugin.Manager.Count == 0) {
if (this.Plugin.Manager.Current == null && this.Plugin.Manager.Count == 0) {
ImGuiHelpers.CenteredText("Fetching questions - please wait...");
return;
}
ImGuiHelpers.CenteredText("Active question");
var active = this.Plugin.Manager.FirstOrDefault(q => q.Active);
var active = this.Plugin.Manager.Current;
if (active == null) {
ImGui.TextUnformatted("There is no active question at the moment.");
} else {
@ -89,16 +90,42 @@ internal class QuestionsTab {
ImGui.PushTextWrapPos();
using var pop = new OnDispose(ImGui.PopTextWrapPos);
foreach (var question in this.Plugin.Manager) {
if (question.Active || question is not FullQuestion full) {
continue;
}
ImGui.TextUnformatted(full.Text);
full.DrawResponses();
this.DrawMoreDetailsButton(full);
var loading = this.Plugin.Manager.Loading;
if (loading) {
ImGui.TextUnformatted("Loading...");
ImGui.Spacing();
} else {
foreach (var question in this.Plugin.Manager) {
if (question.Active || question is not FullQuestion full) {
continue;
}
ImGui.TextUnformatted(full.Text);
full.DrawResponses();
this.DrawMoreDetailsButton(full);
ImGui.Spacing();
}
}
// page buttons
using (ImGuiHelper.WithDisabled(loading || this.Plugin.Manager.Page == 1)) {
if (ImGuiHelper.IconButton(FontAwesomeIcon.ArrowLeft)) {
this.Plugin.Manager.Page -= 1;
}
}
ImGui.SameLine();
ImGui.TextUnformatted($"{this.Plugin.Manager.Page:N0}");
ImGui.SameLine();
using (ImGuiHelper.WithDisabled(loading || !this.Plugin.Manager.HasNext)) {
if (ImGuiHelper.IconButton(FontAwesomeIcon.ArrowRight)) {
this.Plugin.Manager.Page += 1;
}
}
}
}