Pending Zaps
A fairly large change that replaces Zaps in the codebase with "Zapping" which is a tagged union consisting of a resolved Zap and a Pending Zap. These are both counted as Zaps everywhere in Damus, except pending zaps can be cancelled (most of the time).
This commit is contained in:
@@ -7,12 +7,17 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
enum Zapped {
|
||||
case not_zapped
|
||||
case pending
|
||||
case zapped
|
||||
}
|
||||
|
||||
class ActionBarModel: ObservableObject {
|
||||
@Published var our_like: NostrEvent?
|
||||
@Published var our_boost: NostrEvent?
|
||||
@Published var our_reply: NostrEvent?
|
||||
@Published var our_zap: Zap?
|
||||
@Published var our_zap: Zapping?
|
||||
@Published var likes: Int
|
||||
@Published var boosts: Int
|
||||
@Published var zaps: Int
|
||||
@@ -35,7 +40,7 @@ class ActionBarModel: ObservableObject {
|
||||
self.replies = 0
|
||||
}
|
||||
|
||||
init(likes: Int, boosts: Int, zaps: Int, zap_total: Int64, replies: Int, our_like: NostrEvent?, our_boost: NostrEvent?, our_zap: Zap?, our_reply: NostrEvent?) {
|
||||
init(likes: Int, boosts: Int, zaps: Int, zap_total: Int64, replies: Int, our_like: NostrEvent?, our_boost: NostrEvent?, our_zap: Zapping?, our_reply: NostrEvent?) {
|
||||
self.likes = likes
|
||||
self.boosts = boosts
|
||||
self.zaps = zaps
|
||||
@@ -64,10 +69,6 @@ class ActionBarModel: ObservableObject {
|
||||
return likes == 0 && boosts == 0 && zaps == 0
|
||||
}
|
||||
|
||||
var zapped: Bool {
|
||||
return our_zap != nil
|
||||
}
|
||||
|
||||
var liked: Bool {
|
||||
return our_like != nil
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ struct DamusState {
|
||||
let wallet: WalletModel
|
||||
|
||||
@discardableResult
|
||||
func add_zap(zap: Zap) -> Bool {
|
||||
func add_zap(zap: Zapping) -> Bool {
|
||||
// store generic zap mapping
|
||||
self.zaps.add_zap(zap: zap)
|
||||
// associate with events as well
|
||||
|
||||
@@ -129,6 +129,25 @@ class HomeModel: ObservableObject {
|
||||
handle_zap_event(ev)
|
||||
case .zap_request:
|
||||
break
|
||||
case .nwc_request:
|
||||
break
|
||||
case .nwc_response:
|
||||
handle_nwc_response(ev)
|
||||
}
|
||||
}
|
||||
|
||||
func handle_nwc_response(_ ev: NostrEvent) {
|
||||
Task { @MainActor in
|
||||
guard let resp = await FullWalletResponse(from: ev) else {
|
||||
return
|
||||
}
|
||||
|
||||
if resp.response.error == nil {
|
||||
nwc_success(zapcache: self.damus_state.zaps, resp: resp)
|
||||
return
|
||||
}
|
||||
|
||||
nwc_error(zapcache: self.damus_state.zaps, evcache: self.damus_state.events, resp: resp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,13 +156,13 @@ class HomeModel: ObservableObject {
|
||||
return
|
||||
}
|
||||
|
||||
damus_state.add_zap(zap: zap)
|
||||
damus_state.add_zap(zap: .zap(zap))
|
||||
|
||||
guard zap.target.pubkey == our_keypair.pubkey else {
|
||||
return
|
||||
}
|
||||
|
||||
if !notifications.insert_zap(zap) {
|
||||
if !notifications.insert_zap(.zap(zap)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -301,6 +320,16 @@ class HomeModel: ObservableObject {
|
||||
//remove_bootstrap_nodes(damus_state)
|
||||
send_home_filters(relay_id: relay_id)
|
||||
}
|
||||
|
||||
// connect to nwc relays when connected
|
||||
if let nwc_str = damus_state.settings.nostr_wallet_connect,
|
||||
let r = pool.get_relay(relay_id),
|
||||
r.descriptor.variant == .nwc,
|
||||
let nwc = WalletConnectURL(str: nwc_str),
|
||||
nwc.relay.id == relay_id
|
||||
{
|
||||
subscribe_to_nwc(url: nwc, pool: pool)
|
||||
}
|
||||
case .error(let merr):
|
||||
let desc = String(describing: merr)
|
||||
if desc.contains("Software caused connection abort") {
|
||||
@@ -431,7 +460,7 @@ class HomeModel: ObservableObject {
|
||||
|
||||
print_filters(relay_id: relay_id, filters: [home_filters, contacts_filters, notifications_filters, dms_filters])
|
||||
|
||||
if let relay_id = relay_id {
|
||||
if let relay_id {
|
||||
pool.send(.subscribe(.init(filters: home_filters, sub_id: home_subid)), to: [relay_id])
|
||||
pool.send(.subscribe(.init(filters: contacts_filters, sub_id: contacts_subid)), to: [relay_id])
|
||||
pool.send(.subscribe(.init(filters: notifications_filters, sub_id: notifications_subid)), to: [relay_id])
|
||||
@@ -836,7 +865,8 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
||||
changed = true
|
||||
if new.contains(d) {
|
||||
if let url = RelayURL(d) {
|
||||
add_new_relay(relay_filters: state.relay_filters, metadatas: state.relay_metadata, pool: state.pool, url: url, info: decoded[d] ?? .rw, new_relay_filters: new_relay_filters)
|
||||
let descriptor = RelayDescriptor(url: url, info: decoded[d] ?? .rw)
|
||||
add_new_relay(relay_filters: state.relay_filters, metadatas: state.relay_metadata, pool: state.pool, descriptor: descriptor, new_relay_filters: new_relay_filters)
|
||||
}
|
||||
} else {
|
||||
state.pool.remove_relay(d)
|
||||
@@ -849,8 +879,9 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
func add_new_relay(relay_filters: RelayFilters, metadatas: RelayMetadatas, pool: RelayPool, url: RelayURL, info: RelayInfo, new_relay_filters: Bool) {
|
||||
try? pool.add_relay(url, info: info)
|
||||
func add_new_relay(relay_filters: RelayFilters, metadatas: RelayMetadatas, pool: RelayPool, descriptor: RelayDescriptor, new_relay_filters: Bool) {
|
||||
try? pool.add_relay(descriptor)
|
||||
let url = descriptor.url
|
||||
|
||||
let relay_id = url.id
|
||||
guard metadatas.lookup(relay_id: relay_id) == nil else {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Foundation
|
||||
|
||||
class ZapGroup {
|
||||
var zaps: [Zap]
|
||||
var zaps: [Zapping]
|
||||
var msat_total: Int64
|
||||
var zappers: Set<String>
|
||||
|
||||
@@ -17,22 +17,16 @@ class ZapGroup {
|
||||
return 0
|
||||
}
|
||||
|
||||
return first.event.created_at
|
||||
return first.created_at
|
||||
}
|
||||
|
||||
func zap_requests() -> [NostrEvent] {
|
||||
zaps.map { z in
|
||||
if let priv = z.private_request {
|
||||
return priv
|
||||
} else {
|
||||
return z.request.ev
|
||||
}
|
||||
}
|
||||
zaps.map { z in z.request }
|
||||
}
|
||||
|
||||
func would_filter(_ isIncluded: (NostrEvent) -> Bool) -> Bool {
|
||||
for zap in zaps {
|
||||
if !isIncluded(zap.request_ev) {
|
||||
if !isIncluded(zap.request) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -41,7 +35,7 @@ class ZapGroup {
|
||||
}
|
||||
|
||||
func filter(_ isIncluded: (NostrEvent) -> Bool) -> ZapGroup? {
|
||||
let new_zaps = zaps.filter { isIncluded($0.request_ev) }
|
||||
let new_zaps = zaps.filter { isIncluded($0.request) }
|
||||
guard new_zaps.count > 0 else {
|
||||
return nil
|
||||
}
|
||||
@@ -59,15 +53,15 @@ class ZapGroup {
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func insert(_ zap: Zap) -> Bool {
|
||||
func insert(_ zap: Zapping) -> Bool {
|
||||
if !insert_uniq_sorted_zap_by_created(zaps: &zaps, new_zap: zap) {
|
||||
return false
|
||||
}
|
||||
|
||||
msat_total += zap.invoice.amount
|
||||
msat_total += zap.amount
|
||||
|
||||
if !zappers.contains(zap.request.ev.pubkey) {
|
||||
zappers.insert(zap.request.ev.pubkey)
|
||||
if !zappers.contains(zap.request.pubkey) {
|
||||
zappers.insert(zap.request.pubkey)
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
@@ -99,7 +99,7 @@ enum NotificationItem {
|
||||
}
|
||||
|
||||
class NotificationsModel: ObservableObject, ScrollQueue {
|
||||
var incoming_zaps: [Zap]
|
||||
var incoming_zaps: [Zapping]
|
||||
var incoming_events: [NostrEvent]
|
||||
var should_queue: Bool
|
||||
|
||||
@@ -150,7 +150,7 @@ class NotificationsModel: ObservableObject, ScrollQueue {
|
||||
}
|
||||
|
||||
for zap in incoming_zaps {
|
||||
pks.insert(zap.request.ev.pubkey)
|
||||
pks.insert(zap.request.pubkey)
|
||||
}
|
||||
|
||||
return Array(pks)
|
||||
@@ -249,7 +249,7 @@ class NotificationsModel: ObservableObject, ScrollQueue {
|
||||
return false
|
||||
}
|
||||
|
||||
private func insert_zap_immediate(_ zap: Zap) -> Bool {
|
||||
private func insert_zap_immediate(_ zap: Zapping) -> Bool {
|
||||
switch zap.target {
|
||||
case .note(let notezt):
|
||||
let id = notezt.note_id
|
||||
@@ -285,7 +285,7 @@ class NotificationsModel: ObservableObject, ScrollQueue {
|
||||
return false
|
||||
}
|
||||
|
||||
func insert_zap(_ zap: Zap) -> Bool {
|
||||
func insert_zap(_ zap: Zapping) -> Bool {
|
||||
if should_queue {
|
||||
return insert_uniq_sorted_zap_by_created(zaps: &incoming_zaps, new_zap: zap)
|
||||
}
|
||||
@@ -307,7 +307,7 @@ class NotificationsModel: ObservableObject, ScrollQueue {
|
||||
changed = changed || incoming_events.count != count
|
||||
|
||||
count = profile_zaps.zaps.count
|
||||
profile_zaps.zaps = profile_zaps.zaps.filter { zap in isIncluded(zap.request.ev) }
|
||||
profile_zaps.zaps = profile_zaps.zaps.filter { zap in isIncluded(zap.request) }
|
||||
changed = changed || profile_zaps.zaps.count != count
|
||||
|
||||
for el in reactions {
|
||||
@@ -325,7 +325,7 @@ class NotificationsModel: ObservableObject, ScrollQueue {
|
||||
for el in zaps {
|
||||
count = el.value.zaps.count
|
||||
el.value.zaps = el.value.zaps.filter {
|
||||
isIncluded($0.request.ev)
|
||||
isIncluded($0.request)
|
||||
}
|
||||
changed = changed || el.value.zaps.count != count
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class ZapsModel: ObservableObject {
|
||||
self.target = target
|
||||
}
|
||||
|
||||
var zaps: [Zap] {
|
||||
var zaps: [Zapping] {
|
||||
return state.events.lookup_zaps(target: target)
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class ZapsModel: ObservableObject {
|
||||
case .notice:
|
||||
break
|
||||
case .eose:
|
||||
let events = state.events.lookup_zaps(target: target).map { $0.request_ev }
|
||||
let events = state.events.lookup_zaps(target: target).map { $0.request }
|
||||
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, load: .from_events(events), damus_state: state)
|
||||
case .event(_, let ev):
|
||||
guard ev.kind == 9735 else {
|
||||
@@ -61,22 +61,19 @@ class ZapsModel: ObservableObject {
|
||||
}
|
||||
|
||||
if let zap = state.zaps.zaps[ev.id] {
|
||||
if state.events.store_zap(zap: zap) {
|
||||
objectWillChange.send()
|
||||
}
|
||||
} else {
|
||||
guard let zapper = state.profiles.lookup_zapper(pubkey: target.pubkey) else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let zap = Zap.from_zap_event(zap_ev: ev, zapper: zapper, our_privkey: state.keypair.privkey) else {
|
||||
return
|
||||
}
|
||||
|
||||
if self.state.add_zap(zap: zap) {
|
||||
objectWillChange.send()
|
||||
}
|
||||
state.events.store_zap(zap: zap)
|
||||
return
|
||||
}
|
||||
|
||||
guard let zapper = state.profiles.lookup_zapper(pubkey: target.pubkey) else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let zap = Zap.from_zap_event(zap_ev: ev, zapper: zapper, our_privkey: state.keypair.privkey) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.state.add_zap(zap: .zap(zap))
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user