feat: start adding pagination
This commit is contained in:
parent
e47710b7eb
commit
4e29c174fe
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue