Fix typings and output with remixes
This commit is contained in:
parent
d0535d6031
commit
973e7f34da
22 changed files with 246 additions and 207 deletions
|
|
@ -20,12 +20,12 @@ interface Props {
|
|||
shortcode: string
|
||||
id: string
|
||||
name: string
|
||||
raid?: Raid
|
||||
raid: Raid | null
|
||||
weapons: {
|
||||
mainWeapon?: GridWeapon
|
||||
allWeapons: GridArray<GridWeapon>
|
||||
}
|
||||
user?: User
|
||||
mainWeapon: GridWeapon | null
|
||||
allWeapons: GridArray<GridWeapon> | null
|
||||
} | null
|
||||
user: User | null
|
||||
fullAuto: boolean
|
||||
autoGuard: boolean
|
||||
favorited: boolean
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ import type { DetailsObject, JobSkillObject, SearchableObject } from '~types'
|
|||
|
||||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import * as CharacterTransformer from '~transformers/CharacterTransformer'
|
||||
import * as GridCharacterTransformer from '~transformers/GridCharacterTransformer'
|
||||
|
||||
import styles from './index.module.scss'
|
||||
|
||||
|
|
@ -121,8 +123,10 @@ const CharacterGrid = (props: Props) => {
|
|||
|
||||
async function handleCharacterResponse(data: any) {
|
||||
if (data.hasOwnProperty('conflicts')) {
|
||||
setIncoming(data.incoming)
|
||||
setConflicts(data.conflicts)
|
||||
setIncoming(CharacterTransformer.toObject(data.incoming))
|
||||
setConflicts(
|
||||
data.conflicts.map((c: any) => GridCharacterTransformer.toObject(c))
|
||||
)
|
||||
setPosition(data.position)
|
||||
setModalOpen(true)
|
||||
} else {
|
||||
|
|
@ -145,7 +149,8 @@ const CharacterGrid = (props: Props) => {
|
|||
})
|
||||
}
|
||||
|
||||
function storeGridCharacter(gridCharacter: GridCharacter) {
|
||||
function storeGridCharacter(data: any) {
|
||||
const gridCharacter = GridCharacterTransformer.toObject(data)
|
||||
appState.party.grid.characters[gridCharacter.position] = gridCharacter
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +169,7 @@ const CharacterGrid = (props: Props) => {
|
|||
|
||||
// Remove conflicting characters from state
|
||||
conflicts.forEach(
|
||||
(c) => (appState.party.grid.characters[c.position] = undefined)
|
||||
(c) => (appState.party.grid.characters[c.position] = null)
|
||||
)
|
||||
|
||||
// Reset conflict
|
||||
|
|
@ -186,7 +191,7 @@ const CharacterGrid = (props: Props) => {
|
|||
async function removeCharacter(id: string) {
|
||||
try {
|
||||
const response = await api.endpoints.grid_characters.destroy({ id: id })
|
||||
appState.party.grid.characters[response.data.position] = undefined
|
||||
appState.party.grid.characters[response.data.position] = null
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ const CharacterResult = (props: Props) => {
|
|||
flb={character.uncap.flb}
|
||||
ulb={character.uncap.ulb}
|
||||
special={character.special}
|
||||
transcendenceStage={character.uncap.ulb ? 5 : 0}
|
||||
/>
|
||||
<div className={styles.tags}>
|
||||
<WeaponLabelIcon labelType={character.element.slug} />
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import UncapIndicator from '~components/uncap/UncapIndicator'
|
|||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import { ElementMap } from '~utils/elements'
|
||||
import * as GridCharacterTransformer from '~transformers/GridCharacterTransformer'
|
||||
|
||||
import PlusIcon from '~public/icons/Add.svg'
|
||||
import SettingsIcon from '~public/icons/Settings.svg'
|
||||
|
|
@ -37,7 +38,7 @@ import type {
|
|||
import styles from './index.module.scss'
|
||||
|
||||
interface Props {
|
||||
gridCharacter?: GridCharacter
|
||||
gridCharacter: GridCharacter | null
|
||||
position: number
|
||||
editable: boolean
|
||||
removeCharacter: (id: string) => void
|
||||
|
|
@ -145,7 +146,9 @@ const CharacterUnit = ({
|
|||
|
||||
// Save the server's response to state
|
||||
function processResult(response: AxiosResponse) {
|
||||
const gridCharacter: GridCharacter = response.data
|
||||
const gridCharacter: GridCharacter = GridCharacterTransformer.toObject(
|
||||
response.data
|
||||
)
|
||||
let character = cloneDeep(gridCharacter)
|
||||
|
||||
if (character.mastery.overMastery) {
|
||||
|
|
@ -159,7 +162,7 @@ const CharacterUnit = ({
|
|||
character.mastery.overMastery = overMastery
|
||||
}
|
||||
|
||||
appState.grid.characters[gridCharacter.position] = character
|
||||
appState.party.grid.characters[gridCharacter.position] = character
|
||||
}
|
||||
|
||||
function processError(error: any) {
|
||||
|
|
@ -188,7 +191,11 @@ const CharacterUnit = ({
|
|||
|
||||
// Change the image based on the uncap level
|
||||
let suffix = '01'
|
||||
if (gridCharacter.transcendenceStep > 0) suffix = '04'
|
||||
if (
|
||||
gridCharacter.transcendenceStep &&
|
||||
gridCharacter.transcendenceStep > 0
|
||||
)
|
||||
suffix = '04'
|
||||
else if (gridCharacter.uncapLevel >= 5) suffix = '03'
|
||||
else if (gridCharacter.uncapLevel > 2) suffix = '02'
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { accountState } from '~utils/accountState'
|
|||
import { appState, initialAppState } from '~utils/appState'
|
||||
import { getLocalId } from '~utils/localId'
|
||||
import { GridType } from '~utils/enums'
|
||||
import * as PartyTransformer from '~transformers/PartyTransformer'
|
||||
import { retrieveCookies } from '~utils/retrieveCookies'
|
||||
import { setEditKey, storeEditKey, unsetEditKey } from '~utils/userToken'
|
||||
|
||||
|
|
@ -220,11 +221,11 @@ const Party = (props: Props) => {
|
|||
api
|
||||
.remix({ shortcode: props.party.shortcode, body: body })
|
||||
.then((response) => {
|
||||
const remix = response.data.party
|
||||
const remix = PartyTransformer.toObject(response.data.party)
|
||||
|
||||
// Store the edit key in local storage
|
||||
if (remix.edit_key) {
|
||||
storeEditKey(remix.id, remix.edit_key)
|
||||
if (remix.editKey) {
|
||||
storeEditKey(remix.id, remix.editKey)
|
||||
setEditKey(remix.id, remix.user)
|
||||
}
|
||||
|
||||
|
|
@ -275,30 +276,31 @@ const Party = (props: Props) => {
|
|||
appState.party.protagonist.ultimateMastery =
|
||||
team.protagonist.ultimate_mastery
|
||||
appState.party.details.chargeAttack = team.charge_attack
|
||||
appState.party.details.fullAuto = team.full_auto
|
||||
appState.party.details.autoGuard = team.auto_guard
|
||||
appState.party.details.autoSummon = team.auto_summon
|
||||
appState.party.details.clearTime = team.clear_time
|
||||
appState.party.details.fullAuto = team.details.full_auto
|
||||
appState.party.details.autoGuard = team.details.auto_guard
|
||||
appState.party.details.autoSummon = team.details.auto_summon
|
||||
appState.party.details.clearTime = team.details.clear_time
|
||||
appState.party.details.buttonCount =
|
||||
team.button_count !== null ? team.button_count : undefined
|
||||
team.details.button_count !== null ? team.details.button_count : undefined
|
||||
appState.party.details.chainCount =
|
||||
team.chain_count !== null ? team.chain_count : undefined
|
||||
team.details.chain_count !== null ? team.details.chain_count : undefined
|
||||
appState.party.details.turnCount =
|
||||
team.turn_count !== null ? team.turn_count : undefined
|
||||
team.details.turn_count !== null ? team.details.turn_count : undefined
|
||||
|
||||
appState.party.id = team.id
|
||||
appState.party.shortcode = team.shortcode
|
||||
appState.party.details.extra = team.extra
|
||||
appState.party.details.extra = team.details.extra
|
||||
appState.party.guidebooks = team.guidebooks
|
||||
appState.party.user = team.user
|
||||
appState.party.social.favorited = team.favorited
|
||||
appState.party.social.remix = team.remix
|
||||
appState.party.social.remixes = team.remixes
|
||||
appState.party.social.sourceParty = team.source_party
|
||||
appState.party.social.favorited = team.social.favorited
|
||||
appState.party.social.remix = team.social.remix
|
||||
appState.party.social.remixes = team.social.remixes
|
||||
appState.party.social.sourceParty = team.social.sourceParty
|
||||
appState.party.timestamps.createdAt = team.created_at
|
||||
appState.party.timestamps.updatedAt = team.updated_at
|
||||
|
||||
appState.party.grid = team.grid
|
||||
console.log(team.grid)
|
||||
|
||||
// Store the edit key in local storage
|
||||
if (team.edit_key) {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import EditPartyModal from '../EditPartyModal'
|
|||
|
||||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import { youtube } from '~utils/youtube'
|
||||
|
||||
import type { DetailsObject } from 'types'
|
||||
|
||||
|
|
@ -39,10 +38,7 @@ const PartyFooter = (props: Props) => {
|
|||
const { t } = useTranslation('common')
|
||||
const router = useRouter()
|
||||
|
||||
const { party: partySnapshot } = useSnapshot(appState)
|
||||
|
||||
const youtubeUrlRegex =
|
||||
/(?:https:\/\/www\.youtube\.com\/watch\?v=|https:\/\/youtu\.be\/)([\w-]+)/g
|
||||
const { party } = useSnapshot(appState)
|
||||
|
||||
// State: Component
|
||||
const [currentSegment, setCurrentSegment] = useState(0)
|
||||
|
|
@ -55,69 +51,19 @@ const PartyFooter = (props: Props) => {
|
|||
const [sanitizedDescription, setSanitizedDescription] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
if (partySnapshot.description) {
|
||||
const purified = DOMPurify.sanitize(partySnapshot.description)
|
||||
if (party.description) {
|
||||
const purified = DOMPurify.sanitize(party.description)
|
||||
setSanitizedDescription(purified)
|
||||
} else {
|
||||
setSanitizedDescription('')
|
||||
}
|
||||
}, [partySnapshot.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)
|
||||
}
|
||||
}, [party.description])
|
||||
|
||||
// Methods: Navigation
|
||||
function goTo(shortcode?: string) {
|
||||
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
|
||||
function toggleFavorite(teamId: string, favorited: boolean) {
|
||||
if (favorited) unsaveFavorite(teamId)
|
||||
|
|
@ -202,7 +148,7 @@ const PartyFooter = (props: Props) => {
|
|||
onClick={() => setCurrentSegment(1)}
|
||||
>
|
||||
{t('footer.remixes.label', {
|
||||
count: partySnapshot?.social.remixes?.length,
|
||||
count: party?.social.remixes?.length ?? 0,
|
||||
})}
|
||||
</Segment>
|
||||
</SegmentedControl>
|
||||
|
|
@ -218,7 +164,7 @@ const PartyFooter = (props: Props) => {
|
|||
key={props.party?.shortcode}
|
||||
/>
|
||||
)}
|
||||
{(!partySnapshot || !partySnapshot.description) && (
|
||||
{(!party || !party.description) && (
|
||||
<section className={styles.noDescription}>
|
||||
<h3>{t('footer.description.empty')}</h3>
|
||||
{props.editable && (
|
||||
|
|
@ -242,10 +188,10 @@ const PartyFooter = (props: Props) => {
|
|||
|
||||
const remixesSection = (
|
||||
<section className={styles.remixes}>
|
||||
{partySnapshot?.social.remixes?.length > 0 && (
|
||||
{party?.social.remixes?.length > 0 && (
|
||||
<GridRepCollection>{renderRemixes()}</GridRepCollection>
|
||||
)}
|
||||
{partySnapshot?.social.remixes?.length === 0 && (
|
||||
{party?.social.remixes?.length === 0 && (
|
||||
<div className={styles.noRemixes}>
|
||||
<h3>{t('footer.remixes.empty')}</h3>
|
||||
<Button
|
||||
|
|
@ -259,7 +205,7 @@ const PartyFooter = (props: Props) => {
|
|||
)
|
||||
|
||||
function renderRemixes() {
|
||||
return partySnapshot?.social.remixes.map((party, i) => {
|
||||
return party?.social.remixes.map((party, i) => {
|
||||
return (
|
||||
<GridRep
|
||||
id={party.id}
|
||||
|
|
@ -290,7 +236,7 @@ const PartyFooter = (props: Props) => {
|
|||
|
||||
<RemixTeamAlert
|
||||
creator={props.editable}
|
||||
name={partySnapshot.name ? partySnapshot.name : t('no_title')}
|
||||
name={party.name ? party.name : t('no_title')}
|
||||
open={remixAlertOpen}
|
||||
onOpenChange={handleRemixTeamAlertChange}
|
||||
remixCallback={remixTeamCallback}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ import WeaponSearchFilterBar from '~components/weapon/WeaponSearchFilterBar'
|
|||
import SummonSearchFilterBar from '~components/summon/SummonSearchFilterBar'
|
||||
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 WeaponResult from '~components/weapon/WeaponResult'
|
||||
import SummonResult from '~components/summon/SummonResult'
|
||||
|
|
@ -270,13 +276,14 @@ const SearchModal = (props: Props) => {
|
|||
|
||||
const castResults: Weapon[] = results as Weapon[]
|
||||
if (castResults && Object.keys(castResults).length > 0) {
|
||||
jsx = castResults.map((result: Weapon) => {
|
||||
jsx = castResults.map((result: any) => {
|
||||
const weapon = WeaponTransformer.toObject(result)
|
||||
return (
|
||||
<WeaponResult
|
||||
key={result.id}
|
||||
data={result}
|
||||
key={weapon.id}
|
||||
data={weapon}
|
||||
onClick={() => {
|
||||
storeRecentResult(result)
|
||||
storeRecentResult(weapon)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
@ -291,13 +298,14 @@ const SearchModal = (props: Props) => {
|
|||
|
||||
const castResults: Summon[] = results as Summon[]
|
||||
if (castResults && Object.keys(castResults).length > 0) {
|
||||
jsx = castResults.map((result: Summon) => {
|
||||
jsx = castResults.map((result: any) => {
|
||||
const summon = SummonTransformer.toObject(result)
|
||||
return (
|
||||
<SummonResult
|
||||
key={result.id}
|
||||
data={result}
|
||||
key={summon.id}
|
||||
data={summon}
|
||||
onClick={() => {
|
||||
storeRecentResult(result)
|
||||
storeRecentResult(summon)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
@ -312,13 +320,14 @@ const SearchModal = (props: Props) => {
|
|||
|
||||
const castResults: Character[] = results as Character[]
|
||||
if (castResults && Object.keys(castResults).length > 0) {
|
||||
jsx = castResults.map((result: Character) => {
|
||||
jsx = castResults.map((result: any) => {
|
||||
const character = CharacterTransformer.toObject(result)
|
||||
return (
|
||||
<CharacterResult
|
||||
key={result.id}
|
||||
data={result}
|
||||
key={character.id}
|
||||
data={character}
|
||||
onClick={() => {
|
||||
storeRecentResult(result)
|
||||
storeRecentResult(character)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
@ -334,12 +343,13 @@ const SearchModal = (props: Props) => {
|
|||
const castResults: JobSkill[] = results as JobSkill[]
|
||||
if (castResults && Object.keys(castResults).length > 0) {
|
||||
jsx = castResults.map((result: JobSkill) => {
|
||||
const jobSkill = JobSkillTransformer.toObject(result)
|
||||
return (
|
||||
<JobSkillResult
|
||||
key={result.id}
|
||||
data={result}
|
||||
key={jobSkill.id}
|
||||
data={jobSkill}
|
||||
onClick={() => {
|
||||
storeRecentResult(result)
|
||||
storeRecentResult(jobSkill)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
@ -355,12 +365,13 @@ const SearchModal = (props: Props) => {
|
|||
const castResults: Guidebook[] = results as Guidebook[]
|
||||
if (castResults && Object.keys(castResults).length > 0) {
|
||||
jsx = castResults.map((result: Guidebook) => {
|
||||
const guidebook = GuidebookTransformer.toObject(result)
|
||||
return (
|
||||
<GuidebookResult
|
||||
key={result.id}
|
||||
data={result}
|
||||
key={guidebook.id}
|
||||
data={guidebook}
|
||||
onClick={() => {
|
||||
storeRecentResult(result)
|
||||
storeRecentResult(guidebook)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import ExtraSummonsGrid from '~components/extra/ExtraSummonsGrid'
|
|||
|
||||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import * as GridSummonTransformer from '~transformers/GridSummonTransformer'
|
||||
import type { DetailsObject, SearchableObject } from '~types'
|
||||
|
||||
import styles from './index.module.scss'
|
||||
|
|
@ -119,11 +120,11 @@ const SummonGrid = (props: Props) => {
|
|||
const position = data.meta['replaced']
|
||||
|
||||
if (position == -1) {
|
||||
appState.party.grid.summons.mainSummon = undefined
|
||||
appState.party.grid.summons.mainSummon = null
|
||||
} else if (position == 6) {
|
||||
appState.party.grid.summons.friendSummon = undefined
|
||||
appState.party.grid.summons.friendSummon = null
|
||||
} else {
|
||||
appState.party.grid.summons.allSummons[position] = undefined
|
||||
appState.party.grid.summons.allSummons[position] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -146,7 +147,9 @@ const SummonGrid = (props: Props) => {
|
|||
})
|
||||
}
|
||||
|
||||
function storeGridSummon(gridSummon: GridSummon) {
|
||||
function storeGridSummon(data: GridSummon) {
|
||||
const gridSummon = GridSummonTransformer.toObject(data)
|
||||
|
||||
if (gridSummon.position == -1)
|
||||
appState.party.grid.summons.mainSummon = gridSummon
|
||||
else if (gridSummon.position == 6)
|
||||
|
|
@ -360,12 +363,11 @@ const SummonGrid = (props: Props) => {
|
|||
const data = response.data
|
||||
|
||||
if (data.position === -1) {
|
||||
appState.party.grid.summons.mainSummon = undefined
|
||||
appState.party.grid.summons.mainSummon = null
|
||||
} else if (data.position === 6) {
|
||||
appState.party.grid.summons.friendSummon = undefined
|
||||
appState.party.grid.summons.friendSummon = null
|
||||
} else {
|
||||
appState.party.grid.summons.allSummons[response.data.position] =
|
||||
undefined
|
||||
appState.party.grid.summons.allSummons[response.data.position] = null
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
|
|
|||
|
|
@ -28,8 +28,11 @@ const SummonResult = (props: Props) => {
|
|||
<h5>{summon.name[locale]}</h5>
|
||||
<UncapIndicator
|
||||
type="summon"
|
||||
flb={summon.uncap.flb}
|
||||
ulb={summon.uncap.ulb}
|
||||
ulb={summon.uncap.ulb || false}
|
||||
flb={summon.uncap.flb || false}
|
||||
xlb={summon.uncap.xlb || false}
|
||||
uncapLevel={6}
|
||||
transcendenceStage={5}
|
||||
special={false}
|
||||
/>
|
||||
<div className={styles.tags}>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import classNames from 'classnames'
|
|||
|
||||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import * as GridSummonTransformer from '~transformers/GridSummonTransformer'
|
||||
|
||||
import Alert from '~components/common/Alert'
|
||||
import Button from '~components/common/Button'
|
||||
|
|
@ -26,7 +27,7 @@ import SettingsIcon from '~public/icons/Settings.svg'
|
|||
import styles from './index.module.scss'
|
||||
|
||||
interface Props {
|
||||
gridSummon: GridSummon | undefined
|
||||
gridSummon: GridSummon | null
|
||||
unitType: 0 | 1 | 2
|
||||
position: number
|
||||
editable: boolean
|
||||
|
|
@ -125,13 +126,23 @@ const SummonUnit = ({
|
|||
// If a user sets a quick summon while one is already set,
|
||||
// the previous one will be unset.
|
||||
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) {
|
||||
if (gridSummon.main) {
|
||||
appState.grid.summons.mainSummon = gridSummon
|
||||
appState.grid.summons.mainSummon = mainSummon
|
||||
} else if (gridSummon.friend) {
|
||||
appState.grid.summons.friendSummon = gridSummon
|
||||
appState.grid.summons.friendSummon = friendSummon
|
||||
} 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() {
|
||||
let imgSrc = ''
|
||||
if (gridSummon) {
|
||||
const summon = gridSummon.object!
|
||||
|
||||
const summon = gridSummon.object
|
||||
const upgradedSummons = [
|
||||
'2040094000',
|
||||
'2040100000',
|
||||
|
|
@ -179,6 +189,7 @@ const SummonUnit = ({
|
|||
let suffix = ''
|
||||
if (gridSummon.object.uncap.xlb && gridSummon.uncapLevel == 6) {
|
||||
if (
|
||||
gridSummon.transcendenceStep &&
|
||||
gridSummon.transcendenceStep >= 1 &&
|
||||
gridSummon.transcendenceStep < 5
|
||||
) {
|
||||
|
|
@ -187,7 +198,7 @@ const SummonUnit = ({
|
|||
suffix = '_04'
|
||||
}
|
||||
} else if (
|
||||
upgradedSummons.indexOf(summon.granblueId.toString()) != -1 &&
|
||||
upgradedSummons.indexOf(summon.granblueId) != -1 &&
|
||||
gridSummon.uncapLevel == 5
|
||||
) {
|
||||
suffix = '_02'
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const TranscendenceStar = ({
|
|||
const starClasses = classnames({
|
||||
[styles.star]: true,
|
||||
[styles.immutable]: immutable,
|
||||
[styles.empty]: stage === 0,
|
||||
[styles.empty]: true,
|
||||
[styles.stage1]: stage === 1,
|
||||
[styles.stage2]: stage === 2,
|
||||
[styles.stage3]: stage === 3,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import UncapStar from '~components/uncap/UncapStar'
|
||||
import TranscendencePopover from '~components/uncap/TranscendencePopover'
|
||||
import TranscendenceStar from '~components/uncap/TranscendenceStar'
|
||||
|
|
@ -82,7 +82,11 @@ const UncapIndicator = (props: Props) => {
|
|||
return props.type === 'character' || props.type === 'summon' ? (
|
||||
<TranscendencePopover
|
||||
open={popoverOpen}
|
||||
stage={props.transcendenceStage ? props.transcendenceStage : 0}
|
||||
stage={
|
||||
props.transcendenceStage && props.transcendenceStage !== null
|
||||
? props.transcendenceStage
|
||||
: 0
|
||||
}
|
||||
type={props.type}
|
||||
onOpenChange={togglePopover}
|
||||
sendValue={sendTranscendenceStage}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import WeaponConflictModal from '~components/weapon/WeaponConflictModal'
|
|||
|
||||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import * as GridWeaponTransformer from '~transformers/GridWeaponTransformer'
|
||||
|
||||
import type { DetailsObject, SearchableObject } from '~types'
|
||||
|
||||
|
|
@ -58,7 +59,7 @@ const WeaponGrid = (props: Props) => {
|
|||
const [showIncompatibleAlert, setShowIncompatibleAlert] = useState(false)
|
||||
|
||||
// Set up state for view management
|
||||
const { party, grid } = useSnapshot(appState)
|
||||
const { party } = useSnapshot(appState)
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
|
||||
// Set up state for conflict management
|
||||
|
|
@ -150,10 +151,10 @@ const WeaponGrid = (props: Props) => {
|
|||
const position = data.meta['replaced']
|
||||
|
||||
if (position == -1) {
|
||||
appState.party.grid.weapons.mainWeapon = undefined
|
||||
appState.party.grid.weapons.mainWeapon = null
|
||||
appState.party.element = ElementMap.null
|
||||
} else {
|
||||
appState.party.grid.weapons.allWeapons[position] = undefined
|
||||
appState.party.grid.weapons.allWeapons[position] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +196,8 @@ const WeaponGrid = (props: Props) => {
|
|||
}
|
||||
}
|
||||
|
||||
function storeGridWeapon(gridWeapon: GridWeapon) {
|
||||
function storeGridWeapon(data: GridWeapon) {
|
||||
const gridWeapon = GridWeaponTransformer.toObject(data)
|
||||
if (gridWeapon.position === -1) {
|
||||
appState.party.grid.weapons.mainWeapon = gridWeapon
|
||||
appState.party.element = gridWeapon.object.element
|
||||
|
|
@ -220,10 +222,10 @@ const WeaponGrid = (props: Props) => {
|
|||
if (
|
||||
appState.party.grid.weapons.mainWeapon?.object.id === c.object.id
|
||||
) {
|
||||
appState.party.grid.weapons.mainWeapon = undefined
|
||||
appState.party.grid.weapons.mainWeapon = null
|
||||
appState.party.element = ElementMap.null
|
||||
} else {
|
||||
appState.party.grid.weapons.allWeapons[c.position] = undefined
|
||||
appState.party.grid.weapons.allWeapons[c.position] = null
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -251,10 +253,9 @@ const WeaponGrid = (props: Props) => {
|
|||
const data = response.data
|
||||
|
||||
if (data.position === -1) {
|
||||
appState.party.grid.weapons.mainWeapon = undefined
|
||||
appState.party.grid.weapons.mainWeapon = null
|
||||
} else {
|
||||
appState.party.grid.weapons.allWeapons[response.data.position] =
|
||||
undefined
|
||||
appState.party.grid.weapons.allWeapons[response.data.position] = null
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
|
@ -376,7 +377,7 @@ const WeaponGrid = (props: Props) => {
|
|||
return (
|
||||
<li className={itemClasses} key={`grid_unit_${i}`}>
|
||||
<WeaponUnit
|
||||
gridWeapon={appState.party.grid.weapons.allWeapons[i]}
|
||||
gridWeapon={party.grid.weapons.allWeapons[i]}
|
||||
editable={props.editable}
|
||||
position={i}
|
||||
unitType={1}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import SettingsIcon from '~public/icons/Settings.svg'
|
|||
import styles from './index.module.scss'
|
||||
|
||||
interface Props {
|
||||
gridWeapon: GridWeapon | undefined
|
||||
gridWeapon: GridWeapon | null
|
||||
unitType: 0 | 1
|
||||
position: number
|
||||
editable: boolean
|
||||
|
|
|
|||
|
|
@ -193,8 +193,12 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
|||
|
||||
const party: Party | undefined = await api.endpoints.parties.getOne({
|
||||
id: query.party,
|
||||
}).then((response) => PartyTransformer.toObject(response.data.party))
|
||||
}).then((response) =>
|
||||
PartyTransformer.toObject(response.data.party)
|
||||
)
|
||||
|
||||
console.log(party)
|
||||
|
||||
// Consolidate data into context object
|
||||
const context: PageContextObj = {
|
||||
party: party,
|
||||
|
|
|
|||
|
|
@ -4,29 +4,61 @@ import * as GridCharacter from '~transformers/GridCharacterTransformer'
|
|||
|
||||
// Transforms API response to Party object
|
||||
export function toObject(data: any): Grid {
|
||||
const mainSummon = data.summons.find((summon: any) => summon.main === true)
|
||||
const friendSummon = data.summons.find(
|
||||
(summon: any) => summon.friend === true
|
||||
)
|
||||
const mainWeapon = data.weapons.find(
|
||||
(weapon: any) => weapon.mainhand === true
|
||||
)
|
||||
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.map((character: any) =>
|
||||
GridCharacter.toObject(character)
|
||||
),
|
||||
characters: data.characters
|
||||
? mapToGridArray(data.characters, GridCharacter.toObject)
|
||||
: null,
|
||||
summons: {
|
||||
mainSummon: mainSummon ? GridSummon.toObject(mainSummon) : null,
|
||||
friendSummon: friendSummon ? GridSummon.toObject(friendSummon) : null,
|
||||
allSummons: data.summons.map((summon: any) => {
|
||||
if (!summon.main && !summon.friend) return GridSummon.toObject(summon)
|
||||
}),
|
||||
allSummons: allSummons
|
||||
? mapToGridArray(allSummons, GridSummon.toObject)
|
||||
: null,
|
||||
},
|
||||
weapons: {
|
||||
mainWeapon: mainWeapon ? GridWeapon.toObject(mainWeapon) : null,
|
||||
allWeapons: data.weapons.map((weapon: any) => {
|
||||
if (!weapon.mainhand) return GridWeapon.toObject(weapon)
|
||||
}),
|
||||
allWeapons: data.weapons
|
||||
? mapToGridArray(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
|
||||
}
|
||||
|
||||
function mapToGridArray<T>(
|
||||
arr: any[],
|
||||
transformer: (data: any) => T
|
||||
): GridArray<T> {
|
||||
return arr.reduce(
|
||||
(gridArray, item) => ({ ...gridArray, [item.position]: transformer(item) }),
|
||||
{} as GridArray<T>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,16 @@ export function toObject(data: any): GridWeapon {
|
|||
mainhand: data.mainhand,
|
||||
uncapLevel: data.uncap_level,
|
||||
element: Element.toObject(data.element),
|
||||
weaponKeys: data.weapon_keys.map((key: any) => WeaponKey.toObject(key)),
|
||||
ax: data.ax,
|
||||
awakening: {
|
||||
type: Awakening.toObject(data.awakening.type),
|
||||
level: data.awakening.awakening_level,
|
||||
},
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,12 @@ import * as User from './UserTransformer'
|
|||
export function toObject(data: any): Party {
|
||||
return {
|
||||
id: data.id,
|
||||
localId: data.local_id,
|
||||
localId: data.local_id ? data.local_id : null,
|
||||
editKey: data.edit_key ? data.edit_key : null,
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
description: data.description ? data.description : null,
|
||||
shortcode: data.shortcode,
|
||||
user: User.toObject(data.user),
|
||||
user: data.user ? User.toObject(data.user) : null,
|
||||
editable: data.editable ?? false,
|
||||
grid: Grid.toObject({
|
||||
characters: data.characters,
|
||||
|
|
@ -26,35 +27,39 @@ export function toObject(data: any): Party {
|
|||
fullAuto: data.full_auto,
|
||||
autoGuard: data.auto_guard,
|
||||
autoSummon: data.auto_summon,
|
||||
chargeAttack: data.charge_attack,
|
||||
clearTime: data.clear_time,
|
||||
buttonCount: data.button_count,
|
||||
turnCount: data.turn_count,
|
||||
chainCount: data.chain_count,
|
||||
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: {
|
||||
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]),
|
||||
},
|
||||
masterLevel: data.master_level,
|
||||
ultimateMastery: data.ultimate_mastery,
|
||||
accessory: data.accessory && JobAccessory.toObject(data.accessory),
|
||||
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.map((remix: any) => toObject(remix)),
|
||||
sourceParty: data.source_party && toObject(data.source_party),
|
||||
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),
|
||||
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]),
|
||||
|
|
|
|||
12
types/Grid.d.ts
vendored
12
types/Grid.d.ts
vendored
|
|
@ -1,12 +1,12 @@
|
|||
interface Grid {
|
||||
weapons: {
|
||||
mainWeapon?: GridWeapon | undefined
|
||||
allWeapons: GridArray<GridWeapon>
|
||||
mainWeapon: GridWeapon | null
|
||||
allWeapons: GridArray<GridWeapon> | null
|
||||
}
|
||||
summons: {
|
||||
mainSummon?: GridSummon | undefined
|
||||
friendSummon?: GridSummon | undefined
|
||||
allSummons: GridArray<GridSummon>
|
||||
mainSummon: GridSummon | null
|
||||
friendSummon: GridSummon | null
|
||||
allSummons: GridArray<GridSummon> | null
|
||||
}
|
||||
characters: GridArray<GridCharacter>
|
||||
characters: GridArray<GridCharacter> | null
|
||||
}
|
||||
|
|
|
|||
2
types/GridArray.d.ts
vendored
2
types/GridArray.d.ts
vendored
|
|
@ -1 +1 @@
|
|||
type GridArray<T> = { [key: number]: T | undefined }
|
||||
type GridArray<T> = { [key: number]: T | null }
|
||||
|
|
|
|||
4
types/GridWeapon.d.ts
vendored
4
types/GridWeapon.d.ts
vendored
|
|
@ -7,8 +7,8 @@ interface GridWeapon {
|
|||
element: GranblueElement
|
||||
weaponKeys?: WeaponKey[]
|
||||
ax?: SimpleAxSkill[]
|
||||
awakening?: {
|
||||
awakening: {
|
||||
type: Awakening
|
||||
level: number
|
||||
}
|
||||
} | null
|
||||
}
|
||||
|
|
|
|||
27
types/Party.d.ts
vendored
27
types/Party.d.ts
vendored
|
|
@ -15,11 +15,12 @@ type GuidebookList = {
|
|||
|
||||
interface Party {
|
||||
id: string
|
||||
localId?: string
|
||||
localId: string | null
|
||||
editKey: string | null
|
||||
name: string
|
||||
description: string
|
||||
shortcode: string
|
||||
user?: User
|
||||
user: User | null
|
||||
editable: boolean
|
||||
element?: GranblueElement
|
||||
grid: Grid
|
||||
|
|
@ -28,26 +29,26 @@ interface Party {
|
|||
fullAuto: boolean
|
||||
autoGuard: boolean
|
||||
autoSummon: boolean
|
||||
chargeAttack: boolean
|
||||
clearTime: number
|
||||
buttonCount?: number
|
||||
turnCount?: number
|
||||
chainCount?: number
|
||||
chargeAttack: boolean | null
|
||||
clearTime: number | null
|
||||
buttonCount: number | null
|
||||
turnCount: number | null
|
||||
chainCount: number | null
|
||||
}
|
||||
protagonist: {
|
||||
job?: Job
|
||||
skills: JobSkillList
|
||||
masterLevel?: number
|
||||
ultimateMastery?: number
|
||||
accessory?: JobAccessory
|
||||
skills: JobSkillList | null
|
||||
masterLevel: number | null
|
||||
ultimateMastery: number | null
|
||||
accessory: JobAccessory | null
|
||||
}
|
||||
social: {
|
||||
favorited: boolean
|
||||
sourceParty?: Party
|
||||
sourceParty: Party | null
|
||||
remix: boolean
|
||||
remixes: Party[]
|
||||
}
|
||||
raid?: Raid
|
||||
raid: Raid | null
|
||||
guidebooks: GuidebookList
|
||||
timestamps: {
|
||||
createdAt: string
|
||||
|
|
|
|||
Loading…
Reference in a new issue