From 4a219378c7d497da4df234adad21b7d6d47cbd7f Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sat, 7 Jan 2023 22:59:26 -0800 Subject: [PATCH 1/6] Fix bug with party name --- components/PartyDetails/index.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/components/PartyDetails/index.tsx b/components/PartyDetails/index.tsx index 770ded74..ffc3f99e 100644 --- a/components/PartyDetails/index.tsx +++ b/components/PartyDetails/index.tsx @@ -252,11 +252,14 @@ const PartyDetails = (props: Props) => { } function toggleDetails() { - if (name !== party.name) { - const resetName = party.name ? party.name : 'Untitled' - setName(resetName) - if (nameInput.current) nameInput.current.value = resetName - } + // Enabling this code will make live updates not work, + // but I'm not sure why it's here, so we're not going to remove it. + + // if (name !== party.name) { + // const resetName = party.name ? party.name : '' + // setName(resetName) + // if (nameInput.current) nameInput.current.value = resetName + // } setOpen(!open) } @@ -270,7 +273,6 @@ const PartyDetails = (props: Props) => { } function updateDetails(event: React.MouseEvent) { - const nameValue = nameInput.current?.value const descriptionValue = descriptionInput.current?.value const raid = raids.find((raid) => raid.slug === raidSlug) @@ -282,7 +284,7 @@ const PartyDetails = (props: Props) => { buttonCount: buttonCount, turnCount: turnCount, chainCount: chainCount, - name: nameValue, + name: name, description: descriptionValue, raid: raid, } From 5de556b36761de38702f36af3d0f1aa7077da581 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sat, 7 Jan 2023 23:25:55 -0800 Subject: [PATCH 2/6] Create teams when arbitrary details are changed These teams have no weapons and won't show up anywhere but the user's profile. We should probably clean out completely empty teams every once in a while with a CRON job. --- components/Party/index.tsx | 76 +++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/components/Party/index.tsx b/components/Party/index.tsx index 3cd98d4b..ac7348b6 100644 --- a/components/Party/index.tsx +++ b/components/Party/index.tsx @@ -59,44 +59,60 @@ const Party = (props: Props) => { } } - function updateDetails(details: DetailsObject) { + async function updateDetails(details: DetailsObject) { if ( appState.party.name !== details.name || appState.party.description !== details.description || appState.party.raid?.id !== details.raid?.id ) { - if (appState.party.id) - api.endpoints.parties - .update(appState.party.id, { - party: { - name: details.name, - description: details.description, - raid_id: details.raid?.id, - charge_attack: details.chargeAttack, - full_auto: details.fullAuto, - auto_guard: details.autoGuard, - clear_time: details.clearTime, - button_count: details.buttonCount, - chain_count: details.chainCount, - turn_count: details.turnCount, - }, - }) - .then(() => { - appState.party.name = details.name - appState.party.description = details.description - appState.party.raid = details.raid + if (!appState.party.id) + await createParty().then((response) => { + // If the party has no ID, create a new party + const party = response.data.party + storeParty(party) - appState.party.chargeAttack = details.chargeAttack - appState.party.fullAuto = details.fullAuto - appState.party.autoGuard = details.autoGuard + // Then, push the browser history to the new party's URL + if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`) + }) - appState.party.clearTime = details.clearTime - appState.party.buttonCount = details.buttonCount - appState.party.chainCount = details.chainCount - appState.party.turnCount = details.turnCount + // Update the party + await sendUpdate(details) + } + } - appState.party.updated_at = party.updated_at - }) + async function sendUpdate(details: DetailsObject) { + if (appState.party.id) { + return await api.endpoints.parties + .update(appState.party.id, { + party: { + name: details.name, + description: details.description, + raid_id: details.raid?.id, + charge_attack: details.chargeAttack, + full_auto: details.fullAuto, + auto_guard: details.autoGuard, + clear_time: details.clearTime, + button_count: details.buttonCount, + chain_count: details.chainCount, + turn_count: details.turnCount, + }, + }) + .then(() => { + appState.party.name = details.name + appState.party.description = details.description + appState.party.raid = details.raid + + appState.party.chargeAttack = details.chargeAttack + appState.party.fullAuto = details.fullAuto + appState.party.autoGuard = details.autoGuard + + appState.party.clearTime = details.clearTime + appState.party.buttonCount = details.buttonCount + appState.party.chainCount = details.chainCount + appState.party.turnCount = details.turnCount + + appState.party.updated_at = party.updated_at + }) } } From 018aaefa81a4c94c202af87c47917182443903b7 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sat, 7 Jan 2023 23:28:06 -0800 Subject: [PATCH 3/6] Fix SummonUnit showing + over image --- components/SummonUnit/index.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/SummonUnit/index.scss b/components/SummonUnit/index.scss index 28bbf4cc..398d3ae3 100644 --- a/components/SummonUnit/index.scss +++ b/components/SummonUnit/index.scss @@ -91,7 +91,7 @@ img { position: relative; width: 100%; - z-index: 0; + z-index: 2; &.Placeholder { opacity: 0; From 4784a8113ffb2b68a08fa80283bf306ce0964299 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 8 Jan 2023 01:31:43 -0800 Subject: [PATCH 4/6] Make everything in DetailsObject optional --- types/index.d.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/types/index.d.ts b/types/index.d.ts index 4541c991..d73e4242 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -22,14 +22,16 @@ export type PaginationObject = { export type DetailsObject = { [key: string]: boolean | number | string | Raid | undefined - fullAuto: boolean - autoGuard: boolean - chargeAttack: boolean - clearTime: number + fullAuto?: boolean + autoGuard?: boolean + chargeAttack?: boolean + clearTime?: number buttonCount?: number turnCount?: number chainCount?: number name?: string description?: string raid?: Raid + job?: Job + extra?: boolean } From c0cdb9117803cf1802307f1191dd9ec4561da8cb Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 8 Jan 2023 01:31:56 -0800 Subject: [PATCH 5/6] Remove visible from props to remove error --- components/LabelledInput/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/LabelledInput/index.tsx b/components/LabelledInput/index.tsx index 19931805..57a6b837 100644 --- a/components/LabelledInput/index.tsx +++ b/components/LabelledInput/index.tsx @@ -26,7 +26,7 @@ const LabelledInput = React.forwardRef(function Input( // Classes const classes = classNames({ Input: true }, props.className) - const { defaultValue, ...inputProps } = props + const { defaultValue, visible, ...inputProps } = props // Change value when prop updates useEffect(() => { From bd1f6ccb980279b9a08733b62e65a2fe857b8de3 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 8 Jan 2023 01:32:09 -0800 Subject: [PATCH 6/6] Refactor createParty to allow creating anything first --- components/CharacterGrid/index.tsx | 32 ++++---- components/Party/index.tsx | 119 +++++++++++++---------------- components/SummonGrid/index.tsx | 14 +--- components/WeaponGrid/index.tsx | 17 ++--- 4 files changed, 78 insertions(+), 104 deletions(-) diff --git a/components/CharacterGrid/index.tsx b/components/CharacterGrid/index.tsx index f74d6e0b..48cc0ca8 100644 --- a/components/CharacterGrid/index.tsx +++ b/components/CharacterGrid/index.tsx @@ -11,7 +11,7 @@ import JobSection from '~components/JobSection' import CharacterUnit from '~components/CharacterUnit' import CharacterConflictModal from '~components/CharacterConflictModal' -import type { JobSkillObject, SearchableObject } from '~types' +import type { DetailsObject, JobSkillObject, SearchableObject } from '~types' import api from '~utils/api' import { appState } from '~utils/appState' @@ -23,7 +23,7 @@ import './index.scss' interface Props { new: boolean characters?: GridCharacter[] - createParty: () => Promise> + createParty: (details?: DetailsObject) => Promise pushHistory?: (path: string) => void } @@ -95,13 +95,8 @@ const CharacterGrid = (props: Props) => { const character = object as Character if (!party.id) { - props.createParty().then((response) => { - const party = response.data.party - appState.party.id = party.id - setSlug(party.shortcode) - - if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`) - saveCharacter(party.id, character, position) + props.createParty().then((team) => { + saveCharacter(team.id, character, position) .then((response) => storeGridCharacter(response.data)) .catch((error) => console.error(error)) }) @@ -184,19 +179,24 @@ const CharacterGrid = (props: Props) => { }, } - if (party.id && appState.party.editable) { + if (!party.id) { + // If the party has no ID, create a new party + await props.createParty() + } + + if (appState.party.id) { const response = await api.updateJob({ - partyId: party.id, + partyId: appState.party.id, params: payload, }) - const newParty = response.data + const team = response.data - setJob(newParty.job) - appState.party.job = newParty.job + setJob(team.job) + appState.party.job = team.job - setJobSkills(newParty.job_skills) - appState.party.jobSkills = newParty.job_skills + setJobSkills(team.job_skills) + appState.party.jobSkills = team.job_skills } } diff --git a/components/Party/index.tsx b/components/Party/index.tsx index ac7348b6..14c3f49a 100644 --- a/components/Party/index.tsx +++ b/components/Party/index.tsx @@ -11,7 +11,7 @@ import CharacterGrid from '~components/CharacterGrid' import api from '~utils/api' import { appState, initialAppState } from '~utils/appState' -import { GridType, TeamElement } from '~utils/enums' +import { GridType } from '~utils/enums' import type { DetailsObject } from '~types' import './index.scss' @@ -40,82 +40,62 @@ const Party = (props: Props) => { }, []) // Methods: Creating a new party - async function createParty(extra: boolean = false) { - return await api.endpoints.parties.create({ - party: { - extra: extra, - }, - }) + async function createParty(details?: DetailsObject) { + let payload = {} + if (details) payload = formatDetailsObject(details) + + return await api.endpoints.parties + .create(payload) + .then((response) => storeParty(response.data.party)) } // Methods: Updating the party's details + async function updateDetails(details: DetailsObject) { + if (!appState.party.id) return await createParty(details) + else updateParty(details) + } + + function formatDetailsObject(details: DetailsObject) { + const payload: { [key: string]: any } = {} + + if (details.name) payload.name = details.name + if (details.description) payload.description = details.description + if (details.raid) payload.raid_id = details.raid.id + if (details.chargeAttack) payload.charge_attack = details.chargeAttack + if (details.fullAuto) payload.full_auto = details.fullAuto + if (details.autoGuard) payload.auto_guard = details.autoGuard + if (details.clearTime) payload.clear_time = details.clearTime + if (details.buttonCount) payload.button_count = details.buttonCount + if (details.chainCount) payload.chain_count = details.chainCount + if (details.turnCount) payload.turn_count = details.turnCount + if (details.extra) payload.extra = details.extra + if (details.job) payload.job_id = details.job.id + + if (Object.keys(payload).length > 1) return { party: payload } + else return {} + } + + async function updateParty(details: DetailsObject) { + const payload = formatDetailsObject(details) + + if (appState.party.id) { + return await api.endpoints.parties + .update(appState.party.id, payload) + .then((response) => storeParty(response.data.party)) + } + } + function checkboxChanged(event: React.ChangeEvent) { appState.party.extra = event.target.checked - if (party.id) { - api.endpoints.parties.update(party.id, { + // Only save if this is a saved party + if (appState.party.id) { + api.endpoints.parties.update(appState.party.id, { party: { extra: event.target.checked }, }) } } - async function updateDetails(details: DetailsObject) { - if ( - appState.party.name !== details.name || - appState.party.description !== details.description || - appState.party.raid?.id !== details.raid?.id - ) { - if (!appState.party.id) - await createParty().then((response) => { - // If the party has no ID, create a new party - const party = response.data.party - storeParty(party) - - // Then, push the browser history to the new party's URL - if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`) - }) - - // Update the party - await sendUpdate(details) - } - } - - async function sendUpdate(details: DetailsObject) { - if (appState.party.id) { - return await api.endpoints.parties - .update(appState.party.id, { - party: { - name: details.name, - description: details.description, - raid_id: details.raid?.id, - charge_attack: details.chargeAttack, - full_auto: details.fullAuto, - auto_guard: details.autoGuard, - clear_time: details.clearTime, - button_count: details.buttonCount, - chain_count: details.chainCount, - turn_count: details.turnCount, - }, - }) - .then(() => { - appState.party.name = details.name - appState.party.description = details.description - appState.party.raid = details.raid - - appState.party.chargeAttack = details.chargeAttack - appState.party.fullAuto = details.fullAuto - appState.party.autoGuard = details.autoGuard - - appState.party.clearTime = details.clearTime - appState.party.buttonCount = details.buttonCount - appState.party.chainCount = details.chainCount - appState.party.turnCount = details.turnCount - - appState.party.updated_at = party.updated_at - }) - } - } - // Deleting the party function deleteTeam(event: React.MouseEvent) { if (appState.party.editable && appState.party.id) { @@ -142,7 +122,7 @@ const Party = (props: Props) => { // Methods: Storing party data const storeParty = function (team: Party) { - // Store the important party and state-keeping values + // Store the important party and state-keeping values in global state appState.party.name = team.name appState.party.description = team.description appState.party.raid = team.raid @@ -163,6 +143,11 @@ const Party = (props: Props) => { storeCharacters(team.characters) storeWeapons(team.weapons) storeSummons(team.summons) + + // Then, push the browser history to the new party's URL + if (props.pushHistory) props.pushHistory(`/p/${team.shortcode}`) + + return team } const storeCharacters = (list: Array) => { diff --git a/components/SummonGrid/index.tsx b/components/SummonGrid/index.tsx index 820eba24..de1847bb 100644 --- a/components/SummonGrid/index.tsx +++ b/components/SummonGrid/index.tsx @@ -13,7 +13,7 @@ import ExtraSummons from '~components/ExtraSummons' import api from '~utils/api' import { appState } from '~utils/appState' import { accountState } from '~utils/accountState' -import type { SearchableObject } from '~types' +import type { DetailsObject, SearchableObject } from '~types' import './index.scss' @@ -21,7 +21,7 @@ import './index.scss' interface Props { new: boolean summons?: GridSummon[] - createParty: () => Promise> + createParty: (details?: DetailsObject) => Promise pushHistory?: (path: string) => void } @@ -86,14 +86,8 @@ const SummonGrid = (props: Props) => { const summon = object as Summon if (!party.id) { - props.createParty().then((response) => { - const party = response.data.party - appState.party.id = party.id - setSlug(party.shortcode) - - if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`) - - saveSummon(party.id, summon, position).then((response) => + props.createParty().then((team) => { + saveSummon(team.id, summon, position).then((response) => storeGridSummon(response.data) ) }) diff --git a/components/WeaponGrid/index.tsx b/components/WeaponGrid/index.tsx index 59361cfa..f9312a5d 100644 --- a/components/WeaponGrid/index.tsx +++ b/components/WeaponGrid/index.tsx @@ -13,7 +13,7 @@ import ExtraWeapons from '~components/ExtraWeapons' import api from '~utils/api' import { appState } from '~utils/appState' -import type { SearchableObject } from '~types' +import type { DetailsObject, SearchableObject } from '~types' import './index.scss' import WeaponConflictModal from '~components/WeaponConflictModal' @@ -24,7 +24,7 @@ import { accountState } from '~utils/accountState' interface Props { new: boolean weapons?: GridWeapon[] - createParty: (extra: boolean) => Promise> + createParty: (details: DetailsObject) => Promise pushHistory?: (path: string) => void } @@ -89,16 +89,11 @@ const WeaponGrid = (props: Props) => { if (position == 1) appState.party.element = weapon.element if (!party.id) { - props.createParty(party.extra).then((response) => { - const party = response.data.party - appState.party.id = party.id - setSlug(party.shortcode) - - if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`) - - saveWeapon(party.id, weapon, position).then((response) => + const payload: DetailsObject = { extra: party.extra } + props.createParty(payload).then((team) => { + saveWeapon(team.id, weapon, position).then((response) => { storeGridWeapon(response.data.grid_weapon) - ) + }) }) } else { if (party.editable)