feat(settings): add Data & Privacy tab with retention and filter
This commit is contained in:
@@ -180,6 +180,9 @@ internal static class PluginHostFactory
|
|||||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.ChannelsTab(
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.ChannelsTab(
|
||||||
sp.GetRequiredService<Plugin>()
|
sp.GetRequiredService<Plugin>()
|
||||||
));
|
));
|
||||||
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.DataPrivacyTab(
|
||||||
|
sp.GetRequiredService<Plugin>()
|
||||||
|
));
|
||||||
services.AddSingleton(sp => new Ui.Components.StatusBar(
|
services.AddSingleton(sp => new Ui.Components.StatusBar(
|
||||||
sp.GetRequiredService<ThemeRegistry>(),
|
sp.GetRequiredService<ThemeRegistry>(),
|
||||||
sp.GetRequiredService<FontManager>()
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ internal sealed class SettingsWindow : Window
|
|||||||
private readonly ChatTab _chat;
|
private readonly ChatTab _chat;
|
||||||
private readonly WindowTab _window;
|
private readonly WindowTab _window;
|
||||||
private readonly ChannelsTab _channels;
|
private readonly ChannelsTab _channels;
|
||||||
|
private readonly DataPrivacyTab _dataPrivacy;
|
||||||
|
|
||||||
public SettingsWindow(
|
public SettingsWindow(
|
||||||
Plugin plugin,
|
Plugin plugin,
|
||||||
@@ -37,6 +38,7 @@ internal sealed class SettingsWindow : Window
|
|||||||
ChatTab chat,
|
ChatTab chat,
|
||||||
WindowTab window,
|
WindowTab window,
|
||||||
ChannelsTab channels,
|
ChannelsTab channels,
|
||||||
|
DataPrivacyTab dataPrivacy,
|
||||||
ILoggerFactory loggerFactory
|
ILoggerFactory loggerFactory
|
||||||
)
|
)
|
||||||
: base($"{Language.Settings_Title.Format(Plugin.PluginName)}###chat2-settings")
|
: base($"{Language.Settings_Title.Format(Plugin.PluginName)}###chat2-settings")
|
||||||
@@ -52,6 +54,7 @@ internal sealed class SettingsWindow : Window
|
|||||||
_chat = chat;
|
_chat = chat;
|
||||||
_window = window;
|
_window = window;
|
||||||
_channels = channels;
|
_channels = channels;
|
||||||
|
_dataPrivacy = dataPrivacy;
|
||||||
_ = loggerFactory;
|
_ = loggerFactory;
|
||||||
|
|
||||||
Size = new Vector2(720, 540);
|
Size = new Vector2(720, 540);
|
||||||
@@ -92,6 +95,9 @@ internal sealed class SettingsWindow : Window
|
|||||||
case "channels":
|
case "channels":
|
||||||
_channels.Draw();
|
_channels.Draw();
|
||||||
break;
|
break;
|
||||||
|
case "data-privacy":
|
||||||
|
_dataPrivacy.Draw();
|
||||||
|
break;
|
||||||
case "appearance":
|
case "appearance":
|
||||||
_appearance.Draw();
|
_appearance.Draw();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user