diff --git a/HellionChat/HellionChat.csproj b/HellionChat/HellionChat.csproj
index 6c0ea5b..90b7704 100644
--- a/HellionChat/HellionChat.csproj
+++ b/HellionChat/HellionChat.csproj
@@ -1,7 +1,7 @@
- 1.4.9
+ 1.4.10
enable
enable
diff --git a/HellionChat/HellionChat.yaml b/HellionChat/HellionChat.yaml
index eaf0c70..1166aee 100755
--- a/HellionChat/HellionChat.yaml
+++ b/HellionChat/HellionChat.yaml
@@ -35,6 +35,50 @@ tags:
- Replacement
- Privacy
changelog: |-
+ **v1.4.10 — Symbol-Picker and Tell-History Fix (2026-05-16)**
+
+ Eleventh and final sub-patch of the v1.4.x polish-sweep series.
+ Symbol picker for the chat input, a tell-history reload fix for
+ users with many active partners, and a closing cleanup sweep
+ before v1.5.0 picks up the DI-container adoption.
+
+ - Symbol picker: a small smile-icon button left of the channel
+ indicator opens a popup with two tabs. The first lists all 161
+ FFXIV PUA glyphs (Dalamud's SeIconChar enum); the second
+ carries 97 server-verified BMP symbols (latin marks, currency,
+ the full Greek alphabet, geometric shapes, suits, notes) —
+ every one of them round-tripped through /echo and /say in a
+ four-round probe so the in-channel render matches what the
+ picker shows. Click drops the glyph at the caret, multi-insert
+ keeps the popup open, and a recent-used strip floats the last
+ sixteen picks across both tabs. Toggle in Settings → Chat →
+ Message behaviour, default on.
+ - Pinned auto-tell tabs reload their full history again: a
+ hidden 500-row scan cap in PreloadHistory used to override the
+ user-configurable AutoTellTabsHistoryPreload setting, so
+ less-frequent pinned partners (rare /tell sessions in an
+ otherwise busy week) lost their backlog. The cap is removed;
+ the (Receiver, Date) index keeps SQL fast, the client-side
+ loop still respects your setting as the upper bound.
+ - Slash-command teardown: /hellion, /hellionView,
+ /hellionDebugger (and #if DEBUG /hellionSeString) wrappers are
+ now cached as private fields. Plugin teardown detaches the
+ live registration instead of re-Register'ing with identical
+ args — closes a latent maintenance hazard from v1.4.9.
+ - v1.4.x polish-sweep wraps up here. The ImGuiListClipper render
+ refactor that was on the v1.4.10 reserve list got dropped
+ after cross-platform smoke showed the scroll rubber-band is a
+ Wine / Linux render-pipeline quirk, not universal — Windows
+ users never saw it. It will get its own platform-targeted
+ spike in a later patch. Next major cycle is v1.5.0 with the
+ DI-container adoption (Microsoft.Extensions.Hosting +
+ ILogger) modelled on Lightless.
+ - Migration v17 stays (no schema bump).
+
+ Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
+
+ ---
+
**v1.4.9 — Plugin-Load Render Polish (2026-05-15)**
Tenth sub-patch of the v1.4.x polish-sweep series. First-frame
@@ -150,43 +194,4 @@ changelog: |-
---
- **v1.4.6 — Code Hygiene and Refactor (2026-05-12)**
-
- Maintenance patch. No user-visible behaviour changes; tightens the
- development feedback loop, fixes two upstream-inherited bugs, and
- prepares the code for the v1.4.7 backlog cleanup.
-
- - preflight.sh gains a csharpier reflow check and a markdownlint
- pass so style drift and markdown violations are caught at the
- pre-push gate
- - FontManager fallback catches the full set of atlas-toolkit
- throws (IO, InvalidOperation, ArgumentException) — a corrupt
- font config no longer takes down the whole atlas build
- - BrandingLinks and IntegrationLinks URLs validated on plugin
- load — a typo in a future URL rotation now throws at startup
- - Cherry-picked from ChatTwo upstream f35b7d3: Chat.SetChannel
- no longer leaks the native Utf8String when the linkshell check
- rejects the channel
- - Cherry-picked from ChatTwo upstream f35b7d3: Tab.Clone now
- deep-clones UsedChannel and TellTarget — PopOut and Temp tabs
- no longer mutate each other's channel state
- - Active-tab underline scales with DPI and rounds to physical
- pixels for crisp rendering above 100% scaling
- - IconButton width parameter no longer subtracts HUD-scaled
- padding from a raw int (measured width passes through verbatim)
- - Internal: HellionStyle ChildBgAlpha extracted to a testable
- helper; Plugin.SaveConfig clones only the temp tabs;
- SettingsOverview caches the draw-list per frame;
- Dalamud.Utility.Util surface routed through an IPlatformUtil
- indirection (MessageStore IsWine probe is now testable in
- isolation)
- - Built-in themes: Crystal Nocturne (sapphire and electric
- magenta over obsidian, by CRYSTALLITE) replaces Moonlit Bloom.
- Users with Moonlit Bloom selected fall back to Hellion Arctic
- on first load
-
- Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
-
- ---
-
Full history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases
diff --git a/HellionChat/Plugin.cs b/HellionChat/Plugin.cs
index d3aeb88..d4d0a5c 100755
--- a/HellionChat/Plugin.cs
+++ b/HellionChat/Plugin.cs
@@ -198,8 +198,8 @@ public sealed class Plugin : IAsyncDalamudPlugin
if (Config.Version < 16)
{
throw new InvalidOperationException(
- $"HellionChat v1.4.9 requires config schema v16, got v{Config.Version}. "
- + "Please install v1.4.2 first to migrate the configuration, then upgrade to v1.4.9."
+ $"HellionChat v1.4.10 requires config schema v16, got v{Config.Version}. "
+ + "Please install v1.4.2 first to migrate the configuration, then upgrade to v1.4.10."
);
}
Config.Version = 17;
diff --git a/README.md b/README.md
index 9551f2d..c310630 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/actions/workflows/build.yml)
[](LICENSE)
-[](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/latest)
+[](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/latest)
[](https://github.com/goatcorp/Dalamud)
[](https://dotnet.microsoft.com/)
[](https://www.finalfantasyxiv.com/)
@@ -11,7 +11,7 @@
-**Version 1.4.9** — Privacy-first chat plugin for FINAL FANTASY XIV / Dalamud, built on
+**Version 1.4.10** — Privacy-first chat plugin for FINAL FANTASY XIV / Dalamud, built on
[Chat 2](https://github.com/Infiziert90/ChatTwo) (EUPL-1.2).
Hellion Chat is a privacy-first plugin built on the Chat 2 foundation. The majority of the engine comes from Chat 2
@@ -286,24 +286,23 @@ An optional submission to the Dalamud main plugin repo (in addition to the custo
## Project Status
-**Version 1.4.9** — Plugin-Load Render Polish. First-frame render cost is now well under Dalamud's 100 ms HITCH
-warning threshold (~76 ms median, down from ~127 ms). The gain comes from deferring six non-essential rendering
-sections on the very first Draw — bottom status bar, channel-name SeString chunks, window bounds check, hint
-banner, autocomplete and input-preview calculation — so the initial ImGui layout cost is spread between frame 0
-and frame 1 instead of all hitting at once. At 60 fps the user sees those sections one frame (~17 ms) later, which
-is invisible inside the post-reload font-atlas build window. Slash commands `/hellion`, `/hellionView`,
-`/hellionSeString` and `/hellionDebugger` are now registered centrally during plugin load so they work before
-their target window is opened the first time. The configuration-button entry in Dalamud's plugin manager hangs on
-the same path. Three plugin-load profiling logs (auto-translate warm-up, message-store connect, tab filter) stay
-on at Information level as a regression tripwire — if a future change pushes the load past 100 ms again, the cost
-is right there in `/xllog`. The release also ships a ChatTwo IPC compatibility layer: HellionChat now mirrors
-ChatTwo's full IPC surface (`GetChatInputState`, `ChatInputStateChanged`, `Register`, `Unregister`, `Available`,
-`Invoke`) under the `ChatTwo.*` namespace in addition to our existing `HellionChat.*` provider gates, so
-third-party integrations that historically only subscribe to ChatTwo's IPC (Artisan's and AllaganTools' context-
-menu hooks are the practical examples) keep working without requiring a code change on their side. Conflict
-detection prevents ChatTwo from loading in parallel with HellionChat, so there is no slot-collision risk at
-runtime. Migration v17 stays (no schema bump). Tenth sub-patch of the v1.4.x polish sweep series (as of
-2026-05-15).
+**Version 1.4.10** — Symbol-Picker and Tell-History Fix. Eleventh and final sub-patch of the v1.4.x polish sweep
+series. A new symbol-picker popup hangs off a smile-icon button left of the channel indicator: tab one lists all
+161 FFXIV PUA glyphs (Dalamud's `SeIconChar` enum); tab two carries 97 server-verified BMP symbols (latin marks,
+currency, the full Greek alphabet, geometric shapes, suits, notes) — each one round-tripped through `/echo` and
+`/say` in a four-round whitelist probe so the in-channel render matches what the picker shows. Click drops the
+glyph at the caret, multi-insert keeps the popup open, recent-used strip floats the last sixteen picks across
+both tabs. Toggle in Settings → Chat → Message behaviour, default on. Mid-cycle hotfix for pinned auto-tell tabs:
+PreloadHistory had a hidden 500-row SQL scan cap that overrode the user-configurable `AutoTellTabsHistoryPreload`
+setting — active users with many tell partners lost the backlog of less-frequent pinned partners. The cap is
+removed; the `(Receiver, Date)` index keeps SQL fast, the client-side loop respects the user setting as the upper
+bound. Slash-command teardown cleanup: `/hellion`, `/hellionView`, `/hellionDebugger` (and `#if DEBUG /hellionSeString`)
+wrappers are cached as private fields so plugin teardown detaches the live registration instead of re-Register'ing
+with identical args. The original Reserve-A `ImGuiListClipper` refactor for `DrawMessages` was cancelled after
+cross-platform smoke showed the scroll rubber-band is a Wine/Linux render-pipeline quirk, not universal — Windows
+users on v1.4.9 never saw it; the spike that targets the Wine path lives in a later patch. Migration v17 stays
+(no schema bump). v1.4.x polish sweep wraps up here; next major cycle is v1.5.0 with the DI-container adoption
+(`Microsoft.Extensions.Hosting` + `ILogger`) modelled on Lightless (as of 2026-05-16).
Hellion Chat is a standalone plugin, no longer a fork in the repository sense. Fully completed:
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 59d16dd..62c10da 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -10,6 +10,31 @@ to the release pages for details.
---
+## Hellion Chat 1.4.10 — Symbol-Picker and Tell-History Fix (2026-05-16)
+
+Eleventh and final sub-patch of the v1.4.x Polish-Sweep series. Symbol picker for the chat input, a tell-history reload fix
+for users with many active partners, and a closing cleanup sweep before v1.5.0 picks up the DI-container adoption.
+
+- Symbol picker for the chat input: smile-icon button left of the channel indicator opens a popup with two tabs —
+ 161 FFXIV PUA glyphs (Dalamud's SeIconChar enum) and 97 server-verified BMP symbols round-tripped through `/echo` and
+ `/say` in a four-round probe. Cursor-aware splice, multi-insert keeps the popup open, recent-used strip floats the last
+ sixteen picks across both tabs. Toggle in Settings → Chat → Message behaviour, default on.
+- Pinned auto-tell tabs reload their full history again. PreloadHistory had a hidden 500-row scan cap that overrode the
+ user-configurable `AutoTellTabsHistoryPreload` setting whenever you chatted with many partners; less-frequent pinned
+ partners lost their backlog. The cap is removed.
+- Slash-command teardown cleanup: `/hellion`, `/hellionView`, `/hellionDebugger` (and `#if DEBUG /hellionSeString`) wrappers
+ are now cached as private fields so plugin teardown detaches the live registration instead of re-Register'ing with
+ identical args (latent maintenance hazard from v1.4.9).
+- v1.4.x Polish-Sweep wraps up here. The ImGuiListClipper render refactor that was on the v1.4.10 reserve list got dropped
+ after cross-platform smoke showed the scroll rubber-band is a Wine/Linux render-pipeline quirk, not universal — Windows
+ users never saw it. It will get its own platform-targeted spike in a later patch. Next major cycle is v1.5.0 with the
+ DI-container adoption (Microsoft.Extensions.Hosting + ILogger) modelled on Lightless.
+- Migration v17 stays (no schema bump).
+
+Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
+
+---
+
## Hellion Chat 1.4.9 — Plugin-Load Render Polish (2026-05-15)
Tenth sub-patch of the v1.4.x polish-sweep series. First-frame render cost drops from ~127 ms median down to
diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md
index cec3ffc..5dca8f9 100644
--- a/docs/ROADMAP.md
+++ b/docs/ROADMAP.md
@@ -10,16 +10,29 @@ the plugin's privacy-first scope during brainstorming.
---
-## Next Cycle (v1.4.10)
+## Next Cycle (v1.5.0)
-**Render Clipper, Symbol-Picker and Final-Cleanup.** Reserve items inherited from the v1.4.9 plan that did not need to
-land in the HITCH-cut: an `ImGuiListClipper` for variable-height messages in `DrawMessages` (the OtterGui `ImGuiClip.cs`
-wrapper is the idiom anchor), a Symbol Picker popup for the chat input (`imgui_demo.cpp` Popups & Modal Windows section
-is the pattern reference), plus the carry-over from v1.4.9: structural First-Frame-Layout rewrite if the v1.4.9 selective
-defers turn out to be too narrow once user-side regressions surface. Lazy-Window-Init naive is **not** in scope — the
-v1.4.9 Stage-2 diagnose falsified that path (`WindowSystem.windows` is non-thread-safe, Game-Freeze under reload stress,
-no measurable HITCH delta). A clean DI-container adoption (Lightless `PluginHostFactory` pattern) belongs in v1.5.x and
-will revisit the question with the right threading model.
+**DI-container adoption.** Microsoft.Extensions.Hosting plus `ILogger` modelled on Lightless's `PluginHostFactory`
+pattern. The v1.4.x Polish-Sweep series is closed; v1.5.0 starts the structural cycle that the smaller F12.x indirection
+shims (`IPluginLogProxy`, `IPlatformUtil`) were paving the way for. After that, the Wine/Linux scroll-rubber-band spike
+deferred from v1.4.10 (Reserve-A cancelled — Windows users never saw it) plus the First-Run-Wizard rework that lets users
+opt into the curated defaults instead of just picking a privacy profile.
+
+---
+
+## v1.4.10 — Symbol-Picker and Tell-History Fix (released 2026-05-16)
+
+Eleventh and final sub-patch of the v1.4.x Polish Sweep series. Symbol picker for the chat input — popup with two tabs
+(161 FFXIV PUA glyphs via Dalamud's SeIconChar plus 97 server-verified BMP symbols probed through `/echo` and `/say` in
+a four-round whitelist build) — cursor-aware splice, multi-insert, recent-used strip across both tabs, Settings toggle
+in Chat → Message behaviour. Mid-cycle hotfix for pinned auto-tell tabs: PreloadHistory used to cap the SQL scan at
+500 rows regardless of the user's `AutoTellTabsHistoryPreload` setting, so active users with many partners lost the
+backlog of less-frequent pinned partners; the cap is gone, the `(Receiver, Date)` index keeps SQL fast, the client-side
+loop respects the user setting as the upper bound. Slash-command teardown cleanup wires the v1.4.9 wrappers through
+private fields so dispose detaches the live registration instead of re-registering with identical args. The original
+Reserve-A `ImGuiListClipper` refactor for `DrawMessages` was cancelled after cross-platform smoke showed the scroll
+rubber-band is a Wine/Linux render-pipeline quirk, not universal — Windows-side testing on v1.4.9 confirmed no lag.
+Migration v17 stays.
---
diff --git a/repo.json b/repo.json
index ca1f9ac..6e3095d 100644
--- a/repo.json
+++ b/repo.json
@@ -3,7 +3,7 @@
"Author": "Jon Kazama (Hellion Forge)",
"Name": "Hellion Chat",
"InternalName": "HellionChat",
- "AssemblyVersion": "1.4.9.0",
+ "AssemblyVersion": "1.4.10.0",
"Description": "A Hellion Forge plugin — privacy-focused chat replacement for FINAL FANTASY XIV, built for EU, US and JP data rules.\n\nBy default only your own conversations are stored. Public chat, NPC dialogue, system messages and battle logs are discarded at the storage layer unless you opt in. Retention windows are configurable per channel, history can be wiped retroactively, and everything can be exported on demand.\n\nFeatures:\n- Channel whitelist with a Privacy-First default\n- Per-channel retention with a daily background sweep\n- Retroactive cleanup with preview and Ctrl+Shift confirm\n- Export to Markdown, JSON or CSV\n- First-run wizard with three profiles: Privacy-First, Casual, Full History\n- Bilingual UI (EN/DE) with live language switching\n- Own config and database — no shared state with other plugins\n\nBased on Chat 2 by Infi and Anna (EUPL-1.2).\nSupport: https://discord.gg/X9V7Kcv5gR",
"ApplicableVersion": "any",
"RepoUrl": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat",
@@ -14,12 +14,12 @@
"CanUnloadAsync": false,
"LoadPriority": 0,
"Punchline": "A Hellion Forge plugin. Privacy-first chat for FFXIV, built to stay out of your way.",
- "Changelog": "**v1.4.9 — Plugin-Load Render Polish (2026-05-15)**\n\nTenth sub-patch of the v1.4.x polish-sweep series. First-frame render cost drops from ~127 ms median to ~76 ms median, comfortably under Dalamud's 100 ms HITCH warning threshold.\n\n- First-frame defer: six non-essential rendering sections inside ChatLogWindow skip their first Draw and run one frame later (bottom status bar, channel-name SeString chunks, window bounds check, v0.6.1 hint banner, autocomplete, input-preview calculation). User-visible delay is ~17 ms at 60 fps, hidden inside the post-reload font-atlas build window.\n- Slash-command centralisation: /hellion, /hellionView, /hellionSeString and /hellionDebugger are registered in LoadAsync instead of inside the corresponding window constructors. The plugin-manager Open and configuration buttons hang on the same path.\n- Plugin-load profiling logs stay on at Information level (MessageStore connect/migrate, FilterAllTabs, auto-translate warmup) as a regression tripwire — a future load past 100 ms will show up in /xllog without a Debug filter.\n- ChatTwo IPC compatibility layer: HellionChat now mirrors ChatTwo's full IPC surface (GetChatInputState, ChatInputStateChanged, Register, Unregister, Available, Invoke) under the ChatTwo.* namespace in addition to our existing HellionChat.* provider gates. Third-party integrations that historically only subscribe to ChatTwo's IPC — for example Artisan's and AllaganTools' context-menu hooks — keep working without requiring a code change on their side. Conflict detection prevents ChatTwo from loading in parallel with HellionChat, so there is no slot-collision risk at runtime.\n- Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.8 — Hook-Layer and Polish Quick-Wins (2026-05-14)**\n\nNinth sub-patch of the v1.4.x polish-sweep series. Hook-layer cluster (DbViewer FTS5 full-text search, ad-block foundation investigation) plus three polish quick-wins.\n\n- DbViewer full-text search: optional FTS5 index across the full chat history. Built asynchronously on first load after the update with a progress toast. The local page-filter remains available as the default mode. Queries match as exact phrases -- multi-word terms must appear together in order; advanced users can opt into raw FTS5 MATCH syntax by wrapping their own double-quotes.\n- Custom theme files now auto-reload when edited while the theme is active -- no need to re-click the theme in the picker.\n- Retention sweep no longer blocks the framework thread, removing the ~194ms mini-hitch per sweep.\n- Status bar renders correctly at Windows display scaling > 100%.\n- Receive-suppressed-tells routing investigated this cycle and postponed to v1.5.x: when other plugins suppress tells via CheckMessageHandled, the FFXIV chat pipeline skips the RaptureLogModule.AddMsgSourceEntry path so HellionChat's ContentIdResolverHook does not fire and tell-partner identification breaks. The fix belongs next to the planned ad-block hook layer where the same patch surface comes up.\n- Internal: messages.Id is declared BLOB but stored as TEXT (Microsoft.Data.Sqlite Guid binding). FTS bulk insert and LoadByGuids match the TEXT storage form on both sides. Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.7 — Backlog Cleanup and Mid-Features (2026-05-13)**\n\nEighth sub-patch of the v1.4.x polish-sweep series. First user-visible feature bundle since v1.4.5 — pinned tell tabs that survive relog, opt-in Honorific glow rendering, and a configurable sidebar.\n\n- TempTell Pin: right-click a TempTell tab in the sidebar to pin it. Pinned tabs survive relog, keep their conversation history (loaded on demand from the message store), and stay bound to the same /tell partner. Hard cap of 5 pinned tabs in a pool separate from the 15-tab auto-tell pool — total ceiling is 20 tabs. New 'Angepinnt' / 'Pinned' section in the sidebar with its own divider header\n- Honorific Glow outline now renders when the title carries a Glow colour. Opt-in via Settings → Integrations → 'Render glow outlines (Honorific)' (default off, dodges the per-frame DrawList overhead on low-end hardware). Gradient (Color3 / GradientColourSet / Wave / Pulse) is parsed but rendered statically — a later cycle will port the full animation\n- Sidebar width is now configurable in Theme & Layout (range 44–160 px). Default stays icon-only; widen to fit section headers like 'Aktive Tells (3)' without truncation\n- Settings Save no longer pops the chat input back to /tell with a pinned partner — Configuration.UpdateFrom now preserves the runtime CurrentChannel across the persistent-tab merge, and TabSwitched deep-clones the seeded channel instead of sharing the previous tab's UsedChannel\n- Util/ImGuiUtil.cs DrawArrows IconButton id now uses (id + 1).ToString() instead of the operator-precedence quirk id + 1.ToString() — generated IDs stay numerically stable\n- Internal: IPluginLogProxy indirection over Dalamud's IPluginLog routes all ~91 Plugin.Log call sites through a testable proxy. MessageStore.Migrate0 can now run in xUnit without loading Dalamud.dll, closing the gap F12.1 left in v1.4.6\n- Internal: TempTab counter switched from an Interlocked cached field to a derived Tabs.Count(predicate) — pin-state transitions are cold-path and don't need lock-free reads\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.6 — Code Hygiene and Refactor (2026-05-12)**\n\nMaintenance patch. No user-visible behaviour changes; tightens the development feedback loop, fixes two upstream-inherited bugs, and prepares the code for the v1.4.7 backlog cleanup.\n\n- preflight.sh gains a csharpier reflow check and a markdownlint pass so style drift and markdown violations are caught at the pre-push gate\n- FontManager fallback catches the full set of atlas-toolkit throws (IO, InvalidOperation, ArgumentException) — a corrupt font config no longer takes down the whole atlas build\n- BrandingLinks and IntegrationLinks URLs validated on plugin load — a typo in a future URL rotation now throws at startup\n- Cherry-picked from ChatTwo upstream f35b7d3: Chat.SetChannel no longer leaks the native Utf8String when the linkshell check rejects the channel\n- Cherry-picked from ChatTwo upstream f35b7d3: Tab.Clone now deep-clones UsedChannel and TellTarget — PopOut and Temp tabs no longer mutate each other's channel state\n- Active-tab underline scales with DPI and rounds to physical pixels for crisp rendering above 100% scaling\n- IconButton width parameter no longer subtracts HUD-scaled padding from a raw int (measured width passes through verbatim)\n- Internal: HellionStyle ChildBgAlpha extracted to a testable helper; Plugin.SaveConfig clones only the temp tabs; SettingsOverview caches the draw-list per frame; Dalamud.Utility.Util surface routed through an IPlatformUtil indirection (MessageStore IsWine probe is now testable in isolation)\n- Built-in themes: Crystal Nocturne (sapphire and electric magenta over obsidian, by CRYSTALLITE) replaces Moonlit Bloom. Users with Moonlit Bloom selected fall back to Hellion Arctic on first load\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\nFull history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases",
+ "Changelog": "**v1.4.10 — Symbol-Picker and Tell-History Fix (2026-05-16)**\n\nEleventh and final sub-patch of the v1.4.x polish-sweep series. Symbol picker for the chat input, a tell-history reload fix for users with many active partners, and a closing cleanup sweep before v1.5.0 picks up the DI-container adoption.\n\n- Symbol picker: a small smile-icon button left of the channel indicator opens a popup with two tabs. The first lists all 161 FFXIV PUA glyphs (Dalamud's SeIconChar enum); the second carries 97 server-verified BMP symbols (latin marks, currency, the full Greek alphabet, geometric shapes, suits, notes) — every one of them round-tripped through /echo and /say in a four-round probe so the in-channel render matches what the picker shows. Click drops the glyph at the caret, multi-insert keeps the popup open, and a recent-used strip floats the last sixteen picks across both tabs. Toggle in Settings → Chat → Message behaviour, default on.\n- Pinned auto-tell tabs reload their full history again: a hidden 500-row scan cap in PreloadHistory used to override the user-configurable AutoTellTabsHistoryPreload setting, so less-frequent pinned partners (rare /tell sessions in an otherwise busy week) lost their backlog. The cap is removed; the (Receiver, Date) index keeps SQL fast, the client-side loop still respects your setting as the upper bound.\n- Slash-command teardown: /hellion, /hellionView, /hellionDebugger (and #if DEBUG /hellionSeString) wrappers are now cached as private fields. Plugin teardown detaches the live registration instead of re-Register'ing with identical args — closes a latent maintenance hazard from v1.4.9.\n- v1.4.x polish-sweep wraps up here. The ImGuiListClipper render refactor that was on the v1.4.10 reserve list got dropped after cross-platform smoke showed the scroll rubber-band is a Wine / Linux render-pipeline quirk, not universal — Windows users never saw it. It will get its own platform-targeted spike in a later patch. Next major cycle is v1.5.0 with the DI-container adoption (Microsoft.Extensions.Hosting + ILogger) modelled on Lightless.\n- Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.9 — Plugin-Load Render Polish (2026-05-15)**\n\nTenth sub-patch of the v1.4.x polish-sweep series. First-frame render cost drops from ~127 ms median to ~76 ms median, comfortably under Dalamud's 100 ms HITCH warning threshold.\n\n- First-frame defer: six non-essential rendering sections inside ChatLogWindow skip their first Draw and run one frame later (bottom status bar, channel-name SeString chunks, window bounds check, v0.6.1 hint banner, autocomplete, input-preview calculation). User-visible delay is ~17 ms at 60 fps, hidden inside the post-reload font-atlas build window.\n- Slash-command centralisation: /hellion, /hellionView, /hellionSeString and /hellionDebugger are registered in LoadAsync instead of inside the corresponding window constructors. The plugin-manager Open and configuration buttons hang on the same path.\n- Plugin-load profiling logs stay on at Information level (MessageStore connect/migrate, FilterAllTabs, auto-translate warmup) as a regression tripwire — a future load past 100 ms will show up in /xllog without a Debug filter.\n- ChatTwo IPC compatibility layer: HellionChat now mirrors ChatTwo's full IPC surface (GetChatInputState, ChatInputStateChanged, Register, Unregister, Available, Invoke) under the ChatTwo.* namespace in addition to our existing HellionChat.* provider gates. Third-party integrations that historically only subscribe to ChatTwo's IPC — for example Artisan's and AllaganTools' context-menu hooks — keep working without requiring a code change on their side. Conflict detection prevents ChatTwo from loading in parallel with HellionChat, so there is no slot-collision risk at runtime.\n- Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.8 — Hook-Layer and Polish Quick-Wins (2026-05-14)**\n\nNinth sub-patch of the v1.4.x polish-sweep series. Hook-layer cluster (DbViewer FTS5 full-text search, ad-block foundation investigation) plus three polish quick-wins.\n\n- DbViewer full-text search: optional FTS5 index across the full chat history. Built asynchronously on first load after the update with a progress toast. The local page-filter remains available as the default mode. Queries match as exact phrases -- multi-word terms must appear together in order; advanced users can opt into raw FTS5 MATCH syntax by wrapping their own double-quotes.\n- Custom theme files now auto-reload when edited while the theme is active -- no need to re-click the theme in the picker.\n- Retention sweep no longer blocks the framework thread, removing the ~194ms mini-hitch per sweep.\n- Status bar renders correctly at Windows display scaling > 100%.\n- Receive-suppressed-tells routing investigated this cycle and postponed to v1.5.x: when other plugins suppress tells via CheckMessageHandled, the FFXIV chat pipeline skips the RaptureLogModule.AddMsgSourceEntry path so HellionChat's ContentIdResolverHook does not fire and tell-partner identification breaks. The fix belongs next to the planned ad-block hook layer where the same patch surface comes up.\n- Internal: messages.Id is declared BLOB but stored as TEXT (Microsoft.Data.Sqlite Guid binding). FTS bulk insert and LoadByGuids match the TEXT storage form on both sides. Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.7 — Backlog Cleanup and Mid-Features (2026-05-13)**\n\nEighth sub-patch of the v1.4.x polish-sweep series. First user-visible feature bundle since v1.4.5 — pinned tell tabs that survive relog, opt-in Honorific glow rendering, and a configurable sidebar.\n\n- TempTell Pin: right-click a TempTell tab in the sidebar to pin it. Pinned tabs survive relog, keep their conversation history (loaded on demand from the message store), and stay bound to the same /tell partner. Hard cap of 5 pinned tabs in a pool separate from the 15-tab auto-tell pool — total ceiling is 20 tabs. New 'Angepinnt' / 'Pinned' section in the sidebar with its own divider header\n- Honorific Glow outline now renders when the title carries a Glow colour. Opt-in via Settings → Integrations → 'Render glow outlines (Honorific)' (default off, dodges the per-frame DrawList overhead on low-end hardware). Gradient (Color3 / GradientColourSet / Wave / Pulse) is parsed but rendered statically — a later cycle will port the full animation\n- Sidebar width is now configurable in Theme & Layout (range 44–160 px). Default stays icon-only; widen to fit section headers like 'Aktive Tells (3)' without truncation\n- Settings Save no longer pops the chat input back to /tell with a pinned partner — Configuration.UpdateFrom now preserves the runtime CurrentChannel across the persistent-tab merge, and TabSwitched deep-clones the seeded channel instead of sharing the previous tab's UsedChannel\n- Util/ImGuiUtil.cs DrawArrows IconButton id now uses (id + 1).ToString() instead of the operator-precedence quirk id + 1.ToString() — generated IDs stay numerically stable\n- Internal: IPluginLogProxy indirection over Dalamud's IPluginLog routes all ~91 Plugin.Log call sites through a testable proxy. MessageStore.Migrate0 can now run in xUnit without loading Dalamud.dll, closing the gap F12.1 left in v1.4.6\n- Internal: TempTab counter switched from an Interlocked cached field to a derived Tabs.Count(predicate) — pin-state transitions are cold-path and don't need lock-free reads\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\nFull history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases",
"AcceptsFeedback": true,
- "DownloadLinkInstall": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.9/latest.zip",
- "DownloadLinkUpdate": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.9/latest.zip",
- "DownloadLinkTesting": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.9/latest.zip",
- "TestingAssemblyVersion": "1.4.9.0",
+ "DownloadLinkInstall": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.10/latest.zip",
+ "DownloadLinkUpdate": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.10/latest.zip",
+ "DownloadLinkTesting": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.10/latest.zip",
+ "TestingAssemblyVersion": "1.4.10.0",
"IconUrl": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/raw/branch/main/HellionChat/images/icon.png",
"ImageUrls": [
"https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/raw/branch/main/HellionChat/images/chatWindow.png",