From d1bfddd9b8645c1685a0503eb25a1b5081f8a8c2 Mon Sep 17 00:00:00 2001 From: Jon Kazama Date: Wed, 27 May 2026 23:29:18 +0200 Subject: [PATCH] feat(main-window): wire Lender + handler.Draw() (A2, MessageList popups) A2 completes the deferred Lender-cycle from A1 and addresses the handler.Draw() gap identified in I code-quality-review: - MainWindow ctor takes Lender as new param (DI-reg extended in PluginHostFactory); _handlerLender.ResetCounter() called at top of Draw() as primary pool-reset path (InputPreview has the secondary defensive fallback for MainWindow-closed edge case) - MessageList.DrawHandlerPopups() new passthrough method (=> _handler?.Draw()) provides the per-frame popup-tick that PayloadHandler needs to render the right-click context popup; MainWindow.Draw() calls it after the message-list body renders Without this fix, right-clicking a player/item/status in the chat log would silently fail to open a popup (handler.Draw() never fired for the MessageList's _handler). Phase 3 smoke steps 3/4/5 unblocked. Polish-Sweep + Smoke-Gate are the last cycle-tasks. --- HellionChat/PluginHostFactory.cs | 3 ++- HellionChat/Ui/Components/MessageList.cs | 4 ++++ HellionChat/Ui/Windows/MainWindow.cs | 10 +++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/HellionChat/PluginHostFactory.cs b/HellionChat/PluginHostFactory.cs index f56ffbd..c66290b 100644 --- a/HellionChat/PluginHostFactory.cs +++ b/HellionChat/PluginHostFactory.cs @@ -198,7 +198,8 @@ internal static class PluginHostFactory sp.GetRequiredService(), sp.GetRequiredService(), sp.GetRequiredService(), - sp.GetRequiredService() + sp.GetRequiredService(), + sp.GetRequiredService>() )); services.AddSingleton(sp => new Integrations.FailedTellNotifier( sp.GetRequiredService>() diff --git a/HellionChat/Ui/Components/MessageList.cs b/HellionChat/Ui/Components/MessageList.cs index 965d50a..049fce1 100644 --- a/HellionChat/Ui/Components/MessageList.cs +++ b/HellionChat/Ui/Components/MessageList.cs @@ -31,6 +31,10 @@ internal sealed class MessageList _handler = handler; } + // Delegates to PayloadHandler.Draw for per-frame popup tick; PayloadHandler.Draw doesn't auto-fire + // so MainWindow's draw loop must invoke it explicitly to render right-click context popups. + internal void DrawHandlerPopups() => _handler?.Draw(); + public MessageList( ThemeRegistry themes, TokenResolver resolver, diff --git a/HellionChat/Ui/Windows/MainWindow.cs b/HellionChat/Ui/Windows/MainWindow.cs index c1293ca..a434eb7 100644 --- a/HellionChat/Ui/Windows/MainWindow.cs +++ b/HellionChat/Ui/Windows/MainWindow.cs @@ -2,6 +2,7 @@ using System.Numerics; using Dalamud.Bindings.ImGui; using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Windowing; +using HellionChat.Util; namespace HellionChat.Ui.Windows; @@ -26,6 +27,7 @@ internal sealed class MainWindow : Window private readonly Components.MessageList _messages; private readonly Components.InputBar _input; private readonly Components.StatusBar _status; + private readonly Lender _handlerLender; private Tab? _activeTab; @@ -38,7 +40,8 @@ internal sealed class MainWindow : Window Components.Sidebar sidebar, Components.MessageList messages, Components.InputBar input, - Components.StatusBar status + Components.StatusBar status, + Lender handlerLender ) : base($"{Plugin.PluginName}###hellion-main") { @@ -47,6 +50,7 @@ internal sealed class MainWindow : Window _messages = messages; _input = input; _status = status; + _handlerLender = handlerLender; Size = new Vector2(DefaultWidth, DefaultHeight); SizeCondition = ImGuiCond.FirstUseEver; @@ -92,6 +96,9 @@ internal sealed class MainWindow : Window LastViewport = ImGui.GetWindowViewport().Handle; } + // Primary pool-reset path; InputPreview has a defensive fallback for the MainWindow-closed edge case. + _handlerLender.ResetCounter(); + // First-frame seed: the active tab defaults to the first persisted // tab so the message list isn't empty on a clean session. if (_activeTab is null && Plugin.Config.Tabs.Count > 0) @@ -105,6 +112,7 @@ internal sealed class MainWindow : Window DrawBody(); } + _messages.DrawHandlerPopups(); _status.Draw(_activeTab); }