Commit Graph
136 Commits
Author SHA1 Message Date
JonKazama-Hellion 1d3b429f1b style(format): apply csharpier and markdownlint reflow
Security / scan (push) Successful in 23s
Build / Build (Release) (push) Successful in 31s
Forge Announce / Post changelog to Hellion Forge (push) Successful in 6s
Release / Build and attach release ZIP (push) Successful in 41s
2026-05-23 09:07:01 +02:00
JonKazama-Hellion 4cf7aa5501 refactor(settings): merge integrations into the About tab, finalize seven tabs 2026-05-23 04:11:18 +02:00
JonKazama-Hellion 0da4751b0f refactor(settings): merge privacy into the Data and Privacy tab 2026-05-23 03:20:04 +02:00
JonKazama-Hellion ee39fd0eec refactor(settings): rebuild the per-tab panel into sub-sections 2026-05-23 02:22:55 +02:00
JonKazama-Hellion 78efd654e6 refactor(settings): rebuild the Window tab into three sections 2026-05-23 01:30:41 +02:00
JonKazama-Hellion d3cea8c6c0 refactor(settings): rebuild the Chat tab and pull in tooltips and novice network 2026-05-23 00:57:28 +02:00
JonKazama-Hellion 3058e6bc6d refactor(settings): merge fonts, colours and window style into the Appearance tab 2026-05-23 00:05:49 +02:00
JonKazama-Hellion 8a8c6ccae2 refactor(settings): rebuild the General tab into collapsible sections 2026-05-22 23:07:01 +02:00
JonKazama-Hellion eafa20748c refactor(settings): wire the section-open signal, rename tab files 2026-05-22 22:26:04 +02:00
JonKazama-Hellion b3fc96f424 revert(ui): remove the per-tab regex filter 2026-05-22 21:42:43 +02:00
JonKazama-HellionandClaude Sonnet 4.6 c652b102fc feat(ui): add sender name display options
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 17:20:51 +02:00
JonKazama-Hellion ba4cd918da feat(ui): warn before sending plugin-only symbols 2026-05-22 16:41:06 +02:00
JonKazama-Hellion a6e2a75422 feat(ui): add optional regex filter per tab 2026-05-22 15:41:48 +02:00
JonKazama-Hellion d05770fd6d feat(ui): separate opacity for focused and unfocused chat window 2026-05-22 15:03:56 +02:00
JonKazama-Hellion 921dd701c4 feat(audio): add custom sound volume slider 2026-05-22 14:28:22 +02:00
JonKazama-Hellion cc1c05add0 feat(ui): add bundled custom notification sounds
Adds three embedded WAV files as additional notification sound choices
(ids 17-19) alongside the existing 16 game sounds. Playback via NAudio
WaveOutEvent/WinMM, which works correctly on Wine/Linux.
2026-05-21 20:07:09 +02:00
JonKazama-Hellion 969d5e6aa6 feat(ui): add a preview button for the per-tab notification sound 2026-05-21 19:01:45 +02:00
JonKazama-Hellion aaeca76bfd fix(branding): enlarge fox banner and add a contrast card 2026-05-21 19:01:42 +02:00
JonKazama-Hellion 4f6c916bd9 feat(branding): replace ASCII fox banner with embedded image 2026-05-21 18:47:25 +02:00
JonKazama-Hellion ce7dda9e48 fix(ui): null-guard agent access and refocus input after token insert
AgentMap.Instance() and AgentChatLog.Instance() can return null during
zone transitions. Capture pointers into locals and short-circuit the
FlagMarkerCount/LinkedItem deref when null so the entries are correctly
greyed out without faulting. Add Activate/ActivatePos after each append
so the input box regains focus and the caret lands after the token,
matching the SymbolPicker and AutoComplete insert paths.
2026-05-21 18:15:12 +02:00
JonKazama-Hellion 80699b27e4 feat(ui): insert map-flag and item-link tokens from chat input 2026-05-21 18:08:49 +02:00
JonKazama-Hellion 3296a12516 style: drop task references from cycle code comments 2026-05-21 14:52:58 +02:00
JonKazama-Hellion 81123ccddf style: apply csharpier formatting to cycle files 2026-05-21 14:46:19 +02:00
JonKazama-Hellion 636a62814f fix(ui): isolate scroll-button state from pop-outs and tidy toolbar
Guard _childScrolledUp writes behind updateScrollState param so pop-out
windows no longer contaminate the main window's scroll state. Widen the
honorific title slot budget when the scroll button is visible, fix stale
comment, and apply csharpier formatting.
2026-05-21 14:43:26 +02:00
JonKazama-Hellion b5aebaad35 fix(ui): keep scroll-to-bottom button on the toolbar row 2026-05-21 14:32:25 +02:00
JonKazama-Hellion bd75f2453c fix(ui): move scroll-to-bottom button into the chat header toolbar
Drop the three-attempt floating overlay entirely. The button now lives in
the chat header toolbar (DrawScrollToBottomToolbarButton), visible only when
the user is scrolled above the live end. Toolbar layout: honorific slot,
scroll button, pop-out button flush-right -- pop-out position unchanged.
2026-05-21 14:22:58 +02:00
JonKazama-Hellion c909d1646b fix(ui): draw scroll-to-bottom button in a standalone overlay window
Button drawn in the parent window over the ##chat2-messages child was never
clickable: ImGui resolves g.HoveredWindow to the child for that screen rect, so
ItemHoverable rejects any item submitted in the parent. A top-level Begin/End
window is a sibling in the window list and wins the hit-test for its own rect.
ownerId parameter keeps the window name distinct between the main window and
each pop-out, preventing Begin/End collisions when both render in the same frame.
2026-05-21 14:10:01 +02:00
JonKazama-Hellion 65fea0e5f5 fix(ui): render scroll-to-bottom button as a parent overlay
The button was drawn inside the ##chat2-messages child via SetCursorPos,
which inflated ContentSize.y / ScrollMaxY each frame (causing positional
drift) and was clipped by the scrollbar's inner clip rect (causing right-
edge cutoff). Move it to the parent window using screen-space coordinates
captured before the child opens; the scroll state is cached inside the
child while GetScrollMaxY/Y still refer to the child's scroll context.
2026-05-21 13:46:42 +02:00
JonKazama-Hellion 3de6e4a3cb feat(ui): add scroll-to-bottom button to the chat log 2026-05-21 13:03:36 +02:00
JonKazama-Hellion e0289962b1 style: remove em-dashes from new code comments 2026-05-21 12:10:17 +02:00
JonKazama-Hellion 95375c8516 feat(ui): auto-focus tab rename and raise buffer to 512 2026-05-21 11:16:53 +02:00
JonKazama-Hellion 36ea8ddcfc feat(ui): add per-tab notification sound for inactive tabs 2026-05-21 10:39:09 +02:00
JonKazama-Hellion 246f0e2511 feat(ui): notify on failed tell via RaptureLogModule hook 2026-05-21 10:00:53 +02:00
JonKazama-Hellion 57b6ead003 release(v1.5.4): manifest bump and forge post
Bumps csproj, yaml, repo.json, CHANGELOG, ROADMAP and README in
lock-step to 1.5.4. Forge-post DE-body added with the Polish & Motion
versionsnatur. Slim-rule applied to the yaml and repo.json changelog
blocks (keeps v1.5.4 + v1.5.3 + v1.5.2 + v1.5.1, drops v1.5.0).

