Files
Paradise/tgui/packages/common/redux.ts
+12
BurzahGitHubAylongwarriorstar-orionArthri/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>Toastical/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>AylongArthri/tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>Charlie Nolan
18573ef254 Tgui v6 (#29342)
* [TGUI v6 Project] Remove `context` (#29086)

* [TGUI v6 Project] Remove `context`

* I forgot I had to do that.

* [TGUI v6 Project] Move to React (#29090)

* It compiles

* Last Inferno uses

* all works now

* Fixes

* [TGUI v6] Changes files extensions for interfaces from .js to .jsx, Deprecates Inferno State Hooks (#29094)

* Initial Commit

* Apply suggestions from code review

trust me bro

Co-authored-by: Aylong <69762909+AyIong@users.noreply.github.com>
Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>

---------

Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: Aylong <69762909+AyIong@users.noreply.github.com>

* [TGUI v6] Replaces babel with swc, fixes realtive paths on a few files, new build (#29100)

* Initial commit

* Build

* webpack config and errors and rebuild

* export routingError, hopefully

* fix pda app routing

* pass current tab index to tab headers and content in nanobank

---------

Co-authored-by: warriorstar-orion <orion@snowfrost.garden>

* fix dna modifier bluescreen and library computer tabs (#29108)

* TGUI parity with TG

Need to fix a bunch of things...

* Implement TGUI payload chunking backend

https://github.com/tgstation/tgstation/pull/90295

* Filx chan bottom scroll. Again

* Fix TGchat focus

* Fix rounding

* Fix inputs

* Upgrade deps

* More fixes

* Fix chat lineHeight

* Fix NanoMap

* Update `tgui-core`

* fix autolathe

* fix airlock electronics

* fix intercom

* fix compost bin height

* Fix chat preferences

* Move to TSX without types :clueless:

* test tiny meet your new brother test tgui

* Fix RCD

* fix stackcraft

* fix up beakercontents

* Fix MODsuits

* fix seed extractor

* Merge branch 'tgui-v6' of github.com:ParadiseSS13/Paradise into tgui-v6

* fix holodeck

* fix cookbook pda app

* fix remaining useState args

* Fix DNAModifier

* Fix Sleeper

* Fix SupermatterMonitor

* Remove `vitest`

* Update dev-server

* Fix `IconStack`

* Correct margin

* bundles, please don't break

* prettier

* Revert "Remove `vitest`"

This reverts commit 0609006abb.

* Re-add tests

* Prettier

* fix maplint for test_tgui

* TGchat shine effect

* TGUI Rebuildo

* Fix broken tabs, search boxes, sortable tables, and others (#29450)

* Replace KitchenSink theme state with a React context

* Remove last usage of useLocalState

* Rebind unbound useState calls

* Build and update /tg/ui

* Reformat /tg/ui

* [ci skip]

---------

Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>

* Ports #29217 to tgui v6. Added tgui-setup to CI builds (#29787)

* Add tgui-setup to build scripts

* Fix CORS issue

* Build and update /tg/ui

Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>

* Add one missing word to comment

---------

Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix law manager

* Removes dangling references to `context` (#29793)

* Removes dangling references to `context`

* Build and update /tg/ui (#25)

Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix messenger and atmos scanner

* swap out line break in examinate

* fix powermonitor

* Bump tgui-core from 3.1.5/3.1.4 to 4.3.4 (#29799)

* Bump tgui-core

* Build and update /tg/ui (#28)

Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Fixes additional examine text

* oopsie

* Small tgui v6 fixes (#29801)

* Remove flow

* Miscellaneous fixes

* Miscellaneous fixes

* Moved properties placed on the wrong element

* Migrate removed CSS attributes in JSX

* Build and update /tg/ui (#27)

Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix carbon examine

* fix robot examine

* fix lint

* improve SMES appearance

* fix camera console name order

* more newline fixes

* fix boolean modal cancel not working

* fix random disabled access in RCD

* point tgui to correct passthrough verb names

* Fix missing 0 option for ERTs. (#29819)

* fix newlines in damage flavor

* Revert all changes related to newlines in DM

* fix the actual thing that was wrong with newlines

* fix ERT manager deny input

* [tgui-v6] Makes Agent Card UI more aesthethic, fixes input fields, fixes minimum age slider (#29832)

* agent card fixes and tweaks

* tgui bundle

* Reformat /tg/ui (#33) (#29838)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* restore camera console list appearance

* fixed pai ui paths (#29867)

* /tg/ui fixes no. 3 (#29868)

* Remove IconStack styles that conflict with styles added in tgstation/tgui-core#203

* Fix minesweeper icon

* DNA Modifier fixes

* Fix alignment of icons in PDA games menu

* Expand chem dispenser

* Fix pAI interfaces

* Build and update /tg/ui

---------

Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Toastical <20125180+Toastical@users.noreply.github.com>

* teleporter fix, bundle changes, test

* /tg/ui fixes no.4 (#29877)

* Fix translucent buttons

* Remove stories already present in tgui-core

* Make voting choices not transparent

* Build and update /tg/ui

* Fix size of set ringtone in PDA messenger

* Fix crew monitor highlight colors

* Fix ReagentsEditor search. Small style fixes

* tgui-say radio prefix has special color again

* Expand chameleon mask a little

* Fix search in chameleon mask

* Make list input modal slightly taller

* [ci skip]

* Build /tg/ui

---------

Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>

---------

Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: Aylong <69762909+AyIong@users.noreply.github.com>
Co-authored-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: Aylong <alexanderkitsa@gmail.com>
Co-authored-by: Arthri <41360489+Arthri@users.noreply.github.com>
Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
Co-authored-by: /tg/ui Builder <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Charlie Nolan <funnyman3595@gmail.com>
Co-authored-by: Toastical <20125180+Toastical@users.noreply.github.com>
2025-07-27 23:23:20 +00:00

181 lines
5.1 KiB
TypeScript

/**
* @file
* @copyright 2020 Aleksej Komarov
* @license MIT
*/
export type Reducer<State = any, ActionType extends Action = AnyAction> = (
state: State | undefined,
action: ActionType
) => State;
export type Store<State = any, ActionType extends Action = AnyAction> = {
dispatch: Dispatch<ActionType>;
subscribe: (listener: () => void) => void;
getState: () => State;
};
type MiddlewareAPI<State = any, ActionType extends Action = AnyAction> = {
getState: () => State;
dispatch: Dispatch<ActionType>;
};
export type Middleware = <State = any, ActionType extends Action = AnyAction>(
storeApi: MiddlewareAPI<State, ActionType>
) => (next: Dispatch<ActionType>) => Dispatch<ActionType>;
export type Action<TType = any> = {
type: TType;
};
export type AnyAction = Action & {
[extraProps: string]: any;
};
export type Dispatch<ActionType extends Action = AnyAction> = (action: ActionType) => void;
type StoreEnhancer = (createStoreFunction: Function) => Function;
type PreparedAction = {
payload?: any;
meta?: any;
};
/**
* Creates a Redux store.
*/
export const createStore = <State, ActionType extends Action = AnyAction>(
reducer: Reducer<State, ActionType>,
enhancer?: StoreEnhancer
): Store<State, ActionType> => {
// Apply a store enhancer (applyMiddleware is one of them).
if (enhancer) {
return enhancer(createStore)(reducer);
}
let currentState: State;
let listeners: Array<() => void> = [];
const getState = (): State => currentState;
const subscribe = (listener: () => void): void => {
listeners.push(listener);
};
const dispatch = (action: ActionType): void => {
currentState = reducer(currentState, action);
for (let i = 0; i < listeners.length; i++) {
listeners[i]();
}
};
// This creates the initial store by causing each reducer to be called
// with an undefined state
dispatch({ type: '@@INIT' } as ActionType);
return {
dispatch,
subscribe,
getState,
};
};
/**
* Creates a store enhancer which applies middleware to all dispatched
* actions.
*/
export const applyMiddleware = (...middlewares: Middleware[]): StoreEnhancer => {
return (createStoreFunction: (reducer: Reducer, enhancer?: StoreEnhancer) => Store) => {
return (reducer, ...args): Store => {
const store = createStoreFunction(reducer, ...args);
let dispatch: Dispatch = (action, ...args) => {
throw new Error('Dispatching while constructing your middleware is not allowed.');
};
const storeApi: MiddlewareAPI = {
getState: store.getState,
dispatch: (action, ...args) => dispatch(action, ...args),
};
const chain = middlewares.map((middleware) => middleware(storeApi));
dispatch = chain.reduceRight((next, middleware) => middleware(next), store.dispatch);
return {
...store,
dispatch,
};
};
};
};
/**
* Combines reducers by running them in their own object namespaces as
* defined in reducersObj paramter.
*
* Main difference from redux/combineReducers is that it preserves keys
* in the state that are not present in the reducers object. This function
* is also more flexible than the redux counterpart.
*/
export const combineReducers = (reducersObj: Record<string, Reducer>): Reducer => {
const keys = Object.keys(reducersObj);
return (prevState = {}, action) => {
const nextState = { ...prevState };
let hasChanged = false;
for (const key of keys) {
const reducer = reducersObj[key];
const prevDomainState = prevState[key];
const nextDomainState = reducer(prevDomainState, action);
if (prevDomainState !== nextDomainState) {
hasChanged = true;
nextState[key] = nextDomainState;
}
}
return hasChanged ? nextState : prevState;
};
};
/**
* A utility function to create an action creator for the given action
* type string. The action creator accepts a single argument, which will
* be included in the action object as a field called payload. The action
* creator function will also have its toString() overriden so that it
* returns the action type, allowing it to be used in reducer logic that
* is looking for that action type.
*
* @param {string} type The action type to use for created actions.
* @param {any} prepare (optional) a method that takes any number of arguments
* and returns { payload } or { payload, meta }. If this is given, the
* resulting action creator will pass its arguments to this method to
* calculate payload & meta.
*
* @public
*/
export const createAction = <TAction extends string>(type: TAction, prepare?: (...args: any[]) => PreparedAction) => {
const actionCreator = (...args: any[]) => {
let action: Action<TAction> & PreparedAction = { type };
if (prepare) {
const prepared = prepare(...args);
if (!prepared) {
throw new Error('prepare function did not return an object');
}
action = { ...action, ...prepared };
} else {
action.payload = args[0];
}
return action;
};
actionCreator.toString = () => type;
actionCreator.type = type;
actionCreator.match = (action) => action.type === type;
return actionCreator;
};