diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index e9d813c1439..caa051f8748 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -88,7 +88,9 @@ //get message text, limit it's length.and clean/escape html if(!msg) + set_typing(C, TRUE) msg = input(src,"Message:", "Private message to [holder ? key_name(C, FALSE) : key_name_hidden(C, FALSE)]") as text|null + set_typing(C, FALSE) if(!msg) return @@ -130,6 +132,9 @@ var/recieve_message = "" + pm_tracker.add_message(C, src, msg, mob) + C.pm_tracker.add_message(src, src, msg, C.mob) + if(holder && !C.holder) recieve_message = "-- Click the [recieve_pm_type]'s name to reply --\n" if(C.adminhelped) @@ -233,3 +238,141 @@ continue if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, X.mob)) to_chat(X, "PM: [key_name(src, TRUE, 0)]->IRC-Admins: [msg]") + +/client/verb/open_pms_ui() + set name = "My PMs" + set category = "OOC" + pm_tracker.show_ui(usr) + +/client/proc/set_typing(client/target, value) + if(!target) + return + var/datum/pm_convo/convo = target.pm_tracker.pms[key] + if(!convo) + return + convo.typing = value + if(target.pm_tracker.open && target.pm_tracker.current_title == key) + target.pm_tracker.show_ui(target.mob) + +/datum/pm_tracker + var/current_title = "" + var/open = FALSE + var/list/pms = list() + var/show_archived = FALSE + var/window_id = "pms_window" + +/datum/pm_convo + var/list/messages = list() + var/archived = FALSE + var/client/client + var/read = FALSE + var/typing = FALSE + +/datum/pm_convo/New(client/C) + client = C + +/datum/pm_convo/proc/add(client/sender, message) + messages.Add("[sender]: [message]") + archived = FALSE + read = FALSE + +/datum/pm_tracker/proc/add_message(client/title, client/sender, message, mob/user) + if(!pms[title.key]) + pms[title.key] = new /datum/pm_convo(title) + pms[title.key].add(sender, message) + + if(!open) + // The next time the window's opened, it'll be open to the most recent message + current_title = title.key + return + + // If it's already opened, it'll refresh + show_ui(user) + +/datum/pm_tracker/proc/show_ui(mob/user) + var/dat = "" + + dat += "Refresh" + dat += "[show_archived ? "Hide" : "Show"] Archived" + dat += "
" + for(var/title in pms) + if(pms[title].archived && !show_archived) + continue + var/label = "[title]" + var/class = "" + if(title == current_title) + label = "[label]" + class = "linkOn" + else if(!pms[title].read) + label = "*[label]" + dat += "[label]" + + var/datum/pm_convo/convo = pms[current_title] + if(convo) + convo.read = TRUE + dat += "

[check_rights(R_ADMIN, FALSE, user) ? fancy_title(current_title) : current_title]

" + dat += "

" + dat += "" + + for(var/message in convo.messages) + dat += "" + + dat += "
[message]
" + if(convo.typing) + dat += "[current_title] is typing" + dat += "
" + dat += "

" + dat += "Reply" + dat += "[convo.archived ? "Unarchive" : "Archive"]" + if(check_rights(R_ADMIN, FALSE, user)) + dat += "Ping" + + var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src) + popup.set_content(dat) + popup.open() + open = TRUE + +/datum/pm_tracker/proc/fancy_title(title) + var/client/C = pms[title].client + if(!C) + return "[title] (Disconnected)" + return "[key_name(C, FALSE)] ([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_SM(C.mob,"SM")]) ([admin_jump_link(C.mob)]) (CA)" + +/datum/pm_tracker/Topic(href, href_list) + if(href_list["archive"]) + pms[href_list["archive"]].archived = !pms[href_list["archive"]].archived + show_ui(usr) + return + + if(href_list["refresh"]) + show_ui(usr) + return + + if(href_list["newtitle"]) + current_title = href_list["newtitle"] + show_ui(usr) + return + + if(href_list["ping"]) + var/client/C = pms[href_list["ping"]].client + if(C) + C.pm_tracker.current_title = usr.key + window_flash(C) + C.pm_tracker.show_ui(C.mob) + to_chat(usr, "Forced open [C]'s messages window.") + show_ui(usr) + return + + if(href_list["reply"]) + usr.client.cmd_admin_pm(ckey(href_list["reply"]), null) + show_ui(usr) + return + + if(href_list["showarchived"]) + show_archived = !show_archived + show_ui(usr) + return + + if(href_list["close"]) + open = FALSE + return diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index c15ea50c93e..a6bc558842b 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -7,6 +7,7 @@ var/last_message = "" //contains the last message sent by this client - used to protect against copy-paste spamming. var/last_message_count = 0 //contains a number of how many times a message identical to last_message was sent. var/last_message_time = 0 //holds the last time (based on world.time) a message was sent + var/datum/pm_tracker/pm_tracker = new() ///////// //OTHER// diff --git a/html/browser/common.css b/html/browser/common.css index 23b675f7fa2..3480183d129 100644 --- a/html/browser/common.css +++ b/html/browser/common.css @@ -345,4 +345,22 @@ div.notice -ms-interpolation-mode: nearest-neighbor; width: 64px; height:64px; -} \ No newline at end of file +} + +.typing:after +{ + overflow: hidden; + display: inline-block; + vertical-align: bottom; + animation: ellipsis steps(4,end) 900ms infinite; + content: "\2026"; + width: 0px; +} + +@keyframes ellipsis +{ + to + { + width: 1.25em; + } +}