Skip to content

Commit

Permalink
React Migration - part 2 (#5493)
Browse files Browse the repository at this point in the history
# About the pull request

<!-- Remove this text and explain what the purpose of your PR is.

Mention if you have tested your changes. If you changed a map, make sure
you used the mapmerge tool.
If this is an Issue Correction, you can type "Fixes Issue #169420" to
link the PR to the corresponding Issue number #169420.

Remember: something that is self-evident to you might not be to others.
Explain your rationale fully, even if you feel it goes without saying.
-->

Switches TGUI from Inferno to React.

Part 2 of the PR #5435

Based heavily on the work from:
https://github.com/tgstation/tgstation/pull/80044/files

# Explain why it's good for the game
React is a more suitable framework

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

Put screenshots and videos here with an empty line between the
screenshots and the `<details>` tags.

</details>


# Changelog
:cl:
refactor: switched from infernojs to react
/:cl:
  • Loading branch information
mullenpaul authored Jan 23, 2024
1 parent 37d8e71 commit d5dfe13
Show file tree
Hide file tree
Showing 221 changed files with 2,775 additions and 2,653 deletions.
1 change: 0 additions & 1 deletion tgui/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
/**/*.bundle.*
/**/*.chunk.*
/**/*.hot-update.*
/packages/inferno/**
40 changes: 24 additions & 16 deletions tgui/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,36 @@

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',
spec: false,
loose: true,
targets: [],
}],
[
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' }],
...presets,
].filter(Boolean),
plugins: [
[require.resolve('@babel/plugin-proposal-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,
Expand Down
5 changes: 2 additions & 3 deletions tgui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@
"dependencies": {
"@babel/core": "^7.15.0",
"@babel/eslint-parser": "^7.15.0",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-transform-class-properties": "^7.23.3",
"@babel/plugin-transform-jscript": "^7.14.5",
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.23.3",
"@babel/preset-typescript": "^7.15.0",
"@types/jest": "^27.0.1",
"@types/jsdom": "^16.2.13",
Expand All @@ -34,7 +35,6 @@
"@typescript-eslint/parser": "^4.29.1",
"babel-jest": "^27.0.6",
"babel-loader": "^8.2.2",
"babel-plugin-inferno": "^6.3.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"common": "workspace:*",
"css-loader": "^5.2.7",
Expand All @@ -44,7 +44,6 @@
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-unused-imports": "^1.1.4",
"file-loader": "^6.2.0",
"inferno": "^7.4.8",
"jest": "^27.0.6",
"jest-circus": "^27.0.6",
"jsdom": "^16.7.0",
Expand Down
39 changes: 39 additions & 0 deletions tgui/packages/common/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* ### Key codes.
* event.keyCode is deprecated, use this reference instead.
*
* Handles modifier keys (Shift, Alt, Control) and arrow keys.
*
* For alphabetical keys, use the actual character (e.g. 'a') instead of the key code.
*
* Something isn't here that you want? Just add it:
* @url https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
* @usage
* ```ts
* import { KEY } from 'tgui/common/keys';
*
* if (event.key === KEY.Enter) {
* // do something
* }
* ```
*/
export enum KEY {
Alt = 'Alt',
Backspace = 'Backspace',
Control = 'Control',
Delete = 'Delete',
Down = 'ArrowDown',
End = 'End',
Enter = 'Enter',
Escape = 'Escape',
Home = 'Home',
Insert = 'Insert',
Left = 'ArrowLeft',
PageDown = 'PageDown',
PageUp = 'PageUp',
Right = 'ArrowRight',
Shift = 'Shift',
Space = ' ',
Tab = 'Tab',
Up = 'ArrowUp',
}
9 changes: 0 additions & 9 deletions tgui/packages/common/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,6 @@ export const shallowDiffers = (a: object, b: object) => {
return false;
};

/**
* Default inferno hooks for pure components.
*/
export const pureComponentHooks = {
onComponentShouldUpdate: (lastProps, nextProps) => {
return shallowDiffers(lastProps, nextProps);
},
};

/**
* A helper to determine whether the object is renderable by React.
*/
Expand Down
16 changes: 0 additions & 16 deletions tgui/packages/common/redux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,19 +194,3 @@ export const createAction = <TAction extends string>(

return actionCreator;
};

// Implementation specific
// --------------------------------------------------------

export const useDispatch = <TAction extends Action = AnyAction>(context: {
store: Store<unknown, TAction>;
}): Dispatch<TAction> => {
return context.store.dispatch;
};

export const useSelector = <State, Selected>(
context: { store: Store<State, Action> },
selector: (state: State) => Selected
): Selected => {
return selector(context.store.getState());
};
3 changes: 1 addition & 2 deletions tgui/packages/tgui-bench/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
"common": "workspace:*",
"fastify": "^3.29.4",
"fastify-static": "^4.2.3",
"inferno": "^7.4.8",
"inferno-vnode-flags": "^7.4.8",
"lodash": "^4.17.21",
"platform": "^1.3.6",
"react": "^18.2.0",
"tgui": "workspace:*"
}
}
2 changes: 1 addition & 1 deletion tgui/packages/tgui-bench/tests/Button.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { linkEvent } from 'inferno';
import { linkEvent } from 'react';
import { Button } from 'tgui/components';
import { createRenderer } from 'tgui/renderer';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ import { PingIndicator } from './ping';
import { ReconnectButton } from './reconnect';
import { SettingsPanel, useSettings } from './settings';

