292 lines
7.8 KiB
Lua
292 lines
7.8 KiB
Lua
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
|
local DT = E:GetModule("DataTexts")
|
|
|
|
--Lua functions
|
|
local next = next
|
|
local find, format, join = string.find, string.format, string.join
|
|
local sort, wipe = table.sort, table.wipe
|
|
--WoW API / Variables
|
|
local EasyMenu = EasyMenu
|
|
local GetFriendInfo = GetFriendInfo
|
|
local GetMouseFocus = GetMouseFocus
|
|
local GetNumFriends = GetNumFriends
|
|
local GetQuestDifficultyColor = GetQuestDifficultyColor
|
|
local GetRealZoneText = GetRealZoneText
|
|
local InviteUnit = InviteUnit
|
|
local SendChatMessage = SendChatMessage
|
|
local SetItemRef = SetItemRef
|
|
local ToggleFriendsFrame = ToggleFriendsFrame
|
|
local UnitInParty = UnitInParty
|
|
local UnitInRaid = UnitInRaid
|
|
local UnitIsAFK = UnitIsAFK
|
|
local UnitIsDND = UnitIsDND
|
|
local AFK = AFK
|
|
local DND = DND
|
|
local FRIENDS = FRIENDS
|
|
|
|
local tthead = {r=0.4, g=0.78, b=1}
|
|
local activezone, inactivezone = {r=0.3, g=1.0, b=0.3}, {r=0.65, g=0.65, b=0.65}
|
|
|
|
local levelNameFormat = "|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r %s"
|
|
local levelNameStatusFormat = "|cff%02x%02x%02x%d|r %s%s %s"
|
|
local onlineInfoFormat = join("", FRIENDS_LIST_ONLINE, ": %s/%s")
|
|
|
|
local afkStatusString = format("<%s>", AFK)
|
|
local dndStatusString = format("<%s>", DND)
|
|
|
|
local inGroupStamp = "|cffaaaaaa*|r"
|
|
local friendOnlineString = string.gsub(ERR_FRIEND_ONLINE_SS, ".+|h", "")
|
|
local friendOfflineString = string.gsub(ERR_FRIEND_OFFLINE_S, "%%s", "")
|
|
|
|
local onlineStatusString = "|cffFFFFFF[|r|cff%s%s|r|cffFFFFFF]|r"
|
|
local onlineStatus = {
|
|
[""] = "",
|
|
[afkStatusString] = format(onlineStatusString, "FF9900", L["AFK"]),
|
|
[dndStatusString] = format(onlineStatusString, "FF3333", L["DND"]),
|
|
}
|
|
|
|
local displayString = ""
|
|
local lastPanel
|
|
|
|
local dataTable = {}
|
|
local dataUpdated
|
|
|
|
local menuFrame = CreateFrame("Frame", "FriendDatatextRightClickMenu", E.UIParent, "UIDropDownMenuTemplate")
|
|
local menuList = {
|
|
{text = OPTIONS_MENU, isTitle = true, notCheckable = true},
|
|
{text = INVITE, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true, menuList = {}},
|
|
{text = CHAT_MSG_WHISPER_INFORM, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true, menuList = {}},
|
|
{text = PLAYER_STATUS, hasArrow = true, notCheckable = true, keepShownOnClick = true, noClickSound = true,
|
|
menuList = {
|
|
{
|
|
text = format("|cff2BC226%s|r", AVAILABLE),
|
|
notCheckable = true,
|
|
func = function()
|
|
if UnitIsAFK("player") then
|
|
SendChatMessage("", "AFK")
|
|
elseif UnitIsDND("player") then
|
|
SendChatMessage("", "DND")
|
|
end
|
|
end
|
|
},
|
|
{
|
|
text = format("|cffE7E716%s|r", DND),
|
|
notCheckable = true,
|
|
func = function()
|
|
if not UnitIsDND("player") then
|
|
SendChatMessage("", "DND")
|
|
end
|
|
end
|
|
},
|
|
{
|
|
text = format("|cffFF0000%s|r", AFK),
|
|
notCheckable = true,
|
|
func = function()
|
|
if not UnitIsAFK("player") then
|
|
SendChatMessage("", "AFK")
|
|
end
|
|
end
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
local function inviteClick(_, playerName)
|
|
menuFrame:Hide()
|
|
InviteUnit(playerName)
|
|
end
|
|
|
|
local function whisperClick(_, playerName)
|
|
menuFrame:Hide()
|
|
SetItemRef("player:"..playerName, format("|Hplayer:%1$s|h[%1$s]|h", playerName), "LeftButton")
|
|
end
|
|
|
|
local function sortByName(a, b)
|
|
if a[1] and b[1] then
|
|
return a[1] < b[1]
|
|
end
|
|
end
|
|
|
|
local function BuildDataTable(total)
|
|
wipe(dataTable)
|
|
|
|
if total == 0 then return end
|
|
|
|
local name, level, class, area, connected, status, note, className
|
|
|
|
for i = 1, total do
|
|
name, level, class, area, connected, status, note = GetFriendInfo(i)
|
|
|
|
if connected then
|
|
className = E:UnlocalizedClassName(class) or ""
|
|
status = onlineStatus[status] or ""
|
|
|
|
dataTable[i] = {name, level, className, area, connected, status, note}
|
|
end
|
|
end
|
|
|
|
if next(dataTable) then
|
|
sort(dataTable, sortByName)
|
|
end
|
|
end
|
|
|
|
local function OnClick(_, btn)
|
|
if btn == "RightButton" then
|
|
DT.tooltip:Hide()
|
|
|
|
wipe(menuList[2].menuList)
|
|
wipe(menuList[3].menuList)
|
|
|
|
local menuCountWhispers, menuCountInvites = 0, 0
|
|
local classc, levelc, info, grouped, shouldSkip
|
|
|
|
local db = E.db.datatexts.friends
|
|
|
|
for i = 1, #dataTable do
|
|
info = dataTable[i]
|
|
|
|
if info[5] then
|
|
if (info[6] == onlineStatus[afkStatusString]) and db.hideAFK then
|
|
shouldSkip = true
|
|
elseif (info[6] == onlineStatus[dndStatusString]) and db.hideDND then
|
|
shouldSkip = true
|
|
else
|
|
shouldSkip = nil
|
|
end
|
|
|
|
if not shouldSkip then
|
|
classc = E.media.herocolor
|
|
classc = classc or GetQuestDifficultyColor(info[2])
|
|
levelc = GetQuestDifficultyColor(info[2])
|
|
|
|
if UnitInParty(info[1]) or UnitInRaid(info[1]) then
|
|
grouped = inGroupStamp
|
|
else
|
|
grouped = ""
|
|
|
|
menuCountInvites = menuCountInvites + 1
|
|
menuList[2].menuList[menuCountInvites] = {
|
|
text = format(levelNameFormat, levelc.r*255, levelc.g*255, levelc.b*255, info[2], classc.r*255, classc.g*255, classc.b*255, info[1], grouped),
|
|
arg1 = info[1],
|
|
notCheckable = true,
|
|
func = inviteClick
|
|
}
|
|
end
|
|
|
|
menuCountWhispers = menuCountWhispers + 1
|
|
menuList[3].menuList[menuCountWhispers] = {
|
|
text = format(levelNameFormat, levelc.r*255, levelc.g*255, levelc.b*255, info[2], classc.r*255, classc.g*255, classc.b*255, info[1], grouped),
|
|
arg1 = info[1],
|
|
notCheckable = true,
|
|
func = whisperClick
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
menuList[2].disabled = menuCountInvites == 0
|
|
menuList[3].disabled = menuCountWhispers == 0
|
|
|
|
EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
|
|
else
|
|
ToggleFriendsFrame(1)
|
|
end
|
|
end
|
|
|
|
local function OnEnter(self)
|
|
local numberOfFriends, onlineFriends = GetNumFriends()
|
|
if onlineFriends == 0 then return end
|
|
|
|
DT:SetupTooltip(self)
|
|
|
|
if not dataUpdated then
|
|
if numberOfFriends > 0 then
|
|
BuildDataTable(numberOfFriends)
|
|
end
|
|
|
|
dataUpdated = true
|
|
end
|
|
|
|
DT.tooltip:AddDoubleLine(
|
|
L["Friends List"],
|
|
format(onlineInfoFormat, onlineFriends, numberOfFriends),
|
|
tthead.r, tthead.g, tthead.b,
|
|
tthead.r, tthead.g, tthead.b
|
|
)
|
|
|
|
local playerZone = GetRealZoneText()
|
|
local db = E.db.datatexts.friends
|
|
local zonec, classc, levelc, info, grouped, shouldSkip
|
|
|
|
for i = 1, #dataTable do
|
|
info = dataTable[i]
|
|
|
|
if info[5] then
|
|
if (info[6] == onlineStatus[afkStatusString]) and db.hideAFK then
|
|
shouldSkip = true
|
|
elseif (info[6] == onlineStatus[dndStatusString]) and db.hideDND then
|
|
shouldSkip = true
|
|
else
|
|
shouldSkip = nil
|
|
end
|
|
|
|
if not shouldSkip then
|
|
if playerZone == info[4] then
|
|
zonec = activezone
|
|
else
|
|
zonec = inactivezone
|
|
end
|
|
|
|
classc = E.media.herocolor
|
|
classc = classc or GetQuestDifficultyColor(info[2])
|
|
levelc = GetQuestDifficultyColor(info[2])
|
|
|
|
if UnitInParty(info[1]) or UnitInRaid(info[1]) then
|
|
grouped = inGroupStamp
|
|
else
|
|
grouped = ""
|
|
end
|
|
|
|
DT.tooltip:AddDoubleLine(
|
|
format(levelNameStatusFormat, levelc.r*255, levelc.g*255, levelc.b*255, info[2], info[1], grouped, info[6]),
|
|
info[4],
|
|
classc.r, classc.g, classc.b,
|
|
zonec.r, zonec.g, zonec.b
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
DT.tooltip:Show()
|
|
end
|
|
|
|
local function OnEvent(self, event, message)
|
|
lastPanel = self
|
|
|
|
-- special handler to detect friend coming online or going offline
|
|
if event == "CHAT_MSG_SYSTEM" then
|
|
if not (find(message, friendOnlineString) or find(message, friendOfflineString)) then return end
|
|
end
|
|
|
|
local _, onlineFriends = GetNumFriends()
|
|
|
|
self.text:SetFormattedText(displayString, onlineFriends)
|
|
|
|
-- force update when showing tooltip
|
|
dataUpdated = nil
|
|
|
|
if GetMouseFocus() == self then
|
|
self:GetScript("OnEnter")(self)
|
|
end
|
|
end
|
|
|
|
local function ValueColorUpdate(hex)
|
|
displayString = join("", FRIENDS, ": ", hex, "%d|r")
|
|
|
|
if lastPanel ~= nil then
|
|
OnEvent(lastPanel, "ELVUI_COLOR_UPDATE")
|
|
end
|
|
end
|
|
E.valueColorUpdateFuncs[ValueColorUpdate] = true
|
|
|
|
DT:RegisterDatatext("Friends", {"PLAYER_ENTERING_WORLD", "CHAT_MSG_SYSTEM", "FRIENDLIST_UPDATE"}, OnEvent, nil, OnClick, OnEnter, nil, FRIENDS) |