The text-disabled colour alone made greeted tabs visually weak in the
sidebar. Push dimmed Header and HeaderHovered values alongside the
existing Text push so the selected and hovered states match the
greeted state too. Idle state stays untouched because ImGui Selectable
has no idle background slot.
The preview block caches the deletion estimate from the last refresh.
When the user toggles whitelist channels afterwards the cached number
no longer reflects the current selection. Snapshot the whitelist on
refresh and detect drift on every frame; on drift, grey out the counts
and surface a stale hint plus an emphasised refresh button. Sits
alongside the existing Cleanup_Help_SavedNote, which warns about a
different mismatch (mutable vs saved) and stays as-is.
Three FontChooser ContinueWith handlers wrote Mutable.* directly from
the threadpool. Wrap the result-write in Plugin.Framework.Run so the
mutation lands on the same thread that owns the rest of the UI state.
Matches the marshalling pattern already used by Database.cs and
Privacy.cs background work.
async void Task.Run() is a no-op for awaiting purposes since the void
returns immediately. Switch LoadData to async Task and have the two
callers fire-and-forget the task directly. Exceptions still go through
the existing try/catch inside LoadData.
Both tab classes were the last two settings tabs still pulling their
display name from the upstream Language resource bundle. Move them
into HellionStrings so all eight settings tabs share one i18n source.
The unused Language.Options_*_Tab keys stay around for backwards
compat with cherry-picked upstream tabs.
Drop the inline wall-of-text description in favour of the standard
HelpMarker tooltip used across the rest of the v0.5.0 settings UX.
Visual consistency for the General tab.
Spawn six themed tabs out of the box instead of one General catch-all:
General (everything), Free Company (FC chat plus FC announcements and
login/logout), Party (Party, CrossParty, Alliance, PvP team plus loot
rolls), Beginner (Novice Network only when ShowNoviceNetwork is on),
Linkshell (all eight regular and cross-world linkshells together) and
Tell Exclusive (TellIncoming/TellOutgoing as a safety-net catch-all in
case Auto-Tell-Tabs misses one).
Tab names live in HellionStrings (EN/DE). The Tabs settings tab gains a
help-text hint above the list recommending one tab per linkshell when
the user is in multiple, since a single combined Linkshell tab gets
noisy fast for active users.
- Configuration.cs: ShowTitleBar defaults to true so a fresh install
shows the window header instead of leaving the user without a drag
handle and hide button
- Configuration.cs: MaxLinesToRender default drops from 10000 to 5000
to match the slider's intended ceiling and the previous user-tuned
baseline
- ChatLogWindow.cs: 24h-clock checkbox now actually flips the format.
The Bestand path passed null culture which on a German system
locale always rendered 24h regardless of the toggle
- Appearance.cs + ChatLogWindow.cs + Popout.cs: when Hellion theme is
enabled the global theme opacity drives the chat-window BgAlpha and
the legacy WindowAlpha slider is disabled, so the two opacity
controls no longer fight each other
- Appearance.cs: ticking UseHellionFont now flips FontsEnabled off so
the two mutually-exclusive font stacks no longer appear active at
the same time
- Plugin.cs: mark RetentionSweepRunning volatile so the ImGui thread
reads the latest value without a stale register-cached copy
- EmoteCache.cs: reset State to Unloaded on exception so a later
trigger can retry instead of being blocked by the early-out
- Settings.cs: switch the SaveAndClose / Discard buttons to Allman
bracing for consistency with the rest of the file, and include the
ItemSpacing in the Ko-fi-button right-edge calculation
- Privacy.cs: add a saved-policy hint above the manual retention
Ctrl+Shift button so the existing Cleanup wording pattern is
matched here too
- HellionStrings: drop seven unreferenced keys (Theme_Heading,
Migration_Notification_*, Migration_Webinterface_Removed_*,
AutoTellTabs_Migration_*) and their EN/DE values, add the new
Retention_Help_SavedNote string
The nine legacy tab implementations were superseded by the new eight
themed tabs. Removing them now that the consolidated structure is in
place keeps SettingsTabs/ aligned with what actually ships.
Three collapsible sections: version info (author, discord handle,
version, issue tracker), about HellionChat (maintainer, mission, build
lineage, license, SE notice, localisation, translator list), and the
changelog (auto-print toggle plus the manifest changelog renderer).
Drop the redundant inner Advanced TreeNode in the Maintenance section,
flatten the duplicated indent in the Overview section, and rename the
section headings so they reflect their content (Overview shows
metadata, Maintenance hosts the shift-gated tooling).
The translator section sat inside a child window whose height was
computed as "whatever is left in the content region minus a line".
Once the About copy grew with the new mission and rewritten built-on
sections, that remaining space dropped close to zero on smaller
settings windows, so the tree node was rendered but its content was
either invisible or unscrollable from the parent.
Drop the fixed-height child entirely. The settings window already
provides a scroll container around each tab, so rendering the tree
node and the translator list directly into it lets the parent
handle the scroll. The translators get a manual indent push to keep
the visual nesting that the child-frame used to suggest.
The About tab copy was hand-written in English directly in About.cs,
which left the German users on the upstream Chat 2 wording for the
Hellion-specific blocks. The copy itself also leaned on em-dashes
mid-sentence and on a tone that could read as accusing Chat 2 of
GDPR violations, which was never the intent. This commit moves the
six About-tab sections (Maintainer, Why this fork exists, Built on
Chat 2, License, FFXIV disclaimer, Localization) into HellionStrings
and tightens the wording in both languages.
Tone change is the substantive part. Chat 2's full-history default
is now described as "the right one for most users" rather than a
problem the fork is fixing, and the webinterface removal is framed
as a focus mismatch — Chat 2's webinterface targets remote chat
access from a second device, this fork targets a smaller default
footprint, neither approach is wrong. The personal trigger for the
fork (two million logged messages over two years, mostly /say and
/yell from strangers) stays as it is honest context rather than
criticism.
The same neutralised wording is mirrored in three more places that
described the webinterface removal: the README "Was gegenüber
Chat 2 fehlt" block, the HellionChat.yaml description and changelog,
and the matching repo.json fields. The 0.2.0 changelog no longer
recites the upstream auth-flow internals; "different use case,
substantial rebuild, removed" is enough for users.
Em-dashes were also removed from two body strings that previously
used them as comma replacements (Privacy filter storage-only help
and the retention default description). Heading-level dashes
("Hellion Chat — Welcome", "Export (GDPR Art. 15 — right of
access)") stay because dashes are appropriate as separators in
titles.
The Theme description was already inaccurate — it still talked
about slate-violet tabs and amber highlights even though the brand
sweep moved everything onto Arctic Cyan plus Ember Orange. Updated
to describe the current palette honestly.
The About tab already credits Chat 2 and the maintainers, but it
never said why this fork exists in the first place. New users
discovering Hellion Chat through the Dalamud plugin list could
reasonably read it as a replacement attempt rather than what it is:
a niche alternative for users who care about chat persistence and
data minimisation.
The new "Why this fork exists" block sits between the Maintainer
and the Built-on-Chat-2 sections so the reading order goes from
"who" to "why" to "from what". It states three things plainly:
- Hellion Chat is not trying to replace Chat 2
- The trigger was the maintainer's own database (two years,
two million messages, mostly public-chat from strangers)
- Source is open under the same EUPL-1.2 licence; the upstream
authors are welcome to look, take ideas, ask, or ignore
The tone matches the rest of the About tab — direct, no marketing
voice — and stays in English with the other legal-ish copy so a
single source covers every locale.
The plugin theme drifted from the website palette over time: cyan
sat at #00B8D4 instead of the brand #00BED2, the warm highlights
were industrial amber rather than Ember Orange, and active tabs and
title bars were rendered in slate violet — a shade not part of the
brand at all.
This commit moves every HellionStyle slot onto the Arctic Cyan +
Ember Glow tokens documented in the website's BRANDING.md:
- Primary cyan slots (Button, CheckMark, Slider, Separator) now
use brand-color / brand-color-light / brand-color-dark
- Window title bars and the active tab use brand-color-dark as
Identity teal — slightly varied so it reads as identity rather
than as another action surface
- Unfocused-active tabs drop to a deeper teal so the unfocused
window's tab is still visible without pulling focus
- Resize grips and scrollbar grabs lift into Ember Orange on hover
and active states, replacing industrial amber
- Window, child, popup, frame and header surfaces follow the
brand background ladder (#070B12, #0C1220, #141E30, #1A2538,
#22303F)
- Borders use the brand cyan at 40% alpha (matches --border-brand
on the website) instead of neutral steel grey
The slate violet tertiary palette is gone. Brand tokens are
declared once and the slot constants alias them, so a future brand
shift only needs to touch the Identity / Accent / Primary stages.
Hellion Chat is an independent fork with its own assembly name and
plugin slot, but it kept registering the upstream /chat2* slash
commands. That mixed naming caused two friction points: users could
not tell from the in-game help which plugin owned the command, and
running both Hellion Chat and the upstream Chat 2 side by side would
collide on the registration.
Five commands change:
/chat2 -> /hellion (settings + chat toggle)
/chat2Viewer -> /hellionView (database viewer)
/chat2Debugger -> /hellionDebugger (internal, not shown in help)
/chat2SeString -> /hellionSeString (internal, debug-only)
/clearlog2 -> /clearhellion (clear chat log)
Help strings ("Perform various actions with Chat 2.", "Clear the
Chat 2 chat log") are reworded to match. ImGui internal window IDs
(###chat2-settings, ###chat2-dbviewer) are left untouched on purpose
so existing user layouts for those windows do not snap back to
default. Resource files do not reference any of these command names,
so no localisation work needed.
Audit findings M-1 and M-2. Two small consistency issues in the
upstream DbViewer paging path that we now own as a fork:
- RowPerPage is a row count and should be an int. The upstream
declaration was 1000.0f, which forced an implicit float divide
in Math.Ceiling and an implicit float-to-integer conversion when
SQLite bound the LIMIT parameter. Switching the constant to int
and casting Count to double right at the division keeps the
ceiling math intact while making the type story honest.
- GetPagedDateRange's SQL uses the placeholder $OffsetCount, but
the matching AddWithValue call passed the unprefixed name
"OffsetCount". Microsoft.Data.Sqlite tolerates this today, so
paging still worked; another provider or a stricter future
version would not. Re-aligned the parameter name with the SQL.
No behavioural change for users — paging continues to return 1000
rows per page. The fixes are kept on the fork rather than offered
upstream because the project's recent triage history makes a
non-trivial PR turnaround unlikely.
Audit findings M-3 and M-4. The 24h auto-sweep launched from
Plugin's constructor and the manual button in the Privacy tab were
both starting a background thread that called DeleteByRetentionPolicy
on the shared MessageStore connection without coordinating. With
unfortunate timing — manual click moments after a fresh plugin load
— two sweeps would race for the same connection and the second
would just re-do work the first one already did, while still
overwriting RetentionLastRunAt.
Move the running flag and a lock object to Plugin so both paths see
the same gate. Each entry point takes the lock long enough to check
and set the flag, then runs the actual delete on its background
thread without holding the lock (other DB operations already happen
without locking; spreading the lock further would suggest a
guarantee we do not actually provide). The Privacy tab keeps a
read-only property that surfaces the shared flag for its UI disable
state — ImGui is single-threaded and bool reads are atomic, so the
lock-free read is fine.
Audit finding M-5. The master switch description told users what the
filter does to the database, but nothing in the UI ruled out the
common misreading "if I disable a channel, it will also disappear
from the chat log". A help-text line under the toggle now states
explicitly that the filter is storage-only and points at the
in-game chat tab filters for hiding channels visually. EN and DE
strings added together.
README's Stability section gains a "what is missing compared to Chat 2"
block that names the five concrete reasons the upstream webinterface
could not stay (System.Random auth code, bind on all interfaces,
unflagged cookies, SSE stream that bypassed the privacy filter, and
the cumulative hardening cost). The project status list reflects
0.2.0 with Phase 1.5 marked done and the remaining audit follow-ups
queued under Phase 2.
The About tab gets a single-line acknowledgement that the upstream
webinterface is intentionally absent, so users coming from Chat 2 do
not look for it under settings or assume it broke.
The Obsidian project note is updated separately under
Vault/Ideen/Hellion Chat Plugin (ChatTwo Fork).md to record the audit
decision and the six-commit cleanup.
Drops Watson.Lite (the HTTP server) and Newtonsoft.Json (only used by
the webinterface JSON wire format) from the package references and
removes websiteBuild.zip plus the UnzipBuild target that extracted it
into the build output. The commented-out NodeJS compile blocks for
the Svelte frontend go with them.
DbViewer used to ship a CreateTempJsonFile button that exported the
database in the webinterface message-protocol shape (MessageResponse,
MessageTemplate, WebPayloadType). With no client able to consume that
shape any more the button, the method and the two helper methods are
removed. The Privacy tab's MessageExporter already covers Markdown,
JSON and CSV exports with channel and date filters and is the
supported way to get history out of the plugin.
Build verified clean (Release, 0 warnings, 0 errors). The lockfile
shrinks accordingly.
Drops the entire ChatTwo/Http/ tree (ServerCore, HostContext,
RouteController, Processing, SSEConnection, the message protocol DTOs
and the bundled Svelte frontend) plus WebinterfaceUtil. Also removes
every ServerCore.Send* call site that fed the SSE stream:
- MessageManager.ProcessMessage no longer broadcasts new messages
- Chat.cs no longer notifies on login
- PayloadHandler no longer rebroadcasts on screenshot-mode toggle
- ChatLogWindow no longer announces tab and channel switches
The Plugin class drops the ServerCore field, the auto-start branch and
the Dispose hook. The DbViewer still imported a stale namespace from
the message protocol; the using is removed.
Language.resx and its generated Designer file keep the Webinterface
string keys for now so future upstream cherry-picks do not break on
missing resources. They are dead code from our perspective but harmless.
Webinterface adds a third-party HTTP surface that contradicts the
DSGVO-by-default promise: it broadcasts every chat message including
filtered ChatTypes (privacy filter only covers DB writes), ships a
five-digit numeric auth code seeded from System.Random, binds on all
interfaces by default and sets cookies without security flags.
Hardening it for our threat model would land 500+ lines of code and
permanent maintenance for a feature very few users actually use. The
forks audience wants less surface, not more, so the entire feature is
being removed in a focused commit cluster. This first commit drops
the user-facing surface: settings tab class, tab registration and
the Configuration fields plus their UpdateFrom mirror.
The inherited Translators tree node was rendered under the
upstream `Options_About_Translators` label and could be misread
as "people who translated Hellion Chat". The list is in fact the
Chat 2 community Crowdin contributors and covers the inherited
upstream strings only — the Hellion-specific strings live in
HellionStrings.<lang>.resx and are maintained by the Hellion
Online Media maintainer (currently EN + DE; other locales are
not yet covered).
Add a Localization block right above the tree node that spells
this out, and rename the tree node label to "Chat 2 community
translators (upstream)" so the attribution is unambiguous.