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 {
} from '@/components/ui/dropdown-menu' } from '@/components/ui/dropdown-menu'
import { ExtendedKind } from '@/constants' import { ExtendedKind } from '@/constants'
import { useNoteStatsById } from '@/hooks/useNoteStatsById' import { useNoteStatsById } from '@/hooks/useNoteStatsById'
import { createReactionDraftEvent } from '@/lib/draft-event' import { createDeletionRequestDraftEvent, createReactionDraftEvent } from '@/lib/draft-event'
import { getRootEventHexId } from '@/lib/event' import { getRootEventHexId } from '@/lib/event'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider' import { useScreenSize } from '@/providers/ScreenSizeProvider'
@ -79,9 +79,41 @@ export default function LikeButton({ event }: { event: Event }) {
await noteStatsService.fetchNoteStats(event, pubkey) await noteStatsService.fetchNoteStats(event, pubkey)
} }
const reaction = createReactionDraftEvent(event, emoji) // Check if user is clicking the same emoji they already reacted with
const evt = await publish(reaction) const emojiString = typeof emoji === 'string' ? emoji : emoji.shortcode
noteStatsService.updateNoteStatsByEvents([evt])
// 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) { } catch (error) {
console.error('like failed', error) console.error('like failed', error)
} finally { } finally {
@ -97,9 +129,14 @@ export default function LikeButton({ event }: { event: Event }) {
title={t('Like')} title={t('Like')}
disabled={liking || ((isDiscussion || isReplyToDiscussion) && hasVoted)} disabled={liking || ((isDiscussion || isReplyToDiscussion) && hasVoted)}
onClick={() => { onClick={() => {
if (isSmallScreen && !((isDiscussion || isReplyToDiscussion) && hasVoted)) { // If user has already reacted, clicking the button again should toggle it off
setIsEmojiReactionsOpen(true) if (myLastEmoji && !isEmojiReactionsOpen) {
like(myLastEmoji)
return
} }
// Otherwise, open the emoji picker
setIsEmojiReactionsOpen(true)
}} }}
> >
{liking ? ( {liking ? (

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

@ -250,6 +250,20 @@ class NoteStatsService {
return targetEventId 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) { private addRepostByEvent(evt: Event) {
const eventId = evt.tags.find(tagNameEquals('e'))?.[1] const eventId = evt.tags.find(tagNameEquals('e'))?.[1]
if (!eventId) return if (!eventId) return

Loading…
Cancel
Save