Skip to content

Commit 29fc26d

Browse files
committed
Preventing navigation to the next screen if peer connection fails (from FundManualSetupView to FundManualAmountView)
1 parent 3e53a74 commit 29fc26d

File tree

3 files changed

+78
-15
lines changed

3 files changed

+78
-15
lines changed

Bitkit/ViewModels/WalletViewModel.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,36 @@ class WalletViewModel: ObservableObject {
469469
syncState()
470470
}
471471

472+
/// Attempts to connect to a peer if not already connected.
473+
/// - Parameters:
474+
/// - peer: Peer to connect.
475+
/// - app: AppViewModel used to surface errors.
476+
/// - Returns: True if connected (already or after connecting), false otherwise.
477+
func ensurePeerConnection(_ peer: LnPeer, app: AppViewModel) async -> Bool {
478+
let alreadyConnected = await MainActor.run {
479+
peers?.contains(where: { $0.nodeId == peer.nodeId }) ?? false
480+
}
481+
482+
if alreadyConnected {
483+
return true
484+
}
485+
486+
do {
487+
try await connectPeer(peer)
488+
return true
489+
} catch {
490+
Logger.error("Failed to connect to peer \(peer.nodeId): \(error)", context: "WalletViewModel")
491+
await MainActor.run {
492+
app.toast(
493+
type: .error,
494+
title: t("lightning__error_add_title"),
495+
description: t("lightning__error_add")
496+
)
497+
}
498+
return false
499+
}
500+
}
501+
472502
/// Sync all state (node status, channels, peers, balances)
473503
/// Use this for initial load or after sync operations
474504
func syncState() {

Bitkit/Views/Transfer/FundManualAmountView.swift

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,7 @@ struct FundManualAmountView: View {
9292
guard !didAttemptPeerConnection else { return }
9393
didAttemptPeerConnection = true
9494

95-
do {
96-
try await wallet.connectPeer(lnPeer)
97-
} catch {
98-
Logger.error("Failed to connect to peer \(lnPeer.nodeId): \(error)", context: "FundManualAmountView")
99-
await MainActor.run {
100-
app.toast(
101-
type: .error,
102-
title: t("lightning__error_add_title"),
103-
description: t("lightning__error_add")
104-
)
105-
}
106-
}
95+
_ = await wallet.ensurePeerConnection(lnPeer, app: app)
10796
}
10897
}
10998

Bitkit/Views/Transfer/FundManualSetupView.swift

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ struct FundManualSetupView: View {
1414
@State private var showAlert: Bool = false
1515
@State private var alertMessage: String = ""
1616
@State private var alertTitle: String = ""
17+
@State private var isConnectingPeer = false
18+
@State private var showAmountEntry = false
19+
@State private var connectedPeer: LnPeer?
1720

1821
init(initialNodeUri: String? = nil) {
1922
self.initialNodeUri = initialNodeUri
@@ -120,9 +123,11 @@ struct FundManualSetupView: View {
120123
CustomButton(
121124
title: t("common__continue"),
122125
variant: .primary,
123-
isDisabled: nodeId.isEmpty || host.isEmpty || port.isEmpty,
124-
destination: FundManualAmountView(lnPeer: LnPeer(nodeId: nodeId, host: host, port: UInt16(port) ?? 0))
125-
)
126+
isDisabled: !isFormValid || isConnectingPeer,
127+
isLoading: isConnectingPeer
128+
) {
129+
await handleContinueTapped()
130+
}
126131
.accessibilityIdentifier("ExternalContinue")
127132
}
128133
}
@@ -142,6 +147,45 @@ struct FundManualSetupView: View {
142147
parseNodeUri(initialNodeUri)
143148
}
144149
}
150+
151+
NavigationLink(
152+
destination: amountDestination,
153+
isActive: $showAmountEntry
154+
) {
155+
EmptyView()
156+
}
157+
.hidden()
158+
}
159+
160+
private var isFormValid: Bool {
161+
!nodeId.isEmpty && !host.isEmpty && !port.isEmpty
162+
}
163+
164+
@ViewBuilder
165+
private var amountDestination: some View {
166+
if let connectedPeer {
167+
FundManualAmountView(lnPeer: connectedPeer)
168+
} else {
169+
EmptyView()
170+
}
171+
}
172+
173+
private func handleContinueTapped() async {
174+
guard isFormValid, !isConnectingPeer else { return }
175+
176+
let peer = LnPeer(nodeId: nodeId, host: host, port: UInt16(port) ?? 0)
177+
178+
isConnectingPeer = true
179+
defer { isConnectingPeer = false }
180+
181+
let connected = await wallet.ensurePeerConnection(peer, app: app)
182+
if connected {
183+
connectedPeer = peer
184+
showAmountEntry = true
185+
} else {
186+
connectedPeer = nil
187+
showAmountEntry = false
188+
}
145189
}
146190
}
147191

0 commit comments

Comments
 (0)