From a01d3749955ab0e2a2baea6c1b33f7fac7e80edb Mon Sep 17 00:00:00 2001 From: octacian Date: Wed, 22 Feb 2017 07:37:25 -0800 Subject: [PATCH] Add admin dashboard Allows an admin with the contact privilege to view all messages and reports. --- README.md | 2 +- api.md | 17 ++- dash.lua | 220 ++++++++++++++++++++++++++++++++++++++ init.lua | 1 + textures/contact_flag.png | Bin 0 -> 237 bytes textures/contact_msg.png | Bin 0 -> 291 bytes 6 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 dash.lua create mode 100644 textures/contact_flag.png create mode 100644 textures/contact_msg.png diff --git a/README.md b/README.md index 260c294..3c9ce2c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ An admin/moderator can be assigned to each case, as all with the `contact` privi #### To Do List Not all of the features mentioned above are done, so here's what is and what isn't. -- [ ] Admin Dashboard +- [x] Admin Dashboard - [x] Contact - [ ] Conversations - [x] Report diff --git a/api.md b/api.md index 53b5280..1a3b7d1 100644 --- a/api.md +++ b/api.md @@ -53,4 +53,19 @@ contact.toggle_report("singleplayer", "otherplayer", true, { info = "This is the information field", } }) -``` \ No newline at end of file +``` + +## Dash +The dashboard is composed of several different formspecs to allow tabs and views. Only one API function is available to other mods, as documented below. However, it is important to know that if you wish to customize the formspecs, you should modify the `forms` table in `dash.lua`. + +#### `show_dash` +__Usage:__ `contact.show_dash(,
, , <...>)` + +This allows an external mod to show the dashboard to any specific player (specified by `name`). By default, the formspec is shown when a player uses the `/contact_admin` command which requires the `contact` privilege. The player name and form name parameters are the only ones required. If not specified, show/hide will default to show (`true`). Finally, any other parameters can be passed to the `get` function of each form by adding them after show/hide like normal parameters. + +__Example:__ +```lua +contact.show_dash("singleplayer", "view_msg", true, 12}) +``` + +In the example, `12` is the message ID being passed to the `view_msg` formspec `get` function. \ No newline at end of file diff --git a/dash.lua b/dash.lua new file mode 100644 index 0000000..86ccff6 --- /dev/null +++ b/dash.lua @@ -0,0 +1,220 @@ +-- contact/dash.lua + +-- [register] Contact Admin Privilege +minetest.register_privilege("contact", "Access admin dashboard of the contact mod") + +-- [table] Tabs +local tabs = { + "dashboard", + "messages", + "reports" +} + +-- [local function] handle tabs +function handle_tabs(name, fields) + if fields.tabs then + contact.show_dash(name, tabs[tonumber(fields.tabs)]) + return true + end +end + +-- [table] Forms +local forms = { + dashboard = { + get = function() + return [[ + size[10,5] + ]]..contact.gui_bg..[[ + tabheader[0,0;tabs;Dashboard,Messages,Reports;1] + image_button[0.5,0.5;4,4;contact_flag.png;reports;] + tooltip[reports;Reported Players] + image_button[5.5,0.5;4,4;contact_msg.png;msg;] + tooltip[msg;Messages] + ]] + end, + handle = function(name, fields) + if handle_tabs(name, fields) then return end + + if fields.msg then + contact.show_dash(name, "messages", true) + elseif fields.reports then + contact.show_dash(name, "reports", true) + end + end, + }, + messages = { + get = function() + local list = "" + + for _,i in ipairs(contact.msg) do + local c + if _ ~= 1 then c = "," else c = "" end + + list = list..c..i.subject.." - from: "..i.from.." - date: "..i.dtime + end + + return [[ + size[10,11] + ]]..contact.gui_bg..[[ + tabheader[0,0;tabs;Dashboard,Messages,Reports;2] + table[0.25,0.25;9.4,10.5;list;]]..list..[[;1] + ]] + end, + handle = function(name, fields) + if handle_tabs(name, fields) then return end + + if fields.list then + local s = fields.list:split(":") + if s[1] == "DCL" and tonumber(s[3]) ~= 0 then + contact.show_dash(name, "view_msg", true, tonumber(s[2])) + end + end + end, + }, + view_msg = { + cache_name = false, + get = function(name, id) + local e = minetest.formspec_escape + local msg = contact.msg[id] + + local body = msg.msg:split("\n", true) + for i, line in ipairs(body) do + body[i] = e(line) + end + + return [[ + size[10,11] + ]]..contact.gui_bg..[[ + field[100,100;1,1;id;;]]..e(id)..[[] + button[0.1,0.1;1,1;back;Back] + button[1,0.1;1.2,1;del;Delete] + label[2.5,0.1;From: ]]..e(msg.from)..[[] + label[2.5,0.45;Date: ]]..e(msg.dtime)..[[] + label[0.1,1.3;Subject: ]]..e(msg.subject)..[[] + tableoptions[background=#343434;highlight=#00000000;border=false] + table[0,1.8;9.68,7;msg;]]..table.concat(body, ",")..[[;1] + ]] + end, + handle = function(name, fields) + if fields.back then + contact.show_dash(name, "messages", true) + elseif fields.del then + table.remove(contact.msg, tonumber(fields.id)) + contact.show_dash(name, "messages", true) + end + end, + }, + reports = { + get = function() + local list = "" + + for _,i in ipairs(contact.reports) do + local c + if _ ~= 1 then c = "," else c = "" end + + list = list..c..i.target.." - from: "..i.from.." - date: "..i.dtime + end + + return [[ + size[10,11] + ]]..contact.gui_bg..[[ + tabheader[0,0;tabs;Dashboard,Messages,Reports;3] + table[0.25,0.25;9.4,10.5;list;]]..list..[[;1] + ]] + end, + handle = function(name, fields) + if handle_tabs(name, fields) then return end + + if fields.list then + local s = fields.list:split(":") + if s[1] == "DCL" and tonumber(s[3]) ~= 0 then + contact.show_dash(name, "view_report", true, tonumber(s[2])) + end + end + end, + }, + view_report = { + cache_name = false, + get = function(name, id) + local e = minetest.formspec_escape + local rep = contact.reports[id] + + local info = rep.info:split("\n", true) + for i, line in ipairs(info) do + info[i] = e(line) + end + + return [[ + size[10,11] + ]]..contact.gui_bg..[[ + field[100,100;1,1;id;;]]..e(id)..[[] + button[0.1,0.1;1,1;back;Back] + button[1,0.1;1.2,1;del;Delete] + label[0.1,0.92;Target: ]]..e(rep.target)..[[] + label[2.5,0.1;From: ]]..e(rep.from)..[[] + label[2.5,0.45;Date: ]]..e(rep.dtime)..[[] + label[0.1,1.3;Reason: ]]..e(rep.reason)..[[] + tableoptions[background=#343434;highlight=#00000000;border=false] + table[0,1.8;9.68,7;info;]]..table.concat(info, ",")..[[;1] + ]] + end, + handle = function(name, fields) + if fields.back then + contact.show_dash(name, "reports", true) + elseif fields.del then + table.remove(contact.reports, tonumber(fields.id)) + contact.show_dash(name, "reports", true) + end + end, + }, +} + +-- [function] Show/Hide Formspecs +function contact.show_dash(pname, fname, show, ...) + if forms[fname] then + if not minetest.get_player_by_name(pname) then + return + end + + if show ~= false then + minetest.show_formspec(pname, "contact:"..fname, forms[fname].get(pname, ...)) + + -- Update player attribute + if forms[fname].cache_name ~= false then + minetest.get_player_by_name(pname):set_attribute("contact_formname", fname) + end + else + minetest.close_formspec(pname, "contact:"..fname) + end + end +end + +-- [event] on receive fields +minetest.register_on_player_receive_fields(function(player, formname, fields) + local formname = formname:split(":") + + if formname[1] == "contact" and forms[formname[2]] then + local handle = forms[formname[2]].handle + if handle then + handle(player:get_player_name(), fields) + end + end +end) + +-- [register] Dashboard Chatcommand +minetest.register_chatcommand("contact_admin", { + description = "Show admin panel for contact mod", + privs = {contact=true}, + func = function(name) + -- Get player attribute + local fname = minetest.get_player_by_name(name):get_attribute("contact_formname") + + if not forms[fname] then + fname = "dashboard" + end + + contact.show_dash(name, fname, true) + + return true, "Opening admin "..fname + end, +}) diff --git a/init.lua b/init.lua index 30ecd69..df86c7b 100644 --- a/init.lua +++ b/init.lua @@ -59,3 +59,4 @@ contact.load() dofile(modpath.."/contact.lua") -- Contact Functionality dofile(modpath.."/report.lua") -- Report Functionality +dofile(modpath.."/dash.lua") -- Admin Dashboard diff --git a/textures/contact_flag.png b/textures/contact_flag.png new file mode 100644 index 0000000000000000000000000000000000000000..96577d82d05f70cba807ce5cf757980300156c62 GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPtlc<=CdbsSueLx}E%#er@=ltB<)VvZPmw~~#C^fMp zHASI3vm`^o-P1Q9MK6^dC?4qP;uvCaIynIdc2s@UI(&6?xa0{&oq%8V%*@P(rK6+W zf=s$)?0C!@9Bq`D^8`2>CU!PD8Duet@+357#X0NLv4>gTe~DWM4fcJM)$ literal 0 HcmV?d00001 diff --git a/textures/contact_msg.png b/textures/contact_msg.png new file mode 100644 index 0000000000000000000000000000000000000000..03a877d0c811eeabf0fc3f09f89364be17350fbe GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPtlc<=6+-9R&jzA&V%#er@=ltB<)VvZPmw~~#C^fMp zHASI3vm`^o-P1Q9MK6^dDBkYr;uvCa`s(D>e9VdhuJ6sXj|uXGfBHY4B~QgdW?iUi zYwWEQ!P#*~U(2WgEqyYl(3D>%Epo#gUIr(Q^V%D>mfgNDob0nbGTW9x>C&;KA{Ng# z^iTNy@AcYMw>qPQJ)K+@tg=s>l)H9ygG!KB@JSANmid!5_k38HP*yNat;6u%k6HhI b8}DTZ{i43(Sm?1-kXt=n{an^LB{Ts54tir+ literal 0 HcmV?d00001