From b50ea1fa31bc6bab7d4aa49c1e90c729f16db95a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 1 Sep 2023 16:13:39 -0700 Subject: [PATCH] (Hotfix) Popover and hovercard fixes (#379) * Fix job accessory popover, so shields and manatura can be selected again * Don't show AX skill section in weapon hovercard if no AX skill is set * Center uncap indicator under item image and fix hovercard header layout * Fix a bug that prevented all ring bonuses from displaying in hovercard * Fix transcendence_step being set to 0 when updating a character's masteries * Fix weapon modal so you can set AX skills on weapons with rupee or exp gain * Ensure job accessory and transcendence popovers open/close properly --- components/HovercardHeader/index.module.scss | 14 +- components/HovercardHeader/index.tsx | 72 ++++++-- .../about/UpdatesPage/index.module.scss | 17 +- components/about/UpdatesPage/index.tsx | 17 ++ .../character/CharacterHovercard/index.tsx | 3 +- components/character/CharacterModal/index.tsx | 4 +- components/common/Alert/index.module.scss | 2 +- .../common/PopoverContent/index.module.scss | 90 ++++++++++ components/common/PopoverContent/index.tsx | 10 +- .../job/JobAccessoryItem/index.module.scss | 2 +- components/job/JobAccessoryItem/index.tsx | 2 +- .../job/JobAccessoryPopover/index.module.scss | 80 +++------ components/job/JobAccessoryPopover/index.tsx | 10 +- components/job/JobImage/index.tsx | 1 + components/mastery/AxSelect/index.tsx | 45 ++--- .../TranscendencePopover/index.module.scss | 34 ---- .../uncap/TranscendencePopover/index.tsx | 36 +++- components/uncap/TranscendenceStar/index.tsx | 167 +++++++++--------- .../uncap/UncapIndicator/index.module.scss | 5 + components/uncap/UncapIndicator/index.tsx | 32 +++- components/weapon/WeaponHovercard/index.tsx | 4 +- .../weapon/WeaponLabelIcon/index.module.scss | 6 + components/weapon/WeaponLabelIcon/index.tsx | 6 + components/weapon/WeaponUnit/index.tsx | 3 +- .../ax/{secondary_18.png => primary_18.png} | Bin .../ax/{secondary_19.png => primary_19.png} | Bin public/locales/en/updates.json | 10 ++ public/locales/ja/updates.json | 10 ++ 28 files changed, 430 insertions(+), 252 deletions(-) rename public/icons/ax/{secondary_18.png => primary_18.png} (100%) rename public/icons/ax/{secondary_19.png => primary_19.png} (100%) diff --git a/components/HovercardHeader/index.module.scss b/components/HovercardHeader/index.module.scss index dcc1117a..55f85153 100644 --- a/components/HovercardHeader/index.module.scss +++ b/components/HovercardHeader/index.module.scss @@ -41,17 +41,19 @@ align-items: center; display: flex; flex-direction: row; - gap: $unit * 2; + justify-content: space-between; + gap: $unit-2x; .icons { display: flex; flex-direction: row; - flex-grow: 1; - gap: $unit; - } + flex-grow: 0; + gap: $unit-half; - .UncapIndicator { - min-width: 100px; + .proficiencies { + display: flex; + gap: $unit; + } } } } diff --git a/components/HovercardHeader/index.tsx b/components/HovercardHeader/index.tsx index 1acf04e8..03266ab1 100644 --- a/components/HovercardHeader/index.tsx +++ b/components/HovercardHeader/index.tsx @@ -4,6 +4,7 @@ import UncapIndicator from '~components/uncap/UncapIndicator' import WeaponLabelIcon from '~components/weapon/WeaponLabelIcon' import styles from './index.module.scss' +import classNames from 'classnames' interface Props { gridObject: GridCharacter | GridSummon | GridWeapon @@ -107,6 +108,61 @@ const HovercardHeader = ({ gridObject, object, type, ...props }: Props) => { } } + const summonProficiency = ( +
+ +
+ ) + + const weaponProficiency = ( +
+ + {'proficiency' in object && !Array.isArray(object.proficiency) && ( + + )} +
+ ) + + const characterProficiency = ( +
+ + + {'proficiency' in object && Array.isArray(object.proficiency) && ( + + )} + + {'proficiency' in object && + Array.isArray(object.proficiency) && + object.proficiency.length > 1 && ( + + )} +
+ ) + + function proficiency() { + switch (type) { + case 'character': + return characterProficiency + case 'summon': + return summonProficiency + case 'weapon': + return weaponProficiency + } + } + return (
@@ -117,21 +173,9 @@ const HovercardHeader = ({ gridObject, object, type, ...props }: Props) => {
-
- - {'proficiency' in object && Array.isArray(object.proficiency) && ( - - )} - {'proficiency' in object && !Array.isArray(object.proficiency) && ( - - )} - {'proficiency' in object && - Array.isArray(object.proficiency) && - object.proficiency.length > 1 && ( - - )} -
+ {proficiency()} { '202302U2': { updates: 1, }, + '1.2.1': { + bugs: 5, + }, } function image( @@ -75,6 +78,20 @@ const UpdatesPage = () => { return (

{common('about.segmented_control.updates')}

+
+
+

1.2.1

+ +
+

Bug fixes

+
    + {[...Array(versionUpdates['1.2.1'].bugs)].map((e, i) => ( +
  • + {updates(`versions.1.2.1.bugs.${i}`)} +
  • + ))} +
+
{ {[...Array(4)].map((e, i) => { const ringIndex = i + 1 const ringStat: ExtendedMastery = - props.gridCharacter.over_mastery[i] + props.gridCharacter.over_mastery[ringIndex] + if (ringStat && ringStat.modifier && ringStat.modifier > 0) { if (ringIndex === 1 || ringIndex === 2) { return masteryElement(overMastery.a, ringStat) diff --git a/components/character/CharacterModal/index.tsx b/components/character/CharacterModal/index.tsx index 09e3622e..fca6a88b 100644 --- a/components/character/CharacterModal/index.tsx +++ b/components/character/CharacterModal/index.tsx @@ -73,7 +73,9 @@ const CharacterModal = ({ const [earring, setEarring] = useState(emptyExtendedMastery) const [awakening, setAwakening] = useState() const [awakeningLevel, setAwakeningLevel] = useState(1) - const [transcendenceStep, setTranscendenceStep] = useState(0) + const [transcendenceStep, setTranscendenceStep] = useState( + gridCharacter.transcendence_step + ) // Refs const headerRef = React.createRef() diff --git a/components/common/Alert/index.module.scss b/components/common/Alert/index.module.scss index 30a755e9..0f63a93a 100644 --- a/components/common/Alert/index.module.scss +++ b/components/common/Alert/index.module.scss @@ -29,7 +29,7 @@ flex-direction: column; gap: $unit-2x; min-width: 20vw; - max-width: 32vw; + max-width: 40vw; padding: $unit * 4; @include breakpoint(tablet) { diff --git a/components/common/PopoverContent/index.module.scss b/components/common/PopoverContent/index.module.scss index 31fd8e86..290b47e2 100644 --- a/components/common/PopoverContent/index.module.scss +++ b/components/common/PopoverContent/index.module.scss @@ -1,3 +1,93 @@ +.popover { + animation: scaleIn $duration-zoom ease-out; + background: var(--dialog-bg); + border-radius: $card-corner; + border: 0.5px solid rgba(0, 0, 0, 0.18); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24); + outline: none; + padding: $unit; + transform-origin: var(--radix-popover-content-transform-origin); + width: var(--radix-popover-trigger-width); + z-index: 5; + + @include breakpoint(phone) { + min-width: auto; + } + + &.raid { + width: auto; + } + + &.flush { + padding: 0; + } +} + +.jobAccessory { + padding: $unit-2x; + min-width: 40vw; + max-width: 40vw; + max-height: 40vh; + overflow-y: auto; + overflow-x: none; + margin-left: $unit-2x; + + h3 { + font-size: $font-regular; + font-weight: $medium; + margin: 0 0 $unit $unit; + } + + &.readOnly { + min-width: inherit; + max-width: inherit; + } + + @include breakpoint(tablet) { + width: initial; + max-width: initial; + } + + @include breakpoint(phone) { + width: initial; + max-width: initial; + } +} + +.transcendence { + display: flex; + flex-direction: column; + gap: $unit-half; + align-items: center; + justify-content: center; + width: $unit-10x; + height: $unit-10x; + + animation: scaleIn $duration-zoom ease-out; + background: var(--dialog-bg); + border-radius: $card-corner; + border: 0.5px solid rgba(0, 0, 0, 0.18); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24); + outline: none; + padding: $unit; + transform-origin: var(--radix-popover-content-transform-origin); + z-index: 32; + + &.open { + opacity: 1; + display: flex; + } + + h4 { + font-size: $font-small; + font-weight: $medium; + } + + .pending { + color: $yellow; + } +} + .arrow { fill: var(--dialog-bg); filter: drop-shadow(0px 1px 1px rgb(0 0 0 / 0.18)); diff --git a/components/common/PopoverContent/index.tsx b/components/common/PopoverContent/index.tsx index 1ccc1c68..b3cb2a8c 100644 --- a/components/common/PopoverContent/index.tsx +++ b/components/common/PopoverContent/index.tsx @@ -20,9 +20,13 @@ export const PopoverContent = React.forwardRef( { children, ...props }: PropsWithChildren, forwardedRef ) { - const classes = classnames(props.className, { - Popover: true, - }) + const classes = classnames( + { + [styles.popover]: true, + }, + props.className?.split(' ').map((a) => styles[a]) + ) + return ( diff --git a/components/job/JobAccessoryItem/index.module.scss b/components/job/JobAccessoryItem/index.module.scss index 1c255ada..8452bb7a 100644 --- a/components/job/JobAccessoryItem/index.module.scss +++ b/components/job/JobAccessoryItem/index.module.scss @@ -1,4 +1,4 @@ -.JobAccessoryItem { +.item { background: none; border-radius: $input-corner; border: none; diff --git a/components/job/JobAccessoryItem/index.tsx b/components/job/JobAccessoryItem/index.tsx index 9b7ccf9d..954d5825 100644 --- a/components/job/JobAccessoryItem/index.tsx +++ b/components/job/JobAccessoryItem/index.tsx @@ -18,7 +18,7 @@ const JobAccessoryItem = ({ accessory, selected }: Props) => { return ( diff --git a/components/job/JobAccessoryPopover/index.module.scss b/components/job/JobAccessoryPopover/index.module.scss index 88ac72d4..2c1389bc 100644 --- a/components/job/JobAccessoryPopover/index.module.scss +++ b/components/job/JobAccessoryPopover/index.module.scss @@ -1,67 +1,37 @@ -.JobAccessory.Popover { - padding: $unit-2x; - min-width: 40vw; - max-width: 40vw; - max-height: 40vh; - overflow-y: scroll; - margin-left: $unit-2x; - - h3 { - font-size: $font-regular; - font-weight: $medium; - margin: 0 0 $unit $unit; - } - - &.ReadOnly { - min-width: inherit; - max-width: inherit; - } +.accessories { + display: grid; + gap: $unit; + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); @include breakpoint(tablet) { - width: initial; - max-width: initial; + grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); + gap: 0; + } +} + +.equippedAccessory { + display: flex; + flex-direction: column; + gap: $unit-2x; + + h3 { + margin: 0; } - @include breakpoint(phone) { - width: initial; - max-width: initial; - } - - .Accessories { - display: grid; - gap: $unit; - grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); - - @include breakpoint(tablet) { - grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); - gap: 0; - } - } - - .EquippedAccessory { + .accessory { display: flex; flex-direction: column; - gap: $unit-2x; + gap: $unit; - h3 { - margin: 0; + h4 { + font-size: $font-small; + font-weight: $medium; + text-align: center; } - .Accessory { - display: flex; - flex-direction: column; - gap: $unit; - - h4 { - font-size: $font-small; - font-weight: $medium; - text-align: center; - } - - img { - border-radius: $item-corner; - width: 150px; - } + img { + border-radius: $item-corner; + width: 150px; } } } diff --git a/components/job/JobAccessoryPopover/index.tsx b/components/job/JobAccessoryPopover/index.tsx index 6986de4f..26c831c0 100644 --- a/components/job/JobAccessoryPopover/index.tsx +++ b/components/job/JobAccessoryPopover/index.tsx @@ -49,8 +49,8 @@ const JobAccessoryPopover = ({ const [open, setOpen] = useState(false) const classes = classNames({ - JobAccessory: true, - ReadOnly: !editable, + jobAccessory: true, + readOnly: !editable, }) // Hooks @@ -91,7 +91,7 @@ const JobAccessoryPopover = ({ )} {accessories.map((accessory) => ( @@ -110,14 +110,14 @@ const JobAccessoryPopover = ({ ) const readOnly = currentAccessory ? ( -
+

{t('equipped')}{' '} {job.accessory_type === 1 ? `${t('accessories.paladin')}s` : t('accessories.manadiver')}

-
+
{currentAccessory.name[locale]} diff --git a/components/mastery/AxSelect/index.tsx b/components/mastery/AxSelect/index.tsx index 7e6e78af..4cf6865d 100644 --- a/components/mastery/AxSelect/index.tsx +++ b/components/mastery/AxSelect/index.tsx @@ -70,8 +70,12 @@ const AXSelect = (props: Props) => { // States const [primaryAxModifier, setPrimaryAxModifier] = useState(-1) const [secondaryAxModifier, setSecondaryAxModifier] = useState(-1) - const [primaryAxValue, setPrimaryAxValue] = useState(0.0) - const [secondaryAxValue, setSecondaryAxValue] = useState(0.0) + const [primaryAxValue, setPrimaryAxValue] = useState( + props.currentSkills ? props.currentSkills[0].strength : 0.0 + ) + const [secondaryAxValue, setSecondaryAxValue] = useState( + props.currentSkills ? props.currentSkills[1].strength : 0.0 + ) useEffect(() => { setupAx1() @@ -146,7 +150,10 @@ const AXSelect = (props: Props) => { // Classes const secondarySetClasses = classNames({ [styles.set]: true, - [styles.hidden]: primaryAxModifier < 0, + [styles.hidden]: + primaryAxModifier < 0 || + primaryAxModifier === 18 || + primaryAxModifier === 19, }) function setupAx1() { @@ -270,9 +277,12 @@ const AXSelect = (props: Props) => { secondaryAxModifierSelect.current && secondaryAxValueInput.current ) { - setupInput(ax[props.axType - 1][value], primaryAxValueInput.current) + setupInput( + ax[props.axType - 1].find((ax) => ax.id === value), + primaryAxValueInput.current + ) + setPrimaryAxValue(0) - primaryAxValueInput.current.value = '' // Reset the secondary AX modifier, reset the AX value and hide the input setSecondaryAxModifier(-1) @@ -302,7 +312,7 @@ const AXSelect = (props: Props) => { const value = parseFloat(event.target.value) let newErrors = { ...errors } - if (primaryAxValueInput.current == event.target) { + if (primaryAxValueInput.current === event.target) { if (handlePrimaryErrors(value)) setPrimaryAxValue(value) } else { if (handleSecondaryErrors(value)) setSecondaryAxValue(value) @@ -310,16 +320,18 @@ const AXSelect = (props: Props) => { } function handlePrimaryErrors(value: number) { - const primaryAxSkill = ax[props.axType - 1][primaryAxModifier] + const primaryAxSkill = ax[props.axType - 1].find( + (ax) => ax.id === primaryAxModifier + ) let newErrors = { ...errors } - if (value < primaryAxSkill.minValue) { + if (primaryAxSkill && value < primaryAxSkill.minValue) { newErrors.axValue1 = t('ax.errors.value_too_low', { name: primaryAxSkill.name[locale], minValue: primaryAxSkill.minValue, suffix: primaryAxSkill.suffix ? primaryAxSkill.suffix : '', }) - } else if (value > primaryAxSkill.maxValue) { + } else if (primaryAxSkill && value > primaryAxSkill.maxValue) { newErrors.axValue1 = t('ax.errors.value_too_high', { name: primaryAxSkill.name[locale], maxValue: primaryAxSkill.maxValue, @@ -327,7 +339,7 @@ const AXSelect = (props: Props) => { }) } else if (!value || value <= 0) { newErrors.axValue1 = t('ax.errors.value_empty', { - name: primaryAxSkill.name[locale], + name: primaryAxSkill?.name[locale], }) } else { newErrors.axValue1 = '' @@ -380,6 +392,7 @@ const AXSelect = (props: Props) => { } function setupInput(ax: ItemSkill | undefined, element: HTMLInputElement) { + console.log(ax) if (ax) { const rangeString = `${ax.minValue}~${ax.maxValue}${ax.suffix || ''}` @@ -431,11 +444,7 @@ const AXSelect = (props: Props) => { hidden: primaryAxModifier < 0, })} bound={true} - value={ - props.currentSkills && props.currentSkills[0] - ? props.currentSkills[0].strength - : 0 - } + value={primaryAxValue} type="number" onChange={handleInputChange} ref={primaryAxValueInput} @@ -469,11 +478,7 @@ const AXSelect = (props: Props) => { hidden: secondaryAxModifier < 0, })} bound={true} - value={ - props.currentSkills && props.currentSkills[1] - ? props.currentSkills[1].strength - : 0 - } + value={secondaryAxValue} type="number" onChange={handleInputChange} ref={secondaryAxValueInput} diff --git a/components/uncap/TranscendencePopover/index.module.scss b/components/uncap/TranscendencePopover/index.module.scss index 311138fe..de6168ff 100644 --- a/components/uncap/TranscendencePopover/index.module.scss +++ b/components/uncap/TranscendencePopover/index.module.scss @@ -1,37 +1,3 @@ -.transcendence { - display: flex; - flex-direction: column; - gap: $unit-half; - align-items: center; - justify-content: center; - width: $unit-10x; - height: $unit-10x; - - animation: scaleIn $duration-zoom ease-out; - background: var(--dialog-bg); - border-radius: $card-corner; - border: 0.5px solid rgba(0, 0, 0, 0.18); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24); - outline: none; - padding: $unit; - transform-origin: var(--radix-popover-content-transform-origin); - z-index: 32; - - &.open { - opacity: 1; - display: flex; - } - - h4 { - font-size: $font-small; - font-weight: $medium; - } - - .pending { - color: $yellow; - } -} - @keyframes scaleIn { 0% { opacity: 0; diff --git a/components/uncap/TranscendencePopover/index.tsx b/components/uncap/TranscendencePopover/index.tsx index 8d11b484..7e5eb1fe 100644 --- a/components/uncap/TranscendencePopover/index.tsx +++ b/components/uncap/TranscendencePopover/index.tsx @@ -17,6 +17,7 @@ interface Props HTMLDivElement > { type: 'character' | 'summon' + starRef: React.RefObject open: boolean stage: number onOpenChange?: (open: boolean) => void @@ -24,8 +25,9 @@ interface Props } const TranscendencePopover = ({ - children, open: popoverOpen, + starRef, + children, type, stage, tabIndex, @@ -45,8 +47,8 @@ const TranscendencePopover = ({ }) useEffect(() => { - if (open) popoverRef.current?.focus() - }, []) + setOpen(popoverOpen) + }, [popoverOpen]) useEffect(() => { if (stage) setCurrentStage(stage) @@ -57,10 +59,6 @@ const TranscendencePopover = ({ else if (type === 'summon') setBaseLevel(200) }, [type]) - useEffect(() => { - setOpen(popoverOpen) - }, [popoverOpen]) - function handleFragmentClicked(newStage: number) { setCurrentStage(newStage) if (sendValue) sendValue(newStage) @@ -70,13 +68,33 @@ const TranscendencePopover = ({ setCurrentStage(newStage) } + function closePopover() { + setOpen(false) + if (onOpenChange) onOpenChange(false) + } + + function handlePointerDownOutside( + event: CustomEvent<{ originalEvent: PointerEvent }> + ) { + const target = event.detail.originalEvent.target as Element + if ( + target && + starRef.current && + target.closest('.TranscendenceStar') !== starRef.current + ) { + closePopover() + } + } + return ( - + {children} { - const [visibleStage, setVisibleStage] = useState(0) - const [currentStage, setCurrentStage] = useState(0) - const [immutable, setImmutable] = useState(false) - - // Classes - const starClasses = classnames({ - [styles.star]: true, - [styles.immutable]: immutable, - [styles.empty]: stage === 0, - [styles.stage1]: stage === 1, - [styles.stage2]: stage === 2, - [styles.stage3]: stage === 3, - [styles.stage4]: stage === 4, - [styles.stage5]: stage === 5, - }) - - const baseImageClasses = classnames( +const TranscendenceStar = React.forwardRef( + function TranscendenceStar( { - [styles.figure]: true, - }, - className?.split(' ').map((c) => styles[c]) - ) + className, + interactive, + stage, + editable, + tabIndex, + onStarClick, + onFragmentClick, + onFragmentHover, + }: Props, + forwardedRef + ) { + const [visibleStage, setVisibleStage] = useState(0) + const [currentStage, setCurrentStage] = useState(0) + const [immutable, setImmutable] = useState(false) - useEffect(() => { - setVisibleStage(stage) - setCurrentStage(stage) - }, [stage]) + // Classes + const starClasses = classnames({ + TranscendenceStar: true, + [styles.star]: true, + [styles.immutable]: immutable, + [styles.empty]: stage === 0, + [styles.stage1]: stage === 1, + [styles.stage2]: stage === 2, + [styles.stage3]: stage === 3, + [styles.stage4]: stage === 4, + [styles.stage5]: stage === 5, + }) - function handleClick() { - if (onStarClick) { - onStarClick() + const baseImageClasses = classnames( + { + [styles.figure]: true, + }, + className?.split(' ').map((c) => styles[c]) + ) + + useEffect(() => { + setVisibleStage(stage) + setCurrentStage(stage) + }, [stage]) + + function handleClick() { + if (onStarClick) onStarClick() } - } - function handleFragmentClick(index: number) { - let newStage = index - if (index === currentStage) newStage = 0 + function handleFragmentClick(index: number) { + let newStage = index + if (index === currentStage) newStage = 0 - setVisibleStage(newStage) - setCurrentStage(newStage) - if (onFragmentClick) onFragmentClick(newStage) - } + setVisibleStage(newStage) + setCurrentStage(newStage) + if (onFragmentClick) onFragmentClick(newStage) + } - function handleFragmentHover(index: number) { - setVisibleStage(index) - if (onFragmentHover) onFragmentHover(index) - } + function handleFragmentHover(index: number) { + setVisibleStage(index) + if (onFragmentHover) onFragmentHover(index) + } - function handleMouseLeave() { - setVisibleStage(currentStage) - if (onFragmentHover) onFragmentHover(currentStage) - } + function handleMouseLeave() { + setVisibleStage(currentStage) + if (onFragmentHover) onFragmentHover(currentStage) + } - return ( -
{}} - onMouseLeave={interactive ? handleMouseLeave : () => {}} - tabIndex={tabIndex} - > -
- {[...Array(NUM_FRAGMENTS)].map((e, i) => { - const loopStage = i + 1 - return interactive ? ( - - ) : ( - '' - ) - })} + return ( +
{}} + onMouseLeave={interactive ? handleMouseLeave : () => {}} + ref={forwardedRef} + tabIndex={tabIndex} + > +
+ {[...Array(NUM_FRAGMENTS)].map((e, i) => { + const loopStage = i + 1 + return interactive ? ( + + ) : ( + '' + ) + })} +
+
- -
- ) -} + ) + } +) TranscendenceStar.defaultProps = { stage: 0, diff --git a/components/uncap/UncapIndicator/index.module.scss b/components/uncap/UncapIndicator/index.module.scss index dca13379..8aa2be94 100644 --- a/components/uncap/UncapIndicator/index.module.scss +++ b/components/uncap/UncapIndicator/index.module.scss @@ -1,6 +1,11 @@ .wrapper { display: flex; + &.hovercard { + min-width: 100px; + justify-content: center; + } + .indicator { display: flex; flex-direction: row; diff --git a/components/uncap/UncapIndicator/index.tsx b/components/uncap/UncapIndicator/index.tsx index 1711c171..5aa144c2 100644 --- a/components/uncap/UncapIndicator/index.tsx +++ b/components/uncap/UncapIndicator/index.tsx @@ -4,8 +4,9 @@ import TranscendencePopover from '~components/uncap/TranscendencePopover' import TranscendenceStar from '~components/uncap/TranscendenceStar' import styles from './index.module.scss' +import classNames from 'classnames' -interface Props { +interface Props extends React.ComponentProps<'div'> { type: 'character' | 'weapon' | 'summon' rarity?: number uncapLevel?: number @@ -25,6 +26,15 @@ const UncapIndicator = (props: Props) => { const [popoverOpen, setPopoverOpen] = useState(false) + const transcendenceStarRef = React.createRef() + + const classes = classNames( + { + [styles.wrapper]: true, + }, + props.className?.split(' ').map((className) => styles[className]) + ) + function setNumStars() { let numStars @@ -74,7 +84,11 @@ const UncapIndicator = (props: Props) => { function sendTranscendenceStage(stage: number) { if (props.updateTranscendence) props.updateTranscendence(stage) - togglePopover(false) + setPopoverOpen(false) + } + + function handleStarClicked() { + if (props.editable) togglePopover(!popoverOpen) } const transcendence = (i: number) => { @@ -82,25 +96,27 @@ const UncapIndicator = (props: Props) => { return props.type === 'character' || props.type === 'summon' ? ( togglePopover(true)} + ref={transcendenceStarRef} + onStarClick={handleStarClicked} /> ) : ( { } return ( -
+
    {Array.from(Array(numStars)).map((x, i) => { if (props.type === 'character' && i > 4) { diff --git a/components/weapon/WeaponHovercard/index.tsx b/components/weapon/WeaponHovercard/index.tsx index 4ffbe6ab..fb1c8ddd 100644 --- a/components/weapon/WeaponHovercard/index.tsx +++ b/components/weapon/WeaponHovercard/index.tsx @@ -229,8 +229,8 @@ const WeaponHovercard = (props: Props) => { /> {props.gridWeapon.object.ax && props.gridWeapon.ax && - props.gridWeapon.ax[0].modifier !== undefined && - props.gridWeapon.ax[0].strength !== undefined && + props.gridWeapon.ax[0].modifier !== null && + props.gridWeapon.ax[0].strength !== null && axSection} {props.gridWeapon.awakening && awakeningSection} {props.gridWeapon.weapon_keys && diff --git a/components/weapon/WeaponLabelIcon/index.module.scss b/components/weapon/WeaponLabelIcon/index.module.scss index 1def7a3a..036ded65 100644 --- a/components/weapon/WeaponLabelIcon/index.module.scss +++ b/components/weapon/WeaponLabelIcon/index.module.scss @@ -4,6 +4,12 @@ height: 25px; width: 60px; + &.small { + background-size: 50px 20px; + height: 20px; + width: 50px; + } + /* Elements */ &.fire.en { diff --git a/components/weapon/WeaponLabelIcon/index.tsx b/components/weapon/WeaponLabelIcon/index.tsx index 84318877..49dd3bf1 100644 --- a/components/weapon/WeaponLabelIcon/index.tsx +++ b/components/weapon/WeaponLabelIcon/index.tsx @@ -6,6 +6,7 @@ import styles from './index.module.scss' interface Props { labelType: string + size: 'small' | 'normal' } const WeaponLabelIcon = (props: Props) => { @@ -13,6 +14,7 @@ const WeaponLabelIcon = (props: Props) => { const classes = classNames({ [styles.icon]: true, + [styles.small]: props.size === 'small', [styles[props.labelType]]: true, [styles.en]: router.locale === 'en', [styles.ja]: router.locale === 'ja', @@ -21,4 +23,8 @@ const WeaponLabelIcon = (props: Props) => { return } +WeaponLabelIcon.defaultProps = { + size: 'normal', +} + export default WeaponLabelIcon diff --git a/components/weapon/WeaponUnit/index.tsx b/components/weapon/WeaponUnit/index.tsx index 4209c53a..12b3574e 100644 --- a/components/weapon/WeaponUnit/index.tsx +++ b/components/weapon/WeaponUnit/index.tsx @@ -448,7 +448,8 @@ const WeaponUnit = ({ gridWeapon.ax && gridWeapon.ax.length > 0 ) { - for (let i = 0; i < gridWeapon.ax.length; i++) { + const numSkills = gridWeapon.ax[1].modifier ? 2 : 1 + for (let i = 0; i < numSkills; i++) { const image = axImage(i) if (image) images.push(image) } diff --git a/public/icons/ax/secondary_18.png b/public/icons/ax/primary_18.png similarity index 100% rename from public/icons/ax/secondary_18.png rename to public/icons/ax/primary_18.png diff --git a/public/icons/ax/secondary_19.png b/public/icons/ax/primary_19.png similarity index 100% rename from public/icons/ax/secondary_19.png rename to public/icons/ax/primary_19.png diff --git a/public/locales/en/updates.json b/public/locales/en/updates.json index e019f33a..385f3ea9 100644 --- a/public/locales/en/updates.json +++ b/public/locales/en/updates.json @@ -19,6 +19,16 @@ "uncap": "Uncap" }, "versions": { + "1.2.1": { + "bugs": [ + "Job accessory popover has been fixed, so Paladin shields and Manadiver manatura can be selected again", + "The AX skill section no longer shows up in the weapon hovercard if no AX skills are set", + "The top of the character hovercard has been slightly refined", + "Fixed a bug that prevented all character over mastery (ring) bonuses from being displayed", + "Fixed a bug that reset a character's transcendence level if their mastery values are set", + "Fixed a bug that prevented setting the value for Rupee Gain or EXP Gain AX skills on weapons" + ] + }, "1.2.0": { "notes": "I'm very bad at writing actual release notes, so this is a consolidation of the bigger features released in the last six months. Don't worry: there's some new stuff here too!\nThe next features (in no particular order) will be: a way to define roles and substitutions for characters, a collection tracker and hopefully making progress on guides. That's a lot, but I'll chip away at it bit by bit.\nAs always, if you have any feedback, feel free to reach out in the granblue-tools Discord. Thanks for using granblue.team!", "features": [ diff --git a/public/locales/ja/updates.json b/public/locales/ja/updates.json index 3e2de47f..5e0ba2e1 100644 --- a/public/locales/ja/updates.json +++ b/public/locales/ja/updates.json @@ -19,6 +19,16 @@ "uncap": "上限解放" }, "versions": { + "1.2.1": { + "bugs": [ + "ジョブアクセサリーのメニューが修正され、パラディンの盾やマナダイバーのマナベリーが再び選択できるようになりました", + "EXスキルが設定されていない場合、武器ホバーカードにEXスキルの項目が表示されなくなりました", + "キャラクターホバーカードのトップが少し洗練されました", + "キャラクターホバーカードにリミットボーナスを全部表示しないバグを修正しました", + "キャラクターのボーナス値が設定されている場合、キャラクターの超越レベルがリセットされるバグを修正しました", + "武器にルピーUPまたはEXP UPのEXスキルの値を設定できないバグを修正しました" + ] + }, "1.2.0": { "notes": "I'm very bad at writing actual release notes, so this is a consolidation of the bigger features released in the last six months. Don't worry: there's some new stuff here too!\nThe next features (in no particular order) will be: a way to define roles and substitutions for characters, a collection tracker and hopefully making progress on guides. That's a lot, but I'll chip away at it bit by bit.\nAs always, if you have any feedback, feel free to reach out in the granblue-tools Discord. Thanks for using granblue.team!", "features": [