Message filters/sorters (#56)

* Add sorters for inbox/outbox

* Add ascending/descending, fix selection issue

* Add filters

* Update translations

* Fix UI

* Fix luacheck

* Fix fields disappearing after clicking on tabs/buttons

* Fix luacheck (2)

* Fix first message not sorted correctly
This commit is contained in:
Athozus 2023-04-07 10:19:30 +02:00 committed by GitHub
parent def93bdd0f
commit da05b5d108
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 265 additions and 116 deletions

View File

@ -1,6 +1,6 @@
minetest.register_chatcommand("mail",{
description = "Open the mail interface",
func = function(name)
mail.show_inbox(name)
mail.show_inbox(name, "3", "1", "")
end
})

View File

@ -3,12 +3,12 @@ BCC=BCC
Cancel=Abbrechen
Save draft=Entwurf Speichern
Send=Senden
Subject=Betreff
To=An
CC=CC
No drafts=Keine Entwürfe
Edit=Bearbeiten
Note=Notiz
New=Neu
Delete=Löschen
Name=Name
No drafts=Keine Entwürfe
Player name=Spielername
your contacts.=ihre Kontakte.
The contact=Der Kontakt
@ -17,21 +17,20 @@ Desc=Beschreibung
Players=Spieler
your maillists.=ihre Verteilerlisten.
The maillist=Die Verteilerliste
Back=Zurück
Save=Speichern
That name=Der Name
is already in=ist bereits in
name cannot=Name kann nicht
be empty.=leer sein.
Back=Zurück
Mark Read=Als gelesen makieren
Mark Unread=Als ungelesen makieren
(No description)=(Keine Beschreibung)
No maillist=Keine Verteilerliste
Note=Notiz
Edit=Bearbeiten
Name=Name
Date=Datum
From=Von
Read=Lesen
Ascending=
Descending=
Filter=
No mail=Keine Nachrichten
Inbox=Posteingang
Sent messages=Nachrichten senden
Drafts=Entwürfe
@ -40,10 +39,14 @@ Mail lists=Verteilerlisten
About=Über
Close=Schließen
(No subject)=(Kein Betreff)
Read=Lesen
No mail=Keine Nachrichten
Date=Datum
Reply=Antworten
Reply all=Allen antworten
Forward=Weiter
(No description)=(Keine Beschreibung)
No maillist=Keine Verteilerliste
Subject=Betreff
To=An
Delete=Löschen
Add=Hinzufügen
Remove=Entfernen

View File

@ -3,19 +3,12 @@ BCC=Cci
Cancel=Annuler
Save draft=Enregistrer le brouillon
Send=Envoyer
CC=Cc
Edit=Modifier
No drafts=
Inbox=Boîte de réception
Sent messages=Messages envoyés
Drafts=Brouillons
Contacts=Contacts
Mail lists=Listes de diffusion
About=À propos
Close=Fermer
(No subject)=(Sans objet)
Delete=Supprimer
Note=Note
New=Nouveau
Subject=Objet
Name=Nom
No drafts=Pas de brouillons
Player name=Nom du joueur
your contacts.=vos contacts.
The contact=Ce contact
@ -24,6 +17,7 @@ Desc=Desc
Players=Joueurs
your maillists.=vos listes de diffusion.
The maillist=Cette liste de diffusion
Back=Retour
Save=Sauvegarder
That name=Ce nom
is already in=existe déjà
@ -32,18 +26,27 @@ be empty.=être vide.
Mark Read=Marquer comme lu
Mark Unread=Marquer non lu
From=De
Read=Lire
Ascending=Croissant
Descending=Décroissant
Filter=Filtre
No mail=Aucun mail
Inbox=Boîte de réception
Sent messages=Messages envoyés
Drafts=Brouillons
Contacts=Contacts
Mail lists=Listes de diffusion
About=À propos
Close=Fermer
(No subject)=(Sans objet)
Date=Date
Reply=Répondre
Reply all=Répondre à tous
Forward=Transférer
Read=Lire
No mail=Aucun mail
(No description)=Sans description
No maillist=Aucune liste de diffusion
Date=Date
Subject=Objet
To=À
Delete=Supprimer
Add=Ajouter
Remove=Enlever
CC=Cc
Back=Retour
Name=Nom
To=À
Note=Note

View File

@ -3,19 +3,12 @@ BCC=密件副本
Cancel=取消
Save draft=儲存草稿
Send=發送
CC=副本
Edit=編輯
No drafts=沒有草稿
Inbox=收件箱
Sent messages=寄件備份
Drafts=草稿
Contacts=聯繫人
Mail lists=郵件列表
About=關於
Close=關閉
(No subject)=(沒有主旨)
Delete=刪除
Note=備註
New=新建
Subject=主旨
Name=名稱
No drafts=沒有草稿
Player name=玩家名稱
your contacts.=
The contact=
@ -24,6 +17,7 @@ Desc=描述
Players=玩家
your maillists.=
The maillist=
Back=返回
Save=儲存
That name=
is already in=
@ -32,18 +26,27 @@ be empty.=
Mark Read=標記已讀
Mark Unread=標記未讀
From=寄件者
Read=閱讀
Ascending=
Descending=
Filter=
No mail=沒有郵件
Inbox=收件箱
Sent messages=寄件備份
Drafts=草稿
Contacts=聯繫人
Mail lists=郵件列表
About=關於
Close=關閉
(No subject)=(沒有主旨)
Date=日期
Reply=回覆
Reply all=回覆所有人
Forward=轉寄
Read=閱讀
No mail=沒有郵件
(No description)=(沒有描述)
No maillist=沒有郵件列表
Date=日期
Subject=主旨
To=收件人
Delete=刪除
Add=加入
Remove=移除
CC=副本
Back=返回
Name=名稱
To=收件人
Note=備註

View File

@ -3,19 +3,12 @@ BCC=
Cancel=
Save draft=
Send=
CC=
Edit=
No drafts=
Inbox=
Sent messages=
Drafts=
Contacts=
Mail lists=
About=
Close=
(No subject)=
Delete=
Note=
New=
Subject=
Name=
No drafts=
Player name=
your contacts.=
The contact=
@ -24,6 +17,7 @@ Desc=
Players=
your maillists.=
The maillist=
Back=
Save=
That name=
is already in=
@ -32,18 +26,27 @@ be empty.=
Mark Read=
Mark Unread=
From=
Read=
Ascending=
Descending=
Filter=
No mail=
Inbox=
Sent messages=
Drafts=
Contacts=
Mail lists=
About=
Close=
(No subject)=
Date=
Reply=
Reply all=
Forward=
Read=
No mail=
(No description)=
No maillist=
Date=
Subject=
To=
Delete=
Add=
Remove=
CC=
Back=
Name=
To=
Note=

View File

@ -43,6 +43,77 @@ function mail.get_message(playername, msg_id)
end
end
function mail.sort_messages(unsorted_messages, sortfield, sortdirection)
local messages = {}
if not sortfield or sortfield == "" then
sortfield = "3"
end
if not sortdirection or sortdirection == "" then
sortdirection = "1"
end
if unsorted_messages[1] then
-- add first message
table.insert(messages, unsorted_messages[1])
table.remove(unsorted_messages, 1)
-- sort messages
for _, unsorted_msg in ipairs(unsorted_messages) do
local is_message_sorted = false
for j, sorted_msg in ipairs(messages) do
if sortfield == "1" and unsorted_msg.from >= sorted_msg.from then -- for inbox
table.insert(messages, j, unsorted_msg)
is_message_sorted = true
break
elseif sortfield == "1" and unsorted_msg.to >= sorted_msg.to then -- for outbox
table.insert(messages, j, unsorted_msg)
is_message_sorted = true
break
elseif sortfield == "2" and unsorted_msg.subject >= sorted_msg.subject then
table.insert(messages, j, unsorted_msg)
is_message_sorted = true
break
elseif sortfield == "3" and unsorted_msg.time >= sorted_msg.time then
table.insert(messages, j, unsorted_msg)
is_message_sorted = true
break
end
end
if not is_message_sorted then
table.insert(messages, 1, unsorted_msg)
end
end
end
-- reverse for descending
local sorted_messages = messages
if sortdirection == "2" then
sorted_messages = {}
for i=#messages, 1, -1 do
sorted_messages[#sorted_messages+1] = messages[i]
end
end
return sorted_messages
end
function mail.filter_messages(unfiltered_messages, filter)
if not filter or filter == "" then
return unfiltered_messages
end
local filtered_messages = {}
for _, msg in ipairs(unfiltered_messages) do
if string.find(msg.from, filter) or string.find(msg.to, filter) or string.find(msg.subject, filter) then
table.insert(filtered_messages, msg)
end
end
return filtered_messages
end
-- marks a mail read by its id
function mail.mark_read(playername, msg_id)
local entry = mail.get_storage_entry(playername)

View File

@ -8,10 +8,34 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
-- split inbox and sent msgs for different tests
local entry = mail.get_storage_entry(name)
local messagesInbox = entry.inbox
local messagesSent = entry.outbox
local messagesInboxUnAnalyzed = entry.inbox
local messagesOutBoxUnAnalyzed = entry.outbox
local messagesDrafts = entry.drafts
-- filter inbox/outbox messages
local filter = fields.filter
if not filter then
filter = ""
end
local messagesInboxFiltered = mail.filter_messages(messagesInboxUnAnalyzed, filter)
local messagesOutboxFiltered = mail.filter_messages(messagesOutBoxUnAnalyzed, filter)
-- then sort them
local sortfield = tostring(fields.sortfield)
local sortdirection = tostring(fields.sortdirection)
if not sortfield or sortfield == "" or sortfield == "0" then
sortfield = "3"
end
if not sortdirection or sortdirection == "" or sortdirection == "0" then
sortdirection = "1"
end
local messagesInbox = mail.sort_messages(messagesInboxFiltered, sortfield, sortdirection, filter)
local messagesSent = mail.sort_messages(messagesOutboxFiltered, sortfield, sortdirection, filter)
if fields.inbox then -- inbox table
local evt = minetest.explode_table_event(fields.inbox)
mail.selected_idxs.inbox[name] = evt.row - 1
@ -48,11 +72,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.boxtab == "1" then
mail.selected_idxs.boxtab[name] = 1
mail.show_inbox(name)
mail.show_inbox(name, sortfield, sortdirection, filter)
elseif fields.boxtab == "2" then
mail.selected_idxs.boxtab[name] = 2
mail.show_sent(name)
mail.show_sent(name, sortfield, sortdirection, filter)
elseif fields.boxtab == "3" then
mail.selected_idxs.boxtab[name] = 3
@ -86,7 +110,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
mail.delete_mail(name, messagesDrafts[mail.selected_idxs.drafts[name]].id)
end
mail.show_mail_menu(name)
mail.show_mail_menu(name, sortfield, sortdirection, filter)
elseif fields.reply then
if formname == "mail:inbox" and messagesInbox[mail.selected_idxs.inbox[name]] then
@ -122,7 +146,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
mail.mark_read(name, messagesSent[mail.selected_idxs.sent[name]].id)
end
mail.show_mail_menu(name)
mail.show_mail_menu(name, sortfield, sortdirection, filter)
elseif fields.markunread then
if formname == "mail:inbox" and messagesInbox[mail.selected_idxs.inbox[name]] then
@ -131,7 +155,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
mail.mark_unread(name, messagesSent[mail.selected_idxs.sent[name]].id)
end
mail.show_mail_menu(name)
mail.show_mail_menu(name, sortfield, sortdirection, filter)
elseif fields.new then
mail.show_compose(name)
@ -145,6 +169,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
elseif fields.about then
mail.show_about(name)
elseif fields.sortfield or fields.sortdirection or fields.filter then
mail.show_mail_menu(name, sortfield, sortdirection, filter)
end
return true

View File

@ -1,7 +1,23 @@
-- translation
local S = minetest.get_translator("mail")
local inbox_formspec = "size[8.5,10;]" .. mail.theme .. [[
function mail.show_inbox(name, sortfield, sortdirection, filter)
if not sortfield or sortfield == "" or sortfield == "0" then
sortfield = 3
end
if not sortdirection or sortdirection == "" or sortdirection == "0" then
sortdirection = 1
end
sortfield = tostring(sortfield)
sortdirection = tostring(sortdirection)
if not filter then
filter = ""
end
local inbox_formspec = "size[8.5,10;]" .. mail.theme .. [[
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") .. [[]
@ -17,14 +33,18 @@ local inbox_formspec = "size[8.5,10;]" .. mail.theme .. [[
button[6,8.7;2.5,0.5;about;]] .. S("About") .. [[]
button_exit[6,9.5;2.5,0.5;quit;]] .. S("Close") .. [[]
dropdown[0,9.4;2,0.5;sortfield;]] ..
S("From") .. "," .. S("Subject") .. "," .. S("Date") .. [[;]] .. tostring(sortfield) .. [[;1]
dropdown[2.0,9.4;2,0.5;sortdirection;]] ..
S("Ascending") .. "," .. S("Descending") .. [[;]] .. tostring(sortdirection) .. [[;1]
field[4.25,9.85;1.4,0.5;filter;]] .. S("Filter") .. [[:;]] .. filter .. [[]
button[5.14,9.52;0.85,0.5;search;Q]
tablecolumns[color;text;text]
table[0,0.7;5.75,9.35;inbox;#999,]] .. S("From") .. "," .. S("Subject")
function mail.show_inbox(name)
table[0,0.7;5.75,8.35;inbox;#999,]] .. S("From") .. "," .. S("Subject")
local formspec = { inbox_formspec }
local entry = mail.get_storage_entry(name)
local messages = entry.inbox
local messages = mail.sort_messages(mail.filter_messages(entry.inbox, filter), sortfield, sortdirection)
mail.message_drafts[name] = nil

View File

@ -1,11 +1,11 @@
-- helper function for tabbed overview
function mail.show_mail_menu(playername)
function mail.show_mail_menu(playername, sortfield, sortdirection, filter)
local index = mail.selected_idxs.boxtab[playername] or 1
if index == 1 then
mail.show_inbox(playername)
mail.show_inbox(playername, sortfield, sortdirection, filter)
elseif index == 2 then
mail.show_sent(playername)
mail.show_sent(playername, sortfield, sortdirection, filter)
elseif index == 3 then
mail.show_drafts(playername)
end

View File

@ -1,7 +1,23 @@
-- translation
local S = minetest.get_translator("mail")
local sent_formspec = "size[8.5,10;]" .. mail.theme .. [[
function mail.show_sent(name, sortfield, sortdirection, filter)
if not sortfield or sortfield == "" or sortfield == "0" then
sortfield = 3
end
if not sortdirection or sortdirection == "" or sortdirection == "0" then
sortdirection = 1
end
sortfield = tostring(sortfield)
sortdirection = tostring(sortdirection)
if not filter then
filter = ""
end
local sent_formspec = "size[8.5,10;]" .. mail.theme .. [[
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") .. [[]
@ -15,14 +31,18 @@ local sent_formspec = "size[8.5,10;]" .. mail.theme .. [[
button[6,8.7;2.5,0.5;about;]] .. S("About") .. [[]
button_exit[6,9.5;2.5,0.5;quit;]] .. S("Close") .. [[]
dropdown[0,9.4;2,0.5;sortfield;]]
.. S("To") .. "," .. S("Subject") .. "," .. S("Date") .. [[;]] .. tostring(sortfield) .. [[;1]
dropdown[2.0,9.4;2,0.5;sortdirection;]]
.. S("Ascending") .. "," .. S("Descending") .. [[;]] .. tostring(sortdirection) .. [[;1]
field[4.25,9.85;1.4,0.5;filter;]].. S("Filter") .. [[:;]] .. filter .. [[]
button[5.14,9.52;0.85,0.5;search;Q]
tablecolumns[color;text;text]
table[0,0.7;5.75,9.35;sent;#999,]] .. S("To") .. "," .. S("Subject")
function mail.show_sent(name)
table[0,0.7;5.75,8.35;sent;#999,]] .. S("To") .. "," .. S("Subject")
local formspec = { sent_formspec }
local entry = mail.get_storage_entry(name)
local messages = entry.outbox
local messages = mail.sort_messages(mail.filter_messages(entry.outbox, filter), sortfield, sortdirection)
mail.message_drafts[name] = nil