[MIRROR] [READY] Adds notification support to modular computer apps, updates CIMS to use it (#1715)

* [READY] Adds notification support to modular computer apps, updates CIMS to use it

* Update tgui.bundle.js

Co-authored-by: zxaber <37497534+zxaber@users.noreply.github.com>
Co-authored-by: Azarak <azarak10@gmail.com>
This commit is contained in:
SkyratBot
2020-11-19 07:15:31 +01:00
committed by GitHub
co-authored by zxaber Azarak
parent fd276e1be0
commit 2ac44cb9d7
12 changed files with 143 additions and 6 deletions
@@ -263,6 +263,28 @@
handle_power(delta_time) // Handles all computer power interaction
//check_update_ui_need()
/**
* Displays notification text alongside a soundbeep when requested to by a program.
*
* After checking tha the requesting program is allowed to send an alert, creates
* a visible message of the requested text alongside a soundbeep. This proc adds
* text to indicate that the message is coming from this device and the program
* on it, so the supplied text should be the exact message and ending punctuation.
*
* Arguments:
* The program calling this proc.
* The message that the program wishes to display.
*/
/obj/item/modular_computer/proc/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/twobeep_high.ogg')
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
return
playsound(src, sound, 50, TRUE)
visible_message("<span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")
var/mob/living/holder = loc
if(istype(holder))
to_chat(holder, "[icon2html(src)] <span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")
// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
/obj/item/modular_computer/proc/get_header_data()
var/list/data = list()
@@ -80,7 +80,7 @@
if(P in idle_threads)
running = TRUE
data["programs"] += list(list("name" = P.filename, "desc" = P.filedesc, "running" = running, "icon" = P.program_icon))
data["programs"] += list(list("name" = P.filename, "desc" = P.filedesc, "running" = running, "icon" = P.program_icon, "alert" = P.alert_pending))
data["has_light"] = has_light
data["light_on"] = light_on
@@ -148,6 +148,7 @@
if(P in idle_threads)
P.program_state = PROGRAM_STATE_ACTIVE
active_program = P
P.alert_pending = FALSE
idle_threads.Remove(P)
update_icon()
return
@@ -163,6 +164,7 @@
return
if(P.run_program(user))
active_program = P
P.alert_pending = FALSE
update_icon()
return 1
@@ -52,3 +52,9 @@
/obj/item/modular_computer/processor/attack_ghost(mob/user)
ui_interact(user)
/obj/item/modular_computer/processor/alert_call(datum/computer_file/program/caller, alerttext)
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext)
return
playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
machinery_computer.visible_message("<span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")
@@ -130,6 +130,13 @@
borgo.toggle_headlamp(FALSE, TRUE)
return TRUE
/obj/item/modular_computer/tablet/integrated/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/twobeep_high.ogg')
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
return
borgo.playsound_local(src, sound, 50, TRUE)
to_chat(borgo, "<span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")
/obj/item/modular_computer/tablet/integrated/syndicate
icon_state = "tablet-silicon-syndicate"
device_theme = "syndicate"
@@ -35,6 +35,12 @@
var/ui_header = null
/// Font Awesome icon to use as this program's icon in the modular computer main menu. Defaults to a basic program maximize window icon if not overridden.
var/program_icon = "window-maximize-o"
/// Whether this program can send alerts while minimized or closed. Used to show a mute button per program in the file manager
var/alert_able = FALSE
/// Whether the user has muted this program's ability to send alerts.
var/alert_silenced = FALSE
/// Whether to highlight our program in the main screen. Intended for alerts, but loosely available for any need to notify of changed conditions. Think Windows task bar highlighting. Available even if alerts are muted.
var/alert_pending = FALSE
/datum/computer_file/program/New(obj/item/modular_computer/comp = null)
..()
@@ -67,6 +67,13 @@
var/datum/computer_file/C = F.clone(FALSE)
HDD.store_file(C)
return TRUE
if("PRG_togglesilence")
if(!HDD)
return
var/datum/computer_file/program/binary = HDD.find_file_by_name(params["name"])
if(!binary || !istype(binary))
return
binary.alert_silenced = !binary.alert_silenced
/datum/computer_file/program/filemanager/ui_data(mob/user)
var/list/data = get_header_data()
@@ -80,11 +87,19 @@
else
var/list/files = list()
for(var/datum/computer_file/F in HDD.stored_files)
var/noisy = FALSE
var/silenced = FALSE
var/datum/computer_file/program/binary = F
if(istype(binary))
noisy = binary.alert_able
silenced = binary.alert_silenced
files += list(list(
"name" = F.filename,
"type" = F.filetype,
"size" = F.size,
"undeletable" = F.undeletable
"undeletable" = F.undeletable,
"alert_able" = noisy,
"alert_silenced" = silenced
))
data["files"] = files
if(RHDD)
@@ -9,10 +9,15 @@
size = 5
tgui_id = "NtosSupermatterMonitor"
program_icon = "radiation"
alert_able = TRUE
var/last_status = SUPERMATTER_INACTIVE
var/list/supermatters
var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal.
/datum/computer_file/program/supermatter_monitor/Destroy()
clear_signals()
active = null
return ..()
/datum/computer_file/program/supermatter_monitor/process_tick()
..()
@@ -26,10 +31,11 @@
/datum/computer_file/program/supermatter_monitor/run_program(mob/living/user)
. = ..(user)
if(!(active in GLOB.machines))
active = null
refresh()
/datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE)
active = null
supermatters = null
..()
@@ -53,6 +59,58 @@
for(var/obj/machinery/power/supermatter_crystal/S in supermatters)
. = max(., S.get_status())
/**
* Sets up the signal listener for Supermatter delaminations.
*
* Unregisters any old listners for SM delams, and then registers one for the SM refered
* to in the `active` variable. This proc is also used with no active SM to simply clear
* the signal and exit.
*/
/datum/computer_file/program/supermatter_monitor/proc/set_signals()
if(active)
RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM, .proc/send_alert, override = TRUE)
RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM, .proc/send_start_alert, override = TRUE)
/**
* Removes the signal listener for Supermatter delaminations from the selected supermatter.
*
* Pretty much does what it says.
*/
/datum/computer_file/program/supermatter_monitor/proc/clear_signals()
if(active)
UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM)
UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM)
/**
* Sends an SM delam alert to the computer.
*
* Triggered by a signal from the selected supermatter, this proc sends a notification
* to the computer if the program is either closed or minimized. We do not send these
* notifications to the comptuer if we're the active program, because engineers fixing
* the supermatter probably don't need constant beeping to distract them.
*/
/datum/computer_file/program/supermatter_monitor/proc/send_alert()
if(!computer.get_ntnet_status())
return
if(computer.active_program != src)
computer.alert_call(src, "Crystal delamination in progress!")
alert_pending = TRUE
/**
* Sends an SM delam start alert to the computer.
*
* Triggered by a signal from the selected supermatter at the start of a delamination,
* this proc sends a notification to the computer if this program is the active one.
* We do this so that people carrying a tablet with NT CIMS open but with the NTOS window
* closed will still get one audio alert. This is not sent to computers with the program
* minimized or closed to avoid double-notifications.
*/
/datum/computer_file/program/supermatter_monitor/proc/send_start_alert()
if(!computer.get_ntnet_status())
return
if(computer.active_program == src)
computer.alert_call(src, "Crystal delamination in progress!")
/datum/computer_file/program/supermatter_monitor/ui_data()
var/list/data = get_header_data()
@@ -112,6 +170,7 @@
switch(action)
if("PRG_clear")
clear_signals()
active = null
return TRUE
if("PRG_refresh")
@@ -122,4 +181,5 @@
for(var/obj/machinery/power/supermatter_crystal/S in supermatters)
if(S.uid == newuid)
active = S
set_signals()
return TRUE