Fix AwakeningSelect component
It was completely broken for weapons. We managed to fix the problem by refactoring how data is sent to SelectWithInput but I fear the root error is still there. We also cleaned the component up a bit.
This commit is contained in:
parent
39940abf9f
commit
6023f9ab6a
5 changed files with 60 additions and 87 deletions
|
|
@ -1,103 +1,75 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
|
||||
import SelectWithInput from '~components/SelectWithInput'
|
||||
import SelectItem from '~components/SelectItem'
|
||||
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { weaponAwakening, characterAwakening } from '~data/awakening'
|
||||
import type { Awakening } from '~data/awakening'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
object: 'character' | 'weapon'
|
||||
awakeningType?: number
|
||||
awakeningLevel?: number
|
||||
type?: number
|
||||
level?: number
|
||||
onOpenChange?: (open: boolean) => void
|
||||
sendValidity: (isValid: boolean) => void
|
||||
sendValues: (type: number, level: number) => void
|
||||
}
|
||||
|
||||
const AwakeningSelect = (props: Props) => {
|
||||
const router = useRouter()
|
||||
const locale =
|
||||
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
// States
|
||||
// Data states
|
||||
const [awakeningType, setAwakeningType] = useState(
|
||||
props.object === 'weapon' ? -1 : 1
|
||||
props.object === 'weapon' ? 0 : 1
|
||||
)
|
||||
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||
|
||||
const [maxValue, setMaxValue] = useState(1)
|
||||
|
||||
const [error, setError] = useState('')
|
||||
|
||||
// Data
|
||||
const dataSet = () => {
|
||||
if (props.object === 'character') return characterAwakening
|
||||
else {
|
||||
const weaponDataSet = weaponAwakening
|
||||
const chooseDataset = () => {
|
||||
let list: ItemSkill[] = []
|
||||
|
||||
weaponDataSet.unshift({
|
||||
id: 0,
|
||||
name: {
|
||||
en: 'No awakening',
|
||||
ja: '覚醒なし',
|
||||
},
|
||||
slug: 'no-awakening',
|
||||
minValue: 0,
|
||||
maxValue: 0,
|
||||
fractional: false,
|
||||
})
|
||||
|
||||
return weaponDataSet
|
||||
switch (props.object) {
|
||||
case 'character':
|
||||
list = characterAwakening
|
||||
break
|
||||
case 'weapon':
|
||||
// WARNING: Clonedeep is masking a deeper error
|
||||
// which is running this method every time this component is rerendered
|
||||
// causing multiple "No awakening" items to be added
|
||||
const awakening = cloneDeep(weaponAwakening)
|
||||
awakening.unshift({
|
||||
id: 0,
|
||||
name: {
|
||||
en: 'No awakening',
|
||||
ja: '覚醒なし',
|
||||
},
|
||||
slug: 'no-awakening',
|
||||
minValue: 0,
|
||||
maxValue: 0,
|
||||
fractional: false,
|
||||
})
|
||||
list = awakening
|
||||
break
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// Classes
|
||||
const inputClasses = classNames({
|
||||
Bound: true,
|
||||
Hidden: awakeningType === -1,
|
||||
})
|
||||
|
||||
const errorClasses = classNames({
|
||||
errors: true,
|
||||
visible: error !== '',
|
||||
})
|
||||
|
||||
// Set max value based on object type
|
||||
useEffect(() => {
|
||||
if (props.object === 'character') setMaxValue(9)
|
||||
else if (props.object === 'weapon') setMaxValue(15)
|
||||
}, [props.object])
|
||||
|
||||
// Set default awakening and level based on object type
|
||||
useEffect(() => {
|
||||
let defaultAwakening = 1
|
||||
if (props.object === 'weapon') defaultAwakening = -1
|
||||
const defaultAwakening = props.object === 'weapon' ? 0 : 1
|
||||
const type = props.type != undefined ? props.type : defaultAwakening
|
||||
|
||||
setAwakeningType(
|
||||
props.awakeningType != undefined ? props.awakeningType : defaultAwakening
|
||||
)
|
||||
setAwakeningLevel(props.awakeningLevel ? props.awakeningLevel : 1)
|
||||
}, [props.object, props.awakeningType, props.awakeningLevel])
|
||||
setAwakeningType(type)
|
||||
setAwakeningLevel(props.level ? props.level : 1)
|
||||
}, [props.object, props.type, props.level])
|
||||
|
||||
// Send validity of form when awakening level changes
|
||||
useEffect(() => {
|
||||
props.sendValidity(awakeningLevel > 0 && error === '')
|
||||
}, [props.sendValidity, awakeningLevel, error])
|
||||
props.sendValidity(awakeningLevel > 0)
|
||||
}, [props.sendValidity, awakeningLevel])
|
||||
|
||||
// Classes
|
||||
function changeOpen() {
|
||||
setOpen(!open)
|
||||
if (props.onOpenChange) props.onOpenChange(!open)
|
||||
function changeOpen(open: boolean) {
|
||||
if (props.onOpenChange) props.onOpenChange(open)
|
||||
}
|
||||
|
||||
function handleValueChange(type: number, level: number) {
|
||||
|
|
@ -110,7 +82,7 @@ const AwakeningSelect = (props: Props) => {
|
|||
<div className="Awakening">
|
||||
<SelectWithInput
|
||||
object={`${props.object}_awakening`}
|
||||
dataSet={dataSet()}
|
||||
dataSet={chooseDataset()}
|
||||
selectValue={awakeningType}
|
||||
inputValue={awakeningLevel}
|
||||
onOpenChange={changeOpen}
|
||||
|
|
|
|||
|
|
@ -254,8 +254,8 @@ const CharacterModal = ({
|
|||
<h3>{t('modals.characters.subtitles.awakening')}</h3>
|
||||
<AwakeningSelect
|
||||
object="character"
|
||||
awakeningType={awakeningType}
|
||||
awakeningLevel={awakeningLevel}
|
||||
type={awakeningType}
|
||||
level={awakeningLevel}
|
||||
sendValidity={receiveValidity}
|
||||
sendValues={receiveAwakeningValues}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -72,8 +72,11 @@ const SelectWithInput = ({
|
|||
|
||||
// Set default values from props
|
||||
useEffect(() => {
|
||||
setCurrentItemSkill(dataSet.find((sk) => sk.id === selectValue))
|
||||
setFieldInputValue(inputValue)
|
||||
const found = dataSet.find((sk) => sk.id === selectValue)
|
||||
if (found) {
|
||||
setCurrentItemSkill(found)
|
||||
setFieldInputValue(inputValue)
|
||||
}
|
||||
}, [selectValue, inputValue])
|
||||
|
||||
// Methods: UI state management
|
||||
|
|
@ -98,14 +101,6 @@ const SelectWithInput = ({
|
|||
)
|
||||
})
|
||||
|
||||
if (object === 'weapon_awakening') {
|
||||
options?.unshift(
|
||||
<SelectItem key={-1} value={-1}>
|
||||
{t(`${object}.no_type`)}
|
||||
</SelectItem>
|
||||
)
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
|
|
@ -113,12 +108,18 @@ const SelectWithInput = ({
|
|||
function handleSelectChange(rawValue: string) {
|
||||
const value = parseInt(rawValue)
|
||||
const skill = dataSet.find((sk) => sk.id === value)
|
||||
setCurrentItemSkill(skill)
|
||||
|
||||
if (skill) {
|
||||
setCurrentItemSkill(skill)
|
||||
sendValues(skill.id, fieldInputValue)
|
||||
}
|
||||
}
|
||||
|
||||
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
const value = parseFloat(event.target.value)
|
||||
if (handleInputError(value)) setFieldInputValue(value)
|
||||
|
||||
if (currentItemSkill) sendValues(currentItemSkill.id, value)
|
||||
}
|
||||
|
||||
// Methods: Handle error
|
||||
|
|
@ -169,7 +170,7 @@ const SelectWithInput = ({
|
|||
open={open}
|
||||
disabled={selectDisabled}
|
||||
onValueChange={handleSelectChange}
|
||||
onOpenChange={() => changeOpen()}
|
||||
onOpenChange={changeOpen}
|
||||
onClose={onClose}
|
||||
triggerClass="modal"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ const WeaponModal = ({ gridWeapon, children }: Props) => {
|
|||
|
||||
const [element, setElement] = useState(-1)
|
||||
|
||||
const [awakeningType, setAwakeningType] = useState(-1)
|
||||
const [awakeningType, setAwakeningType] = useState(0)
|
||||
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||
|
||||
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
||||
|
|
@ -298,8 +298,8 @@ const WeaponModal = ({ gridWeapon, children }: Props) => {
|
|||
<h3>{t('modals.weapon.subtitles.awakening')}</h3>
|
||||
<AwakeningSelect
|
||||
object="weapon"
|
||||
awakeningType={gridWeapon.awakening?.type}
|
||||
awakeningLevel={gridWeapon.awakening?.level}
|
||||
type={gridWeapon.awakening?.type}
|
||||
level={gridWeapon.awakening?.level}
|
||||
onOpenChange={receiveAwakeningOpen}
|
||||
sendValidity={receiveValidity}
|
||||
sendValues={receiveAwakeningValues}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ const WeaponUnit = (props: Props) => {
|
|||
props.gridWeapon &&
|
||||
props.gridWeapon.object.awakening &&
|
||||
props.gridWeapon.awakening &&
|
||||
props.gridWeapon.awakening.type >= 0 &&
|
||||
props.gridWeapon.awakening.type > 0 &&
|
||||
props.gridWeapon.awakening.type != null
|
||||
) {
|
||||
const awakening = weaponAwakening.find(
|
||||
|
|
|
|||
Loading…
Reference in a new issue