feat: show reaction counts and hide top zap/likes in feed
This commit is contained in:
@@ -5,7 +5,6 @@ import {
|
|||||||
DropdownMenuTrigger
|
DropdownMenuTrigger
|
||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
import { createReactionDraftEvent } from '@/lib/draft-event'
|
import { createReactionDraftEvent } from '@/lib/draft-event'
|
||||||
import { cn } from '@/lib/utils'
|
|
||||||
import { useNostr } from '@/providers/NostrProvider'
|
import { useNostr } from '@/providers/NostrProvider'
|
||||||
import { useNoteStats } from '@/providers/NoteStatsProvider'
|
import { useNoteStats } from '@/providers/NoteStatsProvider'
|
||||||
import { useScreenSize } from '@/providers/ScreenSizeProvider'
|
import { useScreenSize } from '@/providers/ScreenSizeProvider'
|
||||||
@@ -16,6 +15,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import Emoji from '../Emoji'
|
import Emoji from '../Emoji'
|
||||||
import EmojiPicker from '../EmojiPicker'
|
import EmojiPicker from '../EmojiPicker'
|
||||||
import SuggestedEmojis from '../SuggestedEmojis'
|
import SuggestedEmojis from '../SuggestedEmojis'
|
||||||
|
import { formatCount } from './utils'
|
||||||
|
|
||||||
export default function LikeButton({ event }: { event: Event }) {
|
export default function LikeButton({ event }: { event: Event }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@@ -25,10 +25,10 @@ export default function LikeButton({ event }: { event: Event }) {
|
|||||||
const [liking, setLiking] = useState(false)
|
const [liking, setLiking] = useState(false)
|
||||||
const [isEmojiReactionsOpen, setIsEmojiReactionsOpen] = useState(false)
|
const [isEmojiReactionsOpen, setIsEmojiReactionsOpen] = useState(false)
|
||||||
const [isPickerOpen, setIsPickerOpen] = useState(false)
|
const [isPickerOpen, setIsPickerOpen] = useState(false)
|
||||||
const myLastEmoji = useMemo(() => {
|
const { myLastEmoji, likeCount } = useMemo(() => {
|
||||||
const stats = noteStatsMap.get(event.id) || {}
|
const stats = noteStatsMap.get(event.id) || {}
|
||||||
const like = stats.likes?.find((like) => like.pubkey === pubkey)
|
const like = stats.likes?.find((like) => like.pubkey === pubkey)
|
||||||
return like?.emoji
|
return { myLastEmoji: like?.emoji, likeCount: stats.likes?.length }
|
||||||
}, [noteStatsMap, event, pubkey])
|
}, [noteStatsMap, event, pubkey])
|
||||||
|
|
||||||
const like = async (emoji: string) => {
|
const like = async (emoji: string) => {
|
||||||
@@ -58,10 +58,7 @@ export default function LikeButton({ event }: { event: Event }) {
|
|||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
<button
|
<button
|
||||||
className={cn(
|
className="flex items-center enabled:hover:text-primary gap-1 px-3 h-full text-muted-foreground"
|
||||||
'flex items-center enabled:hover:text-primary gap-1 px-3 h-full',
|
|
||||||
!myLastEmoji ? 'text-muted-foreground' : ''
|
|
||||||
)}
|
|
||||||
title={t('Like')}
|
title={t('Like')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (isSmallScreen) {
|
if (isSmallScreen) {
|
||||||
@@ -72,11 +69,17 @@ export default function LikeButton({ event }: { event: Event }) {
|
|||||||
{liking ? (
|
{liking ? (
|
||||||
<Loader className="animate-spin" />
|
<Loader className="animate-spin" />
|
||||||
) : myLastEmoji ? (
|
) : myLastEmoji ? (
|
||||||
<div className="h-5 w-5 flex items-center justify-center">
|
<>
|
||||||
<Emoji emoji={myLastEmoji} />
|
<div className="h-5 w-5 flex items-center justify-center">
|
||||||
</div>
|
<Emoji emoji={myLastEmoji} />
|
||||||
|
</div>
|
||||||
|
{!!likeCount && <div className="text-sm">{formatCount(likeCount)}</div>}
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<SmilePlus />
|
<>
|
||||||
|
<SmilePlus />
|
||||||
|
{!!likeCount && <div className="text-sm">{formatCount(likeCount)}</div>}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ export default function NoteStats({
|
|||||||
event,
|
event,
|
||||||
className,
|
className,
|
||||||
classNames,
|
classNames,
|
||||||
fetchIfNotExisting = false
|
fetchIfNotExisting = false,
|
||||||
|
displayTopZapsAndLikes = false
|
||||||
}: {
|
}: {
|
||||||
event: Event
|
event: Event
|
||||||
className?: string
|
className?: string
|
||||||
@@ -24,6 +25,7 @@ export default function NoteStats({
|
|||||||
buttonBar?: string
|
buttonBar?: string
|
||||||
}
|
}
|
||||||
fetchIfNotExisting?: boolean
|
fetchIfNotExisting?: boolean
|
||||||
|
displayTopZapsAndLikes?: boolean
|
||||||
}) {
|
}) {
|
||||||
const { isSmallScreen } = useScreenSize()
|
const { isSmallScreen } = useScreenSize()
|
||||||
const { fetchNoteStats } = useNoteStats()
|
const { fetchNoteStats } = useNoteStats()
|
||||||
@@ -38,8 +40,12 @@ export default function NoteStats({
|
|||||||
if (isSmallScreen) {
|
if (isSmallScreen) {
|
||||||
return (
|
return (
|
||||||
<div className={cn('select-none', className)}>
|
<div className={cn('select-none', className)}>
|
||||||
<TopZaps event={event} />
|
{displayTopZapsAndLikes && (
|
||||||
<Likes event={event} />
|
<>
|
||||||
|
<TopZaps event={event} />
|
||||||
|
<Likes event={event} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex justify-between items-center h-5 [&_svg]:size-5',
|
'flex justify-between items-center h-5 [&_svg]:size-5',
|
||||||
@@ -61,8 +67,12 @@ export default function NoteStats({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('select-none', className)}>
|
<div className={cn('select-none', className)}>
|
||||||
<TopZaps event={event} />
|
{displayTopZapsAndLikes && (
|
||||||
<Likes event={event} />
|
<>
|
||||||
|
<TopZaps event={event} />
|
||||||
|
<Likes event={event} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div className="flex justify-between h-5 [&_svg]:size-4">
|
<div className="flex justify-between h-5 [&_svg]:size-4">
|
||||||
<div
|
<div
|
||||||
className={cn('flex items-center', loading ? 'animate-pulse' : '')}
|
className={cn('flex items-center', loading ? 'animate-pulse' : '')}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export default function ReplyNote({
|
|||||||
{show ? (
|
{show ? (
|
||||||
<>
|
<>
|
||||||
<Content className="mt-2" event={event} />
|
<Content className="mt-2" event={event} />
|
||||||
<NoteStats className="mt-2" event={event} />
|
<NoteStats className="mt-2" event={event} displayTopZapsAndLikes />
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ const NotePage = forwardRef(({ id, index }: { id?: string; index?: number }, ref
|
|||||||
className="select-text"
|
className="select-text"
|
||||||
hideParentNotePreview
|
hideParentNotePreview
|
||||||
/>
|
/>
|
||||||
<NoteStats className="mt-3" event={event} fetchIfNotExisting />
|
<NoteStats className="mt-3" event={event} fetchIfNotExisting displayTopZapsAndLikes />
|
||||||
</div>
|
</div>
|
||||||
<Separator className="mt-4" />
|
<Separator className="mt-4" />
|
||||||
{event.kind === kinds.ShortTextNote ? (
|
{event.kind === kinds.ShortTextNote ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user