diff --git a/components/comment.js b/components/comment.js index b84ec2e4..036d8768 100644 --- a/components/comment.js +++ b/components/comment.js @@ -25,7 +25,7 @@ import Skull from '@/svgs/death-skull.svg' import { commentSubTreeRootId } from '@/lib/item' import Pin from '@/svgs/pushpin-fill.svg' import LinkToContext from './link-to-context' -import { ItemContextProvider } from './item' +import { ItemContextProvider, useItemContext } from './item' function Parent ({ item, rootText }) { const root = useRoot() @@ -144,11 +144,7 @@ export default function Comment ({ onTouchStart={() => ref.current.classList.add('outline-new-comment-unset')} >
- {item.outlawed && !me?.privates?.wildWestMode - ? - : item.meDontLikeSats > item.meSats - ? - : pin ? : } +
{item.user?.meMute && !includeParent && collapse === 'yep' @@ -250,6 +246,20 @@ export default function Comment ({ ) } +function ZapIcon ({ item, pin }) { + const me = useMe() + const { pendingSats, pendingDownSats } = useItemContext() + + const meSats = item.meSats + pendingSats + const downSats = item.meDontLikeSats + pendingDownSats + + return item.outlawed && !me?.privates?.wildWestMode + ? + : downSats > meSats + ? + : pin ? : +} + export function CommentSkeleton ({ skeletonChildren }) { return (
diff --git a/components/dont-link-this.js b/components/dont-link-this.js index bb5cb761..1c90dba2 100644 --- a/components/dont-link-this.js +++ b/components/dont-link-this.js @@ -4,18 +4,24 @@ import { useToast } from './toast' import ItemAct from './item-act' import AccordianItem from './accordian-item' import Flag from '@/svgs/flag-fill.svg' -import { useMemo } from 'react' +import { useCallback, useMemo } from 'react' import getColor from '@/lib/rainbow' import { gql, useMutation } from '@apollo/client' +import { useItemContext } from './item' +import { useLightning } from './lightning' export function DownZap ({ item, ...props }) { + const { pendingDownSats } = useItemContext() const { meDontLikeSats } = item - const style = useMemo(() => (meDontLikeSats + + const downSats = meDontLikeSats + pendingDownSats + + const style = useMemo(() => (downSats ? { - fill: getColor(meDontLikeSats), - filter: `drop-shadow(0 0 6px ${getColor(meDontLikeSats)}90)` + fill: getColor(downSats), + filter: `drop-shadow(0 0 6px ${getColor(downSats)}90)` } - : undefined), [meDontLikeSats]) + : undefined), [downSats]) return ( } /> ) @@ -24,6 +30,17 @@ export function DownZap ({ item, ...props }) { function DownZapper ({ item, As, children }) { const toaster = useToast() const showModal = useShowModal() + const strike = useLightning() + const { setPendingDownSats } = useItemContext() + + const optimisticUpdate = useCallback((sats, { onClose } = {}) => { + setPendingDownSats(pendingSats => pendingSats + sats) + strike() + onClose?.() + return () => { + setPendingDownSats(pendingSats => pendingSats - sats) + } + }, []) return ( { @@ -58,6 +58,8 @@ export default function ItemInfo ({ const rootReply = item.path.split('.').length === 2 const canPin = (isPost && mySub) || (myPost && rootReply) + const downSats = item.meDontLikeSats + pendingDownSats + return (
{!(item.position && (pinnable || !item.subName)) && !(!item.parentId && Number(item.user?.id) === USER_ID.ad) && @@ -68,8 +70,8 @@ export default function ItemInfo ({ unitPlural: 'stackers' })} ${item.mine ? `\\ ${numWithUnits(item.meSats, { abbreviate: false })} to post` - : `(${numWithUnits(meTotalSats, { abbreviate: false })}${item.meDontLikeSats - ? ` & ${numWithUnits(item.meDontLikeSats, { abbreviate: false, unitSingular: 'downsat', unitPlural: 'downsats' })}` + : `(${numWithUnits(meTotalSats, { abbreviate: false })}${downSats + ? ` & ${numWithUnits(downSats, { abbreviate: false, unitSingular: 'downsat', unitPlural: 'downsats' })}` : ''} from me)`} `} > {numWithUnits(item.sats + pendingSats)} @@ -179,7 +181,7 @@ export default function ItemInfo ({ } {me && !item.position && !item.mine && !item.deletedAt && - (item.meDontLikeSats > meTotalSats + (downSats > meTotalSats ? : )} {me && sub && !item.mine && !item.outlawed && Number(me.id) === Number(sub.userId) && sub.moderated && diff --git a/components/item.js b/components/item.js index b05684ed..ffbd97e8 100644 --- a/components/item.js +++ b/components/item.js @@ -49,7 +49,9 @@ const ItemContext = createContext({ pendingSats: 0, setPendingSats: undefined, pendingVote: undefined, - setPendingVote: undefined + setPendingVote: undefined, + pendingDownSats: 0, + setPendingDownSats: undefined }) export const ItemContextProvider = ({ children }) => { @@ -57,6 +59,7 @@ export const ItemContextProvider = ({ children }) => { const [pendingSats, innerSetPendingSats] = useState(0) const [pendingCommentSats, innerSetPendingCommentSats] = useState(0) const [pendingVote, setPendingVote] = useState() + const [pendingDownSats, setPendingDownSats] = useState(0) // cascade comment sats up to root context const setPendingSats = useCallback((sats) => { @@ -76,9 +79,11 @@ export const ItemContextProvider = ({ children }) => { pendingCommentSats, setPendingCommentSats, pendingVote, - setPendingVote + setPendingVote, + pendingDownSats, + setPendingDownSats }), - [pendingSats, setPendingSats, pendingCommentSats, setPendingCommentSats, pendingVote, setPendingVote]) + [pendingSats, setPendingSats, pendingCommentSats, setPendingCommentSats, pendingVote, setPendingVote, pendingDownSats, setPendingDownSats]) return {children} } @@ -101,13 +106,7 @@ export default function Item ({ item, rank, belowTitle, right, full, children, s
) :
}
- {item.position && (pinnable || !item.subName) - ? - : item.meDontLikeSats > item.meSats - ? - : Number(item.user?.id) === USER_ID.ad - ? - : } +
+ : downSats > meSats + ? + : Number(item.user?.id) === USER_ID.ad + ? + : +} + function PollIndicator ({ item }) { const hasExpiration = !!item.pollExpiresAt const timeRemaining = timeLeft(new Date(item.pollExpiresAt)) diff --git a/components/upvote.js b/components/upvote.js index 0beab754..1cf100e5 100644 --- a/components/upvote.js +++ b/components/upvote.js @@ -56,12 +56,23 @@ const TipPopover = ({ target, show, handleClose }) => ( export function DropdownItemUpVote ({ item }) { const showModal = useShowModal() + const { setPendingSats } = useItemContext() + const strike = useLightning() + + const optimisticUpdate = useCallback((sats, { onClose } = {}) => { + setPendingSats(pendingSats => pendingSats + sats) + strike() + onClose?.() + return () => { + setPendingSats(pendingSats => pendingSats - sats) + } + }, []) return ( { showModal(onClose => - ) + ) }} > zap