A csharpier reflow of two v1.5.4 source files (ChatLogWindow,
HellionStyle) is folded in. preflight.sh blocks A-F all green.
2026-05-20 16:32:42 +02:00
JonKazama-Hellion 96ff4ddfd8 feat(ui): lerp sidebar-icon and card-mode-border hover alphas
Sidebar icons ease from 40% to 100% alpha on hover-in via FrameLerp
plus ApplyAlpha. Card-mode borders aggregate row-hover per tab and
lift the border alpha by up to ~+0x70 across every row in that tab.
borderColorAbgr moves into the loop so the per-iteration boost can
apply. ReduceMotion snaps both paths instantly.

Card-hover detection uses IsMouseHoveringRect over the row bounds --
IsItemHovered would only see the 2px spacer dummy below each row.
2026-05-20 14:42:21 +02:00
JonKazama-Hellion 01a7f9b4ec feat(ui): add header quick-picker for themes and tabs
Palette button left of the cog opens a two-section popup. The themes
section enumerates AllBuiltIns + AllCustom; the tabs section
enumerates Config.Tabs. The active entry gets a leading check-glyph,
inactive rows a same-width blank so labels stay aligned. Click
selects without closing the popup (DontClosePopups).

Theme click triggers the PM-1 crossfade via ThemeRegistry.Switch;
tab click routes through ChangeTab so LastActivityTime stays
consistent with the sidebar and top-bar click paths.

