feat(ui): warn before sending plugin-only symbols

This commit is contained in:
2026-05-22 16:41:06 +02:00
parent a6e2a75422
commit ba4cd918da
5 changed files with 109 additions and 7 deletions
+30 -1
View File
@@ -1,9 +1,11 @@
using System;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility.Raii;
using HellionChat._Helpers;
using HellionChat.Code;
using HellionChat.Resources;
using HellionChat.Util;
namespace HellionChat.Ui;
@@ -19,6 +21,11 @@ public sealed class ChatInputBar
private readonly Func<Tab?> _activeTabAccessor;
private readonly InputState _state = new();
// UI-11: the buffer for which a plugin-disclosure warning was already
// shown. A second Enter on the same buffer sends it anyway; editing the
// buffer clears the arming so the next send is re-checked.
private string? _disclosureArmedBuffer;
public ChatInputBar(Plugin plugin, ChatLogWindow host, Func<Tab?> activeTabAccessor)
{
_plugin = plugin;
@@ -80,11 +87,33 @@ public sealed class ChatInputBar
{
SubmitCompact(tab);
}
// UI-11: disclosure warning, visible only while an armed buffer is held
// unchanged. Editing the buffer clears the condition automatically.
if (Plugin.Config.NotifyPluginDisclosure
&& _disclosureArmedBuffer is not null
&& _state.Buffer == _disclosureArmedBuffer)
{
ImGui.TextColored(ImGuiColors.DalamudYellow, HellionStrings.ChatInput_PluginDisclosure_Warning);
}
}
// TEST-MIRROR: ../_Helpers/CompactInputSubmitter.cs
private void SubmitCompact(Tab tab) =>
private void SubmitCompact(Tab tab)
{
if (Plugin.Config.NotifyPluginDisclosure
&& _state.Buffer != _disclosureArmedBuffer
&& PluginDisclosureScanner.ContainsPrivateUseGlyph(_state.Buffer))
{
// First send attempt on this exact buffer: arm and hold. The buffer
// is kept, the warning renders, the user can press Enter again.
_disclosureArmedBuffer = _state.Buffer;
return;
}
_disclosureArmedBuffer = null;
CompactInputSubmitter.TrySubmit(_state, tab, _host.SendChatBoxFromExternal);
}
// History navigation callback. Cursor math delegated to
// CompactInputHistoryNavigator; ImGui buffer splice stays here.
+39 -6
View File
@@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Dalamud.Bindings.ImGui;
using Dalamud.Game.Addon.Lifecycle;
using Dalamud.Interface.Colors;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface;
@@ -15,6 +16,7 @@ using Dalamud.Interface.Windowing;
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using HellionChat._Helpers;
using HellionChat.Code;
using HellionChat.GameFunctions;
using HellionChat.GameFunctions.Types;
@@ -55,6 +57,11 @@ public sealed class ChatLogWindow : Window
private int ActivatePos = -1;
internal string Chat = string.Empty;
// UI-11: the main-window input buffer for which a plugin-disclosure
// warning was already shown. Mirrors _disclosureArmedBuffer in
// ChatInputBar — a second Enter on the same buffer sends it anyway.
private string? _disclosureArmedBufferMain;
// Input history extracted into InputHistoryService so pop-out windows share
// the same Up/Down history. Cursor stays window-local (independent navigation).
private int InputBacklogIdx = -1;
@@ -1081,6 +1088,10 @@ public sealed class ChatLogWindow : Window
{
Chat = chatCopy;
// UI-11: Escape cancels the input — drop any pending
// disclosure arming so the warning does not linger.
_disclosureArmedBufferMain = null;
if (activeTab.CurrentChannel.UseTempChannel)
{
activeTab.CurrentChannel.ResetTempChannel();
@@ -1090,17 +1101,39 @@ public sealed class ChatLogWindow : Window
if (ImGui.IsKeyDown(ImGuiKey.Enter) || ImGui.IsKeyDown(ImGuiKey.KeypadEnter))
{
Plugin.CommandHelpWindow.IsOpen = false;
SendChatBox(activeTab);
if (activeTab.CurrentChannel.UseTempChannel)
if (Plugin.Config.NotifyPluginDisclosure
&& Chat != _disclosureArmedBufferMain
&& PluginDisclosureScanner.ContainsPrivateUseGlyph(Chat))
{
activeTab.CurrentChannel.ResetTempChannel();
SetChannel(activeTab.CurrentChannel.Channel);
// First send attempt on this exact buffer: arm and hold.
// The warning renders below the input.
_disclosureArmedBufferMain = Chat;
}
else
{
_disclosureArmedBufferMain = null;
Plugin.CommandHelpWindow.IsOpen = false;
SendChatBox(activeTab);
if (activeTab.CurrentChannel.UseTempChannel)
{
activeTab.CurrentChannel.ResetTempChannel();
SetChannel(activeTab.CurrentChannel.Channel);
}
}
}
}
// UI-11: disclosure warning for the main-window input, mirrors the
// ChatInputBar path. Visible only while the armed buffer is held
// unchanged; editing the buffer clears the condition.
if (Plugin.Config.NotifyPluginDisclosure
&& _disclosureArmedBufferMain is not null
&& Chat == _disclosureArmedBufferMain)
{
ImGui.TextColored(ImGuiColors.DalamudYellow, HellionStrings.ChatInput_PluginDisclosure_Warning);
}
// Process keybinds that have modifiers while the chat is focused.
if (inputActive)
{
+6
View File
@@ -151,6 +151,12 @@ internal sealed class Chat : ISettingsTab
ref Mutable.NotifyFailedTell
);
ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_NotifyFailedTell_Description);
ImGui.Checkbox(
HellionStrings.Settings_Chat_NotifyPluginDisclosure_Name,
ref Mutable.NotifyPluginDisclosure
);
ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_NotifyPluginDisclosure_Description);
}
}