From d17a60fb53c16c4d61342c757efb3cf3dc376699 Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Wed, 15 Dec 2021 14:12:04 -0800 Subject: [PATCH] TGUI input box conversions 2 (#63395) More text inputs converted to tgui, TGUI text and number input now more sanely handles ENTER key being pressed, you can now press anywhere in the window to enter the input. TGUI text input now considers placeholder text for the default valid state. IE, if there is default text you can press enter immediately without having to rewrite it just to recheck validity. Fixes: useSharedState => useLocalState. not only was sharedstate not needed but it opened up the ui to vulnerabilities --- code/__HELPERS/areas.dm | 7 +-- code/datums/components/cult_ritual_item.dm | 2 +- code/datums/components/gps.dm | 2 +- code/datums/components/spirit_holding.dm | 2 +- code/game/machinery/camera/camera_assembly.dm | 2 +- .../machinery/computer/prisoner/management.dm | 2 +- code/game/machinery/requests_console.dm | 4 +- code/game/machinery/roulette_machine.dm | 2 +- code/game/objects/items/AI_modules.dm | 12 ++-- code/game/objects/items/blueprints.dm | 2 +- code/game/objects/items/devices/PDA/PDA.dm | 4 +- .../objects/items/devices/PDA/virus_cart.dm | 4 +- code/game/objects/items/devices/beacon.dm | 2 +- .../objects/items/implants/implantcase.dm | 2 +- .../objects/items/implants/implantchair.dm | 4 +- code/game/objects/items/implants/implanter.dm | 2 +- .../objects/items/robot/robot_upgrades.dm | 2 +- code/game/objects/items/signs.dm | 2 +- code/game/objects/items/spear.dm | 2 +- code/game/objects/items/toys.dm | 2 +- code/game/objects/items/virgin_mary.dm | 2 +- code/game/objects/structures/displaycase.dm | 2 +- code/game/objects/structures/door_assembly.dm | 2 +- code/modules/admin/verbs/borgpanel.dm | 2 +- .../abductor/equipment/abduction_gear.dm | 6 +- .../changeling/powers/mimic_voice.dm | 2 +- .../antagonists/cult/rune_spawn_action.dm | 2 +- .../antagonists/disease/disease_mob.dm | 2 +- .../nukeop/equipment/nuclear_challenge.dm | 4 +- code/modules/antagonists/wizard/wizard.dm | 2 +- code/modules/tgui/tgui_input_number.dm | 60 +++++++++---------- code/modules/tgui/tgui_input_text.dm | 55 +++++++++-------- code/modules/vending/_vending.dm | 6 +- .../tgui/interfaces/NumberInputModal.tsx | 20 +++---- .../packages/tgui/interfaces/PaiInterface.tsx | 6 +- .../tgui/interfaces/TextInputModal.tsx | 56 +++++++++-------- 36 files changed, 143 insertions(+), 149 deletions(-) diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index 6323f238844..822c47e1d05 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -74,11 +74,8 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engineerin var/area/newA var/area/oldA = get_area(get_turf(creator)) if(!isarea(area_choice)) - var/str = stripped_input(creator,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN) - if(!str || !length(str)) //cancel - return - if(length(str) > 50) - to_chat(creator, span_warning("The given name is too long. The area remains undefined.")) + var/str = tgui_input_text(creator, "New area name", "Blueprint Editing", max_length = MAX_NAME_LEN) + if(!str) return newA = new area_choice newA.setup(str) diff --git a/code/datums/components/cult_ritual_item.dm b/code/datums/components/cult_ritual_item.dm index eb5876fd612..e4956e40deb 100644 --- a/code/datums/components/cult_ritual_item.dm +++ b/code/datums/components/cult_ritual_item.dm @@ -268,7 +268,7 @@ return FALSE if(initial(rune_to_scribe.req_keyword)) - chosen_keyword = stripped_input(cultist, "Enter a keyword for the new rune.", "Words of Power") + chosen_keyword = tgui_input_text(cultist, "Keyword for the new rune", "Words of Power", max_length = MAX_NAME_LEN) if(!chosen_keyword) drawing_a_rune = FALSE start_scribe_rune(tool, cultist) diff --git a/code/datums/components/gps.dm b/code/datums/components/gps.dm index eeca6811d1d..4ed1e89938a 100644 --- a/code/datums/components/gps.dm +++ b/code/datums/components/gps.dm @@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(GPS_list) switch(action) if("rename") var/atom/parentasatom = parent - var/a = stripped_input(usr, "Please enter desired tag.", parentasatom.name, gpstag, 20) + var/a = tgui_input_text(usr, "Enter the desired tag", "GPS Tag", gpstag, 20) if (!a) return diff --git a/code/datums/components/spirit_holding.dm b/code/datums/components/spirit_holding.dm index 18808457a36..d226c6df9f8 100644 --- a/code/datums/components/spirit_holding.dm +++ b/code/datums/components/spirit_holding.dm @@ -74,7 +74,7 @@ bound_spirit.copy_languages(awakener, LANGUAGE_MASTER) //Make sure the sword can understand and communicate with the awakener. bound_spirit.update_atom_languages() bound_spirit.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue - var/input = sanitize_name(stripped_input(bound_spirit, "What are you named?", ,"", MAX_NAME_LEN)) + var/input = sanitize_name(tgui_input_text(bound_spirit, "What are you named?", "Spectral Nomenclature", max_length = MAX_NAME_LEN)) if(parent && input) parent = input bound_spirit.fully_replace_character_name(null, "The spirit of [input]") diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 96089f35328..f5e00d592e7 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -219,7 +219,7 @@ return FALSE tool.play_tool_sound(src) - var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13") + var/input = tgui_input_text(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret", "Set Network", "SS13", multiline = TRUE) if(!input) to_chat(user, span_warning("No input found, please hang up and try your call again!")) return diff --git a/code/game/machinery/computer/prisoner/management.dm b/code/game/machinery/computer/prisoner/management.dm index bff0d2be14d..f69d7b9e6f2 100644 --- a/code/game/machinery/computer/prisoner/management.dm +++ b/code/game/machinery/computer/prisoner/management.dm @@ -123,7 +123,7 @@ to_chat(usr, span_danger("Unauthorized access.")) else if(href_list["warn"]) - var/warning = stripped_input(usr, "Message:", "Enter your message here!", "", MAX_MESSAGE_LEN) + var/warning = tgui_input_text(usr, "Enter your message here", "Messaging") if(!warning) return var/obj/item/implant/I = locate(href_list["warn"]) in GLOB.tracked_implants diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index bccb8a07992..cae2f1c7678 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -246,7 +246,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/requests_console, 30) if(href_list["write"]) to_department = ckey(reject_bad_text(href_list["write"])) //write contains the string of the receiving department's name - var/new_message = (to_department in GLOB.req_console_ckey_departments) && stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN) + var/new_message = (to_department in GLOB.req_console_ckey_departments) && tgui_input_text(usr, "Write your message", "Awaiting Input") if(new_message) to_department = GLOB.req_console_ckey_departments[to_department] message = new_message @@ -254,7 +254,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/requests_console, 30) priority = clamp(text2num(href_list["priority"]), REQ_NORMAL_MESSAGE_PRIORITY, REQ_EXTREME_MESSAGE_PRIORITY) if(href_list["writeAnnouncement"]) - var/new_message = reject_bad_text(stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN)) + var/new_message = reject_bad_text(tgui_input_text(usr, "Write your message", "Awaiting Input")) if(new_message) message = new_message priority = clamp(text2num(href_list["priority"]) || REQ_NORMAL_MESSAGE_PRIORITY, REQ_NORMAL_MESSAGE_PRIORITY, REQ_EXTREME_MESSAGE_PRIORITY) diff --git a/code/game/machinery/roulette_machine.dm b/code/game/machinery/roulette_machine.dm index 9097a219f87..040b41b96bd 100644 --- a/code/game/machinery/roulette_machine.dm +++ b/code/game/machinery/roulette_machine.dm @@ -171,7 +171,7 @@ else var/obj/item/card/id/new_card = W if(new_card.registered_account) - var/msg = stripped_input(user, "Name of your roulette wheel:", "Roulette Naming", "Roulette Machine") + var/msg = tgui_input_text(user, "Name of your roulette wheel", "Roulette Naming", "Roulette Machine", MAX_NAME_LEN) if(!msg) return name = msg diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm index b805ad61ace..2a65725dd1b 100644 --- a/code/game/objects/items/AI_modules.dm +++ b/code/game/objects/items/AI_modules.dm @@ -169,7 +169,7 @@ AI MODULES lawpos = 4 /obj/item/ai_module/supplied/safeguard/attack_self(mob/user) - var/targName = stripped_input(user, "Please enter the subject to safeguard.", "Safeguard who?", user.name,MAX_NAME_LEN) + var/targName = tgui_input_text(user, "Subject to safeguard.", "Safeguard", user.name, MAX_NAME_LEN) if(!targName) return targetName = targName @@ -195,7 +195,7 @@ AI MODULES laws = list("Only SUBJECT is human.") /obj/item/ai_module/zeroth/onehuman/attack_self(mob/user) - var/targName = stripped_input(user, "Please enter the subject who is the only human.", "Who?", user.real_name,MAX_NAME_LEN) + var/targName = tgui_input_text(user, "Enter the subject who is the only human.", "One Human", user.real_name, MAX_NAME_LEN) if(!targName) return targetName = targName @@ -255,7 +255,7 @@ AI MODULES return newpos = 15 lawpos = min(newpos, 50) - var/targName = stripped_input(user, "Please enter a new law for the AI.", "Freeform Law Entry", laws[1], CONFIG_GET(number/max_law_len)) + var/targName = tgui_input_text(user, "Enter a new law for the AI.", "Freeform Law Entry", laws[1], CONFIG_GET(number/max_law_len), TRUE) if(!targName) return if(is_ic_filtered(targName)) @@ -386,7 +386,7 @@ AI MODULES var/subject = "human being" /obj/item/ai_module/core/full/asimov/attack_self(mob/user as mob) - var/targName = stripped_input(user, "Please enter a new subject that asimov is concerned with.", "Asimov to whom?", subject, MAX_NAME_LEN) + var/targName = tgui_input_text(user, "Enter a new subject that Asimov is concerned with.", "Asimov", subject, MAX_NAME_LEN) if(!targName) return subject = targName @@ -468,7 +468,7 @@ AI MODULES laws = list("") /obj/item/ai_module/core/freeformcore/attack_self(mob/user) - var/targName = stripped_input(user, "Please enter a new core law for the AI.", "Freeform Law Entry", laws[1], CONFIG_GET(number/max_law_len)) + var/targName = tgui_input_text(user, "Enter a new core law for the AI.", "Freeform Law Entry", laws[1], CONFIG_GET(number/max_law_len), TRUE) if(!targName) return if(is_ic_filtered(targName)) @@ -496,7 +496,7 @@ AI MODULES laws = list("") /obj/item/ai_module/syndicate/attack_self(mob/user) - var/targName = stripped_input(user, "Please enter a new law for the AI.", "Freeform Law Entry", laws[1], CONFIG_GET(number/max_law_len)) + var/targName = tgui_input_text(user, "Enter a new law for the AI", "Freeform Law Entry", laws[1], CONFIG_GET(number/max_law_len), TRUE) if(!targName) return if(is_ic_filtered(targName)) // not even the syndicate can uwu diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index 43f7a5d6f40..00b105a7687 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -190,7 +190,7 @@ /obj/item/areaeditor/proc/edit_area() var/area/A = get_area(usr) var/prevname = "[A.name]" - var/str = stripped_input(usr,"New area name:", "Area Creation", "", MAX_NAME_LEN) + var/str = tgui_input_text(usr, "New area name", "Area Creation", max_length = MAX_NAME_LEN) if(!str || !length(str) || str==prevname) //cancel return if(length(str) > 50) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 33e5a7fd0b2..bbbcb7cd5c0 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -649,7 +649,7 @@ GLOBAL_LIST_EMPTY(PDAs) if("Clear")//Clears messages tnote = null if("Ringtone") - var/t = stripped_input(U, "Please enter new ringtone", name, ttone, 20) + var/t = tgui_input_text(U, "Enter a new ringtone", "PDA Ringtone", ttone, 20) if(in_range(src, U) && loc == U && t) if(SEND_SIGNAL(src, COMSIG_PDA_CHANGE_RINGTONE, U, t) & COMPONENT_STOP_RINGTONE_CHANGE) U << browse(null, "window=pda") @@ -767,7 +767,7 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/msg_input(mob/living/U = usr, rigged = FALSE) - var/t = stripped_input(U, "Please enter message", name) + var/t = tgui_input_text(U, "Enter a message", "PDA Messaging") if (!t || toff) return if(!U.canUseTopic(src, BE_CLOSE)) diff --git a/code/game/objects/items/devices/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm index 2c282c63bfd..75ff42e1eb0 100644 --- a/code/game/objects/items/devices/PDA/virus_cart.dm +++ b/code/game/objects/items/devices/PDA/virus_cart.dm @@ -77,10 +77,10 @@ return var/original_host = host_pda - var/fakename = sanitize_name(stripped_input(user, "Enter a name for the rigged message.", "Forge Message", null, MAX_NAME_LEN), allow_numbers = TRUE) + var/fakename = sanitize_name(tgui_input_text(user, "Enter a name for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE) if(!fakename || host_pda != original_host || !user.canUseTopic(host_pda, BE_CLOSE)) return - var/fakejob = sanitize_name(stripped_input(user, "Enter a job for the rigged message.", "Forge Message", null, MAX_NAME_LEN), allow_numbers = TRUE) + var/fakejob = sanitize_name(tgui_input_text(user, "Enter a job for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE) if(!fakejob || host_pda != original_host || !user.canUseTopic(host_pda, BE_CLOSE)) return if(charges > 0 && host_pda.send_message(user, list(target), rigged = REF(user), fakename = fakename, fakejob = fakejob)) diff --git a/code/game/objects/items/devices/beacon.dm b/code/game/objects/items/devices/beacon.dm index 7a6a6185700..2d21f8a8f59 100644 --- a/code/game/objects/items/devices/beacon.dm +++ b/code/game/objects/items/devices/beacon.dm @@ -33,7 +33,7 @@ /obj/item/beacon/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/pen)) // needed for things that use custom names like the locator - var/new_name = stripped_input(user, "What would you like the name to be?") + var/new_name = tgui_input_text(user, "What would you like the name to be?", "Beacon", max_length = MAX_NAME_LEN) if(!user.canUseTopic(src, BE_CLOSE)) return if(new_name) diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index 24465c722fd..51919c0d61e 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -28,7 +28,7 @@ if(!user.is_literate()) to_chat(user, span_notice("You scribble illegibly on the side of [src]!")) return - var/new_name = stripped_input(user, "What would you like the label to be?", name, null) + var/new_name = tgui_input_text(user, "What would you like the label to be?", name, max_length = MAX_NAME_LEN) if((user.get_active_held_item() != used_item) || !user.canUseTopic(src, BE_CLOSE)) return if(new_name) diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index e1b3a94579c..61282d9246c 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -187,13 +187,13 @@ var/objective = "Obey the law. Praise Nanotrasen." var/custom = FALSE -/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user) +/obj/machinery/implantchair/brainwash/implant_action(mob/living/C, mob/user) if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway. return FALSE if(custom) if(!user || !user.Adjacent(src)) return FALSE - objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120) + objective = tgui_input_text(user, "What order do you want to imprint on [C]?", "Brainwashing", max_length = 120) message_admins("[ADMIN_LOOKUPFLW(user)] set brainwash machine objective to '[objective]'.") log_game("[key_name(user)] set brainwash machine objective to '[objective]'.") if(HAS_TRAIT(C, TRAIT_MINDSHIELD)) diff --git a/code/game/objects/items/implants/implanter.dm b/code/game/objects/items/implants/implanter.dm index 4a7abaebcaa..9259c180bc0 100644 --- a/code/game/objects/items/implants/implanter.dm +++ b/code/game/objects/items/implants/implanter.dm @@ -52,7 +52,7 @@ to_chat(user, span_notice("You prod at [src] with [I]!")) return - var/new_name = stripped_input(user, "What would you like the label to be?", name, null) + var/new_name = tgui_input_text(user, "What would you like the label to be?", name, max_length = MAX_NAME_LEN) if(user.get_active_held_item() != I) return if(!user.canUseTopic(src, BE_CLOSE)) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 15ea9bcc9e8..9fe29d87639 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -40,7 +40,7 @@ one_use = TRUE /obj/item/borg/upgrade/rename/attack_self(mob/user) - heldname = sanitize_name(stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN), allow_numbers = TRUE) + heldname = sanitize_name(tgui_input_text(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN), allow_numbers = TRUE) log_game("[key_name(user)] have set \"[heldname]\" as a name in a cyborg reclassification board at [loc_name(user)]") /obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R, user = usr) diff --git a/code/game/objects/items/signs.dm b/code/game/objects/items/signs.dm index 6062d8b3287..ecf12da2c7f 100644 --- a/code/game/objects/items/signs.dm +++ b/code/game/objects/items/signs.dm @@ -22,7 +22,7 @@ if(!user.is_literate()) to_chat(user, span_notice("You scribble illegibly on [src]!")) return - var/txt = stripped_input(user, "What would you like to write on the sign?", "Sign Label", null , 30) + var/txt = tgui_input_text(user, "What would you like to write on the sign?", "Sign Label", max_length = 30) if(txt && user.canUseTopic(src, BE_CLOSE)) label = txt name = "[label] sign" diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index 4c5da9d062e..c0fa9c9752b 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -122,7 +122,7 @@ if(user.canUseTopic(src, BE_CLOSE)) ..() if(istype(user) && loc == user) - var/input = stripped_input(user,"What do you want your war cry to be? You will shout it when you hit someone in melee.", ,"", 50) + var/input = tgui_input_text(user, "What do you want your war cry to be? You will shout it when you hit someone in melee.", "War Cry", max_length = 50) if(input) src.war_cry = input diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 26a08f93fc1..b0016ee18a3 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1467,7 +1467,7 @@ //Add changing looks when i feel suicidal about making 20 inhands for these. /obj/item/toy/dummy/attack_self(mob/user) - var/new_name = stripped_input(usr,"What would you like to name the dummy?","Input a name",doll_name,MAX_NAME_LEN) + var/new_name = tgui_input_text(usr, "What would you like to name the dummy?", "Doll Name", doll_name, MAX_NAME_LEN) if(!new_name) return doll_name = new_name diff --git a/code/game/objects/items/virgin_mary.dm b/code/game/objects/items/virgin_mary.dm index d5ac9f761fa..71ee71ccfd8 100644 --- a/code/game/objects/items/virgin_mary.dm +++ b/code/game/objects/items/virgin_mary.dm @@ -27,7 +27,7 @@ return to_chat(joe, span_notice("As you burn the picture, a nickname comes to mind...")) - var/nickname = stripped_input(joe, "Pick a nickname", "Mafioso Nicknames", null, NICKNAME_CAP, TRUE) + var/nickname = tgui_input_text(joe, "Pick a nickname", "Mafioso Nicknames", max_length = NICKNAME_CAP) nickname = reject_bad_name(nickname, allow_numbers = FALSE, max_length = NICKNAME_CAP, ascii_only = TRUE) if(!nickname) return diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 3828250741a..58ff631bf7b 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -353,7 +353,7 @@ trophy_message = W.desc //default value - var/chosen_plaque = stripped_input(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque") + var/chosen_plaque = tgui_input_text(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque", trophy_message) if(chosen_plaque) if(user.Adjacent(src)) trophy_message = chosen_plaque diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 8c9f9aa4421..29b991f7a19 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -51,7 +51,7 @@ /obj/structure/door_assembly/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) - var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN) + var/t = tgui_input_text(user, "Enter the name for the door.", name, created_name, MAX_NAME_LEN) if(!t) return if(!in_range(src, usr) && loc != usr) diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index cfdd0e8260f..3f6a1ff8aa3 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -139,7 +139,7 @@ message_admins("[key_name_admin(user)] disabled scrambled codes on [ADMIN_LOOKUPFLW(borg)].") log_silicon("[key_name(user)] disabled scrambled codes on [key_name(borg)].") if ("rename") - var/new_name = sanitize_name(stripped_input(user,"What would you like to name this cyborg?","Input a name",borg.real_name,MAX_NAME_LEN), allow_numbers = TRUE) + var/new_name = sanitize_name(tgui_input_text(user, "What would you like to name this cyborg?", "Cyborg Reclassification", borg.real_name, MAX_NAME_LEN), allow_numbers = TRUE) if(!new_name) return message_admins("[key_name_admin(user)] renamed [ADMIN_LOOKUPFLW(borg)] to [new_name].") diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 7f62ec5a719..1fc6c79f0dd 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -332,8 +332,8 @@ to_chat(user, span_warning("Your target is already under a mind-controlling influence!")) return - var/command = stripped_input(user, "Enter the command for your target to follow.\ - Uses Left: [G.mind_control_uses], Duration: [DisplayTimeText(G.mind_control_duration)]","Enter command") + var/command = tgui_input_text(user, "Enter the command for your target to follow.\ + Uses Left: [G.mind_control_uses], Duration: [DisplayTimeText(G.mind_control_duration)]", "Enter command") if(!command) return @@ -357,7 +357,7 @@ if(L.stat == DEAD) to_chat(user, span_warning("Your target is dead!")) return - var/message = stripped_input(user, "Write a message to send to your target's brain.","Enter message") + var/message = tgui_input_text(user, "Message to send to your target's brain", "Enter message") if(!message) return if(QDELETED(L) || L.stat == DEAD) diff --git a/code/modules/antagonists/changeling/powers/mimic_voice.dm b/code/modules/antagonists/changeling/powers/mimic_voice.dm index b6fb42cecfe..e6c8dd4e718 100644 --- a/code/modules/antagonists/changeling/powers/mimic_voice.dm +++ b/code/modules/antagonists/changeling/powers/mimic_voice.dm @@ -16,7 +16,7 @@ to_chat(user, span_notice("We return our vocal glands to their original position.")) return - var/mimic_voice = sanitize_name(stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN)) + var/mimic_voice = sanitize_name(tgui_input_text(user, "Enter a name to mimic", "Mimic Voice", max_length = MAX_NAME_LEN)) if(!mimic_voice) return ..() diff --git a/code/modules/antagonists/cult/rune_spawn_action.dm b/code/modules/antagonists/cult/rune_spawn_action.dm index b18c08518cf..8f212408a27 100644 --- a/code/modules/antagonists/cult/rune_spawn_action.dm +++ b/code/modules/antagonists/cult/rune_spawn_action.dm @@ -39,7 +39,7 @@ if(turf_check(T)) var/chosen_keyword if(initial(rune_type.req_keyword)) - chosen_keyword = stripped_input(owner, "Enter a keyword for the new rune.", "Words of Power") + chosen_keyword = tgui_input_text(owner, "Enter a keyword for the new rune.", "Words of Power", max_length = MAX_NAME_LEN) if(!chosen_keyword) return //the outer ring is always the same across all runes diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index e2bff938890..12fed74ef94 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -172,7 +172,7 @@ the new instance inside the host to be updated to the template's stats. taken_names[initial(D.name)] = TRUE var/set_name while(!set_name) - var/input = sanitize_name(stripped_input(src, "Select a name for your disease", "Select Name", "", MAX_NAME_LEN)) + var/input = sanitize_name(tgui_input_text(src, "Select a name for your disease", "Select Name", max_length = MAX_NAME_LEN)) if(!input) set_name = "Sentient Virus" break diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm index 26d0e1f018d..226005868d1 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm @@ -44,7 +44,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec) if(custom_threat == "Yes") declaring_war = TRUE - war_declaration = stripped_input(user, "Insert your custom declaration", "Declaration") + war_declaration = tgui_input_text(user, "Insert your custom declaration", "Declaration", multiline = TRUE) declaring_war = FALSE if(!check_allowed(user) || !war_declaration) @@ -80,7 +80,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec) var/custom_threat = tgui_alert(usr, "Do you want to customize the declaration?", "Customize?", list("Yes", "No")) if(custom_threat == "Yes") - war_declaration = stripped_input(usr, "Insert your custom declaration", "Declaration") + war_declaration = tgui_input_text(usr, "Insert your custom declaration", "Declaration", multiline = TRUE) if(!war_declaration) to_chat(usr, span_warning("Invalid war declaration.")) diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 054204c8e05..6653f8368c7 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -178,7 +178,7 @@ var/wizard_name_second = pick(GLOB.wizard_second) var/randomname = "[wizard_name_first] [wizard_name_second]" var/mob/living/wiz_mob = owner.current - var/newname = sanitize_name(reject_bad_text(stripped_input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname, MAX_NAME_LEN))) + var/newname = sanitize_name(reject_bad_text(tgui_input_text(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname, MAX_NAME_LEN))) if (!newname) newname = randomname diff --git a/code/modules/tgui/tgui_input_number.dm b/code/modules/tgui/tgui_input_number.dm index cdf1b7a9d52..fcd768f1e73 100644 --- a/code/modules/tgui/tgui_input_number.dm +++ b/code/modules/tgui/tgui_input_number.dm @@ -6,13 +6,13 @@ * validate the input inside the UI and ui_act. * * Arguments: - * * user - The user to show the numbox to. - * * message - The content of the numbox, shown in the body of the TGUI window. - * * title - The title of the numbox modal, shown on the top of the TGUI window. + * * user - The user to show the number input to. + * * message - The content of the number input, shown in the body of the TGUI window. + * * title - The title of the number input modal, shown on the top of the TGUI window. * * default - The default (or current) value, shown as a placeholder. Users can press refresh with this. * * max_value - Specifies a maximum value. If none is set, any number can be entered. Pressing "max" defaults to 1000. * * min_value - Specifies a minimum value. Often 0. - * * timeout - The timeout of the numbox, after which the modal will close and qdel itself. Set to zero for no timeout. + * * timeout - The timeout of the number input, after which the modal will close and qdel itself. Set to zero for no timeout. */ /proc/tgui_input_number(mob/user, message = null, title = "Number Input", default = null, max_value = null, min_value = 0, timeout = 0) if (!user) @@ -26,29 +26,29 @@ /// Client does NOT have tgui_input on: Returns regular input if(!user.client.prefs.read_preference(/datum/preference/toggle/tgui_input)) return input(user, message, title, default) as null|num - var/datum/tgui_input_number/numbox = new(user, message, title, default, max_value, min_value, timeout) - numbox.ui_interact(user) - numbox.wait() - if (numbox) - . = numbox.entry - qdel(numbox) + var/datum/tgui_input_number/number_input = new(user, message, title, default, max_value, min_value, timeout) + number_input.ui_interact(user) + number_input.wait() + if (number_input) + . = number_input.entry + qdel(number_input) /** * Creates an asynchronous TGUI number input window with an associated callback. * - * This proc should be used to create numboxes that invoke a callback with the user's entry. + * This proc should be used to create number inputs that invoke a callback with the user's entry. * * Arguments: - * * user - The user to show the numbox to. - * * message - The content of the numbox, shown in the body of the TGUI window. - * * title - The title of the numbox modal, shown on the top of the TGUI window. + * * user - The user to show the number input to. + * * message - The content of the number input, shown in the body of the TGUI window. + * * title - The title of the number input modal, shown on the top of the TGUI window. * * default - The default (or current) value, shown as a placeholder. Users can press refresh with this. * * max_value - Specifies a maximum value. If none is set, any number can be entered. Pressing "max" defaults to 1000. * * min_value - Specifies a minimum value. Often 0. * * callback - The callback to be invoked when a choice is made. - * * timeout - The timeout of the numbox, after which the modal will close and qdel itself. Disabled by default, can be set to seconds otherwise. + * * timeout - The timeout of the number input, after which the modal will close and qdel itself. Set to zero for no timeout. */ -/proc/tgui_input_number_async(mob/user, message = null, title = "Number Input", default = null, max_value = null, min_value = 0, datum/callback/callback, timeout = 0) +/proc/tgui_input_number_async(mob/user, message = null, title = "Number Input", default = null, max_value = null, min_value = 0, datum/callback/callback, timeout = 60 SECONDS) if (!user) user = usr if (!istype(user)) @@ -57,14 +57,14 @@ user = client.mob else return - var/datum/tgui_input_number/async/numbox = new(user, message, title, default, max_value, min_value, callback, timeout) - numbox.ui_interact(user) + var/datum/tgui_input_number/async/number_input = new(user, message, title, default, max_value, min_value, callback, timeout) + number_input.ui_interact(user) /** * # tgui_input_number * - * Datum used for instantiating and using a TGUI-controlled numbox that prompts the user with - * a message and has an input for text entry. + * Datum used for instantiating and using a TGUI-controlled number input that prompts the user with + * a message and has an input for number entry. */ /datum/tgui_input_number /// Boolean field describing if the tgui_input_number was closed by the user. @@ -79,9 +79,9 @@ var/message /// The minimum value that can be entered. var/min_value - /// The time at which the tgui_modal was created, for displaying timeout progress. + /// The time at which the number input was created, for displaying timeout progress. var/start_time - /// The lifespan of the tgui_input_number, after which the window will close and delete itself. + /// The lifespan of the number input, after which the window will close and delete itself. var/timeout /// The title of the TGUI window var/title @@ -114,6 +114,7 @@ ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "NumberInputModal") + ui.set_autoupdate(FALSE) ui.open() /datum/tgui_input_number/ui_close(mob/user) @@ -125,19 +126,18 @@ /datum/tgui_input_number/ui_static_data(mob/user) . = list( - "preferences" = list() + "max_value" = max_value, + "message" = message, + "min_value" = min_value, + "placeholder" = default, /// You cannot use default as a const + "preferences" = list(), + "title" = title ) .["preferences"]["large_buttons"] = user.client.prefs.read_preference(/datum/preference/toggle/tgui_input_large) .["preferences"]["swapped_buttons"] = user.client.prefs.read_preference(/datum/preference/toggle/tgui_input_swapped) /datum/tgui_input_number/ui_data(mob/user) - . = list( - "max_value" = max_value, - "message" = message, - "min_value" = min_value, - "placeholder" = default, /// You cannot use default as a const - "title" = title, - ) + . = list() if(timeout) .["timeout"] = CLAMP01((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS)) diff --git a/code/modules/tgui/tgui_input_text.dm b/code/modules/tgui/tgui_input_text.dm index aabef0aa787..b855064f14f 100644 --- a/code/modules/tgui/tgui_input_text.dm +++ b/code/modules/tgui/tgui_input_text.dm @@ -6,9 +6,9 @@ * stripped_multiline_input. * * Arguments: - * * user - The user to show the textbox to. - * * message - The content of the textbox, shown in the body of the TGUI window. - * * title - The title of the textbox modal, shown on the top of the TGUI window. + * * user - The user to show the text input to. + * * message - The content of the text input, shown in the body of the TGUI window. + * * title - The title of the text input modal, shown on the top of the TGUI window. * * default - The default (or current) value, shown as a placeholder. * * max_length - Specifies a max length for input. MAX_MESSAGE_LEN is default (1024) * * multiline - Bool that determines if the input box is much larger. Good for large messages, laws, etc. @@ -33,29 +33,28 @@ return stripped_input(user, message, title, default, max_length) else return input(user, message, title, default) - var/datum/tgui_input_text/textbox = new(user, message, title, default, max_length, multiline, encode, timeout) - textbox.ui_interact(user) - textbox.wait() - if (textbox) - . = textbox.entry - qdel(textbox) + var/datum/tgui_input_text/text_input = new(user, message, title, default, max_length, multiline, encode, timeout) + text_input.ui_interact(user) + text_input.wait() + if (text_input) + . = text_input.entry + qdel(text_input) /** * Creates an asynchronous TGUI text input window with an associated callback. * - * This proc should be used to create textboxes that invoke a callback with the user's entry. + * This proc should be used to create text inputs that invoke a callback with the user's entry. * Arguments: - * * user - The user to show the textbox to. - * * message - The content of the textbox, shown in the body of the TGUI window. - * * title - The title of the textbox modal, shown on the top of the TGUI window. + * * user - The user to show the text input to. + * * message - The content of the text input, shown in the body of the TGUI window. + * * title - The title of the text input modal, shown on the top of the TGUI window. * * default - The default (or current) value, shown as a placeholder. * * max_length - Specifies a max length for input. * * multiline - Bool that determines if the input box is much larger. Good for large messages, laws, etc. * * encode - If toggled, input is filtered via html_encode. Setting this to FALSE gives raw input. * * callback - The callback to be invoked when a choice is made. - * * timeout - The timeout of the textbox, after which the modal will close and qdel itself. Disabled by default, can be set to seconds otherwise. */ -/proc/tgui_input_text_async(mob/user, message = null, title = "Text Input", default = null, max_length = null, multiline = FALSE, encode = TRUE, datum/callback/callback, timeout = 0) +/proc/tgui_input_text_async(mob/user, message = null, title = "Text Input", default = null, max_length = null, multiline = FALSE, encode = TRUE, datum/callback/callback, timeout = 60 SECONDS) if (!user) user = usr if (!istype(user)) @@ -64,13 +63,13 @@ user = client.mob else return - var/datum/tgui_input_text/async/textbox = new(user, message, title, default, max_length, multiline, encode, callback, timeout) - textbox.ui_interact(user) + var/datum/tgui_input_text/async/text_input = new(user, message, title, default, max_length, multiline, encode, callback, timeout) + text_input.ui_interact(user) /** * # tgui_input_text * - * Datum used for instantiating and using a TGUI-controlled textbox that prompts the user with + * Datum used for instantiating and using a TGUI-controlled text input that prompts the user with * a message and has an input for text entry. */ /datum/tgui_input_text @@ -88,9 +87,9 @@ var/message /// Multiline input for larger input boxes. var/multiline - /// The time at which the tgui_modal was created, for displaying timeout progress. + /// The time at which the text input was created, for displaying timeout progress. var/start_time - /// The lifespan of the tgui_input_text, after which the window will close and delete itself. + /// The lifespan of the text input, after which the window will close and delete itself. var/timeout /// The title of the TGUI window var/title @@ -124,6 +123,7 @@ ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "TextInputModal") + ui.set_autoupdate(FALSE) ui.open() /datum/tgui_input_text/ui_close(mob/user) @@ -135,19 +135,18 @@ /datum/tgui_input_text/ui_static_data(mob/user) . = list( - "preferences" = list() + "max_length" = max_length, + "message" = message, + "multiline" = multiline, + "placeholder" = default, /// You cannot use default as a const + "preferences" = list(), + "title" = title ) .["preferences"]["large_buttons"] = user.client.prefs.read_preference(/datum/preference/toggle/tgui_input_large) .["preferences"]["swapped_buttons"] = user.client.prefs.read_preference(/datum/preference/toggle/tgui_input_swapped) /datum/tgui_input_text/ui_data(mob/user) - . = list( - "max_length" = max_length, - "message" = message, - "multiline" = multiline, - "placeholder" = default, /// You cannot use default as a const - "title" = title, - ) + . = list() if(timeout) .["timeout"] = CLAMP01((timeout - (world.time - start_time) - 1 SECONDS) / (timeout - 1 SECONDS)) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 7c80bf94d9b..6a216b5f347 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -1214,9 +1214,9 @@ GLOBAL_LIST_EMPTY(vending_products) if(compartmentLoadAccessCheck(user)) if(istype(I, /obj/item/pen)) - name = stripped_input(user,"Set name","Name", name, 20) - desc = stripped_input(user,"Set description","Description", desc, 60) - slogan_list += stripped_input(user,"Set slogan","Slogan","Epic", 60) + name = tgui_input_text(user, "Set name", "Name", name, 20) + desc = tgui_input_text(user, "Set description", "Description", desc, 60) + slogan_list += tgui_input_text(user, "Set slogan", "Slogan", "Epic", 60) last_slogan = world.time + rand(0, slogan_delay) return diff --git a/tgui/packages/tgui/interfaces/NumberInputModal.tsx b/tgui/packages/tgui/interfaces/NumberInputModal.tsx index a5411eb1b8c..ca065e4c37c 100644 --- a/tgui/packages/tgui/interfaces/NumberInputModal.tsx +++ b/tgui/packages/tgui/interfaces/NumberInputModal.tsx @@ -1,7 +1,7 @@ import { Loader } from './common/Loader'; import { InputButtons, Preferences } from './common/InputButtons'; import { KEY_ENTER } from 'common/keycodes'; -import { useBackend, useSharedState } from '../backend'; +import { useBackend, useLocalState } from '../backend'; import { Box, Button, NumberInput, Section, Stack } from '../components'; import { Window } from '../layouts'; @@ -16,10 +16,10 @@ type NumberInputData = { }; export const NumberInputModal = (_, context) => { - const { data } = useBackend(context); + const { act, data } = useBackend(context); const { message, placeholder, preferences, timeout, title } = data; const { large_buttons } = preferences; - const [input, setInput] = useSharedState(context, 'input', placeholder); + const [input, setInput] = useLocalState(context, 'input', placeholder); const onChange = (value: number) => { setInput(value); }; @@ -35,7 +35,13 @@ export const NumberInputModal = (_, context) => { return ( {timeout && } - + { + const keyCode = window.event ? event.which : event.keyCode; + if (keyCode === KEY_ENTER) { + act('submit', { entry: input }); + } + }}>
@@ -77,12 +83,6 @@ const InputArea = (props, context) => { maxValue={max_value} onChange={(_, value) => onChange(value)} onDrag={(_, value) => onChange(value)} - onKeyDown={(event) => { - const keyCode = window.event ? event.which : event.keyCode; - if (keyCode === KEY_ENTER && input) { - act('submit', { entry: input }); - } - }} value={input || placeholder || 0} /> diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index 631bafa27e8..19641ab81d6 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -1,4 +1,4 @@ -import { useBackend, useSharedState } from '../backend'; +import { useBackend, useLocalState } from '../backend'; import { Box, Button, LabeledList, Icon, NoticeBox, ProgressBar, Section, Stack, Table, Tabs, Tooltip } from '../components'; import { Window } from '../layouts'; @@ -104,7 +104,7 @@ const ICON_MAP = { }; export const PaiInterface = (_, context) => { - const [tab, setTab] = useSharedState(context, 'tab', 1); + const [tab, setTab] = useLocalState(context, 'tab', 1); const setTabHandler = (tab: number) => { setTab(tab); }; @@ -299,7 +299,7 @@ const DirectiveDisplay = (_, context) => { * software info. */ const InstalledDisplay = (_, context) => { - const [installSelected, setInstallSelected] = useSharedState( + const [installSelected, setInstallSelected] = useLocalState( context, 'software', '' diff --git a/tgui/packages/tgui/interfaces/TextInputModal.tsx b/tgui/packages/tgui/interfaces/TextInputModal.tsx index d20319b34bd..7c5a708f2e3 100644 --- a/tgui/packages/tgui/interfaces/TextInputModal.tsx +++ b/tgui/packages/tgui/interfaces/TextInputModal.tsx @@ -1,6 +1,6 @@ import { Loader } from './common/Loader'; import { InputButtons, Preferences, Validator } from './common/InputButtons'; -import { useBackend, useSharedState } from '../backend'; +import { useBackend, useLocalState } from '../backend'; import { KEY_ENTER } from 'common/keycodes'; import { Box, Input, Section, Stack, TextArea } from '../components'; import { Window } from '../layouts'; @@ -16,7 +16,7 @@ type TextInputData = { }; export const TextInputModal = (_, context) => { - const { data } = useBackend(context); + const { act, data } = useBackend(context); const { max_length, message, @@ -27,26 +27,37 @@ export const TextInputModal = (_, context) => { title, } = data; const { large_buttons } = preferences; - const [input, setInput] = useSharedState(context, 'input', placeholder); - const [inputIsValid, setInputIsValid] = useSharedState( + const [input, setInput] = useLocalState( + context, + 'input', + placeholder || '' + ); + const [inputIsValid, setInputIsValid] = useLocalState( context, 'inputIsValid', - { isValid: false, error: null } + { isValid: !!placeholder, error: null } ); - const onType = (event) => { - event.preventDefault(); - const target = event.target; - setInputIsValid(validateInput(target.value, max_length)); - setInput(target.value); + const onType = (value: string) => { + setInputIsValid(validateInput(value, max_length)); + setInput(value); }; // Dynamically changes the window height based on the message. const windowHeight - = 125 + Math.ceil(message?.length / 3) + (multiline ? 75 : 0); + = 125 + + Math.ceil(message?.length / 3) + + (multiline ? 75 : 0) + + (large_buttons ? 5 : 0); return ( {timeout && } - + { + const keyCode = window.event ? event.which : event.keyCode; + if (keyCode === KEY_ENTER && inputIsValid.isValid) { + act('submit', { entry: input }); + } + }}>
@@ -69,9 +80,9 @@ export const TextInputModal = (_, context) => { /** Gets the user input and invalidates if there's a constraint. */ const InputArea = (props, context) => { - const { act, data } = useBackend(context); + const { data } = useBackend(context); const { multiline } = data; - const { input, inputIsValid, onType } = props; + const { input, onType } = props; if (!multiline) { return ( @@ -79,13 +90,7 @@ const InputArea = (props, context) => { onType(event)} - onKeyDown={(event) => { - const keyCode = window.event ? event.which : event.keyCode; - if (keyCode === KEY_ENTER && inputIsValid) { - act('submit', { entry: input }); - } - }} + onInput={(_, value) => onType(value)} placeholder="Type something..." value={input} /> @@ -97,14 +102,7 @@ const InputArea = (props, context) => {