refactor(settings): merge privacy into the Data and Privacy tab
This commit is contained in:
@@ -368,7 +368,7 @@ public sealed class FirstRunWizard : Window
|
||||
// Mirror the DataAndPrivacy coupling: turning load-previous on
|
||||
// also turns filter-include on (otherwise old messages bypass
|
||||
// the filter chain), and turning filter-include off forces
|
||||
// load-previous off. Same idiom as Ui/SettingsTabs/DataAndPrivacy.cs:182-200.
|
||||
// load-previous off. Same idiom as Ui/SettingsTabs/DataAndPrivacy.cs.
|
||||
if (loadPrev)
|
||||
_state.PendingFilterIncludePreviousSessions = true;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ public sealed class SettingsWindow : Dalamud.Interface.Windowing.Window
|
||||
new SettingsTabs.Window(Plugin, Mutable),
|
||||
new Chat(Plugin, Mutable),
|
||||
new SettingsTabs.Tabs(Plugin, Mutable),
|
||||
new SettingsTabs.Privacy(Plugin, Mutable),
|
||||
new DataAndPrivacy(Plugin, Mutable, loggerFactory.CreateLogger<DataAndPrivacy>()),
|
||||
new SettingsTabs.Integrations(Plugin, Mutable),
|
||||
new About(Mutable),
|
||||
|
||||
@@ -39,11 +39,6 @@ internal sealed class SettingsOverview
|
||||
HellionStrings.Settings_Card_Tabs_Title,
|
||||
HellionStrings.Settings_Card_Tabs_Subtext
|
||||
),
|
||||
(
|
||||
FontAwesomeIcon.ShieldAlt,
|
||||
HellionStrings.Settings_Card_Privacy_Title,
|
||||
HellionStrings.Settings_Card_Privacy_Subtext
|
||||
),
|
||||
(
|
||||
FontAwesomeIcon.Database,
|
||||
HellionStrings.Settings_Card_DataManagement_Title,
|
||||
|
||||
@@ -24,7 +24,7 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
public string Name =>
|
||||
HellionStrings.Settings_Card_DataManagement_Title + "###tabs-datamanagement";
|
||||
|
||||
// Cleanup state (was in Privacy.cs)
|
||||
// Cleanup state
|
||||
private Dictionary<int, long>? CleanupCounts;
|
||||
private long CleanupKeepCount;
|
||||
private long CleanupDeleteCount;
|
||||
@@ -33,7 +33,7 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
private HashSet<ChatType>? CleanupPreviewSnapshot;
|
||||
private bool RetentionRunning => Plugin.RetentionSweepRunning;
|
||||
|
||||
// Export form state (was in Privacy.cs)
|
||||
// Export form state
|
||||
private int ExportRangeDays = 30;
|
||||
private string ExportSenderSubstring = string.Empty;
|
||||
private readonly HashSet<ChatType> ExportSelectedChannels = [];
|
||||
@@ -152,22 +152,113 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
if (sectionJustEntered)
|
||||
ShowAdvanced = ImGui.GetIO().KeyShift;
|
||||
|
||||
if (sectionJustEntered) ImGui.SetNextItemOpen(false);
|
||||
DrawPrivacyFilterSection();
|
||||
ImGui.Spacing();
|
||||
if (sectionJustEntered) ImGui.SetNextItemOpen(false);
|
||||
DrawStorageSection();
|
||||
ImGui.Spacing();
|
||||
if (sectionJustEntered) ImGui.SetNextItemOpen(false);
|
||||
DrawRetentionSection();
|
||||
ImGui.Spacing();
|
||||
if (sectionJustEntered) ImGui.SetNextItemOpen(false);
|
||||
DrawCleanupSection();
|
||||
ImGui.Spacing();
|
||||
if (sectionJustEntered) ImGui.SetNextItemOpen(false);
|
||||
DrawExportSection();
|
||||
ImGui.Spacing();
|
||||
DrawDatabaseViewerSection();
|
||||
ImGui.Spacing();
|
||||
DrawAdvancedSection();
|
||||
if (sectionJustEntered) ImGui.SetNextItemOpen(false);
|
||||
DrawDatabaseSection();
|
||||
}
|
||||
|
||||
private void DrawPrivacyFilterSection()
|
||||
{
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_PrivacyFilter);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
|
||||
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
||||
{
|
||||
// Wizard re-open sits outside the disabled block so it is always clickable.
|
||||
if (ImGui.Button(HellionStrings.Wizard_Reopen_Button))
|
||||
Plugin.FirstRunWizard.IsOpen = true;
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.OptionCheckbox(
|
||||
ref Mutable.PrivacyFilterEnabled,
|
||||
HellionStrings.Privacy_FilterEnabled_Name,
|
||||
HellionStrings.Privacy_FilterEnabled_Description
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Privacy_FilterEnabled_StorageOnly_Help);
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
// Whitelist, presets, and PersistUnknown are greyed (still visible)
|
||||
// when the filter is off — ImRaii.Disabled block preserved verbatim.
|
||||
using (ImRaii.Disabled(!Mutable.PrivacyFilterEnabled))
|
||||
{
|
||||
ImGuiUtil.HelpText(HellionStrings.Privacy_Whitelist_Help);
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
if (ImGui.Button(HellionStrings.Privacy_Preset_PrivacyFirst))
|
||||
Mutable.PrivacyPersistChannels = [.. PrivacyDefaults.PrivacyFirstWhitelist];
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button(HellionStrings.Privacy_Preset_ClearAll))
|
||||
Mutable.PrivacyPersistChannels.Clear();
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button(HellionStrings.Privacy_Preset_SelectAll))
|
||||
foreach (var group in Groups)
|
||||
foreach (var t in group.Types)
|
||||
Mutable.PrivacyPersistChannels.Add(t);
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
foreach (var (heading, types) in Groups)
|
||||
{
|
||||
using var groupTree = ImRaii.TreeNode(heading());
|
||||
if (!groupTree.Success)
|
||||
continue;
|
||||
|
||||
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
var enabled = Mutable.PrivacyPersistChannels.Contains(type);
|
||||
var label = type.ToString();
|
||||
if (ImGui.Checkbox($"{label}##privacy-{(int)type}", ref enabled))
|
||||
{
|
||||
if (enabled)
|
||||
Mutable.PrivacyPersistChannels.Add(type);
|
||||
else
|
||||
Mutable.PrivacyPersistChannels.Remove(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.OptionCheckbox(
|
||||
ref Mutable.PrivacyPersistUnknownChannels,
|
||||
HellionStrings.Privacy_PersistUnknown_Name,
|
||||
HellionStrings.Privacy_PersistUnknown_Description
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawStorageSection()
|
||||
{
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_DataManagement_Storage_Heading);
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Storage);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
|
||||
@@ -245,7 +336,7 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
|
||||
private void DrawRetentionSection()
|
||||
{
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_DataManagement_Retention_Heading);
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Retention);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
|
||||
@@ -437,7 +528,7 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
|
||||
private void DrawCleanupSection()
|
||||
{
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_DataManagement_Cleanup_Heading);
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Cleanup);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
|
||||
@@ -627,7 +718,7 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
|
||||
private void DrawExportSection()
|
||||
{
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_DataManagement_Export_Heading);
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Export);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
|
||||
@@ -785,9 +876,9 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
}.Start();
|
||||
}
|
||||
|
||||
private void DrawDatabaseViewerSection()
|
||||
private void DrawDatabaseSection()
|
||||
{
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_DataManagement_DbViewer_Heading);
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Database);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
|
||||
@@ -862,49 +953,49 @@ internal sealed class DataAndPrivacy : ISettingsTab
|
||||
NotificationType.Info
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAdvancedSection()
|
||||
{
|
||||
if (!ShowAdvanced)
|
||||
return;
|
||||
// Advanced sub-block: only visible when the tab was opened with Shift held.
|
||||
// Gate matches the Shift-on-open flag set at the top of Draw().
|
||||
if (!ShowAdvanced)
|
||||
return;
|
||||
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Settings_DataManagement_Advanced_Heading);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
ImGui.Spacing();
|
||||
using var advTree = ImRaii.TreeNode(HellionStrings.Settings_DataManagement_Advanced_Heading);
|
||||
if (!advTree.Success)
|
||||
return;
|
||||
|
||||
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
||||
{
|
||||
using var wrap = ImRaii.TextWrapPos(0.0f);
|
||||
|
||||
ImGuiUtil.WarningText(Language.Options_Database_Advanced_Warning);
|
||||
if (
|
||||
ImGuiUtil.CtrlShiftButton(
|
||||
"Perform maintenance",
|
||||
"Ctrl+Shift: MessageManager.Store.PerformMaintenance()"
|
||||
)
|
||||
)
|
||||
Plugin.MessageManager.Store.PerformMaintenance();
|
||||
|
||||
if (
|
||||
ImGuiUtil.CtrlShiftButton(
|
||||
"Reload messages from database",
|
||||
"Ctrl+Shift: MessageManager.FilterAllTabs()"
|
||||
)
|
||||
)
|
||||
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
||||
{
|
||||
Plugin.MessageManager.ClearAllTabs();
|
||||
Plugin.MessageManager.FilterAllTabsAsync();
|
||||
}
|
||||
using var wrap = ImRaii.TextWrapPos(0.0f);
|
||||
|
||||
if (
|
||||
ImGuiUtil.CtrlShiftButton(
|
||||
"Inject 10,000 messages",
|
||||
"Ctrl+Shift: creates 10,000 unique messages (async)"
|
||||
ImGuiUtil.WarningText(Language.Options_Database_Advanced_Warning);
|
||||
if (
|
||||
ImGuiUtil.CtrlShiftButton(
|
||||
"Perform maintenance",
|
||||
"Ctrl+Shift: MessageManager.Store.PerformMaintenance()"
|
||||
)
|
||||
)
|
||||
)
|
||||
new Thread(() => InsertMessages(10_000)).Start();
|
||||
Plugin.MessageManager.Store.PerformMaintenance();
|
||||
|
||||
if (
|
||||
ImGuiUtil.CtrlShiftButton(
|
||||
"Reload messages from database",
|
||||
"Ctrl+Shift: MessageManager.FilterAllTabs()"
|
||||
)
|
||||
)
|
||||
{
|
||||
Plugin.MessageManager.ClearAllTabs();
|
||||
Plugin.MessageManager.FilterAllTabsAsync();
|
||||
}
|
||||
|
||||
if (
|
||||
ImGuiUtil.CtrlShiftButton(
|
||||
"Inject 10,000 messages",
|
||||
"Ctrl+Shift: creates 10,000 unique messages (async)"
|
||||
)
|
||||
)
|
||||
new Thread(() => InsertMessages(10_000)).Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using HellionChat.Code;
|
||||
using HellionChat.Privacy;
|
||||
using HellionChat.Resources;
|
||||
using HellionChat.Util;
|
||||
|
||||
namespace HellionChat.Ui.SettingsTabs;
|
||||
|
||||
internal sealed class Privacy : ISettingsTab
|
||||
{
|
||||
private Plugin Plugin { get; }
|
||||
private Configuration Mutable { get; }
|
||||
|
||||
public string Name => HellionStrings.Privacy_Tab_Title + "###tabs-privacy";
|
||||
|
||||
internal Privacy(Plugin plugin, Configuration mutable)
|
||||
{
|
||||
Plugin = plugin;
|
||||
Mutable = mutable;
|
||||
}
|
||||
|
||||
// (HeadingKey, ChatType list). Heading resolved per-frame for live language switching.
|
||||
private static readonly (Func<string> Heading, ChatType[] Types)[] Groups =
|
||||
[
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_DirectMessages,
|
||||
[ChatType.TellIncoming, ChatType.TellOutgoing]
|
||||
),
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_PartyAlliance,
|
||||
[ChatType.Party, ChatType.CrossParty, ChatType.Alliance, ChatType.PvpTeam]
|
||||
),
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_FreeCompany,
|
||||
[
|
||||
ChatType.FreeCompany,
|
||||
ChatType.FreeCompanyAnnouncement,
|
||||
ChatType.FreeCompanyLoginLogout,
|
||||
]
|
||||
),
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_Linkshells,
|
||||
[
|
||||
ChatType.Linkshell1,
|
||||
ChatType.Linkshell2,
|
||||
ChatType.Linkshell3,
|
||||
ChatType.Linkshell4,
|
||||
ChatType.Linkshell5,
|
||||
ChatType.Linkshell6,
|
||||
ChatType.Linkshell7,
|
||||
ChatType.Linkshell8,
|
||||
]
|
||||
),
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_CrossLinkshells,
|
||||
[
|
||||
ChatType.CrossLinkshell1,
|
||||
ChatType.CrossLinkshell2,
|
||||
ChatType.CrossLinkshell3,
|
||||
ChatType.CrossLinkshell4,
|
||||
ChatType.CrossLinkshell5,
|
||||
ChatType.CrossLinkshell6,
|
||||
ChatType.CrossLinkshell7,
|
||||
ChatType.CrossLinkshell8,
|
||||
]
|
||||
),
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_ExtraChat,
|
||||
[
|
||||
ChatType.ExtraChatLinkshell1,
|
||||
ChatType.ExtraChatLinkshell2,
|
||||
ChatType.ExtraChatLinkshell3,
|
||||
ChatType.ExtraChatLinkshell4,
|
||||
ChatType.ExtraChatLinkshell5,
|
||||
ChatType.ExtraChatLinkshell6,
|
||||
ChatType.ExtraChatLinkshell7,
|
||||
ChatType.ExtraChatLinkshell8,
|
||||
]
|
||||
),
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_PublicChat,
|
||||
[
|
||||
ChatType.Say,
|
||||
ChatType.Shout,
|
||||
ChatType.Yell,
|
||||
ChatType.NoviceNetwork,
|
||||
ChatType.CustomEmote,
|
||||
ChatType.StandardEmote,
|
||||
]
|
||||
),
|
||||
(
|
||||
() => HellionStrings.Privacy_Group_SystemLogs,
|
||||
[
|
||||
ChatType.System,
|
||||
ChatType.Notice,
|
||||
ChatType.Urgent,
|
||||
ChatType.Echo,
|
||||
ChatType.NpcDialogue,
|
||||
ChatType.NpcAnnouncement,
|
||||
ChatType.LootNotice,
|
||||
ChatType.LootRoll,
|
||||
ChatType.RetainerSale,
|
||||
ChatType.Crafting,
|
||||
ChatType.Gathering,
|
||||
ChatType.Sign,
|
||||
ChatType.RandomNumber,
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
public void Draw(bool sectionJustEntered)
|
||||
{
|
||||
if (ImGui.Button(HellionStrings.Wizard_Reopen_Button))
|
||||
Plugin.FirstRunWizard.IsOpen = true;
|
||||
ImGui.Spacing();
|
||||
|
||||
DrawPrivacyFilterSection();
|
||||
}
|
||||
|
||||
private void DrawPrivacyFilterSection()
|
||||
{
|
||||
using var tree = ImRaii.TreeNode(HellionStrings.Privacy_Filter_Tree_Heading);
|
||||
if (!tree.Success)
|
||||
return;
|
||||
|
||||
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
||||
{
|
||||
ImGuiUtil.OptionCheckbox(
|
||||
ref Mutable.PrivacyFilterEnabled,
|
||||
HellionStrings.Privacy_FilterEnabled_Name,
|
||||
HellionStrings.Privacy_FilterEnabled_Description
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Privacy_FilterEnabled_StorageOnly_Help);
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
using (ImRaii.Disabled(!Mutable.PrivacyFilterEnabled))
|
||||
{
|
||||
ImGuiUtil.HelpText(HellionStrings.Privacy_Whitelist_Help);
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
if (ImGui.Button(HellionStrings.Privacy_Preset_PrivacyFirst))
|
||||
Mutable.PrivacyPersistChannels = [.. PrivacyDefaults.PrivacyFirstWhitelist];
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button(HellionStrings.Privacy_Preset_ClearAll))
|
||||
Mutable.PrivacyPersistChannels.Clear();
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button(HellionStrings.Privacy_Preset_SelectAll))
|
||||
foreach (var group in Groups)
|
||||
foreach (var t in group.Types)
|
||||
Mutable.PrivacyPersistChannels.Add(t);
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
foreach (var (heading, types) in Groups)
|
||||
{
|
||||
using var groupTree = ImRaii.TreeNode(heading());
|
||||
if (!groupTree.Success)
|
||||
continue;
|
||||
|
||||
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
var enabled = Mutable.PrivacyPersistChannels.Contains(type);
|
||||
var label = type.ToString();
|
||||
if (ImGui.Checkbox($"{label}##privacy-{(int)type}", ref enabled))
|
||||
{
|
||||
if (enabled)
|
||||
Mutable.PrivacyPersistChannels.Add(type);
|
||||
else
|
||||
Mutable.PrivacyPersistChannels.Remove(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Spacing();
|
||||
ImGui.Separator();
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.OptionCheckbox(
|
||||
ref Mutable.PrivacyPersistUnknownChannels,
|
||||
HellionStrings.Privacy_PersistUnknown_Name,
|
||||
HellionStrings.Privacy_PersistUnknown_Description
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user