Refactor wallet invoice URL handling
This is a minor refactor on the way wallet invoice URLs are handled, in order to better fit the interface, enforce the design pattern, and avoid side-effects in a particular function that handles opening URLs. This design pattern was introduced to prevent issues on the previous pattern, where URL handling was done with side-effects inside multiple levels of nested logic and separate function calls, which would make debugging very difficult, and cause the app to fail silently. Closes: https://github.com/damus-io/damus/issues/3023 Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
@@ -94,26 +94,30 @@ enum OpenWalletError: Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func open_with_wallet(wallet: Wallet.Model, invoice: String) throws {
|
func open_with_wallet(wallet: Wallet.Model, invoice: String) throws {
|
||||||
|
let url = try getUrlToOpen(invoice: invoice, with: wallet)
|
||||||
|
this_app.open(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUrlToOpen(invoice: String, with wallet: Wallet.Model) throws(OpenWalletError) -> URL {
|
||||||
if let url = URL(string: "\(wallet.link)\(invoice)"), this_app.canOpenURL(url) {
|
if let url = URL(string: "\(wallet.link)\(invoice)"), this_app.canOpenURL(url) {
|
||||||
this_app.open(url)
|
return url
|
||||||
} else {
|
} else {
|
||||||
guard let store_link = wallet.appStoreLink else {
|
guard let store_link = wallet.appStoreLink else {
|
||||||
throw OpenWalletError.no_wallet_to_open
|
throw .no_wallet_to_open
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let url = URL(string: store_link) else {
|
guard let url = URL(string: store_link) else {
|
||||||
throw OpenWalletError.store_link_invalid
|
throw .store_link_invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
guard this_app.canOpenURL(url) else {
|
guard this_app.canOpenURL(url) else {
|
||||||
throw OpenWalletError.system_cannot_open_store_link
|
throw .system_cannot_open_store_link
|
||||||
}
|
}
|
||||||
|
|
||||||
this_app.open(url)
|
return url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let test_invoice = Invoice(description: .description("this is a description"), amount: .specific(10000), string: "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r", expiry: 604800, payment_hash: Data(), created_at: 1666139119)
|
let test_invoice = Invoice(description: .description("this is a description"), amount: .specific(10000), string: "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r", expiry: 604800, payment_hash: Data(), created_at: 1666139119)
|
||||||
|
|
||||||
struct InvoiceView_Previews: PreviewProvider {
|
struct InvoiceView_Previews: PreviewProvider {
|
||||||
|
|||||||
@@ -742,6 +742,8 @@ struct ContentView: View {
|
|||||||
case route(Route)
|
case route(Route)
|
||||||
/// Open a sheet
|
/// Open a sheet
|
||||||
case sheet(Sheets)
|
case sheet(Sheets)
|
||||||
|
/// Open an external URL
|
||||||
|
case external_url(URL)
|
||||||
/// Do nothing.
|
/// Do nothing.
|
||||||
///
|
///
|
||||||
/// ## Implementation notes
|
/// ## Implementation notes
|
||||||
@@ -758,6 +760,8 @@ struct ContentView: View {
|
|||||||
navigationCoordinator.push(route: route)
|
navigationCoordinator.push(route: route)
|
||||||
case .sheet(let sheet):
|
case .sheet(let sheet):
|
||||||
self.active_sheet = sheet
|
self.active_sheet = sheet
|
||||||
|
case .external_url(let url):
|
||||||
|
this_app.open(url)
|
||||||
case .no_action:
|
case .no_action:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,13 +47,10 @@ struct DamusURLHandler {
|
|||||||
if damus_state.settings.show_wallet_selector {
|
if damus_state.settings.show_wallet_selector {
|
||||||
return .sheet(.select_wallet(invoice: invoice.string))
|
return .sheet(.select_wallet(invoice: invoice.string))
|
||||||
} else {
|
} else {
|
||||||
do {
|
guard let url = try? getUrlToOpen(invoice: invoice.string, with: damus_state.settings.default_wallet.model) else {
|
||||||
try open_with_wallet(wallet: damus_state.settings.default_wallet.model, invoice: invoice.string)
|
|
||||||
return .no_action
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
return .sheet(.select_wallet(invoice: invoice.string))
|
return .sheet(.select_wallet(invoice: invoice.string))
|
||||||
}
|
}
|
||||||
|
return .external_url(url)
|
||||||
}
|
}
|
||||||
case nil:
|
case nil:
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user