--------- Co-authored-by: gguio <nikvish150@gmail.com> Co-authored-by: Vitaly <vital2580@icloud.com>
171 lines
5.1 KiB
TypeScript
171 lines
5.1 KiB
TypeScript
import { useEffect, useState, useContext } from 'react'
|
|
import { customCommandsConfig } from '../customCommands'
|
|
import { ButtonWithMatchesAlert, Context } from './KeybindingsScreen'
|
|
import Button from './Button'
|
|
import styles from './KeybindingsScreen.module.css'
|
|
import Input from './Input'
|
|
|
|
|
|
export type CustomCommand = {
|
|
keys: undefined | string[]
|
|
gamepad: undefined | string[]
|
|
type: string
|
|
inputs: any[]
|
|
}
|
|
|
|
export type CustomCommandsMap = Record<string, CustomCommand>
|
|
|
|
export default (
|
|
{
|
|
customCommands,
|
|
updateCurrBind,
|
|
resetBinding,
|
|
}: {
|
|
customCommands: CustomCommandsMap,
|
|
updateCurrBind: (group: string, action: string) => void,
|
|
resetBinding: (group: string, action: string, inputType: string) => void,
|
|
}
|
|
) => {
|
|
const { userConfig, setUserConfig } = useContext(Context)
|
|
const [customConfig, setCustomConfig] = useState<any>({ ...customCommands })
|
|
|
|
useEffect(() => {
|
|
setUserConfig({ ...userConfig, custom: { ...customConfig } })
|
|
}, [customConfig])
|
|
|
|
const addNewCommand = (type: string) => {
|
|
// max key + 1
|
|
const newKey = String(Math.max(...Object.keys(customConfig).map(Number).filter(key => !isNaN(key)), 0) + 1)
|
|
setCustomConfig(prev => {
|
|
const newCustomConf = { ...prev }
|
|
newCustomConf[newKey] = {
|
|
keys: undefined as string[] | undefined,
|
|
gamepad: undefined as string[] | undefined,
|
|
type,
|
|
inputs: [] as any[]
|
|
}
|
|
return newCustomConf
|
|
})
|
|
}
|
|
|
|
return <>
|
|
<div className={styles.group}>
|
|
{Object.entries(customCommandsConfig).map(([group, { input }]) => (
|
|
<div key={`group-container-${group}`} className={styles.group}>
|
|
<div key={`category-${group}`} className={styles['group-category']}>{group}</div>
|
|
{Object.entries(customConfig).filter(([key, data]) => data.type === group).map((commandData, indexOption) => {
|
|
return <CustomCommandContainer
|
|
key={indexOption}
|
|
indexOption={indexOption}
|
|
commandData={commandData}
|
|
updateCurrBind={updateCurrBind}
|
|
groupData={[group, { input }]}
|
|
setCustomConfig={setCustomConfig}
|
|
resetBinding={resetBinding}
|
|
/>
|
|
})}
|
|
<Button
|
|
onClick={() => addNewCommand(group)}
|
|
icon={'pixelarticons:add-box'}
|
|
style={{
|
|
alignSelf: 'center'
|
|
}}
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</>
|
|
}
|
|
|
|
const CustomCommandContainer = (
|
|
{
|
|
indexOption,
|
|
commandData,
|
|
updateCurrBind,
|
|
setCustomConfig,
|
|
resetBinding,
|
|
groupData
|
|
}
|
|
) => {
|
|
const { userConfig } = useContext(Context)
|
|
|
|
const [commandKey, { keys, gamepad, inputs }] = commandData
|
|
const [group, { input }] = groupData
|
|
|
|
const setInputValue = (optionKey, indexInput, value) => {
|
|
setCustomConfig(prev => {
|
|
const newConfig = { ...prev }
|
|
newConfig[optionKey].inputs = [...prev[optionKey].inputs]
|
|
newConfig[optionKey].inputs[indexInput] = value
|
|
return newConfig
|
|
})
|
|
}
|
|
|
|
return <div style={{ padding: '10px' }}>
|
|
{input.map((obj, indexInput) => {
|
|
const config = typeof obj === 'function' ? obj(inputs) : obj
|
|
if (!config) return null
|
|
|
|
return config.type === 'select'
|
|
? <select key={indexInput} onChange={(e) => {
|
|
setInputValue(commandKey, indexInput, e.target.value)
|
|
}}>{config.options.map((option) => <option key={option} value={option}>{option}</option>)}</select>
|
|
: <Input key={indexInput} rootStyles={{ width: '99%' }} placeholder={config.placeholder} value={inputs[indexInput] ?? ''} onChange={(e) => setInputValue(commandKey, indexInput, e.target.value)} />
|
|
})}
|
|
<div className={styles.actionBinds}>
|
|
{
|
|
userConfig?.['custom']?.[commandKey]?.keys ? <Button
|
|
onClick={() => {
|
|
updateCurrBind(group, commandKey)
|
|
resetBinding('custom', commandKey, 'keyboard')
|
|
}}
|
|
className={styles['undo-keyboard']}
|
|
icon={'pixelarticons:undo'}
|
|
/>
|
|
: null}
|
|
|
|
{[0, 1].map((key, index) => <ButtonWithMatchesAlert
|
|
key={`custom-keyboard-${group}-${commandKey}-${index}`}
|
|
group={'custom'}
|
|
action={commandKey}
|
|
index={index}
|
|
inputType={'keyboard'}
|
|
keys={keys}
|
|
gamepad={gamepad}
|
|
/>
|
|
)}
|
|
|
|
<div style={{ marginRight: 'auto' }} ></div>
|
|
|
|
{
|
|
userConfig?.['custom']?.[commandKey]?.gamepad ? <Button
|
|
onClick={() => {
|
|
updateCurrBind(group, commandKey)
|
|
resetBinding('custom', commandKey, 'gamepad')
|
|
}}
|
|
className={styles['undo-keyboard']}
|
|
icon={'pixelarticons:undo'}
|
|
/>
|
|
: null}
|
|
<ButtonWithMatchesAlert
|
|
group={'custom'}
|
|
action={commandKey}
|
|
index={0}
|
|
inputType={'gamepad'}
|
|
keys={keys}
|
|
gamepad={gamepad}
|
|
/>
|
|
<Button
|
|
onClick={() => {
|
|
setCustomConfig(prev => {
|
|
const { [commandKey]: commandToRemove, ...newConfig } = prev
|
|
return newConfig
|
|
})
|
|
}}
|
|
|
|
style={{ color: 'red' }}
|
|
icon={'pixelarticons:delete'}
|
|
/>
|
|
</div>
|
|
</div>
|
|
}
|