New logging feature
This commit is contained in:
+292
@@ -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
|
||||
Reference in New Issue
Block a user