The header input-width reservation now counts the new button plus
the per-button SameLine spacing -- the old formula dropped the
spacing term and overflowed the row once a third button appeared.
2026-05-20 12:48:31 +02:00
JonKazama-Hellion a600f014eb i18n: add quick-picker strings and reduce-motion settings toggle
Five new keys across the EN source plus 24 locale variants (DE plus
23 AI-assisted, each carrying the pending-review marker): the header
quick-picker tooltip and two section headers, plus name and
description for a new ReduceMotion checkbox.

ReduceMotion was a config field with no UI -- the checkbox lands in
the Theme & Layout tab's window-style section. Designer.cs hand-edited
as a v1.5.4 block matching the v1.4.8 convention.
2026-05-20 11:07:45 +02:00
JonKazama-Hellion a35067f80a feat(ui): wire ThemeRegistry crossfade into PushGlobal
Switch picks a lerped AbgrCache during the 300ms crossfade window
(ReduceMotion bypass keeps the snap path). Plugin-load init path
switches to SwitchSilent so opening the plugin no longer fades from
the default theme. WindowBg/ChildBg RGBA path stays bound to the
user's per-window opacity override and never fades.

PushGlobal takes the ThemeRegistry as a parameter -- it is an instance
member on Plugin, not static, so the single Plugin.Draw call-site
threads it through alongside the active theme.
2026-05-20 10:36:33 +02:00
JonKazama-Hellion 35e8d3a7fe fix(font): bundled font now actually renders, ship Inter Light, +CJK fallback
Security / scan (push) Successful in 19s
Build / Build (Release) (push) Successful in 29s
Forge Announce / Post changelog to Hellion Forge (push) Successful in 5s
Release / Build and attach release ZIP (push) Successful in 49s
Plugin.cs:937 only pushed RegularFont when Config.FontsEnabled was true.
  FontsAndColours.cs:50 forces FontsEnabled=false whenever UseHellionFont is
  enabled (to hide the chooser UI), so the bundled-font path was silently
  dead and the FFXIV Axis game-font took over. Exo 2 looked "almost right"
  because it overlaps Axis on basic Latin, so the regression went unnoticed
  for the entire v1.5.x series.

  The fix routes RegularFont through draw whenever either FontsEnabled or
  UseHellionFont is on. First-frame HITCH dropped from ~74 ms to ~20 ms
  median (5-reload Linux/Wine sample 17.9-23.6 ms) as a side effect — the
  v1.5.1 "too optimistic" defer-pattern hypothesis was actually a symptom
  of this bug, not bad math.

  Font-stack overhaul on top:
  - Inter Light (Static 18pt-Light, 343 KB, SIL OFL 1.1) replaces Exo 2 as
    the bundled font. Inter ships full Latin Extended-A/B, Greek polytonic
    and Cyrillic Supplement coverage.
  - NotoSansCjkRegular added as a third merge layer for Hangul,
    Simplified-Chinese-specific Han glyphs, and CJK fallbacks the FFXIV
    Japanese font does not ship.
  - Two new ExtraGlyphRanges flags (LatinExtended, Greek) implemented via
    AddChar pair lists in SetUpRanges.
  - Settings.Apply auto-activates the matching ExtraGlyphRanges flag on
    language change. Plugin.LoadAsync runs a one-shot migration that ORs
    in the required flag for an already-selected language.
  - ExtraGlyphRanges CollapsingHeader reachable regardless of
    UseHellionFont (was hidden in the early-return branch).
  - New WarningText below the language combo: FFXIV's chat engine only
    fully supports EN/DE/FR/JA. Other scripts render in the HellionChat
    UI but may garble in in-game chat input/send.

  Localisation wave (originally a FR-only cycle):
  - 24 selectable UI languages. LanguageOverride enum gains 10 new locales
    plus 3 previously commented-out (Italian, Korean, Norwegian with ISO
    code `nb` instead of `no`). All new values append to keep existing
    user-config integer serialisation stable.
  - Resource bundle split: HellionStrings.resx (24 locales, 328 keys) for
    fork-added strings, Language.resx (24 locales, 456 keys) for the
    ChatTwo-Crowdin-heritage. 4 post-sync Crowdin keys backfilled into
    13 legacy locales with per-key AI-assisted comment marker.
  - Em-dash sweep on EN source plus 18 translations. Russian and Ukrainian
    keep their typographic norm.

  Old HellionFont.ttf + HellionFont-OFL.txt removed; Inter-Light.ttf +
  Inter-OFL.txt take their place. Configuration field UseHellionFont keeps
  its name for backwards-compat. Migration v17 stays.
