feat(sidebar): restore per-tab greeted toggle glyph

This commit is contained in:
2026-06-10 14:59:51 +02:00
parent 1f2c354471
commit 540cb7ac52
3 changed files with 186 additions and 3 deletions
@@ -0,0 +1,103 @@
using Dalamud.Bindings.ImGui;
using Dalamud.Plugin.SelfTest;
using HellionChat.Code;
using HellionChat.GameFunctions.Types;
namespace HellionChat.SelfTests;
// B3-2: greeted glyph renders only for temp tabs when the toggle is on. Drives
// the REAL Sidebar.Draw (render precedent: HonorificHeaderRenderStep, the only
// real .Draw in this pool — NOT SidebarModeAutoSwitchStep which only calls
// IsExpanded/GetWidth) inside the /xlperf window frame and reads the render
// observability counter, then drives the real toggle hook both ways. Injects
// a temp tab and restores config in finally.
internal sealed class SidebarGreetedGlyphStep : ISelfTestStep
{
private readonly Plugin plugin;
public SidebarGreetedGlyphStep(Plugin plugin) => this.plugin = plugin;
public string Name => "Hellion Chat - Sidebar greeted glyph";
public SelfTestStepResult RunStep()
{
var sidebar = plugin.MainWindow.GetSidebarForSelfTest();
if (sidebar is null)
{
ImGui.Text("Sidebar null");
return SelfTestStepResult.Fail;
}
var savedFlag = Plugin.Config.AutoTellTabsShowGreetedToggle;
var savedSidebarWidth = Plugin.Config.SidebarWidth;
// Mirror of AutoTellTabsService.BuildTempTab (the real builder is
// private); only the sheet-based tab name is replaced with a literal.
var injected = new Tab
{
Name = "Greeted Probe@SelfTest",
IsTempTab = true,
AllSenderMessages = true,
TellTarget = new TellTarget("Greeted Probe", 0, 0, TellReason.Direct),
Channel = InputChannel.Tell,
DisplayTimestamp = true,
UnreadMode = UnreadMode.Unseen,
HideWhenInactive = false,
SelectedChannels = new Dictionary<ChatType, (ChatSource, ChatSource)>
{
[ChatType.TellIncoming] = (ChatSourceExt.All, ChatSourceExt.All),
[ChatType.TellOutgoing] = (ChatSourceExt.All, ChatSourceExt.All),
},
};
Plugin.Config.Tabs.Add(injected);
Tab? active = null;
var width = (float)Plugin.Config.SidebarAutoSwitchThresholdPx + 100f; // expanded
try
{
Plugin.Config.AutoTellTabsShowGreetedToggle = true;
// Default SidebarWidth (44px) has no room for the third hit area;
// pin a wide value so the glyph branch is reachable, restore after.
Plugin.Config.SidebarWidth = 220;
sidebar.Draw(width, Plugin.Config.Tabs, ref active);
if (sidebar.LastRenderedGreetedGlyphCount == 0)
{
ImGui.Text("No greeted glyph drawn with flag ON");
return SelfTestStepResult.Fail;
}
Plugin.Config.AutoTellTabsShowGreetedToggle = false;
sidebar.Draw(width, Plugin.Config.Tabs, ref active);
if (sidebar.LastRenderedGreetedGlyphCount != 0)
{
ImGui.Text("Greeted glyph drawn with flag OFF");
return SelfTestStepResult.Fail;
}
// Drive the same hook DrawRow's click handler uses (the real toggle
// path, not a direct MarkGreeted call) and assert the flip both ways.
sidebar.ToggleGreetedForSelfTest(injected);
if (!plugin.AutoTellTabsService.IsGreeted(injected))
{
ImGui.Text("Toggle did not mark the tab greeted");
return SelfTestStepResult.Fail;
}
sidebar.ToggleGreetedForSelfTest(injected);
if (plugin.AutoTellTabsService.IsGreeted(injected))
{
ImGui.Text("Toggle did not unmark the tab greeted");
return SelfTestStepResult.Fail;
}
}
finally
{
Plugin.Config.Tabs.Remove(injected);
Plugin.Config.AutoTellTabsShowGreetedToggle = savedFlag;
Plugin.Config.SidebarWidth = savedSidebarWidth;
}
return SelfTestStepResult.Pass;
}
public void CleanUp() { }
}