Bun, Inferno->React migration (#22529)

Re-creation of https://github.com/Aurorastation/Aurora.3/pull/21046 to
skip merge conflict hell. Brings us modern TGUI.

**ALTERNATE TITLE: TGUI HELLSCAPE PR
ABANDON ALL HOPE YE WHO ENTER HERE**

- [x] Migrate build tools (javascript -> typescript, bun for package
management).
- [x] Upgrade all TGUI dependencies and associated root files to
TG-congruent versions (axios, babel, dompurify, eslint, highlight,
marked, prettier, sass, source-map, stacktrace-parser, typescript).
- [x] InfernoJS -> React migrations
- [x] React cleanup and polish (migrate all remaining .js files to
appropriate .ts or .tsx filetype, all remaining hooks, linting, error
corrections, etc.)
- [ ] Test all remaining TGUI interfaces
This commit is contained in:
Batrachophreno
2026-06-05 15:55:22 +02:00
committed by GitHub
parent a52729c105
commit 0d92359da7
930 changed files with 23130 additions and 50520 deletions
+15 -16
View File
@@ -344,23 +344,22 @@
I.forceMove(T)
/obj/item/get_examine_text(mob/user, distance, is_adjacent, infix, suffix, get_extended = FALSE)
var/size
switch(src.w_class)
if (WEIGHT_CLASS_HUGE to INFINITY)
size = "huge"
if (WEIGHT_CLASS_BULKY to WEIGHT_CLASS_HUGE)
size = "bulky"
if (WEIGHT_CLASS_NORMAL to WEIGHT_CLASS_BULKY)
size = "normal-sized"
if (WEIGHT_CLASS_SMALL to WEIGHT_CLASS_NORMAL)
size = "small"
if (0 to WEIGHT_CLASS_SMALL)
size = "tiny"
//Changed this switch to ranges instead of tiered values, to cope with granularity and also
//things outside its range ~Nanako
/obj/item/examine_descriptor(mob/user)
return "item"
. = ..(user, distance, is_adjacent, "It is a [size] item.", get_extended = get_extended)
/obj/item/examine_tags(mob/user)
var/list/parent_tags = ..()
parent_tags.Insert(1, weight_class_to_text(w_class)) // To make size display first, otherwise it looks goofy
. = parent_tags
.[weight_class_to_text(w_class)] = weight_class_to_tooltip(w_class)
if (siemens_coefficient == 0)
.["insulated"] = "It is made from a robust electrical insulator and will block any electricity passing through it!"
else if (siemens_coefficient <= 0.5)
.["partially insulated"] = "It is made from a poor insulator that will dampen (but not fully block) electric shocks passing through it."
/obj/item/get_examine_text(mob/user, distance, is_adjacent, infix, suffix, get_extended = FALSE)
. = ..(user, distance, is_adjacent, get_extended = get_extended)
var/datum/component/armor/armor_component = GetComponent(/datum/component/armor)
if(armor_component && !armor_component.hidden)
. += FONT_SMALL(SPAN_NOTICE("\[?\] This item has armor values. <a href='byond://?src=[REF(src)];examine_armor=1'>\[Show Armor Values\]</a>"))
@@ -42,7 +42,7 @@
else if(crystal_type == CRYSTAL_TYPE_BLUECRYSTAL)
I.hidden_uplink.bluecrystals += amount
I.hidden_uplink.update_tgui_data()
SSnanoui.update_uis(I.hidden_uplink)
SStgui.update_uis(I.hidden_uplink)
use(amount)
to_chat(user, SPAN_NOTICE("You slot \the [src] into \the [I] and charge its internal uplink."))
+16 -4
View File
@@ -6,16 +6,20 @@
pass_flags_self = PASSSTRUCTURE
should_use_health = TRUE
var/material_alteration = MATERIAL_ALTERATION_ALL // Overrides for material shit. Set them manually if you don't want colors etc. See wood chairs/office chairs.
/// Overrides for material shit. Set them manually if you don't want colors etc. See wood chairs/office chairs.
var/material_alteration = MATERIAL_ALTERATION_ALL
var/climbable
var/parts
var/list/climbers
var/list/footstep_sound //footstep sounds when stepped on
/// Footstep sounds when stepped on
var/list/footstep_sound
var/material/material
var/build_amt = 2 // used by some structures to determine into how many pieces they should disassemble into or be made with
/// Used by some structures to determine into how many pieces they should disassemble into or be made with
var/build_amt = 2
var/slowdown = 0 //amount that pulling mobs have their movement delayed by
/// Amount that pulling mobs have their movement delayed by
var/slowdown = 0
/obj/structure/Initialize(mapload)
. = ..()
@@ -40,6 +44,14 @@
material = null
return ..()
/obj/structure/examine_descriptor(mob/user)
return "structure"
/obj/structure/examine_tags(atom/source, mob/user, list/examine_list)
. = ..()
if(climbable)
.["climbable"] = "It can be climbed on, either by dragging your mob onto it or middle-clicking it."
/obj/structure/attackby(obj/item/attacking_item, mob/user, params)
. = ..()
if(user?.a_intent == I_HURT && maxhealth)
+4 -1
View File
@@ -258,6 +258,9 @@ Class Procs:
return FALSE
qdel(src)
/obj/structure/machinery/examine_descriptor(mob/user)
return "machine"
// /obj/structure/machinery/proc/process_all()
// /* Uncomment this if/when you need component processing
// if(processing_flags & MACHINERY_PROCESS_COMPONENTS)
@@ -643,5 +646,5 @@ Class Procs:
/obj/structure/machinery/ui_status(mob/user, datum/ui_state/state)
. = ..()
if(. < UI_INTERACTIVE)
if(user.machine)
if(user?.machine)
user.unset_machine()
+24 -29
View File
@@ -118,9 +118,8 @@ pixel_x = 10;
var/breach_detection = 1
//var/skipprocess = 0 //Experimenting
var/alarm_frequency = 1437
var/remote_control = 0
var/rcon_setting = 2
var/rcon_time = 0
/// If true, RCON is enabled. If false, RCON has been disabled.
var/rcon_setting = TRUE
var/locked = 1
var/aidisabled = 0
var/shorted = 0
@@ -475,18 +474,6 @@ pixel_x = 10;
mode=AALARM_MODE_FILL
apply_mode()
//atmos computer remote controll stuff
switch(rcon_setting)
if(RCON_NO)
remote_control = 0
if(RCON_AUTO)
if(danger_level == 2)
remote_control = 1
else
remote_control = 0
if(RCON_YES)
remote_control = 1
return
/obj/structure/machinery/alarm/proc/handle_heating_cooling(datum/gas_mixture/environment, seconds_per_tick)
@@ -698,6 +685,22 @@ pixel_x = 10;
frequency.post_signal(src, alert_signal)
/obj/structure/machinery/alarm/proc/is_alarming()
return max(danger_level, alarm_area?.atmosalm) > 0
/obj/structure/machinery/alarm/proc/is_remote_user(mob/user)
if(!user)
return FALSE
for(var/datum/tgui/open_tgui in user.tgui_open_uis)
if(open_tgui.interface == "AtmosAlarmControl")
return TRUE
return FALSE
/obj/structure/machinery/alarm/proc/is_unlocked_for(mob/user)
if(is_remote_user(user) && rcon_setting)
return TRUE
return !locked || issilicon(user)
/obj/structure/machinery/alarm/attack_ai(mob/user)
if(!ai_can_interact(user))
return
@@ -751,7 +754,8 @@ pixel_x = 10;
data["target_temperature"] = round(target_temperature - T0C, 0.1)
// Access
data["locked"] = locked && !issilicon(user)
data["locked"] = !is_unlocked_for(user)
data["remote_view"] = is_remote_user(user)
data["shorted"] = shorted
data["rcon"] = rcon_setting
@@ -848,14 +852,6 @@ pixel_x = 10;
// Actions available without unlocking
switch(action)
if("rcon")
var/new_rcon = text2num(params["value"])
switch(new_rcon)
if(RCON_NO) rcon_setting = RCON_NO
if(RCON_AUTO) rcon_setting = RCON_AUTO
if(RCON_YES) rcon_setting = RCON_YES
return TRUE
if("temperature")
var/list/tlv = TLV["temperature"]
var/max_temperature = min(tlv[3] - T0C, MAX_TEMPERATURE)
@@ -871,7 +867,7 @@ pixel_x = 10;
return TRUE
// Actions that require the alarm to be unlocked
if(locked && !issilicon(usr))
if(!is_unlocked_for(usr))
return
switch(action)
@@ -962,11 +958,10 @@ pixel_x = 10;
apply_mode()
return TRUE
/// Snowflake proc to make it so users of the Atmosphere Control app (having the UI open) have full access to an alarm.
/// Lets Atmosphere Control users remotely view alarms.
/obj/structure/machinery/alarm/ui_status(mob/user)
for(var/datum/tgui/open_tgui in user.tgui_open_uis)
if(open_tgui.interface == "AtmosAlarmControl")
return UI_INTERACTIVE
if(is_remote_user(user) && rcon_setting)
return UI_INTERACTIVE
return ..()
/**
@@ -141,7 +141,7 @@
var/list/sensor_information = list()
var/datum/radio_frequency/radio_connection
var/ui_type = "AtmosControl"
ui_type = "AtmosControl"
circuit = /obj/item/circuitboard/air_management
/obj/structure/machinery/computer/general_air_control/Destroy()
@@ -32,6 +32,9 @@
/// The access cable inserted into this computer, if any.
var/obj/item/access_cable/inserted_cable
/// Contains the name of the TGUI interface file opened when using this computer. If null,
var/ui_type = ""
/obj/structure/machinery/computer/Initialize()
. = ..()
overlay_layer = layer
@@ -45,11 +48,6 @@
inserted_cable = null
return ..()
/obj/structure/machinery/computer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = TRUE)
if(!operable() || !is_station_level(z) || user.stat)
user.unset_machine()
return
/obj/structure/machinery/computer/emp_act(severity)
. = ..()
@@ -248,10 +248,7 @@
/obj/structure/machinery/computer/scan_consolenew/attackby(obj/item/attacking_item, mob/user)
if (istype(attacking_item, /obj/item/disk/data)) //INSERT SOME diskS
if (!src.disk)
user.drop_from_inventory(attacking_item, src)
src.disk = attacking_item
to_chat(user, "You insert [attacking_item].")
SSnanoui.update_uis(src) // update all UIs attached to src
to_chat(user, "You try to insert [attacking_item], but the drive seems jammed.")
return TRUE
else
return ..()
@@ -274,7 +274,6 @@
signal.data["dock_status"] = get_docking_status()
post_signal(signal)
//this is mostly for NanoUI
/datum/computer/file/embedded_program/docking/proc/get_docking_status()
switch (dock_state)
if (STATE_UNDOCKED) return "undocked"
@@ -97,7 +97,7 @@
var/categories = CAT_NORMAL
/// What we're requesting payment for right now
var/datum/data/vending_product/currently_vending = null
/// Status screen messages like "insufficient funds", displayed in NanoUI
/// Status screen messages like "insufficient funds", displayed in UI
var/status_message = ""
/// Set to 1 if status_message is an error
var/status_error = 0
@@ -770,7 +770,6 @@
sel_key = params["vendItem"]
var/datum/data/vending_product/R = product_records[key]
// This should not happen unless the request from NanoUI was bad
if(!(R.category & categories))
return