2026-05-19 17:28:48 +02:00
JonKazama-Hellion 35efdd4628 style(wizard): reflow FirstRunWizard and WizardStateSmokeStep to csharpier
Preflight Block E (`dotnet csharpier check`) flagged two reflows
in the v1.5.2 code: the ForgeBronzeDim Vector4 constant needed
multi-line form, and a handful of switch arms / long Plugin.Config
chains in WizardStateSmokeStep needed line-breaks at csharpier's
print-width. Pure formatting — zero functional change. Block D
build stays clean, Block E now passes.
2026-05-18 23:46:00 +02:00
JonKazama-Hellion 1e418ab86f fix(ui): shrink wizard window and fold the Fox banner by default
Smoke feedback v1.5.2 R1: the 900x560 default size dominated the
screen and the centred MonoFont fox silhouette filled the welcome
step. Default size drops to 720x480, MinimumSize to 600x400, so
the wizard fits comfortably on a sub-monitor and still leaves the
power-settings step readable when shrunk. Step 1 wraps the banner
in a folded TreeNode (label "Hellion Forge", same anchor pattern
the v1.5.1 wizard used) so the onboarding copy stays the primary
focus and users opt into the silhouette explicitly.
2026-05-18 23:10:53 +02:00
JonKazama-Hellion 2cc260170e feat(ui): rewrite FirstRunWizard as four-step staged-commit flow
Multi-step navigation (Welcome → Privacy → Power Settings → Done)
with a nested WizardState holding nullable Pending* fields. Profile
picker becomes a 2x2 grid covering all four privacy profiles
(PrivacyFirst, Casual ★ recommended, Roleplay new, FullHistory).
Power-settings step surfaces six previously-hidden Configuration
fields (LoadPreviousSession, FilterIncludePreviousSessions,
AutoTellTabsHistoryPreload, UseCompactDensity, PrettierTimestamps,
Theme) without introducing new ones. ApplyRoleplay mirrors the
existing Apply* methods, CommitPending writes only the non-null
fields back so skipping a step preserves existing config. OnClose
docstring updated to reflect the actual code path (both Decide-Later
and Finish set FirstRunCompleted = true, the wizard does not reopen).
2026-05-18 21:15:27 +02:00
JonKazama-Hellion 54316313dc feat(branding): embed Hellion Forge fox ASCII signature
Ship two ASCII variants as embedded resources under HellionChat.Branding:

