From bf0a7dad9ddfcc93fd02699d6804688c7bfe8cdd Mon Sep 17 00:00:00 2001 From: Athozus Date: Mon, 15 Apr 2024 23:55:54 +0200 Subject: [PATCH] Extend sorters/filters to drafts and trash --- ui/drafts.lua | 108 +++++++++++++++++++++++++++++---------- ui/events.lua | 132 +++++++++++++++++++++++++++++++++-------------- ui/trash.lua | 138 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 269 insertions(+), 109 deletions(-) diff --git a/ui/drafts.lua b/ui/drafts.lua index a7da0a0..7b32b07 100644 --- a/ui/drafts.lua +++ b/ui/drafts.lua @@ -1,9 +1,34 @@ -- translation local S = minetest.get_translator("mail") +function mail.show_drafts(name, sortfieldindex, sortdirection, filter) + sortfieldindex = tonumber(sortfieldindex or mail.selected_idxs.sortfield[name]) + or mail.get_setting(name, "defaultsortfield") or 3 + sortdirection = tostring(sortdirection or mail.selected_idxs.sortdirection[name] + or mail.get_setting(name, "defaultsortdirection") or "1") + filter = filter or mail.selected_idxs.filter[name] or "" + mail.selected_idxs.drafts[name] = mail.selected_idxs.drafts[name] or {} -function mail.show_drafts(name) - local trash_tab = "" + local entry = mail.get_storage_entry(name) + local sortfield = ({"from","subject","time"})[sortfieldindex] + local messages = mail.sort_messages(entry.drafts, sortfield, sortdirection == "2", filter) + + if mail.selected_idxs.drafts[name] and #mail.selected_idxs.drafts[name] > 0 then + for i, selected_msg in ipairs(mail.selected_idxs.drafts[name]) do + local is_present = false + for _, msg in ipairs(messages) do + if msg.id == selected_msg then + is_present = true + break + end + end + if not is_present then + table.remove(mail.selected_idxs.drafts[name], i) + end + end + end + + local trash_tab = "" if mail.get_setting(name, "trash_move_enable") then trash_tab = "," .. S("Trash") end @@ -20,39 +45,66 @@ function mail.show_drafts(name) button[6,9.7;2.5,0.5;options;]] .. S("Options") .. [[] button_exit[6,10.5;2.5,0.5;quit;]] .. S("Close") .. [[] + dropdown[0,9.5;2,0.5;sortfield;]] .. + S("From") .. "," .. S("Subject") .. "," .. S("Date") .. [[;]] .. sortfieldindex .. [[;true] + dropdown[2.0,9.5;2,0.5;sortdirection;]] .. + S("Ascending") .. "," .. S("Descending") .. [[;]] .. sortdirection .. [[;true] + field[4.25,9.95;1.4,0.5;filter;]] .. S("Filter") .. [[:;]] .. filter .. [[] + image_button[5.14,9.5;0.85,0.85;search.png;search;] + + checkbox[0,10.1;multipleselection;]] .. S("Allow multiple selection") .. [[;]] .. + tostring(mail.selected_idxs.multipleselection[name]) .. [[] + label[0,10.65;]] .. + S("@1 of @2 selected", tostring(#mail.selected_idxs.drafts[name]), tostring(#messages)) .. [[] + button[3.5,10.5;2.5,0.5;selectall;]] .. S("(Un)select all") .. [[] + tablecolumns[color;text;text] - table[0,0.7;5.75,10.35;drafts;]] .. mail.get_color("header") .. "," .. S("To") .. "," .. S("Subject") + table[0,0.7;5.75,8.45;drafts;]] .. mail.get_color("header") .. "," .. S("To") .. "," .. S("Subject") 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 + if #messages > 0 then + for _, message in ipairs(messages) do + local selected_id = 0 + local displayed_color = {} + -- check if message is in selection list and return its id + if mail.selected_idxs.drafts[name] and #mail.selected_idxs.drafts[name] > 0 then + for i, selected_msg in ipairs(mail.selected_idxs.drafts[name]) do + if message.id == selected_msg then + selected_id = i + break + end + end + end + if selected_id > 0 then + table.insert(displayed_color, "selected") + end + formspec[#formspec + 1] = "," .. mail.get_color(displayed_color) + formspec[#formspec + 1] = "," + if string.len(message.to) > 20 then + formspec[#formspec + 1] = minetest.formspec_escape(string.sub(message.to, 1, 17)) + formspec[#formspec + 1] = "..." else - formspec[#formspec + 1] = S("(No subject)") + formspec[#formspec + 1] = minetest.formspec_escape(message.to) end - end - if mail.selected_idxs.drafts[name] then - formspec[#formspec + 1] = ";" - formspec[#formspec + 1] = tostring(mail.selected_idxs.drafts[name] + 1) - end - formspec[#formspec + 1] = "]" - else - formspec[#formspec + 1] = "]label[2.25,4.5;" .. S("No drafts") .. "]" - end + 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 + formspec[#formspec + 1] = "]" + else + formspec[#formspec + 1] = "]label[2.25,4.5;" .. S("No mail") .. "]" + end + minetest.show_formspec(name, "mail:drafts", table.concat(formspec, "")) end diff --git a/ui/events.lua b/ui/events.lua index 2686c9d..c3cab2a 100644 --- a/ui/events.lua +++ b/ui/events.lua @@ -24,6 +24,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) return true end + local boxes = {"inbox", "outbox", "drafts", "trash"} + -- Get player name and handle / convert common input fields local name = player:get_player_name() local filter = (fields.search and fields.filter) or mail.selected_idxs.filter[name] or "" @@ -32,9 +34,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local inboxsortfield = ({"from","subject","time"})[sortfieldindex] local outboxsortfield = ({"to","subject","time"})[sortfieldindex] - -- Be sure that inbox/outbox selected idxs aren't nil - mail.selected_idxs.inbox[name] = mail.selected_idxs.inbox[name] or {} - mail.selected_idxs.outbox[name] = mail.selected_idxs.outbox[name] or {} + -- Be sure that selected idxs aren't nil + for _, b in ipairs(boxes) do + mail.selected_idxs[b][name] = mail.selected_idxs[b][name] or {} + end -- Store common player configuration for reuse mail.selected_idxs.sortfield[name] = sortfieldindex @@ -46,16 +49,17 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) -- Avoid several selected after disabling the multiple selection if not mail.selected_idxs.multipleselection[name] then - mail.selected_idxs.inbox[name] = { mail.selected_idxs.inbox[name][#mail.selected_idxs.inbox[name]] } - mail.selected_idxs.outbox[name] = { mail.selected_idxs.outbox[name][#mail.selected_idxs.outbox[name]] } + for _, b in ipairs(boxes) do + mail.selected_idxs[b][name] = { mail.selected_idxs[b][name][#mail.selected_idxs[b][name]] } + end end -- split inbox and outbox msgs for different tests local entry = mail.get_storage_entry(name) - local messagesDrafts = entry.drafts - local messagesTrash = entry.trash local getInbox = message_getter(entry.inbox, inboxsortfield, sortdirection == "2", filter) local getOutbox = message_getter(entry.outbox, outboxsortfield, sortdirection == "2", filter) + local getDrafts = message_getter(entry.drafts, inboxsortfield, sortdirection == "2", filter) + local getTrash = message_getter(entry.trash, outboxsortfield, sortdirection == "2", filter) -- Hanmdle formspec event if fields.inbox then -- inbox table @@ -158,18 +162,44 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end mail.selected_idxs.sortfield[name] = evt.column-1 -- update column mail.show_mail_menu(name) - return + return true end - mail.selected_idxs.drafts[name] = evt.row - 1 - if evt.type == "DCL" and messagesDrafts[mail.selected_idxs.drafts[name]] then - mail.selected_idxs.message[name] = messagesDrafts[mail.selected_idxs.drafts[name]].id + local drafts = getDrafts()[evt.row-1] + if not drafts then + mail.show_mail_menu(name) + return true + end + if mail.selected_idxs.multipleselection[name] then + if not mail.selected_idxs.drafts[name] then + mail.selected_idxs.drafts[name] = {} + end + local selected_id = 0 + if mail.selected_idxs.drafts[name] and #mail.selected_idxs.drafts[name] > 0 then + for i, selected_msg in ipairs(mail.selected_idxs.drafts[name]) do + if drafts.id == selected_msg then + selected_id = i + table.remove(mail.selected_idxs.drafts[name], i) + break + end + end + end + if selected_id == 0 then + table.insert(mail.selected_idxs.drafts[name], drafts.id) + mail.selected_idxs.message[name] = drafts.id + end + else + mail.selected_idxs.drafts[name] = { drafts } + mail.selected_idxs.message[name] = drafts.id + end + if evt.type == "DCL" then + mail.selected_idxs.message[name] = drafts.id 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 + drafts.to, + drafts.subject, + drafts.body, + drafts.cc, + drafts.bcc, + drafts.id ) end return true @@ -183,12 +213,38 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end mail.selected_idxs.sortfield[name] = evt.column-1 -- update column mail.show_mail_menu(name) - return + return true end - mail.selected_idxs.trash[name] = evt.row - 1 - if evt.type == "DCL" and messagesTrash[mail.selected_idxs.trash[name]] then - mail.selected_idxs.message[name] = messagesTrash[mail.selected_idxs.trash[name]].id - mail.show_message(name, messagesTrash[mail.selected_idxs.trash[name]].id) + local trash = getTrash()[evt.row-1] + if not trash then + mail.show_mail_menu(name) + return true + end + if mail.selected_idxs.multipleselection[name] then + if not mail.selected_idxs.trash[name] then + mail.selected_idxs.trash[name] = {} + end + local selected_id = 0 + if mail.selected_idxs.trash[name] and #mail.selected_idxs.trash[name] > 0 then + for i, selected_msg in ipairs(mail.selected_idxs.trash[name]) do + if trash.id == selected_msg then + selected_id = i + table.remove(mail.selected_idxs.trash[name], i) + break + end + end + end + if selected_id == 0 then + table.insert(mail.selected_idxs.trash[name], trash.id) + mail.selected_idxs.message[name] = trash.id + end + else + mail.selected_idxs.trash[name] = { trash.id } + mail.selected_idxs.message[name] = trash.id + end + if evt.type == "DCL" then + mail.selected_idxs.message[name] = trash.id + mail.show_message(name, trash.id) end return true end @@ -214,22 +270,22 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mail.selected_idxs.message[name] = mail.selected_idxs.inbox[name][#mail.selected_idxs.inbox[name]] elseif formname == "mail:outbox" and nonempty(mail.selected_idxs.outbox[name]) then -- outbox table mail.selected_idxs.message[name] = mail.selected_idxs.outbox[name][#mail.selected_idxs.outbox[name]] - elseif formname == "mail:trash" and messagesTrash[mail.selected_idxs.trash[name]] then - mail.selected_idxs.message[name] = messagesTrash[mail.selected_idxs.trash[name]].id + elseif formname == "mail:trash" and mail.selected_idxs.trash[name] then + mail.selected_idxs.message[name] = mail.selected_idxs.trash[name] end if mail.selected_idxs.message[name] then mail.show_message(name, mail.selected_idxs.message[name]) end elseif fields.edit then - if formname == "mail:drafts" and messagesDrafts[mail.selected_idxs.drafts[name]] then + if formname == "mail:drafts" and 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 + mail.selected_idxs.drafts[name].to, + mail.selected_idxs.drafts[name].subject, + mail.selected_idxs.drafts[name].body, + mail.selected_idxs.drafts[name].cc, + mail.selected_idxs.drafts[name].bcc, + mail.selected_idxs.drafts[name].id ) end @@ -249,23 +305,23 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mail.delete_mail(name, mail.selected_idxs.outbox[name]) end mail.selected_idxs.outbox[name] = {} - elseif formname == "mail:drafts" and messagesDrafts[mail.selected_idxs.drafts[name]] then -- drafts table + elseif formname == "mail:drafts" and mail.selected_idxs.drafts[name] then -- drafts table if trash_enabled then - mail.trash_mail(name, messagesDrafts[mail.selected_idxs.drafts[name]].id) + mail.trash_mail(name, mail.selected_idxs.drafts[name]) else - mail.delete_mail(name, messagesDrafts[mail.selected_idxs.drafts[name]].id) + mail.delete_mail(name, mail.selected_idxs.drafts[name]) end mail.selected_idxs.drafts[name] = nil - elseif formname == "mail:trash" and messagesTrash[mail.selected_idxs.trash[name]] then -- trash table - mail.delete_mail(name, messagesTrash[mail.selected_idxs.trash[name]].id, true) + elseif formname == "mail:trash" and mail.selected_idxs.trash[name] then -- trash table + mail.delete_mail(name, mail.selected_idxs.trash[name], true) end mail.show_mail_menu(name, sortfieldindex, sortdirection, filter) elseif fields.restore then - if messagesTrash[mail.selected_idxs.trash[name]] then - mail.restore_mail(name, messagesTrash[mail.selected_idxs.trash[name]].id) + if mail.selected_idxs.trash[name] then + mail.restore_mail(name, mail.selected_idxs.trash[name]) end mail.show_mail_menu(name, sortfieldindex, sortdirection, filter) diff --git a/ui/trash.lua b/ui/trash.lua index e90f0ea..fbb0f8b 100644 --- a/ui/trash.lua +++ b/ui/trash.lua @@ -1,53 +1,105 @@ -- translation local S = minetest.get_translator("mail") -local trash_formspec = "size[8.5,11;]" .. mail.theme .. [[ - tabheader[0.3,1;boxtab;]] .. - S("Inbox") .. "," .. S("Outbox").. "," .. S("Drafts") .. "," .. S("Trash") .. [[;4;false;false] +function mail.show_trash(name, sortfieldindex, sortdirection, filter) + sortfieldindex = tonumber(sortfieldindex or mail.selected_idxs.sortfield[name]) + or mail.get_setting(name, "defaultsortfield") or 3 + sortdirection = tostring(sortdirection or mail.selected_idxs.sortdirection[name] + or mail.get_setting(name, "defaultsortdirection") or "1") + filter = filter or mail.selected_idxs.filter[name] or "" + mail.selected_idxs.trash[name] = mail.selected_idxs.trash[name] or {} - button[6,0.10;2.5,0.5;new;]] .. S("New") .. [[] - button[6,0.95;2.5,0.5;read;]] .. S("Read") .. [[] - button[6,1.70;2.5,0.5;restore;]] .. S("Restore") .. [[] - button[6,2.45;2.5,0.5;delete;]] .. S("Delete") .. [[] - button[6,3.20;2.5,0.5;empty;]] .. S("Empty") .. [[] - button[6,8.0;2.5,0.5;contacts;]] .. S("Contacts") .. [[] - button[6,8.8;2.5,0.5;maillists;]] .. S("Mail lists") .. [[] - button[6,9.7;2.5,0.5;options;]] .. S("Options") .. [[] - button_exit[6,10.5;2.5,0.5;quit;]] .. S("Close") .. [[] - - tablecolumns[color;text;text] - table[0,0.7;5.75,10.35;trash;]] .. mail.get_color("header") .. "," .. S("From/To") .. "," .. S("Subject") - - -function mail.show_trash(name) - local formspec = { trash_formspec } local entry = mail.get_storage_entry(name) - local messages = entry.trash + local sortfield = ({"from","subject","time"})[sortfieldindex] + local messages = mail.sort_messages(entry.trash, sortfield, sortdirection == "2", filter) - 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 + if mail.selected_idxs.trash[name] and #mail.selected_idxs.trash[name] > 0 then + for i, selected_msg in ipairs(mail.selected_idxs.trash[name]) do + local is_present = false + for _, msg in ipairs(messages) do + if msg.id == selected_msg then + is_present = true + break + end + end + if not is_present then + table.remove(mail.selected_idxs.trash[name], i) + end + end + end + + local trash_formspec = "size[8.5,11;]" .. mail.theme .. [[ + tabheader[0.3,1;boxtab;]] .. + S("Inbox") .. "," .. S("Outbox").. "," .. S("Drafts") .. "," .. S("Trash") .. [[;4;false;false] + + button[6,0.10;2.5,0.5;new;]] .. S("New") .. [[] + button[6,0.95;2.5,0.5;read;]] .. S("Read") .. [[] + button[6,1.70;2.5,0.5;restore;]] .. S("Restore") .. [[] + button[6,2.45;2.5,0.5;delete;]] .. S("Delete") .. [[] + button[6,3.20;2.5,0.5;empty;]] .. S("Empty") .. [[] + button[6,8.0;2.5,0.5;contacts;]] .. S("Contacts") .. [[] + button[6,8.8;2.5,0.5;maillists;]] .. S("Mail lists") .. [[] + button[6,9.7;2.5,0.5;options;]] .. S("Options") .. [[] + button_exit[6,10.5;2.5,0.5;quit;]] .. S("Close") .. [[] + + dropdown[0,9.5;2,0.5;sortfield;]] .. + S("From") .. "," .. S("Subject") .. "," .. S("Date") .. [[;]] .. sortfieldindex .. [[;true] + dropdown[2.0,9.5;2,0.5;sortdirection;]] .. + S("Ascending") .. "," .. S("Descending") .. [[;]] .. sortdirection .. [[;true] + field[4.25,9.95;1.4,0.5;filter;]] .. S("Filter") .. [[:;]] .. filter .. [[] + image_button[5.14,9.5;0.85,0.85;search.png;search;] + + checkbox[0,10.1;multipleselection;]] .. S("Allow multiple selection") .. [[;]] .. + tostring(mail.selected_idxs.multipleselection[name]) .. [[] + label[0,10.65;]] .. + S("@1 of @2 selected", tostring(#mail.selected_idxs.trash[name]), tostring(#messages)) .. [[] + button[3.5,10.5;2.5,0.5;selectall;]] .. S("(Un)select all") .. [[] + + tablecolumns[color;text;text] + table[0,0.7;5.75,8.45;trash;]] .. mail.get_color("header") .. "," .. S("From/To") .. "," .. S("Subject") + + local formspec = { trash_formspec } + + if #messages > 0 then + for _, message in ipairs(messages) do + local selected_id = 0 + local displayed_color = {} + -- check if message is in selection list and return its id + if mail.selected_idxs.trash[name] and #mail.selected_idxs.trash[name] > 0 then + for i, selected_msg in ipairs(mail.selected_idxs.trash[name]) do + if message.id == selected_msg then + selected_id = i + break + end + end + end + if selected_id > 0 then + table.insert(displayed_color, "selected") + end + formspec[#formspec + 1] = "," .. mail.get_color(displayed_color) + formspec[#formspec + 1] = "," + if string.len(message.to) > 20 then + formspec[#formspec + 1] = minetest.formspec_escape(string.sub(message.to, 1, 17)) + formspec[#formspec + 1] = "..." else - formspec[#formspec + 1] = S("(No subject)") + formspec[#formspec + 1] = minetest.formspec_escape(message.to) end - end - if mail.selected_idxs.trash[name] then - formspec[#formspec + 1] = ";" - formspec[#formspec + 1] = tostring(mail.selected_idxs.trash[name] + 1) - end - formspec[#formspec + 1] = "]" - else - formspec[#formspec + 1] = "]label[2.25,4.5;" .. S("Trash is empty") .. "]" - end + 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 + formspec[#formspec + 1] = "]" + else + formspec[#formspec + 1] = "]label[2.25,4.5;" .. S("No mail") .. "]" + end + minetest.show_formspec(name, "mail:trash", table.concat(formspec, "")) end