export const Panel = (props, context) => {
export const Panel = (props) => {
// IE8-10: Needs special treatment due to missing Flex support
if (Byond.IS_LTE_IE10) {
return <HoboPanel />;
}
const audio = useAudio(context);
const settings = useSettings(context);
const game = useGame(context);
const audio = useAudio();
const settings = useSettings();
const game = useGame();
if (process.env.NODE_ENV !== 'production') {
const { useDebug, KitchenSink } = require('tgui/debug');
const debug = useDebug(context);
const debug = useDebug();
if (debug.kitchenSink) {
return <KitchenSink panel />;
}
Expand Down Expand Up @@ -103,8 +103,8 @@ export const Panel = (props, context) => {
);
};

const HoboPanel = (props, context) => {
const settings = useSettings(context);
const HoboPanel = (props) => {
const settings = useSettings();
return (
<Pane theme={settings.theme}>
<Pane.Content scrollable>
Expand Down
71 changes: 0 additions & 71 deletions tgui/packages/tgui-panel/audio/NowPlayingWidget.js

This file was deleted.

109 changes: 109 additions & 0 deletions tgui/packages/tgui-panel/audio/NowPlayingWidget.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* @file
* @copyright 2020 Aleksej Komarov
* @license MIT
*/

import { toFixed } from 'common/math';
import { useDispatch, useSelector } from 'tgui/backend';
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(),
title = audio.meta?.title,
URL = audio.meta?.link,
Artist = audio.meta?.artist || 'Unknown Artist',
upload_date = audio.meta?.upload_date || 'Unknown Date',
album = audio.meta?.album || 'Unknown Album',
duration = audio.meta?.duration,
date = !isNaN(upload_date)
? upload_date?.substring(0, 4) +
'-' +
upload_date?.substring(4, 6) +
'-' +
upload_date?.substring(6, 8)
: upload_date;

return (
<Flex align="center">
{(audio.playing && (
<Flex.Item
mx={0.5}
grow={1}
style={{
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}>
{
<Collapsible title={title || 'Unknown Track'} color={'blue'}>
<Section>
{URL !== 'Song Link Hidden' && (
<Flex.Item grow={1} color="label">
URL: {URL}
</Flex.Item>
)}
<Flex.Item grow={1} color="label">
Duration: {duration}
</Flex.Item>
{Artist !== 'Song Artist Hidden' &&
Artist !== 'Unknown Artist' && (
<Flex.Item grow={1} color="label">
Artist: {Artist}
</Flex.Item>
)}
{album !== 'Song Album Hidden' && album !== 'Unknown Album' && (
<Flex.Item grow={1} color="label">
Album: {album}
</Flex.Item>
)}
{upload_date !== 'Song Upload Date Hidden' &&
upload_date !== 'Unknown Date' && (
<Flex.Item grow={1} color="label">
Uploaded: {date}
</Flex.Item>
)}
</Section>
</Collapsible>
}
</Flex.Item>
)) || (
<Flex.Item grow={1} color="label">
Nothing to play.
</Flex.Item>
)}
{audio.playing && (
<Flex.Item mx={0.5} fontSize="0.9em">
<Button
tooltip="Stop"
icon="stop"
onClick={() =>
dispatch({
type: 'audio/stopMusic',
})
}
/>
</Flex.Item>
)}
<Flex.Item mx={0.5} fontSize="0.9em">
<Knob
minValue={0}
maxValue={1}
value={settings.adminMusicVolume}
step={0.0025}
stepPixelSize={1}
format={(value) => toFixed(value * 100) + '%'}
onDrag={(e, value) =>
settings.update({
adminMusicVolume: value,
})
}
/>
</Flex.Item>
</Flex>
);
};
Loading

0 comments on commit d5dfe13

Please sign in to comment.