qrscan: use explicit types when scanning
This commit is contained in:
@@ -8,6 +8,38 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import CoreImage.CIFilterBuiltins
|
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 {
|
struct QRCodeView: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
@State var pubkey: String
|
@State var pubkey: String
|
||||||
@@ -16,12 +48,11 @@ struct QRCodeView: View {
|
|||||||
|
|
||||||
@State private var selectedTab = 0
|
@State private var selectedTab = 0
|
||||||
|
|
||||||
@State var scanResult: Search? = nil
|
@State var scanResult: ProfileScanResult? = nil
|
||||||
|
|
||||||
@State var showProfileView: Bool = false
|
@State var showProfileView: Bool = false
|
||||||
@State var profile: Profile? = nil
|
@State var profile: Profile? = nil
|
||||||
|
@State var error: String? = nil
|
||||||
@State private var scannedCode = ""
|
|
||||||
|
|
||||||
@State private var outerTrimEnd: CGFloat = 0
|
@State private var outerTrimEnd: CGFloat = 0
|
||||||
var animationDuration: Double = 0.5
|
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 {
|
func QRCameraView() -> some View {
|
||||||
return VStack(alignment: .center) {
|
return VStack(alignment: .center) {
|
||||||
Text("Scan a user's pubkey")
|
Text("Scan a user's pubkey")
|
||||||
@@ -185,16 +193,10 @@ struct QRCodeView: View {
|
|||||||
|
|
||||||
CodeScannerView(codeTypes: [.qr], scanMode: .continuous, simulatedData: "npub1k92qsr95jcumkpu6dffurkvwwycwa2euvx4fthv78ru7gqqz0nrs2ngfwd", shouldVibrateOnSuccess: false) { result in
|
CodeScannerView(codeTypes: [.qr], scanMode: .continuous, simulatedData: "npub1k92qsr95jcumkpu6dffurkvwwycwa2euvx4fthv78ru7gqqz0nrs2ngfwd", shouldVibrateOnSuccess: false) { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let result):
|
case .success(let success):
|
||||||
search_changed(result.string)
|
handleProfileScan(success.string)
|
||||||
switch scanResult {
|
case .failure(let failure):
|
||||||
case .profile(let prof):
|
self.error = failure.localizedDescription
|
||||||
handleProfileScan(prof)
|
|
||||||
default:
|
|
||||||
print("Not a profile")
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
print(error.localizedDescription)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
@@ -207,17 +209,11 @@ struct QRCodeView: View {
|
|||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
if showProfileView {
|
if let scanResult {
|
||||||
let decoded = try? bech32_decode(scannedCode)
|
let dst = ProfileView(damus_state: damus_state, pubkey: scanResult.pubkey)
|
||||||
let hex = hex_encode(decoded!.data)
|
NavigationLink(destination: dst, isActive: $showProfileView) {
|
||||||
|
EmptyView()
|
||||||
NavigationLink(
|
}
|
||||||
destination: ProfileView(damus_state: damus_state, pubkey: hex),
|
|
||||||
isActive: $showProfileView,
|
|
||||||
label: {
|
|
||||||
EmptyView()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
@@ -235,33 +231,50 @@ struct QRCodeView: View {
|
|||||||
.padding(50)
|
.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) {
|
func handleProfileScan(_ scanned_str: String) {
|
||||||
guard scannedCode != prof else {
|
guard let result = ProfileScanResult(string: scanned_str) else {
|
||||||
|
self.error = "Invalid profile QR"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.error = nil
|
||||||
|
|
||||||
|
guard result != self.scanResult else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
generator.impactOccurred()
|
generator.impactOccurred()
|
||||||
cameraAnimate {
|
cameraAnimate {
|
||||||
scannedCode = prof
|
scanResult = result
|
||||||
|
|
||||||
if profile(for: scannedCode) != nil {
|
find_event(state: damus_state, query: .profile(pubkey: result.pubkey)) { res in
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + animationDuration) {
|
guard let res else {
|
||||||
showProfileView = true
|
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) {
|
func cameraAnimate(completion: @escaping () -> Void) {
|
||||||
outerTrimEnd = 0.0
|
outerTrimEnd = 0.0
|
||||||
@@ -296,3 +309,4 @@ struct QRCodeView_Previews: PreviewProvider {
|
|||||||
QRCodeView(damus_state: test_damus_state(), pubkey: test_event.pubkey)
|
QRCodeView(damus_state: test_damus_state(), pubkey: test_event.pubkey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user