feat(settings): add Data & Privacy tab with retention and filter

This commit is contained in:
2026-05-26 20:05:52 +02:00
parent 0512d4c9d2
commit 262fb3022a
3 changed files with 126 additions and 0 deletions
+3
View File
@@ -180,6 +180,9 @@ internal static class PluginHostFactory
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.ChannelsTab(
sp.GetRequiredService<Plugin>()
));
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.DataPrivacyTab(
sp.GetRequiredService<Plugin>()
));
services.AddSingleton(sp => new Ui.Components.StatusBar(
sp.GetRequiredService<ThemeRegistry>(),
sp.GetRequiredService<FontManager>()
@@ -0,0 +1,117 @@
using Dalamud.Bindings.ImGui;
using HellionChat.Code;
namespace HellionChat.Ui.Components.Settings.Tabs;
internal sealed class DataPrivacyTab
{
private readonly Plugin _plugin;
public DataPrivacyTab(Plugin plugin)
{
_plugin = plugin;
}
public void Draw()
{
if (ImGui.CollapsingHeader("Logging", ImGuiTreeNodeFlags.DefaultOpen))
{
DrawToggle(
"Print changelog on update",
() => Plugin.Config.PrintChangelog,
v => Plugin.Config.PrintChangelog = v
);
DrawToggle(
"Enable retention sweep",
() => Plugin.Config.RetentionEnabled,
v => Plugin.Config.RetentionEnabled = v
);
DrawSliderInt(
"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))
{
DrawToggle(
"Enable privacy filter",
() => Plugin.Config.PrivacyFilterEnabled,
v => Plugin.Config.PrivacyFilterEnabled = v
);
DrawPrivacyPersistChannelsGrid();
DrawToggle(
"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))
{
if (present)
{
Plugin.Config.PrivacyPersistChannels.Add(ct);
}
else
{
Plugin.Config.PrivacyPersistChannels.Remove(ct);
}
_plugin.SaveConfig();
}
}
}
private void DrawToggle(string label, Func<bool> get, Action<bool> set)
{
var current = get();
if (ImGui.Checkbox(label, ref current))
{
set(current);
_plugin.SaveConfig();
}
}
private void DrawSliderInt(string label, Func<int> get, Action<int> set, int min, int max)
{
var current = get();
ImGui.SetNextItemWidth(200);
if (ImGui.SliderInt(label, ref current, min, max, "%d"))
{
set(current);
_plugin.SaveConfig();
}
}
}
+6
View File
@@ -24,6 +24,7 @@ internal sealed class SettingsWindow : Window
private readonly ChatTab _chat;
private readonly WindowTab _window;
private readonly ChannelsTab _channels;
private readonly DataPrivacyTab _dataPrivacy;
public SettingsWindow(
Plugin plugin,
@@ -37,6 +38,7 @@ internal sealed class SettingsWindow : Window
ChatTab chat,
WindowTab window,
ChannelsTab channels,
DataPrivacyTab dataPrivacy,
ILoggerFactory loggerFactory
)
: base($"{Language.Settings_Title.Format(Plugin.PluginName)}###chat2-settings")
@@ -52,6 +54,7 @@ internal sealed class SettingsWindow : Window
_chat = chat;
_window = window;
_channels = channels;
_dataPrivacy = dataPrivacy;
_ = loggerFactory;
Size = new Vector2(720, 540);
@@ -92,6 +95,9 @@ internal sealed class SettingsWindow : Window
case "channels":
_channels.Draw();
break;
case "data-privacy":
_dataPrivacy.Draw();
break;
case "appearance":
_appearance.Draw();
break;