mirror of
https://github.com/Lacustat/Freewood-OctoWoW-Mail.git
synced 2026-11-03 06:16:57 +00:00
0.1.155: Mail: Lesefenster (Linksklick), Loeschen, Archiv mit Suche, Aufraeumen nach Alle oeffnen
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016onJCSHLwhs9udhC9ZLzk9
This commit is contained in:
+200
-15
@@ -20,6 +20,7 @@ local OWNER = {}
|
||||
local window, content, footer, tabs
|
||||
local current = "inbox"
|
||||
local panes = {}
|
||||
local SelectTab
|
||||
local picks = {} -- Senden-Reiter: gewaehlte Staepel { id, count, key }
|
||||
local picker
|
||||
|
||||
@@ -289,6 +290,7 @@ end
|
||||
local function BuildInbox(parent)
|
||||
local f = CreateFrame("Frame", nil, parent)
|
||||
local rows = {}
|
||||
local LIST_W = 300
|
||||
|
||||
f.info = UI.CreateLabel(f, "", { size = 12, color = "textDim" })
|
||||
f.info:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -6)
|
||||
@@ -313,10 +315,86 @@ local function BuildInbox(parent)
|
||||
|
||||
f.scroll = UI.CreateScrollFrame(f)
|
||||
f.scroll:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -70)
|
||||
f.scroll:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 36)
|
||||
f.scroll:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 36)
|
||||
f.scroll:SetWidth(LIST_W)
|
||||
f.empty = UI.CreateLabel(f.scroll.child, T("MAIL_INBOX_EMPTY"), { size = 12, color = "textDim" })
|
||||
f.empty:SetPoint("TOPLEFT", f.scroll.child, "TOPLEFT", 4, -6)
|
||||
|
||||
---------------- Lesefenster rechts ----------------
|
||||
local d = UI.CreatePanel(f, "card", "bronze")
|
||||
d:SetPoint("TOPLEFT", f, "TOPLEFT", LIST_W + 12, -70)
|
||||
d:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 36)
|
||||
d.empty = UI.CreateLabel(d, T("MAIL_DETAIL_EMPTY"), { size = 12, color = "textDim", justify = "CENTER" })
|
||||
d.empty:SetPoint("CENTER", d, "CENTER", 0, 0)
|
||||
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.attach = UI.CreateLabel(d, "", { size = 12 })
|
||||
d.attach:SetPoint("TOPLEFT", d, "TOPLEFT", 12, -52)
|
||||
d.attach:SetPoint("RIGHT", d, "RIGHT", -12, 0)
|
||||
d.attach:SetWordWrap(false)
|
||||
d.bodyScroll = UI.CreateScrollFrame(d)
|
||||
d.bodyScroll:SetPoint("TOPLEFT", d, "TOPLEFT", 12, -76)
|
||||
d.bodyScroll:SetPoint("BOTTOMRIGHT", d, "BOTTOMRIGHT", -12, 68)
|
||||
d.body = UI.CreateLabel(d.bodyScroll.child, "", { size = 12, justifyV = "TOP" })
|
||||
d.body:SetPoint("TOPLEFT", d.bodyScroll.child, "TOPLEFT", 2, -2)
|
||||
d.msg = UI.CreateLabel(d, "", { size = 11, color = "danger" })
|
||||
d.msg:SetPoint("BOTTOMLEFT", d, "BOTTOMLEFT", 12, 44)
|
||||
d.msg:SetPoint("RIGHT", d, "RIGHT", -12, 0)
|
||||
d.msg:SetWordWrap(false)
|
||||
d.take = UI.CreateButton(d, T("MAIL_TAKE_ITEM"), 120, 26, nil, "primary")
|
||||
d.take:SetPoint("BOTTOMLEFT", d, "BOTTOMLEFT", 12, 12)
|
||||
d.reply = UI.CreateButton(d, T("MAIL_REPLY"), 80, 26, nil, "default")
|
||||
d.reply:SetPoint("LEFT", d.take, "RIGHT", 6, 0)
|
||||
d.delete = UI.CreateButton(d, T("MAIL_DELETE"), 80, 26, nil, "danger")
|
||||
d.delete:SetPoint("BOTTOMRIGHT", d, "BOTTOMRIGHT", -12, 12)
|
||||
UI.AttachTooltip(d.delete, function() return T("MAIL_DELETE") end, function() return T("MAIL_DELETE_TIP") end)
|
||||
f.detail = d
|
||||
|
||||
local function ShowError(why)
|
||||
d.msg:SetText(why and (FW.L["MAIL_ERR_" .. why] or why) or "")
|
||||
end
|
||||
|
||||
d.take:SetScript("OnClick", function()
|
||||
local m = f.current
|
||||
if not m then return end
|
||||
if m.cod > 0 and f.codConfirm ~= m.key then
|
||||
f.codConfirm = m.key
|
||||
f.Refresh()
|
||||
return
|
||||
end
|
||||
f.codConfirm = nil
|
||||
local ok, why = Mail:TakeOne(m)
|
||||
ShowError(not ok and why or nil)
|
||||
f.Refresh()
|
||||
end)
|
||||
d.delete:SetScript("OnClick", function()
|
||||
local m = f.current
|
||||
if not m then return end
|
||||
local ok, why = Mail:RemoveMail(m)
|
||||
if ok then
|
||||
Mail.view, f.current, f.shownKey = nil, nil, nil
|
||||
ShowError(nil)
|
||||
else
|
||||
ShowError(why)
|
||||
end
|
||||
f.Refresh()
|
||||
end)
|
||||
d.reply:SetScript("OnClick", function()
|
||||
local m = f.current
|
||||
if m and panes.send and panes.send.Prefill then
|
||||
local subj = m.subject or ""
|
||||
if subj:sub(1, 3):lower() ~= "re:" then subj = "Re: " .. subj end
|
||||
SelectTab("send")
|
||||
panes.send.Prefill(m.sender, subj)
|
||||
end
|
||||
end)
|
||||
|
||||
local function Row(i)
|
||||
local row = rows[i]
|
||||
if row then return row end
|
||||
@@ -325,38 +403,100 @@ local function BuildInbox(parent)
|
||||
row.cb = UI.CreateCheckbox(row, "", function() return row.mail and Mail.selected[row.mail.key] end, function(v)
|
||||
if row.mail then Mail:ToggleSelect(row.mail.key, v) end
|
||||
end)
|
||||
row.cb:SetPoint("LEFT", row, "LEFT", 8, 0)
|
||||
row.cb:SetPoint("LEFT", row, "LEFT", 6, 0)
|
||||
row.cb:SetWidth(22)
|
||||
row.icon = row:CreateTexture(nil, "ARTWORK")
|
||||
row.icon:SetSize(28, 28)
|
||||
row.icon:SetPoint("LEFT", row, "LEFT", 38, 0)
|
||||
row.icon:SetPoint("LEFT", row, "LEFT", 32, 0)
|
||||
row.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
|
||||
row.l1 = UI.CreateLabel(row, "", { size = 12 })
|
||||
row.l1:SetPoint("TOPLEFT", row, "TOPLEFT", 76, -6)
|
||||
row.l1:SetPoint("RIGHT", row, "RIGHT", -60, 0)
|
||||
row.l1:SetPoint("TOPLEFT", row, "TOPLEFT", 66, -6)
|
||||
row.l1:SetPoint("RIGHT", row, "RIGHT", -40, 0)
|
||||
row.l1:SetWordWrap(false)
|
||||
row.l2 = UI.CreateLabel(row, "", { size = 11, color = "textDim" })
|
||||
row.l2:SetPoint("TOPLEFT", row, "TOPLEFT", 76, -22)
|
||||
row.l2:SetPoint("RIGHT", row, "RIGHT", -60, 0)
|
||||
row.l2:SetPoint("TOPLEFT", row, "TOPLEFT", 66, -22)
|
||||
row.l2:SetPoint("RIGHT", row, "RIGHT", -40, 0)
|
||||
row.l2:SetWordWrap(false)
|
||||
row.days = UI.CreateLabel(row, "", { size = 11, color = "textDim", justify = "RIGHT" })
|
||||
row.days:SetPoint("RIGHT", row, "RIGHT", -10, 0)
|
||||
row.days:SetPoint("RIGHT", row, "RIGHT", -8, 0)
|
||||
Tooltip(row)
|
||||
row:SetScript("OnMouseUp", function()
|
||||
if row.mail then
|
||||
Mail.view = { key = row.mail.key, pair = Mail.Pair(row.mail) }
|
||||
f.codConfirm = nil
|
||||
ShowError(nil)
|
||||
f.Refresh()
|
||||
end
|
||||
end)
|
||||
rows[i] = row
|
||||
return row
|
||||
end
|
||||
|
||||
local function RefreshDetail(list)
|
||||
local view = Mail.view
|
||||
local cur
|
||||
if view then
|
||||
for _, m in ipairs(list) do
|
||||
if m.key == view.key then cur = m break end
|
||||
end
|
||||
if not cur then
|
||||
for _, m in ipairs(list) do
|
||||
if Mail.Pair(m) == view.pair then cur = m break end
|
||||
end
|
||||
end
|
||||
end
|
||||
f.current = cur
|
||||
d.empty:SetShown(cur == nil)
|
||||
for _, w in ipairs({ d.subj, d.meta, d.attach, d.bodyScroll, d.msg, d.take, d.reply, d.delete }) do
|
||||
w:SetShown(cur ~= nil)
|
||||
end
|
||||
if not cur then f.shownKey = nil return end
|
||||
view.key = cur.key
|
||||
if f.shownKey ~= cur.key then
|
||||
f.shownKey = cur.key
|
||||
f.bodyText = Mail.ReadText(cur.i)
|
||||
if FW.Brett and FW.Brett.CheckMailData then pcall(FW.Brett.CheckMailData, cur.i) end
|
||||
end
|
||||
d.subj:SetText(cur.subject ~= "" and cur.subject or T("MAIL_ARCH_NOSUBJECT"))
|
||||
d.meta:SetText(string.format(T("MAIL_DETAIL_FROM"), cur.sender) .. (cur.days and (" " .. string.format(T("MAIL_ROW_DAYS"), math.floor(cur.days))) or ""))
|
||||
local parts = {}
|
||||
if cur.hasItem then parts[#parts + 1] = string.format(T("MAIL_ATTACH_ITEM"), (cur.itemName or "?") .. ((cur.itemCount or 1) > 1 and (" x" .. cur.itemCount) or "")) end
|
||||
if cur.money > 0 then parts[#parts + 1] = string.format(T("MAIL_ATTACH_GOLD"), Mail.Money(cur.money)) end
|
||||
local attach = #parts > 0 and table.concat(parts, " ") or T("MAIL_ATTACH_NONE")
|
||||
if cur.cod > 0 then attach = attach .. " |cffff7060" .. string.format(T("MAIL_ATTACH_COD"), Mail.Money(cur.cod)) .. "|r" end
|
||||
d.attach:SetText(attach)
|
||||
local text = f.bodyText 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)
|
||||
|
||||
local busy = Mail.busy ~= nil
|
||||
local canTake = (cur.money > 0 and cur.cod == 0) or cur.hasItem
|
||||
if cur.cod > 0 then
|
||||
d.take:SetLabel(f.codConfirm == cur.key and string.format(T("MAIL_TAKE_COD_CONFIRM"), Mail.Money(cur.cod)) or string.format(T("MAIL_TAKE_COD"), Mail.Money(cur.cod)))
|
||||
d.take:SetWidth(210)
|
||||
else
|
||||
d.take:SetLabel(cur.money > 0 and T("MAIL_TAKE_GOLD") or T("MAIL_TAKE_ITEM"))
|
||||
d.take:SetWidth(120)
|
||||
end
|
||||
d.take:SetButtonEnabled(canTake and not busy and Mail.open)
|
||||
d.delete:SetButtonEnabled(Mail.Deletable(cur) and not busy and Mail.open)
|
||||
d.reply:SetButtonEnabled(true)
|
||||
end
|
||||
|
||||
function f.Refresh()
|
||||
local list = Mail.ReadInbox()
|
||||
local busy = Mail.busy
|
||||
local takeable = 0
|
||||
local view = Mail.view
|
||||
for i, m in ipairs(list) do local m = m
|
||||
local row = Row(i)
|
||||
row.mail = m
|
||||
row.inboxIndex = m.hasItem and m.i or nil
|
||||
row:ClearAllPoints()
|
||||
row:SetPoint("TOPLEFT", f.scroll.child, "TOPLEFT", 0, -((i - 1) * (ROW_H + ROW_GAP)))
|
||||
row:SetWidth(RowWidth(f.scroll))
|
||||
row:SetWidth(RowWidth(f.scroll, 250))
|
||||
if m.itemTex then
|
||||
row.icon:SetTexture(m.itemTex)
|
||||
elseif m.money > 0 then
|
||||
@@ -367,20 +507,21 @@ local function BuildInbox(parent)
|
||||
row.l1:SetText(m.subject ~= "" and m.subject or m.sender)
|
||||
local parts = {}
|
||||
if m.hasItem then parts[#parts + 1] = (m.itemName or "?") .. ((m.itemCount or 1) > 1 and (" x" .. m.itemCount) or "") end
|
||||
if m.money > 0 then parts[#parts + 1] = string.format(T("MAIL_ROW_GOLD"), Mail.Money(m.money)) end
|
||||
if m.money > 0 then parts[#parts + 1] = Mail.Money(m.money) end
|
||||
local text
|
||||
if m.cod > 0 then
|
||||
text = "|cffff7060" .. string.format(T("MAIL_ROW_COD"), Mail.Money(m.cod)) .. "|r"
|
||||
elseif #parts == 0 then
|
||||
text = T("MAIL_ROW_LETTER")
|
||||
text = m.sender
|
||||
else
|
||||
text = table.concat(parts, " + ")
|
||||
end
|
||||
row.l2:SetText(string.format(T("MAIL_ROW_FROM"), m.sender) .. " " .. text)
|
||||
row.l2:SetText(text)
|
||||
row.days:SetText(m.days and string.format(T("MAIL_ROW_DAYS"), math.floor(m.days)) or "")
|
||||
row.cb:SetShown(m.take)
|
||||
row:SetAlpha(m.take and 1 or 0.55)
|
||||
row:SetAlpha(m.take and 1 or 0.75)
|
||||
row.cb:Refresh()
|
||||
UI.SetBorderColor(row, (view and view.key == m.key) and "gold" or "bronze")
|
||||
if m.take then takeable = takeable + 1 end
|
||||
row:Show()
|
||||
end
|
||||
@@ -388,10 +529,11 @@ local function BuildInbox(parent)
|
||||
f.empty:SetShown(#list == 0)
|
||||
f.scroll:SetContentHeight(#list * (ROW_H + ROW_GAP) + 4)
|
||||
f.info:SetText(string.format(T("MAIL_INBOX_COUNT"), #list))
|
||||
RefreshDetail(list)
|
||||
|
||||
local sel = Mail:SelectedCount()
|
||||
f.open:SetLabel(sel > 0 and string.format(T("MAIL_OPEN_SELECTED"), sel) or T("MAIL_OPEN_ALL"))
|
||||
f.open:SetButtonEnabled(Mail.open and not busy and (sel > 0 or takeable > 0))
|
||||
f.open:SetButtonEnabled(Mail.open and not busy and (sel > 0 or #list > 0))
|
||||
f.stop:SetShown(busy ~= nil)
|
||||
f.all:SetButtonEnabled(not busy and takeable > 0)
|
||||
f.none:SetButtonEnabled(not busy and sel > 0)
|
||||
@@ -477,6 +619,12 @@ local function BuildSend(parent)
|
||||
status:SetTextColor(UI.Color(colorKey or "textDim"))
|
||||
end
|
||||
|
||||
function f.Prefill(to, subject)
|
||||
toBox:Set(to or "")
|
||||
subjBox:Set(subject or "")
|
||||
f.Refresh()
|
||||
end
|
||||
|
||||
function f.Refresh()
|
||||
for i, pk in ipairs(picks) do local pk, i = pk, i
|
||||
local row = rows[i]
|
||||
@@ -693,7 +841,7 @@ local TAB_DEFS = {
|
||||
{ id = "lists", label = "MAIL_TAB_LISTS", build = BuildLists },
|
||||
}
|
||||
|
||||
local function SelectTab(id)
|
||||
function SelectTab(id)
|
||||
current = id
|
||||
for _, def in ipairs(TAB_DEFS) do
|
||||
local pane = panes[def.id]
|
||||
@@ -750,6 +898,10 @@ local function BuildWindow()
|
||||
end, "danger")
|
||||
close:SetPoint("TOPRIGHT", f, "TOPRIGHT", -10, -10)
|
||||
UI.AttachTooltip(close, function() return T("MAIL_CLOSE") end, "")
|
||||
local arch = UI.CreateButton(f, T("MAIL_BTN_ARCHIVE"), 80, 24, function()
|
||||
if Mail.OpenArchive then Mail.OpenArchive(true) end
|
||||
end, "default")
|
||||
arch:SetPoint("TOPRIGHT", f, "TOPRIGHT", -42, -10)
|
||||
local div = UI.CreateDivider(f)
|
||||
div:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -40)
|
||||
div:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -40)
|
||||
@@ -908,10 +1060,41 @@ if UI.RegisterSettingsSection then
|
||||
end)
|
||||
stack:Add(chat, { fit = true, gap = 4 })
|
||||
boxes[#boxes + 1] = chat
|
||||
local cleanup = UI.CreateCheckbox(f, T("MAIL_SET_CLEANUP"), function()
|
||||
return Mail.db.settings.cleanup
|
||||
end, function(value)
|
||||
Mail.db.settings.cleanup = value and true or false
|
||||
end)
|
||||
stack:Add(cleanup, { fit = true, gap = 4 })
|
||||
boxes[#boxes + 1] = cleanup
|
||||
local dd
|
||||
dd = UI.CreateDropdown(f, 300, 24, {
|
||||
prefix = T("MAIL_SET_ARCHIVE_DAYS"),
|
||||
getOptions = function()
|
||||
local o = {}
|
||||
for _, days in ipairs({ 0, 7, 14, 30, 90 }) do
|
||||
o[#o + 1] = { value = days, text = days == 0 and T("MAIL_SET_ARCHIVE_OFF") or string.format(T("MAIL_SET_ARCHIVE_N"), days) }
|
||||
end
|
||||
return o
|
||||
end,
|
||||
onChange = function(v)
|
||||
if v ~= nil then
|
||||
Mail.db.settings.archiveDays = v
|
||||
Mail:Purge()
|
||||
dd:SetValue(v)
|
||||
end
|
||||
end,
|
||||
})
|
||||
stack:Add(dd, { gap = 8, height = 24 })
|
||||
local archBtn = UI.CreateButton(f, T("MAIL_SET_ARCHIVE_BTN"), 160, 26, function()
|
||||
if Mail.OpenArchive then Mail.OpenArchive(true) end
|
||||
end, "default")
|
||||
stack:Add(archBtn, { gap = 8, height = 26 })
|
||||
local note = UI.CreateLabel(f, T("MAIL_SET_NOTE"), { size = 11, color = "textDim", justifyV = "TOP" })
|
||||
stack:Add(note, { fit = true, gap = 10 })
|
||||
function f.Refresh()
|
||||
for _, cb in ipairs(boxes) do cb:Refresh() end
|
||||
dd:SetValue(Mail.db.settings.archiveDays or 0)
|
||||
end
|
||||
stack:Layout()
|
||||
return f
|
||||
@@ -932,6 +1115,8 @@ SlashCmdList["FREEWOODMAIL"] = function(msg)
|
||||
if msg == "on" then
|
||||
Mail:SetReplace(true)
|
||||
FW:Print(T("MAIL_CMD_ON"))
|
||||
elseif msg == "archive" or msg == "archiv" then
|
||||
if Mail.OpenArchive then Mail.OpenArchive(true) end
|
||||
elseif msg == "off" then
|
||||
Mail:SetReplace(false)
|
||||
FW:Print(T("MAIL_CMD_OFF"))
|
||||
|
||||
Reference in New Issue
Block a user