- fox-banner.txt — full silhouette with "Hellion Forge" set inside the
  body, rendered in the first-run wizard and the Settings Information
  tab as a folded "about the makers" anchor
- fox-mini.txt — compact fox-head + curly-tail used by the DI-logger
  bootstrap banner

A small HellionForgeAscii helper lazy-loads both strings; the wizard
and information-tab render them in a collapsed TreeNode using the
UiBuilder MonoFontHandle so the stipple-art lands pixel-aligned.

Both art files are self-made (Julia Moon, free to use) and travel with
the plugin DLL so a partial deploy can't lose them.
2026-05-17 18:40:08 +02:00
JonKazama-Hellion 3283e51381 refactor(fonts): hybrid FontManager init via SuppressAutoRebuild
Move font handle creation from BuildFonts() into the FontManager ctor
inside a single atlas.SuppressAutoRebuild() block. Axis, AxisItalic and
FontAwesome become init-only IFontHandle properties; RegularFont and
ItalicFont stay mutable so the live font-settings rebuild path keeps
working without a plugin reload.

- BuildFonts() renamed to RebuildDelegateFonts(), scope reduced to the
  delegate fonts only
- BuildFontsAsync() removed; Task.Run had no purpose with ctor-init
- FontManagerInitHostedService deleted; PluginHostFactory drops the
  matching AddHostedService registration
- PluginHostFactory FontManager registration takes IDalamudPluginInterface
  via factory lambda
- Settings save path now calls RebuildDelegateFonts() instead of
  BuildFonts()
- Plugin.Draw push site gets a null-forgiving for the nullable
  RegularFont with a one-line WHY
2026-05-17 16:15:28 +02:00
JonKazama-Hellion 54ff88d6d4 refactor(di): migrate Root + Misc to ILogger<T> (DI-4 Slice D)
Slice D shrinks vs the original plan: three of the six files cannot
take an ILogger ctor arg without breaking external contracts.

Migrated (8 LogProxy sites across 4 files):
- Commands: 2 sites (Warning, Error). New ctor takes ILogger<Commands>.
- Themes/ThemeRegistry: 1 site (Debug). ILogger<ThemeRegistry>? is
  optional (default null) so the existing Build-Suite tests that
  construct `new ThemeRegistry()` parameterless keep working without
  changes. _logger?.LogDebug guards the call site.
- PayloadHandler: 3 sites (Error, Warning, Error). New ctor takes
  ILogger<PayloadHandler>. ChatLogWindow's two `new PayloadHandler(this)`
  sites (the direct field and the Lender lambda) now hand a fresh
  CreateLogger<PayloadHandler>() from the existing _loggerFactory.

Not migrated (5 sites stay on Plugin.LogProxy, plan drifts D12-D14):
- D12 - Configuration (1 site): IPluginConfiguration, instantiated by
  Dalamud's Interface.GetPluginConfig() via reflection on the
  parameterless ctor. Adding an ILogger arg would break GetPluginConfig.
- D13 - Message (4 sites): partial data class with two ctor overloads,
  mass-instantiated across 3 plugin sites plus Newtonsoft JSON
  deserialisation. Ctor extension would be invasive across ~20 call
  sites with low payoff (data-class logger is unusual).
- D14 - FontManager (2 sites): both Plugin.LogProxy calls live in
  static methods (TryGetHellionFontBytes, AddFontWithFallback) that
  cannot reach an instance _logger. Same root cause as D8 in
  GameFunctions. FontManager joins the static-bucket alongside
  EmoteCache et al.; the ctor + _logger field added mid-Slice-D were
  rolled back to keep the class clean.

Plugin.LogProxy surface after C9 (8 file buckets, ~12 sites total):
- 4 originally-static consumers: EmoteCache, AutoTranslate,
  MemoryUtil, WrapperUtil
