From 61bb1d9d8e0b24f600f5733ef80aeba06e3b2bdc Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 27 Dec 2025 01:59:14 +0400 Subject: [PATCH] feat: mailbox bug --- Core/Database.lua | 21 +++ Core/Events.lua | 8 ++ Core/Init.lua | 2 + Core/Main.lua | 7 + Data/MailboxScanner.lua | 126 +++++++++++++++++ Guda.toc | 3 + UI/BagFrame.lua | 113 +++++++++++++++ UI/BagFrame.xml | 46 ++++++ UI/BankFrame.xml | 46 ++++++ UI/ItemButton.lua | 38 ++++- UI/MailboxFrame.lua | 302 ++++++++++++++++++++++++++++++++++++++++ UI/MailboxFrame.xml | 244 ++++++++++++++++++++++++++++++++ 12 files changed, 951 insertions(+), 5 deletions(-) create mode 100644 Data/MailboxScanner.lua create mode 100644 UI/MailboxFrame.lua create mode 100644 UI/MailboxFrame.xml diff --git a/Core/Database.lua b/Core/Database.lua index 533b830..aa1d9b7 100644 --- a/Core/Database.lua +++ b/Core/Database.lua @@ -131,6 +131,7 @@ function DB:Initialize() money = 0, bags = {}, bank = {}, + mailbox = {}, -- Add mailbox storage equipped = {}, -- Add equipped items storage character = {}, -- Add character info storage lastUpdate = time(), @@ -153,6 +154,10 @@ function DB:Initialize() char.character = {} addon:Debug("Added character field to existing character") end + if not char.mailbox then + char.mailbox = {} + addon:Debug("Added mailbox field to existing character") + end end addon:Debug("Database initialized for %s", fullName) @@ -215,6 +220,16 @@ function DB:SaveMoney(copper) end end +-- Save mailbox data +function DB:SaveMailbox(mailboxData) + local char = self:GetCurrentCharacter() + if char then + char.mailbox = mailboxData + char.lastUpdate = time() + addon:Debug("Saved mailbox data") + end +end + -- Get all characters (optionally filter by faction and/or realm) function DB:GetAllCharacters(sameFactionOnly, currentRealmOnly) local chars = {} @@ -256,6 +271,12 @@ function DB:GetCharacterBank(fullName) return char and char.bank or {} end +-- Get character's mailbox +function DB:GetCharacterMailbox(fullName) + local char = Guda_DB.characters[fullName] + return char and char.mailbox or {} +end + -- Get character's equipped items function DB:GetCharacterEquipped(fullName) local char = Guda_DB.characters[fullName] diff --git a/Core/Events.lua b/Core/Events.lua index ec4b7a4..b690f16 100644 --- a/Core/Events.lua +++ b/Core/Events.lua @@ -79,3 +79,11 @@ end function Events:OnPlayerLogout(callback, owner) self:Register("PLAYER_LOGOUT", callback, owner) end + +function Events:OnMailShow(callback, owner) + self:Register("MAIL_SHOW", callback, owner) +end + +function Events:OnMailClosed(callback, owner) + self:Register("MAIL_CLOSED", callback, owner) +end diff --git a/Core/Init.lua b/Core/Init.lua index aa68ab4..9066e04 100644 --- a/Core/Init.lua +++ b/Core/Init.lua @@ -102,11 +102,13 @@ addon.Modules = { Tooltip = {}, BagScanner = {}, BankScanner = {}, + MailboxScanner = {}, MoneyTracker = {}, EquipmentScanner = {}, SortEngine = {}, BagFrame = {}, BankFrame = {}, + MailboxFrame = {}, QuestItemBar = {}, TrackedItemBar = {}, SettingsPopup = {}, diff --git a/Core/Main.lua b/Core/Main.lua index 9316884..2025155 100644 --- a/Core/Main.lua +++ b/Core/Main.lua @@ -18,6 +18,7 @@ function Main:Initialize() -- Initialize scanners addon.Modules.BagScanner:Initialize() addon.Modules.BankScanner:Initialize() + addon.Modules.MailboxScanner:Initialize() addon.Modules.MoneyTracker:Initialize() addon.Modules.EquipmentScanner:Initialize() @@ -25,6 +26,7 @@ function Main:Initialize() addon:Print("Initializing UI...") addon.Modules.BagFrame:Initialize() addon.Modules.BankFrame:Initialize() + addon.Modules.MailboxFrame:Initialize() addon:Debug("Checking QuestItemBar module...") if addon.Modules.QuestItemBar and addon.Modules.QuestItemBar.isLoaded then @@ -103,6 +105,10 @@ function Main:SetupSlashCommands() -- Toggle bank addon.Modules.BankFrame:Toggle() + elseif msg == "mail" or msg == "mailbox" then + -- Toggle mailbox + addon.Modules.MailboxFrame:Toggle() + elseif msg == "sort" then -- Sort bags addon.Modules.SortEngine:SortBags() @@ -143,6 +149,7 @@ function Main:SetupSlashCommands() addon:Print("Commands:") addon:Print("/guda - Toggle bags") addon:Print("/guda bank - Toggle bank") + addon:Print("/guda mail - Toggle mailbox") addon:Print("/guda sort - Sort bags") addon:Print("/guda sortbank - Sort bank") addon:Print("/guda track - Toggle item tracking") diff --git a/Data/MailboxScanner.lua b/Data/MailboxScanner.lua new file mode 100644 index 0000000..1c484fe --- /dev/null +++ b/Data/MailboxScanner.lua @@ -0,0 +1,126 @@ +-- Guda Mailbox Scanner +-- Scans and stores mailbox contents + +local addon = Guda + +local MailboxScanner = {} +addon.Modules.MailboxScanner = MailboxScanner + +local mailboxOpen = false + +-- Scan all mailbox items and return data +function MailboxScanner:ScanMailbox() + if not mailboxOpen then + addon:Debug("Cannot scan mailbox - not open") + return {} + end + + local mailboxData = {} + local numItems = GetInboxNumItems() + + for i = 1, numItems do + mailboxData[i] = self:ScanMailItem(i) + end + + return mailboxData +end + +-- Scan a single mail item +function MailboxScanner:ScanMailItem(index) + -- GetInboxItem(index) returns: packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply, isGM + local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply, isGM = GetInboxItem(index) + + local itemData = nil + if hasItem then + addon:Debug("Scanning mail item %d", index) + -- In 1.12.1, GetInboxItemLink(index) returns the link + local itemLink = GetInboxItemLink(index) + + -- GetInboxItemInfo(index) returns: name, texture, count, quality, canUse + local infoName, infoTexture, infoCount, infoQuality, infoCanUse = GetInboxItemInfo(index) + + addon:Debug("Mail item %d: infoName=%s, infoTexture=%s", index, tostring(infoName), tostring(infoTexture)) + + -- Even if link is missing (not cached), we can store what we have from GetInboxItemInfo + itemData = { + link = itemLink, + texture = infoTexture or packageIcon or "Interface\\Icons\\INV_Misc_Bag_08", + count = infoCount or 1, + quality = infoQuality or 0, + name = infoName or subject or "Unknown Item", + } + + -- If we have a link, try to get more detailed info + if itemLink then + local itemName, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(itemLink) + if itemName then + itemData.name = itemName + itemData.quality = itemQuality or itemData.quality + itemData.iLevel = iLevel + itemData.type = itemType + itemData.class = itemCategory + itemData.subclass = itemSubType + itemData.equipSlot = itemEquipLoc + if itemTexture then itemData.texture = itemTexture end + end + end + end + + return { + sender = sender, + subject = subject, + money = money, + CODAmount = CODAmount, + daysLeft = daysLeft, + hasItem = hasItem, + item = itemData, + wasRead = wasRead, + packageIcon = packageIcon, + } +end + +-- Save current mailbox to database +function MailboxScanner:SaveToDatabase() + if not mailboxOpen then + return + end + + local mailboxData = self:ScanMailbox() + addon.Modules.DB:SaveMailbox(mailboxData) + addon:Debug("Mailbox data saved") +end + +-- Initialize mailbox scanner +function MailboxScanner:Initialize() + -- Mailbox opened + addon.Modules.Events:OnMailShow(function() + mailboxOpen = true + addon:Debug("Mailbox opened") + + -- Delay scan slightly to ensure item info is available + local frame = CreateFrame("Frame") + local elapsed = 0 + frame:SetScript("OnUpdate", function() + elapsed = elapsed + arg1 + if elapsed >= 0.5 then + frame:SetScript("OnUpdate", nil) + if mailboxOpen then + MailboxScanner:SaveToDatabase() + end + end + end) + end, "MailboxScanner") + + -- Mailbox closed + addon.Modules.Events:OnMailClosed(function() + -- Final save on close + self:SaveToDatabase() + mailboxOpen = false + addon:Debug("Mailbox closed") + end, "MailboxScanner") +end + +-- Check if mailbox is currently open +function MailboxScanner:IsMailboxOpen() + return mailboxOpen +end diff --git a/Guda.toc b/Guda.toc index 2902f4c..8dddb87 100644 --- a/Guda.toc +++ b/Guda.toc @@ -16,6 +16,7 @@ Core\Tooltip.lua Data\BagScanner.lua Data\BankScanner.lua +Data\MailboxScanner.lua Data\MoneyTracker.lua Data\EquipmentScanner.lua @@ -25,12 +26,14 @@ Sorting\SortEngine.lua UI\ItemButton.lua UI\BagFrame.lua UI\BankFrame.lua +UI\MailboxFrame.lua UI\QuestItemBar.lua UI\TrackedItemBar.lua UI\SettingsPopup.lua UI\ItemButton.xml UI\BagFrame.xml UI\BankFrame.xml +UI\MailboxFrame.xml UI\SettingsPopup.xml Core\Main.lua diff --git a/UI/BagFrame.lua b/UI/BagFrame.lua index 3e30964..7e01ff7 100644 --- a/UI/BagFrame.lua +++ b/UI/BagFrame.lua @@ -1578,6 +1578,119 @@ local function HideCharacterDropdown() end end +-- Toggle mail dropdown +function Guda_BagFrame_ToggleMailDropdown(button) +-- Hide character dropdown if it's shown + if characterDropdown and characterDropdown:IsShown() then + characterDropdown:Hide() + end + + if bankDropdown and bankDropdown:IsShown() then + bankDropdown:Hide() + end + + if mailDropdown and mailDropdown:IsShown() then + mailDropdown:Hide() + return + end + + if not mailDropdown then + -- Create dropdown frame + mailDropdown = CreateFrame("Frame", "Guda_MailDropdown", UIParent) + mailDropdown:SetFrameStrata("DIALOG") + mailDropdown:SetWidth(200) + mailDropdown:SetBackdrop({ + bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", + edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", + tile = true, + tileSize = 16, + edgeSize = 16, + insets = { left = 4, right = 4, top = 4, bottom = 4 } + }) + mailDropdown:SetBackdropColor(0, 0, 0, 0.95) + mailDropdown:EnableMouse(true) + mailDropdown:Hide() + + mailDropdown.buttons = {} + end + + -- Position dropdown below the button + mailDropdown:ClearAllPoints() + mailDropdown:SetPoint("TOPLEFT", button, "BOTTOMLEFT", 0, -2) + -- Clear existing buttons + for _, btn in ipairs(mailDropdown.buttons) do + btn:Hide() + end + mailDropdown.buttons = {} + + -- Get all characters on current realm + local chars = addon.Modules.DB:GetAllCharacters(false, true) + + local yOffset = -8 + + -- Add character buttons + for _, char in ipairs(chars) do + -- Capture variables in local scope for closure + local charFullName = char.fullName + local charName = char.name + local charClassToken = char.classToken + + local charButton = CreateFrame("Button", nil, mailDropdown) + charButton:SetWidth(188) + charButton:SetHeight(20) + charButton:SetPoint("TOP", mailDropdown, "TOP", 0, yOffset) + + -- Button background on hover + local charBg = charButton:CreateTexture(nil, "BACKGROUND") + charBg:SetAllPoints() + charBg:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") + charBg:SetBlendMode("ADD") + charBg:SetAlpha(0) + + -- Get class color + local classColor = charClassToken and RAID_CLASS_COLORS[charClassToken] + local r, g, b = 1, 1, 1 + if classColor then + r, g, b = classColor.r, classColor.g, classColor.b + end + + -- Button text + local charText = charButton:CreateFontString(nil, "ARTWORK", "GameFontHighlight") + charText:SetPoint("LEFT", charButton, "LEFT", 8, 0) + charText:SetText(charName) + charText:SetTextColor(r, g, b) + + -- Button scripts + charButton:SetScript("OnEnter", function() + charBg:SetAlpha(0.3) + end) + charButton:SetScript("OnLeave", function() + charBg:SetAlpha(0) + end) + charButton:SetScript("OnClick", function() + if charFullName then + -- Show mailbox for this character + addon.Modules.MailboxFrame:ShowCharacter(charFullName) + if not Guda_MailboxFrame:IsShown() then + Guda_MailboxFrame:Show() + end + mailDropdown:Hide() + else + addon:Print("Error: Character fullName is nil") + end + end) + + table.insert(mailDropdown.buttons, charButton) + yOffset = yOffset - 20 + end + + -- Set dropdown height based on content + mailDropdown:SetHeight(math.abs(yOffset) + 8) + + -- Show dropdown + mailDropdown:Show() +end + -- Toggle bank dropdown function Guda_BagFrame_ToggleBankDropdown(button) -- Hide character dropdown if it's shown diff --git a/UI/BagFrame.xml b/UI/BagFrame.xml index aa887a5..76d6b7a 100644 --- a/UI/BagFrame.xml +++ b/UI/BagFrame.xml @@ -248,6 +248,52 @@ + + + diff --git a/UI/BankFrame.xml b/UI/BankFrame.xml index 0d22445..5db740e 100644 --- a/UI/BankFrame.xml +++ b/UI/BankFrame.xml @@ -107,6 +107,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Guda_MailboxFrame_OnSearchTextChanged() + + + this:ClearFocus() + + + this:ClearFocus() + + + if this:GetText() == "Search mailbox..." then + this:SetText("") + this:SetTextColor(1, 1, 1, 1) + end + if Guda_MailboxClickCatcher then + Guda_MailboxClickCatcher:Show() + end + + + if this:GetText() == "" then + this:SetText("Search mailbox...") + this:SetTextColor(0.5, 0.5, 0.5, 1) + end + if Guda_MailboxClickCatcher then + Guda_MailboxClickCatcher:Hide() + end + + + + + + + this:SetBackdropBorderColor(0.4, 0.4, 0.4) + this:SetBackdropColor(0.15, 0.15, 0.15, 0.5) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Guda_MailboxFrame_OnLoad(this) + + + Guda_MailboxFrame_OnShow(this) + + + this:StartMoving() + + + this:StopMovingOrSizing() + + + +