nwc: turn pending zap orange when we have a NWC success
Orange means payment successful now, not just presence of zap This introduces a paid pending state, which shows up as an orange timer thing in the zaps view. This can be useful if the zap is never sent. We don't want the user to think the payment didn't go through.
This commit is contained in:
@@ -54,13 +54,14 @@ struct ZapButton: View {
|
||||
}
|
||||
|
||||
var zap_color: Color {
|
||||
switch our_zap {
|
||||
case .none:
|
||||
guard let our_zap else {
|
||||
return Color.gray
|
||||
case .pending:
|
||||
return Color.yellow
|
||||
case .zap:
|
||||
}
|
||||
|
||||
if our_zap.is_paid {
|
||||
return Color.orange
|
||||
} else {
|
||||
return Color.yellow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +261,9 @@ func send_zap(damus_state: DamusState, event: NostrEvent, lnurl: String, is_cust
|
||||
return
|
||||
}
|
||||
|
||||
pzap_state.state = .postbox_pending(nwc_req)
|
||||
if pzap_state.update_state(state: .postbox_pending(nwc_req)) {
|
||||
// we don't need to trigger a ZapsDataModel update here
|
||||
}
|
||||
case .external(let pending_ext):
|
||||
pending_ext.state = .done
|
||||
let ev = ZappingEvent(is_custom: is_custom, type: .got_zap_invoice(inv), event: event)
|
||||
@@ -285,7 +288,9 @@ func cancel_zap(zap: PendingZap, box: PostBox, zapcache: Zaps, evcache: EventCac
|
||||
|
||||
switch nwc_state.state {
|
||||
case .fetching_invoice:
|
||||
nwc_state.state = .cancel_fetching_invoice
|
||||
if nwc_state.update_state(state: .cancel_fetching_invoice) {
|
||||
// we don't need to update the ZapsDataModel here
|
||||
}
|
||||
// let the code that retrieves the invoice remove the zap, because
|
||||
// it still needs access to this pending zap to know to cancel
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ class HomeModel: ObservableObject {
|
||||
}
|
||||
|
||||
if resp.response.error == nil {
|
||||
nwc_success(zapcache: self.damus_state.zaps, resp: resp)
|
||||
nwc_success(zapcache: self.damus_state.zaps, evcache: self.damus_state.events, resp: resp)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -61,17 +61,21 @@ class ZapsDataModel: ObservableObject {
|
||||
self.zaps = zaps
|
||||
}
|
||||
|
||||
func update_state(reqid: String, state: PendingZapState) {
|
||||
func confirm_nwc(reqid: String) {
|
||||
guard let zap = zaps.first(where: { z in z.request.id == reqid }),
|
||||
case .pending(let pzap) = zap,
|
||||
pzap.state != state
|
||||
case .pending(let pzap) = zap
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
pzap.state = state
|
||||
|
||||
self.objectWillChange.send()
|
||||
switch pzap.state {
|
||||
case .external:
|
||||
break
|
||||
case .nwc(let nwc_state):
|
||||
if nwc_state.update_state(state: .confirmed) {
|
||||
self.objectWillChange.send()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var zap_total: Int64 {
|
||||
|
||||
@@ -188,7 +188,7 @@ func nwc_pay(url: WalletConnectURL, pool: RelayPool, post: PostBox, invoice: Str
|
||||
}
|
||||
|
||||
|
||||
func nwc_success(zapcache: Zaps, resp: FullWalletResponse) {
|
||||
func nwc_success(zapcache: Zaps, evcache: EventCache, resp: FullWalletResponse) {
|
||||
// find the pending zap and mark it as pending-confirmed
|
||||
for kv in zapcache.our_zaps {
|
||||
let zaps = kv.value
|
||||
@@ -202,7 +202,10 @@ func nwc_success(zapcache: Zaps, resp: FullWalletResponse) {
|
||||
continue
|
||||
}
|
||||
|
||||
nwc_state.state = .confirmed
|
||||
if nwc_state.update_state(state: .confirmed) {
|
||||
// notify the zaps model of an update so it can mark them as paid
|
||||
evcache.get_cache_data(pzap.target.id).zaps_model.objectWillChange.send()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ enum NWCStateType: Equatable {
|
||||
}
|
||||
|
||||
class NWCPendingZapState: Equatable {
|
||||
var state: NWCStateType
|
||||
private(set) var state: NWCStateType
|
||||
let url: WalletConnectURL
|
||||
|
||||
init(state: NWCStateType, url: WalletConnectURL) {
|
||||
@@ -84,6 +84,15 @@ class NWCPendingZapState: Equatable {
|
||||
self.url = url
|
||||
}
|
||||
|
||||
//@discardableResult -- not discardable, the ZapsDataModel may need to send objectWillChange but we don't force it
|
||||
func update_state(state: NWCStateType) -> Bool {
|
||||
guard state != self.state else {
|
||||
return false
|
||||
}
|
||||
self.state = state
|
||||
return true
|
||||
}
|
||||
|
||||
static func == (lhs: NWCPendingZapState, rhs: NWCPendingZapState) -> Bool {
|
||||
return lhs.state == rhs.state && lhs.url == rhs.url
|
||||
}
|
||||
@@ -94,7 +103,7 @@ class PendingZap {
|
||||
let target: ZapTarget
|
||||
let request: ZapRequest
|
||||
let type: ZapType
|
||||
var state: PendingZapState
|
||||
private(set) var state: PendingZapState
|
||||
|
||||
init(amount_msat: Int64, target: ZapTarget, request: ZapRequest, type: ZapType, state: PendingZapState) {
|
||||
self.amount_msat = amount_msat
|
||||
@@ -103,6 +112,17 @@ class PendingZap {
|
||||
self.type = type
|
||||
self.state = state
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func update_state(model: ZapsDataModel, state: PendingZapState) -> Bool {
|
||||
guard self.state != state else {
|
||||
return false
|
||||
}
|
||||
|
||||
self.state = state
|
||||
model.objectWillChange.send()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +139,23 @@ enum Zapping {
|
||||
}
|
||||
}
|
||||
|
||||
var is_paid: Bool {
|
||||
switch self {
|
||||
case .zap:
|
||||
// we have a zap so this is proof of payment
|
||||
return true
|
||||
case .pending(let pzap):
|
||||
switch pzap.state {
|
||||
case .external:
|
||||
// It could be but we don't know. We have to wait for a zap to know.
|
||||
return false
|
||||
case .nwc(let nwc_state):
|
||||
// nwc confirmed that we have a payment, but we might not have zap yet
|
||||
return nwc_state.state == .confirmed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var is_private: Bool {
|
||||
switch self {
|
||||
case .zap(let zap):
|
||||
|
||||
@@ -26,7 +26,7 @@ struct ZapEvent: View {
|
||||
|
||||
if zap.is_pending {
|
||||
Image(systemName: "clock.arrow.circlepath")
|
||||
.foregroundColor(DamusColors.yellow)
|
||||
.foregroundColor(zap.is_paid ? Color.orange : DamusColors.yellow)
|
||||
.help(NSLocalizedString("Only you can see this message and who sent it.", comment: "Help text on green lock icon that explains that only the current user can see the message of a zap event and who sent the zap."))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user