-
Notifications
You must be signed in to change notification settings - Fork 244
Updated editor to support unactivated stats #3087
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
8a8d4ba
6b376e7
59d2d60
d52c795
779ff8e
0307960
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -23,35 +23,59 @@ import { | |||||||||||||||||||||
| Box, | ||||||||||||||||||||||
| Button, | ||||||||||||||||||||||
| ButtonGroup, | ||||||||||||||||||||||
| FormControlLabel, | ||||||||||||||||||||||
| Grid, | ||||||||||||||||||||||
| ListItemIcon, | ||||||||||||||||||||||
| ListItemText, | ||||||||||||||||||||||
| MenuItem, | ||||||||||||||||||||||
| Slider, | ||||||||||||||||||||||
| Typography, | ||||||||||||||||||||||
| } from '@mui/material' | ||||||||||||||||||||||
| import Checkbox from '@mui/material/Checkbox' | ||||||||||||||||||||||
| import { useEffect, useMemo, useState } from 'react' | ||||||||||||||||||||||
| import { Trans, useTranslation } from 'react-i18next' | ||||||||||||||||||||||
| import { PercentBadge } from '../../PercentBadge' | ||||||||||||||||||||||
| import { ArtifactStatWithUnit } from '../ArtifactStatKeyDisplay' | ||||||||||||||||||||||
| import type { RollColorKey } from '../util' | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| function getCorrectSubstats( | ||||||||||||||||||||||
| artifact: ICachedArtifact | undefined, | ||||||||||||||||||||||
| isUnactivatedSubstat: boolean, | ||||||||||||||||||||||
| substatIndex: number | ||||||||||||||||||||||
| ) { | ||||||||||||||||||||||
| if ( | ||||||||||||||||||||||
| artifact?.unactivatedSubstats && | ||||||||||||||||||||||
| substatIndex === 3 && | ||||||||||||||||||||||
| isUnactivatedSubstat | ||||||||||||||||||||||
| ) { | ||||||||||||||||||||||
| return artifact.unactivatedSubstats[0] | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| return artifact?.substats[substatIndex] | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export function SubstatInput({ | ||||||||||||||||||||||
| index, | ||||||||||||||||||||||
| artifact, | ||||||||||||||||||||||
| setSubstat, | ||||||||||||||||||||||
| }: { | ||||||||||||||||||||||
| index: number | ||||||||||||||||||||||
| artifact: ICachedArtifact | undefined | ||||||||||||||||||||||
| setSubstat: (index: number, substat: ISubstat) => void | ||||||||||||||||||||||
| setSubstat: ( | ||||||||||||||||||||||
| index: number, | ||||||||||||||||||||||
| substat: ISubstat, | ||||||||||||||||||||||
| isUnactivatedSubstat: boolean | ||||||||||||||||||||||
| ) => void | ||||||||||||||||||||||
| }) { | ||||||||||||||||||||||
| const { t } = useTranslation('artifact') | ||||||||||||||||||||||
| const { mainStatKey = '', rarity = 5 } = artifact ?? {} | ||||||||||||||||||||||
| const [isUnactivatedSubstat, setIsUnactivatedSubstat] = useState(false) | ||||||||||||||||||||||
| const { mainStatKey = '', rarity = 5, level = 0 } = artifact ?? {} | ||||||||||||||||||||||
| const { | ||||||||||||||||||||||
| key = '', | ||||||||||||||||||||||
| value = 0, | ||||||||||||||||||||||
| rolls = [], | ||||||||||||||||||||||
| efficiency = 0, | ||||||||||||||||||||||
| } = artifact?.substats[index] ?? {} | ||||||||||||||||||||||
| } = getCorrectSubstats(artifact, isUnactivatedSubstat, index) ?? {} | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const accurateValue = rolls.reduce((a, b) => a + b, 0) | ||||||||||||||||||||||
| const unit = getUnitStr(key), | ||||||||||||||||||||||
|
|
@@ -89,6 +113,24 @@ export function SubstatInput({ | |||||||||||||||||||||
| [key, rarity] | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||||||||||||||||||||||
| setIsUnactivatedSubstat(event.target.checked) | ||||||||||||||||||||||
| setSubstat(index, { key: key, value: 0 }, event.target.checked) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||
| if (level >= 4) { | ||||||||||||||||||||||
| setIsUnactivatedSubstat(false) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if ( | ||||||||||||||||||||||
| artifact?.unactivatedSubstats?.length && | ||||||||||||||||||||||
| artifact.unactivatedSubstats[0].key | ||||||||||||||||||||||
| ) { | ||||||||||||||||||||||
| setIsUnactivatedSubstat(true) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }, [artifact?.unactivatedSubstats, level]) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return ( | ||||||||||||||||||||||
| <CardThemed bgt="light"> | ||||||||||||||||||||||
| <Box sx={{ display: 'flex', height: '2.5em' }}> | ||||||||||||||||||||||
|
|
@@ -108,7 +150,9 @@ export function SubstatInput({ | |||||||||||||||||||||
| > | ||||||||||||||||||||||
| {key && ( | ||||||||||||||||||||||
| <MenuItem | ||||||||||||||||||||||
| onClick={() => setSubstat(index, { key: '', value: 0 })} | ||||||||||||||||||||||
| onClick={() => | ||||||||||||||||||||||
| setSubstat(index, { key: '', value: 0 }, isUnactivatedSubstat) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| {t('editor.substat.noSubstat')} | ||||||||||||||||||||||
| </MenuItem> | ||||||||||||||||||||||
|
|
@@ -120,7 +164,13 @@ export function SubstatInput({ | |||||||||||||||||||||
| key={k} | ||||||||||||||||||||||
| selected={key === k} | ||||||||||||||||||||||
| disabled={key === k} | ||||||||||||||||||||||
| onClick={() => setSubstat(index, { key: k, value: 0 })} | ||||||||||||||||||||||
| onClick={() => | ||||||||||||||||||||||
| setSubstat( | ||||||||||||||||||||||
| index, | ||||||||||||||||||||||
| { key: k, value: 0 }, | ||||||||||||||||||||||
| isUnactivatedSubstat | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| <ListItemIcon> | ||||||||||||||||||||||
| <StatIcon statKey={k} /> | ||||||||||||||||||||||
|
|
@@ -144,8 +194,14 @@ export function SubstatInput({ | |||||||||||||||||||||
| float={unit === '%'} | ||||||||||||||||||||||
| placeholder={t('editor.substat.selectSub')} | ||||||||||||||||||||||
| value={key ? value : 0} | ||||||||||||||||||||||
| onChange={(value) => setSubstat(index, { key, value: value ?? 0 })} | ||||||||||||||||||||||
| disabled={!key} | ||||||||||||||||||||||
| onChange={(value) => | ||||||||||||||||||||||
| setSubstat( | ||||||||||||||||||||||
| index, | ||||||||||||||||||||||
| { key, value: value ?? 0 }, | ||||||||||||||||||||||
| isUnactivatedSubstat | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| disabled={!key || (isUnactivatedSubstat && index === 3)} | ||||||||||||||||||||||
| error={!!error} | ||||||||||||||||||||||
| inputProps={{ | ||||||||||||||||||||||
| sx: { textAlign: 'right' }, | ||||||||||||||||||||||
|
|
@@ -163,9 +219,17 @@ export function SubstatInput({ | |||||||||||||||||||||
| <Button | ||||||||||||||||||||||
| key={i} | ||||||||||||||||||||||
| color={`roll${clamp(rollOffset + i, 1, 6)}` as any} | ||||||||||||||||||||||
| disabled={(value && !rollNum) || allowedRolls <= 0} | ||||||||||||||||||||||
| disabled={ | ||||||||||||||||||||||
| (value && !rollNum) || | ||||||||||||||||||||||
| allowedRolls <= 0 || | ||||||||||||||||||||||
| (isUnactivatedSubstat && rollNum > 0 && index === 3) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+207
to
+211
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unactivated 4th substat still allows “next roll” buttons. These buttons should be disabled when the substat is marked Unactivated; otherwise users can apply rolls to an unactivated slot. - disabled={
- (value && !rollNum) ||
- allowedRolls <= 0 ||
- (isUnactivatedSubstat && rollNum > 0 && index === 3)
- }
+ disabled={
+ (value && !rollNum) ||
+ allowedRolls <= 0 ||
+ (isUnactivatedSubstat && index === 3)
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| onClick={() => | ||||||||||||||||||||||
| setSubstat(index, { key, value: parseFloat(newValue) }) | ||||||||||||||||||||||
| setSubstat( | ||||||||||||||||||||||
| index, | ||||||||||||||||||||||
| { key, value: parseFloat(newValue) }, | ||||||||||||||||||||||
| isUnactivatedSubstat | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| {newValue} | ||||||||||||||||||||||
|
|
@@ -179,9 +243,13 @@ export function SubstatInput({ | |||||||||||||||||||||
| value={value} | ||||||||||||||||||||||
| marks={marks} | ||||||||||||||||||||||
| setValue={(v) => | ||||||||||||||||||||||
| setSubstat(index, { key, value: (v as number) ?? 0 }) | ||||||||||||||||||||||
| setSubstat( | ||||||||||||||||||||||
| index, | ||||||||||||||||||||||
| { key, value: (v as number) ?? 0 }, | ||||||||||||||||||||||
| isUnactivatedSubstat | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| disabled={!key} | ||||||||||||||||||||||
| disabled={!key || (isUnactivatedSubstat && index === 3)} | ||||||||||||||||||||||
| /> | ||||||||||||||||||||||
| </Box> | ||||||||||||||||||||||
| <Box sx={{ px: 1, pb: 1 }}> | ||||||||||||||||||||||
|
|
@@ -202,7 +270,7 @@ export function SubstatInput({ | |||||||||||||||||||||
| : t('editor.substat.noRoll')} | ||||||||||||||||||||||
| </SqBadge> | ||||||||||||||||||||||
| </Grid> | ||||||||||||||||||||||
| <Grid item flexGrow={1}> | ||||||||||||||||||||||
| <Grid item> | ||||||||||||||||||||||
| {!!rolls.length && | ||||||||||||||||||||||
| [...rolls].sort().map((val, i) => ( | ||||||||||||||||||||||
| <Typography | ||||||||||||||||||||||
|
|
@@ -219,6 +287,24 @@ export function SubstatInput({ | |||||||||||||||||||||
| </Typography> | ||||||||||||||||||||||
| ))} | ||||||||||||||||||||||
| </Grid> | ||||||||||||||||||||||
| <Grid item flexGrow={1}> | ||||||||||||||||||||||
| {index === 3 ? ( | ||||||||||||||||||||||
| <FormControlLabel | ||||||||||||||||||||||
| label={t('editor.unactivated')} | ||||||||||||||||||||||
| control={ | ||||||||||||||||||||||
| <Checkbox | ||||||||||||||||||||||
| checked={isUnactivatedSubstat} | ||||||||||||||||||||||
| onChange={handleChange} | ||||||||||||||||||||||
| sx={{ padding: 0 }} | ||||||||||||||||||||||
| disabled={!artifact || level > 0} | ||||||||||||||||||||||
| ></Checkbox> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| sx={{ ml: 1 }} | ||||||||||||||||||||||
| /> | ||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||
| '' | ||||||||||||||||||||||
| )} | ||||||||||||||||||||||
| </Grid> | ||||||||||||||||||||||
| <Grid item xs="auto" flexShrink={1}> | ||||||||||||||||||||||
| <Typography> | ||||||||||||||||||||||
| <Trans | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -98,9 +98,19 @@ import { UploadExplainationModal } from './UploadExplainationModal' | |||||||||||||||||||||||||||
| const allSubstatFilter = new Set(allSubstatKeys) | ||||||||||||||||||||||||||||
| type ResetMessage = { type: 'reset' } | ||||||||||||||||||||||||||||
| type SubstatMessage = { type: 'substat'; index: number; substat: ISubstat } | ||||||||||||||||||||||||||||
| type UnactivatedSubstatMessage = { | ||||||||||||||||||||||||||||
| type: 'unactivatedSubstat' | ||||||||||||||||||||||||||||
| index: number | ||||||||||||||||||||||||||||
| substat: ISubstat | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| type OverwriteMessage = { type: 'overwrite'; artifact: IArtifact } | ||||||||||||||||||||||||||||
| type UpdateMessage = { type: 'update'; artifact: Partial<IArtifact> } | ||||||||||||||||||||||||||||
| type Message = ResetMessage | SubstatMessage | OverwriteMessage | UpdateMessage | ||||||||||||||||||||||||||||
| type Message = | ||||||||||||||||||||||||||||
| | ResetMessage | ||||||||||||||||||||||||||||
| | SubstatMessage | ||||||||||||||||||||||||||||
| | OverwriteMessage | ||||||||||||||||||||||||||||
| | UpdateMessage | ||||||||||||||||||||||||||||
| | UnactivatedSubstatMessage | ||||||||||||||||||||||||||||
| function artifactReducer( | ||||||||||||||||||||||||||||
| state: IArtifact | undefined, | ||||||||||||||||||||||||||||
| action: Message | ||||||||||||||||||||||||||||
|
|
@@ -114,6 +124,14 @@ function artifactReducer( | |||||||||||||||||||||||||||
| const oldIndex = substat.key | ||||||||||||||||||||||||||||
| ? state!.substats.findIndex((current) => current.key === substat.key) | ||||||||||||||||||||||||||||
| : -1 | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
failchon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats?.length && | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats[0].key | ||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats = [] | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if (oldIndex === -1 || oldIndex === index) | ||||||||||||||||||||||||||||
failchon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
| state!.substats[index] = substat | ||||||||||||||||||||||||||||
| // Already in used, swap the items instead | ||||||||||||||||||||||||||||
|
|
@@ -124,6 +142,39 @@ function artifactReducer( | |||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||
| return { ...state! } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| case 'unactivatedSubstat': { | ||||||||||||||||||||||||||||
failchon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
| if (state?.unactivatedSubstats) { | ||||||||||||||||||||||||||||
| const { substat } = action | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let activeSubstat = null | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if (state!.substats[3].key) { | ||||||||||||||||||||||||||||
| activeSubstat = state!.substats[3] | ||||||||||||||||||||||||||||
| state!.substats[3] = { key: '', value: 0 } | ||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||
| activeSubstat = substat | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const oldIndex = substat.key | ||||||||||||||||||||||||||||
failchon marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
| ? state!.unactivatedSubstats.findIndex( | ||||||||||||||||||||||||||||
| (current) => current.key === substat.key | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| : -1 | ||||||||||||||||||||||||||||
| if (oldIndex === -1 || oldIndex === 0) | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats[0] = activeSubstat | ||||||||||||||||||||||||||||
| // Already in used, swap the items instead | ||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||
| [ | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats[0], | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats[oldIndex], | ||||||||||||||||||||||||||||
| ] = [ | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats[oldIndex], | ||||||||||||||||||||||||||||
| state!.unactivatedSubstats[0], | ||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| console.log(state!.substats, 'subers') | ||||||||||||||||||||||||||||
| return { ...state! } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| case 'overwrite': | ||||||||||||||||||||||||||||
| return action.artifact | ||||||||||||||||||||||||||||
| case 'update': | ||||||||||||||||||||||||||||
|
|
@@ -304,8 +355,9 @@ export function ArtifactEditor({ | |||||||||||||||||||||||||||
| [artifact, artStat, artifactDispatch, fixedSlotKey] | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| const setSubstat = useCallback( | ||||||||||||||||||||||||||||
| (index: number, substat: ISubstat) => { | ||||||||||||||||||||||||||||
| artifactDispatch({ type: 'substat', index, substat }) | ||||||||||||||||||||||||||||
| (index: number, substat: ISubstat, isUnactivatedSubstat: boolean) => { | ||||||||||||||||||||||||||||
| const type = isUnactivatedSubstat ? 'unactivatedSubstat' : 'substat' | ||||||||||||||||||||||||||||
| artifactDispatch({ type: type, index, substat }) | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
|
Comment on lines
392
to
396
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gate unactivated handling to the 4th substat only (prevents cross-row mutations). Right now, any row edit while the toggle is on dispatches as “unactivated”, which explains the “editing 3rd changes 4th” reports. Only the 4th slot can be unactivated—gate by index. - const setSubstat = useCallback(
- (index: number, substat: ISubstat, isUnactivatedSubstat: boolean) => {
- const type = isUnactivatedSubstat ? 'unactivatedSubstat' : 'substat'
- artifactDispatch({ type: type, index, substat })
- },
+ const setSubstat = useCallback(
+ (index: number, substat: ISubstat, isUnactivatedSubstat: boolean) => {
+ const type =
+ isUnactivatedSubstat && index === 3 ? 'unactivatedSubstat' : 'substat'
+ artifactDispatch({ type, index, substat })
+ },📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| [artifactDispatch] | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent level check - useEffect vs checkbox disabled condition.
Line 122 resets
isUnactivatedSubstatwhenlevel >= 4, but line 299 disables the checkbox whenlevel > 0. These should match - if the checkbox is disabled at level 1+, the state should also reset at level 1+. squints at the discrepancy through tired eyesApply this diff to align the conditions:
useEffect(() => { - if (level >= 4) { + if (level > 0) { setIsUnactivatedSubstat(false) }📝 Committable suggestion
🤖 Prompt for AI Agents