Fix optimistic UI and prevent saving identical uncap values

This commit is contained in:
Justin Edmund 2022-02-02 20:36:22 -08:00
parent 8f77794262
commit 4fb2fd16b8
3 changed files with 66 additions and 29 deletions

View file

@ -63,6 +63,13 @@ const CharacterGrid = (props: Props) => {
setCharacters(props.characters || {})
}, [props])
// Initialize an array of current uncap values for each characters
useEffect(() => {
let initialPreviousUncapValues: {[key: number]: number} = {}
Object.values(props.characters).map(o => initialPreviousUncapValues[o.position] = o.uncap_level)
setPreviousUncapValues(initialPreviousUncapValues)
}, [props])
// Update search grid whenever characters are updated
useEffect(() => {
let newSearchGrid = Object.values(characters).map((o) => o.character)
@ -131,11 +138,12 @@ const CharacterGrid = (props: Props) => {
// Methods: Updating uncap level
// Note: Saves, but debouncing is not working properly
async function saveUncap(id: string, position: number, uncapLevel: number) {
storePreviousUncapValue(position)
try {
await api.updateUncap('weapon', id, uncapLevel)
.then(response => {
storeGridCharacter(response.data.grid_character)
})
if (uncapLevel != previousUncapValues[position])
await api.updateUncap('weapon', id, uncapLevel)
.then(response => { storeGridCharacter(response.data.grid_character) })
} catch (error) {
console.error(error)
@ -153,11 +161,6 @@ const CharacterGrid = (props: Props) => {
(id: string, position: number, uncapLevel: number) => {
memoizeAction(id, position, uncapLevel)
// Save the current value in case of an unexpected result
let newPreviousValues = {...previousUncapValues}
newPreviousValues[position] = characters[position].uncap_level
setPreviousUncapValues(newPreviousValues)
// Optimistically update UI
updateUncapLevel(position, uncapLevel)
}, [previousUncapValues, characters]
@ -181,6 +184,14 @@ const CharacterGrid = (props: Props) => {
setCharacters(newCharacters)
}
function storePreviousUncapValue(position: number) {
// Save the current value in case of an unexpected result
let newPreviousValues = {...previousUncapValues}
newPreviousValues[position] = characters[position].uncap_level
setPreviousUncapValues(newPreviousValues)
}
// Render: JSX components
return (
<div className="CharacterGrid">

View file

@ -62,6 +62,15 @@ const SummonGrid = (props: Props) => {
// Create a state dictionary to store pure objects for Search
const [searchGrid, setSearchGrid] = useState<GridArray<Summon>>({})
// Initialize an array of current uncap values for each summon
useEffect(() => {
let initialPreviousUncapValues: {[key: number]: number} = {}
if (props.mainSummon) initialPreviousUncapValues[-1] = props.mainSummon.uncap_level
if (props.friendSummon) initialPreviousUncapValues[6] = props.friendSummon.uncap_level
Object.values(props.summons).map(o => initialPreviousUncapValues[o.position] = o.uncap_level)
setPreviousUncapValues(initialPreviousUncapValues)
}, [props])
// Set states from props
useEffect(() => {
setSummons(props.summons || {})
@ -138,11 +147,12 @@ const SummonGrid = (props: Props) => {
// Methods: Updating uncap level
// Note: Saves, but debouncing is not working properly
async function saveUncap(id: string, position: number, uncapLevel: number) {
storePreviousUncapValue(position)
try {
await api.updateUncap('summon', id, uncapLevel)
.then(response => {
storeGridSummon(response.data.grid_summon)
})
if (uncapLevel != previousUncapValues[position])
await api.updateUncap('summon', id, uncapLevel)
.then(response => { storeGridSummon(response.data.grid_summon) })
} catch (error) {
console.error(error)
@ -160,11 +170,6 @@ const SummonGrid = (props: Props) => {
(id: string, position: number, uncapLevel: number) => {
memoizeAction(id, position, uncapLevel)
// Save the current value in case of an unexpected result
let newPreviousValues = {...previousUncapValues}
newPreviousValues[position] = summons[position].uncap_level
setPreviousUncapValues(newPreviousValues)
// Optimistically update UI
updateUncapLevel(position, uncapLevel)
}, [previousUncapValues, summons]
@ -188,6 +193,17 @@ const SummonGrid = (props: Props) => {
setSummons(newSummons)
}
function storePreviousUncapValue(position: number) {
// Save the current value in case of an unexpected result
let newPreviousValues = {...previousUncapValues}
if (mainSummon && position == -1) newPreviousValues[position] = mainSummon.uncap_level
else if (friendSummon && position == 6) newPreviousValues[position] = friendSummon.uncap_level
else newPreviousValues[position] = summons[position].uncap_level
setPreviousUncapValues(newPreviousValues)
}
// Render: JSX components
const mainSummonElement = (
<div className="LabeledUnit">

View file

@ -68,6 +68,14 @@ const WeaponGrid = (props: Props) => {
setMainWeapon(props.mainhand)
}, [props])
// Initialize an array of current uncap values for each weapon
useEffect(() => {
let initialPreviousUncapValues: {[key: number]: number} = {}
if (props.mainhand) initialPreviousUncapValues[-1] = props.mainhand.uncap_level
Object.values(props.weapons).map(o => initialPreviousUncapValues[o.position] = o.uncap_level)
setPreviousUncapValues(initialPreviousUncapValues)
}, [props])
// Update search grid whenever weapons or the mainhand are updated
useEffect(() => {
let newSearchGrid = Object.values(weapons).map((o) => o.weapon)
@ -133,12 +141,12 @@ const WeaponGrid = (props: Props) => {
// Methods: Updating uncap level
// Note: Saves, but debouncing is not working properly
async function saveUncap(id: string, position: number, uncapLevel: number) {
// TODO: Don't make an API call if the new uncapLevel is the same as the current uncapLevel
storePreviousUncapValue(position)
try {
await api.updateUncap('weapon', id, uncapLevel)
.then(response => {
storeGridWeapon(response.data.grid_weapon)
})
if (uncapLevel != previousUncapValues[position])
await api.updateUncap('weapon', id, uncapLevel)
.then(response => { storeGridWeapon(response.data.grid_weapon) })
} catch (error) {
console.error(error)
@ -155,11 +163,6 @@ const WeaponGrid = (props: Props) => {
function initiateUncapUpdate(id: string, position: number, uncapLevel: number) {
memoizeAction(id, position, uncapLevel)
// Save the current value in case of an unexpected result
let newPreviousValues = {...previousUncapValues}
newPreviousValues[position] = (mainWeapon && position == -1) ? mainWeapon.uncap_level : weapons[position].uncap_level
setPreviousUncapValues(newPreviousValues)
// Optimistically update UI
updateUncapLevel(position, uncapLevel)
}
@ -167,7 +170,7 @@ const WeaponGrid = (props: Props) => {
const memoizeAction = useCallback(
(id: string, position: number, uncapLevel: number) => {
debouncedAction(id, position, uncapLevel)
}, [props]
}, [props, previousUncapValues]
)
const debouncedAction = useMemo(() =>
@ -187,6 +190,13 @@ const WeaponGrid = (props: Props) => {
}
}
function storePreviousUncapValue(position: number) {
// Save the current value in case of an unexpected result
let newPreviousValues = {...previousUncapValues}
newPreviousValues[position] = (mainWeapon && position == -1) ? mainWeapon.uncap_level : weapons[position].uncap_level
setPreviousUncapValues(newPreviousValues)
}
// Render: JSX components
const mainhandElement = (
<WeaponUnit