category view issues
This commit is contained in:
+27
-1
@@ -15,13 +15,39 @@ local detectionCache = {}
|
||||
local cacheHits = 0
|
||||
local cacheMisses = 0
|
||||
|
||||
-- Clear the detection cache
|
||||
-- Clear the entire detection cache (use sparingly - only for major events)
|
||||
-- For simple item moves, use InvalidateItem() or don't invalidate at all
|
||||
function ItemDetection:ClearCache()
|
||||
detectionCache = {}
|
||||
cacheHits = 0
|
||||
cacheMisses = 0
|
||||
end
|
||||
|
||||
-- Invalidate a specific item from cache (by itemLink)
|
||||
-- Use this when a specific item's properties might have changed
|
||||
function ItemDetection:InvalidateItem(itemLink)
|
||||
if itemLink then
|
||||
detectionCache[itemLink] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Invalidate multiple items from cache
|
||||
-- Use this for batch operations
|
||||
function ItemDetection:InvalidateItems(itemLinks)
|
||||
if itemLinks then
|
||||
for _, link in ipairs(itemLinks) do
|
||||
if link then
|
||||
detectionCache[link] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if we have cached data for an item (useful for debugging)
|
||||
function ItemDetection:IsCached(itemLink)
|
||||
return itemLink and detectionCache[itemLink] ~= nil
|
||||
end
|
||||
|
||||
-- Get cache statistics
|
||||
function ItemDetection:GetCacheStats()
|
||||
local total = cacheHits + cacheMisses
|
||||
|
||||
+33
-34
@@ -578,10 +578,12 @@ local function ConsolidateStacks(bagIDs)
|
||||
if maxStack > 1 then
|
||||
-- Sort stacks: higher priority bags first, then larger stacks
|
||||
table.sort(group.stacks, function(a, b)
|
||||
if a.priority ~= b.priority then
|
||||
return a.priority > b.priority
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
if (a.priority or 0) ~= (b.priority or 0) then
|
||||
return (a.priority or 0) > (b.priority or 0)
|
||||
end
|
||||
return a.count > b.count
|
||||
return (a.count or 0) > (b.count or 0)
|
||||
end)
|
||||
|
||||
-- Greedy consolidation: fill stacks from left to right
|
||||
@@ -826,9 +828,13 @@ local function SortItems(items)
|
||||
end
|
||||
|
||||
table.sort(items, function(a, b)
|
||||
-- Guard against nil entries
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
|
||||
-- 1. Priority items first (Hearthstone, etc.)
|
||||
if a.priority ~= b.priority then
|
||||
return a.priority < b.priority
|
||||
if (a.priority or 0) ~= (b.priority or 0) then
|
||||
return (a.priority or 0) < (b.priority or 0)
|
||||
end
|
||||
|
||||
-- 2. Equippable items always come before non-equippable items
|
||||
@@ -1018,10 +1024,12 @@ local function BuildTargetPositions(bagIDs, itemCount)
|
||||
-- Only sort if we have more than one element
|
||||
if table.getn(sortedBags) > 1 then
|
||||
table.sort(sortedBags, function(a, b)
|
||||
if a.priority ~= b.priority then
|
||||
return a.priority > b.priority
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
if (a.priority or 0) ~= (b.priority or 0) then
|
||||
return (a.priority or 0) > (b.priority or 0)
|
||||
end
|
||||
return a.bagID < b.bagID
|
||||
return (a.bagID or 0) < (b.bagID or 0)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -1189,10 +1197,12 @@ local function BuildGreyTailPositions(bagIDs, greyCount)
|
||||
-- Only sort if we have more than one element
|
||||
if table.getn(ordered) > 1 then
|
||||
table.sort(ordered, function(a, b)
|
||||
if a.priority ~= b.priority then
|
||||
return a.priority < b.priority -- lowest first
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
if (a.priority or 0) ~= (b.priority or 0) then
|
||||
return (a.priority or 0) < (b.priority or 0) -- lowest first
|
||||
end
|
||||
return a.bagID > b.bagID -- higher bagID later (treated as further to the right)
|
||||
return (a.bagID or 0) > (b.bagID or 0) -- higher bagID later (treated as further to the right)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -1214,15 +1224,17 @@ local function BuildGreyTailPositions(bagIDs, greyCount)
|
||||
-- Ascending order: Priority DESC, BagID ASC, Slot ASC (matching BuildTargetPositions)
|
||||
if table.getn(tailSlots) > 1 then
|
||||
table.sort(tailSlots, function(a, b)
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
local aPrio = tonumber(addon.Modules.Utils:GetContainerPriority(a.bag)) or 0
|
||||
local bPrio = tonumber(addon.Modules.Utils:GetContainerPriority(b.bag)) or 0
|
||||
if aPrio ~= bPrio then
|
||||
return aPrio > bPrio
|
||||
end
|
||||
if a.bag ~= b.bag then
|
||||
return a.bag < b.bag
|
||||
if (a.bag or 0) ~= (b.bag or 0) then
|
||||
return (a.bag or 0) < (b.bag or 0)
|
||||
end
|
||||
return a.slot < b.slot
|
||||
return (a.slot or 0) < (b.slot or 0)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -1518,11 +1530,9 @@ function SortEngine:SortBags()
|
||||
end
|
||||
end
|
||||
|
||||
-- Clear caches after sorting to ensure fresh detection on next UI update
|
||||
-- Clear bag position cache after sorting to ensure fresh slot data on next UI update
|
||||
-- NOTE: Don't clear ItemDetection cache - item properties don't change when items move
|
||||
addon.Modules.BagScanner:ClearCache()
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
|
||||
-- Return total moves made
|
||||
return routeCount + consolidateCount + specializedMoves + regularMoves
|
||||
@@ -1655,11 +1665,9 @@ function SortEngine:SortBank()
|
||||
end
|
||||
end
|
||||
|
||||
-- Clear caches after sorting to ensure fresh detection on next UI update
|
||||
-- Clear bag position cache after sorting to ensure fresh slot data on next UI update
|
||||
-- NOTE: Don't clear ItemDetection cache - item properties don't change when items move
|
||||
addon.Modules.BankScanner:ClearCache()
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
|
||||
-- Return total moves made
|
||||
return routeCount + consolidateCount + specializedMoves + regularMoves
|
||||
@@ -1727,15 +1735,12 @@ function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sort
|
||||
SortEngine.sortingInProgress = false
|
||||
SortEngine:UpdateSortButtonState(false)
|
||||
currentSortType = "bags" -- Reset sort context
|
||||
-- Clear caches after sorting to ensure fresh detection
|
||||
-- Clear bag position cache - item properties don't change on move
|
||||
if sortType == "bank" then
|
||||
addon.Modules.BankScanner:ClearCache()
|
||||
else
|
||||
addon.Modules.BagScanner:ClearCache()
|
||||
end
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
updateFrame()
|
||||
end)
|
||||
elseif passCount >= safetyLimit then
|
||||
@@ -1748,15 +1753,12 @@ function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sort
|
||||
SortEngine.sortingInProgress = false
|
||||
SortEngine:UpdateSortButtonState(false)
|
||||
currentSortType = "bags" -- Reset sort context
|
||||
-- Clear caches after sorting to ensure fresh detection
|
||||
-- Clear bag position cache - item properties don't change on move
|
||||
if sortType == "bank" then
|
||||
addon.Modules.BankScanner:ClearCache()
|
||||
else
|
||||
addon.Modules.BagScanner:ClearCache()
|
||||
end
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
updateFrame()
|
||||
end)
|
||||
else
|
||||
@@ -1776,15 +1778,12 @@ function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sort
|
||||
SortEngine.sortingInProgress = false
|
||||
SortEngine:UpdateSortButtonState(false)
|
||||
currentSortType = "bags" -- Reset sort context
|
||||
-- Clear caches after sorting to ensure fresh detection
|
||||
-- Clear bag position cache - item properties don't change on move
|
||||
if sortType == "bank" then
|
||||
addon.Modules.BankScanner:ClearCache()
|
||||
else
|
||||
addon.Modules.BagScanner:ClearCache()
|
||||
end
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
updateFrame()
|
||||
end)
|
||||
return
|
||||
|
||||
+28
-15
@@ -21,6 +21,7 @@ function BagFrame:GetCurrentViewChar()
|
||||
end
|
||||
local searchText = ""
|
||||
local itemButtons = {}
|
||||
local slotToButton = {} -- Fast O(1) lookup: slotToButton[bagID][slotID] = button
|
||||
local showKeyring = false -- Toggle for keyring display
|
||||
local hiddenBags = {} -- Track which bags are hidden (bagID -> true/false)
|
||||
local bagParents = {} -- Per-bag parent frames to carry bagID for Blizzard item button templates
|
||||
@@ -243,16 +244,13 @@ function BagFrame:UpdateChangedSlots(bagID)
|
||||
local numSlots = GetContainerNumSlots(bagID)
|
||||
if not numSlots or numSlots == 0 then return -1 end
|
||||
|
||||
-- Check if we have the slot lookup table for this bag
|
||||
if not slotToButton[bagID] then return -1 end
|
||||
|
||||
local updatedCount = 0
|
||||
for slotID = 1, numSlots do
|
||||
-- Find button for this slot
|
||||
local targetButton = nil
|
||||
for _, button in ipairs(itemButtons) do
|
||||
if button.bagID == bagID and button.slotID == slotID then
|
||||
targetButton = button
|
||||
break
|
||||
end
|
||||
end
|
||||
-- O(1) button lookup using hash table
|
||||
local targetButton = slotToButton[bagID][slotID]
|
||||
|
||||
if not targetButton then
|
||||
-- Button not found, need full redraw
|
||||
@@ -498,10 +496,13 @@ function BagFrame:Update()
|
||||
-- Display items
|
||||
local viewType = addon.Modules.DB:GetSetting("bagViewType") or "single"
|
||||
|
||||
-- Clear itemButtons table before rebuilding (prevents stale references)
|
||||
-- Clear itemButtons table and slot lookup before rebuilding (prevents stale references)
|
||||
for k in pairs(itemButtons) do
|
||||
itemButtons[k] = nil
|
||||
end
|
||||
for k in pairs(slotToButton) do
|
||||
slotToButton[k] = nil
|
||||
end
|
||||
|
||||
-- Reset all section headers before displaying items
|
||||
local i = 1
|
||||
@@ -704,6 +705,9 @@ function BagFrame:DisplayItemsByCategory(bagData, isOtherChar, charName)
|
||||
Guda_ItemButton_SetItem(button, bagID, slot, itemData, false, isOtherChar and charName or nil, matchesFilter, isOtherChar)
|
||||
button.inUse = true
|
||||
table.insert(itemButtons, button)
|
||||
-- Populate slot lookup for O(1) access
|
||||
if not slotToButton[bagID] then slotToButton[bagID] = {} end
|
||||
slotToButton[bagID][slot] = button
|
||||
|
||||
col = col + 1
|
||||
if col >= blockCols then
|
||||
@@ -766,8 +770,11 @@ function BagFrame:DisplayItemsByCategory(bagData, isOtherChar, charName)
|
||||
if numItems > 0 then
|
||||
if sec.name == "Tools" then
|
||||
table.sort(items, function(a, b)
|
||||
if a.itemData.quality ~= b.itemData.quality then
|
||||
return a.itemData.quality > b.itemData.quality
|
||||
-- Guard against nil entries
|
||||
if not a or not a.itemData then return false end
|
||||
if not b or not b.itemData then return true end
|
||||
if (a.itemData.quality or 0) ~= (b.itemData.quality or 0) then
|
||||
return (a.itemData.quality or 0) > (b.itemData.quality or 0)
|
||||
end
|
||||
return (a.itemData.name or "") < (b.itemData.name or "")
|
||||
end)
|
||||
@@ -830,6 +837,9 @@ function BagFrame:DisplayItemsByCategory(bagData, isOtherChar, charName)
|
||||
Guda_ItemButton_SetItem(button, item.bagID, item.slotID, item.itemData, false, isOtherChar and charName or nil, self:PassesSearchFilter(item.itemData), isOtherChar)
|
||||
button.inUse = true
|
||||
table.insert(itemButtons, button)
|
||||
-- Populate slot lookup for O(1) access
|
||||
if not slotToButton[item.bagID] then slotToButton[item.bagID] = {} end
|
||||
slotToButton[item.bagID][item.slotID] = button
|
||||
|
||||
sCol = sCol + 1
|
||||
if sCol >= blockCols then
|
||||
@@ -1005,6 +1015,9 @@ function BagFrame:DisplayItems(bagData, isOtherChar, charName)
|
||||
Guda_ItemButton_SetItem(button, bagID, slot, itemData, false, isOtherChar and charName or nil, matchesFilter, isOtherChar)
|
||||
|
||||
table.insert(itemButtons, button)
|
||||
-- Populate slot lookup for O(1) access
|
||||
if not slotToButton[bagID] then slotToButton[bagID] = {} end
|
||||
slotToButton[bagID][slot] = button
|
||||
|
||||
-- Advance position
|
||||
col = col + 1
|
||||
@@ -1746,7 +1759,9 @@ function Guda_BagFrame_MergeStacks()
|
||||
if table.getn(group.stacks) > 1 then
|
||||
-- Sort stacks: larger stacks first (targets), smaller stacks last (sources)
|
||||
table.sort(group.stacks, function(a, b)
|
||||
return a.count > b.count
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
return (a.count or 0) > (b.count or 0)
|
||||
end)
|
||||
|
||||
local sourceLoopStart = table.getn(group.stacks)
|
||||
@@ -2688,10 +2703,8 @@ function BagFrame:Initialize()
|
||||
|
||||
if not isSorting then
|
||||
-- Try incremental update for manual item moves
|
||||
-- NOTE: Don't clear ItemDetection cache - item properties don't change on move
|
||||
addon.Modules.BagScanner:InvalidateBag(arg1)
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
|
||||
-- Try to update only changed slots in this bag
|
||||
local result = BagFrame:UpdateChangedSlots(arg1)
|
||||
|
||||
+38
-48
@@ -14,6 +14,7 @@ local searchText = ""
|
||||
local isReadOnlyMode = false -- Track if viewing saved bank (read-only) or live bank (interactive)
|
||||
local hiddenBankBags = {} -- Track which bank bags are hidden (bagID -> true/false)
|
||||
local bankBagParents = {} -- Parent frames per bank bag (same approach as BagFrame)
|
||||
local bankSlotToButton = {} -- Fast O(1) lookup: bankSlotToButton[bagID][slotID] = button
|
||||
-- Global click catcher for clearing bank search focus
|
||||
local bankClickCatcher = nil
|
||||
|
||||
@@ -135,18 +136,9 @@ function BankFrame:UpdateSingleSlot(bagID, slotID)
|
||||
if not Guda_BankFrame:IsShown() then return false end
|
||||
if currentViewChar then return false end -- Can't do single-slot for other characters
|
||||
|
||||
-- Find the button for this slot
|
||||
local bankBagParent = bankBagParents[bagID]
|
||||
if not bankBagParent or not bankBagParent.itemButtons then return false end
|
||||
|
||||
local targetButton = nil
|
||||
for button in pairs(bankBagParent.itemButtons) do
|
||||
if button.bagID == bagID and button.slotID == slotID then
|
||||
targetButton = button
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- O(1) button lookup using hash table
|
||||
if not bankSlotToButton[bagID] then return false end
|
||||
local targetButton = bankSlotToButton[bagID][slotID]
|
||||
if not targetButton then return false end
|
||||
|
||||
-- Get fresh item data for this slot
|
||||
@@ -190,22 +182,16 @@ function BankFrame:UpdateChangedSlots(bagID)
|
||||
if not Guda_BankFrame:IsShown() then return -1 end
|
||||
if currentViewChar then return -1 end
|
||||
|
||||
local bankBagParent = bankBagParents[bagID]
|
||||
if not bankBagParent or not bankBagParent.itemButtons then return -1 end
|
||||
-- Check if we have the slot lookup table for this bag
|
||||
if not bankSlotToButton[bagID] then return -1 end
|
||||
|
||||
local numSlots = addon.Modules.Utils:GetBagSlotCount(bagID)
|
||||
if not numSlots or numSlots == 0 then return -1 end
|
||||
|
||||
local updatedCount = 0
|
||||
for slotID = 1, numSlots do
|
||||
-- Find button for this slot
|
||||
local targetButton = nil
|
||||
for button in pairs(bankBagParent.itemButtons) do
|
||||
if button.bagID == bagID and button.slotID == slotID then
|
||||
targetButton = button
|
||||
break
|
||||
end
|
||||
end
|
||||
-- O(1) button lookup using hash table
|
||||
local targetButton = bankSlotToButton[bagID][slotID]
|
||||
|
||||
if not targetButton then
|
||||
-- Button not found, need full redraw
|
||||
@@ -302,7 +288,7 @@ function BankFrame:Update()
|
||||
end
|
||||
|
||||
-- Mark all existing buttons as not in use (we'll mark active ones during display)
|
||||
-- Mark all existing buttons as not in use (we'll mark active ones during display)
|
||||
-- Also clear the slot lookup table for fresh rebuild
|
||||
for _, bankBagParent in pairs(bankBagParents) do
|
||||
if bankBagParent and bankBagParent.itemButtons then
|
||||
for button in pairs(bankBagParent.itemButtons) do
|
||||
@@ -312,6 +298,9 @@ function BankFrame:Update()
|
||||
end
|
||||
end
|
||||
end
|
||||
for k in pairs(bankSlotToButton) do
|
||||
bankSlotToButton[k] = nil
|
||||
end
|
||||
|
||||
-- Determine if we're in read-only mode:
|
||||
-- - If viewing another character → read-only
|
||||
@@ -522,6 +511,9 @@ function BankFrame:DisplayItemsByCategory(bankData, isOtherChar, charName)
|
||||
local matchesFilter = self:PassesSearchFilter(itemData)
|
||||
Guda_ItemButton_SetItem(button, bagID, slot, itemData, true, isOtherChar and charName or nil, matchesFilter, isOtherChar or isReadOnlyMode)
|
||||
button.inUse = true
|
||||
-- Populate slot lookup for O(1) access
|
||||
if not bankSlotToButton[bagID] then bankSlotToButton[bagID] = {} end
|
||||
bankSlotToButton[bagID][slot] = button
|
||||
|
||||
col = col + 1
|
||||
if col >= blockCols then
|
||||
@@ -580,8 +572,11 @@ function BankFrame:DisplayItemsByCategory(bankData, isOtherChar, charName)
|
||||
if numItems > 0 then
|
||||
if sec.name == "Tools" then
|
||||
table.sort(items, function(a, b)
|
||||
if a.itemData.quality ~= b.itemData.quality then
|
||||
return a.itemData.quality > b.itemData.quality
|
||||
-- Guard against nil entries
|
||||
if not a or not a.itemData then return false end
|
||||
if not b or not b.itemData then return true end
|
||||
if (a.itemData.quality or 0) ~= (b.itemData.quality or 0) then
|
||||
return (a.itemData.quality or 0) > (b.itemData.quality or 0)
|
||||
end
|
||||
return (a.itemData.name or "") < (b.itemData.name or "")
|
||||
end)
|
||||
@@ -642,7 +637,10 @@ function BankFrame:DisplayItemsByCategory(bankData, isOtherChar, charName)
|
||||
button:Show()
|
||||
Guda_ItemButton_SetItem(button, item.bagID, item.slotID, item.itemData, true, isOtherChar and charName or nil, self:PassesSearchFilter(item.itemData), isOtherChar or isReadOnlyMode)
|
||||
button.inUse = true
|
||||
|
||||
-- Populate slot lookup for O(1) access
|
||||
if not bankSlotToButton[item.bagID] then bankSlotToButton[item.bagID] = {} end
|
||||
bankSlotToButton[item.bagID][item.slotID] = button
|
||||
|
||||
sCol = sCol + 1
|
||||
if sCol >= blockCols then
|
||||
sCol = 0
|
||||
@@ -795,6 +793,9 @@ function BankFrame:DisplayItems(bankData, isOtherChar, charName)
|
||||
button:SetPoint("TOPLEFT", itemContainer, "TOPLEFT", xPos, yPos)
|
||||
|
||||
Guda_ItemButton_SetItem(button, bagID, slot, itemData, true, isOtherChar and charName or nil, matchesFilter, isReadOnlyMode)
|
||||
-- Populate slot lookup for O(1) access
|
||||
if not bankSlotToButton[bagID] then bankSlotToButton[bagID] = {} end
|
||||
bankSlotToButton[bagID][slot] = button
|
||||
|
||||
col = col + 1
|
||||
if col >= perRow then
|
||||
@@ -1229,7 +1230,9 @@ function Guda_BankFrame_MergeStacks()
|
||||
if table.getn(group.stacks) > 1 then
|
||||
-- Sort stacks: larger stacks first (targets), smaller stacks last (sources)
|
||||
table.sort(group.stacks, function(a, b)
|
||||
return a.count > b.count
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
return (a.count or 0) > (b.count or 0)
|
||||
end)
|
||||
|
||||
local sourceLoopStart = table.getn(group.stacks)
|
||||
@@ -1730,11 +1733,9 @@ function BankFrame:Initialize()
|
||||
-- arg1 is the slot number (1-28 for main bank)
|
||||
-- Try single-slot update if not sorting
|
||||
if not isSorting then
|
||||
-- Invalidate cache for fresh data
|
||||
-- Invalidate bag scanner cache for fresh slot data
|
||||
-- NOTE: Don't clear ItemDetection cache - item properties don't change on move
|
||||
addon.Modules.BankScanner:InvalidateBag(-1)
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
-- Try single-slot update
|
||||
if BankFrame:UpdateSingleSlot(-1, arg1) then
|
||||
return -- Success, no full redraw needed
|
||||
@@ -1742,30 +1743,21 @@ function BankFrame:Initialize()
|
||||
end
|
||||
-- Fallback: full redraw (sorting or single-slot failed)
|
||||
addon.Modules.BankScanner:InvalidateBag(-1)
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
elseif event == "BAG_UPDATE" and arg1 then
|
||||
-- Check if this is a bank bag (5-10)
|
||||
if arg1 >= 5 and arg1 <= 10 then
|
||||
-- Invalidate bag scanner cache for fresh slot data
|
||||
-- NOTE: Don't clear ItemDetection cache - item properties don't change on move
|
||||
addon.Modules.BankScanner:InvalidateBag(arg1)
|
||||
|
||||
-- Try incremental update if not sorting
|
||||
if not isSorting then
|
||||
addon.Modules.BankScanner:InvalidateBag(arg1)
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
-- Try to update only changed slots
|
||||
local result = BankFrame:UpdateChangedSlots(arg1)
|
||||
if result >= 0 then
|
||||
return -- Success, no full redraw needed
|
||||
end
|
||||
-- Fall through to full redraw
|
||||
else
|
||||
-- Sorting in progress - invalidate for full redraw
|
||||
addon.Modules.BankScanner:InvalidateBag(arg1)
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Not a bank bag, ignore for bank frame
|
||||
@@ -1773,11 +1765,9 @@ function BankFrame:Initialize()
|
||||
end
|
||||
elseif event == "PLAYERBANKBAGSLOTS_CHANGED" then
|
||||
-- Bank container slot changed (bag added/removed)
|
||||
-- Must clear entire cache since bag structure changed
|
||||
-- Clear bag scanner cache since structure changed
|
||||
-- NOTE: Don't clear ItemDetection cache - item properties don't change
|
||||
addon.Modules.BankScanner:ClearCache()
|
||||
if addon.Modules.ItemDetection then
|
||||
addon.Modules.ItemDetection:ClearCache()
|
||||
end
|
||||
end
|
||||
|
||||
-- Slightly longer delay to ensure WoW API has updated
|
||||
|
||||
+6
-5
@@ -212,11 +212,12 @@ end
|
||||
function Guda_SortCategoryItems(items)
|
||||
if not items then return end
|
||||
table.sort(items, function(a, b)
|
||||
-- Nil guards for sort stability
|
||||
-- Guard against nil entries
|
||||
if not a then return false end
|
||||
if not b then return true end
|
||||
if not a.itemData then return false end
|
||||
if not b.itemData then return true end
|
||||
|
||||
-- Rank Trade Goods: meat (name ends with 'meat') = 2, egg (contains 'egg') = 1, others = 0
|
||||
local function tgRank(d)
|
||||
if not d or not d.name then return 0 end
|
||||
@@ -233,8 +234,8 @@ function Guda_SortCategoryItems(items)
|
||||
return ra > rb
|
||||
end
|
||||
-- Priority: consumable restore tags (eat > drink > restore > nil)
|
||||
local pa = a.itemData and a.itemData.restoreTag or nil
|
||||
local pb = b.itemData and b.itemData.restoreTag or nil
|
||||
local pa = a.itemData.restoreTag
|
||||
local pb = b.itemData.restoreTag
|
||||
local function pr(t)
|
||||
if t == "eat" then return 3 end
|
||||
if t == "drink" then return 2 end
|
||||
@@ -248,8 +249,8 @@ function Guda_SortCategoryItems(items)
|
||||
if a.itemData.subclass ~= b.itemData.subclass then
|
||||
return (a.itemData.subclass or "") < (b.itemData.subclass or "")
|
||||
end
|
||||
if a.itemData.quality ~= b.itemData.quality then
|
||||
return a.itemData.quality > b.itemData.quality
|
||||
if (a.itemData.quality or 0) ~= (b.itemData.quality or 0) then
|
||||
return (a.itemData.quality or 0) > (b.itemData.quality or 0)
|
||||
end
|
||||
return (a.itemData.name or "") < (b.itemData.name or "")
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user