- 3 cannot-take-ctor-arg consumers: Configuration, Message, FontManager
- 1 single-static-method consumer: GameFunctions.TryOpenAdventurerPlate
  (D8 from Slice B)

Smoke 2 is now due.
2026-05-17 11:02:08 +02:00
JonKazama-Hellion c955f30422 refactor(di): migrate UI Window-Layer to ILogger<T> (DI-4 Slice C)
Six UI files shift from Plugin.LogProxy to ILogger<T> via
constructor injection.

Container singletons (each takes a typed ILogger plus, where it owns
nested allocations, an ILoggerFactory to spawn child loggers):
- Ui/ChatLogWindow (15 sites, plus an ILoggerFactory for the
  Popout new-call at Ui/ChatLogWindow.cs:2417)
- Ui/Settings (SettingsWindow): no own sites, but takes an
  ILoggerFactory so it can hand typed loggers to its three migrated
  settings tabs (General, the other six tabs stay unchanged)
- Ui/DbViewer (3 sites)

Nested instances allocated by parent containers:
- Ui/Popout (7 sites, ILogger<Popout> as the new 4th ctor arg passed
  from ChatLogWindow)
- Ui/SettingsTabs/ThemeAndLayout (1 site)
- Ui/SettingsTabs/FontsAndColours (1 site)
- Ui/SettingsTabs/DataManagement (15 sites)

PluginHostFactory factory lambdas updated for ChatLogWindow,
SettingsWindow and DbViewer to resolve the new logger args.
2026-05-17 10:26:47 +02:00
JonKazama-Hellion 8a18f7caaa fix(chat-input): replace input on slash-command insert
Cherry-pick from ChatTwo upstream ee7768ac (Infiziert90, 2026-05-16):
when args.AddIfNotPresent or args.Input starts with '/', replace the
chat input instead of appending. Fixes the Friend-List "/tell" path
where existing text like "test" would otherwise concatenate to
"test/tell user@world" before the receiver and channel resolve.

Variable drift versus upstream: HellionChat uses local 'Chat' where
ChatTwo uses InputHandler.ChatInput; logic is 1:1.
2026-05-17 02:26:03 +02:00
JonKazama-Hellion 667950c98e docs: add v1.4.10 forge announcement post and apply csharpier reflow
Forge-Post is required in the tagged tree so forge-announce.yml can read
it during the release-pipeline run. Plus a csharpier reflow on two files
(SymbolPicker.cs, ChatLogWindow.cs) that preflight Block E flagged after
the cycle's comment-tightening sweep — purely whitespace, no behaviour
change.
2026-05-16 14:01:17 +02:00
JonKazama-Hellion 51f18e46a0 chore(comments): tighten v1.4.10 inline commentary after self-review
Five trim spots from the cycle's earlier commits — none change behaviour,
just drop redundant phrasing and stale references per the HellionChat
comment-style convention (1-3 lines default, link "same as X" instead of
repeating, file:line refs only where they aid navigation).

SymbolPicker:
- BmpWhitelist header consolidated to source + filter ranges
- ImRaii.Popup pattern links the established ChatLogWindow popup idiom
  instead of citing three call-sites
- ToIconString comment drops the "discoverability" footnote that the
  code already telegraphs
- Manually-wrapping comment drops the "same modern idiom" tail that
  duplicated the preceding sentence

MessageStore:
- Merge the stale pre-v1.4.10 sqlScanLimit comment with the new
  v1.4.10 commentary; the cap mention now describes the historical
  reason rather than a parameter that no longer exists
2026-05-16 12:49:01 +02:00
JonKazama-Hellion 679b8f0f5e feat(settings): toggle for the symbol-picker chat-input button
Adds a Configuration property, defaulted to enabled, and a checkbox in
the Chat settings tab's Behaviour section. Strings live in HellionStrings
so DE/EN stays in sync. Defaults aligned with our 'discoverable by
default, hidden by user choice' convention. Schema stays at v17 — the
new boolean is additive, the default constructor covers existing configs.
2026-05-16 10:05:37 +02:00