damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

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:
Mdamus/Views/QRCodeView.swift | 140+++++++++++++++++++++++++++++++++++++++++++------------------------------------
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) } } +