Skip to content

Commit

Permalink
Allow scanning QR code from selected wallet screen
Browse files Browse the repository at this point in the history
  • Loading branch information
praveenperera committed Oct 28, 2024
1 parent b8ba104 commit 9378269
Show file tree
Hide file tree
Showing 11 changed files with 286 additions and 60 deletions.
12 changes: 12 additions & 0 deletions ios/Cove.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
AC6F511C2CA205EE00D4D27A /* StringOrData+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6F511B2CA205E900D4D27A /* StringOrData+Ext.swift */; };
AC6F511E2CA36C7600D4D27A /* BinaryDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6F511D2CA36C7100D4D27A /* BinaryDecoder.swift */; };
AC739D502CA09573006B5FF1 /* QrCodeImportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC739D4F2CA09573006B5FF1 /* QrCodeImportScreen.swift */; };
AC73B5952CCEFC5A0003F537 /* QrCodeScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC73B5942CCEFC4C0003F537 /* QrCodeScanView.swift */; };
AC73B5972CCF289A0003F537 /* AppAlertState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC73B5962CCF28960003F537 /* AppAlertState.swift */; };
AC73B5992CCF2D6F0003F537 /* AppSheetState.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC73B5982CCF2D6C0003F537 /* AppSheetState.swift */; };
AC757CBB2C6D277400F3F41C /* ReceiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC757CBA2C6D277400F3F41C /* ReceiveView.swift */; };
AC7DAC9A2C5ACA2800F9DDDB /* String+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC7DAC992C5ACA2800F9DDDB /* String+Ext.swift */; };
AC8189542C4023F0004DCDF5 /* CustomCompletionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC8189532C4023F0004DCDF5 /* CustomCompletionView.swift */; };
Expand Down Expand Up @@ -150,6 +153,9 @@
AC6F511D2CA36C7100D4D27A /* BinaryDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryDecoder.swift; sourceTree = "<group>"; };
AC739D4F2CA09573006B5FF1 /* QrCodeImportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrCodeImportScreen.swift; sourceTree = "<group>"; };
AC739D542CA09AD6006B5FF1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
AC73B5942CCEFC4C0003F537 /* QrCodeScanView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrCodeScanView.swift; sourceTree = "<group>"; };
AC73B5962CCF28960003F537 /* AppAlertState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAlertState.swift; sourceTree = "<group>"; };
AC73B5982CCF2D6C0003F537 /* AppSheetState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSheetState.swift; sourceTree = "<group>"; };
AC757CBA2C6D277400F3F41C /* ReceiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiveView.swift; sourceTree = "<group>"; };
AC7DAC992C5ACA2800F9DDDB /* String+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Ext.swift"; sourceTree = "<group>"; };
AC8189532C4023F0004DCDF5 /* CustomCompletionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCompletionView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -415,10 +421,13 @@
ACCD58D32C5A89FC00CF06F9 /* AsyncPreview.swift */,
AC6F4CE22CC6BC24008D26C0 /* LoadAndResetView.swift */,
AC2B13522CA1EC0200C5C708 /* IdentifiableString.swift */,
AC73B5962CCF28960003F537 /* AppAlertState.swift */,
AC73B5982CCF2D6C0003F537 /* AppSheetState.swift */,
D0BE2EBD2C1614150055FCBE /* MainViewModel.swift */,
2B6032F09EA34DFDCB18090A /* RouteView.swift */,
AC49121A2C77B8A100ED8ED7 /* SecretWordsScreen.swift */,
048B2E5F01EEF26233C1161C /* ImportWalletViewModel.swift */,
AC73B5942CCEFC4C0003F537 /* QrCodeScanView.swift */,
AC6F4CE02CC5DAA9008D26C0 /* PresentableItem.swift */,
ACA4CBEB2C2328BE0008F63E /* Security.swift */,
AC34AC5B6A6EF5288E8B34DC /* WalletViewModel.swift */,
Expand Down Expand Up @@ -563,6 +572,9 @@
382288EEB9734474498ED7EE /* KeyboardObserver.swift in Sources */,
ACCB02CC2C9747AA00FB2EDF /* TransactionCapsule.swift in Sources */,
AC45C4A32C991C1F002C5AEB /* ConfirmationIndicatorView.swift in Sources */,
AC73B5992CCF2D6F0003F537 /* AppSheetState.swift in Sources */,
AC73B5952CCEFC5A0003F537 /* QrCodeScanView.swift in Sources */,
AC73B5972CCF289A0003F537 /* AppAlertState.swift in Sources */,
AC5F3CE52C9A188300469EBA /* FfiColorScheme.swift in Sources */,
AC8459BF2CA5DF4800A3083F /* ScannerView.swift in Sources */,
6B2189B893A545A2F4E3107E /* WalletColor+Ext.swift in Sources */,
Expand Down
47 changes: 47 additions & 0 deletions ios/Cove/AppAlertState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// AppAlertState.swift
// Cove
//
// Created by Praveen Perera on 10/27/24.
//

