diff --git a/components/GridRep/index.tsx b/components/GridRep/index.tsx index b1c92db6..0f908d72 100644 --- a/components/GridRep/index.tsx +++ b/components/GridRep/index.tsx @@ -20,12 +20,12 @@ interface Props { shortcode: string id: string name: string - raid?: Raid + raid: Raid | null weapons: { - mainWeapon?: GridWeapon - allWeapons: GridArray - } - user?: User + mainWeapon: GridWeapon | null + allWeapons: GridArray | null + } | null + user: User | null fullAuto: boolean autoGuard: boolean favorited: boolean diff --git a/components/character/CharacterGrid/index.tsx b/components/character/CharacterGrid/index.tsx index 4be3b5c3..39622d05 100644 --- a/components/character/CharacterGrid/index.tsx +++ b/components/character/CharacterGrid/index.tsx @@ -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) } diff --git a/components/character/CharacterResult/index.tsx b/components/character/CharacterResult/index.tsx index a9473e84..6b723e51 100644 --- a/components/character/CharacterResult/index.tsx +++ b/components/character/CharacterResult/index.tsx @@ -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} />
diff --git a/components/character/CharacterUnit/index.tsx b/components/character/CharacterUnit/index.tsx index ad64c9f4..c89637aa 100644 --- a/components/character/CharacterUnit/index.tsx +++ b/components/character/CharacterUnit/index.tsx @@ -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' diff --git a/components/party/Party/index.tsx b/components/party/Party/index.tsx index 5154f5ac..55d08f45 100644 --- a/components/party/Party/index.tsx +++ b/components/party/Party/index.tsx @@ -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) { diff --git a/components/party/PartyFooter/index.tsx b/components/party/PartyFooter/index.tsx index 76f1133a..54391774 100644 --- a/components/party/PartyFooter/index.tsx +++ b/components/party/PartyFooter/index.tsx @@ -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) => ( - // - // ) - // ) - // 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, })} @@ -218,7 +164,7 @@ const PartyFooter = (props: Props) => { key={props.party?.shortcode} /> )} - {(!partySnapshot || !partySnapshot.description) && ( + {(!party || !party.description) && (

{t('footer.description.empty')}

{props.editable && ( @@ -242,10 +188,10 @@ const PartyFooter = (props: Props) => { const remixesSection = (
- {partySnapshot?.social.remixes?.length > 0 && ( + {party?.social.remixes?.length > 0 && ( {renderRemixes()} )} - {partySnapshot?.social.remixes?.length === 0 && ( + {party?.social.remixes?.length === 0 && (

{t('footer.remixes.empty')}