Skip to content

feat(zap): instant zaps, ZapSheet redesign, per-account presets#211

Merged
barrydeen merged 3 commits into
mainfrom
feat/instant-zaps
May 28, 2026
Merged

feat(zap): instant zaps, ZapSheet redesign, per-account presets#211
barrydeen merged 3 commits into
mainfrom
feat/instant-zaps

Conversation

@dmnyc

@dmnyc dmnyc commented May 26, 2026

Copy link
Copy Markdown
Collaborator

What

Adds opt-in instant zaps (tap fires immediately, long-press opens composer) with a full ZapSheet redesign, per-account preset storage, and undo reactions/reposts.

Instant zaps

  • New `quickZapEnabled` toggle (default off) in Interface Settings → Zaps / Payments
  • Configurable amount: sats integer in bitcoin mode, fiat decimal in fiat mode (clamps at 10,000 sats equivalent so an instant zap can never exceed the large-zap confirmation threshold)
  • Optional default message persisted per account
  • Tap fires the configured amount immediately via `ZapAnimationStore`; falls back to the composer when no wallet is set up or rate cache is cold
  • Long-press always opens the composer (escape hatch for a different amount, anonymous mode, etc.)
  • Self-zap button is non-tappable + dimmed (35% opacity) — self-zapping wastes routing fees
  • Haptics: medium on touch-down, heavy on long-press recognition; scroll contact no longer triggers haptic

ZapSheet redesign

  • Compact recipient row (avatar + name + lud16 + copy pill)
  • Hero amount at 56 pt; register-style decimal entry in fiat mode
  • Presets in `FlowLayout` (all visible, no horizontal scroll); custom pill has inline `+` badge to save; capped at 8 presets
  • Tapping a preset with a configured message always applies that message to the field (even if the field already has text)
  • Message field always visible above privacy dropdown + instant-zaps toggle
  • Hard cap 1,000,000 sats; soft confirmation dialog above 10,000 sats
  • `.scrollDismissesKeyboard(.interactively)` — keyboard appears once on open, drag dismisses cleanly
  • Per-account preset storage (`zapPresetAmounts_`) with one-time migration from the legacy global key

Per-account instant-zap defaults

  • `quickZapEnabled`, `quickZapAmountSats`, `quickZapAmountFiat`, and `quickZapMessage` are all scoped to the active account pubkey
  • Switching accounts loads that account's values immediately; fresh accounts default to 21 sats / 0.10 fiat / disabled / no message

Undo reactions and reposts

  • Tapping the heart on a post you've already reacted to shows a "Remove Reaction" popover that sends a NIP-09 deletion for the kind-7 event
  • Repost menu shows "Undo Repost" when already reposted, sending a NIP-09 deletion for the kind-6 event
  • `reactionEventId` stored on `Reactor` and `reposterEventIds` stored on `EngagementCounts` for deletion lookup

Emoji reaction picker

  • Fixed 3-row grid (max 18 items), pinned "More reactions" footer — no scrolling
  • Expanded emoji catalog with newer emoji across all categories
  • Picking an emoji from the library as a reaction auto-adds it to the quick list

Wallet setup

  • Spark setup screen: single prominent primary button; secondary paths collapsed under a "More options" accordion

Wallet settings

  • NWC and Spark default wallet danger rows unified: same `arrow.triangle.swap` icon + "Switch to a different wallet" label so both providers read identically

In-flight bolt animation

  • `LightningPulseView` renders the hand-built `BoltGlyph` vector shape (white fill + orange stroke halo) regardless of the user's zap icon preference — the bolt is iconic during flight

DEBUG

  • Empty `DeveloperToolsView` scaffolding in Interface Settings (compiled out of release builds via `#if DEBUG`)

What's not here

NIP-78 cross-device sync of instant-zap settings is deferred — tracked in barrydeen/wisp#579.

Replaces

Closes and replaces #159, which bundled this feature with a NIP-78 relay-sync rewrite. The relay sync has been removed; this PR contains only the instant-zap, ZapSheet, and reactions changes.

🤖 Generated with Claude Code

@dmnyc

dmnyc commented May 27, 2026

Copy link
Copy Markdown
Collaborator Author

The per-account instant-zap isolation fix from PR #195 (commit 9216dad) was merged into feat/one-tap-zap but was not carried forward when feat/instant-zaps was branched off. Without it, switching accounts inherits the previous account's instant-zap enabled state, amount, and message.

The fix scopes the four quickZap UserDefaults keys (enabled, amountSats, amountFiat, message) to a per-pubkey suffix and reloads them on every account change via loadQuickZapSettings(for:) in ContentView. Confirmed fixed on device when cherry-picked onto this branch — please fold it in before this PR merges.

dmnyc added 2 commits May 27, 2026 21:50
- Instant zaps: single tap sends configured amount; long-press opens
  composer. Disabled by default. Fiat counterpart 'instant payments'.
- ZapSheet redesign: compact keyboard-friendly layout with preset pills,
  swipe-to-delete presets, auto-focus without keyboard pump.
- BoltGlyph vector pulse animation with white-core glow on send.
- Instant-zap haptics + faster long-press recognition.
- Per-account presets: zap defaults (enabled, amount, message) scoped
  to active account pubkey; reloaded on every account switch.
- Preset message override: tapping a preset always applies its message.
@dmnyc dmnyc force-pushed the feat/instant-zaps branch from bfde111 to bfd39e5 Compare May 28, 2026 01:59
…catalog

- Undo reaction: tapping an already-reacted heart shows a 'Remove
  Reaction' popover that sends a NIP-09 deletion for the kind-7 event.
- Undo repost: repost menu shows 'Undo Repost' when already reposted,
  sending a NIP-09 deletion for the kind-6 event.
- EmojiReactionPicker: fixed 3-row grid (max 18), pinned 'More
  reactions' footer — no scrolling, no maxGridHeight parameter.
- EmojiData: expanded catalog with newer emoji across all categories.
- EmojiLibrarySheet: auto-adds picked emoji to quick list on reaction.
- EngagementRepository/ProfileViewModel: store reactionEventId on
  Reactor and reposterEventIds on EngagementCounts for undo lookup.
@barrydeen barrydeen merged commit a17e4dd into main May 28, 2026
@dmnyc dmnyc deleted the feat/instant-zaps branch June 2, 2026 03:45
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