Added a typing indicator to the tickets interface. (#25189)

* Added a typing indicator to the tickets interface.

* Lint

* Review changes.

---------

Co-authored-by: FunnyMan3595 (Charlie Nolan) <funnyman@google.com>
This commit is contained in:
Charlie Nolan
2024-05-21 16:29:27 -07:00
committed by GitHub
parent 956bf6cd79
commit 8f2bcdba85
2 changed files with 90 additions and 45 deletions
@@ -37,6 +37,9 @@ SUBSYSTEM_DEF(tickets)
// Autoresponse keys, in sorted order.
var/sorted_responses
/// Who has what tickets open? Maps client -> open ticket number.
var/list/open_detail_uis = list()
/datum/controller/subsystem/tickets/get_metrics()
. = ..()
var/list/cust = list()
@@ -79,7 +82,7 @@ SUBSYSTEM_DEF(tickets)
var/report
for(var/num in stales)
report += "[num], "
message_staff("<span class='[span_class]'>Tickets [report] have been open for over [TICKET_TIMEOUT / 600] minutes. Changing status to stale.</span>")
message_staff("<span class='[span_class]'>Tickets [report] have been open for over [TICKET_TIMEOUT / (60 SECONDS)] minutes. Changing status to stale.</span>")
/datum/controller/subsystem/tickets/get_stat_details()
return "Tickets: [LAZYLEN(allTickets)]"
@@ -206,11 +209,18 @@ SUBSYSTEM_DEF(tickets)
to_chat_safe(returnClient(N), "<span class='[span_class]'>Your [ticket_name] has now been resolved.</span>")
return TRUE
/datum/controller/subsystem/tickets/proc/refresh_tickets(list/tickets)
for(var/datum/ticket/T in tickets)
for(var/client/client in open_detail_uis)
if(client && open_detail_uis[client] == T.ticketNum)
showDetailUI(client.mob, T.ticketNum)
/datum/controller/subsystem/tickets/proc/addResponse(list/tickets, who, message)
var/list/ticket_numbers = list()
for(var/datum/ticket/T in tickets)
ticket_numbers += T.ticketNum
T.addResponse(who, message)
refresh_tickets(tickets)
if(length(ticket_numbers) == 1)
for(var/datum/ticket/only_ticket in tickets)
@@ -532,9 +542,11 @@ UI STUFF
/datum/controller/subsystem/tickets/proc/showUI(mob/user, tab)
var/dat = null
dat = returnUI(tab)
var/datum/browser/popup = new(user, ticket_system_name, ticket_system_name, 1400, 600)
var/datum/browser/popup = new(user, ticket_system_name, ticket_system_name, 1400, 800)
popup.set_content(dat)
popup.open()
// This isn't the detail tab, stop listening for the user's typing.
open_detail_uis -= user.client
/datum/controller/subsystem/tickets/proc/showDetailUI(mob/user, ticketID)
var/datum/ticket/T = allTickets[ticketID]
@@ -548,7 +560,8 @@ UI STUFF
dat += "<h3>[T.client_ckey] / [T.mobControlled] opened this [ticket_name] at [T.ingame_time_opened] at location [T.locationSent]</h3>"
dat += "<h4>Ticket Status: [status]"
dat += "<table style='width:950px; border: 3px solid;'>"
dat += "<div id='msgs' style='width:950px; border: 3px solid; overflow-y: scroll; height: 350px;'>"
dat += "<table style='width:100%;'>"
dat += "<tr><td>[makeUrlMessage(T, one_line = TRUE)]</td></tr>"
if(length(T.ticket_responses) > 1)
@@ -556,7 +569,28 @@ UI STUFF
var/datum/ticket_response/TR = T.ticket_responses[i]
dat += "<tr><td>[TR.to_string()]</td></tr>"
dat += "</table><br /><br />"
dat += "</table></div>"
var/client/C = get_client_by_ckey(T.client_ckey)
for(var/key in C?.pm_tracker.pms)
var/datum/pm_convo/convo = C.pm_tracker.pms[key]
if(convo.typing)
dat += "<i><span class='typing'>[T.client_ckey] is typing</span></i><br />"
break
for(var/client/X in GLOB.admins)
if(ckey(X.ckey) == ckey(T.client_ckey))
continue
if(!check_rights_for(X, rights_needed))
continue
for(var/key in X.pm_tracker.pms)
if(ckey(key) != ckey(T.client_ckey))
continue
var/datum/pm_convo/convo = X.pm_tracker.pms[key]
if(convo.typing)
dat += "<i><span class='typing'>[X.ckey] is typing</span></i><br />"
break
dat += "<br />"
dat += "<a href='byond://?src=[UID()];detailreopen=[T.ticketNum]'>Re-Open</a>[check_rights(rights_needed, 0) ? "<a href='byond://?src=[UID()];autorespond=[T.ticketNum]'>Auto</a>": ""]<a href='byond://?src=[UID()];detailresolve=[T.ticketNum]'>Resolve</a><br /><br />"
if(!T.staffAssigned)
@@ -574,9 +608,19 @@ UI STUFF
dat += "<a href='byond://?src=[UID()];detailclose=[T.ticketNum]'>Close Ticket</a>"
dat += "<a href='byond://?src=[UID()];convert_ticket=[T.ticketNum]'>Convert Ticket</a>"
var/datum/browser/popup = new(user, "[ticket_system_name]detail", "[ticket_system_name] #[T.ticketNum]", 1000, 600)
var/datum/browser/popup = new(user, "[ticket_system_name]detail", "[ticket_system_name] #[T.ticketNum]", 1000, 800, src)
popup.add_head_content(@{"<script type='text/javascript'>
window.onload = function () {
var msgs = document.getElementById('msgs');
msgs.scrollTop = msgs.scrollHeight;
}
</script>"})
popup.set_content(dat)
popup.open()
open_detail_uis[user.client] = T.ticketNum
/datum/controller/subsystem/tickets/proc/onCloseDetailUI(mob/user)
open_detail_uis -= user.client
/datum/controller/subsystem/tickets/proc/userDetailUI(mob/user)
//dat
@@ -591,7 +635,7 @@ UI STUFF
dat += "<tr><td>[TR.to_string()]</td></tr>"
dat += "</table>"
var/datum/browser/popup = new(user, "[ticket_system_name]userticketsdetail", ticket_system_name, 1000, 600)
var/datum/browser/popup = new(user, "[ticket_system_name]userticketsdetail", ticket_system_name, 1000, 800)
popup.set_content(dat)
popup.open()
@@ -697,6 +741,9 @@ UI STUFF
else
usr.client.resolveAllAdminTickets()
if(href_list["close"])
onCloseDetailUI(usr)
/datum/controller/subsystem/tickets/proc/takeTicket(index)
if(assignStaffToTicket(usr.client, index))
if(span_class == "mentorhelp")
+37 -39
View File
@@ -86,28 +86,6 @@
if(alert("That player has been PM'd in the last [config.simultaneous_pm_warning_timeout / 10] seconds by: [C.ckey_last_pm]","Simultaneous PMs warning","Continue","Cancel") == "Cancel")
return*/
//get message text, limit it's length.and clean/escape html
if(!msg)
set_typing(C, TRUE)
msg = clean_input("Message:", "Private message to [holder ? key_name(C, FALSE) : key_name_hidden(C, FALSE)]", null, src)
set_typing(C, FALSE)
if(!msg)
return
if(!C)
if(holder)
to_chat(src, "<span class='danger'>Error: Admin-PM: Client not found.</span>")
else
adminhelp(msg) //admin we are replying to has vanished, adminhelp instead
return
if(handle_spam_prevention(msg, MUTE_ADMINHELP, OOC_COOLDOWN))
return
// Let high-rank admins use advanced pencode.
if(check_rights(R_SERVER|R_DEBUG, 0))
msg = admin_pencode_to_html(msg)
var/send_span
var/receive_span
var/send_pm_type = " "
@@ -127,6 +105,41 @@
message_type = MESSAGE_TYPE_ADMINPM
tickets_system = SStickets
//Check if the mob being PM'd has any open tickets.
var/list/tickets = tickets_system.checkForTicket(C, ticket_id)
if(!length(tickets))
// If we didn't find a specific ticket by the target mob, we check for
// tickets by the source mob.
if(message_type == MESSAGE_TYPE_MENTORPM)
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob))
tickets = SSmentor_tickets.checkForTicket(src)
else
if(check_rights(R_ADMIN|R_MOD, 0, C.mob))
tickets = SStickets.checkForTicket(src)
//get message text, limit it's length.and clean/escape html
if(!msg)
set_typing(C, TRUE)
tickets_system.refresh_tickets(tickets)
msg = clean_input("Message:", "Private message to [holder ? key_name(C, FALSE) : key_name_hidden(C, FALSE)]", null, src)
set_typing(C, FALSE)
if(!msg)
tickets_system.refresh_tickets(tickets)
return
if(!C)
if(holder)
to_chat(src, "<span class='danger'>Error: Admin-PM: Client not found.</span>")
else
adminhelp(msg) //admin we are replying to has vanished, adminhelp instead
return
if(handle_spam_prevention(msg, MUTE_ADMINHELP, OOC_COOLDOWN))
return
// Let high-rank admins use advanced pencode.
if(check_rights(R_SERVER|R_DEBUG, 0))
msg = admin_pencode_to_html(msg)
if(holder)
//PMs sent from admins and mods display their rank
@@ -224,22 +237,6 @@
if(check_rights(R_ADMIN|R_MOD, 0, X.mob))
to_chat(X, third_party_message, MESSAGE_TYPE_ADMINPM)
//Check if the mob being PM'd has any open tickets.
var/list/tickets = tickets_system.checkForTicket(C, ticket_id)
if(length(tickets))
tickets_system.addResponse(tickets, src, msg)
return
// If we didn't find a specific ticket by the target mob, we check for
// tickets by the source mob.
if(message_type == MESSAGE_TYPE_MENTORPM)
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob))
tickets = SSmentor_tickets.checkForTicket(src)
else
if(check_rights(R_ADMIN|R_MOD, 0, C.mob))
tickets = SStickets.checkForTicket(src)
if(length(tickets))
tickets_system.addResponse(tickets, src, msg)
@@ -288,7 +285,8 @@
return
var/datum/pm_convo/convo = target.pm_tracker.pms[key]
if(!convo)
return
convo = new /datum/pm_convo(src)
target.pm_tracker.pms[key] = convo
convo.typing = value
if(target.pm_tracker.open && target.pm_tracker.current_title == key)
target.pm_tracker.show_ui(target.mob)