From 0ea3777b514393d9e93200e0635b192280554c42 Mon Sep 17 00:00:00 2001 From: Athozus Date: Fri, 31 Mar 2023 17:14:52 +0200 Subject: [PATCH] Implement drafts (#31) * Add drafts * Update translations * Fix luacheck * Fix luacheck (2) --- api.lua | 51 ++++++++++++++++++++++++++++++++++++++++- init.lua | 2 ++ locale/mail.fr.tr | 53 +++++++++++++++++++++++-------------------- locale/mail.fr.tr.old | 44 ----------------------------------- locale/template.txt | 53 +++++++++++++++++++++++-------------------- storage.lua | 8 +++++++ ui/compose.lua | 44 ++++++++++++++++++++++++++++------- ui/drafts.lua | 49 +++++++++++++++++++++++++++++++++++++++ ui/events.lua | 25 +++++++++++++++++++- ui/inbox.lua | 2 +- ui/mail.lua | 4 +++- ui/outbox.lua | 2 +- 12 files changed, 230 insertions(+), 107 deletions(-) delete mode 100644 locale/mail.fr.tr.old create mode 100644 ui/drafts.lua diff --git a/api.lua b/api.lua index 24d1a47..d6128a2 100644 --- a/api.lua +++ b/api.lua @@ -63,9 +63,16 @@ function mail.send(m) m.from, m.to, extra_log, m.subject, m.body )) + + local id = mail.new_uuid() + if m.id then + mail.delete_mail(m.from, m.id) + id = m.id + end + -- form the actual mail local msg = { - id = mail.new_uuid(), + id = id, from = m.from, to = m.to, cc = m.cc, @@ -104,3 +111,45 @@ function mail.send(m) return true end + +function mail.save_draft(m) + if type(m.from) ~= "string" then return false, "'from' is not a string" end + if type(m.to) ~= "string" then return false, "'to' is not a string" end + if type(m.body) ~= "string" then return false, "'body' is not a string" end + + -- defaults + m.subject = m.subject or "(No subject)" + + -- limit subject line + if string.len(m.subject) > 30 then + m.subject = string.sub(m.subject,1,27) .. "..." + end + + minetest.log("action", f("[mail] %q saves draft with subject %q and body %q", + m.from, m.subject, m.body + )) + + -- remove it is an update + local id = mail.new_uuid() + if m.id then + mail.delete_mail(m.from, m.id) + id = m.id + end + + -- add (again ie. update) in sender drafts + local entry = mail.get_storage_entry(m.from) + table.insert(entry.drafts, 1, { + id = id, + from = m.from, + to = m.to, + cc = m.cc, + bcc = m.bcc, + subject = m.subject, + body = m.body, + time = os.time(), + }) + mail.set_storage_entry(m.from, entry) + + return true + +end diff --git a/init.lua b/init.lua index da280bb..8ed032f 100644 --- a/init.lua +++ b/init.lua @@ -15,6 +15,7 @@ mail = { selected_idxs = { inbox = {}, sent = {}, + drafts = {}, contacts = {}, maillists = {}, to = {}, @@ -47,6 +48,7 @@ dofile(MP .. "/onjoin.lua") dofile(MP .. "/ui/mail.lua") dofile(MP .. "/ui/inbox.lua") dofile(MP .. "/ui/outbox.lua") +dofile(MP .. "/ui/drafts.lua") dofile(MP .. "/ui/message.lua") dofile(MP .. "/ui/events.lua") dofile(MP .. "/ui/contacts.lua") diff --git a/locale/mail.fr.tr b/locale/mail.fr.tr index 1896a00..7f98350 100644 --- a/locale/mail.fr.tr +++ b/locale/mail.fr.tr @@ -1,46 +1,49 @@ # textdomain: mail BCC=Cci Cancel=Annuler +Save draft=Enregistrer le brouillon Send=Envoyer -Player name=Nom du joueur -your contacts.=vos contacts. -The contact=Ce contact -Save=Sauvegarder -That name=Ce nom -is already in=existe déjà -name cannot=nom ne peut pas -be empty.=être vide. -Note=Note -Maillist name=Nom de la liste de diffusion -Desc=Desc -Players=Joueurs -your maillists.=vos listes de diffusion. -The maillist=Cette liste de diffusion -Back=Retour -Mark Read=Marquer comme lu -Mark Unread=Marquer non lu -Delete=Supprimer -New=Nouveau -From=De +Edit=Modifier +No drafts= Inbox=Boîte de réception Sent messages=Messages envoyés -Read=Lire +Drafts=Brouillons Contacts=Contacts Mail lists=Listes de diffusion About=À propos Close=Fermer (No subject)=(Sans objet) -No mail=Aucun mail +Delete=Supprimer +New=Nouveau +Subject=Objet +Player name=Nom du joueur +your contacts.=vos contacts. +The contact=Ce contact +Maillist name=Nom de la liste de diffusion +Desc=Desc +Players=Joueurs +your maillists.=vos listes de diffusion. +The maillist=Cette liste de diffusion +Save=Sauvegarder +That name=Ce nom +is already in=existe déjà +name cannot=nom ne peut pas +be empty.=être vide. +Mark Read=Marquer comme lu +Mark Unread=Marquer non lu +From=De Reply=Répondre Reply all=Répondre à tous Forward=Transférer -Subject=Objet +Read=Lire +No mail=Aucun mail (No description)=Sans description No maillist=Aucune liste de diffusion -Edit=Modifier -Name=Nom Date=Date Add=Ajouter Remove=Enlever CC=Cc +Back=Retour +Name=Nom To=À +Note=Note diff --git a/locale/mail.fr.tr.old b/locale/mail.fr.tr.old deleted file mode 100644 index 6d445c3..0000000 --- a/locale/mail.fr.tr.old +++ /dev/null @@ -1,44 +0,0 @@ -# textdomain: mail -BCC=Cci -Cancel=Annuler -Send=Envoyer -Note=Note -Back=Retour -Delete=Supprimer -Edit=Modifier -Name=Nom -Player name=Nom du joueur -your contacts.=vos contacts. -The contact=Ce contact -Maillist name=Nom de la liste de diffusion -Desc=Desc -Players=Joueurs -your maillists.=vos listes de diffusion. -The maillist=Cette liste de diffusion -Save=Sauvegarder -That name=Ce nom -is already in=existe déjà -name cannot=nom ne peut pas -be empty.=être vide. -Mark Read=Marquer comme lu -Mark Unread=Marquer non lu -New=Nouveau -From=De -Reply=Répondre -Reply all=Répondre à tous -Forward=Transférer -Subject=Objet -Inbox=Boîte de réception -Sent messages=Messages envoyés -Read=Lire -Contacts=Contacts -Mail lists=Listes de diffusion -About=À propos -Close=Fermer -(No subject)=(Sans objet) -No mail=Aucun mail -(No description)=Sans description -No maillist=Aucune liste de diffusion -Date=Date -CC=Cc -To=À diff --git a/locale/template.txt b/locale/template.txt index 47e50fb..d7e75c5 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -1,46 +1,49 @@ # textdomain: mail BCC= Cancel= +Save draft= Send= -Player name= -your contacts.= -The contact= -Save= -That name= -is already in= -name cannot= -be empty.= -Note= -Maillist name= -Desc= -Players= -your maillists.= -The maillist= -Back= -Mark Read= -Mark Unread= -Delete= -New= -From= +Edit= +No drafts= Inbox= Sent messages= -Read= +Drafts= Contacts= Mail lists= About= Close= (No subject)= -No mail= +Delete= +New= +Subject= +Player name= +your contacts.= +The contact= +Maillist name= +Desc= +Players= +your maillists.= +The maillist= +Save= +That name= +is already in= +name cannot= +be empty.= +Mark Read= +Mark Unread= +From= Reply= Reply all= Forward= -Subject= +Read= +No mail= (No description)= No maillist= -Edit= -Name= Date= Add= Remove= CC= +Back= +Name= To= +Note= diff --git a/storage.lua b/storage.lua index 89a1eab..cacc076 100644 --- a/storage.lua +++ b/storage.lua @@ -7,6 +7,7 @@ local function populate_entry(e) e.contacts = e.contacts or {} e.inbox = e.inbox or {} e.outbox = e.outbox or {} + e.drafts = e.drafts or {} e.lists = e.lists or {} return e end @@ -83,6 +84,13 @@ function mail.delete_mail(playername, msg_id) return end end + for i, msg in ipairs(entry.drafts) do + if msg.id == msg_id then + table.remove(entry.drafts, i) + mail.set_storage_entry(playername, entry) + return + end + end end -- add or update a contact diff --git a/ui/compose.lua b/ui/compose.lua index d80d8aa..6aa78a2 100644 --- a/ui/compose.lua +++ b/ui/compose.lua @@ -1,6 +1,7 @@ local FORMNAME = "mail:compose" +local msg_id = nil -function mail.show_compose(name, to, subject, body, cc, bcc) +function mail.show_compose(name, to, subject, body, cc, bcc, id) local formspec = [[ size[8,9] button[0,0;1,1;tocontacts;]] .. S("To") .. [[:] @@ -11,16 +12,21 @@ function mail.show_compose(name, to, subject, body, cc, bcc) field[5.1,1.05;3.1,1;bcc;;%s] field[0.25,2;8,1;subject;]] .. S("Subject") .. [[:;%s] textarea[0.25,2.5;8,6;body;;%s] - button[0.5,8.5;3,1;cancel;]] .. S("Cancel") .. [[] - button[4.5,8.5;3,1;send;]] .. S("Send") .. [[] + button[0.1,8.5;2.5,1;cancel;]] .. S("Cancel") .. [[] + button[2.7,8.5;2.5,1;draft;]] .. S("Save draft") .. [[] + button[5.3,8.5;2.5,1;send;]] .. S("Send") .. [[] ]] .. mail.theme formspec = string.format(formspec, - minetest.formspec_escape(to or ""), - minetest.formspec_escape(cc or ""), - minetest.formspec_escape(bcc or ""), - minetest.formspec_escape(subject or ""), - minetest.formspec_escape(body or "")) + minetest.formspec_escape(to) or "", + minetest.formspec_escape(cc) or "", + minetest.formspec_escape(bcc) or "", + minetest.formspec_escape(subject) or "", + minetest.formspec_escape(body) or "") + + if id then + msg_id = id + end minetest.show_formspec(name, FORMNAME, formspec) end @@ -32,7 +38,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local name = player:get_player_name() if fields.send then + local id = mail.new_uuid() + if msg_id then + id = msg_id + end local success, err = mail.send({ + id = id, from = name, to = fields.to, cc = fields.cc, @@ -82,6 +93,23 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) elseif fields.cancel then mail.message_drafts[name] = nil + mail.show_mail_menu(name) + + elseif fields.draft then + local id = mail.new_uuid() + if msg_id then + id = msg_id + end + mail.save_draft({ + id = id, + from = name, + to = fields.to, + cc = fields.cc, + bcc = fields.bcc, + subject = fields.subject, + body = fields.body + }) + mail.show_mail_menu(name) end diff --git a/ui/drafts.lua b/ui/drafts.lua new file mode 100644 index 0000000..4237677 --- /dev/null +++ b/ui/drafts.lua @@ -0,0 +1,49 @@ +local drafts_formspec = "size[8.5,10;]" .. mail.theme .. [[ + tabheader[0.3,1;boxtab;]] .. S("Inbox") .. "," .. S("Sent messages").. "," .. S("Drafts") .. [[;3;false;false] + + button[6,0.10;2.5,0.5;new;]] .. S("New") .. [[] + button[6,0.95;2.5,0.5;edit;]] .. S("Edit") .. [[] + button[6,1.70;2.5,0.5;delete;]] .. S("Delete") .. [[] + button[6,6.8;2.5,0.5;contacts;]] .. S("Contacts") .. [[] + button[6,7.6;2.5,0.5;maillists;]] .. S("Mail lists") .. [[] + button[6,8.7;2.5,0.5;about;]] .. S("About") .. [[] + button_exit[6,9.5;2.5,0.5;quit;]] .. S("Close") .. [[] + + tablecolumns[color;text;text] + table[0,0.7;5.75,9.35;drafts;#999,]] .. S("To") .. "," .. S("Subject") + + +function mail.show_drafts(name) + local formspec = { drafts_formspec } + local entry = mail.get_storage_entry(name) + local messages = entry.drafts + + mail.message_drafts[name] = nil + + if messages[1] then + for _, message in ipairs(messages) do + formspec[#formspec + 1] = "," + formspec[#formspec + 1] = "," + formspec[#formspec + 1] = minetest.formspec_escape(message.to) + formspec[#formspec + 1] = "," + if message.subject ~= "" then + if string.len(message.subject) > 30 then + formspec[#formspec + 1] = minetest.formspec_escape(string.sub(message.subject, 1, 27)) + formspec[#formspec + 1] = "..." + else + formspec[#formspec + 1] = minetest.formspec_escape(message.subject) + end + else + formspec[#formspec + 1] = S("(No subject)") + end + end + if mail.selected_idxs.sent[name] then + formspec[#formspec + 1] = ";" + formspec[#formspec + 1] = tostring(mail.selected_idxs.sent[name] + 1) + end + formspec[#formspec + 1] = "]" + else + formspec[#formspec + 1] = "]label[2.25,4.5;" .. S("No drafts") .. "]" + end + minetest.show_formspec(name, "mail:drafts", table.concat(formspec, "")) +end diff --git a/ui/events.lua b/ui/events.lua index 04fc878..4f7c1df 100644 --- a/ui/events.lua +++ b/ui/events.lua @@ -1,5 +1,5 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) - if formname ~= "mail:inbox" and formname ~= "mail:sent" then + if formname ~= "mail:inbox" and formname ~= "mail:sent" and formname ~= "mail:drafts" then return end @@ -10,6 +10,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local messagesInbox = entry.inbox local messagesSent = entry.outbox + local messagesDrafts = entry.drafts if fields.inbox then -- inbox table local evt = minetest.explode_table_event(fields.inbox) @@ -29,6 +30,22 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) return true end + if fields.drafts then -- drafts table + local evt = minetest.explode_table_event(fields.drafts) + mail.selected_idxs.drafts[name] = evt.row - 1 + if evt.type == "DCL" and messagesDrafts[mail.selected_idxs.drafts[name]] then + mail.show_compose(name, + messagesDrafts[mail.selected_idxs.drafts[name]].to, + messagesDrafts[mail.selected_idxs.drafts[name]].subject, + messagesDrafts[mail.selected_idxs.drafts[name]].body, + messagesDrafts[mail.selected_idxs.drafts[name]].cc, + messagesDrafts[mail.selected_idxs.drafts[name]].bcc, + messagesDrafts[mail.selected_idxs.drafts[name]].id + ) + end + return true + end + if fields.boxtab == "1" then mail.selected_idxs.boxtab[name] = 1 mail.show_inbox(name) @@ -37,6 +54,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mail.selected_idxs.boxtab[name] = 2 mail.show_sent(name) + elseif fields.boxtab == "3" then + mail.selected_idxs.boxtab[name] = 3 + mail.show_drafts(name) + elseif fields.read then if formname == "mail:inbox" and messagesInbox[mail.selected_idxs.inbox[name]] then -- inbox table mail.show_message(name, messagesInbox[mail.selected_idxs.inbox[name]].id) @@ -49,6 +70,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mail.delete_mail(name, messagesInbox[mail.selected_idxs.inbox[name]].id) elseif formname == "mail:sent" and messagesSent[mail.selected_idxs.sent[name]] then -- sent table mail.delete_mail(name, messagesSent[mail.selected_idxs.sent[name]].id) + elseif formname == "mail:drafts" and messagesDrafts[mail.selected_idxs.drafts[name]] then -- drafts table + mail.delete_mail(name, messagesDrafts[mail.selected_idxs.drafts[name]].id) end mail.show_mail_menu(name) diff --git a/ui/inbox.lua b/ui/inbox.lua index fcb78b9..82042c4 100644 --- a/ui/inbox.lua +++ b/ui/inbox.lua @@ -1,5 +1,5 @@ local inbox_formspec = "size[8.5,10;]" .. mail.theme .. [[ - tabheader[0.3,1;boxtab;]] .. S("Inbox") .. "," .. S("Sent messages") .. [[;1;false;false] + tabheader[0.3,1;boxtab;]] .. S("Inbox") .. "," .. S("Sent messages").. "," .. S("Drafts") .. [[;1;false;false] button[6,0.10;2.5,0.5;new;]] .. S("New") .. [[] button[6,0.95;2.5,0.5;read;]] .. S("Read") .. [[] diff --git a/ui/mail.lua b/ui/mail.lua index 47b92ad..6f7cbe0 100644 --- a/ui/mail.lua +++ b/ui/mail.lua @@ -6,5 +6,7 @@ function mail.show_mail_menu(playername) mail.show_inbox(playername) elseif index == 2 then mail.show_sent(playername) + elseif index == 3 then + mail.show_drafts(playername) end -end \ No newline at end of file +end diff --git a/ui/outbox.lua b/ui/outbox.lua index 6377405..dd2480d 100644 --- a/ui/outbox.lua +++ b/ui/outbox.lua @@ -1,5 +1,5 @@ local sent_formspec = "size[8.5,10;]" .. mail.theme .. [[ - tabheader[0.3,1;boxtab;]] .. S("Inbox") .. "," .. S("Sent messages") .. [[;2;false;false] + tabheader[0.3,1;boxtab;]] .. S("Inbox") .. "," .. S("Sent messages").. "," .. S("Drafts") .. [[;2;false;false] button[6,0.10;2.5,0.5;new;]] .. S("New") .. [[] button[6,0.95;2.5,0.5;read;]] .. S("Read") .. [[]