Files
modpol/modpol/interactions/interactions.lua

239 lines
6.9 KiB
Lua

-- INTERACTIONS.LUA (CLI)
-- User interaction functions for Modular Politics
-- Called by modpol.lua
modpol.interactions = {}
-- DASHBOARDS
-- ==========
-- Function: modpol.interactions.dashboard(user)
-- Params: user (string)
-- Q: Should this return a menu of commands relevant to the specific user?
-- Output: Displays a menu of commands to the user
-- TKTK currently just prints all of modpol---needs major improvement
function modpol.interactions.dashboard(user)
-- adds user to root org if not already in it
if not modpol.instance:has_member(user) then
modpol.instance:add_member(user)
end
local all_users = modpol.list_users()
print('All orgs: (user orgs indicated by *)')
for id, org in ipairs(modpol.orgs.array) do
if type(org) == "table" then
local indicator = ""
if org:has_member(user) then indicator = "*" end
print('['..id..'] '..indicator..org.name)
end
end
print('All users: ' .. table.concat(all_users, ', '))
print()
print('Access which org?')
local sel = io.read()
print()
local sel_org = modpol.orgs.array[tonumber(sel)].name
if not sel_org then return end
modpol.interactions.org_dashboard(user, sel_org)
end
-- Function: modpol.interactions.org_dashboard
-- Params: user (string), org_name (string)
-- Output: Displays a menu of org-specific commands to the user
function modpol.interactions.org_dashboard(user, org_name)
local org = modpol.orgs.get_org(org_name)
if not org then return nil end
local parent = ""
if org.id == 1 then
parent = "none"
else
parent = modpol.orgs.get_org(org.parent).name
end
local children = {}
for k,v in ipairs(org.children) do
local this_child = modpol.orgs.get_org(v)
table.insert(children, this_child.name)
end
local process_msg = #org.processes .. " total"
if org.pending[user] then
process_msg = process_msg .. " (" .. #org.pending[user] .. " pending)"
else
process_msg = process_msg .. " (0 pending)"
end
-- set up output
print("Org: " .. org_name)
print("Parent: " .. parent)
print("Members: " .. table.concat(org.members, ", "))
print("Children: " .. table.concat(children, ", "))
print("Processes: " .. process_msg)
print()
print("Commands: (L)eave, (J)oin, (P)rocesses, (A)dd child, (D)elete org")
local sel = io.read()
print()
if sel == 'l' or sel == 'L' then
org:remove_member(user)
elseif sel == 'j' or sel == 'J' then
org:make_request({user=user, type="add_member", params={user}})
elseif sel == 'a' or sel == 'A' then
print("What should the new org be named?")
local new_org_name = io.read()
org:make_request({user=user, type="add_org", params={new_org_name}})
elseif sel == 'd' or sel == 'D' then
org:make_request({user=user, type="delete", params={}})
elseif sel == 'p' or sel == 'P' then
local processes = {}
print("All processes: (* indicates pending action)")
for k,v in ipairs(org.processes) do
local this_request = org.requests[v.request_id]
if type(this_request) == "table" then
local active = ''
if org.pending[user] then
if org.pending[user][v.id] then
active = '*'
end
end
local req_str = "[" .. v.id .. "] " ..
active .. this_request.type
if this_request.params[1] then
req_str = req_str .. ": " ..
table.concat(this_request.params, ", ")
end
print(req_str)
end
end
print()
print("Interact with which one?")
local to_interact = io.read()
local process = org.processes[tonumber(to_interact)]
if not process then return end
if org:has_pending_actions(user) then
if org.pending[user][process.id] then
process:interact(user)
end
end
end
end
-- Function: modpol.interactions.policy_dashboard
-- input: user (string), org_id (int), policy (string)
-- if policy is nil, enables creating a new policy
-- output: opens a dashboard for viewing/editing policy details
-- TODO
-- Function: modpol.interactions.message
-- input: user (string), message (string)
-- output: prints message to CLI
function modpol.interactions.message(user, message)
print(user .. ": " .. message)
end
-- Function: modpol.interactions.text_query
-- input: User (string), Query (string), func (function)
-- func input: user input (string)
-- output: Applies "func" to user input
function modpol.interactions.text_query(user, query, func)
print(user .. ": " .. query)
answer = io.read()
func(answer)
end
-- Function: dropdown_query
-- input: user (string), label (string), options (table of strings), func(choice) (function)
-- func input: choice (string)
-- output: calls func on choice
function modpol.interactions.dropdown_query(user, label, options, func)
-- set up options
local options_display = ""
local options_number = 0
for k,v in ipairs(options) do
options_display = options_display .. k .. ". " ..
options[k] .. "\n"
options_number = options_number + 1
end
options_display = options_display .. "Select number:"
if options_number == 0 then
print("Error: No options given for dropdown")
return nil
end
-- begin displaying
print(user .. ": " .. label)
print(options_display)
-- read input and produce output
local answer
answer = io.read()
answer = tonumber(answer)
if answer then
if answer >= 1 and answer <= options_number then
print("Selection: " .. options[answer])
func(options[answer])
else
print("Error: Not in dropdown range")
return nil
end
else
print("Error: Must be a number")
return nil
end
end
-- Function: modpol.binary_poll_user(user, question)
-- Params: user (string), question (string), func (function)
-- func input: user input (string: y/n)
-- Output: Applies "func" to user input
function modpol.interactions.binary_poll_user(user, question, func)
local query = "Poll for " .. user .. " (y/n): ".. question
local answer
repeat
print(query)
answer = io.read()
until answer == "y" or answer == "n"
if answer == "y" then
modpol.interactions.message(user, "Response recorded")
func("Yes")
elseif answer == "n" then
modpol.interactions.message(user, "Response recorded")
func("No")
else
modpol.interactions.message(user, "Error: invalid response")
end
end
-- COMPLEX INTERACTIONS
-- ====================
-- Function: modpol.interactions.message_org
-- input: initiator (string), org_id (number), message (string)
-- output: broadcasts message to all org members
-- Function: modpol.interactions.binary_poll_org
-- input: initator (user string), org_id (number)
-- output: gets question from initiator, asks all org members, broadcasts answers