Update all files with new object structure

This commit is contained in:
Justin Edmund 2023-07-07 05:43:02 -07:00
parent 500b7ffbbf
commit d42927623e
80 changed files with 990 additions and 929 deletions

View file

@ -3,12 +3,13 @@ import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
import classNames from 'classnames'
import * as ElementTransformer from '~transformers/ElementTransformer'
import * as ToggleGroup from '@radix-ui/react-toggle-group'
import styles from './index.module.scss'
interface Props {
currentElement: number
sendValue: (value: number) => void
currentElement: GranblueElement
sendValue: (value: GranblueElement) => void
}
const ElementToggle = ({ currentElement, sendValue, ...props }: Props) => {
@ -24,7 +25,7 @@ const ElementToggle = ({ currentElement, sendValue, ...props }: Props) => {
// Methods: Handlers
const handleElementChange = (value: string) => {
const newElement = parseInt(value)
const newElement = ElementTransformer.toObject(parseInt(value))
setElement(newElement)
sendValue(newElement)
}

View file

@ -8,6 +8,7 @@ import 'fix-date'
import { accountState } from '~utils/accountState'
import { formatTimeAgo } from '~utils/timeAgo'
import { ElementMap } from '~utils/elements'
import Button from '~components/common/Button'
@ -19,8 +20,11 @@ interface Props {
shortcode: string
id: string
name: string
raid: Raid
grid: GridWeapon[]
raid?: Raid
weapons: {
mainWeapon?: GridWeapon
allWeapons: GridArray<GridWeapon>
}
user?: User
fullAuto: boolean
autoGuard: boolean
@ -69,27 +73,10 @@ const GridRep = (props: Props) => {
})
useEffect(() => {
const newWeapons = Array(numWeapons)
const gridWeapons = Array(numWeapons)
let foundMainhand = false
for (const [key, value] of Object.entries(props.grid)) {
if (value.position == -1) {
setMainhand(value.object)
foundMainhand = true
} else if (!value.mainhand && value.position != null) {
newWeapons[value.position] = value.object
gridWeapons[value.position] = value
}
}
if (!foundMainhand) {
setMainhand(undefined)
}
setWeapons(newWeapons)
setGrid(gridWeapons)
}, [props.grid])
setMainhand(props.weapons.mainWeapon?.object)
setWeapons(Object.values(props.weapons.allWeapons).map((w) => w?.object))
setGrid(props.weapons.allWeapons)
}, [props.weapons])
function navigate() {
props.onClick(props.shortcode)
@ -99,22 +86,16 @@ const GridRep = (props: Props) => {
let url = ''
if (mainhand) {
const weapon = Object.values(props.grid).find(
(w) => w && w.object.id === mainhand.id
)
const weapon = props.weapons.mainWeapon
if (mainhand.element == 0 && weapon && weapon.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.granblue_id}_${weapon.element}.jpg`
if (mainhand.element === ElementMap.null && weapon && weapon.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.granblueId}_${weapon.element}.jpg`
} else {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.granblue_id}.jpg`
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.granblueId}.jpg`
}
}
return mainhand && props.grid[0] ? (
<img alt={mainhand.name[locale]} src={url} />
) : (
''
)
return mainhand && <img alt={mainhand.name[locale]} src={url} />
}
function generateGridImage(position: number) {
@ -124,17 +105,17 @@ const GridRep = (props: Props) => {
const gridWeapon = grid[position]
if (weapon && gridWeapon) {
if (weapon.element == 0 && gridWeapon.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}_${gridWeapon.element}.jpg`
if (weapon.element === ElementMap.null && gridWeapon.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}_${gridWeapon.element}.jpg`
} else {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg`
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}.jpg`
}
}
return weapons[position] ? (
<img alt={weapons[position]?.name[locale]} src={url} />
) : (
''
return (
weapons[position] && (
<img alt={weapons[position]?.name[locale]} src={url} />
)
)
}
@ -215,24 +196,22 @@ const GridRep = (props: Props) => {
</div>
</div>
{account.authorized &&
((props.user && account.user && account.user.id !== props.user.id) ||
!props.user) ? (
<Link href="#">
<Button
className={classNames({
save: true,
saved: props.favorited,
})}
leftAccessoryIcon={<SaveIcon className="stroke" />}
active={props.favorited}
bound={true}
size="small"
onClick={sendSaveData}
/>
</Link>
) : (
''
)}
((props.user && account.user && account.user.id !== props.user.id) ||
!props.user) && (
<Link href="#">
<Button
className={classNames({
save: true,
saved: props.favorited,
})}
leftAccessoryIcon={<SaveIcon className="stroke" />}
active={props.favorited}
bound={true}
size="small"
onClick={sendSaveData}
/>
</Link>
)}
</div>
<div className={styles.attributed}>
{attribution()}

View file

@ -2,6 +2,7 @@ import { useRouter } from 'next/router'
import UncapIndicator from '~components/uncap/UncapIndicator'
import WeaponLabelIcon from '~components/weapon/WeaponLabelIcon'
import { ElementMap } from '~utils/elements'
import styles from './index.module.scss'
@ -34,10 +35,11 @@ const HovercardHeader = ({ gridObject, object, type, ...props }: Props) => {
const overlay = () => {
if (type === 'character') {
const gridCharacter = gridObject as GridCharacter
if (gridCharacter.perpetuity) return <i className={styles.perpetuity} />
if (gridCharacter.mastery.perpetuity)
return <i className={styles.perpetuity} />
} else if (type === 'summon') {
const gridSummon = gridObject as GridSummon
if (gridSummon.quick_summon) return <i className={styles.quickSummon} />
if (gridSummon.quickSummon) return <i className={styles.quickSummon} />
}
}
@ -47,11 +49,11 @@ const HovercardHeader = ({ gridObject, object, type, ...props }: Props) => {
// Change the image based on the uncap level
let suffix = '01'
if (gridCharacter.uncap_level == 6) suffix = '04'
else if (gridCharacter.uncap_level == 5) suffix = '03'
else if (gridCharacter.uncap_level > 2) suffix = '02'
if (gridCharacter.uncapLevel == 6) suffix = '04'
else if (gridCharacter.uncapLevel == 5) suffix = '03'
else if (gridCharacter.uncapLevel > 2) suffix = '02'
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-grid/${character.granblue_id}_${suffix}.jpg`
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-grid/${character.granblueId}_${suffix}.jpg`
}
const summonImage = () => {
@ -71,29 +73,29 @@ const HovercardHeader = ({ gridObject, object, type, ...props }: Props) => {
let suffix = ''
if (
upgradedSummons.indexOf(summon.granblue_id.toString()) != -1 &&
gridSummon.uncap_level == 5
upgradedSummons.indexOf(summon.granblueId.toString()) != -1 &&
gridSummon.uncapLevel == 5
) {
suffix = '_02'
} else if (
gridSummon.object.uncap.xlb &&
gridSummon.transcendence_step > 0
gridSummon.transcendenceStep > 0
) {
suffix = '_03'
}
// Generate the correct source for the summon
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblue_id}${suffix}.jpg`
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblueId}${suffix}.jpg`
}
const weaponImage = () => {
const gridWeapon = gridObject as GridWeapon
const weapon = object as Weapon
if (gridWeapon.object.element == 0 && gridWeapon.element)
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}_${gridWeapon.element}.jpg`
if (gridWeapon.object.element === ElementMap.null && gridWeapon.element)
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}_${gridWeapon.element}.jpg`
else
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg`
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}.jpg`
}
const image = () => {
@ -118,7 +120,7 @@ const HovercardHeader = ({ gridObject, object, type, ...props }: Props) => {
</div>
<div className={styles.subInfo}>
<div className={styles.icons}>
<WeaponLabelIcon labelType={Element[object.element]} />
<WeaponLabelIcon labelType={object.element.slug} />
{'proficiency' in object && Array.isArray(object.proficiency) && (
<WeaponLabelIcon labelType={Proficiency[object.proficiency[0]]} />
)}
@ -136,9 +138,7 @@ const HovercardHeader = ({ gridObject, object, type, ...props }: Props) => {
ulb={object.uncap.ulb || false}
flb={object.uncap.flb || false}
transcendenceStage={
'transcendence_step' in gridObject
? gridObject.transcendence_step
: 0
'transcendenceStep' in gridObject ? gridObject.transcendenceStep : 0
}
special={'special' in object ? object.special : false}
/>

View file

@ -75,7 +75,7 @@ const Layout = ({ children }: PropsWithChildren<Props>) => {
return (
<>
{appState.version ? ServerAvailable() : ''}
{appState.version && ServerAvailable()}
<main>{children}</main>
</>
)

View file

@ -18,7 +18,7 @@ export type MentionRef = {
}
export type MentionSuggestion = {
granblue_id: string
granblueId: string
name: {
[key: string]: string
en: string
@ -101,10 +101,10 @@ export const MentionList = forwardRef<MentionRef, Props>(
alt={item.name[locale]}
src={
item.type === 'character'
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/${item.type}-square/${item.granblue_id}_01.jpg`
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/${item.type}-square/${item.granblueId}_01.jpg`
: item.type === 'job'
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${item.granblue_id}.png`
: `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/${item.type}-square/${item.granblue_id}.jpg`
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${item.granblueId}.png`
: `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/${item.type}-square/${item.granblueId}.jpg`
}
/>
</div>

View file

@ -83,8 +83,8 @@ const ChangelogUnit = ({ id, type, image }: Props) => {
return (
<div className={styles.unit} key={id}>
<img alt={item ? item.name[locale] : ''} src={imageUrl()} />
<h4>{item ? item.name[locale] : ''}</h4>
<img alt={item && item.name[locale]} src={imageUrl()} />
<h4>{item && item.name[locale]}</h4>
</div>
)
}

View file

@ -9,6 +9,7 @@ import Button from '~components/common/Button'
import Overlay from '~components/common/Overlay'
import { appState } from '~utils/appState'
import { ElementMap } from '~utils/elements'
import styles from './index.module.scss'
@ -46,21 +47,22 @@ const CharacterConflictModal = (props: Props) => {
else if (uncap > 2) suffix = '02'
// Special casing for Lyria (and Young Cat eventually)
if (character?.granblue_id === '3030182000') {
let element = 1
if (character?.granblueId === '3030182000') {
let element: GranblueElement | undefined
if (
appState.grid.weapons.mainWeapon &&
appState.grid.weapons.mainWeapon.element
) {
element = appState.grid.weapons.mainWeapon.element
} else if (appState.party.element != 0) {
element = appState.party.element
} else {
element = ElementMap.wind
}
suffix = `${suffix}_0${element}`
suffix = `${suffix}_0${element?.id}`
}
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-square/${character?.granblue_id}_${suffix}.jpg`
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-square/${character?.granblueId}_${suffix}.jpg`
}
function openChange(open: boolean) {
@ -91,7 +93,7 @@ const CharacterConflictModal = (props: Props) => {
<li className={styles.character} key={`conflict-${i}`}>
<img
alt={character.object.name[locale]}
src={imageUrl(character.object, character.uncap_level)}
src={imageUrl(character.object, character.uncapLevel)}
/>
<span>{character.object.name[locale]}</span>
</li>

View file

@ -23,7 +23,7 @@ import styles from './index.module.scss'
interface Props {
new: boolean
editable: boolean
characters?: GridCharacter[]
characters?: GridArray<GridCharacter>
createParty: (details?: DetailsObject) => Promise<Party>
pushHistory?: (path: string) => void
}
@ -76,16 +76,16 @@ const CharacterGrid = (props: Props) => {
}>({})
useEffect(() => {
setJob(appState.party.job)
setJobSkills(appState.party.jobSkills)
setJobAccessory(appState.party.accessory)
setJob(appState.party.protagonist.job)
setJobSkills(appState.party.protagonist.skills)
setJobAccessory(appState.party.protagonist.accessory)
}, [appState])
// Initialize an array of current uncap values for each characters
useEffect(() => {
let initialPreviousUncapValues: { [key: number]: number } = {}
Object.values(appState.grid.characters).map((o) => {
o ? (initialPreviousUncapValues[o.position] = o.uncap_level) : 0
Object.values(appState.party.grid.characters).map((o) => {
o ? (initialPreviousUncapValues[o.position] = o.uncapLevel) : 0
})
setPreviousUncapValues(initialPreviousUncapValues)
}, [appState.grid.characters])
@ -140,7 +140,7 @@ const CharacterGrid = (props: Props) => {
party_id: partyId,
character_id: character.id,
position: position,
uncap_level: characterUncapLevel(character),
uncapLevel: characterUncapLevel(character),
},
})
}
@ -214,10 +214,10 @@ const CharacterGrid = (props: Props) => {
const team = response.data
setJob(team.job)
appState.party.job = team.job
appState.party.protagonist.job = team.job
setJobSkills(team.job_skills)
appState.party.jobSkills = team.job_skills
appState.party.protagonist.skills = team.job_skills
}
}
@ -244,7 +244,7 @@ const CharacterGrid = (props: Props) => {
// Update the current skills
const newSkills = response.data.job_skills
setJobSkills(newSkills)
appState.party.jobSkills = newSkills
appState.party.protagonist.skills = newSkills
})
.catch((error) => {
const data = error.response.data
@ -268,7 +268,7 @@ const CharacterGrid = (props: Props) => {
// Update the current skills
const newSkills = response.data.job_skills
setJobSkills(newSkills)
appState.party.jobSkills = newSkills
appState.party.protagonist.skills = newSkills
})
.catch((error) => {
const data = error.response.data
@ -291,7 +291,7 @@ const CharacterGrid = (props: Props) => {
)
const team = response.data.party
setJobAccessory(team.accessory)
appState.party.accessory = team.accessory
appState.party.protagonist.accessory = team.accessory
}
}
@ -380,7 +380,7 @@ const CharacterGrid = (props: Props) => {
) => {
const character = appState.grid.characters[position]
if (character && uncapLevel) {
character.uncap_level = uncapLevel
character.uncapLevel = uncapLevel
appState.grid.characters[position] = character
}
}
@ -390,7 +390,7 @@ const CharacterGrid = (props: Props) => {
let newPreviousValues = { ...previousUncapValues }
if (grid.characters[position]) {
newPreviousValues[position] = grid.characters[position]?.uncap_level
newPreviousValues[position] = grid.characters[position]?.uncapLevel
setPreviousUncapValues(newPreviousValues)
}
}
@ -407,7 +407,7 @@ const CharacterGrid = (props: Props) => {
const payload = {
character: {
uncap_level: stage > 0 ? 6 : 5,
uncapLevel: stage > 0 ? 6 : 5,
transcendence_step: stage,
},
}
@ -476,7 +476,7 @@ const CharacterGrid = (props: Props) => {
) => {
const character = appState.grid.characters[position]
if (character && stage !== undefined) {
character.transcendence_step = stage
character.transcendenceStep = stage
appState.grid.characters[position] = character
}
}
@ -486,7 +486,7 @@ const CharacterGrid = (props: Props) => {
let newPreviousValues = { ...previousUncapValues }
if (grid.characters[position]) {
newPreviousValues[position] = grid.characters[position]?.uncap_level
newPreviousValues[position] = grid.characters[position]?.uncapLevel
setPreviousTranscendenceStages(newPreviousValues)
}
}

View file

@ -2,14 +2,13 @@ import React from 'react'
import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
import Button from '~components/common/Button'
import {
Hovercard,
HovercardContent,
HovercardTrigger,
} from '~components/common/Hovercard'
import Button from '~components/common/Button'
import WeaponLabelIcon from '~components/weapon/WeaponLabelIcon'
import UncapIndicator from '~components/uncap/UncapIndicator'
import HovercardHeader from '~components/HovercardHeader'
import {
overMastery,
@ -19,7 +18,6 @@ import {
import { ExtendedMastery } from '~types'
import styles from './index.module.scss'
import HovercardHeader from '~components/HovercardHeader'
interface Props {
gridCharacter: GridCharacter
@ -33,8 +31,7 @@ const CharacterHovercard = (props: Props) => {
const locale =
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
const tintElement = Element[props.gridCharacter.object.element]
const tintElement = props.gridCharacter.object.element.slug
function goTo() {
const urlSafeName = props.gridCharacter.object.name.en.replaceAll(' ', '_')
@ -65,7 +62,7 @@ const CharacterHovercard = (props: Props) => {
}
const overMasterySection = () => {
if (props.gridCharacter && props.gridCharacter.over_mastery) {
if (props.gridCharacter && props.gridCharacter.mastery.overMastery) {
return (
<section className={styles.mastery}>
<h5 className={tintElement}>
@ -75,7 +72,7 @@ const CharacterHovercard = (props: Props) => {
{[...Array(4)].map((e, i) => {
const ringIndex = i + 1
const ringStat: ExtendedMastery =
props.gridCharacter.over_mastery[i]
props.gridCharacter.mastery.overMastery[i]
if (ringStat && ringStat.modifier && ringStat.modifier > 0) {
if (ringIndex === 1 || ringIndex === 2) {
return masteryElement(overMastery.a, ringStat)
@ -95,8 +92,8 @@ const CharacterHovercard = (props: Props) => {
const aetherialMasterySection = () => {
if (
props.gridCharacter &&
props.gridCharacter.aetherial_mastery &&
props.gridCharacter.aetherial_mastery.modifier > 0
props.gridCharacter.mastery.aetherialMastery &&
props.gridCharacter.mastery.aetherialMastery.modifier > 0
) {
return (
<section className={styles.mastery}>
@ -106,7 +103,7 @@ const CharacterHovercard = (props: Props) => {
<ul>
{masteryElement(
aetherialMastery,
props.gridCharacter.aetherial_mastery
props.gridCharacter.mastery.aetherialMastery
)}
</ul>
</section>
@ -115,7 +112,7 @@ const CharacterHovercard = (props: Props) => {
}
const permanentMasterySection = () => {
if (props.gridCharacter && props.gridCharacter.perpetuity) {
if (props.gridCharacter && props.gridCharacter.mastery.perpetuity) {
return (
<section className={styles.mastery}>
<h5 className={tintElement}>
@ -135,7 +132,7 @@ const CharacterHovercard = (props: Props) => {
}
const awakeningSection = () => {
const gridAwakening = props.gridCharacter.awakening
const gridAwakening = props.gridCharacter.mastery.awakening
if (gridAwakening) {
return (

View file

@ -85,16 +85,16 @@ const CharacterModal = ({
}, [modalOpen])
useEffect(() => {
if (gridCharacter.aetherial_mastery) {
if (gridCharacter.mastery.aetherialMastery) {
setEarring({
modifier: gridCharacter.aetherial_mastery.modifier,
strength: gridCharacter.aetherial_mastery.strength,
modifier: gridCharacter.mastery.aetherialMastery.modifier,
strength: gridCharacter.mastery.aetherialMastery.strength,
})
}
setAwakening(gridCharacter.awakening.type)
setAwakeningLevel(gridCharacter.awakening.level)
setPerpetuity(gridCharacter.perpetuity)
setAwakening(gridCharacter.mastery.awakening.type)
setAwakeningLevel(gridCharacter.mastery.awakening.level)
setPerpetuity(gridCharacter.mastery.perpetuity)
}, [gridCharacter])
// Prepare the GridWeaponObject to send to the server
@ -144,7 +144,7 @@ const CharacterModal = ({
rings ||
aetherialMastery ||
awakening ||
gridCharacter.perpetuity !== perpetuity
gridCharacter.mastery.perpetuity !== perpetuity
)
}
@ -159,10 +159,11 @@ const CharacterModal = ({
// Check if the current ringset is empty on the current GridCharacter and our local state
const isEmptyRingset =
gridCharacter.over_mastery === undefined && isEqual(emptyRingset, rings)
gridCharacter.mastery.overMastery === undefined &&
isEqual(emptyRingset, rings)
// Check if the ringset in local state is different from the one on the current GridCharacter
const ringsChanged = !isEqual(gridCharacter.over_mastery, rings)
const ringsChanged = !isEqual(gridCharacter.mastery.overMastery, rings)
// Return true if the ringset has been modified and is not empty
return ringsChanged && !isEmptyRingset
@ -177,12 +178,12 @@ const CharacterModal = ({
// Check if the current earring is empty on the current GridCharacter and our local state
const isEmptyRingset =
gridCharacter.aetherial_mastery === undefined &&
gridCharacter.mastery.aetherialMastery === undefined &&
isEqual(emptyAetherialMastery, earring)
// Check if the earring in local state is different from the one on the current GridCharacter
const aetherialMasteryChanged = !isEqual(
gridCharacter.aetherial_mastery,
gridCharacter.mastery.aetherialMastery,
earring
)
@ -193,8 +194,8 @@ const CharacterModal = ({
function awakeningChanged() {
// Check if the awakening in local state is different from the one on the current GridCharacter
const awakeningChanged =
!isEqual(gridCharacter.awakening.type, awakening) ||
gridCharacter.awakening.level !== awakeningLevel
!isEqual(gridCharacter.mastery.awakening.type, awakening) ||
gridCharacter.mastery.awakening.level !== awakeningLevel
// Return true if the awakening has been modified and is not empty
return awakeningChanged
@ -248,17 +249,17 @@ const CharacterModal = ({
function close() {
setEarring({
modifier: gridCharacter.aetherial_mastery
? gridCharacter.aetherial_mastery.modifier
modifier: gridCharacter.mastery.aetherialMastery
? gridCharacter.mastery.aetherialMastery.modifier
: 0,
strength: gridCharacter.aetherial_mastery
? gridCharacter.aetherial_mastery.strength
strength: gridCharacter.mastery.aetherialMastery
? gridCharacter.mastery.aetherialMastery.strength
: 0,
})
setRings(gridCharacter.over_mastery || emptyExtendedMastery)
setAwakening(gridCharacter.awakening.type)
setAwakeningLevel(gridCharacter.awakening.level)
setRings(gridCharacter.mastery.overMastery || emptyExtendedMastery)
setAwakening(gridCharacter.mastery.awakening.type)
setAwakeningLevel(gridCharacter.mastery.awakening.level)
setAlertOpen(false)
setOpen(false)
@ -305,13 +306,13 @@ const CharacterModal = ({
object="earring"
dataSet={elementalizeAetherialMastery(gridCharacter)}
selectValue={
gridCharacter.aetherial_mastery
? gridCharacter.aetherial_mastery.modifier
gridCharacter.mastery.aetherialMastery
? gridCharacter.mastery.aetherialMastery.modifier
: 0
}
inputValue={
gridCharacter.aetherial_mastery
? gridCharacter.aetherial_mastery.strength
gridCharacter.mastery.aetherialMastery
? gridCharacter.mastery.aetherialMastery.strength
: 0
}
sendValidity={receiveValidity}
@ -325,8 +326,8 @@ const CharacterModal = ({
<h3>{t('modals.characters.subtitles.awakening')}</h3>
<AwakeningSelectWithInput
dataSet={gridCharacter.object.awakenings}
awakening={gridCharacter.awakening.type}
level={gridCharacter.awakening.level}
awakening={gridCharacter.mastery.awakening.type}
level={gridCharacter.mastery.awakening.level}
defaultAwakening={
gridCharacter.object.awakenings.find(
(a) => a.slug === 'character-balanced'
@ -364,7 +365,7 @@ const CharacterModal = ({
title={gridCharacter.object.name[locale]}
subtitle={t('modals.characters.title')}
image={{
src: `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-square/${gridCharacter.object.granblue_id}_01.jpg`,
src: `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-square/${gridCharacter.object.granblueId}_01.jpg`,
alt: gridCharacter.object.name[locale],
}}
/>

View file

@ -21,10 +21,10 @@ const CharacterResult = (props: Props) => {
const character = props.data
const characterUrl = () => {
let url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-grid/${character.granblue_id}_01.jpg`
let url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-grid/${character.granblueId}_01.jpg`
if (character.granblue_id === '3030182000') {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-grid/${character.granblue_id}_01_01.jpg`
if (character.granblueId === '3030182000') {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-grid/${character.granblueId}_01_01.jpg`
}
return url
@ -42,7 +42,7 @@ const CharacterResult = (props: Props) => {
special={character.special}
/>
<div className={styles.tags}>
<WeaponLabelIcon labelType={Element[character.element]} />
<WeaponLabelIcon labelType={character.element.slug} />
</div>
</div>
</li>

View file

@ -21,6 +21,7 @@ import UncapIndicator from '~components/uncap/UncapIndicator'
import api from '~utils/api'
import { appState } from '~utils/appState'
import { ElementMap } from '~utils/elements'
import PlusIcon from '~public/icons/Add.svg'
import SettingsIcon from '~public/icons/Settings.svg'
@ -109,7 +110,7 @@ const CharacterUnit = ({
function handlePerpetuityClick() {
if (gridCharacter) {
let object: PerpetuityObject = {
character: { perpetuity: !gridCharacter.perpetuity },
character: { perpetuity: !gridCharacter.mastery.perpetuity },
}
updateCharacter(object)
@ -147,15 +148,15 @@ const CharacterUnit = ({
const gridCharacter: GridCharacter = response.data
let character = cloneDeep(gridCharacter)
if (character.over_mastery) {
if (character.mastery.overMastery) {
const overMastery: CharacterOverMastery = {
1: gridCharacter.over_mastery[0],
2: gridCharacter.over_mastery[1],
3: gridCharacter.over_mastery[2],
4: gridCharacter.over_mastery[3],
1: gridCharacter.mastery.overMastery[0],
2: gridCharacter.mastery.overMastery[1],
3: gridCharacter.mastery.overMastery[2],
4: gridCharacter.mastery.overMastery[3],
}
character.over_mastery = overMastery
character.mastery.overMastery = overMastery
}
appState.grid.characters[gridCharacter.position] = character
@ -187,23 +188,24 @@ const CharacterUnit = ({
// Change the image based on the uncap level
let suffix = '01'
if (gridCharacter.transcendence_step > 0) suffix = '04'
else if (gridCharacter.uncap_level >= 5) suffix = '03'
else if (gridCharacter.uncap_level > 2) suffix = '02'
if (gridCharacter.transcendenceStep > 0) suffix = '04'
else if (gridCharacter.uncapLevel >= 5) suffix = '03'
else if (gridCharacter.uncapLevel > 2) suffix = '02'
// Special casing for Lyria (and Young Cat eventually)
if (gridCharacter.object.granblue_id === '3030182000') {
let element = 1
if (gridCharacter.object.granblueId === '3030182000') {
let element: GranblueElement | undefined
if (grid.weapons.mainWeapon && grid.weapons.mainWeapon.element) {
element = grid.weapons.mainWeapon.element
} else if (party.element != 0) {
element = party.element
} else {
element = ElementMap.wind
}
suffix = `${suffix}_0${element}`
}
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-main/${character.granblue_id}_${suffix}.jpg`
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-main/${character.granblueId}_${suffix}.jpg`
}
setImageUrl(imgSrc)
@ -292,7 +294,7 @@ const CharacterUnit = ({
if (gridCharacter) {
const classes = classNames({
[styles.perpetuity]: true,
[styles.empty]: !gridCharacter.perpetuity,
[styles.empty]: !gridCharacter.mastery.perpetuity,
})
return <i className={classes} onClick={handlePerpetuityClick} />
@ -348,8 +350,8 @@ const CharacterUnit = ({
type="character"
flb={character.uncap.flb || false}
ulb={character.uncap.ulb || false}
uncapLevel={gridCharacter.uncap_level}
transcendenceStage={gridCharacter.transcendence_step}
uncapLevel={gridCharacter.uncapLevel}
transcendenceStage={gridCharacter.transcendenceStep}
position={gridCharacter.position}
editable={editable}
updateUncap={passUncapData}

View file

@ -23,25 +23,26 @@ const TableField = (props: Props) => {
)
const image = () => {
return props.image && props.image.src.length > 0 ? (
<div
className={classNames(
{
[styles.preview]: true,
},
props.image.className
?.split(' ')
.map((className) => styles[className])
)}
>
<img
alt={props.image.alt}
srcSet={props.image.src.join(', ')}
src={props.image.src[0]}
/>
</div>
) : (
''
return (
props.image &&
props.image.src.length > 0 && (
<div
className={classNames(
{
[styles.preview]: true,
},
props.image.className
?.split(' ')
.map((className) => styles[className])
)}
>
<img
alt={props.image.alt}
srcSet={props.image.src.join(', ')}
src={props.image.src[0]}
/>
</div>
)
)
}

View file

@ -19,7 +19,7 @@ const GuidebookResult = (props: Props) => {
<li className={styles.result} onClick={props.onClick}>
<img
alt={guidebook.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/guidebooks/book_${guidebook.granblue_id}.png`}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/guidebooks/book_${guidebook.granblueId}.png`}
/>
<div className={styles.info}>
<h5>{guidebook.name[locale]}</h5>

View file

@ -99,7 +99,7 @@ const GuidebookUnit = ({
// Methods: Image string generation
function generateImageUrl() {
let imgSrc = guidebook
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/guidebooks/book_${guidebook.granblue_id}.png`
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/guidebooks/book_${guidebook.granblueId}.png`
: ''
setImageUrl(imgSrc)

View file

@ -1,4 +1,4 @@
.JobAccessoryItem {
.item {
background: none;
border-radius: $input-corner;
border: none;

View file

@ -18,13 +18,13 @@ const JobAccessoryItem = ({ accessory, selected }: Props) => {
return (
<RadioGroup.Item
className="JobAccessoryItem"
className={styles.item}
data-state={selected ? 'checked' : 'unchecked'}
value={accessory.id}
>
<img
alt={accessory.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/accessory-grid/${accessory.granblue_id}.jpg`}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/accessory-grid/${accessory.granblueId}.jpg`}
/>
<h4>{accessory.name[locale]}</h4>
</RadioGroup.Item>

View file

@ -12,7 +12,7 @@
margin: 0 0 $unit $unit;
}
&.ReadOnly {
&.readOnly {
min-width: inherit;
max-width: inherit;
}
@ -27,7 +27,7 @@
max-width: initial;
}
.Accessories {
.accessories {
display: grid;
gap: $unit;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
@ -38,7 +38,7 @@
}
}
.EquippedAccessory {
.equipped {
display: flex;
flex-direction: column;
gap: $unit-2x;
@ -47,7 +47,7 @@
margin: 0;
}
.Accessory {
.accessory {
display: flex;
flex-direction: column;
gap: $unit;

View file

@ -6,7 +6,6 @@ import classNames from 'classnames'
import capitalizeFirstLetter from '~utils/capitalizeFirstLetter'
import * as RadioGroup from '@radix-ui/react-radio-group'
import Button from '~components/common/Button'
import {
Popover,
PopoverTrigger,
@ -91,7 +90,7 @@ const JobAccessoryPopover = ({
)}
</h3>
<RadioGroup.Root
className="Accessories"
className={styles.accessories}
onValueChange={handleAccessorySelected}
>
{accessories.map((accessory) => (
@ -110,17 +109,17 @@ const JobAccessoryPopover = ({
)
const readOnly = currentAccessory ? (
<div className="EquippedAccessory">
<div className={styles.equipped}>
<h3>
{t('equipped')}{' '}
{job.accessory_type === 1
? `${t('accessories.paladin')}s`
: t('accessories.manadiver')}
</h3>
<div className="Accessory">
<div className={styles.accessory}>
<img
alt={currentAccessory.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/accessory-grid/${currentAccessory.granblue_id}.jpg`}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/accessory-grid/${currentAccessory.granblueId}.jpg`}
/>
<h4>{currentAccessory.name[locale]}</h4>
</div>

View file

@ -39,8 +39,8 @@ const JobDropdown = React.forwardRef<HTMLSelectElement, Props>(
// Set current job from state on mount
useEffect(() => {
if (party.job?.id !== '-1') {
setCurrentJob(party.job)
if (party.protagonist.job?.id !== '-1') {
setCurrentJob(party.protagonist.job)
}
}, [])
@ -95,7 +95,7 @@ const JobDropdown = React.forwardRef<HTMLSelectElement, Props>(
icon={{
alt: item.name[locale],
src: [
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${item.granblue_id}.png`,
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${item.granblueId}.png`,
],
}}
>
@ -119,7 +119,7 @@ const JobDropdown = React.forwardRef<HTMLSelectElement, Props>(
icon={{
alt: currentJob ? currentJob.name[locale] : '',
src: currentJob
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${currentJob.granblue_id}.png`
? `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${currentJob.granblueId}.png`
: '',
}}
open={open}

View file

@ -85,27 +85,28 @@ const JobImage = ({
}
const accessoryPopover = () => {
return job && accessories ? (
<JobAccessoryPopover
buttonref={buttonRef}
currentAccessory={currentAccessory}
accessories={accessories}
editable={editable}
open={open}
job={job}
onAccessorySelected={onAccessorySelected}
onOpenChange={handlePopoverOpenChanged}
>
{accessoryButton()}
</JobAccessoryPopover>
) : (
''
return (
job &&
accessories && (
<JobAccessoryPopover
buttonref={buttonRef}
currentAccessory={currentAccessory}
accessories={accessories}
editable={editable}
open={open}
job={job}
onAccessorySelected={onAccessorySelected}
onOpenChange={handlePopoverOpenChanged}
>
{accessoryButton()}
</JobAccessoryPopover>
)
)
}
return (
<div className={styles.image}>
{hasAccessory ? accessoryPopover() : ''}
{job && job.id !== '-1' ? image : ''}
{hasAccessory && accessoryPopover()}
{job && job.id !== '-1' && image}
<div className={styles.overlay} />
</div>
)

View file

@ -76,8 +76,11 @@ const JobSection = (props: Props) => {
useEffect(() => {
if (job) {
if ((party.job && job.id != party.job.id) || !party.job)
appState.party.job = job
if (
(party.protagonist.job && job.id != party.protagonist.job.id) ||
!party.protagonist.job
)
appState.party.protagonist.job = job
if (job.row === '1') setNumSkills(3)
else setNumSkills(4)
fetchJobAccessories()
@ -178,7 +181,7 @@ const JobSection = (props: Props) => {
<div className={styles.name}>
<img
alt={job?.name[locale]}
src={`/images/job-icons/${job?.granblue_id}.png`}
src={`/images/job-icons/${job?.granblueId}.png`}
/>
<h3>{job?.name[locale]}</h3>
</div>
@ -188,7 +191,7 @@ const JobSection = (props: Props) => {
return (
<section className={styles.job}>
<JobImage
job={party.job}
job={party.protagonist.job}
currentAccessory={currentAccessory}
accessories={accessories}
editable={props.editable}
@ -198,21 +201,23 @@ const JobSection = (props: Props) => {
<div className={styles.details}>
{props.editable ? (
<JobDropdown
currentJob={party.job?.id}
currentJob={party.protagonist.job?.id}
onChange={receiveJob}
ref={selectRef}
/>
) : (
<div className={styles.name}>
{party.job ? (
{party.protagonist.job && (
<img
alt={party.job.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${party.job.granblue_id}.png`}
alt={party.protagonist.job.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${party.protagonist.job.granblueId}.png`}
/>
) : (
''
)}
<h3>{party.job ? party.job.name[locale] : t('no_job')}</h3>
<h3>
{party.protagonist.job
? party.protagonist.job.name[locale]
: t('no_job')}
</h3>
</div>
)}

View file

@ -107,7 +107,7 @@ const JobSkillItem = React.forwardRef<HTMLDivElement, Props>(
} else {
jsx = (
<div className={imageClasses}>
{editable && hasJob ? <PlusIcon /> : ''}
{editable && hasJob && <PlusIcon />}
</div>
)
}

View file

@ -225,7 +225,7 @@ const AXSelect = (props: Props) => {
if (modifierSet == 0) {
axOptionElements = axOptions.map((ax, i) => {
return (
<SelectItem key={i} value={ax.id} data-granblue-id={ax.granblue_id}>
<SelectItem key={i} value={ax.id} data-granblue-id={ax.granblueId}>
{ax.name[locale]}
</SelectItem>
)

View file

@ -33,12 +33,12 @@ const RingSelect = ({ gridCharacter, sendValues }: Props) => {
})
useEffect(() => {
if (gridCharacter.over_mastery) {
if (gridCharacter.mastery.overMastery) {
setRings({
1: gridCharacter.over_mastery[1],
2: gridCharacter.over_mastery[2],
3: gridCharacter.over_mastery[3],
4: gridCharacter.over_mastery[4],
1: gridCharacter.mastery.overMastery[1],
2: gridCharacter.mastery.overMastery[2],
3: gridCharacter.mastery.overMastery[3],
4: gridCharacter.mastery.overMastery[4],
})
}
}, [gridCharacter])
@ -54,7 +54,7 @@ const RingSelect = ({ gridCharacter, sendValues }: Props) => {
ja: 'EXリミットボーナスなし',
},
id: 0,
granblue_id: '',
granblueId: '',
slug: 'no-bonus',
minValue: 0,
maxValue: 0,

View file

@ -304,14 +304,14 @@ const EditPartyModal = ({
!(description === '' && party.description === undefined)
const raidChanged = raid !== party.raid
const chargeAttackChanged = chargeAttack !== party.chargeAttack
const fullAutoChanged = fullAuto !== party.fullAuto
const autoGuardChanged = autoGuard !== party.autoGuard
const autoSummonChanged = autoSummon !== party.autoSummon
const clearTimeChanged = clearTime !== party.clearTime
const turnCountChanged = turnCount !== party.turnCount
const buttonCountChanged = buttonCount !== party.buttonCount
const chainCountChanged = chainCount !== party.chainCount
const chargeAttackChanged = chargeAttack !== party.details.chargeAttack
const fullAutoChanged = fullAuto !== party.details.fullAuto
const autoGuardChanged = autoGuard !== party.details.autoGuard
const autoSummonChanged = autoSummon !== party.details.autoSummon
const clearTimeChanged = clearTime !== party.details.clearTime
const turnCountChanged = turnCount !== party.details.turnCount
const buttonCountChanged = buttonCount !== party.details.buttonCount
const chainCountChanged = chainCount !== party.details.chainCount
// Debugging for if you need to check if a value is being changed
// console.log(`
@ -349,14 +349,17 @@ const EditPartyModal = ({
setName(party.name ? party.name : '')
setDescription(party.description ? party.description : '')
setRaid(party.raid)
setAutoGuard(party.autoGuard)
setAutoSummon(party.autoSummon)
setFullAuto(party.fullAuto)
setChargeAttack(party.chargeAttack)
setClearTime(party.clearTime)
if (party.turnCount !== undefined) setTurnCount(party.turnCount)
if (party.buttonCount !== undefined) setButtonCount(party.buttonCount)
if (party.chainCount !== undefined) setChainCount(party.chainCount)
setAutoGuard(party.details.autoGuard)
setAutoSummon(party.details.autoSummon)
setFullAuto(party.details.fullAuto)
setChargeAttack(party.details.chargeAttack)
setClearTime(party.details.clearTime)
if (party.details.turnCount !== undefined)
setTurnCount(party.details.turnCount)
if (party.details.buttonCount !== undefined)
setButtonCount(party.details.buttonCount)
if (party.details.chainCount !== undefined)
setChainCount(party.details.chainCount)
}
async function updateDetails(event: React.MouseEvent) {

View file

@ -22,11 +22,12 @@ import { retrieveCookies } from '~utils/retrieveCookies'
import { setEditKey, storeEditKey, unsetEditKey } from '~utils/userToken'
import type { CharacterOverMastery, DetailsObject } from '~types'
import { ElementMap } from '~utils/elements'
// Props
interface Props {
new?: boolean
team?: Party
party?: Party
selectedTab: GridType
raidGroups: RaidGroup[]
handleTabChanged: (value: string) => void
@ -58,9 +59,9 @@ const Party = (props: Props) => {
useEffect(() => {
const resetState = clonedeep(initialAppState)
appState.grid = resetState.grid
if (props.team) {
storeParty(props.team)
setUpdatedParty(props.team)
if (props.party) {
storeParty(props.party)
setUpdatedParty(props.party)
}
}, [])
@ -85,20 +86,20 @@ const Party = (props: Props) => {
if (props.new) editable = true
if (accountData && props.team && !props.new) {
if (accountData && props.party && !props.new) {
if (accountData.token) {
// Authenticated
if (props.team.user && accountData.userId === props.team.user.id) {
if (props.party.user && accountData.userId === props.party.user.id) {
editable = true
}
} else {
// Not authenticated
if (!props.team.user && accountData.userId === props.team.local_id) {
if (!props.party.user && accountData.userId === props.party.localId) {
// Set editable
editable = true
// Also set edit key header
setEditKey(props.team.id, props.team.user)
setEditKey(props.party.id, props.party.user)
}
}
}
@ -122,9 +123,9 @@ const Party = (props: Props) => {
async function updateParty(details: DetailsObject) {
const payload = formatDetailsObject(details)
if (props.team && props.team.id) {
if (props.party && props.party.id) {
return await api.endpoints.parties
.update(props.team.id, payload)
.update(props.party.id, payload)
.then((response) => {
storeParty(response.data.party)
setUpdatedParty(response.data.party)
@ -142,7 +143,7 @@ const Party = (props: Props) => {
// Methods: Updating the party's details
async function updateDetails(details: DetailsObject) {
if (!props.team) return await createParty(details)
if (!props.party) return await createParty(details)
else return await updateParty(details)
}
@ -180,11 +181,11 @@ const Party = (props: Props) => {
}
function checkboxChanged(enabled: boolean) {
appState.party.extra = enabled
appState.party.details.extra = enabled
// Only save if this is a saved party
if (props.team && props.team.id) {
api.endpoints.parties.update(props.team.id, {
if (props.party && props.party.id) {
api.endpoints.parties.update(props.party.id, {
party: { extra: enabled },
})
}
@ -203,7 +204,7 @@ const Party = (props: Props) => {
guidebook3_id: position === 3 ? id : undefined,
}
if (props.team && props.team.id) {
if (props.party && props.party.id) {
updateParty(details)
} else {
createParty(details)
@ -214,10 +215,10 @@ const Party = (props: Props) => {
function remixTeam() {
// setOriginalName(partySnapshot.name ? partySnapshot.name : t('no_title'))
if (props.team && props.team.shortcode) {
if (props.party && props.party.shortcode) {
const body = { local_id: getLocalId() }
api
.remix({ shortcode: props.team.shortcode, body: body })
.remix({ shortcode: props.party.shortcode, body: body })
.then((response) => {
const remix = response.data.party
@ -235,9 +236,9 @@ const Party = (props: Props) => {
// Deleting the party
function deleteTeam() {
if (props.team && editable) {
if (props.party && editable) {
api.endpoints.parties
.destroy({ id: props.team.id })
.destroy({ id: props.party.id })
.then(() => {
// Push to route
if (cookies && cookies.account.username) {
@ -267,36 +268,33 @@ const Party = (props: Props) => {
appState.party.name = team.name
appState.party.description = team.description ? team.description : ''
appState.party.raid = team.raid
appState.party.updated_at = team.updated_at
appState.party.job = team.job
appState.party.jobSkills = team.job_skills
appState.party.accessory = team.accessory
appState.party.protagonist.job = team.job
appState.party.protagonist.skills = team.job_skills
appState.party.protagonist.accessory = team.accessory
appState.party.chargeAttack = team.charge_attack
appState.party.fullAuto = team.full_auto
appState.party.autoGuard = team.auto_guard
appState.party.autoSummon = team.auto_summon
appState.party.clearTime = team.clear_time
appState.party.buttonCount =
appState.party.details.chargeAttack = team.charge_attack
appState.party.details.fullAuto = team.full_auto
appState.party.details.autoGuard = team.auto_guard
appState.party.details.autoSummon = team.auto_summon
appState.party.details.clearTime = team.clear_time
appState.party.details.buttonCount =
team.button_count !== null ? team.button_count : undefined
appState.party.chainCount =
appState.party.details.chainCount =
team.chain_count !== null ? team.chain_count : undefined
appState.party.turnCount =
appState.party.details.turnCount =
team.turn_count !== null ? team.turn_count : undefined
appState.party.id = team.id
appState.party.shortcode = team.shortcode
appState.party.extra = team.extra
appState.party.details.extra = team.extra
appState.party.guidebooks = team.guidebooks
appState.party.user = team.user
appState.party.favorited = team.favorited
appState.party.remix = team.remix
appState.party.remixes = team.remixes
appState.party.sourceParty = team.source_party
appState.party.created_at = team.created_at
appState.party.updated_at = team.updated_at
appState.party.detailsVisible = false
appState.party.social.favorited = team.favorited
appState.party.social.remix = team.remix
appState.party.social.remixes = team.remixes
appState.party.social.sourceParty = team.source_party
appState.party.timestamps.createdAt = team.created_at
appState.party.timestamps.updatedAt = team.updated_at
// Store the edit key in local storage
if (team.edit_key) {
@ -329,15 +327,15 @@ const Party = (props: Props) => {
list.forEach((object: GridCharacter) => {
let character = clonedeep(object)
if (character.over_mastery) {
if (character.mastery.overMastery) {
const overMastery: CharacterOverMastery = {
1: object.over_mastery[0],
2: object.over_mastery[1],
3: object.over_mastery[2],
4: object.over_mastery[3],
1: object.mastery.overMastery[0],
2: object.mastery.overMastery[1],
3: object.mastery.overMastery[2],
4: object.mastery.overMastery[3],
}
character.over_mastery = overMastery
character.mastery.overMastery = overMastery
}
if (character.position != null) {
@ -353,7 +351,10 @@ const Party = (props: Props) => {
appState.party.element = gridObject.object.element
} else if (!gridObject.mainhand && gridObject.position !== null) {
let weapon = clonedeep(gridObject)
if (weapon.object.element === 0 && weapon.element < 1)
if (
weapon.object.element === ElementMap.null &&
weapon.element === ElementMap.null
)
weapon.element = gridObject.object.element
appState.grid.weapons.allWeapons[gridObject.position] = weapon
@ -403,8 +404,8 @@ const Party = (props: Props) => {
<WeaponGrid
new={props.new || false}
editable={editable}
weapons={props.team?.weapons}
guidebooks={props.team?.guidebooks}
weapons={props.party?.grid.weapons}
guidebooks={props.party?.guidebooks}
createParty={createParty}
pushHistory={props.pushHistory}
updateExtra={checkboxChanged}
@ -416,7 +417,7 @@ const Party = (props: Props) => {
<SummonGrid
new={props.new || false}
editable={editable}
summons={props.team?.summons}
summons={props.party?.grid.summons}
createParty={createParty}
pushHistory={props.pushHistory}
/>
@ -426,7 +427,7 @@ const Party = (props: Props) => {
<CharacterGrid
new={props.new || false}
editable={editable}
characters={props.team?.characters}
characters={props.party?.grid.characters}
createParty={createParty}
pushHistory={props.pushHistory}
/>

View file

@ -130,7 +130,7 @@ const PartyFooter = (props: Props) => {
const index = remixes.findIndex((p) => p.id === teamId)
const party = remixes[index]
party.favorited = true
party.social.favorited = true
let clonedParties = clonedeep(remixes)
clonedParties[index] = party
@ -146,7 +146,7 @@ const PartyFooter = (props: Props) => {
const index = remixes.findIndex((p) => p.id === teamId)
const party = remixes[index]
party.favorited = false
party.social.favorited = false
let clonedParties = clonedeep(remixes)
clonedParties[index] = party
@ -201,7 +201,9 @@ const PartyFooter = (props: Props) => {
selected={currentSegment === 1}
onClick={() => setCurrentSegment(1)}
>
{t('footer.remixes.label', { count: partySnapshot?.remixes?.length })}
{t('footer.remixes.label', {
count: partySnapshot?.social.remixes?.length,
})}
</Segment>
</SegmentedControl>
)
@ -240,10 +242,10 @@ const PartyFooter = (props: Props) => {
const remixesSection = (
<section className={styles.remixes}>
{partySnapshot?.remixes?.length > 0 && (
{partySnapshot?.social.remixes?.length > 0 && (
<GridRepCollection>{renderRemixes()}</GridRepCollection>
)}
{partySnapshot?.remixes?.length === 0 && (
{partySnapshot?.social.remixes?.length === 0 && (
<div className={styles.noRemixes}>
<h3>{t('footer.remixes.empty')}</h3>
<Button
@ -257,19 +259,19 @@ const PartyFooter = (props: Props) => {
)
function renderRemixes() {
return partySnapshot?.remixes.map((party, i) => {
return partySnapshot?.social.remixes.map((party, i) => {
return (
<GridRep
id={party.id}
shortcode={party.shortcode}
name={party.name}
createdAt={new Date(party.created_at)}
createdAt={new Date(party.timestamps.createdAt)}
raid={party.raid}
grid={party.weapons}
weapons={party.grid.weapons}
user={party.user}
favorited={party.favorited}
fullAuto={party.full_auto}
autoGuard={party.auto_guard}
favorited={party.social.favorited}
fullAuto={party.details.fullAuto}
autoGuard={party.details.autoGuard}
key={`party-${i}`}
onClick={goTo}
onSave={toggleFavorite}

View file

@ -59,24 +59,24 @@ const PartyHeader = (props: Props) => {
})
const linkClass = classNames({
wind: party && party.element == 1,
fire: party && party.element == 2,
water: party && party.element == 3,
earth: party && party.element == 4,
dark: party && party.element == 5,
light: party && party.element == 6,
wind: party.element && party.element.slug === 'wind',
fire: party.element && party.element.slug === 'fire',
water: party.element && party.element.slug === 'water',
earth: party.element && party.element.slug === 'earth',
dark: party.element && party.element.slug === 'dark',
light: party.element && party.element.slug === 'light',
})
// Actions: Favorites
function toggleFavorite() {
if (appState.party.favorited) unsaveFavorite()
if (appState.party.social.favorited) unsaveFavorite()
else saveFavorite()
}
function saveFavorite() {
if (appState.party.id)
api.saveTeam({ id: appState.party.id }).then((response) => {
if (response.status == 201) appState.party.favorited = true
if (response.status == 201) appState.party.social.favorited = true
})
else console.error('Failed to save team: No party ID')
}
@ -84,7 +84,7 @@ const PartyHeader = (props: Props) => {
function unsaveFavorite() {
if (appState.party.id)
api.unsaveTeam({ id: appState.party.id }).then((response) => {
if (response.status == 200) appState.party.favorited = false
if (response.status == 200) appState.party.social.favorited = false
})
else console.error('Failed to unsave team: No party ID')
}
@ -202,33 +202,33 @@ const PartyHeader = (props: Props) => {
// Render: Tokens
const chargeAttackToken = (
<Token active={party.chargeAttack} className="chargeAttack">
<Token active={party.details.chargeAttack} className="chargeAttack">
{`${t('party.details.labels.charge_attack')} ${
party.chargeAttack ? 'On' : 'Off'
party.details.chargeAttack ? 'On' : 'Off'
}`}
</Token>
)
const fullAutoToken = (
<Token active={party.fullAuto} className="fullAuto">
<Token active={party.details.fullAuto} className="fullAuto">
{`${t('party.details.labels.full_auto')} ${
party.fullAuto ? 'On' : 'Off'
party.details.fullAuto ? 'On' : 'Off'
}`}
</Token>
)
const autoGuardToken = (
<Token active={party.autoGuard} className="autoGuard">
<Token active={party.details.autoGuard} className="autoGuard">
{`${t('party.details.labels.auto_guard')} ${
party.autoGuard ? 'On' : 'Off'
party.details.autoGuard ? 'On' : 'Off'
}`}
</Token>
)
const autoSummonToken = (
<Token active={party.autoSummon} className="autoSummon">
<Token active={party.details.autoSummon} className="autoSummon">
{`${t('party.details.labels.auto_summon')} ${
party.autoSummon ? 'On' : 'Off'
party.details.autoSummon ? 'On' : 'Off'
}`}
</Token>
)
@ -236,31 +236,39 @@ const PartyHeader = (props: Props) => {
const turnCountToken = (
<Token>
{t('party.details.turns.with_count', {
count: party.turnCount,
count: party.details.turnCount,
})}
</Token>
)
const buttonChainToken = () => {
if (party.buttonCount !== undefined || party.chainCount !== undefined) {
if (
party.details.buttonCount !== undefined ||
party.details.chainCount !== undefined
) {
let string = ''
if (party.buttonCount !== undefined) {
string += `${party.buttonCount}b`
if (party.details.buttonCount !== undefined) {
string += `${party.details.buttonCount}b`
}
if (party.buttonCount === undefined && party.chainCount !== undefined) {
string += `0${t('party.details.suffix.buttons')}${party.chainCount}${t(
if (
party.details.buttonCount === undefined &&
party.details.chainCount !== undefined
) {
string += `0${t('party.details.suffix.buttons')}${
party.details.chainCount
}${t('party.details.suffix.chains')}`
} else if (
party.details.buttonCount !== undefined &&
party.details.chainCount !== undefined
) {
string += `${party.details.chainCount}${t(
'party.details.suffix.chains'
)}`
} else if (
party.buttonCount !== undefined &&
party.chainCount !== undefined
) {
string += `${party.chainCount}${t('party.details.suffix.chains')}`
} else if (
party.buttonCount !== undefined &&
party.chainCount === undefined
party.details.buttonCount !== undefined &&
party.details.chainCount === undefined
) {
string += `0${t('party.details.suffix.chains')}`
}
@ -270,8 +278,8 @@ const PartyHeader = (props: Props) => {
}
const clearTimeToken = () => {
const minutes = Math.floor(party.clearTime / 60)
const seconds = party.clearTime - minutes * 60
const minutes = Math.floor(party.details.clearTime / 60)
const seconds = party.details.clearTime - minutes * 60
let string = ''
if (minutes > 0)
@ -291,8 +299,8 @@ const PartyHeader = (props: Props) => {
{fullAutoToken}
{autoSummonToken}
{autoGuardToken}
{party.turnCount !== undefined && turnCountToken}
{party.clearTime > 0 && clearTimeToken()}
{party.details.turnCount !== undefined && turnCountToken}
{party.details.clearTime > 0 && clearTimeToken()}
{buttonChainToken()}
</>
)
@ -307,10 +315,12 @@ const PartyHeader = (props: Props) => {
className={classNames({
save: true,
grow: true,
saved: partySnapshot.favorited,
saved: partySnapshot.social.favorited,
})}
text={
appState.party.favorited ? t('buttons.saved') : t('buttons.save')
appState.party.social.favorited
? t('buttons.saved')
: t('buttons.save')
}
onClick={toggleFavorite}
/>
@ -333,12 +343,13 @@ const PartyHeader = (props: Props) => {
const remixedButton = () => {
const tooltipString =
party.remix && party.sourceParty
party.social.remix && party.social.sourceParty
? t('tooltips.remix.source')
: t('tooltips.remix.deleted')
const buttonAction =
party.sourceParty && (() => goTo(party.sourceParty?.shortcode))
party.social.sourceParty &&
(() => goTo(party.social.sourceParty?.shortcode))
return (
<Tooltip content={tooltipString}>
@ -348,7 +359,7 @@ const PartyHeader = (props: Props) => {
leftAccessoryIcon={<RemixIcon />}
text={t('tokens.remix')}
size="small"
disabled={!party.sourceParty}
disabled={!party.social.sourceParty}
onClick={buttonAction}
/>
</Tooltip>
@ -364,17 +375,17 @@ const PartyHeader = (props: Props) => {
<h1 className={party.name ? '' : styles.empty}>
{party.name ? party.name : t('no_title')}
</h1>
{party.remix && remixedButton()}
{party.social.remix && remixedButton()}
</div>
<div className={styles.attribution}>
{renderUserBlock()}
{appState.party.raid && linkedRaidBlock(appState.party.raid)}
{party.created_at != '' && (
{party.timestamps.createdAt != '' && (
<time
className={styles.lastUpdated}
dateTime={new Date(party.created_at).toString()}
dateTime={new Date(party.timestamps.createdAt).toString()}
>
{formatTimeAgo(new Date(party.created_at), locale)}
{formatTimeAgo(new Date(party.timestamps.createdAt), locale)}
</time>
)}
</div>

View file

@ -12,6 +12,7 @@ import CharacterRep from '~components/reps/CharacterRep'
import WeaponRep from '~components/reps/WeaponRep'
import SummonRep from '~components/reps/SummonRep'
import { ElementMap } from '~utils/elements'
import { GridType } from '~utils/enums'
import styles from './index.module.scss'
@ -33,23 +34,24 @@ const PartySegmentedControl = (props: Props) => {
const { party, grid } = useSnapshot(appState)
const getElement = () => {
let element: number = 0
if (party.element == 0 && grid.weapons.mainWeapon)
let element: GranblueElement
if (party.element === ElementMap.null && grid.weapons.mainWeapon)
element = grid.weapons.mainWeapon.element
else element = party.element
else if (party.element) element = party.element
else element = ElementMap.null
switch (element) {
case 1:
case ElementMap.wind:
return 'wind'
case 2:
case ElementMap.fire:
return 'fire'
case 3:
case ElementMap.water:
return 'water'
case 4:
case ElementMap.earth:
return 'earth'
case 5:
case ElementMap.dark:
return 'dark'
case 6:
case ElementMap.light:
return 'light'
}
}
@ -64,7 +66,7 @@ const PartySegmentedControl = (props: Props) => {
onClick={props.onClick}
>
<CharacterRep
job={party.job}
job={party.protagonist.job}
element={party.element}
gender={
accountState.account.user ? accountState.account.user.gender : 0

View file

@ -3,6 +3,8 @@ import { useRouter } from 'next/router'
import { useTranslation } from 'react-i18next'
import classNames from 'classnames'
import { ElementMap } from '~utils/elements'
import { Command, CommandGroup, CommandInput } from 'cmdk'
import Popover from '~components/common/Popover'
import SegmentedControl from '~components/common/SegmentedControl'
@ -50,7 +52,7 @@ const allRaidsOption: Raid = {
group: untitledGroup,
slug: 'all',
level: 0,
element: 0,
element: ElementMap.null,
}
interface Props {
@ -112,7 +114,6 @@ const RaidCombobox = (props: Props) => {
useEffect(() => {
const sections: [RaidGroup[], RaidGroup[], RaidGroup[]] = [[], [], []]
props.raidGroups.forEach((group) => {
if (group.section > 0) sections[group.section - 1].push(group)
})
@ -354,7 +355,8 @@ const RaidCombobox = (props: Props) => {
function generateRaidItems(raids: Raid[]) {
return raids
.sort((a, b) => {
if (a.element > 0 && b.element > 0) return a.element - b.element
if (a.element.id > 0 && b.element.id > 0)
return a.element.id - b.element.id
if (a.name.en.includes('NM') && b.name.en.includes('NM'))
return a.level - b.level
return a.name.en.localeCompare(b.name.en)
@ -521,12 +523,12 @@ const RaidCombobox = (props: Props) => {
// Methods: Utility
// ----------------------------------------------
const linkClass = classNames({
wind: currentRaid && currentRaid.element == 1,
fire: currentRaid && currentRaid.element == 2,
water: currentRaid && currentRaid.element == 3,
earth: currentRaid && currentRaid.element == 4,
dark: currentRaid && currentRaid.element == 5,
light: currentRaid && currentRaid.element == 6,
wind: currentRaid && currentRaid.element == ElementMap.wind,
fire: currentRaid && currentRaid.element == ElementMap.fire,
water: currentRaid && currentRaid.element == ElementMap.water,
earth: currentRaid && currentRaid.element == ElementMap.earth,
dark: currentRaid && currentRaid.element == ElementMap.dark,
light: currentRaid && currentRaid.element == ElementMap.light,
})
// ----------------------------------------------

View file

@ -3,13 +3,15 @@ import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
import 'fix-date'
import { ElementMap } from '~utils/elements'
import styles from './index.module.scss'
import classNames from 'classnames'
interface Props {
job?: Job
gender?: number
element?: number
element?: GranblueElement
grid: GridArray<GridCharacter>
}
@ -47,17 +49,17 @@ const CharacterRep = (props: Props) => {
// Convert element to string
function numberToElement() {
switch (props.element) {
case 1:
case ElementMap.wind:
return 'wind'
case 2:
case ElementMap.fire:
return 'fire'
case 3:
case ElementMap.water:
return 'water'
case 4:
case ElementMap.earth:
return 'earth'
case 5:
case ElementMap.dark:
return 'dark'
case 6:
case ElementMap.light:
return 'light'
default:
return ''
@ -91,21 +93,21 @@ const CharacterRep = (props: Props) => {
if (character && gridCharacter) {
// Change the image based on the uncap level
let suffix = '01'
if (gridCharacter.transcendence_step > 0) suffix = '04'
else if (gridCharacter.uncap_level >= 5) suffix = '03'
else if (gridCharacter.uncap_level > 2) suffix = '02'
if (gridCharacter.transcendenceStep > 0) suffix = '04'
else if (gridCharacter.uncapLevel >= 5) suffix = '03'
else if (gridCharacter.uncapLevel > 2) suffix = '02'
if (character.element == 0) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-main/${character.granblue_id}_${props.element}.jpg`
if (character.element === ElementMap.null) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-main/${character.granblueId}_${props.element}.jpg`
} else {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-main/${character.granblue_id}_${suffix}.jpg`
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/character-main/${character.granblueId}_${suffix}.jpg`
}
}
return characters[position] ? (
<img alt={characters[position]?.name[locale]} src={url} />
) : (
''
return (
characters[position] && (
<img alt={characters[position]?.name[locale]} src={url} />
)
)
}

View file

@ -70,31 +70,27 @@ const SummonRep = (props: Props) => {
if (mainSummon) {
// Change the image based on the uncap level
let suffix = ''
if (mainSummon.object.uncap.xlb && mainSummon.uncap_level == 6) {
if (mainSummon.object.uncap.xlb && mainSummon.uncapLevel == 6) {
if (
mainSummon.transcendence_step >= 1 &&
mainSummon.transcendence_step < 5
mainSummon.transcendenceStep >= 1 &&
mainSummon.transcendenceStep < 5
) {
suffix = '_03'
} else if (mainSummon.transcendence_step === 5) {
} else if (mainSummon.transcendenceStep === 5) {
suffix = '_04'
}
} else if (
upgradedSummons.indexOf(mainSummon.object.granblue_id.toString()) !=
upgradedSummons.indexOf(mainSummon.object.granblueId.toString()) !=
-1 &&
mainSummon.uncap_level == 5
mainSummon.uncapLevel == 5
) {
suffix = '_02'
}
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-main/${mainSummon.object.granblue_id}${suffix}.jpg`
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-main/${mainSummon.object.granblueId}${suffix}.jpg`
}
return mainSummon ? (
<img alt={mainSummon.object.name[locale]} src={url} />
) : (
''
)
return mainSummon && <img alt={mainSummon.object.name[locale]} src={url} />
}
function generateGridImage(position: number) {
@ -123,29 +119,29 @@ const SummonRep = (props: Props) => {
if (summon && gridSummon) {
// Change the image based on the uncap level
let suffix = ''
if (gridSummon.object.uncap.xlb && gridSummon.uncap_level == 6) {
if (gridSummon.object.uncap.xlb && gridSummon.uncapLevel == 6) {
if (
gridSummon.transcendence_step >= 1 &&
gridSummon.transcendence_step < 5
gridSummon.transcendenceStep >= 1 &&
gridSummon.transcendenceStep < 5
) {
suffix = '_03'
} else if (gridSummon.transcendence_step === 5) {
} else if (gridSummon.transcendenceStep === 5) {
suffix = '_04'
}
} else if (
upgradedSummons.indexOf(summon.granblue_id.toString()) != -1 &&
gridSummon.uncap_level == 5
upgradedSummons.indexOf(summon.granblueId.toString()) != -1 &&
gridSummon.uncapLevel == 5
) {
suffix = '_02'
}
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblue_id}${suffix}.jpg`
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblueId}${suffix}.jpg`
}
return summons[position] ? (
<img alt={summons[position]?.name[locale]} src={url} />
) : (
''
return (
summons[position] && (
<img alt={summons[position]?.name[locale]} src={url} />
)
)
}

View file

@ -1,8 +1,7 @@
import React, { useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { ElementMap } from '~utils/elements'
import styles from './index.module.scss'
import classNames from 'classnames'
interface Props {
grid: {
@ -53,14 +52,14 @@ const WeaponRep = (props: Props) => {
let url = ''
if (mainhand && mainhand.object) {
if (mainhand.object.element == 0 && mainhand.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.object.granblue_id}_${mainhand.element}.jpg`
if (mainhand.object.element === ElementMap.null && mainhand.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.object.granblueId}_${mainhand.element}.jpg`
} else {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.object.granblue_id}.jpg`
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand.object.granblueId}.jpg`
}
}
return mainhand ? <img alt={mainhand.object.name[locale]} src={url} /> : ''
return mainhand && <img alt={mainhand.object.name[locale]} src={url} />
}
function generateGridImage(position: number) {
@ -70,17 +69,17 @@ const WeaponRep = (props: Props) => {
const gridWeapon = grid[position]
if (weapon && gridWeapon) {
if (weapon.element == 0 && gridWeapon.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}_${gridWeapon.element}.jpg`
if (weapon.element === ElementMap.null && gridWeapon.element) {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}_${gridWeapon.element}.jpg`
} else {
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg`
url = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}.jpg`
}
}
return weapons[position] ? (
<img alt={weapons[position]?.name[locale]} src={url} />
) : (
''
return (
weapons[position] && (
<img alt={weapons[position]?.name[locale]} src={url} />
)
)
}

View file

@ -126,7 +126,7 @@ const SearchModal = (props: Props) => {
if (
!recents.find(
(item) =>
(item as Weapon).granblue_id === (result as Weapon).granblue_id
(item as Weapon).granblueId === (result as Weapon).granblueId
)
) {
recents.unshift(result as Weapon)
@ -136,7 +136,7 @@ const SearchModal = (props: Props) => {
if (
!recents.find(
(item) =>
(item as Summon).granblue_id === (result as Summon).granblue_id
(item as Summon).granblueId === (result as Summon).granblueId
)
) {
recents.unshift(result as Summon)

View file

@ -22,7 +22,11 @@ import styles from './index.module.scss'
interface Props {
new: boolean
editable: boolean
summons?: GridSummon[]
summons?: {
mainSummon?: GridSummon
friendSummon?: GridSummon
allSummons: GridArray<GridSummon>
}
createParty: (details?: DetailsObject) => Promise<Party>
pushHistory?: (path: string) => void
}
@ -62,14 +66,14 @@ const SummonGrid = (props: Props) => {
if (appState.grid.summons.mainSummon)
initialPreviousUncapValues[-1] =
appState.grid.summons.mainSummon.uncap_level
appState.grid.summons.mainSummon.uncapLevel
if (appState.grid.summons.friendSummon)
initialPreviousUncapValues[6] =
appState.grid.summons.friendSummon.uncap_level
appState.grid.summons.friendSummon.uncapLevel
Object.values(appState.grid.summons.allSummons).map((o) =>
o ? (initialPreviousUncapValues[o.position] = o.uncap_level) : 0
Object.values(appState.party.grid.summons.allSummons).map((o) =>
o ? (initialPreviousUncapValues[o.position] = o.uncapLevel) : 0
)
setPreviousUncapValues(initialPreviousUncapValues)
@ -137,7 +141,7 @@ const SummonGrid = (props: Props) => {
position: position,
main: position == -1,
friend: position == 6,
uncap_level: uncapLevel,
uncapLevel: uncapLevel,
},
})
}
@ -213,13 +217,13 @@ const SummonGrid = (props: Props) => {
const updateUncapLevel = (position: number, uncapLevel: number) => {
if (appState.grid.summons.mainSummon && position == -1)
appState.grid.summons.mainSummon.uncap_level = uncapLevel
appState.grid.summons.mainSummon.uncapLevel = uncapLevel
else if (appState.grid.summons.friendSummon && position == 6)
appState.grid.summons.friendSummon.uncap_level = uncapLevel
appState.grid.summons.friendSummon.uncapLevel = uncapLevel
else {
const summon = appState.grid.summons.allSummons[position]
if (summon) {
summon.uncap_level = uncapLevel
summon.uncapLevel = uncapLevel
appState.grid.summons.allSummons[position] = summon
}
}
@ -230,13 +234,13 @@ const SummonGrid = (props: Props) => {
let newPreviousValues = { ...previousUncapValues }
if (appState.grid.summons.mainSummon && position == -1)
newPreviousValues[position] = appState.grid.summons.mainSummon.uncap_level
newPreviousValues[position] = appState.grid.summons.mainSummon.uncapLevel
else if (appState.grid.summons.friendSummon && position == 6)
newPreviousValues[position] =
appState.grid.summons.friendSummon.uncap_level
appState.grid.summons.friendSummon.uncapLevel
else {
const summon = appState.grid.summons.allSummons[position]
newPreviousValues[position] = summon ? summon.uncap_level : 0
newPreviousValues[position] = summon ? summon.uncapLevel : 0
}
setPreviousUncapValues(newPreviousValues)
@ -254,7 +258,7 @@ const SummonGrid = (props: Props) => {
const payload = {
summon: {
uncap_level: stage > 0 ? 6 : 5,
uncapLevel: stage > 0 ? 6 : 5,
transcendence_step: stage,
},
}
@ -317,13 +321,13 @@ const SummonGrid = (props: Props) => {
const updateTranscendenceStage = (position: number, stage: number) => {
if (appState.grid.summons.mainSummon && position == -1)
appState.grid.summons.mainSummon.transcendence_step = stage
appState.grid.summons.mainSummon.transcendenceStep = stage
else if (appState.grid.summons.friendSummon && position == 6)
appState.grid.summons.friendSummon.transcendence_step = stage
appState.grid.summons.friendSummon.transcendenceStep = stage
else {
const summon = appState.grid.summons.allSummons[position]
if (summon) {
summon.transcendence_step = stage
summon.transcendenceStep = stage
appState.grid.summons.allSummons[position] = summon
}
}
@ -334,13 +338,13 @@ const SummonGrid = (props: Props) => {
let newPreviousValues = { ...previousUncapValues }
if (appState.grid.summons.mainSummon && position == -1)
newPreviousValues[position] = appState.grid.summons.mainSummon.uncap_level
newPreviousValues[position] = appState.grid.summons.mainSummon.uncapLevel
else if (appState.grid.summons.friendSummon && position == 6)
newPreviousValues[position] =
appState.grid.summons.friendSummon.uncap_level
appState.grid.summons.friendSummon.uncapLevel
else {
const summon = appState.grid.summons.allSummons[position]
newPreviousValues[position] = summon ? summon.uncap_level : 0
newPreviousValues[position] = summon ? summon.uncapLevel : 0
}
setPreviousUncapValues(newPreviousValues)

View file

@ -20,14 +20,9 @@ interface Props {
}
const SummonHovercard = (props: Props) => {
const router = useRouter()
const { t } = useTranslation('common')
const locale =
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
const tintElement = Element[props.gridSummon.object.element]
const tintElement = props.gridSummon.object.element.slug
function goTo() {
const urlSafeName = props.gridSummon.object.name.en.replaceAll(' ', '_')
@ -55,19 +50,19 @@ const SummonHovercard = (props: Props) => {
let suffix = ''
if (
upgradedSummons.indexOf(summon.granblue_id.toString()) != -1 &&
props.gridSummon.uncap_level == 5
upgradedSummons.indexOf(summon.granblueId.toString()) != -1 &&
props.gridSummon.uncapLevel == 5
) {
suffix = '_02'
} else if (
props.gridSummon.object.uncap.xlb &&
props.gridSummon.transcendence_step > 0
props.gridSummon.transcendenceStep > 0
) {
suffix = '_03'
}
// Generate the correct source for the summon
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblue_id}${suffix}.jpg`
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblueId}${suffix}.jpg`
}
return imgSrc

View file

@ -11,8 +11,6 @@ interface Props {
onClick: () => void
}
const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
const SummonResult = (props: Props) => {
const router = useRouter()
const locale =
@ -24,7 +22,7 @@ const SummonResult = (props: Props) => {
<li className={styles.result} onClick={props.onClick}>
<img
alt={summon.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblue_id}.jpg`}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblueId}.jpg`}
/>
<div className={styles.info}>
<h5>{summon.name[locale]}</h5>
@ -35,7 +33,7 @@ const SummonResult = (props: Props) => {
special={false}
/>
<div className={styles.tags}>
<WeaponLabelIcon labelType={Element[summon.element]} />
<WeaponLabelIcon labelType={summon.element.slug} />
</div>
</div>
</li>

View file

@ -3,8 +3,6 @@ import { useTranslation } from 'next-i18next'
import cloneDeep from 'lodash.clonedeep'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import SearchFilter from '~components/search/SearchFilter'
import SearchFilterCheckboxItem from '~components/search/SearchFilterCheckboxItem'

View file

@ -95,7 +95,7 @@ const SummonUnit = ({
}
function handleQuickSummonClick() {
if (gridSummon) updateQuickSummon(!gridSummon.quick_summon)
if (gridSummon) updateQuickSummon(!gridSummon.quickSummon)
}
// Methods: Handle open change
@ -177,27 +177,27 @@ const SummonUnit = ({
]
let suffix = ''
if (gridSummon.object.uncap.xlb && gridSummon.uncap_level == 6) {
if (gridSummon.object.uncap.xlb && gridSummon.uncapLevel == 6) {
if (
gridSummon.transcendence_step >= 1 &&
gridSummon.transcendence_step < 5
gridSummon.transcendenceStep >= 1 &&
gridSummon.transcendenceStep < 5
) {
suffix = '_03'
} else if (gridSummon.transcendence_step === 5) {
} else if (gridSummon.transcendenceStep === 5) {
suffix = '_04'
}
} else if (
upgradedSummons.indexOf(summon.granblue_id.toString()) != -1 &&
gridSummon.uncap_level == 5
upgradedSummons.indexOf(summon.granblueId.toString()) != -1 &&
gridSummon.uncapLevel == 5
) {
suffix = '_02'
}
// Generate the correct source for the summon
if (unitType == 0 || unitType == 2)
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-main/${summon.granblue_id}${suffix}.jpg`
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-main/${summon.granblueId}${suffix}.jpg`
else
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblue_id}${suffix}.jpg`
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/summon-grid/${summon.granblueId}${suffix}.jpg`
}
setImageUrl(imgSrc)
@ -273,7 +273,7 @@ const SummonUnit = ({
if (gridSummon) {
const classes = classNames({
[styles.quickSummon]: true,
[styles.empty]: !gridSummon.quick_summon,
[styles.empty]: !gridSummon.quickSummon,
})
return <i className={classes} onClick={handleQuickSummonClick} />
@ -327,8 +327,8 @@ const SummonUnit = ({
flb={gridSummon.object.uncap.flb || false}
xlb={gridSummon.object.uncap.xlb || false}
editable={editable}
uncapLevel={gridSummon.uncap_level}
transcendenceStage={gridSummon.transcendence_step}
uncapLevel={gridSummon.uncapLevel}
transcendenceStage={gridSummon.transcendenceStep}
position={gridSummon.position}
updateUncap={passUncapData}
updateTranscendence={passTranscendenceData}

View file

@ -39,7 +39,7 @@ const WeaponConflictModal = (props: Props) => {
}, [setOpen, props.open])
function imageUrl(weapon?: Weapon) {
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-square/${weapon?.granblue_id}.jpg`
return `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-square/${weapon?.granblueId}.jpg`
}
function openChange(open: boolean) {

View file

@ -22,12 +22,16 @@ import { appState } from '~utils/appState'
import type { DetailsObject, SearchableObject } from '~types'
import styles from './index.module.scss'
import { ElementMap } from '~utils/elements'
// Props
interface Props {
new: boolean
editable: boolean
weapons?: GridWeapon[]
weapons?: {
mainWeapon?: GridWeapon
allWeapons: GridArray<GridWeapon>
}
guidebooks?: GuidebookList
createParty: (details: DetailsObject) => Promise<Party>
pushHistory?: (path: string) => void
@ -73,10 +77,10 @@ const WeaponGrid = (props: Props) => {
if (appState.grid.weapons.mainWeapon)
initialPreviousUncapValues[-1] =
appState.grid.weapons.mainWeapon.uncap_level
appState.grid.weapons.mainWeapon.uncapLevel
Object.values(appState.grid.weapons.allWeapons).map((o) =>
o ? (initialPreviousUncapValues[o.position] = o.uncap_level) : 0
Object.values(appState.party.grid.weapons.allWeapons).map((o) =>
o ? (initialPreviousUncapValues[o.position] = o.uncapLevel) : 0
)
setPreviousUncapValues(initialPreviousUncapValues)
@ -88,7 +92,7 @@ const WeaponGrid = (props: Props) => {
if (position == 1) appState.party.element = weapon.element
if (!party.id) {
const payload: DetailsObject = { extra: party.extra }
const payload: DetailsObject = { extra: party.details.extra }
props.createParty(payload).then((team) => {
saveWeapon(team.id, weapon, position).then((response) => {
if (response) storeGridWeapon(response.data.grid_weapon)
@ -144,7 +148,7 @@ const WeaponGrid = (props: Props) => {
if (position == -1) {
appState.grid.weapons.mainWeapon = undefined
appState.party.element = 0
appState.party.element = ElementMap.null
} else {
appState.grid.weapons.allWeapons[position] = undefined
}
@ -181,7 +185,7 @@ const WeaponGrid = (props: Props) => {
weapon_id: weapon.id,
position: position,
mainhand: position == -1,
uncap_level: uncapLevel,
uncapLevel: uncapLevel,
},
})
}
@ -211,7 +215,7 @@ const WeaponGrid = (props: Props) => {
conflicts.forEach((c) => {
if (appState.grid.weapons.mainWeapon?.object.id === c.object.id) {
appState.grid.weapons.mainWeapon = undefined
appState.party.element = 0
appState.party.element = ElementMap.null
} else {
appState.grid.weapons.allWeapons[c.position] = undefined
}
@ -308,11 +312,11 @@ const WeaponGrid = (props: Props) => {
const updateUncapLevel = (position: number, uncapLevel: number) => {
// console.log(`Updating uncap level at position ${position} to ${uncapLevel}`)
if (appState.grid.weapons.mainWeapon && position == -1)
appState.grid.weapons.mainWeapon.uncap_level = uncapLevel
appState.grid.weapons.mainWeapon.uncapLevel = uncapLevel
else {
const weapon = appState.grid.weapons.allWeapons[position]
if (weapon) {
weapon.uncap_level = uncapLevel
weapon.uncapLevel = uncapLevel
appState.grid.weapons.allWeapons[position] = weapon
}
}
@ -323,11 +327,11 @@ const WeaponGrid = (props: Props) => {
let newPreviousValues = { ...previousUncapValues }
if (appState.grid.weapons.mainWeapon && position == -1) {
newPreviousValues[position] = appState.grid.weapons.mainWeapon.uncap_level
newPreviousValues[position] = appState.grid.weapons.mainWeapon.uncapLevel
} else {
const weapon = appState.grid.weapons.allWeapons[position]
if (weapon) {
newPreviousValues[position] = weapon.uncap_level
newPreviousValues[position] = weapon.uncapLevel
} else {
newPreviousValues[position] = 0
}
@ -339,7 +343,7 @@ const WeaponGrid = (props: Props) => {
// Methods: Convenience
const displayExtraContainer =
props.editable ||
appState.party.extra ||
appState.party.details.extra ||
Object.values(appState.party.guidebooks).every((el) => el === undefined)
// Render: JSX components
@ -411,30 +415,31 @@ const WeaponGrid = (props: Props) => {
}
const conflictModal = () => {
return incoming && conflicts ? (
<WeaponConflictModal
open={modalOpen}
incomingWeapon={incoming}
conflictingWeapons={conflicts}
desiredPosition={position}
resolveConflict={resolveConflict}
resetConflict={resetConflict}
/>
) : (
''
return (
incoming &&
conflicts && (
<WeaponConflictModal
open={modalOpen}
incomingWeapon={incoming}
conflictingWeapons={conflicts}
desiredPosition={position}
resolveConflict={resolveConflict}
resetConflict={resetConflict}
/>
)
)
}
const incompatibleAlert = () => {
return showIncompatibleAlert ? (
<Alert
open={showIncompatibleAlert}
cancelAction={() => setShowIncompatibleAlert(!showIncompatibleAlert)}
cancelActionText={t('buttons.confirm')}
message={t('alert.incompatible_weapon')}
/>
) : (
''
return (
showIncompatibleAlert && (
<Alert
open={showIncompatibleAlert}
cancelAction={() => setShowIncompatibleAlert(!showIncompatibleAlert)}
cancelActionText={t('buttons.confirm')}
message={t('alert.incompatible_weapon')}
/>
)
)
}

View file

@ -12,6 +12,7 @@ import HovercardHeader from '~components/HovercardHeader'
import Button from '~components/common/Button'
import ax from '~data/ax'
import { ElementMap } from '~utils/elements'
import styles from './index.module.scss'
@ -36,7 +37,6 @@ const WeaponHovercard = (props: Props) => {
const { t } = useTranslation('common')
const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
const WeaponKeyNames: KeyNames = {
'2': {
en: 'Pendulum',
@ -57,9 +57,10 @@ const WeaponHovercard = (props: Props) => {
}
const tintElement =
props.gridWeapon.object.element == 0 && props.gridWeapon.element
? Element[props.gridWeapon.element]
: Element[props.gridWeapon.object.element]
props.gridWeapon.object.element === ElementMap.null &&
props.gridWeapon.element
? props.gridWeapon.element.slug
: props.gridWeapon.object.element.slug
function goTo() {
const urlSafeName = props.gridWeapon.object.name.en.replaceAll(' ', '_')
@ -76,7 +77,7 @@ const WeaponHovercard = (props: Props) => {
}
const createPrimaryAxSkillString = () => {
const primaryAxSkills = ax[props.gridWeapon.object.ax_type - 1]
const primaryAxSkills = ax[props.gridWeapon.object.axType - 1]
if (props.gridWeapon.ax) {
const simpleAxSkill = props.gridWeapon.ax[0]
@ -93,7 +94,7 @@ const WeaponHovercard = (props: Props) => {
}
const createSecondaryAxSkillString = () => {
const primaryAxSkills = ax[props.gridWeapon.object.ax_type - 1]
const primaryAxSkills = ax[props.gridWeapon.object.axType - 1]
if (props.gridWeapon.ax) {
const primarySimpleAxSkill = props.gridWeapon.ax[0]
@ -135,27 +136,24 @@ const WeaponHovercard = (props: Props) => {
const keysSection = (
<section className={styles.weaponKeys}>
{WeaponKeyNames[props.gridWeapon.object.series] ? (
{WeaponKeyNames[props.gridWeapon.object.series] && (
<h5 className={tintElement}>
{WeaponKeyNames[props.gridWeapon.object.series][locale]}
{locale === 'en' ? 's' : ''}
</h5>
) : (
''
)}
{props.gridWeapon.weapon_keys
? Array.from(Array(props.gridWeapon.weapon_keys.length)).map((x, i) => {
return (
<div
className={styles.weaponKey}
key={props.gridWeapon.weapon_keys![i].id}
>
<span>{props.gridWeapon.weapon_keys![i].name[locale]}</span>
</div>
)
})
: ''}
{props.gridWeapon.weaponKeys &&
Array.from(Array(props.gridWeapon.weaponKeys?.length)).map((x, i) => {
return (
<div
className={styles.weaponKey}
key={props.gridWeapon.weaponKeys![i].id}
>
<span>{props.gridWeapon.weaponKeys![i].name[locale]}</span>
</div>
)
})}
</section>
)
@ -181,28 +179,26 @@ const WeaponHovercard = (props: Props) => {
</div>
{props.gridWeapon.ax &&
props.gridWeapon.ax[1].modifier &&
props.gridWeapon.ax[1].strength ? (
<div
className={classNames({
[styles.secondary]: true,
[styles.axSkill]: true,
[styles.skill]: true,
})}
>
<div className={styles.axImageWrapper}>
<img
alt="AX2"
src={`/icons/ax/secondary_${
props.gridWeapon.ax ? props.gridWeapon.ax[1].modifier : ''
}.png`}
/>
props.gridWeapon.ax[1].modifier &&
props.gridWeapon.ax[1].strength && (
<div
className={classNames({
[styles.secondary]: true,
[styles.axSkill]: true,
[styles.skill]: true,
})}
>
<div className={styles.axImageWrapper}>
<img
alt="AX2"
src={`/icons/ax/secondary_${
props.gridWeapon.ax ? props.gridWeapon.ax[1].modifier : ''
}.png`}
/>
</div>
<span>{createSecondaryAxSkillString()}</span>
</div>
<span>{createSecondaryAxSkillString()}</span>
</div>
) : (
''
)}
)}
</div>
</section>
)
@ -233,8 +229,8 @@ const WeaponHovercard = (props: Props) => {
props.gridWeapon.ax[0].strength !== undefined &&
axSection}
{props.gridWeapon.awakening && awakeningSection}
{props.gridWeapon.weapon_keys &&
props.gridWeapon.weapon_keys.length > 0 &&
{props.gridWeapon.weaponKeys &&
props.gridWeapon.weaponKeys.length > 0 &&
keysSection}
{wikiButton}
</HovercardContent>

View file

@ -35,7 +35,7 @@ const gauphNames = [
const emptyWeaponKey: WeaponKey = {
id: 'no-key',
granblue_id: '-1',
granblueId: '-1',
series: 0,
slot: 0,
slug: '',
@ -104,7 +104,7 @@ const WeaponKeySelect = React.forwardRef<HTMLButtonElement, Props>(
<SelectItem
key={i}
value={item.id}
data-granblue-id={item.granblue_id}
data-granblue-id={item.granblueId}
>
{item.name.en}
</SelectItem>

View file

@ -17,6 +17,7 @@ import WeaponKeySelect from '~components/weapon/WeaponKeySelect'
import Button from '~components/common/Button'
import { NO_AWAKENING } from '~data/awakening'
import { ElementMap } from '~utils/elements'
import styles from './index.module.scss'
@ -63,7 +64,7 @@ const WeaponModal = ({
// State: Data
const [element, setElement] = useState<number>(0)
const [element, setElement] = useState<GranblueElement>(ElementMap.null)
const [awakening, setAwakening] = useState<Awakening>()
const [awakeningLevel, setAwakeningLevel] = useState(1)
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
@ -84,8 +85,8 @@ const WeaponModal = ({
useEffect(() => {
setElement(gridWeapon.element)
if (gridWeapon.weapon_keys) {
gridWeapon.weapon_keys.forEach((key) => {
if (gridWeapon.weaponKeys) {
gridWeapon.weaponKeys.forEach((key) => {
if (key.slot + 1 === 1) {
setWeaponKey1(key)
} else if (key.slot + 1 === 2) {
@ -111,8 +112,8 @@ const WeaponModal = ({
// Methods: Data retrieval
// Receive values from ElementToggle
function receiveElementValue(elementId: number) {
setElement(elementId)
function receiveElementValue(element: GranblueElement) {
setElement(element)
}
// Receive values from AXSelect
@ -153,7 +154,8 @@ const WeaponModal = ({
function prepareObject() {
let object: GridWeaponObject = { weapon: {} }
if (gridWeapon.object.element == 0) object.weapon.element = element
if (gridWeapon.object.element === ElementMap.null)
object.weapon.element = element.id
if ([2, 3, 17, 24].includes(gridWeapon.object.series) && weaponKey1) {
object.weapon.weapon_key1_id = weaponKey1.id
@ -165,7 +167,7 @@ const WeaponModal = ({
if (gridWeapon.object.series == 17 && weaponKey3)
object.weapon.weapon_key3_id = weaponKey3.id
if (gridWeapon.object.ax && gridWeapon.object.ax_type > 0) {
if (gridWeapon.object.ax && gridWeapon.object.axType > 0) {
object.weapon.ax_modifier1 = primaryAxModifier
object.weapon.ax_modifier2 = secondaryAxModifier
object.weapon.ax_strength1 = primaryAxValue
@ -215,18 +217,18 @@ const WeaponModal = ({
// Reset values
setElement(gridWeapon.element)
setWeaponKey1(
gridWeapon.weapon_keys && gridWeapon.weapon_keys[0]
? gridWeapon.weapon_keys[0]
gridWeapon.weaponKeys && gridWeapon.weaponKeys[0]
? gridWeapon.weaponKeys[0]
: undefined
)
setWeaponKey2(
gridWeapon.weapon_keys && gridWeapon.weapon_keys[1]
? gridWeapon.weapon_keys[1]
gridWeapon.weaponKeys && gridWeapon.weaponKeys[1]
? gridWeapon.weaponKeys[1]
: undefined
)
setWeaponKey3(
gridWeapon.weapon_keys && gridWeapon.weapon_keys[2]
? gridWeapon.weapon_keys[2]
gridWeapon.weaponKeys && gridWeapon.weaponKeys[2]
? gridWeapon.weaponKeys[2]
: undefined
)
setAwakening(gridWeapon.awakening?.type)
@ -276,13 +278,13 @@ const WeaponModal = ({
if (weaponKey && weaponKey.id === 'no-key') weaponKey = undefined
// If the key is empty and the gridWeapon has no keys, nothing has changed
if (weaponKey === undefined && !gridWeapon.weapon_keys) return false
if (weaponKey === undefined && !gridWeapon.weaponKeys) return false
// If the key is not empty but the gridWeapon has no keys, the key has changed
if (
weaponKey !== undefined &&
gridWeapon.weapon_keys &&
gridWeapon.weapon_keys.length === 0
gridWeapon.weaponKeys &&
gridWeapon.weaponKeys.length === 0
)
return true
@ -290,15 +292,15 @@ const WeaponModal = ({
// then the key has changed
const weaponKeyChanged =
weaponKey &&
gridWeapon.weapon_keys &&
gridWeapon.weapon_keys[index] &&
weaponKey.id !== gridWeapon.weapon_keys[index].id
gridWeapon.weaponKeys &&
gridWeapon.weaponKeys[index] &&
weaponKey.id !== gridWeapon.weaponKeys[index].id
return weaponKeyChanged
}
function weaponKeysChanged() {
if (!gridWeapon.weapon_keys) return false
if (!gridWeapon.weaponKeys) return false
const weaponKey1Changed = weaponKeyChanged(0)
const weaponKey2Changed = weaponKeyChanged(1)
@ -415,7 +417,7 @@ const WeaponModal = ({
<section>
<h3>{t('modals.weapon.subtitles.ax_skills')}</h3>
<AXSelect
axType={gridWeapon.object.ax_type}
axType={gridWeapon.object.axType}
currentSkills={gridWeapon.ax}
onOpenChange={receiveAxOpen}
sendValidity={receiveValidity}
@ -432,7 +434,7 @@ const WeaponModal = ({
awakening={gridWeapon.awakening?.type}
level={gridWeapon.awakening?.level}
defaultAwakening={NO_AWAKENING}
maxLevel={gridWeapon.object.max_awakening_level}
maxLevel={gridWeapon.object.maxAwakeningLevel}
onOpenChange={receiveAwakeningOpen}
sendValidity={receiveValidity}
sendValues={receiveAwakeningValues}
@ -479,12 +481,12 @@ const WeaponModal = ({
title={gridWeapon.object.name[locale]}
subtitle={t('modals.characters.title')}
image={{
src: `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-square/${gridWeapon.object.granblue_id}.jpg`,
src: `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-square/${gridWeapon.object.granblueId}.jpg`,
alt: gridWeapon.object.name[locale],
}}
/>
<section className={styles.mods}>
{gridWeapon.object.element == 0 && elementSelect}
{gridWeapon.object.element === ElementMap.null && elementSelect}
{[2, 3, 17, 24].includes(gridWeapon.object.series) && keySelect}
{gridWeapon.object.ax && axSelect}
{gridWeapon.object.awakenings && awakeningSelect}

View file

@ -11,7 +11,6 @@ interface Props {
onClick: () => void
}
const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
const Proficiency = [
'none',
'sword',
@ -36,7 +35,7 @@ const WeaponResult = (props: Props) => {
<li className={styles.result} onClick={props.onClick}>
<img
alt={weapon.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg`}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}.jpg`}
/>
<div className={styles.info}>
<h5>{weapon.name[locale]}</h5>
@ -47,7 +46,7 @@ const WeaponResult = (props: Props) => {
special={false}
/>
<div className={styles.tags}>
<WeaponLabelIcon labelType={Element[weapon.element]} />
<WeaponLabelIcon labelType={weapon.element.slug} />
<WeaponLabelIcon labelType={Proficiency[weapon.proficiency]} />
</div>
</div>

View file

@ -3,8 +3,6 @@ import { useTranslation } from 'next-i18next'
import cloneDeep from 'lodash.clonedeep'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import SearchFilter from '~components/search/SearchFilter'
import SearchFilterCheckboxItem from '~components/search/SearchFilterCheckboxItem'

View file

@ -24,6 +24,7 @@ import Button from '~components/common/Button'
import type { GridWeaponObject, SearchableObject } from '~types'
import ax from '~data/ax'
import { ElementMap } from '~utils/elements'
import PlusIcon from '~public/icons/Add.svg'
import SettingsIcon from '~public/icons/Settings.svg'
@ -154,7 +155,10 @@ const WeaponUnit = ({
appState.party.element = gridWeapon.object.element
} else if (!gridWeapon.mainhand && gridWeapon.position !== null) {
let weapon = clonedeep(gridWeapon)
if (weapon.object.element === 0 && weapon.element < 1)
if (
weapon.object.element === ElementMap.null &&
weapon.element === ElementMap.null
)
weapon.element = gridWeapon.object.element
appState.grid.weapons.allWeapons[gridWeapon.position] = weapon
@ -170,10 +174,10 @@ const WeaponUnit = ({
if (
gridWeapon &&
gridWeapon.object.ax &&
gridWeapon.object.ax_type > 0 &&
gridWeapon.object.axType > 0 &&
gridWeapon.ax
) {
const axOptions = ax[gridWeapon.object.ax_type - 1]
const axOptions = ax[gridWeapon.object.axType - 1]
const weaponAxSkill: SimpleAxSkill = gridWeapon.ax[0]
let axSkill = axOptions.find((ax) => ax.id === weaponAxSkill.modifier)
@ -196,15 +200,15 @@ const WeaponUnit = ({
const weapon = gridWeapon.object!
if (unitType == 0) {
if (gridWeapon.object.element == 0 && gridWeapon.element)
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${weapon.granblue_id}_${gridWeapon.element}.jpg`
if (gridWeapon.object.element === ElementMap.null && gridWeapon.element)
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${weapon.granblueId}_${gridWeapon.element}.jpg`
else
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${weapon.granblue_id}.jpg`
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${weapon.granblueId}.jpg`
} else {
if (gridWeapon.object.element == 0 && gridWeapon.element)
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}_${gridWeapon.element}.jpg`
if (gridWeapon.object.element === ElementMap.null && gridWeapon.element)
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}_${gridWeapon.element}.jpg`
else
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblue_id}.jpg`
imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapon.granblueId}.jpg`
}
}
@ -242,19 +246,15 @@ const WeaponUnit = ({
let altText = ''
// If there is a grid weapon, it is a Draconic Weapon and it has keys
if (
gridWeapon &&
gridWeapon.object.series === 3 &&
gridWeapon.weapon_keys
) {
if (index === 0 && gridWeapon.weapon_keys[0]) {
altText = `${gridWeapon.weapon_keys[0].name[locale]}`
filename = `${gridWeapon.weapon_keys[0].slug}.png`
} else if (index === 1 && gridWeapon.weapon_keys[1]) {
altText = `${gridWeapon.weapon_keys[1].name[locale]}`
if (gridWeapon && gridWeapon.object.series === 3 && gridWeapon.weaponKeys) {
if (index === 0 && gridWeapon.weaponKeys[0]) {
altText = `${gridWeapon.weaponKeys[0].name[locale]}`
filename = `${gridWeapon.weaponKeys[0].slug}.png`
} else if (index === 1 && gridWeapon.weaponKeys[1]) {
altText = `${gridWeapon.weaponKeys[1].name[locale]}`
const element = gridWeapon.object.element
filename = `${gridWeapon.weapon_keys[1].slug}-${element}.png`
filename = `${gridWeapon.weaponKeys[1].slug}-${element}.png`
}
return (
@ -273,10 +273,10 @@ const WeaponUnit = ({
if (
gridWeapon &&
gridWeapon.object.series === 3 &&
gridWeapon.weapon_keys &&
gridWeapon.weapon_keys.length > 0
gridWeapon.weaponKeys &&
gridWeapon.weaponKeys.length > 0
) {
for (let i = 0; i < gridWeapon.weapon_keys.length; i++) {
for (let i = 0; i < gridWeapon.weaponKeys.length; i++) {
const image = telumaImage(i)
if (image) images.push(image)
}
@ -294,25 +294,25 @@ const WeaponUnit = ({
if (
gridWeapon &&
gridWeapon.object.series === 17 &&
gridWeapon.weapon_keys
gridWeapon.weaponKeys
) {
if (
gridWeapon.weapon_keys[index] &&
(gridWeapon.weapon_keys[index].slot === 1 ||
gridWeapon.weapon_keys[index].slot === 2)
gridWeapon.weaponKeys[index] &&
(gridWeapon.weaponKeys[index].slot === 1 ||
gridWeapon.weaponKeys[index].slot === 2)
) {
altText = `${gridWeapon.weapon_keys[index].name[locale]}`
filename = `${gridWeapon.weapon_keys[index].slug}.png`
altText = `${gridWeapon.weaponKeys[index].name[locale]}`
filename = `${gridWeapon.weaponKeys[index].slug}.png`
} else if (
gridWeapon.weapon_keys[index] &&
gridWeapon.weapon_keys[index].slot === 0
gridWeapon.weaponKeys[index] &&
gridWeapon.weaponKeys[index].slot === 0
) {
altText = `${gridWeapon.weapon_keys[index].name[locale]}`
altText = `${gridWeapon.weaponKeys[index].name[locale]}`
const weapon = gridWeapon.object.proficiency
const suffix = `${weapon}`
filename = `${gridWeapon.weapon_keys[index].slug}-${suffix}.png`
filename = `${gridWeapon.weaponKeys[index].slug}-${suffix}.png`
}
}
@ -331,10 +331,10 @@ const WeaponUnit = ({
if (
gridWeapon &&
gridWeapon.object.series === 17 &&
gridWeapon.weapon_keys &&
gridWeapon.weapon_keys.length > 0
gridWeapon.weaponKeys &&
gridWeapon.weaponKeys.length > 0
) {
for (let i = 0; i < gridWeapon.weapon_keys.length; i++) {
for (let i = 0; i < gridWeapon.weaponKeys.length; i++) {
const image = ultimaImage(i)
if (image) images.push(image)
}
@ -349,22 +349,18 @@ const WeaponUnit = ({
let altText = ''
// If there is a grid weapon, it is a Dark Opus Weapon and it has keys
if (
gridWeapon &&
gridWeapon.object.series === 2 &&
gridWeapon.weapon_keys
) {
if (gridWeapon && gridWeapon.object.series === 2 && gridWeapon.weaponKeys) {
if (
gridWeapon.weapon_keys[index] &&
gridWeapon.weapon_keys[index].slot === 0
gridWeapon.weaponKeys[index] &&
gridWeapon.weaponKeys[index].slot === 0
) {
altText = `${gridWeapon.weapon_keys[index].name[locale]}`
filename = `${gridWeapon.weapon_keys[index].slug}.png`
altText = `${gridWeapon.weaponKeys[index].name[locale]}`
filename = `${gridWeapon.weaponKeys[index].slug}.png`
} else if (
gridWeapon.weapon_keys[index] &&
gridWeapon.weapon_keys[index].slot === 1
gridWeapon.weaponKeys[index] &&
gridWeapon.weaponKeys[index].slot === 1
) {
altText = `${gridWeapon.weapon_keys[index].name[locale]}`
altText = `${gridWeapon.weaponKeys[index].name[locale]}`
const element = gridWeapon.object.element
const mod = gridWeapon.object.name.en.includes('Repudiation')
@ -372,7 +368,7 @@ const WeaponUnit = ({
: 'magna'
const suffix = `${mod}-${element}`
const weaponKey = gridWeapon.weapon_keys[index]
const weaponKey = gridWeapon.weaponKeys[index]
if (
[
@ -384,9 +380,9 @@ const WeaponUnit = ({
'chain-glorification',
].includes(weaponKey.slug)
) {
filename = `${gridWeapon.weapon_keys[index].slug}-${suffix}.png`
filename = `${gridWeapon.weaponKeys[index].slug}-${suffix}.png`
} else {
filename = `${gridWeapon.weapon_keys[index].slug}.png`
filename = `${gridWeapon.weaponKeys[index].slug}.png`
}
}
@ -406,10 +402,10 @@ const WeaponUnit = ({
if (
gridWeapon &&
gridWeapon.object.series === 2 &&
gridWeapon.weapon_keys &&
gridWeapon.weapon_keys.length > 0
gridWeapon.weaponKeys &&
gridWeapon.weaponKeys.length > 0
) {
for (let i = 0; i < gridWeapon.weapon_keys.length; i++) {
for (let i = 0; i < gridWeapon.weaponKeys.length; i++) {
const image = opusImage(i)
if (image) images.push(image)
}
@ -424,7 +420,7 @@ const WeaponUnit = ({
if (
gridWeapon &&
gridWeapon.object.ax &&
gridWeapon.object.ax_type > 0 &&
gridWeapon.object.axType > 0 &&
gridWeapon.ax &&
axSkill
) {
@ -592,7 +588,7 @@ const WeaponUnit = ({
type="weapon"
ulb={gridWeapon.object.uncap.ulb || false}
flb={gridWeapon.object.uncap.flb || false}
uncapLevel={gridWeapon.uncap_level}
uncapLevel={gridWeapon.uncapLevel}
position={gridWeapon.position}
updateUncap={passUncapData}
special={false}

View file

@ -4,7 +4,7 @@ export const NO_AWAKENING: Awakening = {
id: '0',
name: {
en: 'No awakening',
jp: '覚醒なし',
ja: '覚醒なし',
},
slug: 'no-awakening',
order: 0,

View file

@ -6,7 +6,7 @@ const ax: ItemSkill[][] = [
ja: '攻撃',
},
id: 0,
granblue_id: '1589',
granblueId: '1589',
slug: 'atk',
minValue: 1,
maxValue: 3.5,
@ -19,7 +19,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 4,
@ -32,7 +32,7 @@ const ax: ItemSkill[][] = [
ja: 'DA確率',
},
id: 5,
granblue_id: '1596',
granblueId: '1596',
slug: 'da',
minValue: 1,
maxValue: 2,
@ -45,7 +45,7 @@ const ax: ItemSkill[][] = [
ja: 'TA確率',
},
id: 6,
granblue_id: '1597',
granblueId: '1597',
slug: 'ta',
minValue: 1,
maxValue: 2,
@ -58,7 +58,7 @@ const ax: ItemSkill[][] = [
ja: 'アビ上限',
},
id: 7,
granblue_id: '1588',
granblueId: '1588',
slug: 'skill-cap',
minValue: 1,
maxValue: 2,
@ -73,7 +73,7 @@ const ax: ItemSkill[][] = [
ja: '防御',
},
id: 1,
granblue_id: '1590',
granblueId: '1590',
slug: 'def',
minValue: 1,
maxValue: 8,
@ -86,7 +86,7 @@ const ax: ItemSkill[][] = [
ja: 'HP',
},
id: 2,
granblue_id: '1588',
granblueId: '1588',
slug: 'hp',
minValue: 1,
maxValue: 3,
@ -99,7 +99,7 @@ const ax: ItemSkill[][] = [
ja: '弱体耐性',
},
id: 9,
granblue_id: '1593',
granblueId: '1593',
slug: 'debuff',
minValue: 1,
maxValue: 3,
@ -112,7 +112,7 @@ const ax: ItemSkill[][] = [
ja: '回復性能',
},
id: 10,
granblue_id: '1595',
granblueId: '1595',
slug: 'healing',
minValue: 2,
maxValue: 5,
@ -125,7 +125,7 @@ const ax: ItemSkill[][] = [
ja: '背水',
},
id: 11,
granblue_id: '1601',
granblueId: '1601',
slug: 'enmity',
minValue: 1,
maxValue: 3,
@ -139,7 +139,7 @@ const ax: ItemSkill[][] = [
ja: 'HP',
},
id: 2,
granblue_id: '1588',
granblueId: '1588',
slug: 'hp',
minValue: 1,
maxValue: 11,
@ -152,7 +152,7 @@ const ax: ItemSkill[][] = [
ja: '防御',
},
id: 1,
granblue_id: '1590',
granblueId: '1590',
slug: 'def',
minValue: 1,
maxValue: 3,
@ -165,7 +165,7 @@ const ax: ItemSkill[][] = [
ja: '弱体耐性',
},
id: 9,
granblue_id: '1593',
granblueId: '1593',
slug: 'debuff',
minValue: 1,
maxValue: 3,
@ -178,7 +178,7 @@ const ax: ItemSkill[][] = [
ja: '回復性能',
},
id: 10,
granblue_id: '1595',
granblueId: '1595',
slug: 'healing',
minValue: 2,
maxValue: 5,
@ -191,7 +191,7 @@ const ax: ItemSkill[][] = [
ja: '渾身',
},
id: 12,
granblue_id: '1600',
granblueId: '1600',
slug: 'stamina',
minValue: 1,
maxValue: 3,
@ -205,7 +205,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 8.5,
@ -218,7 +218,7 @@ const ax: ItemSkill[][] = [
ja: '攻撃',
},
id: 0,
granblue_id: '1589',
granblueId: '1589',
slug: 'atk',
minValue: 1,
maxValue: 1.5,
@ -231,7 +231,7 @@ const ax: ItemSkill[][] = [
ja: '全属性攻撃力',
},
id: 13,
granblue_id: '1594',
granblueId: '1594',
slug: 'ele-atk',
minValue: 1,
maxValue: 5,
@ -244,7 +244,7 @@ const ax: ItemSkill[][] = [
ja: '奥義上限',
},
id: 8,
granblue_id: '1599',
granblueId: '1599',
slug: 'ca-cap',
minValue: 1,
maxValue: 2,
@ -257,7 +257,7 @@ const ax: ItemSkill[][] = [
ja: '渾身',
},
id: 12,
granblue_id: '1600',
granblueId: '1600',
slug: 'stamina',
minValue: 1,
maxValue: 3,
@ -271,7 +271,7 @@ const ax: ItemSkill[][] = [
ja: '連撃率',
},
id: 4,
granblue_id: '1592',
granblueId: '1592',
slug: 'ta',
minValue: 1,
maxValue: 4,
@ -284,7 +284,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 4,
@ -297,7 +297,7 @@ const ax: ItemSkill[][] = [
ja: '全属性攻撃力',
},
id: 13,
granblue_id: '1594',
granblueId: '1594',
slug: 'ele-atk',
minValue: 1,
maxValue: 5,
@ -310,7 +310,7 @@ const ax: ItemSkill[][] = [
ja: 'DA確率',
},
id: 5,
granblue_id: '1596',
granblueId: '1596',
slug: 'da',
minValue: 1,
maxValue: 2,
@ -323,7 +323,7 @@ const ax: ItemSkill[][] = [
ja: 'TA確率',
},
id: 6,
granblue_id: '1597',
granblueId: '1597',
slug: 'ta',
minValue: 1,
maxValue: 2,
@ -340,7 +340,7 @@ const ax: ItemSkill[][] = [
ja: '攻撃',
},
id: 0,
granblue_id: '1589',
granblueId: '1589',
slug: 'atk',
minValue: 1,
maxValue: 3.5,
@ -353,7 +353,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 8.5,
@ -366,7 +366,7 @@ const ax: ItemSkill[][] = [
ja: '連撃確率',
},
id: 4,
granblue_id: '1592',
granblueId: '1592',
slug: 'ta',
minValue: 1.5,
maxValue: 4,
@ -379,7 +379,7 @@ const ax: ItemSkill[][] = [
ja: '通常ダメ上限',
},
id: 14,
granblue_id: '1722',
granblueId: '1722',
slug: 'na-dmg',
minValue: 0.5,
maxValue: 1.5,
@ -392,7 +392,7 @@ const ax: ItemSkill[][] = [
ja: 'アビ与ダメ上昇',
},
id: 15,
granblue_id: '1719',
granblueId: '1719',
slug: 'skill-supp',
minValue: 1,
maxValue: 5,
@ -406,7 +406,7 @@ const ax: ItemSkill[][] = [
ja: '防御',
},
id: 1,
granblue_id: '1590',
granblueId: '1590',
slug: 'def',
minValue: 1,
maxValue: 8,
@ -419,7 +419,7 @@ const ax: ItemSkill[][] = [
ja: '属性ダメ軽減',
},
id: 17,
granblue_id: '1721',
granblueId: '1721',
slug: 'ele-def',
minValue: 1,
maxValue: 5,
@ -432,7 +432,7 @@ const ax: ItemSkill[][] = [
ja: '弱体耐性',
},
id: 9,
granblue_id: '1593',
granblueId: '1593',
slug: 'debuff',
minValue: 1,
maxValue: 3,
@ -445,7 +445,7 @@ const ax: ItemSkill[][] = [
ja: '回復性能',
},
id: 10,
granblue_id: '1595',
granblueId: '1595',
slug: 'healing',
minValue: 2,
maxValue: 5,
@ -458,7 +458,7 @@ const ax: ItemSkill[][] = [
ja: '背水',
},
id: 11,
granblue_id: '1601',
granblueId: '1601',
slug: 'enmity',
minValue: 1,
maxValue: 3,
@ -472,7 +472,7 @@ const ax: ItemSkill[][] = [
ja: 'HP',
},
id: 2,
granblue_id: '1588',
granblueId: '1588',
slug: 'hp',
minValue: 1,
maxValue: 11,
@ -485,7 +485,7 @@ const ax: ItemSkill[][] = [
ja: '属性ダメ軽減',
},
id: 17,
granblue_id: '1721',
granblueId: '1721',
slug: 'ele-def',
minValue: 1,
maxValue: 5,
@ -498,7 +498,7 @@ const ax: ItemSkill[][] = [
ja: '弱体耐性',
},
id: 9,
granblue_id: '1593',
granblueId: '1593',
slug: 'debuff',
minValue: 1,
maxValue: 3,
@ -511,7 +511,7 @@ const ax: ItemSkill[][] = [
ja: '回復性能',
},
id: 10,
granblue_id: '1595',
granblueId: '1595',
slug: 'healing',
minValue: 2,
maxValue: 5,
@ -524,7 +524,7 @@ const ax: ItemSkill[][] = [
ja: '渾身',
},
id: 12,
granblue_id: '1600',
granblueId: '1600',
slug: 'stamina',
minValue: 1,
maxValue: 3,
@ -538,7 +538,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 8.5,
@ -551,7 +551,7 @@ const ax: ItemSkill[][] = [
ja: '連撃率',
},
id: 4,
granblue_id: '1592',
granblueId: '1592',
slug: 'ta',
minValue: 1.5,
maxValue: 4,
@ -564,7 +564,7 @@ const ax: ItemSkill[][] = [
ja: 'アビ与ダメ上昇',
},
id: 15,
granblue_id: '1719',
granblueId: '1719',
slug: 'skill-supp',
minValue: 1,
maxValue: 5,
@ -576,7 +576,7 @@ const ax: ItemSkill[][] = [
ja: '奥義与ダメ上昇',
},
id: 16,
granblue_id: '1720',
granblueId: '1720',
slug: 'ca-supp',
minValue: 1,
maxValue: 5,
@ -588,7 +588,7 @@ const ax: ItemSkill[][] = [
ja: '渾身',
},
id: 12,
granblue_id: '1600',
granblueId: '1600',
slug: 'stamina',
minValue: 1,
maxValue: 3,
@ -602,7 +602,7 @@ const ax: ItemSkill[][] = [
ja: '連撃率',
},
id: 4,
granblue_id: '1592',
granblueId: '1592',
slug: 'ta',
minValue: 1,
maxValue: 4,
@ -615,7 +615,7 @@ const ax: ItemSkill[][] = [
ja: '奥義与ダメ上昇',
},
id: 16,
granblue_id: '1720',
granblueId: '1720',
slug: 'ca-supp',
minValue: 1,
maxValue: 5,
@ -627,7 +627,7 @@ const ax: ItemSkill[][] = [
ja: '通常ダメ上限',
},
id: 14,
granblue_id: '1722',
granblueId: '1722',
slug: 'na-cap',
minValue: 0.5,
maxValue: 1.5,
@ -640,7 +640,7 @@ const ax: ItemSkill[][] = [
ja: '渾身',
},
id: 12,
granblue_id: '1600',
granblueId: '1600',
slug: 'stamina',
minValue: 1,
maxValue: 3,
@ -652,7 +652,7 @@ const ax: ItemSkill[][] = [
ja: '背水',
},
id: 11,
granblue_id: '1601',
granblueId: '1601',
slug: 'enmity',
minValue: 1,
maxValue: 3,
@ -668,7 +668,7 @@ const ax: ItemSkill[][] = [
ja: '攻撃',
},
id: 0,
granblue_id: '1589',
granblueId: '1589',
slug: 'atk',
minValue: 1,
maxValue: 3.5,
@ -681,7 +681,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 4,
@ -694,7 +694,7 @@ const ax: ItemSkill[][] = [
ja: 'DA確率',
},
id: 5,
granblue_id: '1596',
granblueId: '1596',
slug: 'da',
minValue: 1,
maxValue: 2,
@ -707,7 +707,7 @@ const ax: ItemSkill[][] = [
ja: 'TA確率',
},
id: 6,
granblue_id: '1597',
granblueId: '1597',
slug: 'ta',
minValue: 1,
maxValue: 2,
@ -720,7 +720,7 @@ const ax: ItemSkill[][] = [
ja: 'アビ上限',
},
id: 7,
granblue_id: '1588',
granblueId: '1588',
slug: 'skill-cap',
minValue: 1,
maxValue: 2,
@ -735,7 +735,7 @@ const ax: ItemSkill[][] = [
ja: '防御',
},
id: 1,
granblue_id: '1590',
granblueId: '1590',
slug: 'def',
minValue: 1,
maxValue: 8,
@ -748,7 +748,7 @@ const ax: ItemSkill[][] = [
ja: 'HP',
},
id: 2,
granblue_id: '1588',
granblueId: '1588',
slug: 'hp',
minValue: 1,
maxValue: 3,
@ -761,7 +761,7 @@ const ax: ItemSkill[][] = [
ja: '弱体耐性',
},
id: 9,
granblue_id: '1593',
granblueId: '1593',
slug: 'debuff',
minValue: 1,
maxValue: 3,
@ -774,7 +774,7 @@ const ax: ItemSkill[][] = [
ja: '回復性能',
},
id: 10,
granblue_id: '1595',
granblueId: '1595',
slug: 'healing',
minValue: 2,
maxValue: 5,
@ -787,7 +787,7 @@ const ax: ItemSkill[][] = [
ja: '背水',
},
id: 11,
granblue_id: '1601',
granblueId: '1601',
slug: 'enmity',
minValue: 1,
maxValue: 3,
@ -801,7 +801,7 @@ const ax: ItemSkill[][] = [
ja: 'HP',
},
id: 2,
granblue_id: '1588',
granblueId: '1588',
slug: 'hp',
minValue: 1,
maxValue: 11,
@ -814,7 +814,7 @@ const ax: ItemSkill[][] = [
ja: '防御',
},
id: 1,
granblue_id: '1590',
granblueId: '1590',
slug: 'def',
minValue: 1,
maxValue: 3,
@ -827,7 +827,7 @@ const ax: ItemSkill[][] = [
ja: '弱体耐性',
},
id: 9,
granblue_id: '1593',
granblueId: '1593',
slug: 'debuff',
minValue: 1,
maxValue: 3,
@ -840,7 +840,7 @@ const ax: ItemSkill[][] = [
ja: '回復性能',
},
id: 10,
granblue_id: '1595',
granblueId: '1595',
slug: 'healing',
minValue: 2,
maxValue: 5,
@ -853,7 +853,7 @@ const ax: ItemSkill[][] = [
ja: '渾身',
},
id: 12,
granblue_id: '1600',
granblueId: '1600',
slug: 'stamina',
minValue: 1,
maxValue: 3,
@ -867,7 +867,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 8.5,
@ -880,7 +880,7 @@ const ax: ItemSkill[][] = [
ja: '攻撃',
},
id: 0,
granblue_id: '1589',
granblueId: '1589',
slug: 'atk',
minValue: 1,
maxValue: 1.5,
@ -893,7 +893,7 @@ const ax: ItemSkill[][] = [
ja: '全属性攻撃力',
},
id: 13,
granblue_id: '1594',
granblueId: '1594',
slug: 'ele-atk',
minValue: 1,
maxValue: 5,
@ -906,7 +906,7 @@ const ax: ItemSkill[][] = [
ja: '奥義上限',
},
id: 8,
granblue_id: '1599',
granblueId: '1599',
slug: 'ca-dmg',
minValue: 1,
maxValue: 2,
@ -919,7 +919,7 @@ const ax: ItemSkill[][] = [
ja: '渾身',
},
id: 12,
granblue_id: '1600',
granblueId: '1600',
slug: 'stamina',
minValue: 1,
maxValue: 3,
@ -933,7 +933,7 @@ const ax: ItemSkill[][] = [
ja: '連撃率',
},
id: 4,
granblue_id: '1592',
granblueId: '1592',
slug: 'ta',
minValue: 1,
maxValue: 4,
@ -946,7 +946,7 @@ const ax: ItemSkill[][] = [
ja: '奥義ダメ',
},
id: 3,
granblue_id: '1591',
granblueId: '1591',
slug: 'ca-dmg',
minValue: 2,
maxValue: 4,
@ -959,7 +959,7 @@ const ax: ItemSkill[][] = [
ja: '全属性攻撃力',
},
id: 13,
granblue_id: '1594',
granblueId: '1594',
slug: 'ele-atk',
minValue: 1,
maxValue: 5,
@ -972,7 +972,7 @@ const ax: ItemSkill[][] = [
ja: 'DA確率',
},
id: 5,
granblue_id: '1596',
granblueId: '1596',
slug: 'da',
minValue: 1,
maxValue: 2,
@ -985,7 +985,7 @@ const ax: ItemSkill[][] = [
ja: 'TA確率',
},
id: 6,
granblue_id: '1597',
granblueId: '1597',
slug: 'ta',
minValue: 1,
maxValue: 2,
@ -1000,7 +1000,7 @@ const ax: ItemSkill[][] = [
ja: 'EXP UP',
},
id: 18,
granblue_id: '1837',
granblueId: '1837',
slug: 'exp',
minValue: 5,
maxValue: 10,
@ -1013,7 +1013,7 @@ const ax: ItemSkill[][] = [
ja: '獲得ルピ',
},
id: 19,
granblue_id: '1838',
granblueId: '1838',
slug: 'rupie',
minValue: 10,
maxValue: 20,

View file

@ -5,7 +5,7 @@ const overMasteryPrimary: ItemSkill[] = [
ja: '攻撃',
},
id: 1,
granblue_id: '',
granblueId: '',
slug: 'atk',
minValue: 300,
maxValue: 3000,
@ -19,7 +19,7 @@ const overMasteryPrimary: ItemSkill[] = [
ja: 'HP',
},
id: 2,
granblue_id: '',
granblueId: '',
slug: 'hp',
minValue: 150,
maxValue: 1500,
@ -36,7 +36,7 @@ const overMasterySecondary: ItemSkill[] = [
ja: '弱体成功率',
},
id: 3,
granblue_id: '',
granblueId: '',
slug: 'debuff-success',
minValue: 6,
maxValue: 15,
@ -50,7 +50,7 @@ const overMasterySecondary: ItemSkill[] = [
ja: 'アビダメ上限',
},
id: 4,
granblue_id: '',
granblueId: '',
slug: 'skill-cap',
minValue: 6,
maxValue: 15,
@ -64,7 +64,7 @@ const overMasterySecondary: ItemSkill[] = [
ja: '奥義ダメージ',
},
id: 5,
granblue_id: '',
granblueId: '',
slug: 'ca-dmg',
minValue: 10,
maxValue: 30,
@ -78,7 +78,7 @@ const overMasterySecondary: ItemSkill[] = [
ja: '奥義ダメージ上限',
},
id: 6,
granblue_id: '',
granblueId: '',
slug: 'ca-cap',
minValue: 6,
maxValue: 15,
@ -92,7 +92,7 @@ const overMasterySecondary: ItemSkill[] = [
ja: '渾身',
},
id: 7,
granblue_id: '',
granblueId: '',
slug: 'stamina',
minValue: 1,
maxValue: 10,
@ -106,7 +106,7 @@ const overMasterySecondary: ItemSkill[] = [
ja: '背水',
},
id: 8,
granblue_id: '',
granblueId: '',
slug: 'enmity',
minValue: 1,
maxValue: 10,
@ -120,7 +120,7 @@ const overMasterySecondary: ItemSkill[] = [
ja: 'クリティカル確率',
},
id: 9,
granblue_id: '',
granblueId: '',
slug: 'crit',
minValue: 10,
maxValue: 30,
@ -137,7 +137,7 @@ const overMasteryTertiary: ItemSkill[] = [
ja: 'ダブルアタック確率',
},
id: 10,
granblue_id: '',
granblueId: '',
slug: 'da',
minValue: 6,
maxValue: 15,
@ -151,7 +151,7 @@ const overMasteryTertiary: ItemSkill[] = [
ja: 'トリプルアタック確率',
},
id: 11,
granblue_id: '',
granblueId: '',
slug: 'ta',
minValue: 1,
maxValue: 10,
@ -165,7 +165,7 @@ const overMasteryTertiary: ItemSkill[] = [
ja: '防御',
},
id: 12,
granblue_id: '',
granblueId: '',
slug: 'def',
minValue: 6,
maxValue: 20,
@ -179,7 +179,7 @@ const overMasteryTertiary: ItemSkill[] = [
ja: '回復性能',
},
id: 13,
granblue_id: '',
granblueId: '',
slug: 'heal',
minValue: 3,
maxValue: 30,
@ -193,7 +193,7 @@ const overMasteryTertiary: ItemSkill[] = [
ja: '弱体耐性',
},
id: 14,
granblue_id: '',
granblueId: '',
slug: 'debuff-resist',
minValue: 6,
maxValue: 15,
@ -207,7 +207,7 @@ const overMasteryTertiary: ItemSkill[] = [
ja: '回避',
},
id: 15,
granblue_id: '',
granblueId: '',
slug: 'dodge',
minValue: 1,
maxValue: 10,
@ -230,7 +230,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: 'ダブルアタック確率',
},
id: 1,
granblue_id: '',
granblueId: '',
slug: 'da',
minValue: 10,
maxValue: 17,
@ -243,7 +243,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: 'トリプルアタック確率',
},
id: 2,
granblue_id: '',
granblueId: '',
slug: 'ta',
minValue: 5,
maxValue: 12,
@ -256,7 +256,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: '{属性}攻撃',
},
id: 3,
granblue_id: '',
granblueId: '',
slug: 'element-atk',
minValue: 15,
maxValue: 22,
@ -269,7 +269,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: '{属性}軽減',
},
id: 4,
granblue_id: '',
granblueId: '',
slug: 'element-resist',
minValue: 5,
maxValue: 12,
@ -282,7 +282,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: '渾身',
},
id: 5,
granblue_id: '',
granblueId: '',
slug: 'stamina',
minValue: 5,
maxValue: 12,
@ -295,7 +295,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: '背水',
},
id: 6,
granblue_id: '',
granblueId: '',
slug: 'enmity',
minValue: 5,
maxValue: 12,
@ -308,7 +308,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: '与ダメ上昇',
},
id: 7,
granblue_id: '',
granblueId: '',
slug: 'supplemental',
minValue: 5,
maxValue: 12,
@ -321,7 +321,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: 'クリティカル',
},
id: 8,
granblue_id: '',
granblueId: '',
slug: 'crit',
minValue: 18,
maxValue: 35,
@ -334,7 +334,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: 'カウンター(回避)',
},
id: 9,
granblue_id: '',
granblueId: '',
slug: 'counter-dodge',
minValue: 5,
maxValue: 12,
@ -347,7 +347,7 @@ export const aetherialMastery: ItemSkill[] = [
ja: 'カウンター(被ダメ)',
},
id: 10,
granblue_id: '',
granblueId: '',
slug: 'counter-dmg',
minValue: 10,
maxValue: 17,
@ -363,7 +363,7 @@ export const permanentMastery: ItemSkill[] = [
ja: 'LB強化回数上限',
},
id: 1,
granblue_id: '',
granblueId: '',
slug: 'star-cap',
minValue: 10,
maxValue: 10,
@ -376,7 +376,7 @@ export const permanentMastery: ItemSkill[] = [
ja: '攻撃',
},
id: 2,
granblue_id: '',
granblueId: '',
slug: 'atk',
minValue: 10,
maxValue: 10,
@ -389,7 +389,7 @@ export const permanentMastery: ItemSkill[] = [
ja: 'HP',
},
id: 3,
granblue_id: '',
granblueId: '',
slug: 'hp',
minValue: 10,
maxValue: 10,
@ -402,7 +402,7 @@ export const permanentMastery: ItemSkill[] = [
ja: 'ダメージ上限',
},
id: 4,
granblue_id: '',
granblueId: '',
slug: 'dmg-cap',
minValue: 5,
maxValue: 5,

View file

@ -22,6 +22,8 @@ import FilterBar from '~components/filters/FilterBar'
import ProfileHead from '~components/head/ProfileHead'
import UserInfo from '~components/filters/UserInfo'
import * as RaidGroupTransformer from '~transformers/RaidGroupTransformer'
import type { AxiosError } from 'axios'
import type { NextApiRequest, NextApiResponse } from 'next'
import type {
@ -175,7 +177,11 @@ const ProfileRoute: React.FC<Props> = ({
function replaceResults(count: number, list: Party[]) {
if (count > 0) {
setParties(list.sort((a, b) => (a.created_at > b.created_at ? -1 : 1)))
setParties(
list.sort((a, b) =>
a.timestamps.createdAt > b.timestamps.createdAt ? -1 : 1
)
)
} else {
setParties([])
}
@ -252,13 +258,13 @@ const ProfileRoute: React.FC<Props> = ({
id={party.id}
shortcode={party.shortcode}
name={party.name}
createdAt={new Date(party.created_at)}
createdAt={new Date(party.timestamps.createdAt)}
raid={party.raid}
grid={party.weapons}
weapons={party.grid.weapons}
user={party.user}
favorited={party.favorited}
fullAuto={party.full_auto}
autoGuard={party.auto_guard}
favorited={party.social.favorited}
fullAuto={party.details.fullAuto}
autoGuard={party.details.autoGuard}
key={`party-${i}`}
onClick={goTo}
/>
@ -331,9 +337,11 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
try {
// Fetch and organize raids
let raidGroups: RaidGroup[] = await api
const raidGroups: RaidGroup[] = await api
.raidGroups()
.then((response) => response.data)
.then((response) =>
response.data.map((group: any) => RaidGroupTransformer.toObject(group))
)
// Create filter object
const filters: FilterObject = extractFilters(query, raidGroups)

View file

@ -11,7 +11,13 @@ import elementEmoji from '~utils/elementEmoji'
import fetchLatestVersion from '~utils/fetchLatestVersion'
import { setHeaders } from '~utils/userToken'
import { appState } from '~utils/appState'
import { groupWeaponKeys } from '~utils/groupWeaponKeys'
import { GroupedWeaponKeys, groupWeaponKeys } from '~utils/groupWeaponKeys'
import * as JobTransformer from '~transformers/JobTransformer'
import * as JobSkillTransformer from '~transformers/JobTransformer'
import * as PartyTransformer from '~transformers/PartyTransformer'
import * as RaidGroupTransformer from '~transformers/RaidGroupTransformer'
import * as WeaponKeyTransformer from '~transformers/WeaponKeyTransformer'
import { GridType } from '~utils/enums'
import type { NextApiRequest, NextApiResponse } from 'next'
@ -126,7 +132,7 @@ const PartyRoute: React.FC<Props> = ({
<React.Fragment key={router.asPath}>
{pageHead()}
<Party
team={context.party}
party={context.party}
selectedTab={selectedTab}
raidGroups={context.raidGroups}
handleTabChanged={handleTabChange}
@ -156,33 +162,38 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
try {
// Fetch and organize raids
let raidGroups: RaidGroup[] = await api
const raidGroups: RaidGroup[] = await api
.raidGroups()
.then((response) => response.data)
.then((response) => response.data.map((group: any) => RaidGroupTransformer.toObject(group)))
// Fetch jobs and job skills
let jobs = await api.endpoints.jobs
const jobs: Job[] = await api.endpoints.jobs
.getAll()
.then((response) => response.data)
.then((response) =>
response.data.map((job: any) => JobTransformer.toObject(job))
)
let jobSkills = await api.allJobSkills()
.then((response) => response.data)
const jobSkills: JobSkill[] = await api
.allJobSkills()
.then((response) =>
response.data.map((skill: any) => JobSkillTransformer.toObject(skill))
)
// Fetch and organize weapon keys
let weaponKeys = await api.endpoints.weapon_keys
const weaponKeys: GroupedWeaponKeys = await api.endpoints.weapon_keys
.getAll()
.then((response) => groupWeaponKeys(response.data))
.then((response) =>
response.data.map((key: any) => WeaponKeyTransformer.toObject(key))
)
.then((keys) => groupWeaponKeys(keys))
// Fetch the party
let party: Party | undefined = undefined
if (query.party) {
let response = await api.endpoints.parties.getOne({
id: query.party,
})
party = response.data.party
} else {
console.error('No party code')
}
if (!query.party) throw new Error('No party code')
const party: Party | undefined = await api.endpoints.parties.getOne({
id: query.party,
}).then((response) => PartyTransformer.toObject(response.data.party))
// Consolidate data into context object
const context: PageContextObj = {
@ -206,6 +217,8 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
},
}
} catch (error) {
console.error(error)
// Extract the underlying Axios error
const axiosError = error as AxiosError
const response = axiosError.response

View file

@ -238,7 +238,7 @@ const SavedRoute: React.FC<Props> = ({
const index = parties.findIndex((p) => p.id === teamId)
const party = parties[index]
party.favorited = true
party.social.favorited = true
let clonedParties = clonedeep(parties)
clonedParties[index] = party
@ -254,7 +254,7 @@ const SavedRoute: React.FC<Props> = ({
const index = parties.findIndex((p) => p.id === teamId)
const party = parties[index]
party.favorited = false
party.social.favorited = false
let clonedParties = clonedeep(parties)
clonedParties.splice(index, 1)
@ -291,13 +291,13 @@ const SavedRoute: React.FC<Props> = ({
id={party.id}
shortcode={party.shortcode}
name={party.name}
createdAt={new Date(party.created_at)}
createdAt={new Date(party.timestamps.createdAt)}
raid={party.raid}
grid={party.weapons}
weapons={party.grid.weapons}
user={party.user}
favorited={party.favorited}
fullAuto={party.full_auto}
autoGuard={party.auto_guard}
favorited={party.social.favorited}
fullAuto={party.details.fullAuto}
autoGuard={party.details.autoGuard}
key={`party-${i}`}
onClick={goTo}
onSave={toggleFavorite}

View file

@ -189,7 +189,11 @@ const TeamsRoute: React.FC<Props> = ({
function replaceResults(count: number, list: Party[]) {
if (count > 0) {
setParties(list.sort((a, b) => (a.created_at > b.created_at ? -1 : 1)))
setParties(
list.sort((a, b) =>
a.timestamps.createdAt > b.timestamps.createdAt ? -1 : 1
)
)
} else {
setParties([])
}
@ -249,7 +253,7 @@ const TeamsRoute: React.FC<Props> = ({
const index = parties.findIndex((p) => p.id === teamId)
const party = parties[index]
party.favorited = true
party.social.favorited = true
let clonedParties = clonedeep(parties)
clonedParties[index] = party
@ -265,7 +269,7 @@ const TeamsRoute: React.FC<Props> = ({
const index = parties.findIndex((p) => p.id === teamId)
const party = parties[index]
party.favorited = false
party.social.favorited = false
let clonedParties = clonedeep(parties)
clonedParties[index] = party
@ -302,13 +306,13 @@ const TeamsRoute: React.FC<Props> = ({
id={party.id}
shortcode={party.shortcode}
name={party.name}
createdAt={new Date(party.created_at)}
createdAt={new Date(party.timestamps.createdAt)}
raid={party.raid}
grid={party.weapons}
weapons={party.grid.weapons}
user={party.user}
favorited={party.favorited}
fullAuto={party.full_auto}
autoGuard={party.auto_guard}
favorited={party.social.favorited}
fullAuto={party.details.fullAuto}
autoGuard={party.details.autoGuard}
key={`party-${i}`}
onClick={goTo}
onSave={toggleFavorite}

View file

@ -6,7 +6,7 @@ export function toObject(data: any): Character {
return {
type: 'character',
id: data.id,
granblueId: data.granblue_id,
granblueId: data.granblueId,
characterId: data.character_id,
name: {
en: data.name.en,

View file

@ -7,7 +7,7 @@ export function toObject(data: any): GridCharacter {
id: data.id,
object: Character.toObject(data.object),
position: data.position,
uncapLevel: data.uncap_level,
uncapLevel: data.uncapLevel,
transcendenceStep: data.transcendence_step,
mastery: {
overMastery: data.over_mastery,
@ -26,7 +26,7 @@ export function toParams(data: GridCharacter): GridCharacterParams {
return {
character_id: data.id,
position: data.position,
uncap_level: data.uncapLevel,
uncapLevel: data.uncapLevel,
transcendence_step: data.transcendenceStep,
ring1: data.mastery.overMastery[1],
ring2: data.mastery.overMastery[2],

View file

@ -8,7 +8,7 @@ export function toObject(data: any): GridSummon {
position: data.position,
main: data.main,
friend: data.friend,
uncapLevel: data.uncap_level,
uncapLevel: data.uncapLevel,
transcendenceStep: data.transcendence_step,
quickSummon: data.quick_summon,
}
@ -19,7 +19,7 @@ export function toParams(data: GridSummon): GridSummonParams {
return {
summon_id: data.id,
position: data.position,
uncap_level: data.uncapLevel,
uncapLevel: data.uncapLevel,
transcendence_step: data.transcendenceStep,
quick_summon: data.quickSummon,
}

View file

@ -0,0 +1,31 @@
import * as GridWeapon from '~transformers/GridWeaponTransformer'
import * as GridSummon from '~transformers/GridSummonTransformer'
import * as GridCharacter from '~transformers/GridCharacterTransformer'
// Transforms API response to Party object
export function toObject(data: any): Grid {
return {
characters: data.characters.map((character: any) =>
GridCharacter.toObject(character)
),
summons: {
mainSummon: GridSummon.toObject(
data.summons.find((summon: any) => summon.main === true)
),
friendSummon: GridSummon.toObject(
data.summons.find((summon: any) => summon.friend === true)
),
allSummons: data.summons.map((summon: any) => {
if (!summon.main && !summon.friend) return GridSummon.toObject(summon)
}),
},
weapons: {
mainWeapon: GridWeapon.toObject(
data.weapons.find((weapon: any) => weapon.mainhand === true)
),
allWeapons: data.weapons.map((weapon: any) => {
if (!weapon.mainhand) return GridWeapon.toObject(weapon)
}),
},
}
}

View file

@ -10,7 +10,7 @@ export function toObject(data: any): GridWeapon {
object: Weapon.toObject(data.object),
position: data.position,
mainhand: data.mainhand,
uncapLevel: data.uncap_level,
uncapLevel: data.uncapLevel,
element: Element.toObject(data.element),
weaponKeys: data.weapon_keys.map((key: any) => WeaponKey.toObject(key)),
ax: data.ax,
@ -26,7 +26,7 @@ export function toParams(data: GridWeapon): GridWeaponParams {
return {
weapon_id: data.id,
position: data.position,
uncap_level: data.uncapLevel,
uncapLevel: data.uncapLevel,
element: data.element.id,
weapon_key1_id: data.weaponKeys?.[0].id,
weapon_key2_id: data.weaponKeys?.[1].id,

View file

@ -4,7 +4,7 @@ import * as Job from './JobTransformer'
export function toObject(data: any): JobAccessory {
return {
id: data.id,
granblueId: data.granblue_id,
granblueId: data.granblueId,
name: {
en: data.name.en,
ja: data.name.jp,

View file

@ -2,7 +2,7 @@
export function toObject(data: any): Job {
return {
id: data.id,
granblueId: data.granblue_id,
granblueId: data.granblueId,
name: {
en: data.name.en,
ja: data.name.jp,

View file

@ -1,3 +1,4 @@
import * as Grid from './GridTransformer'
import * as Job from './JobTransformer'
import * as JobAccessory from './JobAccessoryTransformer'
import * as JobSkill from './JobSkillTransformer'
@ -13,6 +14,12 @@ export function toObject(data: any): Party {
description: data.description,
shortcode: data.shortcode,
user: User.toObject(data.user),
editable: data.editable ?? false,
grid: Grid.toObject({
characters: data.characters,
summons: data.summons,
weapons: data.weapons,
}),
details: {
extra: data.extra,
fullAuto: data.full_auto,
@ -61,7 +68,7 @@ export function toParams(party: Party): PartyParams {
button_count: party.details.buttonCount,
turn_count: party.details.turnCount,
chain_count: party.details.chainCount,
raid_id: party.raid.id,
raid_id: party.raid?.id,
job_id: party.protagonist.job.id,
master_level: party.protagonist.masterLevel,
ultimate_mastery: party.protagonist.ultimateMastery,

View file

@ -5,7 +5,7 @@ export function toObject(data: any): Summon {
return {
type: 'summon',
id: data.id,
granblueId: data.granblue_id,
granblueId: data.granblueId,
name: {
en: data.name.en,
ja: data.name.jp,

View file

@ -2,7 +2,7 @@
export function toObject(data: any): WeaponKey {
return {
id: data.id,
granblueId: data.granblue_id,
granblueId: data.granblueId,
name: {
en: data.name.en,
ja: data.name.jp,

View file

@ -6,7 +6,7 @@ export function toObject(data: any): Weapon {
return {
type: 'weapon',
id: data.id,
granblueId: data.granblue_id,
granblueId: data.granblueId,
name: {
en: data.name.en,
ja: data.name.jp,

12
types/Grid.d.ts vendored Normal file
View file

@ -0,0 +1,12 @@
interface Grid {
weapons: {
mainWeapon: GridWeapon | undefined
allWeapons: GridArray<GridWeapon>
}
summons: {
mainSummon: GridSummon | undefined
friendSummon: GridSummon | undefined
allSummons: GridArray<GridSummon>
}
characters: GridArray<GridCharacter>
}

View file

@ -1,7 +1,7 @@
interface GridCharacterParams {
character_id: string
position?: number
uncap_level?: number
uncapLevel?: number
transcendence_step?: number
ring1?: ExtendedMastery
ring2?: ExtendedMastery

View file

@ -1,7 +1,7 @@
interface GridSummonParams {
summon_id: string
position?: number
uncap_level?: number
uncapLevel?: number
transcendence_step?: number
quick_summon?: boolean
}

View file

@ -1,7 +1,7 @@
interface GridWeaponParams {
weapon_id: string
position?: number
uncap_level?: number
uncapLevel?: number
element?: number
weapon_key1_id?: string
weapon_key2_id?: string

View file

@ -1,6 +1,6 @@
interface Guidebook {
id: string
granblue_id: string
granblueId: string
name: {
[key: string]: string
en: string

View file

@ -5,7 +5,7 @@ interface ItemSkill {
ja: string
}
id: number
granblue_id: string
granblueId: string
slug: string
minValue: number
maxValue: number

7
types/Party.d.ts vendored
View file

@ -19,7 +19,10 @@ interface Party {
name: string
description: string
shortcode: string
user: User
user?: User
editable: boolean
element?: GranblueElement
grid: Grid
details: {
extra: boolean
fullAuto: boolean
@ -44,7 +47,7 @@ interface Party {
remix: boolean
remixes: Party[]
}
raid: Raid
raid?: Raid
guidebooks: GuidebookList
timestamps: {
createdAt: string

View file

@ -174,7 +174,7 @@ class Api {
return axios.post(resourceUrl, {
[resource]: {
id: id,
uncap_level: value,
uncapLevel: value,
transcendence_step: 0
}
})

View file

@ -1,13 +1,16 @@
import { proxy } from 'valtio'
import { JobSkillObject, ResponseStatus } from '~types'
import { ResponseStatus } from '~types'
import { GroupedWeaponKeys } from './groupWeaponKeys'
import { elements } from '~utils/elements'
const nullElement = elements[0]
const emptyJob: Job = {
id: '-1',
granblue_id: '-1',
granblueId: '-1',
row: '',
master_level: false,
ultimate_mastery: false,
masterLevel: false,
ultimateMastery: false,
order: 0,
name: {
en: '',
@ -23,7 +26,7 @@ const emptyJob: Job = {
const emptyJobAccessory: JobAccessory = {
id: '-1',
granblue_id: '-1',
granblueId: '-1',
job: emptyJob,
name: {
en: '',
@ -35,48 +38,7 @@ const emptyJobAccessory: JobAccessory = {
interface AppState {
[key: string]: any
party: {
id: string | undefined
shortcode: string | undefined
editable: boolean
detailsVisible: boolean
name: string | undefined
description: string | undefined
job: Job
jobSkills: JobSkillObject
accessory: JobAccessory
raid: Raid | undefined
element: number
fullAuto: boolean
autoGuard: boolean
autoSummon: boolean
chargeAttack: boolean
clearTime: number
buttonCount?: number
turnCount?: number
chainCount?: number
extra: boolean
guidebooks: GuidebookList
user: User | undefined
favorited: boolean
remix: boolean
remixes: Party[]
sourceParty?: Party
created_at: string
updated_at: string
}
grid: {
weapons: {
mainWeapon: GridWeapon | undefined
allWeapons: GridArray<GridWeapon>
}
summons: {
mainSummon: GridSummon | undefined
friendSummon: GridSummon | undefined
allSummons: GridArray<GridSummon>
}
characters: GridArray<GridCharacter>
}
party: Party
search: {
recents: {
characters: Character[]
@ -94,55 +56,64 @@ interface AppState {
export const initialAppState: AppState = {
party: {
id: undefined,
id: '',
shortcode: '',
editable: false,
detailsVisible: false,
name: undefined,
description: undefined,
job: emptyJob,
jobSkills: {
0: undefined,
1: undefined,
2: undefined,
3: undefined,
},
accessory: emptyJobAccessory,
name: '',
description: '',
user: undefined,
raid: undefined,
fullAuto: false,
autoGuard: false,
autoSummon: false,
chargeAttack: true,
clearTime: 0,
buttonCount: undefined,
turnCount: undefined,
chainCount: undefined,
element: 0,
extra: false,
editable: false,
element: nullElement,
protagonist: {
job: emptyJob,
skills: {
0: undefined,
1: undefined,
2: undefined,
3: undefined,
},
masterLevel: 0,
ultimateMastery: 0,
accessory: emptyJobAccessory,
},
details: {
fullAuto: false,
autoGuard: false,
autoSummon: false,
chargeAttack: true,
extra: false,
clearTime: 0,
buttonCount: undefined,
turnCount: undefined,
chainCount: undefined,
},
guidebooks: {
0: undefined,
1: undefined,
2: undefined,
},
user: undefined,
favorited: false,
remix: false,
remixes: [],
sourceParty: undefined,
created_at: '',
updated_at: '',
},
grid: {
weapons: {
mainWeapon: undefined,
allWeapons: {},
social: {
favorited: false,
remix: false,
remixes: [],
sourceParty: undefined,
},
summons: {
mainSummon: undefined,
friendSummon: undefined,
allSummons: {},
timestamps: {
createdAt: '',
updatedAt: '',
},
grid: {
weapons: {
mainWeapon: undefined,
allWeapons: {},
},
summons: {
mainSummon: undefined,
friendSummon: undefined,
allSummons: {},
},
characters: {},
},
characters: {},
},
search: {
recents: {
@ -168,5 +139,5 @@ export const initialAppState: AppState = {
},
status: undefined,
}
// editable: false,
export const appState = proxy(initialAppState)

View file

@ -1,14 +1,15 @@
import { ElementMap } from './elements'
import getElementForParty from './getElementForParty'
export default function elementEmoji(party?: Party) {
const element = party ? getElementForParty(party) : 0
const element = party ? getElementForParty(party) : ElementMap.null
if (element === 0) return '⚪'
else if (element === 1) return '🟢'
else if (element === 2) return '🔴'
else if (element === 3) return '🔵'
else if (element === 4) return '🟤'
else if (element === 5) return '🟣'
else if (element === 6) return '🟡'
if (element === ElementMap.null) return '⚪'
else if (element === ElementMap.wind) return '🟢'
else if (element === ElementMap.fire) return '🔴'
else if (element === ElementMap.water) return '🔵'
else if (element === ElementMap.earth) return '🟤'
else if (element === ElementMap.dark) return '🟣'
else if (element === ElementMap.light) return '🟡'
else return '⚪'
}

View file

@ -1,11 +1,13 @@
import { elements } from '~data/elements'
import { elements } from '~utils/elements'
import { aetherialMastery } from '~data/overMastery'
export default function elementalizeAetherialMastery(
gridCharacter: GridCharacter
) {
const elementalized = aetherialMastery.map((modifier) => {
const element = elements.find((a) => a.id === gridCharacter.object.element)
const element = elements.find(
(a) => a.id === gridCharacter.object.element.id
)
const oppositeElement = elements.find((b) => {
if (element) return b.id === element.opposite_id
@ -40,7 +42,7 @@ export default function elementalizeAetherialMastery(
elementalized.unshift({
id: 0,
granblue_id: '',
granblueId: '',
name: {
en: 'No aetherial mastery',
ja: 'エーテリアルプラス',

View file

@ -63,3 +63,13 @@ export const elements: GranblueElement[] = [
slug: 'light',
},
]
export class ElementMap {
public static null = elements[0]
public static wind = elements[1]
public static fire = elements[2]
public static water = elements[3]
public static earth = elements[4]
public static dark = elements[5]
public static light = elements[6]
}

View file

@ -1,6 +1,8 @@
import { ElementMap } from './elements'
export default function getElementForParty(party: Party) {
const mainhand = party.weapons.find((weapon) => weapon.mainhand)
if (mainhand && mainhand.object.element === 0) {
const mainhand = party.grid.weapons.mainWeapon
if (mainhand && mainhand.object.element === ElementMap.null) {
return mainhand.element
} else {
return mainhand?.object.element

View file

@ -10,12 +10,12 @@ import {
MentionSuggestion,
} from '~components/MentionList'
import api from '~utils/api'
import { numberToElement } from '~utils/elements'
import * as ElementTransformer from '~transformers/ElementTransformer'
import { get } from 'http'
interface RawSearchResponse {
searchable_type: string
granblue_id: string
granblueId: string
name_en: string
name_jp: string
element: number
@ -28,7 +28,7 @@ interface SearchResponse {
ja: string
}
type: string
granblue_id: string
granblueId: string
element: GranblueElement
}
@ -39,8 +39,8 @@ function transform(object: RawSearchResponse) {
ja: object.name_jp,
},
type: object.searchable_type.toLowerCase(),
granblue_id: object.granblue_id,
element: numberToElement(object.element),
granblueId: object.granblueId,
element: ElementTransformer.toObject(object.element),
}
return result
}
@ -57,7 +57,7 @@ export const mentionSuggestionOptions: MentionOptions['suggestion'] = {
.map((rawObject: RawSearchResponse, index: number) => {
const object = transform(rawObject)
return {
granblue_id: object.granblue_id,
granblueId: object.granblueId,
element: object.element,
type: object.type,
name: {