Recognise wrong QR code type in every scanner

When a scanner is shown a QR code of a different kind than it expects, it
now tells the user what they actually scanned and where to use it, instead
of a generic "invalid" message.

Link recognition is done in the core: a new chat_check_link export
classifies a scanned string using the same decoders the views use to
process the links (connection link, server address, migration file link,
desktop address, security code), returning a typed result. Each scanner
calls checkLink first; the expected type proceeds to that scanner's normal
success path, a recognised-but-wrong type shows a shared wrong-type alert
saying what it is and where to use it, and an unrecognised string falls
back to that scanner's own contextual error. Mirrored on Android, desktop
and iOS.

Note: the iOS Swift was written without an Xcode toolchain and is not yet
compiled — needs a Mac/CI build to verify.
This commit is contained in:
Narasimha-sc
2026-07-21 12:33:37 +00:00
parent 2ea5940e81
commit fd34525aa3
31 changed files with 1261 additions and 142 deletions
+19 -12
View File
@@ -8,12 +8,13 @@
import SwiftUI
import CodeScanner
import SimpleXChat
struct ScanCodeView: View {
@Environment(\.dismiss) var dismiss: DismissAction
@Binding var connectionVerified: Bool
var verify: (String?) async -> (Bool, String)?
@State private var showCodeError = false
@State private var scanAlert: SomeAlert?
var body: some View {
VStack(alignment: .leading) {
@@ -25,26 +26,32 @@ struct ScanCodeView: View {
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.alert(isPresented: $showCodeError) {
Alert(title: Text("Incorrect security code!"))
}
.alert(item: $scanAlert) { $0.alert }
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
func processQRCode(_ resp: Result<ScanResult, ScanError>) {
switch resp {
case let .success(r):
Task {
if let (ok, _) = await verify(r.string) {
await MainActor.run {
connectionVerified = ok
if ok {
dismiss()
} else {
showCodeError = true
let trimmed = r.string.trimmingCharacters(in: .whitespacesAndNewlines)
switch checkLink(trimmed) {
case .verificationCode?, nil:
// a security code (or unrecognised text): run the existing verify path
Task {
if let (ok, _) = await verify(trimmed) {
await MainActor.run {
connectionVerified = ok
if ok {
dismiss()
} else {
scanAlert = SomeAlert(alert: Alert(title: Text("Incorrect security code!")), id: "incorrectCode")
}
}
}
}
case let type?:
// valid SimpleX code of another kind: tell the user what it is
scanAlert = SomeAlert(alert: wrongQRCodeAlert(wrongQRCodeMessage(type)), id: "wrongQRCode")
}
case let .failure(e):
logger.error("ScanCodeView.processQRCode QR code error: \(e.localizedDescription)")