v1.2
SaveWhispers v1.2 SW
v1.2 (2026-07-16)
Full Changelog Previous Releases
- Restore X-Curse-Project-ID in both .toc files, fix stale v1.1 in Title
Lost at some point this session - the v1.2 release run just completed
without it, so the packager skipped the CurseForge upload entirely (it
only detected "GitHub: ... [token set]", never "CurseForge ID: ... [token
set]", unlike the v1.1 run's log). GitHub release still went out fine
since that doesn't depend on this field.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Fix the actual cause of the Settings scroll area showing a void
The last two commits (reapplying the backdrop on resize, capping max
window height) didn't fix this - both were chasing the wrong cause. The
real problem: content:SetSize(800, 1150) was a hardcoded guess, not
measured from the actual placed widgets. Different themes have
differently-sized checkboxes/buttons/sliders, so whichever theme's real
content came in under 1150 left a permanently empty gap in the scroll
area below it - showing the game world through, since nothing here puts
an opaque background behind scroll content (only the outer window's own
backdrop sits behind all of it, and empty space just passes that through).
Happened regardless of window size, which is why capping resize height
didn't help. Now measures the real height from content's top to the last
button's bottom instead of guessing.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Cap the window's max resize height at 1050 instead of near-full-screen
Reapplying the backdrop after a resize (previous commit) didn't fix the
void showing the game world through the bottom of a very large window -
whatever the actual cause, it's below whatever Blizzard's tiled dialog
background can reliably handle. The tallest panel's own content (Settings)
is only ~1150px tall anyway, so allowing the window to resize much bigger
than that was mostly just empty scrollable space past that limitation.
Existing saved window sizes above the new cap shrink to fit automatically
on next load (the restore logic already clamps against maxHeight).
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Fix window backdrop not covering the full frame at large sizes
BackdropTemplateMixin is meant to redraw its tiled background automatically
on every size change, but that didn't reliably keep up with a large native
drag-resize or a large saved size restored on open - the tiled center fill
stopped covering the frame partway down while the border kept stretching
fine, leaving a "void" showing the game world through the rest of the
window. Explicitly reapplying the backdrop after a resize settles (and
after restoring a saved size, not before) forces a full redraw at the
frame's actual current size.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Rewrite v1.2 changelog to cover the full Settings/Guild/Party-Raid pass
Consolidates everything from this dev cycle into fewer, clearer bullets:
the Settings reorganization (including the Saved confirmation and No-limit
toggles, previously two separate bullets), the Channels filter pill and
its now-filter-aware counter, Guild Chat's simplified button row, the
Party/Raid Members popup fix, and all three real bug fixes discovered
along the way (blurry chat text, scale-dependent slider/drag jumping, and
the session-fragmentation bug). Drops nothing that shipped - only folds
duplicated bullets together and reflects the final shipped behavior.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Fix a raid session getting silently orphaned mid-conversation
StartGroupSession(kind) only checked its own kind's open-session slot
before creating a new one. IsInRaid()/IsInParty() can briefly misreport
right after a loading screen or raid conversion, so GROUP_JOINED firing
again mid-raid (with the group never actually having left) could compute
the wrong kind and start a second, competing session while the real one
was still actively receiving messages. The moment that stray session later
got relabeled via ConvertGroupSession (GROUP_ROSTER_UPDATE catching up),
it claimed the openRaidSessionKey/openPartySessionKey slot out from under
the real session, silently redirecting all further messages into the new
one and leaving the original to just stop mid-conversation - confirmed in
a live SavedVariables file where a continuous ~1h raid ended up split into
three sessions that all "ended" within about a minute of each other.
Now checks BOTH kinds' open-session slots first and reuses whichever one
is already active instead of starting a competitor.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Rename G/R to Grp in the "All" filter's combined counter
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Show a combined DM/G-R/Chan summary on the "All" filter's counter
No single limit applies while viewing everything, so instead of falling
back to just the DM number, show "DM x/y G/R x/y Chan x/y" all at once.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Messages counter now reflects the active filter pill, not always DM
Each category has its own separate "to keep" limit now, but the header
counter was hardcoded to DM conversations/maxConversations regardless of
which filter pill (DM/Guild/Group/Chan) was selected. Now shows the
matching count/limit per filter - Party/Raid sessions vs maxGroupSessions,
Channels vs maxChannels, DM vs maxConversations - Guild Chat just shows
its name since it's a single fixed conversation with no "keep N" limit.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Guild Chat: drop Pin/Members buttons; Party/Raid Members: drop online status
- Guild Chat is a single fixed conversation (always sorted first already),
so pinning it does nothing, and a members list here just duplicates the
default Guild Roster window - removed both buttons for that one channel. - The Party/Raid Members popup queried the player's CURRENTLY grouped
units, which for an old/closed session shows whoever they happen to be
grouped with today (or nobody) - not the actual roster from that
session. Now lists conversation.members (captured when the session
started) with no online/offline text or color, which wasn't meaningful
data for a historical snapshot anyway.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
- Guild Chat is a single fixed conversation (always sorted first already),
- Fix disabled message-limit field not visibly greying out, checkbox flash anchor
- SetAlpha on the field wasn't visibly dimming its EditBox text on either
theme - set the text color directly to grey instead, which unlike alpha
is guaranteed visible regardless of any EditBox rendering quirk. - The "No limit" checkbox's own OnClick still called flashSaved(field)
without the unlimitedLabel anchor (only apply() had been fixed earlier),
so clicking the checkbox itself still put the "Saved" text behind the
checkbox instead of after "No limit".
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
- SetAlpha on the field wasn't visibly dimming its EditBox text on either
- Drop the "Saved" text on the count-limit fields, border flash only
Anchoring it below the field still collided, this time with "Channels to
keep" sitting in the next row. These fields have no free space on any
side (two-per-row, next row right below), so text never fits regardless
of placement - the green border flash alone already shows the save
unambiguously. Message-limit fields keep both, they have room.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Grey out the message-limit field when its "No limit" box is checked
Disable() alone doesn't change appearance on either theme - alpha dims it
uniformly without needing per-theme color handling.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Fix Settings "Saved" flash overlap and message-limit checkbox alignment
- flashSaved's text landed on top of/behind sibling widgets in tighter
rows: "No limit" checkbox+label on the message-limit rows, and "Party/Raid
sessions to keep"'s caption (which sits immediately right of "DM
conversations to keep" with no gap at all) on the count-limit row.
flashSaved now takes an explicit anchor widget, and abelowmode for
rows with nothing safe to the right. - The "No limit" checkbox is now centered on the field's actual height
instead of a fixed downward nudge - it's a different size per theme
(32px native vs. 24px flat) and was visibly lower than the field on both.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
- flashSaved's text landed on top of/behind sibling widgets in tighter
- Shorten Messages filter pill labels to fix overlap at narrow widths
DMs -> DM, Channels -> Chan. The 5-pill row (All/DMs/Guild/Group/Channels)
overlapped at narrower window widths / flat themes with less padding.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Rework Interface/Chat scale sliders: centered 100%, off-track reset button, step ruler
- Symmetric 0.70-1.30 range on both sliders puts 100% exactly in the middle
instead of off to one side. - The 100% reset control is now a real button beside the track instead of
an invisible hit-region sitting on top of it, which made it hard to grab
the thumb anywhere near that point. - Added a ruler of small step notches along the track so the increments
the slider can land on are visible, not just Low/High/100%.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
- Symmetric 0.70-1.30 range on both sliders puts 100% exactly in the middle
- Fix window landing far short after dragging at any Interface Scale != 100%
normalizeTopLeft (runs after every window drag/resize to keep it
TOPLEFT-anchored) converted frame:GetLeft()/GetTop() by * scale /
parentScale before using them as the new anchor offset. That conversion is
only correct when reparenting to a frame with different scale ancestry -
this frame stays a direct child of UIParent throughout, only the anchor
point changes, so GetLeft()/GetTop() were already the right offsets with
no conversion needed. Since scale/parentScale reduces to the frame's own
uiScale here, the old code silently multiplied the offset by uiScale on
every drag/resize - a no-op at the default 100% (factor of 1), but at any
other Interface Scale it shrank the offset toward UIParent's corner,
landing the window far short of wherever it was actually dropped.
Also added a clickable 100% tick mark + live percentage readout to the
Interface scale and Chat text scale sliders, so drifting away from 100% is
visible and easy to undo.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Add a fixed left margin to the Settings panel's content anchor
content sits flush against the scroll frame's clip edge with no inherent
padding, so several small negative x nudges (e.g. -6 for "Danger Zone")
that used to be safe relative to a margined widget clipped the first
letter once anchored straight to content's own edge.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Fix Settings panel horizontal layout drift
belowPrev anchored both X and Y to the previous widget - every small
per-widget nudge (the -2 used throughout for optical alignment) compounded
across the whole chain instead of applying independently each time, and
rows whose prev became a widget positioned right of its own caption (a
field or checkbox) dragged every following section rightward with it.
Anchor X to the fixed content frame and Y to prev independently instead,
the standard two-point WoW anchoring pattern for this.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - Revert Guild Chat C_Club backfill - API unavailable in Classic Era
RegisterEvent("CLUB_MESSAGE_HISTORY_LOADED") throws "unknown event" on a
live Classic Era client, and aborts the rest of Core.lua's event wiring
when it does - the whole addon stopped receiving events, not just this
feature. Confirmed via research that the C_Club/Communities API is a
retail-only surface not functional in Classic Era, so this can't be made
to work by trying a different event/field name. Removes the button, the
backfill/merge functions, and the event hookup entirely.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com - v1.2: Settings overhaul, Channels filter, Guild Chat history backfill, crisp chat text
- Split per-category message limits (DM/Guild/Party-Raid/Channel) each with
a "No limit" toggle, symmetric conversation/session-count limits including
a new Channels-to-keep cap, reorganized Settings layout with save feedback. - Choose which categories count toward the minimap unread badge.
- New Channels filter pill in the Messages tab.
- Guild Chat "Load older messages" button backfills history via Blizzard's
Communities/Club API (C_Club) - separate from the CHAT_MSG_GUILD event. - Chat text now re-rasterizes via SetFont instead of scaling an already
-rendered glyph via SetTextHeight, fixing blurry text at every scale. - Fixed the Interface/Chat scale sliders fighting their own drag tracking
and visibly jumping around while dragging.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
- Split per-category message limits (DM/Guild/Party-Raid/Channel) each with
- Rename changelog credit labels from Co-Author/Author to Developer
- Grant contents:write permission to the release workflow
The default GITHUB_TOKEN had no write access to Releases, so the
packager's CurseForge upload succeeded but creating the GitHub release
failed with a 403.