mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-17 03:45:01 +00:00
address review: migration close, pause scanner on wrong-type, drop dead strIsSimplexLink
- MigrateToDevice passes the real `close` (not `{}`), so the wrong-type Connect
button would dismiss correctly if the view is ever opened with an active user.
- Keep the connect/migration scanners on .continuous, but pause the scanner while
the wrong-type alert is shown and resume on dismissal (handleScan takes an
optional scannerPaused Binding; the alert's dismiss buttons clear it). This
fixes the alert re-firing every scanInterval without changing the scan mode.
The oncePerCode scanners pass nil — no-op for them.
- Remove the now-uncalled strIsSimplexLink on both platforms (the classifier
inlines parseToMarkdown / parseSimpleXMarkdown; its only caller, verifyOnly,
was already removed).
- Capitalise "Your servers" in the server-scan breadcrumb to match the actual
UI label (your_servers = "Your servers"), consistent with the other labels.
This commit is contained in:
@@ -103,6 +103,7 @@ struct MigrateToDevice: View {
|
||||
// Prevent from hiding the view until migration is finished or app deleted
|
||||
@State private var backDisabled: Bool = false
|
||||
@State private var showQRCodeScanner: Bool = true
|
||||
@State private var scannerPaused: Bool = false
|
||||
@State private var pasteboardHasStrings = UIPasteboard.general.hasStrings
|
||||
|
||||
@State private var importingArchiveFromFileProgressIndicator = false
|
||||
@@ -201,10 +202,10 @@ struct MigrateToDevice: View {
|
||||
ZStack {
|
||||
List {
|
||||
Section(header: Text("Scan QR code").foregroundColor(theme.colors.secondary)) {
|
||||
ScannerInView(showQRCodeScanner: $showQRCodeScanner) { resp in
|
||||
ScannerInView(showQRCodeScanner: $showQRCodeScanner, scannerPaused: $scannerPaused) { resp in
|
||||
switch resp {
|
||||
case let .success(r):
|
||||
handleScan(r.string, expected: .migrationLink, theme: theme) { qr in
|
||||
handleScan(r.string, expected: .migrationLink, theme: theme, scannerPaused: $scannerPaused) { qr in
|
||||
migrationState = .linkDownloading(link: qr.text)
|
||||
}
|
||||
case let .failure(e):
|
||||
|
||||
@@ -700,7 +700,7 @@ private struct ConnectView: View {
|
||||
private func processQRCode(_ resp: Result<ScanResult, ScanError>) {
|
||||
switch resp {
|
||||
case let .success(r):
|
||||
handleScan(r.string, expected: .connectionLink, theme: theme) { qr in connect(qr.text) }
|
||||
handleScan(r.string, expected: .connectionLink, theme: theme, scannerPaused: $scannerPaused) { qr in connect(qr.text) }
|
||||
case let .failure(e):
|
||||
logger.error("processQRCode QR code error: \(e.localizedDescription)")
|
||||
alert = .newChatSomeAlert(alert: SomeAlert(
|
||||
@@ -849,16 +849,6 @@ struct InfoSheetButton<Content: View>: View {
|
||||
}
|
||||
}
|
||||
|
||||
func strIsSimplexLink(_ str: String) -> Bool {
|
||||
if let parsedMd = parseSimpleXMarkdown(str),
|
||||
parsedMd.count == 1,
|
||||
case .simplexLink = parsedMd[0].format {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
enum ConnectTarget {
|
||||
case link(text: String, linkType: SimplexLinkType, linkText: String)
|
||||
case name(SimplexNameInfo)
|
||||
|
||||
@@ -14,21 +14,25 @@ import SimpleXChat
|
||||
// The shared gate every scanner routes through. If the scan is the accepted kind, run the
|
||||
// screen's onMatch; otherwise show the one wrong-type alert. iOS has no Bool return / de-dup
|
||||
// (the scanner controls re-scanning via scanMode / scannerPaused).
|
||||
func handleScan(_ raw: String, expected: QRCodeKind, theme: AppTheme, onMatch: (QRCodeType) -> Void) {
|
||||
func handleScan(_ raw: String, expected: QRCodeKind, theme: AppTheme, scannerPaused: Binding<Bool>? = nil, onMatch: (QRCodeType) -> Void) {
|
||||
let qr = parseQRCode(raw)
|
||||
if qr.kind == expected {
|
||||
onMatch(qr)
|
||||
} else {
|
||||
showWrongQRCodeAlert(qr, expected: expected, theme: theme)
|
||||
// Pause a continuous scanner while the wrong-type alert is up so it doesn't re-fire the
|
||||
// alert every scanInterval; resume on dismissal. oncePerCode scanners pass nil (no-op).
|
||||
scannerPaused?.wrappedValue = true
|
||||
showWrongQRCodeAlert(qr, expected: expected, theme: theme) { scannerPaused?.wrappedValue = false }
|
||||
}
|
||||
}
|
||||
|
||||
private func showWrongQRCodeAlert(_ scanned: QRCodeType, expected: QRCodeKind, theme: AppTheme) {
|
||||
private func showWrongQRCodeAlert(_ scanned: QRCodeType, expected: QRCodeKind, theme: AppTheme, onDismiss: @escaping () -> Void) {
|
||||
// Relay link: it cannot be used to connect — reuse the existing relay alert (title + message).
|
||||
if case .connectionLink(_, .relay) = scanned {
|
||||
AlertManager.shared.showAlert(mkAlert(
|
||||
title: "Relay address",
|
||||
message: "This is a chat relay address, it cannot be used to connect."
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("Relay address"),
|
||||
message: Text("This is a chat relay address, it cannot be used to connect."),
|
||||
dismissButton: .default(Text("Ok"), action: onDismiss)
|
||||
))
|
||||
return
|
||||
}
|
||||
@@ -36,14 +40,18 @@ private func showWrongQRCodeAlert(_ scanned: QRCodeType, expected: QRCodeKind, t
|
||||
// the server screen says "Invalid server address!", the verify screen says "Incorrect security
|
||||
// code!" (it scans a code, not a link), everything else the generic "not a SimpleX link".
|
||||
if case .unknown = scanned {
|
||||
let title: LocalizedStringKey
|
||||
let message: LocalizedStringKey?
|
||||
switch expected {
|
||||
case .serverAddress:
|
||||
AlertManager.shared.showAlert(mkAlert(title: "Invalid server address!", message: "Check server address and try again."))
|
||||
case .securityCode:
|
||||
AlertManager.shared.showAlert(mkAlert(title: "Incorrect security code!"))
|
||||
default:
|
||||
AlertManager.shared.showAlert(mkAlert(title: "Invalid QR code", message: "The code you scanned is not a SimpleX link QR code."))
|
||||
case .serverAddress: title = "Invalid server address!"; message = "Check server address and try again."
|
||||
case .securityCode: title = "Incorrect security code!"; message = nil
|
||||
default: title = "Invalid QR code"; message = "The code you scanned is not a SimpleX link QR code."
|
||||
}
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text(title),
|
||||
message: message.map { Text($0) },
|
||||
dismissButton: .default(Text("Ok"), action: onDismiss)
|
||||
))
|
||||
return
|
||||
}
|
||||
// Recognised wrong kind: "<what it is>\n\n<where to scan it>".
|
||||
@@ -58,14 +66,16 @@ private func showWrongQRCodeAlert(_ scanned: QRCodeType, expected: QRCodeKind, t
|
||||
title: Text("Wrong QR code"),
|
||||
message: Text(verbatim: message),
|
||||
primaryButton: .default(Text("Connect")) {
|
||||
onDismiss()
|
||||
planAndConnect(text, theme: theme, dismiss: true)
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
secondaryButton: .cancel(onDismiss)
|
||||
))
|
||||
} else {
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("Wrong QR code"),
|
||||
message: Text(verbatim: message)
|
||||
message: Text(verbatim: message),
|
||||
dismissButton: .default(Text("Ok"), action: onDismiss)
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -91,7 +101,7 @@ private extension QRCodeType {
|
||||
case let .connectionLink(_, linkType):
|
||||
return linkType == .relay ? nil : NSLocalizedString("Open New chat, then scan or paste the link.", comment: "qr where to scan")
|
||||
case .serverAddress:
|
||||
return NSLocalizedString("Open Settings, Network & servers, your servers, then Scan server QR code.", comment: "qr where to scan")
|
||||
return NSLocalizedString("Open Settings, Network & servers, Your servers, then Scan server QR code.", comment: "qr where to scan")
|
||||
case .migrationLink:
|
||||
return NSLocalizedString("On the new device, when first setting up the app, choose Migrate from another device.", comment: "qr where to scan")
|
||||
case .desktopAddress:
|
||||
|
||||
@@ -65,10 +65,10 @@ func parseQRCode(_ raw: String) -> QRCodeType {
|
||||
let t = raw.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if strHasSimplexFileLink(t) { return .migrationLink(text: t) }
|
||||
if t.hasPrefix(desktopAddressScheme) { return .desktopAddress(text: t) }
|
||||
// Match only when the WHOLE string is exactly one SimpleX link — same as `strIsSimplexLink`
|
||||
// and the master connect scanner — not a link embedded among other text. A SimpleX *name*
|
||||
// (Format.simplexName) is therefore not a connectionLink here; it falls through to .unknown,
|
||||
// exactly as the master scanner treats it (names are handled only by the paste path).
|
||||
// Match only when the WHOLE string is exactly one SimpleX link — not a link embedded among
|
||||
// other text. A SimpleX *name* (Format.simplexName) is therefore not a connectionLink here; it
|
||||
// falls through to .unknown, the same "not a SimpleX link" the connect scanner showed before
|
||||
// this change (names are handled only by the paste path, via strConnectTarget).
|
||||
if let md = parseSimpleXMarkdown(t), md.count == 1,
|
||||
case let .simplexLink(_, linkType, _, _) = md[0].format {
|
||||
return .connectionLink(text: t, linkType: linkType)
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ private fun MutableState<MigrationToState?>.PasteOrScanLinkView(close: () -> Uni
|
||||
if (appPlatform.isAndroid) {
|
||||
SectionView(stringResource(MR.strings.scan_QR_code).replace('\n', ' ')) {
|
||||
QRCodeScanner(showQRCodeScanner = remember { mutableStateOf(true) }) { text ->
|
||||
handleScan(null, text, QRCodeType.MigrationLink::class, close = {}) { checkUserLink(it.text) }
|
||||
handleScan(null, text, QRCodeType.MigrationLink::class, close) { checkUserLink(it.text) }
|
||||
}
|
||||
}
|
||||
SectionSpacer()
|
||||
|
||||
-5
@@ -801,11 +801,6 @@ private fun createInvitation(
|
||||
}
|
||||
}
|
||||
|
||||
fun strIsSimplexLink(str: String): Boolean {
|
||||
val parsedMd = parseToMarkdown(str)
|
||||
return parsedMd != null && parsedMd.size == 1 && parsedMd[0].format is Format.SimplexLink
|
||||
}
|
||||
|
||||
sealed class ConnectTarget {
|
||||
class Link(val text: String, val linkType: SimplexLinkType, val linkText: String) : ConnectTarget()
|
||||
class Name(val nameInfo: SimplexNameInfo) : ConnectTarget()
|
||||
|
||||
@@ -778,7 +778,7 @@
|
||||
<string name="qr_type_desktop_address">This is an address for linking a mobile to a SimpleX desktop app.</string>
|
||||
<string name="qr_type_security_code">This is a contact\'s security code.</string>
|
||||
<string name="qr_where_connection">Tap New chat, then Paste link / Scan.</string>
|
||||
<string name="qr_where_server">Tap your profile image, then Settings, Network & servers, your servers, Scan server QR code.</string>
|
||||
<string name="qr_where_server">Tap your profile image, then Settings, Network & servers, Your servers, Scan server QR code.</string>
|
||||
<string name="qr_where_desktop">Tap your profile image, then Use from desktop, Scan QR code from desktop.</string>
|
||||
<string name="qr_where_migration">On the new device, when first setting up the app, choose Migrate from another device.</string>
|
||||
<string name="qr_where_security_code">Open the chat, tap the contact\'s name, then Verify security code.</string>
|
||||
|
||||
@@ -270,7 +270,7 @@ qr_type_migration_link = "This is a link to migrate to another device."
|
||||
qr_type_desktop_address = "This is an address for linking a mobile to a SimpleX desktop app."
|
||||
qr_type_security_code = "This is a contact's security code."
|
||||
qr_where_connection = "Tap New chat, then Paste link / Scan."
|
||||
qr_where_server = "Tap your profile image, then Settings, Network & servers, your servers, Scan server QR code."
|
||||
qr_where_server = "Tap your profile image, then Settings, Network & servers, Your servers, Scan server QR code."
|
||||
qr_where_desktop = "Tap your profile image, then Use from desktop, Scan QR code from desktop."
|
||||
qr_where_migration = "On the new device, when first setting up the app, choose Migrate from another device."
|
||||
qr_where_security_code = "Open the chat, tap the contact's name, then Verify security code."
|
||||
|
||||
Reference in New Issue
Block a user