mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 05:25:19 +00:00
Fix QR verification sending multiple notifications (#773)
The camera scanner was continuously detecting the same QR code (10-30+ times/second), causing multiple verification notifications to be sent. This happened because: 1. AVCaptureMetadataOutput fires repeatedly while QR is visible 2. Each detection triggered a new verification flow 3. After receiving response, pendingQRVerifications was cleared, allowing duplicate scans Changes: - Add deduplication using lastValid state to ignore re-scans of same QR code - Only set lastValid after successful verification initiation - Add onSuccess callback to close scanner after successful scan - Automatically return to "My QR" view after verification starts - Apply same logic to both iOS camera and macOS manual input paths This ensures exactly one verification request per scan session. Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
@@ -109,6 +109,7 @@ struct ImageWrapper: View {
|
||||
struct QRScanView: View {
|
||||
@EnvironmentObject var viewModel: ChatViewModel
|
||||
var isActive: Bool = true
|
||||
var onSuccess: (() -> Void)? = nil // Called when verification succeeds
|
||||
@State private var input = ""
|
||||
@State private var result: String = "" // not shown for iOS scanner
|
||||
@State private var lastValid: String = ""
|
||||
@@ -131,10 +132,18 @@ struct QRScanView: View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
#if os(iOS)
|
||||
CameraScannerView(isActive: isActive) { code in
|
||||
// Deduplicate: ignore if we just processed this exact QR code
|
||||
guard code != lastValid else { return }
|
||||
|
||||
if let qr = VerificationService.shared.verifyScannedQR(code) {
|
||||
let ok = viewModel.beginQRVerification(with: qr)
|
||||
if !ok { /* already pending; continue scanning */ }
|
||||
lastValid = code
|
||||
if ok {
|
||||
// Successfully initiated verification; remember this QR to prevent re-scanning
|
||||
lastValid = code
|
||||
// Close scanner and return to "My QR" view
|
||||
onSuccess?()
|
||||
}
|
||||
// If !ok, peer not found or already pending - don't set lastValid so user can retry
|
||||
} else {
|
||||
// ignore invalid reads; continue scanning
|
||||
}
|
||||
@@ -148,9 +157,22 @@ struct QRScanView: View {
|
||||
.frame(height: 100)
|
||||
.border(Color.gray.opacity(0.4))
|
||||
Button(Strings.validate) {
|
||||
// Deduplicate: ignore if we just processed this exact QR
|
||||
guard input != lastValid else {
|
||||
result = Strings.requested("") // Already processed
|
||||
return
|
||||
}
|
||||
|
||||
if let qr = VerificationService.shared.verifyScannedQR(input) {
|
||||
let ok = viewModel.beginQRVerification(with: qr)
|
||||
result = ok ? Strings.requested(qr.nickname) : Strings.notFound
|
||||
if ok {
|
||||
result = Strings.requested(qr.nickname)
|
||||
lastValid = input
|
||||
// Close scanner and return to "My QR" view
|
||||
onSuccess?()
|
||||
} else {
|
||||
result = Strings.notFound
|
||||
}
|
||||
} else {
|
||||
result = Strings.invalid
|
||||
}
|
||||
@@ -308,12 +330,16 @@ struct VerificationSheetView: View {
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(accentColor)
|
||||
#if os(iOS)
|
||||
QRScanView(isActive: showingScanner)
|
||||
QRScanView(isActive: showingScanner, onSuccess: {
|
||||
showingScanner = false
|
||||
})
|
||||
.environmentObject(viewModel)
|
||||
.frame(height: 280)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
#else
|
||||
QRScanView()
|
||||
QRScanView(onSuccess: {
|
||||
showingScanner = false
|
||||
})
|
||||
.environmentObject(viewModel)
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user