From 9d2203a447a6b7677635e414906123db06630ea7 Mon Sep 17 00:00:00 2001
From: CHOMPStation2 <58959929+CHOMPStation2@users.noreply.github.com>
Date: Fri, 23 Feb 2024 14:20:50 -0700
Subject: [PATCH] [MIRROR] Tgui ui fix (#7815)
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
---
code/game/machinery/air_alarm.dm | 2 +-
code/game/machinery/biogenerator.dm | 26 +-
.../machinery/casino_prize_dispenser_ch.dm | 2 +-
.../eventkit/gm_interfaces/mob_spawner.dm | 55 +-
code/modules/nifsoft/nif_tgui.dm | 1 +
.../tgui-panel/settings/SettingsPanel.jsx | 2 +
.../tgui/interfaces/AccountsTerminal.jsx | 18 +-
tgui/packages/tgui/interfaces/AirAlarm.jsx | 33 +-
tgui/packages/tgui/interfaces/Autolathe.jsx | 1 +
.../packages/tgui/interfaces/Biogenerator.jsx | 68 +-
.../tgui/interfaces/CameraConsole.jsx | 32 +-
.../tgui/interfaces/CasinoPrizeDispenser.jsx | 75 +-
.../packages/tgui/interfaces/Communicator.tsx | 1600 ++++++++---------
tgui/packages/tgui/interfaces/CrewMonitor.jsx | 43 +-
tgui/packages/tgui/interfaces/DNAModifier.jsx | 28 +-
.../tgui/interfaces/ExosuitFabricator.jsx | 1 +
.../tgui/interfaces/MessageMonitor.jsx | 2 +-
.../packages/tgui/interfaces/MiningVendor.jsx | 65 +-
tgui/packages/tgui/interfaces/MobSpawner.tsx | 224 ++-
tgui/packages/tgui/interfaces/NIF.jsx | 68 +-
.../tgui/interfaces/NtosNetDownloader.jsx | 4 +-
tgui/packages/tgui/interfaces/OvermapFull.tsx | 5 +-
tgui/packages/tgui/interfaces/Pda.jsx | 18 +-
.../tgui/interfaces/PipeDispenser.jsx | 6 +-
.../tgui/interfaces/RapidPipeDispenser.jsx | 5 +-
.../tgui/interfaces/ResearchConsole.jsx | 141 +-
tgui/packages/tgui/interfaces/SecureSafe.jsx | 10 +-
tgui/packages/tgui/interfaces/SuitCycler.jsx | 43 +-
tgui/packages/tgui/interfaces/Uplink.jsx | 4 +-
tgui/packages/tgui/interfaces/VorePanel.jsx | 7 +-
.../common/InterfaceLockNoticeBox.jsx | 21 +-
31 files changed, 1411 insertions(+), 1199 deletions(-)
diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm
index ce718c9c81..5c38eace6f 100644
--- a/code/game/machinery/air_alarm.dm
+++ b/code/game/machinery/air_alarm.dm
@@ -748,7 +748,7 @@
var/env = params["env"]
var/name = params["var"]
- var/value = tgui_input_number(usr, "New [name] for [env]:", name, TLV[env][name], round_value = FALSE)
+ var/value = tgui_input_number(usr, "New [name] for [env]:", name, TLV[env][name], min_value=-1, round_value = FALSE)
if(!isnull(value) && !..())
if(value < 0)
TLV[env][name] = -1
diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm
index 763564fcf9..215b2051fa 100644
--- a/code/game/machinery/biogenerator.dm
+++ b/code/game/machinery/biogenerator.dm
@@ -64,26 +64,26 @@
item_list = list()
item_list["Food Items"] = list(
- BIOGEN_REAGENT("10 milk", "milk", 10, 20),
- BIOGEN_REAGENT("50 milk", "milk", 50, 95),
- BIOGEN_REAGENT("10 Cream", "cream", 10, 30),
- BIOGEN_REAGENT("50 Cream", "cream", 50, 120),
+ BIOGEN_REAGENT("Milk x10", "milk", 10, 20),
+ BIOGEN_REAGENT("Milk x50", "milk", 50, 95),
+ BIOGEN_REAGENT("Cream x10", "cream", 10, 30),
+ BIOGEN_REAGENT("Cream x50", "cream", 50, 120),
BIOGEN_ITEM("Slab of meat", /obj/item/weapon/reagent_containers/food/snacks/meat, 1, 50),
- BIOGEN_ITEM("5 slabs of meat", /obj/item/weapon/reagent_containers/food/snacks/meat, 5, 250),
+ BIOGEN_ITEM("Slabs of meat x5", /obj/item/weapon/reagent_containers/food/snacks/meat, 5, 250),
)
item_list["Cooking Ingredients"] = list(
- BIOGEN_REAGENT("10 Universal Enzyme", "enzyme", 10, 30),
- BIOGEN_REAGENT("50 Universal Enzyme", "enzyme", 50, 120),
+ BIOGEN_REAGENT("Universal Enzyme x10", "enzyme", 10, 30),
+ BIOGEN_REAGENT("Universal Enzyme x50", "enzyme", 50, 120),
BIOGEN_ITEM("Nutri-spread", /obj/item/weapon/reagent_containers/food/snacks/spreads, 1, 30),
- BIOGEN_ITEM("5 nutri-spread", /obj/item/weapon/reagent_containers/food/snacks/spreads, 5, 120),
+ BIOGEN_ITEM("Nutri-spread x5", /obj/item/weapon/reagent_containers/food/snacks/spreads, 5, 120),
)
item_list["Gardening Nutrients"] = list(
BIOGEN_ITEM("E-Z-Nutrient", /obj/item/weapon/reagent_containers/glass/bottle/eznutrient, 1, 60),
- BIOGEN_ITEM("5 E-Z-Nutrient", /obj/item/weapon/reagent_containers/glass/bottle/eznutrient, 5, 300),
+ BIOGEN_ITEM("E-Z-Nutrient x5", /obj/item/weapon/reagent_containers/glass/bottle/eznutrient, 5, 300),
BIOGEN_ITEM("Left 4 Zed", /obj/item/weapon/reagent_containers/glass/bottle/left4zed, 1, 120),
- BIOGEN_ITEM("5 Left 4 Zed", /obj/item/weapon/reagent_containers/glass/bottle/left4zed, 5, 600),
+ BIOGEN_ITEM("Left 4 Zed x5", /obj/item/weapon/reagent_containers/glass/bottle/left4zed, 5, 600),
BIOGEN_ITEM("Robust Harvest", /obj/item/weapon/reagent_containers/glass/bottle/robustharvest, 1, 150),
- BIOGEN_ITEM("5 Robust Harvest", /obj/item/weapon/reagent_containers/glass/bottle/robustharvest, 5, 750),
+ BIOGEN_ITEM("Robust Harvest x5", /obj/item/weapon/reagent_containers/glass/bottle/robustharvest, 5, 750),
)
item_list["Leather Products"] = list(
BIOGEN_ITEM("Wallet", /obj/item/weapon/storage/wallet, 1, 100),
@@ -100,8 +100,8 @@
BIOGEN_ITEM("Leather Jacket", /obj/item/clothing/suit/storage/toggle/brown_jacket, 1, 500),
BIOGEN_ITEM("Winter Coat", /obj/item/clothing/suit/storage/hooded/wintercoat, 1, 500),
//VOREStation Edit - Algae for oxygen generator
- BIOGEN_ITEM("4 Algae Sheets", /obj/item/stack/material/algae, 4, 400),
- BIOGEN_ITEM("50 Algae Sheets", /obj/item/stack/material/algae, 50, 5000),
+ BIOGEN_ITEM("Algae Sheets x4", /obj/item/stack/material/algae, 4, 400),
+ BIOGEN_ITEM("Algae Sheets x50", /obj/item/stack/material/algae, 50, 5000),
)
/obj/machinery/biogenerator/tgui_static_data(mob/user)
diff --git a/code/game/machinery/casino_prize_dispenser_ch.dm b/code/game/machinery/casino_prize_dispenser_ch.dm
index 2cb7cb66ca..b4cbf39690 100644
--- a/code/game/machinery/casino_prize_dispenser_ch.dm
+++ b/code/game/machinery/casino_prize_dispenser_ch.dm
@@ -292,7 +292,7 @@
// Open the window
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
- ui = new(user, src, "CasinoPrizeDispenserCh", name)
+ ui = new(user, src, "CasinoPrizeDispenser", name)
ui.open()
/obj/machinery/casino_prize_dispenser/tgui_act(action, params)
diff --git a/code/modules/eventkit/gm_interfaces/mob_spawner.dm b/code/modules/eventkit/gm_interfaces/mob_spawner.dm
index a829cc3221..19efc7ccfc 100644
--- a/code/modules/eventkit/gm_interfaces/mob_spawner.dm
+++ b/code/modules/eventkit/gm_interfaces/mob_spawner.dm
@@ -47,37 +47,36 @@
data["loc_y"] = usr.y
data["loc_z"] = usr.z
- data["path"] = path;
data["use_custom_ai"] = use_custom_ai
+ if(new_path)
+ data["path"] = path;
+ if(path)
+ var/mob/M = new path()
+ if(M)
+ data["path_name"] = M.name
+ data["desc"] = M.desc
+ data["flavor_text"] = M.flavor_text
+ if(istype(M, /mob/living))
+ var/mob/living/L = M
+ // AI Stuff
+ ai_type = (L.ai_holder_type ? L.ai_holder_type : /datum/ai_holder/simple_mob/inert)
+ faction = (L.faction ? L.faction : "neutral")
+ intent = (L.a_intent ? L.a_intent : I_HELP)
+ new_path = FALSE
- if(path)
- var/mob/M = new path()
- if(M)
- data["default_path_name"] = M.name
- data["default_desc"] = M.desc
- data["default_flavor_text"] = M.flavor_text
- if(new_path && istype(M, /mob/living))
- var/mob/living/L = M
-
- // AI Stuff
- ai_type = (L.ai_holder_type ? L.ai_holder_type : /datum/ai_holder/simple_mob/inert)
- faction = (L.faction ? L.faction : "neutral")
- intent = (L.a_intent ? L.a_intent : I_HELP)
- new_path = FALSE
-
- data["max_health"] = L.maxHealth
- data["health"] = L.health
- if(istype(L, /mob/living/simple_mob))
- var/mob/living/simple_mob/S = L
- data["melee_damage_lower"] = S.melee_damage_lower ? S.melee_damage_lower : 0
- data["melee_damage_upper"] = S.melee_damage_upper ? S.melee_damage_upper : 0
- qdel(S)
- qdel(L)
- qdel(M)
- data["ai_type"] = ai_type
- data["faction"] = faction
- data["intent"] = intent
+ data["max_health"] = L.maxHealth
+ data["health"] = L.health
+ if(istype(L, /mob/living/simple_mob))
+ var/mob/living/simple_mob/S = L
+ data["melee_damage_lower"] = S.melee_damage_lower ? S.melee_damage_lower : 0
+ data["melee_damage_upper"] = S.melee_damage_upper ? S.melee_damage_upper : 0
+ qdel(S)
+ qdel(L)
+ qdel(M)
+ data["ai_type"] = ai_type
+ data["faction"] = faction
+ data["intent"] = intent
return data
diff --git a/code/modules/nifsoft/nif_tgui.dm b/code/modules/nifsoft/nif_tgui.dm
index 7699e9929e..fecf50fe87 100644
--- a/code/modules/nifsoft/nif_tgui.dm
+++ b/code/modules/nifsoft/nif_tgui.dm
@@ -112,6 +112,7 @@
/obj/item/device/nif/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
+ data["valid_themes"] = valid_ui_themes
data["theme"] = save_data["ui_theme"]
data["last_notification"] = last_notification
diff --git a/tgui/packages/tgui-panel/settings/SettingsPanel.jsx b/tgui/packages/tgui-panel/settings/SettingsPanel.jsx
index a445cc7375..8d9d8ea616 100644
--- a/tgui/packages/tgui-panel/settings/SettingsPanel.jsx
+++ b/tgui/packages/tgui-panel/settings/SettingsPanel.jsx
@@ -102,6 +102,7 @@ export const SettingsGeneral = (props) => {
@@ -118,6 +119,7 @@ export const SettingsGeneral = (props) => {
{(!freeFont && (
diff --git a/tgui/packages/tgui/interfaces/AccountsTerminal.jsx b/tgui/packages/tgui/interfaces/AccountsTerminal.jsx
index b00126bf54..998fb72569 100644
--- a/tgui/packages/tgui/interfaces/AccountsTerminal.jsx
+++ b/tgui/packages/tgui/interfaces/AccountsTerminal.jsx
@@ -61,13 +61,17 @@ const AccountTerminalContent = (props) => {
>
New Account
- act('print')}
- >
- Print
-
+ {!creating_new_account ? (
+ act('print')}
+ >
+ Print
+
+ ) : (
+ ''
+ )}
{(creating_new_account && ) ||
(detailed_account_view && ) || }
diff --git a/tgui/packages/tgui/interfaces/AirAlarm.jsx b/tgui/packages/tgui/interfaces/AirAlarm.jsx
index 7c2931e8b3..a2cf9f8fee 100644
--- a/tgui/packages/tgui/interfaces/AirAlarm.jsx
+++ b/tgui/packages/tgui/interfaces/AirAlarm.jsx
@@ -1,7 +1,7 @@
import { toFixed } from 'common/math';
-import { Fragment } from 'react';
+import { Fragment, useState } from 'react';
-import { useBackend, useLocalState } from '../backend';
+import { useBackend } from '../backend';
import { Box, Button, LabeledList, Section } from '../components';
import { getGasColor, getGasLabel } from '../constants';
import { Window } from '../layouts';
@@ -10,6 +10,13 @@ import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox';
export const AirAlarm = (props) => {
const { act, data } = useBackend();
+
+ const [screen, setScreen] = useState('');
+
+ function handleSetScreen(value) {
+ setScreen(value);
+ }
+
const locked = data.locked && !data.siliconUser && !data.remoteUser;
return (
@@ -17,7 +24,9 @@ export const AirAlarm = (props) => {
- {!locked && }
+ {!locked && (
+
+ )}
);
@@ -146,23 +155,22 @@ const AIR_ALARM_ROUTES = {
};
const AirAlarmControl = (props) => {
- const [screen, setScreen] = useLocalState('screen');
- const route = AIR_ALARM_ROUTES[screen] || AIR_ALARM_ROUTES.home;
+ const route = AIR_ALARM_ROUTES[props.screen] || AIR_ALARM_ROUTES.home;
const Component = route.component();
return (
setScreen()}
+ onClick={() => props.onScreen()}
/>
)
}
>
-
+
);
};
@@ -172,7 +180,6 @@ const AirAlarmControl = (props) => {
const AirAlarmControlHome = (props) => {
const { act, data } = useBackend();
- const [screen, setScreen] = useLocalState('screen');
const { mode, atmos_alarm } = data;
return (
<>
@@ -197,25 +204,25 @@ const AirAlarmControlHome = (props) => {
- {context.isDNAInvalid ? (
+ {props.isDNAInvalid ? (
The occupant's DNA structure is ruined beyond
@@ -154,7 +153,7 @@ const DNAModifierMain = (props) => {
);
- } else if (context.isDNAInvalid) {
+ } else if (props.isDNAInvalid) {
return (
@@ -208,15 +207,20 @@ const DNAModifierMain = (props) => {
const DNAModifierMainUI = (props) => {
const { act, data } = useBackend();
- const { selectedUIBlock, selectedUISubBlock, selectedUITarget, occupant } =
- data;
+ const {
+ selectedUIBlock,
+ selectedUISubBlock,
+ selectedUITarget,
+ dnaBlockSize,
+ occupant,
+ } = data;
return (
@@ -244,14 +248,14 @@ const DNAModifierMainUI = (props) => {
const DNAModifierMainSE = (props) => {
const { act, data } = useBackend();
- const { selectedSEBlock, selectedSESubBlock, occupant } = data;
+ const { selectedSEBlock, selectedSESubBlock, dnaBlockSize, occupant } = data;
return (
{
setSearchText(v)}
/>
diff --git a/tgui/packages/tgui/interfaces/MessageMonitor.jsx b/tgui/packages/tgui/interfaces/MessageMonitor.jsx
index c5927ab017..9b8b1fe092 100644
--- a/tgui/packages/tgui/interfaces/MessageMonitor.jsx
+++ b/tgui/packages/tgui/interfaces/MessageMonitor.jsx
@@ -378,7 +378,7 @@ const MessageMonitorAdmin = (props) => {
a - b,
+ Alphabetical: (a, b) => a.name > b.name,
'By availability': (a, b) => -(a.affordable - b.affordable),
'By price': (a, b) => a.price - b.price,
};
export const MiningVendor = (props) => {
+ const [searchText, setSearchText] = useState('');
+ const [sortOrder, setSortOrder] = useState('Alphabetical');
+ const [descending, setDescending] = useState(false);
+
+ function handleSearchText(value) {
+ setSearchText(value);
+ }
+
+ function handleSortOrder(value) {
+ setSortOrder(value);
+ }
+
+ function handleDescending(value) {
+ setDescending(value);
+ }
+
return (
-
-
+
+
);
@@ -35,10 +66,7 @@ const MiningVendorItems = (props) => {
const { act, data } = useBackend();
const { has_id, id, items } = data;
// Search thingies
- const [searchText, _setSearchText] = useLocalState('search', '');
- const [sortOrder, _setSortOrder] = useLocalState('sort', 'Alphabetical');
- const [descending, _setDescending] = useLocalState('descending', false);
- const searcher = createSearch(searchText, (item) => {
+ const searcher = createSearch(props.searchText, (item) => {
return item[0];
});
@@ -50,11 +78,11 @@ const MiningVendorItems = (props) => {
kv2[1].affordable = has_id && id.points >= kv2[1].price;
return kv2[1];
})
- .sort(sortTypes[sortOrder]);
+ .sort(sortTypes[props.sortOrder]);
if (items_in_cat.length === 0) {
return;
}
- if (descending) {
+ if (props.descending) {
items_in_cat = items_in_cat.reverse();
}
@@ -81,9 +109,6 @@ const MiningVendorItems = (props) => {
};
const MiningVendorSearch = (props) => {
- const [_searchText, setSearchText] = useLocalState('search', '');
- const [_sortOrder, setSortOrder] = useLocalState('sort', '');
- const [descending, setDescending] = useLocalState('descending', false);
return (
@@ -91,7 +116,7 @@ const MiningVendorSearch = (props) => {
setSearchText(value)}
+ onInput={(_e, value) => props.onSearchText(value)}
/>
@@ -100,17 +125,17 @@ const MiningVendorSearch = (props) => {
options={Object.keys(sortTypes)}
width="100%"
lineHeight="19px"
- onSelected={(v) => setSortOrder(v)}
+ onSelected={(v) => props.onSortOrder(v)}
/>
setDescending(!descending)}
+ onClick={() => props.onDescending(!props.descending)}
/>
@@ -118,9 +143,9 @@ const MiningVendorSearch = (props) => {
);
};
-const MiningVendorItemsCategory = (properties) => {
+const MiningVendorItemsCategory = (props) => {
const { act, data } = useBackend();
- const { title, items, ...rest } = properties;
+ const { title, items, ...rest } = props;
return (
{items.map((item) => (
diff --git a/tgui/packages/tgui/interfaces/MobSpawner.tsx b/tgui/packages/tgui/interfaces/MobSpawner.tsx
index 135fb46368..e0d00635e2 100644
--- a/tgui/packages/tgui/interfaces/MobSpawner.tsx
+++ b/tgui/packages/tgui/interfaces/MobSpawner.tsx
@@ -19,9 +19,9 @@ import { Window } from '../layouts';
type Data = {
path: string;
- default_path_name: string;
- default_desc: string;
- default_flavor_text: string;
+ path_name: string;
+ desc: string;
+ flavor_text: string;
use_custom_ai: BooleanLike;
ai_type: string;
@@ -49,14 +49,102 @@ export const MobSpawner = (props) => {
const { act, data } = useBackend();
const [tabIndex, setTabIndex] = useState(0);
+ const [radius, setRadius] = useState(0);
+ const [forceUpdate, renderData] = useState();
+ const [x, setX] = useState(data.initial_x);
+ const [y, setY] = useState(data.initial_y);
+ const [z, setZ] = useState(data.initial_z);
+ const [sizeMultiplier, setSizeMultiplier] = useState(100);
+ const [amount, setAmount] = useState(1);
+
+ function handleHealth(value) {
+ data.health = value;
+ renderData(value);
+ }
+
+ function handleMaxHealth(value) {
+ data.max_health = value;
+ renderData(value);
+ }
+
+ function handleMeleeDamageLower(value) {
+ data.melee_damage_lower = value;
+ renderData(value);
+ }
+
+ function handleMeleeDamageupper(value) {
+ data.melee_damage_upper = value;
+ renderData(value);
+ }
+
+ function handleName(value) {
+ data.path_name = value;
+ renderData(value);
+ }
+
+ function handleDesc(value) {
+ data.desc = value;
+ renderData(value);
+ }
+
+ function handleFlavor(value) {
+ data.flavor_text = value;
+ renderData(value);
+ }
+
+ function handleRadius(value) {
+ setRadius(value);
+ }
+
+ function handleX(value) {
+ setX(value);
+ }
+
+ function handleY(value) {
+ setY(value);
+ }
+
+ function handleZ(value) {
+ setZ(value);
+ }
+
+ function handleSizeMultiplier(value) {
+ setSizeMultiplier(value);
+ }
+
+ function handleAmount(value) {
+ setAmount(value);
+ }
const tabs: any = [];
- tabs[0] = ;
+ tabs[0] = (
+
+ );
tabs[1] = ;
return (
-
+
setTabIndex(0)}>
@@ -74,32 +162,6 @@ export const MobSpawner = (props) => {
const GeneralMobSettings = (props) => {
const { act, data } = useBackend();
-
- const [amount, setAmount] = useState(1);
- const [name, setName] = useState(data.default_path_name);
- const [ai_type] = useState(data.ai_type);
- const [use_custom_ai] = useState(data.use_custom_ai);
- const [faction] = useState(data.faction);
- const [intent] = useState(data.intent);
- const [maxHealth, setMaxHealth] = useState(data.max_health);
- const [health, setHealth] = useState(data.health);
- const [meleeDamageLower, setMeleeDamageLower] = useState(
- data.melee_damage_lower,
- );
- const [meleeDamageUpper, setMeleeDamageUpper] = useState(
- data.melee_damage_upper,
- );
- const [desc, setDesc] = useState(data.default_desc);
- const [flavorText, setFlavorText] = useState(data.default_flavor_text);
-
- const [sizeMultiplier, setSizeMultiplier] = useState(100);
-
- const [x, setX] = useState(data.initial_x);
- const [y, setY] = useState(data.initial_y);
- const [z, setZ] = useState(data.initial_z);
-
- const [radius, setRadius] = useState(0);
-
return (
<>
@@ -144,22 +206,22 @@ const GeneralMobSettings = (props) => {
setX(val)}
+ onChange={(e, val) => props.onX(val)}
/>
setY(val)}
+ onChange={(e, val) => props.onY(val)}
/>
setZ(val)}
+ onChange={(e, val) => props.onZ(val)}
/>
{
setRadius(val)}
+ onChange={(e, val) => props.onRadius(val)}
/>
@@ -187,7 +249,7 @@ const GeneralMobSettings = (props) => {
title="AI settings"
buttons={
act('toggle_custom_ai')}
@@ -198,21 +260,21 @@ const GeneralMobSettings = (props) => {
act('set_ai_path')}
/>
act('set_faction')}
/>
act('set_intent')}
/>
@@ -220,36 +282,36 @@ const GeneralMobSettings = (props) => {
- {(maxHealth && (
+ {(data.max_health && (
<>
setMaxHealth(val)}
+ value={data.max_health}
+ onChange={(e, val) => props.onMaxHealth(val)}
/>
setHealth(val)}
+ value={data.health}
+ onChange={(e, val) => props.onHealth(val)}
/>
>
)) ||
"Note: Only available for '/mob/living'"}
- {(meleeDamageLower && (
+ {(data.melee_damage_lower && (
<>
setMeleeDamageLower(val)}
+ value={data.melee_damage_lower}
+ onChange={(e, val) => props.onMeleeDamageLower(val)}
/>
setMeleeDamageUpper(val)}
+ value={data.melee_damage_upper}
+ onChange={(e, val) => props.onMeleeDamageUpper(val)}
/>
>
@@ -267,8 +329,8 @@ const GeneralMobSettings = (props) => {
+ onClick={() =>
act('start_spawn', {
- amount: amount,
- name: name || data.default_path_name,
- desc: desc || data.default_desc,
- max_health: maxHealth || data.max_health,
- health: health || data.health,
- melee_damage_lower: meleeDamageLower || data.melee_damage_lower,
- melee_damage_upper: meleeDamageUpper || data.melee_damage_upper,
- flavor_text: flavorText || data.default_flavor_text,
- size_multiplier: sizeMultiplier * 0.01,
- x: data.loc_lock ? data.loc_x : x,
- y: data.loc_lock ? data.loc_y : y,
- z: data.loc_lock ? data.loc_z : z,
- radius: radius,
+ amount: props.amount,
+ name: data.path_name,
+ desc: data.desc,
+ max_health: data.max_health,
+ health: data.health,
+ melee_damage_lower: data.melee_damage_lower,
+ melee_damage_upper: data.melee_damage_upper,
+ flavor_text: data.flavor_text,
+ size_multiplier: props.sizeMultiplier * 0.01,
+ x: data.loc_lock ? data.loc_x : props.x,
+ y: data.loc_lock ? data.loc_y : props.y,
+ z: data.loc_lock ? data.loc_z : props.z,
+ radius: props.radius,
})
}
- >
- Spawn
-
+ />
>
);
};
diff --git a/tgui/packages/tgui/interfaces/NIF.jsx b/tgui/packages/tgui/interfaces/NIF.jsx
index b59e9cb650..9628062d6c 100644
--- a/tgui/packages/tgui/interfaces/NIF.jsx
+++ b/tgui/packages/tgui/interfaces/NIF.jsx
@@ -6,6 +6,7 @@ import {
Box,
Button,
Dropdown,
+ Flex,
LabeledList,
Modal,
NoticeBox,
@@ -21,17 +22,6 @@ const NIF_TEMPFAIL = 2;
const NIF_INSTALLING = 3;
const NIF_PREINSTALL = 4;
-const validThemes = [
- 'abductor',
- 'cardtable',
- 'hackerman',
- 'malfunction',
- 'ntos',
- 'paper',
- 'retro',
- 'syndicate',
-];
-
export const NIF = (props) => {
const { act, config, data } = useBackend();
@@ -90,14 +80,14 @@ export const NIF = (props) => {
>
{viewingModule.desc}
- It consumes{' '}
+ It consumes
{viewingModule.p_drain}
- {' '}
- energy units while installed, and{' '}
+
+ energy units while installed, and
{viewingModule.a_drain}
- {' '}
+
additionally while active.
@@ -105,7 +95,7 @@ export const NIF = (props) => {
package.
- The MSRP of the package is{' '}
+ The MSRP of the package is
{viewingModule.cost}₮.
@@ -149,16 +139,12 @@ const getNifCondition = (nif_stat, nif_percent) => {
} else {
return 'Operating Normally';
}
- break;
case NIF_POWFAIL:
return 'Insufficient Energy!';
- break;
case NIF_TEMPFAIL:
return 'System Failure!';
- break;
case NIF_INSTALLING:
return 'Adapting To User';
- break;
}
return 'Unknown';
};
@@ -184,14 +170,7 @@ const getNutritionText = (nutrition, isSynthetic) => {
const NIFMain = (props) => {
const { act, config, data } = useBackend();
- const {
- nif_percent,
- nif_stat,
- last_notification,
- nutrition,
- isSynthetic,
- modules,
- } = data;
+ const { nif_percent, nif_stat, nutrition, isSynthetic, modules } = data;
const { setViewing } = props;
@@ -274,18 +253,35 @@ const NIFMain = (props) => {
const NIFSettings = (props) => {
const { act, data } = useBackend();
- const { theme } = data;
+ const { valid_themes, theme } = data;
return (
- act('setTheme', { theme: val })}
- />
+
+
+ act('setTheme', { theme: val })}
+ />
+
+ {theme ? (
+
+ {
+ act('setTheme', { theme: null });
+ }}
+ />
+
+ ) : (
+ ''
+ )}
+
);
diff --git a/tgui/packages/tgui/interfaces/NtosNetDownloader.jsx b/tgui/packages/tgui/interfaces/NtosNetDownloader.jsx
index 8c15dd232d..9653eedbfa 100644
--- a/tgui/packages/tgui/interfaces/NtosNetDownloader.jsx
+++ b/tgui/packages/tgui/interfaces/NtosNetDownloader.jsx
@@ -86,7 +86,7 @@ const Program = (props) => {
{program.size} GQ
-
+
{(program.filename === downloadname && (
{
maxValue={downloadsize}
value={downloadcompletion}
>
- {round((downloadcompletion / downloadsize) * 100, 1)}% (
+ {round((downloadcompletion / downloadsize) * 100, 1)}% (
{downloadspeed}GQ/s)
)) ||
diff --git a/tgui/packages/tgui/interfaces/OvermapFull.tsx b/tgui/packages/tgui/interfaces/OvermapFull.tsx
index d39b3b0774..77736dcbc8 100644
--- a/tgui/packages/tgui/interfaces/OvermapFull.tsx
+++ b/tgui/packages/tgui/interfaces/OvermapFull.tsx
@@ -1,4 +1,5 @@
-import { useLocalState } from '../backend';
+import { useState } from 'react';
+
import { Tabs } from '../components';
import { Window } from '../layouts';
import { OvermapEnginesContent } from './OvermapEngines';
@@ -6,7 +7,7 @@ import { OvermapHelmContent } from './OvermapHelm';
import { OvermapShipSensorsContent } from './OvermapShipSensors';
export const OvermapFull = (props) => {
- const [tab, setTab] = useLocalState('overmapFullState', 0);
+ const [tab, setTab] = useState(0);
return (
diff --git a/tgui/packages/tgui/interfaces/Pda.jsx b/tgui/packages/tgui/interfaces/Pda.jsx
index f8f0435d15..ddc18cf29a 100644
--- a/tgui/packages/tgui/interfaces/Pda.jsx
+++ b/tgui/packages/tgui/interfaces/Pda.jsx
@@ -46,12 +46,16 @@ export const Pda = (props) => {
const [settingsMode, setSettingsMode] = useState(false);
+ function handleSettingsMode(value) {
+ setSettingsMode(value);
+ }
+
return (
{(settingsMode && ) || (
)}
-
+
);
@@ -76,8 +80,6 @@ export const Pda = (props) => {
const PDAHeader = (props) => {
const { act, data } = useBackend();
- const { settingsMode, setSettingsMode } = props;
-
const { idInserted, idLink, cartridge_name, stationTime } = data;
return (
@@ -98,8 +100,8 @@ const PDAHeader = (props) => {
setSettingsMode(!settingsMode)}
+ selected={props.settingsMode}
+ onClick={() => props.onSettingsMode(!props.settingsMode)}
icon="cog"
/>
act('Retro')} icon="adjust" />
@@ -158,8 +160,6 @@ const PDASettings = (props) => {
const PDAFooter = (props) => {
const { act, data } = useBackend();
- const { setSettingsMode } = props;
-
const { app, useRetro } = data;
return (
@@ -193,7 +193,7 @@ const PDAFooter = (props) => {
mb={0}
fontSize={1.7}
onClick={() => {
- setSettingsMode(false);
+ props.onSettingsMode(false);
act('Home');
}}
/>
diff --git a/tgui/packages/tgui/interfaces/PipeDispenser.jsx b/tgui/packages/tgui/interfaces/PipeDispenser.jsx
index 7779c9baef..c63b0c3a8a 100644
--- a/tgui/packages/tgui/interfaces/PipeDispenser.jsx
+++ b/tgui/packages/tgui/interfaces/PipeDispenser.jsx
@@ -1,4 +1,6 @@
-import { useBackend, useLocalState } from '../backend';
+import { useState } from 'react';
+
+import { useBackend } from '../backend';
import { Box, Button, Section, Tabs } from '../components';
import { Window } from '../layouts';
import { ICON_BY_CATEGORY_NAME } from './RapidPipeDispenser';
@@ -7,7 +9,7 @@ export const PipeDispenser = (props) => {
const { act, data } = useBackend();
const { disposals, p_layer, pipe_layers, categories = [] } = data;
- const [categoryName, setCategoryName] = useLocalState('categoryName');
+ const [categoryName, setCategoryName] = useState('categoryName');
const shownCategory =
categories.find((category) => category.cat_name === categoryName) ||
categories[0];
diff --git a/tgui/packages/tgui/interfaces/RapidPipeDispenser.jsx b/tgui/packages/tgui/interfaces/RapidPipeDispenser.jsx
index 300c89f9a8..97a1ae1205 100644
--- a/tgui/packages/tgui/interfaces/RapidPipeDispenser.jsx
+++ b/tgui/packages/tgui/interfaces/RapidPipeDispenser.jsx
@@ -1,7 +1,8 @@
import { classes } from 'common/react';
import { capitalize } from 'common/string';
+import { useState } from 'react';
-import { useBackend, useLocalState } from '../backend';
+import { useBackend } from '../backend';
import {
Box,
Button,
@@ -170,7 +171,7 @@ const LayerSection = (props) => {
const PipeTypeSection = (props) => {
const { act, data } = useBackend();
const { categories = [] } = data;
- const [categoryName, setCategoryName] = useLocalState('categoryName');
+ const [categoryName, setCategoryName] = useState('categoryName');
const shownCategory =
categories.find((category) => category.cat_name === categoryName) ||
categories[0];
diff --git a/tgui/packages/tgui/interfaces/ResearchConsole.jsx b/tgui/packages/tgui/interfaces/ResearchConsole.jsx
index 29fe10895b..dedfa58f7f 100644
--- a/tgui/packages/tgui/interfaces/ResearchConsole.jsx
+++ b/tgui/packages/tgui/interfaces/ResearchConsole.jsx
@@ -1,7 +1,7 @@
import { toTitleCase } from 'common/string';
-import { Fragment } from 'react';
+import { Fragment, useState } from 'react';
-import { useBackend, useLocalState, useSharedState } from '../backend';
+import { useBackend, useSharedState } from '../backend';
import {
Box,
Button,
@@ -135,9 +135,7 @@ const TechDisk = (props) => {
return null;
}
- const [saveDialog, setSaveDialog] = useSharedState('saveDialogTech', false);
-
- if (saveDialog) {
+ if (props.saveDialog) {
return (
{
setSaveDialog(false)}
+ onClick={() => props.onSaveDialog(false)}
/>
}
>
@@ -155,7 +153,7 @@ const TechDisk = (props) => {
{
- setSaveDialog(false);
+ props.onSaveDialog(false);
act('copy_tech', { copy_tech_ID: level.id });
}}
>
@@ -195,7 +193,7 @@ const TechDisk = (props) => {
)) || (
This disk has no data stored on it.
- setSaveDialog(true)}>
+ props.onSaveDialog(true)}>
Load Tech To Disk
act('eject_tech')}>
@@ -218,9 +216,7 @@ const DataDisk = (props) => {
return null;
}
- const [saveDialog, setSaveDialog] = useSharedState('saveDialogData', false);
-
- if (saveDialog) {
+ if (props.saveDialog) {
return (
{
setSaveDialog(false)}
+ onClick={() => props.onSaveDialog(false)}
/>
{ || null}
>
@@ -251,7 +247,7 @@ const DataDisk = (props) => {
{
- setSaveDialog(false);
+ props.onSaveDialog(false);
act('copy_design', { copy_design_ID: item.id });
}}
>
@@ -297,7 +293,7 @@ const DataDisk = (props) => {
)) || (
This disk has no data stored on it.
- setSaveDialog(true)}>
+ props.onSaveDialog(true)}>
Load Design To Disk
act('eject_design')}>
@@ -320,8 +316,16 @@ const ResearchConsoleDisk = (props) => {
return (
);
};
@@ -485,8 +489,6 @@ const ResearchConsoleConstructor = (props) => {
queue,
} = linked;
- const [protoTab, setProtoTab] = useSharedState('protoTab', 0);
-
let queueColor = 'transparent';
let queueSpin = false;
let queueIcon = 'layer-group';
@@ -525,8 +527,8 @@ const ResearchConsoleConstructor = (props) => {
setProtoTab(0)}
+ selected={props.protoTab === 0}
+ onClick={() => props.onProtoTab(0)}
>
Build
@@ -534,27 +536,27 @@ const ResearchConsoleConstructor = (props) => {
icon={queueIcon}
iconSpin={queueSpin}
color={queueColor}
- selected={protoTab === 1}
- onClick={() => setProtoTab(1)}
+ selected={props.protoTab === 1}
+ onClick={() => props.onProtoTab(1)}
>
Queue
setProtoTab(2)}
+ selected={props.protoTab === 2}
+ onClick={() => props.onProtoTab(2)}
>
Mat Storage
setProtoTab(3)}
+ selected={props.protoTab === 3}
+ onClick={() => props.onProtoTab(3)}
>
Chem Storage
- {(protoTab === 0 && (
+ {(props.protoTab === 0 && (
{
buildFiveName={name === 'Protolathe' ? 'buildfive' : null}
/>
)) ||
- (protoTab === 1 && (
+ (props.protoTab === 1 && (
{(queue.length &&
queue.map((item, index) => {
@@ -613,13 +615,10 @@ const ResearchConsoleConstructor = (props) => {
})) || Queue Empty.}
)) ||
- (protoTab === 2 && (
+ (props.protoTab === 2 && (
{mats.map((mat) => {
- const [ejectAmt, setEjectAmt] = useLocalState(
- 'ejectAmt' + mat.name,
- 0,
- );
+ const [ejectAmt, setEjectAmt] = useState(0);
return (
{
})}
)) ||
- (protoTab === 3 && (
+ (props.protoTab === 3 && (
{(reagents.length &&
@@ -702,27 +701,25 @@ const ResearchConsoleSettings = (props) => {
const { sync, linked_destroy, linked_imprinter, linked_lathe } = data.info;
- const [settingsTab, setSettingsTab] = useSharedState('settingsTab', 0);
-
return (
setSettingsTab(0)}
- selected={settingsTab === 0}
+ onClick={() => props.onSettingsTab(0)}
+ selected={props.settingsTab === 0}
>
General
setSettingsTab(1)}
- selected={settingsTab === 1}
+ onClick={() => props.onSettingsTab(1)}
+ selected={props.settingsTab === 1}
>
Device Linkages
- {(settingsTab === 0 && (
+ {(props.settingsTab === 0 && (
{(sync && (
<>
@@ -746,7 +743,7 @@ const ResearchConsoleSettings = (props) => {
)) ||
- (settingsTab === 1 && (
+ (props.settingsTab === 1 && (
act('find_device')}>
Re-sync with Nearby Devices
@@ -798,30 +795,28 @@ const menus = [
{
name: 'Protolathe',
icon: 'wrench',
- template: ,
},
{
name: 'Circuit Imprinter',
icon: 'digital-tachograph',
- template: ,
},
{
name: 'Destructive Analyzer',
icon: 'eraser',
- template: ,
},
- { name: 'Settings', icon: 'cog', template: },
+ {
+ name: 'Settings',
+ icon: 'cog',
+ },
{
name: 'Research List',
icon: 'flask',
- template: ,
},
{
name: 'Design List',
icon: 'file',
- template: ,
},
- { name: 'Disk Operations', icon: 'save', template: },
+ { name: 'Disk Operations', icon: 'save' },
];
export const ResearchConsole = (props) => {
@@ -830,6 +825,16 @@ export const ResearchConsole = (props) => {
const { busy_msg, locked } = data;
const [menu, setMenu] = useSharedState('rdmenu', 0);
+ const [protoTab, setProtoTab] = useSharedState('protoTab', 0);
+ const [settingsTab, setSettingsTab] = useSharedState('settingsTab', 0);
+ const [saveDialogTech, setSaveDialogTech] = useSharedState(
+ 'saveDialogTech',
+ false,
+ );
+ const [saveDialogDesign, setSaveDialogDesign] = useSharedState(
+ 'saveDialogData',
+ false,
+ );
let allTabsDisabled = false;
if (busy_msg || locked) {
@@ -845,7 +850,7 @@ export const ResearchConsole = (props) => {
key={i}
icon={obj.icon}
selected={menu === i}
- disabled={allTabsDisabled}
+ settingsTab={settingsTab}
onClick={() => setMenu(i)}
>
{obj.name}
@@ -860,7 +865,41 @@ export const ResearchConsole = (props) => {
)) ||
- menus[menu].template}
+ (menu === 0 ? (
+
+ ) : (
+ ''
+ )) ||
+ (menu === 1 && (
+
+ )) ||
+ (menu === 2 && (
+
+ )) ||
+ (menu === 3 && (
+
+ )) ||
+ (menu === 4 && ) ||
+ (menu === 5 && ) ||
+ (menu === 6 && (
+
+ ))}
);
diff --git a/tgui/packages/tgui/interfaces/SecureSafe.jsx b/tgui/packages/tgui/interfaces/SecureSafe.jsx
index d66c4365c2..e6b6b373ea 100644
--- a/tgui/packages/tgui/interfaces/SecureSafe.jsx
+++ b/tgui/packages/tgui/interfaces/SecureSafe.jsx
@@ -1,5 +1,5 @@
import { useBackend } from '../backend';
-import { Box, Button, Flex, Grid, NoticeBox, Section } from '../components';
+import { Box, Button, Flex, NoticeBox, Section, Table } from '../components';
import { Window } from '../layouts';
const NukeKeypad = (props) => {
@@ -12,9 +12,9 @@ const NukeKeypad = (props) => {
const { locked, l_setshort, code, emagged } = data;
return (
-
+
{keypadKeys.map((keyColumn) => (
-
+
{keyColumn.map((key) => (
{
onClick={() => act('type', { digit: key })}
/>
))}
-
+
))}
-
+
);
};
diff --git a/tgui/packages/tgui/interfaces/SuitCycler.jsx b/tgui/packages/tgui/interfaces/SuitCycler.jsx
index b1f33c8648..0cb620b0c1 100644
--- a/tgui/packages/tgui/interfaces/SuitCycler.jsx
+++ b/tgui/packages/tgui/interfaces/SuitCycler.jsx
@@ -1,3 +1,5 @@
+import { useState } from 'react';
+
import { useBackend } from '../backend';
import {
Box,
@@ -12,9 +14,32 @@ import { Window } from '../layouts';
export const SuitCycler = (props) => {
const { act, data } = useBackend();
- const { active, locked, uv_active } = data;
+ const { active, locked, uv_active, species, departments } = data;
- let subTemplate = ;
+ const [selectedDepartment, setSelectedDepartment] = useState(
+ (!!departments && departments[0]) || null,
+ );
+
+ const [selectedSpecies, setSelectedSpecies] = useState(
+ (!!species && species[0]) || null,
+ );
+
+ function handleSelectedDepartment(value) {
+ setSelectedDepartment(value);
+ }
+
+ function handleSelectedSpecies(value) {
+ setSelectedSpecies(value);
+ }
+
+ let subTemplate = (
+
+ );
if (uv_active) {
subTemplate = ;
@@ -111,8 +136,11 @@ const SuitCyclerContent = (props) => {
noscroll
width="150px"
options={departments}
- selected={departments[0]}
- onSelected={(val) => act('department', { department: val })}
+ selected={props.selectedDepartment}
+ onSelected={(val) => {
+ props.onSelectedDepartment(val);
+ act('department', { department: val });
+ }}
/>
@@ -120,8 +148,11 @@ const SuitCyclerContent = (props) => {
width="150px"
maxHeight="160px"
options={species}
- selected={species[0]}
- onSelected={(val) => act('species', { species: val })}
+ selected={props.selectedSpecies}
+ onSelected={(val) => {
+ props.onSelectedSpecies(val);
+ act('species', { species: val });
+ }}
/>
diff --git a/tgui/packages/tgui/interfaces/Uplink.jsx b/tgui/packages/tgui/interfaces/Uplink.jsx
index db44410923..e6f7d7d388 100644
--- a/tgui/packages/tgui/interfaces/Uplink.jsx
+++ b/tgui/packages/tgui/interfaces/Uplink.jsx
@@ -1,7 +1,7 @@
import { createSearch, decodeHtmlEntities } from 'common/string';
import { useState } from 'react';
-import { useBackend, useLocalState } from '../backend';
+import { useBackend } from '../backend';
import {
Box,
Button,
@@ -231,7 +231,7 @@ export const GenericUplink = (props) => {
const ItemList = (props) => {
const { compactMode, currencyAmount, currencySymbol } = props;
const { act } = useBackend();
- const [hoveredItem, setHoveredItem] = useLocalState('hoveredItem', {});
+ const [hoveredItem, setHoveredItem] = useState({});
const hoveredCost = (hoveredItem && hoveredItem.cost) || 0;
// Append extra hover data to items
const items = props.items.map((item) => {
diff --git a/tgui/packages/tgui/interfaces/VorePanel.jsx b/tgui/packages/tgui/interfaces/VorePanel.jsx
index 2efc8df4fd..eb1b208d33 100644
--- a/tgui/packages/tgui/interfaces/VorePanel.jsx
+++ b/tgui/packages/tgui/interfaces/VorePanel.jsx
@@ -1,7 +1,8 @@
import { classes } from 'common/react';
import { capitalize } from 'common/string';
+import { useState } from 'react';
-import { useBackend, useLocalState } from '../backend';
+import { useBackend } from '../backend';
import {
Box,
Button,
@@ -56,7 +57,7 @@ const digestModeToPreyMode = {
export const VorePanel = (props) => {
const { act, data } = useBackend();
- const [tabIndex, setTabIndex] = useLocalState('panelTabIndex', 0);
+ const [tabIndex, setTabIndex] = useState(0);
const tabs = [];
@@ -218,7 +219,7 @@ const VoreSelectedBelly = (props) => {
const { belly } = props;
const { contents } = belly;
- const [tabIndex, setTabIndex] = useLocalState('bellyTabIndex', 0);
+ const [tabIndex, setTabIndex] = useState(0);
const tabs = [];
diff --git a/tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.jsx b/tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.jsx
index f90d5551ea..b7744dce8a 100644
--- a/tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.jsx
+++ b/tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.jsx
@@ -7,7 +7,6 @@ import { Button, Flex, NoticeBox } from '../../components';
*
* - siliconUser: boolean
* - locked: boolean
- * - normallyLocked: boolean
*
* And expects the following ui_act action to be implemented:
*
@@ -21,28 +20,24 @@ export const InterfaceLockNoticeBox = (props) => {
const {
siliconUser = data.siliconUser,
locked = data.locked,
- normallyLocked = data.normallyLocked,
onLockStatusChange = () => act('lock'),
accessText = 'an ID card',
- deny = false,
- denialMessage = 'Error.',
+ preventLocking = data.preventLocking,
} = props;
- if (deny) {
- return denialMessage;
- }
// For silicon users
if (siliconUser) {
return (
-
+
Interface lock status:
-
+
{
if (onLockStatusChange) {
onLockStatusChange(!locked);