Add interactive uncap indicators for summons

This commit is contained in:
Justin Edmund 2022-02-01 15:50:06 -08:00
parent 36ddc6e506
commit 44966fe8fe
6 changed files with 85 additions and 50 deletions

View file

@ -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>
)

View file

@ -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,

View file

@ -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}

View file

@ -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>

View file

@ -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

View file

@ -4,4 +4,5 @@ interface GridSummon {
friend: boolean
position: number | null
summon: Summon
uncap_level: number
}