From 91142ac27c8fabd651b8e8db6c3d30baa31a604e Mon Sep 17 00:00:00 2001 From: Sica Date: Sun, 23 Mar 2025 23:27:49 +0100 Subject: [PATCH] New logging feature --- .luarc.json | 6 +- Calendar.lua | 292 ++++++++ README.md | 5 +- TurtleMail-DownArrow.tga | Bin 0 -> 301 bytes TurtleMail.lua | 1541 +++++++++++++++++++++++++++----------- TurtleMail.toc | 4 +- TurtleMail.xml | 558 +++++++++++++- localization.de.lua | 3 + localization.es.lua | 3 + localization.fr.lua | 3 + localization.lua | 26 +- localization.ru.lua | 3 + 12 files changed, 1997 insertions(+), 447 deletions(-) create mode 100644 Calendar.lua create mode 100644 TurtleMail-DownArrow.tga diff --git a/.luarc.json b/.luarc.json index 00e2dd1..f6a3305 100644 --- a/.luarc.json +++ b/.luarc.json @@ -5,8 +5,12 @@ "_", "this", "event", - "GetLocale" + "GetLocale", + "time", + "date", + "mod" ], + "Lua.runtime.version": "Lua 5.1", "Lua.workspace.checkThirdParty": false, "Lua.workspace.ignoreDir": [], "workspace.library": [], diff --git a/Calendar.lua b/Calendar.lua new file mode 100644 index 0000000..8a376d9 --- /dev/null +++ b/Calendar.lua @@ -0,0 +1,292 @@ +TurtleMail = TurtleMail or {} +local m = TurtleMail + +if m.Calendar then return end + +---@class Calendar +---@field show fun( data: table, date: number, anchor: table, on_select: function ) +---@field hide fun() +---@field is_visible fun():boolean + +local M = {} + +function M.new() + local BTN_WIDTH = 25 + local BTN_HEIGHT = 20 + + local calendar + local set_year, set_month + local year_dd, month_dd + local date_data = {} + local months = {} + local days = {} + local select_func + + for i = 1, 12 do + local timestamp = time( { year = 2025, month = i, day = 1 } ) + months[ i ] = date( "%B", timestamp ) + end + + local function get_end_day_of_month( year, month ) + if month == 2 then + if (mod( year, 4 ) == 0 and mod( year, 100 ) ~= 0) or mod( year, 400 ) == 0 then + return 29 + else + return 28 + end + elseif month == 4 or month == 6 or month == 9 or month == 11 then + return 30 + else + return 31 + end + end + + ---@alias DatePart + ---| "Year" + ---| "Month" + ---| "Day" + + ---@param part DatePart + local function get_valid_dates( part ) + local valid = {} + for i, v in ipairs( date_data ) do + local year = tonumber( date( "%Y", v.timestamp ) ) + local month = tonumber( date( "%m", v.timestamp ) ) + local day = tonumber( date( "%d", v.timestamp ) ) + + if year and month and day then + if part == "Day" and year == set_year and month == set_month then + valid[ day ] = valid[ day ] and valid[ day ] + 1 or 1 + elseif part == "Month" and year == set_year then + valid[ month ] = true + elseif part == "Year" then + valid[ year ] = true + end + end + end + + return valid + end + + local function refresh() + local current_month = { year = set_year, month = set_month, day = "01" } + local skip_days = date( "%w", time( current_month ) ) + local end_day = get_end_day_of_month( tonumber( set_year ), tonumber( set_month ) ) + + for i = 1, 42 do + days[ i ]:SetText( "" ) + days[ i ]:Disable() + days[ i ]:Hide() + end + + local valid_days = get_valid_dates( "Day" ) + for i = 1, end_day do + local day = days[ i + skip_days ] + local d = i + day:SetText( i ) + + if valid_days[ i ] then + day.mails = valid_days[ i ] + day:Enable() + end + day:Show() + + day:SetScript( "OnClick", function() + local timestamp = time( { year = set_year, month = set_month, day = d } ) + if select_func then + select_func( timestamp ) + end + calendar:Hide() + end ) + end + + if tonumber( skip_days + end_day ) < 36 then + calendar:SetHeight( 150 ) + else + calendar:SetHeight( 170 ) + end + + m.api.UIDropDownMenu_SetText( months[ set_month ], month_dd ) + m.api.UIDropDownMenu_SetText( set_year, year_dd ) + end + + local function pfui_skin() + if m.pfui_skin_enabled then + m.api.pfUI.api.SkinDropDown( year_dd, nil, nil, nil, true ) + year_dd:SetPoint( "TOPLEFT", -5, -5 ) + m.api.pfUI.api.SkinDropDown( month_dd, nil, nil, nil, true ) + month_dd:SetPoint( "TOPLEFT", 79, -5 ) + m.api.UIDropDownMenu_SetWidth( 70, month_dd ) + + for i = 1, 42 do + local button = days[ i ] + m.api.pfUI.api.SkinButton( button ) + button:SetWidth( BTN_WIDTH - 1 ) + button:SetHeight( BTN_HEIGHT - 1 ) + end + end + end + + ---@param parent table + ---@param index number + local function create_date_button( parent, index ) + local button = m.api.CreateFrame( "Button", "TurtleMailCalendarDay" .. index .. "Button", parent, "UIPanelButtonTemplate" ) + button:SetWidth( BTN_WIDTH ) + button:SetHeight( BTN_HEIGHT ) + button:GetFontString():SetFont( m.pfui_skin_enabled and m.api.pfUI.font_default or "Fonts/FRIZQT__.TTF", 9 ) + button:GetFontString():SetTextColor( 1, 1, 1, 1 ) + + local orig_disable = button.Disable + button.Disable = function( self ) + orig_disable( self ) + button:GetFontString():SetTextColor( 0.5, 0.5, 0.5, 1 ) + end + + local orig_enable = button.Enable + button.Enable = function( self ) + orig_enable( self ) + button:GetFontString():SetTextColor( 1, 1, 1, 1 ) + end + + button:SetScript( "OnEnter", function() + m.api.GameTooltip:SetOwner( this, "ANCHOR_RIGHT" ) + m.api.GameTooltip:SetText( button.mails .. " mail" .. (button.mails > 1 and "s" or ""), 1, 1, 1, 1, true ) + m.api.GameTooltip:Show() + end ) + + button:SetScript( "OnLeave", function() + m.api.GameTooltip:Hide() + end ) + + return button + end + + ---@param parent table + ---@param name DatePart + ---@param on_select function + ---@return table + local function create_dropdown( parent, name, on_select ) + local dropdown = m.api.CreateFrame( "Frame", "TurtleMailDropdown" .. name, parent, "UIDropDownMenuTemplate" ) + + m.api.UIDropDownMenu_Initialize( dropdown, function() + local valid_dates = get_valid_dates( name ) + local info = m.api.UIDropDownMenu_CreateInfo() + + for i in pairs( valid_dates ) do + info.arg1 = i + info.arg2 = name == "Month" and months[ i ] or i + info.value = info.arg1 + info.text = info.arg2 + + info.func = function( index, value ) + m.api.UIDropDownMenu_SetText( value, dropdown ) + m.api.CloseDropDownMenus() + on_select( index, value ) + end + + m.api.UIDropDownMenu_AddButton( info ) + end + end ) + + return dropdown + end + + local function create_calendar() + local frame = m.api.CreateFrame( "Frame", "TurtleMailCalendarFrame" ) + frame:SetFrameStrata( "FULLSCREEN_DIALOG" ) + frame:SetWidth( 195 ) + frame:SetHeight( 170 ) + frame:SetBackdrop( { + bgFile = "Interface/Buttons/WHITE8x8", + edgeFile = "Interface/Buttons/WHITE8x8", + tile = false, + tileSize = 0, + edgeSize = 0.5, + insets = { left = 0, right = 0, top = 0, bottom = 0 } + } ) + + frame:SetBackdropColor( 0, 0, 0, 0.9 ) + frame:SetBackdropBorderColor( .4, .4, .4, 0.9 ) + frame:EnableMouse( true ) + frame:Hide() + m.api.tinsert( m.api.UISpecialFrames, frame:GetName() ) + + frame:SetScript( "OnLeave", function() + if m.api.MouseIsOver( frame ) then + return + end + calendar:Hide() + end ) + + year_dd = create_dropdown( frame, "Year", function( _, v ) + set_year = v + refresh() + end ) + year_dd:SetPoint( "TOPLEFT", -12, -5 ) + m.api.UIDropDownMenu_SetWidth( 55, year_dd ) + + month_dd = create_dropdown( frame, "Month", function( v ) + set_month = v + refresh() + end ) + month_dd:SetPoint( "TOPLEFT", 70, -5 ) + m.api.UIDropDownMenu_SetWidth( 85, month_dd ) + + for i = 1, 42 do + table.insert( days, create_date_button( frame, i ) ) + end + + for i = 1, 6 do + for j = 1, 7 do + days[ (i - 1) * 7 + j ]:SetPoint( "TOPLEFT", frame, 10 + (j - 1) * BTN_WIDTH, -40 - (i - 1) * BTN_HEIGHT ) + days[ (i - 1) * 7 + j ]:Disable() + end + end + + pfui_skin() + return frame + end + + local function show( data, current_date, anchor, on_select ) + date_data = data + set_year = tonumber( date( "%Y", current_date ) ) + set_month = tonumber( date( "%m", current_date ) ) + select_func = on_select + + if not calendar then + calendar = create_calendar() + end + + if m.pfui_skin_enabled then + calendar:SetPoint( "TOPRIGHT", anchor, "BOTTOMRIGHT", 125, -4 ) + else + calendar:SetPoint( "TOPRIGHT", anchor, "BOTTOMRIGHT", 100, 1 ) + end + + refresh() + calendar:Show() + end + + local function hide() + if calendar then + calendar:Hide() + end + end + + local function is_visible() + if calendar then + return calendar:IsVisible() + end + return false + end + + ---@type Calendar + return { + show = show, + hide = hide, + is_visible = is_visible + } +end + +m.Calendar = M +return M diff --git a/README.md b/README.md index 3cdcec0..34d1d6d 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,10 @@ An extension to the Blizzard mail interface which - **Automatically opens mail, very rapidly** - **Mails multiple items at once, very rapidly** - **Autocompletes recipient names** -- **Icons to show if mail was returned or is from** +- **Icons to show if mail was returned or is from AH** - **Shows collected gold from opened mails** - **Apply COD to 1st or all mails** +- **Logging of all sent and received mails** **\** on inbox items to loot the gold, loot the item and destroy the letter, in that order, if any.
**\** or **\** to add inventory items to the attachments.
@@ -14,6 +15,8 @@ An extension to the Blizzard mail interface which Note that COD is always ignored when opening, both automatically as well as by **\**. +Logging is disabled by default. Enable with `/tm log` command + ![Alt text](https://i.imgur.com/H0MUmXd.png) ![Alt text](https://i.imgur.com/LM7tRcx.png) diff --git a/TurtleMail-DownArrow.tga b/TurtleMail-DownArrow.tga new file mode 100644 index 0000000000000000000000000000000000000000..fb6c3b2ca14cc6c4f612711a62184c270e329d3f GIT binary patch literal 301 zcmZQz;9`IQ0R{mE1&;pz|Nk=}h*l7n5lHw6PusAg9mH!v5o#2ev*UjoNT?Y_ycr}8 z*4>06-U<>28_|d&-VPE68^Ht;2V$^|ogiVj2@GIIfP@+~jywPo2X6ca8v`~FY$XFo t0&Fi%u_liL7ydT}012= api.GetInboxNumItems() then + local _, _, _, _, _, COD, _, _, _, _, _, _, isGM = m.api.GetInboxHeaderInfo( m.inbox_index ) + if m.inbox_index > m.api.GetInboxNumItems() then if m.money_received > 0 then - api.DEFAULT_CHAT_FRAME:AddMessage( string.format( "|cffabd473TurtleMail|r: %s%s.", m.format_money( m.money_received ), L[ "collected" ] ) ) + m.info( string.format( "%s%s.", m.format_money( m.money_received ), L[ "collected" ] ) ) end - Inbox_Abort() - elseif Inbox_Skip or COD > 0 or isGM then - Inbox_Skip = false + m.inbox_abort() + elseif m.inbox_skip or COD > 0 or isGM then + m.inbox_skip = false m.inbox_index = m.inbox_index + 1 m.inbox_update = true else - Inbox_Open( m.inbox_index ) + m.inbox_open( m.inbox_index ) end end if m.timer > 0 then m.timer = m.timer - 1 - elseif not Inbox_opening then + elseif not m.inbox_opening then m.timer = 200 - api.CheckInbox() + m.api.CheckInbox() end end -function Mail.CURSOR_UPDATE() +function TurtleMail.CURSOR_UPDATE() m.cursorItem = nil end -function Mail.get_cursor_item() - return Mail.cursorItem +function TurtleMail.get_cursor_item() + return m.cursorItem end ---@param item table -function Mail.set_cursor_item( item ) +function TurtleMail.set_cursor_item( item ) m._cursorItem = item end -function Mail.BAG_UPDATE() - if api.MailFrame:IsVisible() then - api.SendMailFrame_Update() +function TurtleMail.BAG_UPDATE() + if m.api.MailFrame:IsVisible() then + m.api.SendMailFrame_Update() end end -function Mail.MAIL_SHOW() - if api.TurtleMail_Point then - api.MailFrame:SetPoint( api.TurtleMail_Point.point, api.TurtleMail_Point.x, api.TurtleMail_Point.y ) +function TurtleMail.MAIL_SHOW() + if m.api.TurtleMail_Point then + m.debug( "Set point" ) + m.api.MailFrame:SetPoint( m.api.TurtleMail_Point.point, m.api.TurtleMail_Point.x, m.api.TurtleMail_Point.y ) + end + + if not m.first_show then + m.first_show = true + if m.pfui_skin_enabled then + m.api.pfUI.api.StripTextures( m.api.SendMailPackageButton ) + end + + local background = ({ m.api.SendMailPackageButton:GetRegions() })[ 1 ] + background:Hide() + local count = ({ m.api.SendMailPackageButton:GetRegions() })[ 3 ] + count:Hide() + m.api.SendMailPackageButton:Disable() + m.api.SendMailPackageButton:SetScript( "OnReceiveDrag", nil ) + m.api.SendMailPackageButton:SetScript( "OnDragStart", nil ) + end + + if m.log_enabled then + m.api.MailFrameTab3:Show() + else + m.api.MailFrameTab3:Hide() end m.timer = 0 @@ -109,144 +201,171 @@ function Mail.MAIL_SHOW() m.update_money( 0 ) end -function Mail.MAIL_CLOSED() - Inbox_Abort() - SendMail_sending = false - SendMail_Clear() +function TurtleMail.MAIL_CLOSED() + m.inbox_abort() + m.sendmail_sending = false + m.sendmail_clear() end -function Mail.UI_ERROR_MESSAGE() - if Inbox_opening then - if arg1 == api.ERR_INV_FULL then - Inbox_Abort() - elseif arg1 == api.ERR_ITEM_MAX_COUNT then - Inbox_skip = true +function TurtleMail.UI_ERROR_MESSAGE() + if m.inbox_opening then + if arg1 == m.api.ERR_INV_FULL then + m.inbox_abort() + elseif arg1 == m.api.ERR_ITEM_MAX_COUNT then + m.inbox_skip = true end - elseif SendMail_sending and (arg1 == api.ERR_MAIL_TO_SELF or arg1 == api.ERR_PLAYER_WRONG_FACTION or arg1 == api.ERR_MAIL_TARGET_NOT_FOUND or arg1 == api.ERR_MAIL_REACHED_CAP) then - SendMail_sending = false - SendMail_state = nil - api.ClearCursor() + elseif m.sendmail_sending and (arg1 == m.api.ERR_MAIL_TO_SELF or arg1 == m.api.ERR_PLAYER_WRONG_FACTION or arg1 == m.api.ERR_MAIL_TARGET_NOT_FOUND or arg1 == m.api.ERR_MAIL_REACHED_CAP) then + m.sendmail_sending = false + m.sendmail_state = nil + m.api.ClearCursor() m.orig.ClickSendMailItemButton() - api.ClearCursor() + m.api.ClearCursor() end end -function Mail.ADDON_LOADED() +function TurtleMail.ADDON_LOADED() if arg1 ~= "TurtleMail" then return end - local version = api.GetAddOnMetadata( "TurtleMail", "Version" ) - api.DEFAULT_CHAT_FRAME:AddMessage( string.format( "|cffabd473TurtleMail|r: Loaded(|cffeda55fv%s|r).", version ) ) + local version = m.api.GetAddOnMetadata( "TurtleMail", "Version" ) + m.info( string.format( "Loaded (|cffeda55fv%s|r).", version ) ) - api.UIPanelWindows.MailFrame.pushable = 1 - api.UIPanelWindows.FriendsFrame.pushable = 2 + if not m.api.TurtleMail_Log[ "Settings" ].first_run then + m.api.TurtleMail_Log[ "Settings" ].first_run = version + m.info ( "New in |cffeda55fv1.4|r: Enable logging with |cffabd473/tm log|r" ) + end + + if m.api.UIPanelWindows[ "MailFrame" ] then + m.api.UIPanelWindows[ "MailFrame" ].pushable = 1 + else + m.api.UIPanelWindows[ "MailFrame" ] = { area = "left", pushable = 1 } + end + + if m.api.UIPanelWindows[ "FriendsFrame" ] then + m.api.UIPanelWindows[ "FriendsFrame" ].pushable = 2 + else + m.api.UIPanelWindows[ "FriendsFrame" ] = { area = "left", pushable = 2 } + end + + m.api.MailFrame:SetScript( "OnDragStop", m.on_drag_stop ) + m.api.MailFrame:SetClampedToScreen( true ) + m.api.PanelTemplates_SetNumTabs( m.api.MailFrame, 3 ) m.inbox_load() m.sendmail_load() + m.log.load() + m.pfui_skin() end -function Mail.PLAYER_LOGIN() +function TurtleMail.PLAYER_LOGIN() m.debug( "PLAYER_LOGIN" ) for k, v in m.hooks do - m.orig[ k ] = api[ k ] - api[ k ] = v + m.orig[ k ] = m.api[ k ] + m.api[ k ] = v end - local key = api.GetCVar( "realmName" ) .. "|" .. api.UnitFactionGroup( "player" ) - api.TurtleMail_AutoCompleteNames[ key ] = api.TurtleMail_AutoCompleteNames[ key ] or {} - for char, lastSeen in api.TurtleMail_AutoCompleteNames[ key ] do - if api.GetTime() - lastSeen > 60 * 60 * 24 * 30 then - api.TurtleMail_AutoCompleteNames[ key ][ char ] = nil + local key = m.api.GetCVar( "realmName" ) .. "|" .. m.api.UnitFactionGroup( "player" ) + m.api.TurtleMail_AutoCompleteNames[ key ] = m.api.TurtleMail_AutoCompleteNames[ key ] or {} + for char, last_seen in m.api.TurtleMail_AutoCompleteNames[ key ] do + if m.api.GetTime() - last_seen > 60 * 60 * 24 * 30 then + m.api.TurtleMail_AutoCompleteNames[ key ][ char ] = nil end end - m.add_auto_complete_name( api.UnitName( "player" ) ) + m.add_auto_complete_name( m.api.UnitName( "player" ) ) + m.log_enabled = m.api.TurtleMail_Log[ "Settings" ][ "Enabled" ] + + SLASH_TURTLEMAIL1 = "/turtlemail" + SLASH_TURTLEMAIL2 = "/tm" + m.api.SlashCmdList[ "TURTLEMAIL" ] = m.slash_command end -function Mail.MAIL_SEND_SUCCESS() - if SendMail_state then - m.add_auto_complete_name( SendMail_state.to ) +function TurtleMail.MAIL_SEND_SUCCESS() + m.debug( "MAIL_SEND_SUCCESS" ) + if m.sendmail_state then + m.log.add( 'Sent', m.sendmail_state ) + m.add_auto_complete_name( m.sendmail_state.to ) end - if SendMail_sending then + if m.sendmail_sending then m.sendmail_update = true end end -function Mail.MAIL_INBOX_UPDATE() - if Inbox_opening then +function TurtleMail.MAIL_INBOX_UPDATE() + if m.inbox_opening then m.inbox_update = true end - + for i = 1, 7 do - local index = (i + (api.InboxFrame.pageNum - 1) * 7) - if index <= api.GetInboxNumItems() then - local _, _, sender, _, _, _, _, _, _, wasReturned = api.GetInboxHeaderInfo( index ) + local index = (i + (m.api.InboxFrame.pageNum - 1) * 7) + if index <= m.api.GetInboxNumItems() then + local _, _, sender, _, _, _, _, _, _, was_returned = m.api.GetInboxHeaderInfo( index ) if INBOX_AUCTIONHOUSES[ sender ] then - api[ "TurtleMailAuctionIcon" .. i ]:Show() + m.api[ "TurtleMailAuctionIcon" .. i ]:Show() else - api[ "TurtleMailAuctionIcon" .. i ]:Hide() + m.api[ "TurtleMailAuctionIcon" .. i ]:Hide() end - if wasReturned then - api[ "TurtleMailReturnedArrow" .. i ]:Show() + if was_returned then + m.api[ "TurtleMailReturnedArrow" .. i ]:Show() else - api[ "TurtleMailReturnedArrow" .. i ]:Hide() + m.api[ "TurtleMailReturnedArrow" .. i ]:Hide() end end end end ---@param name string -function Mail.add_auto_complete_name( name ) - local key = api.GetCVar( "realmName" ) .. "|" .. api.UnitFactionGroup( "player" ) - api.TurtleMail_AutoCompleteNames[ key ][ name ] = api.GetTime() +function TurtleMail.add_auto_complete_name( name ) + local key = m.api.GetCVar( "realmName" ) .. "|" .. m.api.UnitFactionGroup( "player" ) + m.api.TurtleMail_AutoCompleteNames[ key ][ name ] = m.api.GetTime() end -function Mail.inbox_load() - local btn = api.CreateFrame( "Button", nil, api.InboxFrame, "UIPanelButtonTemplate" ) +function TurtleMail.inbox_load() + m.api.InboxFrame:EnableMouse( false ) + local btn = m.api.CreateFrame( "Button", "TurtleMailOpenMailButton", m.api.InboxFrame, "UIPanelButtonTemplate" ) btn:SetPoint( "BOTTOM", -10, 90 ) - btn:SetText( api.OPENMAIL ) + btn:SetText( m.api.OPENMAIL ) btn:SetWidth( math.max( 120, 30 + ({ btn:GetRegions() })[ 1 ]:GetStringWidth() ) ) btn:SetHeight( 25 ) - btn:SetScript( "OnClick", Inbox_OpenAll ) - - api.MailFrame:SetMovable( true ) - api.MailFrame:SetScript( "OnDragStop", m.on_drag_stop ) + btn:SetScript( "OnClick", m.inbox_open_all ) for i = 1, 7 do - api[ "TurtleMailAuctionIcon" .. i .. "Texture" ]:SetVertexColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b ) - api[ "TurtleMailReturnedArrow" .. i .. "Texture" ]:SetVertexColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b ) + m.api[ "TurtleMailAuctionIcon" .. i .. "Texture" ]:SetVertexColor( m.api.NORMAL_FONT_COLOR.r, m.api.NORMAL_FONT_COLOR.g, m.api.NORMAL_FONT_COLOR.b ) + m.api[ "TurtleMailReturnedArrow" .. i .. "Texture" ]:SetVertexColor( m.api.NORMAL_FONT_COLOR.r, m.api.NORMAL_FONT_COLOR.g, m.api.NORMAL_FONT_COLOR.b ) end end -function Inbox_OpenAll() - Inbox_opening = true - Inbox_UpdateLock() - Inbox_skip = false +function TurtleMail.inbox_open_all() + m.inbox_opening = true + m.inbox_update_lock() + m.inbox_skip = false m.inbox_index = 1 m.inbox_update = true end -function Inbox_Abort() - Inbox_opening = false - Inbox_UpdateLock() +function TurtleMail.inbox_abort() + m.inbox_opening = false + m.inbox_update_lock() m.inbox_update = false end -function Mail.set_cod_text() - local text = string.sub( api.COD_AMOUNT, 1, string.len( api.COD_AMOUNT ) - 1 ) +function TurtleMail.set_cod_text() + local text = string.sub( m.api.COD_AMOUNT, 1, string.len( m.api.COD_AMOUNT ) - 1 ) - ---@diagnostic disable-next-line: undefined-global - if not pfUI or not pfUI.version then + --if not m.api.pfUI or not m.api.pfUI.version then + if not m.pfui_skin_enabled then text = string.match( text, "^(.-)%s+%S+$" ) end - if api.SendMailCODAllButton:GetChecked() then - api.SendMailMoneyText:SetText( text .. " " .. L[ "each mail" ] .. ":" ) + if m.api.SendMailCODAllButton:GetChecked() then + m.api.SendMailMoneyText:SetText( text .. " " .. L[ "each mail" ] .. ":" ) else - api.SendMailMoneyText:SetText( text .. " " .. L[ "1st mail" ] .. ":" ) + m.api.SendMailMoneyText:SetText( text .. " " .. L[ "1st mail" ] .. ":" ) end end ---@param copper number -function Mail.format_money( copper ) +function TurtleMail.format_money( copper ) + if type( copper ) ~= "number" then return "-" end + local gold = math.floor( copper / 10000 ) local silver = math.floor( (copper - gold * 10000) / 100 ) local copper_remain = copper - (gold * 10000) - (silver * 100) @@ -266,163 +385,171 @@ function Mail.format_money( copper ) end ---@param money number -function Mail.update_money( money ) +function TurtleMail.update_money( money ) m.money_received = m.money_received + money - api.MoneyReceived:SetText( L[ "Money received" ] .. ": " .. m.format_money( m.money_received ) ) + m.api.MoneyReceived:SetText( L[ "Money received" ] .. ": " .. m.format_money( m.money_received ) ) if m.money_received > 0 then - api.MoneyReceived:Show() + m.api.MoneyReceived:Show() else - api.MoneyReceived:Hide() + m.api.MoneyReceived:Hide() end end -function Mail.on_drag_stop() - local f = api.MailFrame - if not f then return end - f:StopMovingOrSizing() - - local screen_width = api.GetScreenWidth() - local screen_height = api.GetScreenHeight() - local point, _, _, x, y = api.MailFrame:GetPoint() - local nx, ny = x, y - - if f:GetLeft() < -10 then nx = -10 end - if f:GetRight() > screen_width + 28 then nx = screen_width + 28 - f:GetWidth() end - if f:GetTop() > screen_height + 10 then ny = 10 end - if f:GetBottom() < -44 then ny = -screen_height + f:GetHeight() - 44 end - - if (nx ~= x or ny ~= y) then - api.MailFrame:SetPoint( point, nx, ny ) - end - - api.TurtleMail_Point = { point = point, x = nx, y = ny } +function TurtleMail.on_drag_stop() + this:StopMovingOrSizing() + local point, _, _, x, y = m.api.MailFrame:GetPoint() + m.api.TurtleMail_Point = { point = point, x = x, y = y } end -do - -- hack to prevent beancounter from deleting mail - local TakeInboxMoney, TakeInboxItem, DeleteInboxItem = api.TakeInboxMoney, api.TakeInboxItem, api.DeleteInboxItem - ---@param i number - ---@param manual boolean? - function Inbox_Open( i, manual ) - local _, _, _, _, money, _, _, _, read, _, _, _, _ = api.GetInboxHeaderInfo( i ) - if money and read or manual then +---@param i number +---@param manual boolean? +function TurtleMail.inbox_open( i, manual ) + m.debug( "inbox_open" ) + local package_icon, _, sender, subject, money, cod, _, has_item, read, returned, _, _, gm = m.api.GetInboxHeaderInfo( i ) + + if has_item then + if not m.received_icon then + m.received_item = m.api.GetInboxItem( i ) + m.received_icon = package_icon + end + end + + if (read and not has_item) or manual then + if money > 0 then m.update_money( money ) + m.received_money = money + end + if money == 0 or manual then + m.log.add( "Received", { + from = sender, + subject = subject, + money = manual and money or m.received_money, + cod = cod, + returned = returned, + gm = gm, + icon = m.received_icon, + item = m.received_item + } ) + m.received_money = 0 + m.received_icon = nil + m.received_item = nil end - api.GetInboxText( i ) - - TakeInboxMoney( i ) - TakeInboxItem( i ) - DeleteInboxItem( i ) end + + m.api.GetInboxText( i ) + m.TakeInboxMoney( i ) + m.TakeInboxItem( i ) + m.DeleteInboxItem( i ) end -function Inbox_UpdateLock() +function TurtleMail.inbox_update_lock() for i = 1, 7 do - api[ "MailItem" .. i .. "ButtonIcon" ]:SetDesaturated( Inbox_opening ) - if Inbox_opening then - api[ "MailItem" .. i .. "Button" ]:SetChecked( nil ) + m.api[ "MailItem" .. i .. "ButtonIcon" ]:SetDesaturated( m.inbox_opening ) + if m.inbox_opening then + m.api[ "MailItem" .. i .. "Button" ]:SetChecked( nil ) end end end -function Mail.hook.GetInboxHeaderInfo( ... ) +function TurtleMail.hook.GetInboxHeaderInfo( ... ) local sender, canReply = arg[ 3 ], arg[ 12 ] if sender and canReply then m.add_auto_complete_name( sender ) end + return m.orig.GetInboxHeaderInfo( unpack( arg ) ) end -function Mail.hook.OpenMail_Reply( ... ) - api.TurtleMail_To = nil +function TurtleMail.hook.OpenMail_Reply( ... ) + m.api.TurtleMail_To = nil return m.orig.OpenMail_Reply( unpack( arg ) ) end -function Mail.hook.InboxFrame_Update() +function TurtleMail.hook.InboxFrame_Update() m.orig.InboxFrame_Update() for i = 1, 7 do -- hack for tooltip update - api[ "MailItem" .. i ]:Hide() - api[ "MailItem" .. i ]:Show() + m.api[ "MailItem" .. i ]:Hide() + m.api[ "MailItem" .. i ]:Show() end - local currentPage = api.InboxFrame.pageNum - local totalPages = math.ceil( api.GetInboxNumItems() / api.INBOXITEMS_TO_DISPLAY ) - local text = totalPages > 0 and (currentPage .. "/" .. totalPages) or api.EMPTY - api.InboxTitleText:SetText( api.INBOX .. " [" .. text .. "]" ) + local currentPage = m.api.InboxFrame.pageNum + local totalPages = math.ceil( m.api.GetInboxNumItems() / m.api.INBOXITEMS_TO_DISPLAY ) + local text = totalPages > 0 and (currentPage .. "/" .. totalPages) or m.api.EMPTY + m.api.InboxTitleText:SetText( m.api.INBOX .. " [" .. text .. "]" ) - Inbox_UpdateLock() + m.inbox_update_lock() end -function Mail.hook.InboxFrame_OnClick( i ) - if Inbox_opening or arg1 == "RightButton" and ({ api.GetInboxHeaderInfo( i ) })[ 6 ] > 0 then +---@param i number +function TurtleMail.hook.InboxFrame_OnClick( i ) + if m.inbox_opening or arg1 == "RightButton" and ({ m.api.GetInboxHeaderInfo( i ) })[ 6 ] > 0 then this:SetChecked( nil ) elseif arg1 == "RightButton" then - Inbox_Open( i, true ) + m.inbox_open( i, true ) else return m.orig.InboxFrame_OnClick( i ) end end -function Mail.hook.InboxFrameItem_OnEnter() +function TurtleMail.hook.InboxFrameItem_OnEnter() m.orig.InboxFrameItem_OnEnter() - if api.GetInboxItem( this.index ) then - api.GameTooltip:AddLine( api.ITEM_OPENABLE, "", 0, 1, 0 ) - api.GameTooltip:Show() + if m.api.GetInboxItem( this.index ) then + m.api.GameTooltip:AddLine( m.api.ITEM_OPENABLE, "", 0, 1, 0 ) + m.api.GameTooltip:Show() end end -function Mail.hook.SendMailFrame_Update() +function TurtleMail.hook.SendMailFrame_Update() local gap - -- local last = 0 blizzlike - local last = SendMail_NumAttachments() + local last = m.sendmail_num_attachments() for i = 1, ATTACHMENTS_MAX do - local btn = api[ "MailAttachment" .. i ] + local btn = m.api[ "MailAttachment" .. i ] local texture, count if btn.item then - texture, count = api.GetContainerItemInfo( unpack( btn.item ) ) + texture, count = m.api.GetContainerItemInfo( unpack( btn.item ) ) end if not texture then btn:SetNormalTexture( nil ) - api[ btn:GetName() .. "Count" ]:Hide() + m.api[ btn:GetName() .. "Count" ]:Hide() btn.item = nil else btn:SetNormalTexture( texture ) if count > 1 then - api[ btn:GetName() .. "Count" ]:Show() - api[ btn:GetName() .. "Count" ]:SetText( count ) + m.api[ btn:GetName() .. "Count" ]:Show() + m.api[ btn:GetName() .. "Count" ]:SetText( count ) else - api[ btn:GetName() .. "Count" ]:Hide() + m.api[ btn:GetName() .. "Count" ]:Hide() end end end - if SendMail_NumAttachments() > 0 then - api.SendMailCODButton:Enable() - api.SendMailCODButtonText:SetTextColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b ) - if SendMail_NumAttachments() > 1 and api.SendMailCODButton:GetChecked() then - api.SendMailCODAllButton:Enable() - api.SendMailCODAllButtonText:SetTextColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b ) + if m.sendmail_num_attachments() > 0 then + m.api.SendMailCODButton:Enable() + m.api.SendMailCODButtonText:SetTextColor( m.api.NORMAL_FONT_COLOR.r, m.api.NORMAL_FONT_COLOR.g, m.api.NORMAL_FONT_COLOR.b ) + if m.sendmail_num_attachments() > 1 and m.api.SendMailCODButton:GetChecked() then + m.api.SendMailCODAllButton:Enable() + m.api.SendMailCODAllButtonText:SetTextColor( m.api.NORMAL_FONT_COLOR.r, m.api.NORMAL_FONT_COLOR.g, m.api.NORMAL_FONT_COLOR.b ) m.set_cod_text() else - api.SendMailCODAllButton:Disable() - api.SendMailCODAllButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b ) - api.SendMailMoneyText:SetText( api.AMOUNT_TO_SEND ) + m.api.SendMailCODAllButton:Disable() + m.api.SendMailCODAllButtonText:SetTextColor( m.api.GRAY_FONT_COLOR.r, m.api.GRAY_FONT_COLOR.g, m.api.GRAY_FONT_COLOR.b ) + m.api.SendMailMoneyText:SetText( m.api.AMOUNT_TO_SEND ) end else - api.SendMailSendMoneyButton:SetChecked( 1 ) - api.SendMailCODButton:SetChecked( nil ) - api.SendMailMoneyText:SetText( api.AMOUNT_TO_SEND ) - api.SendMailCODButton:Disable() - api.SendMailCODButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b ) - api.SendMailCODAllButton:Disable() - api.SendMailCODAllButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b ) + m.api.SendMailSendMoneyButton:SetChecked( 1 ) + m.api.SendMailCODButton:SetChecked( nil ) + m.api.SendMailMoneyText:SetText( m.api.AMOUNT_TO_SEND ) + m.api.SendMailCODButton:Disable() + m.api.SendMailCODButtonText:SetTextColor( m.api.GRAY_FONT_COLOR.r, m.api.GRAY_FONT_COLOR.g, m.api.GRAY_FONT_COLOR.b ) + m.api.SendMailCODAllButton:Disable() + m.api.SendMailCODAllButtonText:SetTextColor( m.api.GRAY_FONT_COLOR.r, m.api.GRAY_FONT_COLOR.g, m.api.GRAY_FONT_COLOR.b ) end - api.MoneyFrame_Update( "SendMailCostMoneyFrame", api.GetSendMailPrice() * math.max( 1, SendMail_NumAttachments() ) ) + m.api.MoneyFrame_Update( "SendMailCostMoneyFrame", m.api.GetSendMailPrice() * math.max( 1, m.sendmail_num_attachments() ) ) -- Determine how many rows of attachments to show local itemRowCount = 1 @@ -435,10 +562,10 @@ function Mail.hook.SendMailFrame_Update() if not gap and temp == ATTACHMENTS_PER_ROW_SEND and itemRowCount < ATTACHMENTS_MAX_ROWS_SEND then itemRowCount = itemRowCount + 1 end - if api.SendMailFrame.maxRowsShown and last > 0 and itemRowCount < api.SendMailFrame.maxRowsShown then - itemRowCount = api.SendMailFrame.maxRowsShown + if m.api.SendMailFrame.maxRowsShown and last > 0 and itemRowCount < m.api.SendMailFrame.maxRowsShown then + itemRowCount = m.api.SendMailFrame.maxRowsShown else - api.SendMailFrame.maxRowsShown = itemRowCount + m.api.SendMailFrame.maxRowsShown = itemRowCount end -- Compute sizes @@ -446,11 +573,11 @@ function Mail.hook.SendMailFrame_Update() local cursory = itemRowCount - 1 local marginxl = 8 + 6 local marginxr = 40 + 6 - local areax = api.SendMailFrame:GetWidth() - marginxl - marginxr - local iconx = api.MailAttachment1:GetWidth() + 2 - local icony = api.MailAttachment1:GetHeight() + 2 - local gapx1 = api.floor( (areax - (iconx * ATTACHMENTS_PER_ROW_SEND)) / (ATTACHMENTS_PER_ROW_SEND - 1) ) - local gapx2 = api.floor( (areax - (iconx * ATTACHMENTS_PER_ROW_SEND) - (gapx1 * (ATTACHMENTS_PER_ROW_SEND - 1))) / 2 ) + local areax = m.api.SendMailFrame:GetWidth() - marginxl - marginxr + local iconx = m.api.MailAttachment1:GetWidth() + 2 + local icony = m.api.MailAttachment1:GetHeight() + 2 + local gapx1 = m.api.floor( (areax - (iconx * ATTACHMENTS_PER_ROW_SEND)) / (ATTACHMENTS_PER_ROW_SEND - 1) ) + local gapx2 = m.api.floor( (areax - (iconx * ATTACHMENTS_PER_ROW_SEND) - (gapx1 * (ATTACHMENTS_PER_ROW_SEND - 1))) / 2 ) local gapy1 = 5 local gapy2 = 6 local areay = (gapy2 * 2) + (gapy1 * (itemRowCount - 1)) + (icony * itemRowCount) @@ -460,28 +587,28 @@ function Mail.hook.SendMailFrame_Update() local taby = (icony + gapy1) local scrollHeight = 249 - areay - api.MailHorizontalBarLeft:SetPoint( "TOPLEFT", api.SendMailFrame, "BOTTOMLEFT", 2 + 15, 184 + areay - 14 ) + m.api.MailHorizontalBarLeft:SetPoint( "TOPLEFT", m.api.SendMailFrame, "BOTTOMLEFT", 2 + 15, 184 + areay - 14 ) - api.SendMailScrollFrame:SetHeight( scrollHeight ) - api.SendMailScrollChildFrame:SetHeight( scrollHeight ) + m.api.SendMailScrollFrame:SetHeight( scrollHeight ) + m.api.SendMailScrollChildFrame:SetHeight( scrollHeight ) - local SendMailScrollFrameTop = ({ api.SendMailScrollFrame:GetRegions() })[ 3 ] + local SendMailScrollFrameTop = ({ m.api.SendMailScrollFrame:GetRegions() })[ 3 ] SendMailScrollFrameTop:SetHeight( scrollHeight ) SendMailScrollFrameTop:SetTexCoord( 0, .484375, 0, scrollHeight / 256 ) - api.StationeryBackgroundLeft:SetHeight( scrollHeight ) - api.StationeryBackgroundLeft:SetTexCoord( 0, 1, 0, scrollHeight / 256 ) + m.api.StationeryBackgroundLeft:SetHeight( scrollHeight ) + m.api.StationeryBackgroundLeft:SetTexCoord( 0, 1, 0, scrollHeight / 256 ) - api.StationeryBackgroundRight:SetHeight( scrollHeight ) - api.StationeryBackgroundRight:SetTexCoord( 0, 1, 0, scrollHeight / 256 ) + m.api.StationeryBackgroundRight:SetHeight( scrollHeight ) + m.api.StationeryBackgroundRight:SetTexCoord( 0, 1, 0, scrollHeight / 256 ) -- Set Items for i = 1, ATTACHMENTS_MAX do if cursory >= 0 then - api[ "MailAttachment" .. i ]:Enable() - api[ "MailAttachment" .. i ]:Show() - api[ "MailAttachment" .. i ]:SetPoint( "TOPLEFT", "SendMailFrame", "BOTTOMLEFT", indentx + (tabx * cursorx), + m.api[ "MailAttachment" .. i ]:Enable() + m.api[ "MailAttachment" .. i ]:Show() + m.api[ "MailAttachment" .. i ]:SetPoint( "TOPLEFT", "SendMailFrame", "BOTTOMLEFT", indentx + (tabx * cursorx), indenty + (taby * cursory) ) cursorx = cursorx + 1 @@ -490,67 +617,67 @@ function Mail.hook.SendMailFrame_Update() cursorx = 0 end else - api[ "MailAttachment" .. i ]:Hide() + m.api[ "MailAttachment" .. i ]:Hide() end end - api.SendMailFrame_CanSend() + m.api.SendMailFrame_CanSend() end -function Mail.hook.SendMailRadioButton_OnClick( index ) +function TurtleMail.hook.SendMailRadioButton_OnClick( index ) if (index == 1) then - api.SendMailSendMoneyButton:SetChecked( 1 ); - api.SendMailCODButton:SetChecked( nil ); - api.SendMailMoneyText:SetText( api.AMOUNT_TO_SEND ); - api.SendMailCODAllButton:Disable() - api.SendMailCODAllButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b ) + m.api.SendMailSendMoneyButton:SetChecked( 1 ); + m.api.SendMailCODButton:SetChecked( nil ); + m.api.SendMailMoneyText:SetText( m.api.AMOUNT_TO_SEND ); + m.api.SendMailCODAllButton:Disable() + m.api.SendMailCODAllButtonText:SetTextColor( m.api.GRAY_FONT_COLOR.r, m.api.GRAY_FONT_COLOR.g, m.api.GRAY_FONT_COLOR.b ) else - api.SendMailSendMoneyButton:SetChecked( nil ); - api.SendMailCODButton:SetChecked( 1 ); - api.SendMailMoneyText:SetText( api.COD_AMOUNT ); + m.api.SendMailSendMoneyButton:SetChecked( nil ); + m.api.SendMailCODButton:SetChecked( 1 ); + m.api.SendMailMoneyText:SetText( m.api.COD_AMOUNT ); - if SendMail_NumAttachments() > 1 then - api.SendMailCODAllButton:Enable() - api.SendMailCODAllButtonText:SetTextColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b ) + if m.sendmail_num_attachments() > 1 then + m.api.SendMailCODAllButton:Enable() + m.api.SendMailCODAllButtonText:SetTextColor( m.api.NORMAL_FONT_COLOR.r, m.api.NORMAL_FONT_COLOR.g, m.api.NORMAL_FONT_COLOR.b ) m.set_cod_text() end end - api.PlaySound( "igMainMenuOptionCheckBoxOn" ); + m.api.PlaySound( "igMainMenuOptionCheckBoxOn" ); end -function Mail.hook.ClickSendMailItemButton() - SendMail_SetAttachment( m.get_cursor_item() ) +function TurtleMail.hook.ClickSendMailItemButton() + m.sendmail_set_attachment( m.get_cursor_item() ) end -function Mail.hook.GetContainerItemInfo( bag, slot ) +function TurtleMail.hook.GetContainerItemInfo( bag, slot ) local ret = pack( m.orig.GetContainerItemInfo( bag, slot ) ) - ret[ 3 ] = ret[ 3 ] or SendMail_Attached( bag, slot ) and 1 or nil + ret[ 3 ] = ret[ 3 ] or m.sendmail_attached( bag, slot ) and 1 or nil return unpack( ret ) end -function Mail.hook.PickupContainerItem( bag, slot ) - if SendMail_Attached( bag, slot ) then return end - if api.GetContainerItemInfo( bag, slot ) then m.set_cursor_item( { bag, slot } ) end +function TurtleMail.hook.PickupContainerItem( bag, slot ) + if m.sendmail_attached( bag, slot ) then return end + if m.api.GetContainerItemInfo( bag, slot ) then m.set_cursor_item( { bag, slot } ) end return m.orig.PickupContainerItem( bag, slot ) end -function Mail.hook.SplitContainerItem( bag, slot, amount ) - if SendMail_Attached( bag, slot ) then return end +function TurtleMail.hook.SplitContainerItem( bag, slot, amount ) + if m.sendmail_attached( bag, slot ) then return end return m.orig.SplitContainerItem( bag, slot, amount ) end -function Mail.hook.UseContainerItem( bag, slot, onself ) - if SendMail_Attached( bag, slot ) then return end - if api.IsShiftKeyDown() or api.IsControlKeyDown() or api.IsAltKeyDown() then +function TurtleMail.hook.UseContainerItem( bag, slot, onself ) + if m.sendmail_attached( bag, slot ) then return end + if m.api.IsShiftKeyDown() or m.api.IsControlKeyDown() or m.api.IsAltKeyDown() then return m.orig.UseContainerItem( bag, slot, onself ) - elseif api.MailFrame:IsVisible() then - api.MailFrameTab_OnClick( 2 ) - SendMail_SetAttachment { bag, slot } - elseif api.TradeFrame:IsVisible() then + elseif m.api.MailFrame:IsVisible() then + m.api.MailFrameTab_OnClick( 2 ) + m.sendmail_set_attachment( { bag, slot } ) + elseif m.api.TradeFrame:IsVisible() then for i = 1, 6 do - if not api.GetTradePlayerItemLink( i ) then + if not m.api.GetTradePlayerItemLink( i ) then m.orig.PickupContainerItem( bag, slot ) - api.ClickTradeButton( i ) + m.api.ClickTradeButton( i ) return end end @@ -559,87 +686,122 @@ function Mail.hook.UseContainerItem( bag, slot, onself ) end end -function Mail.hook.SendMailFrame_CanSend() - if not SendMail_sending and string.len( api.SendMailNameEditBox:GetText() ) > 0 and (api.SendMailSendMoneyButton:GetChecked() and api.MoneyInputFrame_GetCopper( api.SendMailMoney ) or 0) + api.GetSendMailPrice() * math.max( 1, SendMail_NumAttachments() ) <= api.GetMoney() then +function TurtleMail.hook.SendMailFrame_CanSend() + if not m.sendmail_sending and string.len( m.api.SendMailNameEditBox:GetText() ) > 0 and (m.api.SendMailSendMoneyButton:GetChecked() and m.api.MoneyInputFrame_GetCopper( m.api.SendMailMoney ) or 0) + m.api.GetSendMailPrice() * math.max( 1, m.sendmail_num_attachments() ) <= m.api.GetMoney() then MailMailButton:Enable() else MailMailButton:Disable() end end -function MailMailButton_OnClick() - api.MailAutoCompleteBox:Hide() +function TurtleMail.hook.MailFrameTab_OnClick( tab ) + if not tab then + tab = this:GetID() + end - api.TurtleMail_To = api.SendMailNameEditBox:GetText() - api.SendMailNameEditBox:HighlightText() + if tab == 3 then + m.api.PanelTemplates_SetTab( m.api.MailFrame, 3 ) + m.api.InboxFrame:Hide() + m.api.SendMailFrame:Hide() + m.api.TurtleMailLogFrame:Show() + m.api.MailFrameTopLeft:SetTexture( "Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopLeft" ) + m.api.MailFrameTopRight:SetTexture( "Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopRight" ) + m.api.MailFrameBotLeft:SetTexture( "Interface\\ClassTrainerFrame\\UI-ClassTrainer-BotLeft" ) + m.api.MailFrameBotRight:SetTexture( "Interface\\ClassTrainerFrame\\UI-ClassTrainer-BotRight" ) + m.api.MailFrameTopLeft:SetPoint( "TOPLEFT", "MailFrame", "TOPLEFT", 2, -1 ) + m.log.populate( "Received" ) + return + else + m.api.TurtleMailLogFrame:Hide() + end - SendMail_state = { - to = api.TurtleMail_To, - subject = MailSubjectEditBox:GetText(), - body = api.SendMailBodyEditBox:GetText(), - money = api.MoneyInputFrame_GetCopper( api.SendMailMoney ), - cod = api.SendMailCODButton:GetChecked(), - attachments = SendMail_Attachments(), - numMessages = math.max( 1, SendMail_NumAttachments() ), - } - - SendMail_Clear() - SendMail_sending = true - SendMail_Send() + m.orig.MailFrameTab_OnClick( tab ) end -function Mail.sendmail_load() - api.SendMailFrame:EnableMouse( false ) - api.SendMailFrame:CreateTexture( "MailHorizontalBarLeft", "BACKGROUND" ) - api.SendMailFrame:CreateTexture( "MailHorizontalBarRight", "BACKGROUND" ) - ---@diagnostic disable-next-line: undefined-global - if not pfUI or not pfUI.version then - api.MailHorizontalBarLeft:SetTexture( [[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]] ) - api.MailHorizontalBarLeft:SetWidth( 256 ) - api.MailHorizontalBarLeft:SetHeight( 16 ) - api.MailHorizontalBarLeft:SetTexCoord( 0, 1, 0, .25 ) - - api.MailHorizontalBarRight:SetTexture( [[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]] ) - api.MailHorizontalBarRight:SetWidth( 75 ) - api.MailHorizontalBarRight:SetHeight( 16 ) - api.MailHorizontalBarRight:SetTexCoord( 0, .29296875, .25, .5 ) - api.MailHorizontalBarRight:SetPoint( "LEFT", api.MailHorizontalBarLeft, "RIGHT" ) +function TurtleMail.hook.OpenMailFrame_OnHide() + if m.api.InboxFrame.openMailID then + local package_icon, _, sender, subject, money, cod, _, itemID, _, returned, text_created, _, gm = m.api.GetInboxHeaderInfo( m.api.InboxFrame.openMailID ) + if (money == 0 and not itemID and text_created) then + local received_item = m.api.GetInboxItem( m.api.InboxFrame.openMailID ) + m.log.add( "Received", { + from = sender, + subject = subject, + money = money, + cod = cod, + returned = returned, + gm = gm, + icon = package_icon, + item = received_item + } ) + end + else + m.debug( "returning mail" ) end - do - local background = ({ api.SendMailPackageButton:GetRegions() })[ 1 ] - background:Hide() - local count = ({ api.SendMailPackageButton:GetRegions() })[ 3 ] - count:Hide() - api.SendMailPackageButton:Disable() - api.SendMailPackageButton:SetScript( "OnReceiveDrag", nil ) - api.SendMailPackageButton:SetScript( "OnDragStart", nil ) - end + m.orig.OpenMailFrame_OnHide() +end - api.SendMailMoneyText:SetJustifyH( "LEFT" ) - api.SendMailMoneyText:SetPoint( "TOPLEFT", 0, 0 ) - api.SendMailMoney:ClearAllPoints() - api.SendMailMoney:SetPoint( "TOPLEFT", api.SendMailMoneyText, "BOTTOMLEFT", 5, -5 ) - api.SendMailMoneyGoldRight:SetPoint( "RIGHT", 20, 0 ) - do ({ api.SendMailMoneyGold:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end - api.SendMailMoneyGold:SetMaxLetters( 7 ) - api.SendMailMoneyGold:SetWidth( 50 ) - api.SendMailMoneySilverRight:SetPoint( "RIGHT", 10, 0 ) - do ({ api.SendMailMoneySilver:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end - api.SendMailMoneySilver:SetWidth( 28 ) - api.SendMailMoneySilver:SetPoint( "LEFT", api.SendMailMoneyGold, "RIGHT", 30, 0 ) - api.SendMailMoneyCopperRight:SetPoint( "RIGHT", 10, 0 ) - do ({ api.SendMailMoneyCopper:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end - api.SendMailMoneyCopper:SetWidth( 28 ) - api.SendMailMoneyCopper:SetPoint( "LEFT", api.SendMailMoneySilver, "RIGHT", 20, 0 ) - api.SendMailSendMoneyButton:SetPoint( "TOPLEFT", api.SendMailMoney, "TOPRIGHT", 0, 12 ) +function TurtleMail.send_mail_button_onclick() + m.api.MailAutoCompleteBox:Hide() + + m.api.TurtleMail_To = m.api.SendMailNameEditBox:GetText() + m.api.SendMailNameEditBox:HighlightText() + + m.sendmail_state = { + to = m.api.TurtleMail_To, + subject = MailSubjectEditBox:GetText(), + body = m.api.SendMailBodyEditBox:GetText(), + money = m.api.MoneyInputFrame_GetCopper( m.api.SendMailMoney ), + cod = m.api.SendMailCODButton:GetChecked(), + attachments = m.sendmail_attachments(), + numMessages = math.max( 1, m.sendmail_num_attachments() ), + } + + m.sendmail_clear() + m.sendmail_sending = true + m.sendmail_send() +end + +function TurtleMail.sendmail_load() + m.api.SendMailFrame:EnableMouse( false ) + + m.api.SendMailFrame:CreateTexture( "MailHorizontalBarLeft", "BACKGROUND" ) + m.api.MailHorizontalBarLeft:SetTexture( "Interface\\ClassTrainerFrame\\UI-ClassTrainer-HorizontalBar" ) + m.api.MailHorizontalBarLeft:SetWidth( 256 ) + m.api.MailHorizontalBarLeft:SetHeight( 16 ) + m.api.MailHorizontalBarLeft:SetTexCoord( 0, 1, 0, .25 ) + + m.api.SendMailFrame:CreateTexture( "MailHorizontalBarRight", "BACKGROUND" ) + m.api.MailHorizontalBarRight:SetTexture( "Interface\\ClassTrainerFrame\\UI-ClassTrainer-HorizontalBar" ) + m.api.MailHorizontalBarRight:SetWidth( 75 ) + m.api.MailHorizontalBarRight:SetHeight( 16 ) + m.api.MailHorizontalBarRight:SetTexCoord( 0, .29296875, .25, .5 ) + m.api.MailHorizontalBarRight:SetPoint( "LEFT", m.api.MailHorizontalBarLeft, "RIGHT" ) + + m.api.SendMailMoneyText:SetJustifyH( "LEFT" ) + m.api.SendMailMoneyText:SetPoint( "TOPLEFT", 0, 0 ) + m.api.SendMailMoney:ClearAllPoints() + m.api.SendMailMoney:SetPoint( "TOPLEFT", m.api.SendMailMoneyText, "BOTTOMLEFT", 5, -5 ) + m.api.SendMailMoneyGoldRight:SetPoint( "RIGHT", 20, 0 ) + do ({ m.api.SendMailMoneyGold:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end + m.api.SendMailMoneyGold:SetMaxLetters( 7 ) + m.api.SendMailMoneyGold:SetWidth( 50 ) + m.api.SendMailMoneySilverRight:SetPoint( "RIGHT", 10, 0 ) + do ({ m.api.SendMailMoneySilver:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end + m.api.SendMailMoneySilver:SetWidth( 28 ) + m.api.SendMailMoneySilver:SetPoint( "LEFT", m.api.SendMailMoneyGold, "RIGHT", 30, 0 ) + m.api.SendMailMoneyCopperRight:SetPoint( "RIGHT", 10, 0 ) + do ({ m.api.SendMailMoneyCopper:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end + m.api.SendMailMoneyCopper:SetWidth( 28 ) + m.api.SendMailMoneyCopper:SetPoint( "LEFT", m.api.SendMailMoneySilver, "RIGHT", 20, 0 ) + m.api.SendMailSendMoneyButton:SetPoint( "TOPLEFT", m.api.SendMailMoney, "TOPRIGHT", 0, 12 ) -- hack to avoid automatic subject setting and button disabling from weird blizzard code - MailMailButton = api.SendMailMailButton - api.SendMailMailButton = setmetatable( {}, { __index = function() return function() end end } ) - api.SendMailMailButton_OnClick = MailMailButton_OnClick - MailSubjectEditBox = api.SendMailSubjectEditBox - api.SendMailSubjectEditBox = setmetatable( {}, { + MailMailButton = m.api.SendMailMailButton + m.api.SendMailMailButton = setmetatable( {}, { __index = function() return function() end end } ) + m.api.SendMailMailButton_OnClick = m.send_mail_button_onclick + MailSubjectEditBox = m.api.SendMailSubjectEditBox + m.api.SendMailSubjectEditBox = setmetatable( {}, { __index = function( _, key ) return function( _, ... ) return MailSubjectEditBox[ key ]( MailSubjectEditBox, unpack( arg ) ) @@ -647,58 +809,58 @@ function Mail.sendmail_load() end, } ) - api.SendMailNameEditBox._SetText = api.SendMailNameEditBox.SetText - function api.SendMailNameEditBox:SetText( ... ) - if not api.TurtleMail_To then + m.api.SendMailNameEditBox._SetText = m.api.SendMailNameEditBox.SetText + function m.api.SendMailNameEditBox:SetText( ... ) + if not m.api.TurtleMail_To then return self:_SetText( unpack( arg ) ) end end - api.SendMailNameEditBox:SetScript( "OnShow", function() - if api.TurtleMail_To then - api.this:_SetText( api.TurtleMail_To ) + m.api.SendMailNameEditBox:SetScript( "OnShow", function() + if m.api.TurtleMail_To then + m.api.this:_SetText( m.api.TurtleMail_To ) end end ) - api.SendMailNameEditBox:SetScript( "OnChar", function() - api.TurtleMail_To = nil + m.api.SendMailNameEditBox:SetScript( "OnChar", function() + m.api.TurtleMail_To = nil GetSuggestions() end ) - api.SendMailNameEditBox:SetScript( "OnTabPressed", function() - if api.MailAutoCompleteBox:IsVisible() then - if api.IsShiftKeyDown() then - PreviousMatch() + m.api.SendMailNameEditBox:SetScript( "OnTabPressed", function() + if m.api.MailAutoCompleteBox:IsVisible() then + if m.api.IsShiftKeyDown() then + m.previous_match() else - NextMatch() + m.next_match() end else MailSubjectEditBox:SetFocus() end end ) - api.SendMailNameEditBox:SetScript( "OnEnterPressed", function() - if api.MailAutoCompleteBox:IsVisible() then - api.MailAutoCompleteBox:Hide() + m.api.SendMailNameEditBox:SetScript( "OnEnterPressed", function() + if m.api.MailAutoCompleteBox:IsVisible() then + m.api.MailAutoCompleteBox:Hide() this:HighlightText( 0, 0 ) else MailSubjectEditBox:SetFocus() end end ) - api.SendMailNameEditBox:SetScript( "OnEscapePressed", function() - if api.MailAutoCompleteBox:IsVisible() then - api.MailAutoCompleteBox:Hide() + m.api.SendMailNameEditBox:SetScript( "OnEscapePressed", function() + if m.api.MailAutoCompleteBox:IsVisible() then + m.api.MailAutoCompleteBox:Hide() else this:ClearFocus() end end ) - function api.SendMailNameEditBox.focusLoss() - api.MailAutoCompleteBox:Hide() + function m.api.SendMailNameEditBox.focusLoss() + m.api.MailAutoCompleteBox:Hide() end - api.SendMailCODAllButtonText:SetText( " " .. L[ "All mails" ] ) - api.SendMailCODAllButton:SetScript( "OnClick", m.set_cod_text ) + m.api.SendMailCODAllButtonText:SetText( " " .. L[ "All mails" ] ) + m.api.SendMailCODAllButton:SetScript( "OnClick", m.set_cod_text ) do - local orig_script = api.SendMailNameEditBox:GetScript( "OnTextChanged" ) - api.SendMailNameEditBox:SetScript( "OnTextChanged", function() + local orig_script = m.api.SendMailNameEditBox:GetScript( "OnTextChanged" ) + m.api.SendMailNameEditBox:SetScript( "OnTextChanged", function() local text = this:GetText() local formatted = string.gsub( string.lower( text ), "^%l", string.upper ) if text ~= formatted then @@ -708,7 +870,7 @@ function Mail.sendmail_load() end ) end - for _, editBox in { api.SendMailNameEditBox, api.SendMailSubjectEditBox } do + for _, editBox in { m.api.SendMailNameEditBox, m.api.SendMailSubjectEditBox } do editBox:SetScript( "OnEditFocusGained", function() this:HighlightText() end ) @@ -719,29 +881,31 @@ function Mail.sendmail_load() do local lastClick editBox:SetScript( "OnMouseDown", function() - local x, y = api.GetCursorPosition() - if lastClick and api.GetTime() - lastClick.t < .5 and x == lastClick.x and y == lastClick.y then + local x, y = m.api.GetCursorPosition() + if lastClick and m.api.GetTime() - lastClick.t < .5 and x == lastClick.x and y == lastClick.y then this:SetScript( "OnUpdate", function() this:HighlightText() this:SetScript( "OnUpdate", nil ) end ) end - lastClick = { t = api.GetTime(), x = x, y = y } + lastClick = { t = m.api.GetTime(), x = x, y = y } end ) end end end -function SendMail_Attached( bag, slot ) - if not api.MailFrame:IsVisible() then return false end +--@param bag number +--@param slot number +function TurtleMail.sendmail_attached( bag, slot ) + if not m.api.MailFrame:IsVisible() then return false end for i = 1, ATTACHMENTS_MAX do - local btn = api[ "MailAttachment" .. i ] + local btn = m.api[ "MailAttachment" .. i ] if btn.item and btn.item[ 1 ] == bag and btn.item[ 2 ] == slot then return true end end - if SendMail_state then - for _, attachment in SendMail_state.attachments do + if m.sendmail_state then + for _, attachment in m.sendmail_state.attachments do if attachment[ 1 ] == bag and attachment[ 2 ] == slot then return true end @@ -749,27 +913,29 @@ function SendMail_Attached( bag, slot ) end end -function Mail.AttachmentButton_OnClick() +function TurtleMail.attachment_button_on_click() local attachedItem = this.item local cursorItem = m.get_cursor_item() - if SendMail_SetAttachment( cursorItem, this ) then + if m.sendmail_set_attachment( cursorItem, this ) then if attachedItem then if arg1 == "LeftButton" then m.set_cursor_item( attachedItem ) end m.orig.PickupContainerItem( unpack( attachedItem ) ) - if arg1 ~= "LeftButton" then api.ClearCursor() end -- for the lock changed event + if arg1 ~= "LeftButton" then m.api.ClearCursor() end -- for the lock changed event end end end -- requires an item lock changed event for a proper update -function SendMail_SetAttachment( item, slot ) - if item and not SendMail_PickupMailable( item ) then - api.ClearCursor() +---@param item table +---@param slot number? +function TurtleMail.sendmail_set_attachment( item, slot ) + if item and not m.sendmail_pickup_mailable( item ) then + m.api.ClearCursor() return elseif not slot then for i = 1, ATTACHMENTS_MAX do - if not api[ "MailAttachment" .. i ].item then - slot = api[ "MailAttachment" .. i ] + if not m.api[ "MailAttachment" .. i ].item then + slot = m.api[ "MailAttachment" .. i ] break end end @@ -777,37 +943,38 @@ function SendMail_SetAttachment( item, slot ) if slot then if not (item or slot.item) then return true end slot.item = item - api.ClearCursor() - api.SendMailFrame_Update() + m.api.ClearCursor() + m.api.SendMailFrame_Update() return true end end -function SendMail_PickupMailable( item ) - api.ClearCursor() +---@param item table +function TurtleMail.sendmail_pickup_mailable( item ) + m.api.ClearCursor() m.orig.ClickSendMailItemButton() - api.ClearCursor() + m.api.ClearCursor() m.orig.PickupContainerItem( unpack( item ) ) m.orig.ClickSendMailItemButton() - local mailable = api.GetSendMailItem() and true or false + local mailable = m.api.GetSendMailItem() and true or false m.orig.ClickSendMailItemButton() return mailable end -function SendMail_NumAttachments() +function TurtleMail.sendmail_num_attachments() local x = 0 for i = 1, ATTACHMENTS_MAX do - if api[ "MailAttachment" .. i ].item then + if m.api[ "MailAttachment" .. i ].item then x = x + 1 end end return x end -function SendMail_Attachments() +function TurtleMail.sendmail_attachments() local t = {} for i = 1, ATTACHMENTS_MAX do - local btn = api[ "MailAttachment" .. i ] + local btn = m.api[ "MailAttachment" .. i ] if btn.item then table.insert( t, btn.item ) end @@ -815,74 +982,80 @@ function SendMail_Attachments() return t end -function SendMail_Clear() +function TurtleMail.sendmail_clear() local anyItem for i = 1, ATTACHMENTS_MAX do - anyItem = anyItem or api[ "MailAttachment" .. i ].item - api[ "MailAttachment" .. i ].item = nil + anyItem = anyItem or m.api[ "MailAttachment" .. i ].item + m.api[ "MailAttachment" .. i ].item = nil end if anyItem then - api.ClearCursor() - api.PickupContainerItem( unpack( anyItem ) ) - api.ClearCursor() + m.api.ClearCursor() + m.api.PickupContainerItem( unpack( anyItem ) ) + m.api.ClearCursor() end MailMailButton:Disable() - api.SendMailNameEditBox:SetText "" - api.SendMailNameEditBox:SetFocus() + m.api.SendMailNameEditBox:SetText "" + m.api.SendMailNameEditBox:SetFocus() MailSubjectEditBox:SetText "" - api.SendMailBodyEditBox:SetText "" - api.MoneyInputFrame_ResetMoney( api.SendMailMoney ) - api.SendMailRadioButton_OnClick( 1 ) + m.api.SendMailBodyEditBox:SetText "" + m.api.MoneyInputFrame_ResetMoney( m.api.SendMailMoney ) + m.api.SendMailRadioButton_OnClick( 1 ) - api.SendMailFrame_Update() + m.api.SendMailFrame_Update() end -function SendMail_Send() - local item = table.remove( SendMail_state.attachments, 1 ) +function TurtleMail.sendmail_send() + local item = table.remove( m.sendmail_state.attachments, 1 ) if item then - api.ClearCursor() + m.api.ClearCursor() m.orig.ClickSendMailItemButton() - api.ClearCursor() + m.api.ClearCursor() m.orig.PickupContainerItem( unpack( item ) ) m.orig.ClickSendMailItemButton() - if not api.GetSendMailItem() then - api.DEFAULT_CHAT_FRAME:AddMessage( "|cffabd473TurtleMail|r: " .. api.ERROR_CAPS, 1, 0, 0 ) + if not m.api.GetSendMailItem() then + m.api.DEFAULT_CHAT_FRAME:AddMessage( "|cffabd473TurtleMail|r: " .. m.api.ERROR_CAPS, 1, 0, 0 ) return end end - local amount = SendMail_state.money + local amount = m.sendmail_state.money + m.sendmail_state.sent_money = m.sendmail_state.money + if amount > 0 then - if not api.SendMailCODAllButton:GetChecked() then - SendMail_state.money = 0 + if not m.api.SendMailCODAllButton:GetChecked() then + m.sendmail_state.money = 0 end - if SendMail_state.cod then - api.SetSendMailCOD( amount ) + if m.sendmail_state.cod then + m.api.SetSendMailCOD( amount ) else - SendMail_state.money = 0 - api.SetSendMailMoney( amount ) + m.sendmail_state.money = 0 + m.api.SetSendMailMoney( amount ) end end - local subject = SendMail_state.subject + local subject = m.sendmail_state.subject if subject == "" then if item then - local itemName, itemTexture, stackCount, quality = api.GetSendMailItem() - subject = itemName .. (stackCount > 1 and " (" .. stackCount .. ")" or "") + local item_name, texture, stack_count = m.api.GetSendMailItem() + subject = item_name .. (stack_count > 1 and " (" .. stack_count .. ")" or "") + m.sendmail_state.item = item_name + m.sendmail_state.icon = texture else - subject = "<" .. api.NO_ATTACHMENTS .. ">" + subject = "<" .. m.api.NO_ATTACHMENTS .. ">" end - elseif SendMail_state.numMessages > 1 then - subject = subject .. - string.format( " [%d/%d]", SendMail_state.numMessages - getn( SendMail_state.attachments ), - SendMail_state.numMessages ) + elseif m.sendmail_state.numMessages > 1 then + subject = subject .. string.format( " [%d/%d]", m.sendmail_state.numMessages - getn( m.sendmail_state.attachments ), + m.sendmail_state.numMessages ) end - api.SendMail( SendMail_state.to, subject, SendMail_state.body ) + m.sendmail_state.sent_subject = subject - if getn( SendMail_state.attachments ) == 0 then - SendMail_sending = false + m.debug( "SendMail" ) + m.api.SendMail( m.sendmail_state.to, subject, m.sendmail_state.body ) + + if getn( m.sendmail_state.attachments ) == 0 then + m.sendmail_sending = false end end @@ -892,10 +1065,10 @@ do local index local function complete() - api.SendMailNameEditBox:SetText( matches[ index ] ) - api.SendMailNameEditBox:HighlightText( inputLength, -1 ) - for i = 1, api.MAIL_AUTOCOMPLETE_MAX_BUTTONS do - local button = api[ "MailAutoCompleteButton" .. i ] + m.api.SendMailNameEditBox:SetText( matches[ index ] ) + m.api.SendMailNameEditBox:HighlightText( inputLength, -1 ) + for i = 1, m.api.MAIL_AUTOCOMPLETE_MAX_BUTTONS do + local button = m.api[ "MailAutoCompleteButton" .. i ] if i == index then button:LockHighlight() else @@ -904,14 +1077,14 @@ do end end - function PreviousMatch() + function TurtleMail.previous_match() if index then index = index > 1 and index - 1 or getn( matches ) complete() end end - function NextMatch() + function TurtleMail.next_match() if index then ---@diagnostic disable-next-line: undefined-global index = mod( index, getn( matches ) ) + 1 @@ -919,15 +1092,15 @@ do end end - function Mail.SelectMatch( i ) + function TurtleMail.select_match( i ) index = i complete() - api.MailAutoCompleteBox:Hide() - api.SendMailNameEditBox:HighlightText( 0, 0 ) + m.api.MailAutoCompleteBox:Hide() + m.api.SendMailNameEditBox:HighlightText( 0, 0 ) end function GetSuggestions() - local input = api.SendMailNameEditBox:GetText() + local input = m.api.SendMailNameEditBox:GetText() inputLength = string.len( input ) ---@diagnostic disable-next-line: undefined-field @@ -935,12 +1108,12 @@ do index = nil local autoCompleteNames = {} - for name, time in api.TurtleMail_AutoCompleteNames[ api.GetCVar "realmName" .. "|" .. api.UnitFactionGroup "player" ] do + for name, time in m.api.TurtleMail_AutoCompleteNames[ m.api.GetCVar "realmName" .. "|" .. m.api.UnitFactionGroup "player" ] do table.insert( autoCompleteNames, { name = name, time = time } ) end table.sort( autoCompleteNames, function( a, b ) return b.time < a.time end ) - local ignore = { [ api.UnitName "player" ] = true } + local ignore = { [ m.api.UnitName "player" ] = true } local function process( name ) if name then if not ignore[ name ] and string.find( string.upper( name ), string.upper( input ), nil, true ) == 1 then @@ -952,18 +1125,18 @@ do for _, t in autoCompleteNames do process( t.name ) end - for i = 1, api.GetNumFriends() do - process( api.GetFriendInfo( i ) ) + for i = 1, m.api.GetNumFriends() do + process( m.api.GetFriendInfo( i ) ) end - for i = 1, api.GetNumGuildMembers( true ) do - process( api.GetGuildRosterInfo( i ) ) + for i = 1, m.api.GetNumGuildMembers( true ) do + process( m.api.GetGuildRosterInfo( i ) ) end ---@diagnostic disable-next-line: undefined-field - table.setn( matches, math.min( getn( matches ), api.MAIL_AUTOCOMPLETE_MAX_BUTTONS ) ) + table.setn( matches, math.min( getn( matches ), m.api.MAIL_AUTOCOMPLETE_MAX_BUTTONS ) ) if getn( matches ) > 0 and (getn( matches ) > 1 or input ~= matches[ 1 ]) then - for i = 1, api.MAIL_AUTOCOMPLETE_MAX_BUTTONS do - local button = api[ "MailAutoCompleteButton" .. i ] + for i = 1, m.api.MAIL_AUTOCOMPLETE_MAX_BUTTONS do + local button = m.api[ "MailAutoCompleteButton" .. i ] if i <= getn( matches ) then button:SetText( matches[ i ] ) button:GetFontString():SetPoint( "LEFT", button, "LEFT", 15, 0 ) @@ -972,18 +1145,525 @@ do button:Hide() end end - api.MailAutoCompleteBox:SetHeight( getn( matches ) * api.MailAutoCompleteButton1:GetHeight() + 35 ) - api.MailAutoCompleteBox:SetWidth( 120 ) - api.MailAutoCompleteBox:Show() + m.api.MailAutoCompleteBox:SetHeight( getn( matches ) * m.api.MailAutoCompleteButton1:GetHeight() + 35 ) + m.api.MailAutoCompleteBox:SetWidth( 120 ) + m.api.MailAutoCompleteBox:Show() index = 1 complete() else - api.MailAutoCompleteBox:Hide() + m.api.MailAutoCompleteBox:Hide() end end end -function Mail.dump( o ) +function TurtleMail.log.load() + m.api.TurtleMailLogTitleText:SetText( L[ "Log" ] ) + m.api.MailFrameTab3:SetText( L[ "Log" ] ) + + --local font_file = m.api.pfUI and m.api.pfUI.version and m.api.pfUI.font_default or "FONTS\\ARIALN.TTF" + local font_file = m.pfui_skin_enabled and m.api.pfUI.font_default or "FONTS\\ARIALN.TTF" + local font_size = 11 + + for i = 1, 10 do + m.api[ "TurtleMailLogItem" .. i .. "Background" ]:SetVertexColor( .5, .5, .5, 0.6 ) + m.api[ "TurtleMailLogItem" .. i .. "TimeStamp" ]:SetTextColor( 1, 1, 1, 1 ) + m.api[ "TurtleMailLogItem" .. i .. "TimeStamp" ]:SetJustifyH( "LEFT" ) + m.api[ "TurtleMailLogItem" .. i .. "TimeStamp" ]:SetFont( font_file, font_size ) + m.api[ "TurtleMailLogItem" .. i .. "Participant" ]:SetTextColor( 1, 1, 1, 1 ) + m.api[ "TurtleMailLogItem" .. i .. "Participant" ]:SetJustifyH( "RIGHT" ) + m.api[ "TurtleMailLogItem" .. i .. "Participant" ]:SetFont( font_file, font_size ) + m.api[ "TurtleMailLogItem" .. i .. "Subject" ]:SetJustifyH( "LEFT" ) + m.api[ "TurtleMailLogItem" .. i .. "Subject" ]:SetFont( font_file, font_size ) + m.api[ "TurtleMailLogItem" .. i .. "Money" ]:SetTextColor( 1, 1, 1, 1 ) + m.api[ "TurtleMailLogItem" .. i .. "Money" ]:SetJustifyH( "LEFT" ) + m.api[ "TurtleMailLogItem" .. i .. "Money" ]:SetFont( font_file, font_size ) + m.api[ "TurtleMailLogItem" .. i .. "Status" ]:SetVertexColor( m.api.NORMAL_FONT_COLOR.r, m.api.NORMAL_FONT_COLOR.g, m.api.NORMAL_FONT_COLOR.b ) + if i > 1 then + m.api[ "TurtleMailLogItem" .. i ]:SetPoint( "TOPLEFT", m.api[ "TurtleMailLogItem" .. i - 1 ], "BOTTOMLEFT", 0, -1 ) + end + end + m.api.TurtleMailLogItem10Background:Hide() + + m.api.TurtleMailLogStatusText:SetTextColor( 1, 1, 1, 1 ) + m.api.TurtleMailLogStatusText:SetFont( "Fonts\\FRIZQT__.TTF", 10 ) + m.api.TurtleMailLogScrollFrameScrollBar:SetValueStep( 1 ) + m.api.TurtleMailLogScrollFrameScrollBar:SetScript( "OnValueChanged", m.log.on_scroll_value_changed ) + + m.api.TurtleMailLogScrollFrame:SetScript( "OnMouseWheel", function() + m.log.scroll( arg1 * 10 ) + end ) + m.api.TurtleMailLogScrollFrameScrollBarScrollUpButton:SetScript( "OnClick", function() + m.api.PlaySound( "UChatScrollButton" ); + m.log.scroll( 10 ) + end ) + m.api.TurtleMailLogScrollFrameScrollBarScrollDownButton:SetScript( "OnClick", function() + m.api.PlaySound( "UChatScrollButton" ); + m.log.scroll( -10 ) + end ) + + m.api.TurtleMailLogFiltersButton:SetText( L[ "Filters" ] ) + m.api.TurtleMailLogFiltersButton:GetFontString():SetPoint( "LEFT", m.api.TurtleMailLogFiltersButton, "LEFT", 10, 0 ) + + m.api.TurtleMailLogFiltersButton:SetScript( "OnMouseDown", function() + m.api.TurtleMailLogFiltersButtonArrow:SetPoint( "RIGHT", m.pfui_skin_enabled and -4 or -8, -3 ) + end ) + m.api.TurtleMailLogFiltersButton:SetScript( "OnMouseUp", function() + m.api.TurtleMailLogFiltersButtonArrow:SetPoint( "RIGHT", m.pfui_skin_enabled and -4 or -8, -1 ) + end ) + + m.api.TurtleMailLogStartTimeText:SetTextColor( 1, 1, 1, 1 ) + m.api.TurtleMailLogStartTimeButton:SetScale( 0.9 ) + m.api.TurtleMailLogEndTimeText:SetTextColor( 1, 1, 1, 1 ) + m.api.TurtleMailLogEndTimeButton:SetScale( 0.9 ) + + m.api.TurtleMailLogStartTime:SetScript( "OnClick", function() + m.api.TurtleMailLogStartTimeText:SetText( "" ) + m[ m.current_log_type .. "_start_time" ] = nil + m.log.populate( m.current_log_type ) + end ) + m.api.TurtleMailLogEndTime:SetScript( "OnClick", function() + m.api.TurtleMailLogEndTimeText:SetText( "" ) + m[ m.current_log_type .. "_end_time" ] = nil + m.log.populate( m.current_log_type ) + end ) + + m.api.TurtleMailLogPlayersDropDown:SetScale( 0.9 ) + m.api.UIDropDownMenu_SetText( "All players", m.api.TurtleMailLogPlayersDropDown ) + + m.dropdown_filters = m.api.CreateFrame( "Frame", "TurtleMailDropDownFilters" ) + m.dropdown_filters.displayMode = "MENU" + m.dropdown_filters.info = {} +end + +function TurtleMail.log.players_dropdown_on_load() + m.api.UIDropDownMenu_Initialize( m.api.TurtleMailLogPlayersDropDown, function() + local info = {} + info.notCheckable = 1 + info.text = "All players" + info.arg1 = info.text + info.arg2 = "All" + info.func = m.log.select_player + m.api.UIDropDownMenu_AddButton( info ) + + if not m.current_log_type then return end + + local players = {} + for _, v in ipairs( m.api.TurtleMail_Log[ m.current_log_type ] ) do + if v then + players[ v.participant ] = players[ v.participant ] and players[ v.participant ] + 1 or 1 + end + end + + for player, count in pairs( players ) do + info.text = player .. " (" .. count .. ")" + info.arg1 = player + info.arg2 = nil + m.api.UIDropDownMenu_AddButton( info ) + end + end ) +end + +function TurtleMail.log.select_player( player, is_all ) + m.api.UIDropDownMenu_SetText( player, m.api.TurtleMailLogPlayersDropDown ) + if is_all then + m.filter_player = nil + else + m.filter_player = player + end + m.log.populate( m.current_log_type ) +end + +function TurtleMail.log.filter_dropdown() + if m.dropdown_filters.initialize ~= TurtleMail.log.filters_menu then + m.api.CloseDropDownMenus() + m.dropdown_filters.initialize = TurtleMail.log.filters_menu + end + m.api.ToggleDropDownMenu( 1, nil, m.dropdown_filters, this:GetName(), 0, 0 ) +end + +function TurtleMail.log.filters_menu( level ) + local filters = m.api.TurtleMail_Log[ "Settings" ][ m.current_log_type .. "Filters" ] or {} + local info = {} + info.keepShownOnClick = 1 + + local values = { "Money", "COD", "Other" } + if m.current_log_type == "Received" then + table.insert( values, "Returned" ) + table.insert( values, "AH" ) + end + + if level == 1 then + for _, filter in values do + info.text = L[ filter ] + info.checked = filters[ filter ] + info.arg1 = filter + info.func = m.log.toggle_filter + if filter == "AH" then info.hasArrow = 1 end + + m.api.UIDropDownMenu_AddButton( info, level ) + end + elseif level == 2 then + for _, filter in { "Sold", "Cancelled", "Expired", "Won", "Outbid" } do + info.text = L[ filter ] + info.checked = filters[ "AH" .. filter ] + info.arg1 = filter + info.arg2 = "AH" + info.func = m.log.toggle_filter + m.api.UIDropDownMenu_AddButton( info, level ) + end + end +end + +function TurtleMail.log.toggle_filter( filter, parent_filter ) + if not parent_filter then parent_filter = "" end + local filter_value = m.api.TurtleMail_Log[ "Settings" ][ m.current_log_type .. "Filters" ][ parent_filter .. filter ] + + m.api.TurtleMail_Log[ "Settings" ][ m.current_log_type .. "Filters" ][ parent_filter .. filter ] = not filter_value + m.log.populate( m.current_log_type ) +end + +function TurtleMail.log.show_calendar() + if m.calendar.is_visible() then + m.calendar.hide() + else + local text = string.gsub( this:GetName(), "Button", "Text" ) + m.calendar.show( m.api.TurtleMail_Log[ m.current_log_type ], time(), this, function( selected_date ) + local date_str = date( L[ "date_format" ], selected_date ) + m.api[ text ]:SetText( date_str ) + + local v = m.current_log_type .. (string.find( text, "Start" ) and "_start_time" or "_end_time") + m[ v ] = selected_date + m.log.populate( m.current_log_type ) + end ) + end +end + +function TurtleMail.log.scroll( step ) + local scroll_bar = m.api.TurtleMailLogScrollFrameScrollBar + local current = scroll_bar:GetValue() + local min, max = scroll_bar:GetMinMaxValues() + local new = current - step + + if new >= max then + scroll_bar:SetValue( max ) + elseif new <= min then + scroll_bar:SetValue( 0 ) + else + scroll_bar:SetValue( new ) + end +end + +function TurtleMail.log.on_scroll_value_changed() + local function round( num ) + return num + (2 ^ 52 + 2 ^ 51) - (2 ^ 52 + 2 ^ 51) + end + + local scrollBar = m.api.TurtleMailLogScrollFrameScrollBar + local scrollUp = m.api.TurtleMailLogScrollFrameScrollBarScrollUpButton + local scrollDown = m.api.TurtleMailLogScrollFrameScrollBarScrollDownButton + + local minVal, maxVal = scrollBar:GetMinMaxValues() + local currentVal = round( scrollBar:GetValue() ) + + if currentVal <= round( minVal ) then + scrollUp:Disable() + else + scrollUp:Enable() + end + + if currentVal >= round( maxVal ) then + scrollDown:Disable() + else + scrollDown:Enable() + end + + m.log.populate( m.current_log_type, currentVal ) +end + +---@alias LogType +---| "Sent" +---| "Received" + +---@param log_type LogType +---@param state table +function TurtleMail.log.add( log_type, state ) + if not m.log_enabled then return end + m.debug( "Logging " .. log_type .. " message" ) + + local data = { + timestamp = time(), + icon = state.icon, + item = state.item + } + + if state.cod and state.cod > 0 then data.cod = tonumber( state.cod ) end + if log_type == "Sent" then + data.participant = state.to + data.subject = state.sent_subject + if state.send_money and state.sent_money > 0 then data.money = tonumber( state.sent_money ) end + else -- Received + data.participant = state.from + data.subject = state.subject + data.returned = state.returned + data.gm = state.gm + + if state.money and state.money > 0 then data.money = tonumber( state.money ) end + + if string.find( data.subject, string.gsub( m.api.AUCTION_SOLD_MAIL_SUBJECT, "%%s", "" ) ) then + data[ "ah" ] = "Sold" + elseif string.find( data.subject, string.gsub( m.api.AUCTION_REMOVED_MAIL_SUBJECT, "%%s", "" ) ) then + data[ "ah" ] = "Removed" + elseif string.find( data.subject, string.gsub( m.api.AUCTION_EXPIRED_MAIL_SUBJECT, "%%s", "" ) ) then + data[ "ah" ] = "Expired" + elseif string.find( data.subject, string.gsub( m.api.AUCTION_WON_MAIL_SUBJECT, "%%s", "" ) ) then + data[ "ah" ] = "Won" + elseif string.find( data.subject, string.gsub( m.api.AUCTION_OUTBID_MAIL_SUBJECT, "%%s", "" ) ) then + data[ "ah" ] = "Outbid" + end + end + + table.insert( m.api.TurtleMail_Log[ log_type ], data ) +end + +---@param log_type LogType +---@param index number? +function TurtleMail.log.populate( log_type, index ) + m.current_log_type = log_type + local filters = m.api.TurtleMail_Log[ "Settings" ][ log_type .. "Filters" ] or {} + local start_time = m[ log_type .. "_start_time" ] + local end_time = m[ log_type .. "_end_time" ] + if start_time then start_time = start_time - 43200 end + if end_time then end_time = end_time + 43140 end + + local log = m.filter( m.api.TurtleMail_Log[ log_type ], function( item ) + local ret = + (filters.Money and item.money and item.money > 0 and (not item.cod or item.cod == 0) and not item.ah) + or + (filters.COD and item.cod and item.cod > 0) + or + (filters.Other and (not item.cod or item.cod == 0) and not item.ah and not item.returned and (not item.money or item.money == 0)) + or + (filters.Returned and item.returned) + or + (filters.AH and filters.AHWon and item.ah == "Won") + or + (filters.AH and filters.AHSold and item.ah == "Sold") + or + (filters.AH and filters.AHCancelled and item.ah == "Removed") + or + (filters.AH and filters.AHOutbid and item.ah == "Outbid") + or + (filters.AH and filters.AHExpired and item.ah == "Expired") + + if m.filter_player then + ret = ret and item.participant == m.filter_player + end + if start_time then + ret = ret and item.timestamp >= start_time + end + if end_time then + ret = ret and item.timestamp <= end_time + end + + return ret + end ) + + m.api.TurtleMailLogStartTimeText:SetText( start_time and date( L[ "date_format" ], start_time ) or "" ) + m.api.TurtleMailLogEndTimeText:SetText( end_time and date( L[ "date_format" ], end_time ) or "" ) + + if not log then return end + local log_count = getn( log ) + + m.api.TurtleMailLogScrollFrameScrollBar:SetMinMaxValues( 0, math.max( 0, log_count - 10 ) ) + + if not index then + m.api.TurtleMailLogScrollFrameScrollBar:SetValue( log_count - 10 ) + m.api.TurtleMailLogScrollFrameScrollBar:SetScript( "OnUpdate", function() + m.api.TurtleMailLogScrollFrameScrollBar:SetValue( log_count - 10 ) + m.api.TurtleMailLogScrollFrameScrollBar:SetScript( "OnUpdate", nil ) + end ) + + index = math.max( 0, log_count - 10 ) + end + + m.api.TurtleMailLogTitleText:SetText( string.format( "%s %s", L[ log_type ], L[ "Log" ] ) ) + m.api.TurtleMailLogStatusText:SetText( string.format( "Showing %d-%d of %d", (index == 0 and log_count == 0) and index or index + 1, math.min( log_count, index + 10 ), log_count ) ) + + for i = 1, 10 do + if log[ index + i ] then + local entry = log[ index + i ] + + m.api[ "TurtleMailLogItem" .. i .. "IconTexture" ]:SetTexture( entry.icon or "Interface/Icons/INV_Misc_Note_01" ) + m.api[ "TurtleMailLogItem" .. i .. "Icon" ].item = entry.item + m.api[ "TurtleMailLogItem" .. i .. "TimeStamp" ]:SetText( date( L[ "date_format" ] .. " " .. L[ "time_format" ], entry.timestamp ) ) + m.api[ "TurtleMailLogItem" .. i .. "Subject" ]:SetText( entry.subject ) + + m.api[ "TurtleMailLogItem" .. i .. "Status" ]:SetTexture( "" ) + if entry.ah then + m.api[ "TurtleMailLogItem" .. i .. "Participant" ]:SetText( "" ) + m.api[ "TurtleMailLogItem" .. i .. "Status" ]:SetTexture( "Interface\\Addons\\TurtleMail\\TurtleMail-AH.blp" ) + m.api[ "TurtleMailLogItem" .. i .. "Status" ]:SetPoint( "TOPRIGHT", 4, -10 ) + else + m.api[ "TurtleMailLogItem" .. i .. "Participant" ]:SetText( entry.participant ) + end + if entry.returned then + m.api[ "TurtleMailLogItem" .. i .. "Status" ]:SetTexture( "Interface\\Addons\\TurtleMail\\TurtleMail-RetArrow.blp" ) + local w = m.api[ "TurtleMailLogItem" .. i .. "Participant" ]:GetStringWidth() + m.api[ "TurtleMailLogItem" .. i .. "Status" ]:SetPoint( "TOPRIGHT", -w + 4, -9 ) + end + + if entry.money and entry.money > 0 then + local cod = (entry.cod and entry.cod > 0) and "COD: " or " " + m.api[ "TurtleMailLogItem" .. i .. "Money" ]:SetText( cod .. m.format_money( entry.money ) ) + elseif entry.cod and entry.cod > 0 then + m.api[ "TurtleMailLogItem" .. i .. "Money" ]:SetText( "COD: " .. m.format_money( entry.cod ) ) + else + m.api[ "TurtleMailLogItem" .. i .. "Money" ]:SetText( "" ) + end + + m.api[ "TurtleMailLogItem" .. i ]:Show(); + else + m.api[ "TurtleMailLogItem" .. i ]:Hide(); + end + end +end + +function TurtleMail.pfui_skin() + if m.api.IsAddOnLoaded( "pfUI" ) and m.api.pfUI and m.api.pfUI.api and m.api.pfUI.env and m.api.pfUI.env.C then + m.api.pfUI:RegisterSkin( "TurtleMail", "vanilla", function() + -- Don't apply our skin when Mailbox skin is disabled because it doesn't make sense. + if m.api.pfUI.env.C.disabled and (m.api.pfUI.env.C.disabled[ "skin_TurtleMail" ] == "1" or m.api.pfUI.env.C.disabled[ "skin_Mailbox" ] == "1") then + return + end + m.pfui_skin_enabled = true + local rawborder, border = m.api.pfUI.api.GetBorderSize() + local bpad = rawborder > 1 and border - m.api.pfUI.api.GetPerfectPixel() or m.api.pfUI.api.GetPerfectPixel() + + --Inbox + m.api.pfUI.api.SkinButton( m.api.TurtleMailOpenMailButton ) + + --Sendmail + m.api.MailHorizontalBarLeft:SetTexture( "" ) + m.api.MailHorizontalBarRight:SetTexture( "" ) + + for i = 1, 21 do + local button = m.api[ "MailAttachment" .. i ] + m.api.pfUI.api.StripTextures( button ) + m.api.pfUI.api.SkinButton( button, nil, nil, nil, nil, true ) + local orig = button.SetNormalTexture + button.SetNormalTexture = function( self, tex ) + orig( self, tex ) + + if button.item then + m.api.pfUI.api.HandleIcon( self, self:GetNormalTexture() ) + + local link = m.api.GetContainerItemLink( button.item[ 1 ], button.item[ 2 ] ) + local _, _, linkstr = string.find( link, "(item:%d+:%d+:%d+:%d+)" ) + local _, _, quality = m.api.GetItemInfo( linkstr ) + local r, g, b = m.api.GetItemQualityColor( quality ) + self:SetBackdropBorderColor( r, g, b, 1 ) + else + self:SetBackdropBorderColor( m.api.pfUI.api.GetStringColor( m.api.pfUI_config.appearance.border.color ) ) + end + end + end + + --Log + m.api.pfUI.api.SkinTab( m.api.MailFrameTab3 ) + m.api.MailFrameTab3:ClearAllPoints() + m.api.MailFrameTab3:SetPoint( "LEFT", m.api.MailFrameTab2, "RIGHT", border * 2 + 1, 0 ) + + m.api.TurtleMailLogTitleText:ClearAllPoints() + m.api.TurtleMailLogTitleText:SetPoint( "TOP", m.api.MailFrame.backdrop, "TOP", 0, -10 ) + + m.api.pfUI.api.CreateBackdrop( m.api.TurtleMailLogScrollFrame ) + + m.api.TurtleMailLogScrollFrame:SetHeight( 307 ) + m.api.TurtleMailLogScrollFrame:ClearAllPoints() + m.api.TurtleMailLogScrollFrame:SetPoint( "TOPLEFT", 23, -90 ) + m.api.TurtleMailLogScrollFrame:SetWidth( 299 ) + m.api.TurtleMailLogEntriesFrame:ClearAllPoints() + m.api.TurtleMailLogEntriesFrame:SetPoint( "TOPLEFT", 23, -90 ) + m.api.TurtleMailLogEntriesFrame:SetWidth( 299 ) + + m.api.pfUI.api.StripTextures( m.api.TurtleMailLogItem10 ) + m.api.pfUI.api.SkinScrollbar( m.api.TurtleMailLogScrollFrameScrollBar ) + m.api.TurtleMailLogScrollFrameScrollBar:SetPoint( "TOPLEFT", m.api.TurtleMailLogScrollFrame, "TOPRIGHT", 6, -14 ) + m.api.TurtleMailLogScrollFrameScrollBar:SetPoint( "BOTTOMLEFT", m.api.TurtleMailLogScrollFrame, "BOTTOMRIGHT", 6, 14 ) + + m.api.pfUI.api.SkinButton( m.api.TurtleMailLogSentButton ) + m.api.pfUI.api.SkinButton( m.api.TurtleMailLogReceivedButton ) + m.api.TurtleMailLogReceivedButton:ClearAllPoints() + m.api.TurtleMailLogReceivedButton:SetPoint( "RIGHT", m.api.TurtleMailLogSentButton, "LEFT", -2 * bpad, 0 ) + + m.api.pfUI.api.SkinButton( m.api.TurtleMailLogFiltersButton ) + m.api.TurtleMailLogFiltersButton:SetPoint( "TOPLEFT", 21, -58 ) + m.api.TurtleMailLogFiltersButton:GetFontString():SetFont( m.api.pfUI.font_default, 12 ) + m.api.TurtleMailLogFiltersButton:GetFontString():SetPoint( "TOPLEFT", 4, -4.5 ) + m.api.TurtleMailLogFiltersButton:SetWidth( 50 ) + m.api.TurtleMailLogFiltersButton:SetHeight( 20 ) + m.api.TurtleMailLogFiltersButtonArrow:SetPoint( "RIGHT", -4, -1 ) + m.api.TurtleMailLogFiltersButtonArrow:SetWidth( 8.5 ) + m.api.TurtleMailLogFiltersButtonArrow:SetHeight( 8.5 ) + m.api.TurtleMailLogFiltersButtonArrow:SetTexture( m.api.pfUI.media[ "img:down" ] ) + + m.api.pfUI.api.StripTextures( m.api.TurtleMailLogStartTime ) + m.api.pfUI.api.SkinButton( m.api.TurtleMailLogStartTime ) + m.api.pfUI.api.SkinArrowButton( m.api.TurtleMailLogStartTimeButton, "down", 16 ) + m.api.TurtleMailLogStartTime:SetPoint( "TOPLEFT", 77, -58 ) + m.api.TurtleMailLogStartTimeText:SetPoint( "LEFT", 5, 0 ) + m.api.TurtleMailLogStartTimeButton:SetPoint( "LEFT", m.api.TurtleMailLogStartTime, "RIGHT", -19, 0 ) + m.api.TurtleMailLogStartTimeTitle:SetPoint( "TOPLEFT", 1, 13 ) + m.api.TurtleMailLogStartTimeTitle:SetFont( m.api.pfUI.font_default, 10 ) + m.api.TurtleMailLogStartTimeTitle:SetText( L[ "Period start" ] ) + + m.api.pfUI.api.StripTextures( m.api.TurtleMailLogEndTime ) + m.api.pfUI.api.SkinButton( m.api.TurtleMailLogEndTime ) + m.api.pfUI.api.SkinArrowButton( m.api.TurtleMailLogEndTimeButton, "down", 16 ) + m.api.TurtleMailLogEndTime:SetPoint( "TOPLEFT", 163, -58 ) + m.api.TurtleMailLogEndTimeText:SetPoint( "LEFT", 5, 0 ) + m.api.TurtleMailLogEndTimeButton:SetPoint( "LEFT", m.api.TurtleMailLogEndTime, "RIGHT", -19, 0 ) + m.api.TurtleMailLogEndTimeTitle:SetPoint( "TOPLEFT", 1, 13 ) + m.api.TurtleMailLogEndTimeTitle:SetFont( m.api.pfUI.font_default, 10 ) + m.api.TurtleMailLogEndTimeTitle:SetText( L[ "Period end" ] ) + + m.api.pfUI.api.SkinDropDown( m.api.TurtleMailLogPlayersDropDown, nil, nil, nil, true ) + m.api.UIDropDownMenu_SetWidth( 90, m.api.TurtleMailLogPlayersDropDown ) + m.api.TurtleMailLogPlayersDropDown:SetScale( 1 ) + m.api.TurtleMailLogPlayersDropDown:SetPoint( "TOPLEFT", 224, -54 ) + m.api.TurtleMailLogPlayersDropDown.backdrop:SetPoint( "TOPLEFT", 26, -4 ) + m.api.TurtleMailLogPlayersDropDown.backdrop:SetPoint( "BOTTOMRIGHT", -20, 8 ) + m.api.TurtleMailLogPlayersDropDown.button.backdrop:SetWidth( 16 ) + m.api.TurtleMailLogPlayersDropDown.button.backdrop:SetHeight( 16 ) + + local label = m.api.TurtleMailLogFrame:CreateFontString( nil, "BACKGROUND", "GameFontNormal" ) + label:SetFont( m.api.pfUI.font_default, 10 ) + label:SetPoint( "TOPLEFT", 251, -45 ) + label:SetText( L[ "Players" ] ) + end ) + end +end + +function TurtleMail.filter( t, f, extract_field ) + if not t then return nil end + if type( f ) ~= "function" then return t end + + local result = {} + + for i = 1, getn( t ) do + local v = t[ i ] + local value = type( v ) == "table" and extract_field and v[ extract_field ] or v + if f( value ) then table.insert( result, v ) end + end + + return result +end + +function TurtleMail.info( message ) + m.api.DEFAULT_CHAT_FRAME:AddMessage( string.format( "|cffabd473TurtleMail|r: %s", message ) ) +end + +function TurtleMail.dump( o ) if not o then return "nil" end if type( o ) ~= 'table' then return tostring( o ) end @@ -994,7 +1674,7 @@ function Mail.dump( o ) if (entries == 0) then s = s .. " " end local key = type( k ) ~= "number" and '"' .. k .. '"' or k if (entries > 0) then s = s .. ", " end - s = s .. "[" .. key .. "] = " .. Mail.dump( v ) + s = s .. "[" .. key .. "] = " .. m.dump( v ) entries = entries + 1 end @@ -1002,22 +1682,23 @@ function Mail.dump( o ) return s .. "}" end -function Mail.debug( m1, m2, m3 ) +function TurtleMail.debug( ... ) if m.debug_enabled then local messages = "" - for _, message in { m1, m2, m3 } do + for i = 1, getn( arg ) do + local message = arg[ i ] if message then messages = messages == "" and "" or messages .. ", " if type( message ) == 'table' then - messages = messages .. Mail.dump( message ) + messages = messages .. TurtleMail.dump( message ) else messages = messages .. message end end end - api.DEFAULT_CHAT_FRAME:AddMessage( string.format( "|cffabd473TurtleMail|r: %s", messages ) ) + m.api.DEFAULT_CHAT_FRAME:AddMessage( string.format( "|cffabd473TurtleMail|r: %s", messages ) ) end end -Mail.init() +TurtleMail:init() diff --git a/TurtleMail.toc b/TurtleMail.toc index d901f68..89136f9 100644 --- a/TurtleMail.toc +++ b/TurtleMail.toc @@ -2,9 +2,9 @@ ## Interface: 11200 ## Title: |cffabd473Turtle|cffffffffMail ## Author: shirsig/sica -## Version: 1.3 +## Version: 1.4 ## Notes: Mailbox enhancement ## SavedVariables: TurtleMail_AutoCompleteNames -## SavedVariablesPerCharacter: TurtleMail_To TurtleMail_Point +## SavedVariablesPerCharacter: TurtleMail_To TurtleMail_Point TurtleMail_Log TurtleMail.xml diff --git a/TurtleMail.xml b/TurtleMail.xml index 68b8b7d..e0ccb3c 100644 --- a/TurtleMail.xml +++ b/TurtleMail.xml @@ -5,15 +5,16 @@