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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,7 +19,7 @@ const GuidebookResult = (props: Props) => {
<li className={styles.result} onClick={props.onClick}> <li className={styles.result} onClick={props.onClick}>
<img <img
alt={guidebook.name[locale]} 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}> <div className={styles.info}>
<h5>{guidebook.name[locale]}</h5> <h5>{guidebook.name[locale]}</h5>

View file

@ -99,7 +99,7 @@ const GuidebookUnit = ({
// Methods: Image string generation // Methods: Image string generation
function generateImageUrl() { function generateImageUrl() {
let imgSrc = guidebook 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) setImageUrl(imgSrc)

View file

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

View file

@ -18,13 +18,13 @@ const JobAccessoryItem = ({ accessory, selected }: Props) => {
return ( return (
<RadioGroup.Item <RadioGroup.Item
className="JobAccessoryItem" className={styles.item}
data-state={selected ? 'checked' : 'unchecked'} data-state={selected ? 'checked' : 'unchecked'}
value={accessory.id} value={accessory.id}
> >
<img <img
alt={accessory.name[locale]} 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> <h4>{accessory.name[locale]}</h4>
</RadioGroup.Item> </RadioGroup.Item>

View file

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

View file

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

View file

@ -39,8 +39,8 @@ const JobDropdown = React.forwardRef<HTMLSelectElement, Props>(
// Set current job from state on mount // Set current job from state on mount
useEffect(() => { useEffect(() => {
if (party.job?.id !== '-1') { if (party.protagonist.job?.id !== '-1') {
setCurrentJob(party.job) setCurrentJob(party.protagonist.job)
} }
}, []) }, [])
@ -95,7 +95,7 @@ const JobDropdown = React.forwardRef<HTMLSelectElement, Props>(
icon={{ icon={{
alt: item.name[locale], alt: item.name[locale],
src: [ 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={{ icon={{
alt: currentJob ? currentJob.name[locale] : '', alt: currentJob ? currentJob.name[locale] : '',
src: currentJob 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} open={open}

View file

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

View file

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

View file

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

View file

@ -225,7 +225,7 @@ const AXSelect = (props: Props) => {
if (modifierSet == 0) { if (modifierSet == 0) {
axOptionElements = axOptions.map((ax, i) => { axOptionElements = axOptions.map((ax, i) => {
return ( 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]} {ax.name[locale]}
</SelectItem> </SelectItem>
) )

View file

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

View file

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

View file

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

View file

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

View file

@ -12,6 +12,7 @@ import CharacterRep from '~components/reps/CharacterRep'
import WeaponRep from '~components/reps/WeaponRep' import WeaponRep from '~components/reps/WeaponRep'
import SummonRep from '~components/reps/SummonRep' import SummonRep from '~components/reps/SummonRep'
import { ElementMap } from '~utils/elements'
import { GridType } from '~utils/enums' import { GridType } from '~utils/enums'
import styles from './index.module.scss' import styles from './index.module.scss'
@ -33,23 +34,24 @@ const PartySegmentedControl = (props: Props) => {
const { party, grid } = useSnapshot(appState) const { party, grid } = useSnapshot(appState)
const getElement = () => { const getElement = () => {
let element: number = 0 let element: GranblueElement
if (party.element == 0 && grid.weapons.mainWeapon) if (party.element === ElementMap.null && grid.weapons.mainWeapon)
element = grid.weapons.mainWeapon.element element = grid.weapons.mainWeapon.element
else element = party.element else if (party.element) element = party.element
else element = ElementMap.null
switch (element) { switch (element) {
case 1: case ElementMap.wind:
return 'wind' return 'wind'
case 2: case ElementMap.fire:
return 'fire' return 'fire'
case 3: case ElementMap.water:
return 'water' return 'water'
case 4: case ElementMap.earth:
return 'earth' return 'earth'
case 5: case ElementMap.dark:
return 'dark' return 'dark'
case 6: case ElementMap.light:
return 'light' return 'light'
} }
} }
@ -64,7 +66,7 @@ const PartySegmentedControl = (props: Props) => {
onClick={props.onClick} onClick={props.onClick}
> >
<CharacterRep <CharacterRep
job={party.job} job={party.protagonist.job}
element={party.element} element={party.element}
gender={ gender={
accountState.account.user ? accountState.account.user.gender : 0 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 { useTranslation } from 'react-i18next'
import classNames from 'classnames' import classNames from 'classnames'
import { ElementMap } from '~utils/elements'
import { Command, CommandGroup, CommandInput } from 'cmdk' import { Command, CommandGroup, CommandInput } from 'cmdk'
import Popover from '~components/common/Popover' import Popover from '~components/common/Popover'
import SegmentedControl from '~components/common/SegmentedControl' import SegmentedControl from '~components/common/SegmentedControl'
@ -50,7 +52,7 @@ const allRaidsOption: Raid = {
group: untitledGroup, group: untitledGroup,
slug: 'all', slug: 'all',
level: 0, level: 0,
element: 0, element: ElementMap.null,
} }
interface Props { interface Props {
@ -112,7 +114,6 @@ const RaidCombobox = (props: Props) => {
useEffect(() => { useEffect(() => {
const sections: [RaidGroup[], RaidGroup[], RaidGroup[]] = [[], [], []] const sections: [RaidGroup[], RaidGroup[], RaidGroup[]] = [[], [], []]
props.raidGroups.forEach((group) => { props.raidGroups.forEach((group) => {
if (group.section > 0) sections[group.section - 1].push(group) if (group.section > 0) sections[group.section - 1].push(group)
}) })
@ -354,7 +355,8 @@ const RaidCombobox = (props: Props) => {
function generateRaidItems(raids: Raid[]) { function generateRaidItems(raids: Raid[]) {
return raids return raids
.sort((a, b) => { .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')) if (a.name.en.includes('NM') && b.name.en.includes('NM'))
return a.level - b.level return a.level - b.level
return a.name.en.localeCompare(b.name.en) return a.name.en.localeCompare(b.name.en)
@ -521,12 +523,12 @@ const RaidCombobox = (props: Props) => {
// Methods: Utility // Methods: Utility
// ---------------------------------------------- // ----------------------------------------------
const linkClass = classNames({ const linkClass = classNames({
wind: currentRaid && currentRaid.element == 1, wind: currentRaid && currentRaid.element == ElementMap.wind,
fire: currentRaid && currentRaid.element == 2, fire: currentRaid && currentRaid.element == ElementMap.fire,
water: currentRaid && currentRaid.element == 3, water: currentRaid && currentRaid.element == ElementMap.water,
earth: currentRaid && currentRaid.element == 4, earth: currentRaid && currentRaid.element == ElementMap.earth,
dark: currentRaid && currentRaid.element == 5, dark: currentRaid && currentRaid.element == ElementMap.dark,
light: currentRaid && currentRaid.element == 6, light: currentRaid && currentRaid.element == ElementMap.light,
}) })
// ---------------------------------------------- // ----------------------------------------------

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -20,14 +20,9 @@ interface Props {
} }
const SummonHovercard = (props: Props) => { const SummonHovercard = (props: Props) => {
const router = useRouter()
const { t } = useTranslation('common') 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 = props.gridSummon.object.element.slug
const tintElement = Element[props.gridSummon.object.element]
function goTo() { function goTo() {
const urlSafeName = props.gridSummon.object.name.en.replaceAll(' ', '_') const urlSafeName = props.gridSummon.object.name.en.replaceAll(' ', '_')
@ -55,19 +50,19 @@ const SummonHovercard = (props: Props) => {
let suffix = '' let suffix = ''
if ( if (
upgradedSummons.indexOf(summon.granblue_id.toString()) != -1 && upgradedSummons.indexOf(summon.granblueId.toString()) != -1 &&
props.gridSummon.uncap_level == 5 props.gridSummon.uncapLevel == 5
) { ) {
suffix = '_02' suffix = '_02'
} else if ( } else if (
props.gridSummon.object.uncap.xlb && props.gridSummon.object.uncap.xlb &&
props.gridSummon.transcendence_step > 0 props.gridSummon.transcendenceStep > 0
) { ) {
suffix = '_03' suffix = '_03'
} }
// Generate the correct source for the summon // 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 return imgSrc

View file

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

View file

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

View file

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

View file

@ -39,7 +39,7 @@ const WeaponConflictModal = (props: Props) => {
}, [setOpen, props.open]) }, [setOpen, props.open])
function imageUrl(weapon?: Weapon) { 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) { function openChange(open: boolean) {

View file

@ -22,12 +22,16 @@ import { appState } from '~utils/appState'
import type { DetailsObject, SearchableObject } from '~types' import type { DetailsObject, SearchableObject } from '~types'
import styles from './index.module.scss' import styles from './index.module.scss'
import { ElementMap } from '~utils/elements'
// Props // Props
interface Props { interface Props {
new: boolean new: boolean
editable: boolean editable: boolean
weapons?: GridWeapon[] weapons?: {
mainWeapon?: GridWeapon
allWeapons: GridArray<GridWeapon>
}
guidebooks?: GuidebookList guidebooks?: GuidebookList
createParty: (details: DetailsObject) => Promise<Party> createParty: (details: DetailsObject) => Promise<Party>
pushHistory?: (path: string) => void pushHistory?: (path: string) => void
@ -73,10 +77,10 @@ const WeaponGrid = (props: Props) => {
if (appState.grid.weapons.mainWeapon) if (appState.grid.weapons.mainWeapon)
initialPreviousUncapValues[-1] = initialPreviousUncapValues[-1] =
appState.grid.weapons.mainWeapon.uncap_level appState.grid.weapons.mainWeapon.uncapLevel
Object.values(appState.grid.weapons.allWeapons).map((o) => Object.values(appState.party.grid.weapons.allWeapons).map((o) =>
o ? (initialPreviousUncapValues[o.position] = o.uncap_level) : 0 o ? (initialPreviousUncapValues[o.position] = o.uncapLevel) : 0
) )
setPreviousUncapValues(initialPreviousUncapValues) setPreviousUncapValues(initialPreviousUncapValues)
@ -88,7 +92,7 @@ const WeaponGrid = (props: Props) => {
if (position == 1) appState.party.element = weapon.element if (position == 1) appState.party.element = weapon.element
if (!party.id) { if (!party.id) {
const payload: DetailsObject = { extra: party.extra } const payload: DetailsObject = { extra: party.details.extra }
props.createParty(payload).then((team) => { props.createParty(payload).then((team) => {
saveWeapon(team.id, weapon, position).then((response) => { saveWeapon(team.id, weapon, position).then((response) => {
if (response) storeGridWeapon(response.data.grid_weapon) if (response) storeGridWeapon(response.data.grid_weapon)
@ -144,7 +148,7 @@ const WeaponGrid = (props: Props) => {
if (position == -1) { if (position == -1) {
appState.grid.weapons.mainWeapon = undefined appState.grid.weapons.mainWeapon = undefined
appState.party.element = 0 appState.party.element = ElementMap.null
} else { } else {
appState.grid.weapons.allWeapons[position] = undefined appState.grid.weapons.allWeapons[position] = undefined
} }
@ -181,7 +185,7 @@ const WeaponGrid = (props: Props) => {
weapon_id: weapon.id, weapon_id: weapon.id,
position: position, position: position,
mainhand: position == -1, mainhand: position == -1,
uncap_level: uncapLevel, uncapLevel: uncapLevel,
}, },
}) })
} }
@ -211,7 +215,7 @@ const WeaponGrid = (props: Props) => {
conflicts.forEach((c) => { conflicts.forEach((c) => {
if (appState.grid.weapons.mainWeapon?.object.id === c.object.id) { if (appState.grid.weapons.mainWeapon?.object.id === c.object.id) {
appState.grid.weapons.mainWeapon = undefined appState.grid.weapons.mainWeapon = undefined
appState.party.element = 0 appState.party.element = ElementMap.null
} else { } else {
appState.grid.weapons.allWeapons[c.position] = undefined appState.grid.weapons.allWeapons[c.position] = undefined
} }
@ -308,11 +312,11 @@ const WeaponGrid = (props: Props) => {
const updateUncapLevel = (position: number, uncapLevel: number) => { const updateUncapLevel = (position: number, uncapLevel: number) => {
// console.log(`Updating uncap level at position ${position} to ${uncapLevel}`) // console.log(`Updating uncap level at position ${position} to ${uncapLevel}`)
if (appState.grid.weapons.mainWeapon && position == -1) if (appState.grid.weapons.mainWeapon && position == -1)
appState.grid.weapons.mainWeapon.uncap_level = uncapLevel appState.grid.weapons.mainWeapon.uncapLevel = uncapLevel
else { else {
const weapon = appState.grid.weapons.allWeapons[position] const weapon = appState.grid.weapons.allWeapons[position]
if (weapon) { if (weapon) {
weapon.uncap_level = uncapLevel weapon.uncapLevel = uncapLevel
appState.grid.weapons.allWeapons[position] = weapon appState.grid.weapons.allWeapons[position] = weapon
} }
} }
@ -323,11 +327,11 @@ const WeaponGrid = (props: Props) => {
let newPreviousValues = { ...previousUncapValues } let newPreviousValues = { ...previousUncapValues }
if (appState.grid.weapons.mainWeapon && position == -1) { if (appState.grid.weapons.mainWeapon && position == -1) {
newPreviousValues[position] = appState.grid.weapons.mainWeapon.uncap_level newPreviousValues[position] = appState.grid.weapons.mainWeapon.uncapLevel
} else { } else {
const weapon = appState.grid.weapons.allWeapons[position] const weapon = appState.grid.weapons.allWeapons[position]
if (weapon) { if (weapon) {
newPreviousValues[position] = weapon.uncap_level newPreviousValues[position] = weapon.uncapLevel
} else { } else {
newPreviousValues[position] = 0 newPreviousValues[position] = 0
} }
@ -339,7 +343,7 @@ const WeaponGrid = (props: Props) => {
// Methods: Convenience // Methods: Convenience
const displayExtraContainer = const displayExtraContainer =
props.editable || props.editable ||
appState.party.extra || appState.party.details.extra ||
Object.values(appState.party.guidebooks).every((el) => el === undefined) Object.values(appState.party.guidebooks).every((el) => el === undefined)
// Render: JSX components // Render: JSX components
@ -411,30 +415,31 @@ const WeaponGrid = (props: Props) => {
} }
const conflictModal = () => { const conflictModal = () => {
return incoming && conflicts ? ( return (
<WeaponConflictModal incoming &&
open={modalOpen} conflicts && (
incomingWeapon={incoming} <WeaponConflictModal
conflictingWeapons={conflicts} open={modalOpen}
desiredPosition={position} incomingWeapon={incoming}
resolveConflict={resolveConflict} conflictingWeapons={conflicts}
resetConflict={resetConflict} desiredPosition={position}
/> resolveConflict={resolveConflict}
) : ( resetConflict={resetConflict}
'' />
)
) )
} }
const incompatibleAlert = () => { const incompatibleAlert = () => {
return showIncompatibleAlert ? ( return (
<Alert showIncompatibleAlert && (
open={showIncompatibleAlert} <Alert
cancelAction={() => setShowIncompatibleAlert(!showIncompatibleAlert)} open={showIncompatibleAlert}
cancelActionText={t('buttons.confirm')} cancelAction={() => setShowIncompatibleAlert(!showIncompatibleAlert)}
message={t('alert.incompatible_weapon')} 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 Button from '~components/common/Button'
import ax from '~data/ax' import ax from '~data/ax'
import { ElementMap } from '~utils/elements'
import styles from './index.module.scss' import styles from './index.module.scss'
@ -36,7 +37,6 @@ const WeaponHovercard = (props: Props) => {
const { t } = useTranslation('common') const { t } = useTranslation('common')
const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light']
const WeaponKeyNames: KeyNames = { const WeaponKeyNames: KeyNames = {
'2': { '2': {
en: 'Pendulum', en: 'Pendulum',
@ -57,9 +57,10 @@ const WeaponHovercard = (props: Props) => {
} }
const tintElement = const tintElement =
props.gridWeapon.object.element == 0 && props.gridWeapon.element props.gridWeapon.object.element === ElementMap.null &&
? Element[props.gridWeapon.element] props.gridWeapon.element
: Element[props.gridWeapon.object.element] ? props.gridWeapon.element.slug
: props.gridWeapon.object.element.slug
function goTo() { function goTo() {
const urlSafeName = props.gridWeapon.object.name.en.replaceAll(' ', '_') const urlSafeName = props.gridWeapon.object.name.en.replaceAll(' ', '_')
@ -76,7 +77,7 @@ const WeaponHovercard = (props: Props) => {
} }
const createPrimaryAxSkillString = () => { const createPrimaryAxSkillString = () => {
const primaryAxSkills = ax[props.gridWeapon.object.ax_type - 1] const primaryAxSkills = ax[props.gridWeapon.object.axType - 1]
if (props.gridWeapon.ax) { if (props.gridWeapon.ax) {
const simpleAxSkill = props.gridWeapon.ax[0] const simpleAxSkill = props.gridWeapon.ax[0]
@ -93,7 +94,7 @@ const WeaponHovercard = (props: Props) => {
} }
const createSecondaryAxSkillString = () => { const createSecondaryAxSkillString = () => {
const primaryAxSkills = ax[props.gridWeapon.object.ax_type - 1] const primaryAxSkills = ax[props.gridWeapon.object.axType - 1]
if (props.gridWeapon.ax) { if (props.gridWeapon.ax) {
const primarySimpleAxSkill = props.gridWeapon.ax[0] const primarySimpleAxSkill = props.gridWeapon.ax[0]
@ -135,27 +136,24 @@ const WeaponHovercard = (props: Props) => {
const keysSection = ( const keysSection = (
<section className={styles.weaponKeys}> <section className={styles.weaponKeys}>
{WeaponKeyNames[props.gridWeapon.object.series] ? ( {WeaponKeyNames[props.gridWeapon.object.series] && (
<h5 className={tintElement}> <h5 className={tintElement}>
{WeaponKeyNames[props.gridWeapon.object.series][locale]} {WeaponKeyNames[props.gridWeapon.object.series][locale]}
{locale === 'en' ? 's' : ''} {locale === 'en' ? 's' : ''}
</h5> </h5>
) : (
''
)} )}
{props.gridWeapon.weapon_keys {props.gridWeapon.weaponKeys &&
? Array.from(Array(props.gridWeapon.weapon_keys.length)).map((x, i) => { Array.from(Array(props.gridWeapon.weaponKeys?.length)).map((x, i) => {
return ( return (
<div <div
className={styles.weaponKey} className={styles.weaponKey}
key={props.gridWeapon.weapon_keys![i].id} key={props.gridWeapon.weaponKeys![i].id}
> >
<span>{props.gridWeapon.weapon_keys![i].name[locale]}</span> <span>{props.gridWeapon.weaponKeys![i].name[locale]}</span>
</div> </div>
) )
}) })}
: ''}
</section> </section>
) )
@ -181,28 +179,26 @@ const WeaponHovercard = (props: Props) => {
</div> </div>
{props.gridWeapon.ax && {props.gridWeapon.ax &&
props.gridWeapon.ax[1].modifier && props.gridWeapon.ax[1].modifier &&
props.gridWeapon.ax[1].strength ? ( props.gridWeapon.ax[1].strength && (
<div <div
className={classNames({ className={classNames({
[styles.secondary]: true, [styles.secondary]: true,
[styles.axSkill]: true, [styles.axSkill]: true,
[styles.skill]: true, [styles.skill]: true,
})} })}
> >
<div className={styles.axImageWrapper}> <div className={styles.axImageWrapper}>
<img <img
alt="AX2" alt="AX2"
src={`/icons/ax/secondary_${ src={`/icons/ax/secondary_${
props.gridWeapon.ax ? props.gridWeapon.ax[1].modifier : '' props.gridWeapon.ax ? props.gridWeapon.ax[1].modifier : ''
}.png`} }.png`}
/> />
</div>
<span>{createSecondaryAxSkillString()}</span>
</div> </div>
<span>{createSecondaryAxSkillString()}</span> )}
</div>
) : (
''
)}
</div> </div>
</section> </section>
) )
@ -233,8 +229,8 @@ const WeaponHovercard = (props: Props) => {
props.gridWeapon.ax[0].strength !== undefined && props.gridWeapon.ax[0].strength !== undefined &&
axSection} axSection}
{props.gridWeapon.awakening && awakeningSection} {props.gridWeapon.awakening && awakeningSection}
{props.gridWeapon.weapon_keys && {props.gridWeapon.weaponKeys &&
props.gridWeapon.weapon_keys.length > 0 && props.gridWeapon.weaponKeys.length > 0 &&
keysSection} keysSection}
{wikiButton} {wikiButton}
</HovercardContent> </HovercardContent>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,7 +8,7 @@ export function toObject(data: any): GridSummon {
position: data.position, position: data.position,
main: data.main, main: data.main,
friend: data.friend, friend: data.friend,
uncapLevel: data.uncap_level, uncapLevel: data.uncapLevel,
transcendenceStep: data.transcendence_step, transcendenceStep: data.transcendence_step,
quickSummon: data.quick_summon, quickSummon: data.quick_summon,
} }
@ -19,7 +19,7 @@ export function toParams(data: GridSummon): GridSummonParams {
return { return {
summon_id: data.id, summon_id: data.id,
position: data.position, position: data.position,
uncap_level: data.uncapLevel, uncapLevel: data.uncapLevel,
transcendence_step: data.transcendenceStep, transcendence_step: data.transcendenceStep,
quick_summon: data.quickSummon, 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), object: Weapon.toObject(data.object),
position: data.position, position: data.position,
mainhand: data.mainhand, mainhand: data.mainhand,
uncapLevel: data.uncap_level, uncapLevel: data.uncapLevel,
element: Element.toObject(data.element), element: Element.toObject(data.element),
weaponKeys: data.weapon_keys.map((key: any) => WeaponKey.toObject(key)), weaponKeys: data.weapon_keys.map((key: any) => WeaponKey.toObject(key)),
ax: data.ax, ax: data.ax,
@ -26,7 +26,7 @@ export function toParams(data: GridWeapon): GridWeaponParams {
return { return {
weapon_id: data.id, weapon_id: data.id,
position: data.position, position: data.position,
uncap_level: data.uncapLevel, uncapLevel: data.uncapLevel,
element: data.element.id, element: data.element.id,
weapon_key1_id: data.weaponKeys?.[0].id, weapon_key1_id: data.weaponKeys?.[0].id,
weapon_key2_id: data.weaponKeys?.[1].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 { export function toObject(data: any): JobAccessory {
return { return {
id: data.id, id: data.id,
granblueId: data.granblue_id, granblueId: data.granblueId,
name: { name: {
en: data.name.en, en: data.name.en,
ja: data.name.jp, ja: data.name.jp,

View file

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

View file

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

View file

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

View file

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

View file

@ -6,7 +6,7 @@ export function toObject(data: any): Weapon {
return { return {
type: 'weapon', type: 'weapon',
id: data.id, id: data.id,
granblueId: data.granblue_id, granblueId: data.granblueId,
name: { name: {
en: data.name.en, en: data.name.en,
ja: data.name.jp, 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 { interface GridCharacterParams {
character_id: string character_id: string
position?: number position?: number
uncap_level?: number uncapLevel?: number
transcendence_step?: number transcendence_step?: number
ring1?: ExtendedMastery ring1?: ExtendedMastery
ring2?: ExtendedMastery ring2?: ExtendedMastery

View file

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

View file

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

View file

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

View file

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

7
types/Party.d.ts vendored
View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -63,3 +63,13 @@ export const elements: GranblueElement[] = [
slug: 'light', 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) { export default function getElementForParty(party: Party) {
const mainhand = party.weapons.find((weapon) => weapon.mainhand) const mainhand = party.grid.weapons.mainWeapon
if (mainhand && mainhand.object.element === 0) { if (mainhand && mainhand.object.element === ElementMap.null) {
return mainhand.element return mainhand.element
} else { } else {
return mainhand?.object.element return mainhand?.object.element

View file

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