fix race condition caused by race condition fix

This commit is contained in:
keyan 2023-07-11 13:33:13 -05:00
parent 0ff4da1a4f
commit bc9081eaab
1 changed files with 49 additions and 48 deletions

View File

@ -6,7 +6,7 @@ import ActionTooltip from './action-tooltip'
import ItemAct from './item-act'
import { useMe } from './me'
import Rainbow from '../lib/rainbow'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import LongPressable from 'react-longpressable'
import { Overlay, Popover } from 'react-bootstrap'
import { useShowModal } from './modal'
@ -78,8 +78,6 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
}`
)
const fwd2me = me && Number(me?.id) === item?.fwdUserId
const setVoteShow = (yes) => {
if (!me) return
@ -117,8 +115,6 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
}
}`, {
update (cache, { data: { act: { sats } } }) {
setPendingSats(0)
cache.modify({
id: `Item:${item.id}`,
fields: {
@ -155,27 +151,28 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
}
)
// prevent updating pendingSats after unmount
useEffect(() => {
return () => { timerRef.current = null }
}, [])
// if we want to use optimistic response, we need to buffer the votes
// because if someone votes in quick succession, responses come back out of order
// so we wait a bit to see if there are more votes coming in
// this effectively performs our own debounced optimistic response
const bufferVotes = useCallback((sats) => {
useEffect(() => {
if (timerRef.current) {
clearTimeout(timerRef.current)
}
timerRef.current = setTimeout(async (pendingSats, sats) => {
if (pendingSats > 0) {
timerRef.current = setTimeout(async (pendingSats) => {
try {
timerRef.current && setPendingSats(0)
await act({
variables: { id: item.id, sats: pendingSats + sats }
variables: { id: item.id, sats: pendingSats },
optimisticResponse: {
act: {
sats: pendingSats
}
}
})
} catch (error) {
timerRef.current && setPendingSats(0)
if (error.toString().includes('insufficient funds')) {
showModal(onClose => {
return <FundError onClose={onClose} />
@ -184,11 +181,20 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
}
throw new Error({ message: error.toString() })
}
}, 1000, pendingSats, sats)
}, 1000, pendingSats)
}
timerRef.current && setPendingSats(pendingSats + sats)
return () => {
clearTimeout(timerRef.current)
timerRef.current = null
}
}, [item, pendingSats, act, setPendingSats, showModal])
const disabled = useMemo(() => {
return item?.mine || (me && Number(me.id) === item?.fwdUserId) || item?.deletedAt
}, [me?.id, item?.fwdUserId, item?.mine, item?.deletedAt])
const [meSats, sats, overlayText, color] = useMemo(() => {
const meSats = (item?.meSats || 0) + pendingSats
// what should our next tip be?
@ -202,13 +208,9 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
sats = raiseTip - meSats
}
const overlayText = () => {
return `${sats} sat${sats > 1 ? 's' : ''}`
}
return [meSats, sats, `${sats} sat${sats > 1 ? 's' : ''}`, getColor(meSats)]
}, [item?.meSats, pendingSats, me?.tipDefault, me?.turboDefault])
const disabled = item?.mine || fwd2me || item?.deletedAt
const color = getColor(meSats)
return (
<LightningConsumer>
{({ strike }) =>
@ -244,7 +246,7 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
strike()
bufferVotes(sats)
setPendingSats(pendingSats + sats)
}
: async () => await router.push({
pathname: '/signup',
@ -252,10 +254,9 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
})
}
>
<ActionTooltip notForm disable={disabled} overlayText={overlayText()}>
<ActionTooltip notForm disable={disabled} overlayText={overlayText}>
<div
className={`${disabled ? styles.noSelfTips : ''}
${styles.upvoteWrapper}`}
className={`${disabled ? styles.noSelfTips : ''} ${styles.upvoteWrapper}`}
>
<UpBolt
width={24}