161 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { useEffect } from 'react'
 | |
| import Table from 'react-bootstrap/Table'
 | |
| import ActionTooltip from './action-tooltip'
 | |
| import Info from './info'
 | |
| import styles from './fee-button.module.css'
 | |
| import { gql, useQuery } from '@apollo/client'
 | |
| import { useFormikContext } from 'formik'
 | |
| import { SSR, ANON_COMMENT_FEE, ANON_POST_FEE } from '../lib/constants'
 | |
| import { numWithUnits } from '../lib/format'
 | |
| import { useMe } from './me'
 | |
| import AnonIcon from '../svgs/spy-fill.svg'
 | |
| import { useShowModal } from './modal'
 | |
| import Link from 'next/link'
 | |
| 
 | |
| function Receipt ({ cost, repetition, hasImgLink, baseFee, parentId, boost }) {
 | |
|   return (
 | |
|     <Table className={styles.receipt} borderless size='sm'>
 | |
|       <tbody>
 | |
|         <tr>
 | |
|           <td>{numWithUnits(baseFee, { abbreviate: false })}</td>
 | |
|           <td align='right' className='font-weight-light'>{parentId ? 'reply' : 'post'} fee</td>
 | |
|         </tr>
 | |
|         {hasImgLink &&
 | |
|           <tr>
 | |
|             <td>x 10</td>
 | |
|             <td align='right' className='font-weight-light'>image/link fee</td>
 | |
|           </tr>}
 | |
|         {repetition > 0 &&
 | |
|           <tr>
 | |
|             <td>x 10<sup>{repetition}</sup></td>
 | |
|             <td className='font-weight-light' align='right'>{repetition} {parentId ? 'repeat or self replies' : 'posts'} in 10m</td>
 | |
|           </tr>}
 | |
|         {boost > 0 &&
 | |
|           <tr>
 | |
|             <td>+ {numWithUnits(boost, { abbreviate: false })}</td>
 | |
|             <td className='font-weight-light' align='right'>boost</td>
 | |
|           </tr>}
 | |
|       </tbody>
 | |
|       <tfoot>
 | |
|         <tr>
 | |
|           <td className='fw-bold'>{numWithUnits(cost, { abbreviate: false })}</td>
 | |
|           <td align='right' className='font-weight-light'>total fee</td>
 | |
|         </tr>
 | |
|       </tfoot>
 | |
|     </Table>
 | |
|   )
 | |
| }
 | |
| 
 | |
| function AnonInfo () {
 | |
|   const showModal = useShowModal()
 | |
| 
 | |
|   return (
 | |
|     <AnonIcon
 | |
|       className='fill-muted ms-2 theme' height={22} width={22}
 | |
|       onClick={
 | |
|         (e) =>
 | |
|           showModal(onClose =>
 | |
|             <div><div className='fw-bold text-center'>You are posting without an account</div>
 | |
|               <ol className='my-3'>
 | |
|                 <li>You'll pay by invoice</li>
 | |
|                 <li>Your content will be content-joined (get it?!) under the <Link href='/anon' target='_blank'>@anon</Link> account</li>
 | |
|                 <li>Any sats your content earns will go toward <Link href='/rewards' target='_blank'>rewards</Link></li>
 | |
|                 <li>We won't be able to notify you when you receive replies</li>
 | |
|               </ol>
 | |
|               <small className='text-center fst-italic text-muted'>btw if you don't need to be anonymous, posting is cheaper with an account</small>
 | |
|             </div>)
 | |
|       }
 | |
|     />
 | |
|   )
 | |
| }
 | |
| 
 | |
