fix: poor tooltip for mailboxframe

This commit is contained in:
Salikh Gurgenidze
2025-12-27 22:59:42 +04:00
parent 0c2954d230
commit 6808a21479
4 changed files with 153 additions and 15 deletions
+42
View File
@@ -230,6 +230,48 @@ function DB:SaveMailbox(mailboxData)
end
end
-- Add a single mail entry to a character's mailbox
function DB:AddMailToCharacter(name, realm, mailRow)
local fullName = name .. "-" .. (realm or playerRealm)
local char = Guda_DB.characters[fullName]
if char then
if not char.mailbox then
char.mailbox = {}
end
-- Check if this exact mail already exists (simplistic check)
local exists = false
for _, m in ipairs(char.mailbox) do
if m.sender == mailRow.sender and m.subject == mailRow.subject and m.money == mailRow.money then
if (not m.item and not mailRow.item) or (m.item and mailRow.item and m.item.name == mailRow.item.name and m.item.count == mailRow.item.count) then
exists = true
-- Update link/itemID if missing in existing but present in new
if mailRow.item and m.item then
if not m.item.link and mailRow.item.link then
m.item.link = mailRow.item.link
addon:Debug("Updated link for existing mail item")
end
if not m.item.itemID and mailRow.item.itemID then
m.item.itemID = mailRow.item.itemID
addon:Debug("Updated itemID for existing mail item")
end
end
break
end
end
end
if not exists then
table.insert(char.mailbox, 1, mailRow) -- Add to beginning
char.lastUpdate = time()
addon:Debug("Added outgoing mail to %s's mailbox", fullName)
return true
end
end
return false
end
-- Get all characters (optionally filter by faction and/or realm)
function DB:GetAllCharacters(sameFactionOnly, currentRealmOnly)
local chars = {}
+6 -6
View File
@@ -101,10 +101,13 @@ scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
-- Get item link from mailbox attachment (WoW 1.12.1 workaround)
function Utils:GetInboxItemLink(index, itemIndex)
-- Try global function first (if it exists on this server/version)
if GetInboxItemLink then
local link = GetInboxItemLink(index)
if link then return link end
end
-- In 1.12.1, GameTooltip:GetHyperlink() does not exist.
-- Actually, in 1.12.1, there's no official API to get the link from a mailbox item
-- if GetInboxItemLink(index) is not available (it's often NOT available in Vanilla).
-- Let's try to use GetItemInfo(name) as the primary way.
local name = GetInboxItem(index, itemIndex)
if name then
@@ -114,9 +117,6 @@ function Utils:GetInboxItemLink(index, itemIndex)
end
end
-- Fallback: If we still don't have it, we might try to scan the tooltip for the name
-- but GetInboxItem already gave us the name.
return nil
end
+93 -3
View File
@@ -48,11 +48,36 @@ function MailboxScanner:ScanMailItemRows(index)
count = count or 1,
quality = quality or 0,
name = name,
itemID = addon.Modules.Utils:ExtractItemID(itemLink),
}
-- Fallback: If link/itemID is missing, try to recover from existing database
if not itemData.itemID or not itemData.link then
local existingMailbox = addon.Modules.DB:GetCharacterMailbox(addon.Modules.DB:GetPlayerFullName())
for _, oldMail in ipairs(existingMailbox) do
-- Match by sender, subject and item name
if oldMail.sender == sender and oldMail.subject == subject and oldMail.item and oldMail.item.name == name then
if not itemData.link and oldMail.item.link then
itemData.link = oldMail.item.link
addon:Debug("Recovered link from database for %s", name)
end
if not itemData.itemID and oldMail.item.itemID then
itemData.itemID = oldMail.item.itemID
addon:Debug("Recovered itemID from database for %s", name)
end
if itemData.link and itemData.itemID then break end
end
end
end
-- If we still don't have itemID but have a link (or vice versa), fix it
if itemData.link and not itemData.itemID then
itemData.itemID = addon.Modules.Utils:ExtractItemID(itemData.link)
end
-- 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 itemData.link then
local itemName, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(itemData.link)
if itemName then
itemData.name = itemName
itemData.quality = itemQuality or itemData.quality
@@ -112,8 +137,73 @@ function MailboxScanner:SaveToDatabase()
addon:Debug("Mailbox data saved")
end
-- Handle outgoing mail
function MailboxScanner:OnSendMail(recipient, subject, body)
if not recipient or recipient == "" then return end
-- In WoW 1.12.1, SendMail(recipient, subject, body) is the signature.
-- To get the attached item, we use GetSendMailItem().
-- GetSendMailItem() returns: name, texture, count, quality
local name, texture, count, quality = GetSendMailItem()
local moneyAmount = GetSendMailMoney()
local itemData = nil
if name then
local _, link = GetItemInfo(name)
itemData = {
name = name,
texture = texture or "Interface\\Icons\\INV_Misc_Bag_08",
count = count or 1,
quality = quality or 0,
link = link,
itemID = addon.Modules.Utils:ExtractItemID(link),
}
-- Try to get more info if it's in cache
local itemName, retLink, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(name)
if itemName then
itemData.link = retLink or itemData.link
itemData.itemID = addon.Modules.Utils:ExtractItemID(itemData.link) or itemData.itemID
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
-- Double check itemID
if not itemData.itemID and itemData.link then
itemData.itemID = addon.Modules.Utils:ExtractItemID(itemData.link)
end
end
if itemData or moneyAmount > 0 then
local mailRow = {
sender = UnitName("player"),
subject = (subject and subject ~= "") and subject or "No Subject",
money = moneyAmount,
CODAmount = 0,
daysLeft = 30, -- Outgoing mail typically has 30 days
hasItem = itemData ~= nil,
item = itemData,
wasRead = false,
}
addon.Modules.DB:AddMailToCharacter(recipient, nil, mailRow)
end
end
-- Initialize mailbox scanner
function MailboxScanner:Initialize()
-- Hook SendMail to capture outgoing mail to alts
local originalSendMail = SendMail
SendMail = function(recipient, subject, body)
MailboxScanner:OnSendMail(recipient, subject, body)
return originalSendMail(recipient, subject, body)
end
-- Mailbox opened
addon.Modules.Events:OnMailShow(function()
mailboxOpen = true
@@ -155,7 +245,7 @@ function MailboxScanner:Initialize()
-- Mailbox closed
addon.Modules.Events:OnMailClosed(function()
-- Final save on close
self:SaveToDatabase()
MailboxScanner:SaveToDatabase()
mailboxOpen = false
addon:Debug("Mailbox closed")
end, "MailboxScanner")
+12 -6
View File
@@ -982,13 +982,19 @@ function Guda_ItemButton_OnEnter(self)
-- Mailbox tooltip handling
if self.isMail then
local currentPlayerName = addon.Modules.DB:GetPlayerFullName()
if (not self.otherChar or self.otherChar == currentPlayerName) and self.mailIndex then
-- Live mailbox for current character
local isMailboxOpen = addon.Modules.MailboxScanner and addon.Modules.MailboxScanner:IsMailboxOpen()
if (not self.otherChar or self.otherChar == currentPlayerName) and self.mailIndex and isMailboxOpen then
-- Live mailbox for current character (only when mailbox is actually open)
GameTooltip:SetInboxItem(self.mailIndex, self.mailItemIndex or 1)
elseif self.itemData and self.itemData.link then
-- Read-only / other character mailbox
GameTooltip.GudaViewedCharacter = self.otherChar
GameTooltip:SetHyperlink(self.itemData.link)
elseif self.itemData and (self.itemData.link or self.itemData.itemID) then
-- Read-only / other character mailbox OR current character mailbox when closed
GameTooltip.GudaViewedCharacter = self.otherChar or currentPlayerName
if self.itemData.link then
GameTooltip:SetHyperlink(self.itemData.link)
else
GameTooltip:SetHyperlink("item:" .. self.itemData.itemID .. ":0:0:0")
end
elseif self.itemData and self.itemData.name then
-- Money or generic mail
GameTooltip:AddLine(self.itemData.name, 1, 1, 1)