Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #50497 from stylemistake/tgui-3.0
About The Pull Request This is a massive rework that is coming down the pipe. Removal of routes.js This PR removes routes.js file in favor of filename-based routing. DM-code will now reference components directly. For example, previously, DM code would use "ntos_main" as a key. Now you need to use "NtosMain" as a key, and it should match both the exported name and a file name of your component. Flexible Layout System As a result of the above, interfaces are now top-level components. To accomodate this change, we have created a new abstraction for the layout: the Window component. You will now see, that interfaces, instead of returning window contents directly, return a tree that starts with a <Window /> component: export const Apc = (props, context) => { return ( <Window resizable> <Window.Content scrollable> <ApcContent /> </Window.Content> </Window> ); }; Metadata, which was previously added to routes.js (things like theme, wrapper, scrollable) can now be declared on the Window. This also eliminates the need for a concept called wrapper, because now you can directly control where you render <Window.Content />, which allows adding things like toolbars, status bars, and modal windows. We also have <NtosWindow /> for NtOS interfaces, and <Layout /> for completely custom, non window-based layouts. (Side-panel tguis, or maybe even goonchat or stat panel replacement, wink wink, nudge nudge, WYCI). Modals Now since we have a new layout system, modals are now easier to implement than ever! This is because now we have a clear slot for them, which would cover all area above the content with a Dimmer. This avoids issues like Dimmer being scrollable together with the content, or covering content only partially, and things like that. export const Apc = (props, context) => { return ( <Window resizable> {/* Dimmer/Modal slot starts here */} {showModal && ( <Modal> {...} </Modal> )} {/* Dimmer/Modal slot ends here */} <Window.Content scrollable> <ApcContent /> </Window.Content> </Window> ); }; React Context You have probably noticed, that we have a second argument to components: context. This is a "magical" state container, that is available on all components without you doing anything extra to support it. It carries the Redux store and all tgui backend related data, meaning that things like useBackend(context) will now use context instead of props. This also means, that you no longer have to pass around the state via the props: <AnotherNestedComponent state={state} /> With context available on all components, this is all you need to do: <AnotherNestedComponent /> Shared TGUI states We introduce a new abstraction, that eliminates all previous use-cases for class-based React components - local component state. You can now achieve the same thing with help of a useLocalState() function: const AirAlarmControl = (props, context) => { const [screen, setScreen] = useLocalState(context, 'screen'); // Use `screen` to access current screen. // Use `setScreen(nextValue)` function to set screen to a new value. }; This also removes the redundant tgui:view action, and config.ui_screen variable, because now this thingie can achieve the same thing in a more generic way. But wait, there's more! You can use useSharedState() function, to not only create a piece of state, but also sync it across all clients, which is a fantastic way to allow observers see how user interacts with the UI. const AirAlarmControl = (props, context) => { const [screen, setScreen] = useSharedState(context, 'screen'); // Now screen will change for everyone who observes the UI. }; useSharedState() is JSON-serializable, which means you can use anything as a state, not only strings and primitive values. Performance Improvements We have sped up the initial render by about a full frame. Miscellaneous Fixed operating computer getting stuck on last step of the surgery. All UIs refactored to use new Tabs API Formatters formatPower, outputs watts with SI units, kilo, mega, etc. formatMoney, formats cash with thousand separators and shit. Code for this is stolen from real business applications. Number helpers round(number, precision) helper, with correct 0.5 rounding, and with other float nonsense fixed. toFixed(number, precision) won't throw an exception on negative values Moving stuff around in webpack DOM polyfills get their own directory, and are bundled together with the rest of the code. 60KB -> 20KB, indirectly adds speed to initial render. Stylesheets are now imported in index.js (well, everything is now imported in index.js now). Achievements UI cleaned up, smaller, neater UI. Black Market Uplink cleaned up Generalized Uplinks, Malf Module Picker now uses this generic uplink UI, with custom theme still applied. Saved a few kilobytes. Uplinks limit search results to 25, which helps reduce lag while typing into the search box. Added padding props to Box, aka all this crap: p, px, py, pt, pr, pl, pb. Reduced stats while building the bundle, now you can actually see the meaningful green text in console instead of all the child module spam. Flattened Crafting Categories New Kiosk UI Modal Tweaks You can track progress of other tgui ideas here: tgui: Roadmap Information for downstreams Your tgui modifications will not be easily mergeable because we have effectively shifted indentation of all interfaces by two, and added a new wrapping component called <Window />. This will be a lot of manual work, but it's not that terrible though. If you can isolate your local contributions to tgui, you can just copy-paste them into the new tgui where needed, and it should just work. If you're not yet using tgui 2.0 (or tgui-next) in your project - great news, this is the final big refactor, and everything will be quieter after this PR. Things are looking really solid now. This will serve as a great base for your future UI work. Acknowledgements Big thanks to @actioninja for converting half of the interfaces, that's a lot of work!
- Loading branch information