Browse Source

toggle off emojis

imwald
Silberengel 5 months ago
parent
commit
a66c1074a4
  1. 49
      src/components/NoteStats/LikeButton.tsx
  2. 14
      src/services/note-stats.service.ts

49
src/components/NoteStats/LikeButton.tsx

@ -6,7 +6,7 @@ import { @@ -6,7 +6,7 @@ import {
} from '@/components/ui/dropdown-menu'
import { ExtendedKind } from '@/constants'
import { useNoteStatsById } from '@/hooks/useNoteStatsById'
import { createReactionDraftEvent } from '@/lib/draft-event'
import { createDeletionRequestDraftEvent, createReactionDraftEvent } from '@/lib/draft-event'
import { getRootEventHexId } from '@/lib/event'
import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
@ -79,9 +79,41 @@ export default function LikeButton({ event }: { event: Event }) { @@ -79,9 +79,41 @@ export default function LikeButton({ event }: { event: Event }) {
await noteStatsService.fetchNoteStats(event, pubkey)
}
const reaction = createReactionDraftEvent(event, emoji)
const evt = await publish(reaction)
noteStatsService.updateNoteStatsByEvents([evt])
// Check if user is clicking the same emoji they already reacted with
const emojiString = typeof emoji === 'string' ? emoji : emoji.shortcode
// Normalize myLastEmoji for comparison
const myLastEmojiString = typeof myLastEmoji === 'string' ? myLastEmoji : typeof myLastEmoji === 'object' ? myLastEmoji.shortcode : undefined
const isTogglingOff = myLastEmojiString === emojiString
console.log('Toggle check:', { myLastEmoji, myLastEmojiString, emojiString, isTogglingOff, myLikes: noteStats?.likes?.filter(l => l.pubkey === pubkey) })
if (isTogglingOff) {
// User wants to toggle off - find their previous reaction and delete it
const myReaction = noteStats?.likes?.find((like) => {
if (like.pubkey !== pubkey) return false
const likeEmojiString = typeof like.emoji === 'string' ? like.emoji : like.emoji.shortcode
return likeEmojiString === emojiString
})
if (myReaction) {
// Optimistically update the UI immediately
noteStatsService.removeLike(event.id, myReaction.id)
// Fetch the actual reaction event
const reactionEvent = await client.fetchEvent(myReaction.id)
if (reactionEvent) {
// Create and publish a deletion request (kind 5)
const deletionRequest = createDeletionRequestDraftEvent(reactionEvent)
await publish(deletionRequest)
}
}
} else {
// User is adding a new reaction
const reaction = createReactionDraftEvent(event, emoji)
const evt = await publish(reaction)
noteStatsService.updateNoteStatsByEvents([evt])
}
} catch (error) {
console.error('like failed', error)
} finally {
@ -97,9 +129,14 @@ export default function LikeButton({ event }: { event: Event }) { @@ -97,9 +129,14 @@ export default function LikeButton({ event }: { event: Event }) {
title={t('Like')}
disabled={liking || ((isDiscussion || isReplyToDiscussion) && hasVoted)}
onClick={() => {
if (isSmallScreen && !((isDiscussion || isReplyToDiscussion) && hasVoted)) {
setIsEmojiReactionsOpen(true)
// If user has already reacted, clicking the button again should toggle it off
if (myLastEmoji && !isEmojiReactionsOpen) {
like(myLastEmoji)
return
}
// Otherwise, open the emoji picker
setIsEmojiReactionsOpen(true)
}}
>
{liking ? (

14
src/services/note-stats.service.ts

@ -250,6 +250,20 @@ class NoteStatsService { @@ -250,6 +250,20 @@ class NoteStatsService {
return targetEventId
}
removeLike(eventId: string, reactionEventId: string) {
const old = this.noteStatsMap.get(eventId) || {}
const likeIdSet = old.likeIdSet || new Set()
const likes = old.likes || []
if (!likeIdSet.has(reactionEventId)) return eventId
likeIdSet.delete(reactionEventId)
const newLikes = likes.filter(like => like.id !== reactionEventId)
this.noteStatsMap.set(eventId, { ...old, likeIdSet, likes: newLikes })
this.notifyNoteStats(eventId)
return eventId
}
private addRepostByEvent(evt: Event) {
const eventId = evt.tags.find(tagNameEquals('e'))?.[1]
if (!eventId) return

Loading…
Cancel
Save