Add interactive uncap indicators for summons
This commit is contained in:
parent
36ddc6e506
commit
44966fe8fe
6 changed files with 85 additions and 50 deletions
|
|
@ -12,12 +12,13 @@ export enum GridType {
|
|||
|
||||
// Props
|
||||
interface Props {
|
||||
grid: GridArray<Summon>
|
||||
grid: GridArray<GridSummon>
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
found?: boolean
|
||||
offset: number
|
||||
onClick: (position: number) => void
|
||||
updateUncap: (id: string, uncap: number) => void
|
||||
}
|
||||
|
||||
const ExtraSummons = (props: Props) => {
|
||||
|
|
@ -32,11 +33,12 @@ const ExtraSummons = (props: Props) => {
|
|||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<SummonUnit
|
||||
onClick={() => { props.onClick(props.offset + i) }}
|
||||
editable={props.editable}
|
||||
position={props.offset + i}
|
||||
unitType={1}
|
||||
summon={props.grid[props.offset + i]}
|
||||
gridSummon={props.grid[props.offset + i]}
|
||||
onClick={() => { props.onClick(props.offset + i) }}
|
||||
updateUncap={props.updateUncap}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ import './index.scss'
|
|||
interface Props {
|
||||
partyId?: string
|
||||
mainWeapon?: GridWeapon
|
||||
mainSummon?: Summon
|
||||
friendSummon?: Summon
|
||||
mainSummon?: GridSummon
|
||||
friendSummon?: GridSummon
|
||||
characters?: GridArray<Character>
|
||||
weapons?: GridArray<GridWeapon>
|
||||
summons?: GridArray<Summon>
|
||||
summons?: GridArray<GridSummon>
|
||||
extra: boolean
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
|
|
@ -47,11 +47,11 @@ const Party = (props: Props) => {
|
|||
// Grid data
|
||||
const [characters, setCharacters] = useState<GridArray<Character>>({})
|
||||
const [weapons, setWeapons] = useState<GridArray<GridWeapon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<Summon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<GridSummon>>({})
|
||||
|
||||
const [mainWeapon, setMainWeapon] = useState<GridWeapon>()
|
||||
const [mainSummon, setMainSummon] = useState<Summon>()
|
||||
const [friendSummon, setFriendSummon] = useState<Summon>()
|
||||
const [mainSummon, setMainSummon] = useState<GridSummon>()
|
||||
const [friendSummon, setFriendSummon] = useState<GridSummon>()
|
||||
|
||||
const [extra, setExtra] = useState<boolean>(false)
|
||||
|
||||
|
|
@ -185,8 +185,8 @@ const Party = (props: Props) => {
|
|||
case GridType.Summon:
|
||||
const summon = item as Summon
|
||||
saveSummon(summon, position, partyId)
|
||||
.then(() => {
|
||||
storeSummon(summon, position)
|
||||
.then((response) => {
|
||||
storeSummon(response.data.grid_summon, position)
|
||||
})
|
||||
break
|
||||
}
|
||||
|
|
@ -224,7 +224,7 @@ const Party = (props: Props) => {
|
|||
}
|
||||
|
||||
// Summons
|
||||
function storeSummon(summon: Summon, position: number) {
|
||||
function storeSummon(summon: GridSummon, position: number) {
|
||||
if (position == -1) {
|
||||
setMainSummon(summon)
|
||||
} else if (position == 6) {
|
||||
|
|
@ -238,7 +238,7 @@ const Party = (props: Props) => {
|
|||
}
|
||||
|
||||
async function saveSummon(summon: Summon, position: number, party: string) {
|
||||
await api.endpoints.summons.create({
|
||||
return await api.endpoints.summons.create({
|
||||
'summon': {
|
||||
'party_id': party,
|
||||
'summon_id': summon.id,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import React, { useState } from 'react'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { useModal as useModal } from '~utils/useModal'
|
||||
|
||||
import SearchModal from '~components/SearchModal'
|
||||
import ExtraSummons from '~components/ExtraSummons'
|
||||
import SummonUnit from '~components/SummonUnit'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import SearchModal from '~components/SearchModal'
|
||||
import SummonUnit from '~components/SummonUnit'
|
||||
import ExtraSummons from '~components/ExtraSummons'
|
||||
|
||||
import api from '~utils/api'
|
||||
import './index.scss'
|
||||
|
||||
// GridType
|
||||
|
|
@ -19,9 +22,9 @@ export enum GridType {
|
|||
interface Props {
|
||||
userId?: string
|
||||
partyId?: string
|
||||
main?: Summon | undefined
|
||||
friend?: Summon | undefined
|
||||
grid: GridArray<Summon>
|
||||
main?: GridSummon | undefined
|
||||
friend?: GridSummon | undefined
|
||||
grid: GridArray<GridSummon>
|
||||
editable: boolean
|
||||
exists: boolean
|
||||
found?: boolean
|
||||
|
|
@ -33,11 +36,7 @@ const SummonGrid = (props: Props) => {
|
|||
const [searchPosition, setSearchPosition] = useState(0)
|
||||
|
||||
const numSummons: number = 4
|
||||
|
||||
function openSearchModal(position: number) {
|
||||
setSearchPosition(position)
|
||||
openModal()
|
||||
}
|
||||
const searchGrid: GridArray<Summon> = Object.values(props.grid).map((o) => o.summon)
|
||||
|
||||
function receiveSummon(summon: Summon, position: number) {
|
||||
props.onSelect(GridType.Summon, summon, position)
|
||||
|
|
@ -54,30 +53,54 @@ const SummonGrid = (props: Props) => {
|
|||
return (object as Summon).granblue_id !== undefined
|
||||
}
|
||||
|
||||
function openSearchModal(position: number) {
|
||||
setSearchPosition(position)
|
||||
openModal()
|
||||
}
|
||||
|
||||
async function updateUncap(id: string, level: number) {
|
||||
await api.updateUncap('summon', id, level)
|
||||
.catch(error => {
|
||||
console.error(error)
|
||||
})
|
||||
}
|
||||
|
||||
const initiateUncapUpdate = (id: string, uncapLevel: number) => {
|
||||
debouncedAction(id, uncapLevel)
|
||||
}
|
||||
|
||||
const debouncedAction = useCallback(
|
||||
() => debounce((id, number) => {
|
||||
updateUncap(id, number)
|
||||
}, 1000), []
|
||||
)()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="SummonGrid">
|
||||
<div className="LabeledUnit">
|
||||
<div className="Label">Main Summon</div>
|
||||
<SummonUnit
|
||||
onClick={() => { openSearchModal(0) }}
|
||||
editable={props.editable}
|
||||
key="grid_main_summon"
|
||||
position={-1}
|
||||
unitType={0}
|
||||
summon={props.main}
|
||||
gridSummon={props.main}
|
||||
onClick={() => { openSearchModal(-1) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="LabeledUnit">
|
||||
<div className="Label">Friend Summon</div>
|
||||
<SummonUnit
|
||||
onClick={() => { openSearchModal(6) }}
|
||||
editable={props.editable}
|
||||
key="grid_friend_summon"
|
||||
position={6}
|
||||
unitType={2}
|
||||
summon={props.friend}
|
||||
gridSummon={props.friend}
|
||||
onClick={() => { openSearchModal(6) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -89,11 +112,12 @@ const SummonGrid = (props: Props) => {
|
|||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<SummonUnit
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
unitType={1}
|
||||
summon={props.grid[i]}
|
||||
gridSummon={props.grid[i]}
|
||||
onClick={() => { openSearchModal(i) }}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
|
|
@ -104,16 +128,17 @@ const SummonGrid = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<ExtraSummons
|
||||
onClick={openSearchModal}
|
||||
grid={props.grid}
|
||||
editable={props.editable}
|
||||
exists={false}
|
||||
offset={numSummons}
|
||||
onClick={openSearchModal}
|
||||
updateUncap={initiateUncapUpdate}
|
||||
/>
|
||||
|
||||
{open ? (
|
||||
<SearchModal
|
||||
grid={props.grid}
|
||||
grid={searchGrid}
|
||||
close={closeModal}
|
||||
send={sendData}
|
||||
fromPosition={searchPosition}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
import classnames from 'classnames'
|
||||
|
||||
import UncapIndicator from '~components/UncapIndicator'
|
||||
|
||||
import PlusIcon from '~public/icons/plus.svg'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
onClick: () => void
|
||||
summon: Summon | undefined
|
||||
updateUncap: (id: string, uncap: number) => void
|
||||
gridSummon: GridSummon | undefined
|
||||
position: number
|
||||
editable: boolean
|
||||
unitType: 0 | 1 | 2
|
||||
|
|
@ -25,10 +24,11 @@ const SummonUnit = (props: Props) => {
|
|||
'grid': props.unitType == 1,
|
||||
'friend': props.unitType == 2,
|
||||
'editable': props.editable,
|
||||
'filled': (props.summon !== undefined)
|
||||
'filled': (props.gridSummon !== undefined)
|
||||
})
|
||||
|
||||
const summon = props.summon
|
||||
const gridSummon = props.gridSummon
|
||||
const summon = gridSummon?.summon
|
||||
|
||||
useEffect(() => {
|
||||
generateImageUrl()
|
||||
|
|
@ -36,8 +36,8 @@ const SummonUnit = (props: Props) => {
|
|||
|
||||
function generateImageUrl() {
|
||||
let imgSrc = ""
|
||||
if (props.summon) {
|
||||
const summon = props.summon!
|
||||
if (props.gridSummon) {
|
||||
const summon = props.gridSummon.summon!
|
||||
|
||||
// Generate the correct source for the summon
|
||||
if (props.unitType == 0 || props.unitType == 2)
|
||||
|
|
@ -49,6 +49,11 @@ const SummonUnit = (props: Props) => {
|
|||
setImageUrl(imgSrc)
|
||||
}
|
||||
|
||||
function passUncapData(uncap: number) {
|
||||
if (props.gridSummon)
|
||||
props.updateUncap(props.gridSummon.id, uncap)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={classes}>
|
||||
|
|
@ -56,12 +61,14 @@ const SummonUnit = (props: Props) => {
|
|||
<img alt={summon?.name.en} className="grid_image" src={imageUrl} />
|
||||
{ (props.editable) ? <span className='icon'><PlusIcon /></span> : '' }
|
||||
</div>
|
||||
{ (gridSummon) ?
|
||||
<UncapIndicator
|
||||
type="summon"
|
||||
ulb={summon?.uncap.ulb || false}
|
||||
ulb={summon?.uncap.ulb || false}
|
||||
flb={summon?.uncap.flb || false}
|
||||
uncapLevel={3}
|
||||
/>
|
||||
uncapLevel={gridSummon?.uncap_level}
|
||||
updateUncap={passUncapData}
|
||||
/> : '' }
|
||||
<h3 className="SummonName">{summon?.name.en}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ const PartyRoute: React.FC = () => {
|
|||
|
||||
const [characters, setCharacters] = useState<GridArray<Character>>({})
|
||||
const [weapons, setWeapons] = useState<GridArray<GridWeapon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<Summon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<GridSummon>>({})
|
||||
|
||||
const [mainWeapon, setMainWeapon] = useState<GridWeapon>()
|
||||
const [mainSummon, setMainSummon] = useState<Summon>()
|
||||
const [friendSummon, setFriendSummon] = useState<Summon>()
|
||||
const [mainSummon, setMainSummon] = useState<GridSummon>()
|
||||
const [friendSummon, setFriendSummon] = useState<GridSummon>()
|
||||
|
||||
const [partyId, setPartyId] = useState('')
|
||||
const [extra, setExtra] = useState<boolean>(false)
|
||||
|
|
@ -97,15 +97,15 @@ const PartyRoute: React.FC = () => {
|
|||
}
|
||||
|
||||
function populateSummons(list: [GridSummon]) {
|
||||
let summons: GridArray<Summon> = {}
|
||||
let summons: GridArray<GridSummon> = {}
|
||||
|
||||
list.forEach((object: GridSummon) => {
|
||||
if (object.main)
|
||||
setMainSummon(object.summon)
|
||||
setMainSummon(object)
|
||||
else if (object.friend)
|
||||
setFriendSummon(object.summon)
|
||||
setFriendSummon(object)
|
||||
else if (!object.main && !object.friend && object.position != null)
|
||||
summons[object.position] = object.summon
|
||||
summons[object.position] = object
|
||||
})
|
||||
|
||||
return summons
|
||||
|
|
|
|||
1
types/GridSummon.d.ts
vendored
1
types/GridSummon.d.ts
vendored
|
|
@ -4,4 +4,5 @@ interface GridSummon {
|
|||
friend: boolean
|
||||
position: number | null
|
||||
summon: Summon
|
||||
uncap_level: number
|
||||
}
|
||||
Loading…
Reference in a new issue