mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
122 lines
5.4 KiB
TypeScript
122 lines
5.4 KiB
TypeScript
import { FC, useEffect, useState } from 'react';
|
|
import { LocalizeText, WiredFurniType } from '../../../../api';
|
|
import { Text } from '../../../../common';
|
|
import { useWired } from '../../../../hooks';
|
|
import iconRotateClockwise from '../../../../assets/images/wired/icon_wired_rotate_clockwise.png';
|
|
import iconRotateCounterClockwise from '../../../../assets/images/wired/icon_wired_rotate_counter_clockwise.png';
|
|
import { WiredDirectionIcon, WIRED_DIRECTION_GRID } from '../WiredDirectionIcon';
|
|
import { WiredActionBaseView } from './WiredActionBaseView';
|
|
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
|
|
|
const ROTATION_CLOCKWISE = 8;
|
|
const ROTATION_COUNTER_CLOCKWISE = 9;
|
|
|
|
interface DirectionExtraOption
|
|
{
|
|
value: number;
|
|
icon: string;
|
|
label: string;
|
|
}
|
|
|
|
interface DirectionPickerProps
|
|
{
|
|
name: string;
|
|
title: string;
|
|
noneLabel: string;
|
|
value: number;
|
|
onChange: (value: number) => void;
|
|
extraOptions?: DirectionExtraOption[];
|
|
}
|
|
|
|
const DirectionPicker: FC<DirectionPickerProps> = props =>
|
|
{
|
|
const { name = '', title = '', noneLabel = '', value = -1, onChange = null, extraOptions = [] } = props;
|
|
|
|
return (
|
|
<div className="flex flex-col gap-2">
|
|
<Text bold>{ title }</Text>
|
|
<label className="flex items-center gap-2 text-[12px]">
|
|
<input checked={ (value === -1) } className="form-check-input" name={ name } type="radio" onChange={ () => onChange(-1) } />
|
|
<span>{ noneLabel }</span>
|
|
</label>
|
|
<div className="grid grid-cols-4 gap-2 max-w-[240px]">
|
|
{ WIRED_DIRECTION_GRID.flatMap((row, rowIndex) => row.map((direction, columnIndex) =>
|
|
{
|
|
if(direction === null)
|
|
{
|
|
return <div key={ `${ name }-empty-${ rowIndex }-${ columnIndex }` } />;
|
|
}
|
|
|
|
const selected = (value === direction);
|
|
|
|
return (
|
|
<label key={ `${ name }-${ direction }` } className="flex items-center justify-center gap-[2px] cursor-pointer">
|
|
<input checked={ selected } className="form-check-input" name={ name } type="radio" onChange={ () => onChange(direction) } />
|
|
<span className="inline-flex items-center justify-center">
|
|
<WiredDirectionIcon direction={ direction } selected={ selected } />
|
|
</span>
|
|
</label>
|
|
);
|
|
})) }
|
|
</div>
|
|
{ extraOptions.length > 0 &&
|
|
<div className="flex flex-wrap gap-3">
|
|
{ extraOptions.map(option => (
|
|
<label key={ `${ name }-extra-${ option.value }` } className="flex items-center gap-[2px] cursor-pointer" title={ option.label }>
|
|
<input checked={ (value === option.value) } className="form-check-input" name={ name } type="radio" onChange={ () => onChange(option.value) } />
|
|
<img alt="" className="h-auto w-auto object-contain" draggable={ false } src={ option.icon } />
|
|
</label>
|
|
)) }
|
|
</div> }
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const WiredActionMoveRotateUserView: FC<{}> = props =>
|
|
{
|
|
const [ movementDirection, setMovementDirection ] = useState(-1);
|
|
const [ rotationDirection, setRotationDirection ] = useState(-1);
|
|
const { trigger = null, setIntParams = null } = useWired();
|
|
const [ userSource, setUserSource ] = useState<number>(() =>
|
|
{
|
|
if(trigger?.intData?.length > 2) return trigger.intData[2];
|
|
return 0;
|
|
});
|
|
|
|
const save = () => setIntParams([ movementDirection, rotationDirection, userSource ]);
|
|
|
|
const rotationExtraOptions: DirectionExtraOption[] = [
|
|
{ value: ROTATION_CLOCKWISE, icon: iconRotateClockwise, label: LocalizeText('wiredfurni.params.rotatefurni.1') },
|
|
{ value: ROTATION_COUNTER_CLOCKWISE, icon: iconRotateCounterClockwise, label: LocalizeText('wiredfurni.params.rotatefurni.2') }
|
|
];
|
|
|
|
useEffect(() =>
|
|
{
|
|
setMovementDirection((trigger.intData.length > 0) ? trigger.intData[0] : -1);
|
|
setRotationDirection((trigger.intData.length > 1) ? trigger.intData[1] : -1);
|
|
setUserSource((trigger.intData.length > 2) ? trigger.intData[2] : 0);
|
|
}, [ trigger ]);
|
|
|
|
return (
|
|
<WiredActionBaseView
|
|
hasSpecialInput={ true }
|
|
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE }
|
|
save={ save }
|
|
footer={ <WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } /> }>
|
|
<DirectionPicker
|
|
name="wired-move-user-direction"
|
|
title={ LocalizeText('wiredfurni.params.moveuser') }
|
|
noneLabel={ LocalizeText('wiredfurni.params.movefurni.0') }
|
|
value={ movementDirection }
|
|
onChange={ setMovementDirection } />
|
|
<DirectionPicker
|
|
name="wired-rotate-user-direction"
|
|
title={ LocalizeText('wiredfurni.params.rotateuser') }
|
|
noneLabel={ LocalizeText('wiredfurni.params.rotatefurni.0') }
|
|
extraOptions={ rotationExtraOptions }
|
|
value={ rotationDirection }
|
|
onChange={ setRotationDirection } />
|
|
</WiredActionBaseView>
|
|
);
|
|
};
|