Merge branch 'cc-bcc' into contacts

adjusted GUI
This commit is contained in:
Peter Nerlich 2020-08-10 13:01:33 +02:00
commit 498ef84026
3 changed files with 155 additions and 61 deletions

13
api.lua
View File

@ -28,6 +28,9 @@ function mail.send(src, dst, subject, body)
m.body = body m.body = body
end end
local cc
local bcc
local extra
-- log mail send action -- log mail send action
if m.cc or m.bcc then if m.cc or m.bcc then
if m.cc then if m.cc then
@ -43,22 +46,22 @@ function mail.send(src, dst, subject, body)
else else
bcc = "" bcc = ""
end end
extra = "(" .. cc .. bcc .. ") " extra = " (" .. cc .. bcc .. ")"
else else
extra = "" extra = ""
end end
minetest.log("action", "[mail] '" .. m.from .. "' sends mail to '" .. m.to .. minetest.log("action", "[mail] '" .. m.from .. "' sends mail to '" .. m.to .. "'" ..
extra .. "' with subject '" .. m.subject .. "' and body: '" .. m.body .. "'") extra .. "' with subject '" .. m.subject .. "' and body: '" .. m.body .. "'")
-- normalize to, cc and bcc while compiling a list of all recipients -- normalize to, cc and bcc while compiling a list of all recipients
local recipients = {} local recipients = {}
m.to = normalize_players_and_add_recipients(m.to, recipients) m.to = mail.normalize_players_and_add_recipients(m.to, recipients)
if m.cc then if m.cc then
m.cc = normalize_players_and_add_recipients(m.cc, recipients) m.cc = mail.normalize_players_and_add_recipients(m.cc, recipients)
end end
if m.bcc then if m.bcc then
m.bcc = normalize_players_and_add_recipients(m.bcc, recipients) m.bcc = mail.normalize_players_and_add_recipients(m.bcc, recipients)
end end
-- form the actual mail -- form the actual mail

155
gui.lua
View File