| export default function FeeButton ({ parentId, hasImgLink, baseFee, ChildButton, variant, text, alwaysShow, disabled }) {
 | |
|   const me = useMe()
 | |
|   baseFee = me ? baseFee : (parentId ? ANON_COMMENT_FEE : ANON_POST_FEE)
 | |
|   const query = parentId
 | |
|     ? gql`{ itemRepetition(parentId: "${parentId}") }`
 | |
|     : gql`{ itemRepetition }`
 | |
|   const { data } = useQuery(query, SSR ? {} : { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' })
 | |
|   const repetition = me ? data?.itemRepetition || 0 : 0
 | |
|   const formik = useFormikContext()
 | |
|   const boost = Number(formik?.values?.boost) || 0
 | |
|   const cost = baseFee * (hasImgLink ? 10 : 1) * Math.pow(10, repetition) + Number(boost)
 | |
| 
 | |
|   useEffect(() => {
 | |
|     formik?.setFieldValue('cost', cost)
 | |
|   }, [formik?.getFieldProps('cost').value, cost])
 | |
| 
 | |
|   const show = alwaysShow || !formik?.isSubmitting
 | |
|   return (
 | |
|     <div className={styles.feeButton}>
 | |
|       <ActionTooltip overlayText={numWithUnits(cost, { abbreviate: false })}>
 | |
|         <ChildButton variant={variant} disabled={disabled}>{text}{cost > 1 && show && <small> {numWithUnits(cost, { abbreviate: false })}</small>}</ChildButton>
 | |
|       </ActionTooltip>
 | |
|       {!me && <AnonInfo />}
 | |
|       {cost > baseFee && show &&
 | |
|         <Info>
 | |
|           <Receipt baseFee={baseFee} hasImgLink={hasImgLink} repetition={repetition} cost={cost} parentId={parentId} boost={boost} />
 | |
|         </Info>}
 | |
|     </div>
 | |
|   )
 | |
| }
 | |
| 
 | |
| function EditReceipt ({ cost, paidSats, addImgLink, boost, parentId }) {
 | |
|   return (
 | |
|     <Table className={styles.receipt} borderless size='sm'>
 | |
|       <tbody>
 | |
|         {addImgLink &&
 | |
|           <>
 | |
|             <tr>
 | |
|               <td>{numWithUnits(paidSats, { abbreviate: false })}</td>
 | |
|               <td align='right' className='font-weight-light'>{parentId ? 'reply' : 'post'} fee</td>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td>x 10</td>
 | |
|               <td align='right' className='font-weight-light'>image/link fee</td>
 | |
|             </tr>
 | |
|             <tr>
 | |
|               <td>- {numWithUnits(paidSats, { abbreviate: false })}</td>
 | |
|               <td align='right' className='font-weight-light'>already paid</td>
 | |
|             </tr>
 | |
|           </>}
 | |
|         {boost > 0 &&
 | |
|           <tr>
 | |
|             <td>+ {numWithUnits(boost, { abbreviate: false })}</td>
 | |
|             <td className='font-weight-light' align='right'>boost</td>
 | |
|           </tr>}
 | |
|       </tbody>
 | |
|       <tfoot>
 | |
|         <tr>
 | |
|           <td className='fw-bold'>{numWithUnits(cost)}</td>
 | |
|           <td align='right' className='font-weight-light'>total fee</td>
 | |
|         </tr>
 | |
|       </tfoot>
 | |
|     </Table>
 | |
|   )
 | |
| }
 | |
| 
 | |
| export function EditFeeButton ({ paidSats, hadImgLink, hasImgLink, ChildButton, variant, text, alwaysShow, parentId }) {
 | |
|   const formik = useFormikContext()
 | |
|   const boost = (formik?.values?.boost || 0) - (formik?.initialValues?.boost || 0)
 | |
|   const addImgLink = hasImgLink && !hadImgLink
 | |
|   const cost = (addImgLink ? paidSats * 9 : 0) + Number(boost)
 | |
| 
 | |
|   useEffect(() => {
 | |
|     formik?.setFieldValue('cost', cost)
 | |
|   }, [formik?.getFieldProps('cost').value, cost])
 | |
| 
 | |
|   const show = alwaysShow || !formik?.isSubmitting
 | |
|   return (
 | |
|     <div className='d-flex align-items-center'>
 | |
|       <ActionTooltip overlayText={numWithUnits(cost >= 0 ? cost : 0, { abbreviate: false })}>
 | |
|         <ChildButton variant={variant}>{text}{cost > 0 && show && <small> {numWithUnits(cost, { abbreviate: false })}</small>}</ChildButton>
 | |
|       </ActionTooltip>
 | |
|       {cost > 0 && show &&
 | |
|         <Info>
 | |
|           <EditReceipt paidSats={paidSats} addImgLink={addImgLink} cost={cost} parentId={parentId} boost={boost} />
 | |
|         </Info>}
 | |
|     </div>
 | |
|   )
 | |
| }
 |