Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions EllesmereUIBags/EUI_Bags_Options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -472,20 +472,28 @@ initFrame:SetScript("OnEvent", function(self)
local cbDD, cbDDRefresh = EllesmereUI.BuildVisOptsCBDropdown(
rightRgn, 210, rightRgn:GetFrameLevel() + 2,
currencyItems,
-- Tracked currencies are per character (the module owns
-- the accessor and its first-use seeding; see
-- CurrencyOrder in EllesmereUIBags.lua). Reading
-- db.profile.currencyOrder here would edit the legacy
-- shared table that nothing renders any more.
function(cID)
local co = db.profile.currencyOrder
local co = EllesmereUI._BagsCurrencyOrder
and EllesmereUI._BagsCurrencyOrder()
return co and co[cID] and true or false
end,
function(cID, v)
if not db.profile.currencyOrder then db.profile.currencyOrder = {} end
local co = EllesmereUI._BagsCurrencyOrder
and EllesmereUI._BagsCurrencyOrder()
if not co then return end
if v then
local maxOrder = 0
for _, ord in pairs(db.profile.currencyOrder) do
for _, ord in pairs(co) do
if type(ord) == "number" and ord > maxOrder then maxOrder = ord end
end
db.profile.currencyOrder[cID] = maxOrder + 1
co[cID] = maxOrder + 1
else
db.profile.currencyOrder[cID] = nil
co[cID] = nil
end
if _G.EUI_Bags and _G.EUI_Bags.RefreshInventory then
C_Timer.After(0.1, function()
Expand Down Expand Up @@ -827,6 +835,7 @@ initFrame:SetScript("OnEvent", function(self)
EllesmereUIDB.bagItemAssignments = nil
EllesmereUIDB.characterGold = nil
EllesmereUIDB.warbandGold = nil
EllesmereUIDB.bagCurrencyByChar = nil
end
EllesmereUI:InvalidatePageCache()
end,
Expand Down
78 changes: 69 additions & 9 deletions EllesmereUIBags/EllesmereUIBags.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,64 @@ local EUI = EllesmereUI
local _emptyP = {}
local function BP() return (EUI._bagsDB and EUI._bagsDB.profile) or _emptyP end

-- Tracked currencies are PER CHARACTER, unlike every other bag setting.
--
-- They used to live in one profile-level `currencyOrder` table, which meant
-- ticking a currency on one character put it in every character's bag. Worse,
-- the input feeding that table is Blizzard's own currency tab, which IS
-- per-character (see the TokenFrame.OnTokenWatchChanged sync below): a
-- per-character source writing a shared store can only ever bleed. Reported by
-- a user wanting one currency on their main and another on the alt that farms
-- it, which the shared table made impossible.
--
-- Stored at the EllesmereUIDB ROOT, not in the bag profile, which is where the
-- module already keeps its other per-character data (characterGold,
-- bagPinnedItems, bagItemAssignments). Profile data is the wrong home for it in
-- two ways: ApplyProfileData wipes db.profile wholesale before copying an
-- imported snapshot, so importing any shared profile would erase every
-- character's currencies, and profile exports would ship a roster of the
-- author's character names, realms and per-alt currency lists to whoever
-- imported it -- the leak PRIVATE_ADDON_KEYS exists to plug.
local _bagsCharKey -- session-constant; UpdateCurrencyDisplays is a render path
local function BagsCharKey()
if not _bagsCharKey then
local n, r = UnitName("player"), GetRealmName()
if not n or not r then return nil end -- too early; do not cache a stub
_bagsCharKey = n .. " - " .. r
end
return _bagsCharKey
end

-- The per-character order table, seeded on this character's first use.
-- Returns nil only when the DB or the player identity is not up yet (callers
-- already handle that).
local function CurrencyOrder()
if not EllesmereUIDB then return nil end
local key = BagsCharKey()
if not key then return nil end
local byChar = EllesmereUIDB.bagCurrencyByChar
if type(byChar) ~= "table" then byChar = {}; EllesmereUIDB.bagCurrencyByChar = byChar end
local t = byChar[key]
if type(t) ~= "table" then
t = {}
-- Seed from the legacy shared table so an upgrading user keeps exactly
-- what they had. The legacy table is deliberately NOT deleted: every
-- character seeds from it once, at ITS first login after the upgrade,
-- so a character that has not logged in yet still inherits the old
-- setup instead of an empty footer. Nothing writes to it any more, so
-- the seed stays stable. A per-character migration is never a one-shot.
local legacy = BP().currencyOrder
if type(legacy) == "table" then
for cID, order in pairs(legacy) do
if type(order) == "number" then t[cID] = order end
end
end
byChar[key] = t
end
return t
end
EUI._BagsCurrencyOrder = CurrencyOrder

-- Resolve the default bag-type view ("all" | "onebag" | "multibag"). Reads the
-- new bagDefaultBagType key, falling back to the legacy bagDefaultOneBag boolean
-- so existing users keep their OneBag default. (Cross-version profile imports are
Expand Down Expand Up @@ -1667,7 +1725,7 @@ local function UpdateCurrencyDisplays(footerWidth)

-- Build tracked list from internal order table (decoupled from Blizzard)
local tracked = {}
local orderDB = BP().currencyOrder
local orderDB = CurrencyOrder()
if orderDB and C_CurrencyInfo and C_CurrencyInfo.GetCurrencyInfo then
for cID, order in pairs(orderDB) do
if type(order) == "number" then
Expand Down Expand Up @@ -6656,14 +6714,16 @@ local function StartAddon()
end
end

-- Seed currencyOrder from Blizzard's tracked currencies on first load
-- Seed this character's tracked currencies from Blizzard's on first load
if EllesmereUIDB and C_CurrencyInfo and C_CurrencyInfo.GetBackpackCurrencyInfo then
if not BP().currencyOrder then BP().currencyOrder = {} end
local co = BP().currencyOrder
-- Only seed if our table is empty (first install or fresh profile)
-- Only seed when this character's table is empty: first install, a
-- fresh profile, or a character whose legacy seed was empty too.
local co = CurrencyOrder()
local hasAny = false
for _ in pairs(co) do hasAny = true; break end
if not hasAny then
if co then
for _ in pairs(co) do hasAny = true; break end
end
if co and not hasAny then
local order = 0
for i = 1, 20 do
local info = C_CurrencyInfo.GetBackpackCurrencyInfo(i)
Expand Down Expand Up @@ -6695,8 +6755,8 @@ local function StartAddon()
if EventRegistry and EventRegistry.RegisterCallback then
EventRegistry:RegisterCallback("TokenFrame.OnTokenWatchChanged", function()
if not EllesmereUIDB then return end
if not BP().currencyOrder then BP().currencyOrder = {} end
local co = BP().currencyOrder
local co = CurrencyOrder()
if not co then return end
local blizzSet = ReadBlizzSet()
-- Add newly checked currencies
for cID in pairs(blizzSet) do
Expand Down