index.tsx raw

   1  import { useStuff } from '@/hooks/useStuff'
   2  import { cn } from '@/lib/utils'
   3  import { useNostr } from '@/providers/NostrProvider'
   4  import { useScreenSize } from '@/providers/ScreenSizeProvider'
   5  import stuffStatsService from '@/services/stuff-stats.service'
   6  import { Event } from 'nostr-tools'
   7  import { useEffect, useState } from 'react'
   8  import BookmarkButton from '../BookmarkButton'
   9  import LikeButton from './LikeButton'
  10  import Likes from './Likes'
  11  import ReplyButton from './ReplyButton'
  12  import RepostButton from './RepostButton'
  13  import SeenOnButton from './SeenOnButton'
  14  import TopZaps from './TopZaps'
  15  import ZapButton from './ZapButton'
  16  
  17  export default function StuffStats({
  18    stuff,
  19    className,
  20    classNames,
  21    fetchIfNotExisting = false,
  22    displayTopZapsAndLikes = false,
  23    onReplyClick
  24  }: {
  25    stuff: Event | string
  26    className?: string
  27    classNames?: {
  28      buttonBar?: string
  29    }
  30    fetchIfNotExisting?: boolean
  31    displayTopZapsAndLikes?: boolean
  32    onReplyClick?: () => void
  33  }) {
  34    const { isSmallScreen } = useScreenSize()
  35    const { pubkey } = useNostr()
  36    const [loading, setLoading] = useState(false)
  37    const { event } = useStuff(stuff)
  38  
  39    useEffect(() => {
  40      if (!fetchIfNotExisting) return
  41      setLoading(true)
  42      stuffStatsService.fetchStuffStats(stuff, pubkey).finally(() => setLoading(false))
  43    }, [event, fetchIfNotExisting])
  44  
  45    if (isSmallScreen) {
  46      return (
  47        <div className={cn('select-none', className)} data-stuff-stats>
  48          {displayTopZapsAndLikes && (
  49            <>
  50              <TopZaps stuff={stuff} />
  51              <Likes stuff={stuff} />
  52            </>
  53          )}
  54          <div
  55            className={cn(
  56              'flex justify-between items-center h-5 [&_svg]:size-5',
  57              loading ? 'animate-pulse' : '',
  58              classNames?.buttonBar
  59            )}
  60            onClick={(e) => e.stopPropagation()}
  61          >
  62            <ReplyButton stuff={stuff} onReplyClick={onReplyClick} />
  63            <RepostButton stuff={stuff} />
  64            <LikeButton stuff={stuff} />
  65            <ZapButton stuff={stuff} />
  66            <BookmarkButton stuff={stuff} />
  67            <SeenOnButton stuff={stuff} />
  68          </div>
  69        </div>
  70      )
  71    }
  72  
  73    return (
  74      <div className={cn('select-none', className)} data-stuff-stats>
  75        {displayTopZapsAndLikes && (
  76          <>
  77            <TopZaps stuff={stuff} />
  78            <Likes stuff={stuff} />
  79          </>
  80        )}
  81        <div className="flex justify-between h-5 [&_svg]:size-4">
  82          <div
  83            className={cn('flex items-center', loading ? 'animate-pulse' : '')}
  84            onClick={(e) => e.stopPropagation()}
  85          >
  86            <ReplyButton stuff={stuff} onReplyClick={onReplyClick} />
  87            <RepostButton stuff={stuff} />
  88            <LikeButton stuff={stuff} />
  89            <ZapButton stuff={stuff} />
  90          </div>
  91          <div className="flex items-center" onClick={(e) => e.stopPropagation()}>
  92            <BookmarkButton stuff={stuff} />
  93            <SeenOnButton stuff={stuff} />
  94          </div>
  95        </div>
  96      </div>
  97    )
  98  }
  99