mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-11 15:39:06 +00:00
ios, android: hand store receipts to core, finish what it settles, and show why a held purchase is not credited yet
This commit is contained in:
@@ -756,6 +756,7 @@ enum ServicePayment: Encodable {
|
||||
struct OpenStorePurchase: Decodable {
|
||||
var invoiceId: String?
|
||||
var transactionRef: String?
|
||||
var creditError: BadgeIssueFailure?
|
||||
}
|
||||
|
||||
// ChatResponse is split to three enums to reduce stack size used when parsing it, parsing large enums is very inefficient.
|
||||
@@ -1290,6 +1291,7 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
// badges
|
||||
case badgeChanged(user: User, badgeState: BadgeState?)
|
||||
case badgeAlert(user: UserRef, badgeAlert: BadgeAlert)
|
||||
case storePurchaseSettled(user: UserRef)
|
||||
|
||||
var responseType: String {
|
||||
switch self {
|
||||
@@ -1364,6 +1366,7 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case .contactPQEnabled: "contactPQEnabled"
|
||||
case .badgeChanged: "badgeChanged"
|
||||
case .badgeAlert: "badgeAlert"
|
||||
case .storePurchaseSettled: "storePurchaseSettled"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1448,6 +1451,7 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case let .contactPQEnabled(u, contact, pqEnabled): return withUser(u, "contact: \(String(describing: contact))\npqEnabled: \(pqEnabled)")
|
||||
case let .badgeChanged(u, badgeState): return withUser(u, String(describing: badgeState))
|
||||
case let .badgeAlert(u, badgeAlert): return withUser(u, String(describing: badgeAlert))
|
||||
case .storePurchaseSettled: return noDetails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2196,24 +2196,18 @@ func apiRedeemBadgeCode(_ userId: Int64, _ code: String) async throws -> (user:
|
||||
throw r.unexpected
|
||||
}
|
||||
|
||||
// a refusal is thrown, as BREServiceError with the code
|
||||
enum BadgePurchaseResult {
|
||||
case redeemed(user: User, badgeState: BadgeState?)
|
||||
case held(user: UserRef, badgeState: BadgeState?, storePurchases: [OpenStorePurchase])
|
||||
case credited(user: User, badgeState: BadgeState?)
|
||||
}
|
||||
|
||||
// log: false because a store receipt is a bearer secret, like a badge code - it is in the command.
|
||||
// nil when the user cancels the retry alert, which is offered only when retry is set.
|
||||
func apiPurchaseBadge(_ userId: Int64, _ echoedInvoiceId: String?, _ payment: ServicePayment, retry: Bool) async throws -> BadgePurchaseResult? {
|
||||
let cmd = ChatCommand.apiPurchaseBadge(userId: userId, echoedInvoiceId: echoedInvoiceId, payment: payment)
|
||||
let r: APIResult<ChatResponse2>?
|
||||
if retry {
|
||||
r = await chatApiSendCmdWithRetry(cmd, log: false)
|
||||
} else {
|
||||
let res: APIResult<ChatResponse2> = await chatApiSendCmd(cmd, log: false)
|
||||
r = res
|
||||
}
|
||||
guard let r else { return nil }
|
||||
func apiPurchaseBadge(_ userId: Int64, _ echoedInvoiceId: String?, _ payment: ServicePayment) async throws -> BadgePurchaseResult {
|
||||
let r: ChatResponse2 = try await chatSendCmd(.apiPurchaseBadge(userId: userId, echoedInvoiceId: echoedInvoiceId, payment: payment), log: false)
|
||||
switch r {
|
||||
case let .result(.badgeRedeemed(user, _, _, badgeState)): return .redeemed(user: user, badgeState: badgeState)
|
||||
case let .badgeState(user, badgeState, storePurchases): return .held(user: user, badgeState: badgeState, storePurchases: storePurchases ?? [])
|
||||
case let .badgeRedeemed(user, _, _, badgeState): return .credited(user: user, badgeState: badgeState)
|
||||
default: throw r.unexpected
|
||||
}
|
||||
}
|
||||
@@ -3100,6 +3094,9 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
BadgeModel.shared.setAlert(userId: user.userId, alert: badgeAlert)
|
||||
}
|
||||
}
|
||||
case .storePurchaseSettled:
|
||||
// whichever profile owns it: only the app can finish the store transaction
|
||||
Task { await BadgeStore.shared.presentUnfinished() }
|
||||
default:
|
||||
logger.debug("unsupported event: \(res.responseType)")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user