Files
HellionChat/HellionChat/Ui/Components/Settings/Tabs/DataPrivacyTab.cs
T
JonKazama-Hellion f999036e50 refactor(settings): merge the duplicated tab helpers
Six tabs carried a byte-identical DrawToggle, four a byte-identical slider, and
five hand-rolled the same enum combo loop. 281 lines out, 82 in.

The combos were not only duplicated, they were wasteful: each one called
Enum.GetValues inside Draw, so every open settings window allocated five arrays
per frame for sets that cannot change at runtime. EnumValues<T> reads them once
per closed generic, and the label array is one buffer shared by all of them.

Two behaviours are now uniform rather than accidental. The range check on the
selected index existed in exactly one of the five and is now in all of them,
and the tell auto-open combo lost its inline literal array in favour of a Name
extension like its seven peers -- still English, but at least in the place the
localisation pass will look.

SettingsWidgets is constructed by each tab rather than injected. The tabs are DI
singletons and a seventh constructor signature change buys nothing here.

One visible difference: the tell auto-open combo was 220px wide against 200 for
every other combo in the window. It is 200 now.
2026-08-18 13:42:21 +02:00

99 lines
3.5 KiB
C#

using Dalamud.Bindings.ImGui;
using HellionChat.Code;
namespace HellionChat.Ui.Components.Settings.Tabs;
internal sealed class DataPrivacyTab
{
private readonly Plugin _plugin;
private readonly SettingsWidgets _w;
public DataPrivacyTab(Plugin plugin)
{
_plugin = plugin;
_w = new SettingsWidgets(plugin);
}
public void Draw()
{
if (ImGui.CollapsingHeader("Logging", ImGuiTreeNodeFlags.DefaultOpen))
{
_w.Toggle(
"Enable retention sweep",
() => Plugin.Config.RetentionEnabled,
v => Plugin.Config.RetentionEnabled = v
);
_w.SliderInt(
"Default retention (days)",
() => Plugin.Config.RetentionDefaultDays,
v => Plugin.Config.RetentionDefaultDays = v,
1,
365
);
// RetentionLastRunAt defaults to MinValue on a fresh install, which
// would render as "0001-01-01 00:00" and look like a bug; the "Never"
// sentinel handles that. Disabling the sweep does NOT reset the
// timestamp — the historical last-run value is kept as informational
// carry-over until the next sweep updates it.
var lastRun =
Plugin.Config.RetentionLastRunAt == DateTimeOffset.MinValue
? "Never"
: Plugin.Config.RetentionLastRunAt.ToLocalTime().ToString("yyyy-MM-dd HH:mm");
ImGui.TextDisabled($"Last run: {lastRun}");
}
if (ImGui.CollapsingHeader("Privacy filter", ImGuiTreeNodeFlags.DefaultOpen))
{
_w.Toggle(
"Enable privacy filter",
() => Plugin.Config.PrivacyFilterEnabled,
v => Plugin.Config.PrivacyFilterEnabled = v
);
DrawPrivacyPersistChannelsGrid();
_w.Toggle(
"Persist unknown channels",
() => Plugin.Config.PrivacyPersistUnknownChannels,
v => Plugin.Config.PrivacyPersistUnknownChannels = v
);
}
if (ImGui.CollapsingHeader("Telemetry"))
{
// Read-only placeholder; no telemetry is wired in v1.7.0. Do not
// promote this to a toggle without an explicit Sub-Spec change.
ImGui.TextUnformatted("No telemetry is collected.");
}
}
private void DrawPrivacyPersistChannelsGrid()
{
// HashSet<ChatType>: iterate Enum.GetValues<ChatType>() for stable
// display order (HashSet itself has none); toggle membership via
// Contains/Add/Remove.
ImGui.TextUnformatted("Persist channels:");
foreach (var ct in Enum.GetValues<ChatType>())
{
var label = ct.ToString();
var present = Plugin.Config.PrivacyPersistChannels.Contains(ct);
if (ImGui.Checkbox($"{label}##privacy-persist-{label}", ref present))
{
// Lock closes before SaveConfig: taking ConfigMapsLock across a save
// would invert the lock order (SaveConfig can reach TabsListLock).
lock (_plugin.ConfigMapsLock)
{
if (present)
{
Plugin.Config.PrivacyPersistChannels.Add(ct);
}
else
{
Plugin.Config.PrivacyPersistChannels.Remove(ct);
}
}
_plugin.SaveConfig();
}
}
}
}