using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Interface; using Dalamud.Utility; using ImGuiNET; using Lumina.Excel.GeneratedSheets; using Newtonsoft.Json; using OrangeGuidanceTomestone.Helpers; namespace OrangeGuidanceTomestone.Ui.MainWindowTabs; internal class MessageList : ITab { public string Name => "Your messages"; private Plugin Plugin { get; } private SortMode Sort { get; set; } private SemaphoreSlim MessagesMutex { get; } = new(1, 1); private List Messages { get; } = new(); internal MessageList(Plugin plugin) { this.Plugin = plugin; } public void Dispose() { } public void Draw() { if (ImGui.Button("Refresh")) { this.Refresh(); } ImGui.SameLine(); if (ImGui.BeginCombo("Sort", $"{this.Sort}")) { foreach (var mode in Enum.GetValues()) { if (ImGui.Selectable($"{mode}", mode == this.Sort)) { this.Sort = mode; } } ImGui.EndCombo(); } this.MessagesMutex.Wait(); try { this.ShowList(); } finally { this.MessagesMutex.Release(); } } private void ShowList() { ImGui.TextUnformatted($"Messages: {this.Messages.Count:N0} / {10 + this.Plugin.Ui.MainWindow.ExtraMessages:N0}"); ImGui.Separator(); if (ImGui.BeginChild("##messages-list")) { var messages = this.Messages; if (this.Sort != SortMode.Date) { messages = messages.ToList(); messages.Sort((a, b) => { return this.Sort switch { SortMode.Date => 0, SortMode.Appraisals => Math.Max(b.PositiveVotes - b.NegativeVotes, 0) .CompareTo(Math.Max(a.PositiveVotes - a.NegativeVotes, 0)), SortMode.Likes => b.PositiveVotes.CompareTo(a.PositiveVotes), SortMode.Dislikes => b.NegativeVotes.CompareTo(a.NegativeVotes), SortMode.Location => a.Territory.CompareTo(b.Territory), _ => throw new ArgumentOutOfRangeException(), }; }); } foreach (var message in messages) { var territory = this.Plugin.DataManager.GetExcelSheet()?.GetRow(message.Territory); var territoryName = territory?.PlaceName.Value?.Name?.ToDalamudString().TextValue ?? "???"; var loc = $"Location: {territoryName}"; if (message.Ward != null) { loc += $" (Ward {message.Ward.Value}"; if (message.Plot != null) { if (message.Plot.Value >= 10_000) { var apartment = message.Plot.Value - 10_000; var wing = apartment < 5_000 ? 1 : 2; var apt = wing == 2 ? apartment - 5_000 : apartment; loc += $", Apt. {apt}, Wing {wing}"; } else { loc += $", Plot {message.Plot.Value}"; } } loc += ")"; } ImGui.TextUnformatted(message.Text); ImGui.TreePush(); ImGui.TextUnformatted(loc); ImGui.SameLine(); if (ImGuiHelper.SmallIconButton(FontAwesomeIcon.MapMarkerAlt, $"{message.Id}") && territory != null) { this.Plugin.GameGui.OpenMapWithMapLink(new MapLinkPayload( territory.RowId, territory.Map.Row, (int) (message.X * 1_000), (int) (message.Z * 1_000) )); } if (message.IsHidden) { ImGuiHelper.WarningText("This message will not be shown to other players due to its low score."); } var ctrl = ImGui.GetIO().KeyCtrl; var appraisals = Math.Max(0, message.PositiveVotes - message.NegativeVotes); ImGui.TextUnformatted($"Appraisals: {appraisals:N0} ({message.PositiveVotes:N0} - {message.NegativeVotes:N0})"); if (!ctrl) { ImGui.BeginDisabled(); } if (ImGui.Button($"Delete##{message.Id}")) { this.Delete(message.Id); } if (!ctrl) { ImGui.EndDisabled(); } ImGui.SameLine(); ImGuiHelper.HelpIcon("Hold Ctrl to enable the delete button."); ImGui.TreePop(); ImGui.Separator(); } } ImGui.EndChild(); } private void Refresh() { Task.Run(async () => { var resp = await ServerHelper.SendRequest( this.Plugin.Config.ApiKey, HttpMethod.Get, "/messages?v=2" ); var json = await resp.Content.ReadAsStringAsync(); var messages = JsonConvert.DeserializeObject(json)!; await this.MessagesMutex.WaitAsync(); try { this.Plugin.Ui.MainWindow.ExtraMessages = messages.Extra; this.Messages.Clear(); this.Messages.AddRange(messages.Messages); } finally { this.MessagesMutex.Release(); } }); } private void Delete(Guid id) { Task.Run(async () => { var resp = await ServerHelper.SendRequest( this.Plugin.Config.ApiKey, HttpMethod.Delete, $"/messages/{id}" ); if (resp.IsSuccessStatusCode) { this.Refresh(); this.Plugin.Vfx.RemoveStatic(id); this.Plugin.Messages.Remove(id); } }); } private enum SortMode { Date, Appraisals, Likes, Dislikes, Location, } }