commit 8f237b47ebfc49c47ae2eb2d38f5b68af7d75e17
parent a0caf9ce07e64fb583816083fb6a6bfbfb930f3c
Author: William Casarin <jb55@jb55.com>
Date: Wed, 7 Jun 2023 07:56:00 +0200
qrscan: use explicit types when scanning
Diffstat:
1 file changed, 77 insertions(+), 63 deletions(-)
diff --git a/damus/Views/QRCodeView.swift b/damus/Views/QRCodeView.swift
@@ -8,6 +8,38 @@
import SwiftUI
import CoreImage.CIFilterBuiltins
+struct ProfileScanResult: Equatable {
+ let pubkey: String
+
+ init(hex: String) {
+ self.pubkey = hex
+ }
+
+ init?(string: String) {
+ var str = string
+ guard str.count != 0 else {
+ return nil
+ }
+
+ if str.hasPrefix("nostr:") {
+ str.removeFirst("nostr:".count)
+ }
+
+ if let _ = hex_decode(str), str.count == 64 {
+ self = .init(hex: str)
+ return
+ }
+
+ if str.starts(with: "npub"), let b32 = try? bech32_decode(str) {
+ let hex = hex_encode(b32.data)
+ self = .init(hex: hex)
+ return
+ }
+
+ return nil
+ }
+}
+
struct QRCodeView: View {
let damus_state: DamusState
@State var pubkey: String
@@ -16,12 +48,11 @@ struct QRCodeView: View {
@State private var selectedTab = 0
- @State var scanResult: Search? = nil
+ @State var scanResult: ProfileScanResult? = nil
@State var showProfileView: Bool = false
@State var profile: Profile? = nil
-
- @State private var scannedCode = ""
+ @State var error: String? = nil
@State private var outerTrimEnd: CGFloat = 0
var animationDuration: Double = 0.5
@@ -152,29 +183,6 @@ struct QRCodeView: View {
}
}
- func search_changed(_ new: String) {
- var str = new
- guard str.count != 0 else {
- return
- }
-
- if str.hasPrefix("nostr:") {
- str.removeFirst("nostr:".count)
- }
-
- if let _ = hex_decode(str), str.count == 64 {
- self.scanResult = .hex(str)
- return
- }
-
- if str.starts(with: "npub") {
- if let _ = try? bech32_decode(str) {
- self.scanResult = .profile(str)
- return
- }
- }
- }
-
func QRCameraView() -> some View {
return VStack(alignment: .center) {
Text("Scan a user's pubkey")
@@ -185,16 +193,10 @@ struct QRCodeView: View {
CodeScannerView(codeTypes: [.qr], scanMode: .continuous, simulatedData: "npub1k92qsr95jcumkpu6dffurkvwwycwa2euvx4fthv78ru7gqqz0nrs2ngfwd", shouldVibrateOnSuccess: false) { result in
switch result {
- case .success(let result):
- search_changed(result.string)
- switch scanResult {
- case .profile(let prof):
- handleProfileScan(prof)
- default:
- print("Not a profile")
- }
- case .failure(let error):
- print(error.localizedDescription)
+ case .success(let success):
+ handleProfileScan(success.string)
+ case .failure(let failure):
+ self.error = failure.localizedDescription
}
}
.scaledToFit()
@@ -207,17 +209,11 @@ struct QRCodeView: View {
Spacer()
- if showProfileView {
- let decoded = try? bech32_decode(scannedCode)
- let hex = hex_encode(decoded!.data)
-
- NavigationLink(
- destination: ProfileView(damus_state: damus_state, pubkey: hex),
- isActive: $showProfileView,
- label: {
- EmptyView()
- }
- )
+ if let scanResult {
+ let dst = ProfileView(damus_state: damus_state, pubkey: scanResult.pubkey)
+ NavigationLink(destination: dst, isActive: $showProfileView) {
+ EmptyView()
+ }
}
Spacer()
@@ -235,33 +231,50 @@ struct QRCodeView: View {
.padding(50)
}
}
-
- func profile(for code: String) -> Profile? {
- guard let decoded = try? bech32_decode(code) else {
- return nil
- }
- let hex = hex_encode(decoded.data)
- return damus_state.profiles.lookup(id: hex)
- }
- func handleProfileScan(_ prof: String) {
- guard scannedCode != prof else {
+ func handleProfileScan(_ scanned_str: String) {
+ guard let result = ProfileScanResult(string: scanned_str) else {
+ self.error = "Invalid profile QR"
+ return
+ }
+
+ self.error = nil
+
+ guard result != self.scanResult else {
return
}
generator.impactOccurred()
cameraAnimate {
- scannedCode = prof
+ scanResult = result
- if profile(for: scannedCode) != nil {
- DispatchQueue.main.asyncAfter(deadline: .now() + animationDuration) {
- showProfileView = true
+ find_event(state: damus_state, query: .profile(pubkey: result.pubkey)) { res in
+ guard let res else {
+ error = "Profile not found"
+ return
}
- } else {
- print("Profile not found")
+
+ switch res {
+ case .invalid_profile:
+ error = "Profile was found but was corrupt."
+
+ case .profile:
+ show_profile_after_delay()
+
+ case .event:
+ print("invalid search result")
+ }
+
}
}
}
+
+ func show_profile_after_delay() {
+ DispatchQueue.main.asyncAfter(deadline: .now() + animationDuration) {
+ showProfileView = true
+ }
+
+ }
func cameraAnimate(completion: @escaping () -> Void) {
outerTrimEnd = 0.0
@@ -296,3 +309,4 @@ struct QRCodeView_Previews: PreviewProvider {
QRCodeView(damus_state: test_damus_state(), pubkey: test_event.pubkey)
}
}
+