Files

230 lines
9.2 KiB
Lua

-- Freewood-OctoWoW-Mail: Archiv der entfernten Briefe (eigenes Fenster mit Suche nach Betreff und Absender).
-- Geoeffnet ueber den Knopf "Archiv" im Briefkasten-Fenster, in den Einstellungen oder mit /fwmail archive.
-- Eintraege: { t, sender, subject, body, money, items, char }. Loeschen nach X Tagen: Einstellung (Standard: nie).
local ADDON, NS = ...
local FW = _G.Freewood
local Mail = NS.Mail
if not FW or not Mail then
return
end
local UI = FW.UI
local W, H = 720, 500
local LIST_W = 290
local ROW_H, ROW_GAP = 40, 4
local win
local rows = {}
local filter = ""
local selected -- gewaehlter Eintrag (Tabelle)
local clearConfirm = false
local function T(key) return FW.L[key] or key end
local function Stamp(t) return date and date("%d.%m.%y %H:%M", t or 0) or "" end
local function Matches(e, q)
if q == "" then return true end
q = q:lower()
return (tostring(e.subject or ""):lower():find(q, 1, true) or tostring(e.sender or ""):lower():find(q, 1, true)) and true or false
end
local function Build()
local f = UI.CreatePanel(UIParent, "bgDeep", "gold")
f:SetSize(W, H)
f:SetFrameStrata("DIALOG")
f:SetClampedToScreen(true)
f:EnableMouse(true)
f:SetMovable(true)
f:RegisterForDrag("LeftButton")
f:SetScript("OnDragStart", function(self) self:StartMoving() end)
f:SetScript("OnDragStop", function(self)
self:StopMovingOrSizing()
local left, top = self:GetLeft(), self:GetTop()
if left and top then Mail.db.settings.archivePos = { x = left, y = top } end
end)
local pos = Mail.db.settings.archivePos
f:ClearAllPoints()
if pos and pos.x and pos.y then
f:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", pos.x, pos.y)
else
f:SetPoint("CENTER", UIParent, "CENTER", 60, 0)
end
local title = UI.CreateLabel(f, T("MAIL_ARCH_TITLE"), { font = "heading", size = 16, color = "goldLight" })
title:SetPoint("TOPLEFT", f, "TOPLEFT", 16, -12)
local close = UI.CreateButton(f, "X", 26, 24, function() f:Hide() end, "danger")
close:SetPoint("TOPRIGHT", f, "TOPRIGHT", -10, -10)
local div = UI.CreateDivider(f)
div:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -40)
div:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -40)
-- Suche
local box = UI.CreatePanel(f, "bgDeep", "bronze")
box:SetSize(LIST_W, 26)
box:SetPoint("TOPLEFT", f, "TOPLEFT", 16, -52)
local edit = CreateFrame("EditBox", nil, box)
edit:SetAutoFocus(false)
edit:SetPoint("TOPLEFT", box, "TOPLEFT", 8, -2)
edit:SetPoint("BOTTOMRIGHT", box, "BOTTOMRIGHT", -8, 2)
edit:SetMaxLetters(60)
if not edit:SetFont(UI.GetFontPath("body"), 12, "") then edit:SetFont("Fonts\\FRIZQT__.TTF", 12, "") end
edit:SetTextColor(UI.Color("text"))
edit:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
edit:SetScript("OnEnterPressed", function(self) self:ClearFocus() end)
local hint = UI.CreateLabel(box, T("MAIL_ARCH_SEARCH"), { size = 12, color = "textDim" })
hint:SetPoint("LEFT", box, "LEFT", 10, 0)
edit:SetScript("OnTextChanged", function(self)
filter = self:GetText() or ""
if filter == "" then hint:Show() else hint:Hide() end
if f.Refresh then f.Refresh() end
end)
f.count = UI.CreateLabel(f, "", { size = 11, color = "textDim" })
f.count:SetPoint("TOPLEFT", f, "TOPLEFT", 16, -84)
-- Liste
f.scroll = UI.CreateScrollFrame(f)
f.scroll:SetPoint("TOPLEFT", f, "TOPLEFT", 16, -102)
f.scroll:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 16, 16)
f.scroll:SetWidth(LIST_W)
f.empty = UI.CreateLabel(f.scroll.child, T("MAIL_ARCH_EMPTY"), { size = 12, color = "textDim" })
f.empty:SetPoint("TOPLEFT", f.scroll.child, "TOPLEFT", 4, -6)
-- Lesefenster
local d = UI.CreatePanel(f, "card", "bronze")
d:SetPoint("TOPLEFT", f, "TOPLEFT", LIST_W + 28, -52)
d:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -16, 16)
d.subj = UI.CreateLabel(d, "", { font = "heading", size = 14, color = "goldLight" })
d.subj:SetPoint("TOPLEFT", d, "TOPLEFT", 12, -10)
d.subj:SetPoint("RIGHT", d, "RIGHT", -12, 0)
d.subj:SetWordWrap(false)
d.meta = UI.CreateLabel(d, "", { size = 11, color = "textDim" })
d.meta:SetPoint("TOPLEFT", d, "TOPLEFT", 12, -32)
d.meta:SetPoint("RIGHT", d, "RIGHT", -12, 0)
d.meta:SetWordWrap(false)
d.taken = UI.CreateLabel(d, "", { size = 12 })
d.taken:SetPoint("TOPLEFT", d, "TOPLEFT", 12, -52)
d.taken:SetPoint("RIGHT", d, "RIGHT", -12, 0)
d.taken:SetWordWrap(false)
d.bodyScroll = UI.CreateScrollFrame(d)
d.bodyScroll:SetPoint("TOPLEFT", d, "TOPLEFT", 12, -76)
d.bodyScroll:SetPoint("BOTTOMRIGHT", d, "BOTTOMRIGHT", -12, 50)
d.body = UI.CreateLabel(d.bodyScroll.child, "", { size = 12, justifyV = "TOP" })
d.body:SetPoint("TOPLEFT", d.bodyScroll.child, "TOPLEFT", 2, -2)
d.del = UI.CreateButton(d, T("MAIL_ARCH_DELETE"), 130, 26, function()
if not selected then return end
local a = Mail.db.archive
for i, e in ipairs(a) do
if e == selected then table.remove(a, i) break end
end
selected = nil
f.Refresh()
end, "danger")
d.del:SetPoint("BOTTOMLEFT", d, "BOTTOMLEFT", 12, 12)
d.clear = UI.CreateButton(d, T("MAIL_ARCH_CLEAR"), 210, 26, function()
if not clearConfirm then
clearConfirm = true
f.Refresh()
return
end
clearConfirm = false
for i = #Mail.db.archive, 1, -1 do table.remove(Mail.db.archive, i) end
selected = nil
f.Refresh()
end, "default")
d.clear:SetPoint("BOTTOMRIGHT", d, "BOTTOMRIGHT", -12, 12)
local function Row(i)
local row = rows[i]
if row then return row end
row = UI.CreatePanel(f.scroll.child, "card", "bronze")
row:SetHeight(ROW_H)
row:EnableMouse(true)
row.l1 = UI.CreateLabel(row, "", { size = 12 })
row.l1:SetPoint("TOPLEFT", row, "TOPLEFT", 10, -6)
row.l1:SetPoint("RIGHT", row, "RIGHT", -10, 0)
row.l1:SetWordWrap(false)
row.l2 = UI.CreateLabel(row, "", { size = 11, color = "textDim" })
row.l2:SetPoint("TOPLEFT", row, "TOPLEFT", 10, -22)
row.l2:SetPoint("RIGHT", row, "RIGHT", -10, 0)
row.l2:SetWordWrap(false)
row:SetScript("OnMouseUp", function()
selected = row.entry
clearConfirm = false
f.Refresh()
end)
rows[i] = row
return row
end
function f.Refresh()
local all = Mail.db.archive
local list = {}
for _, e in ipairs(all) do
if Matches(e, filter) then list[#list + 1] = e end
end
local w = math.max(200, (f.scroll:GetWidth() or 0) - 14)
for i, e in ipairs(list) do
local row = Row(i)
row.entry = e
row:ClearAllPoints()
row:SetPoint("TOPLEFT", f.scroll.child, "TOPLEFT", 0, -((i - 1) * (ROW_H + ROW_GAP)))
row:SetWidth(w)
row.l1:SetText(e.subject ~= "" and e.subject or T("MAIL_ARCH_NOSUBJECT"))
row.l2:SetText(tostring(e.sender or "?") .. " " .. Stamp(e.t))
UI.SetBorderColor(row, e == selected and "gold" or "bronze")
row:Show()
end
for i = #list + 1, #rows do rows[i].entry = nil rows[i]:Hide() end
f.empty:SetShown(#list == 0)
f.scroll:SetContentHeight(#list * (ROW_H + ROW_GAP) + 4)
f.count:SetText(string.format(T("MAIL_ARCH_COUNT"), #list, #all))
if selected then
local e = selected
d.subj:SetText(e.subject ~= "" and e.subject or T("MAIL_ARCH_NOSUBJECT"))
d.meta:SetText(string.format(T("MAIL_DETAIL_FROM"), tostring(e.sender or "?")) .. " " .. Stamp(e.t) ..
(e.char and (" " .. string.format(T("MAIL_ARCH_CHAR"), e.char)) or ""))
local parts = {}
if (e.money or 0) > 0 then parts[#parts + 1] = Mail.Money(e.money) end
for _, it in ipairs(e.items or {}) do parts[#parts + 1] = it end
d.taken:SetText(#parts > 0 and string.format(T("MAIL_ARCH_TAKEN"), table.concat(parts, ", ")) or "")
local text = e.body or ""
d.body:SetText(text ~= "" and text or "|cff8a8f9a" .. T("MAIL_DETAIL_NOTEXT") .. "|r")
local bw = math.max(200, (d.bodyScroll:GetWidth() or 0) - 22)
local h = UI.FitLabel(d.body, bw, 20)
d.bodyScroll:SetContentHeight(h + 8)
end
for _, wdg in ipairs({ d.subj, d.meta, d.taken, d.bodyScroll, d.del }) do wdg:SetShown(selected ~= nil) end
d.clear:SetLabel(clearConfirm and T("MAIL_ARCH_CLEAR_CONFIRM") or T("MAIL_ARCH_CLEAR"))
d.clear:SetButtonEnabled(#all > 0)
end
f:SetScript("OnShow", function() f.Refresh() end)
f:Hide()
return f
end
function Mail.OpenArchive(toggle)
if not win then
local ok, err = pcall(function() win = Build() end)
if not ok then
if FW.Print then FW:Print("Mail archive: " .. tostring(err)) end
return
end
end
if toggle and win:IsShown() then
win:Hide()
return
end
pcall(Mail.Purge, Mail)
win:Show()
win:Raise()
win.Refresh()
end
FW:On("MAIL_ARCHIVE_CHANGED", function()
if win and win:IsShown() then win.Refresh() end
end, {})