Compare commits
41 commits
main
...
transforme
| Author | SHA1 | Date | |
|---|---|---|---|
| 31b590a542 | |||
| 973e7f34da | |||
| d0535d6031 | |||
| b2f64f1d78 | |||
| d42927623e | |||
| 500b7ffbbf | |||
| f73787c23d | |||
| fe32a49bc4 | |||
| 8ef2bf76e3 | |||
| 7cd87bd4a7 | |||
| 511d7ee0ec | |||
| 2838622335 | |||
| 587153a9e2 | |||
| 7224ae8585 | |||
| 43ccb464b1 | |||
| 686d0d0642 | |||
| af9064a356 | |||
| 2049ad4cf7 | |||
| 14994bfbbd | |||
| 8dbc6c1c6c | |||
| 11577a6b61 | |||
| abd98d27c9 | |||
| 17113e2ad9 | |||
| 5e0bda987d | |||
| da1acb1463 | |||
| 93e4fd74fd | |||
| bed7d0d408 | |||
| a70c09b373 | |||
| 5b42ca862e | |||
| 78ae6f2fd1 | |||
| 8ea2f97aac | |||
| 8f7670c07b | |||
| 83bebdb0c2 | |||
| 7c814610b9 | |||
| 881ed31dd1 | |||
| f5ee806f8b | |||
| 6ab2c2488d | |||
| cb4fd491ac | |||
| 9adcd50519 | |||
| 955cd14762 | |||
| 15a32d56bb |
137 changed files with 2326 additions and 1461 deletions
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ 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 { mapToGridArray } from '~utils/mapToGridArray'
|
||||||
|
|
||||||
import Button from '~components/common/Button'
|
import Button from '~components/common/Button'
|
||||||
|
|
||||||
|
|
@ -19,9 +21,12 @@ interface Props {
|
||||||
shortcode: string
|
shortcode: string
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
raid: Raid
|
raid: Raid | null
|
||||||
grid: GridWeapon[]
|
weapons: {
|
||||||
user?: User
|
mainWeapon: GridWeapon | null
|
||||||
|
allWeapons: GridArray<GridWeapon> | null
|
||||||
|
} | null
|
||||||
|
user: User | null
|
||||||
fullAuto: boolean
|
fullAuto: boolean
|
||||||
autoGuard: boolean
|
autoGuard: boolean
|
||||||
favorited: boolean
|
favorited: boolean
|
||||||
|
|
@ -69,27 +74,19 @@ const GridRep = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newWeapons = Array(numWeapons)
|
if (props.weapons && props.weapons.mainWeapon) {
|
||||||
const gridWeapons = Array(numWeapons)
|
setMainhand(props.weapons.mainWeapon?.object)
|
||||||
|
|
||||||
let foundMainhand = false
|
|
||||||
for (const [key, value] of Object.entries(props.grid)) {
|
|
||||||
if (value.position == -1) {
|
|
||||||
setMainhand(value.object)
|
|
||||||
foundMainhand = true
|
|
||||||
} else if (!value.mainhand && value.position != null) {
|
|
||||||
newWeapons[value.position] = value.object
|
|
||||||
gridWeapons[value.position] = value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundMainhand) {
|
if (props.weapons && props.weapons.allWeapons) {
|
||||||
setMainhand(undefined)
|
setWeapons(
|
||||||
|
mapToGridArray(
|
||||||
|
Object.values(props.weapons.allWeapons).map((w) => w?.object)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
setGrid(props.weapons.allWeapons)
|
||||||
}
|
}
|
||||||
|
}, [props.weapons])
|
||||||
setWeapons(newWeapons)
|
|
||||||
setGrid(gridWeapons)
|
|
||||||
}, [props.grid])
|
|
||||||
|
|
||||||
function navigate() {
|
function navigate() {
|
||||||
props.onClick(props.shortcode)
|
props.onClick(props.shortcode)
|
||||||
|
|
@ -99,22 +96,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 +115,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} />
|
||||||
''
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,30 +200,28 @@ const GridRep = (props: Props) => {
|
||||||
{` · ${t('party.details.labels.full_auto')}`}
|
{` · ${t('party.details.labels.full_auto')}`}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{props.raid && props.raid.group.extra && (
|
{props.raid && props.raid.group?.extra && (
|
||||||
<span className={styles.extra}>{` · EX`}</span>
|
<span className={styles.extra}>{` · EX`}</span>
|
||||||
)}
|
)}
|
||||||
</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()}
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ const Layout = ({ children }: PropsWithChildren<Props>) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{appState.version ? ServerAvailable() : ''}
|
{appState.version && ServerAvailable()}
|
||||||
<main>{children}</main>
|
<main>{children}</main>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const AboutHead = ({ page }: Props) => {
|
||||||
name="description"
|
name="description"
|
||||||
content={t(`page.descriptions.${currentPage}`)}
|
content={t(`page.descriptions.${currentPage}`)}
|
||||||
/>
|
/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||||
|
|
||||||
{/* OpenGraph */}
|
{/* OpenGraph */}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,17 @@ import type { DetailsObject, JobSkillObject, SearchableObject } from '~types'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
|
import * as CharacterTransformer from '~transformers/CharacterTransformer'
|
||||||
|
import * as GridCharacterTransformer from '~transformers/GridCharacterTransformer'
|
||||||
|
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
import { use } from 'i18next'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +49,7 @@ const CharacterGrid = (props: Props) => {
|
||||||
const [errorAlertOpen, setErrorAlertOpen] = useState(false)
|
const [errorAlertOpen, setErrorAlertOpen] = useState(false)
|
||||||
|
|
||||||
// Set up state for view management
|
// Set up state for view management
|
||||||
const { party, grid } = useSnapshot(appState)
|
const { party } = useSnapshot(appState)
|
||||||
const [modalOpen, setModalOpen] = useState(false)
|
const [modalOpen, setModalOpen] = useState(false)
|
||||||
|
|
||||||
// Set up state for conflict management
|
// Set up state for conflict management
|
||||||
|
|
@ -76,19 +79,39 @@ const CharacterGrid = (props: Props) => {
|
||||||
}>({})
|
}>({})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setJob(appState.party.job)
|
console.log('loading chara grid')
|
||||||
setJobSkills(appState.party.jobSkills)
|
}, [])
|
||||||
setJobAccessory(appState.party.accessory)
|
|
||||||
}, [appState])
|
useEffect(() => {
|
||||||
|
setJob(appState.party.protagonist.job)
|
||||||
|
setJobSkills(
|
||||||
|
appState.party.protagonist.skills
|
||||||
|
? appState.party.protagonist.skills
|
||||||
|
: {
|
||||||
|
0: undefined,
|
||||||
|
1: undefined,
|
||||||
|
2: undefined,
|
||||||
|
3: undefined,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
setJobAccessory(
|
||||||
|
appState.party.protagonist.accessory
|
||||||
|
? appState.party.protagonist.accessory
|
||||||
|
: undefined
|
||||||
|
)
|
||||||
|
}, [])
|
||||||
|
|
||||||
// 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) => {
|
const values = appState.party.grid.characters
|
||||||
o ? (initialPreviousUncapValues[o.position] = o.uncap_level) : 0
|
? appState.party.grid.characters
|
||||||
|
: {}
|
||||||
|
Object.values(values).map((o) => {
|
||||||
|
o ? (initialPreviousUncapValues[o.position] = o.uncapLevel) : 0
|
||||||
})
|
})
|
||||||
setPreviousUncapValues(initialPreviousUncapValues)
|
setPreviousUncapValues(initialPreviousUncapValues)
|
||||||
}, [appState.grid.characters])
|
}, [appState.party.grid.characters])
|
||||||
|
|
||||||
// Methods: Adding an object from search
|
// Methods: Adding an object from search
|
||||||
function receiveCharacterFromSearch(
|
function receiveCharacterFromSearch(
|
||||||
|
|
@ -121,8 +144,10 @@ const CharacterGrid = (props: Props) => {
|
||||||
|
|
||||||
async function handleCharacterResponse(data: any) {
|
async function handleCharacterResponse(data: any) {
|
||||||
if (data.hasOwnProperty('conflicts')) {
|
if (data.hasOwnProperty('conflicts')) {
|
||||||
setIncoming(data.incoming)
|
setIncoming(CharacterTransformer.toObject(data.incoming))
|
||||||
setConflicts(data.conflicts)
|
setConflicts(
|
||||||
|
data.conflicts.map((c: any) => GridCharacterTransformer.toObject(c))
|
||||||
|
)
|
||||||
setPosition(data.position)
|
setPosition(data.position)
|
||||||
setModalOpen(true)
|
setModalOpen(true)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -140,13 +165,18 @@ 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),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function storeGridCharacter(gridCharacter: GridCharacter) {
|
function storeGridCharacter(data: any) {
|
||||||
appState.grid.characters[gridCharacter.position] = gridCharacter
|
const gridCharacter = GridCharacterTransformer.toObject(data)
|
||||||
|
|
||||||
|
appState.party.grid.characters = {
|
||||||
|
...appState.party.grid.characters,
|
||||||
|
[gridCharacter.position]: gridCharacter,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveConflict() {
|
async function resolveConflict() {
|
||||||
|
|
@ -164,7 +194,11 @@ const CharacterGrid = (props: Props) => {
|
||||||
|
|
||||||
// Remove conflicting characters from state
|
// Remove conflicting characters from state
|
||||||
conflicts.forEach(
|
conflicts.forEach(
|
||||||
(c) => (appState.grid.characters[c.position] = undefined)
|
(c) =>
|
||||||
|
(appState.party.grid.characters = {
|
||||||
|
...appState.party.grid.characters,
|
||||||
|
[c.position]: null,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reset conflict
|
// Reset conflict
|
||||||
|
|
@ -186,7 +220,10 @@ const CharacterGrid = (props: Props) => {
|
||||||
async function removeCharacter(id: string) {
|
async function removeCharacter(id: string) {
|
||||||
try {
|
try {
|
||||||
const response = await api.endpoints.grid_characters.destroy({ id: id })
|
const response = await api.endpoints.grid_characters.destroy({ id: id })
|
||||||
appState.grid.characters[response.data.position] = undefined
|
appState.party.grid.characters = {
|
||||||
|
...appState.party.grid.characters,
|
||||||
|
[response.data.position]: null,
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
|
@ -214,10 +251,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 +281,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 +305,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 +328,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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,10 +415,13 @@ const CharacterGrid = (props: Props) => {
|
||||||
position: number,
|
position: number,
|
||||||
uncapLevel: number | undefined
|
uncapLevel: number | undefined
|
||||||
) => {
|
) => {
|
||||||
const character = appState.grid.characters[position]
|
const character = appState.party.grid.characters?.[position]
|
||||||
if (character && uncapLevel) {
|
if (character && uncapLevel) {
|
||||||
character.uncap_level = uncapLevel
|
character.uncapLevel = uncapLevel
|
||||||
appState.grid.characters[position] = character
|
appState.party.grid.characters = {
|
||||||
|
...appState.party.grid.characters,
|
||||||
|
[position]: character,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -389,8 +429,8 @@ const CharacterGrid = (props: Props) => {
|
||||||
// Save the current value in case of an unexpected result
|
// Save the current value in case of an unexpected result
|
||||||
let newPreviousValues = { ...previousUncapValues }
|
let newPreviousValues = { ...previousUncapValues }
|
||||||
|
|
||||||
if (grid.characters[position]) {
|
if (party.grid.characters && party.grid.characters[position]) {
|
||||||
newPreviousValues[position] = grid.characters[position]?.uncap_level
|
newPreviousValues[position] = party.grid.characters[position]?.uncapLevel
|
||||||
setPreviousUncapValues(newPreviousValues)
|
setPreviousUncapValues(newPreviousValues)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -407,7 +447,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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -474,10 +514,13 @@ const CharacterGrid = (props: Props) => {
|
||||||
position: number,
|
position: number,
|
||||||
stage: number | undefined
|
stage: number | undefined
|
||||||
) => {
|
) => {
|
||||||
const character = appState.grid.characters[position]
|
const character = appState.party.grid.characters?.[position]
|
||||||
if (character && stage !== undefined) {
|
if (character && stage !== undefined) {
|
||||||
character.transcendence_step = stage
|
character.transcendenceStep = stage
|
||||||
appState.grid.characters[position] = character
|
appState.party.grid.characters = {
|
||||||
|
...appState.party.grid.characters,
|
||||||
|
[position]: character,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,8 +528,8 @@ const CharacterGrid = (props: Props) => {
|
||||||
// Save the current value in case of an unexpected result
|
// Save the current value in case of an unexpected result
|
||||||
let newPreviousValues = { ...previousUncapValues }
|
let newPreviousValues = { ...previousUncapValues }
|
||||||
|
|
||||||
if (grid.characters[position]) {
|
if (party.grid.characters && party.grid.characters[position]) {
|
||||||
newPreviousValues[position] = grid.characters[position]?.uncap_level
|
newPreviousValues[position] = party.grid.characters[position]?.uncapLevel
|
||||||
setPreviousTranscendenceStages(newPreviousValues)
|
setPreviousTranscendenceStages(newPreviousValues)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -540,7 +583,9 @@ const CharacterGrid = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<li key={`grid_unit_${i}`}>
|
<li key={`grid_unit_${i}`}>
|
||||||
<CharacterUnit
|
<CharacterUnit
|
||||||
gridCharacter={grid.characters[i]}
|
gridCharacter={
|
||||||
|
party.grid.characters ? party.grid.characters[i] : null
|
||||||
|
}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
position={i}
|
position={i}
|
||||||
updateObject={receiveCharacterFromSearch}
|
updateObject={receiveCharacterFromSearch}
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,13 @@ const emptyExtendedMastery: ExtendedMastery = {
|
||||||
strength: 0,
|
strength: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const emptyRingset: CharacterOverMastery = {
|
||||||
|
1: { ...emptyExtendedMastery, modifier: 1 },
|
||||||
|
2: { ...emptyExtendedMastery, modifier: 2 },
|
||||||
|
3: emptyExtendedMastery,
|
||||||
|
4: emptyExtendedMastery,
|
||||||
|
}
|
||||||
|
|
||||||
const MAX_AWAKENING_LEVEL = 9
|
const MAX_AWAKENING_LEVEL = 9
|
||||||
|
|
||||||
// Styles and icons
|
// Styles and icons
|
||||||
|
|
@ -85,16 +92,29 @@ const CharacterModal = ({
|
||||||
}, [modalOpen])
|
}, [modalOpen])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (gridCharacter.aetherial_mastery) {
|
console.log('Setting up grid character')
|
||||||
|
console.log(gridCharacter)
|
||||||
|
|
||||||
|
if (gridCharacter.mastery.overMastery) {
|
||||||
|
setRings(gridCharacter.mastery.overMastery)
|
||||||
|
} else {
|
||||||
|
setRings(emptyRingset)
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
setPerpetuity(gridCharacter.perpetuity)
|
gridCharacter.mastery.awakening.level
|
||||||
|
? gridCharacter.mastery.awakening.level
|
||||||
|
: 1
|
||||||
|
)
|
||||||
|
setPerpetuity(gridCharacter.mastery.perpetuity)
|
||||||
}, [gridCharacter])
|
}, [gridCharacter])
|
||||||
|
|
||||||
// Prepare the GridWeaponObject to send to the server
|
// Prepare the GridWeaponObject to send to the server
|
||||||
|
|
@ -144,25 +164,18 @@ const CharacterModal = ({
|
||||||
rings ||
|
rings ||
|
||||||
aetherialMastery ||
|
aetherialMastery ||
|
||||||
awakening ||
|
awakening ||
|
||||||
gridCharacter.perpetuity !== perpetuity
|
gridCharacter.mastery.perpetuity !== perpetuity
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ringsChanged() {
|
function ringsChanged() {
|
||||||
// Create an empty ExtendedMastery object
|
|
||||||
const emptyRingset: CharacterOverMastery = {
|
|
||||||
1: { ...emptyExtendedMastery, modifier: 1 },
|
|
||||||
2: { ...emptyExtendedMastery, modifier: 2 },
|
|
||||||
3: emptyExtendedMastery,
|
|
||||||
4: emptyExtendedMastery,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 +190,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 +206,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 +261,21 @@ 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
|
||||||
|
? gridCharacter.mastery.awakening.level
|
||||||
|
: 1
|
||||||
|
)
|
||||||
|
|
||||||
setAlertOpen(false)
|
setAlertOpen(false)
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
|
|
@ -305,13 +322,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 +342,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 +381,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],
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -40,9 +40,10 @@ const CharacterResult = (props: Props) => {
|
||||||
flb={character.uncap.flb}
|
flb={character.uncap.flb}
|
||||||
ulb={character.uncap.ulb}
|
ulb={character.uncap.ulb}
|
||||||
special={character.special}
|
special={character.special}
|
||||||
|
transcendenceStage={character.uncap.ulb ? 5 : 0}
|
||||||
/>
|
/>
|
||||||
<div className={styles.tags}>
|
<div className={styles.tags}>
|
||||||
<WeaponLabelIcon labelType={Element[character.element]} />
|
<WeaponLabelIcon labelType={character.element.slug} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ 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 * as GridCharacterTransformer from '~transformers/GridCharacterTransformer'
|
||||||
|
|
||||||
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'
|
||||||
|
|
@ -36,7 +38,7 @@ import type {
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
gridCharacter?: GridCharacter
|
gridCharacter: GridCharacter | null
|
||||||
position: number
|
position: number
|
||||||
editable: boolean
|
editable: boolean
|
||||||
removeCharacter: (id: string) => void
|
removeCharacter: (id: string) => void
|
||||||
|
|
@ -109,7 +111,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)
|
||||||
|
|
@ -144,21 +146,23 @@ const CharacterUnit = ({
|
||||||
|
|
||||||
// Save the server's response to state
|
// Save the server's response to state
|
||||||
function processResult(response: AxiosResponse) {
|
function processResult(response: AxiosResponse) {
|
||||||
const gridCharacter: GridCharacter = response.data
|
const gridCharacter: GridCharacter = GridCharacterTransformer.toObject(
|
||||||
|
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.party.grid.characters[gridCharacter.position] = character
|
||||||
}
|
}
|
||||||
|
|
||||||
function processError(error: any) {
|
function processError(error: any) {
|
||||||
|
|
@ -187,23 +191,28 @@ 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 (
|
||||||
else if (gridCharacter.uncap_level >= 5) suffix = '03'
|
gridCharacter.transcendenceStep &&
|
||||||
else if (gridCharacter.uncap_level > 2) suffix = '02'
|
gridCharacter.transcendenceStep > 0
|
||||||
|
)
|
||||||
|
suffix = '04'
|
||||||
|
else if (gridCharacter.uncapLevel >= 5) suffix = '03'
|
||||||
|
else if (gridCharacter.uncapLevel > 2) suffix = '02'
|
||||||
|
|
||||||
// Special casing for Lyria (and Young Cat eventually)
|
// 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 +301,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 +357,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}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,14 @@
|
||||||
color: inherit;
|
color: inherit;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
|
@include breakpoint(phone) {
|
||||||
|
place-items: flex-end;
|
||||||
|
overflow-y: hidden;
|
||||||
|
|
||||||
|
&.filter {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dialogContent {
|
.dialogContent {
|
||||||
$multiplier: 4;
|
$multiplier: 4;
|
||||||
|
|
||||||
|
|
@ -51,11 +59,11 @@
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
min-width: inherit;
|
min-width: inherit;
|
||||||
min-height: 90vh;
|
min-height: inherit;
|
||||||
transform: initial;
|
transform: initial;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 5vh;
|
top: $unit-10x;
|
||||||
height: auto;
|
height: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
@ -101,110 +109,6 @@
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Conflict {
|
|
||||||
$weapon-diameter: 14rem;
|
|
||||||
|
|
||||||
.Content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: $unit-4x;
|
|
||||||
padding: $unit-4x $unit-4x $unit-2x $unit-4x;
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
font-size: $font-regular;
|
|
||||||
line-height: 1.4;
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: $bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:lang(ja) {
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.weapon,
|
|
||||||
.character {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: $unit;
|
|
||||||
text-align: center;
|
|
||||||
width: $weapon-diameter;
|
|
||||||
font-weight: $medium;
|
|
||||||
|
|
||||||
img {
|
|
||||||
border-radius: 1rem;
|
|
||||||
width: $weapon-diameter;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
line-height: 1.3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.Diagram {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr auto 1fr;
|
|
||||||
align-items: flex-start;
|
|
||||||
|
|
||||||
&.CharacterDiagram {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: $unit-2x;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
align-items: center;
|
|
||||||
color: $grey-55;
|
|
||||||
display: flex;
|
|
||||||
font-size: 4rem;
|
|
||||||
text-align: center;
|
|
||||||
height: $weapon-diameter;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: $unit;
|
|
||||||
|
|
||||||
.Button {
|
|
||||||
font-size: $font-regular;
|
|
||||||
padding: ($unit * 1.5) ($unit * 2);
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
&.btn-disabled {
|
|
||||||
background: $grey-90;
|
|
||||||
color: $grey-70;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.btn-disabled) {
|
|
||||||
background: $grey-90;
|
|
||||||
color: $grey-50;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $grey-80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes openModalDesktop {
|
@keyframes openModalDesktop {
|
||||||
|
|
@ -221,11 +125,20 @@
|
||||||
|
|
||||||
@keyframes slideUp {
|
@keyframes slideUp {
|
||||||
0% {
|
0% {
|
||||||
transform: translate(0%, 100%);
|
transform: translateY(400px);
|
||||||
|
animation-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
transform: translateY(-30px);
|
||||||
|
animation-timing-function: ease-in;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
transform: translateY(10px);
|
||||||
|
animation-timing-function: ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
transform: translate(0, 0%);
|
transform: translateY(0px);
|
||||||
|
animation-timing-function: ease-in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ interface Props
|
||||||
React.DialogHTMLAttributes<HTMLDivElement>,
|
React.DialogHTMLAttributes<HTMLDivElement>,
|
||||||
HTMLDivElement
|
HTMLDivElement
|
||||||
> {
|
> {
|
||||||
|
wrapperClassName?: string
|
||||||
headerref?: React.RefObject<HTMLDivElement>
|
headerref?: React.RefObject<HTMLDivElement>
|
||||||
footerref?: React.RefObject<HTMLDivElement>
|
footerref?: React.RefObject<HTMLDivElement>
|
||||||
scrollable?: boolean
|
scrollable?: boolean
|
||||||
|
|
@ -127,7 +128,16 @@ const DialogContent = React.forwardRef<HTMLDivElement, Props>(function Dialog(
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogPrimitive.Portal>
|
<DialogPrimitive.Portal>
|
||||||
<dialog className={styles.dialog}>
|
<dialog
|
||||||
|
className={classNames(
|
||||||
|
{
|
||||||
|
[styles.dialog]: true,
|
||||||
|
},
|
||||||
|
props.wrapperClassName
|
||||||
|
?.split(' ')
|
||||||
|
.map((className) => styles[className])
|
||||||
|
)}
|
||||||
|
>
|
||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
{...props}
|
{...props}
|
||||||
className={classes}
|
className={classes}
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,11 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: $unit;
|
gap: $unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include breakpoint(phone) {
|
||||||
|
position: fixed;
|
||||||
|
bottom: $unit-14x;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,14 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.empty:first-child::before {
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
content: attr(data-placeholder);
|
||||||
|
float: left;
|
||||||
|
height: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
&.bound {
|
&.bound {
|
||||||
background-color: var(--input-bound-bg);
|
background-color: var(--input-bound-bg);
|
||||||
|
|
||||||
|
|
@ -74,21 +82,21 @@
|
||||||
h1 {
|
h1 {
|
||||||
font-size: $font-xlarge;
|
font-size: $font-xlarge;
|
||||||
font-weight: $medium;
|
font-weight: $medium;
|
||||||
margin: $unit 0;
|
margin: $unit-2x 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: $font-large;
|
font-size: $font-large;
|
||||||
font-weight: $medium;
|
font-weight: $medium;
|
||||||
margin: $unit 0;
|
margin: $unit-2x 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: $font-regular;
|
font-size: $font-regular;
|
||||||
font-weight: $medium;
|
font-weight: $medium;
|
||||||
margin: $unit 0;
|
margin: $unit-2x 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,6 +104,7 @@
|
||||||
border-radius: $item-corner-small;
|
border-radius: $item-corner-small;
|
||||||
background: var(--highlight-bg);
|
background: var(--highlight-bg);
|
||||||
color: var(--highlight-text);
|
color: var(--highlight-text);
|
||||||
|
font-weight: $normal;
|
||||||
padding: 1px $unit-fourth;
|
padding: 1px $unit-fourth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,15 +125,18 @@
|
||||||
.mention {
|
.mention {
|
||||||
border-radius: $item-corner-small;
|
border-radius: $item-corner-small;
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||||
0 1px 0px rgba(0, 0, 0, 0.25);
|
0 1px 0px var(--null-shadow);
|
||||||
background: var(--card-bg);
|
background: var(--null-bg);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-weight: $medium;
|
font-weight: $medium;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
padding: 1px $unit-half;
|
padding: 1px $unit-half;
|
||||||
|
transition: all 0.1s ease-out;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--card-bg-hover);
|
background: var(--null-bg-hover);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||||
|
0 1px 0px var(--null-shadow-hover);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +148,7 @@
|
||||||
color: var(--fire-text);
|
color: var(--fire-text);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background: var(--fire-bg-hover);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||||
0 1px 0px var(--fire-shadow-hover);
|
0 1px 0px var(--fire-shadow-hover);
|
||||||
color: var(--fire-text-hover);
|
color: var(--fire-text-hover);
|
||||||
|
|
@ -149,6 +162,7 @@
|
||||||
color: var(--water-text);
|
color: var(--water-text);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background: var(--water-bg-hover);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||||
0 1px 0px var(--water-shadow-hover);
|
0 1px 0px var(--water-shadow-hover);
|
||||||
color: var(--water-text-hover);
|
color: var(--water-text-hover);
|
||||||
|
|
@ -162,6 +176,7 @@
|
||||||
color: var(--earth-text);
|
color: var(--earth-text);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background: var(--earth-bg-hover);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||||
0 1px 0px var(--earth-shadow-hover);
|
0 1px 0px var(--earth-shadow-hover);
|
||||||
color: var(--earth-text-hover);
|
color: var(--earth-text-hover);
|
||||||
|
|
@ -188,6 +203,7 @@
|
||||||
color: var(--dark-text);
|
color: var(--dark-text);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background: var(--dark-bg-hover);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||||
0 1px 0px var(--dark-shadow-hover);
|
0 1px 0px var(--dark-shadow-hover);
|
||||||
color: var(--dark-text-hover);
|
color: var(--dark-text-hover);
|
||||||
|
|
@ -201,6 +217,7 @@
|
||||||
color: var(--light-text);
|
color: var(--light-text);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background: var(--light-bg-hover);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||||
0 1px 0px var(--light-shadow-hover);
|
0 1px 0px var(--light-shadow-hover);
|
||||||
color: var(--light-text-hover);
|
color: var(--light-text-hover);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
import { ComponentProps, useCallback, useEffect } from 'react'
|
import { ComponentProps, useCallback, useEffect } from 'react'
|
||||||
import { useRouter } from 'next/router'
|
|
||||||
import { useEditor, EditorContent } from '@tiptap/react'
|
import { useEditor, EditorContent } from '@tiptap/react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
|
||||||
import StarterKit from '@tiptap/starter-kit'
|
import StarterKit from '@tiptap/starter-kit'
|
||||||
import Link from '@tiptap/extension-link'
|
import Link from '@tiptap/extension-link'
|
||||||
import Highlight from '@tiptap/extension-highlight'
|
import Highlight from '@tiptap/extension-highlight'
|
||||||
|
import Placeholder from '@tiptap/extension-placeholder'
|
||||||
import Typography from '@tiptap/extension-typography'
|
import Typography from '@tiptap/extension-typography'
|
||||||
import Youtube from '@tiptap/extension-youtube'
|
import Youtube from '@tiptap/extension-youtube'
|
||||||
import CustomMention from '~extensions/CustomMention'
|
import CustomMention from '~extensions/CustomMention'
|
||||||
|
|
@ -18,7 +21,7 @@ import ItalicIcon from 'remixicon-react/ItalicIcon'
|
||||||
import StrikethroughIcon from 'remixicon-react/StrikethroughIcon'
|
import StrikethroughIcon from 'remixicon-react/StrikethroughIcon'
|
||||||
import UnorderedListIcon from 'remixicon-react/ListUnorderedIcon'
|
import UnorderedListIcon from 'remixicon-react/ListUnorderedIcon'
|
||||||
import OrderedListIcon from '~public/icons/remix/list-ordered-2.svg'
|
import OrderedListIcon from '~public/icons/remix/list-ordered-2.svg'
|
||||||
import PaintbrushIcon from 'remixicon-react/PaintbrushLineIcon'
|
import PaintbrushIcon from 'remixicon-react/PaintBrushLineIcon'
|
||||||
import H1Icon from 'remixicon-react/H1Icon'
|
import H1Icon from 'remixicon-react/H1Icon'
|
||||||
import H2Icon from 'remixicon-react/H2Icon'
|
import H2Icon from 'remixicon-react/H2Icon'
|
||||||
import H3Icon from 'remixicon-react/H3Icon'
|
import H3Icon from 'remixicon-react/H3Icon'
|
||||||
|
|
@ -45,6 +48,8 @@ const Editor = ({
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const locale = router.locale || 'en'
|
const locale = router.locale || 'en'
|
||||||
|
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
editor?.commands.setContent(formatContent(content))
|
editor?.commands.setContent(formatContent(content))
|
||||||
}, [content])
|
}, [content])
|
||||||
|
|
@ -72,6 +77,10 @@ const Editor = ({
|
||||||
}),
|
}),
|
||||||
Link,
|
Link,
|
||||||
Highlight,
|
Highlight,
|
||||||
|
Placeholder.configure({
|
||||||
|
emptyEditorClass: styles.empty,
|
||||||
|
placeholder: t('modals.edit_team.placeholders.description'),
|
||||||
|
}),
|
||||||
Typography,
|
Typography,
|
||||||
CustomMention.configure({
|
CustomMention.configure({
|
||||||
renderLabel({ options, node }) {
|
renderLabel({ options, node }) {
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,6 @@
|
||||||
&.flush {
|
&.flush {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Arrow {
|
|
||||||
fill: var(--dialog-bg);
|
|
||||||
filter: drop-shadow(0px 1px 1px rgb(0 0 0 / 0.18));
|
|
||||||
margin-top: -1px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.trigger {
|
.trigger {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
.arrow {
|
||||||
|
fill: var(--dialog-bg);
|
||||||
|
filter: drop-shadow(0px 1px 1px rgb(0 0 0 / 0.18));
|
||||||
|
margin-top: -1px;
|
||||||
|
}
|
||||||
|
|
@ -63,6 +63,10 @@
|
||||||
|
|
||||||
&.table {
|
&.table {
|
||||||
min-width: $unit * 30;
|
min-width: $unit * 30;
|
||||||
|
|
||||||
|
@include breakpoint(phone) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hidden {
|
&.hidden {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@
|
||||||
border-radius: 9999px;
|
border-radius: 9999px;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.table {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.range {
|
.range {
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ const SliderTableField = (props: Props) => {
|
||||||
max={props.max}
|
max={props.max}
|
||||||
step={props.step}
|
step={props.step}
|
||||||
value={[props.value ? props.value : 0]}
|
value={[props.value ? props.value : 0]}
|
||||||
|
className="table"
|
||||||
onValueChange={handleValueChange}
|
onValueChange={handleValueChange}
|
||||||
onValueCommit={handleValueCommit}
|
onValueCommit={handleValueCommit}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.switch {
|
||||||
|
@include breakpoint(phone) {
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,13 @@ const ToolbarIcon = ({ editor, action, level, icon, onClick }: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip content={t(`toolbar.tooltips.${action}`)}>
|
<Tooltip
|
||||||
|
content={
|
||||||
|
level
|
||||||
|
? t(`toolbar.tooltips.${action}`, { level: level })
|
||||||
|
: t(`toolbar.tooltips.${action}`)
|
||||||
|
}
|
||||||
|
>
|
||||||
<button onClick={onClick} className={classes}>
|
<button onClick={onClick} className={classes}>
|
||||||
{icon}
|
{icon}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -39,5 +39,6 @@
|
||||||
|
|
||||||
@include breakpoint(phone) {
|
@include breakpoint(phone) {
|
||||||
gap: $unit-4x;
|
gap: $unit-4x;
|
||||||
|
margin-bottom: $unit * 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,8 @@ const FilterModal = (props: Props) => {
|
||||||
<Dialog open={open} onOpenChange={openChange}>
|
<Dialog open={open} onOpenChange={openChange}>
|
||||||
<DialogTrigger asChild>{props.children}</DialogTrigger>
|
<DialogTrigger asChild>{props.children}</DialogTrigger>
|
||||||
<DialogContent
|
<DialogContent
|
||||||
className="Filter"
|
className="filter"
|
||||||
|
wrapperClassName="filter"
|
||||||
headerref={headerRef}
|
headerref={headerRef}
|
||||||
footerref={footerRef}
|
footerref={footerRef}
|
||||||
onEscapeKeyDown={onEscapeKeyDown}
|
onEscapeKeyDown={onEscapeKeyDown}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const NewHead = () => {
|
||||||
{/* HTML */}
|
{/* HTML */}
|
||||||
<title>{t('page.titles.new')}</title>
|
<title>{t('page.titles.new')}</title>
|
||||||
<meta name="description" content={t('page.descriptions.new')} />
|
<meta name="description" content={t('page.descriptions.new')} />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||||
|
|
||||||
{/* OpenGraph */}
|
{/* OpenGraph */}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const ProfileHead = ({ user }: Props) => {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||||
|
|
||||||
{/* OpenGraph */}
|
{/* OpenGraph */}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const SavedHead = () => {
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<title>{t('page.titles.saved')}</title>
|
<title>{t('page.titles.saved')}</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||||
|
|
||||||
<meta property="og:title" content={t('page.titles.saved')} />
|
<meta property="og:title" content={t('page.titles.saved')} />
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ const TeamsHead = () => {
|
||||||
{/* HTML */}
|
{/* HTML */}
|
||||||
<title>{t('page.titles.discover')}</title>
|
<title>{t('page.titles.discover')}</title>
|
||||||
<meta name="description" content={t('page.descriptions.discover')} />
|
<meta name="description" content={t('page.descriptions.discover')} />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||||
|
|
||||||
{/* OpenGraph */}
|
{/* OpenGraph */}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
.JobAccessoryItem {
|
.item {
|
||||||
background: none;
|
background: none;
|
||||||
border-radius: $input-corner;
|
border-radius: $input-corner;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ import SearchModal from '~components/search/SearchModal'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
import type { JobSkillObject, SearchableObject } from '~types'
|
import type { SearchableObject } from '~types'
|
||||||
|
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
job?: Job
|
job?: Job
|
||||||
jobSkills: JobSkillObject
|
jobSkills: JobSkillList
|
||||||
jobAccessory?: JobAccessory
|
jobAccessory?: JobAccessory
|
||||||
editable: boolean
|
editable: boolean
|
||||||
saveJob: (job?: Job) => void
|
saveJob: (job?: Job) => void
|
||||||
|
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ const emptyRing: ExtendedMastery = {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
gridCharacter: GridCharacter
|
rings: CharacterOverMastery
|
||||||
sendValues: (overMastery: CharacterOverMastery) => void
|
sendValues: (overMastery: CharacterOverMastery) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const RingSelect = ({ gridCharacter, sendValues }: Props) => {
|
const RingSelect = ({ rings: overMastery, sendValues }: Props) => {
|
||||||
// Ring value states
|
// Ring value states
|
||||||
const [rings, setRings] = useState<CharacterOverMastery>({
|
const [rings, setRings] = useState<CharacterOverMastery>({
|
||||||
1: { ...emptyRing, modifier: 1 },
|
1: { ...emptyRing, modifier: 1 },
|
||||||
|
|
@ -33,15 +33,13 @@ const RingSelect = ({ gridCharacter, sendValues }: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (gridCharacter.over_mastery) {
|
setRings({
|
||||||
setRings({
|
1: overMastery[1],
|
||||||
1: gridCharacter.over_mastery[1],
|
2: overMastery[2],
|
||||||
2: gridCharacter.over_mastery[2],
|
3: overMastery[3],
|
||||||
3: gridCharacter.over_mastery[3],
|
4: overMastery[4],
|
||||||
4: gridCharacter.over_mastery[4],
|
})
|
||||||
})
|
}, [overMastery])
|
||||||
}
|
|
||||||
}, [gridCharacter])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
sendValues(rings)
|
sendValues(rings)
|
||||||
|
|
@ -54,7 +52,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,
|
||||||
|
|
@ -80,6 +78,7 @@ const RingSelect = ({ gridCharacter, sendValues }: Props) => {
|
||||||
function receiveRingValues(index: number, left: number, right: number) {
|
function receiveRingValues(index: number, left: number, right: number) {
|
||||||
// console.log(`Receiving values from ${index}: ${left} ${right}`)
|
// console.log(`Receiving values from ${index}: ${left} ${right}`)
|
||||||
if (index == 1 || index == 2) {
|
if (index == 1 || index == 2) {
|
||||||
|
console.log('1 or 2')
|
||||||
setSyncedRingValues(index, right)
|
setSyncedRingValues(index, right)
|
||||||
} else if (index == 3 && left == 0) {
|
} else if (index == 3 && left == 0) {
|
||||||
setRings({
|
setRings({
|
||||||
|
|
@ -132,6 +131,7 @@ const RingSelect = ({ gridCharacter, sendValues }: Props) => {
|
||||||
{[...Array(4)].map((e, i) => {
|
{[...Array(4)].map((e, i) => {
|
||||||
const index = i + 1
|
const index = i + 1
|
||||||
const ringStat = rings[index]
|
const ringStat = rings[index]
|
||||||
|
console.log(ringStat)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ExtendedMasterySelect
|
<ExtendedMasterySelect
|
||||||
|
|
@ -140,8 +140,8 @@ const RingSelect = ({ gridCharacter, sendValues }: Props) => {
|
||||||
key={`ring-${index}`}
|
key={`ring-${index}`}
|
||||||
dataSet={dataSet(index)}
|
dataSet={dataSet(index)}
|
||||||
leftSelectDisabled={index === 1 || index === 2}
|
leftSelectDisabled={index === 1 || index === 2}
|
||||||
leftSelectValue={ringStat.modifier ? ringStat.modifier : 0}
|
leftSelectValue={ringStat?.modifier ? ringStat?.modifier : 0}
|
||||||
rightSelectValue={ringStat.strength ? ringStat.strength : 0}
|
rightSelectValue={ringStat?.strength ? ringStat?.strength : 0}
|
||||||
sendValues={(left: number, right: number) => {
|
sendValues={(left: number, right: number) => {
|
||||||
receiveRingValues(index, left, right)
|
receiveRingValues(index, left, right)
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -297,20 +297,21 @@ const EditPartyModal = ({
|
||||||
// Methods: Modification checking
|
// Methods: Modification checking
|
||||||
function hasBeenModified() {
|
function hasBeenModified() {
|
||||||
const nameChanged =
|
const nameChanged =
|
||||||
name !== party.name && !(name === '' && party.name === undefined)
|
name !== party.name &&
|
||||||
|
!(name === '' && (party.name === undefined || party.name === null))
|
||||||
const descriptionChanged =
|
const descriptionChanged =
|
||||||
description !== party.description &&
|
description !== party.description &&
|
||||||
!(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(`
|
||||||
|
|
@ -348,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) {
|
||||||
|
|
@ -433,7 +437,7 @@ const EditPartyModal = ({
|
||||||
const nameField = (
|
const nameField = (
|
||||||
<Input
|
<Input
|
||||||
name="name"
|
name="name"
|
||||||
placeholder="Name your team"
|
placeholder={t('modals.edit_team.placeholders.name')}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
value={name}
|
value={name}
|
||||||
maxLength={50}
|
maxLength={50}
|
||||||
|
|
@ -476,15 +480,6 @@ const EditPartyModal = ({
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
const editorField = (
|
|
||||||
<Editor
|
|
||||||
bound={true}
|
|
||||||
content={description}
|
|
||||||
editable={true}
|
|
||||||
onUpdate={handleEditorUpdate}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
const chargeAttackField = (
|
const chargeAttackField = (
|
||||||
<SwitchTableField
|
<SwitchTableField
|
||||||
name="charge_attack"
|
name="charge_attack"
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,17 @@ import { accountState } from '~utils/accountState'
|
||||||
import { appState, initialAppState } from '~utils/appState'
|
import { appState, initialAppState } from '~utils/appState'
|
||||||
import { getLocalId } from '~utils/localId'
|
import { getLocalId } from '~utils/localId'
|
||||||
import { GridType } from '~utils/enums'
|
import { GridType } from '~utils/enums'
|
||||||
|
import * as PartyTransformer from '~transformers/PartyTransformer'
|
||||||
import { retrieveCookies } from '~utils/retrieveCookies'
|
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
|
||||||
|
|
@ -57,10 +59,10 @@ const Party = (props: Props) => {
|
||||||
// Reset state on first load
|
// Reset state on first load
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const resetState = clonedeep(initialAppState)
|
const resetState = clonedeep(initialAppState)
|
||||||
appState.grid = resetState.grid
|
appState.party.grid = resetState.party.grid
|
||||||
if (props.team) {
|
if (props.party) {
|
||||||
storeParty(props.team)
|
storeParty(props.party)
|
||||||
setUpdatedParty(props.team)
|
setUpdatedParty(props.party)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
@ -85,20 +87,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 +124,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 +144,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 +182,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 +205,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,16 +216,16 @@ 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 = PartyTransformer.toObject(response.data.party)
|
||||||
|
|
||||||
// Store the edit key in local storage
|
// Store the edit key in local storage
|
||||||
if (remix.edit_key) {
|
if (remix.editKey) {
|
||||||
storeEditKey(remix.id, remix.edit_key)
|
storeEditKey(remix.id, remix.editKey)
|
||||||
setEditKey(remix.id, remix.user)
|
setEditKey(remix.id, remix.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,9 +237,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 +269,38 @@ 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.protagonist.job
|
||||||
appState.party.job = team.job
|
appState.party.protagonist.skills = team.protagonist.skills
|
||||||
appState.party.jobSkills = team.job_skills
|
appState.party.protagonist.accessory = team.protagonist.accessory
|
||||||
appState.party.accessory = team.accessory
|
appState.party.protagonist.masterLevel = team.protagonist.master_level
|
||||||
|
appState.party.protagonist.ultimateMastery =
|
||||||
appState.party.chargeAttack = team.charge_attack
|
team.protagonist.ultimate_mastery
|
||||||
appState.party.fullAuto = team.full_auto
|
appState.party.details.chargeAttack = team.charge_attack
|
||||||
appState.party.autoGuard = team.auto_guard
|
appState.party.details.fullAuto = team.details.full_auto
|
||||||
appState.party.autoSummon = team.auto_summon
|
appState.party.details.autoGuard = team.details.auto_guard
|
||||||
appState.party.clearTime = team.clear_time
|
appState.party.details.autoSummon = team.details.auto_summon
|
||||||
appState.party.buttonCount =
|
appState.party.details.clearTime = team.details.clear_time
|
||||||
team.button_count !== null ? team.button_count : undefined
|
appState.party.details.buttonCount =
|
||||||
appState.party.chainCount =
|
team.details.button_count !== null ? team.details.button_count : undefined
|
||||||
team.chain_count !== null ? team.chain_count : undefined
|
appState.party.details.chainCount =
|
||||||
appState.party.turnCount =
|
team.details.chain_count !== null ? team.details.chain_count : undefined
|
||||||
team.turn_count !== null ? team.turn_count : undefined
|
appState.party.details.turnCount =
|
||||||
|
team.details.turn_count !== null ? team.details.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.details.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.social.favorited
|
||||||
appState.party.remix = team.remix
|
appState.party.social.remix = team.social.remix
|
||||||
appState.party.remixes = team.remixes
|
appState.party.social.remixes = team.social.remixes
|
||||||
appState.party.sourceParty = team.source_party
|
appState.party.social.sourceParty = team.social.sourceParty
|
||||||
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
|
appState.party.grid = team.grid
|
||||||
|
console.log(team.grid)
|
||||||
|
|
||||||
// Store the edit key in local storage
|
// Store the edit key in local storage
|
||||||
if (team.edit_key) {
|
if (team.edit_key) {
|
||||||
|
|
@ -304,11 +308,6 @@ const Party = (props: Props) => {
|
||||||
setEditKey(team.id, team.user)
|
setEditKey(team.id, team.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate state
|
|
||||||
storeCharacters(team.characters)
|
|
||||||
storeWeapons(team.weapons)
|
|
||||||
storeSummons(team.summons)
|
|
||||||
|
|
||||||
// Create a string to send the user back to the tab they're currently on
|
// Create a string to send the user back to the tab they're currently on
|
||||||
let tab = ''
|
let tab = ''
|
||||||
if (props.selectedTab === GridType.Character) {
|
if (props.selectedTab === GridType.Character) {
|
||||||
|
|
@ -326,53 +325,56 @@ const Party = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeCharacters = (list: Array<GridCharacter>) => {
|
const storeCharacters = (list: Array<GridCharacter>) => {
|
||||||
list.forEach((object: GridCharacter) => {
|
// list.forEach((object: GridCharacter) => {
|
||||||
let character = clonedeep(object)
|
// let character = clonedeep(object)
|
||||||
|
// if (character.mastery.overMastery) {
|
||||||
if (character.over_mastery) {
|
// const overMastery: CharacterOverMastery = {
|
||||||
const overMastery: CharacterOverMastery = {
|
// 1: object.mastery.overMastery[0],
|
||||||
1: object.over_mastery[0],
|
// 2: object.mastery.overMastery[1],
|
||||||
2: object.over_mastery[1],
|
// 3: object.mastery.overMastery[2],
|
||||||
3: object.over_mastery[2],
|
// 4: object.mastery.overMastery[3],
|
||||||
4: object.over_mastery[3],
|
// }
|
||||||
}
|
// character.mastery.overMastery = overMastery
|
||||||
|
// }
|
||||||
character.over_mastery = overMastery
|
// if (character.position != null) {
|
||||||
}
|
// appState.grid.characters[object.position] = character
|
||||||
|
// }
|
||||||
if (character.position != null) {
|
// })
|
||||||
appState.grid.characters[object.position] = character
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeWeapons = (list: Array<GridWeapon>) => {
|
const storeWeapons = (
|
||||||
list.forEach((gridObject: GridWeapon) => {
|
allWeapons: Array<GridWeapon>,
|
||||||
if (gridObject.mainhand) {
|
mainWeapon?: GridWeapon
|
||||||
appState.grid.weapons.mainWeapon = gridObject
|
) => {
|
||||||
appState.party.element = gridObject.object.element
|
// appState.grid.weapons.mainWeapon = mainWeapon
|
||||||
} else if (!gridObject.mainhand && gridObject.position !== null) {
|
// list.forEach((gridObject: GridWeapon) => {
|
||||||
let weapon = clonedeep(gridObject)
|
// if (gridObject.mainhand) {
|
||||||
if (weapon.object.element === 0 && weapon.element < 1)
|
// appState.grid.weapons.mainWeapon = gridObject
|
||||||
weapon.element = gridObject.object.element
|
// appState.party.element = gridObject.object.element
|
||||||
|
// } else if (!gridObject.mainhand && gridObject.position !== null) {
|
||||||
appState.grid.weapons.allWeapons[gridObject.position] = weapon
|
// let weapon = clonedeep(gridObject)
|
||||||
}
|
// if (
|
||||||
})
|
// weapon.object.element === ElementMap.null &&
|
||||||
|
// weapon.element === ElementMap.null
|
||||||
|
// )
|
||||||
|
// weapon.element = gridObject.object.element
|
||||||
|
// appState.grid.weapons.allWeapons[gridObject.position] = weapon
|
||||||
|
// }
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeSummons = (list: Array<GridSummon>) => {
|
const storeSummons = (list: Array<GridSummon>) => {
|
||||||
list.forEach((gridObject: GridSummon) => {
|
// list.forEach((gridObject: GridSummon) => {
|
||||||
if (gridObject.main) appState.grid.summons.mainSummon = gridObject
|
// if (gridObject.main) appState.grid.summons.mainSummon = gridObject
|
||||||
else if (gridObject.friend)
|
// else if (gridObject.friend)
|
||||||
appState.grid.summons.friendSummon = gridObject
|
// appState.grid.summons.friendSummon = gridObject
|
||||||
else if (
|
// else if (
|
||||||
!gridObject.main &&
|
// !gridObject.main &&
|
||||||
!gridObject.friend &&
|
// !gridObject.friend &&
|
||||||
gridObject.position != null
|
// gridObject.position != null
|
||||||
)
|
// )
|
||||||
appState.grid.summons.allSummons[gridObject.position] = gridObject
|
// appState.grid.summons.allSummons[gridObject.position] = gridObject
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods: Navigating with segmented control
|
// Methods: Navigating with segmented control
|
||||||
|
|
@ -403,8 +405,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 +418,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 +428,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}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import EditPartyModal from '../EditPartyModal'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
import { youtube } from '~utils/youtube'
|
|
||||||
|
|
||||||
import type { DetailsObject } from 'types'
|
import type { DetailsObject } from 'types'
|
||||||
|
|
||||||
|
|
@ -39,10 +38,7 @@ const PartyFooter = (props: Props) => {
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const { party: partySnapshot } = useSnapshot(appState)
|
const { party } = useSnapshot(appState)
|
||||||
|
|
||||||
const youtubeUrlRegex =
|
|
||||||
/(?:https:\/\/www\.youtube\.com\/watch\?v=|https:\/\/youtu\.be\/)([\w-]+)/g
|
|
||||||
|
|
||||||
// State: Component
|
// State: Component
|
||||||
const [currentSegment, setCurrentSegment] = useState(0)
|
const [currentSegment, setCurrentSegment] = useState(0)
|
||||||
|
|
@ -55,69 +51,19 @@ const PartyFooter = (props: Props) => {
|
||||||
const [sanitizedDescription, setSanitizedDescription] = useState('')
|
const [sanitizedDescription, setSanitizedDescription] = useState('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (partySnapshot.description) {
|
if (party.description) {
|
||||||
const purified = DOMPurify.sanitize(partySnapshot.description)
|
const purified = DOMPurify.sanitize(party.description)
|
||||||
setSanitizedDescription(purified)
|
setSanitizedDescription(purified)
|
||||||
} else {
|
} else {
|
||||||
setSanitizedDescription('')
|
setSanitizedDescription('')
|
||||||
}
|
}
|
||||||
}, [partySnapshot.description])
|
}, [party.description])
|
||||||
|
|
||||||
// Extract the video IDs from the description
|
|
||||||
// const videoIds = extractYoutubeVideoIds(partySnapshot.description)
|
|
||||||
// Fetch the video titles for each ID
|
|
||||||
// const fetchPromises = videoIds.map(({ id }) => fetchYoutubeData(id))
|
|
||||||
// // Wait for all the video titles to be fetched
|
|
||||||
// Promise.all(fetchPromises).then((videoTitles) => {
|
|
||||||
// // Replace the video URLs in the description with LiteYoutubeEmbed elements
|
|
||||||
// const newDescription = reactStringReplace(
|
|
||||||
// partySnapshot.description,
|
|
||||||
// youtubeUrlRegex,
|
|
||||||
// (match, i) => (
|
|
||||||
// <LiteYouTubeEmbed
|
|
||||||
// key={`${match}-${i}`}
|
|
||||||
// id={match}
|
|
||||||
// title={videoTitles[i]}
|
|
||||||
// wrapperClass={styles.youtube}
|
|
||||||
// playerClass={styles.playerButton}
|
|
||||||
// />
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// Update the state with the new description
|
|
||||||
|
|
||||||
async function fetchYoutubeData(videoId: string) {
|
|
||||||
return await youtube
|
|
||||||
.getVideoById(videoId, { maxResults: 1 })
|
|
||||||
.then((data) => data.items[0].snippet.localized.title)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods: Navigation
|
// Methods: Navigation
|
||||||
function goTo(shortcode?: string) {
|
function goTo(shortcode?: string) {
|
||||||
if (shortcode) router.push(`/p/${shortcode}`)
|
if (shortcode) router.push(`/p/${shortcode}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractYoutubeVideoIds(text: string) {
|
|
||||||
// Initialize an array to store the video IDs
|
|
||||||
const videoIds = []
|
|
||||||
|
|
||||||
// Use the regular expression to find all the Youtube URLs in the text
|
|
||||||
let match
|
|
||||||
while ((match = youtubeUrlRegex.exec(text)) !== null) {
|
|
||||||
// Extract the video ID from the URL
|
|
||||||
const videoId = match[1]
|
|
||||||
|
|
||||||
// Add the video ID to the array, along with the character position of the URL
|
|
||||||
videoIds.push({
|
|
||||||
id: videoId,
|
|
||||||
url: match[0],
|
|
||||||
position: match.index,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the array of video IDs
|
|
||||||
return videoIds
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods: Favorites
|
// Methods: Favorites
|
||||||
function toggleFavorite(teamId: string, favorited: boolean) {
|
function toggleFavorite(teamId: string, favorited: boolean) {
|
||||||
if (favorited) unsaveFavorite(teamId)
|
if (favorited) unsaveFavorite(teamId)
|
||||||
|
|
@ -130,7 +76,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 +92,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 +147,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: party?.social.remixes?.length ?? 0,
|
||||||
|
})}
|
||||||
</Segment>
|
</Segment>
|
||||||
</SegmentedControl>
|
</SegmentedControl>
|
||||||
)
|
)
|
||||||
|
|
@ -216,7 +164,7 @@ const PartyFooter = (props: Props) => {
|
||||||
key={props.party?.shortcode}
|
key={props.party?.shortcode}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{(!partySnapshot || !partySnapshot.description) && (
|
{(!party || !party.description) && (
|
||||||
<section className={styles.noDescription}>
|
<section className={styles.noDescription}>
|
||||||
<h3>{t('footer.description.empty')}</h3>
|
<h3>{t('footer.description.empty')}</h3>
|
||||||
{props.editable && (
|
{props.editable && (
|
||||||
|
|
@ -240,10 +188,10 @@ const PartyFooter = (props: Props) => {
|
||||||
|
|
||||||
const remixesSection = (
|
const remixesSection = (
|
||||||
<section className={styles.remixes}>
|
<section className={styles.remixes}>
|
||||||
{partySnapshot?.remixes?.length > 0 && (
|
{party?.social.remixes?.length > 0 && (
|
||||||
<GridRepCollection>{renderRemixes()}</GridRepCollection>
|
<GridRepCollection>{renderRemixes()}</GridRepCollection>
|
||||||
)}
|
)}
|
||||||
{partySnapshot?.remixes?.length === 0 && (
|
{party?.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 +205,19 @@ const PartyFooter = (props: Props) => {
|
||||||
)
|
)
|
||||||
|
|
||||||
function renderRemixes() {
|
function renderRemixes() {
|
||||||
return partySnapshot?.remixes.map((party, i) => {
|
return party?.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}
|
||||||
|
|
@ -288,7 +236,7 @@ const PartyFooter = (props: Props) => {
|
||||||
|
|
||||||
<RemixTeamAlert
|
<RemixTeamAlert
|
||||||
creator={props.editable}
|
creator={props.editable}
|
||||||
name={partySnapshot.name ? partySnapshot.name : t('no_title')}
|
name={party.name ? party.name : t('no_title')}
|
||||||
open={remixAlertOpen}
|
open={remixAlertOpen}
|
||||||
onOpenChange={handleRemixTeamAlertChange}
|
onOpenChange={handleRemixTeamAlertChange}
|
||||||
remixCallback={remixTeamCallback}
|
remixCallback={remixTeamCallback}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ const PartyHead = ({ party, meta }: Props) => {
|
||||||
raidName: party.raid ? party.raid.name[locale] : '',
|
raidName: party.raid ? party.raid.name[locale] : '',
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||||
|
|
||||||
{/* OpenGraph */}
|
{/* OpenGraph */}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
@ -30,26 +31,27 @@ const PartySegmentedControl = (props: Props) => {
|
||||||
// Set up translations
|
// Set up translations
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
const { party, grid } = useSnapshot(appState)
|
const { party } = 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 && party.grid.weapons.mainWeapon)
|
||||||
element = grid.weapons.mainWeapon.element
|
element = party.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,12 +66,12 @@ 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
|
||||||
}
|
}
|
||||||
grid={grid.characters}
|
grid={party.grid.characters}
|
||||||
/>
|
/>
|
||||||
</RepSegment>
|
</RepSegment>
|
||||||
)
|
)
|
||||||
|
|
@ -85,7 +87,7 @@ const PartySegmentedControl = (props: Props) => {
|
||||||
selected={props.selectedTab === GridType.Weapon}
|
selected={props.selectedTab === GridType.Weapon}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
>
|
>
|
||||||
<WeaponRep grid={grid.weapons} />
|
<WeaponRep grid={party.grid.weapons} />
|
||||||
</RepSegment>
|
</RepSegment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +102,7 @@ const PartySegmentedControl = (props: Props) => {
|
||||||
selected={props.selectedTab === GridType.Summon}
|
selected={props.selectedTab === GridType.Summon}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
>
|
>
|
||||||
<SummonRep grid={grid.summons} />
|
<SummonRep grid={party.grid.summons} />
|
||||||
</RepSegment>
|
</RepSegment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
})
|
})
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -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} />
|
||||||
''
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import styles from './index.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
grid: {
|
grid: {
|
||||||
mainSummon: GridSummon | undefined
|
mainSummon?: GridSummon | undefined
|
||||||
friendSummon: GridSummon | undefined
|
friendSummon?: GridSummon | undefined
|
||||||
allSummons: GridArray<GridSummon>
|
allSummons: GridArray<GridSummon>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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} />
|
||||||
''
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
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: {
|
||||||
mainWeapon: GridWeapon | undefined
|
mainWeapon?: GridWeapon | undefined
|
||||||
allWeapons: GridArray<GridWeapon>
|
allWeapons: GridArray<GridWeapon>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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} />
|
||||||
''
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,12 @@ import WeaponSearchFilterBar from '~components/weapon/WeaponSearchFilterBar'
|
||||||
import SummonSearchFilterBar from '~components/summon/SummonSearchFilterBar'
|
import SummonSearchFilterBar from '~components/summon/SummonSearchFilterBar'
|
||||||
import JobSkillSearchFilterBar from '~components/job/JobSkillSearchFilterBar'
|
import JobSkillSearchFilterBar from '~components/job/JobSkillSearchFilterBar'
|
||||||
|
|
||||||
|
import * as WeaponTransformer from '~transformers/WeaponTransformer'
|
||||||
|
import * as SummonTransformer from '~transformers/SummonTransformer'
|
||||||
|
import * as CharacterTransformer from '~transformers/CharacterTransformer'
|
||||||
|
import * as JobSkillTransformer from '~transformers/JobSkillTransformer'
|
||||||
|
import * as GuidebookTransformer from '~transformers/GuidebookTransformer'
|
||||||
|
|
||||||
import CharacterResult from '~components/character/CharacterResult'
|
import CharacterResult from '~components/character/CharacterResult'
|
||||||
import WeaponResult from '~components/weapon/WeaponResult'
|
import WeaponResult from '~components/weapon/WeaponResult'
|
||||||
import SummonResult from '~components/summon/SummonResult'
|
import SummonResult from '~components/summon/SummonResult'
|
||||||
|
|
@ -126,7 +132,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 +142,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)
|
||||||
|
|
@ -270,13 +276,14 @@ const SearchModal = (props: Props) => {
|
||||||
|
|
||||||
const castResults: Weapon[] = results as Weapon[]
|
const castResults: Weapon[] = results as Weapon[]
|
||||||
if (castResults && Object.keys(castResults).length > 0) {
|
if (castResults && Object.keys(castResults).length > 0) {
|
||||||
jsx = castResults.map((result: Weapon) => {
|
jsx = castResults.map((result: any) => {
|
||||||
|
const weapon = WeaponTransformer.toObject(result)
|
||||||
return (
|
return (
|
||||||
<WeaponResult
|
<WeaponResult
|
||||||
key={result.id}
|
key={weapon.id}
|
||||||
data={result}
|
data={weapon}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
storeRecentResult(result)
|
storeRecentResult(weapon)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
@ -291,13 +298,14 @@ const SearchModal = (props: Props) => {
|
||||||
|
|
||||||
const castResults: Summon[] = results as Summon[]
|
const castResults: Summon[] = results as Summon[]
|
||||||
if (castResults && Object.keys(castResults).length > 0) {
|
if (castResults && Object.keys(castResults).length > 0) {
|
||||||
jsx = castResults.map((result: Summon) => {
|
jsx = castResults.map((result: any) => {
|
||||||
|
const summon = SummonTransformer.toObject(result)
|
||||||
return (
|
return (
|
||||||
<SummonResult
|
<SummonResult
|
||||||
key={result.id}
|
key={summon.id}
|
||||||
data={result}
|
data={summon}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
storeRecentResult(result)
|
storeRecentResult(summon)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
@ -312,13 +320,14 @@ const SearchModal = (props: Props) => {
|
||||||
|
|
||||||
const castResults: Character[] = results as Character[]
|
const castResults: Character[] = results as Character[]
|
||||||
if (castResults && Object.keys(castResults).length > 0) {
|
if (castResults && Object.keys(castResults).length > 0) {
|
||||||
jsx = castResults.map((result: Character) => {
|
jsx = castResults.map((result: any) => {
|
||||||
|
const character = CharacterTransformer.toObject(result)
|
||||||
return (
|
return (
|
||||||
<CharacterResult
|
<CharacterResult
|
||||||
key={result.id}
|
key={character.id}
|
||||||
data={result}
|
data={character}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
storeRecentResult(result)
|
storeRecentResult(character)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
@ -334,12 +343,13 @@ const SearchModal = (props: Props) => {
|
||||||
const castResults: JobSkill[] = results as JobSkill[]
|
const castResults: JobSkill[] = results as JobSkill[]
|
||||||
if (castResults && Object.keys(castResults).length > 0) {
|
if (castResults && Object.keys(castResults).length > 0) {
|
||||||
jsx = castResults.map((result: JobSkill) => {
|
jsx = castResults.map((result: JobSkill) => {
|
||||||
|
const jobSkill = JobSkillTransformer.toObject(result)
|
||||||
return (
|
return (
|
||||||
<JobSkillResult
|
<JobSkillResult
|
||||||
key={result.id}
|
key={jobSkill.id}
|
||||||
data={result}
|
data={jobSkill}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
storeRecentResult(result)
|
storeRecentResult(jobSkill)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
@ -355,12 +365,13 @@ const SearchModal = (props: Props) => {
|
||||||
const castResults: Guidebook[] = results as Guidebook[]
|
const castResults: Guidebook[] = results as Guidebook[]
|
||||||
if (castResults && Object.keys(castResults).length > 0) {
|
if (castResults && Object.keys(castResults).length > 0) {
|
||||||
jsx = castResults.map((result: Guidebook) => {
|
jsx = castResults.map((result: Guidebook) => {
|
||||||
|
const guidebook = GuidebookTransformer.toObject(result)
|
||||||
return (
|
return (
|
||||||
<GuidebookResult
|
<GuidebookResult
|
||||||
key={result.id}
|
key={guidebook.id}
|
||||||
data={result}
|
data={guidebook}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
storeRecentResult(result)
|
storeRecentResult(guidebook)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import ExtraSummonsGrid from '~components/extra/ExtraSummonsGrid'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
|
import * as GridSummonTransformer from '~transformers/GridSummonTransformer'
|
||||||
import type { DetailsObject, SearchableObject } from '~types'
|
import type { DetailsObject, SearchableObject } from '~types'
|
||||||
|
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
@ -22,7 +23,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
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +50,7 @@ const SummonGrid = (props: Props) => {
|
||||||
const [errorAlertOpen, setErrorAlertOpen] = useState(false)
|
const [errorAlertOpen, setErrorAlertOpen] = useState(false)
|
||||||
|
|
||||||
// Set up state for view management
|
// Set up state for view management
|
||||||
const { party, grid } = useSnapshot(appState)
|
const { party } = useSnapshot(appState)
|
||||||
|
|
||||||
// Create a temporary state to store previous weapon uncap values and transcendence stages
|
// Create a temporary state to store previous weapon uncap values and transcendence stages
|
||||||
const [previousUncapValues, setPreviousUncapValues] = useState<{
|
const [previousUncapValues, setPreviousUncapValues] = useState<{
|
||||||
|
|
@ -60,23 +65,23 @@ const SummonGrid = (props: Props) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let initialPreviousUncapValues: { [key: number]: number } = {}
|
let initialPreviousUncapValues: { [key: number]: number } = {}
|
||||||
|
|
||||||
if (appState.grid.summons.mainSummon)
|
if (appState.party.grid.summons.mainSummon)
|
||||||
initialPreviousUncapValues[-1] =
|
initialPreviousUncapValues[-1] =
|
||||||
appState.grid.summons.mainSummon.uncap_level
|
appState.party.grid.summons.mainSummon.uncapLevel
|
||||||
|
|
||||||
if (appState.grid.summons.friendSummon)
|
if (appState.party.grid.summons.friendSummon)
|
||||||
initialPreviousUncapValues[6] =
|
initialPreviousUncapValues[6] =
|
||||||
appState.grid.summons.friendSummon.uncap_level
|
appState.party.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)
|
||||||
}, [
|
}, [
|
||||||
appState.grid.summons.mainSummon,
|
appState.party.grid.summons.mainSummon,
|
||||||
appState.grid.summons.friendSummon,
|
appState.party.grid.summons.friendSummon,
|
||||||
appState.grid.summons.allSummons,
|
appState.party.grid.summons.allSummons,
|
||||||
])
|
])
|
||||||
|
|
||||||
// Methods: Adding an object from search
|
// Methods: Adding an object from search
|
||||||
|
|
@ -115,11 +120,11 @@ const SummonGrid = (props: Props) => {
|
||||||
const position = data.meta['replaced']
|
const position = data.meta['replaced']
|
||||||
|
|
||||||
if (position == -1) {
|
if (position == -1) {
|
||||||
appState.grid.summons.mainSummon = undefined
|
appState.party.grid.summons.mainSummon = null
|
||||||
} else if (position == 6) {
|
} else if (position == 6) {
|
||||||
appState.grid.summons.friendSummon = undefined
|
appState.party.grid.summons.friendSummon = null
|
||||||
} else {
|
} else {
|
||||||
appState.grid.summons.allSummons[position] = undefined
|
appState.party.grid.summons.allSummons[position] = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -137,16 +142,20 @@ 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,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function storeGridSummon(gridSummon: GridSummon) {
|
function storeGridSummon(data: GridSummon) {
|
||||||
if (gridSummon.position == -1) appState.grid.summons.mainSummon = gridSummon
|
const gridSummon = GridSummonTransformer.toObject(data)
|
||||||
|
|
||||||
|
if (gridSummon.position == -1)
|
||||||
|
appState.party.grid.summons.mainSummon = gridSummon
|
||||||
else if (gridSummon.position == 6)
|
else if (gridSummon.position == 6)
|
||||||
appState.grid.summons.friendSummon = gridSummon
|
appState.party.grid.summons.friendSummon = gridSummon
|
||||||
else appState.grid.summons.allSummons[gridSummon.position] = gridSummon
|
else
|
||||||
|
appState.party.grid.summons.allSummons[gridSummon.position] = gridSummon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods: Updating uncap level
|
// Methods: Updating uncap level
|
||||||
|
|
@ -212,15 +221,15 @@ 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.party.grid.summons.mainSummon && position == -1)
|
||||||
appState.grid.summons.mainSummon.uncap_level = uncapLevel
|
appState.party.grid.summons.mainSummon.uncapLevel = uncapLevel
|
||||||
else if (appState.grid.summons.friendSummon && position == 6)
|
else if (appState.party.grid.summons.friendSummon && position == 6)
|
||||||
appState.grid.summons.friendSummon.uncap_level = uncapLevel
|
appState.party.grid.summons.friendSummon.uncapLevel = uncapLevel
|
||||||
else {
|
else {
|
||||||
const summon = appState.grid.summons.allSummons[position]
|
const summon = appState.party.grid.summons.allSummons[position]
|
||||||
if (summon) {
|
if (summon) {
|
||||||
summon.uncap_level = uncapLevel
|
summon.uncapLevel = uncapLevel
|
||||||
appState.grid.summons.allSummons[position] = summon
|
appState.party.grid.summons.allSummons[position] = summon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -229,14 +238,15 @@ const SummonGrid = (props: Props) => {
|
||||||
// Save the current value in case of an unexpected result
|
// Save the current value in case of an unexpected result
|
||||||
let newPreviousValues = { ...previousUncapValues }
|
let newPreviousValues = { ...previousUncapValues }
|
||||||
|
|
||||||
if (appState.grid.summons.mainSummon && position == -1)
|
if (appState.party.grid.summons.mainSummon && position == -1)
|
||||||
newPreviousValues[position] = appState.grid.summons.mainSummon.uncap_level
|
|
||||||
else if (appState.grid.summons.friendSummon && position == 6)
|
|
||||||
newPreviousValues[position] =
|
newPreviousValues[position] =
|
||||||
appState.grid.summons.friendSummon.uncap_level
|
appState.party.grid.summons.mainSummon.uncapLevel
|
||||||
|
else if (appState.party.grid.summons.friendSummon && position == 6)
|
||||||
|
newPreviousValues[position] =
|
||||||
|
appState.party.grid.summons.friendSummon.uncapLevel
|
||||||
else {
|
else {
|
||||||
const summon = appState.grid.summons.allSummons[position]
|
const summon = appState.party.grid.summons.allSummons[position]
|
||||||
newPreviousValues[position] = summon ? summon.uncap_level : 0
|
newPreviousValues[position] = summon ? summon.uncapLevel : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
setPreviousUncapValues(newPreviousValues)
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
|
@ -254,18 +264,16 @@ 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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (stage != previousTranscendenceStages[position])
|
if (stage != previousTranscendenceStages[position])
|
||||||
await api.endpoints.grid_summons
|
await api.updateTranscendence('summon', id, stage).then((response) => {
|
||||||
.update(id, payload)
|
storeGridSummon(response.data.grid_summon)
|
||||||
.then((response) => {
|
})
|
||||||
storeGridSummon(response.data.grid_summon)
|
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
||||||
|
|
@ -318,15 +326,15 @@ 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.party.grid.summons.mainSummon && position == -1)
|
||||||
appState.grid.summons.mainSummon.transcendence_step = stage
|
appState.party.grid.summons.mainSummon.transcendenceStep = stage
|
||||||
else if (appState.grid.summons.friendSummon && position == 6)
|
else if (appState.party.grid.summons.friendSummon && position == 6)
|
||||||
appState.grid.summons.friendSummon.transcendence_step = stage
|
appState.party.grid.summons.friendSummon.transcendenceStep = stage
|
||||||
else {
|
else {
|
||||||
const summon = appState.grid.summons.allSummons[position]
|
const summon = appState.party.grid.summons.allSummons[position]
|
||||||
if (summon) {
|
if (summon) {
|
||||||
summon.transcendence_step = stage
|
summon.transcendenceStep = stage
|
||||||
appState.grid.summons.allSummons[position] = summon
|
appState.party.grid.summons.allSummons[position] = summon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -335,14 +343,15 @@ const SummonGrid = (props: Props) => {
|
||||||
// Save the current value in case of an unexpected result
|
// Save the current value in case of an unexpected result
|
||||||
let newPreviousValues = { ...previousUncapValues }
|
let newPreviousValues = { ...previousUncapValues }
|
||||||
|
|
||||||
if (appState.grid.summons.mainSummon && position == -1)
|
if (appState.party.grid.summons.mainSummon && position == -1)
|
||||||
newPreviousValues[position] = appState.grid.summons.mainSummon.uncap_level
|
|
||||||
else if (appState.grid.summons.friendSummon && position == 6)
|
|
||||||
newPreviousValues[position] =
|
newPreviousValues[position] =
|
||||||
appState.grid.summons.friendSummon.uncap_level
|
appState.party.grid.summons.mainSummon.uncapLevel
|
||||||
|
else if (appState.party.grid.summons.friendSummon && position == 6)
|
||||||
|
newPreviousValues[position] =
|
||||||
|
appState.party.grid.summons.friendSummon.uncapLevel
|
||||||
else {
|
else {
|
||||||
const summon = appState.grid.summons.allSummons[position]
|
const summon = appState.party.grid.summons.allSummons[position]
|
||||||
newPreviousValues[position] = summon ? summon.uncap_level : 0
|
newPreviousValues[position] = summon ? summon.uncapLevel : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
setPreviousUncapValues(newPreviousValues)
|
setPreviousUncapValues(newPreviousValues)
|
||||||
|
|
@ -354,11 +363,11 @@ const SummonGrid = (props: Props) => {
|
||||||
const data = response.data
|
const data = response.data
|
||||||
|
|
||||||
if (data.position === -1) {
|
if (data.position === -1) {
|
||||||
appState.grid.summons.mainSummon = undefined
|
appState.party.grid.summons.mainSummon = null
|
||||||
} else if (data.position === 6) {
|
} else if (data.position === 6) {
|
||||||
appState.grid.summons.friendSummon = undefined
|
appState.party.grid.summons.friendSummon = null
|
||||||
} else {
|
} else {
|
||||||
appState.grid.summons.allSummons[response.data.position] = undefined
|
appState.party.grid.summons.allSummons[response.data.position] = null
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
@ -382,7 +391,7 @@ const SummonGrid = (props: Props) => {
|
||||||
<div className="LabeledUnit">
|
<div className="LabeledUnit">
|
||||||
<div className={styles.label}>{t('summons.main')}</div>
|
<div className={styles.label}>{t('summons.main')}</div>
|
||||||
<SummonUnit
|
<SummonUnit
|
||||||
gridSummon={grid.summons.mainSummon}
|
gridSummon={party.grid.summons.mainSummon}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
key="grid_main_summon"
|
key="grid_main_summon"
|
||||||
position={-1}
|
position={-1}
|
||||||
|
|
@ -406,7 +415,7 @@ const SummonGrid = (props: Props) => {
|
||||||
{t('summons.friend')}
|
{t('summons.friend')}
|
||||||
</div>
|
</div>
|
||||||
<SummonUnit
|
<SummonUnit
|
||||||
gridSummon={grid.summons.friendSummon}
|
gridSummon={party.grid.summons.friendSummon}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
key="grid_friend_summon"
|
key="grid_friend_summon"
|
||||||
position={6}
|
position={6}
|
||||||
|
|
@ -427,7 +436,7 @@ const SummonGrid = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<li key={`grid_unit_${i}`}>
|
<li key={`grid_unit_${i}`}>
|
||||||
<SummonUnit
|
<SummonUnit
|
||||||
gridSummon={grid.summons.allSummons[i]}
|
gridSummon={party.grid.summons.allSummons[i]}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
position={i}
|
position={i}
|
||||||
unitType={1}
|
unitType={1}
|
||||||
|
|
@ -445,7 +454,7 @@ const SummonGrid = (props: Props) => {
|
||||||
|
|
||||||
const subAuraSummonElement = (
|
const subAuraSummonElement = (
|
||||||
<ExtraSummonsGrid
|
<ExtraSummonsGrid
|
||||||
grid={grid.summons.allSummons}
|
grid={party.grid.summons.allSummons}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
exists={false}
|
exists={false}
|
||||||
offset={numSummons}
|
offset={numSummons}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,18 +22,21 @@ 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>
|
||||||
<UncapIndicator
|
<UncapIndicator
|
||||||
type="summon"
|
type="summon"
|
||||||
flb={summon.uncap.flb}
|
ulb={summon.uncap.ulb || false}
|
||||||
ulb={summon.uncap.ulb}
|
flb={summon.uncap.flb || false}
|
||||||
|
xlb={summon.uncap.xlb || false}
|
||||||
|
uncapLevel={6}
|
||||||
|
transcendenceStage={5}
|
||||||
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>
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import classNames from 'classnames'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
|
import * as GridSummonTransformer from '~transformers/GridSummonTransformer'
|
||||||
|
|
||||||
import Alert from '~components/common/Alert'
|
import Alert from '~components/common/Alert'
|
||||||
import Button from '~components/common/Button'
|
import Button from '~components/common/Button'
|
||||||
|
|
@ -26,7 +27,7 @@ import SettingsIcon from '~public/icons/Settings.svg'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
gridSummon: GridSummon | undefined
|
gridSummon: GridSummon | null
|
||||||
unitType: 0 | 1 | 2
|
unitType: 0 | 1 | 2
|
||||||
position: number
|
position: number
|
||||||
editable: boolean
|
editable: boolean
|
||||||
|
|
@ -95,7 +96,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
|
||||||
|
|
@ -125,13 +126,23 @@ const SummonUnit = ({
|
||||||
// If a user sets a quick summon while one is already set,
|
// If a user sets a quick summon while one is already set,
|
||||||
// the previous one will be unset.
|
// the previous one will be unset.
|
||||||
const gridSummons: GridSummon[] = response.data.summons
|
const gridSummons: GridSummon[] = response.data.summons
|
||||||
|
|
||||||
|
const mainSummon = gridSummons.find((summon) =>
|
||||||
|
GridSummonTransformer.toObject(summon)
|
||||||
|
)
|
||||||
|
const friendSummon = gridSummons.find((summon) =>
|
||||||
|
GridSummonTransformer.toObject(summon)
|
||||||
|
)
|
||||||
|
|
||||||
for (const gridSummon of gridSummons) {
|
for (const gridSummon of gridSummons) {
|
||||||
if (gridSummon.main) {
|
if (gridSummon.main) {
|
||||||
appState.grid.summons.mainSummon = gridSummon
|
appState.grid.summons.mainSummon = mainSummon
|
||||||
} else if (gridSummon.friend) {
|
} else if (gridSummon.friend) {
|
||||||
appState.grid.summons.friendSummon = gridSummon
|
appState.grid.summons.friendSummon = friendSummon
|
||||||
} else {
|
} else {
|
||||||
appState.grid.summons.allSummons[gridSummon.position] = gridSummon
|
appState.party.grid.summons.allSummons[gridSummon.position] = gridSummon
|
||||||
|
? GridSummonTransformer.toObject(gridSummon)
|
||||||
|
: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,8 +168,7 @@ const SummonUnit = ({
|
||||||
function generateImageUrl() {
|
function generateImageUrl() {
|
||||||
let imgSrc = ''
|
let imgSrc = ''
|
||||||
if (gridSummon) {
|
if (gridSummon) {
|
||||||
const summon = gridSummon.object!
|
const summon = gridSummon.object
|
||||||
|
|
||||||
const upgradedSummons = [
|
const upgradedSummons = [
|
||||||
'2040094000',
|
'2040094000',
|
||||||
'2040100000',
|
'2040100000',
|
||||||
|
|
@ -177,27 +187,28 @@ 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 &&
|
||||||
gridSummon.transcendence_step < 5
|
gridSummon.transcendenceStep >= 1 &&
|
||||||
|
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) != -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 +284,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 +338,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}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
.Fragment {
|
.fragment {
|
||||||
$degrees: 72deg;
|
$degrees: 72deg;
|
||||||
|
|
||||||
$origWidth: 29px;
|
$origWidth: 29px;
|
||||||
|
|
@ -28,11 +28,11 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Visible {
|
&.visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Stage1 {
|
&.stage1 {
|
||||||
top: 3px;
|
top: 3px;
|
||||||
left: 18px;
|
left: 18px;
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Stage2 {
|
&.stage2 {
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 27px;
|
left: 27px;
|
||||||
transform: rotate($degrees);
|
transform: rotate($degrees);
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Stage3 {
|
&.stage3 {
|
||||||
top: 21px;
|
top: 21px;
|
||||||
left: 24px;
|
left: 24px;
|
||||||
transform: rotate($degrees * 2);
|
transform: rotate($degrees * 2);
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Stage4 {
|
&.stage4 {
|
||||||
top: 21px;
|
top: 21px;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
transform: rotate($degrees * 3);
|
transform: rotate($degrees * 3);
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.Stage5 {
|
&.stage5 {
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
transform: rotate($degrees * 4);
|
transform: rotate($degrees * 4);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import classnames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
|
|
@ -18,14 +18,14 @@ const TranscendenceFragment = ({
|
||||||
onClick,
|
onClick,
|
||||||
onHover,
|
onHover,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const classes = classnames({
|
const classes = classNames({
|
||||||
Fragment: true,
|
[styles.fragment]: true,
|
||||||
Visible: visible,
|
[styles.visible]: visible,
|
||||||
Stage1: stage === 1,
|
[styles.stage1]: stage === 1,
|
||||||
Stage2: stage === 2,
|
[styles.stage2]: stage === 2,
|
||||||
Stage3: stage === 3,
|
[styles.stage3]: stage === 3,
|
||||||
Stage4: stage === 4,
|
[styles.stage4]: stage === 4,
|
||||||
Stage5: stage === 5,
|
[styles.stage5]: stage === 5,
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,20 @@
|
||||||
.Transcendence.Popover {
|
.transcendence {
|
||||||
align-items: center;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: $unit-half;
|
gap: $unit-half;
|
||||||
display: flex;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
width: $unit-10x;
|
width: $unit-10x;
|
||||||
height: $unit-10x;
|
height: $unit-10x;
|
||||||
justify-content: center;
|
|
||||||
|
animation: scaleIn $duration-zoom ease-out;
|
||||||
|
background: var(--dialog-bg);
|
||||||
|
border-radius: $card-corner;
|
||||||
|
border: 0.5px solid rgba(0, 0, 0, 0.18);
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24);
|
||||||
|
outline: none;
|
||||||
|
padding: $unit;
|
||||||
|
transform-origin: var(--radix-popover-content-transform-origin);
|
||||||
z-index: 32;
|
z-index: 32;
|
||||||
|
|
||||||
&.open {
|
&.open {
|
||||||
|
|
@ -18,7 +27,50 @@
|
||||||
font-weight: $medium;
|
font-weight: $medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Pending {
|
.pending {
|
||||||
color: $yellow;
|
color: $yellow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes scaleIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
opacity: 0.2;
|
||||||
|
transform: scale(0.4);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
opacity: 0.4;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
opacity: 0.6;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
65% {
|
||||||
|
opacity: 0.65;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
opacity: 0.7;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
opacity: 0.75;
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
opacity: 0.8;
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
opacity: 0.9;
|
||||||
|
transform: scale(0.96);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import React, { PropsWithChildren, useEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
|
import { Popover } from '@radix-ui/react-popover'
|
||||||
import {
|
import {
|
||||||
Popover,
|
|
||||||
PopoverAnchor,
|
PopoverAnchor,
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
} from '~components/common/PopoverContent'
|
} from '~components/common/PopoverContent'
|
||||||
|
|
@ -40,12 +40,8 @@ const TranscendencePopover = ({
|
||||||
|
|
||||||
const popoverRef = React.createRef<HTMLDivElement>()
|
const popoverRef = React.createRef<HTMLDivElement>()
|
||||||
|
|
||||||
const classes = classNames({
|
|
||||||
Transcendence: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const levelClasses = classNames({
|
const levelClasses = classNames({
|
||||||
Pending: stage != currentStage,
|
[styles.pending]: stage != currentStage,
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -77,16 +73,20 @@ const TranscendencePopover = ({
|
||||||
return (
|
return (
|
||||||
<Popover open={open} onOpenChange={onOpenChange}>
|
<Popover open={open} onOpenChange={onOpenChange}>
|
||||||
<PopoverAnchor>{children}</PopoverAnchor>
|
<PopoverAnchor>{children}</PopoverAnchor>
|
||||||
<PopoverContent className={classes} ref={popoverRef} tabIndex={tabIndex}>
|
<PopoverContent
|
||||||
|
className={styles.transcendence}
|
||||||
|
ref={popoverRef}
|
||||||
|
tabIndex={tabIndex}
|
||||||
|
>
|
||||||
<TranscendenceStar
|
<TranscendenceStar
|
||||||
className="Interactive Base"
|
className="interactive base"
|
||||||
editable={true}
|
editable={true}
|
||||||
interactive={true}
|
interactive={true}
|
||||||
stage={stage}
|
stage={stage}
|
||||||
onFragmentClick={handleFragmentClicked}
|
onFragmentClick={handleFragmentClicked}
|
||||||
onFragmentHover={handleFragmentHovered}
|
onFragmentHover={handleFragmentHovered}
|
||||||
/>
|
/>
|
||||||
<h4>
|
<h4 className="name">
|
||||||
<span>{t('level')} </span>
|
<span>{t('level')} </span>
|
||||||
<span className={levelClasses}>{baseLevel + 10 * currentStage}</span>
|
<span className={levelClasses}>{baseLevel + 10 * currentStage}</span>
|
||||||
</h4>
|
</h4>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const TranscendenceStar = ({
|
||||||
const starClasses = classnames({
|
const starClasses = classnames({
|
||||||
[styles.star]: true,
|
[styles.star]: true,
|
||||||
[styles.immutable]: immutable,
|
[styles.immutable]: immutable,
|
||||||
[styles.empty]: stage === 0,
|
[styles.empty]: true,
|
||||||
[styles.stage1]: stage === 1,
|
[styles.stage1]: stage === 1,
|
||||||
[styles.stage2]: stage === 2,
|
[styles.stage2]: stage === 2,
|
||||||
[styles.stage3]: stage === 3,
|
[styles.stage3]: stage === 3,
|
||||||
|
|
@ -46,9 +46,12 @@ const TranscendenceStar = ({
|
||||||
[styles.stage5]: stage === 5,
|
[styles.stage5]: stage === 5,
|
||||||
})
|
})
|
||||||
|
|
||||||
const baseImageClasses = classnames(className, {
|
const baseImageClasses = classnames(
|
||||||
[styles.figure]: true,
|
{
|
||||||
})
|
[styles.figure]: true,
|
||||||
|
},
|
||||||
|
className?.split(' ').map((c) => styles[c])
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setVisibleStage(stage)
|
setVisibleStage(stage)
|
||||||
|
|
@ -87,7 +90,7 @@ const TranscendenceStar = ({
|
||||||
onMouseLeave={interactive ? handleMouseLeave : () => {}}
|
onMouseLeave={interactive ? handleMouseLeave : () => {}}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
<div className="Fragments">
|
<div className={styles.fragments}>
|
||||||
{[...Array(NUM_FRAGMENTS)].map((e, i) => {
|
{[...Array(NUM_FRAGMENTS)].map((e, i) => {
|
||||||
const loopStage = i + 1
|
const loopStage = i + 1
|
||||||
return interactive ? (
|
return interactive ? (
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import UncapStar from '~components/uncap/UncapStar'
|
import UncapStar from '~components/uncap/UncapStar'
|
||||||
import TranscendencePopover from '~components/uncap/TranscendencePopover'
|
import TranscendencePopover from '~components/uncap/TranscendencePopover'
|
||||||
import TranscendenceStar from '~components/uncap/TranscendenceStar'
|
import TranscendenceStar from '~components/uncap/TranscendenceStar'
|
||||||
|
|
@ -82,7 +82,11 @@ const UncapIndicator = (props: Props) => {
|
||||||
return props.type === 'character' || props.type === 'summon' ? (
|
return props.type === 'character' || props.type === 'summon' ? (
|
||||||
<TranscendencePopover
|
<TranscendencePopover
|
||||||
open={popoverOpen}
|
open={popoverOpen}
|
||||||
stage={props.transcendenceStage ? props.transcendenceStage : 0}
|
stage={
|
||||||
|
props.transcendenceStage && props.transcendenceStage !== null
|
||||||
|
? props.transcendenceStage
|
||||||
|
: 0
|
||||||
|
}
|
||||||
type={props.type}
|
type={props.type}
|
||||||
onOpenChange={togglePopover}
|
onOpenChange={togglePopover}
|
||||||
sendValue={sendTranscendenceStage}
|
sendValue={sendTranscendenceStage}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,21 @@ import WeaponConflictModal from '~components/weapon/WeaponConflictModal'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
|
import * as GridWeaponTransformer from '~transformers/GridWeaponTransformer'
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -54,7 +59,7 @@ const WeaponGrid = (props: Props) => {
|
||||||
const [showIncompatibleAlert, setShowIncompatibleAlert] = useState(false)
|
const [showIncompatibleAlert, setShowIncompatibleAlert] = useState(false)
|
||||||
|
|
||||||
// Set up state for view management
|
// Set up state for view management
|
||||||
const { party, grid } = useSnapshot(appState)
|
const { party } = useSnapshot(appState)
|
||||||
const [modalOpen, setModalOpen] = useState(false)
|
const [modalOpen, setModalOpen] = useState(false)
|
||||||
|
|
||||||
// Set up state for conflict management
|
// Set up state for conflict management
|
||||||
|
|
@ -71,16 +76,19 @@ const WeaponGrid = (props: Props) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let initialPreviousUncapValues: { [key: number]: number } = {}
|
let initialPreviousUncapValues: { [key: number]: number } = {}
|
||||||
|
|
||||||
if (appState.grid.weapons.mainWeapon)
|
if (appState.party.grid.weapons.mainWeapon)
|
||||||
initialPreviousUncapValues[-1] =
|
initialPreviousUncapValues[-1] =
|
||||||
appState.grid.weapons.mainWeapon.uncap_level
|
appState.party.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)
|
||||||
}, [appState.grid.weapons.mainWeapon, appState.grid.weapons.allWeapons])
|
}, [
|
||||||
|
appState.party.grid.weapons.mainWeapon,
|
||||||
|
appState.party.grid.weapons.allWeapons,
|
||||||
|
])
|
||||||
|
|
||||||
// Methods: Adding an object from search
|
// Methods: Adding an object from search
|
||||||
function receiveWeaponFromSearch(object: SearchableObject, position: number) {
|
function receiveWeaponFromSearch(object: SearchableObject, position: number) {
|
||||||
|
|
@ -88,7 +96,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)
|
||||||
|
|
@ -143,10 +151,10 @@ const WeaponGrid = (props: Props) => {
|
||||||
const position = data.meta['replaced']
|
const position = data.meta['replaced']
|
||||||
|
|
||||||
if (position == -1) {
|
if (position == -1) {
|
||||||
appState.grid.weapons.mainWeapon = undefined
|
appState.party.grid.weapons.mainWeapon = null
|
||||||
appState.party.element = 0
|
appState.party.element = ElementMap.null
|
||||||
} else {
|
} else {
|
||||||
appState.grid.weapons.allWeapons[position] = undefined
|
appState.party.grid.weapons.allWeapons[position] = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,16 +168,17 @@ const WeaponGrid = (props: Props) => {
|
||||||
let post = false
|
let post = false
|
||||||
if (
|
if (
|
||||||
position === -1 &&
|
position === -1 &&
|
||||||
(!appState.grid.weapons.mainWeapon ||
|
(!appState.party.grid.weapons.mainWeapon ||
|
||||||
(appState.grid.weapons.mainWeapon &&
|
(appState.party.grid.weapons.mainWeapon &&
|
||||||
appState.grid.weapons.mainWeapon.object.id !== weapon.id))
|
appState.party.grid.weapons.mainWeapon.object.id !== weapon.id))
|
||||||
) {
|
) {
|
||||||
post = true
|
post = true
|
||||||
} else if (
|
} else if (
|
||||||
position !== -1 &&
|
position !== -1 &&
|
||||||
(!appState.grid.weapons.allWeapons[position] ||
|
(!appState.party.grid.weapons.allWeapons[position] ||
|
||||||
(appState.grid.weapons.allWeapons[position] &&
|
(appState.party.grid.weapons.allWeapons[position] &&
|
||||||
appState.grid.weapons.allWeapons[position]?.object.id !== weapon.id))
|
appState.party.grid.weapons.allWeapons[position]?.object.id !==
|
||||||
|
weapon.id))
|
||||||
) {
|
) {
|
||||||
post = true
|
post = true
|
||||||
}
|
}
|
||||||
|
|
@ -181,19 +190,20 @@ 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,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function storeGridWeapon(gridWeapon: GridWeapon) {
|
function storeGridWeapon(data: GridWeapon) {
|
||||||
|
const gridWeapon = GridWeaponTransformer.toObject(data)
|
||||||
if (gridWeapon.position === -1) {
|
if (gridWeapon.position === -1) {
|
||||||
appState.grid.weapons.mainWeapon = gridWeapon
|
appState.party.grid.weapons.mainWeapon = gridWeapon
|
||||||
appState.party.element = gridWeapon.object.element
|
appState.party.element = gridWeapon.object.element
|
||||||
} else {
|
} else {
|
||||||
// Store the grid unit at the correct position
|
// Store the grid unit at the correct position
|
||||||
appState.grid.weapons.allWeapons[gridWeapon.position] = gridWeapon
|
appState.party.grid.weapons.allWeapons[gridWeapon.position] = gridWeapon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,11 +219,13 @@ const WeaponGrid = (props: Props) => {
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
// Remove conflicting characters from state
|
// Remove conflicting characters from state
|
||||||
conflicts.forEach((c) => {
|
conflicts.forEach((c) => {
|
||||||
if (appState.grid.weapons.mainWeapon?.object.id === c.object.id) {
|
if (
|
||||||
appState.grid.weapons.mainWeapon = undefined
|
appState.party.grid.weapons.mainWeapon?.object.id === c.object.id
|
||||||
appState.party.element = 0
|
) {
|
||||||
|
appState.party.grid.weapons.mainWeapon = null
|
||||||
|
appState.party.element = ElementMap.null
|
||||||
} else {
|
} else {
|
||||||
appState.grid.weapons.allWeapons[c.position] = undefined
|
appState.party.grid.weapons.allWeapons[c.position] = null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -241,9 +253,9 @@ const WeaponGrid = (props: Props) => {
|
||||||
const data = response.data
|
const data = response.data
|
||||||
|
|
||||||
if (data.position === -1) {
|
if (data.position === -1) {
|
||||||
appState.grid.weapons.mainWeapon = undefined
|
appState.party.grid.weapons.mainWeapon = null
|
||||||
} else {
|
} else {
|
||||||
appState.grid.weapons.allWeapons[response.data.position] = undefined
|
appState.party.grid.weapons.allWeapons[response.data.position] = null
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
@ -307,13 +319,13 @@ 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.party.grid.weapons.mainWeapon && position == -1)
|
||||||
appState.grid.weapons.mainWeapon.uncap_level = uncapLevel
|
appState.party.grid.weapons.mainWeapon.uncapLevel = uncapLevel
|
||||||
else {
|
else {
|
||||||
const weapon = appState.grid.weapons.allWeapons[position]
|
const weapon = appState.party.grid.weapons.allWeapons[position]
|
||||||
if (weapon) {
|
if (weapon) {
|
||||||
weapon.uncap_level = uncapLevel
|
weapon.uncapLevel = uncapLevel
|
||||||
appState.grid.weapons.allWeapons[position] = weapon
|
appState.party.grid.weapons.allWeapons[position] = weapon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -322,12 +334,13 @@ const WeaponGrid = (props: Props) => {
|
||||||
// Save the current value in case of an unexpected result
|
// Save the current value in case of an unexpected result
|
||||||
let newPreviousValues = { ...previousUncapValues }
|
let newPreviousValues = { ...previousUncapValues }
|
||||||
|
|
||||||
if (appState.grid.weapons.mainWeapon && position == -1) {
|
if (appState.party.grid.weapons.mainWeapon && position == -1) {
|
||||||
newPreviousValues[position] = appState.grid.weapons.mainWeapon.uncap_level
|
newPreviousValues[position] =
|
||||||
|
appState.party.grid.weapons.mainWeapon.uncapLevel
|
||||||
} else {
|
} else {
|
||||||
const weapon = appState.grid.weapons.allWeapons[position]
|
const weapon = appState.party.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,13 +352,13 @@ 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
|
||||||
const mainhandElement = (
|
const mainhandElement = (
|
||||||
<WeaponUnit
|
<WeaponUnit
|
||||||
gridWeapon={appState.grid.weapons.mainWeapon}
|
gridWeapon={appState.party.grid.weapons.mainWeapon}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
key="grid_mainhand"
|
key="grid_mainhand"
|
||||||
position={-1}
|
position={-1}
|
||||||
|
|
@ -358,13 +371,13 @@ const WeaponGrid = (props: Props) => {
|
||||||
|
|
||||||
const weaponGridElement = Array.from(Array(numWeapons)).map((x, i) => {
|
const weaponGridElement = Array.from(Array(numWeapons)).map((x, i) => {
|
||||||
const itemClasses = classNames({
|
const itemClasses = classNames({
|
||||||
Empty: appState.grid.weapons.allWeapons[i] === undefined,
|
Empty: appState.party.grid.weapons.allWeapons[i] === undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className={itemClasses} key={`grid_unit_${i}`}>
|
<li className={itemClasses} key={`grid_unit_${i}`}>
|
||||||
<WeaponUnit
|
<WeaponUnit
|
||||||
gridWeapon={appState.grid.weapons.allWeapons[i]}
|
gridWeapon={party.grid.weapons.allWeapons[i]}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
position={i}
|
position={i}
|
||||||
unitType={1}
|
unitType={1}
|
||||||
|
|
@ -377,13 +390,13 @@ const WeaponGrid = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const extraElement = () => {
|
const extraElement = () => {
|
||||||
if (appState.party.raid && appState.party.raid.group.extra) {
|
if (appState.party.raid && appState.party.raid.group?.extra) {
|
||||||
return (
|
return (
|
||||||
<ExtraContainer>
|
<ExtraContainer>
|
||||||
<ExtraContainerItem title={t('extra_weapons')} className="weapons">
|
<ExtraContainerItem title={t('extra_weapons')} className="weapons">
|
||||||
{appState.party.raid && appState.party.raid.group.extra && (
|
{appState.party.raid && appState.party.raid.group.extra && (
|
||||||
<ExtraWeaponsGrid
|
<ExtraWeaponsGrid
|
||||||
grid={appState.grid.weapons.allWeapons}
|
grid={appState.party.grid.weapons.allWeapons}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
offset={numWeapons}
|
offset={numWeapons}
|
||||||
removeWeapon={removeWeapon}
|
removeWeapon={removeWeapon}
|
||||||
|
|
@ -411,30 +424,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')}
|
||||||
) : (
|
/>
|
||||||
''
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,14 @@ 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'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
gridWeapon: GridWeapon | undefined
|
gridWeapon: GridWeapon | null
|
||||||
unitType: 0 | 1
|
unitType: 0 | 1
|
||||||
position: number
|
position: number
|
||||||
editable: boolean
|
editable: boolean
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
154
data/ax.tsx
154
data/ax.tsx
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
14
package-lock.json
generated
14
package-lock.json
generated
|
|
@ -23,6 +23,7 @@
|
||||||
"@tiptap/extension-highlight": "^2.0.3",
|
"@tiptap/extension-highlight": "^2.0.3",
|
||||||
"@tiptap/extension-link": "^2.0.3",
|
"@tiptap/extension-link": "^2.0.3",
|
||||||
"@tiptap/extension-mention": "^2.0.3",
|
"@tiptap/extension-mention": "^2.0.3",
|
||||||
|
"@tiptap/extension-placeholder": "^2.0.3",
|
||||||
"@tiptap/extension-typography": "^2.0.3",
|
"@tiptap/extension-typography": "^2.0.3",
|
||||||
"@tiptap/extension-youtube": "^2.0.3",
|
"@tiptap/extension-youtube": "^2.0.3",
|
||||||
"@tiptap/pm": "^2.0.3",
|
"@tiptap/pm": "^2.0.3",
|
||||||
|
|
@ -7348,6 +7349,19 @@
|
||||||
"@tiptap/core": "^2.0.0"
|
"@tiptap/core": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tiptap/extension-placeholder": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-Z42jo0termRAf0S0L8oxrts94IWX5waU4isS2CUw8xCUigYyCFslkhQXkWATO1qRbjNFLKN2C9qvCgGf4UeBrw==",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ueberdosis"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@tiptap/core": "^2.0.0",
|
||||||
|
"@tiptap/pm": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tiptap/extension-strike": {
|
"node_modules/@tiptap/extension-strike": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
"@tiptap/extension-highlight": "^2.0.3",
|
"@tiptap/extension-highlight": "^2.0.3",
|
||||||
"@tiptap/extension-link": "^2.0.3",
|
"@tiptap/extension-link": "^2.0.3",
|
||||||
"@tiptap/extension-mention": "^2.0.3",
|
"@tiptap/extension-mention": "^2.0.3",
|
||||||
|
"@tiptap/extension-placeholder": "^2.0.3",
|
||||||
"@tiptap/extension-typography": "^2.0.3",
|
"@tiptap/extension-typography": "^2.0.3",
|
||||||
"@tiptap/extension-youtube": "^2.0.3",
|
"@tiptap/extension-youtube": "^2.0.3",
|
||||||
"@tiptap/pm": "^2.0.3",
|
"@tiptap/pm": "^2.0.3",
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { appWithTranslation } from 'next-i18next'
|
import { appWithTranslation } from 'next-i18next'
|
||||||
|
import Head from 'next/head'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { get } from 'local-storage'
|
import { get } from 'local-storage'
|
||||||
|
|
@ -131,20 +132,28 @@ function MyApp({ Component, pageProps }: AppProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider>
|
<>
|
||||||
<ToastProvider swipeDirection="right">
|
<Head>
|
||||||
<TooltipProvider>
|
<meta
|
||||||
<Layout>
|
name="viewport"
|
||||||
{!appState.version ? (
|
content="viewport-fit=cover, width=device-width, initial-scale=1.0"
|
||||||
serverUnavailable()
|
/>
|
||||||
) : (
|
</Head>
|
||||||
<Component {...pageProps} />
|
<ThemeProvider>
|
||||||
)}
|
<ToastProvider swipeDirection="right">
|
||||||
</Layout>
|
<TooltipProvider>
|
||||||
<Viewport className="ToastViewport" />
|
<Layout>
|
||||||
</TooltipProvider>
|
{!appState.version ? (
|
||||||
</ToastProvider>
|
serverUnavailable()
|
||||||
</ThemeProvider>
|
) : (
|
||||||
|
<Component {...pageProps} />
|
||||||
|
)}
|
||||||
|
</Layout>
|
||||||
|
<Viewport className="ToastViewport" />
|
||||||
|
</TooltipProvider>
|
||||||
|
</ToastProvider>
|
||||||
|
</ThemeProvider>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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/JobSkillTransformer'
|
||||||
|
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'
|
||||||
|
|
@ -90,8 +96,8 @@ const PartyRoute: React.FC<Props> = ({
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (router.asPath !== '/new' && router.asPath !== '/')
|
// if (router.asPath !== '/new' && router.asPath !== '/')
|
||||||
router.replace(path, undefined, { shallow: true })
|
// router.replace(path, undefined, { shallow: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the initial data from props
|
// Set the initial data from props
|
||||||
|
|
@ -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,34 +162,43 @@ 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({
|
|
||||||
id: query.party,
|
|
||||||
})
|
|
||||||
party = response.data.party
|
|
||||||
} else {
|
|
||||||
console.error('No party code')
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const party: Party | undefined = await api.endpoints.parties.getOne({
|
||||||
|
id: query.party,
|
||||||
|
}).then((response) =>
|
||||||
|
PartyTransformer.toObject(response.data.party)
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(party)
|
||||||
|
|
||||||
// Consolidate data into context object
|
// Consolidate data into context object
|
||||||
const context: PageContextObj = {
|
const context: PageContextObj = {
|
||||||
party: party,
|
party: party,
|
||||||
|
|
@ -206,6 +221,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
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -557,6 +557,19 @@
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"remix": "Remixed"
|
"remix": "Remixed"
|
||||||
},
|
},
|
||||||
|
"toolbar": {
|
||||||
|
"tooltips": {
|
||||||
|
"bold": "Bold",
|
||||||
|
"italic": "Italic",
|
||||||
|
"strike": "Strikethrough",
|
||||||
|
"highlight": "Highlight",
|
||||||
|
"link": "Add a link",
|
||||||
|
"youtube": "Add a Youtube video",
|
||||||
|
"heading": "Heading {{level}}",
|
||||||
|
"bulletList": "Bullet list",
|
||||||
|
"orderedList": "Numbered list"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"copy_url": "Copy the URL to this team",
|
"copy_url": "Copy the URL to this team",
|
||||||
"new": "Create a new team",
|
"new": "Create a new team",
|
||||||
|
|
|
||||||
|
|
@ -555,6 +555,19 @@
|
||||||
"tokens": {
|
"tokens": {
|
||||||
"remix": "リミックスされた"
|
"remix": "リミックスされた"
|
||||||
},
|
},
|
||||||
|
"toolbar": {
|
||||||
|
"tooltips": {
|
||||||
|
"bold": "太字",
|
||||||
|
"italic": "斜体",
|
||||||
|
"strike": "取り消し線",
|
||||||
|
"highlight": "ハイライト",
|
||||||
|
"link": "リンクを挿入",
|
||||||
|
"youtube": "Youtube動画を埋め込む",
|
||||||
|
"heading": "見出し {{level}}",
|
||||||
|
"bulletList": "箇条書き",
|
||||||
|
"orderedList": "番号リスト"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"copy_url": "この編成のURLをコピーする",
|
"copy_url": "この編成のURLをコピーする",
|
||||||
"new": "新しい編成を作成する",
|
"new": "新しい編成を作成する",
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,14 @@
|
||||||
--grid-border-color: #{$grid--border--color--light};
|
--grid-border-color: #{$grid--border--color--light};
|
||||||
|
|
||||||
// Light - Element theming
|
// Light - Element theming
|
||||||
|
--null-bg: #{$null--bg--light};
|
||||||
|
--null-bg-hover: #{$null--bg--hover--light};
|
||||||
|
--null-text: #{$null--text--light};
|
||||||
|
--null-raid-text: #{$null--text--raid--light};
|
||||||
|
--null-text-hover: #{$null--text--hover--light};
|
||||||
|
--null-shadow: #{$null--shadow--light};
|
||||||
|
--null-shadow-hover: #{$null--shadow--light--hover};
|
||||||
|
|
||||||
--wind-bg: #{$wind--bg--light};
|
--wind-bg: #{$wind--bg--light};
|
||||||
--wind-bg-hover: #{$wind--bg--hover--light};
|
--wind-bg-hover: #{$wind--bg--hover--light};
|
||||||
--wind-text: #{$wind--text--light};
|
--wind-text: #{$wind--text--light};
|
||||||
|
|
@ -373,6 +381,14 @@
|
||||||
--grid-border-color: #{$grid--border--color--dark};
|
--grid-border-color: #{$grid--border--color--dark};
|
||||||
|
|
||||||
// Dark - Element theming
|
// Dark - Element theming
|
||||||
|
--null-bg: #{$null--bg--dark};
|
||||||
|
--null-bg-hover: #{$null--bg--hover--dark};
|
||||||
|
--null-text: #{$null--text--dark};
|
||||||
|
--null-raid-text: #{$null--text--raid--dark};
|
||||||
|
--null-text-hover: #{$null--text--hover--dark};
|
||||||
|
--null-shadow: #{$null--shadow--dark};
|
||||||
|
--null-shadow-hover: #{$null--shadow--dark--hover};
|
||||||
|
|
||||||
--wind-bg: #{$wind--bg--dark};
|
--wind-bg: #{$wind--bg--dark};
|
||||||
--wind-bg-hover: #{$wind--bg--hover--dark};
|
--wind-bg-hover: #{$wind--bg--hover--dark};
|
||||||
--wind-text: #{$wind--text--dark};
|
--wind-text: #{$wind--text--dark};
|
||||||
|
|
|
||||||
|
|
@ -464,6 +464,28 @@ $wind--shadow--dark: fade-out($wind-text-20, 0.3);
|
||||||
$wind--shadow--light--hover: fade-out($wind-text-00, 0.3);
|
$wind--shadow--light--hover: fade-out($wind-text-00, 0.3);
|
||||||
$wind--shadow--dark--hover: fade-out($wind-text-00, 0.3);
|
$wind--shadow--dark--hover: fade-out($wind-text-00, 0.3);
|
||||||
|
|
||||||
|
// Color Definitions: Element / Null
|
||||||
|
$null--bg--light: $grey-75;
|
||||||
|
$null--bg--dark: $grey-40;
|
||||||
|
|
||||||
|
$null--bg--hover--light: $grey-70;
|
||||||
|
$null--bg--hover--dark: $grey-30;
|
||||||
|
|
||||||
|
$null--text--light: $grey-40;
|
||||||
|
$null--text--dark: $grey-90;
|
||||||
|
|
||||||
|
$null--text--raid--light: $grey-40;
|
||||||
|
$null--text--raid--dark: $grey-90;
|
||||||
|
|
||||||
|
$null--text--hover--light: $grey-20;
|
||||||
|
$null--text--hover--dark: $grey-90;
|
||||||
|
|
||||||
|
$null--shadow--light: fade-out($grey-60, 0.3);
|
||||||
|
$null--shadow--dark: fade-out($grey-25, 0.3);
|
||||||
|
|
||||||
|
$null--shadow--light--hover: fade-out($grey-50, 0.3);
|
||||||
|
$null--shadow--dark--hover: fade-out($grey-10, 0.3);
|
||||||
|
|
||||||
// Color Definitions: Element / Fire
|
// Color Definitions: Element / Fire
|
||||||
$fire--bg--light: $fire-bg-10;
|
$fire--bg--light: $fire-bg-10;
|
||||||
$fire--bg--dark: $fire-bg-10;
|
$fire--bg--dark: $fire-bg-10;
|
||||||
|
|
|
||||||
13
transformers/AwakeningTransformer.tsx
Normal file
13
transformers/AwakeningTransformer.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Transforms API response to Awakening object
|
||||||
|
export function toObject(data: any): Awakening {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
name: {
|
||||||
|
en: data.name.en,
|
||||||
|
ja: data.name.ja,
|
||||||
|
},
|
||||||
|
slug: data.slug,
|
||||||
|
object_type: data.object_type,
|
||||||
|
order: data.order,
|
||||||
|
}
|
||||||
|
}
|
||||||
41
transformers/CharacterTransformer.tsx
Normal file
41
transformers/CharacterTransformer.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import * as Awakening from './AwakeningTransformer'
|
||||||
|
import * as Element from './ElementTransformer'
|
||||||
|
|
||||||
|
// Transforms API response to Character object
|
||||||
|
export function toObject(data: any): Character {
|
||||||
|
return {
|
||||||
|
type: 'character',
|
||||||
|
id: data.id,
|
||||||
|
granblueId: data.granblue_id,
|
||||||
|
characterId: data.character_id,
|
||||||
|
name: {
|
||||||
|
en: data.name.en,
|
||||||
|
ja: data.name.ja,
|
||||||
|
},
|
||||||
|
element: Element.toObject(data.element),
|
||||||
|
rarity: data.rarity,
|
||||||
|
proficiency: data.proficiency,
|
||||||
|
gender: data.gender,
|
||||||
|
race: data.race,
|
||||||
|
hp: {
|
||||||
|
min: data.hp.min_hp,
|
||||||
|
max: data.hp.max_hp,
|
||||||
|
flb: data.hp.max_hp_flb ? data.hp.max_hp_flb : null,
|
||||||
|
ulb: data.hp.max_hp_ulb ? data.hp.max_hp_ulb : null,
|
||||||
|
},
|
||||||
|
atk: {
|
||||||
|
min: data.atk.min_atk,
|
||||||
|
max: data.atk.max_atk,
|
||||||
|
flb: data.atk.max_atk_flb ? data.atk.max_atk_flb : null,
|
||||||
|
ulb: data.atk.max_atk_ulb ? data.atk.max_atk_ulb : null,
|
||||||
|
},
|
||||||
|
uncap: {
|
||||||
|
flb: data.uncap.flb,
|
||||||
|
ulb: data.uncap.ulb,
|
||||||
|
},
|
||||||
|
awakenings: data.awakenings.map((awakening: any) =>
|
||||||
|
Awakening.toObject(awakening)
|
||||||
|
),
|
||||||
|
special: data.special,
|
||||||
|
}
|
||||||
|
}
|
||||||
9
transformers/ElementTransformer.tsx
Normal file
9
transformers/ElementTransformer.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { elements } from '../utils/elements'
|
||||||
|
|
||||||
|
export function toObject(value: number) {
|
||||||
|
return elements.find((element) => element.id === value) || elements[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toParam(value: string) {
|
||||||
|
return elements.find((element) => element.name.en === value)
|
||||||
|
}
|
||||||
53
transformers/GridCharacterTransformer.tsx
Normal file
53
transformers/GridCharacterTransformer.tsx
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import * as Awakening from './AwakeningTransformer'
|
||||||
|
import * as Character from './CharacterTransformer'
|
||||||
|
|
||||||
|
// Transforms API response to GridCharacter object
|
||||||
|
export function toObject(data: any): GridCharacter {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
object: Character.toObject(data.object),
|
||||||
|
position: data.position,
|
||||||
|
uncapLevel: data.uncap_level,
|
||||||
|
transcendenceStep: data.transcendence_step ? data.transcendence_step : null,
|
||||||
|
mastery: {
|
||||||
|
overMastery: data.over_mastery
|
||||||
|
? data.over_mastery
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
modifier: 1,
|
||||||
|
strength: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
modifier: 2,
|
||||||
|
strength: 0,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
],
|
||||||
|
aetherialMastery: data.aetherial_mastery ? data.aetherial_mastery : null,
|
||||||
|
awakening: {
|
||||||
|
type: Awakening.toObject(data.awakening.type),
|
||||||
|
level: data.awakening.level,
|
||||||
|
},
|
||||||
|
perpetuity: data.perpetuity,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transforms User object into API parameters
|
||||||
|
export function toParams(data: GridCharacter): GridCharacterParams {
|
||||||
|
return {
|
||||||
|
character_id: data.id,
|
||||||
|
position: data.position,
|
||||||
|
uncapLevel: data.uncapLevel,
|
||||||
|
transcendence_step: data.transcendenceStep,
|
||||||
|
ring1: data.mastery.overMastery[1],
|
||||||
|
ring2: data.mastery.overMastery[2],
|
||||||
|
ring3: data.mastery.overMastery[3],
|
||||||
|
ring4: data.mastery.overMastery[4],
|
||||||
|
earring: data.mastery.aetherialMastery,
|
||||||
|
awakening_id: data.mastery.awakening.type.id,
|
||||||
|
awakening_level: data.mastery.awakening.level,
|
||||||
|
perpetuity: data.mastery.perpetuity,
|
||||||
|
}
|
||||||
|
}
|
||||||
26
transformers/GridSummonTransformer.tsx
Normal file
26
transformers/GridSummonTransformer.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import * as Summon from './SummonTransformer'
|
||||||
|
|
||||||
|
// Transforms API response to GridSummon object
|
||||||
|
export function toObject(data: any): GridSummon {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
object: Summon.toObject(data.object),
|
||||||
|
position: data.position,
|
||||||
|
main: data.main,
|
||||||
|
friend: data.friend,
|
||||||
|
uncapLevel: data.uncap_level,
|
||||||
|
transcendenceStep: data.transcendence_step ? data.transcendence_step : null,
|
||||||
|
quickSummon: data.quick_summon,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transforms User object into API parameters
|
||||||
|
export function toParams(data: GridSummon): GridSummonParams {
|
||||||
|
return {
|
||||||
|
summon_id: data.id,
|
||||||
|
position: data.position,
|
||||||
|
uncapLevel: data.uncapLevel,
|
||||||
|
transcendence_step: data.transcendenceStep,
|
||||||
|
quick_summon: data.quickSummon,
|
||||||
|
}
|
||||||
|
}
|
||||||
64
transformers/GridTransformer.tsx
Normal file
64
transformers/GridTransformer.tsx
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
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 {
|
||||||
|
console.log('----- GridTransformer.tsx -----')
|
||||||
|
console.log(data.summons, data.characters)
|
||||||
|
console.log('----- End GridTransformer.tsx -----')
|
||||||
|
|
||||||
|
const mainSummon = data.summons
|
||||||
|
? data.summons.find((summon: any) => summon.main === true)
|
||||||
|
: null
|
||||||
|
const friendSummon = data.summons
|
||||||
|
? data.summons.find((summon: any) => summon.friend === true)
|
||||||
|
: null
|
||||||
|
const allSummons = data.summons
|
||||||
|
? removeItem(data.summons, [mainSummon, friendSummon])
|
||||||
|
: null
|
||||||
|
|
||||||
|
const mainWeapon = data.weapons
|
||||||
|
? data.weapons.find((weapon: any) => weapon.mainhand === true)
|
||||||
|
: null
|
||||||
|
|
||||||
|
return {
|
||||||
|
characters: data.characters
|
||||||
|
? mapToGridArrayWithTransformer(data.characters, GridCharacter.toObject)
|
||||||
|
: null,
|
||||||
|
summons: {
|
||||||
|
mainSummon: mainSummon ? GridSummon.toObject(mainSummon) : null,
|
||||||
|
friendSummon: friendSummon ? GridSummon.toObject(friendSummon) : null,
|
||||||
|
allSummons: allSummons
|
||||||
|
? mapToGridArrayWithTransformer(allSummons, GridSummon.toObject)
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
weapons: {
|
||||||
|
mainWeapon: mainWeapon ? GridWeapon.toObject(mainWeapon) : null,
|
||||||
|
allWeapons: data.weapons
|
||||||
|
? mapToGridArrayWithTransformer(data.weapons, GridWeapon.toObject)
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeItem<T>(arr: Array<T>, values: T[]): Array<T> {
|
||||||
|
values.forEach((value) => {
|
||||||
|
const index = arr.indexOf(value)
|
||||||
|
if (index > -1) {
|
||||||
|
arr.splice(index, 1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapToGridArrayWithTransformer<T>(
|
||||||
|
arr: any[],
|
||||||
|
transformer: (data: any) => T
|
||||||
|
): GridArray<T> {
|
||||||
|
return arr.reduce(
|
||||||
|
(gridArray, item) => ({ ...gridArray, [item.position]: transformer(item) }),
|
||||||
|
{} as GridArray<T>
|
||||||
|
)
|
||||||
|
}
|
||||||
45
transformers/GridWeaponTransformer.tsx
Normal file
45
transformers/GridWeaponTransformer.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import * as Awakening from './AwakeningTransformer'
|
||||||
|
import * as Element from './ElementTransformer'
|
||||||
|
import * as Weapon from './WeaponTransformer'
|
||||||
|
import * as WeaponKey from './WeaponKeyTransformer'
|
||||||
|
|
||||||
|
// Transforms API response to GridWeapon object
|
||||||
|
export function toObject(data: any): GridWeapon {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
object: Weapon.toObject(data.object),
|
||||||
|
position: data.position,
|
||||||
|
mainhand: data.mainhand,
|
||||||
|
uncapLevel: data.uncap_level,
|
||||||
|
element: Element.toObject(data.element),
|
||||||
|
weaponKeys: data.weapon_keys
|
||||||
|
? data.weapon_keys.map((key: any) => WeaponKey.toObject(key))
|
||||||
|
: null,
|
||||||
|
ax: data.ax ? data.ax : null,
|
||||||
|
awakening: data.awakening
|
||||||
|
? {
|
||||||
|
type: Awakening.toObject(data.awakening.type),
|
||||||
|
level: data.awakening.awakening_level,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transforms User object into API parameters
|
||||||
|
export function toParams(data: GridWeapon): GridWeaponParams {
|
||||||
|
return {
|
||||||
|
weapon_id: data.id,
|
||||||
|
position: data.position,
|
||||||
|
uncapLevel: data.uncapLevel,
|
||||||
|
element: data.element.id,
|
||||||
|
weapon_key1_id: data.weaponKeys?.[0].id,
|
||||||
|
weapon_key2_id: data.weaponKeys?.[1].id,
|
||||||
|
weapon_key3_id: data.weaponKeys?.[2].id,
|
||||||
|
ax_modifier1: data.ax?.[0].modifier,
|
||||||
|
ax_modifier2: data.ax?.[1].modifier,
|
||||||
|
ax_strength1: data.ax?.[0].strength,
|
||||||
|
ax_strength2: data.ax?.[1].strength,
|
||||||
|
awakening_id: data.awakening?.type.id,
|
||||||
|
awakening_level: data.awakening?.level,
|
||||||
|
}
|
||||||
|
}
|
||||||
15
transformers/GuidebookTransformer.tsx
Normal file
15
transformers/GuidebookTransformer.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Transforms API response to Guidebook object
|
||||||
|
export function toObject(data: any): Guidebook {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
granblueId: data.granblue_id,
|
||||||
|
name: {
|
||||||
|
en: data.name.en,
|
||||||
|
ja: data.name.jp,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
en: data.description.en,
|
||||||
|
ja: data.description.jp,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
15
transformers/JobAccessoryTransformer.tsx
Normal file
15
transformers/JobAccessoryTransformer.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import * as Job from './JobTransformer'
|
||||||
|
|
||||||
|
// Transforms API response to JobAccessory object
|
||||||
|
export function toObject(data: any): JobAccessory {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
granblueId: data.granblue_id,
|
||||||
|
name: {
|
||||||
|
en: data.name.en,
|
||||||
|
ja: data.name.jp,
|
||||||
|
},
|
||||||
|
job: Job.toObject(data.job),
|
||||||
|
rarity: data.rarity,
|
||||||
|
}
|
||||||
|
}
|
||||||
20
transformers/JobSkillTransformer.tsx
Normal file
20
transformers/JobSkillTransformer.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import * as Job from './JobTransformer'
|
||||||
|
|
||||||
|
// Transforms API response to JobSkill object
|
||||||
|
export function toObject(data: any): JobSkill {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
name: {
|
||||||
|
en: data.name.en,
|
||||||
|
ja: data.name.ja,
|
||||||
|
},
|
||||||
|
job: Job.toObject(data.job),
|
||||||
|
slug: data.slug,
|
||||||
|
color: data.color,
|
||||||
|
main: data.main,
|
||||||
|
base: data.base,
|
||||||
|
sub: data.sub,
|
||||||
|
emp: data.emp,
|
||||||
|
order: data.order,
|
||||||
|
}
|
||||||
|
}
|
||||||
21
transformers/JobTransformer.tsx
Normal file
21
transformers/JobTransformer.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Transforms API response to Job object
|
||||||
|
export function toObject(data: any): Job {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
granblueId: data.granblue_id,
|
||||||
|
name: {
|
||||||
|
en: data.name.en,
|
||||||
|
ja: data.name.ja,
|
||||||
|
},
|
||||||
|
row: data.row,
|
||||||
|
order: data.order,
|
||||||
|
masterLevel: data.master_level,
|
||||||
|
ultimateMastery: data.ultimate_mastery,
|
||||||
|
proficiency: {
|
||||||
|
proficiency1: data.proficiency?.[0] ?? null,
|
||||||
|
proficiency2: data.proficiency?.[1] ?? null,
|
||||||
|
},
|
||||||
|
accessory: data.accessory,
|
||||||
|
accessory_type: data.accessory_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
94
transformers/PartyTransformer.tsx
Normal file
94
transformers/PartyTransformer.tsx
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
import * as Grid from './GridTransformer'
|
||||||
|
import * as Guidebook from './GuidebookTransformer'
|
||||||
|
import * as Job from './JobTransformer'
|
||||||
|
import * as JobAccessory from './JobAccessoryTransformer'
|
||||||
|
import * as JobSkill from './JobSkillTransformer'
|
||||||
|
import * as Raid from './RaidTransformer'
|
||||||
|
import * as User from './UserTransformer'
|
||||||
|
|
||||||
|
// Transforms API response to Party object
|
||||||
|
export function toObject(data: any): Party {
|
||||||
|
return {
|
||||||
|
id: data.id,
|
||||||
|
localId: data.local_id ? data.local_id : null,
|
||||||
|
editKey: data.edit_key ? data.edit_key : null,
|
||||||
|
name: data.name,
|
||||||
|
description: data.description ? data.description : null,
|
||||||
|
shortcode: data.shortcode,
|
||||||
|
user: data.user ? User.toObject(data.user) : null,
|
||||||
|
editable: data.editable ?? false,
|
||||||
|
grid: Grid.toObject({
|
||||||
|
characters: data.characters,
|
||||||
|
summons: data.summons,
|
||||||
|
weapons: data.weapons,
|
||||||
|
}),
|
||||||
|
details: {
|
||||||
|
extra: data.extra,
|
||||||
|
fullAuto: data.full_auto,
|
||||||
|
autoGuard: data.auto_guard,
|
||||||
|
autoSummon: data.auto_summon,
|
||||||
|
chargeAttack: data.charge_attack ? data.charge_attack : null,
|
||||||
|
clearTime: data.clear_time ? data.clear_time : null,
|
||||||
|
buttonCount: data.button_count ? data.button_count : null,
|
||||||
|
turnCount: data.turn_count ? data.turn_count : null,
|
||||||
|
chainCount: data.chain_count ? data.chain_count : null,
|
||||||
|
},
|
||||||
|
protagonist: {
|
||||||
|
job: data.job && Job.toObject(data.job),
|
||||||
|
skills: data.job_skills
|
||||||
|
? {
|
||||||
|
0: data.job_skills[0] && JobSkill.toObject(data.job_skills[0]),
|
||||||
|
1: data.job_skills[1] && JobSkill.toObject(data.job_skills[1]),
|
||||||
|
2: data.job_skills[2] && JobSkill.toObject(data.job_skills[2]),
|
||||||
|
3: data.job_skills[3] && JobSkill.toObject(data.job_skills[3]),
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
masterLevel: data.master_level ? data.master_level : null,
|
||||||
|
ultimateMastery: data.ultimate_mastery ? data.ultimate_mastery : null,
|
||||||
|
accessory: data.accessory ? JobAccessory.toObject(data.accessory) : null,
|
||||||
|
},
|
||||||
|
social: {
|
||||||
|
favorited: data.favorited,
|
||||||
|
remix: data.remix,
|
||||||
|
remixes: data.remixes
|
||||||
|
? data.remixes.map((remix: any) => toObject(remix))
|
||||||
|
: [],
|
||||||
|
sourceParty: data.source_party ? toObject(data.source_party) : null,
|
||||||
|
},
|
||||||
|
timestamps: {
|
||||||
|
createdAt: data.created_at,
|
||||||
|
updatedAt: data.updated_at,
|
||||||
|
},
|
||||||
|
raid: data.raid ? Raid.toObject(data.raid) : null,
|
||||||
|
guidebooks: {
|
||||||
|
0: data.guidebooks[1] && Guidebook.toObject(data.guidebooks[1]),
|
||||||
|
1: data.guidebooks[2] && Guidebook.toObject(data.guidebooks[2]),
|
||||||
|
2: data.guidebooks[3] && Guidebook.toObject(data.guidebooks[3]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transforms Party object into API parameters
|
||||||
|
export function toParams(party: Party): PartyParams {
|
||||||
|
return {
|
||||||
|
local_id: party.localId,
|
||||||
|
name: party.name,
|
||||||
|
description: party.description,
|
||||||
|
extra: party.details.extra,
|
||||||
|
full_auto: party.details.fullAuto,
|
||||||
|
auto_guard: party.details.autoGuard,
|
||||||
|
auto_summon: party.details.autoSummon,
|
||||||
|
charge_attack: party.details.chargeAttack,
|
||||||
|
clear_time: party.details.clearTime,
|
||||||
|
button_count: party.details.buttonCount,
|
||||||
|
turn_count: party.details.turnCount,
|
||||||
|
chain_count: party.details.chainCount,
|
||||||
|
raid_id: party.raid?.id,
|
||||||
|
job_id: party.protagonist.job?.id,
|
||||||
|
master_level: party.protagonist.masterLevel,
|
||||||
|
ultimate_mastery: party.protagonist.ultimateMastery,
|
||||||
|
guidebook1_id: party.guidebooks[0]?.id,
|
||||||
|
guidebook2_id: party.guidebooks[1]?.id,
|
||||||
|
guidebook3_id: party.guidebooks[2]?.id,
|
||||||
|
} as PartyParams
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue