![{currentAccessory.name[locale]}]({`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/accessory-grid/${currentAccessory.granblue_id}.jpg`})
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": [