699d4ede1d
Add .prettierrc.json, .markdownlint.json, .yamllint.yaml, .gitattributes Run CSharpier, Prettier and markdownlint across the entire codebase. No logic changes — formatting, using order and line endings only.
329 lines
11 KiB
C#
329 lines
11 KiB
C#
using System.Numerics;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Colors;
|
|
using Dalamud.Interface.Utility;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using HellionChat.Resources;
|
|
using HellionChat.Util;
|
|
|
|
namespace HellionChat.Ui.SettingsTabs;
|
|
|
|
// Chat-Tab — vier eigenständige Sektionen: Auto-Tell-Tabs, Behaviour,
|
|
// Preview, Emotes. Der Emotes-Block ist 1:1 aus der Bestand-Datei
|
|
// Emote.cs übernommen; die Datei wird in Plan-Task 11 (Settings UX
|
|
// Polish v0.5.0) entfernt, sobald alle Tabs migriert sind.
|
|
internal sealed class Chat : ISettingsTab
|
|
{
|
|
private Plugin Plugin { get; }
|
|
private Configuration Mutable { get; }
|
|
|
|
public string Name => HellionStrings.Settings_Tab_Chat + "###tabs-chat";
|
|
|
|
private SearchSelector.SelectorPopupOptions WordPopupOptions;
|
|
|
|
// Snapshot of EmoteCache.State for which we last built WordPopupOptions.
|
|
// Without this, an empty FilteredSheet (e.g., the user blocked every emote)
|
|
// would trigger a refill every frame the settings tab is open.
|
|
private EmoteCache.LoadingState? WordPopupOptionsBuiltFor;
|
|
|
|
internal Chat(Plugin plugin, Configuration mutable)
|
|
{
|
|
Plugin = plugin;
|
|
Mutable = mutable;
|
|
|
|
WordPopupOptions = RefillSheet();
|
|
WordPopupOptionsBuiltFor = EmoteCache.State;
|
|
}
|
|
|
|
private SearchSelector.SelectorPopupOptions RefillSheet()
|
|
{
|
|
return new SearchSelector.SelectorPopupOptions
|
|
{
|
|
FilteredSheet = EmoteCache
|
|
.SortedCodeArray.Where(w => !Mutable.BlockedEmotes.Contains(w))
|
|
.ToArray(),
|
|
};
|
|
}
|
|
|
|
public void Draw(bool changed)
|
|
{
|
|
DrawAutoTellTabsSection();
|
|
ImGui.Spacing();
|
|
DrawBehaviourSection();
|
|
ImGui.Spacing();
|
|
DrawPreviewSection();
|
|
ImGui.Spacing();
|
|
DrawEmotesSection();
|
|
}
|
|
|
|
private void DrawAutoTellTabsSection()
|
|
{
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Chat_AutoTellTabs_Heading);
|
|
if (!tree.Success)
|
|
{
|
|
return;
|
|
}
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
ImGui.Checkbox(
|
|
HellionStrings.ChatLog_AutoTellTabs_Enable_Name,
|
|
ref Mutable.EnableAutoTellTabs
|
|
);
|
|
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Enable_Description);
|
|
|
|
ImGui.SetNextItemWidth(200f * ImGuiHelpers.GlobalScale);
|
|
var limit = Mutable.AutoTellTabsLimit;
|
|
if (ImGui.SliderInt(HellionStrings.ChatLog_AutoTellTabs_Limit_Name, ref limit, 1, 50))
|
|
{
|
|
Mutable.AutoTellTabsLimit = limit;
|
|
}
|
|
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Limit_Description);
|
|
|
|
ImGui.Checkbox(
|
|
HellionStrings.ChatLog_AutoTellTabs_Compact_Name,
|
|
ref Mutable.AutoTellTabsCompactDisplay
|
|
);
|
|
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Compact_Description);
|
|
|
|
ImGui.Checkbox(
|
|
HellionStrings.ChatLog_AutoTellTabs_OpenAsPopout_Name,
|
|
ref Mutable.AutoTellTabsOpenAsPopout
|
|
);
|
|
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_OpenAsPopout_Description);
|
|
|
|
ImGui.Checkbox(
|
|
HellionStrings.ChatLog_AutoTellTabs_GreetedToggle_Name,
|
|
ref Mutable.AutoTellTabsShowGreetedToggle
|
|
);
|
|
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_GreetedToggle_Description);
|
|
|
|
ImGui.Spacing();
|
|
ImGuiUtil.HelpText(HellionStrings.ChatLog_AutoTellTabs_PreloadHint);
|
|
|
|
ImGui.Spacing();
|
|
ImGuiUtil.WarningText(HellionStrings.ChatLog_AutoTellTabs_ConflictHint);
|
|
|
|
ImGui.Spacing();
|
|
ImGui.Separator();
|
|
ImGui.Spacing();
|
|
|
|
var preload = Mutable.AutoTellTabsHistoryPreload;
|
|
ImGui.SetNextItemWidth(200f * ImGuiHelpers.GlobalScale);
|
|
if (
|
|
ImGui.SliderInt(
|
|
HellionStrings.Privacy_AutoTellTabs_Preload_Name,
|
|
ref preload,
|
|
0,
|
|
100
|
|
)
|
|
)
|
|
{
|
|
Mutable.AutoTellTabsHistoryPreload = preload;
|
|
}
|
|
ImGuiUtil.HelpMarker(HellionStrings.Privacy_AutoTellTabs_Preload_Description);
|
|
|
|
ImGui.Spacing();
|
|
ImGuiUtil.HelpText(HellionStrings.Privacy_AutoTellTabs_Preload_Hint);
|
|
}
|
|
}
|
|
|
|
private void DrawBehaviourSection()
|
|
{
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Chat_Behaviour_Heading);
|
|
if (!tree.Success)
|
|
{
|
|
return;
|
|
}
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
ImGui.Checkbox(
|
|
Language.Options_CollapseDuplicateMessages_Name,
|
|
ref Mutable.CollapseDuplicateMessages
|
|
);
|
|
ImGuiUtil.HelpMarker(Language.Options_CollapseDuplicateMessages_Description);
|
|
|
|
if (Mutable.CollapseDuplicateMessages)
|
|
{
|
|
ImGui.Checkbox(
|
|
Language.Options_CollapseDuplicateMsgUniqueLink_Name,
|
|
ref Mutable.CollapseKeepUniqueLinks
|
|
);
|
|
ImGuiUtil.HelpMarker(Language.Options_CollapseDuplicateMsgUniqueLink_Description);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawPreviewSection()
|
|
{
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Chat_Preview_Heading);
|
|
if (!tree.Success)
|
|
{
|
|
return;
|
|
}
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
using (
|
|
var combo = ImGuiUtil.BeginComboVertical(
|
|
Language.Options_Preview_Name,
|
|
Mutable.PreviewPosition.Name()
|
|
)
|
|
)
|
|
{
|
|
if (combo)
|
|
{
|
|
foreach (var position in Enum.GetValues<PreviewPosition>())
|
|
{
|
|
if (ImGui.Selectable(position.Name(), Mutable.PreviewPosition == position))
|
|
{
|
|
Mutable.PreviewPosition = position;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ImGuiUtil.HelpMarker(Language.Options_Preview_Description);
|
|
|
|
if (
|
|
ImGuiUtil.InputIntVertical(
|
|
Language.Options_PreviewMinimum_Name,
|
|
Language.Options_PreviewMinimum_Description,
|
|
ref Mutable.PreviewMinimum
|
|
)
|
|
)
|
|
{
|
|
Mutable.PreviewMinimum = Math.Clamp(Mutable.PreviewMinimum, 1, 250);
|
|
}
|
|
|
|
ImGui.Checkbox(Language.Options_PreviewOnlyIf_Name, ref Mutable.OnlyPreviewIf);
|
|
ImGuiUtil.HelpMarker(Language.Options_PreviewOnlyIf_Description);
|
|
}
|
|
}
|
|
|
|
private void DrawEmotesSection()
|
|
{
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Chat_Emotes_Heading);
|
|
if (!tree.Success)
|
|
{
|
|
return;
|
|
}
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
ImGui.Checkbox(Language.Options_ShowEmotes_Name, ref Mutable.ShowEmotes);
|
|
ImGuiUtil.HelpMarker(Language.Options_ShowEmotes_Desc);
|
|
|
|
ImGui.Spacing();
|
|
ImGui.TextUnformatted(Language.Options_Emote_BlockedEmotes);
|
|
ImGui.Spacing();
|
|
|
|
if (
|
|
EmoteCache.State is EmoteCache.LoadingState.Done
|
|
&& WordPopupOptions.FilteredSheet.Length == 0
|
|
&& WordPopupOptionsBuiltFor != EmoteCache.LoadingState.Done
|
|
)
|
|
{
|
|
WordPopupOptions = RefillSheet();
|
|
WordPopupOptionsBuiltFor = EmoteCache.LoadingState.Done;
|
|
}
|
|
|
|
var buttonWidth = ImGui.GetContentRegionAvail().X / 3;
|
|
using (Plugin.FontManager.FontAwesome.Push())
|
|
ImGui.Button(FontAwesomeIcon.Plus.ToIconString(), new Vector2(buttonWidth, 0));
|
|
|
|
// Open the selector popup on left-click; SelectorPopup uses
|
|
// ImRaii.ContextPopupItem internally which only opens on right-
|
|
// click otherwise — without this OpenPopup the button looked
|
|
// active but the popup never appeared on a normal click.
|
|
if (ImGui.IsItemClicked())
|
|
ImGui.OpenPopup("WordAddPopup");
|
|
|
|
if (SearchSelector.SelectorPopup("WordAddPopup", out var newWord, WordPopupOptions))
|
|
{
|
|
Mutable.BlockedEmotes.Add(newWord);
|
|
}
|
|
|
|
using (
|
|
var table = ImRaii.Table(
|
|
"##BlockedWords",
|
|
2,
|
|
ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInner
|
|
)
|
|
)
|
|
{
|
|
if (table)
|
|
{
|
|
ImGui.TableSetupColumn(Language.Options_Emote_EmoteTable);
|
|
ImGui.TableSetupColumn("##Del", ImGuiTableColumnFlags.WidthStretch, 0.07f);
|
|
|
|
ImGui.TableHeadersRow();
|
|
|
|
var copiedList = Mutable.BlockedEmotes.ToArray();
|
|
foreach (var word in copiedList)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
ImGui.TextUnformatted(word);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (
|
|
ImGuiUtil.Button(
|
|
$"##{word}Del",
|
|
FontAwesomeIcon.Trash,
|
|
!ImGui.GetIO().KeyCtrl
|
|
)
|
|
)
|
|
{
|
|
Mutable.BlockedEmotes.Remove(word);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui.Spacing();
|
|
ImGui.Separator();
|
|
ImGui.Spacing();
|
|
|
|
ImGui.TextUnformatted(Language.Options_Emote_EmoteStats);
|
|
ImGui.Spacing();
|
|
|
|
if (EmoteCache.State is EmoteCache.LoadingState.Done)
|
|
{
|
|
ImGui.TextColored(ImGuiColors.HealerGreen, Language.Options_Emote_Ready);
|
|
}
|
|
else
|
|
{
|
|
ImGui.TextColored(ImGuiColors.DPSRed, Language.Options_Emote_NotReady);
|
|
}
|
|
|
|
ImGui.TextUnformatted(
|
|
$"{Language.Options_Emote_Loaded} {EmoteCache.SortedCodeArray.Length}"
|
|
);
|
|
using (
|
|
var emoteTable = ImRaii.Table(
|
|
"##LoadedEmotes",
|
|
5,
|
|
ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInner
|
|
)
|
|
)
|
|
{
|
|
if (emoteTable)
|
|
{
|
|
ImGui.TableSetupColumn("##word1");
|
|
ImGui.TableSetupColumn("##word2");
|
|
ImGui.TableSetupColumn("##word3");
|
|
ImGui.TableSetupColumn("##word4");
|
|
ImGui.TableSetupColumn("##word5");
|
|
|
|
foreach (var word in EmoteCache.SortedCodeArray)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
ImGui.TextUnformatted(word);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|