From 5c832dfc333310253f16aa66368d69866aa98eef Mon Sep 17 00:00:00 2001 From: Nomad Senaxsys Date: Sat, 28 Sep 2024 22:40:47 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B2=20=C2=AB?= =?UTF-8?q?util=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/colors.lua | 58 +++++++++++++++++++++++++++++ util/contact.lua | 75 ++++++++++++++++++++++++++++++++++++++ util/init.lua | 9 +++++ util/normalize.lua | 81 +++++++++++++++++++++++++++++++++++++++++ util/normalize.spec.lua | 12 ++++++ 5 files changed, 235 insertions(+) create mode 100644 util/colors.lua create mode 100644 util/contact.lua create mode 100644 util/init.lua create mode 100644 util/normalize.lua create mode 100644 util/normalize.spec.lua diff --git a/util/colors.lua b/util/colors.lua new file mode 100644 index 0000000..fa39af6 --- /dev/null +++ b/util/colors.lua @@ -0,0 +1,58 @@ +local generic_colors = { + header = "#999999", + selected = "#72FF63", + important = "#FFD700", + additional = "#CCCCDD", + highlighted = "#608631", + new = "#00F529", + warning = "#FF8800", + disabled = "#332222", + muted = "#CCCCCC", +} + +local function get_base_color(c) + return generic_colors[c] or "" +end + +local function hex2rgb(hex) + hex = hex:gsub("#","") + return { + r = tonumber("0x" .. hex:sub(1,2)), + g = tonumber("0x" .. hex:sub(3,4)), + b = tonumber("0x" .. hex:sub(5,6)) + } +end + +local function rgb2hex(rgb) + return "#" .. string.format("%x", rgb.r) .. string.format("%x", rgb.g) .. string.format("%x", rgb.b) +end + +local function rgb_colors_mix(colors) + local R = 0 + local G = 0 + local B = 0 + for _, c in ipairs(colors) do + R = R + c.r + G = G + c.g + B = B + c.b + end + R = math.floor(R / #colors + 0.5) + G = math.floor(G / #colors + 0.5) + B = math.floor(B / #colors + 0.5) + return {r=R,g=G,b=B} +end + +function mail.get_color(mix) + if type(mix) == "string" then + return get_base_color(mix) + elseif #mix == 1 then + return get_base_color(mix[1]) + else + local colors2mix = {} + for _, c in ipairs(mix) do + colors2mix[#colors2mix+1] = hex2rgb(get_base_color(c)) + end + local mixed_color = rgb_colors_mix(colors2mix) + return rgb2hex(mixed_color) + end +end diff --git a/util/contact.lua b/util/contact.lua new file mode 100644 index 0000000..b890f43 --- /dev/null +++ b/util/contact.lua @@ -0,0 +1,75 @@ +-- translation +local S = mail.S + +function mail.compile_contact_list(name, selected, playernames) + -- TODO: refactor this - not just compiles *a* list, but *the* list for the contacts screen (too inflexible) + local formspec = {} + local contacts = mail.get_contacts(name) + + if playernames == nil then + local length = 0 + for k, contact, i, l in mail.pairs_by_keys(contacts) do + if i == 1 then length = l end + formspec[#formspec + 1] = "," + formspec[#formspec + 1] = "," + formspec[#formspec + 1] = minetest.formspec_escape(contact.name) + formspec[#formspec + 1] = "," + local note = contact.note + -- display an ellipsis if the note spans multiple lines + local idx = string.find(note, '\n') + if idx ~= nil then + note = string.sub(note, 1, idx-1) .. ' ...' + end + formspec[#formspec + 1] = minetest.formspec_escape(note) + if type(selected) == "string" then + if string.lower(selected) == k then + selected = i + end + end + end + if length > 0 then + if selected and type(selected) == "number" then + formspec[#formspec + 1] = ";" + formspec[#formspec + 1] = tostring(selected + 1) + end + formspec[#formspec + 1] = "]" + else + formspec[#formspec + 1] = "]label[2,4.5;" .. S("No contacts") .. "]" + end + else + if type(playernames) == "string" then + playernames = mail.parse_player_list(playernames) + end + for i,c in ipairs(playernames) do + formspec[#formspec + 1] = "," + formspec[#formspec + 1] = "," + formspec[#formspec + 1] = minetest.formspec_escape(c) + formspec[#formspec + 1] = "," + if contacts[string.lower(c)] == nil then + formspec[#formspec + 1] = "" + else + local note = contacts[string.lower(c)].note + -- display an ellipsis if the note spans multiple lines + local idx = string.find(note, '\n') + if idx ~= nil then + note = string.sub(note, 1, idx-1) .. ' ...' + end + formspec[#formspec + 1] = minetest.formspec_escape(note) + end + if not selected then + if type(selected) == "string" then + if string.lower(selected) == string.lower(c) then + selected = i + end + end + end + end + if #playernames > 0 and selected and type(selected) == "number" then + formspec[#formspec + 1] = ";" + formspec[#formspec + 1] = tostring(selected + 1) + end + formspec[#formspec + 1] = "]" + end + return table.concat(formspec, "") + +end diff --git a/util/init.lua b/util/init.lua new file mode 100644 index 0000000..d5e0560 --- /dev/null +++ b/util/init.lua @@ -0,0 +1,9 @@ +-- sub files +local MP = minetest.get_modpath(minetest.get_current_modname()) +dofile(MP .. "/util/normalize.lua") +dofile(MP .. "/util/colors.lua") +dofile(MP .. "/util/contact.lua") +dofile(MP .. "/util/settings.lua") +dofile(MP .. "/util/spam.lua") +dofile(MP .. "/util/time_ago.lua") +dofile(MP .. "/util/uuid.lua") diff --git a/util/normalize.lua b/util/normalize.lua new file mode 100644 index 0000000..4585bd5 --- /dev/null +++ b/util/normalize.lua @@ -0,0 +1,81 @@ +-- translation +local S = mail.S + +local function recursive_expand_recipient_names(sender, list, is_toplevel, recipients, undeliverable) + for _, name in ipairs(list) do + if not (recipients[name] or undeliverable[name] or (name == sender and not is_toplevel)) then + local succ, value + for _, handler in ipairs(mail.registered_recipient_handlers) do + succ, value = handler(sender, name) + if succ ~= nil then + break + end + end + local vtp = type(value) + if succ then + if vtp == "string" then + recursive_expand_recipient_names(sender, {value}, is_toplevel, recipients, undeliverable) + elseif vtp == "table" then + recursive_expand_recipient_names(sender, value, false, recipients, undeliverable) + elseif vtp == "function" then + recipients[name] = value + else + undeliverable[name] = S("The method of delivery to @1 is invalid.", name) + end + elseif succ == nil then + undeliverable[name] = S("The recipient @1 could not be identified.", name) + else + local reason = tostring(value) or S("@1 rejected your mail.", name) + undeliverable[name] = reason + end + end + end +end + +--[[ +return the field normalized (comma separated, single space) +and add individual player names to recipient list +--]] +function mail.normalize_players_and_add_recipients(sender, field, recipients, undeliverable) + local order = mail.parse_player_list(field) + recursive_expand_recipient_names(sender, order, true, recipients, undeliverable) + return mail.concat_player_list(order) +end + +function mail.parse_player_list(field) + if not field then + return {} + end + + local separator = ",%s" + local pattern = "([^" .. separator .. "]+)" + + -- get individual players + local order = {} + for name in field:gmatch(pattern) do + table.insert(order, name) + end + + return order +end + +function mail.concat_player_list(order) + -- turn list of players back into normalized string + if order == nil or #order == 0 then + return "" + end + return table.concat(order, ", ") +end + +function mail.player_in_list(name, list) + list = list or {} + if type(list) == "string" then + list = mail.parse_player_list(list) + end + for _, player_name in pairs(list) do + if name == player_name then + return true + end + end + return false +end diff --git a/util/normalize.spec.lua b/util/normalize.spec.lua new file mode 100644 index 0000000..b9caa0f --- /dev/null +++ b/util/normalize.spec.lua @@ -0,0 +1,12 @@ + +mtt.register("util/normalize_players_and_add_recipients", function(callback) + local recipients = {} + local undeliverable = {} + local to = mail.normalize_players_and_add_recipients("sender", "player1,player2", recipients, undeliverable) + + assert(to == "player1, player2") + assert(not next(undeliverable)) + assert(recipients["player1"]) + assert(recipients["player2"]) + callback() +end)