* typing

* remove warns

* cleaner

* use effect
This commit is contained in:
Kashargul
2025-09-02 09:53:15 +02:00
committed by GitHub
parent 48eeb56db0
commit b8424ffa54
5 changed files with 60 additions and 45 deletions
+1 -2
View File
@@ -44,8 +44,7 @@ const icons = {
type Data = { dates: string[] };
// biome-ignore lint/complexity/noBannedTypes:Ingored here
type ChangelogProps = {};
type ChangelogProps = Record<never, never>;
interface ChangelogState {
data: string | { date: string; authors: { name: string; changes: string[] } };
@@ -46,8 +46,7 @@ interface ColorPickerData {
presets: string;
}
// biome-ignore lint/complexity/noBannedTypes:Ingored here
type ColorPickerModalProps = {};
type ColorPickerModalProps = Record<never, never>;
export const ColorPickerModal: React.FC<ColorPickerModalProps> = () => {
const { act, data } = useBackend<ColorPickerData>();
@@ -17,8 +17,7 @@ import {
PortTypesToColor,
} from './types';
// biome-ignore lint/complexity/noBannedTypes:Ingored here
export type PlaneProps = {};
export type PlaneProps = Record<never, never>;
type PlaneState = {
locations: Record<string, { x: number; y: number }>;
@@ -41,7 +41,6 @@ type record = {
export type modalData = {
id: string;
text: string;
// biome-ignore lint/complexity/noBannedTypes: In this case we got any type of Object
args: {};
args: Record<string, unknown>;
type: string;
};
@@ -1,4 +1,4 @@
import { type KeyboardEvent, useRef, useState } from 'react';
import { type KeyboardEvent, useEffect, useState } from 'react';
import { useBackend } from 'tgui/backend';
import {
Box,
@@ -10,8 +10,16 @@ import {
Stack,
} from 'tgui-core/components';
// biome-ignore lint/complexity/noBannedTypes: In this case, we got any type of Object
type Data = { modal: { id: string; args: {}; text: string; type: string } };
type ModalData<TArgs = Record<string, unknown>> = {
id: string;
args: TArgs;
text: string;
type: string;
};
type Data<TArgs = Record<string, unknown>> = {
modal: ModalData<TArgs> | null;
};
const bodyOverrides = {};
/**
@@ -38,27 +46,32 @@ export const modalOpen = (id, args = {}) => {
* @param {function} bodyOverride The override function that returns the
* modal contents
*/
type ModalOverrideData<TArgs = Record<string, unknown>> = {
id: string;
text: string;
args: TArgs;
type: string;
};
export const modalRegisterBodyOverride = (
id: string,
bodyOverride: (modal: {
id: string;
text: string;
// biome-ignore lint/complexity/noBannedTypes: In this case, we got any type of Object
args: {};
type: string;
}) => React.JSX.Element,
bodyOverride: (modal: ModalOverrideData) => React.JSX.Element,
) => {
bodyOverrides[id] = bodyOverride;
};
// biome-ignore lint/complexity/noBannedTypes: In this case, we got any type of Object
const modalAnswer = (id: string, answer: string, args: {}) => {
const modalAnswer = (
id: string,
answer: string | undefined,
args: Record<string, unknown>,
) => {
const { act, data } = useBackend<Data>();
const { modal } = data;
if (!modal) {
return;
return null;
}
const newArgs = Object.assign(modal.args || {}, args || {});
@@ -76,16 +89,18 @@ const modalClose = (id: string | null) => {
});
};
type complexData = Data &
type ExtendedModalData<TArgs = Record<string, unknown>> = ModalData<TArgs> &
Partial<{
modal: {
value: string;
choices: string[];
no_text: string;
yes_text: string;
};
value: string;
choices: string[];
no_text: string;
yes_text: string;
}>;
type ComplexData<TArgs = Record<string, unknown>> = {
modal: ExtendedModalData<TArgs> | null;
};
/**
* Displays a modal and its actions. Passed data must have a valid modal field
*
@@ -102,16 +117,24 @@ type complexData = Data &
* Defaults to `message` if not found
* @param {object} props
*/
export const ComplexModal = (props) => {
const { data } = useBackend<complexData>();
export const ComplexModal = (props: {
maxWidth?: string;
maxHeight?: string;
}) => {
const { data } = useBackend<ComplexData>();
const { modal } = data;
const lastValue = useRef(modal.value);
const [curValue, setCurValue] = useState(modal.value);
const [curValue, setCurValue] = useState(modal?.value);
useEffect(() => {
if (modal?.type === 'input') {
setCurValue(modal.value);
}
}, [modal?.value, modal?.type]);
if (!modal) {
return;
return null;
}
const { id, text, type } = modal;
@@ -131,11 +154,6 @@ export const ComplexModal = (props) => {
if (bodyOverrides[id]) {
modalBody = bodyOverrides[id](modal);
} else if (type === 'input') {
if (lastValue.current !== modal.value) {
lastValue.current = modal.value;
setCurValue(modal.value);
}
modalOnEnter = (e) => modalAnswer(id, curValue, {});
modalBody = (
<Input
@@ -175,10 +193,9 @@ export const ComplexModal = (props) => {
</Box>
);
} else if (type === 'choice') {
const { choices = [] } = modal;
const realChoices =
typeof modal.choices === 'object'
? Object.values(modal.choices)
: modal.choices;
typeof modal.choices === 'object' ? Object.values(choices) : choices;
modalBody = (
<Dropdown
autoScroll={false}
@@ -190,12 +207,13 @@ export const ComplexModal = (props) => {
/>
);
} else if (type === 'bento') {
const { choices = [], value = '' } = modal;
modalBody = (
<Stack wrap="wrap" my="0.5rem" maxHeight="1%">
{modal.choices.map((c, i) => (
{choices.map((c, i) => (
<Stack.Item key={i}>
<Button
selected={i + 1 === parseInt(modal.value, 10)}
selected={i + 1 === parseInt(value, 10)}
onClick={() => modalAnswer(id, (i + 1).toString(), {})}
>
<Image src={c} />
@@ -205,12 +223,13 @@ export const ComplexModal = (props) => {
</Stack>
);
} else if (type === 'bentospritesheet') {
const { choices = [], value = '' } = modal;
modalBody = (
<Stack wrap="wrap" my="0.5rem" maxHeight="1%">
{modal.choices.map((c, i) => (
{choices.map((c, i) => (
<Stack.Item key={i}>
<Button
selected={i + 1 === parseInt(modal.value, 10)}
selected={i + 1 === parseInt(value, 10)}
onClick={() => modalAnswer(id, (i + 1).toString(), {})}
>
<Box className={c} />