From a0cfc6eb97bbb52544d8e78de61c333659db264a Mon Sep 17 00:00:00 2001 From: Iajret Date: Tue, 12 Dec 2023 00:34:32 +0300 Subject: [PATCH] Revert "[MIRROR] Ports React [READY] [MDB IGNORE] (#1054)" This reverts commit 07cf8853f3369bef9f0b5a87c6842c44669657dc. --- tgui/.eslintignore | 2 +- tgui/.yarnrc.yml | 5 + tgui/README.md | 8 +- tgui/babel.config.js | 40 ++- tgui/docs/component-reference.md | 14 +- tgui/package.json | 4 +- tgui/packages/common/keys.ts | 10 +- tgui/packages/common/react.ts | 15 +- tgui/packages/common/redux.ts | 20 ++ tgui/packages/tgui-bench/package.json | 5 +- .../packages/tgui-bench/tests/Button.test.tsx | 23 ++ .../tgui-bench/tests/DisposalUnit.test.tsx | 12 +- tgui/packages/tgui-dev-server/package.json | 2 +- tgui/packages/tgui-panel/Panel.jsx | 16 +- .../tgui-panel/audio/NowPlayingWidget.jsx | 16 +- tgui/packages/tgui-panel/audio/hooks.js | 8 +- .../tgui-panel/chat/ChatPageSettings.jsx | 8 +- tgui/packages/tgui-panel/chat/ChatPanel.jsx | 8 +- tgui/packages/tgui-panel/chat/ChatTabs.jsx | 22 +- tgui/packages/tgui-panel/chat/renderer.jsx | 2 +- tgui/packages/tgui-panel/game/hooks.js | 6 +- tgui/packages/tgui-panel/index.jsx | 8 +- tgui/packages/tgui-panel/package.json | 4 +- .../tgui-panel/ping/PingIndicator.jsx | 6 +- .../tgui-panel/settings/SettingsPanel.jsx | 32 +-- tgui/packages/tgui-panel/settings/hooks.js | 8 +- tgui/packages/tgui-polyfill/1-misc.js | 5 + tgui/packages/tgui-polyfill/package.json | 2 +- tgui/packages/tgui-say/TguiSay.tsx | 14 +- tgui/packages/tgui-say/package.json | 3 +- tgui/packages/tgui/backend.ts | 8 - .../tgui/components/AnimatedNumber.tsx | 5 +- tgui/packages/tgui/components/Autofocus.tsx | 26 +- tgui/packages/tgui/components/Blink.jsx | 6 +- .../tgui/components/BodyZoneSelector.tsx | 29 ++- tgui/packages/tgui/components/Box.tsx | 187 +++++++------- tgui/packages/tgui/components/Button.jsx | 41 +++- tgui/packages/tgui/components/ByondUi.jsx | 16 +- .../tgui/components/{Chart.tsx => Chart.jsx} | 116 ++++----- tgui/packages/tgui/components/Collapsible.jsx | 2 +- tgui/packages/tgui/components/ColorBox.jsx | 4 +- .../tgui/components/DraggableControl.jsx | 8 +- tgui/packages/tgui/components/Dropdown.tsx | 48 ++-- .../packages/tgui/components/FakeTerminal.jsx | 2 +- tgui/packages/tgui/components/FitText.tsx | 15 +- tgui/packages/tgui/components/Flex.tsx | 81 +++--- tgui/packages/tgui/components/Grid.jsx | 5 + tgui/packages/tgui/components/Icon.tsx | 27 +- .../tgui/components/InfinitePlane.jsx | 30 +-- tgui/packages/tgui/components/Input.jsx | 6 +- tgui/packages/tgui/components/KeyListener.tsx | 6 +- tgui/packages/tgui/components/Knob.jsx | 10 +- tgui/packages/tgui/components/LabeledList.tsx | 35 ++- tgui/packages/tgui/components/MenuBar.tsx | 8 +- tgui/packages/tgui/components/NoticeBox.jsx | 4 +- tgui/packages/tgui/components/NumberInput.jsx | 34 ++- tgui/packages/tgui/components/Popper.tsx | 21 +- .../{ProgressBar.tsx => ProgressBar.jsx} | 49 ++-- .../tgui/components/RestrictedInput.jsx | 6 +- tgui/packages/tgui/components/RoundGauge.jsx | 11 +- tgui/packages/tgui/components/Section.tsx | 145 ++++++----- tgui/packages/tgui/components/Slider.jsx | 5 + tgui/packages/tgui/components/Stack.tsx | 29 +-- .../tgui/components/StyleableSection.tsx | 27 +- tgui/packages/tgui/components/Table.jsx | 8 +- .../tgui/components/{Tabs.tsx => Tabs.jsx} | 32 +-- tgui/packages/tgui/components/TextArea.jsx | 7 +- tgui/packages/tgui/components/TimeDisplay.jsx | 2 +- tgui/packages/tgui/components/Tooltip.tsx | 21 +- .../tgui/components/TrackOutsideClicks.tsx | 8 +- tgui/packages/tgui/debug/hooks.js | 4 +- tgui/packages/tgui/drag.ts | 4 +- .../tgui/interfaces/AdminBookViewer.tsx | 2 +- tgui/packages/tgui/interfaces/AdminFax.jsx | 2 +- tgui/packages/tgui/interfaces/Adminhelp.tsx | 4 +- tgui/packages/tgui/interfaces/AirAlarm.tsx | 2 +- .../tgui/interfaces/AntagInfoAssaultops.tsx | 6 +- .../tgui/interfaces/AntagInfoDemon.tsx | 2 +- .../tgui/interfaces/AntagInfoGlitch.tsx | 2 +- .../tgui/interfaces/AntagInfoHeretic.tsx | 4 +- .../tgui/interfaces/AntagInfoMalf.tsx | 8 +- tgui/packages/tgui/interfaces/ApcControl.jsx | 3 + .../tgui/interfaces/ApprenticeContract.tsx | 4 +- .../packages/tgui/interfaces/Biogenerator.tsx | 6 +- tgui/packages/tgui/interfaces/Canvas.tsx | 28 ++- tgui/packages/tgui/interfaces/Cargo.jsx | 4 +- .../tgui/interfaces/CentcomPodLauncher.jsx | 30 +-- tgui/packages/tgui/interfaces/Changelog.jsx | 6 +- tgui/packages/tgui/interfaces/ChemFilter.tsx | 2 +- tgui/packages/tgui/interfaces/ChemMaster.tsx | 8 +- .../tgui/interfaces/ChemSeparator.tsx | 4 +- .../tgui/interfaces/CircuitAdminPanel.tsx | 2 +- .../tgui/interfaces/CircuitSignalHandler.tsx | 2 +- .../tgui/interfaces/ClockworkResearch.tsx | 10 +- .../tgui/interfaces/ClockworkSlab.jsx | 6 +- tgui/packages/tgui/interfaces/CrewConsole.jsx | 2 +- .../tgui/interfaces/DepartmentOrders.tsx | 5 +- .../tgui/interfaces/DestructiveAnalyzer.tsx | 10 +- .../DnaConsole/DnaConsoleSequencer.jsx | 2 +- .../packages/tgui/interfaces/Electrolyzer.tsx | 3 +- .../tgui/interfaces/ElevatorPanel.tsx | 10 +- .../tgui/interfaces/ExodroneConsole.tsx | 23 +- .../interfaces/Fabrication/DesignBrowser.tsx | 14 +- .../tgui/interfaces/Fabrication/SearchBar.tsx | 2 +- tgui/packages/tgui/interfaces/Fabricator.tsx | 2 +- tgui/packages/tgui/interfaces/FishingRod.tsx | 14 +- .../packages/tgui/interfaces/GlassBlowing.tsx | 5 +- .../tgui/interfaces/GreyscaleModifyMenu.tsx | 14 +- tgui/packages/tgui/interfaces/HoloPay.tsx | 2 +- .../interfaces/Hypertorus/Temperatures.tsx | 8 +- tgui/packages/tgui/interfaces/IVDrip.tsx | 5 +- tgui/packages/tgui/interfaces/InfuserBook.tsx | 4 +- .../IntegratedCircuit/ComponentMenu.jsx | 6 +- .../IntegratedCircuit/DisplayComponent.jsx | 6 +- .../IntegratedCircuit/ObjectComponent.jsx | 6 +- .../interfaces/IntegratedCircuit/Port.jsx | 6 +- .../IntegratedCircuit/VariableMenu.jsx | 6 +- .../interfaces/IntegratedCircuit/index.jsx | 16 +- .../tgui/interfaces/InteractionMenu.tsx | 13 +- .../packages/tgui/interfaces/JobSelection.tsx | 57 +++-- tgui/packages/tgui/interfaces/Lawpanel.tsx | 2 +- .../packages/tgui/interfaces/LibraryAdmin.tsx | 2 +- .../tgui/interfaces/LuaEditor/Log.jsx | 2 +- .../tgui/interfaces/LuaEditor/index.jsx | 4 +- tgui/packages/tgui/interfaces/MODsuit.tsx | 15 +- tgui/packages/tgui/interfaces/MafiaPanel.tsx | 12 +- .../tgui/interfaces/MarkdownViewer.tsx | 2 +- tgui/packages/tgui/interfaces/MassSpec.jsx | 4 +- .../tgui/interfaces/Mecha/ModulesPane.tsx | 18 +- tgui/packages/tgui/interfaces/Mecha/index.tsx | 4 +- tgui/packages/tgui/interfaces/MemoryPanel.jsx | 8 +- tgui/packages/tgui/interfaces/NavBeacon.tsx | 2 +- .../tgui/interfaces/NtosEmojipedia.jsx | 3 + .../interfaces/NtosMessenger/ChatScreen.tsx | 4 +- tgui/packages/tgui/interfaces/NtosNotepad.tsx | 6 +- .../tgui/interfaces/NtosPhysScanner.jsx | 2 +- .../tgui/interfaces/NtosPortraitPrinter.jsx | 8 +- tgui/packages/tgui/interfaces/NtosRadar.tsx | 10 +- .../packages/tgui/interfaces/OreContainer.tsx | 3 +- .../tgui/interfaces/OreRedemptionMachine.jsx | 3 +- .../packages/tgui/interfaces/OutfitEditor.jsx | 14 +- .../tgui/interfaces/OutfitManager.jsx | 8 +- .../tgui/interfaces/PaiInterface/System.tsx | 2 +- .../tgui/interfaces/PaintingAdminPanel.tsx | 10 +- .../tgui/interfaces/Pandemic/Symptom.tsx | 2 +- tgui/packages/tgui/interfaces/PaperSheet.tsx | 20 +- .../tgui/interfaces/PersonalCrafting.tsx | 22 +- .../tgui/interfaces/PlaneMasterDebug.tsx | 12 +- .../tgui/interfaces/PlayerTicketHistory.tsx | 4 +- .../tgui/interfaces/PortraitPicker.jsx | 3 +- .../packages/tgui/interfaces/PowerMonitor.jsx | 5 + .../interfaces/PreferencesMenu/AntagsPage.tsx | 8 +- .../PreferencesMenu/GamePreferencesPage.tsx | 12 +- .../interfaces/PreferencesMenu/JobsPage.tsx | 44 ++-- .../PreferencesMenu/KeybindingsPage.tsx | 8 +- .../interfaces/PreferencesMenu/LimbsPage.tsx | 8 +- .../interfaces/PreferencesMenu/MainPage.tsx | 20 +- .../interfaces/PreferencesMenu/PageButton.tsx | 4 +- .../interfaces/PreferencesMenu/QuirksPage.tsx | 33 +-- .../ServerPreferencesFetcher.tsx | 6 +- .../PreferencesMenu/SpeciesPage.tsx | 10 +- .../interfaces/PreferencesMenu/TabbedMenu.tsx | 4 +- .../tgui/interfaces/PreferencesMenu/names.tsx | 16 +- .../preferences/features/base.tsx | 40 +-- .../character_preferences/skin_tone.tsx | 6 +- .../features/game_preferences/ghost.tsx | 8 +- .../features/game_preferences/ui_style.tsx | 2 +- .../tgui/interfaces/ProduceConsole.tsx | 5 +- tgui/packages/tgui/interfaces/Puzzgrid.tsx | 31 ++- .../tgui/interfaces/RapidPipeDispenser.tsx | 4 +- tgui/packages/tgui/interfaces/Safe.jsx | 2 +- .../tgui/interfaces/SatelliteControl.tsx | 3 + .../tgui/interfaces/SeedExtractor.tsx | 4 +- .../tgui/interfaces/SelectEquipment.jsx | 7 +- .../tgui/interfaces/ServerControl.tsx | 2 +- tgui/packages/tgui/interfaces/Spellbook.tsx | 4 +- .../tgui/interfaces/StackingConsole.jsx | 6 +- tgui/packages/tgui/interfaces/StripMenu.tsx | 11 +- tgui/packages/tgui/interfaces/Supermatter.tsx | 8 +- .../tgui/interfaces/SurgeryInitiator.tsx | 2 +- .../tgui/interfaces/SyndContractor.jsx | 10 +- tgui/packages/tgui/interfaces/Thermometer.jsx | 72 +++--- .../tgui/interfaces/TrackedPlaytime.jsx | 2 +- .../tgui/interfaces/TraitorObjectiveDebug.tsx | 14 +- tgui/packages/tgui/interfaces/TramControl.jsx | 2 +- .../tgui/interfaces/TrophyAdminPanel.jsx | 12 +- tgui/packages/tgui/interfaces/Trophycase.jsx | 3 + .../tgui/interfaces/Uplink/ObjectiveMenu.tsx | 39 +-- .../Uplink/calculateDangerLevel.tsx | 8 +- .../packages/tgui/interfaces/Uplink/index.tsx | 10 +- tgui/packages/tgui/interfaces/Vendatray.tsx | 3 +- tgui/packages/tgui/interfaces/Vending.tsx | 6 +- tgui/packages/tgui/interfaces/VotePanel.tsx | 2 +- .../tgui/interfaces/common/AtmosHandbook.tsx | 6 +- .../tgui/interfaces/common/Connections.tsx | 4 +- .../tgui/interfaces/common/EditableText.tsx | 8 +- .../tgui/interfaces/common/Objectives.tsx | 4 +- .../tgui/interfaces/common/RecipeLookup.jsx | 2 +- tgui/packages/tgui/layouts/Window.jsx | 206 ++++++++++++++++ tgui/packages/tgui/layouts/Window.tsx | 231 ------------------ tgui/packages/tgui/package.json | 8 +- tgui/packages/tgui/renderer.ts | 2 +- tgui/packages/tgui/store.ts | 15 ++ tgui/public/tgui-polyfill.min.js | 2 +- tgui/yarn.lock | 215 +++++----------- 205 files changed, 1686 insertions(+), 1588 deletions(-) rename tgui/packages/tgui/components/{Chart.tsx => Chart.jsx} (53%) rename tgui/packages/tgui/components/{ProgressBar.tsx => ProgressBar.jsx} (57%) rename tgui/packages/tgui/components/{Tabs.tsx => Tabs.jsx} (67%) create mode 100644 tgui/packages/tgui/layouts/Window.jsx delete mode 100644 tgui/packages/tgui/layouts/Window.tsx diff --git a/tgui/.eslintignore b/tgui/.eslintignore index 692ac5f24af..a59187b933a 100644 --- a/tgui/.eslintignore +++ b/tgui/.eslintignore @@ -3,4 +3,4 @@ /**/*.bundle.* /**/*.chunk.* /**/*.hot-update.* - +/packages/inferno/** diff --git a/tgui/.yarnrc.yml b/tgui/.yarnrc.yml index 086484a243a..ddacbb4b64d 100644 --- a/tgui/.yarnrc.yml +++ b/tgui/.yarnrc.yml @@ -6,6 +6,11 @@ logFilters: - code: YN0062 level: discard +packageExtensions: + 'babel-plugin-inferno@*': + dependencies: + '@babel/core': '*' + plugins: - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs spec: '@yarnpkg/plugin-interactive-tools' diff --git a/tgui/README.md b/tgui/README.md index 1bae91fd132..e8713024342 100644 --- a/tgui/README.md +++ b/tgui/README.md @@ -16,9 +16,10 @@ If you are completely new to frontend and prefer to **learn by doing**, start wi ### Guides -This project uses React. Take your time to read the guide: +This project uses **Inferno** - a very fast UI rendering engine with a similar API to React. Take your time to read these guides: -- [React guide](https://react.dev/learn) +- [React guide](https://reactjs.org/docs/hello-world.html) +- [Inferno documentation](https://infernojs.org/docs/guides/components) - highlights differences with React. If you were already familiar with an older, Ractive-based tgui, and want to translate concepts between old and new tgui, read this [interface conversion guide](docs/converting-old-tgui-interfaces.md). @@ -70,7 +71,6 @@ However, if you want finer control over the installation or build process, you w - `tools/build/build tgui-clean` - Clean up tgui folder. > With Juke Build, you can run multiple targets together, e.g.: -> > ``` > tools/build/build tgui tgui-lint tgui-tsc tgui-test > ``` @@ -137,7 +137,7 @@ Press `F12` or click the green bug to open the KitchenSink interface. This inter playground to test various tgui components. **Layout Debugger.** -Press `F11` to toggle the _layout debugger_. It will show outlines of +Press `F11` to toggle the *layout debugger*. It will show outlines of all tgui elements, which makes it easy to understand how everything comes together, and can reveal certain layout bugs which are not normally visible. diff --git a/tgui/babel.config.js b/tgui/babel.config.js index 69a5a401cc7..5f86bada506 100644 --- a/tgui/babel.config.js +++ b/tgui/babel.config.js @@ -6,36 +6,28 @@ const createBabelConfig = (options) => { const { presets = [], plugins = [], removeConsole } = options; + // prettier-ignore return { presets: [ - [ - require.resolve('@babel/preset-typescript'), - { - allowDeclareFields: true, - }, - ], - [ - require.resolve('@babel/preset-env'), - { - modules: 'commonjs', - useBuiltIns: 'entry', - corejs: '3.3.2', - spec: false, - loose: true, - targets: [], - }, - ], - [require.resolve('@babel/preset-react'), { runtime: 'automatic' }], + [require.resolve('@babel/preset-typescript'), { + allowDeclareFields: true, + }], + [require.resolve('@babel/preset-env'), { + modules: 'commonjs', + useBuiltIns: 'entry', + corejs: '3', + spec: false, + loose: true, + targets: [], + }], ...presets, ].filter(Boolean), plugins: [ - [ - require.resolve('@babel/plugin-transform-class-properties'), - { - loose: true, - }, - ], + [require.resolve('@babel/plugin-transform-class-properties'), { + loose: true, + }], require.resolve('@babel/plugin-transform-jscript'), + require.resolve('babel-plugin-inferno'), removeConsole && require.resolve('babel-plugin-transform-remove-console'), require.resolve('common/string.babel-plugin.cjs'), ...plugins, diff --git a/tgui/docs/component-reference.md b/tgui/docs/component-reference.md index f56bb68eec7..9fff68172fd 100644 --- a/tgui/docs/component-reference.md +++ b/tgui/docs/component-reference.md @@ -65,13 +65,17 @@ it is used a lot in this framework. **Event handlers.** Event handlers are callbacks that you can attack to various element to -listen for browser events. React supports camelcase (`onClick`) event names. +listen for browser events. Inferno supports camelcase (`onClick`) and +lowercase (`onclick`) event names. - Camel case names are what's called *synthetic* events, and are the **preferred way** of handling events in React, for efficiency and performance reasons. Please read -[React Event Handling](https://react.dev/learn/responding-to-events) +[Inferno Event Handling](https://infernojs.org/docs/guides/event-handling) to understand what this is about. +- Lower case names are native browser events and should be used sparingly, +for example when you need an explicit IE8 support. **DO NOT** use +lowercase event handlers unless you really know what you are doing. ## `tgui/components` @@ -366,7 +370,7 @@ dropdown when open. See Dropdown.tsx for more adcanced usage with DropdownEntry - `over: boolean` - Dropdown renders over instead of below - `color: string` - Color of dropdown button - `nochevron: boolean` - Whether or not the arrow on the right hand side of the dropdown button is visible -- `displayText: string | number | ReactNode` - Text to always display in place of the selected text +- `displayText: string | number | InfernoNode` - Text to always display in place of the selected text - `onClick: (e) => void` - Called when dropdown button is clicked - `onSelected: (value) => void` - Called when a value is picked from the list, `value` is the value that was picked @@ -661,7 +665,7 @@ to perform some sort of action), there is a way to do that: **Props:** - `className: string` - Applies a CSS class to the element. -- `label: string|ReactNode` - Item label. +- `label: string|InfernoNode` - Item label. - `labelWrap: boolean` - Lets the label wrap and makes it not take the minimum width. - `labelColor: string` - Sets the color of the label. - `color: string` - Sets the color of the content text. @@ -756,7 +760,7 @@ Popper lets you position elements so that they don't go out of the bounds of the **Props:** -- `popperContent: ReactNode` - The content that will be put inside the popper. +- `popperContent: InfernoNode` - The content that will be put inside the popper. - `options?: { ... }` - An object of options to pass to `createPopper`. See [https://popper.js.org/docs/v2/constructors/#options], but the one you want most is `placement`. Valid placements are "bottom", "top", "left", and "right". You can affix "-start" and "-end" to achieve something like top left or top right respectively. You can also use "auto" (with an optional "-start" or "-end"), where a best fit will be chosen. - `additionalStyles: { ... }` - A map of CSS styles to add to the element that will contain the popper. diff --git a/tgui/package.json b/tgui/package.json index 9ae4f99dbca..79e4946875d 100644 --- a/tgui/package.json +++ b/tgui/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "tgui-workspace", - "version": "5.0.0", + "version": "4.4.0", "packageManager": "yarn@3.3.1", "workspaces": [ "packages/*" @@ -25,7 +25,6 @@ "@babel/plugin-transform-class-properties": "^7.23.3", "@babel/plugin-transform-jscript": "^7.23.3", "@babel/preset-env": "^7.23.3", - "@babel/preset-react": "^7.23.3", "@babel/preset-typescript": "^7.23.3", "@types/jest": "^29.5.10", "@types/jsdom": "^21.1.6", @@ -35,6 +34,7 @@ "@typescript-eslint/parser": "^5.62.0", "babel-jest": "^29.7.0", "babel-loader": "^8.3.0", + "babel-plugin-inferno": "^6.7.0", "babel-plugin-transform-remove-console": "^6.9.4", "common": "workspace:*", "css-loader": "^6.8.1", diff --git a/tgui/packages/common/keys.ts b/tgui/packages/common/keys.ts index 34ac9e1614d..61b79992b48 100644 --- a/tgui/packages/common/keys.ts +++ b/tgui/packages/common/keys.ts @@ -22,18 +22,18 @@ export enum KEY { Backspace = 'Backspace', Control = 'Control', Delete = 'Delete', - Down = 'ArrowDown', + Down = 'Down', End = 'End', Enter = 'Enter', - Escape = 'Escape', + Escape = 'Esc', Home = 'Home', Insert = 'Insert', - Left = 'ArrowLeft', + Left = 'Left', PageDown = 'PageDown', PageUp = 'PageUp', - Right = 'ArrowRight', + Right = 'Right', Shift = 'Shift', Space = ' ', Tab = 'Tab', - Up = 'ArrowUp', + Up = 'Up', } diff --git a/tgui/packages/common/react.ts b/tgui/packages/common/react.ts index 5260ff6ae12..8e42d0971ab 100644 --- a/tgui/packages/common/react.ts +++ b/tgui/packages/common/react.ts @@ -52,10 +52,13 @@ export const shallowDiffers = (a: object, b: object) => { }; /** - * A common case in tgui, when you pass a value conditionally, these are - * the types that can fall through the condition. + * Default inferno hooks for pure components. */ -export type BooleanLike = number | boolean | null | undefined; +export const pureComponentHooks = { + onComponentShouldUpdate: (lastProps, nextProps) => { + return shallowDiffers(lastProps, nextProps); + }, +}; /** * A helper to determine whether the object is renderable by React. @@ -66,3 +69,9 @@ export const canRender = (value: unknown) => { && value !== null && typeof value !== 'boolean'; }; + +/** + * A common case in tgui, when you pass a value conditionally, these are + * the types that can fall through the condition. + */ +export type BooleanLike = number | boolean | null | undefined; diff --git a/tgui/packages/common/redux.ts b/tgui/packages/common/redux.ts index 7b4999d93b1..1635853c6b4 100644 --- a/tgui/packages/common/redux.ts +++ b/tgui/packages/common/redux.ts @@ -194,3 +194,23 @@ export const createAction = ( return actionCreator; }; + +// Implementation specific +// -------------------------------------------------------- + +export const useDispatch = (context: { + store: Store; +}): Dispatch => { + return context?.store?.dispatch; +}; + +export const useSelector = ( + context: { store: Store }, + selector: (state: State) => Selected +): Selected => { + if (!context) { + return {} as Selected; + } + + return selector(context?.store?.getState()); +}; diff --git a/tgui/packages/tgui-bench/package.json b/tgui/packages/tgui-bench/package.json index 47cad082fb9..22719711733 100644 --- a/tgui/packages/tgui-bench/package.json +++ b/tgui/packages/tgui-bench/package.json @@ -1,14 +1,15 @@ { "private": true, "name": "tgui-bench", - "version": "5.0.0", + "version": "4.4.0", "dependencies": { "@fastify/static": "^6.12.0", "common": "workspace:*", "fastify": "^3.29.5", + "inferno": "^7.4.11", + "inferno-vnode-flags": "^7.4.11", "lodash": "^4.17.21", "platform": "^1.3.6", - "react": "^18.2.0", "tgui": "workspace:*" } } diff --git a/tgui/packages/tgui-bench/tests/Button.test.tsx b/tgui/packages/tgui-bench/tests/Button.test.tsx index 0549e69b623..6b806d720ab 100644 --- a/tgui/packages/tgui-bench/tests/Button.test.tsx +++ b/tgui/packages/tgui-bench/tests/Button.test.tsx @@ -1,8 +1,11 @@ +import { linkEvent } from 'inferno'; import { Button } from 'tgui/components'; import { createRenderer } from 'tgui/renderer'; const render = createRenderer(); +const handleClick = () => undefined; + export const SingleButton = () => { const node = ; render(node); @@ -13,6 +16,13 @@ export const SingleButtonWithCallback = () => { render(node); }; +export const SingleButtonWithLinkEvent = () => { + const node = ( + + ); + render(node); +}; + export const ListOfButtons = () => { const nodes: JSX.Element[] = []; for (let i = 0; i < 100; i++) { @@ -35,6 +45,19 @@ export const ListOfButtonsWithCallback = () => { render(
{nodes}
); }; +export const ListOfButtonsWithLinkEvent = () => { + const nodes: JSX.Element[] = []; + for (let i = 0; i < 100; i++) { + const node = ( + + ); + nodes.push(node); + } + render(
{nodes}
); +}; + export const ListOfButtonsWithIcons = () => { const nodes: JSX.Element[] = []; for (let i = 0; i < 100; i++) { diff --git a/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx b/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx index a3a53cf750c..1ae610e2e2e 100644 --- a/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx +++ b/tgui/packages/tgui-bench/tests/DisposalUnit.test.tsx @@ -1,20 +1,22 @@ -import { configureStore } from 'tgui/store'; +import { StoreProvider, configureStore } from 'tgui/store'; import { DisposalUnit } from 'tgui/interfaces/DisposalUnit'; -import { backendUpdate, setGlobalStore } from 'tgui/backend'; +import { backendUpdate } from 'tgui/backend'; import { createRenderer } from 'tgui/renderer'; const store = configureStore({ sideEffects: false }); const renderUi = createRenderer((dataJson: string) => { - setGlobalStore(store); - store.dispatch( backendUpdate({ data: Byond.parseJson(dataJson), }) ); - return ; + return ( + + + + ); }); export const data = JSON.stringify({ diff --git a/tgui/packages/tgui-dev-server/package.json b/tgui/packages/tgui-dev-server/package.json index 496e25c6c18..d911f9693de 100644 --- a/tgui/packages/tgui-dev-server/package.json +++ b/tgui/packages/tgui-dev-server/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "tgui-dev-server", - "version": "5.0.0", + "version": "4.4.0", "type": "module", "dependencies": { "axios": "^1.6.2", diff --git a/tgui/packages/tgui-panel/Panel.jsx b/tgui/packages/tgui-panel/Panel.jsx index 260e1dfd6df..83150ab6ef1 100644 --- a/tgui/packages/tgui-panel/Panel.jsx +++ b/tgui/packages/tgui-panel/Panel.jsx @@ -14,17 +14,17 @@ import { PingIndicator } from './ping'; import { ReconnectButton } from './reconnect'; import { SettingsPanel, useSettings } from './settings'; -export const Panel = (props) => { +export const Panel = (props, context) => { // IE8-10: Needs special treatment due to missing Flex support if (Byond.IS_LTE_IE10) { return ; } - const audio = useAudio(); - const settings = useSettings(); - const game = useGame(); + const audio = useAudio(context); + const settings = useSettings(context); + const game = useGame(context); if (process.env.NODE_ENV !== 'production') { const { useDebug, KitchenSink } = require('tgui/debug'); - const debug = useDebug(); + const debug = useDebug(context); if (debug.kitchenSink) { return ; } @@ -103,8 +103,8 @@ export const Panel = (props) => { ); }; -const HoboPanel = (props) => { - const settings = useSettings(); +const HoboPanel = (props, context) => { + const settings = useSettings(context); return ( @@ -113,7 +113,7 @@ const HoboPanel = (props) => { position: 'fixed', top: '1em', right: '2em', - zIndex: 1000, + 'z-index': 1000, }} selected={settings.visible} onClick={() => settings.toggle()}> diff --git a/tgui/packages/tgui-panel/audio/NowPlayingWidget.jsx b/tgui/packages/tgui-panel/audio/NowPlayingWidget.jsx index 8260ee8c233..30052c3f3a3 100644 --- a/tgui/packages/tgui-panel/audio/NowPlayingWidget.jsx +++ b/tgui/packages/tgui-panel/audio/NowPlayingWidget.jsx @@ -5,15 +5,15 @@ */ import { toFixed } from 'common/math'; -import { useDispatch, useSelector } from 'tgui/backend'; +import { useDispatch, useSelector } from 'common/redux'; import { Button, Collapsible, Flex, Knob, Section } from 'tgui/components'; import { useSettings } from '../settings'; import { selectAudio } from './selectors'; -export const NowPlayingWidget = (props) => { - const audio = useSelector(selectAudio), - dispatch = useDispatch(), - settings = useSettings(), +export const NowPlayingWidget = (props, context) => { + const audio = useSelector(context, selectAudio), + dispatch = useDispatch(context), + settings = useSettings(context), title = audio.meta?.title, URL = audio.meta?.link, Artist = audio.meta?.artist || 'Unknown Artist', @@ -35,9 +35,9 @@ export const NowPlayingWidget = (props) => { mx={0.5} grow={1} style={{ - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', + 'white-space': 'nowrap', + 'overflow': 'hidden', + 'text-overflow': 'ellipsis', }}> { diff --git a/tgui/packages/tgui-panel/audio/hooks.js b/tgui/packages/tgui-panel/audio/hooks.js index 1286754a37d..504b4f5c6e7 100644 --- a/tgui/packages/tgui-panel/audio/hooks.js +++ b/tgui/packages/tgui-panel/audio/hooks.js @@ -4,12 +4,12 @@ * @license MIT */ -import { useSelector, useDispatch } from 'tgui/backend'; +import { useSelector, useDispatch } from 'common/redux'; import { selectAudio } from './selectors'; -export const useAudio = () => { - const state = useSelector(selectAudio); - const dispatch = useDispatch(); +export const useAudio = (context) => { + const state = useSelector(context, selectAudio); + const dispatch = useDispatch(context); return { ...state, toggle: () => dispatch({ type: 'audio/toggle' }), diff --git a/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx b/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx index 2da47daa07d..c0d9962d253 100644 --- a/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx +++ b/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx @@ -4,15 +4,15 @@ * @license MIT */ -import { useDispatch, useSelector } from 'tgui/backend'; +import { useDispatch, useSelector } from 'common/redux'; import { Button, Collapsible, Divider, Input, Section, Stack } from 'tgui/components'; import { removeChatPage, toggleAcceptedType, updateChatPage } from './actions'; import { MESSAGE_TYPES } from './constants'; import { selectCurrentChatPage } from './selectors'; -export const ChatPageSettings = (props) => { - const page = useSelector(selectCurrentChatPage); - const dispatch = useDispatch(); +export const ChatPageSettings = (props, context) => { + const page = useSelector(context, selectCurrentChatPage); + const dispatch = useDispatch(context); return (
diff --git a/tgui/packages/tgui-panel/chat/ChatPanel.jsx b/tgui/packages/tgui-panel/chat/ChatPanel.jsx index 166705361fa..3132a66ce7f 100644 --- a/tgui/packages/tgui-panel/chat/ChatPanel.jsx +++ b/tgui/packages/tgui-panel/chat/ChatPanel.jsx @@ -5,13 +5,13 @@ */ import { shallowDiffers } from 'common/react'; -import { Component, createRef } from 'react'; +import { Component, createRef } from 'inferno'; import { Button } from 'tgui/components'; import { chatRenderer } from './renderer'; export class ChatPanel extends Component { - constructor(props) { - super(props); + constructor() { + super(); this.ref = createRef(); this.state = { scrollTracking: true, @@ -46,7 +46,7 @@ export class ChatPanel extends Component { !prevProps || shallowDiffers(this.props, prevProps); if (shouldUpdateStyle) { chatRenderer.assignStyle({ - width: '100%', + 'width': '100%', 'white-space': 'pre-wrap', 'font-size': this.props.fontSize, 'line-height': this.props.lineHeight, diff --git a/tgui/packages/tgui-panel/chat/ChatTabs.jsx b/tgui/packages/tgui-panel/chat/ChatTabs.jsx index 04d5f25b4bf..1d4f6f65edf 100644 --- a/tgui/packages/tgui-panel/chat/ChatTabs.jsx +++ b/tgui/packages/tgui-panel/chat/ChatTabs.jsx @@ -4,7 +4,7 @@ * @license MIT */ -import { useDispatch, useSelector } from 'tgui/backend'; +import { useDispatch, useSelector } from 'common/redux'; import { Box, Tabs, Flex, Button } from 'tgui/components'; import { changeChatPage, addChatPage } from './actions'; import { selectChatPages, selectCurrentChatPage } from './selectors'; @@ -13,21 +13,21 @@ import { openChatSettings } from '../settings/actions'; const UnreadCountWidget = ({ value }) => ( {Math.min(value, 99)} ); -export const ChatTabs = (props) => { - const pages = useSelector(selectChatPages); - const currentPage = useSelector(selectCurrentChatPage); - const dispatch = useDispatch(); +export const ChatTabs = (props, context) => { + const pages = useSelector(context, selectChatPages); + const currentPage = useSelector(context, selectCurrentChatPage); + const dispatch = useDispatch(context); return ( diff --git a/tgui/packages/tgui-panel/chat/renderer.jsx b/tgui/packages/tgui-panel/chat/renderer.jsx index f2b4ac2caa6..5d6337148fb 100644 --- a/tgui/packages/tgui-panel/chat/renderer.jsx +++ b/tgui/packages/tgui-panel/chat/renderer.jsx @@ -8,7 +8,7 @@ import { EventEmitter } from 'common/events'; import { classes } from 'common/react'; import { createLogger } from 'tgui/logging'; import { COMBINE_MAX_MESSAGES, COMBINE_MAX_TIME_WINDOW, IMAGE_RETRY_DELAY, IMAGE_RETRY_LIMIT, IMAGE_RETRY_MESSAGE_AGE, MAX_PERSISTED_MESSAGES, MAX_VISIBLE_MESSAGES, MESSAGE_PRUNE_INTERVAL, MESSAGE_TYPES, MESSAGE_TYPE_INTERNAL, MESSAGE_TYPE_UNKNOWN } from './constants'; -import { render } from 'react-dom'; +import { render } from 'inferno'; import { canPageAcceptType, createMessage, isSameMessage } from './model'; import { highlightNode, linkifyNode } from './replaceInTextNode'; import { Tooltip } from 'tgui/components'; diff --git a/tgui/packages/tgui-panel/game/hooks.js b/tgui/packages/tgui-panel/game/hooks.js index c3e7c062847..859aaa09a40 100644 --- a/tgui/packages/tgui-panel/game/hooks.js +++ b/tgui/packages/tgui-panel/game/hooks.js @@ -4,9 +4,9 @@ * @license MIT */ -import { useSelector } from 'tgui/backend'; +import { useSelector } from 'common/redux'; import { selectGame } from './selectors'; -export const useGame = () => { - return useSelector(selectGame); +export const useGame = (context) => { + return useSelector(context, selectGame); }; diff --git a/tgui/packages/tgui-panel/index.jsx b/tgui/packages/tgui-panel/index.jsx index ed0f01a6e79..336d46031c4 100644 --- a/tgui/packages/tgui-panel/index.jsx +++ b/tgui/packages/tgui-panel/index.jsx @@ -14,7 +14,7 @@ import { setupHotReloading } from 'tgui-dev-server/link/client.cjs'; import { setupGlobalEvents } from 'tgui/events'; import { captureExternalLinks } from 'tgui/links'; import { createRenderer } from 'tgui/renderer'; -import { configureStore } from 'tgui/store'; +import { configureStore, StoreProvider } from 'tgui/store'; import { audioMiddleware, audioReducer } from './audio'; import { chatMiddleware, chatReducer } from './chat'; import { gameMiddleware, gameReducer } from './game'; @@ -51,7 +51,11 @@ const renderApp = createRenderer(() => { setGlobalStore(store); const { Panel } = require('./Panel'); - return ; + return ( + + + + ); }); const setupApp = () => { diff --git a/tgui/packages/tgui-panel/package.json b/tgui/packages/tgui-panel/package.json index b1c4bb1786c..9d2aa05be22 100644 --- a/tgui/packages/tgui-panel/package.json +++ b/tgui/packages/tgui-panel/package.json @@ -3,11 +3,9 @@ "name": "tgui-panel", "version": "4.3.2", "dependencies": { - "@types/react": "^18.2.39", "common": "workspace:*", "dompurify": "^2.4.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "inferno": "^7.4.11", "tgui": "workspace:*", "tgui-dev-server": "workspace:*", "tgui-polyfill": "workspace:*" diff --git a/tgui/packages/tgui-panel/ping/PingIndicator.jsx b/tgui/packages/tgui-panel/ping/PingIndicator.jsx index b2355820e58..aadbd1c134b 100644 --- a/tgui/packages/tgui-panel/ping/PingIndicator.jsx +++ b/tgui/packages/tgui-panel/ping/PingIndicator.jsx @@ -6,12 +6,12 @@ import { Color } from 'common/color'; import { toFixed } from 'common/math'; -import { useSelector } from 'tgui/backend'; +import { useSelector } from 'common/redux'; import { Box } from 'tgui/components'; import { selectPing } from './selectors'; -export const PingIndicator = (props) => { - const ping = useSelector(selectPing); +export const PingIndicator = (props, context) => { + const ping = useSelector(context, selectPing); const color = Color.lookup(ping.networkQuality, [ new Color(220, 40, 40), new Color(220, 200, 40), diff --git a/tgui/packages/tgui-panel/settings/SettingsPanel.jsx b/tgui/packages/tgui-panel/settings/SettingsPanel.jsx index 87e5d8b74e7..90abe4e36b2 100644 --- a/tgui/packages/tgui-panel/settings/SettingsPanel.jsx +++ b/tgui/packages/tgui-panel/settings/SettingsPanel.jsx @@ -6,7 +6,7 @@ import { toFixed } from 'common/math'; import { useLocalState } from 'tgui/backend'; -import { useDispatch, useSelector } from 'tgui/backend'; +import { useDispatch, useSelector } from 'common/redux'; import { Box, Button, ColorBox, Divider, Dropdown, Flex, Input, LabeledList, NumberInput, Section, Stack, Tabs, TextArea } from 'tgui/components'; import { ChatPageSettings } from '../chat'; import { rebuildChat, saveChatToDisk } from '../chat/actions'; @@ -15,9 +15,9 @@ import { changeSettingsTab, updateSettings, addHighlightSetting, removeHighlight import { SETTINGS_TABS, FONTS, MAX_HIGHLIGHT_SETTINGS } from './constants'; import { selectActiveTab, selectSettings, selectHighlightSettings, selectHighlightSettingById } from './selectors'; -export const SettingsPanel = (props) => { - const activeTab = useSelector(selectActiveTab); - const dispatch = useDispatch(); +export const SettingsPanel = (props, context) => { + const activeTab = useSelector(context, selectActiveTab); + const dispatch = useDispatch(context); return ( @@ -49,11 +49,13 @@ export const SettingsPanel = (props) => { ); }; -export const SettingsGeneral = (props) => { - const { theme, fontFamily, fontSize, lineHeight } = - useSelector(selectSettings); - const dispatch = useDispatch(); - const [freeFont, setFreeFont] = useLocalState('freeFont', false); +export const SettingsGeneral = (props, context) => { + const { theme, fontFamily, fontSize, lineHeight } = useSelector( + context, + selectSettings + ); + const dispatch = useDispatch(context); + const [freeFont, setFreeFont] = useLocalState(context, 'freeFont', false); return (
@@ -157,9 +159,9 @@ export const SettingsGeneral = (props) => { ); }; -const TextHighlightSettings = (props) => { - const highlightSettings = useSelector(selectHighlightSettings); - const dispatch = useDispatch(); +const TextHighlightSettings = (props, context) => { + const highlightSettings = useSelector(context, selectHighlightSettings); + const dispatch = useDispatch(context); return (
@@ -198,10 +200,10 @@ const TextHighlightSettings = (props) => { ); }; -const TextHighlightSetting = (props) => { +const TextHighlightSetting = (props, context) => { const { id, ...rest } = props; - const highlightSettingById = useSelector(selectHighlightSettingById); - const dispatch = useDispatch(); + const highlightSettingById = useSelector(context, selectHighlightSettingById); + const dispatch = useDispatch(context); const { highlightColor, highlightText, diff --git a/tgui/packages/tgui-panel/settings/hooks.js b/tgui/packages/tgui-panel/settings/hooks.js index 5ea91c86067..da46322f9a9 100644 --- a/tgui/packages/tgui-panel/settings/hooks.js +++ b/tgui/packages/tgui-panel/settings/hooks.js @@ -4,13 +4,13 @@ * @license MIT */ -import { useDispatch, useSelector } from 'tgui/backend'; +import { useDispatch, useSelector } from 'common/redux'; import { updateSettings, toggleSettings } from './actions'; import { selectSettings } from './selectors'; -export const useSettings = () => { - const settings = useSelector(selectSettings); - const dispatch = useDispatch(); +export const useSettings = (context) => { + const settings = useSelector(context, selectSettings); + const dispatch = useDispatch(context); return { ...settings, visible: settings.view.visible, diff --git a/tgui/packages/tgui-polyfill/1-misc.js b/tgui/packages/tgui-polyfill/1-misc.js index cefbdbdbdfc..af9b900fe0b 100644 --- a/tgui/packages/tgui-polyfill/1-misc.js +++ b/tgui/packages/tgui-polyfill/1-misc.js @@ -8,6 +8,11 @@ (function () { 'use strict'; + // Inferno needs Int32Array, and it is not covered by core-js. + if (!window.Int32Array) { + window.Int32Array = Array; + } + // ie11 polyfills !(function () { // append diff --git a/tgui/packages/tgui-polyfill/package.json b/tgui/packages/tgui-polyfill/package.json index 8e43bb87224..c0cb0911160 100644 --- a/tgui/packages/tgui-polyfill/package.json +++ b/tgui/packages/tgui-polyfill/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "tgui-polyfill", - "version": "5.0.0", + "version": "4.4.0", "scripts": { "tgui-polyfill:build": "terser 1-misc.js -f ascii_only,comments=false -o ../../public/tgui-polyfill.min.js" }, diff --git a/tgui/packages/tgui-say/TguiSay.tsx b/tgui/packages/tgui-say/TguiSay.tsx index b5ac871130a..267febef650 100644 --- a/tgui/packages/tgui-say/TguiSay.tsx +++ b/tgui/packages/tgui-say/TguiSay.tsx @@ -1,6 +1,6 @@ import { Channel, ChannelIterator } from './ChannelIterator'; import { ChatHistory } from './ChatHistory'; -import { Component, createRef, RefObject } from 'react'; +import { Component, createRef, InfernoKeyboardEvent, RefObject } from 'inferno'; import { LINE_LENGTHS, RADIO_PREFIXES, WINDOW_SIZES } from './constants'; import { byondMessages } from './timers'; import { dragStartHandler } from 'tgui/drag'; @@ -221,7 +221,7 @@ export class TguiSay extends Component<{}, State> { this.setValue(typed.slice(3)); } - handleKeyDown(event) { + handleKeyDown(event: InfernoKeyboardEvent) { switch (event.key) { case KEY.Up: case KEY.Down: @@ -310,11 +310,13 @@ export class TguiSay extends Component<{}, State> { this.channelIterator.current(); return ( -
+
-
+
-
+
diff --git a/tgui/packages/tgui/interfaces/Changelog.jsx b/tgui/packages/tgui/interfaces/Changelog.jsx index 3ac6205fd03..a3e84ad8ea9 100644 --- a/tgui/packages/tgui/interfaces/Changelog.jsx +++ b/tgui/packages/tgui/interfaces/Changelog.jsx @@ -1,6 +1,6 @@ import { classes } from 'common/react'; import { useBackend } from '../backend'; -import { Component, Fragment } from 'react'; +import { Component, Fragment } from 'inferno'; import { Box, Button, Dropdown, Icon, Section, Stack, Table } from '../components'; import { Window } from '../layouts'; import { resolveAsset } from '../assets'; @@ -35,8 +35,8 @@ const icons = { }; export class Changelog extends Component { - constructor(props) { - super(props); + constructor() { + super(); this.state = { data: 'Loading changelog data...', selectedDate: '', diff --git a/tgui/packages/tgui/interfaces/ChemFilter.tsx b/tgui/packages/tgui/interfaces/ChemFilter.tsx index fc3774ee5bb..9a7cfe5f30e 100644 --- a/tgui/packages/tgui/interfaces/ChemFilter.tsx +++ b/tgui/packages/tgui/interfaces/ChemFilter.tsx @@ -1,4 +1,4 @@ -import { Fragment } from 'react'; +import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Button, Section, Stack } from '../components'; import { Window } from '../layouts'; diff --git a/tgui/packages/tgui/interfaces/ChemMaster.tsx b/tgui/packages/tgui/interfaces/ChemMaster.tsx index 441a411d60b..6b911c77ee7 100644 --- a/tgui/packages/tgui/interfaces/ChemMaster.tsx +++ b/tgui/packages/tgui/interfaces/ChemMaster.tsx @@ -249,7 +249,7 @@ const ChemMasterContent = (props) => { {`Printing ${printingProgress} out of ${printingTotal}`} @@ -366,7 +366,7 @@ const ContainerButton = ({ container, category }) => { @@ -405,7 +405,7 @@ const AnalysisResults = (props) => { {purityLevel} @@ -440,7 +440,7 @@ const GroupTitle = ({ title }) => { {title} diff --git a/tgui/packages/tgui/interfaces/ChemSeparator.tsx b/tgui/packages/tgui/interfaces/ChemSeparator.tsx index de91668cc8e..bf6130d710e 100644 --- a/tgui/packages/tgui/interfaces/ChemSeparator.tsx +++ b/tgui/packages/tgui/interfaces/ChemSeparator.tsx @@ -78,7 +78,7 @@ export const ChemSeparator = (props) => { {`${Math.ceil(data.own_total_volume)} of ${ data.own_maximum_volume @@ -125,7 +125,7 @@ export const ChemSeparator = (props) => { {`${Math.ceil(data.beaker_total_volume)} of ${ data.beaker_maximum_volume diff --git a/tgui/packages/tgui/interfaces/CircuitAdminPanel.tsx b/tgui/packages/tgui/interfaces/CircuitAdminPanel.tsx index 02acc8ec135..0687f0d4de0 100644 --- a/tgui/packages/tgui/interfaces/CircuitAdminPanel.tsx +++ b/tgui/packages/tgui/interfaces/CircuitAdminPanel.tsx @@ -16,7 +16,7 @@ export const CircuitAdminPanel = (props) => { const { act, data } = useBackend(); return ( - + diff --git a/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx b/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx index 3a756209e3e..d2d53e09c60 100644 --- a/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx +++ b/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx @@ -1,4 +1,4 @@ -import { Component } from 'react'; +import { Component } from 'inferno'; import { useBackend } from '../backend'; import { Box, Stack, Section, Input, Button, Dropdown } from '../components'; import { Window } from '../layouts'; diff --git a/tgui/packages/tgui/interfaces/ClockworkResearch.tsx b/tgui/packages/tgui/interfaces/ClockworkResearch.tsx index 80a18280224..4edd1a6c4a5 100644 --- a/tgui/packages/tgui/interfaces/ClockworkResearch.tsx +++ b/tgui/packages/tgui/interfaces/ClockworkResearch.tsx @@ -52,7 +52,7 @@ const SelectedSection = (props) => { const { act, data } = useBackend(); return ( -
+
{'Selected Research'} @@ -61,7 +61,7 @@ const SelectedSection = (props) => { {data.focused_research.name} {data.focused_research.desc} -
+
{data.focused_research.lore} @@ -103,7 +103,7 @@ const ResearchSection = (props) => {
-
+
{ResearchNode(data.starting_research, act)}
@@ -115,7 +115,7 @@ const ResearchSection = (props) => { {inside_array.map((single_research: Research) => (
-
+
{ResearchNode(single_research, act)}
@@ -141,7 +141,7 @@ const ResearchNode = (research: Research, act: any) => { />
-
{research.desc}
+
{research.desc}

diff --git a/tgui/packages/tgui/interfaces/ClockworkSlab.jsx b/tgui/packages/tgui/interfaces/ClockworkSlab.jsx index 16f1d04aeca..144ed917f2c 100644 --- a/tgui/packages/tgui/interfaces/ClockworkSlab.jsx +++ b/tgui/packages/tgui/interfaces/ClockworkSlab.jsx @@ -1,5 +1,5 @@ // THIS IS A SKYRAT UI FILE -import { Fragment } from 'react'; +import { Fragment } from 'inferno'; import { useBackend, useLocalState } from '../backend'; import { Icon, Box, Button, Section, Table, Divider, Grid, ProgressBar, Collapsible } from '../components'; import { Window } from '../layouts'; @@ -66,7 +66,7 @@ export const ClockworkSlab = (props) => { const ClockworkHelp = (props) => { return ( - <> +
After a long and destructive war, Rat'Var has been imprisoned @@ -195,7 +195,7 @@ const ClockworkHelp = (props) => {
- +
); }; diff --git a/tgui/packages/tgui/interfaces/CrewConsole.jsx b/tgui/packages/tgui/interfaces/CrewConsole.jsx index bacb91c383c..a7e5fb45c43 100644 --- a/tgui/packages/tgui/interfaces/CrewConsole.jsx +++ b/tgui/packages/tgui/interfaces/CrewConsole.jsx @@ -125,7 +125,7 @@ const CrewTableEntry = (props) => { } = sensor_data; return ( - + {name} {assignment !== undefined ? ` (${assignment})` : ''} diff --git a/tgui/packages/tgui/interfaces/DepartmentOrders.tsx b/tgui/packages/tgui/interfaces/DepartmentOrders.tsx index 76447fd7eda..d17d7971861 100644 --- a/tgui/packages/tgui/interfaces/DepartmentOrders.tsx +++ b/tgui/packages/tgui/interfaces/DepartmentOrders.tsx @@ -116,7 +116,7 @@ const DepartmentCatalog = (props) => { {supplies.map((cat) => ( setTabCategory(cat)}> {cat.name} @@ -135,7 +135,8 @@ const DepartmentCatalog = (props) => { {pack.name} diff --git a/tgui/packages/tgui/interfaces/DestructiveAnalyzer.tsx b/tgui/packages/tgui/interfaces/DestructiveAnalyzer.tsx index 6fe0b16fdd3..3561058d79f 100644 --- a/tgui/packages/tgui/interfaces/DestructiveAnalyzer.tsx +++ b/tgui/packages/tgui/interfaces/DestructiveAnalyzer.tsx @@ -56,7 +56,12 @@ export const DestructiveAnalyzer = (props) => { ); } return ( - +
{ height="64px" width="64px" style={{ - verticalAlign: 'middle', + '-ms-interpolation-mode': 'nearest-neighbor', + 'vertical-align': 'middle', }} />
diff --git a/tgui/packages/tgui/interfaces/DnaConsole/DnaConsoleSequencer.jsx b/tgui/packages/tgui/interfaces/DnaConsole/DnaConsoleSequencer.jsx index 7fb1445b1c9..512613b256c 100644 --- a/tgui/packages/tgui/interfaces/DnaConsole/DnaConsoleSequencer.jsx +++ b/tgui/packages/tgui/interfaces/DnaConsole/DnaConsoleSequencer.jsx @@ -18,7 +18,7 @@ const GenomeImage = (props) => { style={{ width: '64px', margin: '2px', - marginLeft: '4px', + 'margin-left': '4px', outline, }} onClick={onClick} diff --git a/tgui/packages/tgui/interfaces/Electrolyzer.tsx b/tgui/packages/tgui/interfaces/Electrolyzer.tsx index 3f2365bd5b5..34b457803d6 100644 --- a/tgui/packages/tgui/interfaces/Electrolyzer.tsx +++ b/tgui/packages/tgui/interfaces/Electrolyzer.tsx @@ -38,10 +38,11 @@ export const Electrolyzer = (props) => { }> - + {(hasPowercell && ( { diff --git a/tgui/packages/tgui/interfaces/Mecha/index.tsx b/tgui/packages/tgui/interfaces/Mecha/index.tsx index f243083fe63..2c17ff5a91c 100644 --- a/tgui/packages/tgui/interfaces/Mecha/index.tsx +++ b/tgui/packages/tgui/interfaces/Mecha/index.tsx @@ -148,7 +148,7 @@ const PowerBar = (props) => { bad: [-Infinity, 0.25], }} style={{ - textShadow: '1px 1px 0 black', + 'text-shadow': '1px 1px 0 black', }}> {power_max === null ? 'Power cell missing' @@ -177,7 +177,7 @@ const IntegrityBar = (props) => { bad: [-Infinity, 0.25], }} style={{ - textShadow: '1px 1px 0 black', + 'text-shadow': '1px 1px 0 black', }}> {!scanmod_rating ? 'Unknown' : `${integrity} of ${integrity_max}`} diff --git a/tgui/packages/tgui/interfaces/MemoryPanel.jsx b/tgui/packages/tgui/interfaces/MemoryPanel.jsx index dd57a659c06..ac39ecca607 100644 --- a/tgui/packages/tgui/interfaces/MemoryPanel.jsx +++ b/tgui/packages/tgui/interfaces/MemoryPanel.jsx @@ -59,7 +59,7 @@ const MemoryQuality = (props) => {
diff --git a/tgui/packages/tgui/interfaces/NtosPortraitPrinter.jsx b/tgui/packages/tgui/interfaces/NtosPortraitPrinter.jsx index 0042d05eb68..fa67d921804 100644 --- a/tgui/packages/tgui/interfaces/NtosPortraitPrinter.jsx +++ b/tgui/packages/tgui/interfaces/NtosPortraitPrinter.jsx @@ -1,6 +1,6 @@ import { resolveAsset } from '../assets'; import { useBackend, useLocalState } from '../backend'; -import { Box, Button, NoticeBox, Section, Stack, Input } from '../components'; +import { Button, NoticeBox, Section, Stack, Input } from '../components'; import { NtosWindow } from '../layouts'; export const NtosPortraitPrinter = (props) => { @@ -52,13 +52,13 @@ export const NtosPortraitPrinter = (props) => { {got_paintings ? ( <> - diff --git a/tgui/packages/tgui/interfaces/NtosRadar.tsx b/tgui/packages/tgui/interfaces/NtosRadar.tsx index f94e0389712..ab16bf63330 100644 --- a/tgui/packages/tgui/interfaces/NtosRadar.tsx +++ b/tgui/packages/tgui/interfaces/NtosRadar.tsx @@ -43,11 +43,11 @@ export const NtosRadarContent = (props) => { { top="20px" left="243px" style={{ - transform: `rotate(${target.rot}deg)`, + 'transform': `rotate(${target.rot}deg)`, }} /> ) : ( diff --git a/tgui/packages/tgui/interfaces/OreContainer.tsx b/tgui/packages/tgui/interfaces/OreContainer.tsx index 5f7db63a838..3c79971390c 100644 --- a/tgui/packages/tgui/interfaces/OreContainer.tsx +++ b/tgui/packages/tgui/interfaces/OreContainer.tsx @@ -103,7 +103,8 @@ const RetrieveIcon = (props) => { height="64px" width="64px" style={{ - verticalAlign: 'middle', + '-ms-interpolation-mode': 'nearest-neighbor', + 'vertical-align': 'middle', }} /> ); diff --git a/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx b/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx index e3eb91cc6ed..ed50b922775 100644 --- a/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx +++ b/tgui/packages/tgui/interfaces/OreRedemptionMachine.jsx @@ -181,7 +181,8 @@ const MaterialRow = (props) => { height="18px" width="18px" style={{ - verticalAlign: 'middle', + '-ms-interpolation-mode': 'nearest-neighbor', + 'vertical-align': 'middle', }} /> diff --git a/tgui/packages/tgui/interfaces/OutfitEditor.jsx b/tgui/packages/tgui/interfaces/OutfitEditor.jsx index ae2b0825486..b4373e591e2 100644 --- a/tgui/packages/tgui/interfaces/OutfitEditor.jsx +++ b/tgui/packages/tgui/interfaces/OutfitEditor.jsx @@ -16,6 +16,9 @@ export const OutfitEditor = (props) => { opacity={0.5} py={3} src={`data:image/jpeg;base64,${dummy64}`} + style={{ + '-ms-interpolation-mode': 'nearest-neighbor', + }} />
{ grow={1} style={{ 'overflow': 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', + 'white-space': 'nowrap', + 'text-overflow': 'ellipsis', }}> diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx index cf96adcc6ba..b5ea05dd600 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx @@ -1,7 +1,7 @@ import { sortBy, sortStrings } from 'common/collections'; import { BooleanLike, classes } from 'common/react'; -import { ComponentType, createElement, ReactNode } from 'react'; - +import { ComponentType, createComponentVNode, InfernoNode } from 'inferno'; +import { VNodeFlags } from 'inferno-vnode-flags'; import { sendAct, useBackend, useLocalState } from '../../../../backend'; // SKYRAT EDIT - adds TextArea to imports import { Box, Button, Dropdown, Input, NumberInput, Slider, Stack, TextArea } from '../../../../components'; @@ -9,7 +9,7 @@ import { Box, Button, Dropdown, Input, NumberInput, Slider, Stack, TextArea } fr import { createSetPreference, PreferencesMenuData } from '../../data'; import { ServerPreferencesFetcher } from '../../ServerPreferencesFetcher'; -export const sortChoices = sortBy<[string, ReactNode]>(([name]) => name); +export const sortChoices = sortBy<[string, InfernoNode]>(([name]) => name); export type Feature< TReceiving, @@ -63,12 +63,12 @@ export const FeatureColorInput = (props: FeatureValueProps) => { ? props.value : `#${props.value}`, border: '2px solid white', - boxSizing: 'content-box', + 'box-sizing': 'content-box', height: '11px', width: '11px', ...(props.shrink ? { - margin: '1px', + 'margin': '1px', } : {}), }} @@ -111,7 +111,7 @@ export const CheckboxInputInverse = ( export const createDropdownInput = ( // Map of value to display texts - choices: Record, + choices: Record, dropdownProps?: Record ): FeatureValue => { return (props: FeatureValueProps) => { @@ -152,7 +152,7 @@ const capitalizeFirstLetter = (text: string) => export const StandardizedDropdown = (props: { choices: string[]; disabled?: boolean; - displayNames: Record; + displayNames: Record; onSetValue: (newValue: string) => void; value: string; buttons?: boolean; @@ -242,7 +242,7 @@ export const FeatureIconnedDropdownInput = ( const displayNames = Object.fromEntries( Object.entries(textNames).map(([choice, textName]) => { - let element: ReactNode = textName; + let element: InfernoNode = textName; if (icons && icons[choice]) { const icon = icons[choice]; @@ -252,7 +252,7 @@ export const FeatureIconnedDropdownInput = ( @@ -350,15 +350,19 @@ export const FeatureValueInput = (props: { return ( { - return createElement(feature.component, { - act: props.act, - featureId: props.featureId, - serverData: serverData?.[props.featureId] as any, - shrink: props.shrink, - - handleSetValue: changeValue, - value: predictedValue, - }); + return createComponentVNode( + VNodeFlags.ComponentUnknown, + feature.component, + { + act: props.act, + featureId: props.featureId, + serverData: serverData && serverData[props.featureId], + shrink: props.shrink, + + handleSetValue: changeValue, + value: predictedValue, + } + ); }} /> ); diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx index 544070d0468..68be3a01c5a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx @@ -41,9 +41,9 @@ export const skin_tone: Feature = { diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx index 8ee50d9ab18..a3ccca9c796 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx @@ -2,7 +2,7 @@ import { multiline } from 'common/string'; import { CheckboxInput, FeatureChoiced, FeatureChoicedServerData, FeatureDropdownInput, FeatureToggle, FeatureValueProps } from '../base'; import { Box, Dropdown, Flex } from '../../../../../components'; import { classes } from 'common/react'; -import { ReactNode } from 'react'; +import { InfernoNode } from 'inferno'; import { binaryInsertWith } from 'common/collections'; import { useBackend } from '../../../../../backend'; import { PreferencesMenuData } from '../../../data'; @@ -15,7 +15,7 @@ export const ghost_accs: FeatureChoiced = { }; const insertGhostForm = binaryInsertWith<{ - displayText: ReactNode; + displayText: InfernoNode; value: string; }>(({ value }) => value); @@ -26,7 +26,7 @@ const GhostFormInput = ( const serverData = props.serverData; if (!serverData) { - return <> ; + return; } const displayNames = serverData.display_names; @@ -36,7 +36,7 @@ const GhostFormInput = ( const displayTexts = {}; let options: { - displayText: ReactNode; + displayText: InfernoNode; value: string; }[] = []; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx index c13a004f74f..df33e4c4c94 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx @@ -25,7 +25,7 @@ const UIStyleInput = ( diff --git a/tgui/packages/tgui/interfaces/ProduceConsole.tsx b/tgui/packages/tgui/interfaces/ProduceConsole.tsx index 83de80805e8..19ab62dc30c 100644 --- a/tgui/packages/tgui/interfaces/ProduceConsole.tsx +++ b/tgui/packages/tgui/interfaces/ProduceConsole.tsx @@ -110,7 +110,7 @@ const ShoppingTab = (props) => { {' '} {!condensed && ( @@ -121,7 +121,8 @@ const ShoppingTab = (props) => { height="34px" width="34px" style={{ - verticalAlign: 'middle', + '-ms-interpolation-mode': 'nearest-neighbor', + 'vertical-align': 'middle', }} /> diff --git a/tgui/packages/tgui/interfaces/Puzzgrid.tsx b/tgui/packages/tgui/interfaces/Puzzgrid.tsx index 0eb005876e1..df9c442cfa9 100644 --- a/tgui/packages/tgui/interfaces/Puzzgrid.tsx +++ b/tgui/packages/tgui/interfaces/Puzzgrid.tsx @@ -1,7 +1,6 @@ import { range } from 'common/collections'; import { BooleanLike } from 'common/react'; -import { PropsWithChildren } from 'react'; - +import { SFC } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, FitText, Stack } from '../components'; import { Window } from '../layouts'; @@ -24,12 +23,10 @@ type PuzzgridData = { wrong_group_select_cooldown: BooleanLike; }; -const PuzzgridButton = ( - props: { - // In the future, this would be the TypeScript props of the button - [key: string]: unknown; - } & PropsWithChildren -) => { +const PuzzgridButton: SFC<{ + // In the future, this would be the TypeScript props of the button + [key: string]: unknown; +}> = (props) => { return (
@@ -186,8 +189,8 @@ const CurrentlySelectedDisplay = (props) => { title={entry?.path} style={{ 'overflow': 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', + 'white-space': 'nowrap', + 'text-overflow': 'ellipsis', }}> {entry?.name} diff --git a/tgui/packages/tgui/interfaces/ServerControl.tsx b/tgui/packages/tgui/interfaces/ServerControl.tsx index 9e0c86d4715..1084d3f87ca 100644 --- a/tgui/packages/tgui/interfaces/ServerControl.tsx +++ b/tgui/packages/tgui/interfaces/ServerControl.tsx @@ -46,7 +46,7 @@ export const ServerControl = (props) => { ); } return ( - + {!servers ? ( diff --git a/tgui/packages/tgui/interfaces/Spellbook.tsx b/tgui/packages/tgui/interfaces/Spellbook.tsx index 38ca9b47355..f16a5aeee6d 100644 --- a/tgui/packages/tgui/interfaces/Spellbook.tsx +++ b/tgui/packages/tgui/interfaces/Spellbook.tsx @@ -3,7 +3,7 @@ import { multiline } from 'common/string'; import { useBackend, useLocalState } from '../backend'; import { Box, Button, Dimmer, Divider, Icon, Input, NoticeBox, ProgressBar, Section, Stack } from '../components'; import { Window } from '../layouts'; -import { ReactNode } from 'react'; +import { InfernoNode } from 'inferno'; enum SpellCategory { Offensive = 'Offensive', @@ -49,7 +49,7 @@ type Data = { type TabType = { title: string; blurb?: string; - component?: () => ReactNode; + component?: () => InfernoNode; locked?: boolean; scrollable?: boolean; }; diff --git a/tgui/packages/tgui/interfaces/StackingConsole.jsx b/tgui/packages/tgui/interfaces/StackingConsole.jsx index c147038adfc..296ea072161 100644 --- a/tgui/packages/tgui/interfaces/StackingConsole.jsx +++ b/tgui/packages/tgui/interfaces/StackingConsole.jsx @@ -46,7 +46,9 @@ export const StackingConsoleContent = (props) => { } /> }> - {input_direction} + + {input_direction} + { } /> }> - + {output_direction} diff --git a/tgui/packages/tgui/interfaces/StripMenu.tsx b/tgui/packages/tgui/interfaces/StripMenu.tsx index f193a29feac..40616e7d965 100644 --- a/tgui/packages/tgui/interfaces/StripMenu.tsx +++ b/tgui/packages/tgui/interfaces/StripMenu.tsx @@ -27,8 +27,8 @@ const CornerText = (props: { style={{ position: 'relative', left: align === 'left' ? '2px' : '-2px', - textAlign: align, - textShadow: '1px 1px 1px #555', + 'text-align': align, + 'text-shadow': '1px 1px 1px #555', }}> {children} @@ -324,7 +324,8 @@ export const StripMenu = (props) => { height="100%" width="100%" style={{ - verticalAlign: 'middle', + '-ms-interpolation-mode': 'nearest-neighbor', + 'vertical-align': 'middle', }} /> ); @@ -342,7 +343,7 @@ export const StripMenu = (props) => { ml={0} mt={1.3} style={{ - textAlign: 'center', + 'text-align': 'center', height: '100%', width: '100%', }} @@ -409,7 +410,7 @@ export const StripMenu = (props) => { position: 'absolute', bottom: 0, right: 0, - zIndex: 2, + 'z-index': 2, }}> diff --git a/tgui/packages/tgui/interfaces/Supermatter.tsx b/tgui/packages/tgui/interfaces/Supermatter.tsx index 9f3c46b6061..052dff046b4 100644 --- a/tgui/packages/tgui/interfaces/Supermatter.tsx +++ b/tgui/packages/tgui/interfaces/Supermatter.tsx @@ -2,7 +2,7 @@ import { filter, sortBy } from 'common/collections'; import { flow } from 'common/fp'; import { toFixed } from 'common/math'; import { BooleanLike } from 'common/react'; -import { ReactNode } from 'react'; +import { InfernoNode } from 'inferno'; import { useBackend, useLocalState } from '../backend'; import { Box, Button, LabeledList, ProgressBar, Section, Stack } from '../components'; import { getGasFromPath } from '../constants'; @@ -23,7 +23,7 @@ type SMGasMetadata = { }; type SupermatterProps = { - sectionButton?: ReactNode; + sectionButton?: InfernoNode; uid: number; area_name: string; integrity: number; @@ -50,8 +50,8 @@ type SupermatterProps = { // LabeledList but stack and with a chevron dropdown. type SupermatterEntryProps = { title: string; - content: ReactNode; - detail?: ReactNode; + content: InfernoNode; + detail?: InfernoNode; alwaysShowChevron?: boolean; }; const SupermatterEntry = (props: SupermatterEntryProps) => { diff --git a/tgui/packages/tgui/interfaces/SurgeryInitiator.tsx b/tgui/packages/tgui/interfaces/SurgeryInitiator.tsx index aed55ae8080..8be56e3728a 100644 --- a/tgui/packages/tgui/interfaces/SurgeryInitiator.tsx +++ b/tgui/packages/tgui/interfaces/SurgeryInitiator.tsx @@ -1,7 +1,7 @@ import { sortBy } from 'common/collections'; import { KEY_DOWN, KEY_ENTER, KEY_UP } from 'common/keycodes'; import { BooleanLike } from 'common/react'; -import { Component } from 'react'; +import { Component } from 'inferno'; import { useBackend } from '../backend'; import { Button, KeyListener, Stack } from '../components'; import { BodyZone, BodyZoneSelector } from '../components/BodyZoneSelector'; diff --git a/tgui/packages/tgui/interfaces/SyndContractor.jsx b/tgui/packages/tgui/interfaces/SyndContractor.jsx index fff904c758b..bb7f9887f75 100644 --- a/tgui/packages/tgui/interfaces/SyndContractor.jsx +++ b/tgui/packages/tgui/interfaces/SyndContractor.jsx @@ -1,4 +1,4 @@ -import { Component, Fragment } from 'react'; +import { Component, Fragment } from 'inferno'; import { useBackend, useLocalState } from '../backend'; import { Box, Button, Flex, Grid, Icon, LabeledList, Modal, NoticeBox, Section, Table, Tabs } from '../components'; import { NtosWindow } from '../layouts'; @@ -227,17 +227,17 @@ export const StatusPane = (props) => { onClick={() => act('PRG_redeem_TC')} /> }> - {String(redeemable_tc)} + {data.redeemable_tc} - {String(earned_tc)} + {data.earned_tc} - {String(contracts_completed)} + {data.contracts_completed} ACTIVE @@ -303,7 +303,7 @@ const ContractsTab = (props) => { buttons={ <> - {`${contract.payout} (+${contract.payout_bonus}) TC`} + {contract.payout} (+{contract.payout_bonus}) TC
) : ( diff --git a/tgui/packages/tgui/interfaces/Uplink/ObjectiveMenu.tsx b/tgui/packages/tgui/interfaces/Uplink/ObjectiveMenu.tsx index a1f8e746336..bec7c918a48 100644 --- a/tgui/packages/tgui/interfaces/Uplink/ObjectiveMenu.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/ObjectiveMenu.tsx @@ -1,5 +1,5 @@ import { BooleanLike, classes } from 'common/react'; -import { Component } from 'react'; +import { Component } from 'inferno'; import { Section, Stack, Box, Button, Flex, Tooltip, NoticeBox, Dimmer, Icon } from '../../components'; import { calculateProgression, getDangerLevel, Rank } from './calculateDangerLevel'; import { ObjectiveState } from './constants'; @@ -50,8 +50,8 @@ export class ObjectiveMenu extends Component< ObjectiveMenuProps, ObjectiveMenuState > { - constructor(props) { - super(props); + constructor() { + super(); this.state = { draggingObjective: null, objectiveX: 0, @@ -206,7 +206,7 @@ export class ObjectiveMenu extends Component< )) || ( )) || (potentialObjectives.length < maximumPotentialObjectives && ( - + {ObjectiveFunction(draggingObjective, false)} @@ -437,10 +446,10 @@ export const ObjectiveElement = (props: ObjectiveElementProps) => { { inline className={dangerLevel.gradient} style={{ - borderRadius: '0', - border: '2px solid rgba(0, 0, 0, 0.5)', - borderLeft: 'none', - borderRight: 'none', + 'border-radius': '0', + 'border': '2px solid rgba(0, 0, 0, 0.5)', + 'border-left': 'none', + 'border-right': 'none', }} position="relative" width="100%" @@ -522,7 +531,7 @@ export const ObjectiveElement = (props: ObjectiveElementProps) => { onClick={handleCompletion} color={objectiveFailed ? 'bad' : 'good'} style={{ - border: '1px solid rgba(0, 0, 0, 0.65)', + 'border': '1px solid rgba(0, 0, 0, 0.65)', }} my={1}> TURN IN diff --git a/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx b/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx index 88c32aa22e6..f2dc9bdd037 100644 --- a/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/calculateDangerLevel.tsx @@ -90,8 +90,8 @@ export const dangerLevelsTooltip = ( color="white" className={value.gradient} style={{ - borderRadius: '5px', - display: 'inline-block', + 'border-radius': '5px', + 'display': 'inline-block', }} px={0.8} py={0.6}> @@ -136,8 +136,8 @@ export const calculateDangerLevel = ( color="white" className={dangerLevel.gradient} style={{ - borderRadius: '5px', - display: 'inline-block', + 'border-radius': '5px', + 'display': 'inline-block', }} px={0.8} py={0.6}> diff --git a/tgui/packages/tgui/interfaces/Uplink/index.tsx b/tgui/packages/tgui/interfaces/Uplink/index.tsx index 1ad17f8a084..6753b1a232e 100644 --- a/tgui/packages/tgui/interfaces/Uplink/index.tsx +++ b/tgui/packages/tgui/interfaces/Uplink/index.tsx @@ -1,7 +1,7 @@ import { useBackend } from '../../backend'; import { Window } from '../../layouts'; import { GenericUplink, Item } from './GenericUplink'; -import { Component, Fragment } from 'react'; +import { Component, Fragment } from 'inferno'; import { fetchRetry } from '../../http'; import { resolveAsset } from '../../assets'; import { BooleanLike } from 'common/react'; @@ -81,8 +81,8 @@ type ItemExtraData = { let fetchServerData: Promise | undefined; export class Uplink extends Component<{}, UplinkState> { - constructor(props) { - super(props); + constructor() { + super(); this.state = { allItems: [], allCategories: [], @@ -346,7 +346,7 @@ export class Uplink extends Component<{}, UplinkState> { {!!has_objectives && ( - <> + this.setState({ currentTab: 0 })}> @@ -357,7 +357,7 @@ export class Uplink extends Component<{}, UplinkState> { onClick={() => this.setState({ currentTab: 1 })}> Secondary Objectives - + )} { height="96px" width="96px" style={{ - verticalAlign: 'middle', + '-ms-interpolation-mode': 'nearest-neighbor', + 'vertical-align': 'middle', }} />
diff --git a/tgui/packages/tgui/interfaces/Vending.tsx b/tgui/packages/tgui/interfaces/Vending.tsx index ca7f4981b7f..ceb429cb100 100644 --- a/tgui/packages/tgui/interfaces/Vending.tsx +++ b/tgui/packages/tgui/interfaces/Vending.tsx @@ -275,14 +275,16 @@ const ProductImage = (props) => { ) : ( ); diff --git a/tgui/packages/tgui/interfaces/VotePanel.tsx b/tgui/packages/tgui/interfaces/VotePanel.tsx index 0d080b47f57..fe8e2bf9c93 100644 --- a/tgui/packages/tgui/interfaces/VotePanel.tsx +++ b/tgui/packages/tgui/interfaces/VotePanel.tsx @@ -67,7 +67,7 @@ export const VotePanel = (props) => { } return ( - +
diff --git a/tgui/packages/tgui/interfaces/common/AtmosHandbook.tsx b/tgui/packages/tgui/interfaces/common/AtmosHandbook.tsx index 378227b326f..c221769668c 100644 --- a/tgui/packages/tgui/interfaces/common/AtmosHandbook.tsx +++ b/tgui/packages/tgui/interfaces/common/AtmosHandbook.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { InfernoNode } from 'inferno'; import { useBackend, useLocalState } from '../../backend'; import { Box, Button, Flex, Input, LabeledList, Section, Stack, Tooltip } from '../../components'; @@ -37,7 +37,7 @@ type Gas = { }; const GasSearchBar = (props: { - title: ReactNode; + title: InfernoNode; onChange: (inputValue: string) => void; activeInput: boolean; setActiveInput: (toggle: boolean) => void; @@ -170,7 +170,7 @@ const ReactionHandbook = (props) => { {factor.factor_name + ':'} diff --git a/tgui/packages/tgui/interfaces/common/Connections.tsx b/tgui/packages/tgui/interfaces/common/Connections.tsx index 853008a8bb1..1595c52b210 100644 --- a/tgui/packages/tgui/interfaces/common/Connections.tsx +++ b/tgui/packages/tgui/interfaces/common/Connections.tsx @@ -45,8 +45,8 @@ export const Connections = (props: { height="100%" style={{ 'position': 'absolute', - pointerEvents: 'none', - zIndex: zLayer, + 'pointer-events': 'none', + 'z-index': zLayer, }}> {connections.map((val, index) => { const from = val.from; diff --git a/tgui/packages/tgui/interfaces/common/EditableText.tsx b/tgui/packages/tgui/interfaces/common/EditableText.tsx index ee12e453cc4..9bcfbf61578 100644 --- a/tgui/packages/tgui/interfaces/common/EditableText.tsx +++ b/tgui/packages/tgui/interfaces/common/EditableText.tsx @@ -49,10 +49,10 @@ export const EditableText = (props: Props) => { as="span" color={!text ? 'grey' : color || 'white'} style={{ - textDecoration: 'underline', - textDecorationColor: 'white', - textDecorationThickness: '1px', - textUnderlineOffset: '1px', + 'text-decoration': 'underline', + 'text-decoration-color': 'white', + 'text-decoration-thickness': '1px', + 'text-underline-offset': '1px', }} onClick={() => setEditing(true)}> {!text ? '(none)' : text} diff --git a/tgui/packages/tgui/interfaces/common/Objectives.tsx b/tgui/packages/tgui/interfaces/common/Objectives.tsx index 73fbfe2ccf2..d96c6bce5d4 100644 --- a/tgui/packages/tgui/interfaces/common/Objectives.tsx +++ b/tgui/packages/tgui/interfaces/common/Objectives.tsx @@ -1,5 +1,5 @@ import { BooleanLike } from 'common/react'; -import { ReactNode } from 'react'; +import { InfernoNode } from 'inferno'; import { useBackend } from '../../backend'; import { Button, Stack } from '../../components'; @@ -18,7 +18,7 @@ type ObjectivePrintoutProps = { // For passing onto the Stack component fill?: boolean; // Allows additional components to follow the printout in the same stack - objectiveFollowup?: ReactNode; + objectiveFollowup?: InfernoNode; // The prefix to use for each objective, defaults to "#" (#1, #2) objectivePrefix?: string; // The font size to use for each objective diff --git a/tgui/packages/tgui/interfaces/common/RecipeLookup.jsx b/tgui/packages/tgui/interfaces/common/RecipeLookup.jsx index fb26f4c474b..53ae3e435fa 100644 --- a/tgui/packages/tgui/interfaces/common/RecipeLookup.jsx +++ b/tgui/packages/tgui/interfaces/common/RecipeLookup.jsx @@ -176,7 +176,7 @@ export const RecipeLookup = (props) => { height="50px" position="relative" style={{ - backgroundColor: 'black', + 'background-color': 'black', }}> + { + logger.log('pressed close'); + dispatch(backendSuspendStart()); + }} + canClose={canClose}> + {buttons} + +
+ {!suspended && children} + {showDimmer &&
} +
+ {fancy && ( + <> +
+
+
+ + )} + + ); + } +} + +const WindowContent = (props) => { + const { className, fitted, children, ...rest } = props; + return ( + + {(fitted && children) || ( +
{children}
+ )} +
+ ); +}; + +Window.Content = WindowContent; + +const statusToColor = (status) => { + switch (status) { + case UI_INTERACTIVE: + return 'good'; + case UI_UPDATE: + return 'average'; + case UI_DISABLED: + default: + return 'bad'; + } +}; + +const TitleBar = (props) => { + const { + className, + title, + status, + canClose, + fancy, + onDragStart, + onClose, + children, + } = props; + const dispatch = globalStore.dispatch; + // prettier-ignore + const finalTitle = ( + typeof title === 'string' + && title === title.toLowerCase() + && toTitleCase(title) + || title + ); + return ( +
+ {(status === undefined && ( + + )) || ( + + )} +
fancy && onDragStart(e)} + /> +
+ {finalTitle} + {!!children &&
{children}
} +
+ {process.env.NODE_ENV !== 'production' && ( +
dispatch(toggleKitchenSink())}> + +
+ )} + {Boolean(fancy && canClose) && ( +
+ {Byond.IS_LTE_IE8 ? 'x' : '×'} +
+ )} +
+ ); +}; diff --git a/tgui/packages/tgui/layouts/Window.tsx b/tgui/packages/tgui/layouts/Window.tsx deleted file mode 100644 index 658c21bff54..00000000000 --- a/tgui/packages/tgui/layouts/Window.tsx +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file - * @copyright 2020 Aleksej Komarov - * @license MIT - */ - -import { classes } from 'common/react'; -import { decodeHtmlEntities, toTitleCase } from 'common/string'; -import { backendSuspendStart, useBackend } from '../backend'; -import { Icon } from '../components'; -import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants'; -import { toggleKitchenSink } from '../debug/actions'; -import { dragStartHandler, recallWindowGeometry, resizeStartHandler, setWindowKey } from '../drag'; -import { createLogger } from '../logging'; -import { Layout } from './Layout'; -import { globalStore } from '../backend'; -import { PropsWithChildren, ReactNode, useEffect } from 'react'; -import { BoxProps } from '../components/Box'; - -const logger = createLogger('Window'); - -const DEFAULT_SIZE: [number, number] = [400, 600]; - -type Props = Partial<{ - buttons: ReactNode; - canClose: boolean; - height: number; - theme: string; - title: string; - width: number; -}> & - PropsWithChildren; - -export const Window = (props: Props) => { - const { - canClose = true, - theme, - title, - children, - buttons, - width, - height, - } = props; - - const { config, suspended, debug } = useBackend(); - if (suspended) { - return null; - } - - useEffect(() => { - const updateGeometry = () => { - const options = { - ...config.window, - size: DEFAULT_SIZE, - }; - - if (width && height) { - options.size = [width, height]; - } - if (config.window?.key) { - setWindowKey(config.window.key); - } - recallWindowGeometry(options); - }; - - Byond.winset(Byond.windowId, { - 'can-close': Boolean(canClose), - }); - logger.log('mounting'); - updateGeometry(); - - return () => { - logger.log('unmounting'); - }; - }, [width, height]); - - let debugLayout = false; - if (debug) { - debugLayout = debug.debugLayout; - } - - const dispatch = globalStore.dispatch; - const fancy = config.window?.fancy; - - // Determine when to show dimmer - const showDimmer = - config.user && - (config.user.observer - ? config.status < UI_DISABLED - : config.status < UI_INTERACTIVE); - - return ( - - { - logger.log('pressed close'); - dispatch(backendSuspendStart()); - }} - canClose={canClose}> - {buttons} - -
- {!suspended && children} - {showDimmer &&
} -
- {fancy && ( - <> -
-
-
- - )} - - ); -}; - -type ContentProps = Partial<{ - className: string; - fitted: boolean; - scrollable: boolean; - vertical: boolean; -}> & - BoxProps & - PropsWithChildren; - -const WindowContent = (props: ContentProps) => { - const { className, fitted, children, ...rest } = props; - - return ( - - {(fitted && children) || ( -
{children}
- )} -
- ); -}; - -Window.Content = WindowContent; - -const statusToColor = (status) => { - switch (status) { - case UI_INTERACTIVE: - return 'good'; - case UI_UPDATE: - return 'average'; - case UI_DISABLED: - default: - return 'bad'; - } -}; - -type TitleBarProps = Partial<{ - canClose: boolean; - className: string; - fancy: boolean; - onClose: (e) => void; - onDragStart: (e) => void; - status: number; - title: string; -}> & - PropsWithChildren; - -const TitleBar = (props: TitleBarProps) => { - const { - className, - title, - status, - canClose, - fancy, - onDragStart, - onClose, - children, - } = props; - const dispatch = globalStore.dispatch; - - const finalTitle = - (typeof title === 'string' && - title === title.toLowerCase() && - toTitleCase(title)) || - title; - - return ( -
- {(status === undefined && ( - - )) || ( - - )} -
fancy && onDragStart && onDragStart(e)} - /> -
- {finalTitle} - {!!children &&
{children}
} -
- {process.env.NODE_ENV !== 'production' && ( -
dispatch(toggleKitchenSink())}> - -
- )} - {Boolean(fancy && canClose) && ( -
- × -
- )} -
- ); -}; diff --git a/tgui/packages/tgui/package.json b/tgui/packages/tgui/package.json index b59766c04b2..d7cdd701db4 100644 --- a/tgui/packages/tgui/package.json +++ b/tgui/packages/tgui/package.json @@ -1,20 +1,18 @@ { "private": true, "name": "tgui", - "version": "5.0.0", + "version": "4.4.0", "dependencies": { "@popperjs/core": "^2.11.8", "@types/marked": "^4.0.8", - "@types/react": "^18.2.39", - "@types/react-dom": "^18.2.17", "common": "workspace:*", "dateformat": "^4.6.2", "dompurify": "^2.4.4", "highlight.js": "^11.9.0", + "inferno": "^7.4.11", + "inferno-vnode-flags": "^7.4.11", "js-yaml": "^4.1.0", "marked": "^4.2.12", - "react": "^18.2.0", - "react-dom": "^18.2.0", "tgui-dev-server": "workspace:*", "tgui-polyfill": "workspace:*" } diff --git a/tgui/packages/tgui/renderer.ts b/tgui/packages/tgui/renderer.ts index 4478cedc761..1c7068f8be2 100644 --- a/tgui/packages/tgui/renderer.ts +++ b/tgui/packages/tgui/renderer.ts @@ -1,5 +1,5 @@ import { perf } from 'common/perf'; -import { render } from 'react-dom'; +import { render } from 'inferno'; import { createLogger } from './logging'; const logger = createLogger('renderer'); diff --git a/tgui/packages/tgui/store.ts b/tgui/packages/tgui/store.ts index 4b1455b9029..468298fe07c 100644 --- a/tgui/packages/tgui/store.ts +++ b/tgui/packages/tgui/store.ts @@ -8,6 +8,7 @@ import { Middleware, Reducer, Store, applyMiddleware, combineReducers, createSto import { backendMiddleware, backendReducer } from './backend'; import { debugMiddleware, debugReducer, relayMiddleware } from './debug'; +import { Component } from 'inferno'; import { assetMiddleware } from './assets'; import { createLogger } from './logging'; import { flow } from 'common/fp'; @@ -102,3 +103,17 @@ const createStackAugmentor = }) ); }; + +/** + * Store provider for Inferno apps. + */ +export class StoreProvider extends Component { + getChildContext() { + const { store } = this.props; + return { store }; + } + + render() { + return this.props.children; + } +} diff --git a/tgui/public/tgui-polyfill.min.js b/tgui/public/tgui-polyfill.min.js index fc7c7a51287..68c21147e6d 100644 --- a/tgui/public/tgui-polyfill.min.js +++ b/tgui/public/tgui-polyfill.min.js @@ -1 +1 @@ -(function(){"use strict";!function(){function t(){var e=Array.prototype.slice.call(arguments),n=document.createDocumentFragment();e.forEach((function(e){var t=e instanceof Node;n.appendChild(t?e:document.createTextNode(String(e)))})),this.appendChild(n)}function n(){this.parentNode&&this.parentNode.removeChild(this)}[Element.prototype,Document.prototype,DocumentFragment.prototype].forEach((function(e){e.hasOwnProperty("append")||Object.defineProperty(e,"append",{configurable:!0,enumerable:!0,writable:!0,value:t});e.hasOwnProperty("remove")||Object.defineProperty(e,"remove",{configurable:!0,enumerable:!0,writable:!0,value:n})}))}()})(); \ No newline at end of file +(function(){"use strict";if(!window.Int32Array){window.Int32Array=Array}!function(){function t(){var e=Array.prototype.slice.call(arguments),n=document.createDocumentFragment();e.forEach((function(e){var t=e instanceof Node;n.appendChild(t?e:document.createTextNode(String(e)))})),this.appendChild(n)}function n(){this.parentNode&&this.parentNode.removeChild(this)}[Element.prototype,Document.prototype,DocumentFragment.prototype].forEach((function(e){e.hasOwnProperty("append")||Object.defineProperty(e,"append",{configurable:!0,enumerable:!0,writable:!0,value:t});e.hasOwnProperty("remove")||Object.defineProperty(e,"remove",{configurable:!0,enumerable:!0,writable:!0,value:n})}))}()})(); \ No newline at end of file diff --git a/tgui/yarn.lock b/tgui/yarn.lock index 2b8978c9623..925234c1a72 100644 --- a/tgui/yarn.lock +++ b/tgui/yarn.lock @@ -68,7 +68,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.23.3": +"@babel/core@npm:*, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.23.3": version: 7.23.3 resolution: "@babel/core@npm:7.23.3" dependencies: @@ -595,6 +595,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^7": + version: 7.12.13 + resolution: "@babel/plugin-syntax-jsx@npm:7.12.13" + dependencies: + "@babel/helper-plugin-utils": ^7.12.13 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 30697ad4607a9339b06c2648c2d128ce6865c3d2d14049b422c5ca060d6532978bb1008e086df402d365fda04fbafe9bd4ad9f62d78ef2e7a7063459b59645c0 + languageName: node + linkType: hard + "@babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.7.2": version: 7.23.3 resolution: "@babel/plugin-syntax-jsx@npm:7.23.3" @@ -1193,55 +1204,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-transform-react-display-name@npm:7.23.3" - dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 7f86964e8434d3ddbd3c81d2690c9b66dbf1cd8bd9512e2e24500e9fa8cf378bc52c0853270b3b82143aba5965aec04721df7abdb768f952b44f5c6e0b198779 - languageName: node - linkType: hard - -"@babel/plugin-transform-react-jsx-development@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" - dependencies: - "@babel/plugin-transform-react-jsx": ^7.22.5 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 - languageName: node - linkType: hard - -"@babel/plugin-transform-react-jsx@npm:^7.22.15, @babel/plugin-transform-react-jsx@npm:^7.22.5": - version: 7.23.4 - resolution: "@babel/plugin-transform-react-jsx@npm:7.23.4" - dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-module-imports": ^7.22.15 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/plugin-syntax-jsx": ^7.23.3 - "@babel/types": ^7.23.4 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: d8b8c52e8e22e833bf77c8d1a53b0a57d1fd52ba9596a319d572de79446a8ed9d95521035bc1175c1589d1a6a34600d2e678fa81d81bac8fac121137097f1f0a - languageName: node - linkType: hard - -"@babel/plugin-transform-react-pure-annotations@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.23.3" - dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 9ea3698b1d422561d93c0187ac1ed8f2367e4250b10e259785ead5aa643c265830fd0f4cf5087a5bedbc4007444c06da2f2006686613220acf0949895f453666 - languageName: node - linkType: hard - "@babel/plugin-transform-regenerator@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-regenerator@npm:7.23.3" @@ -1485,22 +1447,6 @@ __metadata: languageName: node linkType: hard -"@babel/preset-react@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/preset-react@npm:7.23.3" - dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-validator-option": ^7.22.15 - "@babel/plugin-transform-react-display-name": ^7.23.3 - "@babel/plugin-transform-react-jsx": ^7.22.15 - "@babel/plugin-transform-react-jsx-development": ^7.22.5 - "@babel/plugin-transform-react-pure-annotations": ^7.23.3 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 2d90961e7e627a74b44551e88ad36a440579e283e8dc27972bf2f50682152bbc77228673a3ea22c0e0d005b70cbc487eccd64897c5e5e0384e5ce18f300b21eb - languageName: node - linkType: hard - "@babel/preset-typescript@npm:^7.23.3": version: 7.23.3 resolution: "@babel/preset-typescript@npm:7.23.3" @@ -1572,7 +1518,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.14.5, @babel/types@npm:^7.15.0, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": +"@babel/types@npm:^7, @babel/types@npm:^7.0.0, @babel/types@npm:^7.14.5, @babel/types@npm:^7.15.0, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.15.0 resolution: "@babel/types@npm:7.15.0" dependencies: @@ -2612,40 +2558,6 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*": - version: 15.7.11 - resolution: "@types/prop-types@npm:15.7.11" - checksum: 7519ff11d06fbf6b275029fe03fff9ec377b4cb6e864cac34d87d7146c7f5a7560fd164bdc1d2dbe00b60c43713631251af1fd3d34d46c69cd354602bc0c7c54 - languageName: node - linkType: hard - -"@types/react-dom@npm:^18.2.17": - version: 18.2.17 - resolution: "@types/react-dom@npm:18.2.17" - dependencies: - "@types/react": "*" - checksum: 7a4e704ed4be6e0c3ccd8a22ff69386fe548304bf4db090513f42e059ff4c65f7a427790320051524d6578a2e4c9667bb7a80a4c989b72361c019fbe851d9385 - languageName: node - linkType: hard - -"@types/react@npm:*, @types/react@npm:^18.2.39": - version: 18.2.39 - resolution: "@types/react@npm:18.2.39" - dependencies: - "@types/prop-types": "*" - "@types/scheduler": "*" - csstype: ^3.0.2 - checksum: 9bcb1f1f060f1bf8f4730fb1c7772d0323a6e707f274efee3b976c40d92af4677df4d88e9135faaacf34e13e02f92ef24eb7d0cbcf7fb75c1883f5623ccb19f4 - languageName: node - linkType: hard - -"@types/scheduler@npm:*": - version: 0.16.8 - resolution: "@types/scheduler@npm:0.16.8" - checksum: 6c091b096daa490093bf30dd7947cd28e5b2cd612ec93448432b33f724b162587fed9309a0acc104d97b69b1d49a0f3fc755a62282054d62975d53d7fd13472d - languageName: node - linkType: hard - "@types/stack-utils@npm:^2.0.0": version: 2.0.0 resolution: "@types/stack-utils@npm:2.0.0" @@ -3691,6 +3603,16 @@ __metadata: languageName: node linkType: hard +"babel-plugin-inferno@npm:^6.7.0": + version: 6.7.0 + resolution: "babel-plugin-inferno@npm:6.7.0" + dependencies: + "@babel/plugin-syntax-jsx": ^7 + "@babel/types": ^7 + checksum: 37b04f04ca326a41e5717a0dbc419d264b05fed57daff8300bd6988608517946f419014b96e546595dbd093e16db136844d7dc95897db0a8b7e2b870d020a00c + languageName: node + linkType: hard + "babel-plugin-istanbul@npm:^6.1.1": version: 6.1.1 resolution: "babel-plugin-istanbul@npm:6.1.1" @@ -4510,13 +4432,6 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2": - version: 3.1.2 - resolution: "csstype@npm:3.1.2" - checksum: e1a52e6c25c1314d6beef5168da704ab29c5186b877c07d822bd0806717d9a265e8493a2e35ca7e68d0f5d472d43fac1cdce70fd79fd0853dff81f3028d857b5 - languageName: node - linkType: hard - "cubic2quad@npm:^1.0.0": version: 1.1.1 resolution: "cubic2quad@npm:1.1.1" @@ -6598,6 +6513,31 @@ __metadata: languageName: node linkType: hard +"inferno-shared@npm:7.4.11": + version: 7.4.11 + resolution: "inferno-shared@npm:7.4.11" + checksum: 48b453fb11d7126d30668e3d74ccc4a4f00f9f7b191d27eded2138acc0cd07c02d14c1c936319b5b25bf46f7476b480938337ec7a64b932b2949b73c968ae52a + languageName: node + linkType: hard + +"inferno-vnode-flags@npm:7.4.11, inferno-vnode-flags@npm:^7.4.11": + version: 7.4.11 + resolution: "inferno-vnode-flags@npm:7.4.11" + checksum: 8a2f1d8d546b99c14c31a25a88ac45f076be9ac630202f898c49140aa420cf2c96d871fcc3f8e5813d5176d569a40c3fd1727198edf46306de3a989fe85176ab + languageName: node + linkType: hard + +"inferno@npm:^7.4.11": + version: 7.4.11 + resolution: "inferno@npm:7.4.11" + dependencies: + inferno-shared: 7.4.11 + inferno-vnode-flags: 7.4.11 + opencollective-postinstall: ^2.0.3 + checksum: 1651aad357995170c135520ff09d6e24311e05f0b0736b66d50dba5e68ff521b6c9dff13eec64effd6b79455d39f06176f0a5be50a1aaa979384721ae9b9862c + languageName: node + linkType: hard + "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -8089,7 +8029,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -8775,6 +8715,15 @@ __metadata: languageName: node linkType: hard +"opencollective-postinstall@npm:^2.0.3": + version: 2.0.3 + resolution: "opencollective-postinstall@npm:2.0.3" + bin: + opencollective-postinstall: index.js + checksum: 0a68c5cef135e46d11e665d5077398285d1ce5311c948e8327b435791c409744d4a6bb9c55bd6507fb5f2ef34b0ad920565adcdaf974cbdae701aead6f32b396 + languageName: node + linkType: hard + "opener@npm:^1.5.2": version: 1.5.2 resolution: "opener@npm:1.5.2" @@ -9461,18 +9410,6 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.2.0": - version: 18.2.0 - resolution: "react-dom@npm:18.2.0" - dependencies: - loose-envify: ^1.1.0 - scheduler: ^0.23.0 - peerDependencies: - react: ^18.2.0 - checksum: 7d323310bea3a91be2965f9468d552f201b1c27891e45ddc2d6b8f717680c95a75ae0bc1e3f5cf41472446a2589a75aed4483aee8169287909fcd59ad149e8cc - languageName: node - linkType: hard - "react-is@npm:^16.13.1": version: 16.13.1 resolution: "react-is@npm:16.13.1" @@ -9487,15 +9424,6 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.2.0": - version: 18.2.0 - resolution: "react@npm:18.2.0" - dependencies: - loose-envify: ^1.1.0 - checksum: 88e38092da8839b830cda6feef2e8505dec8ace60579e46aa5490fc3dc9bba0bd50336507dc166f43e3afc1c42939c09fe33b25fae889d6f402721dcd78fca1b - languageName: node - linkType: hard - "readable-stream@npm:^1.0.33": version: 1.1.14 resolution: "readable-stream@npm:1.1.14" @@ -9971,15 +9899,6 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.0": - version: 0.23.0 - resolution: "scheduler@npm:0.23.0" - dependencies: - loose-envify: ^1.1.0 - checksum: d79192eeaa12abef860c195ea45d37cbf2bbf5f66e3c4dcd16f54a7da53b17788a70d109ee3d3dde1a0fd50e6a8fc171f4300356c5aee4fc0171de526bf35f8a - languageName: node - linkType: hard - "schema-utils@npm:^2.6.5": version: 2.7.1 resolution: "schema-utils@npm:2.7.1" @@ -10925,9 +10844,10 @@ __metadata: "@fastify/static": ^6.12.0 common: "workspace:*" fastify: ^3.29.5 + inferno: ^7.4.11 + inferno-vnode-flags: ^7.4.11 lodash: ^4.17.21 platform: ^1.3.6 - react: ^18.2.0 tgui: "workspace:*" languageName: unknown linkType: soft @@ -10948,11 +10868,9 @@ __metadata: version: 0.0.0-use.local resolution: "tgui-panel@workspace:packages/tgui-panel" dependencies: - "@types/react": ^18.2.39 common: "workspace:*" dompurify: ^2.4.4 - react: ^18.2.0 - react-dom: ^18.2.0 + inferno: ^7.4.11 tgui: "workspace:*" tgui-dev-server: "workspace:*" tgui-polyfill: "workspace:*" @@ -10974,9 +10892,8 @@ __metadata: version: 0.0.0-use.local resolution: "tgui-say@workspace:packages/tgui-say" dependencies: - "@types/react": ^18.2.39 common: "workspace:*" - react: ^18.2.0 + inferno: ^7.4.11 tgui: "workspace:*" tgui-polyfill: "workspace:*" languageName: unknown @@ -10991,7 +10908,6 @@ __metadata: "@babel/plugin-transform-class-properties": ^7.23.3 "@babel/plugin-transform-jscript": ^7.23.3 "@babel/preset-env": ^7.23.3 - "@babel/preset-react": ^7.23.3 "@babel/preset-typescript": ^7.23.3 "@types/jest": ^29.5.10 "@types/jsdom": ^21.1.6 @@ -11001,6 +10917,7 @@ __metadata: "@typescript-eslint/parser": ^5.62.0 babel-jest: ^29.7.0 babel-loader: ^8.3.0 + babel-plugin-inferno: ^6.7.0 babel-plugin-transform-remove-console: ^6.9.4 common: "workspace:*" css-loader: ^6.8.1 @@ -11034,16 +10951,14 @@ __metadata: dependencies: "@popperjs/core": ^2.11.8 "@types/marked": ^4.0.8 - "@types/react": ^18.2.39 - "@types/react-dom": ^18.2.17 common: "workspace:*" dateformat: ^4.6.2 dompurify: ^2.4.4 highlight.js: ^11.9.0 + inferno: ^7.4.11 + inferno-vnode-flags: ^7.4.11 js-yaml: ^4.1.0 marked: ^4.2.12 - react: ^18.2.0 - react-dom: ^18.2.0 tgui-dev-server: "workspace:*" tgui-polyfill: "workspace:*" languageName: unknown