Skip to content

feat(reactions): undo reactions/reposts, expanded catalog, adaptive recent list#192

Merged
barrydeen merged 6 commits into
feat/nip78-settings-syncfrom
feat/emoji-reactions
May 26, 2026
Merged

feat(reactions): undo reactions/reposts, expanded catalog, adaptive recent list#192
barrydeen merged 6 commits into
feat/nip78-settings-syncfrom
feat/emoji-reactions

Conversation

@dmnyc

@dmnyc dmnyc commented May 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Three improvements to the emoji reaction experience, built on top of the NIP-78 cross-device settings sync branch so the adaptive quick list syncs across devices automatically.

  • Undo reactions — tapping the heart on a post you've already reacted to shows a "Remove Reaction" confirmation popover (matching the repost undo pattern). Confirmed removal sends a NIP-09 kind-5 deletion and removes the reaction optimistically.
  • Undo repost — the repost popover shows "Undo Repost" (in red) when you've already reposted, using NIP-09 kind-5 deletion.
  • Expanded emoji catalog — ~300 additional entries across all categories (Emoji 13–15: new faces, hand gestures, animals, food, activities, travel, objects, symbols).
  • Adaptive recent list — any emoji you react with is automatically added to your quick-reaction picker on first use, including emojis picked from the full library. The existing frequency sort ensures often-used emojis rise to the top; long-press any cell to remove it. The quick list and frequency map are included in the NIP-78 kind-30078 settings payload so the adapted list syncs across devices.
  • Reaction picker UX fixes — quick-reaction grid is capped at 18 (3 rows × 6 columns, no scrolling). "More reactions" is pinned as a centered footer row that is always visible regardless of list length. Popover arrow now matches the body material.

Base branch: feat/nip78-settings-sync — the NIP-78 sync infrastructure is a prerequisite. This PR should merge after #173.

Implementation notes

  • DeletionSender.deleteById() — new helper for undo flows when only the event ID is known.
  • EngagementCounts.reposterEventIds — maps pubkey → kind-6 event ID so repost undo knows which event to delete.
  • Reactor.reactionEventId — populated after signing or on relay ingest for reaction undo.
  • ReactionSender.clearSent() / RepostSender.clearSent() — reset local sent-state so re-reacting/reposting works after an undo.
  • EmojiRepository.setFrequency(_:) — restore-only setter that skips the sync trigger.
  • Reaction undo uses a dedicated showRemoveReactionMenu popover (same pattern as repost) rather than an inline button, preventing accidental dismissal from triggering removal.
  • EmojiReactionPicker no longer carries a ScrollView or maxGridHeight parameter — fixed grid + pinned footer eliminates the scroll-hides-plus-button problem.

Test plan

  • Tap the heart on a post → emoji picker opens. Pick an emoji → reaction appears, count increments.
  • Tap the heart again on a post you've already reacted to → "Remove Reaction" popover appears; tapping it removes the reaction. Dismissing without tapping does nothing.
  • Open and close the "Remove Reaction" popover repeatedly — reaction stays until explicitly confirmed.
  • Long-press the repost icon on a post you've reposted → "Undo Repost" appears in red. Tap it → repost removed.
  • React with an emoji not in your quick list → it auto-appears in the picker next time.
  • Pick an emoji from the full library (+) and use it as a reaction → it is added to the quick list.
  • Use the same emoji several times → it rises toward the top of the picker grid.
  • Long-press a cell in the picker → "Remove from quick reactions" removes it.
  • With more than 18 quick reactions, confirm the grid shows exactly 3 rows and "More reactions" footer is always visible without scrolling.
  • Confirm the popover arrow color matches the popup body in both light and dark mode.
  • Open the full emoji library (+) → confirm ~300 new emojis are present across categories.
  • Sign in on a second device after reacting on the first → quick list and frequency map sync via NIP-78 (requires feat(settings): NIP-78 cross-device sync of Interface preferences #173 merged first).

dmnyc added 5 commits May 24, 2026 16:11
- Tap an already-reacted emoji to instantly un-react (NIP-09 kind-5 deletion)
- "Undo Repost" destructive option in the repost popover menu (NIP-09 kind-5 deletion)
- Both undos update local engagement counts immediately before the network call
- Reactor struct now carries reactionEventId (populated after signing or on relay ingest)
- EngagementCounts.reposterEventIds maps pubkey → kind-6 event ID for repost undo
- DeletionSender gains deleteById() helper for undo flows (no full NostrEvent needed)
- ReactionSender/RepostSender gain clearSent() so user can re-react/repost after undoing
Adds recent Emoji 13–15 additions across all categories: faces, hand
gestures, animals (jellyfish, phoenix, moose), food, activities, travel,
and objects. Ensures the full library sheet covers the complete current
Unicode emoji set.
…sync

Previously the quick-reaction picker required manual curation — tapping the
+ button to add each emoji individually. Now the picker adapts automatically:

- recordUse() auto-adds any reacted emoji to the quick list on first use.
  The existing frequency sort ensures often-used emojis rise to the top over
  time, while rarely-used ones stay near the bottom where they can be
  long-pressed to remove them.

- The quick list and frequency map are included in the NIP-78 kind-30078
  settings payload (quickReactions + emojiFrequency fields) so the adapted
  list syncs across devices via the cross-device settings sync introduced
  in feat/nip78-settings-sync.

- addToQuickList / removeFromQuickList trigger a debounced settings sync so
  manual edits also propagate. setQuickList (used by applyRestored) and the
  new setFrequency helper skip the sync trigger — the restore caller
  already suppresses the publish loop.
@dmnyc dmnyc force-pushed the feat/emoji-reactions branch from d86fd8a to e754996 Compare May 25, 2026 16:41
@barrydeen barrydeen merged commit 176a829 into feat/nip78-settings-sync May 26, 2026
@dmnyc dmnyc deleted the feat/emoji-reactions branch May 26, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants