mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 15:42:35 +00:00
A user ahelping creates a ticket. Any further ahelps while that ticket is open will go to that ticket (and either adminhelp or pm an admin assigned to the ticket, if one has taken it). A user can close their own ticket up until an admin takes it. Admins can take tickets either manually or just by replying to the PM. An admin taking a ticket notifies other admins. If another admin attempts to take or respond to an assigned ticket, they receive a notification asking if they would like to join the ticket or cancel (any number of admins can join a ticket). When an admin finishes with a ticket, they must close it -- both for logistics and closure for the user. If there is an open ticket assigned to an active admin, round end is automatically delayed (unassigned tickets or tickets assigned to disconnected or afk admins do not delay). Round end will automatically continue once all active tickets are closed. Both staff and non-staff have access to a ticket panel listing tickets, their statuses, and their messages. Non-staff can only see their own tickets. This panel is optional and all features are available inline with chat.
200 lines
5.7 KiB
Plaintext
200 lines
5.7 KiB
Plaintext
/datum/browser
|
|
var/mob/user
|
|
var/title
|
|
var/window_id // window_id is used as the window name for browse and onclose
|
|
var/width = 0
|
|
var/height = 0
|
|
var/atom/ref = null
|
|
var/window_options = "focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
|
|
var/stylesheets[0]
|
|
var/scripts[0]
|
|
var/title_image
|
|
var/head_elements
|
|
var/body_elements
|
|
var/head_content = ""
|
|
var/content = ""
|
|
var/title_buttons = ""
|
|
|
|
|
|
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
|
|
|
|
user = nuser
|
|
window_id = nwindow_id
|
|
if (ntitle)
|
|
title = format_text(ntitle)
|
|
if (nwidth)
|
|
width = nwidth
|
|
if (nheight)
|
|
height = nheight
|
|
if (nref)
|
|
ref = nref
|
|
add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs
|
|
|
|
/datum/browser/proc/set_user(nuser)
|
|
user = nuser
|
|
|
|
/datum/browser/proc/set_title(ntitle)
|
|
title = format_text(ntitle)
|
|
|
|
/datum/browser/proc/add_head_content(nhead_content)
|
|
head_content = nhead_content
|
|
|
|
/datum/browser/proc/set_title_buttons(ntitle_buttons)
|
|
title_buttons = ntitle_buttons
|
|
|
|
/datum/browser/proc/set_window_options(nwindow_options)
|
|
window_options = nwindow_options
|
|
|
|
/datum/browser/proc/set_title_image(ntitle_image)
|
|
//title_image = ntitle_image
|
|
|
|
/datum/browser/proc/add_stylesheet(name, file)
|
|
stylesheets["[ckey(name)].css"] = file
|
|
register_asset("[ckey(name)].css", file)
|
|
|
|
/datum/browser/proc/add_script(name, file)
|
|
scripts["[ckey(name)].js"] = file
|
|
register_asset("[ckey(name)].js", file)
|
|
|
|
/datum/browser/proc/set_content(ncontent)
|
|
content = ncontent
|
|
|
|
/datum/browser/proc/add_content(ncontent)
|
|
content += ncontent
|
|
|
|
/datum/browser/proc/get_header()
|
|
var/file
|
|
for (file in stylesheets)
|
|
head_content += "<link rel='stylesheet' type='text/css' href='[file]'>"
|
|
|
|
for (file in scripts)
|
|
head_content += "<script type='text/javascript' src='[file]'></script>"
|
|
|
|
var/title_attributes = "class='uiTitle'"
|
|
if (title_image)
|
|
title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'"
|
|
|
|
return {"<!DOCTYPE html>
|
|
<html>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<head>
|
|
[head_content]
|
|
</head>
|
|
<body scroll=auto>
|
|
<div class='uiWrapper'>
|
|
[title ? "<div class='uiTitleWrapper'><div [title_attributes]><tt>[title]</tt></div><div class='uiTitleButtons'>[title_buttons]</div></div>" : ""]
|
|
<div class='uiContent'>
|
|
"}
|
|
|
|
/datum/browser/proc/get_footer()
|
|
return {"
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>"}
|
|
|
|
/datum/browser/proc/get_content()
|
|
return {"
|
|
[get_header()]
|
|
[content]
|
|
[get_footer()]
|
|
"}
|
|
|
|
/datum/browser/proc/open(var/use_onclose = 1)
|
|
var/window_size = ""
|
|
if (width && height)
|
|
window_size = "size=[width]x[height];"
|
|
if (stylesheets.len)
|
|
send_asset_list(user, stylesheets, verify = FALSE)
|
|
if (scripts.len)
|
|
send_asset_list(user, scripts, verify = FALSE)
|
|
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
|
|
if (use_onclose)
|
|
setup_onclose()
|
|
|
|
// Fix from /tg/.
|
|
/datum/browser/proc/setup_onclose()
|
|
set waitfor = 0
|
|
for (var/i in 1 to 10)
|
|
if (user && winexists(user, window_id))
|
|
onclose(user, window_id, ref)
|
|
break
|
|
|
|
/datum/browser/proc/update(var/force_open = 0, var/use_onclose = 1)
|
|
if(force_open)
|
|
open(use_onclose)
|
|
else
|
|
send_output(user, get_content(), "[window_id].browser")
|
|
|
|
/datum/browser/proc/close()
|
|
user << browse(null, "window=[window_id]")
|
|
|
|
// This will allow you to show an icon in the browse window
|
|
// This is added to mob so that it can be used without a reference to the browser object
|
|
// There is probably a better place for this...
|
|
/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1)
|
|
/*
|
|
var/icon/I
|
|
if (dir >= 0)
|
|
I = new /icon(icon, icon_state, dir)
|
|
else
|
|
I = new /icon(icon, icon_state)
|
|
dir = "default"
|
|
|
|
var/filename = "[ckey("[icon]_[icon_state]_[dir]")].png"
|
|
src << browse_rsc(I, filename)
|
|
return filename
|
|
*/
|
|
|
|
|
|
// Registers the on-close verb for a browse window (client/verb/.windowclose)
|
|
// this will be called when the close-button of a window is pressed.
|
|
//
|
|
// This is usually only needed for devices that regularly update the browse window,
|
|
// e.g. canisters, timers, etc.
|
|
//
|
|
// windowid should be the specified window name
|
|
// e.g. code is : user << browse(text, "window=fred")
|
|
// then use : onclose(user, "fred")
|
|
//
|
|
// Optionally, specify the "ref" parameter as the controlled atom (usually src)
|
|
// to pass a "close=1" parameter to the atom's Topic() proc for special handling.
|
|
// Otherwise, the user mob's machine var will be reset directly.
|
|
//
|
|
/proc/onclose(mob/user, windowid, var/atom/ref=null)
|
|
if(!user || !user.client) return
|
|
var/param = "null"
|
|
if(ref)
|
|
param = "\ref[ref]"
|
|
|
|
winset(user, windowid, "on-close=\".windowclose [param]\"")
|
|
|
|
//world << "OnClose [user]: [windowid] : ["on-close=\".windowclose [param]\""]"
|
|
|
|
|
|
// the on-close client verb
|
|
// called when a browser popup window is closed after registering with proc/onclose()
|
|
// if a valid atom reference is supplied, call the atom's Topic() with "close=1"
|
|
// otherwise, just reset the client mob's machine var.
|
|
//
|
|
/client/verb/windowclose(var/atomref as text)
|
|
set hidden = 1 // hide this verb from the user's panel
|
|
set name = ".windowclose" // no autocomplete on cmd line
|
|
|
|
//world << "windowclose: [atomref]"
|
|
if(atomref!="null") // if passed a real atomref
|
|
var/hsrc = locate(atomref) // find the reffed atom
|
|
if(hsrc)
|
|
//world << "[src] Topic [href] [hsrc]"
|
|
usr = src.mob
|
|
src.Topic("close=1", list("close"="1"), hsrc) // this will direct to the atom's
|
|
return // Topic() proc via client.Topic()
|
|
|
|
// no atomref specified (or not found)
|
|
// so just reset the user mob's machine var
|
|
if(src && src.mob)
|
|
//world << "[src] was [src.mob.machine], setting to null"
|
|
src.mob.unset_machine()
|
|
return
|