Files
coa-bagnon/Bagnon/components/sortBtn.lua
T
Simon Moe Sørensen 5b7a73a9c2 fix(db): 🐛 Fixes an issue where personal and realm bank information wouldn't get updated (#11)
* fix(db): 🐛 Fixes an issue where personal and realm bank information wouldn't get updated

Introduce the "Blizzard_GuildBankUI" addon in constructor, ensuring that the `GuildBankFrame` is loaded for bank type detection.
Hide the Blizzard Guildbank to avoid both Bagnon and Blizzard banks being shown at the same time.

This breaks the red color from the bank tabs

* refactor(db): ♻️ Use old implementation for personal and guild bank detection

* fix: 🐛 Fix issue where personal and realm bank wasn't identified on guild bank change event

* fix(db): 🐛 Fixes an issue where only current guild bank tab would be added to db

Use `QueryGuildBankTab` to preload items in guild bank tabs and identify trigger in GUILDBANKBAGSLOTS_CHANGED event to update bags when items are ready

* fix(db): 🐛 Correctly index realm and personal banks on initial load
2026-01-19 12:48:24 -07:00

482 lines
11 KiB
Lua

--[[
sortBtn.lua
imagine a button that sorts your inventory in Bagnon, crazy am I right?!1
--]]
local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon')
local L = LibStub('AceLocale-3.0'):GetLocale('Bagnon')
local SortBtn = Bagnon.Classy:New('Button')
Bagnon.SortBtn = SortBtn
local SIZE = 20
local NORMAL_TEXTURE_SIZE = 64 * (SIZE / 36)
-- Bag Sorter code from Sushi Regular
local moves = {};
local frame = CreateFrame("Frame");
local t = 0;
local current = nil;
local isGuildBankSort = false;
local function GetIDFromLink(link)
return link and tonumber(string.match(link, "item:(%d+)"));
end
local function GetAscensionBankType()
-- The logic doesn't work because GuildBankFrame is not loaded
-- However the sort still works because it can sort using 'guild' as a fallback
-- but personal and realm branches are never reached
if GuildBankFrame and GuildBankFrame.IsPersonalBank then
return "personal"
elseif GuildBankFrame and GuildBankFrame.IsRealmBank then
return "realm"
else
return "guild"
end
end
local function DoGuildBankMoves()
while (current ~= nil or #moves > 0) do
if current ~= nil then
if CursorHasItem() then
local _, id = GetCursorInfo();
if (current ~= nil and current.id == id) then
if (current.sourcetab ~= nil) then
PickupGuildBankItem(current.targettab, current.targetslot);
local link = GetGuildBankItemLink(current.targettab, current.targetslot);
if (current.id ~= GetIDFromLink(link)) then
return;
end
end
else
moves = {};
current = nil;
frame:Hide();
return;
end
else
if (current.sourcetab ~= nil) then
local link = GetGuildBankItemLink(current.targettab, current.targetslot);
if (current.id ~= GetIDFromLink(link)) then
return;
end
end
current = nil;
end
else
if (#moves > 0) then
current = table.remove(moves, 1);
if (current.sourcetab ~= nil) then
PickupGuildBankItem(current.sourcetab, current.sourceslot);
if CursorHasItem() == false then
return;
end
PickupGuildBankItem(current.targettab, current.targetslot);
local link = GetGuildBankItemLink(current.targettab, current.targetslot);
if (current.id == GetIDFromLink(link)) then
current = nil;
else
return;
end
end
end
end
end
frame:Hide();
isGuildBankSort = false;
end
local function DoContainerMoves()
while (current ~= nil or #moves > 0) do
if current ~= nil then
if CursorHasItem() then
local _, id = GetCursorInfo();
if (current ~= nil and current.id == id) then
if (current.sourcebag ~= nil) then
PickupContainerItem(current.targetbag, current.targetslot);
local link = select(7, GetContainerItemInfo(current.targetbag, current.targetslot));
if (current.id ~= GetIDFromLink(link)) then
return;
end
end
else
moves = {};
current = nil;
frame:Hide();
return;
end
else
if (current.sourcebag ~= nil) then
local link = select(7, GetContainerItemInfo(current.targetbag, current.targetslot));
if (current.id ~= GetIDFromLink(link)) then
return;
end
end
current = nil;
end
else
if (#moves > 0) then
current = table.remove(moves, 1);
if (current.sourcebag ~= nil) then
PickupContainerItem(current.sourcebag, current.sourceslot);
if CursorHasItem() == false then
return;
end
PickupContainerItem(current.targetbag, current.targetslot);
local link = select(7, GetContainerItemInfo(current.targetbag, current.targetslot));
if (current.id == GetIDFromLink(link)) then
current = nil;
else
return;
end
end
end
end
end
frame:Hide();
end
local function DoMoves()
if isGuildBankSort then
DoGuildBankMoves()
else
DoContainerMoves()
end
end
local function CompareItems(lItem, rItem)
if (rItem.id == nil) then
return true;
elseif (lItem.id == nil) then
return false;
elseif (lItem.class ~= rItem.class) then
if lItem.class == "Weapon" or rItem.class == "Weapon" then
return lItem.class == "Weapon"
end
return (lItem.class < rItem.class);
elseif (lItem.subclass ~= rItem.subclass) then
return (lItem.subclass < rItem.subclass);
elseif (lItem.quality ~= rItem.quality) then
return (lItem.quality > rItem.quality);
elseif (lItem.name ~= rItem.name) then
return (lItem.name < rItem.name);
elseif ((lItem.count) ~= (rItem.count)) then
return ((lItem.count) >= (rItem.count));
else
return true;
end
end
local function BeginSort()
current = nil;
moves = {};
ClearCursor();
end
local function SortGuildBankTab(tabItems)
for i = 1, #tabItems, 1 do
local lowest = i;
for j = #tabItems, i + 1, -1 do
if (CompareItems(tabItems[lowest], tabItems[j]) == false) then
lowest = j;
end
end
if (i ~= lowest) then
local move = {};
move.id = tabItems[lowest].id;
move.name = tabItems[lowest].name;
move.sourcetab = tabItems[lowest].tab;
move.sourceslot = tabItems[lowest].slot;
move.targettab = tabItems[i].tab;
move.targetslot = tabItems[i].slot;
table.insert(moves, move);
local tmp = tabItems[i];
tabItems[i] = tabItems[lowest];
tabItems[lowest] = tmp;
tmp = tabItems[i].slot;
tabItems[i].slot = tabItems[lowest].slot;
tabItems[lowest].slot = tmp;
tmp = tabItems[i].tab;
tabItems[i].tab = tabItems[lowest].tab;
tabItems[lowest].tab = tmp;
end
end
end
local function SortBag(bag)
for i = 1, #bag, 1 do
local lowest = i;
for j = #bag, i + 1, -1 do
if (CompareItems(bag[lowest], bag[j]) == false) then
lowest = j;
end
end
if (i ~= lowest) then
-- store move
local move = {};
move.id = bag[lowest].id;
move.name = bag[lowest].name;
move.sourcebag = bag[lowest].bag;
move.sourcetab = bag[lowest].tab;
move.sourceslot = bag[lowest].slot;
move.targetbag = bag[i].bag;
move.targettab = bag[i].tab;
move.targetslot = bag[i].slot;
table.insert(moves, move);
-- swap items
local tmp = bag[i];
bag[i] = bag[lowest];
bag[lowest] = tmp;
-- swap slots
tmp = bag[i].slot;
bag[i].slot = bag[lowest].slot;
bag[lowest].slot = tmp;
tmp = bag[i].bag;
bag[i].bag = bag[lowest].bag;
bag[lowest].bag = tmp;
tmp = bag[i].tab;
bag[i].tab = bag[lowest].tab;
bag[lowest].tab = tmp;
end
end
end
local function CreateBagFromID(bagID)
local items = GetContainerNumSlots(bagID);
local bag = {};
for i = 1, items, 1 do
local item = {};
local _, count, _, _, _, _, link = GetContainerItemInfo(bagID, i);
item.bag = bagID;
item.slot = i;
item.name = "<EMPTY>";
item.id = GetIDFromLink(link);
if (item.id ~= nil) then
item.count = count;
item.name, _, item.quality, _, _, item.class, item.subclass, _, item.type, _, item.price = GetItemInfo(item.id);
end
table.insert(bag, item);
end
return bag;
end
local function CreateGuildBankTabItems(tabID)
local items = {};
local numSlots = 98;
for i = 1, numSlots, 1 do
local item = {};
local texture, count, locked = GetGuildBankItemInfo(tabID, i);
local link = GetGuildBankItemLink(tabID, i);
item.tab = tabID;
item.slot = i;
item.name = "<EMPTY>";
item.id = GetIDFromLink(link);
if (item.id ~= nil) then
item.count = count or 1;
item.name, _, item.quality, _, _, item.class, item.subclass, _, item.type, _, item.price = GetItemInfo(item.id);
end
table.insert(items, item);
end
return items;
end
frame:SetScript("OnUpdate", function()
t = t + arg1;
if t > 0.03 then
t = 0
DoMoves();
end
end)
frame:Hide();
--
--[[ Constructor ]] --
function SortBtn:New(frameID, parent)
local b = self:Bind(CreateFrame('Button', nil, parent))
b:SetWidth(SIZE)
b:SetHeight(SIZE)
b:RegisterForClicks('anyUp')
local nt = b:CreateTexture()
nt:SetTexture([[Interface\Buttons\UI-Quickslot2]])
nt:SetWidth(NORMAL_TEXTURE_SIZE)
nt:SetHeight(NORMAL_TEXTURE_SIZE)
nt:SetPoint('CENTER', 0, -1)
b:SetNormalTexture(nt)
local pt = b:CreateTexture()
pt:SetTexture([[Interface\Buttons\UI-Quickslot-Depress]])
pt:SetAllPoints(b)
b:SetPushedTexture(pt)
local ht = b:CreateTexture()
ht:SetTexture([[Interface\Buttons\ButtonHilight-Square]])
ht:SetAllPoints(b)
b:SetHighlightTexture(ht)
local icon = b:CreateTexture()
icon:SetAllPoints(b)
icon:SetTexture([[Interface\Icons\ability_racial_bagoftricks]])
b:SetScript('OnClick', b.OnClick)
b:SetScript('OnEnter', b.OnEnter)
b:SetScript('OnLeave', b.OnLeave)
b:SetFrameID(frameID)
return b
end
--[[ Frame Events ]] --
function SortBtn:OnClick()
local bags = {};
if self.frameID == "inventory" then
isGuildBankSort = false;
for i = 0, NUM_BAG_FRAMES, 1 do
local bag = CreateBagFromID(i);
local type = select(2, GetContainerNumFreeSlots(i));
if type == nil then
type = "ALL"
else
type = tostring(type);
end
if bags[type] == nil then
bags[type] = bag;
else
for j = 1, #bag, 1 do
table.insert(bags[type], bag[j]);
end
end
end
elseif self.frameID == "bank" then
isGuildBankSort = false;
local i = -1
local bag = CreateBagFromID(i);
local type = select(2, GetContainerNumFreeSlots(i));
if type == nil then
type = "ALL"
else
type = tostring(type);
end
if bags[type] == nil then
bags[type] = bag;
else
for j = 1, #bag, 1 do
table.insert(bags[type], bag[j]);
end
end
for i = NUM_BAG_FRAMES+1, NUM_BAG_FRAMES + NUM_BANKBAGSLOTS, 1 do
local bag = CreateBagFromID(i);
local type = select(2, GetContainerNumFreeSlots(i));
if type == nil then
type = "ALL"
else
type = tostring(type);
end
if bags[type] == nil then
bags[type] = bag;
else
for j = 1, #bag, 1 do
table.insert(bags[type], bag[j]);
end
end
end
elseif self.frameID == "guildbank" then
isGuildBankSort = true;
local currentTab = GetCurrentGuildBankTab and GetCurrentGuildBankTab() or 0
if currentTab and currentTab > 0 then
local bankType = GetAscensionBankType()
local canSort = false
if bankType == "personal" or bankType == "realm" then
canSort = true
else
local _, _, canView, canDeposit, _, remainingWithdrawals = GetGuildBankTabInfo(currentTab)
if canDeposit and (remainingWithdrawals == -1 or remainingWithdrawals > 0) then
canSort = true
end
end
if canSort then
local tabItems = CreateGuildBankTabItems(currentTab)
bags["GUILDBANK"] = tabItems
else
return
end
else
return
end
end
local bagCount = 0
for k, v in pairs(bags) do
if v ~= nil then
bagCount = bagCount + 1
end
end
if bagCount == 0 then
return
end
BeginSort();
for k, v in pairs(bags) do
if v ~= nil then
if isGuildBankSort then
SortGuildBankTab(v);
else
SortBag(v);
end
end
end
frame:Show();
end
function SortBtn:OnEnter()
if self:GetRight() > (GetScreenWidth() / 2) then
GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
else
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
end
self:UpdateTooltip()
end
function SortBtn:OnLeave()
if GameTooltip:IsOwned(self) then
GameTooltip:Hide()
end
end
--[[ Update Methods ]] --
function SortBtn:UpdateTooltip()
if GameTooltip:IsOwned(self) then
GameTooltip:SetText(L.TipShowSortBtn)
end
end
--[[ Properties ]] --
function SortBtn:SetFrameID(frameID)
if self:GetFrameID() ~= frameID then
self.frameID = frameID
end
end
function SortBtn:GetFrameID()
return self.frameID
end