public enum AppAlertState {
case invalidWordGroup
case duplicateWallet(WalletId)
case errorImportingHotWallet(String)
case importedSuccessfully
case unableToSelectWallet
case errorImportingHardwareWallet(String)
case invalidFileFormat(String)
case addressWrongNetwork(address: Address, network: Network, currentNetwork: Network)
case noWalletSelected(Address)
case foundAddress(Address)
case noCameraPermission

func title() -> String {
switch self {
case .invalidWordGroup:
return "Words Not Valid"
case .duplicateWallet:
return "Duplicate Wallet"
case .errorImportingHotWallet:
return "Error"
case .importedSuccessfully:
return "Success"
case .unableToSelectWallet:
return "Error"
case .errorImportingHardwareWallet:
return "Error Importing Hardware Wallet"
case .invalidFileFormat:
return "Invalid File Format"
case .addressWrongNetwork:
return "Wrong Network"
case .noWalletSelected:
return "No Wallet Selected"
case .foundAddress:
return "Found Address"
case .noCameraPermission:
return "Camera Access is Required"
}
}
}
10 changes: 10 additions & 0 deletions ios/Cove/AppSheetState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// AppSheetState.swift
// Cove
//
// Created by Praveen Perera on 10/27/24.
//

public enum AppSheetState {
case qr
}
100 changes: 51 additions & 49 deletions ios/Cove/CoveApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,11 @@ struct CoveApp: App {
@State var model: MainViewModel
@State var id = UUID()

// PRIVATE
@State private var alert: PresentableItem<AlertState>? = .none

private enum AlertState {
case invalidWordGroup
case duplicateWallet(WalletId)
case errorImportingHotWallet(String)
case importedSuccessfully
case unableToSelectWallet
case errorImportingHardwareWallet(String)
case invalidFileFormat(String)
case addressWrongNetwork(address: Address, network: Network, currentNetwork: Network)
case noWalletSelected(Address)
case foundAddress(Address)

func title() -> String {
switch self {
case .invalidWordGroup:
return "Words Not Valid"
case .duplicateWallet:
return "Duplicate Wallet"
case .errorImportingHotWallet:
return "Error"
case .importedSuccessfully:
return "Success"
case .unableToSelectWallet:
return "Error"
case .errorImportingHardwareWallet:
return "Error Importing Hardware Wallet"
case .invalidFileFormat:
return "Invalid File Format"
case .addressWrongNetwork:
return "Wrong Network"
case .noWalletSelected:
return "No Wallet Selected"
case .foundAddress:
return "Found Address"
}
}
}
@State var alert: PresentableItem<AppAlertState>? = .none
@State var scannedCode: IdentifiableString? = .none

@ViewBuilder
private func alertMessage(alert: PresentableItem<AlertState>) -> some View {
private func alertMessage(alert: PresentableItem<AppAlertState>) -> some View {
let text = {
switch alert.item {
case .invalidWordGroup:
Expand All @@ -90,14 +52,16 @@ struct CoveApp: App {
return "No Wallet Selected"
case .foundAddress:
return "Found Address"
case .noCameraPermission:
return "Please allow camera access in Settings to use this feature."
}
}()

Text(text)
}

@ViewBuilder
private func alertButtons(alert: PresentableItem<AlertState>) -> some View {
private func alertButtons(alert: PresentableItem<AppAlertState>) -> some View {
switch alert.item {
case let .duplicateWallet(walletId):
Button("OK") {
Expand Down Expand Up @@ -141,6 +105,12 @@ struct CoveApp: App {
Button("Cancel") {
self.alert = .none
}
case .noCameraPermission:
Button("OK") {
self.alert = .none
let url = URL(string: UIApplication.openSettingsURLString)!
UIApplication.shared.open(url)
}
}
}

Expand Down Expand Up @@ -229,14 +199,19 @@ struct CoveApp: App {
let selectedWallet = Database().globalConfig().selectedWallet()

if selectedWallet == nil {
return alert = PresentableItem(AlertState.noWalletSelected(address))
alert = PresentableItem(AppAlertState.noWalletSelected(address))
return
}

if network != currentNetwork {
return alert = PresentableItem(AlertState.addressWrongNetwork(address: address, network: network, currentNetwork: currentNetwork))
alert = PresentableItem(
AppAlertState.addressWrongNetwork(
address: address, network: network, currentNetwork: currentNetwork
))
return
}

return alert = PresentableItem(.foundAddress(address))
alert = PresentableItem(.foundAddress(address))
}

func handleFileOpen(_ url: URL) {
Expand Down Expand Up @@ -268,16 +243,39 @@ struct CoveApp: App {
Log.error("File not found")

default:
()
Log.error("Unknown error file handling file: \(error)")
}
}
}

func handleScannedCode(_ stringOrData: StringOrData) {
do {
let multiFormat = try stringOrData.toMultiFormat()
switch multiFormat {
case let .mnemonic(mnemonic):
importHotWallet(mnemonic.words())
case let .hardwareExport(export):
importColdWallet(export)
case let .address(addressWithNetwork):
handleAddress(addressWithNetwork)
}
} catch {
switch error {
case let FileHandlerError.NotRecognizedFormat(multiFormatError):
Log.error("Unrecognized format mulit format error: \(multiFormatError)")
alert = PresentableItem(.invalidFileFormat(multiFormatError.localizedDescription))

default:
Log.error("Unable to handle scanned code, error: \(error)")
}
}
}

@ViewBuilder
func SheetContent(_ state: MainViewModel.SheetState) -> some View {
switch state {
func SheetContent(_ state: PresentableItem<AppSheetState>) -> some View {
switch state.item {
case .qr:
Text("QR")
QrCodeScanView(app: $model, alert: $alert, scannedCode: $scannedCode)
}
}

Expand Down Expand Up @@ -327,6 +325,10 @@ struct CoveApp: App {
.onChange(of: model.selectedNetwork) {
id = UUID()
}
.onChange(of: scannedCode) { _, scannedCode in
guard let scannedCode else { return }
handleScannedCode(StringOrData(scannedCode.value))
}
.alert(
alert?.item.title() ?? "Alert",
isPresented: showingAlert,
Expand Down
6 changes: 5 additions & 1 deletion ios/Cove/Extention/StringOrData+Ext.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// FfiScanResultData.swift
// StringOrData+Ext.swift
// Cove
//
// Created by Praveen Perera on 9/23/24.
Expand All @@ -24,4 +24,8 @@ extension StringOrData {
init(_ value: Data) {
self.self = .data(value)
}

func toMultiFormat() throws -> MultiFormat {
try stringOrDataTryIntoMultiFormat(stringOrData: self)
}
}
2 changes: 1 addition & 1 deletion ios/Cove/HomeScreens/SelectedWalletScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ struct SelectedWalletScreenInner: View {
}

Button(action: {
sheetState = PresentableItem(.settings)
app.sheetState = PresentableItem(.qr)
}) {
HStack {
Image(systemName: "qrcode")
Expand Down
6 changes: 1 addition & 5 deletions ios/Cove/MainViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,14 @@ import SwiftUI
var colorSchemeSelection = Database().globalConfig().colorScheme()
var selectedNode = Database().globalConfig().selectedNode()

var sheetState: PresentableItem<SheetState>? = .none
var sheetState: PresentableItem<AppSheetState>? = .none

// changed when route is reset, to clear lifecycle view state
var routeId = UUID()

@ObservationIgnored
weak var walletViewModel: WalletViewModel?

enum SheetState {
case qr
}

public var selectedNetwork: Network {
rust.network()
}
Expand Down
4 changes: 0 additions & 4 deletions ios/Cove/NewWalletFlow/ColdWallet/QrCodeImportScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,3 @@ struct HelpView: View {
QrCodeImportScreen()
.environment(MainViewModel())
}

#Preview("help") {
HelpView()
}
Loading

0 comments on commit 9378269

Please sign in to comment.