@ -7,17 +7,19 @@ else
theme = "" theme = ""
end end
mail.inbox_formspec = "size[8,10;]" .. theme .. [[ mail.inbox_formspec = "size[8,9;]" .. theme .. [[
button[6,0.00;2,0.5;new;New] button[6,0.10;2,0.5;new;New]
button[6,0.75;2,0.5;read;Read] button[6,0.95;2,0.5;read;Read]
button[6,1.50;2,0.5;reply;Reply] button[6,1.70;2,0.5;reply;Reply]
button[6,2.25;2,0.5;forward;Forward] button[6,2.45;2,0.5;replyall;Reply All]
button[6,3.00;2,0.5;delete;Delete] button[6,3.20;2,0.5;forward;Forward]
button[6,4.25;2,0.5;markread;Mark Read] button[6,3.95;2,0.5;delete;Delete]
button[6,5.00;2,0.5;markunread;Mark Unread] button[6,4.82;2,0.5;markread;Mark Read]
button[6,6.25;2,0.5;contacts;Contacts] button[6,5.55;2,0.5;markunread;Mark Unread]
button[6,7.00;2,0.5;about;About] button[6,6.55;2,0.5;contacts;Contacts]
button_exit[6,8.25;2,0.5;quit;Close] button[6,7.40;2,0.5;about;About]
button_exit[6,8.45;2,0.5;quit;Close]
tablecolumns[color;text;text] tablecolumns[color;text;text]
table[0,0;5.75,9;messages;#999,From,Subject]] table[0,0;5.75,9;messages;#999,From,Subject]]
@ -39,7 +41,7 @@ mail.select_contact_formspec = "size[8,10;]" .. theme .. [[
function mail.show_about(name) function mail.show_about(name)
local formspec = [[ local formspec = [[
size[8,5;] size[8,5;]
button[7.5,0;0.5,0.5;back;X] button[7.25,0;0.75,0.5;back;X]
label[0,0;Mail] label[0,0;Mail]
label[0,0.5;By cheapie] label[0,0.5;By cheapie]
label[0,1;http://github.com/cheapie/mail] label[0,1;http://github.com/cheapie/mail]
@ -59,13 +61,22 @@ function mail.show_inbox(name)
if messages[1] then if messages[1] then
for _, message in ipairs(messages) do for _, message in ipairs(messages) do
mail.ensure_new_format(message)
if message.unread then if message.unread then
if not mail.player_in_list(name, message.to) then
formspec[#formspec + 1] = ",#FFD788"
else
formspec[#formspec + 1] = ",#FFD700" formspec[#formspec + 1] = ",#FFD700"
end
else
if not mail.player_in_list(name, message.to) then
formspec[#formspec + 1] = ",#CCCCDD"
else else
formspec[#formspec + 1] = "," formspec[#formspec + 1] = ","
end end
end
formspec[#formspec + 1] = "," formspec[#formspec + 1] = ","
formspec[#formspec + 1] = minetest.formspec_escape(message.sender) formspec[#formspec + 1] = minetest.formspec_escape(message.from)
formspec[#formspec + 1] = "," formspec[#formspec + 1] = ","
if message.subject ~= "" then if message.subject ~= "" then
if string.len(message.subject) > 30 then if string.len(message.subject) > 30 then
@ -141,47 +152,88 @@ function mail.show_message(name, msgnumber)
local messages = mail.getMessages(name) local messages = mail.getMessages(name)
local message = messages[msgnumber] local message = messages[msgnumber]
local formspec = [[ local formspec = [[
size[8,7.2] size[8,9]
button[7,0;1,0.5;back;X] button[7.25,0;0.75,0.5;back;X]
label[0,0;From: %s] label[0,0;From: %s]
label[0,0.5;Subject: %s] label[0,0.4;To: %s]
textarea[0.25,1.25;8,6.25;body;;%s] label[0,0.8;CC: %s]
button[1,6.7;2,1;reply;Reply] label[0,1.3;Subject: %s]
button[3,6.7;2,1;forward;Forward] textarea[0.25,1.8;8,7.8;body;;%s]
button[5,6.7;2,1;delete;Delete] button[0,8.5;2,1;reply;Reply]
button[2,8.5;2,1;replyall;Reply All]
button[4,8.5;2,1;forward;Forward]
button[6,8.5;2,1;delete;Delete]
]] .. theme ]] .. theme
local from = minetest.formspec_escape(message.from) local from = minetest.formspec_escape(message.from)
local to = minetest.formspec_escape(message.to)
local cc = minetest.formspec_escape(message.cc)
local subject = minetest.formspec_escape(message.subject) local subject = minetest.formspec_escape(message.subject)
local body = minetest.formspec_escape(message.body) local body = minetest.formspec_escape(message.body)
formspec = string.format(formspec, from, subject, body) formspec = string.format(formspec, from, to, cc, subject, body)
minetest.show_formspec(name,"mail:message",formspec) minetest.show_formspec(name,"mail:message",formspec)
end end
function mail.show_compose(name, defaultto, defaultsubj, defaultbody, defaultcc, defaultbcc) function mail.show_compose(name, defaultto, defaultsubj, defaultbody, defaultcc, defaultbcc)
local formspec = [[ local formspec = [[
size[8,7.2] size[8,9]
field[0.25,0.5;4,1;to;To:;%s] field[0.25,0.5;3.5,1;to;To:;%s]
field[0.25,0.5;4,1;to;CC:;%s] field[3.75,0.5;3.75,1;cc;CC:;%s]
field[0.25,0.5;4,1;to;BCC:;%s] field[3.75,1.6;3.75,1;bcc;BCC:;%s]
field[0.25,1.7;8,1;subject;Subject:;%s] field[0.25,2.5;8,1;subject;Subject:;%s]
textarea[0.25,2.4;8,5;body;;%s] textarea[0.25,3.2;8,6;body;;%s]
button[0.5,6.7;3,1;cancel;Cancel] button[0.5,8.5;3,1;cancel;Cancel]
button[7,0;1,0.5;cancel;X] button[7.25,0;0.75,0.5;cancel;X]
button[4.5,6.7;3,1;send;Send] button[4.5,8.5;3,1;send;Send]
]] .. theme ]] .. theme
defaultto = defaultto or ""
defaultsubj = defaultsubj or ""
defaultbody = defaultbody or ""
defaultcc = defaultcc or ""
defaultbcc = defaultbcc or ""
formspec = string.format(formspec, formspec = string.format(formspec,
minetest.formspec_escape(defaulttgt), minetest.formspec_escape(defaultto),
minetest.formspec_escape(defaultsubj),
minetest.formspec_escape(defaultbody),
minetest.formspec_escape(defaultcc), minetest.formspec_escape(defaultcc),
minetest.formspec_escape(defaultbcc)) minetest.formspec_escape(defaultbcc),
minetest.formspec_escape(defaultsubj),
minetest.formspec_escape(defaultbody))
minetest.show_formspec(name, "mail:compose", formspec) minetest.show_formspec(name, "mail:compose", formspec)
end end
function mail.reply(name, message)
mail.ensure_new_format(message)
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
mail.show_compose(name, message.from, "Re: "..message.subject, replyfooter)
end
function mail.replyall(name, message)
mail.ensure_new_format(message)
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
-- new recipients are the sender plus the original recipients, minus ourselves
local recipients = message.to
if message.from ~= nil then
recipients = message.from .. ", " .. recipients
end
recipients = mail.parse_player_list(recipients)
for k,v in pairs(recipients) do
if v == name then
table.remove(recipients, k)
break
end
end
recipients = mail.concat_player_list(recipients)
mail.show_compose(name, recipients, "Re: "..message.subject, replyfooter, message.cc)
end
function mail.forward(name, message)
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
end
function mail.handle_receivefields(player, formname, fields) function mail.handle_receivefields(player, formname, fields)
if formname == "" and fields and fields.quit and minetest.get_modpath("unified_inventory") then if formname == "" and fields and fields.quit and minetest.get_modpath("unified_inventory") then
unified_inventory.set_inventory_formspec(player, "craft") unified_inventory.set_inventory_formspec(player, "craft")
@ -220,28 +272,36 @@ function mail.handle_receivefields(player, formname, fields)
mail.show_inbox(name) mail.show_inbox(name)
elseif fields.reply and messages[selected_message_idxs[name]] then elseif fields.reply and messages[selected_message_idxs[name]] then
local message = messages[selected_message_idxs[name]] local message = messages[selected_message_idxs[name]]
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body mail.reply(name, message)
mail.show_compose(name, message.from, "Re: "..message.subject,replyfooter)
elseif fields.replyall and messages[selected_message_idxs[name]] then
local message = messages[selected_message_idxs[name]]
mail.replyall(name, message)
elseif fields.forward and messages[selected_message_idxs[name]] then elseif fields.forward and messages[selected_message_idxs[name]] then
local message = messages[selected_message_idxs[name]] local message = messages[selected_message_idxs[name]]
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body mail.forward(name, message)
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
elseif fields.markread then elseif fields.markread then
if messages[selected_message_idxs[name]] then if messages[selected_message_idxs[name]] then
messages[selected_message_idxs[name]].unread = false messages[selected_message_idxs[name]].unread = false
end end
-- set messages immediately, so it shows up already when updating the inbox
mail.setMessages(name, messages)
mail.show_inbox(name) mail.show_inbox(name)
return true
elseif fields.markunread then elseif fields.markunread then
if messages[selected_message_idxs[name]] then if messages[selected_message_idxs[name]] then
messages[selected_message_idxs[name]].unread = true messages[selected_message_idxs[name]].unread = true
end end
-- set messages immediately, so it shows up already when updating the inbox
mail.setMessages(name, messages)
mail.show_inbox(name) mail.show_inbox(name)
return true
elseif fields.new then elseif fields.new then
mail.show_compose(name,"","","Type your message here.") mail.show_compose(name)
elseif fields.quit then elseif fields.quit then
if minetest.get_modpath("unified_inventory") then if minetest.get_modpath("unified_inventory") then
@ -261,14 +321,16 @@ function mail.handle_receivefields(player, formname, fields)
if fields.back then if fields.back then
mail.show_inbox(name) mail.show_inbox(name)
return true -- don't uselessly set messages
elseif fields.reply then elseif fields.reply then
local message = messages[selected_message_idxs[name]] local message = messages[selected_message_idxs[name]]
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body mail.reply(name, message)
mail.show_compose(name, message.sender, "Re: "..message.subject, replyfooter) elseif fields.replyall then
local message = messages[selected_message_idxs[name]]
mail.replyall(name, message)
elseif fields.forward then elseif fields.forward then
local message = messages[selected_message_idxs[name]] local message = messages[selected_message_idxs[name]]
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body mail.forward(name, message.subject)
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
elseif fields.delete then elseif fields.delete then
if messages[selected_message_idxs[name]] then if messages[selected_message_idxs[name]] then
table.remove(messages,selected_message_idxs[name]) table.remove(messages,selected_message_idxs[name])
@ -283,10 +345,10 @@ function mail.handle_receivefields(player, formname, fields)
mail.send({ mail.send({
from = player:get_player_name(), from = player:get_player_name(),
to = fields.to, to = fields.to,
cc = "", cc = fields.cc,
bcc = "" bcc = fields.bcc,
subject = fields.subject, subject = fields.subject,
body = fields.body body = fields.body,
}) })
end end
minetest.after(0.5, function() minetest.after(0.5, function()
@ -323,7 +385,6 @@ function mail.handle_receivefields(player, formname, fields)
end end
mail.setContacts(name, contacts) mail.setContacts(name, contacts)
return true return true
end
elseif fields.new then elseif fields.new then
mail.show_edit_contact(name,"", "") mail.show_edit_contact(name,"", "")
elseif fields.edit then elseif fields.edit then

View File

@ -2,7 +2,18 @@
return the field normalized (comma separated, single space) return the field normalized (comma separated, single space)
and add individual player names to recipient list and add individual player names to recipient list
--]] --]]
function normalize_players_and_add_recipients(field, recipients) function mail.normalize_players_and_add_recipients(field, recipients)
local order = mail.parse_player_list(field)
for i,c in ipairs(order) do
if recipients[string.lower(c)] == nil then
recipients[string.lower(c)] = c
end
end
return mail.concat_player_list(order)
end
function mail.parse_player_list(field)
local separator = ", " local separator = ", "
local pattern = "([^" .. separator .. "]+)" local pattern = "([^" .. separator .. "]+)"
@ -10,17 +21,36 @@ function normalize_players_and_add_recipients(field, recipients)
local player_set = {} local player_set = {}
local order = {} local order = {}
field:gsub(pattern, function(c) field:gsub(pattern, function(c)
if player_set[string.lower(c)] ~= nil then if player_set[string.lower(c)] == nil then
player_set[string.lower(c)] = c player_set[string.lower(c)] = c
order[#order+1] = c order[#order+1] = c
-- also sort into recipients
if recipients[string.lower(c)] ~= nil then
recipients[string.lower(c)] = c
end
end end
end) end)
return order
end
function mail.concat_player_list(order)
-- turn list of players back into normalized string -- turn list of players back into normalized string
return table.concat(order, ", ") return table.concat(order, ", ")
end end
function mail.player_in_list(name, list)
if type(list) == "string" then
list = mail.parse_player_list(list)
end
for k,c in pairs(list) do
if name == c then
return true
end
end
return false
end
function mail.ensure_new_format(message)
if message.sender then
message.from = message.sender
message.to = name
end
end