From 4f287432520eac2cdae65c9b45078c48507d2c3c Mon Sep 17 00:00:00 2001 From: Sinclair Chen Date: Wed, 22 Jun 2022 11:30:10 -0500 Subject: [PATCH] Non-quad tip UI (WIP) --- web/components/tipper.tsx | 126 ++++++++++---------------------------- 1 file changed, 32 insertions(+), 94 deletions(-) diff --git a/web/components/tipper.tsx b/web/components/tipper.tsx index 3b4d3603..57c15e05 100644 --- a/web/components/tipper.tsx +++ b/web/components/tipper.tsx @@ -1,3 +1,4 @@ +import { XIcon } from '@heroicons/react/outline' import { ChevronDoubleRightIcon, ChevronLeftIcon, @@ -7,7 +8,7 @@ import clsx from 'clsx' import { Comment } from 'common/comment' import { User } from 'common/user' import { formatMoney } from 'common/util/format' -import { debounce, sumBy } from 'lodash' +import { debounce, sum, sumBy } from 'lodash' import { useEffect, useMemo, useRef, useState } from 'react' import { CommentTips } from 'web/hooks/use-tip-txns' import { useUser } from 'web/hooks/use-user' @@ -16,33 +17,24 @@ import { track } from 'web/lib/service/analytics' import { Row } from './layout/row' import { Tooltip } from './tooltip' -// xth triangle number * 5 = 5 + 10 + 15 + ... + (x * 5) -const quad = (x: number) => (5 / 2) * x * (x + 1) - -// inverse (see https://math.stackexchange.com/questions/2041988/how-to-get-inverse-of-formula-for-sum-of-integers-from-1-to-nsee ) -const invQuad = (y: number) => Math.sqrt((2 / 5) * y + 1 / 4) - 1 / 2 - export function Tipper(prop: { comment: Comment; tips: CommentTips }) { const { comment, tips } = prop const me = useUser() const myId = me?.id ?? '' - const savedTip = tips[myId] as number | undefined + const savedTip = tips[myId] ?? 0 - // optimistically increase the tip count, but debounce the update - const [localTip, setLocalTip] = useState(savedTip ?? 0) + const [localTip, setLocalTip] = useState(savedTip) + // listen for user being set const initialized = useRef(false) useEffect(() => { - if (savedTip && !initialized.current) { - setLocalTip(savedTip) + if (tips[myId] && !initialized.current) { + setLocalTip(tips[myId]) initialized.current = true } - }, [savedTip]) + }, [tips, myId]) - const score = useMemo(() => { - const tipVals = Object.values({ ...tips, [myId]: localTip }) - return sumBy(tipVals, invQuad) - }, [localTip, tips, myId]) + const total = sum(Object.values(tips)) - savedTip + localTip // declare debounced function only on first render const [saveTip] = useState(() => @@ -80,87 +72,33 @@ export function Tipper(prop: { comment: Comment; tips: CommentTips }) { const changeTip = (tip: number) => { setLocalTip(tip) - me && saveTip(me, tip - (savedTip ?? 0)) + me && saveTip(me, tip - savedTip) } return ( - - - {Math.floor(score)} - - {localTip === 0 ? ( - '' - ) : ( - 0 ? 'text-primary' : 'text-red-400' - )} - > - ({formatMoney(localTip)} tip) - + + {total > 0 && {total}} + + + {localTip > 0 && ( + (+{localTip}) + )} + {/* undo button */} + {localTip > 0 && ( + )} ) } - -function DownTip(prop: { - value: number - onChange: (tip: number) => void - disabled?: boolean -}) { - const { onChange, value, disabled } = prop - const marginal = 5 * invQuad(value) - return ( - - - - ) -} - -function UpTip(prop: { - value: number - onChange: (tip: number) => void - disabled?: boolean -}) { - const { onChange, value, disabled } = prop - const marginal = 5 * invQuad(value) + 5 - - return ( - - - - ) -}