made tip jar thingy
This commit is contained in:
parent
4381911dbd
commit
c72d6c5df5
|
@ -82,3 +82,39 @@ export function Button(props: {
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function IconButton(props: {
|
||||||
|
className?: string
|
||||||
|
onClick?: MouseEventHandler<any> | undefined
|
||||||
|
children?: ReactNode
|
||||||
|
size?: SizeType
|
||||||
|
type?: 'button' | 'reset' | 'submit'
|
||||||
|
disabled?: boolean
|
||||||
|
loading?: boolean
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
onClick,
|
||||||
|
size = 'md',
|
||||||
|
type = 'button',
|
||||||
|
disabled = false,
|
||||||
|
loading,
|
||||||
|
} = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type={type}
|
||||||
|
className={clsx(
|
||||||
|
'inline-flex items-center justify-center transition-colors disabled:cursor-not-allowed',
|
||||||
|
sizeClasses[size],
|
||||||
|
'disabled:text-greyscale-2 text-greyscale-6 hover:text-indigo-600',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
disabled={disabled || loading}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { HeartIcon } from '@heroicons/react/outline'
|
|
||||||
|
|
||||||
import { Button } from 'web/components/button'
|
|
||||||
import { formatMoney, shortFormatNumber } from 'common/util/format'
|
import { formatMoney, shortFormatNumber } from 'common/util/format'
|
||||||
import { Col } from 'web/components/layout/col'
|
import { Col } from 'web/components/layout/col'
|
||||||
import { Tooltip } from '../tooltip'
|
import { Tooltip } from '../tooltip'
|
||||||
import TipJar from 'web/public/custom-components/tipJar'
|
import TipJar from 'web/public/custom-components/tipJar'
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
export function TipButton(props: {
|
export function TipButton(props: {
|
||||||
tipAmount: number
|
tipAmount: number
|
||||||
|
@ -20,6 +18,8 @@ export function TipButton(props: {
|
||||||
|
|
||||||
const tipDisplay = shortFormatNumber(Math.ceil(totalTipped / 10))
|
const tipDisplay = shortFormatNumber(Math.ceil(totalTipped / 10))
|
||||||
|
|
||||||
|
const [hover, setHover] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
text={
|
text={
|
||||||
|
@ -31,35 +31,39 @@ export function TipButton(props: {
|
||||||
noTap
|
noTap
|
||||||
noFade
|
noFade
|
||||||
>
|
>
|
||||||
<Button
|
<button
|
||||||
size={'sm'}
|
|
||||||
className={clsx(
|
|
||||||
'max-w-xs self-center',
|
|
||||||
isCompact && 'px-0 py-0',
|
|
||||||
disabled && 'hover:bg-inherit'
|
|
||||||
)}
|
|
||||||
color={'gray-white'}
|
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
className={clsx(
|
||||||
|
'text-greyscale-6 transition-transform hover:text-indigo-600 disabled:cursor-not-allowed',
|
||||||
|
!disabled ? 'hover:rotate-12' : ''
|
||||||
|
)}
|
||||||
|
onMouseOver={() => setHover(true)}
|
||||||
|
onMouseLeave={() => setHover(false)}
|
||||||
>
|
>
|
||||||
<Col
|
<Col className={clsx('relative', disabled ? 'opacity-30' : '')}>
|
||||||
className={
|
<TipJar
|
||||||
'relative items-center transition-transform hover:rotate-12 sm:flex-row'
|
size={16}
|
||||||
}
|
color={hover || userTipped ? '#4f46e5' : '#66667C'}
|
||||||
>
|
fill={userTipped ? '#4f46e5' : 'none'}
|
||||||
<TipJar />
|
/>
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'bg-greyscale-5 absolute rounded-full text-white',
|
' absolute top-[3px] text-[0.5rem]',
|
||||||
tipDisplay.length > 2
|
userTipped ? 'text-white' : '',
|
||||||
? 'text-[0.4rem] sm:text-[0.5rem]'
|
tipDisplay.length === 1
|
||||||
: 'text-[0.5rem]'
|
? 'left-[6px]'
|
||||||
|
: tipDisplay.length === 2
|
||||||
|
? 'left-[3.5px]'
|
||||||
|
: tipDisplay.length > 2
|
||||||
|
? 'left-[3px] top-[5px] text-[0.35rem]'
|
||||||
|
: ''
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{totalTipped > 0 ? tipDisplay : ''}
|
{totalTipped > 0 ? tipDisplay : ''}
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { UserLink } from 'web/components/user-link'
|
||||||
import { CommentInput } from '../comment-input'
|
import { CommentInput } from '../comment-input'
|
||||||
import { AwardBountyButton } from 'web/components/award-bounty-button'
|
import { AwardBountyButton } from 'web/components/award-bounty-button'
|
||||||
import { ReplyIcon } from '@heroicons/react/solid'
|
import { ReplyIcon } from '@heroicons/react/solid'
|
||||||
import { Button } from '../button'
|
import { IconButton } from '../button'
|
||||||
import { ReplyToggle } from '../comments/reply-toggle'
|
import { ReplyToggle } from '../comments/reply-toggle'
|
||||||
|
|
||||||
export type ReplyTo = { id: string; username: string }
|
export type ReplyTo = { id: string; username: string }
|
||||||
|
@ -154,36 +154,50 @@ export function ParentFeedComment(props: {
|
||||||
numComments={numComments}
|
numComments={numComments}
|
||||||
onClick={onSeeReplyClick}
|
onClick={onSeeReplyClick}
|
||||||
/>
|
/>
|
||||||
<Row className="grow justify-end gap-2">
|
<CommentActions
|
||||||
{onReplyClick && (
|
onReplyClick={onReplyClick}
|
||||||
<Button
|
comment={comment}
|
||||||
size={'sm'}
|
showTip={showTip}
|
||||||
className={clsx(
|
myTip={myTip}
|
||||||
'hover:bg-greyscale-2 mt-0 mb-1 max-w-xs px-0 py-0'
|
totalTip={totalTip}
|
||||||
)}
|
contract={contract}
|
||||||
color={'gray-white'}
|
/>
|
||||||
onClick={() => onReplyClick(comment)}
|
|
||||||
>
|
|
||||||
<ReplyIcon className="h-5 w-5" />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{showTip && (
|
|
||||||
<Tipper
|
|
||||||
comment={comment}
|
|
||||||
myTip={myTip ?? 0}
|
|
||||||
totalTip={totalTip ?? 0}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{(contract.openCommentBounties ?? 0) > 0 && (
|
|
||||||
<AwardBountyButton comment={comment} contract={contract} />
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function CommentActions(props: {
|
||||||
|
onReplyClick?: (comment: ContractComment) => void
|
||||||
|
comment: ContractComment
|
||||||
|
showTip?: boolean
|
||||||
|
myTip?: number
|
||||||
|
totalTip?: number
|
||||||
|
contract: Contract
|
||||||
|
}) {
|
||||||
|
const { onReplyClick, comment, showTip, myTip, totalTip, contract } = props
|
||||||
|
return (
|
||||||
|
<Row className="grow justify-end gap-2">
|
||||||
|
{onReplyClick && (
|
||||||
|
<IconButton
|
||||||
|
size={'xs'}
|
||||||
|
className={clsx('mt-0 mb-1 max-w-xs')}
|
||||||
|
onClick={() => onReplyClick(comment)}
|
||||||
|
>
|
||||||
|
<ReplyIcon className="h-4 w-4" />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
{showTip && (
|
||||||
|
<Tipper comment={comment} myTip={myTip ?? 0} totalTip={totalTip ?? 0} />
|
||||||
|
)}
|
||||||
|
{(contract.openCommentBounties ?? 0) > 0 && (
|
||||||
|
<AwardBountyButton comment={comment} contract={contract} />
|
||||||
|
)}
|
||||||
|
</Row>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const FeedComment = memo(function FeedComment(props: {
|
export const FeedComment = memo(function FeedComment(props: {
|
||||||
contract: Contract
|
contract: Contract
|
||||||
comment: ContractComment
|
comment: ContractComment
|
||||||
|
@ -233,30 +247,14 @@ export const FeedComment = memo(function FeedComment(props: {
|
||||||
content={content || text}
|
content={content || text}
|
||||||
smallImage
|
smallImage
|
||||||
/>
|
/>
|
||||||
<Row className="grow justify-end gap-2">
|
<CommentActions
|
||||||
{onReplyClick && (
|
onReplyClick={onReplyClick}
|
||||||
<Button
|
comment={comment}
|
||||||
size={'sm'}
|
showTip={showTip}
|
||||||
className={clsx(
|
myTip={myTip}
|
||||||
'hover:bg-greyscale-2 mt-0 mb-1 max-w-xs px-0 py-0'
|
totalTip={totalTip}
|
||||||
)}
|
contract={contract}
|
||||||
color={'gray-white'}
|
/>
|
||||||
onClick={() => onReplyClick(comment)}
|
|
||||||
>
|
|
||||||
<ReplyIcon className="h-5 w-5" />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{showTip && (
|
|
||||||
<Tipper
|
|
||||||
comment={comment}
|
|
||||||
myTip={myTip ?? 0}
|
|
||||||
totalTip={totalTip ?? 0}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{(contract.openCommentBounties ?? 0) > 0 && (
|
|
||||||
<AwardBountyButton comment={comment} contract={contract} />
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
|
|
23
web/public/custom-components/tipJar.tsx
Normal file
23
web/public/custom-components/tipJar.tsx
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export default function TipJar({
|
||||||
|
size = 18,
|
||||||
|
color = '#66667C',
|
||||||
|
strokeWidth = 1.5,
|
||||||
|
fill = 'none',
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 18 18"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
fill={fill}
|
||||||
|
stroke={color}
|
||||||
|
strokeWidth={strokeWidth}
|
||||||
|
opacity={50}
|
||||||
|
>
|
||||||
|
<path d="M15.5,8.1v5.8c0,1.43-1.16,2.6-2.6,2.6H5.1c-1.44,0-2.6-1.16-2.6-2.6v-5.8c0-1.04,.89-3.25,1.5-4.1h0v-2c0-.55,.45-1,1-1H13c.55,0,1,.45,1,1v2h0c.61,.85,1.5,3.06,1.5,4.1Z" />
|
||||||
|
<line x1="4" y1="4" x2="9" y2="4" />
|
||||||
|
<line x1="11.26" y1="4" x2="14" y2="4" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user