From e6c6c0278039d38645098d6183922e1425b7349e Mon Sep 17 00:00:00 2001 From: JonKazama-Hellion Date: Tue, 5 May 2026 23:27:41 +0200 Subject: [PATCH] feat(sidebar): hash-color tint for auto-tell tabs to disambiguate parallel conversations --- HellionChat/Ui/AutoTellTabTint.cs | 64 +++++++++++++++++++++++++++++++ HellionChat/Ui/ChatLogWindow.cs | 22 +++++++++-- 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 HellionChat/Ui/AutoTellTabTint.cs diff --git a/HellionChat/Ui/AutoTellTabTint.cs b/HellionChat/Ui/AutoTellTabTint.cs new file mode 100644 index 0000000..da74d14 --- /dev/null +++ b/HellionChat/Ui/AutoTellTabTint.cs @@ -0,0 +1,64 @@ +namespace HellionChat.Ui; + +/// +/// Hash-Color-Tinting für Auto-Tell-Tabs in der Sidebar (v1.2.0). +/// Differenziert Tells visuell ohne dass User pro Tab manuell ein +/// Custom-Icon setzen muss. Gleicher Tell-Partner (Name+World) liefert +/// konsistent dieselbe Farbe über Sessions hinweg. +/// +/// Kuratierte 12-Farb-Palette aus dem Hellion-Theme-Pool: alle saturiert +/// mid-bright, lesbar gegen Dark-Theme-Backgrounds. Bei realistischen +/// 1-5 parallelen Tells ist Kollisions-Wahrscheinlichkeit gering. +/// +/// Reine String-Logik (kein Dalamud-Dep) — testbar im HellionChat.Tests- +/// Projekt das ohne Dalamud-Reference baut. +/// +internal static class AutoTellTabTint +{ + /// + /// Fallback bei ungültigem Input (leerer Name, World=0). Standard- + /// Text-Color (weiß) — passt mit existierendem TextPrimary-Default + /// zusammen, sodass die Sidebar visuell konsistent bleibt. + /// + public const uint Fallback = 0xFFFFFFFFu; + + /// + /// 12 saturierte mid-bright Farben aus den 5 Built-In-Themes + /// (Hellion-Arctic, Chat2-Klassik, Event-Horizon, Moonlit-Bloom, + /// Mint-Grove). Reihenfolge ist deterministisch — Hash-Index wählt + /// Farbe per Modulo. RGBA-Format (passt zu ColourUtil.RgbaToAbgr- + /// Konvention im restlichen Code). + /// + public static readonly IReadOnlyList Palette = new uint[] + { + 0x00BED2FFu, // Arctic Cyan + 0xF97316FFu, // Ember Orange + 0xB585FFFFu, // Light Cosmic Purple + 0xE374E8FFu, // Bloom Magenta + 0x5DD39EFFu, // Mint Green + 0xF0AD4EFFu, // Warning Yellow + 0xE85C6AFFu, // Coral + 0x5CB85CFFu, // Status Green + 0x6278FFFFu, // Bloom Blue + 0xC9982EFFu, // Warm Gold + 0x9CCB7CFFu, // Soft Sage + 0xE85D04FFu, // Deep Ember + }; + + /// + /// Liefert eine konsistente Tint-Color für einen Tell-Partner. + /// Hash basiert auf "Name@World" — Cross-World-Namen kollidieren + /// nur bei Hash-Bucket-Kollision, nicht durch Identitäts-Annahme. + /// + public static uint For(string name, uint world) + { + if (string.IsNullOrEmpty(name) || world == 0) + return Fallback; + + // GetHashCode kann negativ sein; Bitmaske auf positive Range + // damit Modulo-Division immer einen validen Index liefert. + var key = $"{name}@{world}"; + var hash = (uint)(key.GetHashCode() & 0x7FFFFFFF); + return Palette[(int)(hash % Palette.Count)]; + } +} diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs index f92c888..68c0a3b 100644 --- a/HellionChat/Ui/ChatLogWindow.cs +++ b/HellionChat/Ui/ChatLogWindow.cs @@ -1544,9 +1544,25 @@ public sealed class ChatLogWindow : Window // Dim-Trick ab, da wir keine Selectable mehr nutzen). var theme = Plugin.ThemeRegistry.Active; var icon = TabIconMapping.Resolve(tab); - var iconColor = isCurrentTab - ? theme.Colors.Accent - : (showGreetedAffordance && tab.IsGreeted ? theme.Colors.TextDim : theme.Colors.TextPrimary); + uint iconColor; + if (isCurrentTab) + { + iconColor = theme.Colors.Accent; + } + else if (showGreetedAffordance && tab.IsGreeted) + { + iconColor = theme.Colors.TextDim; + } + else if (tab.IsTempTab && tab.TellTarget != null && tab.TellTarget.IsSet()) + { + // v1.2.0 — Hash-Color-Tint differenziert parallele Auto-Tell-Tabs + // visuell ohne dass User pro Tab manuell ein Custom-Icon setzen muss. + iconColor = AutoTellTabTint.For(tab.TellTarget.Name, tab.TellTarget.World); + } + else + { + iconColor = theme.Colors.TextPrimary; + } bool clicked; using (ImRaii.PushColor(ImGuiCol.Button, 0u))