From abb0822c81dcc9b018989d26a01d4643e96b41fd Mon Sep 17 00:00:00 2001 From: Mohamed Barry Date: Thu, 19 Mar 2020 18:19:24 +0100 Subject: [PATCH 001/114] fix crash: window required --- loafwallet/AppDelegate.swift | 6 ++---- loafwallet/src/ApplicationController.swift | 13 +++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/loafwallet/AppDelegate.swift b/loafwallet/AppDelegate.swift index 3980663d6..d0eb0243f 100644 --- a/loafwallet/AppDelegate.swift +++ b/loafwallet/AppDelegate.swift @@ -30,15 +30,13 @@ import Firebase @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - private var window: UIWindow? { - return applicationController.window - } + var window: UIWindow? let applicationController = ApplicationController() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { setFirebaseConfiguration() UIView.swizzleSetFrame() - applicationController.launch(application: application, options: launchOptions) + applicationController.launch(application: application, window: self.window, options: launchOptions) LWAnalytics.logEventWithParameters(itemName:._20191105_AL) return true } diff --git a/loafwallet/src/ApplicationController.swift b/loafwallet/src/ApplicationController.swift index 99a0a57ce..b637abf20 100644 --- a/loafwallet/src/ApplicationController.swift +++ b/loafwallet/src/ApplicationController.swift @@ -18,7 +18,7 @@ class ApplicationController : Subscriber, Trackable { //Ideally the window would be private, but is unfortunately required //by the UIApplicationDelegate Protocol - let window = UIWindow() + var window: UIWindow? fileprivate let store = Store() private var startFlowController: StartFlowPresenter? private var modalPresenter: ModalPresenter? @@ -61,8 +61,9 @@ class ApplicationController : Subscriber, Trackable { } } - func launch(application: UIApplication, options: [UIApplicationLaunchOptionsKey: Any]?) { + func launch(application: UIApplication, window: UIWindow?, options: [UIApplicationLaunchOptionsKey: Any]?) { self.application = application + self.window = window application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum) setup() handleLaunchOptions(options) @@ -86,7 +87,7 @@ class ApplicationController : Subscriber, Trackable { countLaunches() setupAppearance() setupRootViewController() - window.makeKeyAndVisible() + window?.makeKeyAndVisible() listenForPushNotificationRequest() offMainInitialization() store.subscribe(self, name: .reinitWalletManager(nil), callback: { @@ -176,12 +177,12 @@ class ApplicationController : Subscriber, Trackable { private func didInitWalletManager() { guard let walletManager = walletManager else { assert(false, "WalletManager should exist!"); return } - guard let rootViewController = window.rootViewController else { return } + guard let rootViewController = window?.rootViewController else { return } hasPerformedWalletDependentInitialization = true store.perform(action: PinLength.set(walletManager.pinLength)) walletCoordinator = WalletCoordinator(walletManager: walletManager, store: store) - modalPresenter = ModalPresenter(store: store, walletManager: walletManager, window: window, apiClient: noAuthApiClient) + modalPresenter = ModalPresenter(store: store, walletManager: walletManager, window: window!, apiClient: noAuthApiClient) exchangeUpdater = ExchangeUpdater(store: store, walletManager: walletManager) feeUpdater = FeeUpdater(walletManager: walletManager, store: store) startFlowController = StartFlowPresenter(store: store, walletManager: walletManager, rootViewController: rootViewController) @@ -257,7 +258,7 @@ class ApplicationController : Subscriber, Trackable { private func setupRootViewController() { mainViewController = MainViewController(store: store) - window.rootViewController = mainViewController + window?.rootViewController = mainViewController } private func startDataFetchers() { From 60c2e128392e755422a816c877cf5e4cf9f0228a Mon Sep 17 00:00:00 2001 From: Mohamed Barry Date: Thu, 19 Mar 2020 18:21:18 +0100 Subject: [PATCH 002/114] compute QR code only once --- loafwallet/src/ViewControllers/ScanViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loafwallet/src/ViewControllers/ScanViewController.swift b/loafwallet/src/ViewControllers/ScanViewController.swift index d55c79649..7940c7d7b 100644 --- a/loafwallet/src/ViewControllers/ScanViewController.swift +++ b/loafwallet/src/ViewControllers/ScanViewController.swift @@ -189,9 +189,9 @@ extension ScanViewController : AVCaptureMetadataOutputObjectsDelegate { NSLog("ERROR: URI String not found") return } - if completion != nil { + if completion != nil && guide.state != .positive { handleURI(uri) - } else if scanKeyCompletion != nil { + } else if scanKeyCompletion != nil && guide.state != .positive { handleKey(uri) } } From f9fa5c2d3e97a4dac65dda09bbfd513c00320fbc Mon Sep 17 00:00:00 2001 From: Mohamed Barry Date: Thu, 19 Mar 2020 18:21:49 +0100 Subject: [PATCH 003/114] run code on main thread --- .../Import/StartImportViewController.swift | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/loafwallet/src/ViewControllers/Import/StartImportViewController.swift b/loafwallet/src/ViewControllers/Import/StartImportViewController.swift index 2d6fcead3..8f14d0a9b 100644 --- a/loafwallet/src/ViewControllers/Import/StartImportViewController.swift +++ b/loafwallet/src/ViewControllers/Import/StartImportViewController.swift @@ -170,7 +170,10 @@ class StartImportViewController : UIViewController { guard let data = data, let jsonData = try? JSONSerialization.jsonObject(with: data, options: []), let json = jsonData as? [[String: Any]] else { return } - myself.handleData(data: json, key: key) + + DispatchQueue.main.async { + myself.handleData(data: json, key: key) + } } task.resume() }) @@ -223,22 +226,26 @@ class StartImportViewController : UIViewController { let _ = tx.sign(keys: &keys) guard tx.isSigned else { - self.importingActivity.dismiss(animated: true, completion: { - self.showErrorMessage(S.Import.Error.signing) - }) + DispatchQueue.main.async { + self.importingActivity.dismiss(animated: true, completion: { + self.showErrorMessage(S.Import.Error.signing) + }) + } return } self.walletManager.peerManager?.publishTx(tx, completion: { [weak self] success, error in guard let myself = self else { return } - myself.importingActivity.dismiss(animated: true, completion: { - DispatchQueue.main.async { - if let error = error { - myself.showErrorMessage(error.localizedDescription) - return + DispatchQueue.main.async { + myself.importingActivity.dismiss(animated: true, completion: { + DispatchQueue.main.async { + if let error = error { + myself.showErrorMessage(error.localizedDescription) + return + } + myself.showSuccess() } - myself.showSuccess() - } - }) + }) + } }) }) } From 28f61222018af8957af21798725cac4aee0f0844 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 9 Apr 2020 21:51:44 -0700 Subject: [PATCH 004/114] update cocoapods firebase --- Podfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Podfile b/Podfile index 12e596541..9559095cb 100644 --- a/Podfile +++ b/Podfile @@ -10,8 +10,8 @@ def shared_pods pod 'Alamofire', '~> 4.7' pod 'SwiftyJSON', '~> 4.0' pod 'CryptoSwift', '~> 1.0' - pod 'Firebase/Crashlytics' - pod 'FirebaseAnalytics', '~> 6.2' + pod 'Firebase/Crashlytics' + pod 'Firebase/Analytics' # add after v2.6.0 pod 'SwiftLint' end From 9463dec4b21564b6dbb3e2b5fefc1dd148471140 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 11 Apr 2020 12:37:20 -0700 Subject: [PATCH 005/114] update addresses + event --- loafwallet/src/Constants/Constants.swift | 4 ++-- .../src/ViewControllers/RootModals/SendViewController.swift | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index d701662ad..1d9727300 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -20,8 +20,8 @@ enum LWDonationAddress: String { var address: String { switch self { - case .litwalletHardware: return "MVRj1whQ8hqcpffjRxLLCJG1mD27V9YygY" - case .generalLitecoinFoundation: return "MDPqwDf9eUErGLcZNt1HN9HqnbFCSCSRme" + case .litwalletHardware: return "MJ4W7NZya4SzE7R6xpEVdamGCimaQYPiWu" //old MVRj1whQ8hqcpffjRxLLCJG1mD27V9YygY + case .generalLitecoinFoundation: return "MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe" //old MDPqwDf9eUErGLcZNt1HN9HqnbFCSCSRme } } } diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index dc2c4f695..e42f6696a 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -203,7 +203,8 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track dynamicDonate.dismiss(animated: true, completion: { self.send() - let properties: [String: String] = ["PLATFORM":"iOS", + let properties: [String: String] = ["ADDRESS_SCHEME":"v2", + "PLATFORM":"iOS", "DONATION_ACCOUNT": dynamicDonate.finalDonationMemo, "DONATION_AMOUNT": String(describing: dynamicDonate.finalDonationAmount.rawValue)] From 5fd76c2380de4dd66e9408679343634d08bbcde2 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 12 Apr 2020 16:28:25 -0700 Subject: [PATCH 006/114] version bump --- loafwallet.xcodeproj/project.pbxproj | 60 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index ffcacf158..43b6286a2 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -5008,7 +5008,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5022,7 +5022,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5039,14 +5039,14 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; IBSC_MODULE = loafwallet_WatchKit_Extension; INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit App/Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; "LIBRARY_SEARCH_PATHS[arch=*]" = "$(inherited)"; - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -5210,7 +5210,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit Extension/Info.plist"; @@ -5219,7 +5219,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp.watchkitextension; PRODUCT_NAME = Litewallet; SDKROOT = watchos; @@ -5234,7 +5234,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5244,7 +5244,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -5256,7 +5256,7 @@ buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = NotificationServiceExtension/Info.plist; @@ -5266,7 +5266,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.NotificationServiceExtension; PRODUCT_NAME = Litewallet; PROVISIONING_PROFILE = ""; @@ -5621,7 +5621,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit Extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( @@ -5629,7 +5629,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp.watchkitextension; PRODUCT_NAME = Litewallet; SDKROOT = watchos; @@ -5645,13 +5645,13 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = ZV7987N2ZC; IBSC_MODULE = loafwallet_WatchKit_Extension; INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit App/Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; "LIBRARY_SEARCH_PATHS[arch=*]" = "$(inherited)"; - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -5668,7 +5668,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5681,7 +5681,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5696,7 +5696,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5705,7 +5705,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -5717,7 +5717,7 @@ buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = NotificationServiceExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; @@ -5726,7 +5726,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.NotificationServiceExtension; PRODUCT_NAME = Litewallet; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5819,7 +5819,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5833,7 +5833,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5850,13 +5850,13 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; IBSC_MODULE = loafwallet_WatchKit_Extension; INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit App/Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -5871,7 +5871,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit Extension/Info.plist"; @@ -5880,7 +5880,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp.watchkitextension; PRODUCT_NAME = Litewallet; SDKROOT = watchos; @@ -5895,7 +5895,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5905,7 +5905,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -5917,7 +5917,7 @@ buildSettings = { CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 108; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = NotificationServiceExtension/Info.plist; @@ -5927,7 +5927,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.0; + MARKETING_VERSION = 2.7.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.NotificationServiceExtension; PRODUCT_NAME = Litewallet; PROVISIONING_PROFILE_SPECIFIER = ""; From 40d45a0785c79e402263fac1bd94ebbf42bd268d Mon Sep 17 00:00:00 2001 From: Kerry Date: Thu, 9 Jul 2020 11:36:00 -0700 Subject: [PATCH 007/114] remove unused fonts --- .gitignore | 3 +-- loafwallet.xcodeproj/project.pbxproj | 6 ------ loafwallet/Info.plist | 3 --- loafwallet/src/Extensions/UIFont+BRWAdditions.swift | 8 ++++---- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index c0d581b7b..3012330d3 100644 --- a/.gitignore +++ b/.gitignore @@ -66,5 +66,4 @@ fastlane/test_output Screenshots/shots .DS_Store *.xcscheme -GoogleService-Info.plist -GoogleService-iOS-Beta-Info.plist +loafwallet/GoogleService-Info.plist diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index ffcacf158..541ee003f 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -380,10 +380,7 @@ CEAA9E971DC18E1F0066731D /* PhraseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA9E961DC18E1F0066731D /* PhraseView.swift */; }; CEAA9E991DC262800066731D /* ConfirmPaperPhraseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA9E981DC262800066731D /* ConfirmPaperPhraseViewController.swift */; }; CEAA9E9B1DC2B9320066731D /* ConfirmPhrase.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA9E9A1DC2B9320066731D /* ConfirmPhrase.swift */; }; - CEAA9E9E1DC2F90C0066731D /* CircularPro-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CEAA9E9D1DC2F90C0066731D /* CircularPro-Bold.otf */; }; CEAA9EA01DC2F9F50066731D /* UIFont+BRWAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA9E9F1DC2F9F50066731D /* UIFont+BRWAdditions.swift */; }; - CEAA9EA31DC2FC700066731D /* CircularPro-Book.otf in Resources */ = {isa = PBXBuildFile; fileRef = CEAA9EA11DC2FC700066731D /* CircularPro-Book.otf */; }; - CEAA9EA41DC2FC700066731D /* CircularPro-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = CEAA9EA21DC2FC700066731D /* CircularPro-Medium.otf */; }; CEAA9EA61DC3246F0066731D /* StartNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA9EA51DC3246F0066731D /* StartNavigationDelegate.swift */; }; CEAA9EA81DC3342E0066731D /* PinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA9EA71DC3342E0066731D /* PinView.swift */; }; CEAFC8611E5D5B0500E4FD06 /* SegmentedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAFC8601E5D5B0500E4FD06 /* SegmentedButton.swift */; }; @@ -4061,7 +4058,6 @@ 24B8FAD72162B6FB00A155B1 /* bitrefill_index.html in Resources */, 75A2A79E1DA5934300A983D8 /* LaunchScreen.storyboard in Resources */, 24D5F23822599C0B00225462 /* BarlowSemiCondensed-Italic.ttf in Resources */, - CEAA9EA31DC2FC700066731D /* CircularPro-Book.otf in Resources */, 24D5F25922599C0B00225462 /* BarlowSemiCondensed-Medium.ttf in Resources */, 24313C9B23824F5800A83F69 /* Transactions.storyboard in Resources */, 222319B21F279B3C00008F20 /* POSTBouncer.html in Resources */, @@ -4082,14 +4078,12 @@ 24B8FADC2162D29100A155B1 /* general.css in Resources */, 24313CA323824F5800A83F69 /* Send.storyboard in Resources */, 2485F7D023728C19005962F1 /* RELEASE_NOTES.md in Resources */, - CEAA9EA41DC2FC700066731D /* CircularPro-Medium.otf in Resources */, 24B523AD238A53DC0030594D /* BIP39Words.plist in Resources */, 24313CAA23824F9800A83F69 /* Main.storyboard in Resources */, 24D5F25F22599C0B00225462 /* BarlowSemiCondensed-Regular.ttf in Resources */, 24DFCE6823B89CDE001F17F8 /* Settings.storyboard in Resources */, 24016D8E23F887C3006A6791 /* GoogleService-Info.plist in Resources */, 24393B5C23C259400075218D /* Phrase.storyboard in Resources */, - CEAA9E9E1DC2F90C0066731D /* CircularPro-Bold.otf in Resources */, 24313CA723824F5800A83F69 /* Spend.storyboard in Resources */, 75A2A79B1DA5934300A983D8 /* Assets.xcassets in Resources */, ); diff --git a/loafwallet/Info.plist b/loafwallet/Info.plist index 85b4d76ed..ed3c47731 100644 --- a/loafwallet/Info.plist +++ b/loafwallet/Info.plist @@ -117,9 +117,6 @@ Used to scan barcodes UIAppFonts - CircularPro-Bold.otf - CircularPro-Book.otf - CircularPro-Medium.otf BarlowSemiCondensed-SemiBold.ttf BarlowSemiCondensed-Medium.ttf BarlowSemiCondensed-Light.ttf diff --git a/loafwallet/src/Extensions/UIFont+BRWAdditions.swift b/loafwallet/src/Extensions/UIFont+BRWAdditions.swift index 727915921..fc15cb298 100644 --- a/loafwallet/src/Extensions/UIFont+BRWAdditions.swift +++ b/loafwallet/src/Extensions/UIFont+BRWAdditions.swift @@ -10,19 +10,19 @@ import UIKit extension UIFont { static var header: UIFont { - return UIFont(name: "CircularPro-Bold", size: 17.0) ?? UIFont.preferredFont(forTextStyle: .headline) + return UIFont(name: "BarlowSemiCondensed-Bold", size: 17.0) ?? UIFont.preferredFont(forTextStyle: .headline) } static func customBold(size: CGFloat) -> UIFont { - return UIFont(name: "CircularPro-Bold", size: size) ?? UIFont.preferredFont(forTextStyle: .headline) + return UIFont(name: "BarlowSemiCondensed-Bold", size: size) ?? UIFont.preferredFont(forTextStyle: .headline) } static func customBody(size: CGFloat) -> UIFont { - return UIFont(name: "CircularPro-Book", size: size) ?? UIFont.preferredFont(forTextStyle: .subheadline) + return UIFont(name: "BarlowSemiCondensed-Regular", size: size) ?? UIFont.preferredFont(forTextStyle: .subheadline) } static func customMedium(size: CGFloat) -> UIFont { - return UIFont(name: "CircularPro-Medium", size: size) ?? UIFont.preferredFont(forTextStyle: .body) + return UIFont(name: "BarlowSemiCondensed-Medium", size: size) ?? UIFont.preferredFont(forTextStyle: .body) } static func barlowBold(size: CGFloat) -> UIFont { From f6e2504bced10c28d64b66368a2138d7a06b43b2 Mon Sep 17 00:00:00 2001 From: Kerry Date: Wed, 14 Oct 2020 19:16:02 +0100 Subject: [PATCH 008/114] Updated key for RemoteRunnable in xcscheme --- .../loafwallet WatchKit App.xcscheme | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme index 1c2ce4696..c24cd938e 100644 --- a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme +++ b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme @@ -93,10 +93,8 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> - + - + - + - - - - - + From fc7bf0430d61df799f15b38b0479fe147058dc45 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 14 Oct 2020 23:32:08 +0100 Subject: [PATCH 009/114] Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade --- .github/bug_report.md | 32 +++++++++++++++++++ .github/feature_request.md | 20 ++++++++++++ .../loafwallet WatchKit App.xcscheme | 25 +++++++++++---- 3 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 .github/bug_report.md create mode 100644 .github/feature_request.md diff --git a/.github/bug_report.md b/.github/bug_report.md new file mode 100644 index 000000000..6dd708f75 --- /dev/null +++ b/.github/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots or GIFs** +If applicable, add screenshots or GIFs to help explain your problem. + +**Mobile device (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Litewallet Version [e.g. v2.7.1] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/feature_request.md b/.github/feature_request.md new file mode 100644 index 000000000..15c70fd2e --- /dev/null +++ b/.github/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for Litewallet +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme index c24cd938e..2b117aa58 100644 --- a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme +++ b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme @@ -93,8 +93,10 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> - + - + - + - + + + + + From 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 15 Oct 2020 23:11:13 +0100 Subject: [PATCH 010/114] [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message --- loafwallet.xcodeproj/project.pbxproj | 4 - loafwallet/BuyCenterTableViewController.swift | 128 -------------- loafwallet/BuyTableViewController.swift | 42 ++--- loafwallet/Storyboards/Buy.storyboard | 166 ++---------------- loafwallet/src/Constants/Strings.swift | 2 + .../Strings/Base.lproj/Localizable.strings | 3 + .../src/Strings/ar.lproj/Localizable.strings | 3 + .../src/Strings/da.lproj/Localizable.strings | 3 + .../src/Strings/de.lproj/Localizable.strings | 3 + .../src/Strings/en.lproj/Localizable.strings | 3 + .../src/Strings/es.lproj/Localizable.strings | 3 + .../src/Strings/fr.lproj/Localizable.strings | 3 + .../src/Strings/id.lproj/Localizable.strings | 3 + .../src/Strings/it.lproj/Localizable.strings | 3 + .../src/Strings/ja.lproj/Localizable.strings | 3 + .../src/Strings/ko.lproj/Localizable.strings | 3 + .../src/Strings/nl.lproj/Localizable.strings | 3 + .../src/Strings/pt.lproj/Localizable.strings | 3 + .../src/Strings/ru.lproj/Localizable.strings | 3 + .../src/Strings/sv.lproj/Localizable.strings | 3 + .../Strings/zh-Hans.lproj/Localizable.strings | 3 + .../Strings/zh-Hant.lproj/Localizable.strings | 3 + 22 files changed, 86 insertions(+), 307 deletions(-) delete mode 100644 loafwallet/BuyCenterTableViewController.swift diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 1481919af..572ed5039 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -123,7 +123,6 @@ 24AF00FE221B331D00FF636F /* WarningConfirmation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24AF00FC221B331D00FF636F /* WarningConfirmation.storyboard */; }; 24AF0101221B349100FF636F /* WarningConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24AF00FF221B349100FF636F /* WarningConfirmationViewController.swift */; }; 24B523AD238A53DC0030594D /* BIP39Words.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24B523AF238A53DC0030594D /* BIP39Words.plist */; }; - 24B8FAC12160497C00A155B1 /* BuyCenterTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B8FAC02160497B00A155B1 /* BuyCenterTableViewController.swift */; }; 24B8FAC4216128A000A155B1 /* PartnerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B8FAC3216128A000A155B1 /* PartnerData.swift */; }; 24B8FAD22162B10200A155B1 /* BuyCenterWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B8FAD12162B10200A155B1 /* BuyCenterWebViewController.swift */; }; 24B8FAD72162B6FB00A155B1 /* bitrefill_index.html in Resources */ = {isa = PBXBuildFile; fileRef = 24B8FAD62162B6FB00A155B1 /* bitrefill_index.html */; }; @@ -887,7 +886,6 @@ 24AF00FF221B349100FF636F /* WarningConfirmationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarningConfirmationViewController.swift; sourceTree = ""; }; 24B523AE238A53DC0030594D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/BIP39Words.plist; sourceTree = ""; }; 24B523B0238A53E40030594D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "zh-Hans"; path = "zh-Hans.lproj/BIP39Words.plist"; sourceTree = ""; }; - 24B8FAC02160497B00A155B1 /* BuyCenterTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuyCenterTableViewController.swift; sourceTree = ""; }; 24B8FAC3216128A000A155B1 /* PartnerData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnerData.swift; sourceTree = ""; }; 24B8FAD12162B10200A155B1 /* BuyCenterWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuyCenterWebViewController.swift; sourceTree = ""; }; 24B8FAD62162B6FB00A155B1 /* bitrefill_index.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = bitrefill_index.html; sourceTree = ""; }; @@ -2361,7 +2359,6 @@ 24C516502158820E007CE038 /* Buy */ = { isa = PBXGroup; children = ( - 24B8FAC02160497B00A155B1 /* BuyCenterTableViewController.swift */, 24B8FAD12162B10200A155B1 /* BuyCenterWebViewController.swift */, 248BFE2323AAD53700CE1A71 /* BuyTableViewController.swift */, 248BFE2523AB302200CE1A71 /* BuyWKWebViewController.swift */, @@ -4507,7 +4504,6 @@ CEC6AA3D1DEE687000EE5AFD /* RadialGradientView.swift in Sources */, 2494038123AF208F00369261 /* PromptModalViewController.swift in Sources */, CEEC70921E95DA4400EF788E /* GradientSwitch.swift in Sources */, - 24B8FAC12160497C00A155B1 /* BuyCenterTableViewController.swift in Sources */, CE0CD1591DBFBCF5004023DA /* ModalPresenter.swift in Sources */, CEE20C2F1EA3E5820086F724 /* BlinkingView.swift in Sources */, CEC6AA441DEFCDE900EE5AFD /* ModalViewController.swift in Sources */, diff --git a/loafwallet/BuyCenterTableViewController.swift b/loafwallet/BuyCenterTableViewController.swift deleted file mode 100644 index ec6c52d79..000000000 --- a/loafwallet/BuyCenterTableViewController.swift +++ /dev/null @@ -1,128 +0,0 @@ -// -// BuyCenterTableViewController.swift -// breadwallet -// -// Created by Kerry Washington on 9/27/18. -// Copyright © 2018 breadwallet LLC. All rights reserved. -// - -import UIKit - -//let buyCellReuseIdentifier = "buyCell" - -//class BuyCenterTableViewController: UITableViewController, BuyCenterTableViewCellDelegate { -// -// fileprivate let litecoinLogo = UIImageView(image:#imageLiteral(resourceName: "litecoinLogo")) -// private let store: Store -// private let walletManager: WalletManager -// private let mountPoint: String -// private let partnerArray = Partner.dataArray() -// private let headerHeight : CGFloat = 140 -// -// init(store: Store, walletManager: WalletManager, mountPoint: String) { -// self.store = store -// self.walletManager = walletManager -// self.mountPoint = mountPoint -// super.init(nibName: nil, bundle: nil) -// } -// -// required init?(coder aDecoder: NSCoder) { -// fatalError("init(coder:) has not been implemented") -// } -// -// override func viewDidLoad() { -// super.viewDidLoad() -// self.tableView.separatorColor = UIColor.clear -// self.tableView.dataSource = self -// self.tableView.delegate = self -// self.tableView.register(BuyCenterTableViewCell.self, forCellReuseIdentifier: buyCellReuseIdentifier) -// self.tableView.backgroundColor = #colorLiteral(red: 0.9529411765, green: 0.9529411765, blue: 0.9529411765, alpha: 1) // #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9411764706, alpha: 1) -// self.clearsSelectionOnViewWillAppear = false -// Mixpanel.mainInstance().track(event: K.MixpanelEvents._20191105_DTBT.rawValue, properties: nil) -// } -// -// override func didReceiveMemoryWarning() { -// super.didReceiveMemoryWarning() -// // Dispose of any resources that can be recreated. -// } -// -// override var preferredStatusBarStyle: UIStatusBarStyle { -// return .lightContent -// } -// -// // MARK: - Table view data source -// override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 150 } -// -// override func numberOfSections(in tableView: UITableView) -> Int { return 1 } -// -// override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return partnerArray.count } -// -// override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { -// -// let fr = CGRect(x: 0, y: 0, width: self.view.frame.width, height: headerHeight) -// let buyCenterHeaderView = BuyCenterHeaderView(frame: fr, height: headerHeight) -// buyCenterHeaderView.closeCallback = { -// self.dismiss(animated: true, completion: nil) -// } -// return buyCenterHeaderView -// } -// -// override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return headerHeight } -// -// override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { -// let cell = tableView.dequeueReusableCell(withIdentifier: buyCellReuseIdentifier, for: indexPath) as! BuyCenterTableViewCell -// let partnerData = partnerArray[indexPath.row] -// cell.partnerLabel.text = partnerData["title"] as? String -// -// if let details = partnerData["details"] as? String, -// let color = partnerData["baseColor"] as? UIColor { -// cell.financialDetailsLabel.text = details -// cell.frameView.backgroundColor = color -// } else { -// NSLog("ERROR: Unable to retrieve partner details") -// } -// -// cell.logoImageView.image = partnerData["logo"] as? UIImage -// -// cell.delegate = self -// -// return cell -// } -// -// func didClickPartnerCell(partner: String) { -// -// switch partner { -// case "Simplex": -// let simplexWebviewVC = BRWebViewController(partner: "Simplex", mountPoint: mountPoint + "_simplex", walletManager: walletManager, store: store, noAuthApiClient: nil) -// present(simplexWebviewVC, animated: true -// , completion: nil) -// case "Changelly": -// print("Changelly No Code Placeholder") -// case "Coinbase": -// let coinbaseWebViewWC = BRWebViewController(partner: "Coinbase", mountPoint: mountPoint + "_coinbase", walletManager: walletManager, store: store, noAuthApiClient: nil) -// present(coinbaseWebViewWC, animated: true) { -// // -// } -// default: -// fatalError("No Partner Chosen") -// } -// } -// -// @objc func dismissWebContainer() { -// dismiss(animated: true, completion: nil) -// } -//} - - -//extension BuyCenterTableViewController: ModalDisplayable { - -// var faqArticleId: String? { -// return nil -// } -// -// var modalTitle: String { -// return S.BuyCenter.buyModalTitle -// } -//} - - diff --git a/loafwallet/BuyTableViewController.swift b/loafwallet/BuyTableViewController.swift index c4d8cff5d..81cd9ad1c 100644 --- a/loafwallet/BuyTableViewController.swift +++ b/loafwallet/BuyTableViewController.swift @@ -8,18 +8,10 @@ import UIKit -class BuyTableViewController: UITableViewController { - - @IBOutlet weak var simplexLogoImageView: UIImageView! - @IBOutlet weak var simplexHeaderLabel: UILabel! - @IBOutlet weak var simplexDetailsLabel: UILabel! - @IBOutlet weak var simplexCellContainerView: UIView! - - @IBOutlet weak var chooseFiatLabel: UILabel! - @IBOutlet weak var currencySegmentedControl: UISegmentedControl! +class BuyTableViewController: UITableViewController { private var currencyCode: String = "USD" - + @IBAction func didTapSimplex(_ sender: Any) { if let vcWKVC = UIStoryboard.init(name: "Buy", bundle: nil).instantiateViewController(withIdentifier: "BuyWKWebViewController") as? BuyWKWebViewController { @@ -39,7 +31,7 @@ class BuyTableViewController: UITableViewController { NSLog("ERROR: Storyboard not initialized") } } - + var store: Store? var walletManager: WalletManager? let mountPoint = "" @@ -50,29 +42,29 @@ class BuyTableViewController: UITableViewController { thinHeaderView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 1.0) thinHeaderView.backgroundColor = .white tableView.tableHeaderView = thinHeaderView + + + // TODO: Remove when Simplex or any partner is ready for operations + let comingSoonLabel = UILabel() + comingSoonLabel.textAlignment = .center + comingSoonLabel.textColor = .white + comingSoonLabel.font = UIFont.barlowBold(size: 20) + comingSoonLabel.text = S.BuyCenter.comingSoon + + tableView.backgroundView = comingSoonLabel + tableView.tableFooterView = UIView() - currencySegmentedControl.addTarget(self, action: #selector(didChangeCurrency), for: .valueChanged) - currencySegmentedControl.selectedSegmentIndex = PartnerFiatOptions.usd.index + LWAnalytics.logEventWithParameters(itemName: ._20191105_DTBT) setupData() } private func setupData() { - let simplexData = Partner.partnerDataArray()[0] - simplexLogoImageView.image = simplexData.logo - simplexHeaderLabel.text = simplexData.headerTitle - simplexDetailsLabel.text = simplexData.details - simplexCellContainerView.layer.cornerRadius = 6.0 - simplexCellContainerView.layer.borderColor = UIColor.white.cgColor - simplexCellContainerView.layer.borderWidth = 1.0 - simplexCellContainerView.clipsToBounds = true - chooseFiatLabel.text = S.DefaultCurrency.chooseFiatLabel } @objc private func didChangeCurrency() { - if let code = PartnerFiatOptions(rawValue: currencySegmentedControl.selectedSegmentIndex)?.description { - self.currencyCode = code - } + } } + diff --git a/loafwallet/Storyboards/Buy.storyboard b/loafwallet/Storyboards/Buy.storyboard index 09e7dd959..fc06098f5 100644 --- a/loafwallet/Storyboards/Buy.storyboard +++ b/loafwallet/Storyboards/Buy.storyboard @@ -1,16 +1,14 @@ - + - + + - - BarlowSemiCondensed-Bold - BarlowSemiCondensed-Light @@ -29,136 +27,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -166,14 +35,6 @@ - - - - - - - - @@ -201,11 +62,11 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -35,6 +166,14 @@ + + + + + + + + @@ -62,11 +201,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loafwallet/SupportLFViewModel.swift b/loafwallet/SupportLFViewModel.swift new file mode 100644 index 000000000..03a5057e3 --- /dev/null +++ b/loafwallet/SupportLFViewModel.swift @@ -0,0 +1,15 @@ +// +// SupportLFViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 11/2/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation + +class SupportLFViewModel: ObservableObject { + + init() {} + +} diff --git a/loafwallet/SupportLitecoinFoundationView.swift b/loafwallet/SupportLitecoinFoundationView.swift new file mode 100644 index 000000000..f9694228b --- /dev/null +++ b/loafwallet/SupportLitecoinFoundationView.swift @@ -0,0 +1,91 @@ +// +// SupportLitecoinFoundationView.swift +// loafwallet +// +// Created by Kerry Washington on 11/9/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI +import Foundation +import WebKit + +/// This cell is under the amount view and above the Memo view in the Send VC +struct SupportLitecoinFoundationView: View { + + //MARK: - Combine Variables + @ObservedObject + var viewModel: SupportLitecoinFoundationViewModel + + @State + var supportLTCAddress = "" + + @State + private var showSupportLFPage: Bool = false + + //MARK: - Public + var supportSafariView = SupportSafariView(url: FoundationSupport.url, + viewModel: SupportSafariViewModel()) + + init(viewModel: SupportLitecoinFoundationViewModel) { + self.viewModel = viewModel + } + + var body: some View { + VStack { + Spacer() + Button(action: { + self.showSupportLFPage = true + }) { + + Text(S.SupportLitecoinFoundation.title) + .padding(.all,10) + .font(Font(UIFont.customMedium(size: 16.0))) + .foregroundColor(Color(UIColor.grayTextTint)) + .background(Color(UIColor.secondaryButton)) + .overlay( + RoundedRectangle(cornerRadius: 4) + .stroke(Color(UIColor.secondaryBorder)) + ) + } + .sheet(isPresented: self.$showSupportLFPage, + onDismiss: { + viewModel.updateAddressString(address: supportSafariView + .viewModel + .supportLTCAddress) + } + ) { + VStack { + Spacer() + supportSafariView + .frame(height: 500, + alignment: .center + ) + .padding(.bottom, 50) + Button(action: { + self.showSupportLFPage = false + }) { + Text(S.URLHandling.copy) + .padding([.leading,.trailing],20) + .padding([.top,.bottom],10) + .font(Font(UIFont.customMedium(size: 16.0))) + .foregroundColor(Color(UIColor.grayTextTint)) + .background(Color(UIColor.secondaryButton)) + .overlay( + RoundedRectangle(cornerRadius: 4) + .stroke(Color(UIColor.secondaryBorder)) + ) + } + .padding(.bottom, 50) + .padding([.leading,.trailing], 50) + } + } + Spacer() + Rectangle() + .fill(Color(UIColor.secondaryBorder)) + .frame(height: 1.0) + + } + } +} + diff --git a/loafwallet/SupportLitecoinFoundationViewModel.swift b/loafwallet/SupportLitecoinFoundationViewModel.swift new file mode 100644 index 000000000..9c5db45f6 --- /dev/null +++ b/loafwallet/SupportLitecoinFoundationViewModel.swift @@ -0,0 +1,28 @@ +// +// SupportLitecoinFoundationViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 11/9/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine + + +class SupportLitecoinFoundationViewModel: ObservableObject { + + //MARK: - Combine Variables + @Published + var supportLTCAddress: String = "" + + //MARK: - Public Variables + var didGetLTCAddress: ((String) -> Void)? + + init() {} + + func updateAddressString(address: String) { + didGetLTCAddress?(address) + } +} diff --git a/loafwallet/SupportSafariView.swift b/loafwallet/SupportSafariView.swift new file mode 100644 index 000000000..4074ed8b3 --- /dev/null +++ b/loafwallet/SupportSafariView.swift @@ -0,0 +1,91 @@ +// +// SupportSafariView.swift +// loafwallet +// +// Created by Kerry Washington on 11/13/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI +import WebKit + +/// Customized version of Embedded WKWebView +struct SupportSafariView: UIViewRepresentable { + + //MARK: - Combine Variables + @ObservedObject + var viewModel: SupportSafariViewModel + + //MARK: - Public Variables + let url: URL + var wkWebView = WKWebView() + + init(url: URL, viewModel: SupportSafariViewModel) { + self.viewModel = viewModel + self.url = url + } + + class Coordinator: NSObject, WKUIDelegate, WKNavigationDelegate { + var parent: SupportSafariView + private var wkWebView: WKWebView + + init(_ parent: SupportSafariView) { + self.parent = parent + self.wkWebView = self.parent.wkWebView + } + + /// WKNavigationDelegate Method + /// - Parameters: + /// - webView: Embedded webView + /// - navigation: nil + func webView(_ webView: WKWebView, + didFinish navigation: WKNavigation!) { + + // MARK: - Parse LF LTC Address + webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", + completionHandler: { ( htmlString: Any, error: Error?) in + if let string = htmlString as? String, + let suffix = string.components(separatedBy:"") + let element = content.filter{ $0.contains(" WKWebView { + return WKWebView(frame: .zero) + } + + func updateUIView(_ view: WKWebView, context: Context) { + + /// Sets the delegates and lets coordinator fire delegate actions + view.uiDelegate = context.coordinator + view.navigationDelegate = context.coordinator + + view.load(URLRequest(url: self.url)) + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + func reload(){ + wkWebView.reload() + } + +} + +struct GenericSafariView_Previews: PreviewProvider { + static let viewModel = SupportSafariViewModel() + static var previews: some View { + SupportSafariView(url: FoundationSupport.url, viewModel: viewModel) + } +} diff --git a/loafwallet/SupportSafariViewModel.swift b/loafwallet/SupportSafariViewModel.swift new file mode 100644 index 000000000..136d8737d --- /dev/null +++ b/loafwallet/SupportSafariViewModel.swift @@ -0,0 +1,17 @@ +// +// SupportSafariViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 11/13/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation + +class SupportSafariViewModel: ObservableObject { + + @Published + var supportLTCAddress = "" + + init() { } +} diff --git a/loafwallet/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index bd542f5da..66d3c36ef 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -6,7 +6,7 @@ // Copyright © 2019 Litecoin Foundation. All rights reserved. import UIKit -import Foundation +import Foundation enum TabViewControllerIndex: Int { case transactions = 0 diff --git a/loafwallet/TransactionTableViewCells.swift b/loafwallet/TransactionTableViewCells.swift index 0f26423de..c5284758d 100644 --- a/loafwallet/TransactionTableViewCells.swift +++ b/loafwallet/TransactionTableViewCells.swift @@ -262,7 +262,7 @@ enum PromptType { } } - func shouldPrompt(walletManager: WalletManager, state: State) -> Bool { + func shouldPrompt(walletManager: WalletManager, state: ReduxState) -> Bool { switch self { case .biometrics: diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index eea3058d1..e51fb60dc 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -9,23 +9,7 @@ import UIKit let π: CGFloat = .pi -let kDonationAmount: UInt64 = 1800000 -let kDonationAmountInDouble: Double = Double(kDonationAmount) / Double(100000000) - -enum LWDonationAddress: String { - case litwalletHardware = "Litewallet Hardware Fundraiser" //TODO: Remove after fundraiser goal is acheived in 2020 - case generalLitecoinFoundation = "Litecoin Foundation" - - static let allValues = [litwalletHardware, generalLitecoinFoundation] - - var address: String { - switch self { - case .litwalletHardware: return "MJ4W7NZya4SzE7R6xpEVdamGCimaQYPiWu" //old MVRj1whQ8hqcpffjRxLLCJG1mD27V9YygY - case .generalLitecoinFoundation: return "MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe" //old MDPqwDf9eUErGLcZNt1HN9HqnbFCSCSRme - } - } -} - + enum CustomEvent: String { case _20191105_AL = "APP_LAUNCHED" case _20191105_VSC = "VISIT_SEND_CONTROLLER" @@ -49,8 +33,16 @@ enum CustomEvent: String { case _20200223_DD = "DID_DONATE" case _20200225_DCD = "DID_CANCEL_DONATE" case _20200301_DUDFPK = "DID_USE_DEFAULT_FEE_PER_KB" + case _20201118_DTS = "DID_TAP_SUPPORT_LF" +} + +struct FoundationSupport { + + static let url = URL(string: "https://lite-wallet.org/support_address.html")! - + /// Litecoin Foundation main donation address: MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe + /// As of Nov 14th, 2020 + static let supportLTCAddress = "MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe" } struct Padding { @@ -59,6 +51,12 @@ struct Padding { return CGFloat(multiplier) * 8.0 } } + + subscript(multiplier: Double) -> CGFloat { + get { + return CGFloat(multiplier) * 8.0 + } + } } struct C { diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index 7d325550d..f7e33df56 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -573,12 +573,8 @@ enum S { } - enum Donate { - static let title = NSLocalizedString("Donate.title", value: "**Donate to the Litecoin Foundation! %@**", comment: "Donate to the Litecoin Foundation") - static let titleConfirmation = NSLocalizedString("Donate.title.confirmation", value: "**Confirm Donation**", comment: "Donate Confirmation") - static let memo = NSLocalizedString("Donate.memo", value: "**Donation to the Litecoin Foundation**", comment: "Donate Memo") - static let toThe = NSLocalizedString("Donate.toThe", value: "**Donate to the**", comment: "Donate articles to the") - static let word = NSLocalizedString("Donate.word", value: "**Donate**", comment: "Donate") + enum SupportLitecoinFoundation { + static let title = NSLocalizedString("SupportTheFoundation.title", value: "**Support the Litecoin Foundation**", comment: "Support the Litecoin Foundation") } enum WipeWallet { diff --git a/loafwallet/src/Extensions/UIColor+Extension.swift b/loafwallet/src/Extensions/UIColor+Extension.swift index 605a4c731..ef7c991f8 100644 --- a/loafwallet/src/Extensions/UIColor+Extension.swift +++ b/loafwallet/src/Extensions/UIColor+Extension.swift @@ -155,4 +155,4 @@ extension UIColor { static var txListGreen: UIColor { return UIColor(red: 0.0, green: 169.0/255.0, blue: 157.0/255.0, alpha: 1.0) } -} +} diff --git a/loafwallet/src/FlowControllers/StartFlowPresenter.swift b/loafwallet/src/FlowControllers/StartFlowPresenter.swift index 1b03b0232..95435ef87 100644 --- a/loafwallet/src/FlowControllers/StartFlowPresenter.swift +++ b/loafwallet/src/FlowControllers/StartFlowPresenter.swift @@ -48,7 +48,7 @@ class StartFlowPresenter : Subscriber { callback: { _ in self.presentLoginFlow(isPresentedForLock: true) }) } - private func handleStartFlowChange(state: State) { + private func handleStartFlowChange(state: ReduxState) { if state.isStartFlowVisible { guardProtected(queue: DispatchQueue.main) { [weak self] in self?.presentStartFlow() @@ -58,7 +58,7 @@ class StartFlowPresenter : Subscriber { } } - private func handleLoginRequiredChange(state: State) { + private func handleLoginRequiredChange(state: ReduxState) { if state.isLoginRequired { presentLoginFlow(isPresentedForLock: false) } else { diff --git a/loafwallet/src/SimpleRedux.swift b/loafwallet/src/SimpleRedux.swift index f65bc13be..fc36ced6e 100644 --- a/loafwallet/src/SimpleRedux.swift +++ b/loafwallet/src/SimpleRedux.swift @@ -8,8 +8,8 @@ import UIKit -typealias Reducer = (State) -> State -typealias Selector = (_ oldState: State, _ newState: State) -> Bool +typealias Reducer = (ReduxState) -> ReduxState +typealias Selector = (_ oldState: ReduxState, _ newState: ReduxState) -> Bool protocol Action { var reduce: Reducer { get } @@ -24,11 +24,11 @@ extension Subscriber { } } -typealias StateUpdatedCallback = (State) -> Void +typealias StateUpdatedCallback = (ReduxState) -> Void struct Subscription { - let selector: ((_ oldState: State, _ newState: State) -> Bool) - let callback: (State) -> Void + let selector: ((_ oldState: ReduxState, _ newState: ReduxState) -> Bool) + let callback: (ReduxState) -> Void } struct Trigger { @@ -148,13 +148,13 @@ class Store { //Subscription callback is immediately called with current State value on subscription //and then any time the selected value changes - func subscribe(_ subscriber: Subscriber, selector: @escaping Selector, callback: @escaping (State) -> Void) { + func subscribe(_ subscriber: Subscriber, selector: @escaping Selector, callback: @escaping (ReduxState) -> Void) { lazySubscribe(subscriber, selector: selector, callback: callback) callback(state) } //Same as subscribe(), but doesn't call the callback with current state upon subscription - func lazySubscribe(_ subscriber: Subscriber, selector: @escaping Selector, callback: @escaping (State) -> Void) { + func lazySubscribe(_ subscriber: Subscriber, selector: @escaping Selector, callback: @escaping (ReduxState) -> Void) { let key = subscriber.hashValue let subscription = Subscription(selector: selector, callback: callback) if subscriptions[key] != nil { @@ -180,7 +180,7 @@ class Store { } //MARK: - Private - private(set) var state = State.initial { + private(set) var state = ReduxState.initial { didSet { subscriptions .flatMap { $0.value } //Retreive all subscriptions (subscriptions is a dictionary) diff --git a/loafwallet/src/SimpleRedux/Actions.swift b/loafwallet/src/SimpleRedux/Actions.swift index 06441f3d0..228b585c5 100644 --- a/loafwallet/src/SimpleRedux/Actions.swift +++ b/loafwallet/src/SimpleRedux/Actions.swift @@ -17,7 +17,7 @@ struct ShowStartFlow : Action { struct HideStartFlow : Action { let reduce: Reducer = { state in - return State(isStartFlowVisible: false, + return ReduxState(isStartFlowVisible: false, isLoginRequired: state.isLoginRequired, rootModal: .none, walletState: state.walletState, @@ -39,7 +39,7 @@ struct HideStartFlow : Action { struct Reset : Action { let reduce: Reducer = { _ in - return State.initial.clone(isLoginRequired: false) + return ReduxState.initial.clone(isLoginRequired: false) } } @@ -241,9 +241,9 @@ enum UpdateFees { //MARK: - State Creation Helpers -extension State { - func clone(isStartFlowVisible: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, +extension ReduxState { + func clone(isStartFlowVisible: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -261,8 +261,8 @@ extension State { pinLength: pinLength, fees: fees) } - func rootModal(_ type: RootModal) -> State { - return State(isStartFlowVisible: false, + func rootModal(_ type: RootModal) -> ReduxState { + return ReduxState(isStartFlowVisible: false, isLoginRequired: isLoginRequired, rootModal: type, walletState: walletState, @@ -280,8 +280,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(pasteboard: String?) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(pasteboard: String?) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -299,8 +299,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(walletSyncProgress: Double, timestamp: UInt32) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(walletSyncProgress: Double, timestamp: UInt32) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletSyncProgress, syncState: walletState.syncState, balance: walletState.balance, transactions: walletState.transactions, lastBlockTimestamp: timestamp, name: walletState.name, creationDate: walletState.creationDate, isRescanning: walletState.isRescanning), @@ -318,8 +318,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(syncState: SyncState) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(syncState: SyncState) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletState.syncProgress, syncState: syncState, balance: walletState.balance, transactions: walletState.transactions, lastBlockTimestamp: walletState.lastBlockTimestamp, name: walletState.name, creationDate: walletState.creationDate, isRescanning: walletState.isRescanning), @@ -337,8 +337,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(balance: UInt64) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(balance: UInt64) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletState.syncProgress, syncState: walletState.syncState, balance: balance, transactions: walletState.transactions, lastBlockTimestamp: walletState.lastBlockTimestamp, name: walletState.name, creationDate: walletState.creationDate, isRescanning: walletState.isRescanning), @@ -356,8 +356,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(transactions: [Transaction]) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(transactions: [Transaction]) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletState.syncProgress, syncState: walletState.syncState, balance: walletState.balance, transactions: transactions, lastBlockTimestamp: walletState.lastBlockTimestamp, name: walletState.name, creationDate: walletState.creationDate, isRescanning: walletState.isRescanning), @@ -375,8 +375,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(walletName: String) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(walletName: String) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletState.syncProgress, syncState: walletState.syncState, balance: walletState.balance, transactions: walletState.transactions, lastBlockTimestamp: walletState.lastBlockTimestamp, name: walletName, creationDate: walletState.creationDate, isRescanning: walletState.isRescanning), @@ -394,8 +394,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(walletSyncingErrorMessage: String?) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(walletSyncingErrorMessage: String?) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletState.syncProgress, syncState: walletState.syncState, balance: walletState.balance, transactions: walletState.transactions, lastBlockTimestamp: walletState.lastBlockTimestamp, name: walletState.name, creationDate: walletState.creationDate, isRescanning: walletState.isRescanning), @@ -413,8 +413,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(walletCreationDate: Date) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(walletCreationDate: Date) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletState.syncProgress, syncState: walletState.syncState, balance: walletState.balance, transactions: walletState.transactions, lastBlockTimestamp: walletState.lastBlockTimestamp, name: walletState.name, creationDate: walletCreationDate, isRescanning: walletState.isRescanning), @@ -432,8 +432,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(isRescanning: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(isRescanning: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: WalletState(isConnected: walletState.isConnected, syncProgress: walletState.syncProgress, syncState: walletState.syncState, balance: walletState.balance, transactions: walletState.transactions, lastBlockTimestamp: walletState.lastBlockTimestamp, name: walletState.name, creationDate: walletState.creationDate, isRescanning: isRescanning), @@ -451,8 +451,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(isLtcSwapped: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(isLtcSwapped: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -470,8 +470,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(isLoginRequired: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(isLoginRequired: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -489,8 +489,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(currentRate: Rate, rates: [Rate]) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(currentRate: Rate, rates: [Rate]) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -508,8 +508,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(currentRate: Rate) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(currentRate: Rate) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -527,8 +527,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(alert: AlertType?) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(alert: AlertType?) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -546,8 +546,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(isBiometricsEnabled: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(isBiometricsEnabled: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -565,8 +565,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(defaultCurrencyCode: String) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(defaultCurrencyCode: String) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -584,8 +584,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(recommendRescan: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(recommendRescan: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -603,8 +603,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(isLoadingTransactions: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(isLoadingTransactions: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -622,8 +622,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(maxDigits: Int) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(maxDigits: Int) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -641,8 +641,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(isPushNotificationsEnabled: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(isPushNotificationsEnabled: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -660,8 +660,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(isPromptingBiometrics: Bool) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(isPromptingBiometrics: Bool) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -679,8 +679,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(pinLength: Int) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(pinLength: Int) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, @@ -698,8 +698,8 @@ extension State { pinLength: pinLength, fees: fees) } - func clone(fees: Fees) -> State { - return State(isStartFlowVisible: isStartFlowVisible, + func clone(fees: Fees) -> ReduxState { + return ReduxState(isStartFlowVisible: isStartFlowVisible, isLoginRequired: isLoginRequired, rootModal: rootModal, walletState: walletState, diff --git a/loafwallet/src/SimpleRedux/State.swift b/loafwallet/src/SimpleRedux/ReduxState.swift similarity index 95% rename from loafwallet/src/SimpleRedux/State.swift rename to loafwallet/src/SimpleRedux/ReduxState.swift index 4a0c72bd9..d77009e7c 100644 --- a/loafwallet/src/SimpleRedux/State.swift +++ b/loafwallet/src/SimpleRedux/ReduxState.swift @@ -8,7 +8,7 @@ import UIKit -struct State { +struct ReduxState { let isStartFlowVisible: Bool let isLoginRequired: Bool let rootModal: RootModal @@ -28,9 +28,9 @@ struct State { let fees: Fees } -extension State { - static var initial: State { - return State( isStartFlowVisible: false, +extension ReduxState { + static var initial: ReduxState { + return ReduxState( isStartFlowVisible: false, isLoginRequired: true, rootModal: .none, walletState: WalletState.initial, diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index cf4338431..9b40160e3 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1263,3 +1263,6 @@ /* Message for luxury fee */ "FeeSelector.luxuryMessage" = "This option virtually guarantees acceptance of your transaction though you are paying a premium."; + +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Support the Litecoin Foundation"; diff --git a/loafwallet/src/Strings/ar.lproj/Localizable.strings b/loafwallet/src/Strings/ar.lproj/Localizable.strings index e9007dc6d..a672cd2e3 100644 --- a/loafwallet/src/Strings/ar.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ar.lproj/Localizable.strings @@ -248,15 +248,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Exchange Rate"; -/* Donate Memo */ -"Donate.memo" = "Donation to the Litecoin Foundation"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Tap to Donate to the Litecoin Foundation!"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Confirm Donation"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "This device isn't configured to send email with the iOS mail app."; @@ -890,6 +881,9 @@ /* Start view message */ "StartViewController.message" = "The most secure and safest way to use Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Support the Litecoin Foundation"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Connecting..."; @@ -1238,12 +1232,6 @@ /* Corruption Error alert title */ "Alert.corruptionMessage" = ""; -/* Donate Memo */ -"Donate.toThe" = ""; - -/* Donate */ -"Donate.word" = ""; - /* Luxury fee */ "FeeSelector.luxury" = ""; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index 2c3c1b16e..3f7657a3d 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Valutakurs"; -/* Donate Memo */ -"Donate.memo" = "Donation til Litecoin Foundation"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Tryk for at donere til Litecoin Foundation (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Bekræft donation"; - -/* Donate articles to the */ -"Donate.toThe" = "Doner til"; - -/* Donate */ -"Donate.word" = "Doner"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Denne enhed er ikke konfigureret til at sende e-mail med iOS mailappen."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "Den mest sikre og trygge måde at bruge Litecoins på."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Støt Litecoin Foundation"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Tilslutning..."; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index 897d164d3..bcefc1ba4 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Wechselkurs"; -/* Donate Memo */ -"Donate.memo" = "Spende an die Litecoin Foundation"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Spenden Sie an die Litecoin Foundation (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Spendenbestätigung"; - -/* Donate articles to the */ -"Donate.toThe" = "Spenden Sie an die"; - -/* Donate */ -"Donate.word" = "Spenden"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Dieses Gerät ist nicht dafür eingerichtet, E-Mails mit der iOS-Mail-App zu versenden."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "Die sicherste Option zur Nutzung von Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Unterstützung der Litecoin Foundation"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Verbindung wird hergestellt ..."; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index 879b5dba0..960ffc336 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Exchange Rate"; -/* Donate Memo */ -"Donate.memo" = "Donation to the Litecoin Foundation"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Donate to the Litecoin Foundation (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Confirm Donation"; - -/* Donate to the articles */ -"Donate.toThe" = "Donate to the"; - -/* Donate */ -"Donate.word" = "Donate"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "This device isn't configured to send email with the iOS mail app."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "The most secure and safest way to use Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Support the Litecoin Foundation"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Connecting..."; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 1321d903c..1ad53e09c 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -255,21 +255,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Tasa de cambio"; -/* Donate Memo */ -"Donate.memo" = "Donación a la Fundación Litecoin"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Done a la Fundación Litecoin (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Confirmar donación"; - -/* Donate articles to the */ -"Donate.toThe" = "Done a la"; - -/* Donate */ -"Donate.word" = "Donar"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Este dispositivo no está configurado para enviar correo electrónico mediante una aplicación de iOS"; @@ -912,6 +897,9 @@ /* Start view message */ "StartViewController.message" = "La forma más segura de usar Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Apoyar la Fundación Litecoin"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Conectando ..."; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index 906484ddb..8ad5c11bf 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Taux de change"; -/* Donate Memo */ -"Donate.memo" = "Don à la Fondation Litecoin"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Faites un don à la Fondation Litecoin (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Confirmer le don"; - -/* Donate articles to the */ -"Donate.toThe" = "Faire un don à"; - -/* Donate */ -"Donate.word" = "Faire un don"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Cet appareil n'est pas configuré pour envoyer un e-mail avec l'application e-mail pour iOS."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "La façon la plus sécurisée et sûre d'utiliser Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Soutenez la Fondation Litecoin"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "De liaison..."; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index caeea1224..66fadc81d 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Kurs"; -/* Donate Memo */ -"Donate.memo" = "Sumbangan untuk Yayasan Litecoin"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Ketuk untuk Menyumbang ke Yayasan Litecoin (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Konfirmasi Sumbangan"; - -/* Donate to the articles */ -"Donate.toThe" = "Donasi ke"; - -/* Donate */ -"Donate.word" = "Menyumbangkan"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Perangkat ini tidak dikonfigurasikan untuk mengirim email dengan aplikasi surat iOS."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "Cara paling aman dan teraman untuk menggunakan Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Dukung Yayasan Litecoin"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Menghubungkan ..."; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index 597e0b3ae..75c6f7e89 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Tasso di Cambio"; -/* Donate Memo */ -"Donate.memo" = "Donazione alla Fondazione Litecoin"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Tocca per donare alla Fondazione Litecoin (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Conferma donazione"; - -/* Donate to the articles */ -"Donate.toThe" = "Dona al"; - -/* Donate */ -"Donate.word" = "Donare"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Questo dispositivo non è configurato per inviare e-mail con l'app Mail di iOS."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "Il modo più sicuro per usare i Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Sostenere la Fondazione Litecoin"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Connessione in corso ..."; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index 896b3880e..dd0bd9fce 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "為替レート"; -/* Donate Memo */ -"Donate.memo" = "ライトコイン財団への寄付"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "ライトコイン財団に寄付してください (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "寄付を確認する"; - -/* Donate articles to the */ -"Donate.toThe" = "に寄付する"; - -/* Donate */ -"Donate.word" = "寄付"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "この端末は、iOSのメールアプリを使用してメールを送信する設定がされていません。"; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "最も安全にリテコインを使う手段。"; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Litecoin基金を支援する"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "接続しています..."; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index 7bfd30921..fffd6620e 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "환율"; -/* Donate Memo */ -"Donate.memo" = "라이트 코인 재단에 기부"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "라이트 코인 재단에 기부하려면 탭하세요 (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "기부 확인"; - -/* Donate to the articles */ -"Donate.toThe" = "에 기부"; - -/* Donate */ -"Donate.word" = "기부"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "이 장치는 iOS 메일 앱으로 이메일을 전송하도록 설정되지 않았습니다."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "Litecoin을 사용하는 가장 안정되고 안전한 방법."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "라이트 코인 재단 지원"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "연결 중 ..."; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index c25aa3e72..0bb354677 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Wisselkoers"; -/* Donate Memo */ -"Donate.memo" = "Donatie aan de Litecoin Foundation"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Tik om te doneren aan de Litecoin Foundation (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Bevestig donatie"; - -/* Donate articles to the */ -"Donate.toThe" = "Doneer aan de"; - -/* Donate */ -"Donate.word" = "schenken"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Dit apparaat is niet geconfigureerd om e-mails te sturen via de iOS Mail app."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "De veiligste en betrouwbaarste manier om Litecoin te gebruiken."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Steun de Stichting Litecoin"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Verbinden..."; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index 2af7dc58b..200fd59c3 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -255,21 +255,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Taxa de Câmbio"; -/* Donate Memo */ -"Donate.memo" = "Doação para a Litecoin Foundation"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Toque para doar para a Litecoin Foundation (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Confirmar Doação"; - -/* Donate to the articles */ -"Donate.toThe" = "Doe para o"; - -/* Donate */ -"Donate.word" = "Doar"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Este dispositivo não está configurado para enviar emails com a app Mail do iOS."; @@ -912,6 +897,9 @@ /* Start view message */ "StartViewController.message" = "A forma mais protegida e segura de utilizar a Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Apoiar a Fundação Litecoin"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Connecting..."; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index 5447eadcc..7ab4875de 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Обменный курс"; -/* Donate Memo */ -"Donate.memo" = "Пожертвование в фонд Litecoin"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Нажмите, чтобы пожертвовать в фонд Litecoin (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Подтвердите Пожертвование"; - -/* Donate articles to the */ -"Donate.toThe" = "Пожертвовать"; - -/* Donate */ -"Donate.word" = "жертвовать"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Для этого устройства не настроена отправка электронных писем через почтовое приложение iOS."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "Самый надежный и безопасный способ использования биткойна."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Поддержите фонд Litecoin"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Подключение ..."; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index aec3bc6c6..fdc589c34 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "Växelkurs"; -/* Donate Memo */ -"Donate.memo" = "Donation till Litecoin Foundation"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "Tryck för att donera till Litecoin Foundation (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "Bekräfta donation"; - -/* Donate to the articles */ -"Donate.toThe" = "Donera till"; - -/* Donate */ -"Donate.word" = "Donera"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "Enheten är inte konfigurerad för att skicka e-post med post-appen i iOS."; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "Det säkraste och tryggaste sättet att använda Litecoin."; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "Stöd Litecoin Foundation"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "Ansluter..."; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index 70f23e347..96343cc7b 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "汇率"; -/* Donate Memo */ -"Donate.memo" = "捐赠给莱特币基金会"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "点击捐赠给莱特币基金会 (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "确认捐赠"; - -/* Donate to the articles */ -"Donate.toThe" = "捐赠给"; - -/* Donate */ -"Donate.word" = "捐"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "此设备未进行配置,无法用 iOS 邮件应用发送电子邮件。"; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "使用莱特币最安全且最可靠的方式。"; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "支持Litecoin基金会"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "正在连线..."; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index 39d81889b..e54c9a5dc 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -254,21 +254,6 @@ /* Exchange rate label */ "DefaultCurrency.rateLabel" = "匯率"; -/* Donate Memo */ -"Donate.memo" = "捐贈給萊特幣基金會"; - -/* Donate to the Litecoin Foundation */ -"Donate.title" = "點擊捐贈給萊特幣基金會 (%@)"; - -/* Donate Confirmation */ -"Donate.title.confirmation" = "確認捐贈"; - -/* Donate to the articles */ -"Donate.toThe" = "捐贈給"; - -/* Donate */ -"Donate.word" = "捐"; - /* Email unavailable alert title */ "ErrorMessages.emailUnavailableMessage" = "本裝置並非設定來以 iOS 郵件應用程式傳送電子郵件。"; @@ -911,6 +896,9 @@ /* Start view message */ "StartViewController.message" = "使用萊特幣最安全、最有保障的方式。"; +/* Support the Litecoin Foundation */ +"SupportTheFoundation.title" = "支持萊特幣基金會"; + /* Syncing view connection state header text */ "SyncingHeader.connecting" = "正在連線..."; diff --git a/loafwallet/src/ViewControllers/ConfirmationViewController.swift b/loafwallet/src/ViewControllers/ConfirmationViewController.swift index 625860184..88a8b7903 100644 --- a/loafwallet/src/ViewControllers/ConfirmationViewController.swift +++ b/loafwallet/src/ViewControllers/ConfirmationViewController.swift @@ -11,7 +11,7 @@ import LocalAuthentication class ConfirmationViewController : UIViewController, ContentBoxPresenter { - init(amount: Satoshis, fee: Satoshis, feeType: FeeType, state: State, selectedRate: Rate?, minimumFractionDigits: Int?, address: String, isUsingBiometrics: Bool, isDonation: Bool = false) { + init(amount: Satoshis, fee: Satoshis, feeType: FeeType, state: ReduxState, selectedRate: Rate?, minimumFractionDigits: Int?, address: String, isUsingBiometrics: Bool, isDonation: Bool = false) { self.amount = amount self.feeAmount = fee self.feeType = feeType @@ -28,7 +28,7 @@ class ConfirmationViewController : UIViewController, ContentBoxPresenter { private let amount: Satoshis private let feeAmount: Satoshis private let feeType: FeeType - private let state: State + private let state: ReduxState private let selectedRate: Rate? private let minimumFractionDigits: Int? private let addressText: String diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index e42f6696a..8aa826c0a 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -10,10 +10,11 @@ import UIKit import LocalAuthentication import BRCore import FirebaseAnalytics +import SwiftUI typealias PresentScan = ((@escaping ScanCompletion) -> Void) -private let verticalButtonPadding: CGFloat = 32.0 +private let verticalButtonPadding: CGFloat = 15.0 private let buttonSize = CGSize(width: 52.0, height: 32.0) class SendViewController : UIViewController, Subscriber, ModalPresentable, Trackable { @@ -35,7 +36,6 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self.initialRequest = initialRequest self.currency = ShadowButton(title: S.Symbols.currencyButtonTitle(maxDigits: store.state.maxDigits), type: .tertiary) self.amountView = AmountViewController(store: store, isPinPadExpandedAtLaunch: false) - self.donationCell = DonationSetupCell(store: store, isLTCSwapped: store.state.isLtcSwapped) super.init(nibName: nil, bundle: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil) @@ -53,7 +53,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track private let amountView: AmountViewController private let addressCell = AddressCell() private let descriptionCell = DescriptionSendCell(placeholder: S.Send.descriptionLabel) - private let donationCell: DonationSetupCell + private let supportLitecoinFoundationCell = UIHostingController(rootView: SupportLitecoinFoundationView(viewModel: SupportLitecoinFoundationViewModel())) private var sendButton = ShadowButton(title: S.Send.sendLabel, type: .flatLitecoinBlue) private let currency: ShadowButton private let currencyBorder = UIView(color: .secondaryShadow) @@ -82,7 +82,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track walletManager.wallet?.feePerKb = store.state.fees.regular view.addSubview(addressCell) - view.addSubview(donationCell) + view.addSubview(supportLitecoinFoundationCell.view) view.addSubview(descriptionCell) view.addSubview(sendButton) @@ -91,19 +91,20 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track amountView.view.constrain([ amountView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), amountView.view.topAnchor.constraint(equalTo: addressCell.bottomAnchor), - amountView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) - }) + amountView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) }) + + supportLitecoinFoundationCell.view.constrain([ + supportLitecoinFoundationCell.view.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), + supportLitecoinFoundationCell.view.topAnchor.constraint(equalTo: amountView.view.bottomAnchor), + supportLitecoinFoundationCell.view.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), + supportLitecoinFoundationCell.view.heightAnchor.constraint(equalToConstant: SendCell.defaultHeight)]) - donationCell.constrain([ - donationCell.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), - donationCell.topAnchor.constraint(equalTo: amountView.view.bottomAnchor), - donationCell.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), - donationCell.heightAnchor.constraint(equalToConstant: 72.0)]) descriptionCell.constrain([ descriptionCell.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), - descriptionCell.topAnchor.constraint(equalTo: donationCell.bottomAnchor), + descriptionCell.topAnchor.constraint(equalTo: supportLitecoinFoundationCell.view.bottomAnchor), descriptionCell.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), - descriptionCell.heightAnchor.constraint(equalTo: descriptionCell.textView.heightAnchor, constant: C.padding[4]) ]) + descriptionCell.heightAnchor.constraint(equalTo: descriptionCell.textView.heightAnchor, constant: C.padding[3]) ]) + descriptionCell.accessoryView.constrain([ descriptionCell.accessoryView.constraint(.width, constant: 0.0) ]) sendButton.constrain([ @@ -117,7 +118,6 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track callback: { if let balance = $0.walletState.balance { self.balance = balance - self.donationCell.donateButton.isEnabled = (balance >= (kDonationAmount * 2)) ? true : false } }) } @@ -136,8 +136,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track addressCell.paste.addTarget(self, action: #selector(SendViewController.pasteTapped), for: .touchUpInside) addressCell.scan.addTarget(self, action: #selector(SendViewController.scanTapped), for: .touchUpInside) sendButton.addTarget(self, action: #selector(sendTapped), for: .touchUpInside) - donationCell.donateButton.isEnabled = false - + descriptionCell.didReturn = { textView in textView.resignFirstResponder() } @@ -177,48 +176,21 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self?.addressCell.textField.resignFirstResponder() } } - amountView.didShowFiat = { isLTCSwapped in - guard let fiatSymbol = self.store.state.currentRate?.currencySymbol else { return } - self.donationCell.donateButton.title = String(format: S.Donate.title, isLTCSwapped ? "Ł":"\(fiatSymbol)") - } - - donationCell.didTapToDonate = { - - if let dynamicDonate = UIStoryboard.init(name: "DynamicDonation", bundle: nil).instantiateViewController(withIdentifier: "DynamicDonation") as? DynamicDonationViewController { - if #available(iOS 13.0, *) { - dynamicDonate.isModalInPresentation = true - } - - dynamicDonate.store = self.store - dynamicDonate.senderClass = self.sender - dynamicDonate.balance = self.balance - dynamicDonate.providesPresentationContextTransitionStyle = true - dynamicDonate.definesPresentationContext = true - dynamicDonate.modalPresentationStyle = .fullScreen - dynamicDonate.modalTransitionStyle = .crossDissolve - - dynamicDonate.successCallback = { - if self.sender.createTransaction(amount: dynamicDonate.finalDonationAmount.rawValue, to: dynamicDonate.finalDonationAddress) { - self.descriptionCell.textView.text = dynamicDonate.finalDonationMemo - dynamicDonate.dismiss(animated: true, completion: { - self.send() - - let properties: [String: String] = ["ADDRESS_SCHEME":"v2", - "PLATFORM":"iOS", - "DONATION_ACCOUNT": dynamicDonate.finalDonationMemo, - "DONATION_AMOUNT": String(describing: dynamicDonate.finalDonationAmount.rawValue)] - - LWAnalytics.logEventWithParameters(itemName: ._20200223_DD, properties: properties) - }) - } - } - dynamicDonate.cancelCallback = { - dynamicDonate.dismiss(animated: true, completion: { - self.sender.transaction = nil - }) - } - self.present(dynamicDonate, animated: true, completion: nil) - } + + supportLitecoinFoundationCell.rootView.viewModel.didGetLTCAddress = { ltcAddress in + + ///Paste in Support Litecoin Foundation address to textField + self.addressCell.textField.text = ltcAddress + self.addressCell.textField.becomeFirstResponder() + self.addressCell.textField.isHidden = false + + /// Paste in Memo + self.descriptionCell.clearPlaceholder() + self.descriptionCell.textView.text = "Litecoin Foundation" + + /// Track Support LF Taps + LWAnalytics.logEventWithParameters(itemName:._20201118_DTS) + } } diff --git a/loafwallet/src/ViewModels/Amount.swift b/loafwallet/src/ViewModels/Amount.swift index edf214e2e..604c0b7a1 100644 --- a/loafwallet/src/ViewModels/Amount.swift +++ b/loafwallet/src/ViewModels/Amount.swift @@ -97,7 +97,7 @@ struct Amount { struct DisplayAmount { let amount: Satoshis - let state: State + let state: ReduxState let selectedRate: Rate? let minimumFractionDigits: Int? diff --git a/loafwallet/src/Views/SendViewCells/AddressCell.swift b/loafwallet/src/Views/SendViewCells/AddressCell.swift index ddb41e5d8..4a07b0bf0 100644 --- a/loafwallet/src/Views/SendViewCells/AddressCell.swift +++ b/loafwallet/src/Views/SendViewCells/AddressCell.swift @@ -36,7 +36,7 @@ class AddressCell : UIView { let textField = UITextField() let paste = ShadowButton(title: S.Send.pasteLabel, type: .tertiary) let scan = ShadowButton(title: S.Send.scanLabel, type: .tertiary) - fileprivate var contentLabel = UILabel(font: .customBody(size: 14.0), color: .darkText) + fileprivate var contentLabel = UILabel(font: .customBody(size: 12.0), color: .darkText) private var label = UILabel(font: .customBody(size: 16.0)) fileprivate let gr = UITapGestureRecognizer() fileprivate let tapView = UIView() @@ -92,7 +92,7 @@ class AddressCell : UIView { scan.centerYAnchor.constraint(equalTo: centerYAnchor) ]) paste.constrain([ paste.centerYAnchor.constraint(equalTo: centerYAnchor), - paste.trailingAnchor.constraint(equalTo: scan.leadingAnchor, constant: -C.padding[1]) ]) + paste.trailingAnchor.constraint(equalTo: scan.leadingAnchor, constant: -C.padding[0.625]) ]) border.constrain([ border.leadingAnchor.constraint(equalTo: leadingAnchor), border.bottomAnchor.constraint(equalTo: bottomAnchor), diff --git a/loafwallet/src/Views/SendViewCells/DescriptionSendCell.swift b/loafwallet/src/Views/SendViewCells/DescriptionSendCell.swift index cbca8e494..8a5fa69c9 100644 --- a/loafwallet/src/Views/SendViewCells/DescriptionSendCell.swift +++ b/loafwallet/src/Views/SendViewCells/DescriptionSendCell.swift @@ -49,8 +49,7 @@ class DescriptionSendCell : SendCell { addSubview(textView) textView.constrain([ textView.constraint(.leading, toView: self, constant: 11.0), - textView.topAnchor.constraint(equalTo: topAnchor, constant: C.padding[2]), - textView.heightAnchor.constraint(greaterThanOrEqualToConstant: 30.0), + textView.centerYAnchor.constraint(equalTo: self.centerYAnchor), textView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -C.padding[2]) ]) textView.addSubview(placeholder) @@ -58,6 +57,11 @@ class DescriptionSendCell : SendCell { placeholder.centerYAnchor.constraint(equalTo: textView.centerYAnchor), placeholder.leadingAnchor.constraint(equalTo: textView.leadingAnchor, constant: 5.0) ]) } + + func clearPlaceholder() { + placeholder.text = "" + placeholder.isHidden = true + } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") diff --git a/loafwallet/src/Views/SendViewCells/SendCell.swift b/loafwallet/src/Views/SendViewCells/SendCell.swift index e640cfa56..9d04c8f61 100644 --- a/loafwallet/src/Views/SendViewCells/SendCell.swift +++ b/loafwallet/src/Views/SendViewCells/SendCell.swift @@ -10,8 +10,8 @@ import UIKit class SendCell : UIView { - static let defaultHeight: CGFloat = 72.0 - + static let defaultHeight: CGFloat = 60.0 + init() { super.init(frame: .zero) setupViews() diff --git a/loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift b/loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift new file mode 100644 index 000000000..a1a9b719b --- /dev/null +++ b/loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift @@ -0,0 +1,31 @@ +// +// SupportLitecoinFoundationViewModelTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 11/16/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import XCTest +@testable import loafwallet + +class SupportLitecoinFoundationViewModelTests: XCTestCase { + + var viewModel: SupportLitecoinFoundationViewModel! + + override func setUp() { + super.setUp() + viewModel = SupportLitecoinFoundationViewModel() + } + + func testDidGetLTCAddress() throws { + + } + + func testDidUpdateAddressString() throws { + + } + +} + + diff --git a/loafwalletTests/Constants Tests/ConstantsTests.swift b/loafwalletTests/Constants Tests/ConstantsTests.swift new file mode 100644 index 000000000..ea9d6e036 --- /dev/null +++ b/loafwalletTests/Constants Tests/ConstantsTests.swift @@ -0,0 +1,18 @@ +// +// ConstantsTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 11/14/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import XCTest +@testable import loafwallet + +class ConstantsTests: XCTestCase { + + func testLFDonationAddressPage() throws { + XCTAssertTrue(FoundationSupport.url.absoluteString == "https://lite-wallet.org/support_address.html" ) + } + +} diff --git a/loafwalletTests/Legacy BRTests/TouchIdEnabledTests.swift b/loafwalletTests/Legacy BRTests/TouchIdEnabledTests.swift index e34be2f46..ba3b048af 100644 --- a/loafwalletTests/Legacy BRTests/TouchIdEnabledTests.swift +++ b/loafwalletTests/Legacy BRTests/TouchIdEnabledTests.swift @@ -25,11 +25,11 @@ class TouchIdEnabledTests : XCTestCase { func testInitialState() { UserDefaults.isBiometricsEnabled = true - let state = State.initial + let state = ReduxState.initial XCTAssertTrue(state.isBiometricsEnabled, "Initial state should be same as stored value") UserDefaults.isBiometricsEnabled = false - let state2 = State.initial + let state2 = ReduxState.initial XCTAssertFalse(state2.isBiometricsEnabled, "Initial state should be same as stored value") } From bb23a590858df8c2242780c4c7016a2d8a03159b Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 22 Nov 2020 17:15:12 +0000 Subject: [PATCH 017/114] [Release] Merge v2.8.2 into Develop (#158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry --- loafwallet.xcodeproj/project.pbxproj | 29 ++++++++++-------------- loafwallet/src/Constants/Constants.swift | 4 ++-- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 381699eb8..91a0f3c61 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -3524,8 +3524,6 @@ 752FB04F1DF8BF5C009086FB /* PBXTargetDependency */, ); name = loafwallet; - packageProductDependencies = ( - ); productName = breadwallet; productReference = 75A2A7901DA5934300A983D8 /* Litewallet.app */; productType = "com.apple.product-type.application"; @@ -3655,8 +3653,6 @@ Base, ); mainGroup = 75A2A7871DA5934300A983D8; - packageReferences = ( - ); productRefGroup = 75A2A7911DA5934300A983D8 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -3854,7 +3850,6 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -4513,7 +4508,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4527,7 +4522,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.1; + MARKETING_VERSION = 2.8.2; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4620,7 +4615,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4630,7 +4625,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.1; + MARKETING_VERSION = 2.8.2; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4930,7 +4925,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -4943,7 +4938,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.1; + MARKETING_VERSION = 2.8.2; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4960,7 +4955,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -4969,7 +4964,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.1; + MARKETING_VERSION = 2.8.2; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5060,7 +5055,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5074,7 +5069,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.1; + MARKETING_VERSION = 2.8.2; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5092,7 +5087,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5102,7 +5097,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.1; + MARKETING_VERSION = 2.8.2; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index e51fb60dc..97b7394bc 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -9,7 +9,7 @@ import UIKit let π: CGFloat = .pi - + enum CustomEvent: String { case _20191105_AL = "APP_LAUNCHED" case _20191105_VSC = "VISIT_SEND_CONTROLLER" @@ -39,7 +39,7 @@ enum CustomEvent: String { struct FoundationSupport { static let url = URL(string: "https://lite-wallet.org/support_address.html")! - + /// Litecoin Foundation main donation address: MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe /// As of Nov 14th, 2020 static let supportLTCAddress = "MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe" From 5a5b5bd0f1434e4cfec729905ae9243d22dec41d Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 30 Nov 2020 20:18:54 +0000 Subject: [PATCH 018/114] [Bugfix] Replace the LF Support View (#159) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Moved the LF Cell from Send. - BartyCrouch linted the stigns files. * Updated the LF Support location - Reset the localiaztion language to ‘Customer support’ - Add the dismissal actions --- TodayExtension/ar.lproj/MainInterface.strings | 1 - TodayExtension/da.lproj/MainInterface.strings | 1 - TodayExtension/de.lproj/MainInterface.strings | 1 - TodayExtension/el.lproj/MainInterface.strings | 1 - TodayExtension/en.lproj/MainInterface.strings | 1 - TodayExtension/es.lproj/MainInterface.strings | 1 - TodayExtension/fr.lproj/MainInterface.strings | 1 - TodayExtension/hu.lproj/MainInterface.strings | 1 - TodayExtension/id.lproj/MainInterface.strings | 1 - TodayExtension/it.lproj/MainInterface.strings | 1 - TodayExtension/ja.lproj/MainInterface.strings | 1 - TodayExtension/ko.lproj/MainInterface.strings | 1 - TodayExtension/nb.lproj/MainInterface.strings | 1 - TodayExtension/nl.lproj/MainInterface.strings | 1 - TodayExtension/pl.lproj/MainInterface.strings | 1 - .../pt-BR.lproj/MainInterface.strings | 1 - TodayExtension/pt.lproj/MainInterface.strings | 1 - TodayExtension/ru.lproj/MainInterface.strings | 1 - TodayExtension/sv.lproj/MainInterface.strings | 1 - TodayExtension/tr.lproj/MainInterface.strings | 1 - .../zh-Hans.lproj/MainInterface.strings | 1 - .../zh-Hant.lproj/MainInterface.strings | 1 - .../SupportLitecoinFoundationView.swift | 91 +++++++++---------- .../SupportLitecoinFoundationViewModel.swift | 12 +-- loafwallet/SupportSafariView.swift | 17 ---- loafwallet/ar.lproj/LaunchScreen.strings | 1 - loafwallet/id.lproj/LaunchScreen.strings | 1 - loafwallet/src/Constants/Strings.swift | 2 +- loafwallet/src/Controls/MenuButtonType.swift | 5 + loafwallet/src/ModalPresenter.swift | 29 +++++- .../Strings/Base.lproj/Localizable.strings | 3 + .../src/Strings/ar.lproj/Localizable.strings | 4 +- .../src/Strings/da.lproj/Localizable.strings | 4 +- .../src/Strings/de.lproj/Localizable.strings | 4 +- .../src/Strings/en.lproj/Localizable.strings | 4 +- .../src/Strings/es.lproj/Localizable.strings | 4 +- .../src/Strings/fr.lproj/Localizable.strings | 4 +- .../src/Strings/id.lproj/Localizable.strings | 4 +- .../src/Strings/it.lproj/Localizable.strings | 4 +- .../src/Strings/ja.lproj/Localizable.strings | 4 +- .../src/Strings/ko.lproj/Localizable.strings | 4 +- .../src/Strings/nl.lproj/Localizable.strings | 4 +- .../src/Strings/pt.lproj/Localizable.strings | 4 +- .../src/Strings/ru.lproj/Localizable.strings | 4 +- .../src/Strings/sv.lproj/Localizable.strings | 4 +- .../Strings/zh-Hans.lproj/Localizable.strings | 4 +- .../Strings/zh-Hant.lproj/Localizable.strings | 4 +- .../RootModals/MenuViewController.swift | 5 +- .../RootModals/SendViewController.swift | 27 +----- 49 files changed, 139 insertions(+), 140 deletions(-) diff --git a/TodayExtension/ar.lproj/MainInterface.strings b/TodayExtension/ar.lproj/MainInterface.strings index bec70f614..7456566de 100644 --- a/TodayExtension/ar.lproj/MainInterface.strings +++ b/TodayExtension/ar.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "setup wallet"; diff --git a/TodayExtension/da.lproj/MainInterface.strings b/TodayExtension/da.lproj/MainInterface.strings index eb14e5ae5..0cd85f910 100644 --- a/TodayExtension/da.lproj/MainInterface.strings +++ b/TodayExtension/da.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "opsætning tegnebog"; diff --git a/TodayExtension/de.lproj/MainInterface.strings b/TodayExtension/de.lproj/MainInterface.strings index dd146510a..15b6232c8 100644 --- a/TodayExtension/de.lproj/MainInterface.strings +++ b/TodayExtension/de.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "Brieftasche einrichten"; diff --git a/TodayExtension/el.lproj/MainInterface.strings b/TodayExtension/el.lproj/MainInterface.strings index b6a7bf51f..c6e21cfa3 100644 --- a/TodayExtension/el.lproj/MainInterface.strings +++ b/TodayExtension/el.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "Ρύθμιση πορτοφολιού"; diff --git a/TodayExtension/en.lproj/MainInterface.strings b/TodayExtension/en.lproj/MainInterface.strings index bec70f614..7456566de 100644 --- a/TodayExtension/en.lproj/MainInterface.strings +++ b/TodayExtension/en.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "setup wallet"; diff --git a/TodayExtension/es.lproj/MainInterface.strings b/TodayExtension/es.lproj/MainInterface.strings index 470d4a611..4cc3f2414 100644 --- a/TodayExtension/es.lproj/MainInterface.strings +++ b/TodayExtension/es.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "billetera de configuración"; diff --git a/TodayExtension/fr.lproj/MainInterface.strings b/TodayExtension/fr.lproj/MainInterface.strings index f7c04bfa7..e558abff9 100644 --- a/TodayExtension/fr.lproj/MainInterface.strings +++ b/TodayExtension/fr.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "le portefeuille de configuration"; diff --git a/TodayExtension/hu.lproj/MainInterface.strings b/TodayExtension/hu.lproj/MainInterface.strings index cdadf10fe..5adb89fee 100644 --- a/TodayExtension/hu.lproj/MainInterface.strings +++ b/TodayExtension/hu.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "**setup wallet**"; diff --git a/TodayExtension/id.lproj/MainInterface.strings b/TodayExtension/id.lproj/MainInterface.strings index 5bd8c3570..a4afe953d 100644 --- a/TodayExtension/id.lproj/MainInterface.strings +++ b/TodayExtension/id.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "setup wallet"; diff --git a/TodayExtension/it.lproj/MainInterface.strings b/TodayExtension/it.lproj/MainInterface.strings index b315ff7d3..4b0b58a90 100644 --- a/TodayExtension/it.lproj/MainInterface.strings +++ b/TodayExtension/it.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "portafoglio di installazione"; diff --git a/TodayExtension/ja.lproj/MainInterface.strings b/TodayExtension/ja.lproj/MainInterface.strings index 04f931daf..c4129f8c8 100644 --- a/TodayExtension/ja.lproj/MainInterface.strings +++ b/TodayExtension/ja.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "セットアップウォレット"; diff --git a/TodayExtension/ko.lproj/MainInterface.strings b/TodayExtension/ko.lproj/MainInterface.strings index d39379b1f..8a304f86a 100644 --- a/TodayExtension/ko.lproj/MainInterface.strings +++ b/TodayExtension/ko.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "설정 지갑"; diff --git a/TodayExtension/nb.lproj/MainInterface.strings b/TodayExtension/nb.lproj/MainInterface.strings index b6a7bf51f..c6e21cfa3 100644 --- a/TodayExtension/nb.lproj/MainInterface.strings +++ b/TodayExtension/nb.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "Ρύθμιση πορτοφολιού"; diff --git a/TodayExtension/nl.lproj/MainInterface.strings b/TodayExtension/nl.lproj/MainInterface.strings index fb17e72b8..7bd387a3a 100644 --- a/TodayExtension/nl.lproj/MainInterface.strings +++ b/TodayExtension/nl.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "portemonnee instellen"; diff --git a/TodayExtension/pl.lproj/MainInterface.strings b/TodayExtension/pl.lproj/MainInterface.strings index cdadf10fe..5adb89fee 100644 --- a/TodayExtension/pl.lproj/MainInterface.strings +++ b/TodayExtension/pl.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "**setup wallet**"; diff --git a/TodayExtension/pt-BR.lproj/MainInterface.strings b/TodayExtension/pt-BR.lproj/MainInterface.strings index cdadf10fe..5adb89fee 100644 --- a/TodayExtension/pt-BR.lproj/MainInterface.strings +++ b/TodayExtension/pt-BR.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "**setup wallet**"; diff --git a/TodayExtension/pt.lproj/MainInterface.strings b/TodayExtension/pt.lproj/MainInterface.strings index bec70f614..7456566de 100644 --- a/TodayExtension/pt.lproj/MainInterface.strings +++ b/TodayExtension/pt.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "setup wallet"; diff --git a/TodayExtension/ru.lproj/MainInterface.strings b/TodayExtension/ru.lproj/MainInterface.strings index 8906d9f2b..309e21a02 100644 --- a/TodayExtension/ru.lproj/MainInterface.strings +++ b/TodayExtension/ru.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "настроить кошелек"; diff --git a/TodayExtension/sv.lproj/MainInterface.strings b/TodayExtension/sv.lproj/MainInterface.strings index 2ff2a83ba..039cdde3d 100644 --- a/TodayExtension/sv.lproj/MainInterface.strings +++ b/TodayExtension/sv.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "installationsplånbok"; diff --git a/TodayExtension/tr.lproj/MainInterface.strings b/TodayExtension/tr.lproj/MainInterface.strings index cdadf10fe..5adb89fee 100644 --- a/TodayExtension/tr.lproj/MainInterface.strings +++ b/TodayExtension/tr.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "**setup wallet**"; diff --git a/TodayExtension/zh-Hans.lproj/MainInterface.strings b/TodayExtension/zh-Hans.lproj/MainInterface.strings index 3447e8822..d0bfa9d9f 100644 --- a/TodayExtension/zh-Hans.lproj/MainInterface.strings +++ b/TodayExtension/zh-Hans.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "设置钱包"; diff --git a/TodayExtension/zh-Hant.lproj/MainInterface.strings b/TodayExtension/zh-Hant.lproj/MainInterface.strings index bec70f614..7456566de 100644 --- a/TodayExtension/zh-Hant.lproj/MainInterface.strings +++ b/TodayExtension/zh-Hant.lproj/MainInterface.strings @@ -1,4 +1,3 @@ - /* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ "fgE-Q8-uG8.normalTitle" = "setup wallet"; diff --git a/loafwallet/SupportLitecoinFoundationView.swift b/loafwallet/SupportLitecoinFoundationView.swift index f9694228b..da37a79bb 100644 --- a/loafwallet/SupportLitecoinFoundationView.swift +++ b/loafwallet/SupportLitecoinFoundationView.swift @@ -8,11 +8,11 @@ import SwiftUI import Foundation -import WebKit +import WebKit /// This cell is under the amount view and above the Memo view in the Send VC struct SupportLitecoinFoundationView: View { - + //MARK: - Combine Variables @ObservedObject var viewModel: SupportLitecoinFoundationViewModel @@ -22,70 +22,65 @@ struct SupportLitecoinFoundationView: View { @State private var showSupportLFPage: Bool = false - + //MARK: - Public var supportSafariView = SupportSafariView(url: FoundationSupport.url, - viewModel: SupportSafariViewModel()) + viewModel: SupportSafariViewModel()) init(viewModel: SupportLitecoinFoundationViewModel) { self.viewModel = viewModel } var body: some View { + VStack { Spacer() + supportSafariView + .frame(height: 500, + alignment: .center + ) + .padding(.bottom, 50) + + // Copy the LF Address and paste into the SendViewController Button(action: { - self.showSupportLFPage = true - }) { + UIPasteboard.general.string = FoundationSupport.supportLTCAddress + self.viewModel.didCopyLTCAddress?() - Text(S.SupportLitecoinFoundation.title) - .padding(.all,10) + }) { + Text(S.URLHandling.copy) + .padding([.leading,.trailing],20) + .padding([.top,.bottom],10) .font(Font(UIFont.customMedium(size: 16.0))) - .foregroundColor(Color(UIColor.grayTextTint)) - .background(Color(UIColor.secondaryButton)) + .foregroundColor(Color(UIColor.white)) + .background(Color(UIColor.liteWalletBlue)) .overlay( RoundedRectangle(cornerRadius: 4) - .stroke(Color(UIColor.secondaryBorder)) + .stroke(Color(UIColor.liteWalletBlue)) ) } - .sheet(isPresented: self.$showSupportLFPage, - onDismiss: { - viewModel.updateAddressString(address: supportSafariView - .viewModel - .supportLTCAddress) - } - ) { - VStack { - Spacer() - supportSafariView - .frame(height: 500, - alignment: .center - ) - .padding(.bottom, 50) - Button(action: { - self.showSupportLFPage = false - }) { - Text(S.URLHandling.copy) - .padding([.leading,.trailing],20) - .padding([.top,.bottom],10) - .font(Font(UIFont.customMedium(size: 16.0))) - .foregroundColor(Color(UIColor.grayTextTint)) - .background(Color(UIColor.secondaryButton)) - .overlay( - RoundedRectangle(cornerRadius: 4) - .stroke(Color(UIColor.secondaryBorder)) - ) - } - .padding(.bottom, 50) - .padding([.leading,.trailing], 50) - } + .padding(.bottom, 30) + .padding([.leading,.trailing], 20) + + // Cancel + Button(action: { + self.viewModel.didCancel?() + }) { + Text(S.Button.cancel) + .padding([.leading,.trailing],20) + .padding([.top,.bottom],10) + .font(Font(UIFont.customMedium(size: 16.0))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + .background(Color(UIColor.white)) + .overlay( + RoundedRectangle(cornerRadius: 4) + .stroke(Color(UIColor.secondaryBorder)) + ) } - Spacer() - Rectangle() - .fill(Color(UIColor.secondaryBorder)) - .frame(height: 1.0) - + .padding(.bottom, 50) + .padding([.leading,.trailing], 20) } + Spacer() } } - + + diff --git a/loafwallet/SupportLitecoinFoundationViewModel.swift b/loafwallet/SupportLitecoinFoundationViewModel.swift index 9c5db45f6..1ce550ecf 100644 --- a/loafwallet/SupportLitecoinFoundationViewModel.swift +++ b/loafwallet/SupportLitecoinFoundationViewModel.swift @@ -14,15 +14,13 @@ import Combine class SupportLitecoinFoundationViewModel: ObservableObject { //MARK: - Combine Variables - @Published - var supportLTCAddress: String = "" //MARK: - Public Variables - var didGetLTCAddress: ((String) -> Void)? - init() {} - func updateAddressString(address: String) { - didGetLTCAddress?(address) - } + var didCancel: (()->())? + + var didCopyLTCAddress: (()->())? + + init() {} } diff --git a/loafwallet/SupportSafariView.swift b/loafwallet/SupportSafariView.swift index 4074ed8b3..d2304572e 100644 --- a/loafwallet/SupportSafariView.swift +++ b/loafwallet/SupportSafariView.swift @@ -40,23 +40,6 @@ struct SupportSafariView: UIViewRepresentable { /// - navigation: nil func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { - - // MARK: - Parse LF LTC Address - webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", - completionHandler: { ( htmlString: Any, error: Error?) in - if let string = htmlString as? String, - let suffix = string.components(separatedBy:"") - let element = content.filter{ $0.contains(" Void)? var didTapSupport: (() -> Void)? + var didTapSupportLF: (() -> Void)? var didTapSettings: (() -> Void)? var didTapLock: (() -> Void)? //MARK: - Private fileprivate let buttonHeight: CGFloat = 72.0 fileprivate let buttons: [MenuButton] = { - let types: [MenuButtonType] = [.security, .support, .settings, .lock] + let types: [MenuButtonType] = [.security, .support, .supportLF, .settings, .lock] return types.compactMap { return MenuButton(type: $0) } @@ -63,6 +64,8 @@ class MenuViewController : UIViewController, Trackable { didTapSecurity?() case .support: didTapSupport?() + case .supportLF: + didTapSupportLF?() case .settings: didTapSettings?() case .lock: diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index 8aa826c0a..ff026382d 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -53,7 +53,6 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track private let amountView: AmountViewController private let addressCell = AddressCell() private let descriptionCell = DescriptionSendCell(placeholder: S.Send.descriptionLabel) - private let supportLitecoinFoundationCell = UIHostingController(rootView: SupportLitecoinFoundationView(viewModel: SupportLitecoinFoundationViewModel())) private var sendButton = ShadowButton(title: S.Send.sendLabel, type: .flatLitecoinBlue) private let currency: ShadowButton private let currencyBorder = UIView(color: .secondaryShadow) @@ -82,7 +81,6 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track walletManager.wallet?.feePerKb = store.state.fees.regular view.addSubview(addressCell) - view.addSubview(supportLitecoinFoundationCell.view) view.addSubview(descriptionCell) view.addSubview(sendButton) @@ -92,16 +90,10 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track amountView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), amountView.view.topAnchor.constraint(equalTo: addressCell.bottomAnchor), amountView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) }) - - supportLitecoinFoundationCell.view.constrain([ - supportLitecoinFoundationCell.view.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), - supportLitecoinFoundationCell.view.topAnchor.constraint(equalTo: amountView.view.bottomAnchor), - supportLitecoinFoundationCell.view.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), - supportLitecoinFoundationCell.view.heightAnchor.constraint(equalToConstant: SendCell.defaultHeight)]) - + descriptionCell.constrain([ descriptionCell.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), - descriptionCell.topAnchor.constraint(equalTo: supportLitecoinFoundationCell.view.bottomAnchor), + descriptionCell.topAnchor.constraint(equalTo: amountView.view.bottomAnchor), descriptionCell.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), descriptionCell.heightAnchor.constraint(equalTo: descriptionCell.textView.heightAnchor, constant: C.padding[3]) ]) @@ -177,21 +169,6 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track } } - supportLitecoinFoundationCell.rootView.viewModel.didGetLTCAddress = { ltcAddress in - - ///Paste in Support Litecoin Foundation address to textField - self.addressCell.textField.text = ltcAddress - self.addressCell.textField.becomeFirstResponder() - self.addressCell.textField.isHidden = false - - /// Paste in Memo - self.descriptionCell.clearPlaceholder() - self.descriptionCell.textView.text = "Litecoin Foundation" - - /// Track Support LF Taps - LWAnalytics.logEventWithParameters(itemName:._20201118_DTS) - - } } private func balanceTextForAmount(amount: Satoshis?, rate: Rate?) -> (NSAttributedString?, NSAttributedString?) { From bfb81a5bce8142904fcad238ad5831294349bc13 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 30 Nov 2020 20:19:19 +0000 Subject: [PATCH 019/114] [Bugfix] Fix buy tab: Simplex urls (#157) * Updated the url to new servers * Linted the Localized strings * Setup url constants * updated pk file status * Updated per PR review comments * fixed naming of the url variable --- .gitignore | 1 + loafwallet/BRAPIClient+Wallet.swift | 5 ++--- loafwallet/BuyWKWebViewController.swift | 4 ++-- loafwallet/src/Constants/Constants.swift | 9 +++++++++ loafwallet/src/ViewControllers/AboutViewController.swift | 4 ++-- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 0052f7bd7..e9d084823 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ fastlane/test_output Screenshots/shots .DS_Store loafwallet/GoogleService-Info.plist +partner-keys.plist diff --git a/loafwallet/BRAPIClient+Wallet.swift b/loafwallet/BRAPIClient+Wallet.swift index a57d09685..27d40895e 100644 --- a/loafwallet/BRAPIClient+Wallet.swift +++ b/loafwallet/BRAPIClient+Wallet.swift @@ -7,8 +7,7 @@ import Foundation -private let ratesURL = "https://api.loshan.co.uk/api/v1/rates" -private let fallbackRatesURL = "https://api.loafwallet.org/api/v1/rates" +private let fallbackRatesURL = "https://api.loshan.co.uk/api/v1/rates" extension BRAPIClient { func feePerKb(_ handler: @escaping (_ fees: Fees, _ error: String?) -> Void) { @@ -22,7 +21,7 @@ extension BRAPIClient { } func exchangeRates(isFallback: Bool = false, _ handler: @escaping (_ rates: [Rate], _ error: String?) -> Void) { - let request = isFallback ? URLRequest(url: URL(string: fallbackRatesURL)!) : URLRequest(url: URL(string: ratesURL)!) + let request = isFallback ? URLRequest(url: URL(string: fallbackRatesURL)!) : URLRequest(url: URL(string: APIServer.baseUrl + "v1/rates")!) let task = dataTaskWithRequest(request) { (data, response, error) in if error == nil, let data = data, let parsedData = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) { diff --git a/loafwallet/BuyWKWebViewController.swift b/loafwallet/BuyWKWebViewController.swift index c59f7d173..75b7ee3a2 100644 --- a/loafwallet/BuyWKWebViewController.swift +++ b/loafwallet/BuyWKWebViewController.swift @@ -70,8 +70,8 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe self.wkWebContainerView.addSubview(wkWebView) let timestamp = Int(appInstallDate.timeIntervalSince1970) - let urlString = "https://buy.loafwallet.org/?address=\(currentWalletAddress)&code=\(currencyCode)&idate=\(timestamp)&uid=\(uuidString)" - //https://buy.loafwallet.org/?address=LZhz8NvsWHFdAK1H85dEDQiVhFGUJo9rsk&code=USD&idate=1578376166&uid=5DE36BF9-73A8-4B84-8229-2C60FABC5E25 + let urlString = APIServer.baseUrl + "?address=\(currentWalletAddress)&code=\(currencyCode)&idate=\(timestamp)&uid=\(uuidString)" + guard let url = URL(string: urlString) else { NSLog("ERROR: URL not initialized") return diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index 97b7394bc..3749ff661 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -45,6 +45,15 @@ struct FoundationSupport { static let supportLTCAddress = "MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe" } +struct APIServer { + + #if DEBUG + static let baseUrl = "https://api-stage.lite-wallet.org/" + #else + static let baseUrl = "https://api-prod.lite-wallet.org/" + #endif +} + struct Padding { subscript(multiplier: Int) -> CGFloat { get { diff --git a/loafwallet/src/ViewControllers/AboutViewController.swift b/loafwallet/src/ViewControllers/AboutViewController.swift index 2bec2b307..7b456b949 100644 --- a/loafwallet/src/ViewControllers/AboutViewController.swift +++ b/loafwallet/src/ViewControllers/AboutViewController.swift @@ -92,7 +92,7 @@ class AboutViewController : UIViewController { private func setActions() { blog.button.tap = strongify(self) { myself in - myself.presentURL(string: "https://loafwallet.org") + myself.presentURL(string: "https://lite-wallet.org") } twitter.button.tap = strongify(self) { myself in myself.presentURL(string: "https://twitter.com/Litewallet_App") @@ -101,7 +101,7 @@ class AboutViewController : UIViewController { myself.presentURL(string: "https://www.reddit.com/r/Litewallet/") } privacy.tap = strongify(self) { myself in - myself.presentURL(string: "http://loafwallet.org/policy.html") + myself.presentURL(string: "http://lite-wallet.org/policy.html") } } From 2f609dcc910e021308d7b9a40ead5b87a24bf7f1 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 5 Dec 2020 23:05:04 +0000 Subject: [PATCH 020/114] [Merge v2.8.3] into Develop (#169) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Master (#153) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * version bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov --- loafwallet.xcodeproj/project.pbxproj | 12 +++++------ .../SupportLitecoinFoundationView.swift | 3 --- loafwallet/SupportSafariView.swift | 20 +++++++++++++++++-- loafwallet/src/Constants/Constants.swift | 1 + .../RootModals/SendViewController.swift | 3 +-- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 91a0f3c61..b1d381fec 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -4522,7 +4522,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.2; + MARKETING_VERSION = 2.8.3; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4625,7 +4625,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.2; + MARKETING_VERSION = 2.8.3; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4938,7 +4938,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.2; + MARKETING_VERSION = 2.8.3; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4964,7 +4964,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.2; + MARKETING_VERSION = 2.8.3; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5069,7 +5069,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.2; + MARKETING_VERSION = 2.8.3; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5097,7 +5097,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.2; + MARKETING_VERSION = 2.8.3; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/loafwallet/SupportLitecoinFoundationView.swift b/loafwallet/SupportLitecoinFoundationView.swift index da37a79bb..a07e269a7 100644 --- a/loafwallet/SupportLitecoinFoundationView.swift +++ b/loafwallet/SupportLitecoinFoundationView.swift @@ -12,7 +12,6 @@ import WebKit /// This cell is under the amount view and above the Memo view in the Send VC struct SupportLitecoinFoundationView: View { - //MARK: - Combine Variables @ObservedObject var viewModel: SupportLitecoinFoundationViewModel @@ -82,5 +81,3 @@ struct SupportLitecoinFoundationView: View { Spacer() } } - - diff --git a/loafwallet/SupportSafariView.swift b/loafwallet/SupportSafariView.swift index d2304572e..b1cb36563 100644 --- a/loafwallet/SupportSafariView.swift +++ b/loafwallet/SupportSafariView.swift @@ -39,8 +39,24 @@ struct SupportSafariView: UIViewRepresentable { /// - webView: Embedded webView /// - navigation: nil func webView(_ webView: WKWebView, - didFinish navigation: WKNavigation!) { - } + didFinish navigation: WKNavigation!) { + // MARK: - Parse LF LTC Address + webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", + completionHandler: { ( htmlString: Any, error: Error?) in + if let string = htmlString as? String, + let suffix = string.components(separatedBy:"") + let element = content.filter{ $0.contains(" WKWebView { diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index 3749ff661..8db925f08 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -45,6 +45,7 @@ struct FoundationSupport { static let supportLTCAddress = "MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe" } + struct APIServer { #if DEBUG diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index ff026382d..8a4daca80 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -90,7 +90,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track amountView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), amountView.view.topAnchor.constraint(equalTo: addressCell.bottomAnchor), amountView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) }) - + descriptionCell.constrain([ descriptionCell.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), descriptionCell.topAnchor.constraint(equalTo: amountView.view.bottomAnchor), @@ -168,7 +168,6 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self?.addressCell.textField.resignFirstResponder() } } - } private func balanceTextForAmount(amount: Satoshis?, rate: Rate?) -> (NSAttributedString?, NSAttributedString?) { From 1b1ee32e3cceb2d261237fe51edce1c5f55e5425 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 7 Dec 2020 13:54:52 +0000 Subject: [PATCH 021/114] [Feature Issue 154] Adding Unstoppable Domains functionality (#155) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added UD to Podfile - Stubbed out the view, viewModel and the test class for UD * [UI Polish] Added images and localized strings - Added more of strings and UD structure - Trimmed images to resize for button - Added localized strings for placeholder * Updated UnstoppableDomainsView and Model details - Added DEV notes script - Adjusted Previews by unchecking the `build install only` * Added more tests - UnstoppableDomains View Model tests - SupportLitecoinFoundationViewModel tests * reformatted code in new SwiftUI views and viewModels * Added UD action to the SendViewController * Updated project * Updated localized UD Placeholder * Setup API keys * removed pk file * Changed the localizations related to UD - Added ‘Or’ label - Added UD placeholder text - Changed the LTC address placeholder text * Added in the Or and relayout of the button - Added Partner layout view for UD and Simplex * Resolved code review comments - Update the localizations - Refactored the UD shared instance (singleton) to retain throguh the call - Added timing probes * revert to current version * reformatted the Support LF view strings * Remove Test Playground. * Removed unused SocialView and ViewModel * Improved resolution - Added a Dispatch and ‘exit’ when address is found sooner than 12 secs. Much better experience for the user. * Added infura * Resolved review comments * Rewrote copy for “Enter a Litecoin address” --- .gitignore | 1 + Podfile | 5 +- Resources/Logo-Full-Mono@3x.png | Bin 0 -> 22766 bytes loafwallet.xcodeproj/project.pbxproj | 128 ++++-- .../Assets.xcassets/Partners/Contents.json | 6 +- .../ud-color-logo.imageset/Contents.json | 23 ++ .../ud-Logo-Full-Light@1x.png | Bin 0 -> 7014 bytes .../ud-Logo-Full-Light@2x.png | Bin 0 -> 13516 bytes .../ud-Logo-Full-Light@3x.png | Bin 0 -> 20366 bytes .../ud-monotone-logo.imageset/Contents.json | 23 ++ .../Logo-Full-Mono.png | Bin 0 -> 6991 bytes .../Logo-Full-Mono@2x.png | Bin 0 -> 14762 bytes .../Logo-Full-Mono@3x.png | Bin 0 -> 22766 bytes loafwallet/LWActivityIndicator.swift | 27 ++ loafwallet/PartnersView.swift | 47 +++ loafwallet/PartnersViewModel.swift | 16 + loafwallet/ResolutionModel.swift | 38 ++ .../SupportLitecoinFoundationView.swift | 69 ++-- .../SupportLitecoinFoundationViewModel.swift | 6 +- loafwallet/SupportSafariView.swift | 19 +- loafwallet/SupportSafariViewModel.swift | 5 +- loafwallet/UnstoppableDomainView.swift | 117 ++++++ loafwallet/UnstoppableDomainViewModel.swift | 107 +++++ loafwallet/src/Constants/Constants.swift | 5 +- loafwallet/src/Constants/Strings.swift | 11 + .../Extensions/UserDefaults+Additions.swift | 5 - loafwallet/src/ModalPresenter.swift | 371 +++++++++--------- .../Strings/Base.lproj/Localizable.strings | 12 + .../src/Strings/ar.lproj/Localizable.strings | 12 + .../src/Strings/da.lproj/Localizable.strings | 12 + .../src/Strings/de.lproj/Localizable.strings | 12 + .../src/Strings/en.lproj/Localizable.strings | 12 + .../src/Strings/es.lproj/Localizable.strings | 12 + .../src/Strings/fr.lproj/Localizable.strings | 12 + .../src/Strings/id.lproj/Localizable.strings | 12 + .../src/Strings/it.lproj/Localizable.strings | 12 + .../src/Strings/ja.lproj/Localizable.strings | 12 + .../src/Strings/ko.lproj/Localizable.strings | 12 + .../src/Strings/nl.lproj/Localizable.strings | 12 + .../src/Strings/pt.lproj/Localizable.strings | 12 + .../src/Strings/ru.lproj/Localizable.strings | 12 + .../src/Strings/sv.lproj/Localizable.strings | 12 + .../Strings/zh-Hans.lproj/Localizable.strings | 12 + .../Strings/zh-Hant.lproj/Localizable.strings | 12 + .../RootModals/SendViewController.swift | 246 ++++++------ .../src/Views/SendViewCells/AddressCell.swift | 2 +- ...portLitecoinFoundationViewModelTests.swift | 18 +- .../UnstoppableDomainViewModelTests.swift | 34 ++ .../Constants Tests/ConstantsTests.swift | 1 - 49 files changed, 1131 insertions(+), 403 deletions(-) create mode 100644 Resources/Logo-Full-Mono@3x.png create mode 100644 loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/Contents.json create mode 100644 loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/ud-Logo-Full-Light@1x.png create mode 100644 loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/ud-Logo-Full-Light@2x.png create mode 100644 loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/ud-Logo-Full-Light@3x.png create mode 100644 loafwallet/Assets.xcassets/Partners/ud-monotone-logo.imageset/Contents.json create mode 100644 loafwallet/Assets.xcassets/Partners/ud-monotone-logo.imageset/Logo-Full-Mono.png create mode 100644 loafwallet/Assets.xcassets/Partners/ud-monotone-logo.imageset/Logo-Full-Mono@2x.png create mode 100644 loafwallet/Assets.xcassets/Partners/ud-monotone-logo.imageset/Logo-Full-Mono@3x.png create mode 100644 loafwallet/LWActivityIndicator.swift create mode 100644 loafwallet/PartnersView.swift create mode 100644 loafwallet/PartnersViewModel.swift create mode 100644 loafwallet/ResolutionModel.swift create mode 100644 loafwallet/UnstoppableDomainView.swift create mode 100644 loafwallet/UnstoppableDomainViewModel.swift create mode 100644 loafwalletTests/Class Tests/UnstoppableDomainViewModelTests.swift diff --git a/.gitignore b/.gitignore index e9d084823..47e80f59a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ DerivedData/ ## Playgrounds timeline.xctimeline playground.xcworkspace +TestPlaygroung.playground # Swift Package Manager # diff --git a/Podfile b/Podfile index 074bfad4a..9a8bd52c4 100644 --- a/Podfile +++ b/Podfile @@ -7,10 +7,11 @@ platform :ios, '13.0' #Shared Cocopods def shared_pods + pod 'Firebase/Crashlytics' pod 'Firebase/Analytics' - - # add after v2.6.0 pod 'SwiftLint' + pod 'UnstoppableDomainsResolution', '~> 0.1.6' + # add after v2.9.0 pod 'SwiftLint' end target 'loafwallet' do diff --git a/Resources/Logo-Full-Mono@3x.png b/Resources/Logo-Full-Mono@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b10be09f20fbedf9e4ffb68ddc81975f162fa4 GIT binary patch literal 22766 zcmZ^L2Ut_f*7gpeNJn}V5RqP_6I$pXQk7nn-fQS30TmSKO+g^iL7H@sdJyTog9uUt zLhl{^c<#O5ImdhdJkQRaJ+t1KHEZ6P%$`}3S6Uj%gm|=g000oGswn6H02mzvN^fDK zzY!r0QRo|{t*p8%0DOwUzkG^?er~lkP_30097q7WgHB4gt?V zbpIE20I~mD1_Pb=06>2O#OTWdB=BdL932h~w+ArM_g~m#^!4kbg1&w||9RK4_qBF% ze(L4w!6e8l4gdoD0{oB%4aVQ!CeJ*1W#XZog1~q%Q;=bhh?- z%H-?pRL?lt{&D*!n{Jf{CB1Cn3$L(J*;dX zItohvhNGXP?%H{Ixk32&e0+R(eFS-3J#6_Nh>MH!@eA+?2=JgKcs%`Fyq@~0$5YW$)_3^ef+|&s< zv$cztC*K3!2Ymkvhpz4a0bM-*Z4Iu<5>v_Eb9*xH@%Z_$!`|5I8LT|bDrtChWtpTbiw zYw7<%DoMWIWd5@5pJ;gx>tCdN;_B)o{ZEem3;Fl-zd?Ul0`jN4fr34{4Ls3}C@m@? zCdv0dQ~oE?@Gs;8QK7#h|CaJQQr^|c)#I_-Q%h^<2mglrE$VO5zl;u%cXf92u=e~@ zJ7Gz_|BCxv-ayCN)71&~i;~i!0{;g5J@R*eriVS6fKUGfp!NB)fWOE6F8^2lx-Rx! z(*G&qx9HzdhJU61rPkjg{|%7j`_+&B*0286Y5$Bx_gZN@besNX1dzs4gm8HQ02EMF zkbU9{+DgZnVo*H#iu-)X(e4=&i5#JN>XQT95$)SqUbob>piq)*6*3ZX5{jHK*`m9l zhXcwxr2c%&hh`Xl*TWg+H($pa%bS8{)-o*67GbXtv!{_u_t>q~^zd1F~%W>sDlKq14BS zAq}8Tl`ST}{FU%;v4$524*M?N1zi%@`O<7dm8TK?nX&2n2QvT6<_$u_Y5_;=N-V;J5PMAgIBP6*AbT-iMWkmU&#W{l@z&EiPbr&X02hbbo7%KWpFB8h;wd z+J)*0&(l}$5P3p!layJPdG7ipJoH*u;^}eJKbi+^*QXXF(bt3pmGnE3Db?l_#Qn*a zlFA+JAB(=}+LMtgqR(h=D3oY820kG9sgJN~ccwYFfP51~(->mIDsr_@I)@l9S4fAvWo z4Z_o7pQrbCOVeWOWwF-68>9Vo{j6i()-JCKa*B}>bQRh$?3)1&*{^;lYBd43N^jMj z=Awb7$hoX#moP*zs|;U!t&IlOXq*py#KpU87sKD{U@O2+=W>G;NU)eb@4Xo=Fomvf z2X%&2=V{Nf6mGop0LQcc#ysFB+`h(Z1jjSXdozUd|I$sK0LAi?dsqiKk0{O*?&q{! z|GlJ6etz)`7w}hvH|($yb;PQ@)n&AQ0Qg0&Qjf_9ekQg$%km=od&fc>5SdM5fWOlT zZ`5#=I56pUu326+AW%<#`Uo_{*QU($v7{_k6yxoG^^fjW9p4}{Lv|-v=U#kkWR)p< zW)Viuf*(7%NfkXHXKN8n*emcG2OS2X6SOA{UY9H~skg;RU!ZNLA1A6GjY#hrmAQG1 zdgzkL#>eN|^}zYR?9oK6;_bcR|GvZMdpsl0$~4_!FT14ZdP-QMNan-qM>H!u)4w;a z81_D-1=gd+;!XXE7$GFX$QtynN-nBOeX1EW(!;rB7<Js_Aqd;O1#YAp%BME)c z_m~~K2fLToGktQqi|=LNSIp$!+$tu1k&ko#cgs&ch#kLOYV5Dj2szG{O$~94Z+_4f z59{^?$KNub4c9+1Q4<~wICOQHTa~T4&4{dErP_gg`hh0B ztT4O+J)GXq4!XA~C8g^*5vwV(U&^iryT+ltBp=Dogmt?q*8B>m^?x|;f(jnWWf1c= zuU(WE5JGSq9y72m*I(WuEZl$34G+Sq(|xs_w71ao^?0d>^N;Nj=#Dp|AF#q1^!h?a zcyh17)JY`!Co-ZfWr^ z>10L@EKNa332^$&;!$pOQ%?Bp6ll}f5*9R`URRqr8ZuZxhNSZxMV`WbmfMOOBa$M z7b|GL*TnrUvV0bM$hK@y`HU?rN%r&dNpAf_J+BgE@_0!gkaExT@uuNcU5cdo)k^nC_gI)vuaeocM&HH;2tIHS z%$i=OhY5gpkF;Vb-`kj0TIV=YYRG;{Ht5JT1_Q91V509}>)pw|mjkQjt#6P7_R0W> z>k_`uGh31wW@ml$L;KNb*}Dk6*UfadecWXNk3~NYO+zq&+f=CxQ-l#^B%grR9oh>? zpv%bRwg*P>n+FT+aF;0_gi^|(PIP2xuQoIrjE51w{{XiI)EoAoyYK6sq!XW$h1Sbx z)|5_Y%l;#ZnjFKhD176>@2&5jxYG^Y`awRfFRDs7>QN=})-`@?ThbufW)2*UkxJ~ZZL5fi*(w)ViHJh-xXg&){0}38y`eSm(dt)#LOckovKT`F%$@$|v z2E0al-j+*mRYKgOjANv?ZI5XStB?kf3(wn?!BW+>HBS$QT~lCMy;54F#KM!4?$N0@ zEPZNm$H)UzAdkbZQ3T1`%1HOcVH~kpSPb^wZx;Lh(T31~IK)dTuit5+Z#-|iV8;#5 z;B%o(5QPxF4;K4|M3j|UFRCttu^mNz!a5vqeiBsJwq^Gb3)r%lL%k6!=fF9~9fU2u zin`i!@&UKEkwsN4+sKpN0R;d&H>zYSWw=W4)e&;;5=R<$8U?U~7xMgPYYqQ(nPZbS% z-Z2a(NpqPaL*f??EoX-{@PV1OhH(yT8?4n(&sJ_G4*i63F)_*adUV!CyrO!l8eom*RuF3@T3S{f=mwXUNw+e_sajvAuKV7*;cRZ;uGuTW2H4XAZK zfiP^~kh$Ef&c1^CmC-=l$tb#1fyhSl8u?*F&I)G zgSa~Dk3@*SN*X6?lVSYj_dAbNv;$*=uyEq(THP~uuF5JKa4*t8{qPRfkyrVO7Y(&? zW_tVX>s=8`$82lew&s4~+3*Y=JdD>7$@mW5%aXBrF%X{(3?5Ab!so9c3bvsgvbubJ zXX4m7ueNbuoE<3xXFhGUvR(E1G%x~KR5FLArBf1p7`SWnj2fdER|F?aHeyZEu5kT` z`30G^_k!=af)P!)OnX;mTfQ|le$|J8kV+rNkwcSvYfUANefmF-c(fj0#h&cnni(-3 zJ$`E}Yzd_@$X|p74yK{f5SKC_snd#?)BAq@xb`p6KfHfDR(^W-Rz1go(jEcFq;9hB2GHilGF>ggreonJY*UX~gTdgR| zd~$dj3xgPgYF0J9mO~V#Va+@k-s!QKYt2!hZE-BEa=z*j=#Z*CC^Tn0h>>zG=M}uR zu9#(-rvMgaSAIoX3S@!VbC@4#%Gp5Fx|G z9j%5m{j;%$;ceSc;?tZpW`8^b>Prf%sOYs7Aw0XYFB-_#8YDLA4g;;1r}>U9JtC(x z0;#!792=?L&VS6YyAZrYWWuwK`L!j)>)^_G70FnWzB5|3^*HoPhPaGs&fkx5O2bxGTe zdZ?;a^^Aa>WP_Y0IvbDDn5Po^NdZk{#qw*TzPNs8?p)PmrGeK;jO7gqLFUX6^ z`xvGM0!nRkn|$?@=tksit&`aoK0>o=?k}$6B{BRjReJMf)cL?%}6+XmakH zA*W$BXX9_yvnR~um{W6P%?^w&oogBWrc6JIXRm5uYC-#ni^Tn`D z*-ZKDQ6@&-Mkk#2UV<0)*gJZx!?UVT>JJft=I+f+oPH1ROfq!ZvEJ6Qfr+4^9-1W z+yx))M69jL1r0=7yO%h!-!(LI(tf)|s4^-xdgN_s^fEW78-9oObLb>=f;54zdZUuf zTmp34lJ-G8f9GmUw**EXuy4g6z=+vDBTbaP)kcm?Q)KwV#^m0?Bo~4NhD`8IW60dn zDl_xw-%N}Pp*Xr%7S#_%edo$oAC1emhFYJ})qV(2%#LWm*$5Lbr+w=gZ#?w+V!49P zJhG>r+O3eQ)YE+UVOnBLGTYY;r{|+7)@_w&=WdAB$W$WZ>m^`R|nw`{&gZAY6#i!+Jeyy zcSyL5YR$~z)|!nWC(@k?CvlI1^qKi;x6edtC!6_Pbs#?S#zEtqo(!X2Yf3Cstc=jG ze|Dm>RC%a{mcu<|}SfP*oox`9%020nY9WAv*a)q}~x}YEVGVs!L zx(**E>UrhZiVh^corNJ95pM0@#-TnB8ez8O!9R1)heyhK)1ddD{3v^nc`4=3xFW=I!| z#%l)C{3SL?&IY%d(N*A(fTnp|%t-*{h*WNLUCjHpAKoWre7N>=ySXavBT{bxwFI;} zGN3|~>*u2QFf+-J1I>^t)Fs!gUqgkpPSI(E5Nv`9Yc+qF%ie(>Z*7ucOm*~;Txy`) z;wLD>%@tfp?@^I0l;LfIir((p;`{^lqdInMlpRA}GG!2nfppH44mpHD5;GVR~Y-IKi!+7H?OETblD3scS4I= zsDiaa2Hh5jMuf{(SOU)3Ck^y>oU2!6Eu5mRHaREH9ROrpatqKzBD!59IO7*pkC{^a zTsi%ySYtSEx$trR@Fj3tHQR8l9c$yhYymx zu>rw_O|u0N{>ZYWHLijNwtN$=3}Srk8@~k~@!(}^)7X@EajUbSln__zDV>TP?pB9H zLy=Cie5>{Pk4Wcn4fi^_O9DS%Z;#LUZD&%g?6Ko#&lxNxZOD`1!4Q5a z)xB8_9sTZ-s{7MlZ8|rST3bcIDBb)I@93Y)3Em`}p-xp^B79^8=8sOJ;1vPdUzHED zCgWekHki!D<>trS9!GG>yR@n3Ng1whq-cFonyK8h%?&Ag?tk!zy{@N7f-mS5eKswB zH`nZdq}1s6Pf1)q>8c8KKd`pp79^d3k&&@aAW=o8V|2T7Ekx>R`-)Z=z4Udhj{e}* z58f!dwdaznH~~|9MgAacqi%B}Qxx5!yC`a(&&7)19jxp&CW{d>>?(pETD#h>>1g-F z=_T<*RJ&v1w{4ZvCDlW|)3e$*1*q&`i2|88cqj%A=IjW+wzpik%p!7uup?!EVnjb8 zIs8ReG4l(_-hu-!YHAE3%)wB-SKA#nEb%4#tW_C4733a)B{I1A&phfnvP zk%gQKce~owWXNCmLinl9)BKa&np=-##&(~%4#k?b@uJlEo~ z2Rpf#^&)7ru!?v$5B@s6jcg%>>7(EofuAvkx}hlDr*+wUDih*!xz0?RU|v^6i95zp zPLU5IqDahxt{R_XWC!9`%bGJ7_Ivjcdj;K4N&-ccSTkIDrm8QF(_oULMP^JqpT1O) zT#yysjFSf0C2{bKihcP|apO5;pVEVPQrw2YIE}Rex`QRHa6+Jb^?B&?q_(Ke#RG{^ zB^=X=@%XLCRspoaGs4*+TaujHu}Wu0&>1{0Px#~ah5iNxIHJ**?H=F!UNnZasV*eY zOIaVm!LsJ4!_jYi%TavC-+XMm_4~&NKHXk)%ma(lD96@{O+l3NH4ITtaB<+%h~zTG zAq%DH!D^}Ub%|8fIHL&2L$v^Z0gRxM2Sn*K4tnXKoaTOSF&NJ%9V)NW#`t*I#7?y* zX#heJJEa-rJS9W0p7g#*kN;qO4|(ZpLaBbeXv|LG=#Mi_;ZG+Q6eNR65Z2QunkBj% z_AUqwH*rye`2$lmaZp(X=Wu0gTRiEHK^l`-bzHd;H6)@3E-k&z6}YLo1k0khL=2soOZ`T<31@ zsx;9VwuP>F#j|t4Pa)j5e#j3tO8TWdGXETQK#=_2M;0C;#d@(z;b|RnFDN&Z@}Aw* ztP7O5%N(Rm_iii&A?~Igw-v;+!77Q6gjrDmwCR3~R;t7_O@sutX>4TOl4RVVG1Vve zxwH4Ip3JQ(W_0NPB3>oRHMw+noDuHcPwtpehCCHO+RouYPexVTSZ^^fKi2w0y{1sl zGqlct(JRbVLx^{k#*w=mUc=JyWJQ%&r`-WM=%&B7{fZNasJLWN|r+?DYzS!WN|5~4m+GJ|JqFPJck3+BzZai-F`Wyp-9gk~|^?ue} z!=xN{ccEakp7a!M=39k&5JQ?;bFZm}X6a77A99RPkO~+T5SQ2z*)=JFYEyM9)?~IvNxPQkF0dXaCQ-{AV=9a31$O=g{$V}lrn#Lun9qNo5JDQ}N(AU$Y zy<)&Bb$(VJehF@K8+vp{`NyqYpIvvs72biCjGFZeT*hHiWI|gWlrKbI+jg{;cY1p~ zQ>3SDtfX~1_dxeW8qPB>_i~(5tUA0zR_5$8*JNEky3Ms_89FB#t=eRkHN&dgb$rOn z_lak0r+QFB3P0-iR0cJMpM135zRk|LxV*v^GCmj5Lb}V;;j)*c@6#l$o*^|pWE^PI znLWGVK#F`L+6MV;vCXP^m3fESiRkZ4q&T8B@eslG<=r{N50J$E!p`|P?_7?(;SP=* zMm|!sRbdHtVbZS$X|J5_OR*nfq%>^HX^NOCKc+Y>TJoV=QyPv)!FRQXtUlIb5$ac{ z<%AI4LNCy1XnJ_ zGDSNy$9fL{U9UbYkPQ{58=f(09jCOe%qVXiz;=x*gFsf(UaFIxy^3RnuuoKz?oFL0 zD88b~XYiXCijt}?`;|}CCRN_gLv|eD+3!r=gu2q{IonjJUcXu9YCSB`KR;NV3Knhs zxj-LaZEH%hV6Hi>ac^rJh7Dy9mokCfCVmKU?#zraaTv4zM6~>jT6#5#|0FhqiJB<2 zTbP}msMI-csw*>TE2fPXnO61@-#%06;3Z%_9f9#NYzb~gV%dtxL<4yBmk@t>x;6r* z;|QR#s|}0*(_x&E&Lqc*TuSB+dF0@xYM&9;VHP|tIauRN)fOY}`(cFqaKdRE_1?Qe z^3_2I$o^YHm0BAzgB1ru${5RCfN~A;jVo~ILk$Kn zyxQ*YwncZ=Cd~dUu4<#qVn*p=OnmlZ+=NQe(a%wW9e))W5}}RLkeAVBss4tJuO}5L z743b>DI$D5IVKAsWbP)H@5!g&?>J62u&oxQkOz5(0?V-iZxXHKS?cgG#%R(S?xp$J zyo{^&j{f7x@>Kz-(B3c%1JwV1-I_v{Poarv3^$#z7{@C;yz2$?3kL(G$>Q&fc+ce& zC*jzc&sC}j6a~3x-*T#r$!ak`V(uT=SOD8wI<8bLi|IDpht2pwIDs7&EV6_537^zO zZ0FX)A)k8TADEup`LLk;;e}uiLwcNSFdl8iX2N(%KGJ_Tt8A?>bsPzrC zk4Lbkvj`ipz@Xw$Qlu;P>CIbWSqhXAB9-{Yb}1&K&H5>^)7co`TsY!;n4!l5nr4yN z+?$WZNZ4u!H7Et!yU_~l}&owNCr$HoVXPg(^ag}AA z`z%cjE&;pMlWpeJp5{oL%t!*cb^cxKUHi|GTN)F$*`x!X6w>Xt+FJw2;fgF4VLwnS zNEku|8BEQ~AWme4;Q?cJqGo>fU+Vg$uTEb-W}2o1FiG{x4Tx6`25gNourrHdNBL9r z%*|$W#iP-R?QXmmQ7}Yr^O@5z?<_^^^wjuKc}nbaI@*!7({|q>Ty$=Zw=5})jLeIl z$8>Mf_#X1IW)s6irfy_xU%b`!i>u^$eyBjQv_;-T7OXb~;cZUFhFvk%13-B-aK6H| znk&$}nrPB#bt#ZBTsc%%?$Y6So%?VO0}!tlFBp9jY4euc>SY8Lz+6nhcfk0_YEIs8 z{WDdW$hcgW0OuJs519t-)^h+VL;YiaD+&v^o-D)yOiT<#-4in!?Ty?Usgu5>Tn2vm z1fkqZ=`5zd0V@Q1pC1R$RA8+Ur@rzM!KwvkddtACOD*mXr6^RgPl6ard&ZvuFf{5s>%!sU@fdsK%D29THAgN@=>8BfIQ~tay_Z#Pi?!3d(Xjy-UMahD__&< z;m|s+pR9Uho7{SC^7;k0GK96=Z4M0Q+70+hFrU!4bHYP1QtR<41w11 z(ajI!rWU%cqsf==ALTxbvGVt>O1!&WDII&}e3vJ~yfdhzf4p5eottVH|In9&_)Ti{ zhWp_OHW<;JLg4gedjm-mqIl4$)9GNYN7p!63P6csFq_x-s|yNN@o1&`7t2%c9_A`SnY#Yqr{ zhUp`tZzqsV^XHm|YRNjOyNdB>7Oak70O52CkzB=pq<55GY4uT+tj~*SXDXFvzFuFm zx#BaxQ$e{MG@QC&H#dA+xEeCXF#(y#{2YxqXleC<_oU?rB4OJB7@6;td4X!9RV6{`WeK(IZD zXZQ0E>F{4Yu8b0Jdtp7tuiY@HNS!4SFSi%BWfr{(inCjXC%b%+z$FvA7LL%2Q@oxC zikz*_q9IoIl*TZb6`-7(hu6bjNq`$_YOrWw+C%F-K02D&={J~oMr=6N4?lx}>Q$Xs zC(nsbjsVH3%IE=0o1L4C7E_w_ys#;QwtFp;-3xT*Cs~zahz7SxwI)ppNx=qUu%(cU z1#%E6z~HvdNL{a*qdt1zLZPR&*Ez4rGM_zG3qA1d?HR3<<}JAe+}HUryWodx`ykP3 zXklJ{`z>Q4^RHTwN$4Jxb9%_Z_9j$|7F8JLmRd!kzM_=GN$9bK7I}u(nw9!ehGgYk zY(Fz-;fRx}t#(>ahQEx+?rp_g@E~#jTB-_wQEMm&9g&c{AW0wX z?CW_^I0lyUi-5K$D6x0KKK0Prr-2Ru3+kczq4?)wUW`FQ@PQ6N!f%6m>3fq1w2h2X zS({;7_y?ghbVF~ZF?U_Sc)rz%DnkW3Wa!oEKiv#I<{ zMF{!nEd`S`>#|`**w|tPGmb9zN(720fbPWf!r`R86*hLj>O~ClmreVp$CMWcZ0#c! zIm4AU5=Z@p?@T;liRM`nfwhcydNA1jVN9e_-wpV6P1*R$_{(dH$H-}dlyl+pKtgKJ zlZk)&J0c^g-PTEJbn>|!(C&Uh5rHA$S3FRYs+Vq(5nkUd&3m6M_Sy(Zl(T7>$gAZr&}<-%m!0*hFL;pOo_gM z7yZx0PIDBDBwNT%T(hL`qVq6*^L#QLfX+dR71!^)LfCc3KsLhRrvj8bFJ9eXL^i*j zzw<>=?fEt46X}7N<^uCODvRssb!Fa+;KSkHTQ;qK+ix=W;2h3IGVEcX6p7GeRd+5yKd4i(-rablLrF9apM z*O5#PA14~vT5yJxo2kBf<$TP<8)rZ3W8!`6Mly|hUefF-M#D|#`h4r34v^@ra?}Lk zND7~YgM{ZyTUoUEy)7g<;if~gt&N_E6!vpedVhSUWP@??o;3sM9Zc8~Pj9B_u5L@2 z^FK{&K@d0q)$9CZx?Y;kTEDE!xWP-#)rfbY8Ct+_ZYx07xnKS9_TI8`Ghb}-dxqF; z{@6=5u?o}Gl0ebl-O`#Zei?|5zIXZ+-`TM11S2lC&|$R{{TG=9sW8hRFp276Tv_s| z!q&~(D;D_vV%Bsh8Pr6Sa};;h*Vt+PH|Mz1EU-z+fK%mT0n!)fcAGdVqv0wizc>ji z;2ErJ3FbEcY|nUxVuMntuBrF$u_JF7Nv0!fQu1;X{a~|;MZfz+?y`c@N1m$lp4Gp- z-#20Ra$@ge<@N1|nd}%dTa37zpk;~VzU2z0byvI$thf@p073hYAk{>@ldYS^>XzSK z>B0~VFpE)*M}ggg;q05Vk7;|Zd6*nJ1vkrX_v*WqAG3n*$)02ER1%&663)K7! z5mtuY@#r0qM>DZ1A3mkWY}GS$cZ}vZ6W+&BRYgr4iLKW%{6-LWG(p^>G?YEM2R~Wa znKmojG;ZLLoL!4ud<<3j#n#Zi^jP|q5SI>;vb+6vo2EL2FrkTWx zl5|GvD^(VE=W&`71JM(a?=C_5ZsgRr;z#7=_#!rZMx;xB8_TG{<^o!s1I5ApwtPcn zKYlhinPcuBks*nFaRAjB__Lo$RrHkRunEIi&6#h6)95_o--( zI{VO;rv7t){FUj@HjzWcwX(bOyO#k*uRSp$ysmq%N6;FgTc=qq6(gJ@X*#wzWEm!X z7OC*?lQZ!}6H}33b5rUedwE3uq#t97`tKgWd^82dtHMShEqJ`rxXYQ+Bjb?kYba^Z z@&(65+>LFyOo{-Vfbgs~(^*VoDXa6@OO3$Mc3HlNO-1AJ54j3>B8#LelR(1^jPAI+)9Lc3a5C z-dDY9xRZb8V*gLx2fanp-sDKLc6k&B+Uu7!zmOSzg)h5Y7L030g>(h(s$M9Y#l(wa zD9n>7G)Qe8hIXN8FOVezUt6;DX1g8a8^{}RxY3;c#ZTgQ_j%M5q6smYb+gN*jT1t= zdndLmm1d~x(upblY)aL;r!%gGB?9Lby~YICU$$cITvdxlFqP(>qFPKa=E$|0+lavls2ljukVnY`Qlvc9bE`|6tBn`m6EMD4qWrKjxq5{(I1AY z@XerFu8Icip*l9KPZ^OGcSm-roGaA5od~KDKtaf|3kMRd@^peBRRQ$4he#DbUcmhM zafYNM$s%mlr-gq-a${#jJL?5YjEsLMNr+$xS`Of!B3%2iPkTxsM%ZO8^<1bSgk&g8 zCF_P^m(2}xD7+=^u-p^90I`^rtJH#X1ElIkL^g|S&CSBAS}nNO!(`c17|QB37W&6K z5$pr2MVlW^Xc`*wI>G(H_8%Qv9$Qh;o04%8QsT73lgD%CG#O*1i6p1s!CMAzqoP#B$TD)gN-vNiDB4>WUu*2EGa$Ixvt~(@I)PeI3H~Q)jS~U1|YY#|{~V ztgU|^JF&C=o-JRVf6=AvMI5yJm`UCTSf_;>V{zmB#5q8$1@&%IWr=K@9rF58Dx7?( zIYHFIe~q_ev7os|*dH%Xv#H(&rrwGM(Q>@8V(>n+cojGic4@%R7NJIr)5J6qStA-> zBdzipf>{wnqqWL45>tam%8Pwo_66@@)?tII`*@BVc1?#jS1AY<-w6*vZw?R-sWoV1 z#a&6Y9xae*J*T?zY*uR{YRv_|Oifvn3HyAWU&9_@pYmR=qqO-t_ZeHr>JPQ$%I3+` zQn{97qFwvqY?+4DEN`LN*J%QZC;pX?gfn@3F{ICePpchrAaKOH>(loi{;S)Bl-R$f z4_YkPaxN&n#9?{MZfZ?h*+vWn*hl%``_veVBft9IVU=#US^7zmtj<{d6pbXtqIK34 zm8uMNAO8P!#$H>bE(kgU6Uq2lkkBYjtra}_o`)BnhXFfF_-Q*_C0ZVE>n(mFt279H zIeDPMkfYa&_vEbzQ(Q;kfV^&2oOgO;al^rgPhk(o<^(ICby3UyDZPXM2!_u~w`qK@ zALtE;^;ZhL{&O-o(+B2QGx#&<3BO0lt)d*0*2Uk@dJ={6}6$Gv%oY=TH#k zNp4XPPX`UwA%m>;9w9K6=log^Wf<&nxPvJjcxS^fJf;Er7pXR+HKvO&3LscOYQ4^o z-pi`Hz*`*UGK@XX@z+h}G}2U;lrQv*fgu zokbvh1j>2km>D%5WTGI40bm(6J61%V)`4FH`IT@2TB}ly$z$W4JCw{U`A+E=fcpp8 z;vnlNN6%>KJCw^&-V&3=)`>!7JVO)iOl*Z4eEg(14` z&}|6+E`xLR#GwVhL`38rfeJr~hz;cnJnk9*MPB#tNzJzLQkT&>HczrsV8Q zYC2R@Wj9~}4kvRKsi8c@0>CM#dEN5Ivbe*_9ti8~)8a3l#v=5-@AAUtlmhNb!JgG% zrsBoqgr}R4tlM2kPT@ZyUd)OiRYp|BJ&X#pOSW()xx071(a1O=!nHI2H3b8v3I1&< z^~Xk)cvNtR=}tp9MdIm0I{@h#Q*^61{@U@L%=6Wy_?HhM&5)r?E4nd5K4TO$P%wvT zrHU)UfLpsgtX%H)9PP2}Zyhv!PS53tHd_ac-HQ5-(PXcXqdti_<5aslU&O3$;?h78nh^OL~$$aG^M3XPqXfwTf;~-WZqfZ}MnU6+hon5ZS0Aq&Xr& z^UXy{eld)cKA96W^tHur|3|}X8a%@I)6>}e0RO^ASAz!VitLq#AddBJ1MCqYc+2V8 zddunha4Iebv^uO0hF+)5}3^@KPu^jT%6h@|i?Fh!*tzna6)IZwp=r3XEofYuXK zE&Uw)DCl5HEP5#meX~CoQm+N!P#Lhy1*#hgCn(XZub-;_H35*r4J`P*}CiR-q@r zRQerf-fkiy@v;Kl(g)`nrE6zgM%Owl zPep?M9;2PVVLC_;r2BB$e6Cj4!=i>QtvCS#h-$vSlWnuAmHtschBA;Yz!DyM77n*r z?P&-`SveJ+^Q5>o8CO2<#{7AaO9Z zj(!<>yI`jnePnTo`Q<9${ZdmabO`U&r0MFFp4)KB#w}dH<#~BhnuYqlD3-tBHK8Q9 zr*6P2v(CHuJo~}|_vm{lVNjopph|+c$|Z*{K<=EK3^b_FfZ%})+dA*E2ej8HoI~D$ z;9~x{n3*FpRS7I?ybkFkKt$LqTnt9hwEAm-fiBhZ@(>81g^vmjD4%~QUY&iwL_@&7 zpuh0v3#_mO)6Ub8=tiF(%eVM_-q67m#%LPAUxIW-SSXYTc0bq}3!RtwxY3Ldv(Uj`^zz$?{5l3kk1hSjBO2oB3Mad&5N#xp!lkX` z5q|@9G4XwztwfrF#^Pf=d*#)M93$+R+dzThD7;d3?I^nyqWSvGwPg~x$ezOWE z?(}QOx6)mHS9?>x|4ce*)nFNEnS!GsRnIm_K@)3omZ`p{N<1 zgg*6&I2YijoUCxU_Rig?O(+A=fu-tD_oc+fcwGWfL3u7;U>{_*2mpoEM;7$E^}KiI zo(ja?HD^;lvB+6%2to){=1y_NSMk5-1nV>2ZK~zS)(B2cWB>}jA60Pns>&obcC8B3 zDTd-hlw!pgUft@9EZ?v77V%_;Wh- z2I0+Ts(N6?Hwo#MaaZEI+JPUmDQJnl3PGBP&M#g!QpuEGm0B$@80FGbkWBMu$BtBE zcIpQ!BPwju@3iM7gU?@MWZU$@1D!=iC(API3SWFAP;}?hU!g>8$(l;9-t4R?_YwvT zCfN`ja%lx=|I8ou?@ZdeU5_6!SjW!lMUK40S+hJb2L%Yw1g=aP^dmq2;5@u}zZ(O9W5{#dq8 z21Xzj#$Z@WSbA%`g~y*gPo278DQaJpEYmo>$>t*$K|$H$JOv)$mRLQ5fkLGf%J-~C z6s<@aT9H7|JJ%Hs@~+4EOVRLs=B--=Ht~1QU!-8MsjA8hDI+&>Z7Ck|&;kXIMN7hQ zM3EPEkId(RQ*0-h509o1T79`QJKON^&$X?+k!nTqYM8Yc=PEboG53~r0Au-GyYV;J zy67{|U!k|a{#`NHctGGJmR{iv&2=9UiZivQq~gkYW`aFRwVJ>w(r@0=`zaQ${d9C0 z<47j+k6s{}LhE#9hWly$W_u7g&|jnz7bX@oyH*rptwY^8^kpRF(34oF7lIl3pplb}&J%5#`f&_V7^RZzR`EdL999MofR|`R$ z`#tu!UF5HXQsgIzk|Ill(n&71XjKd%u`l^cZbwy_movmCnBP+y9Mp;%q@9CN1ntBf zZzvDO1=oL!d-**h<9sf!G+^7L-0cP7W43Es=q#tT|CtVTIcbkL_74kAkyyQdX6h2<%qub?1_>ZRpDYJ8gsh;WzJXk&Lf8SVDd=~_FWeXG{3QYWoY0qYpW6R2? z@io=(9YbR2z|j)o8ufithZgIHZgbQR|khqrKc0c)iX1{Q`I2AL&NQ($NSfbzAs zAcWyc{zQOLco7uoQUMT+yHi@IT^eP%Sgo8M7-(cz!>GWFL-beqn&zq+!{L~KQO!xb zYe&YpQ7Y+O=B@4`<#cNOVU=@PjvhRMJXKXqHUD>CEJp-5Rg5Xpdi`dk#FcLZ_5%ms zxdQQzgJvtpfwiV{ZzK-B&UPj;#KJG-*~Nz{(b%#Qax9D!ID@fa;kY%yAq<-`4B$DN z#&E(DlKU{QS+U@P#F3qIlabavBl*&p@+j)qKua{E;&PbQ* z1#r6uf@8Q&rMDcfWLb&od#K;Z$LoLJYW-)fqk2$M#jURgsKK6ITJ@wBL+gr>>NjoS zOPWJ5#ME~7TFF~ghb2SvbCrGb!^Ck19Em^W^=4p1N%RZ$j}gmRMBWLUY5^13BI}0R zcP+Jg7MXZV2Tfnu2;L7BVn`9f3bqab!@E@#fJl#_939U?{y_(7d*k^iiaC_N}K|Q8!`&<-A%WZO)=m!;Ictq z9Nl~eJ0yeD<05icLEsK9j6J{0jq@Hb6n_V15_nmM8wB&p!;JAyY^vAZw!LG$JW124 z|1%%%Y6~L^e~67WB{kgUqLUkqp2B=1JT>7`ofF0A*|nT%ap3ZfS_ zwM34hr{<(gJZI=LQHWhzJ7IW7B#URb}xJy%CIsiR;@!wZ%o06B7ak-E&NHm3YzxB)AqiptDJmdUMx+WzPz(qGkrt##4^i}(EA=h^G5{p{zg_3d|mR56A{ZQ_$4KJTrVsAolJ z>5k-&muto3C0=Z(w_w?)BG|l`V3nAXOJrkXF8fd(g#x@bI7|&J{N%zoRj6KCVhl>&AegA6#`uO2e0<*U^S6 zgXI>?vW?q~AxNBbjKwn6!%Bm)j%+&We7SgK~^g`P7<{8}Hj`R+D znmrL=;U&An>B3sWJLh0^k9#)dvY6v(@L0@kk#osX#L`M7)oPveyRH0lfe0ha)4utE z##Keqi_^hNeyqDut_0sjFWQQeYK@3GBm^=^5a|t$MxE18xY>LBA1A{xIHOfB%hB=~ z?$p`xr^o%y_{ZAYToe`j9Ii~`l7}0;oYZfx``Eq0r`n!=x9BfqFuI%Jom_R#cqC^G zq$AnKT`-ZFDik~59$FsKyxJ8f6f{^6c%*;gLuCT~h1n5c|ih*F5rVmScDDB!MVLq8^%3#Dk@`3P8d$!Lf-H z^G~9taL2FPNlxKQ7?SZSmloF?^fGwbgB62`7zJG>eiai)9as)Mix*+b1G%>K^7FZg z5>Qnmefi8b$>v4Zi={ra%9}F?nkj=zz}7;~#Z&~t4 zi|1QyViwU@`;wu9TIoyO3CWuk--Hi{_y9*tCEz@{3Mz_fo|x;W=bMEuG+G#fjSZ& z=kKB&a0)%oxhvXogAo-d(41Zmo^_NpXCO9e=0MEEqU)+yMVy`V?)rQ7fR%?YPNT}j zBMy_C)mmkgL4R|Q8BLD@Dg&o1T0_)K>JIhazAzHhX*i!1a_yT{MaJDX=?3|LSoIuM z)ExC{?~k@RRuFr^+DE=l@G7y)B>?e(GXXy>Y$8<{Q0|Nfl7+;?Z?eFn_Um(;vYR*b zs|0@xnDo2}R1?Yo{R^sNDV`60Az-=#ni?rewsypiPJDmk?A(olRlSxOdoa-e+C*xr z^Qg1o7BCE1wvZR=riRJuSMbp*44U!eO#zfLF`Kwd%g?Hz_IE45(hPupo-qt=+V>x^ zj(=@zp8V{O#=hjWgH%_kWPDBjjqIJa{=P~@O#5cVh%o}x%en0^g*BNR22@wmlM02d zJ<^KhOVrRollb56Ncqfbxm^f%DOMW%#i4BfXhOH_AFV@$w-tiJ7NYp;mkUSsDT})(cOEqt18?3}i8dHNX%0gTqs6@_1W$30m`jW+= z8foYYH7I=Q&&16QY13EKtTs*XJ;=c9o_mlVJnU?pMt6}!Ek|?f%t*_p6C)#1YkDMC z%!uS+p4KjrXxCesNpTy_c!#7=Y*n=evZ6eK=`G;(E3ERG79T}PuP9wKreww1MRK(UT%>h|CtiUq&YN!d z1nFLx+h+B;m~t8<<#+E93aAwK6lE zl1@i~%!qc}1wB2rDkeXSlgV$=@zqM1G#iaNOo3V9z|(7oN(>p#Y#8QWDuK8=NyNmT z`(Q1+w;oQNg@P8$$Fw)tiC-<YsfVk(B%sZL;NoeBDnplx8rt zb?2SGR6Dep-K{JWqT~oeb;sZeR&(FFWGjU4?C7#*a^Iu_I%(z?bnhFJRR;{d3U(EJ zABE?_u_7TPg-sPpikbS@qx09_>yVAf?+yPBP!lNqdKgmXIQFhD)kZkuR>D)k&_U6y zIKvc+ed~62o%?G3-PQra=}QU)U3UE>SN^o2U~We$neZytM}G2a<+wx%8TZiytT!@C zulsIxnR<$c*3>o-?zp+|5M7TRTJb?#aH#sqvXPa)_&oCGx&z4&(3LAv2nPavTxT76 z0(-#o?!Ct3U6aVdGcDd&8Fr*E%ZNIo`=+*Rfl*JhxI$0NccpTb+v7ZYgCg&-Wtwnj z6Ny2$sCi5k)7iMIC6?x+5sjtPDF^#x+#Hk5ov&rcd=$K1bAe5E`51~LbxYP-%q!=1KVbgZi22)mHo}MWpdMJg9z>D;f=a>0nI$_#7C8_@ zO!miLx6lvo2ar-pe*HhR=NmP=?aFtrEmRJ8)^FRyqmZg!Rg` zmMgBQFT@UK2X`XBP=+$}OC0Q=s;i)1ohWciGd_>T$yyg>N$6%sV(q?BA4T`2cZH86 zYxFXQeWEpkkAbM<+d+SF7{a@feU5 zcO6~xrZZ7tUY$(?OF!jJr)H|lrdKynvo8H{<&d8g2yi!RVX)rq0Z3sSdEfTD+k=ZZKU_~qvT`Qx z%ME2yOAv|s-Dac)0w+Y_#mNl9ai`l645`8&y)V!jr^8_1F=5clV<1a?Ae5cX`bRA; zpc5;L_$R3RqNp{#bZpsFkH&l))V#?%*b79G^o%t1ns&GnzyWemOZYsreXi!jW4nQO zWos4R7w?x!P!Rka*2d=DOI64FhFSZCJ~_i-qIw_ zhoqq!b9AF`tW~Ihl)hP?cTeGqNE)VT6F)yaJRBolE9G>{15>I z?rG5e_mmD+i$((e&W*#`ufI=4;eec(d~zWB1`3`IAdT7Hs=nklB=kEqbq68Ew#9FA z!ju!v*z*&d90>W{xo%jgR7514O^!{fnUK6c_$7jQ!7uR3k<^IA68a2;xa8Q_CefmM z!)b>VvTfZ*K@-n5T6gHBQ#L2YTL^eY51yG{l~Q@-?vYQAZ=ngfi~=+HPofW}+VHcQ zKV!<&k3tp0%A`Yn98am3SURz5e3s4W@W*MMU!vUqEY>?Bct5QpoyI~ixI({wxL!BO zXD54f$TNb00DUF7FcJzroJ6;gXHpZ-s{QW9_UZNm(%m1_MG;ac zyKKa&>{Vxu{Baz4d6b}9G20Zdk zCn9mgAedUycG4{;ype|EK=^vQxv2@$175iU0M{lDf7i0?_*?!grwEq+OGK2wR>Z{T V+e-#^z;Pe&7+g2jp=vut{RaxntC0Wz literal 0 HcmV?d00001 diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index b1d381fec..75b89342b 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -268,10 +268,18 @@ 75A2A8141DA5936F00A983D8 /* TodayExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 75A2A8081DA5936F00A983D8 /* TodayExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 75C735AA1DAA1B9C00251ECF /* libunbound.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD4121DAA0E3E0075898E /* libunbound.c */; }; BB66CB271F7F2FD1936AA04B /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FEAAB89A265CC043F53CC51 /* Pods_loafwalletTests.framework */; }; + C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD222574070A002BB9BB /* PartnersView.swift */; }; + C35ABD332574073F002BB9BB /* PartnersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD322574073F002BB9BB /* PartnersViewModel.swift */; }; + C35ABD4325741E19002BB9BB /* ResolutionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD4225741E19002BB9BB /* ResolutionModel.swift */; }; C3B7C3B9255EABBF00E98A64 /* SupportSafariViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */; }; C3B7C3C2255EAF1200E98A64 /* SupportSafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */; }; C3B7C3EE255FF59200E98A64 /* ConstantsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3ED255FF59200E98A64 /* ConstantsTests.swift */; }; C3B7C43F25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C43E25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift */; }; + C3D4379F2566EA3E00F423E1 /* LWActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */; }; + C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */; }; + C3D783B72565EA6B0004FF70 /* UnstoppableDomainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */; }; + C3D783C02565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783BF2565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift */; }; + C3EB574C257D95B7003E3949 /* partner-keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = C3EB574B257D95B7003E3949 /* partner-keys.plist */; }; C3F55645255A193D005F786F /* SupportLitecoinFoundationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F55644255A193D005F786F /* SupportLitecoinFoundationView.swift */; }; C3F55655255A195B005F786F /* SupportLitecoinFoundationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F55654255A195B005F786F /* SupportLitecoinFoundationViewModel.swift */; }; CE03EC741EF256AC0038E3A8 /* SimpleUTXO.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */; }; @@ -519,26 +527,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75A2A7E21DA5934400A983D8 /* Embed Watch Content */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; - dstSubfolderSpec = 16; - files = ( - ); - name = "Embed Watch Content"; - runOnlyForDeploymentPostprocessing = 0; - }; 75A2A8031DA5935F00A983D8 /* Embed App Extensions */ = { isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 8; dstPath = ""; dstSubfolderSpec = 13; files = ( 75A2A8141DA5936F00A983D8 /* TodayExtension.appex in Embed App Extensions */, ); name = "Embed App Extensions"; - runOnlyForDeploymentPostprocessing = 0; + runOnlyForDeploymentPostprocessing = 1; }; 75C735AD1DAA1C9F00251ECF /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -1422,10 +1420,18 @@ 93035AB774472BF9805FD3F9 /* Pods-loafwallet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.debug.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.debug.xcconfig"; sourceTree = ""; }; 9AA160F2A4C1674AC8595E65 /* Pods-loafwalletTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.debug.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.debug.xcconfig"; sourceTree = ""; }; 9C4905F581557D8FD607EB73 /* Pods-loafwallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.release.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.release.xcconfig"; sourceTree = ""; }; + C35ABD222574070A002BB9BB /* PartnersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersView.swift; sourceTree = ""; }; + C35ABD322574073F002BB9BB /* PartnersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersViewModel.swift; sourceTree = ""; }; + C35ABD4225741E19002BB9BB /* ResolutionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResolutionModel.swift; sourceTree = ""; }; C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportSafariViewModel.swift; sourceTree = ""; }; C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportSafariView.swift; sourceTree = ""; }; C3B7C3ED255FF59200E98A64 /* ConstantsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsTests.swift; sourceTree = ""; }; C3B7C43E25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportLitecoinFoundationViewModelTests.swift; sourceTree = ""; }; + C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LWActivityIndicator.swift; sourceTree = ""; }; + C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainView.swift; sourceTree = ""; }; + C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainViewModel.swift; sourceTree = ""; }; + C3D783BF2565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainViewModelTests.swift; sourceTree = ""; }; + C3EB574B257D95B7003E3949 /* partner-keys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "partner-keys.plist"; sourceTree = ""; }; C3F55644255A193D005F786F /* SupportLitecoinFoundationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportLitecoinFoundationView.swift; sourceTree = ""; }; C3F55654255A195B005F786F /* SupportLitecoinFoundationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportLitecoinFoundationViewModel.swift; sourceTree = ""; }; CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SimpleUTXO.swift; path = src/Models/SimpleUTXO.swift; sourceTree = ""; }; @@ -2105,6 +2111,7 @@ 2494037523AD35C000369261 /* BuyWKWebVCTests.swift */, 249C570423B51F9B009CB5A9 /* TransactionsViewControllerTests.swift */, C3B7C43E25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift */, + C3D783BF2565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift */, ); path = "Class Tests"; sourceTree = ""; @@ -2910,6 +2917,8 @@ 75A2A7921DA5934300A983D8 /* loafwallet */ = { isa = PBXGroup; children = ( + C3EB574B257D95B7003E3949 /* partner-keys.plist */, + C35ABD07257404C6002BB9BB /* SwiftUI+UIKit */, 75A2A87C1DA59E4E00A983D8 /* loafwallet.entitlements */, 75A2A7931DA5934300A983D8 /* AppDelegate.swift */, CE20C8F11DBAF71500C8397A /* ApplicationController.swift */, @@ -3017,6 +3026,36 @@ path = Modules/sqlite3; sourceTree = ""; }; + C35ABD07257404C6002BB9BB /* SwiftUI+UIKit */ = { + isa = PBXGroup; + children = ( + C35ABD08257404D2002BB9BB /* Partners */, + C35ABD0925740518002BB9BB /* About */, + C3F55643255A1916005F786F /* SupportLitecoinFoundation */, + C3D783A52565EA1E0004FF70 /* Unstoppable */, + C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, + C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */, + C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */, + ); + name = "SwiftUI+UIKit"; + sourceTree = ""; + }; + C35ABD08257404D2002BB9BB /* Partners */ = { + isa = PBXGroup; + children = ( + C35ABD222574070A002BB9BB /* PartnersView.swift */, + C35ABD322574073F002BB9BB /* PartnersViewModel.swift */, + ); + name = Partners; + sourceTree = ""; + }; + C35ABD0925740518002BB9BB /* About */ = { + isa = PBXGroup; + children = ( + ); + name = About; + sourceTree = ""; + }; C3B7C3EC255FF56100E98A64 /* Constants Tests */ = { isa = PBXGroup; children = ( @@ -3025,6 +3064,16 @@ path = "Constants Tests"; sourceTree = ""; }; + C3D783A52565EA1E0004FF70 /* Unstoppable */ = { + isa = PBXGroup; + children = ( + C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */, + C35ABD4225741E19002BB9BB /* ResolutionModel.swift */, + C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */, + ); + name = Unstoppable; + sourceTree = ""; + }; C3F55643255A1916005F786F /* SupportLitecoinFoundation */ = { isa = PBXGroup; children = ( @@ -3146,8 +3195,6 @@ CE20C90F1DBE5B5100C8397A /* Views */ = { isa = PBXGroup; children = ( - C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, - C3F55643255A1916005F786F /* SupportLitecoinFoundation */, 24BA90C52410129E001E3825 /* FeeSelectorView.swift */, CE6BCF5C1EE9E89A0029849C /* CustomTitleView.swift */, CED341321EF5A5C00014912A /* InAppAlert.swift */, @@ -3291,7 +3338,6 @@ CEBF33021DDE177F00348FC6 /* ViewModels */ = { isa = PBXGroup; children = ( - C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */, CEBF33031DDE17A600348FC6 /* Transaction.swift */, CE27F9581E2C8EA300F7F7F2 /* Amount.swift */, CE124CF71E67A8E500DFA146 /* TransactionDirection.swift */, @@ -3509,11 +3555,11 @@ 75A2A78C1DA5934300A983D8 /* Sources */, 75A2A78D1DA5934300A983D8 /* Frameworks */, 75A2A78E1DA5934300A983D8 /* Resources */, - 75A2A7E21DA5934400A983D8 /* Embed Watch Content */, 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, 24E179F123BDAC2C00F928D9 /* Swift Lint Script */, 8B664BEE6304C1815A957FC6 /* [CP] Embed Pods Frameworks */, + C3D1588125666B69009BD3BC /* Mark Dev Notes */, ); buildRules = ( ); @@ -3725,6 +3771,7 @@ 24016D8E23F887C3006A6791 /* GoogleService-Info.plist in Resources */, 24393B5C23C259400075218D /* Phrase.storyboard in Resources */, 24313CA723824F5800A83F69 /* Spend.storyboard in Resources */, + C3EB574C257D95B7003E3949 /* partner-keys.plist in Resources */, 75A2A79B1DA5934300A983D8 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3743,7 +3790,7 @@ /* Begin PBXShellScriptBuildPhase section */ 156E4E7F04DB5E000B3A1A91 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputFileListPaths = ( @@ -3765,7 +3812,7 @@ }; 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputPaths = ( @@ -3779,7 +3826,7 @@ }; 24E179F123BDAC2C00F928D9 /* Swift Lint Script */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 8; files = ( ); inputFileListPaths = ( @@ -3791,13 +3838,13 @@ ); outputPaths = ( ); - runOnlyForDeploymentPostprocessing = 0; + runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; shellScript = "# add after v2.6.0\n#\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; }; 24E179F223BDAF8000F928D9 /* Xcode custom warnings */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 12; + buildActionMask = 8; files = ( ); inputFileListPaths = ( @@ -3809,13 +3856,13 @@ ); outputPaths = ( ); - runOnlyForDeploymentPostprocessing = 0; + runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; shellScript = "TAGS=\"TODO:|FIXME:|WARNING:\"\nfind \"${SRCROOT}\" \\( -name \"*.h\" -or -name \"*.m\" -or -name \"*.swift\" \\) -print0 | xargs -0 egrep --with-filename --line-number --only-matching \"($TAGS).*\\$\" | perl -p -e \"s/($TAGS)/ warning: \\$1/\"\n"; }; 8B664BEE6304C1815A957FC6 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputFileListPaths = ( @@ -3851,6 +3898,24 @@ shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; }; + C3D1588125666B69009BD3BC /* Mark Dev Notes */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Mark Dev Notes"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "# http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos\necho \"make-xcode-nag-you-about-unfinished-todos for swift files only\"\nKEYWORDS=\"DEV|TODO|FIXME|\\?\\?\\?:|\\!\\!\\!:\"\nfind \"${SRCROOT}\" \\( -name \"*.swift\" \\) -print0 | \\\nxargs -0 egrep --with-filename --line-number --only-matching \"($KEYWORDS).*\\$\" | \\\nperl -p -e \"s/($KEYWORDS)/ warning: \\$1/\"\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -3876,6 +3941,7 @@ 24470E3823A5FEF200ADDA27 /* SpendingLimitTests.swift in Sources */, 24470E3E23A6000900ADDA27 /* WalletAuthenticationTests.swift in Sources */, 24470E2A23A5F33000ADDA27 /* BRReplicatedKVStoreTests.swift in Sources */, + C3D783C02565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift in Sources */, 249C570523B51F9B009CB5A9 /* TransactionsViewControllerTests.swift in Sources */, 24470E2523A5EF0D00ADDA27 /* BRAPIClientTests.swift in Sources */, 24470E3C23A5FFD700ADDA27 /* TouchIdEnabledTests.swift in Sources */, @@ -4012,7 +4078,9 @@ 754AE0BC1DFE8A46007FD001 /* BRCore.swift in Sources */, 22A9A94A1DF61945000F0016 /* BRCameraPlugin.swift in Sources */, 24306797238F3DF900EBEA99 /* BartyCrouch.swift in Sources */, + C3D783B72565EA6B0004FF70 /* UnstoppableDomainViewModel.swift in Sources */, CEC6AA3B1DEE4EB000EE5AFD /* CGRect+Additions.swift in Sources */, + C35ABD4325741E19002BB9BB /* ResolutionModel.swift in Sources */, CE45C1FB1E74F89C002C3847 /* WalletInfo.swift in Sources */, CEE659E71F65A936001FF29D /* RetryTimer.swift in Sources */, 248BFE2623AB302200CE1A71 /* BuyWKWebViewController.swift in Sources */, @@ -4049,6 +4117,7 @@ 24A6DCFC2230BD9000505F44 /* WipeEmptyWalletViewController.swift in Sources */, CE92F9F61DEDF6890046B516 /* UIViewControllerContextTransitioning+BRAdditions.swift in Sources */, CEA362681E00EE320061FC0E /* CameraGuideView.swift in Sources */, + C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */, CE03EC741EF256AC0038E3A8 /* SimpleUTXO.swift in Sources */, 24016D9023F913C1006A6791 /* LWAnalytics.swift in Sources */, CE124CFC1E68932C00DFA146 /* FeeManager.swift in Sources */, @@ -4097,6 +4166,7 @@ CEBF32EE1DDBC30000348FC6 /* ShadowButton.swift in Sources */, CEB909F71E5FE654001804DC /* EnterPhraseCollectionViewController.swift in Sources */, CEF3D2DD1E8CBA790070178E /* LAContext+Extensions.swift in Sources */, + C3D4379F2566EA3E00F423E1 /* LWActivityIndicator.swift in Sources */, CECCE5AE1E04AD6300D99448 /* AddressCell.swift in Sources */, CE6BCF5D1EE9E89A0029849C /* CustomTitleView.swift in Sources */, CE83DE2A1E9EB7F600D07636 /* SendAmountCell.swift in Sources */, @@ -4154,6 +4224,7 @@ CE6D0F991DE8B75900BD4BCF /* DismissModalAnimator.swift in Sources */, CE4C1CC61ED65D830063E184 /* DrawableCircle.swift in Sources */, CE8CD8E31E31978100785E02 /* LoginBackgroundTriangle.swift in Sources */, + C35ABD332574073F002BB9BB /* PartnersViewModel.swift in Sources */, CEEC708C1E95461A00EF788E /* AboutViewController.swift in Sources */, CEF61B141ED0D10000C7EA6A /* Types.swift in Sources */, CEEC708A1E945E3B00EF788E /* UnEditableTextView.swift in Sources */, @@ -4187,6 +4258,7 @@ CEEC70861E94397D00EF788E /* UserDefaults+Additions.swift in Sources */, 22A9A9501DF61945000F0016 /* BRHTTPServer.swift in Sources */, 22A9A9531DF61945000F0016 /* BRLinkPlugin.swift in Sources */, + C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */, CE3D4C571EF5D5740016B1C8 /* ReachabilityMonitor.swift in Sources */, 22A9A9571DF61945000F0016 /* BRWebSocket.swift in Sources */, CE4DFB2E1E9C26DA0014009E /* ShareDataViewController.swift in Sources */, @@ -4625,7 +4697,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.8.3; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4938,7 +5010,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.8.3; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4964,7 +5036,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.8.3; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5069,7 +5141,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.8.3; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5097,7 +5169,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.8.3; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/loafwallet/Assets.xcassets/Partners/Contents.json b/loafwallet/Assets.xcassets/Partners/Contents.json index da4a164c9..73c00596a 100644 --- a/loafwallet/Assets.xcassets/Partners/Contents.json +++ b/loafwallet/Assets.xcassets/Partners/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/Contents.json b/loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/Contents.json new file mode 100644 index 000000000..abe66c16b --- /dev/null +++ b/loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "ud-Logo-Full-Light@1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ud-Logo-Full-Light@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ud-Logo-Full-Light@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/ud-Logo-Full-Light@1x.png b/loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/ud-Logo-Full-Light@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..222a66f75cc5af8449e4622404acd380262d3c11 GIT binary patch literal 7014 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 MsngmIG#z9A2WCJ7m;e9( literal 0 HcmV?d00001 diff --git a/loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/ud-Logo-Full-Light@2x.png b/loafwallet/Assets.xcassets/Partners/ud-color-logo.imageset/ud-Logo-Full-Light@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..703d1468be140702c2fde5bf3a1e329c11629c87 GIT binary patch literal 13516 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 a<^6N4=u*6%=m2;zWjp{bkm4^45C8-KfDC{e z3QP%L4P^Yg{1kZm-!xd5MqvQv8$gaZJb@yAm8mf0h-fDOHs*YT&A=Qt9}UcL^ZT!} zo|B&)%*D#v&67=3Kw3Z;01y!p5t0!WmJyL=6PCOwNQq(i&jE!P1d?O2)zYxYMPMB5j z!YreLq=b~5;Q!h3e=cCm4f&($59%AS%iMEw zardsEmPv!?&C0SW}Q zM4cF`qXf`YQ8x4g?wI4YP<{LL#^2jeg@=IPh4^t8Lo7o=HT(b(^#$6=q7^UB5YM0` z2C05r#VE{MSQv{FQ1GF;i{N|yyO@E17Ln_{&ibqLXM=OHK_{{o3O>H;IbNfe_Lx(^ z-jEklEL}`!s8u-Q6st_bQZikZ0j0GPQ4CO+4crB%BLmsdIa=E1`NW1Ih~nvfmXD3q zpv^}2Nj&8$1*+~zlY#yq#_NI;z?F{r8>m3%#QRM_UuWF!-}740)VOMvvf$Biq5YFM zCIy(#*VFGqTqFK8b;@cpk+^s0kYPc2B&1}6{YUm& z9Qyupu^>DfENyYf&2O-W3^+(x@}xep4S;A{_%U$ zSRe(9dCi;fyYy0n=N|yuQ?MaGW!RnicV*?ta~Yik2mgc-edFD)>^tT# z(*seG{_7`BNssnp{}!(G-;gs_;f}2dp^&A0i-#*e{N6g$^LguN1%Gl+r7FU#!oQ?U zb_>J{Shkfda!Fv>`KA+6=5&p7$T-qF{N;{)0ppW{l*ppDblo?rc0(V^MW+XRiM>Vt z)C>85cvjcHV1Ly3=VxW3j_3-)Y>U zi6YKzVxAlva#BC%{F^o=w2;P!p39oIRRn0o7!dbAnWHSThfpWXVNieta-PO!r_ zufL^;hzC*w>;oT_9|zxSab1)mE|u_4xK;A2@+6JJQY-kraM8}cCij=Vo$_F27(Ae< z<3cY!u!WwEPEf~a#mLoC<;k+Ht(`{A>aBaYS_LoumS7oF2}g;ScyZ@0b~v4rY2>H3MaT)9T&B$l_gSxVh!tFYhdd zQMH2*t~Zzkk2A-}n2$xgo9}PAy-mgp?w5m*(66T75sU!kNw|x=`FY42K)_DA~Gb$Nc;UNbXUfE z2|PSpP8(3ZKw`2-k$zD# z{;*;@)KZ(cSIkju1=k9mv)`~QKdHCUmH2}NAqOQ%$(no&@+EKH9y9S2@_x3%IAqs(c+1B~d)-&sPtS zz%{}(0-yTIzsRlkiUiDFk)oe4TC{KB!Y!xqUO45^ze%7|Jeg%@ea`o`4hM|2Rac;B zah5AUb#Ouda>W<2aLt%OsKOKf;b9+f4Pw#P<&>dvF?w5ZF?aZkeX(`&Ty4AWS7Z zG^R-N6)zOJnMhdm0&;mUUY<+Z!+NWkqTLf))FZPo$JC`QbVKiO8SY z29~$yjF%2`k!@}`xn5P*+XOO=^AGp!@4$;{t?+D`=f}qT$J!>xAeKSIfl_49S!2l*z!@_`q16oukc%U{)gEYVkxw;?%p8uL={C%57^R znqYMFm!7xWXS%PVd111|IGajn8A#DwMR>y=cmaC^yW{@V($n$ncDH>Q{0z_q{wB_3 zVbx+0aD-zHdlFO}Iur5gl4j$j_e|HhY{ z??nsT!{YPnOXq@Mj9QmUO%^%m(TLJy><9dy4JChH%J2y9^n1;M00#h*YU0DD!s?aK z*DElwg1QV_Z5#odw0Isci!MYgXMCE!M4|{*BADZ4A1+tnGOoukLORRldbNNg%_jHH zpeMxT>dP(9adgfQmK`Cfg4!4K92RncZ$?%6l!dt?u^E9gU~@$1o~oMrA=t-qRUTo$ z5v5t}nD-_mDjRQbzU#hA$+0@S<<720JY{+yg@eTHd+!bj4>IP7BEi-{Nvg)1r9HaS zadnWB+Rg2qDXaF){q6wM4+3K%Lw1nG!0#IDWq*tjbfi#U^zYo{ReII&tl=AvyIXT3Q5LFl9bIBXv168kY7>mRdpe3ActTVDFg1;YU4 z^3qB2Nsz61hU^?*J7X!)oo1Ju?ftn}$NjlzPBln(Ethk_XWDND(J7lBZf>}bvoVIP zs~f>4=5214aON1TbzALhEbfUNAH%7_Pc@2z(bC(+{AZ*3)$$8-z^X&OLM6e zZGfB6@cWNZ2)7q(r;kux#u~wA=1Z3{wGj29PN$sq@~oA7to)}W#WEb=E+u?$14&L& zmR5L96x+nh3-esC2uF;S!>ODgR-0AR9P^0rTf^`pm0JQMe(HX5QnHjKLRO@rZ8CIM zg;`~IpBJruFZ+A82{8{$EfdvPUKA-{wD+Y4Sc*42g6mtwVygu}RUvC%xeZLd$q&kF zHu-%?<-;T$OyGyHb7BB3Ecux#5(`OZQ0bUf{|a*7s4SO$VS%waS~}}o{$dzQ0i3Z} zLFA3wL8kEjSRYj^l*7Gk<5n}u{rKxZSMu>8C_UR@-V9&j#h>ft18=9EArZ^)11k4#g}#bh z9|D#x6%b&TSx-Uf+_{a5#|t%%Ue(s|B`4xcIE+0o-n`dB4d7W5Z0ux7=+Jbshf=jq z#vCz_?pzRPYIWC}u}XmKo9Y{n5x@)l5K?X4e%d5|dGsB`I`V5&EPGp#)j)uIohp4a zb9GX$4K->5(F)&53G!pA1HZuzBcS}n9WKLTea#3vXB;!IwKU7lxKMOP(!~J@QYhiWa6yVqA@xq}HA^8WGNCVU0fd=sVsSx+uUwxGx}ENC)CHZvzP1=B1$MR%@d_ zALz~#4Wf2C&ApO$=R!N=-+}U;cd|JG5q5WaGbOekhH!80fa4F#@@T|aI==vdNBsmu zlBu;*i=BIvax^+Cu?_ZMd5+l>}jGpLdmVO8P^rrb?h7N->BJQzOYwQUQZo z8{n8teIyAsFZXq%PD>Q=EFhhBSLiel?CtXEQ8*;Hp zb8|;zax+RJdT!s%PDcfNiVP8my&s1h8Td$>57Hjeu~%-m_!*3H?Uc|JnbeJI8YX&2 z0LM#ugZb)z?JSJh&Nk3*Z&{KZk_h(w}4p!R0~P~t=& z^=YE&+D8M~LD(YIxe@l!zBiFDu!S9I2b|MkNLL;G6NHGL-@8>PpL^=2@lqb>`s^#f#bR|>n@oN3 zS+{*8t6U;>hh2UPqQ0#*_Z3RMXH1yAOK@q&B}V}{z)5x4WfXEMDtUIM`ija5+Qx2C z@0Jtw@Rs(rr+xDL3>U^^J`+L^UV#9mdzlDTo>5%)k@0UfGiZK`JSR|)XQNsM=d^n| z{nBP*!kn$mYG>4-bOV#4CTr6fZ{20z3Hf?JHixK-Wcut;`}(@o!AQg$SKhK`wV)Fc zl0)1echcT_$02(J=qI4@!ChjF7Lkk~i({*dB6j%s^pRA9mFY{GmH5T_(nH^jK&!)@ z_s5s-^ev)w?Zp$bHpDO5_h}ON$^h?Xipmos`{1;Nl?~?Qq2SDheGY0niq5yWs%m2? zGAUX;S_{HLT7q>TlAdfgl<&Nql zw6q6;HkK6>-Pd8Nghm6u3R0W7tHSXcW2pqr8>xF}f#yLnOEAJVn~;+-*0h;i_nQ2$ z&kvAoa%0tD7LD_A(Ycln3c$y?jGnC0U%SG#)yvNJa~Gs;p3`5fUMnW9n2)DjU`z%Z z_(B*#=$d91fE{Ae#e7O~03d&92UU4RU>VDSHLn!m^66b3nW?R^U zv_buJsPM3K*y%$5%CNjv0KV4y{reS>zr`X}1GXP+29OD0xN_D?``eE9voH-m2 zA9d9{1Rliwu%dI0HpXjMLA~D%DAfF88~^POWA+@SPc@OhqG==`5Y|l0y3WKKZ)8Rv z_yqYa%{VhIeYsuCHL^GN1Fx{vkj<{HEg^_0Rx-IjPl6|{p(MAh+xmb)VuY`*XsC{I zaC>kZpfir4Ge))%5mm*M;=&pd&pioE+aOFkD<4-ll~TLas{N!0$7tzD+|@WfOu*>< z)U{;W?4Rk?G}c80fn?N6rv%8wY*xjqB&*2LT2Oq1(JtHysj09c`%YU)E-?qV>=q~r zrDThlvv+J^KdKk5DN98yl7xhSwG+EF#}-G062;!T#pTEJhNgsiY7JDGQltX2Qw+x> zZ0cF%XFgCF?ld*^cAXBuDKEGZN6kXfAU)63H$`HmY5 zLWkA!k)^x8-I0cRK`qP@qUK1{rx}4?r->{;C6P>8t<7uu?dvnYpS7ltE#xtWktzzb zMjKG+7O^MUTw;@jjdY^-vkF+hj)w@eueep@1cvA46v)=(7__&Np9T`3J=%{y249F{ zg)pGbW_=)%AA*v^cbkk&weqX2WW`~MYmq%p{N?wN5<5vWa|HLIw1<1f~;3Sh!N^Nm@;f>J}p&_E2=ntH|L{SDUDF1;mwKOAN=bY)Gi zt!M!Xox~q~=;ZELS8ldvsh!faPU1imJo(lEG}kQela^_Mz161qIvz-@`qKR zy}Unkd7JfXaS&DQ30pR~*G1+03vEK8jmo^!kM*qC0>Q1H+?_=4S|H;SNVAOzXUmVy zlyB!4Y4YHlXZF1Txl4DdAy`8nhrWx{4V;$ysm5_+$+OS*{pfwSL{!6Yk7By$v|N}- zS5>*0M`n+|0$-;E%W9G4B5zSae>)bXGgJgo|tLlm!gZ{dKUMKmy7)K0TirE2w4yZV?@E)WH1KT}v9ef%SyRDJ!%G&*mZ zE#DI?oe((b*|_6yM;+_&*<}4AS?s9bILd>`Qex2lfLFXzatFuObLd01_ltMTN)0NM z4fmqxrggzu?@Itkx0tCN#?qxpNael?*VRWRZtHv+`YO%$Qv{*68CfN&XQBqkKYa^T zt|OuNbk4MM^_iHcKo*f5U5^z^jP78lVMB?@Qr3tiO>ndnicp)93N)1-sR@ivv-s82 zy!iEI&8jga@>%K$mvO|y@rXq&&rL~X%@yA*t1d+>p@ba(@(5cyA{Jc$0n;?~cCJ4~ z)F?u9_FIeTAz=TeTTAkBS)y&d6xQGOJVgv&%6fi8hJj zu``Bd5?@xoGiK~7Y=P1rS*7{B9wG?~8%AWgDDrkwc3(}QQgJr5K^solzy^})!$6e7 zabZ>VEh<-y{ta=m-VvVIVq?0)s(mS_S#>UTovOLqBga-5Uxy|DLgsp2A@kd5-gl!t z&&ie?-t?HzCl1gw9AJ)x9f#AMobU5J9Y}~#oPDs^8S4TusP)`K>v*v$rimVfH!XuW zgeSNg%Efggd$kpfon5X>ysk#CA9alj%b03zl&F-MF?>5cQRC)csl z0uQ#dFuuOi(9lx;7*x!f0*#M!iaFZ8e-1aVa`B$q3*C94Z}y1kP^BjnuY}HzAvrsM zp*r`bkC8f0w0A!d+461welkOo^{gvOHnf<)_w@8a%3I;2AU*XyA;Y>SHl+0ymPFCI z<|v>_Z~Y^ETn$?{&3T^v8Fkp_%!Gu`x_mQdxgyCddb@7cZ1V#|w(kMRAji(1zhoum zR{VyU)|O?A@#&Dzir!?!SUNTkD{#+P&jSo=GDYsIRVqF~?n}Z%u^h%Hb+vc9(-bdk zom&`v)V**)R(avl&7q;mS+7jTOtaT?&3c0*tF)EsjFl{LVAekz;)~5w?N_~I+!@A5 zk&LL{dwl)%cs^J{SkMArc0?$ysTHt`9$uq06PH@SR+Wnrd-3J|U0e9Aib<`YFH>Kg zp2`JSrFi}2AN~dGr9(w|wIo0I>}40P^ShnaNAl}f;P#lz7>Q)#;t0(0a9`wphH|xHEr6u_&;)2Ago`FY+)Gbk zcbcSdyheq<7bkmI+nsR;!+f*r>RF9b)8R08iS)=>2OeS{(ZL2OBo}^is39$YQ_atu zVM9=^ptfvZtoN`f61g|j%&_TiZmQs0anSN9gjfFX(h&C}ogbA^w2AR9kP#wU1bC2{ zPAPEKNL1w%9o(ty_hVE|3Tt$^+h_HAiO$S6Kv>i4N4|tF z_XeI)EoRn^&v#hlgcI{wxKucOK;vLiE#=4S-ET=p{xTRbeQ};6TyehQFUmKe;4Y#(o56y}7j zDOgBKpVJtoMTXz5)H*bH445Q!LRt+FCeW_1d?60|^f=+Tkz4Up+`GKzs!X>)XbekG z+rHxS(RXGahni4t?9w1nVtM_&vC+HQuU9r-a}BT<2JiVeUz=VYrYok{0F5H)QRaiPtAhpx~g6k}Mba zY_{p{L{Di#*+@CSsYArO$&zqcg1?1dwd5wNy_@ub%)zkPEpEVr|D4!Mr6|omzGlxw zD;VPZCFHHxdLcw207ZE6~ zhebr2N$T;@SXPOFQQvmj+Q+4>q*LFVKLac6hD3B6I8I}E zHWANamS(8B^aZdX@#i4XK^~J`o8?ibiyDnPSWB=jTqpe7t5U9^iY$XsFE7C!z4Vam z@l`gL0SP*gMDLyVhdBw0JL8vZCtcV!f(^e!-IGg{KceLCC*x8Bcx31r^)P{-UX{(t zO7?xl3a^0Dy`hC&tFO-+AKr6g4#<-om z@bwrX25m?{r*8|M(ky(frbg>`98L0X*0rX>dZ(bUr?TqB$asU?`ijR-PYGx|p0_rP8(PJ;sN>&V*1C5)Y*rz`5E9))OJb zJ2`|x`x|a4dECN6V+v6clPdJ!qv$UKFIT+M{1#+1hd%+~b-@--fr$4m1nBZQDmYRQmqPJc6mw_DAZ_;(`ZF zyo&tqJi^!=cQiu9FL9cd&c>Q5Ou*rdv`uoSTuTV9A2Uk&sSH|yO%onEd3if}w}I`^ ztx;Uo9SVGPt81&uU|h(T8cZDXq|;Q2kv^>9!5xyJE}5xDdt=>=rSS?=9Zd&3Z2D#t zj7?p=9{e5WIbd-8%d5pkM7m35;An~@<+UVG(~k(P-eJ@JHdV{VkFSA?omEaSXc5dp zXrU7O7`_1)1jL4be=EHXJZ#oI!fmRx!f!diKG$KC>O<(?w}#|n5pro@c8Ps7AZ7K; zPv2%!Rc7l}H(U*6oJ+ah4n>68DVW{$c-VYA^6X*yGY3($Q)aBfw@{IG2a$Ukuk7Ic z>#Gu6jG8+&BZmX`T;Ancd?>wfYV+O1&lHZH9M~u~#PK{E^$#n$)H?Cp&0Ag8Ez#09DOy)JJLs4{`QkB1}?4-F*E>pG2?Wnl-Zu#?*hZTrgc@+hStYN?4Z} z&izTOX;+rGgMn`jf95#Aw9tyQi&IX**lR<%=IbmU`CQqOCV{-C z9Dlj(|I>fWOH8@|`O6R7iqx8yB%0UeJ7ya{oxaSKQP&p#J2mHD+>kL~L~^(209XBn z54|br3NP7>wDjiH^m=Ev1GFiBk##=Y`)(g`mV6P{1Q z)z=E3+B?9As@jEc}S|1YK=5jlbp8%txa zSo2ggb^fdA8>T29)cPt&qIcVch z@6g`CHB!2X>Cs~rGnM_;oo2J%%mm|e2X2dQ zdLEEGDrgPw2@2&3EK;!A;us}BmW z?_ne<^Y=Rz*S*<>7B_j(y^G1QXvs-OYrVVa{g+BmLMSB^P$e?Pc$?}tbEDJ^P70sf z%cv9$tpvoB|{wMHre1LI{{ac<&UZ7dh5R)Y|rKo zU0s;dqB`l%7_nMQ+vJIZK9U5@TF0sGSB74O&I4!yf+Kt;xs3qEVyh9K1LSn&0onk+ zt5-3hS++_i0Nd@V=88ie_u%v65jg#q`2x&Ngf!8|JaOcHmr@RqdumE79%Yy!Ko`pr zixhZ{rR|vV>e09mr7q-=woyIs0&=a#&zoEQ>=x=doO5OaI0(|jJNKkUsN8a$CL(6B z9&=0;K9Kc`Q09|w2&w{ z8VOIi_`>*MNXc!OEBqmii%D`Y-jOBZ3jmj{kVXK93FMx(?8p|oD3bL$CiL{iVk&O5 zns$A25=a&7-pa!4m+G?@X1_SR+LAc;VN(@;$prc`cEp321*mgKhp`kBMS2OS{^lo} za%4#-@G$8jf_kyJF5QNxe_nZYZ)~i@L)@r<8M3Fn>=LQ<@HDr~XK8OY7#d0BeKZxb z{|I`HZEcS4^6A|Pg`=s?i%^xDj5xfVHO6j=yp0^65n#}B**k3eiu9aU+JzWt#1Xmw zywXK%DN*%vQnq^mDt?%gYux>=R-_Ax?wym0%GrP9;hIesgnwqCxZ-y> z_IAtOY)arJuDM5K8y5=1J263JkaezaLedFxh*e%Y{w7Y>!p%@ZFN90k&_^B@-u{U4 z5tgRSdoEDdy%_zjL2BIc(5|+w-9mx-J&i4!jI=~C^E{o$JPDWoA{piN*296M4hm4R z5Jmwgo?ObRPAGmW_abqd8vGI0b&cd1Y|@mU?hF~5paS_2p|M8ASJS661?{`-6nsI= ze0Abyq%9}#pm;4mk~W5z1G5pXGmSwKReiw6IODp{@ug#Y@plWy9G)od#UhOPN;QqU zl0dKC>edTCbcJNhN3XOsss{d`c-nliKD_AN)AT}*jEyrWeDOwRJUR!?-tI_Fi zrt6~u(Q?d`0#oj04C;3jMd360E;9gC#x=tj*;K?%?bXkx^( zi=%ozgh_4!@OXbisd3r3=$cK#AmB#THZyEou4n!7k*ganTpi!=eH0WLFbySeyvT!`Q~K)EIp4wq*#`;9+Ql-$AE^9 zQCq_O1f|_Fz_6}3BRyL$p)^+$EXlZGTm%oTpb?KTN0VC?5ldXy#F&H%={)s9J^azh-OeUgDSVuu$^y|(3|`d;?d z(Ei$XTb3!qL@l~`9l%7*RR?wj7=d6Bnj>`xN{JpCiTKRVTsky$XAtL=PPYR|<5q_Q z>a=Y_^)H>CMyL&J3==y1xt}G~Ln?7Qa>T=A7dwu1B72?U3&@jrM%}P?POu+)r zjKws%l!k@%9(&0r=65!94ELyXQAViJE4|=mX0kg#HmLSAUg*`8Zs_4`y)PI={^s63S01i< zvw%8;B4vG#;T-b4L9>%bwhmIDRnGw;%x~wqtbUQzP0cGmZFjwFPhGEooj`c!=_4al zEXoh6X7{a-p>Ch{nUNLe-qfinPOd?7vvqHAvCk72sWTWMChbt&v&IkESl=mNU427J z_}sv%Lk`Zl<#GIFx^QCRn~B+S=|zMdQ3EQn-(%&=69Rn4o5p&#%p6osEFOe# zUA5&keUxp+%Zr5_Joy5n0$|vSW%~HjHI??+g4}tss$^zh>XXGbtmDgxj*VMY^iEcf z2i}s)9)tZ>^2@ftpoK1m^z9c>KA#-7wUOAF^0#3k@mNse&eoyGD|rMTN*|%3O-M|+ z==9y3pj{q-j@p!p*dWMumQUKMlEN}%w9cQQ*RTXaeGOu^rJe;22H-ue5_b^TaFzU0 zA27-_RZHI(!>1tQTJ~X34fyht4dV~xGV_hYv0q;N&23uvvaa=-T#YqLaTE$Jl3x7) z^>iIOCpwt(Q!2e{Ph>XVXJg{uZNx}>s`Xolvi|)xoZo!kZaHW`0@`5*cwtRFN=0H?2EK}noAln|=b?rjvx+3c2G~A^r zNG(uqtPd^Zv`rqwJC&O%76_{?m7K<)LYhf6th(l(j-hMd=T>#U+;PA)VNxQi3r4^ zMS8`{Ml#JK8c9pQ>0LttclWbp1@`qf?%5Zm-@OHRQ&mFTJh!pj@P@ zd{QnKr0{F4r)4yF;b2cO!W{3+Ns?bCnw@N6kD^u^uM8+aE(d4;XW$RvY@SoWNpHnC ztATVhyOezBG<1MMV~0(yQoW3`4N=V&S(}~jem(#7i%?2D>%J8%Uifu8HFl&a&pH)s zqW7mAYLUj=6kkG%8u_ftA@Ml#zHz^5nUBkbo8Ev)#B64tg?_tYI{syC*aM2@%m!v> zr2Exo$Ve)VlJjnO(qjSOvO)fnG_CP7W=;r{)cfW1?w1zg> z`97yYdf;m`hq(kRj2skEDfRY*R04Kzgy(@hoC8v)%*W*h_8~9LT>&;dL*wRc9q019 z{DpFivl+0gzF5e>qj!UgbLNOF@?&CMr14Sj`YA&(AO1!FpdQ2&!9WTlz}Q_K(U*R8 z3HsN`7NW1N>-1aK6_hJz$(glArEQNK1wASV0_tx=x{Mm+%kz};3E(v>Ip~$&a}(U^ zdk4j6ud7ziJw?8H(TE_4tHxCBvNgQ)0vE{L$PSbAuY{6mXG7zLl=z-^C3QM_IjVXn z+RaU^1ImWCtb31(ee4}&Q=Dh@eXfqBzIJoS@%mFGjwTKGlegvQuYOuc2hw0|fhdIa zQi!dyyU0X-;k=Kjc*Eq9HRMQr) zuMS8*|7vD(*er#Dr0`Kd5dCFz_2^MXCJmcimM)Bz5dIwHJcwr$JwLA$pcSBK@1Xp{ z7GB-M!-rjh72P}iZiWKnWW|<@#TL@9%TA8*C!*8qCLraQ_i0!pyS7r(8q^YxWJF79 zx*qb7Tu`IF+dcOUY<~6T_%SueObyD*j{}xSnqTuDF4+ky84TXm^Ktu;i(z$b$9UV= z_^CrO#;aWS>!8ldiR@Y-)N)DZwdL6(*RP-DGqWL!x`kgnIp;4d=Am@w(9P?iF-XGC zRXg2$bp4v-_nrJc`nR_uPnfm|GXnEEW1=I6p8*`$VQn9*y4YE**?hp(f&k3+n(7$Y zX;<6m@H;q~E^G5T^fNl5!!PBx+(`&wl7qHpt=stScD0SULYBS(Ba!z#N$Gi4-a`T+ zn7Y7YJ~ZWVZ!issbjMjjq&ZKDWYx+m1KBv3!zV9l1SKC~MjI%2P5Sl%xQY~F?Ipqr z2S;U#VVNsx1-eGO(WDqc>JXB5R@pqf_C>T-A#K^oiqUVvYvHDVlocv9Z3hH?2qQ)l zM2WhL0I3*fO#F|M*RTruZn?;o;lnFq#RjLrmtPo~O);;e2uo;BAWX%+W!Yjsm9+q; zeTG#CEeZ1BT{P8dj$QsPd6RJMW<~2`?Zpxp3^=8J(?)`of&BfYJw;d)XnVk_4n$-U zq|h@hxOuYbX)1(ubiPg{IA(>9MoN~@zO!BDOn39BnKeqQ6&I@tAZ@w`t{|Kvh%gcA zG&hl^2sjb=P>^e#|AH>27;w9OwUjQM*twU&sJdj(we$IT;+wC5d#*;p0;OSnhyT7CoIUITPh@M|O1MYM1@GP%0=p;whVk}@`66vsv#Zy2J%FkdZ)!T7TA-N1r4bubH)w`oDkyMa#J_36z zMaiRj+9Nly8e#p7tfvn%?Vq9^UbAm{Ukl)?wHAFX zx-*Dao9t3U_I5QX#DkgmG7i|L3O0OrM<)hGin4>go>V)#4oyCcbwL>|r0fsM9j)|` z*{Pn+Frz%VFfNa$V2(S0hSkzFuMJ*>*~QfMlGci^pK7*hvK^k63%m3`U@h9);v^3t zDcbMc4MOJHZFCR4;Jntpny$;VBd9Uo_qM z-Xor~wobL4Z;UBt@go=FuY0vi;{cA?n!z%muQbKF(D59zvSWLPK7WhFc02Bqt~@CD zW38|`Mx~1lN3qzTkYz$sMo6!RE?^dFnyG!&{(4JVmrAy0#;BI)f=1r7r_fjMb(McX z*Rf}|zpL!qo4aYW$;`}Ar`to;yZcOS0}8(|&sMx+F8rrV>%HbE*qRV?)Mng?wqZ(3 z;>b2g#b0g(wFMIMWE3Kx1Gq<_h}inzUumi^DG~1-*p9IBCmsf02)!tUD@2!)oaavb zS`lH$Rn_u%!cxgP;m6B5NbkdWq`BCDNq6BBI6q4!eT;)hGBdnpOpKr9(qb}ct;d!p zg$CHf2CYe4lgLi-mO`tOLP*8~oea+5+JR&JeJjcP8Ds>&5WnI8QKQJs^eE zG<8oh;?PocS_!MQ(VJ*0{r#)@v1~$kZK!#uAmHJW2peX-pM&q-0cgL$i0cv8bSYL^5#~omQKl!_kdi*?x!V8xfD#ou02U+V_#dM{?b>>*b*_XHN^)`aL zhD^90{=f#kk>#?^e@|c4`0_I1C7V|8%Ol-qTREKpC!R)1%OTsTcJr#7#*~l-OO!;p zdhmqteM!`d*|y@^we>PViII1#6Yh6|F0me{GvK>8YOx-v=BbfPyog9v8jIeLvYfu7~{i>Q(pE2K4YvWUh9X(l^mD1xHes zHwWPoZTCDw9?MQOK7S(U`?QSir`bsw&FBZgTE&D};U{e@J&OXJha3VQSm)3$w){x_ zo;`D`adx@vD)&-!YEvoIrSm=XO$hp8ROzN=Zf;p$`;33oBif(PKiti5YRVS5EUaB( zSIa;NVp?Jbnt}Lirq^YwR{EYxXTo#8!V?C0UL$+CWj_Go4_7E;)+D^7fq9>7Oy}kZ zXCDuWlO41^M7c>J=;;}yDb>8R=(67AUkm|0#?<-2CIq$z@e#sKq?1Al0+qAW8AM#d zn_Y!Jwzq9Vr{(1_Hs(D%tj0Krg(rh4RjU&WiXGg5R<-}GtZ%9F7o zXnSlT)3&kv<+e73!Ll=WS&FOy7jLD0r_?m3n873;3C#0#?sV|`0`g<>1ENj+zA2}7 zN9d4W$ZcaTx1aPv0)PvFv-X**`s4=7sp>e<^)*-5vLCjr*i-ZHfOHI_W^2 znjD0`ZKH1++kf_KMEvV>sibCsHvm>Wh}?w7!B{(S(o*~RERHw#p%lIQe6Qd3GR(lm z?nNk#%HZmrP3Jqs$g3p)JzB{P7-&7 zFVgm?s&Ic^I!%6;GgwKdK?!O>KT5r?d)8j*De>UYVQFg4&ECy7>4*G$Z->T}S7@zo z%c0lauPkD)_s}Pg9EumOG`UhjW`A9rv`Y++3OZaL<4XO0Q{ygnV#BJem$Zer6Z<3o zK_eE_L99-#7)*Gqm@tY-1b$U6ga}ZE+4EjfJ#x=Ak;YC|zr3^y9hbBt%8m3pJ;%7h zG20qzpxyy#K;wfuY8R|eA8$b@>>cU_o?F2>Kl}kfY_cn>f%|u;^BhXZq7{;D~y= z;r--D*p3xMT|!fAuME$$BKqFfU>B_H@(vO%)hlBXxe%$MEucQ{J|wPp7)a=>K&RtAeId_Ou|1$6K6(*{ z@(gR>T1*&SCd>GoGU(^}hiNLIvty@_(ZwwRKwN0m+GFD+qwdX-1fFGK!HUO)QQ8Q=V1W5}y5Ppbc?igS-=djI42cbkSxq-4sSIB0Ik z6qaj}OP$E2)R{}9)54_Y);77+FCmos8ki5~6#>S8uSKsD#f2I$QcB$c4YAw$h@dWt)K8%XSW1N?}{48w3E!$Bgq~>XG0z7JN9X zEKIy_MH7l?5SB}il&{ab_Px! z4PH?T(If34A;|lDURk&>Psf9RT?eTsTh)(k+V+w(=%%6_M4J*6cw6LXV8{WHU} z2X+Ak%3mPkVDIjaJ3}TU8S;$ZRU~Vqt&%Vu?zri*^FBa2>|8deLmaTTDjhlU1l(BU zNZ>$3n_&@*Z`(5?>=1c}Ck)5>N&g+UoQKP9si?Q^Fp+?wkZYQx4pRkO!OVbE5N^92 zpudn-EFY2|7&6Hk@Y$SCEN(33JWT^7uVDa#HkCDCbht;h>cEv2kmppiSO}Du1&xMn zHH&T+5|u7t{Ro}p%a*HPHj*w9Ek!!c+s$xlj{@$>#;WtTT7paPE`Jc2n<%xq_QJ&2 zi9*sixg#wOPL{iL_52KV-#ulPkx$yc8oWSmFU}(>2ZLQA@{Wq9h?maQi!!ai-Z?4` zaUi)AKdjX0r9v^@Wnqcl9p?WMKnE-1YL{(r3mYZw7MZ`Ipv|s~ zTMy{!C4Vr>PqxiKa*zA^6Y|p6;kj|D|j0wB8JT^leU+edA!& zS_mK*@-NZ}0I+>DDX;ohlP^%ol(?n)H`7w($$qHT8}x?XPG$|>$2ZvtEx;>b@HpbCW4Y}K}rm_=Mil`HLP*~1@$i(0xuK@{I7mY)M>oHW|yVO|}e zt5Ku;C78DU4wiZlTRPQhg=2GH${IhAg*kcPD z=Nw#ridX{X76T&RA_opg(VLd_s|$X}&=rzotD&)|@AEriY?W+a{#Diz82M3q9c*cS>tYZYku9b%3yfMX|Y<*u;_J-Ji_ zbH-WpbAx{6vQwi={_4J?WBtuC0~+s63EgK1U8E@iDD5>@>Qgi+W=ih{$@R}(0qlP) zQkq?2(7rRdr0@2Qk82il&twSYoS2}^Nr#+DQq^qQrSui+H*+s%HFp`PYL5?1O(FIFrf?+|!3v z9AkcBWY`n|(Frc#%EdLivsMQ;?#7@K_-X~?evLAD6oxN=MG>a1x+A~S$# zvB>RNknMA=-j}kxu@|{IHg6h^bix%+PPvJcs0gh}1$tUwNdpunGV4_@lnznb*W5pv zNq3UbyCI6vId2{%6t{{y@YTaBqa5+2lX2Zz4fm>zpB?*Y2BS{F40k)u{Lh*t;j#4K zKv+Izv7sqGm!Vm?EMG9QEF#0#%G;4oIhn<{xs(26i@*7IvvAw;YOpqKXk4JzySqNG zLllsnBj^~|cgncD*vihQIJZFE4eGIKL)nk)=o*`-)jNN8X~dY_!j*XyBd%!5&5A1P+!^*u+T ze-us*G{@^qAd=XvFPvD(!6}M!CI@_h3bI$*qbI-l^`JK6wWMXullU;}%002&XJsnd3 z05M1a!OFsTJIp5vGCF2A6dDBpwP_sNP7ubp17oG{ibey{44M^yf(`*-1_jzff`ouQ zjXfJzK*E31?jYEoI!p|qBEWb9+>GW2Qrf5a7<6nR4q#^Vd)O>S+k5mFZEw8ao8W>m zo?cFPA3t$r`O^TPq@bjLP*g-HDT^y9?h$G#001U{{)vXb^p`~tKmh+m1BgA-`oh{p zjE>D$&)OdVIC%FO2*}PAV9fUz&fE%bg*HSu`*_Jax%gbc$On7*?x6tnU<8Bo!r-06 zgS|Yx{Sm<$68jnm2EE6IONj5Q;5{@Xtk5Rn+CF|5aaDO0c?Ahgc5!iWbw3wZgsINC zKjDm#h6EOm_eH?rK|w+CLCW$zer|BZ)2C0v6_nsgN^%ShIsXuEyi>58xBsy}jQnLs z2jlPThx5hbe7wc?>^fcX3BYSeNbEWK`}reI7w5nI_y+iS?t5`@hGRT2UKnq@KU`5> z5&mB|#%%uvdi(#G4Mtwz!A`ymkivh0Fu}NgruDy2dy@YbhR3=7Kd?Q?AF%x-{xLUo z7iWZjz!i6lGyW$oL$;q|Gt5=^Pi%Gge`>2U=7&K0xZqqvbe!-Q&Hva`>hOQ*{FB{% zw6-5+Z&RB4_;_mm?>+hl@@M%^(7j9`_VulFaEvwZXDp(olB$|I{68iCiM0L)se0;X z;7@{o1GRlTef-RPot!b6ihn|WV*RAOmve-+kC(3>#(zIJ1$FrU;r(0R$`s@8;~B8G zBQ;Md{R#M)`EP)+AC9sAob~~Xc=jFq%=@?gKlU$q_)BZZswoQu+Hy0sa)^+`t!I)U*)~l-9&fWtI%dAB=y|FgzeI)&fCs=81<(oQ53d{rvG1VWS((*W z6nT@GQ|j{0#Zh7?G0!(TXtwWFteBk!CL7+evN(S|*upJ&TRC-Y4=eWqyd&6C;rL5S zpW6+K^YomICgTim?u&)cLZ}6p`|}Hde4u@7s0a6uH+7q4q`+d+`QhuC-}a*EKdVv0 zJJ$>zJRF+UJJaLHhgfX~L62wd=zWZ%{h`66p^&N=!EVi=aY4-cndqiu!P^59oxvuP z@xHP;Nus}rVq-+RZDtp!&6&RQyXo8g^V3wJZ$f1|RsEns9q!5z(SGvR>=W9L3LLs* z$9NZ=WOF%ux(@onJ)tK%F7}&@=X3GlV=4Hn#<071%TBpD zW#H~ZCH|pqEw`SY#qsroIAoMet(0u+ zl?(IAH=F}AO2;{MACt<ND}FD7R=-F52VQ-EEX1=Or*CJxRv2QnY)D*R8*I2*VWfX$W+fN zgC?Ri6KFJbjF<|aZ^I*l#*z2S9Js=7x7~#o7i)zZC0sKXGDOh8 zcI7dh=`!>EwFQ!>eIc{yfTxnDnQ!!Nax49Kv&X%_VoG3xJno@?h{BaN~F%6ZoZtI$jow2Mv0JDpm_+=q{E&KB1Tff*eMx zCz*;Q%3Xj>dgOjw#8kw$KxDxl6-h)0Y3NR|ND6>Hdusf}rr#muGl91B{PWQ}w$uAm&z+?|MyySC)HS%j>_j z34LB1N}ibi9I!N)Qt6FW2T>xzgUX=jRWgbfbzUyQ#Y|;5cEr1EG~WHU-08cka)@20 zR1OMuX~B&6BX>2A(D6vU+)P@`TIF3;w@;IO$kav<>iV;ua=u6=C)1^2MJ|;juXgrx zb*~SNFE*dOevx=rxueIGuh}a8RpPqPD>H?Tk%}>8U1F_G)U;tpYVDG)y}3kl^+#Ln zDTiCvMUl=uig?n?H@E#Xe-Q>1p?IlB9tphxkHqKczqpcV`HSEaqyrPAQFdT70xd5* zwwC>!d7Di%zMLRJ&cz1x9b-RkAzDfh&pq+5KwT(RHB&m@qi3Pcr&s{SI-eOY5XmHb zm!+-s%MP^E-g@emQP!P`^zM7bFXGQ8nG?y8`mOd-fid4R{Paj{_oPcjKD~ne-oL}) zBFYx;PTU%J=YZmgm6ABsv1C=~7 z#t;iTieJHaatvb>c632}G@~{^v-)KlodVBj(3&#^X=ER)qn zu%nJsltn(n7Te^mCQG_Z(#?(P?S%yezP8rbbpBR%tDKt4J~!;=I0F#q046wx33HBm zIXBBeNVoAi_`X-?%hUsKPdLa_(LHPi~hvG(AHh}=idSaCO6LAUIDc`k9#apzkBrSi=%CdhM9N4Fkehkt9RCoz#g>i z!WQZC^)~x6SIAGh9qN@s^SGYE9*M~_$qd1Mf5?7ov^8O!J!69Ji_%(;wBCxjpPD&nrFGO=R)XSikZ&G96hd+gE;wQexDI)cN<5ojRwu8g6}3oxSr_ zakvXc0gq&qkc!qxN0RMVe$lSsC}$ceRY1V>8es-Wfn{d1T8`pJ4uqj5{0F{=@_B>d zA@-mK$B(ERxR%zJL`+0$I8UH^)N7IQEo&ReBqQ>C_n|d*pk$)rQ(C8H;+Naprn(X` zdJdpX6D9ssyL($7wY2rmbtdl0meS8~EZdqDML!gV5iYo+`cMeSJ@=RA@zl_BZr_!t z@xxxVZNNMdouFc3c^nt9FmPkR-G&k>Zga{h@xiYS&_!+X93O>qB>fiUX)2nI%^dvJ z*z289`{~2t@Qj*%tC2!eRQ~7}3j?*{I(Q0HPH56zvPs1{WpE@2XiLsfMUIno&hu7+Bh`2By1R`tKE{f<% z`l?z}=wYmq9AIc~Ew>(*OVazMolPe>vQEY?qVb zf$wqG=6oMf@UaO~hA;oHm1jgORO>`Z(Fit&lynE%oo%nRM0mV-#I{IaNw$45@n*0| z9#<`FuE3T$RO@lPd!T@G{DGcUC|kq_{pvu=<*dPJ_jqs$Vv8xb%HjInPASZ@tOO#-3O}B2}=F(h}_=9v5nX!c9mq<)d8=tbvs? z#L7GkPPtPaTd)OjI|9Lq2h?`U+JY zE3tCGIC_Ps7oxcwVEC5xIJqmhU%o7|L62Gz4lgUUHE;_NeXBjTnI~lo^joDtS2#A& ze$3d5TeOC{&uvg^)8jxHx5mk38g6v8`Ip*B&K4CnK%mR<^C{Ky6I-C{xhQb9 znasehhD4t_`=~<|xP#}&NpNV4#1HjTf?coq(IZW&6xI>$`CK@1hk_t>o#?l!J0qgS zBo-$^KKxcjfoJfz4`4E>=(xoNLIzB|GwA!A18`_rx zAFtKHM`3o0ju6mYT?`Uv$)y&=2g^_sO8G>D$mHiNvYe$T@O)b3Ik;pR4-EPS9$najcTGKaTS__R`6U`=$HE_i8Y5r5t?}u{v{)kU!7Tp|8Md zl<>q+69)4HX^0z8kyIoH75Sz&r$nqvuvZ(iY)E%Tn>k)zx?Q}LP1CriB%`%_cx3}cT`nEIn^qF}-O=y?cXN~)CV#|Z8g#B) z5v{OrbpEm=#?Ero_?A6vEr=8KA!A@BBluIyS^DHbY6MQId)-HTYm=uW8mdxo-Ir^f z9Y~8w-GRoO=w^K1L(>t0vI#uLyAL-fh@?%ZHRis6EDO}F<~wbi?}v*m%p(uDA}t&S zmx^!}gyF7Quf7snBdSp8GpEUM$Jxo1YggjyqjLO&eXu>mQ(I|$GfT+-g3o zYHFt!3+-8LZ2T4i5rddQ5@Dw`X7j8_;qV=4R%%@0?BV`mAyzXdq1*%6;TAn>IhTC4 zun$@eTfPadqu#<6jpnHc-Y_KxT3oIeJ>Di>!Yc-7J}q@l&bzd8Eq3|xrbboFD;dYI zu*}Bp`eH2b<96!jq@&c!(f~#CBWhx-#al2iC*H`}W*R&lv(Q6Ztfo}HEPRRA{5^K5 zK+;A3ab*2sJV1Si)8oJTG}dXgq?RD!ms= zWm_W`(YFl1(X_T8dlS9g zSaT$Djym0Y>7(=_e|K{1vUr8wOQOhT&@-dC$HG*!lQdSdn%kplo)gHH4NY8Tjgp~M z&DFvWUG=EZBF?JDhWJB(c5GMhpeb4to>OQNJ=JlkWu>Q$vNY+OzGmoE(;q;J5i(I= zE%Z?d9c_9K?uay}Usp`;TS51X3bxkGB*^8Fuvhswr~Pk`h%I-9#tWHlepphfPzjkD z(j;`Oxux%p8obPweIpnFql^g!(t|uPsoRIgD5tU|2NydHqi+-(x@WInB;D}sda?N( zau8y;^6>pP9>^=rJ65>$tG*zm0e7{3zEoSG?UktB;xT;fM!+@7&K>@`2)CG*n5|E}v-(3h=YT&J22Us>-10{HdF)qZX@ z@G|XAEO*1sKviZ2KY$+|jWc5&c|ZE4hDW87rPC88O&hGllA!&+G_mY7luXTC2?hz( z{b&rfPt1~DZ43|17A6Er<^jiTu30qP{Sy1eLf^hKm>r9<`L^tpx4JrzX|He1@xDvP zK^nlG90`X>g!Zx@;>@i0G~1k;*U;rH(4f37)2+pMr-QY~GLWMtruS0yW8Kp|7vOx* zxWlcYO@}}De-&cBhjcZB@#!_r!lfM@o|=mV*(6i=Kg7BytU7UaS5I~HxbdA6ein6W z^z3JMd}2lvyLUneK{x8qk2X4VO2fn`GNlta)+<0y-#(*14vls!4MUvfV=r~P66M^f zhWo&NpFKHZQ2NFftJU_{S1A7g#P6{W#ebxImJZ3ZeG^fwWHY3UC>4Qbi~CXO=>ho3 ztY%}Bkp~-P$6E#~fBFuG<@>|}De$!5R2XC{On9r8RDH%yY(3x|%xvR8NZ29sn%a#z zI3_7Ds=@*JShcK*m{@;_3`Y5}k3~|KpCq>j$+^miz$nFTTPE~K=lPY+Nm`wet4AZ{ zuG$e5MZ^O2DgRi=c{R(;j9h1L+4@2d;eHH76?UN^+7&4p~=6DN7g!$DjYtyePHRW$*Bqy){0YyW7rZqc>0AbY9i?xYlPG|8PjcK%K z_^}aPIi>kZak)I0*WmO+sYR;Sm7+?N+D&?kQe^*`b;G-?FOZjEl3oe|Ae&iS7$4rWSet?OVUhEw8cJu1l+mx6r3MfMH zKKBS0Gsma;s0%IcPL=LmaPBUFb{M}qv$VCrF_A+fq?xx`Yl_$Qiy2*YLVh(htdf4M z5i5Qdm2<&K=8ua>R#EJOAeWy0GLn%5&i%WGw_Ro zPy_5hEPvNsLHz%rA#ewY{gy#Zpz#HX|E|*#>QT`yz%OaPuo;Bw*GG$R{ks2M8o1nZ zboaR9@8!#JU04?K?06;jD8;&lw5!a=VzA`)Cy?mWS#AIbD6aVhd-~tGcg@p} z>n|pM_^3Jh+55V9`@48~a{S_Z$IdIjUxAbJm!Q8tf9dI9|F<0P0AKgtQXK3>9Nir~ z96kO0M8t%}ME)0!VC~;PPrv_ogWwmDdw0AEAkqH`a=hpAk6Hf*^{eOq3G;Wk`~QIb z>iG-y+lhbKChuSm^$W0bb+q^YS1Y0Kw~vh-eMJ7%EHCmuspSdwLE&BwE_Z{~?)W<@ z{*Or|FY;eB|9JN|TGiL_*Q7M@@^V-FzjO321^wj-=x=&+H5bAd_z?zCQBq7? zUgUrF{7>Yqe~@BgQvXK&tLMLws$TA1zQ*2n>>U-w{sZ|})4!;HIUTC%<>Bq?==WPY zQF)R7U)z7vn;SX$dASGtnv#mr1Y>>!{@wWB0DWHAJYc>*Ysms=~D0Dy#n zwwkiZJ8LmJkO_1ZcWe13F{&HVUg4JH zdu-`TZ7*@T$!DOAvFq#%zirjg=&{)_K0DXeu^ieToIA08J+!7FcdybZe1FzW!EH0V zeHTgn)L#f(G5>|Vbxd}*k5Lqo0J29DiZw@DpHDdyFOX+9Yg}I4rDOzmA;fG6#Y`9a zxePXZn;jK9haAyxFsn>-dtb*S`3IPQ*n4eLdZ$M0GfEmL-=SOkI_+Ac5>R3H z51UQVZ6-l|qDeBP$l1hjo0*xOuxleP^gr(WM?RrIfgp-;pIKlLbqB@kuGW_L<>0Bx zzV=D6e?$>MGPuqzVX{}^cgSy~_x5|@S_7@S-Y)Cj5_9}*#&2%?AJ8Yxd6X}Rq(LQY zx{?cqvpH`zGCHQ($ga*0HC+9NuoQ{BRqMllkE}@VFu1MU^RV$`ujJuJ1XDS4L&$&Z zClm&s(4+#xy~kq7d4qi~;w=S)e|q4Q;*PpLm{z|3$AwdOZ2bi1$a?j#>PL>@lR4zL zYiIF2*?dmU*24@-J6B!)@dghQBeFfBrOBDICM$34kyqcDsbJ)!y{+y}F0j+{FP?&; zsJtJnq+j(9%yL%Z*NR^+Oz(6&juToE9MCwTO!g2evD5y?o^xUZ>QhknnZH+{Z`Hi~ z!u{Sr(#dOQP1!u|Fty*O6}X z>pxC;OS!-|@?s>|OCvR9X6H=AWmC&RJ@U~#(R*Nr)6nPGM)bd|)e%q5F_825@pab& zH>di|RWCo_cE&sv$JX>fcXmawJ?USjBJcDgPC36~UW3d&e4Yb5PUU3NQ}3hKh40T> zV~9~Tr#V=^9XjuvK4;dw35q%~@l3Ct&JT#d&I)}+nIg`Q)lBhd~t4#`c;(g^wSGJCG z2yJ^<OIKgiTVrth3aWC8YkxZ}@`-%7%xY>= z_gAVF%VhDLYiXJ!f;WoY@56!{wd7OvTh-=uu8} z3GaW*aay)yj<)Z9Q|zySh(z(K4aDU>OHON^Rg_~$Zhlh3A*K(i?NTO*OYLmKbdAeK zJ2ZnnKO>rIGHi50$v0>n9MYBb((M_2%#K@%zT0pz9>O;=p|bi`)6|Z> zj@k0;xRsp*{HHc8EAgMmBA)6bA{oozX+j|i7j9(!bhPdlA)4H;hq6-K1>G9bIpap{ zRJQlGs%v1hW}CuVEQtVIv2Eoi*pw$wE57N%let`!Q~x7+5m7Wvged;0EmR+PlvyQr z(UKihW)uWq!h&f?v01{72UYz5x}m0!cO(GDDh}bgHLbqfGT{%e&@l!fb`K&hAA3jn z(F5Gc5^1JisYc2QA;KP-cO8W;8NiKG<@s1e**T*`W|JI$V*qvY>Qp&=Rh5agDvBC%beDq{ zP6G7LMO?o%>kDLOjo6dpBFDZqnjf z9!9@PS#U8DEH`$FaNnDb1z@MR>}b+Vy4J{bjA{+TgdbIg{Ose1TkQTyH&gUBfYkkE_Bv^ZanC3bIzD z(8DWJhu6#*L9&M3NcdDm?wXPU-2oRWXN69zSSafo^+bqG97+H+yiE)Ny)5%;#RUh@_4a7ibHLFnibZIGwi* zA@*!T)w%_(wc3iz}bpt#y1DaJaF!TW@zNYtHW6)E5i+G=}bh9fY^%ik!-a?1J-( zHh|08>Tuy(S8rH!VwO9r&=a1DTNc=`ORbT41xAe?IRjv9XK6bPlq9AmEEHG&gLF)Q zD-tH_#V2_>DNfbk?-gHP;v>%cDt}w(!tQP};tKqA{?R-*ppSM>Z7PM@9-$r0bk6F8 zx3At}#NkIE=ysE)Z-J>nyGPXvdLNx<^HI<9$Zppr3os9kbg}_4XF@Rik&ICVF;H0g zyrUY29j`{dpSM_H%_v*Gsl!tRIhZ=-zqfq?9fFVkR&SQW3amaT>z(n$0hZBa#@4(ar!ek-Ex( z+ppv6AvGchJ|s=mwuG(1xqafvF&gbuX2vh{ERK+2^Hkj~TK>pu%6t_CNbK=s0!VR! zJJ>slI;o(L^&*ZvHQMkC;7r1nT2m;hd85p(8M0o8rXt&uG?cy)GJBvW`h4ypxhW3v zu*Fl|SB7MOf$qtfVQmEJO%La03|5o*9=FkK?Dq>D4Gmr(n1_kfU1#>I2Sf_pm*8JR zfGzMem`}u;)2b?Y$8x%`JNsNBiNF@x;Cfj%T6uK3%5EmC!5zpH@pB0$EwJ^jjpJR* zjoBUHpCftDcz2h#KJNJPJsz86-2t5t2jQCjq9}wA4W)1n%GgwWvo9&Rs8LBoL*=09 zo)X20{3xR%sakKg;P_#a`}@Pql$|Ta@?XG+TaP}a^Z)2}p>2-7nR-0enbf%fE2zr@ zsc#RD*{-Uk?87lCwP}6stY@8u>^o0K2M`dL&s_Cul!$|q0(o)C3-)oNuN3qqxw^V?Kr*pK%4xCb7P zTRO6TFa62O?fL!Y;0S35QePr*leB$Ns4}^UKLDHaSbyn?F{u9|;^@L95>eBr&&i(! z9Y=UfhV`~rh}+)unmIVTGo{tZTCXcKaTX=2Y0GBZZq0$Zh8m@6H7Y1nh9XYj;(Wnb zhc=|Q!gKl_t=*t*G1S1A%r1u=eR+~N$MjM*A3dv=5)#}IHymX95kAZOJPw<7W`jw6 z*F!m`D-e2_r6dZjjL*GNk;adpY$!7gVhSc-Ol~VnYYH83jpiPG)cZByJC=1aCel9O zyvu6W`Aps~Q*Z6L1JCq+j{bBEm(M>H3a9f6Zq?XW=y=agHx!xTd(G2mK`PB|qHt!1 z#f7V}qHV6LWj_VVEvY5a)fVOi%pj{*4nZ7_}; zR>5iI91H1gLqJ;YBRM1ZjuA=X-=FCowlVDm9qkXQ zYH*fGBk2rhNXg|(aNo_@S4oeUozp*@Xo-F^oqYB+W%kLzT}AAygNML1@_wD#jA1iX-w_j%V?+YALhVoMNH`A$U7{FoCtf#_rTa ztE!@;#81`8Vwx_b3ozL0LuU6*xp>AgCPCajg{*3f4~#cVO+f$XrDb|RYrUhjP- z|HK=ELPkS~qN+Z*I9i=0p?mF=Czszhs_JG5S1I~MQR`w;0Eb^F z{-kQ!ye)xizuM4o<#6R#=hr#RVBrXiV$o&jI7b^`5_jS(Xd{HOQc$>^{>BZ~Zl&N~ zf_R9~m%8$b`gMq64zimigfC9m`vqioou?F@c|v zS&rNnzqGFTY=(R@;SGrjUSDwjHuA?-9

LU`x&?C9{56fj%8mIt#D@gWZX~nI>;8Idkd3TmQYyaR9)$2Sm9ryH z;2R(H+$a>DsFoXN0=k!WQ86@&ZfK92_*kR?i{MDPf{*|R_UWz;?!JUYJ&hlqqkz=Z z*rf2Z&p>lmnz_Nt+>+eBqw9QE*lU8~koF~nZ7oj7fR>oD46uC!d;=TSgCD!5my`}I zSV62^F6M6zdm&Vjftq!`JhAW4Gn1djgGD}y+0qPt-q|8v&d?h45wx%pUb;l`F-?l1 z9B;EP`@9O`?*YA%G}0YpVg79XuI)TM?d6Pgt}+z*XK@{!+wcT=cv`WoE)9(C zBA<|&pzGp^omxq(T^sux^P9;BKh?4|Q9;3K(v9$%P^ZuIVK3^RQuJuhR#V|G8pWlp zN)E(=a&8G&67w6};zE@a3?M7eBsvRf^Eyp2UB|70GR7ZY-^`!S&%#28J(t5>9s|q&N9Se@^-YpQYzZse?Kv&>t|S8268fd1}(8YqKDk^hfsi^ch^w z{vw+AxFs-nsEBsABFC3xe|?GNbMcn@7t&4cE(bl@@;BrBeV;|R65j^`VexsKsg{P@ z&~vy$kzS{5#z8;ka_L#)5*;)BB37IzgwpjE+m;CEii*8s4ll=&{>-9u@S)*o6I}UY zXwMc{QK^2|z@&oCO#8vljag3jx?$T*XGXb}er)>J!xXKqq2tF6B zim$XdUL7&~8h@USTt2JZ=J^Lx0yIGB+(*rgvTK_<3&qADw2{Q+wVK|pg&dZvt0dl7 zT2wsSxqntgcQ zqkc}d!T?ghYpCm<=)y>GC6DJDR;;f*n|vwDE_SzvOn7d`W{n=1cbNw;9G`3e3BPi;)n4gSy-?8{Vn3Tzw-Vz=Nw}qtkxD&Ou1%MSCm}t*UIfk(xO3Dybf_i%sO|+VY16G~i3^(j*6UOhrnR}^et9iu) zs5Oa-v=37Yu+KFUDMYd*Fs?fGiA}z)RG~PCs%sz1k7V5JUs}B*5*&`6=%QI*Keq%Z zK0|)WL7JJ)a0`7;fJoZp5iA+suPPd?;p(g>W{FfO(V8Ly9E>{&!;!XI0N84{!+X9Q zlP(`4M#B=Sd5%%)LKs(u6 zrwUi=tH5CRP|;V!Pg=J1QCx^}^cp2#hI;HobJSS!kwKv(AD?(ITJ~g&#zj*x0pvkA z7QAruV`ii<^J>X|w2{>H!v&VI+5kIUEecbbFc(=RJcW`owH+=~_meVz-6_zXuYl2v ze#gBP)^hW0rVN9AkLOL$?Tp8;q0qiOwSrH{inN?t#fl@eG!Ob*ZEKQ^>?ZlK^gS!p zADXxAQDk;RuUX}(>UUCCpl)_7WOfG?jW5p5LyY`cJAi87IQc z;T$&A*eaNGz!0VkX-GZh#$l6JS^Xpl1Md}vwX-`8TTDK1;3K!+mmrH)>)gvz{*)*r zG6fps-ty0q!OM@5=|79APi9Y52rzn8UvPf1`qjopj4=z(A!lTE+LwmBVcU5IJGu7< zk^Fh=D~clbX}AK%mP%mO^}BRCB|pUB-$#~nII1EhW-?v{!Ctf#GrNCm2r_%o)}?1< z4`wGxpo%&yk^qXAutiXSJ>?-;;~Oxf6TWdO`>R6TgUU7`2nwq%?z^tSol2c z&mm8I$ICYNqWiy&I4VLvBayUu;UF~MrS%tI4pvJ))4`Zr#DQdX22fs2z>)y)-0(4p zgA6GU|E@2a<2^1I^g~6xWlkl~be|y!`9%ov^mE)>wOR-;FrEqzCVL;YPXgTJ9gUy7CO9Ef;GulW1quv~S2iB1D!Uox8SO;g-weJ4 zRd^0Yu)oz$=u6`DHZLk5Q@k7b`1Yb61PEy>73=1s2M*227Cs33w=N=I=+e1-m#6M# zueuZjT&kkQ!koW*OiTo>btoT`Ytbqns~H}@!~`3R_A8`qf_vZasfWYVrsI?#>fr*} zXA+Ge%5kGiKxtbQYyJP;)~>`#a}4gVNRItfS}3q$Io_lf)C{trXIGWYc?0w&_jcF!r{halGZxFhQGO z1%=TLa6HmPn+Y|pBRM{N%=__;*JQm2U|?!>Frw^k&_6|)$Kx`4h% zym#R4lSlcxu`9X2IA}9&>U@J_^9)3OkFNGIS^W-WL(a9(3p4Dm79dMs=sznU6Zi zX^Y(qKJ{5T+=lcMM}pvf`ZTPW&s=;IY6UN_hum`li6EAdX7uC<5+F*)XF2_=3ah=a zt$I3s@)lBwZiNx3>#)0>QP&2do3p+=N7m{LhvelV*_;v>5$-v~cn(tEAS6y~5ln;J zquk~G`W0_OEhDVZL+bURKGoVbcx#Fbq9?LwZP*Ln@+>VIqE@1w0t_=phc$61z{e#UOj+vALD-n=1y-D1^&07J zC2|MX6N&$w;%SLPZWN8Z4|a8GSd3&#rj|w)BOPc5$Mbh2^MxVYx`;l+E-s}1=0K5E zL`hOeQ&o_?E)mV23<%1N$vGtI#_H?oor!WBBPwYHi$CP#ILiflO529?cYv%xf+G*s zdu2{L5UAA%$4xg=g%N#jB*h-1jSsmVi|L0CV=OD6EW0AY`0)gTnuzEeMXDgD*N~Q1S>ZE4((D=V|X%Hr`Bj204BSq-fjE?q| zAa<-rH?9M*kw=Xshdnv%*0&jHMZp}8jA7v-n6MCjzaKkUio->*zY}$YM3v|v;|i8o zmN~9|v8L*Tt}_86gE}}%y6=JDK2DiiFWS446G+9afZ@c1O?Y;;!y0c}mn2HK{GFzw zRD@*Z^0RVz_Svw1TD>_SacjLI{PaRxm<-D&k{x!OmGW#ItY8joP>Vvq0(+i&7A>Lt`=HlJbp^PrEb6hvdbnqFFF^YMGK9ly*kefhHD?(>6qe zx*mRYnJtod39J_)y9y3CW`Cub%KInphQ`=)NOd+?Dl+R3%t=2Xf>q#H5P?K`Ad5C9 zrJd9tcWik%CNG`PbW@)W4#?X2V2UzR6$h*HOxH*1|Lu}e=+ENu5!Y}pQPx30Yj!-G zhy|p*&(#sHy*|_7VCqffy?K)17k>RW9@E>9jhZ+oJX6L6&-yzFdOr#Ig0FWBrKYqP zDmh3VarG&Qb3stYLJ<3MHc>2o>FfrF6)up~oK$9Yv4~oxV=phE`^8l9>k~cJIghdb zGr(~Dv_g!k(qe_jNdR(oxz%Q8WFeemFtQkWeJ}`gRI9HzL;kf1^gIH^fCVkrw37~2 zL^UI6PFGPvTcbk_9-4n9yRCuPAXW{>>wcN)F0mVO8Zjl$zS40%onLE(v^VcuAn|Xf z_76nM&apT%boTT^X|xm)^q7|k@if9l{Z|Ao|<54Ls22b?Ak zY@v@ZKHGGn=Wl@9Y$?AGYyAKz5qCgB6i{B|SR@8-8*i3%KUU138(~c&VE&wXMPFy{ z%9;@77HYy^0HCo)2|(&C%R;?DqDq5_i|epf!cl}2JwkX`+>1u$UjVR!sX}OXSnA$0 zflV6YfOLPnabsty~_ z&S_oMk_gUPu_0mR-5-<*JGa z7dMR_95rdOP_eST+?*N{YIU4;F6jYat->s6+f_3FOepM{j@`rupUe>XHZ}GeV~kpN zIrboxo|CQcp;=l?PbRyBk8vJ;$flVf^tx zR`kL3EK1<(UJE0hz7m}enFS*uVNMm*^Fm*4 z%Xx}vDq{qvGitSwRjh?qE}DvbROFCL0xMj71@7s^+}LI|z*WG&M;53`lf752ZFP96 zyQg|2KnuM^!yfmO2I&yf8k@&vL z<-->Opce`1&4D&)9~QX+qNExPsGc3e2^{`Pbk!$D=V)Y$=P;*So6H2M2_6`9wVsX- zxv&?4VMZMk2zHPyvN^OSw#=r|DbUdc%7YCiRmm~@SxPVzl$*IP!tXi?oe;i zTFU2GN_~YRZz(~JA*1y9TKM)#ES8C8;`NmLNApCF6k$BaU`HaL;pH>I^yKuxYc%y? z4G%m@LP+@X@zK55O}$$~hZpL~+-`H9(mq%_>eZlQ;_7e(wlibcy^QgDu-0m4Ry{r9 z0WdCtUQ`UiY>z%bj6Q2}>D%RzVI%!2^^Eh5dgm?@TC6u`>^`;{+B6*pZ=C9dUu+X% zqmbZ#;eDI-a)i>$cB0fp*o|?Ra%yOt{xKb+5DVaZ^M;&VneVkY0laLEf-zMSHe;Ew zMffGh>e7=um33atOIWV;?n-)ZG#F~;Kw1A8 zZF2Q>c75!;#+QzBZzkVrVJQlkHCyKOp~;zbAjAf1hO|*Ko)TAmIy!Gn(im6Q zpnIvVs_Ms=@LJ`RpHU~4Tps0ZoU0`q3tonkG^3WI_Vqdd>X?I8qK9-&VZ&v%E&PQoSK@|xm z#49rmh0jlIvu2+IM*FK^Z|)Wo)H%`z}$5`IszNu$23Z5&v{NQIX zve9iXSwbM>o}7RMGOPY0y3C|Q$xekm!{gb=q+;ei&j7cv<%Z)Tz2FHne>ji~Dj=Bk zKrfb`O$TRmk=5p>fBUB>`EU_YOXX*Ek}uckW+!1ZmMLLbQMm;w`Vma*3S&Y}Rq)S# zLK6{QAGEjN?IL?ue7lgb7_HhX{JU$U0jb}*V0=V?`W`$ELhF$fpn`45PqhQVj@{R1 z4_%_3B`x@m_ZElu1VRqdTC!kkPdvm-Xh*NAPBsZir9qnoyQlbuyKYtOkjf@fujuLD z8j`-$?wW7=w#3G1mOml9337i5u61!!i}gG&A`@{>p4=Ux(#i0Fw+j|dxzbiTdjJQ8 z0NGKVguU&i#Hfiai^|l;uYCIa01`WMIgw?TV5zLl4;e+H+XX4Iro0| zUE=-^0meHjQFna&6&X`dmPMSxiTr{$K25kq=|^3MDan97QQvqZ01h}WocLD6yN=>1 z@i=KXN_*&CfOjfYy*v8|Qfdco4kSAjSy%{dmZg+WjydeVDYamo%a*_8@Fu+`G;}{k zul?}6xb=AW9^#itMhjR4J=wYc$ zGb;+jGv$#w3M%Jh7aiK}jW20G5mpoc(Lx&k@J9m`En04wp4`?qCx$i^O+vdoj9Nc= z+?L2L+1D{O`&ALmJSZl!ZN42WRYoS&2u>aofhJYqBUL{zD5MYYibzaegX6UH+rrFr zlAqKV^R_AVMrxPVazi_G1}Vy(Ykh0P%qAPfij#1MqZpo2UWcra17=8R5B)YGdXlWy zSe8=@1?P%t7el4`4;gj7LhF4eCe8=>*QQ@!CAVE9orV>`U$adg8V7$ zuYL+PV&~d3=&IJX$V`r89HSBMh@c^XXXjLCYRf(e1s~(G469v=Ld`Mnk*CVrw zb;U@(TcT|IUT{?OF%4=p2dIKbI150>GwfIk#)f%djdItR(Ru6sg{t*!vkxK^o(>I_ zAN$na;}wZ)p=2TtELotqG{UYSLVsCbr#}7W$b))@r$8L9^X52RY%aU>%XX`x(O!|d zt@6!}+RoW{$6m>2WQt_rD85sw&KAs;4z1SJ7=cnV!Q(mSNJ2DZNzn9FR$X;GKF#DQ zt2;yr#B%>4$9vfiTQrX+juA9-H|>~IGmuPEE6*BFIw1bL+V!TTyCrC5478SJ5ctW5 ziY|09MCBj2%K=nZH)G83nSg=`_(~*Gj7GF`b}J87sAJk!EFY2~` zx;^XB?Eh@xF@GM#KEH8UaRmm|5ir}oAWJG`w>c2o&s5b|&PH1qCTt)}UqoDsGalDVp;wAh19fYl7~DzfRkJyV8vu@nWmgJzJL66Vsfwff;rNzG8!!df zWBMAA#69bCX5gHd7?&khL+&t!FPIsJ;>d}T3^Q7=B(Bee0(h@-Tt~$lLi34V>vON< zq*^Dgec>jK-d1}p{3ZIXl-!5t$_V_4t$6MLVY5$ds3=vq8@Ti}h&k)FB+f0$%ObD{ z$&=;DJ=9)3sT|t^FKc^nr;YiL-ki=^IZ!gDhg^(Ah~0wHgbZkWM5I2Qg>8Ti0{KCj zaVkz=a&k{l94r(8L0&_&Q?I092M6~sL@0pU)J*NCoi~j+w801*GSxPCK2AH7lHXuV z;R4M}&8cj$u2x5SUmxEdIp%BFUGA#orA!Wb+I6?4?b=%S~cS5ldRQ^gI9299K$|A46&}we{ z@QTJqg|4Po#y8-sq?_GfxK~W*CBRXUt-v6XLs=jxwc5O|J*If*Uc3}e^`WC!kZ*0( z`UmO9s5&{J?-;!cPZ$IeNZRs`%%r**wI1(h6xzsvtFV&%aBvH#glNXx>;5xz8AcmJ zQx(#V5ptH%?~Jo1t>4u_-C>w>!ZU33y-Z*PlN)4`WFr*N%pB_Vf-SFMKlyipKrLIU zbuhB1j~$^8@ah257K5H5|};xIXHF0IKcV5<(Tl3*m$~hl@b>(n4EQxM(lP{7U zlbYH?*|1C@C>%37biRiOmTJND{K88ir6$tgAwl_3(wQLjVSVM&YO`-*h8IMs9&9-D z)zP%QVr~5~d1TtZC-0nzc3>1k(Z%W0^BJe^4a2BQIoC?iZJ2Z3y!U9+(({b3U~AJG zq(`wOgZVzHRmN6d*k=Z8AT*c4M|yW^Vp}##PZN7Jo9sCZ4orJTsq?~8Kb^Qyl$7)o zC0u>9qnAR?U|j73+sf|4l&pL_S;bb6-j3^CbiPbKMlQ6%EGaOxXoPSUPhi|80oF&( zM3B!qu^3NpkPMS^g$=d4Y4GE?XtOGL$~BjVg<4;WWFfqEA*$XHvAq5RZjQlsVxf+v z1E{yl%I;A@ZqgMsfNE+AZ)kLd%*}|D_b1PUZ~Cwghw#u`f-jgZC<~tQ82QljDqR|4 ziupe8jLoEDnSC1KW?GqT1fM^WHl~F;t%!@#SQ#%ULRPNe84avw3P4Pty%}tQu8FKdaCu-E75MVB~Wx|lk|`pfFfINwQXjW zo4a4t2a`M4&K{lU&&q8RA6^A8nlcO_ystoruH@wE-ulZXJn_~MUIAIJ^hm)x>1646zM7+V{Kq>m7+GU zCTKpHPR&h~_EkE}?Q5rj=Z`pKM-zLoFY8jj6qWrxnx1Pgy-SL2$iGQ@M)qZo1gNe~ z>_e!c_b`qZc0?@q$y+j`6cANMSMI!yXPZJ^B4MLOKp_v1YpSf9?J+4AF+)fRqgr6Ph&uhp{mrkw(*5*dOkQ06weCJQ>)jtE&md9F|8q^w*_w`nJmE@mrA*z*e zFtk39Z=}=g400rIA7lmD?fUaO{gtcW5Su+}(J#C|%ki_iHp`n=Ka6Mn2`dlgP+omx zsgEd6U9&AKNjjz9>esckX8Q9E0r(w^`tvL`q|d>6Tpx}X`X?TbX6zP2RsAGGZ7fV} z9!>2xrAPj-vmE{-wOd^DdaN$2Nq?;jzj|LObUCl>ZJ_5LOK3&6m3JbEjQA!!$42sw zCMWPD43l*Pzx@?x=Y(h&p=@5Rjgz%^*D!43uB+$Nh5a!W%@}hXm1nBJN||9pb)wL2 zc3O2H!}8*9FA;W=Qbip{@Vx@l1K6@sg4ce>5!I{g;TE^Qqz^Jdu!^SuswWV|7dFuz z(E(GOJgX%k`#U%dOQl@l>eRolh~fRN$IdshZ;cu`OBerF$hZrEmz(iJ;5&Z4xR1!R z@bGx+!*M3(m?iypt|I{?hMJ@PLjD}Wi-amNr#)^(Cn0CIrlpj)f4ze6>-8H-PspPq z@<2A>fhk*fE#(U62pTCY%JP)X`6DKsGI!|&B>FPo&HZ`5e=;zP;*=+m$X1s_y4Q%z QUvC_0tLv#%tJp^Uf4L6ckpKVy literal 0 HcmV?d00001 diff --git a/loafwallet/Assets.xcassets/Partners/ud-monotone-logo.imageset/Logo-Full-Mono@3x.png b/loafwallet/Assets.xcassets/Partners/ud-monotone-logo.imageset/Logo-Full-Mono@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b10be09f20fbedf9e4ffb68ddc81975f162fa4 GIT binary patch literal 22766 zcmZ^L2Ut_f*7gpeNJn}V5RqP_6I$pXQk7nn-fQS30TmSKO+g^iL7H@sdJyTog9uUt zLhl{^c<#O5ImdhdJkQRaJ+t1KHEZ6P%$`}3S6Uj%gm|=g000oGswn6H02mzvN^fDK zzY!r0QRo|{t*p8%0DOwUzkG^?er~lkP_30097q7WgHB4gt?V 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 V+e-#^z;Pe&7+g2jp=vut{RaxntC0Wz literal 0 HcmV?d00001 diff --git a/loafwallet/LWActivityIndicator.swift b/loafwallet/LWActivityIndicator.swift new file mode 100644 index 000000000..90defaae5 --- /dev/null +++ b/loafwallet/LWActivityIndicator.swift @@ -0,0 +1,27 @@ +// +// LWActivityIndicator.swift +// loafwallet +// +// Created by Kerry Washington on 11/19/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import UIKit +import SwiftUI + +struct ActivityIndicator: UIViewRepresentable { + + @Binding + var isAnimating: Bool + + let style: UIActivityIndicatorView.Style + + func makeUIView(context: UIViewRepresentableContext) -> UIActivityIndicatorView { + return UIActivityIndicatorView(activityIndicatorStyle: style) + } + + func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext) { + isAnimating ? uiView.startAnimating() : uiView.stopAnimating() + } +} diff --git a/loafwallet/PartnersView.swift b/loafwallet/PartnersView.swift new file mode 100644 index 000000000..2936a43ed --- /dev/null +++ b/loafwallet/PartnersView.swift @@ -0,0 +1,47 @@ +// +// PartnersView.swift +// loafwallet +// +// Created by Kerry Washington on 11/29/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct PartnersView: View { + + @ObservedObject + var viewModel: PartnerViewModel + + init(viewModel: PartnerViewModel) { + self.viewModel = viewModel + } + var body: some View { + VStack { + Image("ud-color-logo") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 200) + .padding(.top, 50) + .padding(.bottom, 60) + + Image("simplexLogoTypeColor") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 200) + .padding(.bottom, 60) + + Spacer() + } + } +} + +struct PartnersView_Previews: PreviewProvider { + + static let viewModel = PartnerViewModel() + + static var previews: some View { + PartnersView(viewModel: viewModel) + } +} + diff --git a/loafwallet/PartnersViewModel.swift b/loafwallet/PartnersViewModel.swift new file mode 100644 index 000000000..5d313ff7c --- /dev/null +++ b/loafwallet/PartnersViewModel.swift @@ -0,0 +1,16 @@ +// +// PartnersViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 11/29/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation + +class PartnerViewModel: ObservableObject { + + init() { + + } +} diff --git a/loafwallet/ResolutionModel.swift b/loafwallet/ResolutionModel.swift new file mode 100644 index 000000000..e4a7f409c --- /dev/null +++ b/loafwallet/ResolutionModel.swift @@ -0,0 +1,38 @@ +// +// ResolutionModel.swift +// loafwallet +// +// Created by Kerry Washington on 11/29/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import UnstoppableDomainsResolution + +class ResolutionModel: NSObject { + + static let shared = ResolutionModel() + + var resolution: Resolution? + + override init() { + super.init() + + if let path = Bundle.main.path(forResource: "partner-keys", ofType: "plist"), + let dictionary = NSDictionary(contentsOfFile:path) as? Dictionary, + let key = dictionary["infura"] as? String { + let keypath = "https://mainnet.infura.io/v3/" + key + + do { + guard let resolution = try? Resolution(providerUrl: keypath, network: "mainnet") else { + print ("Init of Resolution instance with custom parameters failed...") + return + } + self.resolution = resolution + + } catch { + print("Unstoppable Domains Error: \(String(describing: self.resolution))") + } + } + } +} diff --git a/loafwallet/SupportLitecoinFoundationView.swift b/loafwallet/SupportLitecoinFoundationView.swift index a07e269a7..579b28a48 100644 --- a/loafwallet/SupportLitecoinFoundationView.swift +++ b/loafwallet/SupportLitecoinFoundationView.swift @@ -12,15 +12,14 @@ import WebKit /// This cell is under the amount view and above the Memo view in the Send VC struct SupportLitecoinFoundationView: View { + //MARK: - Combine Variables @ObservedObject var viewModel: SupportLitecoinFoundationViewModel - @State - var supportLTCAddress = "" - @State private var showSupportLFPage: Bool = false + //MARK: - Public var supportSafariView = SupportSafariView(url: FoundationSupport.url, @@ -31,53 +30,67 @@ struct SupportLitecoinFoundationView: View { } var body: some View { - VStack { - Spacer() + Spacer(minLength: 40) + supportSafariView - .frame(height: 500, - alignment: .center - ) - .padding(.bottom, 50) + .frame(height: 300, + alignment: .center) + .padding([.bottom, .top], 10) // Copy the LF Address and paste into the SendViewController Button(action: { UIPasteboard.general.string = FoundationSupport.supportLTCAddress - self.viewModel.didCopyLTCAddress?() - + self.viewModel.didTapToDismiss?() }) { - Text(S.URLHandling.copy) - .padding([.leading,.trailing],20) - .padding([.top,.bottom],10) + Text(S.URLHandling.copy.uppercased()) .font(Font(UIFont.customMedium(size: 16.0))) + .padding() + .frame(maxWidth: .infinity) .foregroundColor(Color(UIColor.white)) .background(Color(UIColor.liteWalletBlue)) - .overlay( - RoundedRectangle(cornerRadius: 4) - .stroke(Color(UIColor.liteWalletBlue)) - ) + .cornerRadius(4.0) } - .padding(.bottom, 30) - .padding([.leading,.trailing], 20) - + .padding([.leading, .trailing], 40) + .padding(.bottom, 10) + // Cancel Button(action: { - self.viewModel.didCancel?() + self.viewModel.didTapToDismiss?() }) { - Text(S.Button.cancel) - .padding([.leading,.trailing],20) - .padding([.top,.bottom],10) + Text(S.Button.cancel.uppercased()) .font(Font(UIFont.customMedium(size: 16.0))) + .padding() + .frame(maxWidth: .infinity) .foregroundColor(Color(UIColor.liteWalletBlue)) .background(Color(UIColor.white)) + .cornerRadius(4.0) .overlay( RoundedRectangle(cornerRadius: 4) .stroke(Color(UIColor.secondaryBorder)) ) } - .padding(.bottom, 50) - .padding([.leading,.trailing], 20) + .padding([.leading, .trailing], 40) + + Spacer(minLength: 100) } - Spacer() } } + +struct SupportLitecoinFoundationView_Previews: PreviewProvider { + + static let viewModel = SupportLitecoinFoundationViewModel() + + static var previews: some View { + Group { + SupportLitecoinFoundationView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro Max")) + .previewDisplayName("iPhone 12 Pro Max") + + SupportLitecoinFoundationView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: "iPhone SE")) + .previewDisplayName("iPhone SE") + } + } +} + diff --git a/loafwallet/SupportLitecoinFoundationViewModel.swift b/loafwallet/SupportLitecoinFoundationViewModel.swift index 1ce550ecf..b5ffd4d05 100644 --- a/loafwallet/SupportLitecoinFoundationViewModel.swift +++ b/loafwallet/SupportLitecoinFoundationViewModel.swift @@ -16,11 +16,7 @@ class SupportLitecoinFoundationViewModel: ObservableObject { //MARK: - Combine Variables //MARK: - Public Variables - - - var didCancel: (()->())? - - var didCopyLTCAddress: (()->())? + var didTapToDismiss: (()->())? init() {} } diff --git a/loafwallet/SupportSafariView.swift b/loafwallet/SupportSafariView.swift index b1cb36563..e03f77a1e 100644 --- a/loafwallet/SupportSafariView.swift +++ b/loafwallet/SupportSafariView.swift @@ -39,24 +39,7 @@ struct SupportSafariView: UIViewRepresentable { /// - webView: Embedded webView /// - navigation: nil func webView(_ webView: WKWebView, - didFinish navigation: WKNavigation!) { - // MARK: - Parse LF LTC Address - webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", - completionHandler: { ( htmlString: Any, error: Error?) in - if let string = htmlString as? String, - let suffix = string.components(separatedBy:"") - let element = content.filter{ $0.contains(" WKWebView { diff --git a/loafwallet/SupportSafariViewModel.swift b/loafwallet/SupportSafariViewModel.swift index 136d8737d..bbd38cb9d 100644 --- a/loafwallet/SupportSafariViewModel.swift +++ b/loafwallet/SupportSafariViewModel.swift @@ -9,9 +9,6 @@ import Foundation class SupportSafariViewModel: ObservableObject { - - @Published - var supportLTCAddress = "" - + init() { } } diff --git a/loafwallet/UnstoppableDomainView.swift b/loafwallet/UnstoppableDomainView.swift new file mode 100644 index 000000000..12801dc92 --- /dev/null +++ b/loafwallet/UnstoppableDomainView.swift @@ -0,0 +1,117 @@ +// +// UnstoppableDomainView.swift +// loafwallet +// +// Created by Kerry Washington on 11/18/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct UnstoppableDomainView: View { + + //MARK: - Combine Variables + @ObservedObject + var viewModel: UnstoppableDomainViewModel + + @State + private var didReceiveLTCfromUD: Bool = false + + init(viewModel: UnstoppableDomainViewModel) { + self.viewModel = viewModel + } + + var body: some View { + + ZStack { + VStack { + Spacer() + HStack { + + if viewModel.isDomainResolving { + if #available(iOS 14.0, *) { + ProgressView() + .padding(.leading, 20) + .padding(.trailing, 20) + + } else { + ActivityIndicator(isAnimating: .constant(true), style: .large) + .padding(.leading, 20) + .padding(.trailing, 20) + } + } else { + + TextField(viewModel.placeholderString, text: $viewModel.searchString) + .font(Font(UIFont.customBody(size: 16.0))) + .keyboardType(.URL) + .autocapitalization(.none) + .disableAutocorrection(true) + .padding(.leading, 18) + .padding(.trailing, 5) + } + + Spacer() + Button(action: { + viewModel.resolveDomain() + }) { + HStack(spacing: 10) { + ZStack { + + RoundedRectangle(cornerRadius: 4) + .frame(width: 60, height: 30, alignment: .center) + .foregroundColor(Color(UIColor.secondaryButton)) + .shadow(color:Color(UIColor.grayTextTint), radius: 3, x: 0, y: 4) .padding(.trailing, 18) + + Text("Lookup") + .frame(width: 60, height: 30, alignment: .center) + .font(Font(UIFont.customMedium(size: 15.0))) + .foregroundColor(Color(UIColor.grayTextTint)) + .overlay( + RoundedRectangle(cornerRadius:4) + .stroke(Color(UIColor.secondaryBorder)) + ) + .padding(.trailing, 18) + } + } + } + + } + Spacer() + Rectangle() + .fill(Color(UIColor.secondaryBorder)) + .frame(height: 1.0) + } + + HStack { + Text(S.Fragments.or) + .frame(width: 70, height: 12, alignment: .center) + .font(Font(UIFont.customBody(size: 15.0))) + .foregroundColor(Color(UIColor.grayTextTint)) + .background(Color.white) + .padding(.top, -35) + .padding(.leading, 60) + Spacer() + } + } + } +} + +struct UnstoppableDomainView_Previews: PreviewProvider { + + static let viewModel = UnstoppableDomainViewModel() + + static var previews: some View { + Group { + UnstoppableDomainView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: "iPhone SE")) + .previewDisplayName("iPhone SE") + + UnstoppableDomainView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro Max")) + .previewDisplayName("iPhone 12 Pro Max") + } + } +} + + + diff --git a/loafwallet/UnstoppableDomainViewModel.swift b/loafwallet/UnstoppableDomainViewModel.swift new file mode 100644 index 000000000..49744535f --- /dev/null +++ b/loafwallet/UnstoppableDomainViewModel.swift @@ -0,0 +1,107 @@ +// +// UnstoppableDomainViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 11/18/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine +import UnstoppableDomainsResolution + +class UnstoppableDomainViewModel: ObservableObject { + + //MARK: - Combine Variables + @Published + var searchString: String = "" + + @Published + var placeholderString: String = S.Send.UnstoppableDomains.placeholder + + @Published + var isDomainResolving: Bool = false + + //MARK: - Public Variables + var didResolveUDAddress: ((String) -> Void)? + + //MARK: - Private Variables + private var ltcAddress = "" + + + private var dateFormatter: DateFormatter? { + + didSet { + dateFormatter = DateFormatter() + dateFormatter?.dateFormat = "yyyy-MM-dd hh:mm:ss" + } + } + + init() { + + //Triggers 'failed' RPC connection + _ = ResolutionModel.shared.resolution + + } + + func resolveDomain() { + + isDomainResolving = true + + // Added timing peroformance probes to see what the average time is + let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" + + LWAnalytics.logEventWithParameters(itemName: + CustomEvent._20201121_SIL, + properties: + ["start_time": timestamp]) + + self.resolveUDAddress(domainName: searchString) + + ///Fallback resolution: Set in case it takes a longer time to resolve. + DispatchQueue.main.asyncAfter(deadline: .now() + 12) { + self.didResolveUDAddress?(self.ltcAddress) + self.isDomainResolving = false + } + } + + private func resolveUDAddress(domainName: String) { + + ResolutionModel + .shared + .resolution?.addr(domain: domainName, ticker: "ltc") { result in + + switch result { + case .success(let returnValue): + + let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" + + LWAnalytics.logEventWithParameters(itemName: + CustomEvent._20201121_DRIA, + properties: + ["success_time": timestamp]) + + ///Quicker resolution: When the resolution is done, the activity indicatior stops and the address is updated + DispatchQueue.main.async { + self.ltcAddress = returnValue + self.didResolveUDAddress?(self.ltcAddress) + self.isDomainResolving = false + } + + case .failure(let error): + + let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" + + LWAnalytics.logEventWithParameters(itemName: + CustomEvent._20201121_FRIA, + properties: + ["failure_time": timestamp, + "error":error.localizedDescription]) + + print("Expected LTC Address, but got \(error.localizedDescription)") + + } + } + } +} diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index 8db925f08..b59c1b704 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -34,6 +34,9 @@ enum CustomEvent: String { case _20200225_DCD = "DID_CANCEL_DONATE" case _20200301_DUDFPK = "DID_USE_DEFAULT_FEE_PER_KB" case _20201118_DTS = "DID_TAP_SUPPORT_LF" + case _20201121_SIL = "STARTED_IFPS_LOOKUP" + case _20201121_DRIA = "DID_RESOLVE_IPFS_ADDRESS" + case _20201121_FRIA = "FAILED_RESOLVE_IPFS_ADDRESS" } struct FoundationSupport { @@ -44,7 +47,7 @@ struct FoundationSupport { /// As of Nov 14th, 2020 static let supportLTCAddress = "MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe" } - + struct APIServer { diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index 4fe741355..0b159d9bd 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -66,6 +66,7 @@ enum S { enum Send { static let title = NSLocalizedString("Send.title", value: "**Send**", comment: "Send modal title") static let toLabel = NSLocalizedString("Send.toLabel", value: "**To**", comment: "Send money to label") + static let enterLTCAddressLabel = NSLocalizedString("Send.enterLTCAddress", value: "**Enter LTC Address**", comment: "Enter LTC Address") static let amountLabel = NSLocalizedString("Send.amountLabel", value: "**Amount**", comment: "Send money amount label") static let descriptionLabel = NSLocalizedString("Send.descriptionLabel", value: "**Memo**", comment: "Description for sending money label") static let sendLabel = NSLocalizedString("Send.sendLabel", value: "**Send**", comment: "Send button label") @@ -95,6 +96,11 @@ enum S { static let loadingRequest = NSLocalizedString("Send.loadingRequest", value: "**Loading Request**", comment: "Loading request activity view message") static let insufficientFunds = NSLocalizedString("Send.insufficientFunds", value: "**Insufficient Funds**", comment: "Insufficient funds error") static let barItemTitle = NSLocalizedString("Send.barItemTitle", value: "**Send**", comment: "Send Bar Item Title") + + enum UnstoppableDomains { + static let placeholder = NSLocalizedString("Send.UnstoppableDomains.placeholder", value: "**Enter a .crypto or .zil domain**", comment: "Enter a .crypto or .zil domain") + + } } enum Receive { @@ -322,6 +328,7 @@ enum S { static let litewalletVersion = NSLocalizedString("Settings.litewallet.version", value: "**Litewallet Version:**", comment: "Litewallet version") static let litewalletEnvironment = NSLocalizedString("Settings.litewallet.environment", value: "**Litewallet Environment:**", comment: "Litewallet environment") static let socialLinks = NSLocalizedString("Settings.socialLinks", value: "**Social Links:**", comment: "Litewallet Social links") + static let litewalletPartners = NSLocalizedString("Settings.litewallet.partners", value: "**Litewallet Partners:**", comment: "Litewallet Partners") } enum About { @@ -662,4 +669,8 @@ enum S { static let title = NSLocalizedString("Welcome.title", value: "**Welcome to Litewallet**", comment: "Welcome view title") static let body = NSLocalizedString("Welcome.body", value: "**Litewallet now has a brand new look and some new features.\n\nAll coins are displayed in lites (ł). 1 Litecoin (Ł) = 1000 lites (ł).**", comment: "Welcome view body text") } + + enum Fragments { + static let or = NSLocalizedString("Fragment.or", value: "**or**", comment: "Or") + } } diff --git a/loafwallet/src/Extensions/UserDefaults+Additions.swift b/loafwallet/src/Extensions/UserDefaults+Additions.swift index 52bb7f10e..6053e5135 100644 --- a/loafwallet/src/Extensions/UserDefaults+Additions.swift +++ b/loafwallet/src/Extensions/UserDefaults+Additions.swift @@ -169,11 +169,6 @@ extension UserDefaults { } else { return true } - - if let legacyWalletNeedsBackup = UserDefaults.legacyWalletNeedsBackup, legacyWalletNeedsBackup == true { - return true - } - return false } } diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 843b67005..0c399f9d9 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -11,7 +11,7 @@ import LocalAuthentication import SwiftUI class ModalPresenter : Subscriber, Trackable { - + //MARK: - Public var walletManager: WalletManager? init(store: Store, walletManager: WalletManager, window: UIWindow, apiClient: BRAPIClient) { @@ -20,10 +20,10 @@ class ModalPresenter : Subscriber, Trackable { self.walletManager = walletManager self.modalTransitionDelegate = ModalTransitionDelegate(type: .regular, store: store) self.wipeNavigationDelegate = StartNavigationDelegate(store: store) - self.noAuthApiClient = apiClient + self.noAuthApiClient = apiClient addSubscriptions() } - + //MARK: - Private private let store: Store private let window: UIWindow @@ -33,12 +33,12 @@ class ModalPresenter : Subscriber, Trackable { private let securityCenterNavigationDelegate = SecurityCenterNavigationDelegate() private let verifyPinTransitionDelegate = TransitioningDelegate() private let noAuthApiClient: BRAPIClient - + private var currentRequest: PaymentRequest? private var reachability = ReachabilityMonitor() private var notReachableAlert: InAppAlert? private let wipeNavigationDelegate: StartNavigationDelegate - + private func addSubscriptions() { store.subscribe(self, selector: { $0.rootModal != $1.rootModal}, @@ -76,7 +76,7 @@ class ModalPresenter : Subscriber, Trackable { store.subscribe(self, name: .recommendRescan, callback: { _ in self.presentRescan() }) - + //URLs store.subscribe(self, name: .receivedPaymentRequest(nil), callback: { guard let trigger = $0 else { return } @@ -146,7 +146,7 @@ class ModalPresenter : Subscriber, Trackable { nc.delegate = securityCenterNavigationDelegate topViewController?.present(nc, animated: true, completion: nil) } - + private func promptShareData() { let shareData = ShareDataViewController(store: store) let nc = ModalNavigationController(rootViewController: shareData) @@ -156,12 +156,12 @@ class ModalPresenter : Subscriber, Trackable { shareData.addCloseNavigationItem() topViewController?.present(nc, animated: true, completion: nil) } - + func presentWritePaperKey() { guard let vc = topViewController else { return } presentWritePaperKey(fromViewController: vc) } - + func presentUpgradePin() { guard let walletManager = walletManager else { return } let updatePin = UpdatePinViewController(store: store, walletManager: walletManager, type: .update) @@ -172,7 +172,7 @@ class ModalPresenter : Subscriber, Trackable { updatePin.addCloseNavigationItem() topViewController?.present(nc, animated: true, completion: nil) } - + private func presentModal(_ type: RootModal, configuration: ((UIViewController) -> Void)? = nil) { guard type != .loginScan else { return presentLoginScan() } guard let vc = rootModalViewController(type) else { @@ -188,28 +188,28 @@ class ModalPresenter : Subscriber, Trackable { self.store.trigger(name: .hideStatusBar) }) } - + private func handleAlertChange(_ type: AlertType?) { guard let type = type else { return } presentAlert(type, completion: { self.store.perform(action: Alert.Hide()) }) } - + private func presentAlert(_ type: AlertType, completion: @escaping ()->Void) { let alertView = AlertView(type: type) let window = UIApplication.shared.keyWindow! let size = window.bounds.size window.addSubview(alertView) - + let topConstraint = alertView.constraint(.top, toView: window, constant: size.height) alertView.constrain([ - alertView.constraint(.width, constant: size.width), - alertView.constraint(.height, constant: alertHeight + 25.0), - alertView.constraint(.leading, toView: window, constant: nil), - topConstraint ]) + alertView.constraint(.width, constant: size.width), + alertView.constraint(.height, constant: alertHeight + 25.0), + alertView.constraint(.leading, toView: window, constant: nil), + topConstraint ]) window.layoutIfNeeded() - + UIView.spring(0.6, animations: { topConstraint?.constant = size.height - self.alertHeight window.layoutIfNeeded() @@ -234,61 +234,61 @@ class ModalPresenter : Subscriber, Trackable { }) }) } - + private func presentWebView(_ mountPoint: String) { guard let walletManager = self.walletManager else { return } let vc = WebViewContainer(mountPoint: mountPoint, walletManager: walletManager, store: store, apiClient: self.noAuthApiClient) vc.modalPresentationStyle = .overFullScreen vc.modalPresentationCapturesStatusBarAppearance = true - vc.transitioningDelegate = vc + vc.transitioningDelegate = vc topViewController?.present(vc, animated: true, completion: {}) } - + private func rootModalViewController(_ type: RootModal) -> UIViewController? { switch type { - case .none: - return nil - case .send: - return makeSendView() - case .receive: - return receiveView(isRequestAmountVisible: true) - case .menu: - return menuViewController() - case .loginScan: - return nil //The scan view needs a custom presentation - case .loginAddress: - return receiveView(isRequestAmountVisible: false) - case .manageWallet: - return ModalViewController(childViewController: ManageWalletViewController(store: store), store: store) - case .wipeEmptyWallet: - return wipeEmptyView() - case .requestAmount: - guard let wallet = walletManager?.wallet else { return nil } - let requestVc = RequestAmountViewController(wallet: wallet, store: store) - requestVc.presentEmail = { [weak self] bitcoinURL, image in - self?.messagePresenter.presenter = self?.topViewController - self?.messagePresenter.presentMailCompose(bitcoinURL: bitcoinURL, image: image) - } - requestVc.presentText = { [weak self] bitcoinURL, image in - self?.messagePresenter.presenter = self?.topViewController - self?.messagePresenter.presentMessageCompose(bitcoinURL: bitcoinURL, image: image) - } - return ModalViewController(childViewController: requestVc, store: store) + case .none: + return nil + case .send: + return makeSendView() + case .receive: + return receiveView(isRequestAmountVisible: true) + case .menu: + return menuViewController() + case .loginScan: + return nil //The scan view needs a custom presentation + case .loginAddress: + return receiveView(isRequestAmountVisible: false) + case .manageWallet: + return ModalViewController(childViewController: ManageWalletViewController(store: store), store: store) + case .wipeEmptyWallet: + return wipeEmptyView() + case .requestAmount: + guard let wallet = walletManager?.wallet else { return nil } + let requestVc = RequestAmountViewController(wallet: wallet, store: store) + requestVc.presentEmail = { [weak self] bitcoinURL, image in + self?.messagePresenter.presenter = self?.topViewController + self?.messagePresenter.presentMailCompose(bitcoinURL: bitcoinURL, image: image) + } + requestVc.presentText = { [weak self] bitcoinURL, image in + self?.messagePresenter.presenter = self?.topViewController + self?.messagePresenter.presentMessageCompose(bitcoinURL: bitcoinURL, image: image) + } + return ModalViewController(childViewController: requestVc, store: store) } - + } private func wipeEmptyView() -> UIViewController? { - - guard let walletManager = walletManager else { return nil } - - let wipeEmptyvc = WipeEmptyWalletViewController(walletManager: walletManager, store: store, didTapNext: ({ [weak self] in - guard let myself = self else { return } - myself.wipeWallet() - })) - return ModalViewController(childViewController: wipeEmptyvc, store: store) + + guard let walletManager = walletManager else { return nil } + + let wipeEmptyvc = WipeEmptyWalletViewController(walletManager: walletManager, store: store, didTapNext: ({ [weak self] in + guard let myself = self else { return } + myself.wipeWallet() + })) + return ModalViewController(childViewController: wipeEmptyvc, store: store) } - + private func makeSendView() -> UIViewController? { guard !store.state.walletState.isRescanning else { let alert = UIAlertController(title: S.Alert.error, message: S.Send.isRescanning, preferredStyle: .alert) @@ -298,14 +298,14 @@ class ModalPresenter : Subscriber, Trackable { } guard let walletManager = walletManager else { return nil } guard let kvStore = walletManager.apiClient?.kv else { return nil } - + let sendVC = SendViewController(store: store, sender: Sender(walletManager: walletManager, kvStore: kvStore, store: store), walletManager: walletManager, initialRequest: currentRequest) currentRequest = nil - + if store.state.isLoginRequired { sendVC.isPresentedFromLock = true } - + let root = ModalViewController(childViewController: sendVC, store: store) sendVC.presentScan = presentScan(parent: root) sendVC.presentVerifyPin = { [weak self, weak root] bodyText, callback in @@ -322,7 +322,7 @@ class ModalPresenter : Subscriber, Trackable { } return root } - + private func receiveView(isRequestAmountVisible: Bool) -> UIViewController? { guard let wallet = walletManager?.wallet else { return nil } let receiveVC = ReceiveViewController(wallet: wallet, store: store, isRequestAmountVisible: isRequestAmountVisible) @@ -339,7 +339,7 @@ class ModalPresenter : Subscriber, Trackable { } return root } - + private func menuViewController() -> UIViewController? { let menu = MenuViewController() let root = ModalViewController(childViewController: menu, store: store) @@ -349,7 +349,7 @@ class ModalPresenter : Subscriber, Trackable { self?.presentSecurityCenter() } } - menu.didTapSupport = { [weak self, weak menu] in + menu.didTapSupport = { [weak self, weak menu] in menu?.dismiss(animated: true, completion: { self?.messagePresenter.presenter = self?.topViewController self?.messagePresenter.presentSupportCompose() @@ -374,7 +374,7 @@ class ModalPresenter : Subscriber, Trackable { } return root } - + private func presentLoginScan() { guard let top = topViewController else { return } let present = presentScan(parent: top) @@ -385,61 +385,66 @@ class ModalPresenter : Subscriber, Trackable { self.presentModal(.send) }) } - - private func presentSettings() { + + private func presentSettings() { guard let top = topViewController else { return } guard let walletManager = self.walletManager else { return } let settingsNav = UINavigationController() let sections = ["About", "Wallet", "Manage", "Support", "Blockchain"] let rows = [ "About": [Setting(title: S.Settings.litewalletVersion, accessoryText: { [weak self] in - return AppVersion.string - }, callback: {}), - Setting(title: S.Settings.litewalletEnvironment, accessoryText: { [weak self] in - var envName = "Release" - #if Debug || Testflight - envName = "Debug" - #endif - return envName - }, callback: {}), - Setting(title: S.Settings.socialLinks, callback: { - settingsNav.pushViewController(AboutViewController(), animated: true) - }) + return AppVersion.string + }, callback: {}), + Setting(title: S.Settings.litewalletEnvironment, accessoryText: { [weak self] in + var envName = "Release" + #if Debug || Testflight + envName = "Debug" + #endif + return envName + }, callback: {}), + Setting(title: S.Settings.litewalletPartners, callback: { + let partnerView = UIHostingController(rootView: PartnersView(viewModel: PartnerViewModel())) + settingsNav.pushViewController(partnerView, animated: true) + }), + Setting(title: S.Settings.socialLinks, callback: { + settingsNav.pushViewController(AboutViewController(), animated: true) + }) + ], "Wallet": [Setting(title: S.Settings.importTile, callback: { [weak self] in - guard let myself = self else { return } - guard let walletManager = myself.walletManager else { return } - let importNav = ModalNavigationController() - importNav.setClearNavbar() - importNav.setWhiteStyle() - let start = StartImportViewController(walletManager: walletManager, store: myself.store) - start.addCloseNavigationItem(tintColor: .white) - start.navigationItem.title = S.Import.title - importNav.viewControllers = [start] - settingsNav.dismiss(animated: true, completion: { - myself.topViewController?.present(importNav, animated: true, completion: nil) - }) - }), - Setting(title: S.Settings.wipe, callback: { [weak self] in - guard let myself = self else { return } - guard let walletManager = myself.walletManager else { return } - let nc = ModalNavigationController() - nc.setClearNavbar() - nc.setWhiteStyle() - nc.delegate = myself.wipeNavigationDelegate - let start = StartWipeWalletViewController { - let recover = EnterPhraseViewController(store: myself.store, walletManager: walletManager, reason: .validateForWipingWallet( { - myself.wipeWallet() - })) - nc.pushViewController(recover, animated: true) - } - start.addCloseNavigationItem(tintColor: .white) - start.navigationItem.title = S.WipeWallet.title - nc.viewControllers = [start] - settingsNav.dismiss(animated: true, completion: { - myself.topViewController?.present(nc, animated: true, completion: nil) - }) - }), + guard let myself = self else { return } + guard let walletManager = myself.walletManager else { return } + let importNav = ModalNavigationController() + importNav.setClearNavbar() + importNav.setWhiteStyle() + let start = StartImportViewController(walletManager: walletManager, store: myself.store) + start.addCloseNavigationItem(tintColor: .white) + start.navigationItem.title = S.Import.title + importNav.viewControllers = [start] + settingsNav.dismiss(animated: true, completion: { + myself.topViewController?.present(importNav, animated: true, completion: nil) + }) + }), + Setting(title: S.Settings.wipe, callback: { [weak self] in + guard let myself = self else { return } + guard let walletManager = myself.walletManager else { return } + let nc = ModalNavigationController() + nc.setClearNavbar() + nc.setWhiteStyle() + nc.delegate = myself.wipeNavigationDelegate + let start = StartWipeWalletViewController { + let recover = EnterPhraseViewController(store: myself.store, walletManager: walletManager, reason: .validateForWipingWallet( { + myself.wipeWallet() + })) + nc.pushViewController(recover, animated: true) + } + start.addCloseNavigationItem(tintColor: .white) + start.navigationItem.title = S.WipeWallet.title + nc.viewControllers = [start] + settingsNav.dismiss(animated: true, completion: { + myself.topViewController?.present(nc, animated: true, completion: nil) + }) + }), ], "Manage": [ Setting(title: S.Settings.languages, callback: strongify(self) { _ in @@ -486,22 +491,22 @@ class ModalPresenter : Subscriber, Trackable { settingsNav.pushViewController(nodeSelector, animated: true) })] -// TODO: Develop this feature for issues with the TXID -// if UserDefaults.didSeeCorruption { -// networkRows.append( -// Setting(title: S.WipeWallet.deleteDatabase, callback: { -// self?.deleteDatabase() -// }) -// ) -// } - + // TODO: Develop this feature for issues with the TXID + // if UserDefaults.didSeeCorruption { + // networkRows.append( + // Setting(title: S.WipeWallet.deleteDatabase, callback: { + // self?.deleteDatabase() + // }) + // ) + // } + let advancedSettings = ["Network": networkRows] let advancedSettingsVC = SettingsViewController(sections: sections, rows: advancedSettings, optionalTitle: S.Settings.advancedTitle) settingsNav.pushViewController(advancedSettingsVC, animated: true) }) ] ] - + let settings = SettingsViewController(sections: sections, rows: rows) settings.addCloseNavigationItem() settingsNav.viewControllers = [settings] @@ -513,7 +518,7 @@ class ModalPresenter : Subscriber, Trackable { settingsNav.setBlackBackArrow() top.present(settingsNav, animated: true, completion: nil) } - + private func presentScan(parent: UIViewController) -> PresentScan { return { [weak parent] scanCompletion in guard ScanViewController.isCameraAllowed else { @@ -533,18 +538,13 @@ class ModalPresenter : Subscriber, Trackable { parent?.present(vc, animated: true, completion: {}) } } + // MARK: - Present Support LF View private func presentSupportLF() { let supportLFView = UIHostingController(rootView: SupportLitecoinFoundationView(viewModel: SupportLitecoinFoundationViewModel())) - - supportLFView.rootView.viewModel.didCancel = { - supportLFView.dismiss(animated: true) { - //TODO: Track in Analytics - } - } - - supportLFView.rootView.viewModel.didCopyLTCAddress = { + + supportLFView.rootView.viewModel.didTapToDismiss = { supportLFView.dismiss(animated: true) { //TODO: Track in Analytics } @@ -553,7 +553,7 @@ class ModalPresenter : Subscriber, Trackable { window.rootViewController?.present(supportLFView, animated: true, completion: nil) } - + private func presentSecurityCenter() { guard let walletManager = walletManager else { return } let securityCenter = SecurityCenterViewController(store: store, walletManager: walletManager) @@ -576,13 +576,13 @@ class ModalPresenter : Subscriber, Trackable { securityCenter.didTapPaperKey = { [weak self] in self?.presentWritePaperKey(fromViewController: nc) } - + window.rootViewController?.present(nc, animated: true, completion: nil) } - + private func pushBiometricsSpendingLimit(onNc: UINavigationController) { guard let walletManager = walletManager else { return } - + let verify = VerifyPinViewController(bodyText: S.VerifyPin.continueBody, pinLength: store.state.pinLength, callback: { [weak self] pin, vc in guard let myself = self else { return false } if walletManager.authenticate(pin: pin) { @@ -600,7 +600,7 @@ class ModalPresenter : Subscriber, Trackable { verify.modalPresentationCapturesStatusBarAppearance = true onNc.present(verify, animated: true, completion: nil) } - + private func presentWritePaperKey(fromViewController vc: UIViewController) { guard let walletManager = walletManager else { return } let paperPhraseNavigationController = UINavigationController() @@ -632,8 +632,8 @@ class ModalPresenter : Subscriber, Trackable { } }) write?.hideCloseNavigationItem() - /// write?.navigationItem.title = S.SecurityCenter.Cells.paperKeyTitle - + /// write?.navigationItem.title = S.SecurityCenter.Cells.paperKeyTitle + vc.dismiss(animated: true, completion: { guard let write = write else { return } paperPhraseNavigationController.pushViewController(write, animated: true) @@ -654,7 +654,7 @@ class ModalPresenter : Subscriber, Trackable { var staticColor = UIColor() if #available(iOS 11.0, *), - let tempStaticColor = UIColor(named: "staticWhiteColor") { + let tempStaticColor = UIColor(named: "staticWhiteColor") { staticColor = tempStaticColor } else { staticColor = .whiteTint @@ -669,8 +669,8 @@ class ModalPresenter : Subscriber, Trackable { paperPhraseNavigationController.viewControllers = [start] vc.present(paperPhraseNavigationController, animated: true, completion: nil) } - - + + private func wipeWallet() { let group = DispatchGroup() let alert = UIAlertController(title: S.WipeWallet.alertTitle, message: S.WipeWallet.alertMessage, preferredStyle: .alert) @@ -691,24 +691,24 @@ class ModalPresenter : Subscriber, Trackable { print("Pausing to show 'Wiping' Dialog") group.leave() } - + group.notify(queue: .main) { if let canForceWipeWallet = (self.walletManager?.wipeWallet(pin: "forceWipe")), - canForceWipeWallet { - self.store.trigger(name: .reinitWalletManager({ - activity.dismiss(animated: true, completion: {}) - })) + canForceWipeWallet { + self.store.trigger(name: .reinitWalletManager({ + activity.dismiss(animated: true, completion: {}) + })) } else { - let failure = UIAlertController(title: S.WipeWallet.failedTitle, message: S.WipeWallet.failedMessage, preferredStyle: .alert) - failure.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) - self.topViewController?.present(failure, animated: true, completion: nil) + let failure = UIAlertController(title: S.WipeWallet.failedTitle, message: S.WipeWallet.failedMessage, preferredStyle: .alert) + failure.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) + self.topViewController?.present(failure, animated: true, completion: nil) } } }) })) topViewController?.present(alert, animated: true, completion: nil) } - + private func handleFile(_ file: Data) { if let request = PaymentProtocolRequest(data: file) { if let topVC = topViewController as? ModalViewController { @@ -735,18 +735,18 @@ class ModalPresenter : Subscriber, Trackable { alert.addAction(UIAlertAction(title: S.Button.ok, style: .cancel, handler: nil)) topViewController?.present(alert, animated: true, completion: nil) } - //TODO - handle payment type + //TODO - handle payment type } else { let alert = UIAlertController(title: S.Alert.error, message: S.PaymentProtocol.Errors.corruptedDocument, preferredStyle: .alert) alert.addAction(UIAlertAction(title: S.Button.ok, style: .cancel, handler: nil)) topViewController?.present(alert, animated: true, completion: nil) } } - + private func handlePaymentRequest(request: PaymentRequest) { self.currentRequest = request guard !store.state.isLoginRequired else { presentModal(.send); return } - + if topViewController is MainViewController { presentModal(.send) } else { @@ -757,10 +757,10 @@ class ModalPresenter : Subscriber, Trackable { } } } - + private func handleScanQrURL() { guard !store.state.isLoginRequired else { presentLoginScan(); return } - + if topViewController is MainViewController || topViewController is LoginViewController { presentLoginScan() } else { @@ -771,7 +771,7 @@ class ModalPresenter : Subscriber, Trackable { } } } - + private func handleCopyAddresses(success: String?, error: String?) { guard let walletManager = walletManager else { return } let alert = UIAlertController(title: S.URLHandling.addressListAlertTitle, message: S.URLHandling.addressListAlertMessage, preferredStyle: .alert) @@ -784,7 +784,7 @@ class ModalPresenter : Subscriber, Trackable { view.dismiss(animated: true, completion: { self?.store.perform(action: Alert.Show(.addressesCopied)) if let success = success, let url = URL(string: success) { - UIApplication.shared.open(url, options: [:], completionHandler: nil) + UIApplication.shared.open(url, options: [:], completionHandler: nil) } }) return true @@ -799,26 +799,26 @@ class ModalPresenter : Subscriber, Trackable { })) topViewController?.present(alert, animated: true, completion: nil) } - + private func authenticateForBitId(prompt: String, callback: @escaping (BitIdAuthResult) -> Void) { if UserDefaults.isBiometricsEnabled { walletManager?.authenticate(biometricsPrompt: prompt, completion: { result in switch result { - case .success: - return callback(.success) - case .cancel: - return callback(.cancelled) - case .failure: - self.verifyPinForBitId(prompt: prompt, callback: callback) - case .fallback: - self.verifyPinForBitId(prompt: prompt, callback: callback) + case .success: + return callback(.success) + case .cancel: + return callback(.cancelled) + case .failure: + self.verifyPinForBitId(prompt: prompt, callback: callback) + case .fallback: + self.verifyPinForBitId(prompt: prompt, callback: callback) } }) } else { self.verifyPinForBitId(prompt: prompt, callback: callback) } } - + private func verifyPinForBitId(prompt: String, callback: @escaping (BitIdAuthResult) -> Void) { guard let walletManager = walletManager else { return } let verify = VerifyPinViewController(bodyText: prompt, pinLength: store.state.pinLength, callback: { pin, view in @@ -837,13 +837,13 @@ class ModalPresenter : Subscriber, Trackable { verify.modalPresentationCapturesStatusBarAppearance = true topViewController?.present(verify, animated: true, completion: nil) } - + private func copyAllAddressesToClipboard() { guard let wallet = walletManager?.wallet else { return } let addresses = wallet.allAddresses.filter({wallet.addressIsUsed($0)}) UIPasteboard.general.string = addresses.joined(separator: "\n") } - + private var topViewController: UIViewController? { var viewController = window.rootViewController while viewController?.presentedViewController != nil { @@ -851,7 +851,7 @@ class ModalPresenter : Subscriber, Trackable { } return viewController } - + private func showNotReachable() { guard notReachableAlert == nil else { return } let alert = InAppAlert(message: S.Alert.noInternet, image: #imageLiteral(resourceName: "BrokenCloud")) @@ -861,10 +861,10 @@ class ModalPresenter : Subscriber, Trackable { window.addSubview(alert) let bottomConstraint = alert.bottomAnchor.constraint(equalTo: window.topAnchor, constant: 0.0) alert.constrain([ - alert.constraint(.width, constant: size.width), - alert.constraint(.height, constant: InAppAlert.height), - alert.constraint(.leading, toView: window, constant: nil), - bottomConstraint ]) + alert.constraint(.width, constant: size.width), + alert.constraint(.height, constant: InAppAlert.height), + alert.constraint(.leading, toView: window, constant: nil), + bottomConstraint ]) window.layoutIfNeeded() alert.bottomConstraint = bottomConstraint alert.hide = { @@ -875,7 +875,7 @@ class ModalPresenter : Subscriber, Trackable { window.layoutIfNeeded() }, completion: {_ in}) } - + private func hideNotReachable() { UIView.animate(withDuration: C.animationDuration, animations: { self.notReachableAlert?.bottomConstraint?.constant = 0.0 @@ -885,14 +885,14 @@ class ModalPresenter : Subscriber, Trackable { self.notReachableAlert = nil }) } - + private func showLightWeightAlert(message: String) { let alert = LightWeightAlert(message: message) let view = UIApplication.shared.keyWindow! view.addSubview(alert) alert.constrain([ - alert.centerXAnchor.constraint(equalTo: view.centerXAnchor), - alert.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) + alert.centerXAnchor.constraint(equalTo: view.centerXAnchor), + alert.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) alert.background.effect = nil UIView.animate(withDuration: 0.6, animations: { alert.background.effect = alert.effect @@ -907,13 +907,13 @@ class ModalPresenter : Subscriber, Trackable { } class SecurityCenterNavigationDelegate : NSObject, UINavigationControllerDelegate { - + func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { - + guard let coordinator = navigationController.topViewController?.transitionCoordinator else { return } - + if coordinator.isInteractive { - coordinator.notifyWhenInteractionChanges { context in + coordinator.notifyWhenInteractionChanges { context in //We only want to style the view controller if the //pop animation wasn't cancelled if !context.isCancelled { @@ -924,14 +924,14 @@ class SecurityCenterNavigationDelegate : NSObject, UINavigationControllerDelegat setStyle(navigationController: navigationController, viewController: viewController) } } - + func setStyle(navigationController: UINavigationController, viewController: UIViewController) { if viewController is SecurityCenterViewController { navigationController.isNavigationBarHidden = true } else { navigationController.isNavigationBarHidden = false } - + if viewController is BiometricsSettingsViewController { navigationController.setWhiteStyle() } else { @@ -939,3 +939,4 @@ class SecurityCenterNavigationDelegate : NSObject, UINavigationControllerDelegat } } } + diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 014f4b229..25195ca00 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1269,3 +1269,15 @@ /* Menu button title */ "MenuButton.customer.support" = "Customer support"; + +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Enter a .crypto or .zil domain"; + +/* Or */ +"Fragment.or" = "or"; + +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Enter a Litecoin address"; + +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet partners"; diff --git a/loafwallet/src/Strings/ar.lproj/Localizable.strings b/loafwallet/src/Strings/ar.lproj/Localizable.strings index eb93508a3..ab4ba6291 100644 --- a/loafwallet/src/Strings/ar.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ar.lproj/Localizable.strings @@ -301,6 +301,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Processing Speed"; +/* Or */ +"Fragment.or" = "or"; + /* History Bar Item Title */ "History.barItemTitle" = "HISTORY"; @@ -1243,6 +1246,15 @@ /* Menu button title */ "MenuButton.customer.support" = ""; +/* Enter LTC Address */ +"Send.enterLTCAddress" = ""; + +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = ""; + +/* Litewallet Partners */ +"Settings.litewallet.partners" = ""; + /* Delete database title */ "WipeWallet.alertDeleteTitle" = ""; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index c13e06dba..e528ef11b 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Behandlingshastighed"; +/* Or */ +"Fragment.or" = "eller"; + /* History Bar Item Title */ "History.barItemTitle" = "HISTORIE"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Tegnebord er tomt"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Indtast en Litecoin-adresse"; + /* Network Fee: $0.01 */ "Send.fee" = "Netværksafgift: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "Til"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Indtast et .crypto- eller .zil-domæne"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin adresser er kun beregnet til en enkelt anvendelse."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Miljø:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet-partnere"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet version:"; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index d29a0be9c..348a051ff 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Verarbeitungsgeschwindigkeit"; +/* Or */ +"Fragment.or" = "oder"; + /* History Bar Item Title */ "History.barItemTitle" = "GESCHICHTE"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Pasteboard ist leer."; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Geben Sie eine Litecoin-Adresse ein"; + /* Network Fee: $0.01 */ "Send.fee" = "Netzwerkgebühr: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "An"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Geben Sie eine .crypto- oder .zil-Domain ein"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin-Adressen sind lediglich zur einmaligen Benutzung vorgesehen."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Umgebung:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet-Partner"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet-Version:"; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index c8887d155..fbc59048b 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Processing Speed"; +/* Or */ +"Fragment.or" = "or"; + /* History Bar Item Title */ "History.barItemTitle" = "HISTORY"; @@ -745,6 +748,9 @@ /* Empty pasteboard error message */ "Send.emptyPasteboard" = "Pasteboard is empty"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Enter a Litecoin address"; + /* Network Fee: $0.01 */ "Send.fee" = "Network Fee: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "To"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Enter a .crypto or .zil domain"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin addresses are intended for single use only."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Environment:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet partners"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet version:"; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 728f633f2..7c7e197ef 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -317,6 +317,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Velocidad de procesamiento"; +/* Or */ +"Fragment.or" = "o"; + /* History Bar Item Title */ "History.barItemTitle" = "HISTORIA"; @@ -746,6 +749,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Pasteboard está vacío"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Introduzca una dirección de Litecoin"; + /* Network Fee: $0.01 */ "Send.fee" = "Tarifa de red: %1$@"; @@ -797,6 +803,9 @@ /* Send money to label */ "Send.toLabel" = "A"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Ingrese un dominio .crypto o .zil"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Las direcciones Litecoin están diseñadas para un solo uso."; @@ -836,6 +845,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Ambiente:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Socios de Litewallet"; + /* Litewallet version */ "Settings.litewallet.version" = "Versión Litewallet:"; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index 2abc1bb65..f1a8dcb3e 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Vitesse de traitement"; +/* Or */ +"Fragment.or" = "ou"; + /* History Bar Item Title */ "History.barItemTitle" = "HISTOIRE"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Le tableau d'affichage est vide."; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Entrez une adresse Litecoin"; + /* Network Fee: $0.01 */ "Send.fee" = "Frais de réseau : %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "Pour"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Entrez un domaine .crypto ou .zil"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Les adresses Litecoin sont destinées à une utilisation unique."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Environnement:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Partenaires Litewallet"; + /* Litewallet version */ "Settings.litewallet.version" = "Version Litewallet:"; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 2230dac22..42573b3d6 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Kecepatan pemrosesan"; +/* Or */ +"Fragment.or" = "atau"; + /* History Bar Item Title */ "History.barItemTitle" = "SEJARAH"; @@ -745,6 +748,9 @@ /* Empty pasteboard error message */ "Send.emptyPasteboard" = "Papan tulis kosong"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Masukkan alamat Litecoin"; + /* Network Fee: $0.01 */ "Send.fee" = "Biaya Jaringan: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "Untuk"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Masukkan domain .crypto atau .zil"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Alamat Litecoin hanya ditujukan untuk penggunaan tunggal."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Lingkungan Hidup:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Mitra Litewallet"; + /* Litewallet version */ "Settings.litewallet.version" = "Versi litewallet:"; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index 1a0cdb4f4..774c68fda 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Velocità di lavorazione"; +/* Or */ +"Fragment.or" = "o"; + /* History Bar Item Title */ "History.barItemTitle" = "STORIA"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Il cartone è vuoto"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Inserire un indirizzo Litecoin"; + /* Network Fee: $0.01 */ "Send.fee" = "Spese network: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "A"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Inserisci un dominio .crypto o .zil"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Gli indirizzi Litecoin dovrebbero essere utilizzati una sola volta."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Ambiente:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Partner di Litewallet"; + /* Litewallet version */ "Settings.litewallet.version" = "Versione Litewallet:"; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index 3a796d833..f4ea3138d 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "処理速度"; +/* Or */ +"Fragment.or" = "或いは"; + /* History Bar Item Title */ "History.barItemTitle" = "歴史"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "ペーストボードが空です"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Litecoinのアドレスを入力してください。"; + /* Network Fee: $0.01 */ "Send.fee" = "ネットワーク手数料: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "宛先"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = ".cryptoまたは.zilドメインを入力してください"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "リテコインアドレスは、個人利用のみを想定しています。"; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "環境:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewalletパートナー"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewalletバージョン:"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index 8608a3632..a9d0e2101 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "처리 속도"; +/* Or */ +"Fragment.or" = "또는"; + /* History Bar Item Title */ "History.barItemTitle" = "역사"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "클립보드가 비어 있습니다"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "라이트 코인 주소를 입력하세요"; + /* Network Fee: $0.01 */ "Send.fee" = "네트워크 비용: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "수취인"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = ".crypto 또는 .zil 도메인을 입력하세요."; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin 주소는 일회용입니다."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "환경:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet 파트너"; + /* Litewallet version */ "Settings.litewallet.version" = "라이트 월렛 버전 :"; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index 71b3aad49..a536fb9dc 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Verwerkingssnelheid"; +/* Or */ +"Fragment.or" = "of"; + /* History Bar Item Title */ "History.barItemTitle" = "GESCHIEDENIS"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Plakbord is leeg"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Voer een Litecoin-adres in"; + /* Network Fee: $0.01 */ "Send.fee" = "Netwerkkosten: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "Naar"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Voer een .crypto- of .zil-domein in"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin adressen zijn alleen bedoeld voor enkel gebruik."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Milieu:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet-partners"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet-versie:"; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index 9a8859099..8adb83b6c 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -317,6 +317,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Velocidade de processamento"; +/* Or */ +"Fragment.or" = "ou"; + /* History Bar Item Title */ "History.barItemTitle" = "HISTORY"; @@ -746,6 +749,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "A área de transferência está vazia"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Introduzir um endereço Litecoin"; + /* Network Fee: $0.01 */ "Send.fee" = "Taxa de rede: %1$@"; @@ -797,6 +803,9 @@ /* Send money to label */ "Send.toLabel" = "Para"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Insira um domínio .crypto ou .zil"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Os endereços de Litecoin destinam-se apenas a uma única utilização."; @@ -836,6 +845,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Meio Ambiente:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Parceiros Litewallet"; + /* Litewallet version */ "Settings.litewallet.version" = "Versão Litewallet:"; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index ac1ea27b4..63b81e63c 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Скорость обработки"; +/* Or */ +"Fragment.or" = "или"; + /* History Bar Item Title */ "History.barItemTitle" = "ИСТОРИЯ"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Буфер обмена пуст"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Введите адрес Litecoin"; + /* Network Fee: $0.01 */ "Send.fee" = "Комиссия сети: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "На"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Введите домен .crypto или .zil"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Биткойн-адреса предназначены исключительно для однократного использования."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Окружающая среда:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Партнеры Litewallet"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet версия:"; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index f329a32a5..cc2e9c21a 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "Bearbetningshastighet"; +/* Or */ +"Fragment.or" = "eller"; + /* History Bar Item Title */ "History.barItemTitle" = "HISTORIA"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "Urklipp är tomt"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "Ange en Litecoin-adress"; + /* Network Fee: $0.01 */ "Send.fee" = "Nätverksavgift: %1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "Till"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "Ange en .crypto- eller .zil-domän"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin-adresser är avsedda för engångsanvändning."; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "Miljö:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet-partners"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet version:"; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index d6e20fd6a..f3cd372e7 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "处理速度"; +/* Or */ +"Fragment.or" = "要么"; + /* History Bar Item Title */ "History.barItemTitle" = "历史"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "粘贴板为空"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "输入一个Litecoin地址"; + /* Network Fee: $0.01 */ "Send.fee" = "网络费:%1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "至"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "输入.crypto或.zil域"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "莱特币地址仅供一次性使用。"; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "环境:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet合作伙伴"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet版本:"; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index aede921a8..fb1c4f7ac 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -316,6 +316,9 @@ /* Fee Selector title */ "FeeSelector.title" = "處理速度"; +/* Or */ +"Fragment.or" = "要么"; + /* History Bar Item Title */ "History.barItemTitle" = "歷史"; @@ -745,6 +748,9 @@ /* Emtpy pasteboard error message */ "Send.emptyPasteboard" = "剪貼板是空的"; +/* Enter LTC Address */ +"Send.enterLTCAddress" = "輸入萊特幣地址"; + /* Network Fee: $0.01 */ "Send.fee" = "網路費:%1$@"; @@ -796,6 +802,9 @@ /* Send money to label */ "Send.toLabel" = "給"; +/* Enter to match domain name to LTC Address */ +"Send.UnstoppableDomains.placeholder" = "輸入.crypto或.zil域"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "萊特幣位址專供一次性使用。"; @@ -835,6 +844,9 @@ /* Litewallet environment */ "Settings.litewallet.environment" = "環境:"; +/* Litewallet Partners */ +"Settings.litewallet.partners" = "Litewallet合作夥伴"; + /* Litewallet version */ "Settings.litewallet.version" = "Litewallet版本:"; diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index 8a4daca80..fa8a1bf54 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -8,7 +8,7 @@ import UIKit import LocalAuthentication -import BRCore +import BRCore import FirebaseAnalytics import SwiftUI @@ -16,10 +16,10 @@ typealias PresentScan = ((@escaping ScanCompletion) -> Void) private let verticalButtonPadding: CGFloat = 15.0 private let buttonSize = CGSize(width: 52.0, height: 32.0) - + class SendViewController : UIViewController, Subscriber, ModalPresentable, Trackable { //TODO: Review dark mode color scheme - + //MARK - Public var presentScan: PresentScan? var presentVerifyPin: ((String, @escaping VerifyPinCallback)->Void)? @@ -27,7 +27,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track var parentView: UIView? //ModalPresentable var initialAddress: String? var isPresentedFromLock = false - + init(store: Store, sender: Sender, walletManager: WalletManager, initialAddress: String? = nil, initialRequest: PaymentRequest? = nil) { self.store = store self.sender = sender @@ -40,20 +40,22 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil) } - + //MARK - Private deinit { store.unsubscribe(self) NotificationCenter.default.removeObserver(self) } - + private let store: Store private let sender: Sender private let walletManager: WalletManager private let amountView: AmountViewController private let addressCell = AddressCell() + private var orLabelView = UIView() + private let unstoppableCell = UIHostingController(rootView: UnstoppableDomainView(viewModel: UnstoppableDomainViewModel())) private let descriptionCell = DescriptionSendCell(placeholder: S.Send.descriptionLabel) - private var sendButton = ShadowButton(title: S.Send.sendLabel, type: .flatLitecoinBlue) + private var sendButton = ShadowButton(title: S.Send.sendLabel, type: .flatLitecoinBlue) private let currency: ShadowButton private let currencyBorder = UIView(color: .secondaryShadow) private var pinPadHeightConstraint: NSLayoutConstraint? @@ -64,56 +66,65 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track private let initialRequest: PaymentRequest? private let confirmTransitioningDelegate = TransitioningDelegate() private var feeType: FeeType? - + override func viewDidLoad() { if #available(iOS 11.0, *) { guard let backgroundColor = UIColor(named: "lfBackgroundColor") else { - NSLog("ERROR: Main color") - return + NSLog("ERROR: Main color") + return } view.backgroundColor = backgroundColor } else { view.backgroundColor = .white } - + // set as regular at didLoad walletManager.wallet?.feePerKb = store.state.fees.regular - + view.addSubview(addressCell) + view.addSubview(unstoppableCell.view) view.addSubview(descriptionCell) view.addSubview(sendButton) addressCell.constrainTopCorners(height: SendCell.defaultHeight) + + addChildViewController(amountView, layout: { - amountView.view.constrain([ - amountView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), - amountView.view.topAnchor.constraint(equalTo: addressCell.bottomAnchor), - amountView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) }) - + amountView.view.constrain([ + amountView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + amountView.view.topAnchor.constraint(equalTo: unstoppableCell.view.bottomAnchor), + amountView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) }) + + unstoppableCell.view.constrain([ + unstoppableCell.view.topAnchor.constraint(equalTo: addressCell.bottomAnchor), + unstoppableCell.view.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), + unstoppableCell.view.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), + unstoppableCell.view.heightAnchor.constraint(equalToConstant: SendCell.defaultHeight) ]) + descriptionCell.constrain([ - descriptionCell.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), + descriptionCell.widthAnchor.constraint(equalTo: amountView.view.widthAnchor), descriptionCell.topAnchor.constraint(equalTo: amountView.view.bottomAnchor), - descriptionCell.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), - descriptionCell.heightAnchor.constraint(equalTo: descriptionCell.textView.heightAnchor, constant: C.padding[3]) ]) - + descriptionCell.leadingAnchor.constraint(equalTo: amountView.view.leadingAnchor), + descriptionCell.heightAnchor.constraint(equalTo: descriptionCell.textView.heightAnchor, constant: C.padding[3]) ]) + descriptionCell.accessoryView.constrain([ - descriptionCell.accessoryView.constraint(.width, constant: 0.0) ]) + descriptionCell.accessoryView.constraint(.width, constant: 0.0) ]) sendButton.constrain([ - sendButton.constraint(.leading, toView: view, constant: C.padding[2]), - sendButton.constraint(.trailing, toView: view, constant: -C.padding[2]), - sendButton.constraint(toBottom: descriptionCell, constant: verticalButtonPadding), - sendButton.constraint(.height, constant: C.Sizes.buttonHeight), - sendButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: E.isIPhoneX ? -C.padding[5] : -C.padding[2]) ]) + sendButton.constraint(.leading, toView: view, constant: C.padding[2]), + sendButton.constraint(.trailing, toView: view, constant: -C.padding[2]), + sendButton.constraint(toBottom: descriptionCell, constant: verticalButtonPadding), + sendButton.constraint(.height, constant: C.Sizes.buttonHeight), + sendButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: E.isIPhoneX ? -C.padding[5] : -C.padding[2]) ]) addButtonActions() store.subscribe(self, selector: { $0.walletState.balance != $1.walletState.balance }, callback: { if let balance = $0.walletState.balance { self.balance = balance } - }) + }) } - + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if initialAddress != nil { @@ -123,12 +134,12 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track handleRequest(initialRequest) } } - + private func addButtonActions() { addressCell.paste.addTarget(self, action: #selector(SendViewController.pasteTapped), for: .touchUpInside) addressCell.scan.addTarget(self, action: #selector(SendViewController.scanTapped), for: .touchUpInside) sendButton.addTarget(self, action: #selector(sendTapped), for: .touchUpInside) - + descriptionCell.didReturn = { textView in textView.resignFirstResponder() } @@ -144,37 +155,44 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track amountView.balanceTextForAmount = { [weak self] amount, rate in return self?.balanceTextForAmount(amount: amount, rate: rate) } - + amountView.didUpdateAmount = { [weak self] amount in self?.amount = amount } amountView.didUpdateFee = strongify(self) { myself, feeType in - - myself.feeType = feeType - let fees = myself.store.state.fees - switch feeType { + myself.feeType = feeType + let fees = myself.store.state.fees + + switch feeType { case .regular: myself.walletManager.wallet?.feePerKb = fees.regular case .economy: myself.walletManager.wallet?.feePerKb = fees.economy case .luxury: myself.walletManager.wallet?.feePerKb = fees.luxury - } - + } + myself.amountView.updateBalanceLabel() } - + amountView.didChangeFirstResponder = { [weak self] isFirstResponder in if isFirstResponder { self?.descriptionCell.textView.resignFirstResponder() self?.addressCell.textField.resignFirstResponder() } } + + unstoppableCell.rootView.viewModel.didResolveUDAddress = { resolvedUDAddress in + ///Paste in Unstoppable Domain resolved LTC address to textField + self.addressCell.textField.text = resolvedUDAddress + self.addressCell.textField.resignFirstResponder() + self.addressCell.textField.isHidden = false + } } - + private func balanceTextForAmount(amount: Satoshis?, rate: Rate?) -> (NSAttributedString?, NSAttributedString?) { - + let balanceAmount = DisplayAmount(amount: Satoshis(rawValue: balance), state: store.state, selectedRate: rate, minimumFractionDigits: 2) let balanceText = balanceAmount.description - + let balanceOutput = String(format: S.Send.balance, balanceText) var feeOutput = "" var color: UIColor = .grayTextTint @@ -182,27 +200,27 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track if let amount = amount, amount > 0 { let fee = sender.feeForTx(amount: amount.rawValue) let feeAmount = DisplayAmount(amount: Satoshis(rawValue: fee), state: store.state, selectedRate: rate, minimumFractionDigits: 2) - + let feeText = feeAmount.description.replacingZeroFeeWithOneCent() feeOutput = String(format: S.Send.fee, feeText) if (balance >= fee) && amount.rawValue > (balance - fee) { color = .cameraGuideNegative } } - + let balanceAttributes: [NSAttributedStringKey: Any] = [ NSAttributedStringKey.font: UIFont.customBody(size: 14.0), NSAttributedStringKey.foregroundColor: color ] - + let feeAttributes: [NSAttributedStringKey: Any] = [ NSAttributedStringKey.font: UIFont.customBody(size: 14.0), NSAttributedStringKey.foregroundColor: UIColor.grayTextTint ] - + return (NSAttributedString(string: balanceOutput, attributes: balanceAttributes), NSAttributedString(string: feeOutput, attributes: feeAttributes)) } - + @objc private func pasteTapped() { guard let pasteboard = UIPasteboard.general.string, pasteboard.utf8.count > 0 else { return showAlert(title: S.Alert.error, message: S.Send.emptyPasteboard, buttonLabel: S.Button.ok) @@ -212,7 +230,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track } handleRequest(request) } - + @objc private func scanTapped() { descriptionCell.textView.resignFirstResponder() addressCell.textField.resignFirstResponder() @@ -221,12 +239,12 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self?.handleRequest(request) } } - + @objc private func sendTapped() { if addressCell.textField.isFirstResponder { addressCell.textField.resignFirstResponder() } - + if sender.transaction == nil { guard let address = addressCell.address else { return showAlert(title: S.Alert.error, message: S.Send.noAddress, buttonLabel: S.Button.ok) @@ -254,13 +272,13 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track return showAlert(title: S.Alert.error, message: S.Send.createTransactionError, buttonLabel: S.Button.ok) } } - + guard let amount = amount else { return } let confirm = ConfirmationViewController(amount: amount, fee: Satoshis(sender.fee), feeType: feeType ?? .regular, state: store.state, selectedRate: amountView.selectedRate, minimumFractionDigits: amountView.minimumFractionDigits, address: addressCell.address ?? "", isUsingBiometrics: sender.canUseBiometrics) confirm.successCallback = { confirm.dismiss(animated: true, completion: { - self.send() + self.send() }) } confirm.cancelCallback = { @@ -275,39 +293,39 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track present(confirm, animated: true, completion: nil) return } - + private func handleRequest(_ request: PaymentRequest) { switch request.type { - case .local: - addressCell.setContent(request.toAddress) - addressCell.isEditable = true - if let amount = request.amount { - amountView.forceUpdateAmount(amount: amount) - } - if request.label != nil { - descriptionCell.content = request.label - } - case .remote: - let loadingView = BRActivityViewController(message: S.Send.loadingRequest) - present(loadingView, animated: true, completion: nil) - request.fetchRemoteRequest(completion: { [weak self] request in - DispatchQueue.main.async { - loadingView.dismiss(animated: true, completion: { - if let paymentProtocolRequest = request?.paymentProtocolRequest { - self?.confirmProtocolRequest(protoReq: paymentProtocolRequest) - } else { - self?.showErrorMessage(S.Send.remoteRequestError) - } - }) + case .local: + addressCell.setContent(request.toAddress) + addressCell.isEditable = true + if let amount = request.amount { + amountView.forceUpdateAmount(amount: amount) } - }) + if request.label != nil { + descriptionCell.content = request.label + } + case .remote: + let loadingView = BRActivityViewController(message: S.Send.loadingRequest) + present(loadingView, animated: true, completion: nil) + request.fetchRemoteRequest(completion: { [weak self] request in + DispatchQueue.main.async { + loadingView.dismiss(animated: true, completion: { + if let paymentProtocolRequest = request?.paymentProtocolRequest { + self?.confirmProtocolRequest(protoReq: paymentProtocolRequest) + } else { + self?.showErrorMessage(S.Send.remoteRequestError) + } + }) + } + }) } } - + private func send() { guard let rate = store.state.currentRate else { return } guard let feePerKb = walletManager.wallet?.feePerKb else { return } - + sender.send(biometricsMessage: S.VerifyPin.touchIdMessage, rate: rate, comment: descriptionCell.textView.text, @@ -323,44 +341,44 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track return false } } - }, completion: { [weak self] result in - switch result { - case .success: - self?.dismiss(animated: true, completion: { - guard let myself = self else { return } - myself.store.trigger(name: .showStatusBar) - if myself.isPresentedFromLock { - myself.store.trigger(name: .loginFromSend) + }, completion: { [weak self] result in + switch result { + case .success: + self?.dismiss(animated: true, completion: { + guard let myself = self else { return } + myself.store.trigger(name: .showStatusBar) + if myself.isPresentedFromLock { + myself.store.trigger(name: .loginFromSend) + } + myself.onPublishSuccess?() + }) + self?.saveEvent("send.success") + LWAnalytics.logEventWithParameters(itemName:._20191105_DSL) + + case .creationError(let message): + self?.showAlert(title: S.Send.createTransactionError, message: message, buttonLabel: S.Button.ok) + self?.saveEvent("send.publishFailed", attributes: ["errorMessage": message]) + case .publishFailure(let error): + if case .posixError(let code, let description) = error { + self?.showAlert(title: S.Alerts.sendFailure, message: "\(description) (\(code))", buttonLabel: S.Button.ok) + self?.saveEvent("send.publishFailed", attributes: ["errorMessage": "\(description) (\(code))"]) + } } - myself.onPublishSuccess?() }) - self?.saveEvent("send.success") - LWAnalytics.logEventWithParameters(itemName:._20191105_DSL) - - case .creationError(let message): - self?.showAlert(title: S.Send.createTransactionError, message: message, buttonLabel: S.Button.ok) - self?.saveEvent("send.publishFailed", attributes: ["errorMessage": message]) - case .publishFailure(let error): - if case .posixError(let code, let description) = error { - self?.showAlert(title: S.Alerts.sendFailure, message: "\(description) (\(code))", buttonLabel: S.Button.ok) - self?.saveEvent("send.publishFailed", attributes: ["errorMessage": "\(description) (\(code))"]) - } - } - }) } - + func confirmProtocolRequest(protoReq: PaymentProtocolRequest) { guard let firstOutput = protoReq.details.outputs.first else { return } guard let wallet = walletManager.wallet else { return } - + let address = firstOutput.swiftAddress let isValid = protoReq.isValid() var isOutputTooSmall = false - + if let errorMessage = protoReq.errorMessage, errorMessage == S.PaymentProtocol.Errors.requestExpired, !isValid { return showAlert(title: S.PaymentProtocol.Errors.badPaymentRequest, message: errorMessage, buttonLabel: S.Button.ok) } - + //TODO: check for duplicates of already paid requests var requestAmount = Satoshis(0) protoReq.details.outputs.forEach { output in @@ -369,7 +387,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track } requestAmount += output.amount } - + if wallet.containsAddress(address) { return showAlert(title: S.Alert.warning, message: S.Send.containsAddress, buttonLabel: S.Button.ok) } else if wallet.addressIsUsed(address) && !didIgnoreUsedAddressWarning { @@ -392,16 +410,16 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track let message = String(format: S.PaymentProtocol.Errors.smallTransaction, amount.bits) return showAlert(title: S.PaymentProtocol.Errors.smallOutputErrorTitle, message: message, buttonLabel: S.Button.ok) } - + if let name = protoReq.commonName { addressCell.setContent(protoReq.pkiType != "none" ? "\(S.Symbols.lock) \(name.sanitized)" : name.sanitized) } - + if requestAmount > 0 { amountView.forceUpdateAmount(amount: requestAmount) } descriptionCell.content = protoReq.details.memo - + if requestAmount == 0 { if let amount = amount { guard sender.createTransaction(amount: amount.rawValue, to: address) else { @@ -413,7 +431,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track sender.createTransaction(forPaymentProtocol: protoReq) } } - + private func showError(title: String, message: String, ignore: @escaping () -> Void) { let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) alertController.addAction(UIAlertAction(title: S.Button.ignore, style: .default, handler: { _ in @@ -422,16 +440,16 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track alertController.addAction(UIAlertAction(title: S.Button.cancel, style: .cancel, handler: nil)) present(alertController, animated: true, completion: nil) } - + //MARK: - Keyboard Notifications @objc private func keyboardWillShow(notification: Notification) { copyKeyboardChangeAnimation(notification: notification) } - + @objc private func keyboardWillHide(notification: Notification) { copyKeyboardChangeAnimation(notification: notification) } - + //TODO - maybe put this in ModalPresentable? private func copyKeyboardChangeAnimation(notification: Notification) { guard let info = KeyboardNotificationInfo(notification.userInfo) else { return } @@ -440,7 +458,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track parentView.frame = parentView.frame.offsetBy(dx: 0, dy: info.deltaY) }, completion: nil) } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -450,8 +468,10 @@ extension SendViewController : ModalDisplayable { var faqArticleId: String? { return ArticleIds.sendBitcoin } - + var modalTitle: String { return S.Send.title } } + + diff --git a/loafwallet/src/Views/SendViewCells/AddressCell.swift b/loafwallet/src/Views/SendViewCells/AddressCell.swift index 4a07b0bf0..38205ea8d 100644 --- a/loafwallet/src/Views/SendViewCells/AddressCell.swift +++ b/loafwallet/src/Views/SendViewCells/AddressCell.swift @@ -101,7 +101,7 @@ class AddressCell : UIView { } private func setInitialData() { - label.text = S.Send.toLabel + label.text = S.Send.enterLTCAddressLabel textField.font = contentLabel.font textField.textColor = contentLabel.textColor textField.isHidden = true diff --git a/loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift b/loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift index a1a9b719b..8e6f35fcd 100644 --- a/loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift +++ b/loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift @@ -17,15 +17,15 @@ class SupportLitecoinFoundationViewModelTests: XCTestCase { super.setUp() viewModel = SupportLitecoinFoundationViewModel() } - - func testDidGetLTCAddress() throws { - - } - - func testDidUpdateAddressString() throws { - + + /// Checks the user taps on the closure + func testDidTapToDismiss() throws { + + self.viewModel.didTapToDismiss?() + + viewModel.didTapToDismiss = { + XCTAssert(true, "Tap did work") + } } } - - diff --git a/loafwalletTests/Class Tests/UnstoppableDomainViewModelTests.swift b/loafwalletTests/Class Tests/UnstoppableDomainViewModelTests.swift new file mode 100644 index 000000000..13cecfc63 --- /dev/null +++ b/loafwalletTests/Class Tests/UnstoppableDomainViewModelTests.swift @@ -0,0 +1,34 @@ +// +// UnstoppableDomainViewModelTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 11/18/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import XCTest +@testable import loafwallet + +class UnstoppableDomainViewModelTests: XCTestCase { + + var viewModel: UnstoppableDomainViewModel! + + override func setUp() { + super.setUp() + viewModel = UnstoppableDomainViewModel() + } + + /// Checks the domain address closure + /// - Throws: Error + func testDomainLookupForLTC() throws { + + self.viewModel.didResolveUDAddress?("RESOLVED_LTC_ADDRESS") + + //DEV: This test succeeds incorrectly + viewModel.didResolveUDAddress = { address in + XCTAssertTrue(address == "RESOLVED_LTC_ADDRESS") + } + } + +} + diff --git a/loafwalletTests/Constants Tests/ConstantsTests.swift b/loafwalletTests/Constants Tests/ConstantsTests.swift index ea9d6e036..71f897912 100644 --- a/loafwalletTests/Constants Tests/ConstantsTests.swift +++ b/loafwalletTests/Constants Tests/ConstantsTests.swift @@ -14,5 +14,4 @@ class ConstantsTests: XCTestCase { func testLFDonationAddressPage() throws { XCTAssertTrue(FoundationSupport.url.absoluteString == "https://lite-wallet.org/support_address.html" ) } - } From f5a8a2d12582c7ba8014ac26ac26e4fe357556f4 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 3 Jan 2021 18:51:37 +0000 Subject: [PATCH 022/114] Fix some trivial conflict markers (#177) --- loafwallet/src/ModalPresenter.swift | 30 +---------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 5d62d1996..53b69418b 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -538,38 +538,19 @@ class ModalPresenter : Subscriber, Trackable { parent?.present(vc, animated: true, completion: {}) } } -<<<<<<< HEAD -======= - ->>>>>>> develop // MARK: - Present Support LF View private func presentSupportLF() { let supportLFView = UIHostingController(rootView: SupportLitecoinFoundationView(viewModel: SupportLitecoinFoundationViewModel())) -<<<<<<< HEAD - -======= - ->>>>>>> develop supportLFView.rootView.viewModel.didTapToDismiss = { supportLFView.dismiss(animated: true) { //TODO: Track in Analytics } } -<<<<<<< HEAD - window.rootViewController?.present(supportLFView, animated: true, completion: nil) } - -======= - - window.rootViewController?.present(supportLFView, animated: true, completion: nil) - - } - ->>>>>>> develop private func presentSecurityCenter() { guard let walletManager = walletManager else { return } let securityCenter = SecurityCenterViewController(store: store, walletManager: walletManager) @@ -685,11 +666,7 @@ class ModalPresenter : Subscriber, Trackable { paperPhraseNavigationController.viewControllers = [start] vc.present(paperPhraseNavigationController, animated: true, completion: nil) } - -<<<<<<< HEAD -======= - ->>>>>>> develop + private func wipeWallet() { let group = DispatchGroup() let alert = UIAlertController(title: S.WipeWallet.alertTitle, message: S.WipeWallet.alertMessage, preferredStyle: .alert) @@ -958,8 +935,3 @@ class SecurityCenterNavigationDelegate : NSObject, UINavigationControllerDelegat } } } - -<<<<<<< HEAD - -======= ->>>>>>> develop From 8155d013c1dc8c44712da0fd5bbed34cffea1dc6 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 4 Jan 2021 10:02:08 +0000 Subject: [PATCH 023/114] [Bugfix] Upgrade the business logic for Unstoppable Domains (#179) * Fix some triival conflict markers * Added test to button once the UD string meets a minimum length * Clears address text field when Lookup button is pressed * Set the background color of the AlertToast * Locailization of the alert language * move logic to release the first responder * per review notes --- loafwallet/Assets.xcassets/Contents.json | 6 +-- .../colorImageBlue.imageset/Contents.json | 21 ++++++++++ .../colorImageBlue.imageset/colorBlue.png | Bin 0 -> 1702 bytes .../Contents.json | 38 ++++++++++++++++++ loafwallet/UnstoppableDomainView.swift | 15 ++++++- loafwallet/UnstoppableDomainViewModel.swift | 8 +++- loafwallet/src/Constants/Strings.swift | 8 ++-- loafwallet/src/ModalPresenter.swift | 5 +++ .../Strings/Base.lproj/Localizable.strings | 9 +++++ .../src/Strings/ar.lproj/Localizable.strings | 9 +++++ .../src/Strings/da.lproj/Localizable.strings | 9 +++++ .../src/Strings/de.lproj/Localizable.strings | 9 +++++ .../src/Strings/en.lproj/Localizable.strings | 9 +++++ .../src/Strings/es.lproj/Localizable.strings | 9 +++++ .../src/Strings/fr.lproj/Localizable.strings | 9 +++++ .../src/Strings/id.lproj/Localizable.strings | 9 +++++ .../src/Strings/it.lproj/Localizable.strings | 9 +++++ .../src/Strings/ja.lproj/Localizable.strings | 9 +++++ .../src/Strings/ko.lproj/Localizable.strings | 9 +++++ .../src/Strings/nl.lproj/Localizable.strings | 9 +++++ .../src/Strings/pt.lproj/Localizable.strings | 9 +++++ .../src/Strings/ru.lproj/Localizable.strings | 9 +++++ .../src/Strings/sv.lproj/Localizable.strings | 9 +++++ .../Strings/zh-Hans.lproj/Localizable.strings | 9 +++++ .../Strings/zh-Hant.lproj/Localizable.strings | 9 +++++ .../RootModals/SendViewController.swift | 19 ++++++++- loafwallet/src/Views/AlertView.swift | 17 +++++--- loafwallet/src/Views/GradientView.swift | 14 +++++++ 28 files changed, 287 insertions(+), 17 deletions(-) create mode 100644 loafwallet/Assets.xcassets/colorImageBlue.imageset/Contents.json create mode 100644 loafwallet/Assets.xcassets/colorImageBlue.imageset/colorBlue.png create mode 100644 loafwallet/Assets.xcassets/colorLitewalletBlue.colorset/Contents.json diff --git a/loafwallet/Assets.xcassets/Contents.json b/loafwallet/Assets.xcassets/Contents.json index da4a164c9..73c00596a 100644 --- a/loafwallet/Assets.xcassets/Contents.json +++ b/loafwallet/Assets.xcassets/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/loafwallet/Assets.xcassets/colorImageBlue.imageset/Contents.json b/loafwallet/Assets.xcassets/colorImageBlue.imageset/Contents.json new file mode 100644 index 000000000..0175c4c94 --- /dev/null +++ b/loafwallet/Assets.xcassets/colorImageBlue.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "colorBlue.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/loafwallet/Assets.xcassets/colorImageBlue.imageset/colorBlue.png b/loafwallet/Assets.xcassets/colorImageBlue.imageset/colorBlue.png new file mode 100644 index 0000000000000000000000000000000000000000..88d24f69d9d3b55611637d81230b329dd1d67763 GIT binary patch literal 1702 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1SGeyEo=o+jKx9jP7LeL$-D$|j-^I;ruq6Z zXaU(A3~Y=-49p-UK*+!-#lQ+?GcbfPO2gT4j2ciiKrAz-EX5*_#$HBJ5wl1UIi@0W*RP zRL5XsU}R`z07S+LhNe~~hE_%f409}1t^%bv3p^r=85p>QL70(Y)*J~22Idu+ArU1J zzCKpT`MG+DDfvmMdKI|^Ad?tuDy)Fa+|-gpg^Jvqyke^gTP3gxD1^l#~=$>Fbx5m+O@q>*W`v z>l<2HTIw4Z=^Gj80#)c1SLT%@R_NvxD?a#8ycO zWDy)d+*y*DhOjBG80syc2lYWR`i6Q2`q;FkR%GJP29m+44H!mnZ=qOLkyrrH1P%;{ z8*M-?unI~o&d(_Yc_lP2v&7EG2JA3&VT8{hx*`zT?97b}fI#06L_&2VOQUP`FUm{> z1}n%$J42{?WHEI0k@&4bmPXPF3MMOXVvcml%uUTJ23uzYbRbq4tU4ob>O_)3(g_TG zE9atAQ058A&(E>LmX~bw(N$qHAk`(YB-IX-e{>Ci$T$R+f1;4|LlmKD_XXyKl*E!m zYzCNE8JR*2Kv4!Y!bTsImXXpnB;$ZZfjP&H3urei7us>{HJYdfEH{pNx;TbZFuuLC zF_$S&#MN<6j Void)? + + var shouldClearAddressField: (() -> Void)? //MARK: - Private Variables private var ltcAddress = "" - private var dateFormatter: DateFormatter? { didSet { @@ -49,6 +50,9 @@ class UnstoppableDomainViewModel: ObservableObject { isDomainResolving = true + //Clear existing LTC Address to avoid confusion + self.shouldClearAddressField?() + // Added timing peroformance probes to see what the average time is let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" @@ -60,7 +64,7 @@ class UnstoppableDomainViewModel: ObservableObject { self.resolveUDAddress(domainName: searchString) ///Fallback resolution: Set in case it takes a longer time to resolve. - DispatchQueue.main.asyncAfter(deadline: .now() + 12) { + DispatchQueue.main.asyncAfter(deadline: .now() + 5) { self.didResolveUDAddress?(self.ltcAddress) self.isDomainResolving = false } diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index 0b159d9bd..c4b4a3e16 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -99,7 +99,7 @@ enum S { enum UnstoppableDomains { static let placeholder = NSLocalizedString("Send.UnstoppableDomains.placeholder", value: "**Enter a .crypto or .zil domain**", comment: "Enter a .crypto or .zil domain") - + static let lookup = NSLocalizedString("Send.UnstoppableDomains.lookup", value: "**Lookup**", comment: "Lookup") } } @@ -421,6 +421,8 @@ enum S { static let pinSet = NSLocalizedString("Alerts.pinSet", value: "**PIN Set**", comment: "Alert Header label (the PIN was set)") static let paperKeySet = NSLocalizedString("Alerts.paperKeySet", value: "**Paper Key Set**", comment: "Alert Header Label (the paper key was set)") static let sendSuccess = NSLocalizedString("Alerts.sendSuccess", value: "**Send Confirmation**", comment: "Send success alert header label (confirmation that the send happened)") + static let resolvedSuccess = NSLocalizedString("Alerts.resolvedSuccess", value: "**Resolved Success**", comment: "Resolved Success") + static let resolvedSuccessSubheader = NSLocalizedString("Alerts.resolvedSuccessSubheader", value: "Resolved", comment: "Resolved Success subheader") static let sendFailure = NSLocalizedString("Alerts.sendFailure", value: "**Send failed**", comment: "Send failure alert header label (the send failed to happen)") static let paperKeySetSubheader = NSLocalizedString("Alerts.paperKeySetSubheader", value: "**Awesome!**", comment: "Alert Subheader label (playfully positive)") static let sendSuccessSubheader = NSLocalizedString("Alerts.sendSuccessSubheader", value: "**Money Sent!**", comment: "Send success alert subheader label (e.g. the money was sent)") @@ -605,9 +607,7 @@ enum S { static let alertDeleteTitle = NSLocalizedString("WipeWallet.alertDeleteTitle", value: "**Delet Database**", comment: "Delete database title") static let deleteMessageTitle = NSLocalizedString("WipeWallet.deleteMessageTitle", value: "**This deletes the database but retains the PIN and phrase. You will be asked to confirm your existing PIN, seed and will re-sync the new db**", comment: "Delete database message") static let deleteSync = NSLocalizedString("WipeWallet.deleteSync", value: "**Delete & Sync**", comment: "Delete and sync") - - - + } enum FeeSelector { diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 53b69418b..902738b6c 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -320,6 +320,11 @@ class ModalPresenter : Subscriber, Trackable { sendVC.onPublishSuccess = { [weak self] in self?.presentAlert(.sendSuccess, completion: {}) } + + sendVC.onResolvedSuccess = { [weak self] in + self?.presentAlert(.resolvedSuccess, completion: {}) + } + return root } diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 25195ca00..16311cde3 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1281,3 +1281,12 @@ /* Litewallet Partners */ "Settings.litewallet.partners" = "Litewallet partners"; + +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Domain Resolution"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Address was resolved!"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Lookup"; diff --git a/loafwallet/src/Strings/ar.lproj/Localizable.strings b/loafwallet/src/Strings/ar.lproj/Localizable.strings index ab4ba6291..c47cc6913 100644 --- a/loafwallet/src/Strings/ar.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ar.lproj/Localizable.strings @@ -1234,6 +1234,12 @@ /* Corruption Error alert title */ "Alert.corruptionMessage" = ""; +/* Resolved Success */ +"Alerts.resolvedSuccess" = ""; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = ""; + /* Luxury fee */ "FeeSelector.luxury" = ""; @@ -1249,6 +1255,9 @@ /* Enter LTC Address */ "Send.enterLTCAddress" = ""; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = ""; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = ""; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index e528ef11b..90f1a4b9e 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN indstillet"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Domæneopløsning"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Din adresse blev løst!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Afsendelse mislykkedes"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d af %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Kig op"; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index 348a051ff..dc8596cca 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN festgelegt"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Domänenauflösung"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Die Adresse wurde aufgelöst!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Versand fehlgeschlagen"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d von %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Nachsehen"; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index fbc59048b..67c365bb4 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN Set"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Domain Resolution"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Address was resolved!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Send failed"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d of %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Lookup"; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 7c7e197ef..cd8e1cc88 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "Conjunto de PIN"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Resolución de dominio"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "¡Tu dirección fue resuelta!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Error en el envío"; @@ -1267,3 +1273,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d de %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Buscar"; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index f1a8dcb3e..ddf9af3bd 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "Ensemble PIN"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Résolution de domaine"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "L'adresse a été résolue!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Échec de l'envoi"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d de %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Chercher"; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 42573b3d6..684d57217 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "Set PIN"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Resolusi Domain"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Alamatnya sudah teratasi!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Pengiriman gagal"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d dari %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Lihatlah"; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index 774c68fda..e08c253ea 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN Impostato"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Risoluzione del dominio"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Il tuo indirizzo è stato risolto!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Invio fallito"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d di %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Consultare"; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index f4ea3138d..b43c40282 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PINコードのセット"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "ドメイン解決"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "あなたの住所は解決されました!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "送金に失敗しました"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%2$dの%1$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "調べる"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index a9d0e2101..db7f6d8a3 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN 준비"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "도메인 확인"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "주소가 확인되었습니다!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "보내기 실패함"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%2$d의 %1$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "조회"; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index a536fb9dc..861e83af1 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN Set."; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Domeinresolutie"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Uw adres is opgelost!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Zending mislukt"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d van %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Opzoeken"; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index 8adb83b6c..0c312f7ac 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -62,6 +62,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN Definido"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Resolução de Domínio"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Seu endereço foi resolvido!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Falha no envio"; @@ -1267,3 +1273,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d de %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Olho para cima"; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index 63b81e63c..322754323 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN-код задан"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Разрешение домена"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Ваш адрес решен!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Ошибка отправки"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d из %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Искать"; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index cc2e9c21a..811da3ba6 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN-kod är inställd"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "Domänupplösning"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "Din adress har lösts!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "Sändningen misslyckades"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d av %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Slå upp"; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index f3cd372e7..c84e13705 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN 已设置"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "域解析"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "您的地址已解决!"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "发送失败"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d / %2$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "抬头"; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index fb1c4f7ac..c72fa3366 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -61,6 +61,12 @@ /* Alert Header label (the PIN was set) */ "Alerts.pinSet" = "PIN 已設定"; +/* Resolved Success */ +"Alerts.resolvedSuccess" = "域解析"; + +/* No comment provided by engineer. */ +"Alerts.resolvedSuccessSubheader" = "您的地址已解決"; + /* Send failure alert header label (the send failed to happen) */ "Alerts.sendFailure" = "寄出失敗"; @@ -1266,3 +1272,6 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%2$d 之 %1$d"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "抬頭"; diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index 72579f7b3..bcabacebe 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -24,6 +24,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track var presentScan: PresentScan? var presentVerifyPin: ((String, @escaping VerifyPinCallback)->Void)? var onPublishSuccess: (()->Void)? + var onResolvedSuccess: (()->Void)? var parentView: UIView? //ModalPresentable var initialAddress: String? var isPresentedFromLock = false @@ -179,12 +180,28 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track } } + //MARK: - Unstopplable Domain Callbacks + unstoppableCell.rootView.viewModel.shouldClearAddressField = { + + ///clear the existing textfield + self.addressCell.textField.becomeFirstResponder() + self.addressCell.textField.text = "" + } + unstoppableCell.rootView.viewModel.didResolveUDAddress = { resolvedUDAddress in + ///Paste in Unstoppable Domain resolved LTC address to textField self.addressCell.textField.becomeFirstResponder() self.addressCell.textField.isHidden = false - self.addressCell.textField.text = resolvedUDAddress + + if !resolvedUDAddress.isEmpty { + + // Toast the successful resolution + self.onResolvedSuccess?() + self.addressCell.textField.text = resolvedUDAddress + } } + } private func balanceTextForAmount(amount: Satoshis?, rate: Rate?) -> (NSAttributedString?, NSAttributedString?) { diff --git a/loafwallet/src/Views/AlertView.swift b/loafwallet/src/Views/AlertView.swift index 5a77ade05..8936e392d 100644 --- a/loafwallet/src/Views/AlertView.swift +++ b/loafwallet/src/Views/AlertView.swift @@ -12,6 +12,7 @@ enum AlertType { case pinSet(callback: () -> Void) case paperKeySet(callback: () -> Void) case sendSuccess + case resolvedSuccess case addressesCopied case sweepSuccess(callback: () -> Void) @@ -23,6 +24,8 @@ enum AlertType { return S.Alerts.paperKeySet case .sendSuccess: return S.Alerts.sendSuccess + case .resolvedSuccess: + return S.Alerts.resolvedSuccess case .addressesCopied: return S.Alerts.copiedAddressesHeader case .sweepSuccess: @@ -38,6 +41,8 @@ enum AlertType { return S.Alerts.paperKeySetSubheader case .sendSuccess: return S.Alerts.sendSuccessSubheader + case .resolvedSuccess: + return S.Alerts.resolvedSuccessSubheader case .addressesCopied: return S.Alerts.copiedAddressesSubheader case .sweepSuccess: @@ -60,6 +65,8 @@ func ==(lhs: AlertType, rhs: AlertType) -> Bool { return true case (.sendSuccess, .sendSuccess): return true + case (.resolvedSuccess, .resolvedSuccess): + return true case (.addressesCopied, .addressesCopied): return true case (.sweepSuccess(_), .sweepSuccess(_)): @@ -69,7 +76,7 @@ func ==(lhs: AlertType, rhs: AlertType) -> Bool { } } -class AlertView : UIView, GradientDrawable { +class AlertView : UIView, SolidColorDrawable { private let type: AlertType private let header = UILabel() @@ -81,7 +88,7 @@ class AlertView : UIView, GradientDrawable { init(type: AlertType) { self.type = type - self.icon = type.icon + self.icon = type.icon super.init(frame: .zero) layer.cornerRadius = 6.0 @@ -107,7 +114,7 @@ class AlertView : UIView, GradientDrawable { private func setData() { header.text = type.header header.textAlignment = .center - header.font = UIFont.customBold(size: 14.0) + header.font = UIFont.barlowBold(size: 16.0) header.textColor = .white icon.backgroundColor = .clear @@ -115,7 +122,7 @@ class AlertView : UIView, GradientDrawable { subheader.text = type.subheader subheader.textAlignment = .center - subheader.font = UIFont.customBody(size: 14.0) + subheader.font = UIFont.barlowSemiBold(size: 16.0) subheader.textColor = .white } @@ -143,7 +150,7 @@ class AlertView : UIView, GradientDrawable { } override func draw(_ rect: CGRect) { - drawGradient(rect) + drawColor(color: .liteWalletBlue, rect) } required init?(coder aDecoder: NSCoder) { diff --git a/loafwallet/src/Views/GradientView.swift b/loafwallet/src/Views/GradientView.swift index 7b4e108fd..556923aa9 100644 --- a/loafwallet/src/Views/GradientView.swift +++ b/loafwallet/src/Views/GradientView.swift @@ -40,3 +40,17 @@ class GradientView : UIView { drawGradient(rect) } } + +protocol SolidColorDrawable { + func drawColor(color: UIColor, _ rect: CGRect) +} + +extension UIView { + func drawColor(color: UIColor = .liteWalletBlue, _ rect: CGRect) { + let image = UIImageView(image: #imageLiteral(resourceName: "colorImageBlue")) + image.contentMode = .scaleToFill + addSubview(image) + image.constrain(toSuperviewEdges: nil) + sendSubview(toBack: image) + } +} From 3954e3b277c9f9c779effa00b103ba17a64bb3a8 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Fri, 8 Jan 2021 13:16:23 +0000 Subject: [PATCH 024/114] [Feature] Litecoin card v1 (#180) * [Litecoin Card] Progress Step 1 - Major work: litecoin-card TabBarView refactor - Updated UIColor for Color - SwiftUI preview devices - Working out the Nav polish - Fixed hard-coded UD lookup label with proper localizations - Commented out BitId * [Litecoin Card] Progress Step 2 - Added more localizations - Rebuilding registration view need to add keyboard - Fixed the animation for the card view - Fixed Alert name collisions to the SimplexAlert * [Litecoin Card] Progress Step 3 - Added Login views and localizations - Added partnerAPI Swift Package - Layout the registration view - Add more localizations - BUGFIX: Image missing in this branch. * [Litecoin Card] Progress Step 4 More localizations Added data Validators Final Polish for Registration View Registration View Modal wiring works * [Litecoin Card] Progress Step 5 Register works to the model Login is working Added animation for Login/Logout Login and Loogut working Added localizations More localizations * [Litecoin Card] RC 1 polishes Communcations polishing + dev cleanup Polishing the RegistrationView layout Fixed bug: https://github.com/litecoin-foundation/loafwallet-ios/issues/175 * [Litecoin Card] RC2: removed defunct script * per review comments - Ar files removal - Cleanup localizable - Removed Ar.proj files - Removed empty class - Added all Validation localization framework - Added localizations of the validations - Refactored per review notes * Bugfix- login message Added failure message localizations --- Podfile | 1 + TodayExtension/ar.lproj/MainInterface.strings | 14 - loafwallet.xcodeproj/project.pbxproj | 165 +- .../xcshareddata/swiftpm/Package.resolved | 16 + loafwallet/AnimatedCardView.swift | 66 + loafwallet/AnimatedCardViewModel.swift | 26 + loafwallet/AppDelegate.swift | 8 +- .../Assets.xcassets/MenuIcons/Contents.json | 6 +- .../BuyLitecoin.pdf | Bin .../Contents.json | 0 .../Partners/litecoincard/Contents.json | 6 + .../litecoin-card-back.imageset/Contents.json | 23 + .../litecoin-back-1x.png | Bin 0 -> 75475 bytes .../litecoin-back-2x.png | Bin 0 -> 207986 bytes .../litecoin-back-3x.png | Bin 0 -> 331002 bytes .../Contents.json | 23 + .../litecoin-card-3x.png | Bin 0 -> 225468 bytes .../litecoin-front-1x.png | Bin 0 -> 41426 bytes .../litecoin-front-2x.png | Bin 0 -> 118447 bytes .../BuyIcon.pdf | Bin .../BuyIcon.pxm | Bin .../Contents.json | 0 .../Contents.json | 0 .../history1x.png | Bin .../Contents.json | 0 .../ReceiveTabIcon.pdf | Bin .../send.imageset/Contents.json | 21 + .../send.imageset/history1x.png | Bin 0 -> 1511 bytes .../Contents.json | 0 .../SendTabIcon.pdf | Bin loafwallet/BuyCenterTableViewController.swift | 128 - loafwallet/CardLoggedInView.swift | 106 + loafwallet/CardView.swift | 248 ++ loafwallet/CardViewController.swift | 85 + loafwallet/CardViewModel.swift | 25 + loafwallet/Color+Extension.swift | 17 + loafwallet/DataValidation.swift | 139 ++ loafwallet/ForgotView.swift | 89 + loafwallet/ForgotViewModel.swift | 12 + loafwallet/LitecoinCardUser.swift | 17 + loafwallet/LoginCardAlertView.swift | 83 + loafwallet/LoginViewModel.swift | 77 + loafwallet/MainTabBarViewModel.swift | 12 + loafwallet/MainViewController.swift | 16 +- loafwallet/PartnerAPIManager.swift | 20 + loafwallet/RegistrationAlertView.swift | 92 + loafwallet/RegistrationView.swift | 360 +++ loafwallet/RegistrationViewModel.swift | 198 ++ loafwallet/Storyboards/Alerts.storyboard | 130 +- loafwallet/Storyboards/Card.storyboard | 27 + loafwallet/Storyboards/Main.storyboard | 57 +- loafwallet/Storyboards/Spend.storyboard | 551 ----- .../XIBs/SyncProgressHeaderView.xib | 14 +- loafwallet/TabBarViewController.swift | 37 +- loafwallet/TransactionsViewController.swift | 23 +- loafwallet/TransactionsViewModel.swift | 26 + loafwallet/View+Extension.swift | 44 + loafwallet/ar.lproj/BIP39Words.plist | 2054 ----------------- loafwallet/ar.lproj/LaunchScreen.strings | 1 - loafwallet/src/ApplicationController.swift | 13 +- loafwallet/src/Constants/Constants.swift | 17 + loafwallet/src/Constants/Strings.swift | 81 +- loafwallet/src/Controls/MenuButtonType.swift | 2 +- ...=> UINavigationController+Extension.swift} | 18 +- .../Extensions/UIViewController+Alerts.swift | 2 +- .../FlowControllers/StartFlowPresenter.swift | 4 +- .../src/FlowControllers/URLController.swift | 50 +- loafwallet/src/ModalPresenter.swift | 24 +- loafwallet/src/Sender.swift | 2 +- loafwallet/src/SimpleRedux/Actions.swift | 2 +- .../Strings/Base.lproj/Localizable.strings | 118 +- .../src/Strings/ar.lproj/Localizable.strings | 1277 ---------- .../src/Strings/da.lproj/Localizable.strings | 117 +- .../src/Strings/de.lproj/Localizable.strings | 117 +- .../src/Strings/en.lproj/Localizable.strings | 117 +- .../src/Strings/es.lproj/Localizable.strings | 117 +- .../src/Strings/fr.lproj/Localizable.strings | 117 +- .../src/Strings/id.lproj/Localizable.strings | 117 +- .../src/Strings/it.lproj/Localizable.strings | 117 +- .../src/Strings/ja.lproj/Localizable.strings | 117 +- .../src/Strings/ko.lproj/Localizable.strings | 117 +- .../src/Strings/nl.lproj/Localizable.strings | 117 +- .../src/Strings/pt.lproj/Localizable.strings | 117 +- .../src/Strings/ru.lproj/Localizable.strings | 117 +- .../src/Strings/sv.lproj/Localizable.strings | 117 +- .../Strings/zh-Hans.lproj/Localizable.strings | 115 +- .../Strings/zh-Hant.lproj/Localizable.strings | 117 +- .../Import/StartImportViewController.swift | 2 +- .../RootModals/SendViewController.swift | 22 +- .../UpdatePinViewController.swift | 4 +- loafwallet/src/Views/AlertView.swift | 22 +- loafwallet/src/WalletManager.swift | 3 + 92 files changed, 4106 insertions(+), 4373 deletions(-) delete mode 100644 TodayExtension/ar.lproj/MainInterface.strings create mode 100644 loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 loafwallet/AnimatedCardView.swift create mode 100644 loafwallet/AnimatedCardViewModel.swift rename loafwallet/Assets.xcassets/MenuIcons/{BuyLitecoin.imageset => buy_icon_gray.imageset}/BuyLitecoin.pdf (100%) rename loafwallet/Assets.xcassets/MenuIcons/{BuyLitecoin.imageset => buy_icon_gray.imageset}/Contents.json (100%) create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/Contents.json create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/Contents.json create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/litecoin-back-1x.png create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/litecoin-back-2x.png create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/litecoin-back-3x.png create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/Contents.json create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/litecoin-card-3x.png create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/litecoin-front-1x.png create mode 100644 loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/litecoin-front-2x.png rename loafwallet/Assets.xcassets/{BuyIcon.imageset => buy_icon.imageset}/BuyIcon.pdf (100%) rename loafwallet/Assets.xcassets/{BuyIcon.imageset => buy_icon.imageset}/BuyIcon.pxm (100%) rename loafwallet/Assets.xcassets/{BuyIcon.imageset => buy_icon.imageset}/Contents.json (100%) rename loafwallet/Assets.xcassets/{historyIcon.imageset => history_icon.imageset}/Contents.json (100%) rename loafwallet/Assets.xcassets/{historyIcon.imageset => history_icon.imageset}/history1x.png (100%) rename loafwallet/Assets.xcassets/{ReceiveButtonIcon.imageset => receive_icon.imageset}/Contents.json (100%) rename loafwallet/Assets.xcassets/{ReceiveButtonIcon.imageset => receive_icon.imageset}/ReceiveTabIcon.pdf (100%) create mode 100644 loafwallet/Assets.xcassets/send.imageset/Contents.json create mode 100644 loafwallet/Assets.xcassets/send.imageset/history1x.png rename loafwallet/Assets.xcassets/{SendButtonIcon.imageset => send_icon.imageset}/Contents.json (100%) rename loafwallet/Assets.xcassets/{SendButtonIcon.imageset => send_icon.imageset}/SendTabIcon.pdf (100%) delete mode 100644 loafwallet/BuyCenterTableViewController.swift create mode 100644 loafwallet/CardLoggedInView.swift create mode 100644 loafwallet/CardView.swift create mode 100644 loafwallet/CardViewController.swift create mode 100644 loafwallet/CardViewModel.swift create mode 100644 loafwallet/Color+Extension.swift create mode 100644 loafwallet/DataValidation.swift create mode 100644 loafwallet/ForgotView.swift create mode 100644 loafwallet/ForgotViewModel.swift create mode 100644 loafwallet/LitecoinCardUser.swift create mode 100644 loafwallet/LoginCardAlertView.swift create mode 100644 loafwallet/LoginViewModel.swift create mode 100644 loafwallet/MainTabBarViewModel.swift create mode 100644 loafwallet/PartnerAPIManager.swift create mode 100644 loafwallet/RegistrationAlertView.swift create mode 100644 loafwallet/RegistrationView.swift create mode 100644 loafwallet/RegistrationViewModel.swift create mode 100644 loafwallet/Storyboards/Card.storyboard delete mode 100644 loafwallet/Storyboards/Spend.storyboard create mode 100644 loafwallet/TransactionsViewModel.swift create mode 100644 loafwallet/View+Extension.swift delete mode 100644 loafwallet/ar.lproj/BIP39Words.plist delete mode 100644 loafwallet/ar.lproj/LaunchScreen.strings rename loafwallet/src/Extensions/{UINavigationController+BRAdditions.swift => UINavigationController+Extension.swift} (92%) delete mode 100644 loafwallet/src/Strings/ar.lproj/Localizable.strings diff --git a/Podfile b/Podfile index 02798405e..d148c1fc1 100644 --- a/Podfile +++ b/Podfile @@ -10,6 +10,7 @@ def shared_pods pod 'Firebase/Crashlytics' pod 'Firebase/Analytics' pod 'UnstoppableDomainsResolution', '~> 0.1.6' + pod 'KeychainAccess', '~> 4.2' # add after v2.9.0 pod 'SwiftLint' end diff --git a/TodayExtension/ar.lproj/MainInterface.strings b/TodayExtension/ar.lproj/MainInterface.strings deleted file mode 100644 index 7456566de..000000000 --- a/TodayExtension/ar.lproj/MainInterface.strings +++ /dev/null @@ -1,14 +0,0 @@ -/* Class = "UIButton"; normalTitle = "setup wallet"; ObjectID = "fgE-Q8-uG8"; */ -"fgE-Q8-uG8.normalTitle" = "setup wallet"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "gQm-B2-ZXE"; */ -"gQm-B2-ZXE.text" = "Label"; - -/* Class = "UILabel"; text = "scan QR code"; ObjectID = "JgG-Ah-UZk"; */ -"JgG-Ah-UZk.text" = "scan QR code"; - -/* Class = "UILabel"; text = "receive"; ObjectID = "KJN-zr-IQB"; */ -"KJN-zr-IQB.text" = "receive"; - -/* Class = "UILabel"; text = "send"; ObjectID = "QMM-JV-cTG"; */ -"QMM-JV-cTG.text" = "send"; diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 3304ec8b6..1e3419f6c 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -81,7 +81,7 @@ 24313CA123824F5800A83F69 /* Receive.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9623824F5800A83F69 /* Receive.storyboard */; }; 24313CA323824F5800A83F69 /* Send.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9723824F5800A83F69 /* Send.storyboard */; }; 24313CA523824F5800A83F69 /* Buy.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9823824F5800A83F69 /* Buy.storyboard */; }; - 24313CA723824F5800A83F69 /* Spend.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9923824F5800A83F69 /* Spend.storyboard */; }; + 24313CA723824F5800A83F69 /* Card.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9923824F5800A83F69 /* Card.storyboard */; }; 24313CAA23824F9800A83F69 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313CA823824F9800A83F69 /* Main.storyboard */; }; 24393B5C23C259400075218D /* Phrase.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24393B5B23C259400075218D /* Phrase.storyboard */; }; 24470E2123A5DA9700ADDA27 /* APIManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2023A5DA9700ADDA27 /* APIManagerTests.swift */; }; @@ -117,7 +117,6 @@ 24AF00FE221B331D00FF636F /* WarningConfirmation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24AF00FC221B331D00FF636F /* WarningConfirmation.storyboard */; }; 24AF0101221B349100FF636F /* WarningConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24AF00FF221B349100FF636F /* WarningConfirmationViewController.swift */; }; 24B523AD238A53DC0030594D /* BIP39Words.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24B523AF238A53DC0030594D /* BIP39Words.plist */; }; - 24B8FAC12160497C00A155B1 /* BuyCenterTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B8FAC02160497B00A155B1 /* BuyCenterTableViewController.swift */; }; 24B8FAC4216128A000A155B1 /* PartnerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B8FAC3216128A000A155B1 /* PartnerData.swift */; }; 24B8FAD22162B10200A155B1 /* BuyCenterWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B8FAD12162B10200A155B1 /* BuyCenterWebViewController.swift */; }; 24B8FAD72162B6FB00A155B1 /* bitrefill_index.html in Resources */ = {isa = PBXBuildFile; fileRef = 24B8FAD62162B6FB00A155B1 /* bitrefill_index.html */; }; @@ -268,13 +267,34 @@ 75A2A8141DA5936F00A983D8 /* TodayExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 75A2A8081DA5936F00A983D8 /* TodayExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 75C735AA1DAA1B9C00251ECF /* libunbound.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD4121DAA0E3E0075898E /* libunbound.c */; }; BB66CB271F7F2FD1936AA04B /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FEAAB89A265CC043F53CC51 /* Pods_loafwalletTests.framework */; }; + C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */ = {isa = PBXBuildFile; productRef = C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */; }; + C30AFB642598FFB200CDCF69 /* PartnerAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */; }; + C3270B99259BF7F20073DA7B /* LitecoinCardUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */; }; + C32DAE0725925B7E003FC978 /* Color+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DAE0625925B7E003FC978 /* Color+Extension.swift */; }; + C32DAE9125929492003FC978 /* CardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DAE9025929492003FC978 /* CardViewController.swift */; }; + C32DC793259396AB00A7FDB4 /* CardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DC792259396AB00A7FDB4 /* CardViewModel.swift */; }; + C32DC79C2593971500A7FDB4 /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DC79B2593971500A7FDB4 /* CardView.swift */; }; + C32DC7AC2593B5C900A7FDB4 /* AnimatedCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DC7AB2593B5C900A7FDB4 /* AnimatedCardView.swift */; }; + C32DC7B52593B61F00A7FDB4 /* AnimatedCardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DC7B42593B61F00A7FDB4 /* AnimatedCardViewModel.swift */; }; + C354C45A258FA9C000675E0E /* MainTabBarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C354C459258FA9C000675E0E /* MainTabBarViewModel.swift */; }; + C354C4632590059500675E0E /* TransactionsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C354C4622590059500675E0E /* TransactionsViewModel.swift */; }; C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD222574070A002BB9BB /* PartnersView.swift */; }; C35ABD332574073F002BB9BB /* PartnersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD322574073F002BB9BB /* PartnersViewModel.swift */; }; C35ABD4325741E19002BB9BB /* ResolutionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD4225741E19002BB9BB /* ResolutionModel.swift */; }; + C379F228259B9BF000B25883 /* RegistrationAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C379F227259B9BF000B25883 /* RegistrationAlertView.swift */; }; + C3A4647D259A646A00D74D81 /* DataValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A4647C259A646A00D74D81 /* DataValidation.swift */; }; C3B7C3B9255EABBF00E98A64 /* SupportSafariViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */; }; C3B7C3C2255EAF1200E98A64 /* SupportSafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */; }; C3B7C3EE255FF59200E98A64 /* ConstantsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3ED255FF59200E98A64 /* ConstantsTests.swift */; }; C3B7C43F25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C43E25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift */; }; + C3BD49B72595420A00D97079 /* RegistrationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD49B62595420A00D97079 /* RegistrationViewModel.swift */; }; + C3BD49C02595423400D97079 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD49BF2595423400D97079 /* RegistrationView.swift */; }; + C3BD49C925954A1B00D97079 /* ForgotView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD49C825954A1B00D97079 /* ForgotView.swift */; }; + C3BD49D225954A3200D97079 /* ForgotViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD49D125954A3200D97079 /* ForgotViewModel.swift */; }; + C3BD4A4A2597542700D97079 /* LoginCardAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD4A492597542700D97079 /* LoginCardAlertView.swift */; }; + C3BD4A5325975C6000D97079 /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD4A5225975C6000D97079 /* View+Extension.swift */; }; + C3BD4A6A2597E1E900D97079 /* CardLoggedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD4A692597E1E900D97079 /* CardLoggedInView.swift */; }; + C3BFD349259E31C100136837 /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BFD348259E31C100136837 /* LoginViewModel.swift */; }; C3D4379F2566EA3E00F423E1 /* LWActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */; }; C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */; }; C3D783B72565EA6B0004FF70 /* UnstoppableDomainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */; }; @@ -382,7 +402,7 @@ CEBF33041DDE17A600348FC6 /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBF33031DDE17A600348FC6 /* Transaction.swift */; }; CEC4CF071F0C48DD00E5C82E /* StartWipeWalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC4CF061F0C48DD00E5C82E /* StartWipeWalletViewController.swift */; }; CEC4CF091F0C84AB00E5C82E /* UIViewController+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC4CF081F0C84AB00E5C82E /* UIViewController+Alerts.swift */; }; - CEC6AA391DEE10BA00EE5AFD /* UINavigationController+BRAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC6AA381DEE10BA00EE5AFD /* UINavigationController+BRAdditions.swift */; }; + CEC6AA391DEE10BA00EE5AFD /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC6AA381DEE10BA00EE5AFD /* UINavigationController+Extension.swift */; }; CEC6AA3B1DEE4EB000EE5AFD /* CGRect+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC6AA3A1DEE4EB000EE5AFD /* CGRect+Additions.swift */; }; CEC6AA3D1DEE687000EE5AFD /* RadialGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC6AA3C1DEE687000EE5AFD /* RadialGradientView.swift */; }; CEC6AA401DEFC87300EE5AFD /* SendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC6AA3F1DEFC87300EE5AFD /* SendViewController.swift */; }; @@ -740,7 +760,7 @@ 24313C9623824F5800A83F69 /* Receive.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Receive.storyboard; sourceTree = ""; }; 24313C9723824F5800A83F69 /* Send.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Send.storyboard; sourceTree = ""; }; 24313C9823824F5800A83F69 /* Buy.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Buy.storyboard; sourceTree = ""; }; - 24313C9923824F5800A83F69 /* Spend.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Spend.storyboard; sourceTree = ""; }; + 24313C9923824F5800A83F69 /* Card.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Card.storyboard; sourceTree = ""; }; 24313CA823824F9800A83F69 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 2437530C238AE08100E1B2AE /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = nl; path = nl.lproj/BIP39Words.plist; sourceTree = ""; }; 2437530D238AE08200E1B2AE /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = da; path = da.lproj/BIP39Words.plist; sourceTree = ""; }; @@ -794,7 +814,6 @@ 24AF00FF221B349100FF636F /* WarningConfirmationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarningConfirmationViewController.swift; sourceTree = ""; }; 24B523AE238A53DC0030594D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = en.lproj/BIP39Words.plist; sourceTree = ""; }; 24B523B0238A53E40030594D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "zh-Hans"; path = "zh-Hans.lproj/BIP39Words.plist"; sourceTree = ""; }; - 24B8FAC02160497B00A155B1 /* BuyCenterTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuyCenterTableViewController.swift; sourceTree = ""; }; 24B8FAC3216128A000A155B1 /* PartnerData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnerData.swift; sourceTree = ""; }; 24B8FAD12162B10200A155B1 /* BuyCenterWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuyCenterWebViewController.swift; sourceTree = ""; }; 24B8FAD62162B6FB00A155B1 /* bitrefill_index.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = bitrefill_index.html; sourceTree = ""; }; @@ -1420,13 +1439,33 @@ 93035AB774472BF9805FD3F9 /* Pods-loafwallet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.debug.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.debug.xcconfig"; sourceTree = ""; }; 9AA160F2A4C1674AC8595E65 /* Pods-loafwalletTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.debug.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.debug.xcconfig"; sourceTree = ""; }; 9C4905F581557D8FD607EB73 /* Pods-loafwallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.release.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.release.xcconfig"; sourceTree = ""; }; + C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnerAPIManager.swift; sourceTree = ""; }; + C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LitecoinCardUser.swift; sourceTree = ""; }; + C32DAE0625925B7E003FC978 /* Color+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = ""; }; + C32DAE9025929492003FC978 /* CardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardViewController.swift; sourceTree = ""; }; + C32DC792259396AB00A7FDB4 /* CardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardViewModel.swift; sourceTree = ""; }; + C32DC79B2593971500A7FDB4 /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = ""; }; + C32DC7AB2593B5C900A7FDB4 /* AnimatedCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedCardView.swift; sourceTree = ""; }; + C32DC7B42593B61F00A7FDB4 /* AnimatedCardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedCardViewModel.swift; sourceTree = ""; }; + C354C459258FA9C000675E0E /* MainTabBarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewModel.swift; sourceTree = ""; }; + C354C4622590059500675E0E /* TransactionsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsViewModel.swift; sourceTree = ""; }; C35ABD222574070A002BB9BB /* PartnersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersView.swift; sourceTree = ""; }; C35ABD322574073F002BB9BB /* PartnersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersViewModel.swift; sourceTree = ""; }; C35ABD4225741E19002BB9BB /* ResolutionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResolutionModel.swift; sourceTree = ""; }; + C379F227259B9BF000B25883 /* RegistrationAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationAlertView.swift; sourceTree = ""; }; + C3A4647C259A646A00D74D81 /* DataValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataValidation.swift; sourceTree = ""; }; C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportSafariViewModel.swift; sourceTree = ""; }; C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportSafariView.swift; sourceTree = ""; }; C3B7C3ED255FF59200E98A64 /* ConstantsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsTests.swift; sourceTree = ""; }; C3B7C43E25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportLitecoinFoundationViewModelTests.swift; sourceTree = ""; }; + C3BD49B62595420A00D97079 /* RegistrationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationViewModel.swift; sourceTree = ""; }; + C3BD49BF2595423400D97079 /* RegistrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationView.swift; sourceTree = ""; }; + C3BD49C825954A1B00D97079 /* ForgotView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForgotView.swift; sourceTree = ""; }; + C3BD49D125954A3200D97079 /* ForgotViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForgotViewModel.swift; sourceTree = ""; }; + C3BD4A492597542700D97079 /* LoginCardAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginCardAlertView.swift; sourceTree = ""; }; + C3BD4A5225975C6000D97079 /* View+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extension.swift"; sourceTree = ""; }; + C3BD4A692597E1E900D97079 /* CardLoggedInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardLoggedInView.swift; sourceTree = ""; }; + C3BFD348259E31C100136837 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = ""; }; C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LWActivityIndicator.swift; sourceTree = ""; }; C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainView.swift; sourceTree = ""; }; C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainViewModel.swift; sourceTree = ""; }; @@ -1553,7 +1592,7 @@ CEBF33031DDE17A600348FC6 /* Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Transaction.swift; path = src/ViewModels/Transaction.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; CEC4CF061F0C48DD00E5C82E /* StartWipeWalletViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StartWipeWalletViewController.swift; path = src/ViewControllers/StartWipeWalletViewController.swift; sourceTree = ""; }; CEC4CF081F0C84AB00E5C82E /* UIViewController+Alerts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIViewController+Alerts.swift"; path = "src/Extensions/UIViewController+Alerts.swift"; sourceTree = ""; }; - CEC6AA381DEE10BA00EE5AFD /* UINavigationController+BRAdditions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UINavigationController+BRAdditions.swift"; path = "src/Extensions/UINavigationController+BRAdditions.swift"; sourceTree = ""; }; + CEC6AA381DEE10BA00EE5AFD /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UINavigationController+Extension.swift"; path = "src/Extensions/UINavigationController+Extension.swift"; sourceTree = ""; }; CEC6AA3A1DEE4EB000EE5AFD /* CGRect+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "CGRect+Additions.swift"; path = "src/Extensions/CGRect+Additions.swift"; sourceTree = ""; }; CEC6AA3C1DEE687000EE5AFD /* RadialGradientView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RadialGradientView.swift; path = src/Views/RadialGradientView.swift; sourceTree = ""; }; CEC6AA3F1DEFC87300EE5AFD /* SendViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = SendViewController.swift; path = src/ViewControllers/RootModals/SendViewController.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; @@ -1659,6 +1698,7 @@ 22A9A9601DF61FD8000F0016 /* CoreLocation.framework in Frameworks */, 22A9A95E1DF61FD0000F0016 /* PushKit.framework in Frameworks */, 223DB21B1DF69F0F0076A151 /* libbz2.framework in Frameworks */, + C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */, 752FB04D1DF8BF4B009086FB /* sqlite3.framework in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, DC03CB1EE9228BC37FA36F54 /* Pods_loafwallet.framework in Frameworks */, @@ -2150,7 +2190,7 @@ 24313C9623824F5800A83F69 /* Receive.storyboard */, 24313C9723824F5800A83F69 /* Send.storyboard */, 24393B5B23C259400075218D /* Phrase.storyboard */, - 24313C9923824F5800A83F69 /* Spend.storyboard */, + 24313C9923824F5800A83F69 /* Card.storyboard */, 24313C9323824F5700A83F69 /* Transactions.storyboard */, 24DFCE6723B89CDE001F17F8 /* Settings.storyboard */, 24AF00FC221B331D00FF636F /* WarningConfirmation.storyboard */, @@ -2186,7 +2226,6 @@ 24C516502158820E007CE038 /* Buy */ = { isa = PBXGroup; children = ( - 24B8FAC02160497B00A155B1 /* BuyCenterTableViewController.swift */, 24B8FAD12162B10200A155B1 /* BuyCenterWebViewController.swift */, 248BFE2323AAD53700CE1A71 /* BuyTableViewController.swift */, 248BFE2523AB302200CE1A71 /* BuyWKWebViewController.swift */, @@ -3026,15 +3065,20 @@ path = Modules/sqlite3; sourceTree = ""; }; + C3270B97259BF7BE0073DA7B /* CardModels */ = { + isa = PBXGroup; + children = ( + C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */, + ); + name = CardModels; + sourceTree = ""; + }; C35ABD07257404C6002BB9BB /* SwiftUI+UIKit */ = { isa = PBXGroup; children = ( C35ABD08257404D2002BB9BB /* Partners */, C35ABD0925740518002BB9BB /* About */, - C3F55643255A1916005F786F /* SupportLitecoinFoundation */, C3D783A52565EA1E0004FF70 /* Unstoppable */, - C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, - C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */, C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */, ); name = "SwiftUI+UIKit"; @@ -3110,6 +3154,7 @@ 24C516502158820E007CE038 /* Buy */, CE760ED71E55F9E000EFAC2B /* SecurityCenter */, CE20C9061DBC587200C8397A /* StartViewController.swift */, + C32DAE9025929492003FC978 /* CardViewController.swift */, 2494038023AF208F00369261 /* PromptModalViewController.swift */, CEAA9E981DC262800066731D /* ConfirmPaperPhraseViewController.swift */, CEF3E8351DE60222007C0A9E /* ModalNavigationController.swift */, @@ -3139,6 +3184,8 @@ isa = PBXGroup; children = ( CE20C8F51DBAF77D00C8397A /* UIViewController+BRWAdditions.swift */, + C3BD4A5225975C6000D97079 /* View+Extension.swift */, + C32DAE0625925B7E003FC978 /* Color+Extension.swift */, CE20C8FB1DBB0F3A00C8397A /* UIColor+Extension.swift */, CE20C90D1DBE52B000C8397A /* UIView+BRWAdditions.swift */, CE20C9161DBE6F2A00C8397A /* UIButton+BRWAdditions.swift */, @@ -3147,7 +3194,7 @@ CEAA9E9F1DC2F9F50066731D /* UIFont+BRWAdditions.swift */, CE92F9F31DED59E80046B516 /* UIView+AnimationAdditions.swift */, CE92F9F51DEDF6890046B516 /* UIViewControllerContextTransitioning+BRAdditions.swift */, - CEC6AA381DEE10BA00EE5AFD /* UINavigationController+BRAdditions.swift */, + CEC6AA381DEE10BA00EE5AFD /* UINavigationController+Extension.swift */, CEC6AA3A1DEE4EB000EE5AFD /* CGRect+Additions.swift */, CE25BF901DF9ADE700BC67B6 /* UIImage+Utils.swift */, CE9057171DFF0FA8006BA848 /* String+Additions.swift */, @@ -3196,8 +3243,10 @@ isa = PBXGroup; children = ( C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, + C3BD4A692597E1E900D97079 /* CardLoggedInView.swift */, C3F55643255A1916005F786F /* SupportLitecoinFoundation */, 24BA90C52410129E001E3825 /* FeeSelectorView.swift */, + C32DC7AB2593B5C900A7FDB4 /* AnimatedCardView.swift */, CE6BCF5C1EE9E89A0029849C /* CustomTitleView.swift */, CED341321EF5A5C00014912A /* InAppAlert.swift */, CE3645461E7B40280079D0CF /* PinPadCells */, @@ -3206,10 +3255,12 @@ CEF3E8301DE554F1007C0A9E /* AnimatedIcons */, CEC6AA471DEFCFCD00EE5AFD /* Controls */, CE20C9101DBE5B6F00C8397A /* Circle.swift */, + C3BD4A492597542700D97079 /* LoginCardAlertView.swift */, CEF3E82A1DE51612007C0A9E /* GradientCircle.swift */, CEAA9E961DC18E1F0066731D /* PhraseView.swift */, CEAA9E9A1DC2B9320066731D /* ConfirmPhrase.swift */, CEAA9EA71DC3342E0066731D /* PinView.swift */, + C379F227259B9BF000B25883 /* RegistrationAlertView.swift */, CEBF32ED1DDBC30000348FC6 /* ShadowButton.swift */, CEF3E82C1DE528BF007C0A9E /* AlertView.swift */, CEF3E82E1DE534C5007C0A9E /* GradientView.swift */, @@ -3228,6 +3279,7 @@ CEEC70801E90C04700EF788E /* SeparatorCell.swift */, CEEC70891E945E3B00EF788E /* UnEditableTextView.swift */, CEEC708D1E954AAB00EF788E /* AboutCell.swift */, + C3BD49C825954A1B00D97079 /* ForgotView.swift */, CEEC70911E95DA4400EF788E /* GradientSwitch.swift */, CE83DE291E9EB7F600D07636 /* SendAmountCell.swift */, CEE20C2C1EA288FA0086F724 /* UpdatingLabel.swift */, @@ -3235,8 +3287,10 @@ CE5E6C931EB7964900A476DB /* WalletDisabledView.swift */, CE8F0AE21EB91BB500AA7642 /* SearchHeaderView.swift */, CE4C1CC51ED65D830063E184 /* DrawableCircle.swift */, + C3BD49BF2595423400D97079 /* RegistrationView.swift */, CEBF292D1EF99E55005C330A /* LightWeightAlert.swift */, 2494037C23AE0C7100369261 /* SyncProgressHeaderView.swift */, + C32DC79B2593971500A7FDB4 /* CardView.swift */, ); name = Views; sourceTree = ""; @@ -3261,12 +3315,15 @@ CE6D0E5A1E14BF8400137DF1 /* Models */ = { isa = PBXGroup; children = ( + C3270B97259BF7BE0073DA7B /* CardModels */, CE20C8FF1DBBFFDD00C8397A /* SimpleRedux */, CE6D0E5B1E14BFA600137DF1 /* KeyboardNotificationInfo.swift */, CEE65DEF1E39056F0002994D /* Rate.swift */, 24016D8F23F913C1006A6791 /* LWAnalytics.swift */, CEEC70821E90C07C00EF788E /* Setting.swift */, + C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */, CEF61B131ED0D10000C7EA6A /* Types.swift */, + C3A4647C259A646A00D74D81 /* DataValidation.swift */, CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */, 24D91D0D2166A5480077A619 /* TestnetData.swift */, 24B8FAC3216128A000A155B1 /* PartnerData.swift */, @@ -3341,9 +3398,16 @@ isa = PBXGroup; children = ( C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */, + C3BD49D125954A3200D97079 /* ForgotViewModel.swift */, + C3BD49B62595420A00D97079 /* RegistrationViewModel.swift */, + C32DC792259396AB00A7FDB4 /* CardViewModel.swift */, + C354C459258FA9C000675E0E /* MainTabBarViewModel.swift */, CEBF33031DDE17A600348FC6 /* Transaction.swift */, CE27F9581E2C8EA300F7F7F2 /* Amount.swift */, CE124CF71E67A8E500DFA146 /* TransactionDirection.swift */, + C354C4622590059500675E0E /* TransactionsViewModel.swift */, + C32DC7B42593B61F00A7FDB4 /* AnimatedCardViewModel.swift */, + C3BFD348259E31C100136837 /* LoginViewModel.swift */, ); name = ViewModels; sourceTree = ""; @@ -3560,7 +3624,6 @@ 75A2A78E1DA5934300A983D8 /* Resources */, 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, - 24E179F123BDAC2C00F928D9 /* Swift Lint Script */, 8B664BEE6304C1815A957FC6 /* [CP] Embed Pods Frameworks */, C3D1588125666B69009BD3BC /* Mark Dev Notes */, ); @@ -3573,6 +3636,9 @@ 752FB04F1DF8BF5C009086FB /* PBXTargetDependency */, ); name = loafwallet; + packageProductDependencies = ( + C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */, + ); productName = breadwallet; productReference = 75A2A7901DA5934300A983D8 /* Litewallet.app */; productType = "com.apple.product-type.application"; @@ -3702,6 +3768,9 @@ Base, ); mainGroup = 75A2A7871DA5934300A983D8; + packageReferences = ( + C30AFB4C2598FC1B00CDCF69 /* XCRemoteSwiftPackageReference "LitewalletPartnerAPI" */, + ); productRefGroup = 75A2A7911DA5934300A983D8 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -3773,7 +3842,7 @@ 24DFCE6823B89CDE001F17F8 /* Settings.storyboard in Resources */, 24016D8E23F887C3006A6791 /* GoogleService-Info.plist in Resources */, 24393B5C23C259400075218D /* Phrase.storyboard in Resources */, - 24313CA723824F5800A83F69 /* Spend.storyboard in Resources */, + 24313CA723824F5800A83F69 /* Card.storyboard in Resources */, C3EB574C257D95B7003E3949 /* partner-keys.plist in Resources */, 75A2A79B1DA5934300A983D8 /* Assets.xcassets in Resources */, ); @@ -3827,24 +3896,6 @@ shellPath = /bin/sh; shellScript = "## This only notates strings that have yet to be localized. The Base Localizable file is wnere the change needs to be changed.\n\nif which bartycrouch > /dev/null; then\n bartycrouch update -x\n bartycrouch lint -x\nelse\n echo \"warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch\"\nfi\n"; }; - 24E179F123BDAC2C00F928D9 /* Swift Lint Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Swift Lint Script"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "# add after v2.6.0\n#\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; - }; 24E179F223BDAF8000F928D9 /* Xcode custom warnings */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -3903,7 +3954,7 @@ }; C3D1588125666B69009BD3BC /* Mark Dev Notes */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + buildActionMask = 12; files = ( ); inputFileListPaths = ( @@ -3915,9 +3966,9 @@ ); outputPaths = ( ); - runOnlyForDeploymentPostprocessing = 1; + runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos\necho \"make-xcode-nag-you-about-unfinished-todos for swift files only\"\nKEYWORDS=\"DEV|TODO|FIXME|\\?\\?\\?:|\\!\\!\\!:\"\nfind \"${SRCROOT}\" \\( -name \"*.swift\" \\) -print0 | \\\nxargs -0 egrep --with-filename --line-number --only-matching \"($KEYWORDS).*\\$\" | \\\nperl -p -e \"s/($KEYWORDS)/ warning: \\$1/\"\n"; + shellScript = "# http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos\necho \"make-xcode-nag-you-about-unfinished-todos for swift files only\"\nKEYWORDS=\"DEV|TODO|FIXME|\\?\\?\\?:|\\!\\!\\!:\"\nfind \"${SRCROOT}\" \\( -name \"*.swift\" \\) -print0 | \\\nxargs -0 egrep --with-filename --line-number --only-matching \"($KEYWORDS).*\\$\" | \\\nperl -p -e \"s/($KEYWORDS)/ warning: \\$1/\"\n\n\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -4078,6 +4129,7 @@ CEC6AA4D1DF0741100EE5AFD /* ModalDisplayable.swift in Sources */, CEE0EF521EBD14B60018DB36 /* PinTransitioningDelegate.swift in Sources */, CE45C1FD1E7650F5002C3847 /* KVStoreCoordinator.swift in Sources */, + C3A4647D259A646A00D74D81 /* DataValidation.swift in Sources */, 754AE0BC1DFE8A46007FD001 /* BRCore.swift in Sources */, 22A9A94A1DF61945000F0016 /* BRCameraPlugin.swift in Sources */, 24306797238F3DF900EBEA99 /* BartyCrouch.swift in Sources */, @@ -4105,16 +4157,19 @@ CE8644251F2C160200033129 /* ConfirmationViewController.swift in Sources */, CEE1F5631DF13E5A00D733AD /* ModalHeaderView.swift in Sources */, CE5F21DB1E4A93A500C47B8E /* LoginTransitionDelegate.swift in Sources */, + C354C45A258FA9C000675E0E /* MainTabBarViewModel.swift in Sources */, CEE659E91F664C73001FF29D /* WelcomeViewController.swift in Sources */, 24313C8723821B8C00A83F69 /* TransactionTableViewCells.swift in Sources */, 2228734F1E916FC30044BA15 /* BRAPIClient+Wallet.swift in Sources */, CEAA9EA81DC3342E0066731D /* PinView.swift in Sources */, CE1D84B61EAEB2F4002A5D7B /* UIBarButtonItem+Additions.swift in Sources */, + C3BD49C02595423400D97079 /* RegistrationView.swift in Sources */, CE4B6C1A1E219CA600CF935B /* WalletCoordinator.swift in Sources */, CE6D0E5C1E14BFA700137DF1 /* KeyboardNotificationInfo.swift in Sources */, CE20C8F21DBAF71500C8397A /* ApplicationController.swift in Sources */, 1B3F74231FFB106200CCA50C /* BiometricsSettingsViewController.swift in Sources */, CEC4CF071F0C48DD00E5C82E /* StartWipeWalletViewController.swift in Sources */, + C32DC793259396AB00A7FDB4 /* CardViewModel.swift in Sources */, 7528D2981ECF655500925DBC /* PaymentProtocol.swift in Sources */, 22A9A9491DF61945000F0016 /* BRBSPatch.swift in Sources */, 24A6DCFC2230BD9000505F44 /* WipeEmptyWalletViewController.swift in Sources */, @@ -4129,7 +4184,7 @@ CE25BF8D1DF3B8A500BC67B6 /* InViewAlert.swift in Sources */, 22A9A9511DF61945000F0016 /* TxMetaData.swift in Sources */, CE8CD8E11E31976800785E02 /* LoginViewController.swift in Sources */, - CEC6AA391DEE10BA00EE5AFD /* UINavigationController+BRAdditions.swift in Sources */, + CEC6AA391DEE10BA00EE5AFD /* UINavigationController+Extension.swift in Sources */, CECCE5B01E04AD7600D99448 /* DescriptionSendCell.swift in Sources */, CE44BA1B1F33BFC500392A1A /* NodeSelectorViewController.swift in Sources */, CE124D001E69170900DFA146 /* SyncingView.swift in Sources */, @@ -4154,8 +4209,8 @@ 2494038123AF208F00369261 /* PromptModalViewController.swift in Sources */, C3B7C3C2255EAF1200E98A64 /* SupportSafariView.swift in Sources */, CEEC70921E95DA4400EF788E /* GradientSwitch.swift in Sources */, - 24B8FAC12160497C00A155B1 /* BuyCenterTableViewController.swift in Sources */, CE0CD1591DBFBCF5004023DA /* ModalPresenter.swift in Sources */, + C30AFB642598FFB200CDCF69 /* PartnerAPIManager.swift in Sources */, CEE20C2F1EA3E5820086F724 /* BlinkingView.swift in Sources */, CEC6AA441DEFCDE900EE5AFD /* ModalViewController.swift in Sources */, 24313C8423820C4B00A83F69 /* ReceiveLTCViewController.swift in Sources */, @@ -4172,10 +4227,12 @@ C3D4379F2566EA3E00F423E1 /* LWActivityIndicator.swift in Sources */, CECCE5AE1E04AD6300D99448 /* AddressCell.swift in Sources */, CE6BCF5D1EE9E89A0029849C /* CustomTitleView.swift in Sources */, + C3BFD349259E31C100136837 /* LoginViewModel.swift in Sources */, CE83DE2A1E9EB7F600D07636 /* SendAmountCell.swift in Sources */, 22A9A9521DF61945000F0016 /* BRKVStorePlugin.swift in Sources */, CEAFC8611E5D5B0500E4FD06 /* SegmentedButton.swift in Sources */, 2427342D2381C21800E2D22F /* MainViewController.swift in Sources */, + C32DAE9125929492003FC978 /* CardViewController.swift in Sources */, 7503773D1DF57428005EB8AE /* WalletManager+Auth.swift in Sources */, 22A9A9581DF61945000F0016 /* BRWebViewController.swift in Sources */, CEC4CF091F0C84AB00E5C82E /* UIViewController+Alerts.swift in Sources */, @@ -4196,9 +4253,13 @@ C3F55645255A193D005F786F /* SupportLitecoinFoundationView.swift in Sources */, CEF61B161ED2056D00C7EA6A /* NumberFormatter+Additions.swift in Sources */, CEF3E8321DE55540007C0A9E /* CheckView.swift in Sources */, + C3BD49C925954A1B00D97079 /* ForgotView.swift in Sources */, CECCE5A91E0378FB00D99448 /* PinPadViewController.swift in Sources */, + C354C4632590059500675E0E /* TransactionsViewModel.swift in Sources */, CEF3D2DB1E8B55C80070178E /* UISlider+Gradient.swift in Sources */, + C32DAE0725925B7E003FC978 /* Color+Extension.swift in Sources */, CEC6AA4B1DEFD24C00EE5AFD /* MenuButtonType.swift in Sources */, + C3BD4A6A2597E1E900D97079 /* CardLoggedInView.swift in Sources */, 24313C752381E73200A83F69 /* TransactionManager.swift in Sources */, CE4CA7BC1EE3649100373F11 /* BRActivityView.swift in Sources */, CEC6AA421DEFC88F00EE5AFD /* ReceiveViewController.swift in Sources */, @@ -4223,7 +4284,9 @@ CE8F0AE31EB91BB500AA7642 /* SearchHeaderView.swift in Sources */, 22A9A9551DF61945000F0016 /* BRTar.swift in Sources */, CEAA9E971DC18E1F0066731D /* PhraseView.swift in Sources */, + C32DC7AC2593B5C900A7FDB4 /* AnimatedCardView.swift in Sources */, CEF3E82F1DE534C5007C0A9E /* GradientView.swift in Sources */, + C3BD49B72595420A00D97079 /* RegistrationViewModel.swift in Sources */, CE6D0F991DE8B75900BD4BCF /* DismissModalAnimator.swift in Sources */, CE4C1CC61ED65D830063E184 /* DrawableCircle.swift in Sources */, CE8CD8E31E31978100785E02 /* LoginBackgroundTriangle.swift in Sources */, @@ -4234,6 +4297,7 @@ CEAA9E991DC262800066731D /* ConfirmPaperPhraseViewController.swift in Sources */, 22A9A9591DF61945000F0016 /* Extensions.swift in Sources */, 24470E4723A6B6E900ADDA27 /* MockSeeds.swift in Sources */, + C32DC7B52593B61F00A7FDB4 /* AnimatedCardViewModel.swift in Sources */, 22A9A94C1DF61945000F0016 /* BRGeoLocationPlugin.swift in Sources */, CEAA9EA61DC3246F0066731D /* StartNavigationDelegate.swift in Sources */, 22A9A94B1DF61945000F0016 /* BRCoding.swift in Sources */, @@ -4244,6 +4308,7 @@ CEBF33041DDE17A600348FC6 /* Transaction.swift in Sources */, CEAA9E911DC0FDFE0066731D /* UIViewPropertyAnimator+BRWAdditions.swift in Sources */, 22E773041EE7813000397E0E /* Bonjour.swift in Sources */, + C3BD4A4A2597542700D97079 /* LoginCardAlertView.swift in Sources */, CEAA9EA01DC2F9F50066731D /* UIFont+BRWAdditions.swift in Sources */, CEC6AA491DEFD00100EE5AFD /* MenuButton.swift in Sources */, CEF61B121ECF52C700C7EA6A /* AmountViewController.swift in Sources */, @@ -4252,6 +4317,7 @@ CE6DCC301E6666470044257B /* NonScrollingCollectionView.swift in Sources */, 22A9A9471DF61945000F0016 /* BRAPIProxy.swift in Sources */, CE20C9011DBBFFF800C8397A /* Actions.swift in Sources */, + C3270B99259BF7F20073DA7B /* LitecoinCardUser.swift in Sources */, CE20C9191DBE7B8200C8397A /* ReduxState.swift in Sources */, CEEC70811E90C04700EF788E /* SeparatorCell.swift in Sources */, CE20C8FE1DBB133A00C8397A /* SimpleRedux.swift in Sources */, @@ -4262,6 +4328,7 @@ 22A9A9501DF61945000F0016 /* BRHTTPServer.swift in Sources */, 22A9A9531DF61945000F0016 /* BRLinkPlugin.swift in Sources */, C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */, + C379F228259B9BF000B25883 /* RegistrationAlertView.swift in Sources */, CE3D4C571EF5D5740016B1C8 /* ReachabilityMonitor.swift in Sources */, 22A9A9571DF61945000F0016 /* BRWebSocket.swift in Sources */, CE4DFB2E1E9C26DA0014009E /* ShareDataViewController.swift in Sources */, @@ -4270,6 +4337,7 @@ CE20C90C1DBC59E600C8397A /* StartFlowPresenter.swift in Sources */, CE20C8FC1DBB0F3A00C8397A /* UIColor+Extension.swift in Sources */, C3B7C3B9255EABBF00E98A64 /* SupportSafariViewModel.swift in Sources */, + C32DC79C2593971500A7FDB4 /* CardView.swift in Sources */, CEA3626A1E01150D0061FC0E /* CGContext+Additions.swift in Sources */, 22A9A9541DF61945000F0016 /* BRReplicatedKVStore.swift in Sources */, CE6B6B4A1E54C0CB00B31405 /* SecurityCenterCell.swift in Sources */, @@ -4281,6 +4349,7 @@ CE760EDD1E561DF900EFAC2B /* UpdatePinViewController.swift in Sources */, 22A9A9481DF61945000F0016 /* BRBitID.swift in Sources */, 24BA90C62410129E001E3825 /* FeeSelectorView.swift in Sources */, + C3BD49D225954A3200D97079 /* ForgotViewModel.swift in Sources */, CE9057181DFF0FA8006BA848 /* String+Additions.swift in Sources */, CED341331EF5A5C00014912A /* InAppAlert.swift in Sources */, CE47A8E01F7DA54000FF35BA /* UIScreen+Additions.swift in Sources */, @@ -4288,6 +4357,7 @@ 222C42521E904C5000078EB5 /* AssociatedObject.swift in Sources */, CEB909F51E5FE63D001804DC /* EnterPhraseViewController.swift in Sources */, CE6D0F971DE8B73A00BD4BCF /* ModalTransitionDelegate.swift in Sources */, + C3BD4A5325975C6000D97079 /* View+Extension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5394,6 +5464,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + C30AFB4C2598FC1B00CDCF69 /* XCRemoteSwiftPackageReference "LitewalletPartnerAPI" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/litecoin-foundation/LitewalletPartnerAPI.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.2.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */ = { + isa = XCSwiftPackageProductDependency; + package = C30AFB4C2598FC1B00CDCF69 /* XCRemoteSwiftPackageReference "LitewalletPartnerAPI" */; + productName = LitewalletPartnerAPI; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 75A2A7881DA5934300A983D8 /* Project object */; } diff --git a/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved b/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 000000000..48bb5fcc5 --- /dev/null +++ b/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "LitewalletPartnerAPI", + "repositoryURL": "https://github.com/litecoin-foundation/LitewalletPartnerAPI.git", + "state": { + "branch": null, + "revision": "3dc7a74f5c4a3dd054b5eaacfe68909e68e99766", + "version": "0.3.0" + } + } + ] + }, + "version": 1 +} diff --git a/loafwallet/AnimatedCardView.swift b/loafwallet/AnimatedCardView.swift new file mode 100644 index 000000000..a847d8452 --- /dev/null +++ b/loafwallet/AnimatedCardView.swift @@ -0,0 +1,66 @@ +// +// AnimatedCardView.swift +// loafwallet +// +// Created by Kerry Washington on 12/23/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct AnimatedCardView: View { + + @ObservedObject + var viewModel: AnimatedCardViewModel + + @State private var didDropCard = false + + @Binding + var isLoggedIn: Bool + + init(viewModel: AnimatedCardViewModel, isLoggedIn: Binding) { + _isLoggedIn = isLoggedIn + self.viewModel = viewModel + } + + var body: some View { + + if isLoggedIn { + Image(viewModel.imageFront) + .resizable() + .aspectRatio(contentMode: .fit) + .onAppear() { + withAnimation { + viewModel.dropOffset = 0.0 + } + } + .padding() + .shadow(color: .gray, radius: 6, x: 4, y: 4) + } else { + Image(viewModel.imageFront) + .resizable() + .aspectRatio(contentMode: .fit) + .rotation3DEffect(.degrees(viewModel.rotateIn3D ? -20 : 20), axis: (x: 0, y: 1, z: 0)) + .animation(.easeInOut(duration: 0.5)) + .offset(x: 0.0, y: CGFloat(viewModel.dropOffset)) + .onAppear() { + viewModel.rotateIn3D = true + withAnimation { + viewModel.dropOffset = 0.0 + } + } + .padding() + .shadow(color: .gray, radius: 6, x: 4, y: 4) + } + } + +} + +struct AnimatedCardView_Previews: PreviewProvider { + + static let viewModel = AnimatedCardViewModel() + + static var previews: some View { + AnimatedCardView(viewModel: viewModel, isLoggedIn: .constant(true)) + } +} diff --git a/loafwallet/AnimatedCardViewModel.swift b/loafwallet/AnimatedCardViewModel.swift new file mode 100644 index 000000000..14bbba940 --- /dev/null +++ b/loafwallet/AnimatedCardViewModel.swift @@ -0,0 +1,26 @@ +// +// AnimatedCardViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 12/23/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import UIKit + +class AnimatedCardViewModel: ObservableObject { + + @Published + var rotateIn3D = false + + @Published + var isLoggedIn = false + + @Published + var imageFront = "litecoin-card-front" + + var dropOffset: CGFloat = -200.0 + + init() { } +} diff --git a/loafwallet/AppDelegate.swift b/loafwallet/AppDelegate.swift index d0eb0243f..9f3196847 100644 --- a/loafwallet/AppDelegate.swift +++ b/loafwallet/AppDelegate.swift @@ -24,6 +24,7 @@ // THE SOFTWARE. import UIKit +import SwiftUI import LocalAuthentication import Firebase @@ -34,10 +35,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let applicationController = ApplicationController() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + setFirebaseConfiguration() + UIView.swizzleSetFrame() + applicationController.launch(application: application, window: self.window, options: launchOptions) + LWAnalytics.logEventWithParameters(itemName:._20191105_AL) + return true } @@ -95,4 +101,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate { FirebaseApp.configure() } } -} +} diff --git a/loafwallet/Assets.xcassets/MenuIcons/Contents.json b/loafwallet/Assets.xcassets/MenuIcons/Contents.json index da4a164c9..73c00596a 100644 --- a/loafwallet/Assets.xcassets/MenuIcons/Contents.json +++ b/loafwallet/Assets.xcassets/MenuIcons/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/loafwallet/Assets.xcassets/MenuIcons/BuyLitecoin.imageset/BuyLitecoin.pdf b/loafwallet/Assets.xcassets/MenuIcons/buy_icon_gray.imageset/BuyLitecoin.pdf similarity index 100% rename from loafwallet/Assets.xcassets/MenuIcons/BuyLitecoin.imageset/BuyLitecoin.pdf rename to loafwallet/Assets.xcassets/MenuIcons/buy_icon_gray.imageset/BuyLitecoin.pdf diff --git a/loafwallet/Assets.xcassets/MenuIcons/BuyLitecoin.imageset/Contents.json b/loafwallet/Assets.xcassets/MenuIcons/buy_icon_gray.imageset/Contents.json similarity index 100% rename from loafwallet/Assets.xcassets/MenuIcons/BuyLitecoin.imageset/Contents.json rename to loafwallet/Assets.xcassets/MenuIcons/buy_icon_gray.imageset/Contents.json diff --git a/loafwallet/Assets.xcassets/Partners/litecoincard/Contents.json b/loafwallet/Assets.xcassets/Partners/litecoincard/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/loafwallet/Assets.xcassets/Partners/litecoincard/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/Contents.json b/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/Contents.json new file mode 100644 index 000000000..d127d6083 --- /dev/null +++ b/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "litecoin-back-1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "litecoin-back-2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "litecoin-back-3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/litecoin-back-1x.png b/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-back.imageset/litecoin-back-1x.png new file mode 100644 index 0000000000000000000000000000000000000000..fe9fb96961ee5ff4efa14cd3d7bbbc0204500c07 GIT binary patch literal 75475 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�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�t)DyUn}b+R_%`*#V2+F$%Y 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%0A`FY@Vr8LL} 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 z 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 z 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 literal 0 HcmV?d00001 diff --git a/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/Contents.json b/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/Contents.json new file mode 100644 index 000000000..594c2253e --- /dev/null +++ b/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "litecoin-front-1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "litecoin-front-2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "litecoin-card-3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/litecoin-card-3x.png b/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/litecoin-card-3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f03027485cb98fb73e54fe66eba545de18395f1b GIT binary patch literal 225468 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%0D3Neys*(P#|=7;dv2Mj36JFaR*P!;<> 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

W-tMhUGEOpAns`4}QF8iMUGfG6vxo`btn;JHz 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≧e{gQgf`UR6|n~vG{~{r@WW%1T%%sp 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 literal 0 HcmV?d00001 diff --git a/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/litecoin-front-1x.png b/loafwallet/Assets.xcassets/Partners/litecoincard/litecoin-card-front.imageset/litecoin-front-1x.png new file mode 100644 index 0000000000000000000000000000000000000000..eb5c284b83b2cb0854b9ceaa301081468975adc3 GIT binary patch literal 41426 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 r#l^WpV`7|D;Icm>NxO^eUBh5ca90u&zbSmB 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 literal 0 HcmV?d00001 diff --git a/loafwallet/Assets.xcassets/BuyIcon.imageset/BuyIcon.pdf b/loafwallet/Assets.xcassets/buy_icon.imageset/BuyIcon.pdf similarity index 100% rename from loafwallet/Assets.xcassets/BuyIcon.imageset/BuyIcon.pdf rename to loafwallet/Assets.xcassets/buy_icon.imageset/BuyIcon.pdf diff --git a/loafwallet/Assets.xcassets/BuyIcon.imageset/BuyIcon.pxm b/loafwallet/Assets.xcassets/buy_icon.imageset/BuyIcon.pxm similarity index 100% rename from loafwallet/Assets.xcassets/BuyIcon.imageset/BuyIcon.pxm rename to loafwallet/Assets.xcassets/buy_icon.imageset/BuyIcon.pxm diff --git a/loafwallet/Assets.xcassets/BuyIcon.imageset/Contents.json b/loafwallet/Assets.xcassets/buy_icon.imageset/Contents.json similarity index 100% rename from loafwallet/Assets.xcassets/BuyIcon.imageset/Contents.json rename to loafwallet/Assets.xcassets/buy_icon.imageset/Contents.json diff --git a/loafwallet/Assets.xcassets/historyIcon.imageset/Contents.json b/loafwallet/Assets.xcassets/history_icon.imageset/Contents.json similarity index 100% rename from loafwallet/Assets.xcassets/historyIcon.imageset/Contents.json rename to loafwallet/Assets.xcassets/history_icon.imageset/Contents.json diff --git a/loafwallet/Assets.xcassets/historyIcon.imageset/history1x.png b/loafwallet/Assets.xcassets/history_icon.imageset/history1x.png similarity index 100% rename from loafwallet/Assets.xcassets/historyIcon.imageset/history1x.png rename to loafwallet/Assets.xcassets/history_icon.imageset/history1x.png diff --git a/loafwallet/Assets.xcassets/ReceiveButtonIcon.imageset/Contents.json b/loafwallet/Assets.xcassets/receive_icon.imageset/Contents.json similarity index 100% rename from loafwallet/Assets.xcassets/ReceiveButtonIcon.imageset/Contents.json rename to loafwallet/Assets.xcassets/receive_icon.imageset/Contents.json diff --git a/loafwallet/Assets.xcassets/ReceiveButtonIcon.imageset/ReceiveTabIcon.pdf b/loafwallet/Assets.xcassets/receive_icon.imageset/ReceiveTabIcon.pdf similarity index 100% rename from loafwallet/Assets.xcassets/ReceiveButtonIcon.imageset/ReceiveTabIcon.pdf rename to loafwallet/Assets.xcassets/receive_icon.imageset/ReceiveTabIcon.pdf diff --git a/loafwallet/Assets.xcassets/send.imageset/Contents.json b/loafwallet/Assets.xcassets/send.imageset/Contents.json new file mode 100644 index 000000000..2c97f3387 --- /dev/null +++ b/loafwallet/Assets.xcassets/send.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "history1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/loafwallet/Assets.xcassets/send.imageset/history1x.png b/loafwallet/Assets.xcassets/send.imageset/history1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c57618eaba33ff954ec125a8af17f1073de34172 GIT binary patch literal 1511 zcmY*Z2{0R27=EsXIA_%nSFY%IEk#l1Cfe=pzM20W-~YYud;gm^@AgG|D`}_-6aXM?V{Pul zAK`)!KgREw5fK~wK{UYB&J=*^JCb|eVuGZvwUZqH5!wJm#{sazhoTn%2*Uud5K%b?I%6j}&epzG~J3u6%x2!YX;_UW7~ivPb(A0+7b;^}F*A#zy{#7%2MPxx_SyN+MA;a#UX{UB}zaeS>)TbJ4e zSFw|~P#Q2%Cbf0COjuH#3g+_;X>;f1yYdX?Dx+5OR@S2KZE>1c4trQ(`;&$E+3X&QhGaje$IAuB(=Xoko?KXPCqBfv_j3<0eF*pecog(lJ>_ zkNB^Z{pPt4&_J%_C7?jH+U*Q#K@xC&uwQ$0m|BDRr*)2f|OIM2#B7CtEBrd$Q+CKc2bV z+D1Q?FpVC8z+Nr(N!@49CYSQ2?bbwHTkhio^Y-Fi7k-#7T8`v~D6*{Yex9q0vq0oV;N4 z&0jgu>W`%9T8q#Xpu<$AI6G9=bZRO{5MBwd1sOSfWzmJ>u)5$w!2_=cglaq;91 z{0#ba+m^w0p#4+W>iVdZqkTqQAs5yR*7x1F9?N@|kw@Qd}J@TQ($D%cu1_?>-j4*~5%1`WmqncS$OVSC3)hBlFrg(|WN?%Q~ zNXhagnnH8VhKqiQni@yH@bb$B#+9Ys0WS1)Bq+*E>a=4l6_PfeomRRxvh3Wm&a{Vm znC&Y|#k!8|DfAoGUeQe}FM7utk##UTr5-wvl1kN6aEO%YQZFzWTxRd6c1U5hxMD_6 z{MLxU!pt^Zoe#>Xm#XCVVh9b~lFgXgB=Y!>WkvD(ww9&^jcxHgTHDH)GY5MpccY&F zI3uHbqjP#f>!+C8K+QK}xf!WdlfOyC$sFV~2^UQ|V(?ko%DY_1dh2g;tfkM(ft^#WQ)~2QT8U6wR4(K!AyNn6WA!@_uyxvVJl CGFloat { return 150 } -// -// override func numberOfSections(in tableView: UITableView) -> Int { return 1 } -// -// override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return partnerArray.count } -// -// override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { -// -// let fr = CGRect(x: 0, y: 0, width: self.view.frame.width, height: headerHeight) -// let buyCenterHeaderView = BuyCenterHeaderView(frame: fr, height: headerHeight) -// buyCenterHeaderView.closeCallback = { -// self.dismiss(animated: true, completion: nil) -// } -// return buyCenterHeaderView -// } -// -// override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return headerHeight } -// -// override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { -// let cell = tableView.dequeueReusableCell(withIdentifier: buyCellReuseIdentifier, for: indexPath) as! BuyCenterTableViewCell -// let partnerData = partnerArray[indexPath.row] -// cell.partnerLabel.text = partnerData["title"] as? String -// -// if let details = partnerData["details"] as? String, -// let color = partnerData["baseColor"] as? UIColor { -// cell.financialDetailsLabel.text = details -// cell.frameView.backgroundColor = color -// } else { -// NSLog("ERROR: Unable to retrieve partner details") -// } -// -// cell.logoImageView.image = partnerData["logo"] as? UIImage -// -// cell.delegate = self -// -// return cell -// } -// -// func didClickPartnerCell(partner: String) { -// -// switch partner { -// case "Simplex": -// let simplexWebviewVC = BRWebViewController(partner: "Simplex", mountPoint: mountPoint + "_simplex", walletManager: walletManager, store: store, noAuthApiClient: nil) -// present(simplexWebviewVC, animated: true -// , completion: nil) -// case "Changelly": -// print("Changelly No Code Placeholder") -// case "Coinbase": -// let coinbaseWebViewWC = BRWebViewController(partner: "Coinbase", mountPoint: mountPoint + "_coinbase", walletManager: walletManager, store: store, noAuthApiClient: nil) -// present(coinbaseWebViewWC, animated: true) { -// // -// } -// default: -// fatalError("No Partner Chosen") -// } -// } -// -// @objc func dismissWebContainer() { -// dismiss(animated: true, completion: nil) -// } -//} - - -//extension BuyCenterTableViewController: ModalDisplayable { - -// var faqArticleId: String? { -// return nil -// } -// -// var modalTitle: String { -// return S.BuyCenter.buyModalTitle -// } -//} - - diff --git a/loafwallet/CardLoggedInView.swift b/loafwallet/CardLoggedInView.swift new file mode 100644 index 000000000..f898fc5ec --- /dev/null +++ b/loafwallet/CardLoggedInView.swift @@ -0,0 +1,106 @@ +// +// CardLoggedInView.swift +// loafwallet +// +// Created by Kerry Washington on 12/26/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct CardLoggedInView: View { + + @ObservedObject + var viewModel: CardViewModel + + @ObservedObject + var animatedViewModel = AnimatedCardViewModel() + + @State + private var shouldLogout: Bool = false + + init(viewModel: CardViewModel) { + self.viewModel = viewModel + } + + var body: some View { + GeometryReader { geometry in + VStack { + + //MARK: - Animated Card View + HStack() { + AnimatedCardView(viewModel: animatedViewModel, isLoggedIn: .constant(true)) + .frame(minWidth:0, + maxWidth: geometry.size.width * 0.4, + alignment: .center) + .padding(.all, 30) + } + + Button(action: { + shouldLogout = true + viewModel.isLoggedIn = false + NotificationCenter.default.post(name: .LitecoinCardLogoutNotification, + object: nil, + userInfo: nil) + + }) { + Text(S.LitecoinCard.logout) + .frame(minWidth: 0, + maxWidth: geometry.size.width * 0.7, + alignment: .center) + .padding(.all, 10) + .font(Font(UIFont.barlowRegular(size: 18.0))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + .cornerRadius(8.0) + .padding(.all, 10) + } + + //MARK: - Card Balance + + Text(S.LitecoinCard.cardBalance) + .frame(minWidth: 0, + maxWidth: geometry.size.width * 0.4, + alignment: .center) + .padding(.top, 40) + .font(Font(UIFont.barlowBold(size: 20.0))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + Divider() + .frame(minWidth: 0, + maxWidth: geometry.size.width * 0.4, + alignment: .center) + + Text("$") + .frame(minWidth: 0, + maxWidth: .infinity, + alignment: .center) + .padding() + .font(Font(UIFont.barlowBold(size: 40.0))) + .foregroundColor(Color(UIColor.litecoinGray)) + .background(Color(UIColor.white)) + + Spacer() + } + + } + } +} + +struct CardLoggedInView_Previews: PreviewProvider { + + static let viewModel = CardViewModel() + + static var previews: some View { + Group { + CardLoggedInView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhoneSE2)) + .previewDisplayName(DeviceType.Name.iPhoneSE2) + + CardLoggedInView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone8)) + .previewDisplayName(DeviceType.Name.iPhone8) + + CardLoggedInView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone12ProMax)) + .previewDisplayName(DeviceType.Name.iPhone12ProMax) + } } +} diff --git a/loafwallet/CardView.swift b/loafwallet/CardView.swift new file mode 100644 index 000000000..20a92ef1e --- /dev/null +++ b/loafwallet/CardView.swift @@ -0,0 +1,248 @@ +// +// CardView.swift +// loafwallet +// +// Created by Kerry Washington on 12/23/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI +import UIKit + + +struct CardView: View { + + @ObservedObject + var viewModel: CardViewModel + + @ObservedObject + var registrationModel = RegistrationViewModel() + + @ObservedObject + var loginModel = LoginViewModel() + + @ObservedObject + var animatedViewModel = AnimatedCardViewModel() + + @State + private var shouldShowLoginModal: Bool = false + + @State + private var didFailToLogin: Bool = false + + @State + var didTapIForgot: Bool = false + + @State + private var shouldShowRegistrationView: Bool = false + + @State + private var shouldShowPassword: Bool = false + + @State + private var forgotEmailAddressInput = "" + + @State + var didCompleteLogin: Bool = false + + @State + var cannotLogin: Bool = true + + + init(viewModel: CardViewModel) { + + self.viewModel = viewModel + } + + var body: some View { + GeometryReader { geometry in + VStack { + + //MARK: - Animated Card View + Group { + AnimatedCardView(viewModel: animatedViewModel, isLoggedIn: $didCompleteLogin) + .frame(minWidth:0, + maxWidth: didCompleteLogin ? geometry.size.width * 0.4 : geometry.size.width * 0.6) + .padding(.all, didCompleteLogin ? 20 : 30) + } + + //MARK: - Login Textfields + Group { + + TextField(S.Receive.emailButton, text: $loginModel.emailString) { _ in + cannotLogin = loginModel.emailString.count < 4 + } + .font(Font(UIFont.barlowSemiBold(size:18.0))) + .accentColor(Color(UIColor.liteWalletBlue)) + .padding([.leading, .trailing], 20) + .padding(.top, 30) + .foregroundColor(.black) + .autocapitalization(.none) + .keyboardType(.emailAddress) + + Divider().padding([.leading, .trailing], 20) + + HStack { + if shouldShowPassword { + + TextField(S.Import.passwordPlaceholder.capitalized, text: $loginModel.passwordString) + .font(Font(UIFont.barlowSemiBold(size:18.0))) + .accentColor(Color(UIColor.liteWalletBlue)) + .padding(.leading, 20) + .padding(.top, 20) + .autocapitalization(.none) + .keyboardType(.asciiCapable) + + } else { + + SecureField(S.Import.passwordPlaceholder.capitalized, text: $loginModel.passwordString) + .font(Font(UIFont.barlowSemiBold(size:18.0))) + .accentColor(Color(UIColor.liteWalletBlue)) + .padding(.leading, 20) + .padding(.top, 20) + .autocapitalization(.none) + .keyboardType(.asciiCapable) + } + + Spacer() + Button(action: { + shouldShowPassword.toggle() + }) { + Image(systemName: shouldShowPassword ? "eye.fill" : "eye.slash.fill") + .padding(.top, 20) + .padding(.trailing, 20) + .foregroundColor(.gray) + } + } + + Divider().padding([.leading, .trailing], 20) + Spacer() + } + + //MARK: - Action Buttons + Group { + + // Forgot password button + Button(action: { + didTapIForgot = true + }) { + + Text(S.LitecoinCard.forgotPassword) + .frame(minWidth:0, maxWidth: .infinity) + .font(Font(UIFont.barlowLight(size: 15))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + .padding(.all, 30) + } + + Spacer(minLength: 5) + + // Login button + Button(action: { + shouldShowLoginModal = true + loginModel.login { didLogin in + + if didLogin { + viewModel.isLoggedIn = true + shouldShowLoginModal = false + NotificationCenter.default.post(name: .LitecoinCardLoginNotification, object: nil, + userInfo: nil) + } else { + viewModel.isLoggedIn = true + didFailToLogin = true + + DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) { + shouldShowLoginModal = false + } + } + } + + }) { + + Text(S.LitecoinCard.login) + .frame(minWidth:0, maxWidth: .infinity) + .padding() + .font(Font(UIFont.barlowMedium(size: 16.0))) + .padding([.leading, .trailing], 16) + .foregroundColor(cannotLogin ? Color(UIColor.litecoinSilver) : + Color(.white)) + .background(cannotLogin ? .gray : + Color(UIColor.liteWalletBlue)) + .cornerRadius(4.0) + .overlay( + RoundedRectangle(cornerRadius:4) + .stroke((cannotLogin ? .gray : + Color(UIColor.liteWalletBlue)), lineWidth: 1) + ) + } + .disabled(cannotLogin) + .padding([.leading, .trailing], 16) + + // Registration button + Button(action: { + shouldShowRegistrationView = true + }) { + Text(S.LitecoinCard.registerCard) + .frame(minWidth:0, maxWidth: .infinity) + .padding() + .font(Font(UIFont.barlowMedium(size: 15.0))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + .overlay( + RoundedRectangle(cornerRadius:4) + .stroke(Color(UIColor.liteWalletBlue), lineWidth: 1) + ) + .padding([.leading, .trailing], 16) + .padding([.top,.bottom], 15) + } + .sheet(isPresented: $shouldShowRegistrationView) { + RegistrationView(viewModel: registrationModel) + } + } + Spacer() + } + }.onReceive(NotificationCenter.default.publisher(for: NSNotification.Name.UIKeyboardWillShow)) { _ in + animatedViewModel.dropOffset = -200 + }.onReceive(NotificationCenter.default.publisher(for: NSNotification.Name.UIKeyboardWillHide)) { _ in + animatedViewModel.dropOffset = 0 + } + .forgotPasswordView(isShowingForgot: $didTapIForgot, + emailString: $forgotEmailAddressInput, + message: S.LitecoinCard.forgotPassword) + .loginAlertView(isShowingLoginAlert: $shouldShowLoginModal, + didFail: $didFailToLogin, + message: S.LitecoinCard.login) + .registeredAlertView(shouldStartRegistering: $registrationModel.isRegistering, + didRegister: $registrationModel.didRegister, + data: registrationModel.dataDictionary, + message: $registrationModel.message) + .frame(minWidth: 0, + maxWidth: .infinity, + minHeight: 0, + maxHeight: .infinity, + alignment: .center) + } +} + +struct CardView_Previews: PreviewProvider { + + static let viewModel = CardViewModel() + + static var previews: some View { + + Group { + CardView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhoneSE2)) + .previewDisplayName(DeviceType.Name.iPhoneSE2) + + CardView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone8)) + .previewDisplayName(DeviceType.Name.iPhone8) + + CardView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone12ProMax)) + .previewDisplayName(DeviceType.Name.iPhone12ProMax) + } + } +} + + + diff --git a/loafwallet/CardViewController.swift b/loafwallet/CardViewController.swift new file mode 100644 index 000000000..c19b535be --- /dev/null +++ b/loafwallet/CardViewController.swift @@ -0,0 +1,85 @@ +// +// CardViewController.swift +// loafwallet +// +// Created by Kerry Washington on 12/22/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation + +import UIKit +import SwiftUI + + +/// A container for a CardView - SwiftUI +class CardViewController: UIViewController { + + var viewModel = CardViewModel() + + var cardLoggedInView: CardLoggedInView? + + var cardView: CardView? + + var parentFrame: CGRect? + + var swiftUIContainerView = UIHostingController(rootView: AnyView(EmptyView())) + + var notificationToken: NSObjectProtocol? + + private func updateLoginStatusFromViewModel() { + + // Bugfix: https://github.com/litecoin-foundation/loafwallet-ios/issues/175 + // Verifies the stack has only one VC and it is the UIHostingController + + DispatchQueue.main.async { + if self.childViewControllers.count == 1, + ((self.childViewControllers.first?.isKind(of: UIHostingController.self)) != nil) { + self.swiftUIContainerView.willMove(toParent: nil) + self.swiftUIContainerView.removeFromParentViewController() + self.swiftUIContainerView.view.removeFromSuperview() + } + + if self.viewModel.isLoggedIn { + self.cardLoggedInView = CardLoggedInView(viewModel: self.viewModel) + self.swiftUIContainerView = UIHostingController(rootView: AnyView(self.cardLoggedInView)) + } else { + self.cardView = CardView(viewModel: self.viewModel) + self.swiftUIContainerView = UIHostingController(rootView: AnyView(self.cardView)) + } + + //Constraint the view to Tab container + if let size = self.parentFrame?.size { + self.swiftUIContainerView.view.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: size) + } + + self.addChildViewController(self.swiftUIContainerView) + self.view.addSubview(self.swiftUIContainerView.view) + self.swiftUIContainerView.didMove(toParent: self) + } + } + + override func viewDidLoad() { + + self.updateLoginStatusFromViewModel() + + // Listens for Login notification and updates the CardView + notificationToken = NotificationCenter.default + .addObserver(forName: NSNotification.Name.LitecoinCardLoginNotification, + object: nil, + queue: nil) { _ in + self.updateLoginStatusFromViewModel() + } + + // Listens for Logout notification and updates the CardView + notificationToken = NotificationCenter.default + .addObserver(forName: NSNotification.Name.LitecoinCardLogoutNotification, + object: nil, + queue: nil) { _ in + self.updateLoginStatusFromViewModel() + } + } + +} + + diff --git a/loafwallet/CardViewModel.swift b/loafwallet/CardViewModel.swift new file mode 100644 index 000000000..89bf7a353 --- /dev/null +++ b/loafwallet/CardViewModel.swift @@ -0,0 +1,25 @@ +// +// CardViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 12/23/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI +import KeychainAccess + + +class CardViewModel: ObservableObject { + + //MARK: - Login Status + @Published + var isLoggedIn: Bool = false + + @Published + var isNotRegistered: Bool = true + + init() { } + +} diff --git a/loafwallet/Color+Extension.swift b/loafwallet/Color+Extension.swift new file mode 100644 index 000000000..3e8b34029 --- /dev/null +++ b/loafwallet/Color+Extension.swift @@ -0,0 +1,17 @@ +// +// Color+Extension.swift +// loafwallet +// +// Created by Kerry Washington on 12/22/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI + +extension Color { + + static var liteWalletBlue: Color { //345D9D + return Color(UIColor.liteWalletBlue) + } +} diff --git a/loafwallet/DataValidation.swift b/loafwallet/DataValidation.swift new file mode 100644 index 000000000..79bb44148 --- /dev/null +++ b/loafwallet/DataValidation.swift @@ -0,0 +1,139 @@ +// +// DataValidation.swift +// loafwallet +// +// Created by Kerry Washington on 12/28/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation + +enum ValidatorType { + case email + case genericString + case password + case mobileNumber + case requiredField(field: String) +} + +protocol ValidatorConvertible { + func validated(_ value: String) throws -> String +} + +struct ValidationError: Error { + var message: String + + init(_ message: String) { + self.message = message + } +} + +enum VaildatorFactory { + static func validatorFor(type: ValidatorType) -> ValidatorConvertible { + switch type { + case .genericString: return GenericStringValidator() + case .email: return EmailValidator() + case .password: return PasswordValidator() + case .mobileNumber: return MobileNumberValidator() + case let .requiredField(fieldName): return RequiredFieldValidator(fieldName) + } + } +} + +struct GenericStringValidator: ValidatorConvertible { + + func validated(_ value: String) throws -> String { + + guard !value.isEmpty else { throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .empty) } + return value + } +} + +struct MobileNumberValidator: ValidatorConvertible { + + func validated(_ value: String) throws -> String { + + guard value != "" else { throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .empty) } + + guard value.count >= 10 else { throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .numberDigitsRequired) } + return value + } +} + +struct RequiredFieldValidator: ValidatorConvertible { + private let fieldName: String + + init(_ field: String) { + fieldName = field + } + + func validated(_ value: String) throws -> String { + guard !value.isEmpty else { + throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .requiredField + fieldName) + } + return value + } +} + +struct PasswordValidator: ValidatorConvertible { + + func validated(_ value: String) throws -> String { + + guard value != "" else { throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .empty) } + + guard value.count >= 6 else { throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .passwordCharacters) } + + do { + if try NSRegularExpression(pattern: "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{6,}$", options: .caseInsensitive).firstMatch(in: value, options: [], range: NSRange(location: 0, length: value.count)) == nil { + throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .passwordComposition) + } + } catch { + throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .passwordComposition) + } + return value + } +} + +struct EmailValidator: ValidatorConvertible { + + func validated(_ value: String) throws -> String { + do { + if try NSRegularExpression(pattern: "^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}$", options: .caseInsensitive).firstMatch(in: value, options: [], range: NSRange(location: 0, length: value.count)) == nil { + throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .invalidEmail) + } + } catch { + throw ValidationError(S.LitecoinCard + .Registration + .ValidationError + .invalidEmail) + } + return value + } +} diff --git a/loafwallet/ForgotView.swift b/loafwallet/ForgotView.swift new file mode 100644 index 000000000..1a55533aa --- /dev/null +++ b/loafwallet/ForgotView.swift @@ -0,0 +1,89 @@ +// ForgotAlertView.swift +// +// Created by Kerry Washington on 12/26/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. + + +import SwiftUI + +struct ForgotAlertView: View where Presenting: View { + + @Binding + var isShowingForgot: Bool + + @Binding + var emailString: String + + let presenting: Presenting + + var mainMessage: String + + var body: some View { + GeometryReader { (deviceSize: GeometryProxy) in + HStack{ + Spacer() + ZStack { + self.presenting.disabled(isShowingForgot) + VStack { + Text(S.LitecoinCard.resetPassword) + .font(Font(UIFont.barlowBold(size: 20.0))) + .padding() + .foregroundColor(Color.white) + + Text(S.LitecoinCard.visitToReset) + .font(Font(UIFont.barlowMedium(size: 18.0))) + .foregroundColor(Color.white) + .padding(.all, 10) + + Divider().background(Color.white) + HStack { + Button(action: { + withAnimation { + self.isShowingForgot.toggle() + } + }) { + Text(S.Button.ok) + .frame(minWidth:0, maxWidth: .infinity) + .padding() + .font(Font(UIFont.barlowBold(size: 20.0))) + .foregroundColor(Color.white) + } + } + } + .padding() + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.gray, lineWidth: 1.5) + ) + .background(Color(UIColor.liteWalletBlue)) + .cornerRadius(8) + .frame( + width: deviceSize.size.width * 0.8, + height: deviceSize.size.height * 0.9 + ) + .shadow(color: .black, radius: 10, x: 5, y: 5) + .opacity(self.isShowingForgot ? 1 : 0) + } + Spacer() + } + } + } +} + +struct ForgotAlertView_Previews: PreviewProvider { + + + static var previews: some View { + VStack { + Spacer() + Text("") + .padding(.all, 10) + .forgotPasswordView(isShowingForgot: .constant(true), emailString: .constant("efef@sec.com"), message: "Forgot message") + Spacer() + } + } +} + + + + diff --git a/loafwallet/ForgotViewModel.swift b/loafwallet/ForgotViewModel.swift new file mode 100644 index 000000000..29205a7c3 --- /dev/null +++ b/loafwallet/ForgotViewModel.swift @@ -0,0 +1,12 @@ +// +// ForgotViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 12/24/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +class ForgotViewModel: ObservableObject { + init() {} +} diff --git a/loafwallet/LitecoinCardUser.swift b/loafwallet/LitecoinCardUser.swift new file mode 100644 index 000000000..6ad345f3a --- /dev/null +++ b/loafwallet/LitecoinCardUser.swift @@ -0,0 +1,17 @@ +// +// LitecoinCardUser.swift +// loafwallet +// +// Created by Kerry Washington on 12/29/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation + +struct LitecoinCardUser: Codable { + + var userID: String + var referralCode: String + var createdAt: String + +} diff --git a/loafwallet/LoginCardAlertView.swift b/loafwallet/LoginCardAlertView.swift new file mode 100644 index 000000000..d12fd94db --- /dev/null +++ b/loafwallet/LoginCardAlertView.swift @@ -0,0 +1,83 @@ +// +// LoginCardAlertView.swift +// +// Created by Kerry Washington on 12/26/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. + + +import SwiftUI + +struct LoginCardAlertView: View where Presenting: View { + + @Binding + var isShowingLoginAlert: Bool + + @Binding + var didFail: Bool + + let presenting: Presenting + + var mainMessage: String + + var body: some View { + GeometryReader { (deviceSize: GeometryProxy) in + HStack{ Spacer() + ZStack { + self.presenting.disabled(isShowingLoginAlert) + + VStack { + Text(didFail ? S.LitecoinCard.failedlogin : self.mainMessage) + .padding() + .font(Font(UIFont.customMedium(size: 16.0))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + ActivityIndicator(isAnimating: $isShowingLoginAlert, + style: .medium) + .padding(.bottom, 15) + Divider() + HStack { + Button(action: { + + withAnimation { + self.isShowingLoginAlert.toggle() + } + }) { + Text(S.Prompts.dismiss.localizedCapitalized) + .font(Font(UIFont.barlowLight(size: 14.0))) + .foregroundColor(.gray) + }.padding([.top,.bottom], 5) + } + } + .padding() + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.gray, lineWidth: 1.5) + ) + .background(Color.white) + .cornerRadius(8) + .frame( + width: deviceSize.size.width * 0.85, + height: deviceSize.size.height * 0.5 + ) + .shadow(color: .gray, radius: /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/, x: 5, y: 5) + .opacity(self.isShowingLoginAlert ? 1 : 0) + } + Spacer() + } + } + } +} + +struct LoginCardAlertView_Previews: PreviewProvider { + + static var previews: some View { + VStack { + Spacer() + Text("").padding(.all, 10) + .loginAlertView(isShowingLoginAlert: .constant(true), + didFail: .constant(true), + message: "Login...") + Spacer() + } + } +} + diff --git a/loafwallet/LoginViewModel.swift b/loafwallet/LoginViewModel.swift new file mode 100644 index 000000000..0d5c3eb00 --- /dev/null +++ b/loafwallet/LoginViewModel.swift @@ -0,0 +1,77 @@ +// +// LoginViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 12/31/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import KeychainAccess + +class LoginViewModel: ObservableObject { + + @Published + var emailString: String = "" + + @Published + var passwordString: String = "" + + //MARK: - Login Status + @Published + var isLoggedIn: Bool = false + + @Published + var doShowModal: Bool = false + + @Published + var didCompleteLogin: Bool = false + + func login(completion: @escaping (Bool) -> ()) { + + //Turn on the modal + self.doShowModal = false + + let credentials: [String: Any] = ["email": emailString, "password": passwordString] + + PartnerAPI.shared.loginUser(credentials: credentials) { dataDictionary in + + if let error = dataDictionary?["error"] as? String { + + DispatchQueue.main.async { + print("ERROR: Login failure: \(error.description)") + self.isLoggedIn = false + self.didCompleteLogin = false + completion(self.didCompleteLogin) + } + } + + let cardService = "com.litecoincard.service" + let keychain = Keychain(service: cardService) + + if let responeDict = dataDictionary, + let token = responeDict["token"] as? String, + let userID = responeDict["uuid"] as? String, + let email = credentials["email"] as? String, + let password = credentials["password"] as? String { + + keychain[email] = password + keychain["userID"] = userID + keychain["token"] = token + + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + + self.isLoggedIn = true + self.didCompleteLogin = true + + //Turn modal off + self.doShowModal = false + + NotificationCenter.default.post(name: .LitecoinCardLoginNotification, object: nil, + userInfo: nil) + completion(self.didCompleteLogin) + } + } + } + } +} diff --git a/loafwallet/MainTabBarViewModel.swift b/loafwallet/MainTabBarViewModel.swift new file mode 100644 index 000000000..fd3ee5e01 --- /dev/null +++ b/loafwallet/MainTabBarViewModel.swift @@ -0,0 +1,12 @@ +// +// MainTabBarViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 12/20/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +class MainTabBarViewModel: ObservableObject { + init() {} +} diff --git a/loafwallet/MainViewController.swift b/loafwallet/MainViewController.swift index 5ee88de54..011af0c31 100644 --- a/loafwallet/MainViewController.swift +++ b/loafwallet/MainViewController.swift @@ -9,6 +9,7 @@ import UIKit import BRCore import MachO +import SwiftUI private let transactionsLoadingViewHeightConstant: CGFloat = 48.0 @@ -94,12 +95,13 @@ class MainViewController : UIViewController, Subscriber, LoginViewControllerDele } func didUnlockLogin() { + if let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "TabBarViewController") as? TabBarViewController { - + vc.store = self.store vc.isLtcSwapped = store.state.isLtcSwapped vc.walletManager = self.walletManager - + if let rate = store.state.currentRate { vc.exchangeRate = rate let placeholderAmount = Amount(amount: 0, rate: rate, maxDigits: store.state.maxDigits) @@ -110,25 +112,25 @@ class MainViewController : UIViewController, Subscriber, LoginViewControllerDele vc.primaryBalanceLabel = UpdatingLabel(formatter: NumberFormatter()) } - + addChildViewController(vc, layout:{ vc.view.constrain(toSuperviewEdges: nil) vc.view.alpha = 0 vc.view.layoutIfNeeded() }) - + UIView.animate(withDuration: 0.3, delay: 0.1, options: .transitionCrossDissolve, animations: { vc.view.alpha = 1 }) { (finished) in NSLog("MainView Controller presented") } - + } else { NSLog("ERROR: MainView Controller Not presented") } - + } - + private func addTemporaryStartupViews() { guardProtected(queue: DispatchQueue.main) { if !WalletManager.staticNoWallet { diff --git a/loafwallet/PartnerAPIManager.swift b/loafwallet/PartnerAPIManager.swift new file mode 100644 index 000000000..337708b87 --- /dev/null +++ b/loafwallet/PartnerAPIManager.swift @@ -0,0 +1,20 @@ +// +// PartnerAPIManager.swift +// loafwallet +// +// Created by Kerry Washington on 12/27/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import LitewalletPartnerAPI + +class PartnerAPI: NSObject { + + static let shared = PartnerAPIManager() + + override init() { + super.init() + } +} + diff --git a/loafwallet/RegistrationAlertView.swift b/loafwallet/RegistrationAlertView.swift new file mode 100644 index 000000000..189f5b2c5 --- /dev/null +++ b/loafwallet/RegistrationAlertView.swift @@ -0,0 +1,92 @@ +// +// RegistrationAlertView.swift +// loafwallet +// +// Created by Kerry Washington on 12/29/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct RegistrationAlertView: View where Presenting: View { + + @Binding + var shouldStartRegistering: Bool + + @Binding + var didRegister: Bool + + @Binding + var mainMessage: String + + let presenting: Presenting + + var body: some View { + GeometryReader { (deviceSize: GeometryProxy) in + HStack{ Spacer() + ZStack { + self.presenting + .disabled(shouldStartRegistering) + VStack { + Text(mainMessage) + .frame(minWidth: 0, + maxWidth: .infinity, + alignment: .center) + .multilineTextAlignment(.center) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + .padding(.bottom, 20) + .padding(.top, 10) + .padding([.leading,.trailing], 20) + ActivityIndicator(isAnimating: $shouldStartRegistering, + style: .medium) + .padding(.bottom, 15) + Divider() + HStack { + Button(action: { + + withAnimation { + shouldStartRegistering.toggle() + } + }) { + Text(S.Prompts.dismiss.localizedCapitalized) + .font(Font(UIFont.barlowLight(size: 14.0))) + .foregroundColor(.gray) + }.padding([.top,.bottom], 5) + } + } + .padding() + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.gray, lineWidth: 1.5) + ) + .background(Color.white) + .cornerRadius(8) + .frame( + width: deviceSize.size.width*0.8, + height: deviceSize.size.height*0.7 + ) + .shadow(color: .gray, radius: /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/, x: 5, y: 5) + .opacity(shouldStartRegistering ? 1 : 0) + } + Spacer() + } + } + } +} + +struct RegistrationAlertView_Previews: PreviewProvider { + + static var previews: some View { + VStack { + Spacer() + Text("").padding(.all, 10) + .registeredAlertView(shouldStartRegistering: .constant(true), + didRegister: .constant(false), + data: [:], + message: .constant("vwevwvvwv\nwevwevwevwevwevwvwevwvwvewRegistering...")) + Spacer() + } + } +} + diff --git a/loafwallet/RegistrationView.swift b/loafwallet/RegistrationView.swift new file mode 100644 index 000000000..456467e29 --- /dev/null +++ b/loafwallet/RegistrationView.swift @@ -0,0 +1,360 @@ +// +// RegistrationView.swift +// loafwallet +// +// Created by Kerry Washington on 12/24/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct RegistrationView: View { + + @ObservedObject + var viewModel: RegistrationViewModel + + @Environment(\.presentationMode) + var presentationMode + + @State + var usernameEmail: String = "" + + @State + var password: String = "" + + @State + var confirmPassword: String = "" + + @State + var firstName: String = "" + + @State + var lastName: String = "" + + @State + var address: String = "" + + @State + var city: String = "" + + @State + var state: String = "" + + @State + var country: String = "US" + + @State + var zipCodePostCode: String = "" + + @State + var mobileNumber: String = "" + + @State + var currentOffset = 0.0 + + @State + private var shouldStartRegistering: Bool = false + + @State + private var didRegister: Bool = false + + init(viewModel: RegistrationViewModel) { + self.viewModel = viewModel + UITableView.appearance().backgroundColor = .clear + } + + //DEV: This layout needs to be polished after v1 so it looks nicer. + var body: some View { + + GeometryReader { geometry in + // Litewallet Blue Background + VStack { + + Text(S.LitecoinCard.Registration.registerCardPhrase) + .multilineTextAlignment(.leading) + .foregroundColor(.white) + .font(Font(UIFont.barlowBold(size: 20.0))) + .padding(.top, 20) + .padding(.bottom, 10) + + // White Background + VStack { + + //MARK: - User names + Group { + HStack { + VStack { + TextField(S.LitecoinCard.Registration.firstName, + text: $firstName) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .keyboardType(.namePhonePad) + .padding([.leading, .trailing, .top], 4) + .padding(.top, 12) + .foregroundColor(viewModel.isDataValid(dataType: .genericString, + data: firstName) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + + VStack { + TextField(S.LitecoinCard.Registration.lastName, + text: $lastName) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .keyboardType(.namePhonePad) + .padding([.leading, .trailing, .top], 4) + .padding(.top, 12) + .foregroundColor(viewModel.isDataValid(dataType: .genericString, + data: lastName) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + } + } + + //MARK: - Login credentials + Group { + TextField(S.Receive.emailButton, + text: $usernameEmail) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .keyboardType(.emailAddress) + .padding([.leading, .trailing, .top], 4) + .foregroundColor(viewModel.isDataValid(dataType: .email, + data: usernameEmail) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + + HStack { + VStack { + TextField(S.LitecoinCard.Registration.password, + text: $password) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .autocapitalization(.none) + .keyboardType(.default) + .padding([.leading, .trailing, .top], 4) + .foregroundColor(viewModel.isDataValid(dataType: .password, + data: password) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + + VStack { + TextField(S.LitecoinCard.Registration.confirmPassword, + text: $confirmPassword) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .autocapitalization(.none) + .keyboardType(.default) + .padding([.leading, .trailing, .top], 4) + .foregroundColor(viewModel.isDataValid(dataType: .confirmation, + firstString: password, + data: confirmPassword) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + } + + } + + //MARK: - Mobile number + Group { + VStack { + TextField(S.LitecoinCard.Registration.mobileNumber, text: $mobileNumber) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .keyboardType(.numberPad) + .padding([.leading, .trailing, .top], 4) + .foregroundColor(viewModel.isDataValid(dataType: .mobileNumber, + data: mobileNumber) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + + } + } + + //MARK: - Location + Group { + HStack { + VStack { + TextField(S.LitecoinCard.Registration.address, text: $address) + .padding([.leading, .trailing, .top], 4) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .foregroundColor(viewModel.isDataValid(dataType: .genericString, + data: address) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + } + HStack { + VStack { + TextField(S.LitecoinCard.Registration.city, text: $city) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .padding([.leading, .trailing, .top], 4) + .foregroundColor(viewModel.isDataValid(dataType: .genericString, + data: city) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + VStack { + TextField(S.LitecoinCard.Registration.stateProvince, text: $state) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .padding([.leading, .trailing, .top], 4) + .foregroundColor(viewModel.isDataValid(dataType: .genericString, + data: state) ? .black : Color(UIColor.litecoinOrange)) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + } + + HStack { + VStack { + //DEV: Will change when EU support comes + TextField("US", text: $country) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .foregroundColor(.gray) + .padding([.leading, .trailing, .top], 4) + .disabled(true) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + + VStack { + //DEV: Will change when EU support comes + TextField(S.LitecoinCard.Registration.zipPostCode, text: $zipCodePostCode) + .font(Font(UIFont.barlowRegular(size: 16.0))) + .padding([.leading, .trailing, .top], 4) + Divider() + .padding([.leading, .bottom, .trailing], 4) + .padding(.top, 1) + } + } + } + } + .padding([.leading, .trailing], 15) //This pads all subviews + .padding(.bottom, 30) + .background(Color.white) + .cornerRadius(4) + + Spacer(minLength: CGFloat(self.currentOffset)) + //MARK: - Action Buttons + HStack{ + // Button to reset fields + Button(action: { + resetFields() + }) { + Text(S.Button.resetFields) + .frame(minWidth:0, maxWidth: .infinity) + .padding() + .font(Font(UIFont.barlowRegular(size:20.0))) + .foregroundColor(Color(UIColor.litecoinOrange)) + .overlay( + RoundedRectangle(cornerRadius:4) + .stroke(Color(UIColor.white), lineWidth: 1) + ) + } + + // Button to register user + Button(action: { + viewModel.verify(data: loadDataDictionary()) { (isAllRegisterDataValid) in + + //Pass state to trigger the modal view + shouldStartRegistering = isAllRegisterDataValid + + //Make a registration call + viewModel.registerCardUser() + + //Dismiss Sheet + self.presentationMode.wrappedValue.dismiss() + } + + }) { + Text(S.Button.submit) + .frame(minWidth:0, maxWidth: .infinity) + .padding() + .font(Font(UIFont.barlowBold(size:20.0))) + .foregroundColor(Color(UIColor.liteWalletBlue)) + .background(Color.white) + .cornerRadius(4) + .overlay( + RoundedRectangle(cornerRadius:4) + .stroke(Color(UIColor.white), lineWidth: 1) + ) + } + + } + } + .padding([.leading,.trailing], 15) + .padding(.top, 15) + .padding(.bottom, 30) + .background(Color(UIColor.liteWalletBlue)) + .edgesIgnoringSafeArea(.all) + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name.UIKeyboardWillShow)) { notification in + if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { + self.currentOffset = Double(keyboardSize.height) + } + }.onReceive(NotificationCenter.default.publisher(for: NSNotification.Name.UIKeyboardWillHide)) { notification in + self.currentOffset = 0.0 + } + + } + + private func resetFields() { + usernameEmail = "" + password = "" + confirmPassword = "" + firstName = "" + lastName = "" + address = "" + city = "" + state = "" + zipCodePostCode = "" + mobileNumber = "" + } + + private func loadDataDictionary() -> [String: Any] { + + viewModel.dataDictionary["firstname"] = firstName + viewModel.dataDictionary["lastname"] = lastName + viewModel.dataDictionary["email"] = usernameEmail.lowercased() + viewModel.dataDictionary["password"] = password + viewModel.dataDictionary["password_confirmation"] = confirmPassword + viewModel.dataDictionary["phone"] = mobileNumber + viewModel.dataDictionary["city"] = city + viewModel.dataDictionary["country"] = country + viewModel.dataDictionary["state"] = state + viewModel.dataDictionary["address1"] = address + viewModel.dataDictionary["address2"] = "second line" //API requires this but it doesnt use the data + viewModel.dataDictionary["zip_code"] = zipCodePostCode + return viewModel.dataDictionary + } +} + +struct RegistrationView_Previews: PreviewProvider { + + static let viewModel = RegistrationViewModel() + + static var previews: some View { + + Group { + RegistrationView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhoneSE2)) + .previewDisplayName(DeviceType.Name.iPhoneSE2) + + RegistrationView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone8)) + .previewDisplayName(DeviceType.Name.iPhone8) + + RegistrationView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone12ProMax)) + .previewDisplayName(DeviceType.Name.iPhone12ProMax) + } + } +} diff --git a/loafwallet/RegistrationViewModel.swift b/loafwallet/RegistrationViewModel.swift new file mode 100644 index 000000000..704e1c16b --- /dev/null +++ b/loafwallet/RegistrationViewModel.swift @@ -0,0 +1,198 @@ +// +// RegistrationViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 12/24/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI +import KeychainAccess + +enum UserDataType { + case genericString + case email + case country + case mobileNumber + case password + case confirmation +} + +class RegistrationViewModel: ObservableObject { + + @Published + var isRegistering: Bool = false + + @Published + var didRegister: Bool = false + + @Published + var message: String = S.LitecoinCard.registeringUser + + var dataDictionary = [String: Any]() + + init() { + + } + + func verify(data: [String: Any], + completion: @escaping (Bool) -> ()) { + + if self.isDataValid(dataType: .genericString, data: (dataDictionary["firstname"] as! String)) && + isDataValid(dataType: .genericString, data: (dataDictionary["lastname"] as! String)) && + isDataValid(dataType: .email, data: (dataDictionary["email"] as! String)) && + isDataValid(dataType: .password, data: (dataDictionary["password"] as! String)) && + isDataValid(dataType: .mobileNumber, data: (dataDictionary["phone"] as! String)) && + isDataValid(dataType: .country, data: (dataDictionary["country"] as! String)) && + isDataValid(dataType: .genericString, data: (dataDictionary["state"] as! String)) && + isDataValid(dataType: .genericString, data: (dataDictionary["city"] as! String)) && + isDataValid(dataType: .genericString, data: (dataDictionary["address1"] as! String)) && + isDataValid(dataType: .genericString, data: (dataDictionary["zip_code"] as! String)) { + + self.isRegistering = true + + completion(isRegistering) + } + } + + func registerCardUser() { + + var setupUserID: String? + + PartnerAPI.shared.createUser(userDataParams: dataDictionary) { (newUser) in + + if let userID = newUser?.userID, + let createdAt = newUser?.createdAtDateString { + + ///Move setupUserID + setupUserID = userID + + guard let password = self.dataDictionary["password"] as? String else { return } + guard let email = self.dataDictionary["email"] as? String else { return } + + let cardService = "com.litecoincard.service" + let keychain = Keychain(service: cardService) + + keychain[email] = password + keychain["userID"] = userID + keychain["createdAt"] = createdAt + + DispatchQueue.main.async { + self.message = S.LitecoinCard.registrationSuccess + self.didRegister = true + + DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { + self.isRegistering = false + } + } + } + } + + if setupUserID == nil { + DispatchQueue.main.async { + self.message = S.LitecoinCard.registrationFailure + DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) { + self.isRegistering = false + } + } + } + } + + func isDataValid(dataType: UserDataType, firstString: String = "", data: Any) -> Bool { + + switch dataType { + case .genericString: + return isGenericStringValid(genericString: (data as! String)) + case .email: + return isEmailValid(emailString: (data as! String)) + case .country: + return (data as! String) == "US" ? true : false + case .mobileNumber: + return isMobileNumberValid(mobileString: (data as! String)) + case .password: + return isPasswordValid(passwordString: (data as! String)) + case .confirmation: + return isConfirmedValid(firstString: firstString, confirmingString: (data as! String)) + } + } + + //MARK: - Data Validators + + func isGenericStringValid(genericString: String) -> Bool { + + guard genericString != "" else { + return false + } + + guard genericString.count <= 32 else { + return false + } + + return true + } + + func isConfirmedValid(firstString: String, confirmingString: String) -> Bool { + return firstString == confirmingString ? true : false + } + + func isEmailValid(emailString: String) -> Bool { + + if try! NSRegularExpression(pattern: "^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}$", options: .caseInsensitive) + .firstMatch(in: emailString, options: [], + range: NSRange(location: 0, + length: emailString.count)) == nil { + return false + } else { + return true + } + } + + /// Password Validator + /// - Parameter passwordString: 6 - 10 chars + /// - Returns: Bool + func isPasswordValid(passwordString: String) -> Bool { + + guard passwordString != "" else { + return false + } + + guard (passwordString.count >= 6 && passwordString.count <= 10) else { + return false + } + + if try! NSRegularExpression(pattern: "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{6,}$", options: .caseInsensitive) + .firstMatch(in: passwordString, options: [], + range: NSRange(location: 0, + length: passwordString.count)) == nil { + return false + } else { + return true + } + } + + /// Mobile Number Validator + /// - Parameter mobileString: 10+ integers 0 - 9 + /// - Returns: Bool + func isMobileNumberValid(mobileString: String) -> Bool { + guard mobileString != "" else { + return false + } + + //https://boards.straightdope.com/t/longest-telephone-number-in-the-world/400450 + guard (mobileString.count >= 10 && mobileString.count <= 20) else { + return false + } + + if try! NSRegularExpression(pattern: "^[0-9]*$", options: .caseInsensitive) + .firstMatch(in: mobileString, options: [], + range: NSRange(location: 0, + length: mobileString.count)) == nil { + return false + } else { + return true + } + } +} + + diff --git a/loafwallet/Storyboards/Alerts.storyboard b/loafwallet/Storyboards/Alerts.storyboard index 0e0e68ba0..fcd9f8549 100644 --- a/loafwallet/Storyboards/Alerts.storyboard +++ b/loafwallet/Storyboards/Alerts.storyboard @@ -1,10 +1,11 @@ - + - + + @@ -19,107 +20,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -138,7 +38,7 @@ - - - + @@ -280,12 +180,12 @@ + - @@ -299,4 +199,12 @@ + + + + + + + + diff --git a/loafwallet/Storyboards/Card.storyboard b/loafwallet/Storyboards/Card.storyboard new file mode 100644 index 000000000..b375d8c04 --- /dev/null +++ b/loafwallet/Storyboards/Card.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/loafwallet/Storyboards/Main.storyboard b/loafwallet/Storyboards/Main.storyboard index 5772185cf..5aad4a497 100644 --- a/loafwallet/Storyboards/Main.storyboard +++ b/loafwallet/Storyboards/Main.storyboard @@ -1,10 +1,11 @@ - + - + + @@ -33,14 +34,16 @@ - + - - - - + + + + + + @@ -81,7 +84,8 @@ - + + @@ -89,7 +93,6 @@ - @@ -99,7 +102,9 @@ + + @@ -112,7 +117,6 @@ - @@ -138,8 +142,8 @@ - + @@ -172,7 +176,7 @@ - + @@ -184,7 +188,7 @@ - + @@ -233,7 +238,6 @@ - @@ -264,7 +268,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loafwallet/Storyboards/XIBs/SyncProgressHeaderView.xib b/loafwallet/Storyboards/XIBs/SyncProgressHeaderView.xib index 2eb822f0d..86811b641 100644 --- a/loafwallet/Storyboards/XIBs/SyncProgressHeaderView.xib +++ b/loafwallet/Storyboards/XIBs/SyncProgressHeaderView.xib @@ -1,9 +1,9 @@ - + - + @@ -26,25 +26,25 @@ - + - + @@ -54,12 +54,12 @@ - + diff --git a/loafwallet/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index 66d3c36ef..fc4e36da5 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -6,7 +6,7 @@ // Copyright © 2019 Litecoin Foundation. All rights reserved. import UIKit -import Foundation +import Foundation enum TabViewControllerIndex: Int { case transactions = 0 @@ -14,11 +14,7 @@ enum TabViewControllerIndex: Int { case buy = 2 case receive = 3 } - -protocol MainTabBarControllerDelegate { - func alertViewShouldDismiss() -} - + class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDelegate { let kInitialChildViewControllerIndex = 0 // TransactionsViewController @@ -38,18 +34,17 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel private let largeFontSize: CGFloat = 24.0 private let smallFontSize: CGFloat = 12.0 private var hasInitialized = false + private var didLoginLitecoinCardAccount = false private let dateFormatter = DateFormatter() private let equalsLabel = UILabel(font: .barlowMedium(size: 12), color: .whiteTint) private var regularConstraints: [NSLayoutConstraint] = [] private var swappedConstraints: [NSLayoutConstraint] = [] private let currencyTapView = UIView() - private let storyboardNames:[String] = ["Transactions","Send","Receive","Buy"] - var storyboardIDs:[String] = ["TransactionsViewController","SendLTCViewController","ReceiveLTCViewController","BuyTableViewController"] + private let storyboardNames:[String] = ["Transactions","Send","Card","Receive","Buy"] + var storyboardIDs:[String] = ["TransactionsViewController","SendLTCViewController","CardViewController","ReceiveLTCViewController","BuyTableViewController"] var viewControllers:[UIViewController] = [] var activeController:UIViewController? = nil - - var delegate: MainTabBarControllerDelegate? - + var updateTimer: Timer? var store: Store? var walletManager: WalletManager? @@ -179,6 +174,8 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel private func addSubscriptions() { + + guard let store = self.store else { NSLog("ERROR - Store not passed") return @@ -306,10 +303,11 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel switch item.tag { case 0: item.title = S.History.barItemTitle case 1: item.title = S.Send.barItemTitle - case 2: item.title = S.Receive.barItemTitle - case 3: item.title = S.BuyCenter.barItemTitle + case 2: item.title = S.LitecoinCard.barItemTitle + case 3: item.title = S.Receive.barItemTitle + case 4: item.title = S.BuyCenter.barItemTitle default: - item.title = "XXXXXX" + item.title = "NO-TITLE" NSLog("ERROR: UITabbar item count is wrong") } } @@ -322,6 +320,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel func displayContentController(contentController:UIViewController) { + //MARK: - Tab View Controllers Configuration switch NSStringFromClass(contentController.classForCoder) { case "loafwallet.TransactionsViewController": @@ -333,7 +332,15 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel transactionVC.walletManager = self.walletManager transactionVC.isLtcSwapped = self.store?.state.isLtcSwapped - case "loafwallet.BuyTableViewController": + + case "loafwallet.CardViewController": + guard let cardVC = contentController as? CardViewController else { + return + } + + cardVC.parentFrame = self.containerView.frame + + case "loafwallet.BuyTableViewController": guard let buyVC = contentController as? BuyTableViewController else { return } diff --git a/loafwallet/TransactionsViewController.swift b/loafwallet/TransactionsViewController.swift index d47bceb45..f330b5b1a 100644 --- a/loafwallet/TransactionsViewController.swift +++ b/loafwallet/TransactionsViewController.swift @@ -7,10 +7,12 @@ // import UIKit +import SwiftUI import LocalAuthentication private let promptDelay: TimeInterval = 0.6 private let qrImageSize = 120.0 + class TransactionsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, Subscriber, Trackable { @IBOutlet weak var tableView: UITableView! @@ -48,7 +50,8 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable var isLtcSwapped: Bool? { didSet { reload() } } - + + override func viewDidLoad() { setup() addSubscriptions() @@ -405,3 +408,21 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable } } +//struct TransactionsSwiftUIView: UIViewControllerRepresentable { +// +// +// +// typealias UIViewControllerType = TransactionsViewController +// +// +// +// func makeUIViewController(context: UIViewControllerRepresentableContext) -> TransactionsSwiftUIView.UIViewControllerType { +// let viewModel = TransactionsViewModel(store: Store(), walletManager: WalletManager(store: Store())) +// +// return TransactionsViewController(viewModel: viewModel, store: ) +// } +// +// func updateUIViewController(_ uiViewController: TransactionsSwiftUIView.UIViewControllerType, context: UIViewControllerRepresentableContext) { +// // +// } +//} diff --git a/loafwallet/TransactionsViewModel.swift b/loafwallet/TransactionsViewModel.swift new file mode 100644 index 000000000..73bcfcf1d --- /dev/null +++ b/loafwallet/TransactionsViewModel.swift @@ -0,0 +1,26 @@ +// +// TransactionsViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 12/20/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation + +class TransactionsViewModel: ObservableObject { + + var store: Store + + var walletManager: WalletManager + + var isLTCSwapped: Bool = false + + init(store: Store, walletManager: WalletManager) { + + self.store = store + self.walletManager = walletManager + self.isLTCSwapped = store.state.isLtcSwapped + } +} + diff --git a/loafwallet/View+Extension.swift b/loafwallet/View+Extension.swift new file mode 100644 index 000000000..7733ecc34 --- /dev/null +++ b/loafwallet/View+Extension.swift @@ -0,0 +1,44 @@ +// +// View+Extension.swift +// loafwallet +// +// Created by Kerry Washington on 12/26/20. +// Copyright © 2020 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI + + +extension View { + + func loginAlertView(isShowingLoginAlert: Binding, + didFail: Binding, + message: String) -> some View { + loafwallet.LoginCardAlertView(isShowingLoginAlert: isShowingLoginAlert, + didFail: didFail, + presenting: self, + mainMessage: message) + } + + func forgotPasswordView(isShowingForgot: Binding, + emailString: Binding, + message: String) -> some View { + loafwallet.ForgotAlertView(isShowingForgot: isShowingForgot, + emailString: emailString, + presenting: self, + mainMessage: message) + } + + func registeredAlertView(shouldStartRegistering: Binding, + didRegister: Binding, + data: [String: Any], + message: Binding) -> some View { + loafwallet.RegistrationAlertView(shouldStartRegistering: shouldStartRegistering, + didRegister: didRegister, + mainMessage: message, + presenting: self) + } + +} + diff --git a/loafwallet/ar.lproj/BIP39Words.plist b/loafwallet/ar.lproj/BIP39Words.plist deleted file mode 100644 index 01e69ff4c..000000000 --- a/loafwallet/ar.lproj/BIP39Words.plist +++ /dev/null @@ -1,2054 +0,0 @@ - - - - - abandon - ability - able - about - above - absent - absorb - abstract - absurd - abuse - access - accident - account - accuse - achieve - acid - acoustic - acquire - across - act - action - actor - actress - actual - adapt - add - addict - address - adjust - admit - adult - advance - advice - aerobic - affair - afford - afraid - again - age - agent - agree - ahead - aim - air - airport - aisle - alarm - album - alcohol - alert - alien - all - alley - allow - almost - alone - alpha - already - also - alter - always - amateur - amazing - among - amount - amused - analyst - anchor - ancient - anger - angle - angry - animal - ankle - announce - annual - another - answer - antenna - antique - anxiety - any - apart - apology - appear - apple - approve - april - arch - arctic - area - arena - argue - arm - armed - armor - army - around - arrange - arrest - arrive - arrow - art - artefact - artist - artwork - ask - aspect - assault - asset - assist - assume - asthma - athlete - atom - attack - attend - attitude - attract - auction - audit - august - aunt - author - auto - autumn - average - avocado - avoid - awake - aware - away - awesome - awful - awkward - axis - baby - bachelor - bacon - badge - bag - balance - balcony - ball - bamboo - banana - banner - bar - barely - bargain - barrel - base - basic - basket - battle - beach - bean - beauty - because - become - beef - before - begin - behave - behind - believe - below - belt - bench - benefit - best - betray - better - between - beyond - bicycle - bid - bike - bind - biology - bird - birth - bitter - black - blade - blame - blanket - blast - bleak - bless - blind - blood - blossom - blouse - blue - blur - blush - board - boat - body - boil - bomb - bone - bonus - book - boost - border - boring - borrow - boss - bottom - bounce - box - boy - bracket - brain - brand - brass - brave - bread - breeze - brick - bridge - brief - bright - bring - brisk - broccoli - broken - bronze - broom - brother - brown - brush - bubble - buddy - budget - buffalo - build - bulb - bulk - bullet - bundle - bunker - burden - burger - burst - bus - business - busy - butter - buyer - buzz - cabbage - cabin - cable - cactus - cage - cake - call - calm - camera - camp - can - canal - cancel - candy - cannon - canoe - canvas - canyon - capable - capital - captain - car - carbon - card - cargo - carpet - carry - cart - case - cash - casino - castle - casual - cat - catalog - catch - category - cattle - caught - cause - caution - cave - ceiling - celery - cement - census - century - cereal - certain - chair - chalk - champion - change - chaos - chapter - charge - chase - chat - cheap - check - cheese - chef - cherry - chest - chicken - chief - child - chimney - choice - choose - chronic - chuckle - chunk - churn - cigar - cinnamon - circle - citizen - city - civil - claim - clap - clarify - claw - clay - clean - clerk - clever - click - client - cliff - climb - clinic - clip - clock - clog - close - cloth - cloud - clown - club - clump - cluster - clutch - coach - coast - coconut - code - coffee - coil - coin - collect - color - column - combine - come - comfort - comic - common - company - concert - conduct - confirm - congress - connect - consider - control - convince - cook - cool - copper - copy - coral - core - corn - correct - cost - cotton - couch - country - couple - course - cousin - cover - coyote - crack - cradle - craft - cram - crane - crash - crater - crawl - crazy - cream - credit - creek - crew - cricket - crime - crisp - critic - crop - cross - crouch - crowd - crucial - cruel - cruise - crumble - crunch - crush - cry - crystal - cube - culture - cup - cupboard - curious - current - curtain - curve - cushion - custom - cute - cycle - dad - damage - damp - dance - danger - daring - dash - daughter - dawn - day - deal - debate - debris - decade - december - decide - decline - decorate - decrease - deer - defense - define - defy - degree - delay - deliver - demand - demise - denial - dentist - deny - depart - depend - deposit - depth - deputy - derive - describe - desert - design - desk - despair - destroy - detail - detect - develop - device - devote - diagram - dial - diamond - diary - dice - diesel - diet - differ - digital - dignity - dilemma - dinner - dinosaur - direct - dirt - disagree - discover - disease - dish - dismiss - disorder - display - distance - divert - divide - divorce - dizzy - doctor - document - dog - doll - dolphin - domain - donate - donkey - donor - door - dose - double - dove - draft - dragon - drama - drastic - draw - dream - dress - drift - drill - drink - drip - drive - drop - drum - dry - duck - dumb - dune - during - dust - dutch - duty - dwarf - dynamic - eager - eagle - early - earn - earth - easily - east - easy - echo - ecology - economy - edge - edit - educate - effort - egg - eight - either - elbow - elder - electric - elegant - element - elephant - elevator - elite - else - embark - embody - embrace - emerge - emotion - employ - empower - empty - enable - enact - end - endless - endorse - enemy - energy - enforce - engage - engine - enhance - enjoy - enlist - enough - enrich - enroll - ensure - enter - entire - entry - envelope - episode - equal - equip - era - erase - erode - erosion - error - erupt - escape - essay - essence - estate - eternal - ethics - evidence - evil - evoke - evolve - exact - example - excess - exchange - excite - exclude - excuse - execute - exercise - exhaust - exhibit - exile - exist - exit - exotic - expand - expect - expire - explain - expose - express - extend - extra - eye - eyebrow - fabric - face - faculty - fade - faint - faith - fall - false - fame - family - famous - fan - fancy - fantasy - farm - fashion - fat - fatal - father - fatigue - fault - favorite - feature - february - federal - fee - feed - feel - female - fence - festival - fetch - fever - few - fiber - fiction - field - figure - file - film - filter - final - find - fine - finger - finish - fire - firm - first - fiscal - fish - fit - fitness - fix - flag - flame - flash - flat - flavor - flee - flight - flip - float - flock - floor - flower - fluid - flush - fly - foam - focus - fog - foil - fold - follow - food - foot - force - forest - forget - fork - fortune - forum - forward - fossil - foster - found - fox - fragile - frame - frequent - fresh - friend - fringe - frog - front - frost - frown - frozen - fruit - fuel - fun - funny - furnace - fury - future - gadget - gain - galaxy - gallery - game - gap - garage - garbage - garden - garlic - garment - gas - gasp - gate - gather - gauge - gaze - general - genius - genre - gentle - genuine - gesture - ghost - giant - gift - giggle - ginger - giraffe - girl - give - glad - glance - glare - glass - glide - glimpse - globe - gloom - glory - glove - glow - glue - goat - goddess - gold - good - goose - gorilla - gospel - gossip - govern - gown - grab - grace - grain - grant - grape - grass - gravity - great - green - grid - grief - grit - grocery - group - grow - grunt - guard - guess - guide - guilt - guitar - gun - gym - habit - hair - half - hammer - hamster - hand - happy - harbor - hard - harsh - harvest - hat - have - hawk - hazard - head - health - heart - heavy - hedgehog - height - hello - helmet - help - hen - hero - hidden - high - hill - hint - hip - hire - history - hobby - hockey - hold - hole - holiday - hollow - home - honey - hood - hope - horn - horror - horse - hospital - host - hotel - hour - hover - hub - huge - human - humble - humor - hundred - hungry - hunt - hurdle - hurry - hurt - husband - hybrid - ice - icon - idea - identify - idle - ignore - ill - illegal - illness - image - imitate - immense - immune - impact - impose - improve - impulse - inch - include - income - increase - index - indicate - indoor - industry - infant - inflict - inform - inhale - inherit - initial - inject - injury - inmate - inner - innocent - input - inquiry - insane - insect - inside - inspire - install - intact - interest - into - invest - invite - involve - iron - island - isolate - issue - item - ivory - jacket - jaguar - jar - jazz - jealous - jeans - jelly - jewel - job - join - joke - journey - joy - judge - juice - jump - jungle - junior - junk - just - kangaroo - keen - keep - ketchup - key - kick - kid - kidney - kind - kingdom - kiss - kit - kitchen - kite - kitten - kiwi - knee - knife - knock - know - lab - label - labor - ladder - lady - lake - lamp - language - laptop - large - later - latin - laugh - laundry - lava - law - lawn - lawsuit - layer - lazy - leader - leaf - learn - leave - lecture - left - leg - legal - legend - leisure - lemon - lend - length - lens - leopard - lesson - letter - level - liar - liberty - library - license - life - lift - light - like - limb - limit - link - lion - liquid - list - little - live - lizard - load - loan - lobster - local - lock - logic - lonely - long - loop - lottery - loud - lounge - love - loyal - lucky - luggage - lumber - lunar - lunch - luxury - lyrics - machine - mad - magic - magnet - maid - mail - main - major - make - mammal - man - manage - mandate - mango - mansion - manual - maple - marble - march - margin - marine - market - marriage - mask - mass - master - match - material - math - matrix - matter - maximum - maze - meadow - mean - measure - meat - mechanic - medal - media - melody - melt - member - memory - mention - menu - mercy - merge - merit - merry - mesh - message - metal - method - middle - midnight - milk - million - mimic - mind - minimum - minor - minute - miracle - mirror - misery - miss - mistake - mix - mixed - mixture - mobile - model - modify - mom - moment - monitor - monkey - monster - month - moon - moral - more - morning - mosquito - mother - motion - motor - mountain - mouse - move - movie - much - muffin - mule - multiply - muscle - museum - mushroom - music - must - mutual - myself - mystery - myth - naive - name - napkin - narrow - nasty - nation - nature - near - neck - need - negative - neglect - neither - nephew - nerve - nest - net - network - neutral - never - news - next - nice - night - noble - noise - nominee - noodle - normal - north - nose - notable - note - nothing - notice - novel - now - nuclear - number - nurse - nut - oak - obey - object - oblige - obscure - observe - obtain - obvious - occur - ocean - october - odor - off - offer - office - often - oil - okay - old - olive - olympic - omit - once - one - onion - online - only - open - opera - opinion - oppose - option - orange - orbit - orchard - order - ordinary - organ - orient - original - orphan - ostrich - other - outdoor - outer - output - outside - oval - oven - over - own - owner - oxygen - oyster - ozone - pact - paddle - page - pair - palace - palm - panda - panel - panic - panther - paper - parade - parent - park - parrot - party - pass - patch - path - patient - patrol - pattern - pause - pave - payment - peace - peanut - pear - peasant - pelican - pen - penalty - pencil - people - pepper - perfect - permit - person - pet - phone - photo - phrase - physical - piano - picnic - picture - piece - pig - pigeon - pill - pilot - pink - pioneer - pipe - pistol - pitch - pizza - place - planet - plastic - plate - play - please - pledge - pluck - plug - plunge - poem - poet - point - polar - pole - police - pond - pony - pool - popular - portion - position - possible - post - potato - pottery - poverty - powder - power - practice - praise - predict - prefer - prepare - present - pretty - prevent - price - pride - primary - print - priority - prison - private - prize - problem - process - produce - profit - program - project - promote - proof - property - prosper - protect - proud - provide - public - pudding - pull - pulp - pulse - pumpkin - punch - pupil - puppy - purchase - purity - purpose - purse - push - put - puzzle - pyramid - quality - quantum - quarter - question - quick - quit - quiz - quote - rabbit - raccoon - race - rack - radar - radio - rail - rain - raise - rally - ramp - ranch - random - range - rapid - rare - rate - rather - raven - raw - razor - ready - real - reason - rebel - rebuild - recall - receive - recipe - record - recycle - reduce - reflect - reform - refuse - region - regret - regular - reject - relax - release - relief - rely - remain - remember - remind - remove - render - renew - rent - reopen - repair - repeat - replace - report - require - rescue - resemble - resist - resource - response - result - retire - retreat - return - reunion - reveal - review - reward - rhythm - rib - ribbon - rice - rich - ride - ridge - rifle - right - rigid - ring - riot - ripple - risk - ritual - rival - river - road - roast - robot - robust - rocket - romance - roof - rookie - room - rose - rotate - rough - round - route - royal - rubber - rude - rug - rule - run - runway - rural - sad - saddle - sadness - safe - sail - salad - salmon - salon - salt - salute - same - sample - sand - satisfy - satoshi - sauce - sausage - save - say - scale - scan - scare - scatter - scene - scheme - school - science - scissors - scorpion - scout - scrap - screen - script - scrub - sea - search - season - seat - second - secret - section - security - seed - seek - segment - select - sell - seminar - senior - sense - sentence - series - service - session - settle - setup - seven - shadow - shaft - shallow - share - shed - shell - sheriff - shield - shift - shine - ship - shiver - shock - shoe - shoot - shop - short - shoulder - shove - shrimp - shrug - shuffle - shy - sibling - sick - side - siege - sight - sign - silent - silk - silly - silver - similar - simple - since - sing - siren - sister - situate - six - size - skate - sketch - ski - skill - skin - skirt - skull - slab - slam - sleep - slender - slice - slide - slight - slim - slogan - slot - slow - slush - small - smart - smile - smoke - smooth - snack - snake - snap - sniff - snow - soap - soccer - social - sock - soda - soft - solar - soldier - solid - solution - solve - someone - song - soon - sorry - sort - soul - sound - soup - source - south - space - spare - spatial - spawn - speak - special - speed - spell - spend - sphere - spice - spider - spike - spin - spirit - split - spoil - sponsor - spoon - sport - spot - spray - spread - spring - spy - square - squeeze - squirrel - stable - stadium - staff - stage - stairs - stamp - stand - start - state - stay - steak - steel - stem - step - stereo - stick - still - sting - stock - stomach - stone - stool - story - stove - strategy - street - strike - strong - struggle - student - stuff - stumble - style - subject - submit - subway - success - such - sudden - suffer - sugar - suggest - suit - summer - sun - sunny - sunset - super - supply - supreme - sure - surface - surge - surprise - surround - survey - suspect - sustain - swallow - swamp - swap - swarm - swear - sweet - swift - swim - swing - switch - sword - symbol - symptom - syrup - system - table - tackle - tag - tail - talent - talk - tank - tape - target - task - taste - tattoo - taxi - teach - team - tell - ten - tenant - tennis - tent - term - test - text - thank - that - theme - then - theory - there - they - thing - this - thought - three - thrive - throw - thumb - thunder - ticket - tide - tiger - tilt - timber - time - tiny - tip - tired - tissue - title - toast - tobacco - today - toddler - toe - together - toilet - token - tomato - tomorrow - tone - tongue - tonight - tool - tooth - top - topic - topple - torch - tornado - tortoise - toss - total - tourist - toward - tower - town - toy - track - trade - traffic - tragic - train - transfer - trap - trash - travel - tray - treat - tree - trend - trial - tribe - trick - trigger - trim - trip - trophy - trouble - truck - true - truly - trumpet - trust - truth - try - tube - tuition - tumble - tuna - tunnel - turkey - turn - turtle - twelve - twenty - twice - twin - twist - two - type - typical - ugly - umbrella - unable - unaware - uncle - uncover - under - undo - unfair - unfold - unhappy - uniform - unique - unit - universe - unknown - unlock - until - unusual - unveil - update - upgrade - uphold - upon - upper - upset - urban - urge - usage - use - used - useful - useless - usual - utility - vacant - vacuum - vague - valid - valley - valve - van - vanish - vapor - various - vast - vault - vehicle - velvet - vendor - venture - venue - verb - verify - version - very - vessel - veteran - viable - vibrant - vicious - victory - video - view - village - vintage - violin - virtual - virus - visa - visit - visual - vital - vivid - vocal - voice - void - volcano - volume - vote - voyage - wage - wagon - wait - walk - wall - walnut - want - warfare - warm - warrior - wash - wasp - waste - water - wave - way - wealth - weapon - wear - weasel - weather - web - wedding - weekend - weird - welcome - west - wet - whale - what - wheat - wheel - when - where - whip - whisper - wide - width - wife - wild - will - win - window - wine - wing - wink - winner - winter - wire - wisdom - wise - wish - witness - wolf - woman - wonder - wood - wool - word - work - world - worry - worth - wrap - wreck - wrestle - wrist - write - wrong - yard - year - yellow - you - young - youth - zebra - zero - zone - zoo - - diff --git a/loafwallet/ar.lproj/LaunchScreen.strings b/loafwallet/ar.lproj/LaunchScreen.strings deleted file mode 100644 index 8b1378917..000000000 --- a/loafwallet/ar.lproj/LaunchScreen.strings +++ /dev/null @@ -1 +0,0 @@ - diff --git a/loafwallet/src/ApplicationController.swift b/loafwallet/src/ApplicationController.swift index ce4439d35..e69bcf1e5 100644 --- a/loafwallet/src/ApplicationController.swift +++ b/loafwallet/src/ApplicationController.swift @@ -7,7 +7,7 @@ // import UIKit -import StoreKit +import StoreKit private let timeSinceLastExitKey = "TimeSinceLastExit" private let shouldRequireLoginTimeoutKey = "ShouldRequireLoginTimeoutKey" @@ -83,8 +83,7 @@ class ApplicationController : Subscriber, Trackable { private func setup() { setupDefaults() - countLaunches() - setupAppearance() + countLaunches() setupRootViewController() window?.makeKeyAndVisible() listenForPushNotificationRequest() @@ -246,14 +245,6 @@ class ApplicationController : Subscriber, Trackable { UserDefaults.standard.set(NSNumber(value: 1), forKey: numberOfLitewalletLaunches) } } - - private func setupAppearance() { - let tabBar = UITabBar.appearance() - tabBar.barTintColor = .liteWalletBlue - tabBar.unselectedItemTintColor = #colorLiteral(red: 0.7764705882, green: 0.7764705882, blue: 0.7843137255, alpha: 0.5) - tabBar.tintColor = .white - } - private func setupRootViewController() { mainViewController = MainViewController(store: store) window?.rootViewController = mainViewController diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index d6b9cf4a9..a6f5cf93f 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -71,6 +71,23 @@ struct Padding { } } +struct DeviceType { + + enum Name { + static var iPhoneSE = "iPhone SE" + static var iPhoneSE2 = "iPhone SE2" + static var iPhone7 = "iPhone 7" + static var iPhone8 = "iPhone 8" + static var iPhone8Plus = "iPhone 8+" + static var iPhoneXSMax = "iPhone Xs Max" + static var iPhone11ProMax = "iPhone 11 Pro Max" + static var iPhone12Pro = "iPhone 12 Pro" + static var iPhone12ProMax = "iPhone 12 Pro Max" + static var iPadPro = "iPad Pro (12.9-inch) (3rd generation)" + } + +} + struct C { static let padding = Padding() struct Sizes { diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index c4b4a3e16..eabf375fb 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -35,6 +35,7 @@ enum S { static let asOf = NSLocalizedString("Conjunction.asOf", value: "**as of**", comment: "as of a time or date") } + //MARK: - Generic Button labels enum Button { static let ok = NSLocalizedString("Button.ok", value: "**OK**", comment: "OK button label") static let cancel = NSLocalizedString("Button.cancel", value: "**Cancel**", comment: "Cancel button label") @@ -47,10 +48,10 @@ enum S { static let receive = NSLocalizedString("Button.receive", value: "**receive**", comment: "receive button") static let menu = NSLocalizedString("Button.menu", value: "**menu**", comment: "menu button") static let buy = NSLocalizedString("Button.buy", value: "**buy**", comment: "buy button") - + static let resetFields = NSLocalizedString("Button.resetFields", value: "**reset**", comment: "resetFields") } - enum Alert { + enum LitewalletAlert { static let warning = NSLocalizedString("Alert.warning", value: "**Warning**", comment: "Warning alert title") static let error = NSLocalizedString("Alert.error", value: "**Error**", comment: "Error alert title") static let noInternet = NSLocalizedString("Alert.noInternet", value: "**No internet connection found. Check your connection and try again.**", comment: "No internet alert message") @@ -113,6 +114,52 @@ enum S { static let barItemTitle = NSLocalizedString("Receive.barItemTitle", value: "**Receive**", comment: "Receive Bar Item Title") } + //MARK: - Litecoin Card + enum LitecoinCard { + static let barItemTitle = NSLocalizedString("LitecoinCard.barItemTitle", value: "**Card**", comment: "Card Bar Item Title") + static let login = NSLocalizedString("LitecoinCard.login", value: "**Login**", comment: "Login") + static let failedlogin = NSLocalizedString("LitecoinCard.failed.login", value: "**Failed Login**", comment: "Failed Login") + static let logout = NSLocalizedString("LitecoinCard.logout", value: "**Logout**", comment: "Logout") + static let forgotPassword = NSLocalizedString("LitecoinCard.forgotPassword", value: "**Forgot password?**", comment: "Forgot password?") + static let visitToReset = NSLocalizedString("LitecoinCard.visit.toReset", value: "**Reset Litecoin card visit**", comment: "Litecoin card visit") + static let resetPassword = NSLocalizedString("LitecoinCard.resetPassword", value: "**Reset Litecoin card password**", comment: "Reset Litecoin card password") + static let registerCard = NSLocalizedString("LitecoinCard.registerCard", value: "**Register**", comment: "Register") + static let registeringUser = NSLocalizedString("LitecoinCard.registering.user", value: "**Registering user...**", comment: "Registering user...") + + static let cardBalance = NSLocalizedString("LitecoinCard.cardBalance", value: "", comment: "Card balance") + static let registrationSuccess = NSLocalizedString("LitecoinCard.registrationSuccess", value: "", comment: "Registration success") + static let registrationFailure = NSLocalizedString("LitecoinCard.registrationFailure", value: "", comment: "Registration failure") + + //MARK: - Registration + enum Registration { + static let registerCardPhrase = NSLocalizedString("LitecoinCard.registerCardPhrase", value: "**Register for Litecoin Card**", comment: "Register for Litecoin Card") + static let password = NSLocalizedString("LitecoinCard.Registration.password", value: "", comment: "password") + static let confirmPassword = NSLocalizedString("LitecoinCard.Registration.confirmPassword", value: "", comment: "confirm password") + static let firstName = NSLocalizedString("LitecoinCard.Registration.firstName", value: "", comment: "First name") + static let lastName = NSLocalizedString("LitecoinCard.Registration.lastName", value: "", comment: "Last name") + static let kycSSN = NSLocalizedString("LitecoinCard.Registration.kycSSN", value: "", comment: "SSN") + static let kycIDNumber = NSLocalizedString("LitecoinCard.Registration.kycIDNumber", value: "", comment: "kycIDNumber") + static let kycIDType = NSLocalizedString("LitecoinCard.Registration.kycIDType", value: "", comment: "kycIDType") + static let address = NSLocalizedString("LitecoinCard.Registration.address", value: "", comment: "address") + static let city = NSLocalizedString("LitecoinCard.Registration.city", value: "", comment: "city") + static let stateProvince = NSLocalizedString("LitecoinCard.Registration.stateProvince", value: "", comment: "state province") + static let country = NSLocalizedString("LitecoinCard.Registration.country", value: "", comment: "country") + static let zipPostCode = NSLocalizedString("LitecoinCard.Registration.zipPostCode", value: "", comment: "zip post Code") + static let mobileNumber = NSLocalizedString("LitecoinCard.Registration.mobileNumber", value: "", comment: "mobile number") + static let identification = NSLocalizedString("LitecoinCard.Registration.identification", value: "", comment: "identification") + + enum ValidationError { + static let empty = NSLocalizedString("LitecoinCard.Registration.ValidationError.empty", value: "Most not be empty", comment: "must not be empty") + static let numberRequired = NSLocalizedString("LitecoinCard.Registration.ValidationError.numberRequired", value: "Mobile number required", comment: "Mobile number required") + static let numberDigitsRequired = NSLocalizedString("LitecoinCard.Registration.ValidationError.numberDigitsRequired", value: "Mobile number 10 digits required", comment: "Mobile number 10 digits required") + static let requiredField = NSLocalizedString("LitecoinCard.Registration.ValidationError.requiredField", value: "Required field", comment: "Required field") + static let passwordRequired = NSLocalizedString("LitecoinCard.Registration.ValidationError.passwordRequired", value: "Password required", comment: "Password required") + static let passwordCharacters = NSLocalizedString("LitecoinCard.Registration.ValidationError.passwordCharacters", value: "6 password Characters required", comment: "6 Password characters required") + static let passwordComposition = NSLocalizedString("LitecoinCard.Registration.ValidationError.passwordComposition", value: "Capital and numeric password characters required", comment: "Captial and numeric password characters required") + static let invalidEmail = NSLocalizedString("LitecoinCard.Registration.ValidationError.invalidEmail", value: "Invalid email address", comment: "Invalid email address") + } + } + } enum Account { static let loadingMessage = NSLocalizedString("Account.loadingMessage", value: "**Loading Wallet**", comment: "Loading Wallet Message") } @@ -192,7 +239,8 @@ enum S { static let staticTXIDLabel = NSLocalizedString("TransactionDetails.staticTXLabel", value: "**TXID:**", comment: "Label for TXID") static let priceTimeStampLabel = NSLocalizedString("TransactionDetails.priceTimeStampPrefix", value: "**as of**", comment: "Prefix for price") } - + + //MARK: - Buy Center enum BuyCenter { static let title = NSLocalizedString("BuyCenter.title", value: "**Buy Litecoin**", comment: "Buy Center Title") static let buyModalTitle = NSLocalizedString("BuyCenter.ModalTitle", value: "**Buy Łitecoin**", comment: "Buy Modal Title") @@ -206,7 +254,8 @@ enum S { } static let barItemTitle = NSLocalizedString("BuyCenter.barItemTitle", value: "**Buy**", comment: "Buy Bar Item Title") } - + + //MARK: - Security Center enum SecurityCenter { static let title = NSLocalizedString("SecurityCenter.title", value: "**Security Center**", comment: "Security Center Title") static let info = NSLocalizedString("SecurityCenter.info", value: "**Enable all security features for maximum protection.**", comment: "Security Center Info") @@ -305,6 +354,7 @@ enum S { static let title = NSLocalizedString("FaceIDSpendingLimit.title", value: "**Face ID Spending Limit**", comment: "Face Id spending limit screen title") } + //MARK: - Settings enum Settings { static let title = NSLocalizedString("Settings.title", value: "**Settings**", comment: "Settings title") static let wallet = NSLocalizedString("Settings.wallet", value: "**Wallet**", comment: "Wallet Settings section header") @@ -417,7 +467,8 @@ enum S { static let noAmount = NSLocalizedString("RequestAnAmount.noAmount", value: "**Please enter an amount first.**", comment: "No amount entered error message.") } - enum Alerts { + //MARK: - Security Alerts + enum SecurityAlerts { static let pinSet = NSLocalizedString("Alerts.pinSet", value: "**PIN Set**", comment: "Alert Header label (the PIN was set)") static let paperKeySet = NSLocalizedString("Alerts.paperKeySet", value: "**Paper Key Set**", comment: "Alert Header Label (the paper key was set)") static let sendSuccess = NSLocalizedString("Alerts.sendSuccess", value: "**Send Confirmation**", comment: "Send success alert header label (confirmation that the send happened)") @@ -495,6 +546,7 @@ enum S { } } + //MARK: - Payment Protocol enum PaymentProtocol { enum Errors { static let untrustedCertificate = NSLocalizedString("PaymentProtocol.Errors.untrustedCertificate", value: "**untrusted certificate**", comment: "Untrusted certificate payment protocol error message") @@ -571,16 +623,17 @@ enum S { } } - enum BitID { - static let title = NSLocalizedString("BitID.title", value: "**BitID Authentication Request**", comment: "BitID Authentication Request alert view title") - static let authenticationRequest = NSLocalizedString("BitID.authenticationRequest", value: "**%1$@ is requesting authentication using your Litecoin wallet**", comment: " is requesting authentication using your Litecoin wallet") - static let deny = NSLocalizedString("BitID.deny", value: "**Deny**", comment: "Deny button label") - static let approve = NSLocalizedString("BitID.approve", value: "**Approve**", comment: "Approve button label") - static let success = NSLocalizedString("BitID.success", value: "**Successfully Authenticated**", comment: "BitID success alert title") - static let error = NSLocalizedString("BitID.error", value: "**Authentication Error**", comment: "BitID error alert title") - static let errorMessage = NSLocalizedString("BitID.errorMessage", value: "**Please check with the service. You may need to try again.**", comment: "BitID error alert messaage") + //DEV: Removing eventually + // enum BitID { +// static let title = NSLocalizedString("BitID.title", value: "**BitID Authentication Request**", comment: "BitID Authentication Request alert view title") +// static let authenticationRequest = NSLocalizedString("BitID.authenticationRequest", value: "**%1$@ is requesting authentication using your Litecoin wallet**", comment: " is requesting authentication using your Litecoin wallet") +// static let deny = NSLocalizedString("BitID.deny", value: "**Deny**", comment: "Deny button label") +// static let approve = NSLocalizedString("BitID.approve", value: "**Approve**", comment: "Approve button label") +// static let success = NSLocalizedString("BitID.success", value: "**Successfully Authenticated**", comment: "BitID success alert title") +// static let error = NSLocalizedString("BitID.error", value: "**Authentication Error**", comment: "BitID error alert title") +// static let errorMessage = NSLocalizedString("BitID.errorMessage", value: "**Please check with the service. You may need to try again.**", comment: "BitID error alert messaage") - } + // } enum SupportLitecoinFoundation { static let title = NSLocalizedString("SupportTheFoundation.title", value: "**Support the Litecoin Foundation**", comment: "Support the Litecoin Foundation") diff --git a/loafwallet/src/Controls/MenuButtonType.swift b/loafwallet/src/Controls/MenuButtonType.swift index f320b13af..0fc8c44c7 100644 --- a/loafwallet/src/Controls/MenuButtonType.swift +++ b/loafwallet/src/Controls/MenuButtonType.swift @@ -37,7 +37,7 @@ enum MenuButtonType { case .support: return #imageLiteral(resourceName: "FaqFill") case .supportLF: - return #imageLiteral(resourceName: "BuyLitecoin") + return #imageLiteral(resourceName: "buy_icon_gray") case .settings: return #imageLiteral(resourceName: "Settings") case .lock: diff --git a/loafwallet/src/Extensions/UINavigationController+BRAdditions.swift b/loafwallet/src/Extensions/UINavigationController+Extension.swift similarity index 92% rename from loafwallet/src/Extensions/UINavigationController+BRAdditions.swift rename to loafwallet/src/Extensions/UINavigationController+Extension.swift index eb5b6acbd..bcc316e2b 100644 --- a/loafwallet/src/Extensions/UINavigationController+BRAdditions.swift +++ b/loafwallet/src/Extensions/UINavigationController+Extension.swift @@ -7,14 +7,19 @@ // import UIKit +import SwiftUI extension UINavigationController { - + + override open func viewDidLoad() { + super.viewDidLoad() + } + func setDefaultStyle() { setClearNavbar() setBlackBackArrow() } - + func setWhiteStyle() { navigationBar.tintColor = .white navigationBar.titleTextAttributes = [ @@ -23,28 +28,27 @@ extension UINavigationController { ] setTintableBackArrow() } - + func setClearNavbar() { navigationBar.setBackgroundImage(UIImage(), for: .default) navigationBar.shadowImage = UIImage() navigationBar.isTranslucent = true } - + func setNormalNavbar() { navigationBar.setBackgroundImage(nil, for: .default) navigationBar.shadowImage = nil } - + func setBlackBackArrow() { let image = #imageLiteral(resourceName: "Back") let renderedImage = image.withRenderingMode(.alwaysOriginal) navigationBar.backIndicatorImage = renderedImage navigationBar.backIndicatorTransitionMaskImage = renderedImage } - + func setTintableBackArrow() { navigationBar.backIndicatorImage = #imageLiteral(resourceName: "Back") navigationBar.backIndicatorTransitionMaskImage = #imageLiteral(resourceName: "Back") } - } diff --git a/loafwallet/src/Extensions/UIViewController+Alerts.swift b/loafwallet/src/Extensions/UIViewController+Alerts.swift index af720cb1f..b0f1b9b28 100644 --- a/loafwallet/src/Extensions/UIViewController+Alerts.swift +++ b/loafwallet/src/Extensions/UIViewController+Alerts.swift @@ -11,7 +11,7 @@ import UIKit extension UIViewController { func showErrorMessage(_ message: String) { - let alert = UIAlertController(title: S.Alert.error, message: message, preferredStyle: .alert) + let alert = UIAlertController(title: S.LitewalletAlert.error, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) present(alert, animated: true, completion: nil) } diff --git a/loafwallet/src/FlowControllers/StartFlowPresenter.swift b/loafwallet/src/FlowControllers/StartFlowPresenter.swift index 95435ef87..a9cbccb04 100644 --- a/loafwallet/src/FlowControllers/StartFlowPresenter.swift +++ b/loafwallet/src/FlowControllers/StartFlowPresenter.swift @@ -169,7 +169,7 @@ class StartFlowPresenter : Subscriber { confirmVC?.pin = pin confirmVC?.didCompleteConfirmation = { [weak self] in guard let myself = self else { return } - myself.store.perform(action: Alert.Show(.paperKeySet(callback: { + myself.store.perform(action: SimpleReduxAlert.Show(.paperKeySet(callback: { self?.store.perform(action: HideStartFlow()) }))) } @@ -192,7 +192,7 @@ class StartFlowPresenter : Subscriber { } private func handleWalletCreationError() { - let alert = UIAlertController(title: S.Alert.error, message: "Could not create wallet", preferredStyle: .alert) + let alert = UIAlertController(title: S.LitewalletAlert.error, message: "Could not create wallet", preferredStyle: .alert) alert.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) navigationController?.present(alert, animated: true, completion: nil) } diff --git a/loafwallet/src/FlowControllers/URLController.swift b/loafwallet/src/FlowControllers/URLController.swift index b1fd54bc7..be6916162 100644 --- a/loafwallet/src/FlowControllers/URLController.swift +++ b/loafwallet/src/FlowControllers/URLController.swift @@ -64,11 +64,11 @@ class URLController : Trackable { return true case "litecoin": return handleBitcoinUri(url) - case "bitid": - if BRBitID.isBitIDURL(url) { - handleBitId(url) - } - return true +// case "bitid": +// if BRBitID.isBitIDURL(url) { +// handleBitId(url) +// } +// return true default: return false } @@ -103,26 +103,26 @@ class URLController : Trackable { } } - private func handleBitId(_ url: URL) { - let bitid = BRBitID(url: url, walletManager: walletManager) - let message = String(format: S.BitID.authenticationRequest, bitid.siteName) - let alert = UIAlertController(title: S.BitID.title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: S.BitID.deny, style: .cancel, handler: nil)) - alert.addAction(UIAlertAction(title: S.BitID.approve, style: .default, handler: { _ in - bitid.runCallback(store: self.store) { data, response, error in - if let resp = response as? HTTPURLResponse, error == nil && resp.statusCode >= 200 && resp.statusCode < 300 { - let alert = UIAlertController(title: S.BitID.success, message: nil, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) - self.present(alert: alert) - } else { - let alert = UIAlertController(title: S.BitID.error, message: S.BitID.errorMessage, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) - self.present(alert: alert) - } - } - })) - present(alert: alert) - } +// private func handleBitId(_ url: URL) { +// let bitid = BRBitID(url: url, walletManager: walletManager) +// let message = String(format: S.BitID.authenticationRequest, bitid.siteName) +// let alert = UIAlertController(title: S.BitID.title, message: message, preferredStyle: .alert) +// alert.addAction(UIAlertAction(title: S.BitID.deny, style: .cancel, handler: nil)) +// alert.addAction(UIAlertAction(title: S.BitID.approve, style: .default, handler: { _ in +// bitid.runCallback(store: self.store) { data, response, error in +// if let resp = response as? HTTPURLResponse, error == nil && resp.statusCode >= 200 && resp.statusCode < 300 { +// let alert = UIAlertController(title: S.BitID.success, message: nil, preferredStyle: .alert) +// alert.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) +// self.present(alert: alert) +// } else { +// let alert = UIAlertController(title: S.BitID.error, message: S.BitID.errorMessage, preferredStyle: .alert) +// alert.addAction(UIAlertAction(title: S.Button.ok, style: .default, handler: nil)) +// self.present(alert: alert) +// } +// } +// })) +// present(alert: alert) +// } private func present(alert: UIAlertController) { store.trigger(name: .showAlert(alert)) diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 902738b6c..1526a61a3 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -192,7 +192,7 @@ class ModalPresenter : Subscriber, Trackable { private func handleAlertChange(_ type: AlertType?) { guard let type = type else { return } presentAlert(type, completion: { - self.store.perform(action: Alert.Hide()) + self.store.perform(action: SimpleReduxAlert.Hide()) }) } @@ -291,7 +291,7 @@ class ModalPresenter : Subscriber, Trackable { private func makeSendView() -> UIViewController? { guard !store.state.walletState.isRescanning else { - let alert = UIAlertController(title: S.Alert.error, message: S.Send.isRescanning, preferredStyle: .alert) + let alert = UIAlertController(title: S.LitewalletAlert.error, message: S.Send.isRescanning, preferredStyle: .alert) alert.addAction(UIAlertAction(title: S.Button.ok, style: .cancel, handler: nil)) topViewController?.present(alert, animated: true, completion: nil) return nil @@ -363,10 +363,16 @@ class ModalPresenter : Subscriber, Trackable { menu.didTapSupportLF = { [weak self, weak menu] in menu?.dismiss(animated: true, completion: { - self?.presentSupportLF() + self?.messagePresenter.presenter = self?.topViewController + self?.messagePresenter.presentSupportCompose() }) } + menu.didTapSupportLF = { [weak self, weak menu] in + menu?.dismiss(animated: true, completion: { + self?.presentSupportLF() + }) + } menu.didTapLock = { [weak self, weak menu] in menu?.dismiss(animated: true) { self?.store.trigger(name: .lock) @@ -548,6 +554,7 @@ class ModalPresenter : Subscriber, Trackable { private func presentSupportLF() { let supportLFView = UIHostingController(rootView: SupportLitecoinFoundationView(viewModel: SupportLitecoinFoundationViewModel())) + supportLFView.rootView.viewModel.didTapToDismiss = { supportLFView.dismiss(animated: true) { //TODO: Track in Analytics @@ -556,6 +563,7 @@ class ModalPresenter : Subscriber, Trackable { window.rootViewController?.present(supportLFView, animated: true, completion: nil) } + private func presentSecurityCenter() { guard let walletManager = walletManager else { return } let securityCenter = SecurityCenterViewController(store: store, walletManager: walletManager) @@ -622,7 +630,7 @@ class ModalPresenter : Subscriber, Trackable { confirmVC?.pin = pin confirmVC?.didCompleteConfirmation = { confirmVC?.dismiss(animated: true, completion: { - myself.store.perform(action: Alert.Show(.paperKeySet(callback: { + myself.store.perform(action: SimpleReduxAlert.Show(.paperKeySet(callback: { myself.store.perform(action: HideStartFlow()) }))) @@ -671,7 +679,7 @@ class ModalPresenter : Subscriber, Trackable { paperPhraseNavigationController.viewControllers = [start] vc.present(paperPhraseNavigationController, animated: true, completion: nil) } - + private func wipeWallet() { let group = DispatchGroup() let alert = UIAlertController(title: S.WipeWallet.alertTitle, message: S.WipeWallet.alertMessage, preferredStyle: .alert) @@ -738,7 +746,7 @@ class ModalPresenter : Subscriber, Trackable { } //TODO - handle payment type } else { - let alert = UIAlertController(title: S.Alert.error, message: S.PaymentProtocol.Errors.corruptedDocument, preferredStyle: .alert) + let alert = UIAlertController(title: S.LitewalletAlert.error, message: S.PaymentProtocol.Errors.corruptedDocument, preferredStyle: .alert) alert.addAction(UIAlertAction(title: S.Button.ok, style: .cancel, handler: nil)) topViewController?.present(alert, animated: true, completion: nil) } @@ -783,7 +791,7 @@ class ModalPresenter : Subscriber, Trackable { if walletManager.authenticate(pin: pin) { self?.copyAllAddressesToClipboard() view.dismiss(animated: true, completion: { - self?.store.perform(action: Alert.Show(.addressesCopied)) + self?.store.perform(action: SimpleReduxAlert.Show(.addressesCopied)) if let success = success, let url = URL(string: success) { UIApplication.shared.open(url, options: [:], completionHandler: nil) } @@ -855,7 +863,7 @@ class ModalPresenter : Subscriber, Trackable { private func showNotReachable() { guard notReachableAlert == nil else { return } - let alert = InAppAlert(message: S.Alert.noInternet, image: #imageLiteral(resourceName: "BrokenCloud")) + let alert = InAppAlert(message: S.LitewalletAlert.noInternet, image: #imageLiteral(resourceName: "BrokenCloud")) notReachableAlert = alert let window = UIApplication.shared.keyWindow! let size = window.bounds.size diff --git a/loafwallet/src/Sender.swift b/loafwallet/src/Sender.swift index 2731834d7..618ed5406 100644 --- a/loafwallet/src/Sender.swift +++ b/loafwallet/src/Sender.swift @@ -104,7 +104,7 @@ class Sender { let properties: [String: String] = ["ERROR_TX":"\(tx.txHash)","ERROR_BLOCKHEIGHT": "\(tx.blockHeight)"] LWAnalytics.logEventWithParameters(itemName:._20200112_ERR, properties: properties) - let alert = UIAlertController(title: S.Alert.corruptionError, message: S.Alert.corruptionMessage, preferredStyle: .alert) + let alert = UIAlertController(title: S.LitewalletAlert.corruptionError, message: S.LitewalletAlert.corruptionMessage, preferredStyle: .alert) UserDefaults.didSeeCorruption = true alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) diff --git a/loafwallet/src/SimpleRedux/Actions.swift b/loafwallet/src/SimpleRedux/Actions.swift index 228b585c5..77d37490c 100644 --- a/loafwallet/src/SimpleRedux/Actions.swift +++ b/loafwallet/src/SimpleRedux/Actions.swift @@ -139,7 +139,7 @@ enum ExchangeRates { } //MARK: - Alerts -enum Alert { +enum SimpleReduxAlert { struct Show : Action { let reduce: Reducer init(_ type: AlertType) { diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 16311cde3..90e42bf76 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1282,11 +1282,125 @@ /* Litewallet Partners */ "Settings.litewallet.partners" = "Litewallet partners"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "Card"; + +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Lookup"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Forgot password?"; + +/* Login */ +"LitecoinCard.login" = "Login"; + +/* Register */ +"LitecoinCard.registerCard" = "Register"; + +/* Litecoin card */ +"LitecoinCard.registerCardPhrase" = "Register for Litecoin Card"; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Reset password"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Visit https://litecoin.dashboard.getblockcard.com/password/forgot\nto reset your password."; + +/* address */ +"LitecoinCard.Registration.address" = "Address"; + +/* city */ +"LitecoinCard.Registration.city" = "City"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "Confirm password"; + +/* country */ +"LitecoinCard.Registration.country" = "Country"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "First name"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "ID Number"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "Last name"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Mobile number"; + +/* password */ +"LitecoinCard.Registration.password" = "Password"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "State / Province"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Email (Username)"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Zip / Postcode"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identification"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCard.phrase" = "Register for Litecoin Card"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID Type"; + +/* resetFields */ +"Button.resetFields" = "Reset fields"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Registering user ..."; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Card balance"; + +/* Logout */ +"LitecoinCard.logout" = "Logout"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "There was a problem with your registration. \nPlease check your data and try again."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "You have registered!\nPlease check and confirm your email. Then come back to login."; + /* Resolved Success */ "Alerts.resolvedSuccess" = "Domain Resolution"; /* No comment provided by engineer. */ "Alerts.resolvedSuccessSubheader" = "Address was resolved!"; -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Lookup"; +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Must not be empty"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Invalid e-mail Address"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Mobile number must have at least 10 digits"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Mobile number is required"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Password must have at least 6 characters"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Password must be more than 6 characters, with at least one character and one numeric character"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Password is Required"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "Required field"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Login failed"; diff --git a/loafwallet/src/Strings/ar.lproj/Localizable.strings b/loafwallet/src/Strings/ar.lproj/Localizable.strings deleted file mode 100644 index c47cc6913..000000000 --- a/loafwallet/src/Strings/ar.lproj/Localizable.strings +++ /dev/null @@ -1,1277 +0,0 @@ -/* About screen website label */ -"About.blog" = "Website"; - -/* About screen footer */ -"About.footer" = "Made by the LiteWallet Team\nof the\nLitecoin Foundation\n%1$@"; - -/* Privay Policy button label */ -"About.privacy" = "Privacy Policy"; - -/* About screen reddit label */ -"About.reddit" = "Reddit"; - -/* About screen title */ -"About.title" = "About"; - -/* About screen twitter label */ -"About.twitter" = "Twitter"; - -/* Close modal button accessibility label */ -"AccessibilityLabels.close" = "Close"; - -/* Support center accessibiliy label */ -"AccessibilityLabels.faq" = "Support Center"; - -/* Loading Wallet Message */ -"Account.loadingMessage" = "Loading Wallet"; - -/* Default wallet name */ -"AccountHeader.defaultWalletName" = "My Litewallet"; - -/* Manage wallet button title */ -"AccountHeader.manageButtonName" = "MANAGE"; - -/* Error alert title */ -"Alert.error" = "Error"; - -/* No internet alert message */ -"Alert.noInternet" = "No internet connection found. Check your connection and try again."; - -/* Warning alert title */ -"Alert.warning" = "Warning"; - -/* 'the addresses were copied'' Alert title */ -"Alerts.copiedAddressesHeader" = "Addresses Copied"; - -/* Addresses Copied Alert sub header */ -"Alerts.copiedAddressesSubheader" = "All wallet addresses successfully copied."; - -/* Alert Header Label (the paper key was set) */ -"Alerts.paperKeySet" = "Paper Key Set"; - -/* Alert Subheader label (playfully positive) */ -"Alerts.paperKeySetSubheader" = "Awesome!"; - -/* Alert Header label (the PIN was set) */ -"Alerts.pinSet" = "PIN Set"; - -/* Send failure alert header label (the send failed to happen) */ -"Alerts.sendFailure" = "Send failed"; - -/* Send success alert header label (confirmation that the send happened) */ -"Alerts.sendSuccess" = "Send Confirmation"; - -/* Send success alert subheader label (e.g. the money was sent) */ -"Alerts.sendSuccessSubheader" = "Money Sent!"; - -/* JSON Serialization error message */ -"ApiClient.jsonError" = "JSON Serialization Error"; - -/* Wallet not ready error message */ -"ApiClient.notReady" = "Wallet not ready"; - -/* API Token error message */ -"ApiClient.tokenError" = "Unable to retrieve API token"; - -/* Send BCH view body. */ -"BCH.body" = "Enter a destination BCH address below. All BCH in your wallet at the time of the fork (%1$@) will be sent."; - -/* Confirm sending <$5.00> to

? */ -"BCH.confirmationMessage" = "Confirm sending %1$@ to %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Confirmation"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Your account does not contain any BCH, or you received BCH after the fork."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transaction ID copied"; - -/* No address error message */ -"BCH.noAddressError" = "Please enter an address"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Payment Protocol Requests are not supported for BCH transactions"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH was successfully sent."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Withdraw BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH Transaction ID"; - -/* Approve button label */ -"BitID.approve" = "Approve"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ is requesting authentication using your Litecoin wallet"; - -/* Deny button label */ -"BitID.deny" = "Deny"; - -/* BitID error alert title */ -"BitID.error" = "Authentication Error"; - -/* BitID error alert messaage */ -"BitID.errorMessage" = "Please check with the service. You may need to try again."; - -/* BitID success alert title */ -"BitID.success" = "Successfully Authenticated"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID Authentication Request"; - -/* buy button */ -"Button.buy" = "buy"; - -/* Cancel button label */ -"Button.cancel" = "Cancel"; - -/* Ignore button label */ -"Button.ignore" = "Ignore"; - -/* menu button */ -"Button.menu" = "menu"; - -/* No button */ -"Button.no" = "No"; - -/* OK button label */ -"Button.ok" = "OK"; - -/* receive button */ -"Button.receive" = "receive"; - -/* send button */ -"Button.send" = "send"; - -/* Settings button label */ -"Button.settings" = "Settings"; - -/* Settings button label */ -"Button.submit" = "Submit"; - -/* Yes button */ -"Button.yes" = "Yes"; - -/* Buy Bar Item Title */ -"BuyCenter.barItemTitle" = "BUY"; - -/* Bitrefill buy financial details */ -"BuyCenter.bitrefillFinancialDetails" = "• Buy gift cards\n• Refill prepaid phones\n• Steam, Amazon, Hotels.com\n• Works in 170 countries"; - -/* Bitrefill Title */ -"BuyCenter.BitrefillTitle" = "Bitrefill"; - -/* Changelly buy financial details */ -"BuyCenter.changellyFinancialDetails" = "• Change Litecoin for other cryptos\n• No ID Required\n• Buy via credit card\n• Global coverage"; - -/* Changelly Title */ -"BuyCenter.changellyTitle" = "Changelly"; - -/* Buy Modal Title */ -"BuyCenter.ModalTitle" = "Buy Łitecoin"; - -/* Simplex buy financial details */ -"BuyCenter.simplexFinancialDetails" = "• Get Litecoin in 5 mins!\n• Buy Litecoin via credit card\n• Passport or State ID"; - -/* Simplex Title */ -"BuyCenter.simplexTitle" = "Simplex"; - -/* Buy Center Title */ -"BuyCenter.title" = "Buy Litecoin"; - -/* Camera plugin instruction */ -"CameraPlugin.centerInstruction" = "Center your ID in the box"; - -/* $53.09/L + 1.07% */ -"Confirmation.amountDetailLabel" = "Exchange details:"; - -/* Amount to Send: ($1.00) */ -"Confirmation.amountLabel" = "Amount to Send:"; - -/* Amount to Donate: ($1.00) */ -"Confirmation.donateLabel" = "Amount to Donate:"; - -/* Network Fee: ($1.00) */ -"Confirmation.feeLabel" = "Network Fee:"; - -/* eg. Processing with Donation time: This transaction will take 10-30 minutes to process. */ -"Confirmation.processingAndDonationTime" = "Processing time: These transactions will take %1$@ minutes to process."; - -/* eg. Processing time: This transaction will take 10-30 minutes to process. */ -"Confirmation.processingTime" = "Processing time: This transaction will take %1$@ minutes to process."; - -/* Send: (amount) */ -"Confirmation.send" = "Send"; - -/* Short Network Fee: ($1.00) */ -"Confirmation.shortFeeLabel" = "FEE:"; - -/* Address label */ -"Confirmation.staticAddressLabel" = "ADDRESS:"; - -/* Confirmation Screen title */ -"Confirmation.title" = "Confirmation"; - -/* To: (address) */ -"Confirmation.to" = "To"; - -/* Total Cost: ($5.00) */ -"Confirmation.totalLabel" = "Total Cost:"; - -/* Confirm paper phrase error message */ -"ConfirmPaperPhrase.error" = "The words entered do not match your paper key. Please try again."; - -/* Confirm paper phrase view label. */ -"ConfirmPaperPhrase.label" = "To make sure everything was written down correctly, please enter the following words from your paper key."; - -/* Word label eg. Word #1, Word #2 */ -"ConfirmPaperPhrase.word" = "Word #%1$@"; - -/* as of a time or date */ -"Conjunction.asOf" = "as of"; - -/* No comment provided by engineer. */ -"Copy" = "Copy"; - -/* Litecoin denomination picker label */ -"DefaultCurrency.bitcoinLabel" = "Litecoin Display Unit"; - -/* Label to pick fiat */ -"DefaultCurrency.chooseFiatLabel" = "Choose:"; - -/* Exchange rate label */ -"DefaultCurrency.rateLabel" = "Exchange Rate"; - -/* Email unavailable alert title */ -"ErrorMessages.emailUnavailableMessage" = "This device isn't configured to send email with the iOS mail app."; - -/* Email unavailable alert title */ -"ErrorMessages.emailUnavailableTitle" = "Email Unavailable"; - -/* Messaging unavailable alert title */ -"ErrorMessages.messagingUnavailableMessage" = "This device isn't configured to send messages."; - -/* Messaging unavailable alert title */ -"ErrorMessages.messagingUnavailableTitle" = "Messaging Unavailable"; - -/* You can customize your Face ID Spending Limit from the [TouchIdSettings.linkText gets added here as a button] */ -"FaceIDSettings.customizeText" = "You can customize your Face ID spending limit from the %1$@."; - -/* Face ID screen label */ -"FaceIDSettings.label" = "Use your face to unlock your Litewallet and send money up to a set limit."; - -/* Link Text (see TouchIdSettings.customizeText) */ -"FaceIDSettings.linkText" = "Face ID Spending Limit Screen"; - -/* Face id switch label. */ -"FaceIDSettings.switchLabel" = "Enable Face ID for Litewallet"; - -/* Face ID settings view title */ -"FaceIDSettings.title" = "Face ID"; - -/* Face ID unavailable alert message */ -"FaceIDSettings.unavailableAlertMessage" = "You have not set up Face ID on this device. Go to Settings->Face ID & Passcode to set it up now."; - -/* Face ID unavailable alert title */ -"FaceIDSettings.unavailableAlertTitle" = "Face ID Not Set Up"; - -/* Face Id spending limit screen title */ -"FaceIDSpendingLimit.title" = "Face ID Spending Limit"; - -/* Economy fee */ -"FeeSelector.economy" = "Economy"; - -/* Fee Selector economly fee description */ -"FeeSelector.economyLabel" = "Estimated Delivery: 60+ minutes"; - -/* Warning message for economy fee */ -"FeeSelector.economyWarning" = "This option is not recommended for time-sensitive transactions."; - -/* Regular fee */ -"FeeSelector.regular" = "Regular"; - -/* Fee Selector regular fee description */ -"FeeSelector.regularLabel" = "Estimated Delivery: 10-30 minutes"; - -/* Fee Selector title */ -"FeeSelector.title" = "Processing Speed"; - -/* Or */ -"Fragment.or" = "or"; - -/* History Bar Item Title */ -"History.barItemTitle" = "HISTORY"; - -/* Checking private key balance progress view text */ -"Import.checking" = "Checking private key balance..."; - -/* Sweep private key confirmation message */ -"Import.confirm" = "Send %1$@ from this private key into your wallet? The Litecoin network will receive a fee of %2$@."; - -/* Duplicate key error message */ -"Import.Error.duplicate" = "This private key is already in your wallet."; - -/* empty private key error message */ -"Import.Error.empty" = "This private key is empty."; - -/* High fees error message */ -"Import.Error.highFees" = "Transaction fees would cost more than the funds available on this private key."; - -/* Not a valid private key error message */ -"Import.Error.notValid" = "Not a valid private key"; - -/* Import signing error message */ -"Import.Error.signing" = "Error signing transaction"; - -/* Import button label */ -"Import.importButton" = "Import"; - -/* Importing wallet progress view label */ -"Import.importing" = "Importing Wallet"; - -/* Caption for graphics */ -"Import.leftCaption" = "Wallet to be imported"; - -/* Import wallet intro screen message */ -"Import.message" = "Importing a wallet transfers all the money from your other wallet into your Litewallet wallet using a single transaction."; - -/* Enter password alert view title */ -"Import.password" = "This private key is password protected."; - -/* password textfield placeholder */ -"Import.passwordPlaceholder" = "password"; - -/* Caption for graphics */ -"Import.rightCaption" = "Your Litewallet Wallet"; - -/* Scan Private key button label */ -"Import.scan" = "Scan Private Key"; - -/* Import wallet success alert title */ -"Import.success" = "Success"; - -/* Successfully imported wallet message body */ -"Import.SuccessBody" = "Successfully imported wallet."; - -/* Import Wallet screen title */ -"Import.title" = "Import Wallet"; - -/* Unlocking Private key activity view message. */ -"Import.unlockingActivity" = "Unlocking Key"; - -/* Import wallet intro warning message */ -"Import.warning" = "Importing a wallet does not include transaction history or other details."; - -/* Wrong password alert message */ -"Import.wrongPassword" = "Wrong password, please try again."; - -/* Close app button */ -"JailbreakWarnings.close" = "Close"; - -/* Ignore jailbreak warning button */ -"JailbreakWarnings.ignore" = "Ignore"; - -/* Jailbreak warning message */ -"JailbreakWarnings.messageWithBalance" = "DEVICE SECURITY COMPROMISED\n Any 'jailbreak' app can access Litewallet's keychain data and steal your Litecoin! Wipe this wallet immediately and restore on a secure device."; - -/* Jailbreak warning message */ -"JailbreakWarnings.messageWithoutBalance" = "DEVICE SECURITY COMPROMISED\n Any 'jailbreak' app can access Litewallet's keychain data and steal your Litecoin. Please only use Litewallet on a non-jailbroken device."; - -/* Jailbreak warning title */ -"JailbreakWarnings.title" = "WARNING"; - -/* Wipe wallet button */ -"JailbreakWarnings.wipe" = "Wipe"; - -/* Location services disabled error */ -"LocationPlugin.disabled" = "Location services are disabled."; - -/* No permissions for location services */ -"LocationPlugin.notAuthorized" = "Litewallet does not have permission to access location services."; - -/* No comment provided by engineer. */ -"Malformed URI" = "Malformed URI"; - -/* Wallet creation date prefix */ -"ManageWallet.creationDatePrefix" = "You created your wallet on %1$@"; - -/* Manage wallet description text */ -"ManageWallet.description" = "Your wallet name only appears in your account transaction history and cannot be seen by anyone else."; - -/* Change Wallet name textfield label */ -"ManageWallet.textFeildLabel" = "Wallet Name"; - -/* Manage wallet modal title */ -"ManageWallet.title" = "Manage Wallet"; - -/* Buy Litecoin title */ -"MenuButton.buy" = "Buy Litecoin"; - -/* Menu button title */ -"MenuButton.lock" = "Lock Wallet"; - -/* Menu button title */ -"MenuButton.security" = "Security Center"; - -/* Menu button title */ -"MenuButton.settings" = "Settings"; - -/* Menu button title */ -"MenuButton.support" = "Support"; - -/* button label */ -"MenuViewController.createButton" = "Create New Wallet"; - -/* Menu modal title */ -"MenuViewController.modalTitle" = "Menu"; - -/* button label */ -"MenuViewController.recoverButton" = "Recover Wallet"; - -/* No comment provided by engineer. */ -"No wallet" = "No wallet"; - -/* Switch to automatic mode button label */ -"NodeSelector.automaticButton" = "Switch to Automatic Mode"; - -/* Node is connected label */ -"NodeSelector.connected" = "Connected"; - -/* Enter node ip address view body */ -"NodeSelector.enterBody" = "Enter Node IP address and port (optional)"; - -/* Enter Node ip address view title */ -"NodeSelector.enterTitle" = "Enter Node"; - -/* Switch to manual mode button label */ -"NodeSelector.manualButton" = "Switch to Manual Mode"; - -/* Node address label */ -"NodeSelector.nodeLabel" = "Current Primary Node"; - -/* Node is not connected label */ -"NodeSelector.notConnected" = "Not Connected"; - -/* Node status label */ -"NodeSelector.statusLabel" = "Node Connection Status"; - -/* Node Selector view title */ -"NodeSelector.title" = "Litecoin Nodes"; - -/* Bad Payment request alert title */ -"PaymentProtocol.Errors.badPaymentRequest" = "Bad Payment Request"; - -/* Error opening payment protocol file message */ -"PaymentProtocol.Errors.corruptedDocument" = "Unsupported or corrupted document"; - -/* Missing certificate payment protocol error message */ -"PaymentProtocol.Errors.missingCertificate" = "missing certificate"; - -/* Request expired payment protocol error message */ -"PaymentProtocol.Errors.requestExpired" = "request expired"; - -/* Payment too small alert title */ -"PaymentProtocol.Errors.smallOutputError" = "Couldn't make payment"; - -/* Amount too small error message */ -"PaymentProtocol.Errors.smallPayment" = "Litecoin payments can't be less than %1$@."; - -/* Output too small error message. */ -"PaymentProtocol.Errors.smallTransaction" = "Litecoin transaction outputs can't be less than $@."; - -/* Unsupported signature type payment protocol error message */ -"PaymentProtocol.Errors.unsupportedSignatureType" = "unsupported signature type"; - -/* Untrusted certificate payment protocol error message */ -"PaymentProtocol.Errors.untrustedCertificate" = "untrusted certificate"; - -/* Dismiss button. */ -"Prompts.dismiss" = "DISMISS"; - -/* Enable face ID prompt body */ -"Prompts.FaceId.body" = "Tap here to enable Face ID"; - -/* Enable face ID prompt title */ -"Prompts.FaceId.title" = "Enable Face ID"; - -/* No passcode set warning body */ -"Prompts.NoPasscode.body" = "A device passcode is needed to safeguard your wallet."; - -/* No Passcode set warning title */ -"Prompts.NoPasscode.title" = "Turn device passcode on"; - -/* Affirm button title. */ -"Prompts.PaperKey.affirm" = "Continue"; - -/* Warning about paper key. */ -"Prompts.PaperKey.body" = "Your Paper Key must be kept in a safe place. It is the only way modify or restore your Litewallet or transfer your Litecoin. Please write it down."; - -/* Cancel button. */ -"Prompts.PaperKey.cancel" = "Cancel"; - -/* Enable button. */ -"Prompts.PaperKey.enable" = "Enable"; - -/* An action is required (You must do this action). */ -"Prompts.PaperKey.title" = "Action Required"; - -/* Transaction rejected prompt body */ -"Prompts.RecommendRescan.body" = "Your wallet may be out of sync. This can often be fixed by rescanning the blockchain."; - -/* Transaction rejected prompt title */ -"Prompts.RecommendRescan.title" = "Transaction Rejected"; - -/* Upgrade PIN prompt body. */ -"Prompts.SetPin.body" = "Litewallet requires a 6-digit PIN. Please set and store your PIN in a safe place."; - -/* Upgrade PIN prompt title. */ -"Prompts.SetPin.title" = "Set PIN"; - -/* Share data prompt body */ -"Prompts.ShareData.body" = "Help improve Litewallet by sharing your anonymous data with us"; - -/* Share data prompt title */ -"Prompts.ShareData.title" = "Share Anonymous Data"; - -/* Enable touch ID prompt body */ -"Prompts.TouchId.body" = "Tap here to enable Touch ID"; - -/* Enable touch ID prompt title */ -"Prompts.TouchId.title" = "Enable Touch ID"; - -/* Push notifications settings view body */ -"PushNotifications.body" = "Turn on notifications to receive special messages from Litewallet in the future."; - -/* Push notifications toggle switch label */ -"PushNotifications.label" = "Push Notifications"; - -/* Push notifications are off label */ -"PushNotifications.off" = "Off"; - -/* Push notifications are on label */ -"PushNotifications.on" = "On"; - -/* Push notifications settings view title label */ -"PushNotifications.title" = "Notifications"; - -/* Receive Bar Item Title */ -"Receive.barItemTitle" = "RECEIVE"; - -/* Address copied message. */ -"Receive.copied" = "Copied to clipboard."; - -/* Share via email button label */ -"Receive.emailButton" = "Email"; - -/* Request button label */ -"Receive.request" = "Request an Amount"; - -/* Share button label */ -"Receive.share" = "Share"; - -/* Share via text message (SMS) */ -"Receive.textButton" = "Text Message"; - -/* Receive modal title */ -"Receive.title" = "Receive"; - -/* Done button text */ -"RecoverWallet.done" = "Done"; - -/* Recover wallet header */ -"RecoverWallet.header" = "Recover Wallet"; - -/* Reset PIN with paper key: header */ -"RecoverWallet.header_reset_pin" = "Reset PIN"; - -/* Enter paper key instruction */ -"RecoverWallet.instruction" = "Enter Paper Key"; - -/* Recover wallet intro */ -"RecoverWallet.intro" = "Recover your Litewallet with your paper key."; - -/* Invalid paper key message */ -"RecoverWallet.invalid" = "The paper key you entered is invalid. Please double-check each word and try again."; - -/* Previous button accessibility label */ -"RecoverWallet.leftArrow" = "Left Arrow"; - -/* Next button label */ -"RecoverWallet.next" = "Next"; - -/* Reset PIN with paper key: more information button. */ -"RecoverWallet.reset_pin_more_info" = "Tap here for more information."; - -/* Next button accessibility label */ -"RecoverWallet.rightArrow" = "Right Arrow"; - -/* Recover wallet sub-header */ -"RecoverWallet.subheader" = "Enter the paper key for the wallet you want to recover."; - -/* Reset PIN with paper key: sub-header */ -"RecoverWallet.subheader_reset_pin" = "To reset your PIN, enter the words from your paper key into the boxes below."; - -/* No amount entered error message. */ -"RequestAnAmount.noAmount" = "Please enter an amount first."; - -/* Request a specific amount of Litecoin */ -"RequestAnAmount.title" = "Request an Amount"; - -/* Alert action button label */ -"ReScan.alertAction" = "Sync"; - -/* Alert message body */ -"ReScan.alertMessage" = "You will not be able to send money while syncing."; - -/* Alert message title */ -"ReScan.alertTitle" = "Sync with Blockchain?"; - -/* extimated time */ -"ReScan.body1" = "20-45 minutes"; - -/* Syncing explanation */ -"ReScan.body2" = "If a transaction shows as completed on the Litecoin network but not in your Litewallet."; - -/* Syncing explanation */ -"ReScan.body3" = "You repeatedly get an error saying your transaction was rejected."; - -/* Start Sync button label */ -"ReScan.buttonTitle" = "Start Sync"; - -/* Sync blockchain view footer */ -"ReScan.footer" = "You will not be able to send money while syncing with the blockchain."; - -/* Sync Blockchain view header */ -"ReScan.header" = "Sync Blockchain"; - -/* Subheader label */ -"ReScan.subheader1" = "Estimated time"; - -/* Subheader label */ -"ReScan.subheader2" = "When to Sync?"; - -/* Reset walet button title */ -"resetButton" = "Yes, reset wallet"; - -/* Warning Empty Wipe title */ -"resetTitle" = "Empty Wallet Reset"; - -/* Scan Litecoin address camera flash toggle */ -"Scanner.flashButtonLabel" = "Camera Flash"; - -/* Complete filter label */ -"Search.complete" = "complete"; - -/* Pending filter label */ -"Search.pending" = "pending"; - -/* Received filter label */ -"Search.received" = "received"; - -/* Sent filter label */ -"Search.sent" = "sent"; - -/* Face ID button title */ -"SecurityCenter.faceIdTitle" = "Face ID"; - -/* Security Center Info */ -"SecurityCenter.info" = "Enable all security features for maximum protection."; - -/* Paper Key button description */ -"SecurityCenter.paperKeyDescription" = "The only way to access your Litecoin if you lose or upgrade your phone."; - -/* Paper Key button title */ -"SecurityCenter.paperKeyTitle" = "Paper Key"; - -/* PIN button description */ -"SecurityCenter.pinDescription" = "Protects your Litewallet from unauthorized users."; - -/* PIN button title */ -"SecurityCenter.pinTitle" = "6-Digit PIN"; - -/* Security Center Title */ -"SecurityCenter.title" = "Security Center"; - -/* Touch ID/FaceID button description */ -"SecurityCenter.touchIdDescription" = "Conveniently unlock your Litewallet and send money up to a set limit."; - -/* Touch ID button title */ -"SecurityCenter.touchIdTitle" = "Touch ID"; - -/* Send money amount label */ -"Send.amountLabel" = "Amount"; - -/* Balance: $4.00 */ -"Send.balance" = "Balance: %1$@"; - -/* Send Bar Item Title */ -"Send.barItemTitle" = "SEND"; - -/* Camera not allowed message */ -"Send.cameraunavailableMessage" = "Go to Settings to allow camera access."; - -/* Camera not allowed alert title */ -"Send.cameraUnavailableTitle" = "Litewallet is not allowed to access the camera"; - -/* Warning when sending to self. */ -"Send.containsAddress" = "The destination is your own address. You cannot send to yourself."; - -/* Could not create transaction alert title */ -"Send.creatTransactionError" = "Could not create transaction."; - -/* Description for sending money label */ -"Send.descriptionLabel" = "Memo"; - -/* Empty pasteboard error message */ -"Send.emptyPasteboard" = "Pasteboard is empty"; - -/* Network Fee: $0.01 */ -"Send.fee" = "Network Fee: %1$@"; - -/* Payee identity not certified alert title. */ -"Send.identityNotCertified" = "Payee identity isn't certified."; - -/* Insufficient funds error */ -"Send.insufficientFunds" = "Insufficient Funds"; - -/* Invalid address alert message */ -"Send.invalidAddressMessage" = "The destination address is not a valid Litecoin address."; - -/* Invalid address on pasteboard message */ -"Send.invalidAddressOnPasteboard" = "Pasteboard does not contain a valid Litecoin address."; - -/* Invalid address alert title */ -"Send.invalidAddressTitle" = "Invalid Address"; - -/* Is rescanning error message */ -"Send.isRescanning" = "Sending is disabled during a full rescan."; - -/* Loading request activity view message */ -"Send.loadingRequest" = "Loading Request"; - -/* Empty address alert message */ -"Send.noAddress" = "Please enter the recipient's address."; - -/* Emtpy amount alert message */ -"Send.noAmount" = "Please enter an amount to send."; - -/* Paste button label */ -"Send.pasteLabel" = "Paste"; - -/* Could not publish transaction alert title */ -"Send.publishTransactionError" = "Could not publish transaction."; - -/* Could not load remote request error message */ -"Send.remoteRequestError" = "Could not load payment request"; - -/* Scan button label */ -"Send.scanLabel" = "Scan"; - -/* Send button label */ -"Send.sendLabel" = "Send"; - -/* Send modal title */ -"Send.title" = "Send"; - -/* Send money to label */ -"Send.toLabel" = "To"; - -/* Adress already used alert message - first part */ -"Send.UsedAddress.firstLine" = "Litecoin addresses are intended for single use only."; - -/* Adress already used alert message - second part */ -"Send.UsedAddress.secondLIne" = "Re-use reduces privacy for both you and the recipient and can result in loss if the recipient doesn't directly control the address."; - -/* Adress already used alert title */ -"Send.UsedAddress.title" = "Address Already Used"; - -/* About label */ -"Settings.about" = "About"; - -/* Advanced Settings title */ -"Settings.advancedTitle" = "Advanced Settings"; - -/* Blockchain settings section header */ -"Settings.blockchain" = "Blockchain"; - -/* Default currency label */ -"Settings.currency" = "Display Currency"; - -/* Join Early access label */ -"Settings.earlyAccess" = "Join Early Access"; - -/* Are you enjoying Litewallet alert message body */ -"Settings.enjoying" = "Are you enjoying Litewallet?"; - -/* Face ID spending limit label */ -"Settings.faceIdLimit" = "Face ID Spending Limit"; - -/* Import wallet label */ -"Settings.importTitle" = "Import Wallet"; - -/* Languages label */ -"Settings.languages" = "Languages"; - -/* Litewallet environment */ -"Settings.litewallet.environment" = "Environment:"; - -/* Litewallet version */ -"Settings.litewallet.version" = "Litewallet version:"; - -/* Manage settings section header */ -"Settings.manage" = "Manage"; - -/* Notifications label */ -"Settings.notifications" = "Notifications"; - -/* Leave review button label */ -"Settings.review" = "Leave us a Review"; - -/* Share anonymous data label */ -"Settings.shareData" = "Share Anonymous Data"; - -/* Litewallet Social links */ -"Settings.socialLinks" = "Social"; - -/* Support settings section header */ -"Settings.support" = "Support"; - -/* Sync blockchain label */ -"Settings.sync" = "Sync Blockchain"; - -/* Settings title */ -"Settings.title" = "Settings"; - -/* Touch ID spending limit label */ -"Settings.touchIdLimit" = "Touch ID Spending Limit"; - -/* Wallet Settings section header */ -"Settings.wallet" = "Wallet"; - -/* Start or recover another wallet menu label. */ -"Settings.wipe" = "Start/Recover Another Wallet"; - -/* Share data view body */ -"ShareData.body" = "Help improve Litewallet by sharing your anonymous data with us. This does not include any financial information. We respect your financial privacy."; - -/* Share data header */ -"ShareData.header" = "Share Data?"; - -/* Share data switch label. */ -"ShareData.toggleLabel" = "Share Anonymous Data?"; - -/* Current spending limit: */ -"SpendingLimit.title" = "Current Spending Limit: "; - -/* button label */ -"StartPaperPhrase.againButtonTitle" = "Write Down Paper Key Again"; - -/* Paper key explanation text. */ -"StartPaperPhrase.body" = "Your paper key is the only way to restore your Litewallet if your phone is lost, stolen, broken, or upgraded.\n\nWe will show you a list of words to write down on a piece of paper and keep safe."; - -/* button label */ -"StartPaperPhrase.buttonTitle" = "Write Down Paper Key"; - -/* Argument is date */ -"StartPaperPhrase.date" = "You last wrote down your paper key on %1$@"; - -/* Start view message */ -"StartViewController.message" = "The most secure and safest way to use Litecoin."; - -/* Support the Litecoin Foundation */ -"SupportTheFoundation.title" = "Support the Litecoin Foundation"; - -/* Syncing view connection state header text */ -"SyncingHeader.connecting" = "Connecting..."; - -/* Rescanning header success state header text */ -"SyncingHeader.rescan" = "Rescanning..."; - -/* Syncing header success state header text */ -"SyncingHeader.success" = "Success!"; - -/* Syncing view syncing state header text */ -"SyncingHeader.syncing" = "Syncing..."; - -/* Syncing view connectiong state header text */ -"SyncingView.connecting" = "Connecting"; - -/* Syncing view syncing state header text */ -"SyncingView.syncing" = "Syncing"; - -/* 6 d (6 days) */ -"TimeSince.days" = "%1$@ d"; - -/* 6 h (6 hours) */ -"TimeSince.hours" = "%1$@ h"; - -/* 6 m (6 minutes) */ -"TimeSince.minutes" = "%1$@ m"; - -/* 6 s (6 seconds) */ -"TimeSince.seconds" = "%1$@ s"; - -/* You can customize your Touch ID Spending Limit from the [TouchIdSettings.linkText gets added here as a button] */ -"TouchIdSettings.customizeText" = "You can customize your Touch ID spending limit from the %1$@."; - -/* Touch Id screen label */ -"TouchIdSettings.label" = "Use your fingerprint to unlock your Litewallet and send money up to a set limit."; - -/* ł100,000 ($100) */ -"TouchIdSettings.limitValue" = "%1$@ (%2$@)"; - -/* Link Text (see TouchIdSettings.customizeText) */ -"TouchIdSettings.linkText" = "Touch ID Spending Limit Screen"; - -/* Spending Limit: b100,000 ($100) */ -"TouchIdSettings.spendingLimit" = "Spending limit: %1$@ (%2$@)"; - -/* Touch id switch label. */ -"TouchIdSettings.switchLabel" = "Enable Touch ID for Litewallet"; - -/* Touch ID settings view title */ -"TouchIdSettings.title" = "Touch ID"; - -/* Touch ID unavailable alert message */ -"TouchIdSettings.unavailableAlertMessage" = "You have not set up Touch ID on this device. Go to Settings->Touch ID & Passcode to set it up now."; - -/* Touch ID unavailable alert title */ -"TouchIdSettings.unavailableAlertTitle" = "Touch ID Not Set Up"; - -/* Always require passcode option */ -"TouchIdSpendingLimit" = "Always require passcode"; - -/* Touch ID spending limit screen body */ -"TouchIdSpendingLimit.body" = "You will be asked to enter your 6-digit PIN to send any transaction over your spending limit, and every 48 hours since the last time you entered your 6-digit PIN."; - -/* Touch Id spending limit screen title */ -"TouchIdSpendingLimit.title" = "Touch ID Spending Limit"; - -/* Static amount Label */ -"Transaction.amountDetailLabel" = "Amount Detail:"; - -/* Availability status text */ -"Transaction.available" = "Available to Spend"; - -/* Static blockHeight Label */ -"Transaction.blockHeightLabel" = "Block:"; - -/* Static comment Label */ -"Transaction.commentLabel" = "Memo:"; - -/* Transaction complete label */ -"Transaction.complete" = "Complete"; - -/* Static end amount Label */ -"Transaction.endAmountDetailLabel" = "Transaction end amount detail"; - -/* eg. Ending balance: $50.00 */ -"Transaction.ending" = "Ending balance: %1$@"; - -/* Exchange rate on date header */ -"Transaction.exchangeOnDayReceived" = "Exchange rate when received:"; - -/* Exchange rate on date header */ -"Transaction.exchangeOnDaySent" = "Exchange rate when sent:"; - -/* (b600 fee) */ -"Transaction.fee" = "(%1$@ fee)"; - -/* Invalid transaction */ -"Transaction.invalid" = "INVALID"; - -/* Timestamp label for event that just happened */ -"Transaction.justNow" = "just now"; - -/* Receive status text: 'In progress: 20%' */ -"Transaction.receivedStatus" = "In progress: %1$@"; - -/* Send status text: 'In progress: 20%' */ -"Transaction.sendingStatus" = "In progress: %1$@"; - -/* eg. Starting balance: $50.00 */ -"Transaction.starting" = "Starting balance: %1$@"; - -/* Static starting amount Label */ -"Transaction.startingAmountDetailLabel" = "Transaction starting amount detail"; - -/* Static TX iD Label */ -"Transaction.txIDLabel" = "Tx ID:"; - -/* Waiting to be confirmed string */ -"Transaction.waiting" = "Waiting to be confirmed. Some merchants require confirmation to complete a transaction. Estimated time: 1-2 hours."; - -/* e.g. I received money from an account. */ -"TransactionDetails.account" = "account"; - -/* Amount section header */ -"TransactionDetails.amountHeader" = "Amount"; - -/* Block height label */ -"TransactionDetails.blockHeightLabel" = "Confirmed in Block"; - -/* Memo section header */ -"TransactionDetails.commentsHeader" = "Memo"; - -/* Empty transaction list message. */ -"TransactionDetails.emptyMessage" = "Your transactions will appear here."; - -/* [received] at
(received title 2/2) */ -"TransactionDetails.from" = "at %1$@"; - -/* Less button title */ -"TransactionDetails.less" = "Less..."; - -/* Moved $5.00 */ -"TransactionDetails.moved" = "Moved %1$@"; - -/* Moved $5.00 */ -"TransactionDetails.movedAmountDescription" = "Moved %1@"; - -/* eg. Confirmed in Block: Not Confirmed */ -"TransactionDetails.notConfirmedBlockHeightLabel" = "Not Confirmed"; - -/* Prefix for price */ -"TransactionDetails.priceTimeStampPrefix" = "as of"; - -/* Received $5.00 (received title 1/2) */ -"TransactionDetails.received" = "Received %1$@"; - -/* Received $5.00 */ -"TransactionDetails.receivedAmountDescription" = "Received %1@"; - -/* RECEIVE LTCTitle */ -"TransactionDetails.receivedModalTitle" = "RECEIVE ADDRESS"; - -/* Sent $5.00 (sent title 1/2) */ -"TransactionDetails.sent" = "Sent %1$@"; - -/* Sent $5.00 */ -"TransactionDetails.sentAmountDescription" = "Sent %1@"; - -/* Label for TXID */ -"TransactionDetails.staticTXLabel" = "TXID:"; - -/* Status section header */ -"TransactionDetails.statusHeader" = "Status"; - -/* Transaction Details Title */ -"TransactionDetails.title" = "Transaction Details"; - -/* [sent] to
(sent title 2/2) */ -"TransactionDetails.to" = "to %1$@"; - -/* Transaction ID header */ -"TransactionDetails.txHashHeader" = "Litecoin Transaction ID"; - -/* (this transaction was) Received at this address: */ -"TransactionDirection.address" = "Received at this Address"; - -/* (this transaction was) Sent to this address: */ -"TransactionDirection.to" = "Sent to this Address"; - -/* Disabled until date */ -"UnlockScreen.disabled" = "Disabled until: %1$@"; - -/* Unlock Screen sub-header */ -"UnlockScreen.enterPin" = "Enter PIN"; - -/* Unlock with FaceID accessibility label */ -"UnlockScreen.faceIdText" = "Unlock with FaceID"; - -/* My Address button title */ -"UnlockScreen.myAddress" = "My Address"; - -/* Reset PIN with Paper Key button label. */ -"UnlockScreen.resetPin" = "Reset PIN"; - -/* Scan button title */ -"UnlockScreen.scan" = "Scan"; - -/* TouchID/FaceID prompt text */ -"UnlockScreen.touchIdPrompt" = "Unlock your Litewallet."; - -/* Unlock with TouchID accessibility label */ -"UnlockScreen.touchIdText" = "Unlock with TouchID"; - -/* Wallet unlocked message */ -"UnlockScreen.unlocked" = "Wallet Unlocked"; - -/* Update PIN caption text */ -"UpdatePin.caption" = "Remember this PIN. If you forget it, you won't be able to access your Litecoin."; - -/* PIN creation info. */ -"UpdatePin.createInstruction" = "Your PIN will be used to unlock your Litewallet and send money."; - -/* Update PIN title */ -"UpdatePin.createTitle" = "Set PIN"; - -/* Update PIN title */ -"UpdatePin.createTitleConfirm" = "Re-Enter PIN"; - -/* Enter current PIN instruction */ -"UpdatePin.enterCurrent" = "Enter your current PIN."; - -/* Enter new PIN instruction */ -"UpdatePin.enterNew" = "Enter your new PIN."; - -/* Re-Enter new PIN instruction */ -"UpdatePin.reEnterNew" = "Re-Enter your new PIN."; - -/* Update PIN failure error message. */ -"UpdatePin.setPinError" = "Sorry, could not update PIN."; - -/* Update PIN failure alert view title */ -"UpdatePin.setPinErrorTitle" = "Update PIN Error"; - -/* Update PIN title */ -"UpdatePin.updateTitle" = "Update PIN"; - -/* Authorize to copy wallet addresses alert message */ -"URLHandling.addressaddressListAlertMessage" = "Copy wallet addresses to clipboard?"; - -/* Authorize to copy wallet address PIN view prompt. */ -"URLHandling.addressList" = "Authorize to copy wallet address to clipboard"; - -/* Authorize to copy wallet address alert title */ -"URLHandling.addressListAlertTitle" = "Copy Wallet Addresses"; - -/* Copy wallet addresses alert button label */ -"URLHandling.copy" = "Copy"; - -/* Verify PIN for transaction view body */ -"VerifyPin.authorize" = "Please enter your PIN to authorize this transaction."; - -/* Verify PIN view body */ -"VerifyPin.continueBody" = "Please enter your PIN to continue."; - -/* Verify PIN view title */ -"VerifyPin.title" = "PIN Required"; - -/* Authorize transaction with touch id message */ -"VerifyPin.touchIdMessage" = "Authorize this transaction"; - -/* 'No wallet' warning for watch app */ -"Watch.noWalletWarning" = "Open the Litewallet iPhone app to set up your wallet."; - -/* Dismiss button label */ -"Webview.dismiss" = "Dismiss"; - -/* Webview loading error message */ -"Webview.errorMessage" = "There was an error loading the content. Please try again."; - -/* Updating webview message */ -"Webview.updating" = "Updating..."; - -/* Welcome view body text */ -"Welcome.body" = "Litewallet now has a brand new look and some new features.\n\nAll coins are displayed in lites (ł). 1 Litecoin (Ł) = 1000 lites (ł)."; - -/* Welcome view title */ -"Welcome.title" = "Welcome to Litewallet!"; - -/* Wipe wallet alert message */ -"WipeWallet.alertMessage" = "Are you sure you want to delete this wallet?"; - -/* Wipe wallet alert title */ -"WipeWallet.alertTitle" = "Wipe Wallet?"; - -/* Warning if user lost phrase */ -"WipeWallet.emptyWallet" = "Forget your seed phrase or PIN?"; - -/* Failed wipe wallet alert message */ -"WipeWallet.failedMessage" = "Failed to wipe wallet."; - -/* Failed wipe wallet alert title */ -"WipeWallet.failedTitle" = "Failed"; - -/* Enter key to wipe wallet instruction. */ -"WipeWallet.instruction" = "To start a new wallet or restore an existing wallet, you must first erase the wallet that is currently installed. To continue, enter the current wallet's Paper Key."; - -/* Start wipe wallet view message */ -"WipeWallet.startMessage" = "Starting or recovering another wallet allows you to access and manage a different Litewallet wallet on this device."; - -/* Start wipe wallet view warning */ -"WipeWallet.startWarning" = "Your current wallet will be removed from this device. If you wish to restore it in the future, you will need to enter your Paper Key."; - -/* Wipe wallet navigation item title. */ -"WipeWallet.title" = "Start or Recover Another Wallet"; - -/* Warning Alert */ -"WipeWallet.warningAlert" = "DO NOT LOSE IT!"; - -/* Warning description */ -"WipeWallet.warningDescription" = "Your LiteWallet is empty. Resetting will delete the old private key and wipe the app data.\n\nAfter the reset, be prepared to record the new 12 words and keep them in a very secure place.\n\nNo LiteWallet developers can retrieve this seed for you."; - -/* Warning title */ -"WipeWallet.warningTitle" = "PLEASE READ!"; - -/* Wipe wallet button title */ -"WipeWallet.wipe" = "Wipe"; - -/* Wiping activity message */ -"WipeWallet.wiping" = "Wiping..."; - -/* Paper key instructions. */ -"WritePaperPhrase.instruction" = "Write down each word in order and store it in a safe place."; - -/* button label */ -"WritePaperPhrase.next" = "Next"; - -/* button label */ -"WritePaperPhrase.previous" = "Previous"; - -/* 1 of 3 */ -"WritePaperPhrase.step" = "%1$d of %2$d"; - -/* Corruption Error alert title */ -"Alert.corruptionError" = ""; - -/* Corruption Error alert title */ -"Alert.corruptionMessage" = ""; - -/* Resolved Success */ -"Alerts.resolvedSuccess" = ""; - -/* No comment provided by engineer. */ -"Alerts.resolvedSuccessSubheader" = ""; - -/* Luxury fee */ -"FeeSelector.luxury" = ""; - -/* Fee Selector economly fee description */ -"FeeSelector.luxuryLabel" = ""; - -/* Message for luxury fee */ -"FeeSelector.luxuryMessage" = ""; - -/* Menu button title */ -"MenuButton.customer.support" = ""; - -/* Enter LTC Address */ -"Send.enterLTCAddress" = ""; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = ""; - -/* Enter to match domain name to LTC Address */ -"Send.UnstoppableDomains.placeholder" = ""; - -/* Litewallet Partners */ -"Settings.litewallet.partners" = ""; - -/* Delete database title */ -"WipeWallet.alertDeleteTitle" = ""; - -/* Delete db */ -"WipeWallet.deleteDatabase" = ""; - -/* Delete database message */ -"WipeWallet.deleteMessageTitle" = ""; - -/* Delete and sync */ -"WipeWallet.deleteSync" = ""; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index 90f1a4b9e..18f54d2e7 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "modtag"; +/* resetFields */ +"Button.resetFields" = "Nulstil felter"; + /* send button */ "Button.send" = "send"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Ryd"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "KORT"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Kortbalance"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Login mislykkedes"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Glemt kodeord?"; + +/* Login */ +"LitecoinCard.login" = "Log på"; + +/* Logout */ +"LitecoinCard.logout" = "Log ud"; + +/* Register */ +"LitecoinCard.registerCard" = "Tilmeld"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Tilmeld dig Litecoin-kort"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Registrerer bruger ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Vejnavn"; + +/* city */ +"LitecoinCard.Registration.city" = "By"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "bekræft kodeord"; + +/* country */ +"LitecoinCard.Registration.country" = "Land"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "fornavn"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identifikation"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Kend din kunde ID-type"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID-type"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "efternavn"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Mobilnummer"; + +/* password */ +"LitecoinCard.Registration.password" = "adgangskode"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Stat / provins"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Email"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Må ikke være tom"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Ugyldig emailadresse"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Mobilnummeret skal have mindst 10 cifre"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Mobilnummer er påkrævet"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Adgangskoden skal indeholde mindst 6 tegn"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Adgangskoden skal bestå af mere end 6 tegn med mindst et tegn og et numerisk tegn"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Adgangskode er påkrævet"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "påkrævet område"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Postnummer"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Der var et problem med din registrering. Kontroller dine data, og prøv igen."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Du har tilmeldt dig! Kontroller og bekræft din e-mail. Så kom tilbage for at logge ind."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Nulstille kodeord"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Besøg https://litecoin.dashboard.getblockcard.com/password/forgot for at nulstille din adgangskode."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Placeringstjenester er deaktiveret."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "Til"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Kig op"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Indtast et .crypto- eller .zil-domæne"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d af %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Kig op"; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index dc8596cca..4b8c3d035 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "erhalten"; +/* resetFields */ +"Button.resetFields" = "Felder zurücksetzen"; + /* send button */ "Button.send" = "senden"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Löschen"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "Card"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Kartenguthaben"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Anmeldung fehlgeschlagen"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Passwort vergessen?"; + +/* Login */ +"LitecoinCard.login" = "Anmeldung"; + +/* Logout */ +"LitecoinCard.logout" = "Ausloggen"; + +/* Register */ +"LitecoinCard.registerCard" = "Registrieren"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Registrieren für Litecoin Card"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Benutzer registrieren ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Adresse"; + +/* city */ +"LitecoinCard.Registration.city" = "Stadt"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "Kennwort bestätigen"; + +/* country */ +"LitecoinCard.Registration.country" = "Land"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "Vorname"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identifizierung"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Kenne deinen Kunden ID-Typ"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID Typ"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "Familienname"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Handynummer"; + +/* password */ +"LitecoinCard.Registration.password" = "Passwort"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Staat / Provinz"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "E-Mail (Benutzername)"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Darf nicht leer sein"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Ungültige E-Mail-Adresse"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Die Handynummer muss mindestens 10 Ziffern haben"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Handynummer ist erforderlich"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Das Passwort muss mindestens 6 Zeichen lang sein"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Das Passwort muss aus mehr als 6 Zeichen bestehen, mit mindestens einem Zeichen und einem numerischen Zeichen"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Passwort wird benötigt"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "Pflichtfeld"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Postleitzahl"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Bei Ihrer Registrierung ist ein Problem aufgetreten. Bitte überprüfen Sie Ihre Daten und versuchen Sie es erneut."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Sie haben sich registriert! Bitte überprüfen und bestätigen Sie Ihre E-Mail. Dann komm zurück zum Login."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Passwort zurücksetzen"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Besuchen Sie https://litecoin.dashboard.getblockcard.com/password/forgot, um Ihr Passwort zurückzusetzen."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Standortdienste sind deaktiviert"; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "An"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Nachsehen"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Geben Sie eine .crypto- oder .zil-Domain ein"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d von %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Nachsehen"; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index 67c365bb4..e1ad9ca5d 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "receive"; +/* resetFields */ +"Button.resetFields" = "Reset fields"; + /* send button */ "Button.send" = "send"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Wipe"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "CARD"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Card balance"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Login failed"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Forgot password?"; + +/* Login */ +"LitecoinCard.login" = "Login"; + +/* Logout */ +"LitecoinCard.logout" = "Logout"; + +/* Register */ +"LitecoinCard.registerCard" = "Register"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Register for Litecoin Card"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Registering user..."; + +/* address */ +"LitecoinCard.Registration.address" = "Address"; + +/* city */ +"LitecoinCard.Registration.city" = "City"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "Confirm password"; + +/* country */ +"LitecoinCard.Registration.country" = "Country"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "First name"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identification"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "ID Number"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID Type"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "Last name"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Mobile number"; + +/* password */ +"LitecoinCard.Registration.password" = "Password"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "State / Province"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Email (Username)"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Must not be empty"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Invalid e-mail Address"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Mobile number must have at least 10 digits"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Mobile number is required"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Password must have at least 6 characters"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Password must be more than 6 characters, with at least one character and one numeric character"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Password is Required"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "Required field"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Zip / Postcode"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "There was a problem with your registration. \nPlease check your data and try again."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "You have registered!\nPlease check and confirm your email. Then come back to login."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Reset password"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Visit https://litecoin.dashboard.getblockcard.com/password/forgot\nto reset your password."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Location services are disabled."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "To"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Lookup"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Enter a .crypto or .zil domain"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d of %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Lookup"; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index cd8e1cc88..88c662353 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "recibir"; +/* resetFields */ +"Button.resetFields" = "Reestablecer campos"; + /* send button */ "Button.send" = "Enviar"; @@ -410,6 +413,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Borrar"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "TARJETA"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Balance de tarjeta"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "error de inicio de sesion"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "¿Se te olvidó tu contraseña?"; + +/* Login */ +"LitecoinCard.login" = "Iniciar sesión"; + +/* Logout */ +"LitecoinCard.logout" = "Cerrar sesión"; + +/* Register */ +"LitecoinCard.registerCard" = "Registrarse"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Registrarse para la tarjeta Litecoin"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Registrando usuario ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Dirección"; + +/* city */ +"LitecoinCard.Registration.city" = "Ciudad"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "Confirmar contraseña"; + +/* country */ +"LitecoinCard.Registration.country" = "País"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "primer nombre"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identificación"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Conozca a su cliente Tipo de identificación"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "tipo de identificación"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "apellido"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Número de teléfono móvil"; + +/* password */ +"LitecoinCard.Registration.password" = "contraseña"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Provincia del estado"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Email"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "No debe estar vacío"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Dirección de correo electrónico inválida"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "El número de móvil debe tener al menos 10 dígitos"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Se requiere un número de celular"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "La contraseña debe tener al menos 6 caracteres"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "La contraseña debe tener más de 6 caracteres, con al menos un carácter y un carácter numérico"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Se requiere contraseña"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "Campo requerido"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Código postal"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Hubo un problema con tu registro. Verifique sus datos y vuelva a intentarlo."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "¡Te has registrado! Por favor revise y confirme su correo electrónico. Luego vuelve a iniciar sesión."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Restablecer la contraseña"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Visita https://litecoin.dashboard.getblockcard.com/password/forgot para restablecer tu contraseña."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Los servicios de ubicación están desactivados."; @@ -809,6 +920,9 @@ /* Send money to label */ "Send.toLabel" = "A"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Buscar"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Ingrese un dominio .crypto o .zil"; @@ -1273,6 +1387,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d de %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Buscar"; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index ddf9af3bd..05d276d1e 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "recevoir"; +/* resetFields */ +"Button.resetFields" = "Réinitialisation des champs"; + /* send button */ "Button.send" = "envoyer"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Supprimer"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "CARTE"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Solde de la carte"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Échec de la connexion"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Mot de passe oublié?"; + +/* Login */ +"LitecoinCard.login" = "S'identifier"; + +/* Logout */ +"LitecoinCard.logout" = "Se déconnecter"; + +/* Register */ +"LitecoinCard.registerCard" = "S'inscrire"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Inscrivez-vous à la carte Litecoin"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Enregistrement de l'utilisateur ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Adresse de rue"; + +/* city */ +"LitecoinCard.Registration.city" = "Ville"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "Confirmez le mot de passe"; + +/* country */ +"LitecoinCard.Registration.country" = "Pays"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "Prénom"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identification"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Connaissez votre client Type d'identification"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "Type d'identification"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "nom de famille"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Numéro de portable"; + +/* password */ +"LitecoinCard.Registration.password" = "mot de passe"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "État / Province"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Email"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Ne doit pas être vide"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Adresse e-mail invalide"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Le numéro de mobile doit comporter au moins 10 chiffres"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Le numéro de portable est requis"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Le mot de passe doit comporter au moins 6 caractères"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Le mot de passe doit contenir plus de 6 caractères, avec au moins un caractère et un caractère numérique"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Mot de passe requis"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "champs requis"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Code postal"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Un problème est survenu lors de votre inscription. Veuillez vérifier vos données et réessayer."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Vous vous êtes inscrit! Veuillez vérifier et confirmer votre email. Puis revenez vous connecter."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Réinitialiser le mot de passe"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Visitez le site https://litecoin.dashboard.getblockcard.com/password/forgot pour réinitialiser votre mot de passe."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Les services de localisation sont désactivés."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "Pour"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Chercher"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Entrez un domaine .crypto ou .zil"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d de %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Chercher"; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 684d57217..1638e5fb0 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "menerima"; +/* resetFields */ +"Button.resetFields" = "Setel ulang bidang"; + /* send button */ "Button.send" = "kirim"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Hapus"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "KARTU"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Saldo kartu"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Gagal masuk"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Tidak ingat kata sandi?"; + +/* Login */ +"LitecoinCard.login" = "Gabung"; + +/* Logout */ +"LitecoinCard.logout" = "Keluar"; + +/* Register */ +"LitecoinCard.registerCard" = "Daftar"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Daftar untuk Kartu Litecoin"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Mendaftarkan pengguna ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Alamat jalan"; + +/* city */ +"LitecoinCard.Registration.city" = "Kota"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "konfirmasi sandi"; + +/* country */ +"LitecoinCard.Registration.country" = "Negara"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "nama depan"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identifikasi"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Kenali pelanggan Anda Jenis ID"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "Jenis ID"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "nama keluarga"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Nomor handphone"; + +/* password */ +"LitecoinCard.Registration.password" = "kata sandi"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Negara Bagian / Provinsi"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Surel"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Wajib diisi"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Alamat email salah"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Nomor ponsel setidaknya harus terdiri dari 10 digit"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Nomor ponsel diperlukan"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Kata sandi harus memiliki setidaknya 6 karakter"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Kata sandi harus lebih dari 6 karakter, dengan setidaknya satu karakter dan satu karakter numerik"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Kata sandi diperlukan"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "kolom yang harus diisi"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Kode Pos"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Ada masalah dengan pendaftaran Anda. Silakan periksa data Anda dan coba lagi."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Anda telah mendaftar! Silakan periksa dan konfirmasi email Anda. Kemudian kembali untuk masuk."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Setel ulang kata sandi"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Kunjungi https://litecoin.dashboard.getblockcard.com/password/forgot untuk mengatur ulang kata sandi Anda."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Layanan lokasi dinonaktifkan."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "Untuk"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Lihatlah"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Masukkan domain .crypto atau .zil"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d dari %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Lihatlah"; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index e08c253ea..fe500cb11 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "ricevi"; +/* resetFields */ +"Button.resetFields" = "Resettare i campi"; + /* send button */ "Button.send" = "invia"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Cancella"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "CARTA"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Saldo della carta"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Accesso fallito"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Ha dimenticato la password?"; + +/* Login */ +"LitecoinCard.login" = "Accesso"; + +/* Logout */ +"LitecoinCard.logout" = "Disconnettersi"; + +/* Register */ +"LitecoinCard.registerCard" = "Registrati"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Registrati per Litecoin Card"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Registrazione utente ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Indirizzo"; + +/* city */ +"LitecoinCard.Registration.city" = "Città"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "conferma password"; + +/* country */ +"LitecoinCard.Registration.country" = "Nazione"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "nome di battesimo"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identificazione"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Conosci il tuo cliente Tipo di ID"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "Tipo di ID"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "cognome"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Numero di cellulare"; + +/* password */ +"LitecoinCard.Registration.password" = "parola d'ordine"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Stato / provincia"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "E-mail"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Non deve essere vuoto"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Indirizzo email non valido"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Il numero di cellulare deve contenere almeno 10 cifre"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "È richiesto il numero di cellulare"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "La password deve contenere almeno 6 caratteri"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "La password deve contenere più di 6 caratteri, con almeno un carattere e un carattere numerico"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "E 'richiesta la password"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "campo obbligatorio"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Codice postale"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Si è verificato un problema con la tua registrazione. Controlla i tuoi dati e riprova."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Ti sei registrato! Controlla e conferma la tua email. Quindi torna indietro per accedere."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Resetta la password"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Visita https://litecoin.dashboard.getblockcard.com/password/forgot per reimpostare la tua password."; + /* Location services disabled error */ "LocationPlugin.disabled" = "I servizi di localizzazione sono disabilitati."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "A"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Consultare"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Inserisci un dominio .crypto o .zil"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d di %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Consultare"; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index b43c40282..2940abb76 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "受取"; +/* resetFields */ +"Button.resetFields" = "フィールドをリセット"; + /* send button */ "Button.send" = "送金する"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "完全削除"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "カード"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "カード残高"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "ログインに失敗しました"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "パスワードをお忘れですか?"; + +/* Login */ +"LitecoinCard.login" = "ログインする"; + +/* Logout */ +"LitecoinCard.logout" = "ログアウト"; + +/* Register */ +"LitecoinCard.registerCard" = "登録"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "ライトコインカードに登録"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "ユーザーを登録しています..."; + +/* address */ +"LitecoinCard.Registration.address" = "住所"; + +/* city */ +"LitecoinCard.Registration.city" = "市"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "パスワードを認証する"; + +/* country */ +"LitecoinCard.Registration.country" = "国"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "ファーストネーム"; + +/* identification */ +"LitecoinCard.Registration.identification" = "識別"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "顧客を知る IDタイプ"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "IDタイプ"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "苗字"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "携帯電話番号"; + +/* password */ +"LitecoinCard.Registration.password" = "パスワード"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "州/県"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Eメール"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "空であってはなりません"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "無効なメールアドレス"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "携帯電話番号は10桁以上である必要があります"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "携帯電話番号が必要です"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "パスワードは6文字以上である必要があります"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "パスワードは6文字を超え、少なくとも1文字と1つの数字を使用する必要があります"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "パスワードが必要"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "必須フィールド"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "郵便番号"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "登録に問題がありました。 データを確認して、もう一度お試しください。"; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "登録しました! メールを確認してください。 その後、ログインに戻ります。"; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "パスワードを再設定する"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "https://litecoin.dashboard.getblockcard.com/password/forgot にアクセスしてパスワードをリセットしてください。"; + /* Location services disabled error */ "LocationPlugin.disabled" = "位置情報サービスが無効化されています。"; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "宛先"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "調べる"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = ".cryptoまたは.zilドメインを入力してください"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%2$dの%1$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "調べる"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index db7f6d8a3..a56848dc0 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "받기"; +/* resetFields */ +"Button.resetFields" = "리셋 필드"; + /* send button */ "Button.send" = "보내기"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "초기화"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "카드"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "카드 잔액"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "로그인 실패"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "비밀번호를 잊으 셨나요?"; + +/* Login */ +"LitecoinCard.login" = "로그인"; + +/* Logout */ +"LitecoinCard.logout" = "로그 아웃"; + +/* Register */ +"LitecoinCard.registerCard" = "레지스터"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "라이트 코인 카드 등록"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "사용자 등록 중 ..."; + +/* address */ +"LitecoinCard.Registration.address" = "주소"; + +/* city */ +"LitecoinCard.Registration.city" = "시티"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "비밀번호 확인"; + +/* country */ +"LitecoinCard.Registration.country" = "국가"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "이름"; + +/* identification */ +"LitecoinCard.Registration.identification" = "신분증"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "고객 파악 ID 유형"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID 유형"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "성"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "휴대폰 번호"; + +/* password */ +"LitecoinCard.Registration.password" = "암호"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "주 / 도"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "ID 유형"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "비워 둘 수 없습니다."; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "잘못된 이메일 주소"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "휴대 전화 번호는 10 자리 이상이어야합니다."; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "휴대폰 번호가 필요합니다."; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "비밀번호는 6 자 이상이어야합니다."; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "비밀번호는 6 자 이상이어야하며 최소 1 개의 문자와 1 개의 숫자가 있어야합니다."; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "비밀번호가 필요합니다"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "필수 필드"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "우편 번호"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "등록에 문제가 있습니다. 데이터를 확인하고 다시 시도하십시오."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "등록하셨습니다! 이메일을 확인하고 확인하십시오. 그런 다음 다시 로그인하십시오."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "암호를 재설정"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "https://litecoin.dashboard.getblockcard.com/password/forgot을 방문하여 암호를 재설정하십시오."; + /* Location services disabled error */ "LocationPlugin.disabled" = "위치 서비스가 꺼졌습니다."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "수취인"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "조회"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = ".crypto 또는 .zil 도메인을 입력하세요."; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%2$d의 %1$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "조회"; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index 861e83af1..18360417c 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "ontvangen"; +/* resetFields */ +"Button.resetFields" = "Reset velden"; + /* send button */ "Button.send" = "versturen"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Wissen"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "KAART"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Kaartsaldo"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Inloggen mislukt"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Wachtwoord vergeten?"; + +/* Login */ +"LitecoinCard.login" = "Log in"; + +/* Logout */ +"LitecoinCard.logout" = "Uitloggen"; + +/* Register */ +"LitecoinCard.registerCard" = "Registreren"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Registreer voor Litecoin Card"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Gebruiker registreren ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Woonadres"; + +/* city */ +"LitecoinCard.Registration.city" = "stad"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "bevestig wachtwoord"; + +/* country */ +"LitecoinCard.Registration.country" = "Land"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "Voornaam"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identificatie"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Ken uw klant ID Type"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID Type"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "achternaam"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Mobiele nummer"; + +/* password */ +"LitecoinCard.Registration.password" = "wachtwoord"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Staat / Provincie"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "E-mail"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Mag niet leeg zijn"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Ongeldig e-mailadres"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Het mobiele nummer moet minimaal 10 cijfers hebben"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Mobiel nummer is vereist"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Wachtwoord moet minimaal 6 tekens bevatten"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Wachtwoord moet uit meer dan 6 tekens bestaan, met minimaal één teken en één numeriek teken"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Een wachtwoord is verplicht"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "verplicht veld"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Postcode"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Er is een probleem opgetreden met uw registratie. Controleer uw gegevens en probeer het opnieuw."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "U bent geregistreerd! Controleer en bevestig uw e-mail. Kom dan terug om in te loggen."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Wachtwoord opnieuw instellen"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Ga naar https://litecoin.dashboard.getblockcard.com/password/forgot om uw wachtwoord te resetten."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Locatievoorzieningen zijn uitgeschakeld."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "Naar"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Opzoeken"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Voer een .crypto- of .zil-domein in"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d van %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Opzoeken"; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index 0c312f7ac..fc139c62d 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -158,6 +158,9 @@ /* receive button */ "Button.receive" = "receber"; +/* resetFields */ +"Button.resetFields" = "Limpar campos"; + /* send button */ "Button.send" = "enviar"; @@ -410,6 +413,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Apagar"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "CARTÃO"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Saldo do cartão"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Falha na autenticação"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Esqueceu a senha?"; + +/* Login */ +"LitecoinCard.login" = "Conecte-se"; + +/* Logout */ +"LitecoinCard.logout" = "Sair"; + +/* Register */ +"LitecoinCard.registerCard" = "Registro"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Registre-se para Cartão Litecoin"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Registrando usuário ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Endereço"; + +/* city */ +"LitecoinCard.Registration.city" = "Cidade"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "Confirme a Senha"; + +/* country */ +"LitecoinCard.Registration.country" = "País"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "primeiro nome"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identificação"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Conheça seu cliente Tipo de identificação"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "Tipo de ID"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "último nome"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Número de celular"; + +/* password */ +"LitecoinCard.Registration.password" = "senha"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Estado / Província"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "E-mail"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Não deve estar vazio"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Endereço de email invalido"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "O número do celular deve ter pelo menos 10 dígitos"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "O número do celular é obrigatório"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "A senha deve ter pelo menos 6 caracteres"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "A senha deve ter mais de 6 caracteres, com pelo menos um caractere e um caractere numérico"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Senha requerida"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "Campo obrigatório"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Código postal"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Ocorreu um problema com seu registro. Verifique seus dados e tente novamente."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Você se inscreveu! Verifique e confirme seu e-mail. Em seguida, volte para fazer o login."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Redefinir senha"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Visite https://litecoin.dashboard.getblockcard.com/password/forgot para redefinir a sua palavra-passe."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Os serviços de localização estão desativados."; @@ -809,6 +920,9 @@ /* Send money to label */ "Send.toLabel" = "Para"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Pesquisa"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Insira um domínio .crypto ou .zil"; @@ -1273,6 +1387,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d de %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Olho para cima"; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index 322754323..d6a608dc9 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "получить"; +/* resetFields */ +"Button.resetFields" = "Очистить поля"; + /* send button */ "Button.send" = "отправить"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Очистить"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "КАРТА"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Баланс карты"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Ошибка входа"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Забыли пароль?"; + +/* Login */ +"LitecoinCard.login" = "Авторизоваться"; + +/* Logout */ +"LitecoinCard.logout" = "Выйти"; + +/* Register */ +"LitecoinCard.registerCard" = "регистр"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Зарегистрируйтесь для получения карты Litecoin"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Регистрация пользователя ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Адрес улицы"; + +/* city */ +"LitecoinCard.Registration.city" = "город"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "Подтвердите Пароль"; + +/* country */ +"LitecoinCard.Registration.country" = "Страна"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "Имя"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Идентификация"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Знай своего клиента Тип ID"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "Тип ID"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "фамилия"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Номер мобильного"; + +/* password */ +"LitecoinCard.Registration.password" = "пароль"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Штат / провинция"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "Эл. адрес"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Не должно быть пустым"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Неверный адрес электронной почты"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Номер мобильного телефона должен состоять не менее чем из 10 цифр."; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Требуется номер мобильного телефона"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Пароль должен состоять не менее чем из 6 символов."; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Пароль должен содержать более 6 символов, по крайней мере, один символ и один цифровой символ."; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Необходим пароль"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "Обязательное поле"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Почтовый индекс"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "При регистрации возникла проблема. Пожалуйста, проверьте свои данные и попробуйте еще раз."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Вы зарегистрировались! Пожалуйста, проверьте и подтвердите свою электронную почту. Затем вернитесь к логину."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Сброс пароля"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Посетите https://litecoin.dashboard.getblockcard.com/password/forgot, чтобы сбросить пароль."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Сервисы определения местоположения отключены."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "На"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Искать"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Введите домен .crypto или .zil"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d из %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Искать"; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index 811da3ba6..c4031cf4e 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "ta emot"; +/* resetFields */ +"Button.resetFields" = "Nollställ fält"; + /* send button */ "Button.send" = "skicka"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "Töm"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "KORT"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "Kortbalans"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "Inloggningen misslyckades"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "Glömt ditt lösenord?"; + +/* Login */ +"LitecoinCard.login" = "Logga in"; + +/* Logout */ +"LitecoinCard.logout" = "Logga ut"; + +/* Register */ +"LitecoinCard.registerCard" = "Registrera"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "Registrera dig för Litecoin-kort"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "Registrerar användare ..."; + +/* address */ +"LitecoinCard.Registration.address" = "Gatuadress"; + +/* city */ +"LitecoinCard.Registration.city" = "Stad"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "bekräfta lösenord"; + +/* country */ +"LitecoinCard.Registration.country" = "Land"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "förnamn"; + +/* identification */ +"LitecoinCard.Registration.identification" = "Identifiering"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "Känn din kund ID-typ"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID-typ"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "efternamn"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "Mobilnummer"; + +/* password */ +"LitecoinCard.Registration.password" = "Lösenord"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "Stat / provins"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "E-mail"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "Får inte vara tom"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "Ogiltig e-postadress"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "Mobilnumret måste innehålla minst tio siffror"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "Mobilnummer krävs"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "Lösenordet måste innehålla minst sex tecken"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "Lösenordet måste innehålla mer än sex tecken, med minst ett tecken och ett numeriskt tecken"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "Lösenord krävs"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "obligatoriskt fält"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "Postnummer"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "Det uppstod ett problem med din registrering.\nKontrollera dina uppgifter och försök igen."; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "Du har registrerat dig! Kontrollera och bekräfta din e-post.\nKom sedan tillbaka för att logga in."; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "Återställ lösenord"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "Besök https://litecoin.dashboard.getblockcard.com/password/forgot för att återställa ditt lösenord."; + /* Location services disabled error */ "LocationPlugin.disabled" = "Platstjänster är inaktiverade."; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "Till"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "Slå upp"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Ange en .crypto- eller .zil-domän"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d av %2$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "Slå upp"; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index c84e13705..5e84126e7 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "收到"; +/* resetFields */ +"Button.resetFields" = "重新设置领域"; + /* send button */ "Button.send" = "发送"; @@ -409,6 +412,108 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "擦除"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "卡"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "卡余额"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "登录失败"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "忘记密码?"; + +/* Login */ +"LitecoinCard.login" = "登录"; + +/* Logout */ +"LitecoinCard.logout" = "登出"; + +/* Register */ +"LitecoinCard.registerCard" = "寄存器"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "正在注册用户..."; + +/* address */ +"LitecoinCard.Registration.address" = "街道地址"; + +/* city */ +"LitecoinCard.Registration.city" = "市"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "确认密码"; + +/* country */ +"LitecoinCard.Registration.country" = "国家"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "名字"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "了解你的顾客 证件类型"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "ID 유형"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "姓"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "手机号码"; + +/* password */ +"LitecoinCard.Registration.password" = "密码"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "州/省"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "ID 유형"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "不能为空"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "无效的邮件地址"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "手机号码必须至少有10位数字"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "手机号码为必填项"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "密码必须至少包含6个字符"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "密码必须超过6个字符,并且至少包含一个字符和一个数字字符"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "密码是必需的"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "必填项目"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "邮编"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "您的注册有问题。 请检查您的数据,然后重试。"; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "您已经注册! 请检查并确认您的电子邮件。 然后返回登录。"; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "重设密码"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "请访问 https://litecoin.dashboard.getblockcard.com/password/forgot 重置您的密码。"; + /* Location services disabled error */ "LocationPlugin.disabled" = "位置服务被禁用。"; @@ -808,6 +913,9 @@ /* Send money to label */ "Send.toLabel" = "至"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "抬头"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "输入.crypto或.zil域"; @@ -1273,5 +1381,8 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d / %2$d"; -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "抬头"; +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = ""; + +/* identification */ +"LitecoinCard.Registration.identification" = ""; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index c72fa3366..5622e8eab 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -157,6 +157,9 @@ /* receive button */ "Button.receive" = "接收"; +/* resetFields */ +"Button.resetFields" = "resetFields"; + /* send button */ "Button.send" = "寄出"; @@ -409,6 +412,114 @@ /* Wipe wallet button */ "JailbreakWarnings.wipe" = "抹除"; +/* Card Bar Item Title */ +"LitecoinCard.barItemTitle" = "卡"; + +/* Card balance */ +"LitecoinCard.cardBalance" = "卡餘額"; + +/* Failed Login */ +"LitecoinCard.failed.login" = "登錄失敗"; + +/* Forgot password? */ +"LitecoinCard.forgotPassword" = "忘記密碼?"; + +/* Login */ +"LitecoinCard.login" = "登錄"; + +/* Logout */ +"LitecoinCard.logout" = "登出"; + +/* Register */ +"LitecoinCard.registerCard" = "寄存器"; + +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "註冊萊特幣卡"; + +/* Registering user... */ +"LitecoinCard.registering.user" = "正在註冊用戶..."; + +/* address */ +"LitecoinCard.Registration.address" = "街道地址"; + +/* city */ +"LitecoinCard.Registration.city" = "市"; + +/* confirm password */ +"LitecoinCard.Registration.confirmPassword" = "確認密碼"; + +/* country */ +"LitecoinCard.Registration.country" = "國家"; + +/* First name */ +"LitecoinCard.Registration.firstName" = "名字"; + +/* identification */ +"LitecoinCard.Registration.identification" = "身份證明"; + +/* kycIDNumber */ +"LitecoinCard.Registration.kycIDNumber" = "了解你的顧客 證件類型"; + +/* kycIDType */ +"LitecoinCard.Registration.kycIDType" = "證件類型"; + +/* SSN */ +"LitecoinCard.Registration.kycSSN" = "SSN"; + +/* Last name */ +"LitecoinCard.Registration.lastName" = "姓"; + +/* mobile number */ +"LitecoinCard.Registration.mobileNumber" = "手機號碼"; + +/* password */ +"LitecoinCard.Registration.password" = "密碼"; + +/* state province */ +"LitecoinCard.Registration.stateProvince" = "州/省"; + +/* registraition username / email */ +"LitecoinCard.Registration.usernameEmail" = "電子郵件"; + +/* must not be empty */ +"LitecoinCard.Registration.ValidationError.empty" = "必填項目"; + +/* Invalid email address */ +"LitecoinCard.Registration.ValidationError.invalidEmail" = "無效的郵件地址"; + +/* Mobile number 10 digits required */ +"LitecoinCard.Registration.ValidationError.numberDigitsRequired" = "手機號碼必須至少有10位數字"; + +/* Mobile number required */ +"LitecoinCard.Registration.ValidationError.numberRequired" = "手機號碼為必填項"; + +/* 6 Password characters required */ +"LitecoinCard.Registration.ValidationError.passwordCharacters" = "密碼必須至少包含6個字符"; + +/* Captial and numeric password characters required */ +"LitecoinCard.Registration.ValidationError.passwordComposition" = "密碼必須超過6個字符,並且至少包含一個字符和一個數字字符"; + +/* Password required */ +"LitecoinCard.Registration.ValidationError.passwordRequired" = "密碼是必需的"; + +/* Required field */ +"LitecoinCard.Registration.ValidationError.requiredField" = "不能為空"; + +/* zip post Code */ +"LitecoinCard.Registration.zipPostCode" = "郵編"; + +/* Registration failure */ +"LitecoinCard.registrationFailure" = "您的註冊有問題。 請檢查您的數據,然後重試。"; + +/* Registration success */ +"LitecoinCard.registrationSuccess" = "您已經註冊! 請檢查並確認您的電子郵件。 然後返回登錄。"; + +/* Reset Litecoin card password */ +"LitecoinCard.resetPassword" = "重設密碼"; + +/* Litecoin card visit */ +"LitecoinCard.visit.toReset" = "訪問https://litecoin.dashboard.getblockcard.com/password/forgot重設密碼。"; + /* Location services disabled error */ "LocationPlugin.disabled" = "定位服務已停用。"; @@ -808,6 +919,9 @@ /* Send money to label */ "Send.toLabel" = "給"; +/* Lookup */ +"Send.UnstoppableDomains.lookup" = "抬頭"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "輸入.crypto或.zil域"; @@ -1272,6 +1386,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%2$d 之 %1$d"; - -/* Lookup */ -"Send.UnstoppableDomains.lookup" = "抬頭"; diff --git a/loafwallet/src/ViewControllers/Import/StartImportViewController.swift b/loafwallet/src/ViewControllers/Import/StartImportViewController.swift index 8f14d0a9b..397ab41d2 100644 --- a/loafwallet/src/ViewControllers/Import/StartImportViewController.swift +++ b/loafwallet/src/ViewControllers/Import/StartImportViewController.swift @@ -251,7 +251,7 @@ class StartImportViewController : UIViewController { } private func showSuccess() { - store.perform(action: Alert.Show(.sweepSuccess(callback: { [weak self] in + store.perform(action: SimpleReduxAlert.Show(.sweepSuccess(callback: { [weak self] in guard let myself = self else { return } myself.dismiss(animated: true, completion: nil) }))) diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index bcabacebe..8df70c501 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -239,7 +239,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track @objc private func pasteTapped() { guard let pasteboard = UIPasteboard.general.string, pasteboard.utf8.count > 0 else { - return showAlert(title: S.Alert.error, message: S.Send.emptyPasteboard, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: S.Send.emptyPasteboard, buttonLabel: S.Button.ok) } guard let request = PaymentRequest(string: pasteboard) else { return showAlert(title: S.Send.invalidAddressTitle, message: S.Send.invalidAddressOnPasteboard, buttonLabel: S.Button.ok) @@ -263,29 +263,29 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track if sender.transaction == nil { guard let address = addressCell.address else { - return showAlert(title: S.Alert.error, message: S.Send.noAddress, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: S.Send.noAddress, buttonLabel: S.Button.ok) } guard address.isValidAddress else { return showAlert(title: S.Send.invalidAddressTitle, message: S.Send.invalidAddressMessage, buttonLabel: S.Button.ok) } guard let amount = amount else { - return showAlert(title: S.Alert.error, message: S.Send.noAmount, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: S.Send.noAmount, buttonLabel: S.Button.ok) } if let minOutput = walletManager.wallet?.minOutputAmount { guard amount.rawValue >= minOutput else { let minOutputAmount = Amount(amount: minOutput, rate: Rate.empty, maxDigits: store.state.maxDigits) let message = String(format: S.PaymentProtocol.Errors.smallPayment, minOutputAmount.string(isLtcSwapped: store.state.isLtcSwapped)) - return showAlert(title: S.Alert.error, message: message, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: message, buttonLabel: S.Button.ok) } } guard !(walletManager.wallet?.containsAddress(address) ?? false) else { - return showAlert(title: S.Alert.error, message: S.Send.containsAddress, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: S.Send.containsAddress, buttonLabel: S.Button.ok) } guard amount.rawValue <= (walletManager.wallet?.maxOutputAmount ?? 0) else { - return showAlert(title: S.Alert.error, message: S.Send.insufficientFunds, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: S.Send.insufficientFunds, buttonLabel: S.Button.ok) } guard sender.createTransaction(amount: amount.rawValue, to: address) else { - return showAlert(title: S.Alert.error, message: S.Send.createTransactionError, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: S.Send.createTransactionError, buttonLabel: S.Button.ok) } } @@ -376,7 +376,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self?.saveEvent("send.publishFailed", attributes: ["errorMessage": message]) case .publishFailure(let error): if case .posixError(let code, let description) = error { - self?.showAlert(title: S.Alerts.sendFailure, message: "\(description) (\(code))", buttonLabel: S.Button.ok) + self?.showAlert(title: S.SecurityAlerts.sendFailure, message: "\(description) (\(code))", buttonLabel: S.Button.ok) self?.saveEvent("send.publishFailed", attributes: ["errorMessage": "\(description) (\(code))"]) } } @@ -405,10 +405,10 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track } if wallet.containsAddress(address) { - return showAlert(title: S.Alert.warning, message: S.Send.containsAddress, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.warning, message: S.Send.containsAddress, buttonLabel: S.Button.ok) } else if wallet.addressIsUsed(address) && !didIgnoreUsedAddressWarning { let message = "\(S.Send.UsedAddress.title)\n\n\(S.Send.UsedAddress.firstLine)\n\n\(S.Send.UsedAddress.secondLine)" - return showError(title: S.Alert.warning, message: message, ignore: { [weak self] in + return showError(title: S.LitewalletAlert.warning, message: message, ignore: { [weak self] in self?.didIgnoreUsedAddressWarning = true self?.confirmProtocolRequest(protoReq: protoReq) }) @@ -439,7 +439,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track if requestAmount == 0 { if let amount = amount { guard sender.createTransaction(amount: amount.rawValue, to: address) else { - return showAlert(title: S.Alert.error, message: S.Send.createTransactionError, buttonLabel: S.Button.ok) + return showAlert(title: S.LitewalletAlert.error, message: S.Send.createTransactionError, buttonLabel: S.Button.ok) } } } else { diff --git a/loafwallet/src/ViewControllers/SecurityCenter/UpdatePinViewController.swift b/loafwallet/src/ViewControllers/SecurityCenter/UpdatePinViewController.swift index 731379015..0889db30a 100644 --- a/loafwallet/src/ViewControllers/SecurityCenter/UpdatePinViewController.swift +++ b/loafwallet/src/ViewControllers/SecurityCenter/UpdatePinViewController.swift @@ -263,13 +263,13 @@ class UpdatePinViewController: UIViewController, Subscriber { if let success = success, success == true { if self?.resetFromDisabledSuccess != nil { self?.resetFromDisabledWillSucceed?() - self?.store.perform(action: Alert.Show(.pinSet(callback: { [weak self] in + self?.store.perform(action: SimpleReduxAlert.Show(.pinSet(callback: { [weak self] in self?.dismiss(animated: true, completion: { self?.resetFromDisabledSuccess?() }) }))) } else { - self?.store.perform(action: Alert.Show(.pinSet(callback: { [weak self] in + self?.store.perform(action: SimpleReduxAlert.Show(.pinSet(callback: { [weak self] in self?.setPinSuccess?(newPin) if self?.type != .creationNoPhrase { self?.parent?.dismiss(animated: true, completion: nil) diff --git a/loafwallet/src/Views/AlertView.swift b/loafwallet/src/Views/AlertView.swift index 8936e392d..46fbb2ca3 100644 --- a/loafwallet/src/Views/AlertView.swift +++ b/loafwallet/src/Views/AlertView.swift @@ -19,15 +19,15 @@ enum AlertType { var header: String { switch self { case .pinSet: - return S.Alerts.pinSet + return S.SecurityAlerts.pinSet case .paperKeySet: - return S.Alerts.paperKeySet - case .sendSuccess: - return S.Alerts.sendSuccess + return S.SecurityAlerts.paperKeySet + case .sendSuccess: + return S.SecurityAlerts.sendSuccess case .resolvedSuccess: - return S.Alerts.resolvedSuccess + return S.SecurityAlerts.resolvedSuccess case .addressesCopied: - return S.Alerts.copiedAddressesHeader + return S.SecurityAlerts.copiedAddressesHeader case .sweepSuccess: return S.Import.success } @@ -38,13 +38,13 @@ enum AlertType { case .pinSet: return "" case .paperKeySet: - return S.Alerts.paperKeySetSubheader - case .sendSuccess: - return S.Alerts.sendSuccessSubheader + return S.SecurityAlerts.paperKeySetSubheader + case .sendSuccess: + return S.SecurityAlerts.sendSuccessSubheader case .resolvedSuccess: - return S.Alerts.resolvedSuccessSubheader + return S.SecurityAlerts.resolvedSuccessSubheader case .addressesCopied: - return S.Alerts.copiedAddressesSubheader + return S.SecurityAlerts.copiedAddressesSubheader case .sweepSuccess: return S.Import.successBody } diff --git a/loafwallet/src/WalletManager.swift b/loafwallet/src/WalletManager.swift index 5b1fea792..bb0cb1a1a 100644 --- a/loafwallet/src/WalletManager.swift +++ b/loafwallet/src/WalletManager.swift @@ -43,6 +43,9 @@ extension NSNotification.Name { public static let WalletSyncStoppedNotification = NSNotification.Name("WalletSyncStopped") public static let WalletDidWipeNotification = NSNotification.Name("WalletDidWipe") public static let DidDeleteWalletDBNotification = NSNotification.Name("DidDeleteDatabase") + public static let LitecoinCardLoginNotification = NSNotification.Name("LitecoinCardLogin") + public static let LitecoinCardLogoutNotification = NSNotification.Name("LitecoinCardLogout") + } From 09d4c2b4eec4ba725835fd63b471a61c73809ba2 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 10 Jan 2021 02:02:57 +0000 Subject: [PATCH 025/114] [Merge v3.0.0] into Develop (#184) * version bump * Added some tests * Refactored the login logic - Used the status of the binding to change the UI * Added combined logic of the email and password fields to enable login button Reference @losh11 comment: `The cards login now gives a good login failed alert. However I think the login button should be disabled until the text in the email input is validated as email format.` * build bump --- loafwallet.xcodeproj/project.pbxproj | 44 ++++++--- loafwallet/CardView.swift | 53 ++++++++--- loafwallet/RegistrationViewModel.swift | 47 ++++++---- .../AnimatedCardViewModelTests.swift | 27 ++++++ .../LoginViewModelTests.swift | 41 +++++++++ .../RegistrationViewModelTests.swift | 92 +++++++++++++++++++ 6 files changed, 264 insertions(+), 40 deletions(-) create mode 100644 loafwalletTests/Class Tests/LitecoinCardTests/AnimatedCardViewModelTests.swift create mode 100644 loafwalletTests/Class Tests/LitecoinCardTests/LoginViewModelTests.swift create mode 100644 loafwalletTests/Class Tests/LitecoinCardTests/RegistrationViewModelTests.swift diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 1e3419f6c..643f23a39 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -276,6 +276,9 @@ C32DC79C2593971500A7FDB4 /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DC79B2593971500A7FDB4 /* CardView.swift */; }; C32DC7AC2593B5C900A7FDB4 /* AnimatedCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DC7AB2593B5C900A7FDB4 /* AnimatedCardView.swift */; }; C32DC7B52593B61F00A7FDB4 /* AnimatedCardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DC7B42593B61F00A7FDB4 /* AnimatedCardViewModel.swift */; }; + C345D81525A8D52600657E30 /* LoginViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C345D81425A8D52600657E30 /* LoginViewModelTests.swift */; }; + C345D82525A8D54200657E30 /* RegistrationViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C345D82425A8D54200657E30 /* RegistrationViewModelTests.swift */; }; + C345D83725A8D57E00657E30 /* AnimatedCardViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C345D83625A8D57E00657E30 /* AnimatedCardViewModelTests.swift */; }; C354C45A258FA9C000675E0E /* MainTabBarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C354C459258FA9C000675E0E /* MainTabBarViewModel.swift */; }; C354C4632590059500675E0E /* TransactionsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C354C4622590059500675E0E /* TransactionsViewModel.swift */; }; C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD222574070A002BB9BB /* PartnersView.swift */; }; @@ -1447,6 +1450,9 @@ C32DC79B2593971500A7FDB4 /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = ""; }; C32DC7AB2593B5C900A7FDB4 /* AnimatedCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedCardView.swift; sourceTree = ""; }; C32DC7B42593B61F00A7FDB4 /* AnimatedCardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedCardViewModel.swift; sourceTree = ""; }; + C345D81425A8D52600657E30 /* LoginViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModelTests.swift; sourceTree = ""; }; + C345D82425A8D54200657E30 /* RegistrationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationViewModelTests.swift; sourceTree = ""; }; + C345D83625A8D57E00657E30 /* AnimatedCardViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedCardViewModelTests.swift; sourceTree = ""; }; C354C459258FA9C000675E0E /* MainTabBarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewModel.swift; sourceTree = ""; }; C354C4622590059500675E0E /* TransactionsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsViewModel.swift; sourceTree = ""; }; C35ABD222574070A002BB9BB /* PartnersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersView.swift; sourceTree = ""; }; @@ -2147,6 +2153,7 @@ 24470E4323A6088700ADDA27 /* Class Tests */ = { isa = PBXGroup; children = ( + C345D81325A8D50600657E30 /* LitecoinCardTests */, 24470E4423A608A700ADDA27 /* AmountTests.swift */, 2494037523AD35C000369261 /* BuyWKWebVCTests.swift */, 249C570423B51F9B009CB5A9 /* TransactionsViewControllerTests.swift */, @@ -3073,6 +3080,16 @@ name = CardModels; sourceTree = ""; }; + C345D81325A8D50600657E30 /* LitecoinCardTests */ = { + isa = PBXGroup; + children = ( + C345D81425A8D52600657E30 /* LoginViewModelTests.swift */, + C345D83625A8D57E00657E30 /* AnimatedCardViewModelTests.swift */, + C345D82425A8D54200657E30 /* RegistrationViewModelTests.swift */, + ); + path = LitecoinCardTests; + sourceTree = ""; + }; C35ABD07257404C6002BB9BB /* SwiftUI+UIKit */ = { isa = PBXGroup; children = ( @@ -3996,13 +4013,16 @@ 24470E3E23A6000900ADDA27 /* WalletAuthenticationTests.swift in Sources */, 24470E2A23A5F33000ADDA27 /* BRReplicatedKVStoreTests.swift in Sources */, C3D783C02565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift in Sources */, + C345D81525A8D52600657E30 /* LoginViewModelTests.swift in Sources */, 249C570523B51F9B009CB5A9 /* TransactionsViewControllerTests.swift in Sources */, 24470E2523A5EF0D00ADDA27 /* BRAPIClientTests.swift in Sources */, 24470E3C23A5FFD700ADDA27 /* TouchIdEnabledTests.swift in Sources */, 24470E3023A5F55700ADDA27 /* BRHTTPServerTests.swift in Sources */, 24470E3A23A5FF5700ADDA27 /* TestHelpers.swift in Sources */, + C345D83725A8D57E00657E30 /* AnimatedCardViewModelTests.swift in Sources */, C3B7C43F25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift in Sources */, 2465873923A5AAD100A32E9E /* loafwalletTests.swift in Sources */, + C345D82525A8D54200657E30 /* RegistrationViewModelTests.swift in Sources */, 24470E3623A5FDE800ADDA27 /* PhraseTests.swift in Sources */, 24470E4523A608A700ADDA27 /* AmountTests.swift in Sources */, C3B7C3EE255FF59200E98A64 /* ConstantsTests.swift in Sources */, @@ -4653,7 +4673,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4667,7 +4687,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.9.0; + MARKETING_VERSION = 3.0.0; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4760,7 +4780,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4770,7 +4790,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.9.0; + MARKETING_VERSION = 3.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5070,7 +5090,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5083,7 +5103,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.9.0; + MARKETING_VERSION = 3.0.0; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5100,7 +5120,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5109,7 +5129,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.9.0; + MARKETING_VERSION = 3.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5200,7 +5220,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5214,7 +5234,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.9.0; + MARKETING_VERSION = 3.0.0; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5232,7 +5252,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5242,7 +5262,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.9.0; + MARKETING_VERSION = 3.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/loafwallet/CardView.swift b/loafwallet/CardView.swift index 20a92ef1e..9d00a6785 100644 --- a/loafwallet/CardView.swift +++ b/loafwallet/CardView.swift @@ -46,8 +46,16 @@ struct CardView: View { var didCompleteLogin: Bool = false @State - var cannotLogin: Bool = true + var isEmailValid: Bool = false + @State + var isPasswordValid: Bool = false + + private var shouldEnableLogin: Binding { + return Binding( + get: { return (self.isPasswordValid && self.isEmailValid) }, + set: { if !$0 { (self.isPasswordValid && self.isEmailValid) } }) + } init(viewModel: CardViewModel) { @@ -62,21 +70,29 @@ struct CardView: View { Group { AnimatedCardView(viewModel: animatedViewModel, isLoggedIn: $didCompleteLogin) .frame(minWidth:0, - maxWidth: didCompleteLogin ? geometry.size.width * 0.4 : geometry.size.width * 0.6) + maxWidth: + didCompleteLogin ? geometry.size.width * 0.4 : + geometry.size.width * 0.6) .padding(.all, didCompleteLogin ? 20 : 30) } //MARK: - Login Textfields Group { - TextField(S.Receive.emailButton, text: $loginModel.emailString) { _ in - cannotLogin = loginModel.emailString.count < 4 + TextField(S.Receive.emailButton, + text: $loginModel.emailString) + .onReceive(loginModel.$emailString) { currentEmail in + if currentEmail.count < 4 || !registrationModel.isEmailValid(emailString: currentEmail) { + isEmailValid = false + } else { + isEmailValid = true + } } + .foregroundColor(isEmailValid ? .black : Color(UIColor.litecoinOrange)) .font(Font(UIFont.barlowSemiBold(size:18.0))) .accentColor(Color(UIColor.liteWalletBlue)) .padding([.leading, .trailing], 20) .padding(.top, 30) - .foregroundColor(.black) .autocapitalization(.none) .keyboardType(.emailAddress) @@ -86,6 +102,14 @@ struct CardView: View { if shouldShowPassword { TextField(S.Import.passwordPlaceholder.capitalized, text: $loginModel.passwordString) + .onReceive(loginModel.$passwordString) { currentPassword in + if !registrationModel.isPasswordValid(passwordString: currentPassword) { + isPasswordValid = false + } else { + isPasswordValid = true + } + } + .foregroundColor(isPasswordValid ? .black : Color(UIColor.litecoinOrange)) .font(Font(UIFont.barlowSemiBold(size:18.0))) .accentColor(Color(UIColor.liteWalletBlue)) .padding(.leading, 20) @@ -96,6 +120,14 @@ struct CardView: View { } else { SecureField(S.Import.passwordPlaceholder.capitalized, text: $loginModel.passwordString) + .onReceive(loginModel.$passwordString) { currentPassword in + if !registrationModel.isPasswordValid(passwordString: currentPassword) { + isPasswordValid = false + } else { + isPasswordValid = true + } + } + .foregroundColor(isPasswordValid ? .black : Color(UIColor.litecoinOrange)) .font(Font(UIFont.barlowSemiBold(size:18.0))) .accentColor(Color(UIColor.liteWalletBlue)) .padding(.leading, 20) @@ -163,18 +195,15 @@ struct CardView: View { .padding() .font(Font(UIFont.barlowMedium(size: 16.0))) .padding([.leading, .trailing], 16) - .foregroundColor(cannotLogin ? Color(UIColor.litecoinSilver) : - Color(.white)) - .background(cannotLogin ? .gray : - Color(UIColor.liteWalletBlue)) + .foregroundColor(shouldEnableLogin.wrappedValue ? .white : Color(UIColor.litecoinSilver)) + .background(shouldEnableLogin.wrappedValue ? Color(UIColor.liteWalletBlue) : Color(UIColor.litecoinGray)) .cornerRadius(4.0) .overlay( RoundedRectangle(cornerRadius:4) - .stroke((cannotLogin ? .gray : - Color(UIColor.liteWalletBlue)), lineWidth: 1) + .stroke(shouldEnableLogin.wrappedValue ? Color(UIColor.liteWalletBlue) : .gray, lineWidth: 1) ) } - .disabled(cannotLogin) + .disabled(!shouldEnableLogin.wrappedValue) .padding([.leading, .trailing], 16) // Registration button diff --git a/loafwallet/RegistrationViewModel.swift b/loafwallet/RegistrationViewModel.swift index 704e1c16b..18c969706 100644 --- a/loafwallet/RegistrationViewModel.swift +++ b/loafwallet/RegistrationViewModel.swift @@ -39,16 +39,29 @@ class RegistrationViewModel: ObservableObject { func verify(data: [String: Any], completion: @escaping (Bool) -> ()) { - if self.isDataValid(dataType: .genericString, data: (dataDictionary["firstname"] as! String)) && - isDataValid(dataType: .genericString, data: (dataDictionary["lastname"] as! String)) && - isDataValid(dataType: .email, data: (dataDictionary["email"] as! String)) && - isDataValid(dataType: .password, data: (dataDictionary["password"] as! String)) && - isDataValid(dataType: .mobileNumber, data: (dataDictionary["phone"] as! String)) && - isDataValid(dataType: .country, data: (dataDictionary["country"] as! String)) && - isDataValid(dataType: .genericString, data: (dataDictionary["state"] as! String)) && - isDataValid(dataType: .genericString, data: (dataDictionary["city"] as! String)) && - isDataValid(dataType: .genericString, data: (dataDictionary["address1"] as! String)) && - isDataValid(dataType: .genericString, data: (dataDictionary["zip_code"] as! String)) { + guard let first = data["firstname"] as? String else { return } + guard let last = data["lastname"] as? String else { return } + guard let email = data["email"] as? String else { return } + guard let password = data["password"] as? String else { return } + guard let phone = data["phone"] as? String else { return } + guard let country = data["country"] as? String else { return } + guard let state = data["state"] as? String else { return } + guard let city = data["city"] as? String else { return } + guard let address1 = data["address1"] as? String else { return } + guard let zip = data["zip_code"] as? String else { return } + + if self.isDataValid(dataType: .genericString, data: first) && + isDataValid(dataType: .genericString, data: last) && + isDataValid(dataType: .email, data: email) && + isDataValid(dataType: .password, data: password) && + isDataValid(dataType: .mobileNumber, data: phone) && + isDataValid(dataType: .country, data: country) && + isDataValid(dataType: .genericString, data: state) && + isDataValid(dataType: .genericString, data: city) && + isDataValid(dataType: .genericString, data: address1) && + isDataValid(dataType: .genericString, data: zip) { + + self.dataDictionary = data self.isRegistering = true @@ -101,19 +114,21 @@ class RegistrationViewModel: ObservableObject { func isDataValid(dataType: UserDataType, firstString: String = "", data: Any) -> Bool { + guard let dataString = data as? String else { return false } + switch dataType { case .genericString: - return isGenericStringValid(genericString: (data as! String)) + return isGenericStringValid(genericString: dataString) case .email: - return isEmailValid(emailString: (data as! String)) + return isEmailValid(emailString: dataString) case .country: - return (data as! String) == "US" ? true : false + return dataString == "US" ? true : false case .mobileNumber: - return isMobileNumberValid(mobileString: (data as! String)) + return isMobileNumberValid(mobileString: dataString) case .password: - return isPasswordValid(passwordString: (data as! String)) + return isPasswordValid(passwordString: dataString) case .confirmation: - return isConfirmedValid(firstString: firstString, confirmingString: (data as! String)) + return isConfirmedValid(firstString: firstString, confirmingString: dataString) } } diff --git a/loafwalletTests/Class Tests/LitecoinCardTests/AnimatedCardViewModelTests.swift b/loafwalletTests/Class Tests/LitecoinCardTests/AnimatedCardViewModelTests.swift new file mode 100644 index 000000000..64ab50f90 --- /dev/null +++ b/loafwalletTests/Class Tests/LitecoinCardTests/AnimatedCardViewModelTests.swift @@ -0,0 +1,27 @@ +// +// AnimatedCardViewModelTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 1/8/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import XCTest +import Foundation +import SwiftUI +@testable import loafwallet + +class AnimatedCardViewModelTests: XCTestCase { + + var viewModel: AnimatedCardViewModel! + + override func setUp() { + super.setUp() + viewModel = AnimatedCardViewModel() + } + + func testCardImageFrontIsFound() throws { + let image = Image(viewModel.imageFront) + XCTAssertNotNil(image) + } +} diff --git a/loafwalletTests/Class Tests/LitecoinCardTests/LoginViewModelTests.swift b/loafwalletTests/Class Tests/LitecoinCardTests/LoginViewModelTests.swift new file mode 100644 index 000000000..1b74da164 --- /dev/null +++ b/loafwalletTests/Class Tests/LitecoinCardTests/LoginViewModelTests.swift @@ -0,0 +1,41 @@ +// +// LoginViewModelTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 1/8/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import XCTest +import Foundation +import SwiftUI +@testable import loafwallet + +class LoginViewModelTests: XCTestCase { + + var viewModel: LoginViewModel! + + let mockFailingUserCreds = ["email": "myemail@com.com", + "password": ""] + + override func setUp() { + super.setUp() + viewModel = LoginViewModel() + } + + func testLoginFailingCreds() throws { + + guard let email = mockFailingUserCreds["email"] else { return } + + guard let password = mockFailingUserCreds["password"] else { return } + + viewModel.emailString = email + + viewModel.passwordString = password + + viewModel.login { (didLogin) in + XCTAssert(didLogin == false) + } + } +} + diff --git a/loafwalletTests/Class Tests/LitecoinCardTests/RegistrationViewModelTests.swift b/loafwalletTests/Class Tests/LitecoinCardTests/RegistrationViewModelTests.swift new file mode 100644 index 000000000..27967b492 --- /dev/null +++ b/loafwalletTests/Class Tests/LitecoinCardTests/RegistrationViewModelTests.swift @@ -0,0 +1,92 @@ +// +// RegistrationViewModelTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 1/8/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import XCTest +import Foundation +import SwiftUI +@testable import loafwallet + +class RegistrationViewModelTests: XCTestCase { + + var viewModel: RegistrationViewModel! + + let mockRegistrationData = ["firstname": "Firstname", + "lastname": "Lastname", + "email": "myemail@co.com", + "password": "Password9", + "phone": "14047721517", + "country": "US", + "state": "AL", + "city": "Anytown", + "address1": "123 Town", + "zip_code": "95014"] + + let mockBadRegistrationData = ["firstname": "", + "lastname": "Lastname", + "email": "myemail@co", + "password": "Pas", + "phone": "12345670", + "country": "US", + "state": "AL", + "city": "Anytown", + "address1": "123 Town", + "zip_code": ""] + + override func setUp() { + super.setUp() + viewModel = RegistrationViewModel() + } + + func testCountryDataValid() throws { + + XCTAssertTrue(mockRegistrationData["country"] == "US") + + //DEV: For US only now + XCTAssertFalse(mockRegistrationData["country"] != "US") + + XCTAssertTrue(viewModel.isDataValid(dataType: .country, + data: mockRegistrationData["country"] as Any)) + + } + + func testIfGenericDataValid() throws { + XCTAssertTrue(viewModel.isDataValid(dataType: .genericString, + data: mockRegistrationData["address1"] as Any)) + } + + func testIsEmailDataValid() throws { + + XCTAssertTrue(viewModel.isDataValid(dataType: .email, + data: mockRegistrationData["email"] as Any)) + + XCTAssertFalse(viewModel.isDataValid(dataType: .email, + data: mockBadRegistrationData["email"] as Any)) + + } + + func testIsPasswordDataValid() throws { + + XCTAssertTrue(viewModel.isDataValid(dataType: .password, + data: mockRegistrationData["password"] as Any)) + + XCTAssertFalse(viewModel.isDataValid(dataType: .password, + data: mockBadRegistrationData["password"] as Any)) + + } + + func testIsMobileNumberDataValid() throws { + + XCTAssertTrue(viewModel.isDataValid(dataType: .mobileNumber, + data: mockRegistrationData["phone"] as Any)) + + XCTAssertFalse(viewModel.isDataValid(dataType: .mobileNumber, + data: mockBadRegistrationData["phone"] as Any)) + + } + +} From 7bc51d8eb32214c35c3c4bde4829523813711f53 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 12 Jan 2021 00:06:58 +0000 Subject: [PATCH 026/114] [HOTFIX] hide litecoin card (#192) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Merge v3.0.0] into Master (#183) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release] Merge v2.8.2 into Develop (#158) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry * [Bugfix] Replace the LF Support View (#159) * Moved the LF Cell from Send. - BartyCrouch linted the stigns files. * Updated the LF Support location - Reset the localiaztion language to ‘Customer support’ - Add the dismissal actions * [Bugfix] Fix buy tab: Simplex urls (#157) * Updated the url to new servers * Linted the Localized strings * Setup url constants * updated pk file status * Updated per PR review comments * fixed naming of the url variable * [Merge v2.8.3] into Develop (#169) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Master (#153) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * version bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [Feature Issue 154] Adding Unstoppable Domains functionality (#155) * Added UD to Podfile - Stubbed out the view, viewModel and the test class for UD * [UI Polish] Added images and localized strings - Added more of strings and UD structure - Trimmed images to resize for button - Added localized strings for placeholder * Updated UnstoppableDomainsView and Model details - Added DEV notes script - Adjusted Previews by unchecking the `build install only` * Added more tests - UnstoppableDomains View Model tests - SupportLitecoinFoundationViewModel tests * reformatted code in new SwiftUI views and viewModels * Added UD action to the SendViewController * Updated project * Updated localized UD Placeholder * Setup API keys * removed pk file * Changed the localizations related to UD - Added ‘Or’ label - Added UD placeholder text - Changed the LTC address placeholder text * Added in the Or and relayout of the button - Added Partner layout view for UD and Simplex * Resolved code review comments - Update the localizations - Refactored the UD shared instance (singleton) to retain throguh the call - Added timing probes * revert to current version * reformatted the Support LF view strings * Remove Test Playground. * Removed unused SocialView and ViewModel * Improved resolution - Added a Dispatch and ‘exit’ when address is found sooner than 12 secs. Much better experience for the user. * Added infura * Resolved review comments * Rewrote copy for “Enter a Litecoin address” * Fix some trivial conflict markers (#177) * [Bugfix] Upgrade the business logic for Unstoppable Domains (#179) * Fix some triival conflict markers * Added test to button once the UD string meets a minimum length * Clears address text field when Lookup button is pressed * Set the background color of the AlertToast * Locailization of the alert language * move logic to release the first responder * per review notes * [Feature] Litecoin card v1 (#180) * [Litecoin Card] Progress Step 1 - Major work: litecoin-card TabBarView refactor - Updated UIColor for Color - SwiftUI preview devices - Working out the Nav polish - Fixed hard-coded UD lookup label with proper localizations - Commented out BitId * [Litecoin Card] Progress Step 2 - Added more localizations - Rebuilding registration view need to add keyboard - Fixed the animation for the card view - Fixed Alert name collisions to the SimplexAlert * [Litecoin Card] Progress Step 3 - Added Login views and localizations - Added partnerAPI Swift Package - Layout the registration view - Add more localizations - BUGFIX: Image missing in this branch. * [Litecoin Card] Progress Step 4 More localizations Added data Validators Final Polish for Registration View Registration View Modal wiring works * [Litecoin Card] Progress Step 5 Register works to the model Login is working Added animation for Login/Logout Login and Loogut working Added localizations More localizations * [Litecoin Card] RC 1 polishes Communcations polishing + dev cleanup Polishing the RegistrationView layout Fixed bug: https://github.com/litecoin-foundation/loafwallet-ios/issues/175 * [Litecoin Card] RC2: removed defunct script * per review comments - Ar files removal - Cleanup localizable - Removed Ar.proj files - Removed empty class - Added all Validation localization framework - Added localizations of the validations - Refactored per review notes * Bugfix- login message Added failure message localizations * version bump * Added some tests * Refactored the login logic - Used the status of the binding to change the UI * Added combined logic of the email and password fields to enable login button Reference @losh11 comment: `The cards login now gives a good login failed alert. However I think the login button should be disabled until the text in the email input is validated as email format.` * build bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * Hide Card Tab * added comments for v1 Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov --- loafwallet.xcodeproj/project.pbxproj | 24 ++++++++++++------------ loafwallet/Storyboards/Main.storyboard | 6 ++---- loafwallet/TabBarViewController.swift | 23 +++++++++++++---------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 643f23a39..4313cdd44 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -4673,7 +4673,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4687,7 +4687,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4780,7 +4780,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4790,7 +4790,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5090,7 +5090,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5103,7 +5103,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5120,7 +5120,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5129,7 +5129,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5220,7 +5220,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5234,7 +5234,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5252,7 +5252,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5262,7 +5262,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.0.0; + MARKETING_VERSION = 3.0.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/loafwallet/Storyboards/Main.storyboard b/loafwallet/Storyboards/Main.storyboard index 5aad4a497..b2f1b6bf6 100644 --- a/loafwallet/Storyboards/Main.storyboard +++ b/loafwallet/Storyboards/Main.storyboard @@ -39,9 +39,8 @@ - - - + + @@ -368,7 +367,6 @@ - diff --git a/loafwallet/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index fc4e36da5..40956edfe 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -303,9 +303,10 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel switch item.tag { case 0: item.title = S.History.barItemTitle case 1: item.title = S.Send.barItemTitle - case 2: item.title = S.LitecoinCard.barItemTitle - case 3: item.title = S.Receive.barItemTitle - case 4: item.title = S.BuyCenter.barItemTitle + //DEV: re-add when launching v1 + //case 2: item.title = S.LitecoinCard.barItemTitle + case 2: item.title = S.Receive.barItemTitle + case 3: item.title = S.BuyCenter.barItemTitle default: item.title = "NO-TITLE" NSLog("ERROR: UITabbar item count is wrong") @@ -332,13 +333,13 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel transactionVC.walletManager = self.walletManager transactionVC.isLtcSwapped = self.store?.state.isLtcSwapped - - case "loafwallet.CardViewController": - guard let cardVC = contentController as? CardViewController else { - return - } - - cardVC.parentFrame = self.containerView.frame + //DEV: Unhiding when launching Litecoin Card v1 + // case "loafwallet.CardViewController": + // guard let cardVC = contentController as? CardViewController else { + // return + // } + // + // cardVC.parentFrame = self.containerView.frame case "loafwallet.BuyTableViewController": guard let buyVC = contentController as? BuyTableViewController else { @@ -383,6 +384,8 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel if let tempActiveController = activeController { self.hideContentController(contentController: tempActiveController) } + + //DEV: This happens because it relies on the tab in the storyboard tag self.displayContentController(contentController: viewControllers[item.tag]) } } From 1535c2956c4e5f692700ce58dc17bd470fb8ac85 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 13 Jan 2021 13:04:18 +0000 Subject: [PATCH 027/114] [Bugfix]UD resolved address / got callback (#193) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed bug: resolved address / got callback - Added a dispatch group - Fixed the bug by adding wait to the group from (@JohnnyJumper) - Refactored partner plist * removed cruft * polish UD model * v3.0.1 Card Hidden - found hidden code… * Resolved review comment - polished the address send label * removed unused code - clean comments --- loafwallet.xcodeproj/project.pbxproj | 4 - loafwallet/ResolutionModel.swift | 38 ------ loafwallet/TabBarViewController.swift | 4 +- loafwallet/UnstoppableDomainView.swift | 1 - loafwallet/UnstoppableDomainViewModel.swift | 126 +++++++++++------- .../src/Views/SendViewCells/AddressCell.swift | 4 +- 6 files changed, 80 insertions(+), 97 deletions(-) delete mode 100644 loafwallet/ResolutionModel.swift diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 4313cdd44..b75dc0493 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -283,7 +283,6 @@ C354C4632590059500675E0E /* TransactionsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C354C4622590059500675E0E /* TransactionsViewModel.swift */; }; C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD222574070A002BB9BB /* PartnersView.swift */; }; C35ABD332574073F002BB9BB /* PartnersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD322574073F002BB9BB /* PartnersViewModel.swift */; }; - C35ABD4325741E19002BB9BB /* ResolutionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD4225741E19002BB9BB /* ResolutionModel.swift */; }; C379F228259B9BF000B25883 /* RegistrationAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C379F227259B9BF000B25883 /* RegistrationAlertView.swift */; }; C3A4647D259A646A00D74D81 /* DataValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A4647C259A646A00D74D81 /* DataValidation.swift */; }; C3B7C3B9255EABBF00E98A64 /* SupportSafariViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */; }; @@ -1457,7 +1456,6 @@ C354C4622590059500675E0E /* TransactionsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsViewModel.swift; sourceTree = ""; }; C35ABD222574070A002BB9BB /* PartnersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersView.swift; sourceTree = ""; }; C35ABD322574073F002BB9BB /* PartnersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersViewModel.swift; sourceTree = ""; }; - C35ABD4225741E19002BB9BB /* ResolutionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResolutionModel.swift; sourceTree = ""; }; C379F227259B9BF000B25883 /* RegistrationAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationAlertView.swift; sourceTree = ""; }; C3A4647C259A646A00D74D81 /* DataValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataValidation.swift; sourceTree = ""; }; C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportSafariViewModel.swift; sourceTree = ""; }; @@ -3129,7 +3127,6 @@ isa = PBXGroup; children = ( C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */, - C35ABD4225741E19002BB9BB /* ResolutionModel.swift */, C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */, ); name = Unstoppable; @@ -4155,7 +4152,6 @@ 24306797238F3DF900EBEA99 /* BartyCrouch.swift in Sources */, C3D783B72565EA6B0004FF70 /* UnstoppableDomainViewModel.swift in Sources */, CEC6AA3B1DEE4EB000EE5AFD /* CGRect+Additions.swift in Sources */, - C35ABD4325741E19002BB9BB /* ResolutionModel.swift in Sources */, CE45C1FB1E74F89C002C3847 /* WalletInfo.swift in Sources */, CEE659E71F65A936001FF29D /* RetryTimer.swift in Sources */, 248BFE2623AB302200CE1A71 /* BuyWKWebViewController.swift in Sources */, diff --git a/loafwallet/ResolutionModel.swift b/loafwallet/ResolutionModel.swift deleted file mode 100644 index e4a7f409c..000000000 --- a/loafwallet/ResolutionModel.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// ResolutionModel.swift -// loafwallet -// -// Created by Kerry Washington on 11/29/20. -// Copyright © 2020 Litecoin Foundation. All rights reserved. -// - -import Foundation -import UnstoppableDomainsResolution - -class ResolutionModel: NSObject { - - static let shared = ResolutionModel() - - var resolution: Resolution? - - override init() { - super.init() - - if let path = Bundle.main.path(forResource: "partner-keys", ofType: "plist"), - let dictionary = NSDictionary(contentsOfFile:path) as? Dictionary, - let key = dictionary["infura"] as? String { - let keypath = "https://mainnet.infura.io/v3/" + key - - do { - guard let resolution = try? Resolution(providerUrl: keypath, network: "mainnet") else { - print ("Init of Resolution instance with custom parameters failed...") - return - } - self.resolution = resolution - - } catch { - print("Unstoppable Domains Error: \(String(describing: self.resolution))") - } - } - } -} diff --git a/loafwallet/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index 40956edfe..3c6fda719 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -40,8 +40,8 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel private var regularConstraints: [NSLayoutConstraint] = [] private var swappedConstraints: [NSLayoutConstraint] = [] private let currencyTapView = UIView() - private let storyboardNames:[String] = ["Transactions","Send","Card","Receive","Buy"] - var storyboardIDs:[String] = ["TransactionsViewController","SendLTCViewController","CardViewController","ReceiveLTCViewController","BuyTableViewController"] + private let storyboardNames:[String] = ["Transactions","Send","Receive","Buy"] + var storyboardIDs:[String] = ["TransactionsViewController","SendLTCViewController","ReceiveLTCViewController","BuyTableViewController"] var viewControllers:[UIViewController] = [] var activeController:UIViewController? = nil diff --git a/loafwallet/UnstoppableDomainView.swift b/loafwallet/UnstoppableDomainView.swift index aaec969be..d85b55c22 100644 --- a/loafwallet/UnstoppableDomainView.swift +++ b/loafwallet/UnstoppableDomainView.swift @@ -80,7 +80,6 @@ struct UnstoppableDomainView: View { // Description: the minmum domain length is 4 e.g.; 'a.zil' // Enabling the button until the domain string is at least 4 chars long - shouldDisableLookupButton = currentString.count < 4 }) diff --git a/loafwallet/UnstoppableDomainViewModel.swift b/loafwallet/UnstoppableDomainViewModel.swift index f442544da..8bd896333 100644 --- a/loafwallet/UnstoppableDomainViewModel.swift +++ b/loafwallet/UnstoppableDomainViewModel.swift @@ -10,27 +10,27 @@ import Foundation import SwiftUI import Combine import UnstoppableDomainsResolution - + class UnstoppableDomainViewModel: ObservableObject { //MARK: - Combine Variables @Published var searchString: String = "" - + @Published var placeholderString: String = S.Send.UnstoppableDomains.placeholder @Published var isDomainResolving: Bool = false - + //MARK: - Public Variables var didResolveUDAddress: ((String) -> Void)? - + var shouldClearAddressField: (() -> Void)? //MARK: - Private Variables private var ltcAddress = "" - + private var dateFormatter: DateFormatter? { didSet { @@ -39,12 +39,7 @@ class UnstoppableDomainViewModel: ObservableObject { } } - init() { - - //Triggers 'failed' RPC connection - _ = ResolutionModel.shared.resolution - - } + init() { } func resolveDomain() { @@ -55,57 +50,86 @@ class UnstoppableDomainViewModel: ObservableObject { // Added timing peroformance probes to see what the average time is let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" - + LWAnalytics.logEventWithParameters(itemName: CustomEvent._20201121_SIL, properties: ["start_time": timestamp]) self.resolveUDAddress(domainName: searchString) - - ///Fallback resolution: Set in case it takes a longer time to resolve. - DispatchQueue.main.asyncAfter(deadline: .now() + 5) { - self.didResolveUDAddress?(self.ltcAddress) - self.isDomainResolving = false - } } private func resolveUDAddress(domainName: String) { - ResolutionModel - .shared - .resolution?.addr(domain: domainName, ticker: "ltc") { result in + // This group is created to allow the threads to complete. + // Otherwise, we may never get in the callback relative to UDR v0.1.6 + let group = DispatchGroup() + + guard let keyPath = fetchKeyPath() else { + print ("Error: Key path not found") + return + } + + guard let resolution = try? Resolution(providerUrl: keyPath, network: "mainnet") else { + print ("Error: Init of Resolution instance with custom parameters failed...") + return + } + + group.enter() + + resolution.addr(domain: domainName, ticker: "ltc") { result in + + switch result { + case .success(let returnValue): - switch result { - case .success(let returnValue): - - let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" - - LWAnalytics.logEventWithParameters(itemName: - CustomEvent._20201121_DRIA, - properties: - ["success_time": timestamp]) - - ///Quicker resolution: When the resolution is done, the activity indicatior stops and the address is updated - DispatchQueue.main.async { - self.ltcAddress = returnValue - self.didResolveUDAddress?(self.ltcAddress) - self.isDomainResolving = false - } - - case .failure(let error): - - let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" - - LWAnalytics.logEventWithParameters(itemName: - CustomEvent._20201121_FRIA, - properties: - ["failure_time": timestamp, - "error":error.localizedDescription]) - - print("Expected LTC Address, but got \(error.localizedDescription)") - + let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" + + LWAnalytics.logEventWithParameters(itemName: + CustomEvent._20201121_DRIA, + properties: + ["success_time": timestamp]) + + ///Quicker resolution: When the resolution is done, the activity indicatior stops and the address is updated + DispatchQueue.main.async { + self.ltcAddress = returnValue + self.didResolveUDAddress?(self.ltcAddress) + self.isDomainResolving = false } - } + + case .failure(let error): + + let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" + + LWAnalytics.logEventWithParameters(itemName: + CustomEvent._20201121_FRIA, + properties: + ["failure_time": timestamp, + "error":error.localizedDescription]) + + ///Quicker resolution: When the resolution is done, the activity indicatior stops and the address is updated + DispatchQueue.main.asyncAfter(deadline: .now() + 3, + execute: { + print("Expected LTC Address, but got \(error.localizedDescription)") + + self.isDomainResolving = false + + }) + } + group.leave() } + group.wait() + } + + /// Lookup the API Key + /// - Returns: String or nil + private func fetchKeyPath() -> String? { + + if let path = Bundle.main.path(forResource: "partner-keys", ofType: "plist"), + let dictionary = NSDictionary(contentsOfFile:path) as? Dictionary, + let key = dictionary["infura-api"] as? String { + return "https://mainnet.infura.io/v3/" + key + } else { + return nil + } + } } diff --git a/loafwallet/src/Views/SendViewCells/AddressCell.swift b/loafwallet/src/Views/SendViewCells/AddressCell.swift index 38205ea8d..52920b7c7 100644 --- a/loafwallet/src/Views/SendViewCells/AddressCell.swift +++ b/loafwallet/src/Views/SendViewCells/AddressCell.swift @@ -36,7 +36,7 @@ class AddressCell : UIView { let textField = UITextField() let paste = ShadowButton(title: S.Send.pasteLabel, type: .tertiary) let scan = ShadowButton(title: S.Send.scanLabel, type: .tertiary) - fileprivate var contentLabel = UILabel(font: .customBody(size: 12.0), color: .darkText) + fileprivate var contentLabel = UILabel(font: .customBody(size: 13.0), color: .darkText) private var label = UILabel(font: .customBody(size: 16.0)) fileprivate let gr = UITapGestureRecognizer() fileprivate let tapView = UIView() @@ -103,6 +103,8 @@ class AddressCell : UIView { private func setInitialData() { label.text = S.Send.enterLTCAddressLabel textField.font = contentLabel.font + textField.adjustsFontSizeToFitWidth = true + textField.minimumFontSize = 10.0 textField.textColor = contentLabel.textColor textField.isHidden = true textField.returnKeyType = .done From fece939f64426d4e122268eeec47e40ec4b4637f Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Fri, 15 Jan 2021 22:38:47 +0000 Subject: [PATCH 028/114] [Merge into Develop] Release v3.1.1 (#195) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Merge v3.0.0] into Master (#183) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release] Merge v2.8.2 into Develop (#158) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry * [Bugfix] Replace the LF Support View (#159) * Moved the LF Cell from Send. - BartyCrouch linted the stigns files. * Updated the LF Support location - Reset the localiaztion language to ‘Customer support’ - Add the dismissal actions * [Bugfix] Fix buy tab: Simplex urls (#157) * Updated the url to new servers * Linted the Localized strings * Setup url constants * updated pk file status * Updated per PR review comments * fixed naming of the url variable * [Merge v2.8.3] into Develop (#169) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Master (#153) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * version bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [Feature Issue 154] Adding Unstoppable Domains functionality (#155) * Added UD to Podfile - Stubbed out the view, viewModel and the test class for UD * [UI Polish] Added images and localized strings - Added more of strings and UD structure - Trimmed images to resize for button - Added localized strings for placeholder * Updated UnstoppableDomainsView and Model details - Added DEV notes script - Adjusted Previews by unchecking the `build install only` * Added more tests - UnstoppableDomains View Model tests - SupportLitecoinFoundationViewModel tests * reformatted code in new SwiftUI views and viewModels * Added UD action to the SendViewController * Updated project * Updated localized UD Placeholder * Setup API keys * removed pk file * Changed the localizations related to UD - Added ‘Or’ label - Added UD placeholder text - Changed the LTC address placeholder text * Added in the Or and relayout of the button - Added Partner layout view for UD and Simplex * Resolved code review comments - Update the localizations - Refactored the UD shared instance (singleton) to retain throguh the call - Added timing probes * revert to current version * reformatted the Support LF view strings * Remove Test Playground. * Removed unused SocialView and ViewModel * Improved resolution - Added a Dispatch and ‘exit’ when address is found sooner than 12 secs. Much better experience for the user. * Added infura * Resolved review comments * Rewrote copy for “Enter a Litecoin address” * Fix some trivial conflict markers (#177) * [Bugfix] Upgrade the business logic for Unstoppable Domains (#179) * Fix some triival conflict markers * Added test to button once the UD string meets a minimum length * Clears address text field when Lookup button is pressed * Set the background color of the AlertToast * Locailization of the alert language * move logic to release the first responder * per review notes * [Feature] Litecoin card v1 (#180) * [Litecoin Card] Progress Step 1 - Major work: litecoin-card TabBarView refactor - Updated UIColor for Color - SwiftUI preview devices - Working out the Nav polish - Fixed hard-coded UD lookup label with proper localizations - Commented out BitId * [Litecoin Card] Progress Step 2 - Added more localizations - Rebuilding registration view need to add keyboard - Fixed the animation for the card view - Fixed Alert name collisions to the SimplexAlert * [Litecoin Card] Progress Step 3 - Added Login views and localizations - Added partnerAPI Swift Package - Layout the registration view - Add more localizations - BUGFIX: Image missing in this branch. * [Litecoin Card] Progress Step 4 More localizations Added data Validators Final Polish for Registration View Registration View Modal wiring works * [Litecoin Card] Progress Step 5 Register works to the model Login is working Added animation for Login/Logout Login and Loogut working Added localizations More localizations * [Litecoin Card] RC 1 polishes Communcations polishing + dev cleanup Polishing the RegistrationView layout Fixed bug: https://github.com/litecoin-foundation/loafwallet-ios/issues/175 * [Litecoin Card] RC2: removed defunct script * per review comments - Ar files removal - Cleanup localizable - Removed Ar.proj files - Removed empty class - Added all Validation localization framework - Added localizations of the validations - Refactored per review notes * Bugfix- login message Added failure message localizations * version bump * Added some tests * Refactored the login logic - Used the status of the binding to change the UI * Added combined logic of the email and password fields to enable login button Reference @losh11 comment: `The cards login now gives a good login failed alert. However I think the login button should be disabled until the text in the email input is validated as email format.` * build bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [HOTFIX] Hide Card Tab (#191) * Hide Card Tab * added comments for v1 * version bump * -build bump - polished cruft - clean package Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov --- loafwallet.xcodeproj/project.pbxproj | 141 ++++++++++---------- loafwallet/UnstoppableDomainView.swift | 2 +- loafwallet/UnstoppableDomainViewModel.swift | 8 +- 3 files changed, 76 insertions(+), 75 deletions(-) diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index b75dc0493..2caaa0a24 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 1991125B1B86B90CA24B7286 /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */; }; 1B3F74231FFB106200CCA50C /* BiometricsSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74211FFB106200CCA50C /* BiometricsSettingsViewController.swift */; }; 1B3F74241FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74221FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift */; }; 1BA9FE3D216F68A700BB2DE8 /* BRBech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BA9FE3C216F68A700BB2DE8 /* BRBech32.c */; }; @@ -266,7 +267,7 @@ 75A2A8101DA5936F00A983D8 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75A2A80E1DA5936F00A983D8 /* MainInterface.storyboard */; }; 75A2A8141DA5936F00A983D8 /* TodayExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 75A2A8081DA5936F00A983D8 /* TodayExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 75C735AA1DAA1B9C00251ECF /* libunbound.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD4121DAA0E3E0075898E /* libunbound.c */; }; - BB66CB271F7F2FD1936AA04B /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FEAAB89A265CC043F53CC51 /* Pods_loafwalletTests.framework */; }; + 8BFF92CC86553A47974D867D /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B994E2162ECCFE0BB90CC714 /* Pods_loafwalletTests.framework */; }; C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */ = {isa = PBXBuildFile; productRef = C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */; }; C30AFB642598FFB200CDCF69 /* PartnerAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */; }; C3270B99259BF7F20073DA7B /* LitecoinCardUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */; }; @@ -456,7 +457,6 @@ CEF61B121ECF52C700C7EA6A /* AmountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF61B111ECF52C700C7EA6A /* AmountViewController.swift */; }; CEF61B141ED0D10000C7EA6A /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF61B131ED0D10000C7EA6A /* Types.swift */; }; CEF61B161ED2056D00C7EA6A /* NumberFormatter+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF61B151ED2056D00C7EA6A /* NumberFormatter+Additions.swift */; }; - DC03CB1EE9228BC37FA36F54 /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4241321F8719503196989C34 /* Pods_loafwallet.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -572,7 +572,6 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 012F76A05D15F227D7C3EF9A /* Pods-loafwallet.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.testnet.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.testnet.xcconfig"; sourceTree = ""; }; 1B3F74211FFB106200CCA50C /* BiometricsSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BiometricsSettingsViewController.swift; path = src/ViewControllers/BiometricsSettingsViewController.swift; sourceTree = ""; }; 1B3F74221FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BiometricsSpendingLimitViewController.swift; path = src/ViewControllers/BiometricsSpendingLimitViewController.swift; sourceTree = ""; }; 1BA74B85206AD60A0083BD2A /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = ""; }; @@ -835,9 +834,10 @@ 24D91D0A2166923E0077A619 /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; }; 24D91D0D2166A5480077A619 /* TestnetData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestnetData.swift; sourceTree = ""; }; 24DFCE6723B89CDE001F17F8 /* Settings.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; }; - 4241321F8719503196989C34 /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5551B367195CB66F70E7147C /* Pods-loafwalletTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.release.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.release.xcconfig"; sourceTree = ""; }; - 6FEAAB89A265CC043F53CC51 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 40524F4C990EE3717AE4D70C /* Pods-loafwallet.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.testnet.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.testnet.xcconfig"; sourceTree = ""; }; + 72359B62E9336B8B8C58C7B3 /* Pods-loafwalletTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.release.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.release.xcconfig"; sourceTree = ""; }; + 743B301179ED3019FA9E6247 /* Pods-loafwallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.release.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.release.xcconfig"; sourceTree = ""; }; 7503773C1DF57428005EB8AE /* WalletManager+Auth.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "WalletManager+Auth.swift"; path = "src/WalletManager+Auth.swift"; sourceTree = ""; }; 7528D2971ECF655500925DBC /* PaymentProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PaymentProtocol.swift; path = src/PaymentProtocol.swift; sourceTree = ""; }; 752FB03B1DF8BE4B009086FB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1437,10 +1437,10 @@ 75A2A87C1DA59E4E00A983D8 /* loafwallet.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = loafwallet.entitlements; sourceTree = ""; }; 75C735AF1DAA1C9F00251ECF /* libnettle.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libnettle.a; sourceTree = BUILT_PRODUCTS_DIR; }; 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; - 91361B2DF7CFBF96F66DE835 /* Pods-loafwalletTests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.testnet.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.testnet.xcconfig"; sourceTree = ""; }; - 93035AB774472BF9805FD3F9 /* Pods-loafwallet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.debug.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.debug.xcconfig"; sourceTree = ""; }; - 9AA160F2A4C1674AC8595E65 /* Pods-loafwalletTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.debug.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.debug.xcconfig"; sourceTree = ""; }; - 9C4905F581557D8FD607EB73 /* Pods-loafwallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.release.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.release.xcconfig"; sourceTree = ""; }; + A1C0235D73D79DA3FB4FFDF7 /* Pods-loafwalletTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.debug.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.debug.xcconfig"; sourceTree = ""; }; + ADB3C165455573400E04EC13 /* Pods-loafwalletTests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.testnet.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.testnet.xcconfig"; sourceTree = ""; }; + B994E2162ECCFE0BB90CC714 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C2728A44EB43C7CCAA987B89 /* Pods-loafwallet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.debug.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.debug.xcconfig"; sourceTree = ""; }; C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnerAPIManager.swift; sourceTree = ""; }; C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LitecoinCardUser.swift; sourceTree = ""; }; C32DAE0625925B7E003FC978 /* Color+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = ""; }; @@ -1665,7 +1665,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BB66CB271F7F2FD1936AA04B /* Pods_loafwalletTests.framework in Frameworks */, + 8BFF92CC86553A47974D867D /* Pods_loafwalletTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1705,7 +1705,7 @@ C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */, 752FB04D1DF8BF4B009086FB /* sqlite3.framework in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, - DC03CB1EE9228BC37FA36F54 /* Pods_loafwallet.framework in Frameworks */, + 1991125B1B86B90CA24B7286 /* Pods_loafwallet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3023,8 +3023,8 @@ 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */, 75A2A7F21DA5935F00A983D8 /* Messages.framework */, 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */, - 4241321F8719503196989C34 /* Pods_loafwallet.framework */, - 6FEAAB89A265CC043F53CC51 /* Pods_loafwalletTests.framework */, + 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */, + B994E2162ECCFE0BB90CC714 /* Pods_loafwalletTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -3488,12 +3488,12 @@ FEE036865998B9DFEEF3139A /* Pods */ = { isa = PBXGroup; children = ( - 93035AB774472BF9805FD3F9 /* Pods-loafwallet.debug.xcconfig */, - 012F76A05D15F227D7C3EF9A /* Pods-loafwallet.testnet.xcconfig */, - 9C4905F581557D8FD607EB73 /* Pods-loafwallet.release.xcconfig */, - 9AA160F2A4C1674AC8595E65 /* Pods-loafwalletTests.debug.xcconfig */, - 91361B2DF7CFBF96F66DE835 /* Pods-loafwalletTests.testnet.xcconfig */, - 5551B367195CB66F70E7147C /* Pods-loafwalletTests.release.xcconfig */, + C2728A44EB43C7CCAA987B89 /* Pods-loafwallet.debug.xcconfig */, + 40524F4C990EE3717AE4D70C /* Pods-loafwallet.testnet.xcconfig */, + 743B301179ED3019FA9E6247 /* Pods-loafwallet.release.xcconfig */, + A1C0235D73D79DA3FB4FFDF7 /* Pods-loafwalletTests.debug.xcconfig */, + ADB3C165455573400E04EC13 /* Pods-loafwalletTests.testnet.xcconfig */, + 72359B62E9336B8B8C58C7B3 /* Pods-loafwalletTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -3557,7 +3557,7 @@ isa = PBXNativeTarget; buildConfigurationList = 2465873D23A5AAD100A32E9E /* Build configuration list for PBXNativeTarget "loafwalletTests" */; buildPhases = ( - ABD5154B4DB399A4A81559CD /* [CP] Check Pods Manifest.lock */, + 539F95D1D2880CDB55F16CD2 /* [CP] Check Pods Manifest.lock */, 2465873223A5AAD000A32E9E /* Sources */, 2465873323A5AAD000A32E9E /* Frameworks */, 2465873423A5AAD000A32E9E /* Resources */, @@ -3630,7 +3630,7 @@ isa = PBXNativeTarget; buildConfigurationList = 75A2A7E31DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet" */; buildPhases = ( - 156E4E7F04DB5E000B3A1A91 /* [CP] Check Pods Manifest.lock */, + 421B6524385300316FBCCDF8 /* [CP] Check Pods Manifest.lock */, 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */, 24E179F223BDAF8000F928D9 /* Xcode custom warnings */, 75A2A78C1DA5934300A983D8 /* Sources */, @@ -3638,8 +3638,8 @@ 75A2A78E1DA5934300A983D8 /* Resources */, 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, - 8B664BEE6304C1815A957FC6 /* [CP] Embed Pods Frameworks */, C3D1588125666B69009BD3BC /* Mark Dev Notes */, + CB23F16DD689CE4EDFBEB417 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -3874,28 +3874,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 156E4E7F04DB5E000B3A1A91 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 12; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwallet-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 12; @@ -3928,24 +3906,29 @@ shellPath = /bin/sh; shellScript = "TAGS=\"TODO:|FIXME:|WARNING:\"\nfind \"${SRCROOT}\" \\( -name \"*.h\" -or -name \"*.m\" -or -name \"*.swift\" \\) -print0 | xargs -0 egrep --with-filename --line-number --only-matching \"($TAGS).*\\$\" | perl -p -e \"s/($TAGS)/ warning: \\$1/\"\n"; }; - 8B664BEE6304C1815A957FC6 /* [CP] Embed Pods Frameworks */ = { + 421B6524385300316FBCCDF8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 12; + buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-loafwallet-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - ABD5154B4DB399A4A81559CD /* [CP] Check Pods Manifest.lock */ = { + 539F95D1D2880CDB55F16CD2 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3965,6 +3948,7 @@ runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; C3D1588125666B69009BD3BC /* Mark Dev Notes */ = { isa = PBXShellScriptBuildPhase; @@ -3984,6 +3968,23 @@ shellPath = /bin/sh; shellScript = "# http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos\necho \"make-xcode-nag-you-about-unfinished-todos for swift files only\"\nKEYWORDS=\"DEV|TODO|FIXME|\\?\\?\\?:|\\!\\!\\!:\"\nfind \"${SRCROOT}\" \\( -name \"*.swift\" \\) -print0 | \\\nxargs -0 egrep --with-filename --line-number --only-matching \"($KEYWORDS).*\\$\" | \\\nperl -p -e \"s/($KEYWORDS)/ warning: \\$1/\"\n\n\n"; }; + CB23F16DD689CE4EDFBEB417 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -4664,12 +4665,12 @@ }; 24470E0123A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 93035AB774472BF9805FD3F9 /* Pods-loafwallet.debug.xcconfig */; + baseConfigurationReference = C2728A44EB43C7CCAA987B89 /* Pods-loafwallet.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4683,7 +4684,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.1.1; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4697,7 +4698,7 @@ }; 24470E0323A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9AA160F2A4C1674AC8595E65 /* Pods-loafwalletTests.debug.xcconfig */; + baseConfigurationReference = A1C0235D73D79DA3FB4FFDF7 /* Pods-loafwalletTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -4776,7 +4777,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4786,7 +4787,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.1.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4905,7 +4906,7 @@ }; 2465873F23A5AAD100A32E9E /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 91361B2DF7CFBF96F66DE835 /* Pods-loafwalletTests.testnet.xcconfig */; + baseConfigurationReference = ADB3C165455573400E04EC13 /* Pods-loafwalletTests.testnet.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -4933,7 +4934,7 @@ }; 2465874023A5AAD100A32E9E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5551B367195CB66F70E7147C /* Pods-loafwalletTests.release.xcconfig */; + baseConfigurationReference = 72359B62E9336B8B8C58C7B3 /* Pods-loafwalletTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -5081,12 +5082,12 @@ }; 75A2A7E51DA5934400A983D8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9C4905F581557D8FD607EB73 /* Pods-loafwallet.release.xcconfig */; + baseConfigurationReference = 743B301179ED3019FA9E6247 /* Pods-loafwallet.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5099,7 +5100,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.1.1; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5116,7 +5117,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5125,7 +5126,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.1.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5211,12 +5212,12 @@ }; CEA7E69C1F0AAA84001F8C27 /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 012F76A05D15F227D7C3EF9A /* Pods-loafwallet.testnet.xcconfig */; + baseConfigurationReference = 40524F4C990EE3717AE4D70C /* Pods-loafwallet.testnet.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5230,7 +5231,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.1.1; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5248,7 +5249,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5258,7 +5259,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.1.1; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/loafwallet/UnstoppableDomainView.swift b/loafwallet/UnstoppableDomainView.swift index d85b55c22..0993a900d 100644 --- a/loafwallet/UnstoppableDomainView.swift +++ b/loafwallet/UnstoppableDomainView.swift @@ -79,7 +79,7 @@ struct UnstoppableDomainView: View { }.onReceive(viewModel.$searchString, perform: { currentString in // Description: the minmum domain length is 4 e.g.; 'a.zil' - // Enabling the button until the domain string is at least 4 chars long + // Enabling the button until the domain string is at least 4 chars long shouldDisableLookupButton = currentString.count < 4 }) diff --git a/loafwallet/UnstoppableDomainViewModel.swift b/loafwallet/UnstoppableDomainViewModel.swift index 8bd896333..f129dbae7 100644 --- a/loafwallet/UnstoppableDomainViewModel.swift +++ b/loafwallet/UnstoppableDomainViewModel.swift @@ -25,12 +25,12 @@ class UnstoppableDomainViewModel: ObservableObject { //MARK: - Public Variables var didResolveUDAddress: ((String) -> Void)? - + var shouldClearAddressField: (() -> Void)? //MARK: - Private Variables - private var ltcAddress = "" - + private var ltcAddress = "" + private var dateFormatter: DateFormatter? { didSet { @@ -56,7 +56,7 @@ class UnstoppableDomainViewModel: ObservableObject { properties: ["start_time": timestamp]) - self.resolveUDAddress(domainName: searchString) + self.resolveUDAddress(domainName: searchString) } private func resolveUDAddress(domainName: String) { From d07544db9e04af4b2a331bc2ecd4430a415b4872 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 19 Jan 2021 20:56:07 +0000 Subject: [PATCH 029/114] Update issue templates (#127) * Update issue templates * Update bug_report.md * Update feature_request.md Update with Litewallet data --- .github/ISSUE_TEMPLATE/bug_report.md | 35 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 27 +++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..e225bde25 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report - Litewallet iOS +about: Create a report to help us improve Litewallet +title: 'Bug - Litewallet iOS' +labels: 'bug' +assignees: 'kcw-grunt' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Litewallet Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..5768c576f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,27 @@ +--- +name: Litewallet iOS Feature request +about: Suggest an idea for Litewallet +title: 'Litewallet Feature' +labels: 'enhancement' +assignees: 'kcw-grunt' + +--- +**Value of feature** +Add the bid of value of the work + +|**Feature Name**|**Value(Ł)**| +|----------------|------------| +|For example: Add glitter|20Ł| +||| + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 599704056939ee44fe26f6717eade325d96df865 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 20 Jan 2021 11:18:23 +0000 Subject: [PATCH 030/114] [Tech Debt] Update readme.md (#174) * update readme.md * per review notes --- pages/development.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 pages/development.md diff --git a/pages/development.md b/pages/development.md new file mode 100644 index 000000000..24a089af8 --- /dev/null +++ b/pages/development.md @@ -0,0 +1,30 @@ +## Development +This page outlines the steps to making changes to the code base. +____ + +### Release Process +The following outlines the steps for releasing a version. + +#### Step A +1. When the develop branch has the features, changes as decided a draft of a release tag should be begun: [releases page](https://github.com/litecoin-foundation/loafwallet-ios/releases) + +2. From the develop branch, a new branch needs to be created in the semver method (v#.#.#) e.g.; `release/v2.9.0` + +3. Final testing and changes are committed to the branch. When ready, a build is created and sent to the App Store. The build should been set to the TestFlight and encourage testers....wait. + +4. Once the build is approved, a PR to merge the `release/v2.9.0` into `master` is pushed to Github. + +5. Once approved, it's merged. + + +#### Step B +6. A new PR from the `release/v2.9.0` to `develop` is created + +7. The resolution of conflicts is completed + +8. Once approved, it's merged. + + + + +--- \ No newline at end of file From a39f6d7c142c80b64884ca92ce03057ac0fcfb90 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 20 Jan 2021 11:27:15 +0000 Subject: [PATCH 031/114] Clean up the cocoapod installation (#196) - Remove Firebase pod - Added Firebase Swift package - Removed some old dead code --- Gemfile | 2 - Gemfile.lock | 159 ------------------ Podfile | 2 - fastlane/Appfile | 7 - fastlane/Fastfile | 74 -------- loafwallet.xcodeproj/project.pbxproj | 132 ++++++++++----- .../xcschemes/loafwallet.xcscheme | 6 + .../xcshareddata/swiftpm/Package.resolved | 72 ++++++++ 8 files changed, 168 insertions(+), 286 deletions(-) delete mode 100644 Gemfile delete mode 100644 Gemfile.lock delete mode 100644 fastlane/Appfile delete mode 100644 fastlane/Fastfile diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 6a6bdf9c3..000000000 --- a/Gemfile +++ /dev/null @@ -1,2 +0,0 @@ -source "https://rubygems.org" -gem "bundle exec fastlane scan" diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 5b26b3f75..000000000 --- a/Gemfile.lock +++ /dev/null @@ -1,159 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - CFPropertyList (3.0.2) - addressable (2.7.0) - public_suffix (>= 2.0.2, < 5.0) - atomos (0.1.3) - babosa (1.0.3) - claide (1.0.3) - colored (1.2) - colored2 (3.1.2) - commander-fastlane (4.4.6) - highline (~> 1.7.2) - declarative (0.0.10) - declarative-option (0.1.0) - digest-crc (0.4.1) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.5) - emoji_regex (1.0.1) - excon (0.71.1) - faraday (0.17.1) - multipart-post (>= 1.2, < 3) - faraday-cookie_jar (0.0.6) - faraday (>= 0.7.4) - http-cookie (~> 1.0.0) - faraday_middleware (0.13.1) - faraday (>= 0.7.4, < 1.0) - fastimage (2.1.7) - fastlane (2.139.0) - CFPropertyList (>= 2.3, < 4.0.0) - addressable (>= 2.3, < 3.0.0) - babosa (>= 1.0.2, < 2.0.0) - bundler (>= 1.12.0, < 3.0.0) - colored - commander-fastlane (>= 4.4.6, < 5.0.0) - dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 2.0) - excon (>= 0.71.0, < 1.0.0) - faraday (~> 0.17) - faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 0.13.1) - fastimage (>= 2.1.0, < 3.0.0) - gh_inspector (>= 1.1.2, < 2.0.0) - google-api-client (>= 0.29.2, < 0.37.0) - google-cloud-storage (>= 1.15.0, < 2.0.0) - highline (>= 1.7.2, < 2.0.0) - json (< 3.0.0) - jwt (~> 2.1.0) - mini_magick (>= 4.9.4, < 5.0.0) - multi_xml (~> 0.5) - multipart-post (~> 2.0.0) - plist (>= 3.1.0, < 4.0.0) - public_suffix (~> 2.0.0) - rubyzip (>= 1.3.0, < 2.0.0) - security (= 0.1.3) - simctl (~> 1.6.3) - slack-notifier (>= 2.0.0, < 3.0.0) - terminal-notifier (>= 2.0.0, < 3.0.0) - terminal-table (>= 1.4.5, < 2.0.0) - tty-screen (>= 0.6.3, < 1.0.0) - tty-spinner (>= 0.8.0, < 1.0.0) - word_wrap (~> 1.0.0) - xcodeproj (>= 1.13.0, < 2.0.0) - xcpretty (~> 0.3.0) - xcpretty-travis-formatter (>= 0.0.3) - gh_inspector (1.1.3) - google-api-client (0.36.3) - addressable (~> 2.5, >= 2.5.1) - googleauth (~> 0.9) - httpclient (>= 2.8.1, < 3.0) - mini_mime (~> 1.0) - representable (~> 3.0) - retriable (>= 2.0, < 4.0) - signet (~> 0.12) - google-cloud-core (1.4.1) - google-cloud-env (~> 1.0) - google-cloud-env (1.3.0) - faraday (~> 0.11) - google-cloud-storage (1.25.0) - addressable (~> 2.5) - digest-crc (~> 0.4) - google-api-client (~> 0.33) - google-cloud-core (~> 1.2) - googleauth (~> 0.9) - mini_mime (~> 1.0) - googleauth (0.10.0) - faraday (~> 0.12) - jwt (>= 1.4, < 3.0) - memoist (~> 0.16) - multi_json (~> 1.11) - os (>= 0.9, < 2.0) - signet (~> 0.12) - highline (1.7.10) - http-cookie (1.0.3) - domain_name (~> 0.5) - httpclient (2.8.3) - json (2.3.0) - jwt (2.1.0) - memoist (0.16.2) - mini_magick (4.9.5) - mini_mime (1.0.2) - multi_json (1.14.1) - multi_xml (0.6.0) - multipart-post (2.0.0) - nanaimo (0.2.6) - naturally (2.2.0) - os (1.0.1) - plist (3.5.0) - public_suffix (2.0.5) - representable (3.0.4) - declarative (< 0.1.0) - declarative-option (< 0.2.0) - uber (< 0.2.0) - retriable (3.1.2) - rouge (2.0.7) - rubyzip (1.3.0) - security (0.1.3) - signet (0.12.0) - addressable (~> 2.3) - faraday (~> 0.9) - jwt (>= 1.5, < 3.0) - multi_json (~> 1.10) - simctl (1.6.7) - CFPropertyList - naturally - slack-notifier (2.3.2) - terminal-notifier (2.0.0) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - tty-cursor (0.7.0) - tty-screen (0.7.0) - tty-spinner (0.9.2) - tty-cursor (~> 0.7) - uber (0.1.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.7.6) - unicode-display_width (1.6.0) - word_wrap (1.0.0) - xcodeproj (1.14.0) - CFPropertyList (>= 2.3.3, < 4.0) - atomos (~> 0.1.3) - claide (>= 1.0.2, < 2.0) - colored2 (~> 3.1) - nanaimo (~> 0.2.6) - xcpretty (0.3.0) - rouge (~> 2.0.7) - xcpretty-travis-formatter (1.0.0) - xcpretty (~> 0.2, >= 0.0.7) - -PLATFORMS - ruby - -DEPENDENCIES - fastlane - -BUNDLED WITH - 2.1.2 diff --git a/Podfile b/Podfile index d148c1fc1..df2323e8b 100644 --- a/Podfile +++ b/Podfile @@ -7,8 +7,6 @@ platform :ios, '13.0' #Shared Cocopods def shared_pods - pod 'Firebase/Crashlytics' - pod 'Firebase/Analytics' pod 'UnstoppableDomainsResolution', '~> 0.1.6' pod 'KeychainAccess', '~> 4.2' # add after v2.9.0 pod 'SwiftLint' diff --git a/fastlane/Appfile b/fastlane/Appfile deleted file mode 100644 index be80566be..000000000 --- a/fastlane/Appfile +++ /dev/null @@ -1,7 +0,0 @@ -app_identifier "com.litecoin.loafwallet" # The bundle identifier of your app -apple_id "iosagent@litecoinfoundation.net" # Your Apple email address - -team_id "[[DEV_PORTAL_TEAM_ID]]" # Developer Portal Team ID - -# you can even provide different app identifiers, Apple IDs and team names per lane: -# More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md diff --git a/fastlane/Fastfile b/fastlane/Fastfile deleted file mode 100644 index 67c1263e9..000000000 --- a/fastlane/Fastfile +++ /dev/null @@ -1,74 +0,0 @@ -# Customise this file, documentation can be found here: -# https://github.com/fastlane/fastlane/tree/master/fastlane/docs -# All available actions: https://docs.fastlane.tools/actions -# can also be listed using the `fastlane actions` command - -# Change the syntax highlighting to Ruby -# All lines starting with a # are ignored when running `fastlane` - -# If you want to automatically update fastlane if a new version is available: -# update_fastlane - -# This is the minimum version number required. -# Update this, if you use features of a newer version -fastlane_version "2.28.3" - -default_platform :ios - -platform :ios do - before_all do - setup_circle_ci - #ENV["SLACK_URL"] = "https://hooks.slack.com/services/..." - cocoapods - - end - - desc "Runs all the tests" - lane :test do - scan - end - - desc "Submit a new Beta Build to Apple TestFlight" - desc "This will also make sure the profile is up to date" - lane :beta do - # match(type: "appstore") # more information: https://codesigning.guide - gym # Build your app - more options available - pilot - - # sh "your_script.sh" - # You can also use other beta testing services here (run `fastlane actions`) - end - - desc "Deploy a new version to the App Store" - lane :release do - # match(type: "appstore") - # snapshot - gym # Build your app - more options available - deliver(force: true) - # frameit - end - - # You can define as many lanes as you want - - after_all do |lane| - # This block is called, only if the executed lane was successful - - # slack( - # message: "Successfully deployed new App Update." - # ) - end - - error do |lane, exception| - # slack( - # message: exception.message, - # success: false - # ) - end -end - - -# More information about multiple platforms in fastlane: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md -# All available actions: https://docs.fastlane.tools/actions - -# fastlane reports which actions are used -# No personal data is recorded. Learn more at https://github.com/fastlane/enhancer diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 2caaa0a24..2a4a4b1dd 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 1991125B1B86B90CA24B7286 /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */; }; 1B3F74231FFB106200CCA50C /* BiometricsSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74211FFB106200CCA50C /* BiometricsSettingsViewController.swift */; }; 1B3F74241FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74221FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift */; }; 1BA9FE3D216F68A700BB2DE8 /* BRBech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BA9FE3C216F68A700BB2DE8 /* BRBech32.c */; }; @@ -133,6 +132,7 @@ 24D5F26F225A5BEA00225462 /* ContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D5F26D225A5BEA00225462 /* ContainerViewController.swift */; }; 24D91D0B2166923E0077A619 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24D91D0A2166923E0077A619 /* UserNotifications.framework */; }; 24DFCE6823B89CDE001F17F8 /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24DFCE6723B89CDE001F17F8 /* Settings.storyboard */; }; + 74B3E4C4DD12414DD0484B2F /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDAC39ACED69AB0E4CAAEE32 /* Pods_loafwallet.framework */; }; 7503773D1DF57428005EB8AE /* WalletManager+Auth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7503773C1DF57428005EB8AE /* WalletManager+Auth.swift */; }; 751734B91DAC941E00193C87 /* sec-sub-1.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD8BE1DAA16820075898E /* sec-sub-1.c */; }; 752438751DAAC50800844BEC /* alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD6761DAA0E400075898E /* alloc.c */; }; @@ -267,7 +267,7 @@ 75A2A8101DA5936F00A983D8 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75A2A80E1DA5936F00A983D8 /* MainInterface.storyboard */; }; 75A2A8141DA5936F00A983D8 /* TodayExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 75A2A8081DA5936F00A983D8 /* TodayExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 75C735AA1DAA1B9C00251ECF /* libunbound.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD4121DAA0E3E0075898E /* libunbound.c */; }; - 8BFF92CC86553A47974D867D /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B994E2162ECCFE0BB90CC714 /* Pods_loafwalletTests.framework */; }; + 9F277AD526A9DAEC0A5F4008 /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2CCD0579E0855FDF49144D8A /* Pods_loafwalletTests.framework */; }; C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */ = {isa = PBXBuildFile; productRef = C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */; }; C30AFB642598FFB200CDCF69 /* PartnerAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */; }; C3270B99259BF7F20073DA7B /* LitecoinCardUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */; }; @@ -285,6 +285,8 @@ C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD222574070A002BB9BB /* PartnersView.swift */; }; C35ABD332574073F002BB9BB /* PartnersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35ABD322574073F002BB9BB /* PartnersViewModel.swift */; }; C379F228259B9BF000B25883 /* RegistrationAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C379F227259B9BF000B25883 /* RegistrationAlertView.swift */; }; + C38345F725B3393E00E065FD /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = C38345F625B3393E00E065FD /* FirebaseAnalytics */; }; + C38345F925B3393E00E065FD /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = C38345F825B3393E00E065FD /* FirebaseCrashlytics */; }; C3A4647D259A646A00D74D81 /* DataValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A4647C259A646A00D74D81 /* DataValidation.swift */; }; C3B7C3B9255EABBF00E98A64 /* SupportSafariViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */; }; C3B7C3C2255EAF1200E98A64 /* SupportSafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */; }; @@ -572,6 +574,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 140FA787B8C189CDA7E8EA0A /* Pods-loafwalletTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.release.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.release.xcconfig"; sourceTree = ""; }; 1B3F74211FFB106200CCA50C /* BiometricsSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BiometricsSettingsViewController.swift; path = src/ViewControllers/BiometricsSettingsViewController.swift; sourceTree = ""; }; 1B3F74221FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BiometricsSpendingLimitViewController.swift; path = src/ViewControllers/BiometricsSpendingLimitViewController.swift; sourceTree = ""; }; 1BA74B85206AD60A0083BD2A /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = ""; }; @@ -834,10 +837,7 @@ 24D91D0A2166923E0077A619 /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; }; 24D91D0D2166A5480077A619 /* TestnetData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestnetData.swift; sourceTree = ""; }; 24DFCE6723B89CDE001F17F8 /* Settings.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; }; - 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 40524F4C990EE3717AE4D70C /* Pods-loafwallet.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.testnet.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.testnet.xcconfig"; sourceTree = ""; }; - 72359B62E9336B8B8C58C7B3 /* Pods-loafwalletTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.release.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.release.xcconfig"; sourceTree = ""; }; - 743B301179ED3019FA9E6247 /* Pods-loafwallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.release.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.release.xcconfig"; sourceTree = ""; }; + 2CCD0579E0855FDF49144D8A /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7503773C1DF57428005EB8AE /* WalletManager+Auth.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "WalletManager+Auth.swift"; path = "src/WalletManager+Auth.swift"; sourceTree = ""; }; 7528D2971ECF655500925DBC /* PaymentProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PaymentProtocol.swift; path = src/PaymentProtocol.swift; sourceTree = ""; }; 752FB03B1DF8BE4B009086FB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1437,10 +1437,8 @@ 75A2A87C1DA59E4E00A983D8 /* loafwallet.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = loafwallet.entitlements; sourceTree = ""; }; 75C735AF1DAA1C9F00251ECF /* libnettle.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libnettle.a; sourceTree = BUILT_PRODUCTS_DIR; }; 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; - A1C0235D73D79DA3FB4FFDF7 /* Pods-loafwalletTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.debug.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.debug.xcconfig"; sourceTree = ""; }; - ADB3C165455573400E04EC13 /* Pods-loafwalletTests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.testnet.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.testnet.xcconfig"; sourceTree = ""; }; - B994E2162ECCFE0BB90CC714 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C2728A44EB43C7CCAA987B89 /* Pods-loafwallet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.debug.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.debug.xcconfig"; sourceTree = ""; }; + 80008B6D966315A287287C5F /* Pods-loafwalletTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.debug.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.debug.xcconfig"; sourceTree = ""; }; + 82B54D9BA6CCD590F3B15E32 /* Pods-loafwallet.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.testnet.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.testnet.xcconfig"; sourceTree = ""; }; C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnerAPIManager.swift; sourceTree = ""; }; C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LitecoinCardUser.swift; sourceTree = ""; }; C32DAE0625925B7E003FC978 /* Color+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = ""; }; @@ -1650,6 +1648,10 @@ CEF61B111ECF52C700C7EA6A /* AmountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = AmountViewController.swift; path = src/ViewControllers/AmountViewController.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; CEF61B131ED0D10000C7EA6A /* Types.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Types.swift; path = src/Models/Types.swift; sourceTree = ""; }; CEF61B151ED2056D00C7EA6A /* NumberFormatter+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NumberFormatter+Additions.swift"; path = "src/Extensions/NumberFormatter+Additions.swift"; sourceTree = ""; }; + D65EC4117578A5C9BA040F8D /* Pods-loafwalletTests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.testnet.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.testnet.xcconfig"; sourceTree = ""; }; + DDAC39ACED69AB0E4CAAEE32 /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E4CCF28E98A07DAA4910FCA8 /* Pods-loafwallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.release.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.release.xcconfig"; sourceTree = ""; }; + F2DC7DD25C905C64E479CE86 /* Pods-loafwallet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.debug.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1665,7 +1667,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8BFF92CC86553A47974D867D /* Pods_loafwalletTests.framework in Frameworks */, + 9F277AD526A9DAEC0A5F4008 /* Pods_loafwalletTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1701,11 +1703,13 @@ 22A9A9621DF61FE0000F0016 /* SystemConfiguration.framework in Frameworks */, 22A9A9601DF61FD8000F0016 /* CoreLocation.framework in Frameworks */, 22A9A95E1DF61FD0000F0016 /* PushKit.framework in Frameworks */, + C38345F725B3393E00E065FD /* FirebaseAnalytics in Frameworks */, 223DB21B1DF69F0F0076A151 /* libbz2.framework in Frameworks */, C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */, + C38345F925B3393E00E065FD /* FirebaseCrashlytics in Frameworks */, 752FB04D1DF8BF4B009086FB /* sqlite3.framework in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, - 1991125B1B86B90CA24B7286 /* Pods_loafwallet.framework in Frameworks */, + 74B3E4C4DD12414DD0484B2F /* Pods_loafwallet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3023,8 +3027,8 @@ 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */, 75A2A7F21DA5935F00A983D8 /* Messages.framework */, 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */, - 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */, - B994E2162ECCFE0BB90CC714 /* Pods_loafwalletTests.framework */, + DDAC39ACED69AB0E4CAAEE32 /* Pods_loafwallet.framework */, + 2CCD0579E0855FDF49144D8A /* Pods_loafwalletTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -3488,12 +3492,12 @@ FEE036865998B9DFEEF3139A /* Pods */ = { isa = PBXGroup; children = ( - C2728A44EB43C7CCAA987B89 /* Pods-loafwallet.debug.xcconfig */, - 40524F4C990EE3717AE4D70C /* Pods-loafwallet.testnet.xcconfig */, - 743B301179ED3019FA9E6247 /* Pods-loafwallet.release.xcconfig */, - A1C0235D73D79DA3FB4FFDF7 /* Pods-loafwalletTests.debug.xcconfig */, - ADB3C165455573400E04EC13 /* Pods-loafwalletTests.testnet.xcconfig */, - 72359B62E9336B8B8C58C7B3 /* Pods-loafwalletTests.release.xcconfig */, + F2DC7DD25C905C64E479CE86 /* Pods-loafwallet.debug.xcconfig */, + 82B54D9BA6CCD590F3B15E32 /* Pods-loafwallet.testnet.xcconfig */, + E4CCF28E98A07DAA4910FCA8 /* Pods-loafwallet.release.xcconfig */, + 80008B6D966315A287287C5F /* Pods-loafwalletTests.debug.xcconfig */, + D65EC4117578A5C9BA040F8D /* Pods-loafwalletTests.testnet.xcconfig */, + 140FA787B8C189CDA7E8EA0A /* Pods-loafwalletTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -3557,7 +3561,7 @@ isa = PBXNativeTarget; buildConfigurationList = 2465873D23A5AAD100A32E9E /* Build configuration list for PBXNativeTarget "loafwalletTests" */; buildPhases = ( - 539F95D1D2880CDB55F16CD2 /* [CP] Check Pods Manifest.lock */, + C181B998505AF9F669EA21C4 /* [CP] Check Pods Manifest.lock */, 2465873223A5AAD000A32E9E /* Sources */, 2465873323A5AAD000A32E9E /* Frameworks */, 2465873423A5AAD000A32E9E /* Resources */, @@ -3630,7 +3634,7 @@ isa = PBXNativeTarget; buildConfigurationList = 75A2A7E31DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet" */; buildPhases = ( - 421B6524385300316FBCCDF8 /* [CP] Check Pods Manifest.lock */, + 95A0AE4B0D23BB143F8D11D7 /* [CP] Check Pods Manifest.lock */, 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */, 24E179F223BDAF8000F928D9 /* Xcode custom warnings */, 75A2A78C1DA5934300A983D8 /* Sources */, @@ -3639,7 +3643,8 @@ 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, C3D1588125666B69009BD3BC /* Mark Dev Notes */, - CB23F16DD689CE4EDFBEB417 /* [CP] Embed Pods Frameworks */, + C38056DB231D707AAC9C4808 /* [CP] Embed Pods Frameworks */, + C383465325B34D8F00E065FD /* Upload dSYMs to Firebase */, ); buildRules = ( ); @@ -3652,6 +3657,8 @@ name = loafwallet; packageProductDependencies = ( C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */, + C38345F625B3393E00E065FD /* FirebaseAnalytics */, + C38345F825B3393E00E065FD /* FirebaseCrashlytics */, ); productName = breadwallet; productReference = 75A2A7901DA5934300A983D8 /* Litewallet.app */; @@ -3784,6 +3791,7 @@ mainGroup = 75A2A7871DA5934300A983D8; packageReferences = ( C30AFB4C2598FC1B00CDCF69 /* XCRemoteSwiftPackageReference "LitewalletPartnerAPI" */, + C38345F525B3393E00E065FD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, ); productRefGroup = 75A2A7911DA5934300A983D8 /* Products */; projectDirPath = ""; @@ -3906,7 +3914,7 @@ shellPath = /bin/sh; shellScript = "TAGS=\"TODO:|FIXME:|WARNING:\"\nfind \"${SRCROOT}\" \\( -name \"*.h\" -or -name \"*.m\" -or -name \"*.swift\" \\) -print0 | xargs -0 egrep --with-filename --line-number --only-matching \"($TAGS).*\\$\" | perl -p -e \"s/($TAGS)/ warning: \\$1/\"\n"; }; - 421B6524385300316FBCCDF8 /* [CP] Check Pods Manifest.lock */ = { + 95A0AE4B0D23BB143F8D11D7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3928,7 +3936,7 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 539F95D1D2880CDB55F16CD2 /* [CP] Check Pods Manifest.lock */ = { + C181B998505AF9F669EA21C4 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3950,40 +3958,60 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - C3D1588125666B69009BD3BC /* Mark Dev Notes */ = { + C38056DB231D707AAC9C4808 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 12; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + C383465325B34D8F00E065FD /* Upload dSYMs to Firebase */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( + "$(SRCROOT)/$(BUIILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)", + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}", ); - name = "Mark Dev Notes"; + name = "Upload dSYMs to Firebase"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos\necho \"make-xcode-nag-you-about-unfinished-todos for swift files only\"\nKEYWORDS=\"DEV|TODO|FIXME|\\?\\?\\?:|\\!\\!\\!:\"\nfind \"${SRCROOT}\" \\( -name \"*.swift\" \\) -print0 | \\\nxargs -0 egrep --with-filename --line-number --only-matching \"($KEYWORDS).*\\$\" | \\\nperl -p -e \"s/($KEYWORDS)/ warning: \\$1/\"\n\n\n"; + shellScript = "# Upload dSYMs\n\"${BUILD_DIR%Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\"\n"; }; - CB23F16DD689CE4EDFBEB417 /* [CP] Embed Pods Frameworks */ = { + C3D1588125666B69009BD3BC /* Mark Dev Notes */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + ); + name = "Mark Dev Notes"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "# http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos\necho \"make-xcode-nag-you-about-unfinished-todos for swift files only\"\nKEYWORDS=\"DEV|TODO|FIXME|\\?\\?\\?:|\\!\\!\\!:\"\nfind \"${SRCROOT}\" \\( -name \"*.swift\" \\) -print0 | \\\nxargs -0 egrep --with-filename --line-number --only-matching \"($KEYWORDS).*\\$\" | \\\nperl -p -e \"s/($KEYWORDS)/ warning: \\$1/\"\n\n\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -4652,6 +4680,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_INCLUDE_PATHS = "$(SDK_DIR)/usr/include $(SRCROOT)/Modules $(SRCROOT)/loafwallet/src/Platform"; @@ -4665,7 +4694,7 @@ }; 24470E0123A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C2728A44EB43C7CCAA987B89 /* Pods-loafwallet.debug.xcconfig */; + baseConfigurationReference = F2DC7DD25C905C64E479CE86 /* Pods-loafwallet.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -4698,7 +4727,7 @@ }; 24470E0323A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A1C0235D73D79DA3FB4FFDF7 /* Pods-loafwalletTests.debug.xcconfig */; + baseConfigurationReference = 80008B6D966315A287287C5F /* Pods-loafwalletTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -4906,7 +4935,7 @@ }; 2465873F23A5AAD100A32E9E /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = ADB3C165455573400E04EC13 /* Pods-loafwalletTests.testnet.xcconfig */; + baseConfigurationReference = D65EC4117578A5C9BA040F8D /* Pods-loafwalletTests.testnet.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -4934,7 +4963,7 @@ }; 2465874023A5AAD100A32E9E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 72359B62E9336B8B8C58C7B3 /* Pods-loafwalletTests.release.xcconfig */; + baseConfigurationReference = 140FA787B8C189CDA7E8EA0A /* Pods-loafwalletTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -5069,6 +5098,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; + "OTHER_LDFLAGS[arch=*]" = "-ObjC "; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_INCLUDE_PATHS = "$(SDK_DIR)/usr/include $(SRCROOT)/Modules $(SRCROOT)/loafwallet/src/Platform"; @@ -5082,7 +5112,7 @@ }; 75A2A7E51DA5934400A983D8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 743B301179ED3019FA9E6247 /* Pods-loafwallet.release.xcconfig */; + baseConfigurationReference = E4CCF28E98A07DAA4910FCA8 /* Pods-loafwallet.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -5212,7 +5242,7 @@ }; CEA7E69C1F0AAA84001F8C27 /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 40524F4C990EE3717AE4D70C /* Pods-loafwallet.testnet.xcconfig */; + baseConfigurationReference = 82B54D9BA6CCD590F3B15E32 /* Pods-loafwallet.testnet.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -5491,6 +5521,14 @@ minimumVersion = 0.2.0; }; }; + C38345F525B3393E00E065FD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 7.0.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -5499,6 +5537,16 @@ package = C30AFB4C2598FC1B00CDCF69 /* XCRemoteSwiftPackageReference "LitewalletPartnerAPI" */; productName = LitewalletPartnerAPI; }; + C38345F625B3393E00E065FD /* FirebaseAnalytics */ = { + isa = XCSwiftPackageProductDependency; + package = C38345F525B3393E00E065FD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAnalytics; + }; + C38345F825B3393E00E065FD /* FirebaseCrashlytics */ = { + isa = XCSwiftPackageProductDependency; + package = C38345F525B3393E00E065FD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseCrashlytics; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 75A2A7881DA5934300A983D8 /* Project object */; diff --git a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme index 150bb23ca..df974d625 100644 --- a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme +++ b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme @@ -72,6 +72,12 @@ ReferencedContainer = "container:loafwallet.xcodeproj"> + + + + Date: Sat, 23 Jan 2021 15:44:59 +0000 Subject: [PATCH 032/114] [Feature] Simplex: Add more fiat pairs (#199) * Added the new fiat pairs - IDR - RUB - GBP - AUD - CAD * Adjusted hit target of the Buy Simplex Button * per review notes --- loafwallet/BuyTableViewController.swift | 8 +-- loafwallet/BuyWKWebViewController.swift | 21 ++------ loafwallet/Currency.swift | 53 ++++++++++--------- loafwallet/Storyboards/Buy.storyboard | 51 +++++++++--------- .../src/Platform/BRWebViewController.swift | 35 +----------- 5 files changed, 65 insertions(+), 103 deletions(-) diff --git a/loafwallet/BuyTableViewController.swift b/loafwallet/BuyTableViewController.swift index c4d8cff5d..52b28acca 100644 --- a/loafwallet/BuyTableViewController.swift +++ b/loafwallet/BuyTableViewController.swift @@ -15,7 +15,6 @@ class BuyTableViewController: UITableViewController { @IBOutlet weak var simplexDetailsLabel: UILabel! @IBOutlet weak var simplexCellContainerView: UIView! - @IBOutlet weak var chooseFiatLabel: UILabel! @IBOutlet weak var currencySegmentedControl: UISegmentedControl! private var currencyCode: String = "USD" @@ -54,6 +53,9 @@ class BuyTableViewController: UITableViewController { currencySegmentedControl.addTarget(self, action: #selector(didChangeCurrency), for: .valueChanged) currencySegmentedControl.selectedSegmentIndex = PartnerFiatOptions.usd.index + currencySegmentedControl.selectedSegmentTintColor = .white + currencySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: .normal) + currencySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.liteWalletBlue], for: .selected) setupData() } @@ -66,13 +68,13 @@ class BuyTableViewController: UITableViewController { simplexCellContainerView.layer.borderColor = UIColor.white.cgColor simplexCellContainerView.layer.borderWidth = 1.0 simplexCellContainerView.clipsToBounds = true - - chooseFiatLabel.text = S.DefaultCurrency.chooseFiatLabel } @objc private func didChangeCurrency() { if let code = PartnerFiatOptions(rawValue: currencySegmentedControl.selectedSegmentIndex)?.description { self.currencyCode = code + } else { + print("Error: Code not found: XXXX\(currencySegmentedControl.selectedSegmentIndex)") } } } diff --git a/loafwallet/BuyWKWebViewController.swift b/loafwallet/BuyWKWebViewController.swift index 75b7ee3a2..7bf0c20b5 100644 --- a/loafwallet/BuyWKWebViewController.swift +++ b/loafwallet/BuyWKWebViewController.swift @@ -36,8 +36,11 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe }() private let wkProcessPool = WKProcessPool() + var partnerPrefixString: String? + var currencyCode: String = "USD" + override func viewDidLoad() { super.viewDidLoad() setupSubViews() @@ -71,7 +74,6 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe let timestamp = Int(appInstallDate.timeIntervalSince1970) let urlString = APIServer.baseUrl + "?address=\(currentWalletAddress)&code=\(currencyCode)&idate=\(timestamp)&uid=\(uuidString)" - guard let url = URL(string: urlString) else { NSLog("ERROR: URL not initialized") return @@ -119,21 +121,8 @@ extension BuyWKWebViewController { func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in - if complete != nil { - -// document.documentElement.scrollHeight, -// document.body.offsetHeight, -// document.documentElement.offsetHeight, -// document.documentElement.clientHeight -// webView.evaluateJavaScript("document.body.scrollHeight", -// completionHandler: { (height, error) in -// }) -// -// webView.evaluateJavaScript("document.documentElement.scrollWidth", -// completionHandler: { (width, error) in -// }) - } - }) + if complete != nil { } + }) } func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { diff --git a/loafwallet/Currency.swift b/loafwallet/Currency.swift index a50763b44..7f921ecb6 100644 --- a/loafwallet/Currency.swift +++ b/loafwallet/Currency.swift @@ -10,50 +10,51 @@ import Foundation import UIKit class Currency { - - class func simplexDailyLimits() -> [String:[String]] { - return ["EUR":["40","16.000"],"USD":["40","18,500"]] - } - - class func getSymbolForCurrencyCode(code: String) -> String? { - let result = Locale.availableIdentifiers.map { Locale(identifier: $0) }.first { $0.currencyCode == code } - return result?.currencySymbol - } - - class func returnSimplexSupportedFiat(givenCode:String) -> String { - if (givenCode == "USD" || givenCode == "EUR") { - return givenCode - } - return "USD" - } + class func getSymbolForCurrencyCode(code: String) -> String? { + let result = Locale.availableIdentifiers.map { Locale(identifier: $0) }.first { $0.currencyCode == code } + return result?.currencySymbol + } } enum PartnerFiatOptions: Int, CustomStringConvertible { case cad - case eur + case aud + case idr + case rub case jpy + case eur + case gbp case usd public var description: String { return code } - + private var code: String { switch self { - case .cad: return "CAD" - case .eur: return "EUR" - case .jpy: return "JPY" - case .usd: return "USD" + case .cad: return "CAD" + case .aud: return "AUD" + case .idr: return "IDR" + case .rub: return "RUB" + case .jpy: return "JPY" + case .eur: return "EUR" + case .gbp: return "GBP" + case .usd: return "USD" } } public var index: Int { switch self { - case .cad: return 0 - case .eur: return 1 - case .jpy: return 2 - case .usd: return 3 + case .cad: return 0 + case .aud: return 1 + case .idr: return 2 + case .rub: return 3 + case .jpy: return 4 + case .eur: return 5 + case .gbp: return 6 + case .usd: return 7 } } } + diff --git a/loafwallet/Storyboards/Buy.storyboard b/loafwallet/Storyboards/Buy.storyboard index 09e7dd959..67ebe4c6e 100644 --- a/loafwallet/Storyboards/Buy.storyboard +++ b/loafwallet/Storyboards/Buy.storyboard @@ -1,10 +1,11 @@ - + - + + @@ -54,7 +55,7 @@ - + @@ -68,8 +69,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 1526a61a3..be0458b8c 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -233,17 +233,7 @@ class ModalPresenter : Subscriber, Trackable { alertView.removeFromSuperview() }) }) - } - - private func presentWebView(_ mountPoint: String) { - guard let walletManager = self.walletManager else { return } - let vc = WebViewContainer(mountPoint: mountPoint, walletManager: walletManager, store: store, apiClient: self.noAuthApiClient) - - vc.modalPresentationStyle = .overFullScreen - vc.modalPresentationCapturesStatusBarAppearance = true - vc.transitioningDelegate = vc - topViewController?.present(vc, animated: true, completion: {}) - } + } private func rootModalViewController(_ type: RootModal) -> UIViewController? { switch type { diff --git a/loafwallet/src/ViewControllers/WebViewContainer.swift b/loafwallet/src/ViewControllers/WebViewContainer.swift deleted file mode 100644 index 4c471d96b..000000000 --- a/loafwallet/src/ViewControllers/WebViewContainer.swift +++ /dev/null @@ -1,113 +0,0 @@ -// -// WebViewContainer.swift -// breadwallet -// -// Created by Adrian Corscadden on 2017-05-02. -// Copyright © 2017 breadwallet LLC. All rights reserved. -// - -import UIKit - -class WebViewContainer : UIViewController { - - init(mountPoint: String, walletManager: WalletManager, store: Store, apiClient: BRAPIClient) { - #if Debug || Testflight - webView = BRWebViewController(partner: "Simplex", mountPoint: mountPoint, walletManager: walletManager, store: store, noAuthApiClient: apiClient) - #else - webView = BRWebViewController(partner: "Simplex", mountPoint: mountPoint, walletManager: walletManager, store: store, noAuthApiClient: apiClient) - #endif - webView.preload() - super.init(nibName: nil, bundle: nil) - } - - private let webView: BRWebViewController - let blur = UIVisualEffectView() - - override func viewDidLoad() { - view.backgroundColor = .clear - addChildViewController(webView, layout: { - webView.view.constrain([ - webView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), - webView.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), - webView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), - webView.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) - }) - addTopCorners() - } - - private func addTopCorners() { - let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 6.0, height: 6.0)).cgPath - let maskLayer = CAShapeLayer() - maskLayer.path = path - webView.view.layer.mask = maskLayer - } - - override var preferredStatusBarStyle: UIStatusBarStyle { - return .lightContent - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} - -extension WebViewContainer : UIViewControllerTransitioningDelegate { - func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { - return DismissSupportCenterAnimator() - } - - func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { - return PresentSupportCenterAnimator() - } -} - -class PresentSupportCenterAnimator : NSObject, UIViewControllerAnimatedTransitioning { - func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { - return 0.4 - } - - func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { - let duration = transitionDuration(using: transitionContext) - guard let toViewController = transitionContext.viewController(forKey: .to) as? WebViewContainer else { assert(false, "Missing to view controller"); return } - guard let toView = transitionContext.view(forKey: .to) else { assert(false, "Missing to view"); return } - let container = transitionContext.containerView - - let blur = toViewController.blur - blur.frame = container.frame - container.addSubview(blur) - - let finalToViewFrame = toView.frame - toView.frame = toView.frame.offsetBy(dx: 0, dy: toView.frame.height) - container.addSubview(toView) - - - UIView.spring(duration, animations: { - blur.effect = UIBlurEffect(style: .dark) - toView.frame = finalToViewFrame - }, completion: { _ in - transitionContext.completeTransition(true) - }) - - } -} - -class DismissSupportCenterAnimator : NSObject, UIViewControllerAnimatedTransitioning { - func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { - return 0.4 - } - - func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { - guard transitionContext.isAnimated else { return } - let duration = transitionDuration(using: transitionContext) - guard let fromView = transitionContext.view(forKey: .from) else { assert(false, "Missing from view"); return } - guard let fromViewController = transitionContext.viewController(forKey: .from) as? WebViewContainer else { assert(false, "Missing to view controller"); return } - let originalFrame = fromView.frame - UIView.animate(withDuration: duration, animations: { - fromViewController.blur.effect = nil - fromView.frame = fromView.frame.offsetBy(dx: 0, dy: fromView.frame.height) - }, completion: { _ in - fromView.frame = originalFrame //Because this view gets reused, it's frame needs to be reset everytime - transitionContext.completeTransition(true) - }) - } -} From 7b31236ca5eaa73443ce8760828db1ac7dcc1c0a Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 27 Jan 2021 14:21:12 +0000 Subject: [PATCH 037/114] [Bugfix] Fix buywebview (#215) * Resolve Crash issue * Fixes the webview --- loafwallet/BuyTableViewController.swift | 3 +-- loafwallet/BuyWKWebViewController.swift | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/loafwallet/BuyTableViewController.swift b/loafwallet/BuyTableViewController.swift index 52b28acca..5728853eb 100644 --- a/loafwallet/BuyTableViewController.swift +++ b/loafwallet/BuyTableViewController.swift @@ -28,8 +28,7 @@ class BuyTableViewController: UITableViewController { self.view.addSubview(vcWKVC.view) vcWKVC.didMove(toParentViewController: self) - vcWKVC.didDismissChildView = { [weak self] in - guard self != nil else { return } + vcWKVC.didDismissChildView = { vcWKVC.willMove(toParentViewController: nil) vcWKVC.view.removeFromSuperview() vcWKVC.removeFromParentViewController() diff --git a/loafwallet/BuyWKWebViewController.swift b/loafwallet/BuyWKWebViewController.swift index 7bf0c20b5..ce53d5dad 100644 --- a/loafwallet/BuyWKWebViewController.swift +++ b/loafwallet/BuyWKWebViewController.swift @@ -63,13 +63,14 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe config.processPool = wkProcessPool config.userContentController = contentController - let wkWithFooter = CGRect(x: 0, y: 0, width: self.wkWebContainerView.bounds.width, height: self.wkWebContainerView.bounds.height-100) + let wkWithFooter = CGRect(x: 0, y: 0, width: self.wkWebContainerView.bounds.width, + height: self.wkWebContainerView.bounds.height - 100) let wkWebView = WKWebView(frame:wkWithFooter, configuration: config) wkWebView.navigationDelegate = self wkWebView.allowsBackForwardNavigationGestures = true - wkWebView.scrollView.contentInset = UIEdgeInsetsMake(-50, 0, 0, 0) - - wkWebView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + wkWebView.contentMode = .scaleAspectFit + wkWebView.autoresizesSubviews = true + wkWebView.autoresizingMask = [.flexibleHeight, .flexibleWidth] self.wkWebContainerView.addSubview(wkWebView) let timestamp = Int(appInstallDate.timeIntervalSince1970) From 79407560287b14a54666643b15f647654263e3c8 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 7 Feb 2021 22:02:46 +0000 Subject: [PATCH 038/114] [Merge v3.2.0] into Develop (#217) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Merge v3.0.0] into Master (#183) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release] Merge v2.8.2 into Develop (#158) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry * [Bugfix] Replace the LF Support View (#159) * Moved the LF Cell from Send. - BartyCrouch linted the stigns files. * Updated the LF Support location - Reset the localiaztion language to ‘Customer support’ - Add the dismissal actions * [Bugfix] Fix buy tab: Simplex urls (#157) * Updated the url to new servers * Linted the Localized strings * Setup url constants * updated pk file status * Updated per PR review comments * fixed naming of the url variable * [Merge v2.8.3] into Develop (#169) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Master (#153) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * version bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [Feature Issue 154] Adding Unstoppable Domains functionality (#155) * Added UD to Podfile - Stubbed out the view, viewModel and the test class for UD * [UI Polish] Added images and localized strings - Added more of strings and UD structure - Trimmed images to resize for button - Added localized strings for placeholder * Updated UnstoppableDomainsView and Model details - Added DEV notes script - Adjusted Previews by unchecking the `build install only` * Added more tests - UnstoppableDomains View Model tests - SupportLitecoinFoundationViewModel tests * reformatted code in new SwiftUI views and viewModels * Added UD action to the SendViewController * Updated project * Updated localized UD Placeholder * Setup API keys * removed pk file * Changed the localizations related to UD - Added ‘Or’ label - Added UD placeholder text - Changed the LTC address placeholder text * Added in the Or and relayout of the button - Added Partner layout view for UD and Simplex * Resolved code review comments - Update the localizations - Refactored the UD shared instance (singleton) to retain throguh the call - Added timing probes * revert to current version * reformatted the Support LF view strings * Remove Test Playground. * Removed unused SocialView and ViewModel * Improved resolution - Added a Dispatch and ‘exit’ when address is found sooner than 12 secs. Much better experience for the user. * Added infura * Resolved review comments * Rewrote copy for “Enter a Litecoin address” * Fix some trivial conflict markers (#177) * [Bugfix] Upgrade the business logic for Unstoppable Domains (#179) * Fix some triival conflict markers * Added test to button once the UD string meets a minimum length * Clears address text field when Lookup button is pressed * Set the background color of the AlertToast * Locailization of the alert language * move logic to release the first responder * per review notes * [Feature] Litecoin card v1 (#180) * [Litecoin Card] Progress Step 1 - Major work: litecoin-card TabBarView refactor - Updated UIColor for Color - SwiftUI preview devices - Working out the Nav polish - Fixed hard-coded UD lookup label with proper localizations - Commented out BitId * [Litecoin Card] Progress Step 2 - Added more localizations - Rebuilding registration view need to add keyboard - Fixed the animation for the card view - Fixed Alert name collisions to the SimplexAlert * [Litecoin Card] Progress Step 3 - Added Login views and localizations - Added partnerAPI Swift Package - Layout the registration view - Add more localizations - BUGFIX: Image missing in this branch. * [Litecoin Card] Progress Step 4 More localizations Added data Validators Final Polish for Registration View Registration View Modal wiring works * [Litecoin Card] Progress Step 5 Register works to the model Login is working Added animation for Login/Logout Login and Loogut working Added localizations More localizations * [Litecoin Card] RC 1 polishes Communcations polishing + dev cleanup Polishing the RegistrationView layout Fixed bug: https://github.com/litecoin-foundation/loafwallet-ios/issues/175 * [Litecoin Card] RC2: removed defunct script * per review comments - Ar files removal - Cleanup localizable - Removed Ar.proj files - Removed empty class - Added all Validation localization framework - Added localizations of the validations - Refactored per review notes * Bugfix- login message Added failure message localizations * version bump * Added some tests * Refactored the login logic - Used the status of the binding to change the UI * Added combined logic of the email and password fields to enable login button Reference @losh11 comment: `The cards login now gives a good login failed alert. However I think the login button should be disabled until the text in the email input is validated as email format.` * build bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [HOTFIX] Hide Card Tab (#191) * Hide Card Tab * added comments for v1 * [Merge into Master] v3.1.1 (#194) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release] Merge v2.8.2 into Develop (#158) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry * [Bugfix] Replace the LF Support View (#159) * Moved the LF Cell from Send. - BartyCrouch linted the stigns files. * Updated the LF Support location - Reset the localiaztion language to ‘Customer support’ - Add the dismissal actions * [Bugfix] Fix buy tab: Simplex urls (#157) * Updated the url to new servers * Linted the Localized strings * Setup url constants * updated pk file status * Updated per PR review comments * fixed naming of the url variable * [Merge v2.8.3] into Develop (#169) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Master (#153) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * version bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [Feature Issue 154] Adding Unstoppable Domains functionality (#155) * Added UD to Podfile - Stubbed out the view, viewModel and the test class for UD * [UI Polish] Added images and localized strings - Added more of strings and UD structure - Trimmed images to resize for button - Added localized strings for placeholder * Updated UnstoppableDomainsView and Model details - Added DEV notes script - Adjusted Previews by unchecking the `build install only` * Added more tests - UnstoppableDomains View Model tests - SupportLitecoinFoundationViewModel tests * reformatted code in new SwiftUI views and viewModels * Added UD action to the SendViewController * Updated project * Updated localized UD Placeholder * Setup API keys * removed pk file * Changed the localizations related to UD - Added ‘Or’ label - Added UD placeholder text - Changed the LTC address placeholder text * Added in the Or and relayout of the button - Added Partner layout view for UD and Simplex * Resolved code review comments - Update the localizations - Refactored the UD shared instance (singleton) to retain throguh the call - Added timing probes * revert to current version * reformatted the Support LF view strings * Remove Test Playground. * Removed unused SocialView and ViewModel * Improved resolution - Added a Dispatch and ‘exit’ when address is found sooner than 12 secs. Much better experience for the user. * Added infura * Resolved review comments * Rewrote copy for “Enter a Litecoin address” * Fix some trivial conflict markers (#177) * [Bugfix] Upgrade the business logic for Unstoppable Domains (#179) * Fix some triival conflict markers * Added test to button once the UD string meets a minimum length * Clears address text field when Lookup button is pressed * Set the background color of the AlertToast * Locailization of the alert language * move logic to release the first responder * per review notes * [Feature] Litecoin card v1 (#180) * [Litecoin Card] Progress Step 1 - Major work: litecoin-card TabBarView refactor - Updated UIColor for Color - SwiftUI preview devices - Working out the Nav polish - Fixed hard-coded UD lookup label with proper localizations - Commented out BitId * [Litecoin Card] Progress Step 2 - Added more localizations - Rebuilding registration view need to add keyboard - Fixed the animation for the card view - Fixed Alert name collisions to the SimplexAlert * [Litecoin Card] Progress Step 3 - Added Login views and localizations - Added partnerAPI Swift Package - Layout the registration view - Add more localizations - BUGFIX: Image missing in this branch. * [Litecoin Card] Progress Step 4 More localizations Added data Validators Final Polish for Registration View Registration View Modal wiring works * [Litecoin Card] Progress Step 5 Register works to the model Login is working Added animation for Login/Logout Login and Loogut working Added localizations More localizations * [Litecoin Card] RC 1 polishes Communcations polishing + dev cleanup Polishing the RegistrationView layout Fixed bug: https://github.com/litecoin-foundation/loafwallet-ios/issues/175 * [Litecoin Card] RC2: removed defunct script * per review comments - Ar files removal - Cleanup localizable - Removed Ar.proj files - Removed empty class - Added all Validation localization framework - Added localizations of the validations - Refactored per review notes * Bugfix- login message Added failure message localizations * [Merge v3.0.0] into Develop (#184) * version bump * Added some tests * Refactored the login logic - Used the status of the binding to change the UI * Added combined logic of the email and password fields to enable login button Reference @losh11 comment: `The cards login now gives a good login failed alert. However I think the login button should be disabled until the text in the email input is validated as email format.` * build bump * [HOTFIX] hide litecoin card (#192) * [Merge v3.0.0] into Master (#183) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release] Merge v2.8.2 into Develop (#158) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry * [Bugfix] Replace the LF Support View (#159) * Moved the LF Cell from Send. - BartyCrouch linted the stigns files. * Updated the LF Support location - Reset the localiaztion language to ‘Customer support’ - Add the dismissal actions * [Bugfix] Fix buy tab: Simplex urls (#157) * Updated the url to new servers * Linted the Localized strings * Setup url constants * updated pk file status * Updated per PR review comments * fixed naming of the url variable * [Merge v2.8.3] into Develop (#169) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * Release/v2.8.0 (#131) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * [Release v2.8.2] Merge into Master (#153) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade * [Bugfix] Cleared Simplex (#126) * Disabled Simplex - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker * Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message * Develop - Release/v2.8.0 (#132) * [Merge to Master] Develop with tech debt improvements (#123) * fix crash: window required * compute QR code only once * run code on main thread * update cocoapods firebase * update addresses + event * version bump * remove unused fonts * Updated key for RemoteRunnable in xcscheme * Added Issue templates (#122) - Bug Report - Feature Request - Also have watch xcscheme added per upgrade Co-authored-by: Mohamed Barry * ## Release Notes: v2.8.0 (version bump) This release is the first release in months that needed an update based on the changes in the enviroment. In general, the Litewallet code base is bloated with 1000's of lines of unused code and this makes debugging and adding new features very difficult. In addition, the requirements of iOS 14 and the plan to move from UIKit to a SwiftUI+Combine architecture means subsequent PRs will reflect a more streamlined codebase. ## Tech Debt - Also have watch xcscheme added per upgrade - Added Issue templates (#122) - Bug Report - Feature Request - Updated key for RemoteRunnable in xcscheme - remove unused fonts - run code on main thread - update cocoapods firebase - update addresses + event ## Improvements * compute QR code only once - Soft launch for Import QR Code ## Bugfixes * fix crash: window required ## Temporary Workarounds The proxy server the supports buying LTC is being refactored and so no mobile clients can use the Simplex service * Disabled Simplex / Added temp message - Was causing crashes when return messages were happening. - Will update in the next cycle with an updated UI - Added a Analytics: DID TAP BUY TAB marker - Added Coming Soon label to the tableview background view for a temporary sign - Added all translation for the coming soon message ## Authors Kerry Washington Mohamed Barry * Removed schemes (#125) Goal: Reduce the codebase in prep for a major refactor. This removed the debug scheme and watch scheme. * [Tech Debt] Remove Apple Watch code (#124) * Remove Apple Watch code - The Apple Code is very old and has never been updated. - There is a longer plan to remove superflous code. - If others ask to re-add it we will look again with the later versions * Removed NotificationServiceExtension - This is cruft that has never been called - Added in 2016 - This is not supported currently * Change email addresses Also added feedback and support emails. * Added HTML for support email Fixed bitcoin references * Removed empty UITests * bump build number * updated html to be for iPhone only * Fix podfile and build version * Revert "[Bugfix] Cleared Simplex (#126)" This reverts commit 154eb4fbbe71b4ff1a2323dd316bf7b6783c3b0a. * bump build number Co-authored-by: Mohamed Barry * Fix crash in Amount formatter (#140) * 🦺 [Tech Debt] Update Podfile and Refactor build process (#144) * Update Podfile - Set mimum value of iOS 13 - Removed unused SwiftyJSON - Removed unused Watch Scheme - re-added xcscheme - removed non-used code - added status badge in README * removed the podfile target force * added SPM .build folder exclusion in gitignore * [Bugfix] Renamed enum from State (#147) * Renamed enum from State ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` * Toggled iOS version 13 * Revert "[Bugfix] Renamed enum from State (#147)" (#150) This reverts commit ea8293b5c7f206706942416a1d7d9b139926fa97. * [Warmfix] Issue:146 Remove direct donation: support litecoin foundation (#151) * Prepared the code for differnt Cell / Remove Donation Code - Updated localized strings file(s) - Removed old Donate files - Updated SendVIewController * Resolved the previous conflicts - Added in SupportLitecoinFoundation SwiftUI view and model - Working in the basic functionality of the new Support Litecoin Foundation view * Worked in the vars of SupportLitecoinFoundation view * Removed Donation code * Set a URL for the support LTC address * Add new WebKit view and supporting code * Adjusted height constants in the nightmare scenario of the SendCell -There is a nasty sandwich of ViewControllers where SwiftUI should be used. - This needs to be simplified # Conflicts: # loafwallet/src/ViewControllers/RootModals/SendViewController.swift * Added new MVVM Views and ViewModels - Adding more SwiftUI code * Refactored and stubbed out tests * version bump * Renamed enum from State to ReduxState ## Problem The original design of Breadwallet (Loafwallet) used a SimpleRedux architecture which maanged the State in an unsual (yet effective) way. Within that design ‘state’ was managed by an enum named “State” This was fine until SwiftUI and Combine where there is now a name collision since @State is referring to the SwfitUI attribute. ## Approach While redesiging the app would be ideal, the reality is this needs to be fixed as soon as possible because Litewallet is now using SwiftUI. Steps to fix the problem: - [ ] Renamed variable from `State` to `ReduxState` using Xcode Refactor: Rename * Cleaned up Localized strings file * Added review fixes - Added CGFloat multiplier in padding - Fixed formatting - Added tracking Support taps * [Release v2.8.2] Merge into Develop ## Release Notes: v2.8.2 (1) This release is due to a requirement to App Store to remove references to donations. In it’s replacement, a reference to the Litecoin Foundation support page where the user can elect to send LTC if they so choose. - [Warmfix] Issue:146 Remove direct donation: support litecoin foundati… ## Other Improvements - Fix crash in Amount formatter (#140) - [Bugfix] Renamed enum from State (#147) (#150) ## Bugfixes - Renaming the enum caused a conflict with SwiftUI @State ## Authors Kerry Washington Mohamed Barry * Hotfix Increment -Updated to allow upload to App Store * build number change * fixed conflicts Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * version bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [Feature Issue 154] Adding Unstoppable Domains functionality (#155) * Added UD to Podfile - Stubbed out the view, viewModel and the test class for UD * [UI Polish] Added images and localized strings - Added more of strings and UD structure - Trimmed images to resize for button - Added localized strings for placeholder * Updated UnstoppableDomainsView and Model details - Added DEV notes script - Adjusted Previews by unchecking the `build install only` * Added more tests - UnstoppableDomains View Model tests - SupportLitecoinFoundationViewModel tests * reformatted code in new SwiftUI views and viewModels * Added UD action to the SendViewController * Updated project * Updated localized UD Placeholder * Setup API keys * removed pk file * Changed the localizations related to UD - Added ‘Or’ label - Added UD placeholder text - Changed the LTC address placeholder text * Added in the Or and relayout of the button - Added Partner layout view for UD and Simplex * Resolved code review comments - Update the localizations - Refactored the UD shared instance (singleton) to retain throguh the call - Added timing probes * revert to current version * reformatted the Support LF view strings * Remove Test Playground. * Removed unused SocialView and ViewModel * Improved resolution - Added a Dispatch and ‘exit’ when address is found sooner than 12 secs. Much better experience for the user. * Added infura * Resolved review comments * Rewrote copy for “Enter a Litecoin address” * Fix some trivial conflict markers (#177) * [Bugfix] Upgrade the business logic for Unstoppable Domains (#179) * Fix some triival conflict markers * Added test to button once the UD string meets a minimum length * Clears address text field when Lookup button is pressed * Set the background color of the AlertToast * Locailization of the alert language * move logic to release the first responder * per review notes * [Feature] Litecoin card v1 (#180) * [Litecoin Card] Progress Step 1 - Major work: litecoin-card TabBarView refactor - Updated UIColor for Color - SwiftUI preview devices - Working out the Nav polish - Fixed hard-coded UD lookup label with proper localizations - Commented out BitId * [Litecoin Card] Progress Step 2 - Added more localizations - Rebuilding registration view need to add keyboard - Fixed the animation for the card view - Fixed Alert name collisions to the SimplexAlert * [Litecoin Card] Progress Step 3 - Added Login views and localizations - Added partnerAPI Swift Package - Layout the registration view - Add more localizations - BUGFIX: Image missing in this branch. * [Litecoin Card] Progress Step 4 More localizations Added data Validators Final Polish for Registration View Registration View Modal wiring works * [Litecoin Card] Progress Step 5 Register works to the model Login is working Added animation for Login/Logout Login and Loogut working Added localizations More localizations * [Litecoin Card] RC 1 polishes Communcations polishing + dev cleanup Polishing the RegistrationView layout Fixed bug: https://github.com/litecoin-foundation/loafwallet-ios/issues/175 * [Litecoin Card] RC2: removed defunct script * per review comments - Ar files removal - Cleanup localizable - Removed Ar.proj files - Removed empty class - Added all Validation localization framework - Added localizations of the validations - Refactored per review notes * Bugfix- login message Added failure message localizations * version bump * Added some tests * Refactored the login logic - Used the status of the binding to change the UI * Added combined logic of the email and password fields to enable login button Reference @losh11 comment: `The cards login now gives a good login failed alert. However I think the login button should be disabled until the text in the email input is validated as email format.` * build bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * Hide Card Tab * added comments for v1 Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * [Bugfix]UD resolved address / got callback (#193) * Fixed bug: resolved address / got callback - Added a dispatch group - Fixed the bug by adding wait to the group from (@JohnnyJumper) - Refactored partner plist * removed cruft * polish UD model * v3.0.1 Card Hidden - found hidden code… * Resolved review comment - polished the address send label * removed unused code - clean comments * version bump * -build bump - polished cruft - clean package Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov * Conflict resolved - SW resolved - TabBarViewController - Main Storyboard * package resolution * build bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov --- Podfile | 2 +- loafwallet.xcodeproj/project.pbxproj | 13 +++++++------ loafwallet/Storyboards/Main.storyboard | 2 +- loafwallet/TabBarViewController.swift | 8 ++++---- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Podfile b/Podfile index ebd7df3a1..2b9ebb14c 100644 --- a/Podfile +++ b/Podfile @@ -10,7 +10,7 @@ def shared_pods pod 'UnstoppableDomainsResolution', '~> 0.1.6' pod 'KeychainAccess', '~> 4.2' pod 'Firebase/Analytics' - pod 'Firebase/Crashlytics' + pod 'Firebase/Crashlytics' # add after v2.9.0 pod 'SwiftLint' end diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 76639aaf7..a0c49c0b5 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 1991125B1B86B90CA24B7286 /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */; }; 1B3F74231FFB106200CCA50C /* BiometricsSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74211FFB106200CCA50C /* BiometricsSettingsViewController.swift */; }; 1B3F74241FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74221FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift */; }; 1BA9FE3D216F68A700BB2DE8 /* BRBech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BA9FE3C216F68A700BB2DE8 /* BRBech32.c */; }; @@ -4663,7 +4664,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4770,7 +4771,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5081,7 +5082,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5111,7 +5112,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5211,7 +5212,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5243,7 +5244,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; diff --git a/loafwallet/Storyboards/Main.storyboard b/loafwallet/Storyboards/Main.storyboard index 65aa41aff..dd20cc8e9 100644 --- a/loafwallet/Storyboards/Main.storyboard +++ b/loafwallet/Storyboards/Main.storyboard @@ -33,7 +33,7 @@ - + diff --git a/loafwallet/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index cc9193d2d..1c52f3eac 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -6,7 +6,7 @@ // Copyright © 2019 Litecoin Foundation. All rights reserved. import UIKit -import Foundation +import Foundation enum TabViewControllerIndex: Int { case transactions = 0 @@ -42,7 +42,6 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel var storyboardIDs:[String] = ["TransactionsViewController","SendLTCViewController","CardViewController","ReceiveLTCViewController","BuyTableViewController"] var viewControllers:[UIViewController] = [] var activeController:UIViewController? = nil - var updateTimer: Timer? var store: Store? var walletManager: WalletManager? @@ -170,7 +169,6 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel } //MARK: - Adding Subscriptions private func addSubscriptions() { - guard let store = self.store else { NSLog("ERROR - Store not passed") return @@ -333,7 +331,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel } cardVC.parentFrame = self.containerView.frame - + case "loafwallet.BuyTableViewController": guard let buyVC = contentController as? BuyTableViewController else { return @@ -377,6 +375,8 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel if let tempActiveController = activeController { self.hideContentController(contentController: tempActiveController) } + + //DEV: This happens because it relies on the tab in the storyboard tag self.displayContentController(contentController: viewControllers[item.tag]) } } From 5bcdb3e0d30236a0fe587cca108037267d629b5c Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 17 Feb 2021 15:48:53 +0000 Subject: [PATCH 039/114] Added SFSafariVC (#225) - Renamed the types - cleaned up old code - added HC Url --- loafwallet/BuyTableViewController.swift | 1 - loafwallet/src/Controls/MenuButtonType.swift | 12 ++++----- loafwallet/src/ModalPresenter.swift | 25 +++++++++++-------- .../RootModals/MenuViewController.swift | 10 ++++---- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/loafwallet/BuyTableViewController.swift b/loafwallet/BuyTableViewController.swift index 5728853eb..34282481f 100644 --- a/loafwallet/BuyTableViewController.swift +++ b/loafwallet/BuyTableViewController.swift @@ -22,7 +22,6 @@ class BuyTableViewController: UITableViewController { @IBAction func didTapSimplex(_ sender: Any) { if let vcWKVC = UIStoryboard.init(name: "Buy", bundle: nil).instantiateViewController(withIdentifier: "BuyWKWebViewController") as? BuyWKWebViewController { - vcWKVC.partnerPrefixString = PartnerPrefix.simplex.rawValue vcWKVC.currencyCode = currencyCode addChildViewController(vcWKVC) self.view.addSubview(vcWKVC.view) diff --git a/loafwallet/src/Controls/MenuButtonType.swift b/loafwallet/src/Controls/MenuButtonType.swift index 0fc8c44c7..78e9c7402 100644 --- a/loafwallet/src/Controls/MenuButtonType.swift +++ b/loafwallet/src/Controls/MenuButtonType.swift @@ -10,8 +10,8 @@ import UIKit enum MenuButtonType { case security - case support - case supportLF + case customerSupport + case supportGiveToLF case settings case lock @@ -19,9 +19,9 @@ enum MenuButtonType { switch self { case .security: return S.MenuButton.security - case .support: + case .customerSupport: return S.MenuButton.support - case .supportLF: + case .supportGiveToLF: return S.SupportLitecoinFoundation.title case .settings: return S.MenuButton.settings @@ -34,9 +34,9 @@ enum MenuButtonType { switch self { case .security: return #imageLiteral(resourceName: "Shield") - case .support: + case .customerSupport: return #imageLiteral(resourceName: "FaqFill") - case .supportLF: + case .supportGiveToLF: return #imageLiteral(resourceName: "buy_icon_gray") case .settings: return #imageLiteral(resourceName: "Settings") diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index be0458b8c..cabb3f522 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -9,6 +9,8 @@ import UIKit import LocalAuthentication import SwiftUI +import SafariServices + class ModalPresenter : Subscriber, Trackable { @@ -344,25 +346,26 @@ class ModalPresenter : Subscriber, Trackable { self?.presentSecurityCenter() } } - menu.didTapSupport = { [weak self, weak menu] in - menu?.dismiss(animated: true, completion: { - self?.messagePresenter.presenter = self?.topViewController - self?.messagePresenter.presentSupportCompose() - }) - } - menu.didTapSupportLF = { [weak self, weak menu] in + menu.didTapSupport = { [weak self, weak menu] in menu?.dismiss(animated: true, completion: { - self?.messagePresenter.presenter = self?.topViewController - self?.messagePresenter.presentSupportCompose() + + let urlString = "https://litecoinfoundation.zendesk.com/hc/en-us" + + guard let url = URL(string: urlString) else { return } + + let vc = SFSafariViewController(url: url) + self?.topViewController?.present(vc, animated: true, completion: nil) }) + } - - menu.didTapSupportLF = { [weak self, weak menu] in + + menu.didTapGiveSupportLF = { [weak self, weak menu] in menu?.dismiss(animated: true, completion: { self?.presentSupportLF() }) } + menu.didTapLock = { [weak self, weak menu] in menu?.dismiss(animated: true) { self?.store.trigger(name: .lock) diff --git a/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift b/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift index e9677ff8e..77bfedb54 100644 --- a/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift @@ -13,14 +13,14 @@ class MenuViewController : UIViewController, Trackable { //MARK: - Public var didTapSecurity: (() -> Void)? var didTapSupport: (() -> Void)? - var didTapSupportLF: (() -> Void)? + var didTapGiveSupportLF: (() -> Void)? var didTapSettings: (() -> Void)? var didTapLock: (() -> Void)? //MARK: - Private fileprivate let buttonHeight: CGFloat = 72.0 fileprivate let buttons: [MenuButton] = { - let types: [MenuButtonType] = [.security, .support, .supportLF, .settings, .lock] + let types: [MenuButtonType] = [.security, .customerSupport, .supportGiveToLF, .settings, .lock] return types.compactMap { return MenuButton(type: $0) } @@ -62,10 +62,10 @@ class MenuViewController : UIViewController, Trackable { switch button.type { case .security: didTapSecurity?() - case .support: + case .customerSupport: didTapSupport?() - case .supportLF: - didTapSupportLF?() + case .supportGiveToLF: + didTapGiveSupportLF?() case .settings: didTapSettings?() case .lock: From f07fc8b2d67803d1cfaa928c3cc1158d5a349eb7 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 18 Feb 2021 09:18:53 +0000 Subject: [PATCH 040/114] [Feature] Add animation when refreshing LTC price (#221) * Add animation when refreshing LTC price * Added log event for when user taps on the balance on the header --- loafwallet/TabBarViewController.swift | 23 ++++++++++++++++++++--- loafwallet/src/Constants/Constants.swift | 2 ++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/loafwallet/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index 1c52f3eac..0f7908b04 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -220,6 +220,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel } }) } + /// This is called when the price changes private func setBalances() { guard let rate = exchangeRate, let store = self.store, let isLTCSwapped = self.isLtcSwapped else { NSLog("ERROR: Rate, Store not initialized") @@ -266,15 +267,29 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel primaryLabel.transform = transform(forView: primaryLabel) } - self.timeStampLabel.text = S.TransactionDetails.priceTimeStampLabel + " " + dateFormatter.string(from: Date()) + // Time and Price Label + let timeText = S.TransactionDetails.priceTimeStampLabel + " " + dateFormatter.string(from: Date()) let fiatRate = Double(round(100*rate.rate)/100) let formattedFiatString = String(format: "%.02f", fiatRate) - self.currentLTCPriceLabel.text = Currency.getSymbolForCurrencyCode(code: rate.code)! + formattedFiatString + let newPrice = Currency.getSymbolForCurrencyCode(code: rate.code)! + formattedFiatString + self.currentLTCPriceLabel.text = " " + self.timeStampLabel.text = timeText + + // Transitions when the data changes + UIView.transition(with: self.currentLTCPriceLabel, + duration: 2.0, + options: .transitionFlipFromLeft, + animations: { [weak self] in + self?.currentLTCPriceLabel.text = newPrice + }, completion: nil) } + /// Transform LTC and Fiat Balances + /// - Parameter forView: Views + /// - Returns: the inverse transform private func transform(forView: UIView) -> CGAffineTransform { - forView.transform = .identity //Must reset the view's transform before we calculate the next transform + forView.transform = .identity let scaleFactor: CGFloat = smallFontSize/largeFontSize let deltaX = forView.frame.width * (1-scaleFactor) let deltaY = forView.frame.height * (1-scaleFactor) @@ -400,6 +415,8 @@ extension TabBarViewController { NSLayoutConstraint.activate(!isLTCSwapped ? self.swappedConstraints : self.regularConstraints) self.view.layoutIfNeeded() + LWAnalytics.logEventWithParameters(itemName: ._20200207_DTHB) + }) { _ in } store.perform(action: CurrencyChange.toggle()) } diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index a6f5cf93f..213a21fbc 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -37,6 +37,8 @@ enum CustomEvent: String { case _20201121_SIL = "STARTED_IFPS_LOOKUP" case _20201121_DRIA = "DID_RESOLVE_IPFS_ADDRESS" case _20201121_FRIA = "FAILED_RESOLVE_IPFS_ADDRESS" + case _20200207_DTHB = "DID_TAP_HEADER_BALANCE" + } struct FoundationSupport { From 26bca67617e650d241d549fdda9892bd7f5f1f77 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 18 Feb 2021 16:56:43 +0000 Subject: [PATCH 041/114] [Bugfix] Refactor transactions and missing details #172 (#220) * Began layout of new cell in transactions - Labeled combine variables * [Bugfix] Attempt to fix thunkee crash for Buy TableViewController * Added support elements for new layouts - Added HostingTransactionCell - Refactoring * [Tech Debt] Remove labels for BCH and BitID * Refactored code for the SwiftUI Transactions TableViewCell - Polished transaction details - Removed the old UITableViewCells (UIKit) - SwiftUI Used whenever available - Added supporting SwiftUI Views * Add copy data labels and localizations - SwiftUI layout polish - Add localizable * Remove dead timer code * Per comments * remove cruft per comments --- loafwallet.xcodeproj/project.pbxproj | 53 +- loafwallet/AnimatedCardView.swift | 1 + .../Assets.xcassets/Transaction/Contents.json | 6 +- .../down-chevron-green.imageset/Contents.json | 21 - .../down-chevron-green.png | Bin 21992 -> 0 bytes .../up-chevron-gray.imageset/Contents.json | 21 - .../up-chevron-gray.png | Bin 23943 -> 0 bytes loafwallet/BuyTableViewController.swift | 15 +- loafwallet/CardLoggedInView.swift | 1 + loafwallet/CardView.swift | 1 + loafwallet/CopyButtonView.swift | 38 ++ loafwallet/HostingTransactionCell.swift | 46 ++ loafwallet/PartnersView.swift | 1 + loafwallet/PromptTableViewCell.swift | 105 ++++ loafwallet/RegistrationView.swift | 1 + loafwallet/StandardDividerView.swift | 25 + .../Storyboards/Transactions.storyboard | 286 +---------- loafwallet/TransactionCellView.swift | 93 ++++ loafwallet/TransactionCellViewModel.swift | 119 +++++ loafwallet/TransactionModalView.swift | 250 ++++++++++ loafwallet/TransactionTableViewCells.swift | 311 ------------ loafwallet/TransactionsViewController.swift | 472 ++++++++---------- loafwallet/src/Constants/Strings.swift | 29 +- .../src/Extensions/String+Additions.swift | 6 +- .../Strings/Base.lproj/Localizable.strings | 57 +-- .../src/Strings/da.lproj/Localizable.strings | 57 +-- .../src/Strings/de.lproj/Localizable.strings | 57 +-- .../src/Strings/en.lproj/Localizable.strings | 57 +-- .../src/Strings/es.lproj/Localizable.strings | 57 +-- .../src/Strings/fr.lproj/Localizable.strings | 57 +-- .../src/Strings/id.lproj/Localizable.strings | 57 +-- .../src/Strings/it.lproj/Localizable.strings | 57 +-- .../src/Strings/ja.lproj/Localizable.strings | 57 +-- .../src/Strings/ko.lproj/Localizable.strings | 57 +-- .../src/Strings/nl.lproj/Localizable.strings | 57 +-- .../src/Strings/pt.lproj/Localizable.strings | 57 +-- .../src/Strings/ru.lproj/Localizable.strings | 57 +-- .../src/Strings/sv.lproj/Localizable.strings | 57 +-- .../Strings/zh-Hans.lproj/Localizable.strings | 69 +-- .../Strings/zh-Hant.lproj/Localizable.strings | 57 +-- loafwallet/src/ViewModels/Transaction.swift | 3 +- .../Views/TransactionCells/MaskedShadow.swift | 47 -- .../TransactionCells/RoundedContainer.swift | 45 -- .../TransactionTableViewCell.swift | 228 --------- 44 files changed, 1046 insertions(+), 2102 deletions(-) delete mode 100644 loafwallet/Assets.xcassets/Transaction/down-chevron-green.imageset/Contents.json delete mode 100644 loafwallet/Assets.xcassets/Transaction/down-chevron-green.imageset/down-chevron-green.png delete mode 100644 loafwallet/Assets.xcassets/Transaction/up-chevron-gray.imageset/Contents.json delete mode 100644 loafwallet/Assets.xcassets/Transaction/up-chevron-gray.imageset/up-chevron-gray.png create mode 100644 loafwallet/CopyButtonView.swift create mode 100644 loafwallet/HostingTransactionCell.swift create mode 100644 loafwallet/PromptTableViewCell.swift create mode 100644 loafwallet/StandardDividerView.swift create mode 100644 loafwallet/TransactionCellView.swift create mode 100644 loafwallet/TransactionCellViewModel.swift create mode 100644 loafwallet/TransactionModalView.swift delete mode 100644 loafwallet/TransactionTableViewCells.swift delete mode 100644 loafwallet/src/Views/TransactionCells/MaskedShadow.swift delete mode 100644 loafwallet/src/Views/TransactionCells/RoundedContainer.swift delete mode 100644 loafwallet/src/Views/TransactionCells/TransactionTableViewCell.swift diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index a0c49c0b5..1e7b26147 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 1991125B1B86B90CA24B7286 /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */; }; 1B3F74231FFB106200CCA50C /* BiometricsSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74211FFB106200CCA50C /* BiometricsSettingsViewController.swift */; }; 1B3F74241FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B3F74221FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift */; }; 1BA9FE3D216F68A700BB2DE8 /* BRBech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BA9FE3C216F68A700BB2DE8 /* BRBech32.c */; }; @@ -72,7 +71,7 @@ 24313C7B23820BC200A83F69 /* SendLTCViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C7923820BC200A83F69 /* SendLTCViewController.swift */; }; 24313C7E23820C1900A83F69 /* TransactionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C7C23820C1900A83F69 /* TransactionsViewController.swift */; }; 24313C8423820C4B00A83F69 /* ReceiveLTCViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C8223820C4B00A83F69 /* ReceiveLTCViewController.swift */; }; - 24313C8723821B8C00A83F69 /* TransactionTableViewCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C8523821B8C00A83F69 /* TransactionTableViewCells.swift */; }; + 24313C8723821B8C00A83F69 /* PromptTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C8523821B8C00A83F69 /* PromptTableViewCell.swift */; }; 24313C922382433700A83F69 /* LFModalReceiveQRViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C902382433700A83F69 /* LFModalReceiveQRViewController.swift */; }; 24313C9B23824F5800A83F69 /* Transactions.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9323824F5700A83F69 /* Transactions.storyboard */; }; 24313C9D23824F5800A83F69 /* Alerts.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9423824F5700A83F69 /* Alerts.storyboard */; }; @@ -267,8 +266,13 @@ 75C735AA1DAA1B9C00251ECF /* libunbound.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD4121DAA0E3E0075898E /* libunbound.c */; }; 92FB6A24C5F95B5239A226B4 /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AC86E61BB430C1275F605F8 /* Pods_loafwalletTests.framework */; }; BC40800031AC198047C76D8C /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D69FD9757DAE828E1DB3DC2D /* Pods_loafwallet.framework */; }; + C30029E225D0185500F08C2B /* StandardDividerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30029E125D0185500F08C2B /* StandardDividerView.swift */; }; + C30029EB25D019BC00F08C2B /* CopyButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30029EA25D019BC00F08C2B /* CopyButtonView.swift */; }; C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */ = {isa = PBXBuildFile; productRef = C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */; }; C30AFB642598FFB200CDCF69 /* PartnerAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */; }; + C32142EA25C97CD900BECCD0 /* TransactionCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32142E925C97CD900BECCD0 /* TransactionCellView.swift */; }; + C32142FA25C988C800BECCD0 /* TransactionCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32142F925C988C800BECCD0 /* TransactionCellViewModel.swift */; }; + C321442B25CC2B2C00BECCD0 /* TransactionModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C321442A25CC2B2C00BECCD0 /* TransactionModalView.swift */; }; C3270B99259BF7F20073DA7B /* LitecoinCardUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */; }; C32DAE0725925B7E003FC978 /* Color+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DAE0625925B7E003FC978 /* Color+Extension.swift */; }; C32DAE9125929492003FC978 /* CardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32DAE9025929492003FC978 /* CardViewController.swift */; }; @@ -297,6 +301,7 @@ C3BD4A5325975C6000D97079 /* View+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD4A5225975C6000D97079 /* View+Extension.swift */; }; C3BD4A6A2597E1E900D97079 /* CardLoggedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD4A692597E1E900D97079 /* CardLoggedInView.swift */; }; C3BFD349259E31C100136837 /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BFD348259E31C100136837 /* LoginViewModel.swift */; }; + C3C8973825CD6B9300241FBE /* HostingTransactionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C8973725CD6B9300241FBE /* HostingTransactionCell.swift */; }; C3D4379F2566EA3E00F423E1 /* LWActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */; }; C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */; }; C3D783B72565EA6B0004FF70 /* UnstoppableDomainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */; }; @@ -330,8 +335,6 @@ CE27F9591E2C8EA300F7F7F2 /* Amount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE27F9581E2C8EA300F7F7F2 /* Amount.swift */; }; CE29901A1EFD6DE50093A0F2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE29901C1EFD6DE50093A0F2 /* Localizable.strings */; }; CE36454C1E7B42850079D0CF /* PinPadCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE36454B1E7B42850079D0CF /* PinPadCells.swift */; }; - CE3754AD1DDE6E080045B0CB /* MaskedShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3754AC1DDE6E080045B0CB /* MaskedShadow.swift */; }; - CE3754AF1DDE6E2E0045B0CB /* RoundedContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3754AE1DDE6E2E0045B0CB /* RoundedContainer.swift */; }; CE3D4C571EF5D5740016B1C8 /* ReachabilityMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3D4C561EF5D5740016B1C8 /* ReachabilityMonitor.swift */; }; CE3D4C591EF743EF0016B1C8 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3D4C581EF743EF0016B1C8 /* Functions.swift */; }; CE44BA1B1F33BFC500392A1A /* NodeSelectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE44BA1A1F33BFC500392A1A /* NodeSelectorViewController.swift */; }; @@ -400,7 +403,6 @@ CEBF292E1EF99E55005C330A /* LightWeightAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBF292D1EF99E55005C330A /* LightWeightAlert.swift */; }; CEBF29301EF9D76F005C330A /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBF292F1EF9D76F005C330A /* Environment.swift */; }; CEBF32EE1DDBC30000348FC6 /* ShadowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBF32ED1DDBC30000348FC6 /* ShadowButton.swift */; }; - CEBF32F91DDD193500348FC6 /* TransactionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBF32F81DDD193500348FC6 /* TransactionTableViewCell.swift */; }; CEBF33041DDE17A600348FC6 /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBF33031DDE17A600348FC6 /* Transaction.swift */; }; CEC4CF071F0C48DD00E5C82E /* StartWipeWalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC4CF061F0C48DD00E5C82E /* StartWipeWalletViewController.swift */; }; CEC4CF091F0C84AB00E5C82E /* UIViewController+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC4CF081F0C84AB00E5C82E /* UIViewController+Alerts.swift */; }; @@ -750,7 +752,7 @@ 24313C7923820BC200A83F69 /* SendLTCViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendLTCViewController.swift; sourceTree = ""; }; 24313C7C23820C1900A83F69 /* TransactionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsViewController.swift; sourceTree = ""; }; 24313C8223820C4B00A83F69 /* ReceiveLTCViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiveLTCViewController.swift; sourceTree = ""; }; - 24313C8523821B8C00A83F69 /* TransactionTableViewCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionTableViewCells.swift; sourceTree = ""; }; + 24313C8523821B8C00A83F69 /* PromptTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromptTableViewCell.swift; sourceTree = ""; }; 24313C902382433700A83F69 /* LFModalReceiveQRViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LFModalReceiveQRViewController.swift; sourceTree = ""; }; 24313C9323824F5700A83F69 /* Transactions.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Transactions.storyboard; sourceTree = ""; }; 24313C9423824F5700A83F69 /* Alerts.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Alerts.storyboard; sourceTree = ""; }; @@ -1436,7 +1438,12 @@ 9AC86E61BB430C1275F605F8 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A3E5444354AB8914A966CDC2 /* Pods-loafwallet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.release.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.release.xcconfig"; sourceTree = ""; }; B1E980ED11476D536096EFFC /* Pods-loafwallet.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.testnet.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.testnet.xcconfig"; sourceTree = ""; }; + C30029E125D0185500F08C2B /* StandardDividerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardDividerView.swift; sourceTree = ""; }; + C30029EA25D019BC00F08C2B /* CopyButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyButtonView.swift; sourceTree = ""; }; C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnerAPIManager.swift; sourceTree = ""; }; + C32142E925C97CD900BECCD0 /* TransactionCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCellView.swift; sourceTree = ""; }; + C32142F925C988C800BECCD0 /* TransactionCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCellViewModel.swift; sourceTree = ""; }; + C321442A25CC2B2C00BECCD0 /* TransactionModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionModalView.swift; sourceTree = ""; }; C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LitecoinCardUser.swift; sourceTree = ""; }; C32DAE0625925B7E003FC978 /* Color+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = ""; }; C32DAE9025929492003FC978 /* CardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardViewController.swift; sourceTree = ""; }; @@ -1465,6 +1472,7 @@ C3BD4A5225975C6000D97079 /* View+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extension.swift"; sourceTree = ""; }; C3BD4A692597E1E900D97079 /* CardLoggedInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardLoggedInView.swift; sourceTree = ""; }; C3BFD348259E31C100136837 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = ""; }; + C3C8973725CD6B9300241FBE /* HostingTransactionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostingTransactionCell.swift; sourceTree = ""; }; C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LWActivityIndicator.swift; sourceTree = ""; }; C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainView.swift; sourceTree = ""; }; C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainViewModel.swift; sourceTree = ""; }; @@ -1509,8 +1517,6 @@ CE2990221EFD6F500093A0F2 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; CE2990231EFD6F5D0093A0F2 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; CE36454B1E7B42850079D0CF /* PinPadCells.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PinPadCells.swift; path = src/Views/PinPadCells/PinPadCells.swift; sourceTree = ""; }; - CE3754AC1DDE6E080045B0CB /* MaskedShadow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MaskedShadow.swift; path = src/Views/TransactionCells/MaskedShadow.swift; sourceTree = ""; }; - CE3754AE1DDE6E2E0045B0CB /* RoundedContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RoundedContainer.swift; path = src/Views/TransactionCells/RoundedContainer.swift; sourceTree = ""; }; CE3D4C561EF5D5740016B1C8 /* ReachabilityMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ReachabilityMonitor.swift; path = src/ReachabilityMonitor.swift; sourceTree = ""; }; CE3D4C581EF743EF0016B1C8 /* Functions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Functions.swift; path = src/Constants/Functions.swift; sourceTree = ""; }; CE44BA1A1F33BFC500392A1A /* NodeSelectorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NodeSelectorViewController.swift; path = src/ViewControllers/NodeSelectorViewController.swift; sourceTree = ""; }; @@ -1587,7 +1593,6 @@ CEBF292D1EF99E55005C330A /* LightWeightAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LightWeightAlert.swift; path = src/Views/LightWeightAlert.swift; sourceTree = ""; }; CEBF292F1EF9D76F005C330A /* Environment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Environment.swift; path = src/Environment.swift; sourceTree = ""; }; CEBF32ED1DDBC30000348FC6 /* ShadowButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShadowButton.swift; path = src/Views/ShadowButton.swift; sourceTree = ""; }; - CEBF32F81DDD193500348FC6 /* TransactionTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TransactionTableViewCell.swift; path = src/Views/TransactionCells/TransactionTableViewCell.swift; sourceTree = ""; }; CEBF33031DDE17A600348FC6 /* Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Transaction.swift; path = src/ViewModels/Transaction.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; CEC4CF061F0C48DD00E5C82E /* StartWipeWalletViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StartWipeWalletViewController.swift; path = src/ViewControllers/StartWipeWalletViewController.swift; sourceTree = ""; }; CEC4CF081F0C84AB00E5C82E /* UIViewController+Alerts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIViewController+Alerts.swift"; path = "src/Extensions/UIViewController+Alerts.swift"; sourceTree = ""; }; @@ -3066,6 +3071,17 @@ path = Modules/sqlite3; sourceTree = ""; }; + C32142E825C97CB900BECCD0 /* Transactions */ = { + isa = PBXGroup; + children = ( + C32142E925C97CD900BECCD0 /* TransactionCellView.swift */, + C3C8973725CD6B9300241FBE /* HostingTransactionCell.swift */, + C321442A25CC2B2C00BECCD0 /* TransactionModalView.swift */, + C32142F925C988C800BECCD0 /* TransactionCellViewModel.swift */, + ); + name = Transactions; + sourceTree = ""; + }; C3270B97259BF7BE0073DA7B /* CardModels */ = { isa = PBXGroup; children = ( @@ -3087,10 +3103,13 @@ C35ABD07257404C6002BB9BB /* SwiftUI+UIKit */ = { isa = PBXGroup; children = ( + C32142E825C97CB900BECCD0 /* Transactions */, C35ABD08257404D2002BB9BB /* Partners */, C35ABD0925740518002BB9BB /* About */, C3D783A52565EA1E0004FF70 /* Unstoppable */, C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */, + C30029E125D0185500F08C2B /* StandardDividerView.swift */, + C30029EA25D019BC00F08C2B /* CopyButtonView.swift */, ); name = "SwiftUI+UIKit"; sourceTree = ""; @@ -3395,10 +3414,7 @@ CEBF32F71DDD191300348FC6 /* TransactionCells */ = { isa = PBXGroup; children = ( - CEBF32F81DDD193500348FC6 /* TransactionTableViewCell.swift */, - 24313C8523821B8C00A83F69 /* TransactionTableViewCells.swift */, - CE3754AC1DDE6E080045B0CB /* MaskedShadow.swift */, - CE3754AE1DDE6E2E0045B0CB /* RoundedContainer.swift */, + 24313C8523821B8C00A83F69 /* PromptTableViewCell.swift */, ); name = TransactionCells; sourceTree = ""; @@ -4157,9 +4173,9 @@ CE74F58D1E3BA85600ED5FA9 /* ExchangeUpdater.swift in Sources */, 24313C7B23820BC200A83F69 /* SendLTCViewController.swift in Sources */, CE6DCC251E6001E50044257B /* UIControl+Callback.swift in Sources */, + C30029E225D0185500F08C2B /* StandardDividerView.swift in Sources */, 223DB2191DF691260076A151 /* BRSocketHelpers.c in Sources */, CEF3E82D1DE528BF007C0A9E /* AlertView.swift in Sources */, - CEBF32F91DDD193500348FC6 /* TransactionTableViewCell.swift in Sources */, CEF3E82B1DE51612007C0A9E /* GradientCircle.swift in Sources */, CE124CFE1E68F57700DFA146 /* Async.swift in Sources */, 2218BD771E8F55430091D5E8 /* BRAPIClient+Assets.swift in Sources */, @@ -4170,7 +4186,7 @@ CE5F21DB1E4A93A500C47B8E /* LoginTransitionDelegate.swift in Sources */, C354C45A258FA9C000675E0E /* MainTabBarViewModel.swift in Sources */, CEE659E91F664C73001FF29D /* WelcomeViewController.swift in Sources */, - 24313C8723821B8C00A83F69 /* TransactionTableViewCells.swift in Sources */, + 24313C8723821B8C00A83F69 /* PromptTableViewCell.swift in Sources */, 2228734F1E916FC30044BA15 /* BRAPIClient+Wallet.swift in Sources */, CEAA9EA81DC3342E0066731D /* PinView.swift in Sources */, CE1D84B61EAEB2F4002A5D7B /* UIBarButtonItem+Additions.swift in Sources */, @@ -4178,6 +4194,7 @@ CE4B6C1A1E219CA600CF935B /* WalletCoordinator.swift in Sources */, CE6D0E5C1E14BFA700137DF1 /* KeyboardNotificationInfo.swift in Sources */, CE20C8F21DBAF71500C8397A /* ApplicationController.swift in Sources */, + C32142EA25C97CD900BECCD0 /* TransactionCellView.swift in Sources */, 1B3F74231FFB106200CCA50C /* BiometricsSettingsViewController.swift in Sources */, CEC4CF071F0C48DD00E5C82E /* StartWipeWalletViewController.swift in Sources */, C32DC793259396AB00A7FDB4 /* CardViewModel.swift in Sources */, @@ -4189,6 +4206,7 @@ C35ABD232574070A002BB9BB /* PartnersView.swift in Sources */, CE03EC741EF256AC0038E3A8 /* SimpleUTXO.swift in Sources */, 24016D9023F913C1006A6791 /* LWAnalytics.swift in Sources */, + C3C8973825CD6B9300241FBE /* HostingTransactionCell.swift in Sources */, CE124CFC1E68932C00DFA146 /* FeeManager.swift in Sources */, CEE20C381EA5B4680086F724 /* Strings.swift in Sources */, 24AF0101221B349100FF636F /* WarningConfirmationViewController.swift in Sources */, @@ -4207,6 +4225,7 @@ 1B3F74241FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift in Sources */, CEC6F8451E886723000795B8 /* PaymentRequest.swift in Sources */, CE4C1CC81ED88B600063E184 /* URLController.swift in Sources */, + C30029EB25D019BC00F08C2B /* CopyButtonView.swift in Sources */, 24313C922382433700A83F69 /* LFModalReceiveQRViewController.swift in Sources */, CE20C9171DBE6F2A00C8397A /* UIButton+BRWAdditions.swift in Sources */, CEAA9E931DC110E70066731D /* WritePaperPhraseViewController.swift in Sources */, @@ -4278,7 +4297,6 @@ CEE20C341EA5B4550086F724 /* ArticleIds.swift in Sources */, CEE65DF01E39056F0002994D /* Rate.swift in Sources */, CEE20C361EA5B4620086F724 /* Constants.swift in Sources */, - CE3754AF1DDE6E2E0045B0CB /* RoundedContainer.swift in Sources */, CEC6AA461DEFCE9200EE5AFD /* MenuViewController.swift in Sources */, CEEC707F1E8D6B4100EF788E /* SettingsViewController.swift in Sources */, CEEE92F11EBA7CBA00B7AC9C /* RequestAmountViewController.swift in Sources */, @@ -4291,6 +4309,7 @@ CE124CF81E67A8E500DFA146 /* TransactionDirection.swift in Sources */, CE8CD8DD1E2D9EF200785E02 /* Sender.swift in Sources */, CE4DFB2C1E9BE5880014009E /* ReScanViewController.swift in Sources */, + C321442B25CC2B2C00BECCD0 /* TransactionModalView.swift in Sources */, CE8F0AE31EB91BB500AA7642 /* SearchHeaderView.swift in Sources */, 22A9A9551DF61945000F0016 /* BRTar.swift in Sources */, CEAA9E971DC18E1F0066731D /* PhraseView.swift in Sources */, @@ -4340,6 +4359,7 @@ C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */, C379F228259B9BF000B25883 /* RegistrationAlertView.swift in Sources */, CE3D4C571EF5D5740016B1C8 /* ReachabilityMonitor.swift in Sources */, + C32142FA25C988C800BECCD0 /* TransactionCellViewModel.swift in Sources */, 22A9A9571DF61945000F0016 /* BRWebSocket.swift in Sources */, CE4DFB2E1E9C26DA0014009E /* ShareDataViewController.swift in Sources */, CE1E5F261EF083A600BD0F72 /* StartImportViewController.swift in Sources */, @@ -4363,7 +4383,6 @@ CE9057181DFF0FA8006BA848 /* String+Additions.swift in Sources */, CED341331EF5A5C00014912A /* InAppAlert.swift in Sources */, CE47A8E01F7DA54000FF35BA /* UIScreen+Additions.swift in Sources */, - CE3754AD1DDE6E080045B0CB /* MaskedShadow.swift in Sources */, 222C42521E904C5000078EB5 /* AssociatedObject.swift in Sources */, CEB909F51E5FE63D001804DC /* EnterPhraseViewController.swift in Sources */, CE6D0F971DE8B73A00BD4BCF /* ModalTransitionDelegate.swift in Sources */, diff --git a/loafwallet/AnimatedCardView.swift b/loafwallet/AnimatedCardView.swift index a847d8452..2732945ba 100644 --- a/loafwallet/AnimatedCardView.swift +++ b/loafwallet/AnimatedCardView.swift @@ -10,6 +10,7 @@ import SwiftUI struct AnimatedCardView: View { + //MARK: - Combine Variables @ObservedObject var viewModel: AnimatedCardViewModel diff --git a/loafwallet/Assets.xcassets/Transaction/Contents.json b/loafwallet/Assets.xcassets/Transaction/Contents.json index da4a164c9..73c00596a 100644 --- a/loafwallet/Assets.xcassets/Transaction/Contents.json +++ b/loafwallet/Assets.xcassets/Transaction/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/loafwallet/Assets.xcassets/Transaction/down-chevron-green.imageset/Contents.json b/loafwallet/Assets.xcassets/Transaction/down-chevron-green.imageset/Contents.json deleted file mode 100644 index 1cdde2881..000000000 --- a/loafwallet/Assets.xcassets/Transaction/down-chevron-green.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "down-chevron-green.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet/Assets.xcassets/Transaction/down-chevron-green.imageset/down-chevron-green.png b/loafwallet/Assets.xcassets/Transaction/down-chevron-green.imageset/down-chevron-green.png deleted file mode 100644 index 1d7c93c60cc37f259e1d09b72b01c9a7983ee181..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21992 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: UITableViewCell { + private let hostingController = UIHostingController(rootView: nil) + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + hostingController.view.backgroundColor = .clear + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func set(rootView: Content, parentController: UIViewController) { + self.hostingController.rootView = rootView + self.hostingController.view.invalidateIntrinsicContentSize() + + let requiresControllerMove = hostingController.parent != parentController + if requiresControllerMove { + parentController.addChildViewController(hostingController) + } + + if !self.contentView.subviews.contains(hostingController.view) { + self.contentView.addSubview(hostingController.view) + hostingController.view.translatesAutoresizingMaskIntoConstraints = false + hostingController.view.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor).isActive = true + hostingController.view.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor).isActive = true + hostingController.view.topAnchor.constraint(equalTo: self.contentView.topAnchor).isActive = true + hostingController.view.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true + } + + if requiresControllerMove { + hostingController.didMove(toParent: parentController) + } + } +} diff --git a/loafwallet/PartnersView.swift b/loafwallet/PartnersView.swift index 2936a43ed..167dbfc23 100644 --- a/loafwallet/PartnersView.swift +++ b/loafwallet/PartnersView.swift @@ -10,6 +10,7 @@ import SwiftUI struct PartnersView: View { + //MARK: - Combine Variables @ObservedObject var viewModel: PartnerViewModel diff --git a/loafwallet/PromptTableViewCell.swift b/loafwallet/PromptTableViewCell.swift new file mode 100644 index 000000000..87d596ad9 --- /dev/null +++ b/loafwallet/PromptTableViewCell.swift @@ -0,0 +1,105 @@ +// +// PromptTableViewCell.swift +// loafwallet +// +// Created by Kerry Washington on 11/17/19. +// Copyright © 2019 Litecoin Foundation. All rights reserved. + +import UIKit +import LocalAuthentication + +class PromptTableViewCell : UITableViewCell { + + @IBOutlet weak var closeButton: UIButton! + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var bodyLabel: UILabel! + @IBOutlet weak var tapButton: UIButton! + + var type: PromptType? = nil + var didClose: (() -> ())? + var didTap: (() -> ())? + + @IBAction func didTapAction(_ sender: Any) { + didTap?() + } + + @IBAction func closeAction(_ sender: Any) { + didClose?() + } +} + +enum PromptType { + case biometrics + case paperKey + case upgradePin + case recommendRescan + case noPasscode + case shareData + + static var defaultOrder: [PromptType] = { + return [.recommendRescan, .upgradePin, .paperKey, .noPasscode, .biometrics, .shareData] + }() + + var title: String { + switch self { + case .biometrics: return LAContext.biometricType() == .face ? S.Prompts.FaceId.title : S.Prompts.TouchId.title + case .paperKey: return S.Prompts.PaperKey.title + case .upgradePin: return S.Prompts.SetPin.title + case .recommendRescan: return S.Prompts.RecommendRescan.title + case .noPasscode: return S.Prompts.NoPasscode.title + case .shareData: return S.Prompts.ShareData.title + } + } + + var name: String { + switch self { + case .biometrics: return "biometricsPrompt" + case .paperKey: return "paperKeyPrompt" + case .upgradePin: return "upgradePinPrompt" + case .recommendRescan: return "recommendRescanPrompt" + case .noPasscode: return "noPasscodePrompt" + case .shareData: return "shareDataPrompt" + } + } + + var body: String { + switch self { + case .biometrics: return LAContext.biometricType() == .face ? S.Prompts.FaceId.body : S.Prompts.TouchId.body + case .paperKey: return S.Prompts.PaperKey.body + case .upgradePin: return S.Prompts.SetPin.body + case .recommendRescan: return S.Prompts.RecommendRescan.body + case .noPasscode: return S.Prompts.NoPasscode.body + case .shareData: return S.Prompts.ShareData.body + } + } + + //This is the trigger that happens when the prompt is tapped + var trigger: TriggerName? { + switch self { + case .biometrics: return .promptBiometrics + case .paperKey: return .promptPaperKey + case .upgradePin: return .promptUpgradePin + case .recommendRescan: return .recommendRescan + case .noPasscode: return nil + case .shareData: return .promptShareData + } + } + + func shouldPrompt(walletManager: WalletManager, state: ReduxState) -> Bool { + + switch self { + case .biometrics: + return !UserDefaults.hasPromptedBiometrics && LAContext.canUseBiometrics && !UserDefaults.isBiometricsEnabled + case .paperKey: + return UserDefaults.walletRequiresBackup + case .upgradePin: + return walletManager.pinLength != 6 + case .recommendRescan: + return state.recommendRescan + case .noPasscode: + return !LAContext.isPasscodeEnabled + case .shareData: + return !UserDefaults.hasAquiredShareDataPermission && !UserDefaults.hasPromptedShareData + } + } +} diff --git a/loafwallet/RegistrationView.swift b/loafwallet/RegistrationView.swift index 456467e29..826fa22ba 100644 --- a/loafwallet/RegistrationView.swift +++ b/loafwallet/RegistrationView.swift @@ -10,6 +10,7 @@ import SwiftUI struct RegistrationView: View { + //MARK: - Combine Variables @ObservedObject var viewModel: RegistrationViewModel diff --git a/loafwallet/StandardDividerView.swift b/loafwallet/StandardDividerView.swift new file mode 100644 index 000000000..d28e58092 --- /dev/null +++ b/loafwallet/StandardDividerView.swift @@ -0,0 +1,25 @@ +// +// StandardDividerView.swift +// loafwallet +// +// Created by Kerry Washington on 2/7/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct StandardDividerView: View { + var body: some View { + Divider() + .frame(height: 2.0) + .foregroundColor(.black) + .padding([.leading, .trailing], 20) + } +} + +struct StandardDividerView_Previews: PreviewProvider { + static var previews: some View { + StandardDividerView() + } +} + diff --git a/loafwallet/Storyboards/Transactions.storyboard b/loafwallet/Storyboards/Transactions.storyboard index c67ae1f38..6c37e230b 100644 --- a/loafwallet/Storyboards/Transactions.storyboard +++ b/loafwallet/Storyboards/Transactions.storyboard @@ -1,9 +1,9 @@ - + - + @@ -11,15 +11,9 @@ BarlowSemiCondensed-Bold - - BarlowSemiCondensed-Light - BarlowSemiCondensed-Medium - - BarlowSemiCondensed-Regular - @@ -61,7 +55,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -393,6 +119,7 @@ + @@ -400,7 +127,6 @@ - @@ -412,10 +138,6 @@ - - - - diff --git a/loafwallet/TransactionCellView.swift b/loafwallet/TransactionCellView.swift new file mode 100644 index 000000000..8d52df8b3 --- /dev/null +++ b/loafwallet/TransactionCellView.swift @@ -0,0 +1,93 @@ +// +// TransactionCellView.swift +// loafwallet +// +// Created by Kerry Washington on 2/2/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + + +struct TransactionCellView: View { + + private let imageLength: CGFloat = 15.0 + + + //MARK: - Combine Variables + @ObservedObject + var viewModel: TransactionCellViewModel + + init(viewModel: TransactionCellViewModel) { + self.viewModel = viewModel + } + + var body: some View { + + VStack(alignment: .leading, spacing: 1.0) { + + //Send and Date Labels + HStack(alignment: .bottom, spacing: 1.0) { + + Text(viewModel.amountText) + .font(Font(UIFont.barlowSemiBold(size: 14.0))) + .foregroundColor(.black) + + Spacer() + + Image(systemName: viewModel.directionImageText) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: imageLength, + height: imageLength) + .foregroundColor(viewModel.directionArrowColor) + .padding(.trailing, 1.0) + + Text(viewModel.timedateText) + .font(Font(UIFont.barlowRegular(size: 13.0))) + .foregroundColor(Color.black) + .frame(width: 50.0, alignment: .trailing) + } + .padding([.leading,.trailing], 10.0) + + //Info and Direction arrow + HStack(alignment: .center, spacing: 1.0) { + + Text(viewModel.addressText) + .truncationMode(.middle) + .font(Font(UIFont.barlowRegular(size: 14.0))) + .foregroundColor(.black) + .frame(width: 180.0) + .lineLimit(1) + + Spacer() + + Image("modeDropArrow") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: imageLength + 4.0, + height: imageLength + 4.0) + .foregroundColor(.gray) + } + .padding([.leading,.trailing], 10.0) + + //Address + HStack(alignment: .top, spacing: 1.0) { + + Text(viewModel.transaction.status) + .font(Font(UIFont.barlowSemiBold(size: 13.0))) + .foregroundColor(.black) + + Spacer() + } + .padding([.leading,.trailing], 10.0) + .padding(.bottom,5.0) + + Divider() + .frame(height: 1.0) + .background(Color(UIColor.lightGray)) + .padding([.leading,.trailing], 10.0) + } + + } +} diff --git a/loafwallet/TransactionCellViewModel.swift b/loafwallet/TransactionCellViewModel.swift new file mode 100644 index 000000000..e2bc0af7f --- /dev/null +++ b/loafwallet/TransactionCellViewModel.swift @@ -0,0 +1,119 @@ +// +// TransactionCellViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 2/2/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI + +private let timestampRefreshRate: TimeInterval = 10.0 + +class TransactionCellViewModel: ObservableObject { + + //MARK: - Public Variables + var transaction: Transaction + + var isLtcSwapped: Bool + + var rate: Rate + + var maxDigits: Int + + var isSyncing: Bool + + var amountText: String = "" + + var feeText: String = "" + + var directionText: String = "" + + var directionImageText: String = "" + + var directionArrowColor: Color = .clear + + var addressText: String = "" + + var timedateText: String = "" + + var memoString: String = "" + + var qrImage = UIImage() + + //MARK: - Private Variables + private var timer: Timer? = nil + + init(transaction: Transaction, + isLtcSwapped: Bool, + rate: Rate, + maxDigits: Int, + isSyncing: Bool) { + + self.transaction = transaction + self.isLtcSwapped = isLtcSwapped + self.rate = rate + self.maxDigits = maxDigits + self.isSyncing = isSyncing + + loadVariables() + } + + @objc private func timerDidFire() { + updateTimestamp() + } + + private func updateTimestamp() { + + let timestampInfo = transaction.timeSince + + timedateText = timestampInfo.0 + if !timestampInfo.1 { + timer?.invalidate() + } + } + + deinit { + timer?.invalidate() + } + + private func loadVariables() { + + amountText = transaction.descriptionString(isLtcSwapped: isLtcSwapped, rate: rate, maxDigits: maxDigits).string + + feeText = transaction.amountDetails(isLtcSwapped: isLtcSwapped, rate: rate, rates: [rate], maxDigits: maxDigits) + + addressText = String(format: transaction.direction.addressTextFormat, transaction.toAddress ?? "") + + if self.transaction.direction == .sent { + directionImageText = "arrowtriangle.up.circle.fill" + directionArrowColor = Color(UIColor.litecoinOrange) + } else if self.transaction.direction == .received { + directionImageText = "arrowtriangle.down.circle.fill" + directionArrowColor = Color(UIColor.litecoinGreen) + } + + let timestampInfo = transaction.timeSince + timedateText = timestampInfo.0 + if timestampInfo.1 { + timer = Timer.scheduledTimer(timeInterval: timestampRefreshRate, target: self, selector: #selector(TransactionCellViewModel.timerDidFire), userInfo: nil, repeats: true) + } else { + timer?.invalidate() + } + + if let address = transaction.toAddress, + let data = address.data(using: .utf8), + let image = UIImage + .qrCode(data: data, + color: .black)? + .resize(CGSize(width: kQRImageSide, + height: kQRImageSide)) { + qrImage = image + } + + if let memo = self.transaction.comment { + memoString = memo + } + } +} diff --git a/loafwallet/TransactionModalView.swift b/loafwallet/TransactionModalView.swift new file mode 100644 index 000000000..98bc2a6a0 --- /dev/null +++ b/loafwallet/TransactionModalView.swift @@ -0,0 +1,250 @@ +// +// TransactionModalView.swift +// loafwallet +// +// Created by Kerry Washington on 2/4/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import SwiftUI +import UIKit + +private let qrImageSize = 180.0 + +struct TransactionModalView: View { + + @ObservedObject + var viewModel: TransactionCellViewModel + + let dataRowHeight: CGFloat = 65.0 + + @State + var isDisplayed: Bool = false + + @State + var didCopy: Bool = false + + @State + var copiedData: String = "" + + init(viewModel: TransactionCellViewModel) { + self.viewModel = viewModel + } + var body: some View { + + VStack(spacing: 1.0) { + HStack { + Text("Transaction Details") + .font(Font(UIFont.barlowSemiBold(size: 18.0))) + .foregroundColor(.white) + .frame(minWidth: 0, maxWidth: .infinity) + .padding() + } + .edgesIgnoringSafeArea(.all) + .background(Color(UIColor.liteWalletBlue)) + + + //MARK: Amount data + Group { + + VStack(alignment: .leading) { + + Text(S.Transaction.amountDetailLabel) + .font(Font(UIFont.barlowSemiBold(size: 16.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + .padding(.top, 5.0) + + HStack { + + Text(viewModel.feeText) + .font(Font(UIFont.barlowRegular(size: 15.0))) + .lineLimit(3) + .scaledToFill() + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + .padding(.top, 10.0) + + Spacer() + + CopyButtonView(idString: viewModel.amountText) + .padding(.trailing, 20.0) + } + .padding(.top, 1.0) + .padding(.bottom, 5.0) + + StandardDividerView() + } + .padding(.bottom, 2.0) + + + VStack(alignment: .leading, spacing: 1.0) { + + Text(S.Confirmation.staticAddressLabel.capitalized(with: Locale.current)) + .font(Font(UIFont.barlowSemiBold(size: 16.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + .padding(.top, 5.0) + + HStack { + + Text(viewModel.addressText) + .font(Font(UIFont.barlowRegular(size: 15.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + + Spacer() + + CopyButtonView(idString: viewModel.addressText) + .padding(.trailing, 20.0) + } + .padding(.bottom, 2.0) + StandardDividerView() + } + .frame(height: dataRowHeight) + } + + //MARK: Transaction data + Group { + + VStack(alignment: .leading, spacing: 1.0) { + + Text(S.Transaction.txIDLabel) + .font(Font(UIFont.barlowSemiBold(size: 16.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + .padding(.top, 5.0) + + HStack { + + Text(viewModel.transaction.hash) + .font(Font(UIFont.barlowLight(size: 9.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + .padding(.trailing, 40.0) + + Spacer() + + CopyButtonView(idString: viewModel.transaction.hash) + .padding(.trailing, 20.0) + } + .padding(.bottom, 2.0) + + StandardDividerView() + } + .frame(height: dataRowHeight) + + VStack(alignment: .leading, spacing: 1.0) { + + Text(S.Transaction.commentLabel) + .font(Font(UIFont.barlowSemiBold(size: 16.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + .padding(.top, 5.0) + + HStack { + + Text(viewModel.memoString) + .font(Font(UIFont.barlowRegular(size: 15.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + + Spacer() + + if viewModel.memoString != "" { + CopyButtonView(idString: viewModel.memoString) + .padding(.trailing, 20.0) + } + } + .padding(.bottom, 2.0) + + StandardDividerView() + } + .frame(height: dataRowHeight) + + VStack(alignment: .leading, spacing: 1.0) { + + Text(S.TransactionDetails.blockHeightLabel + ":") + .font(Font(UIFont.barlowSemiBold(size: 16.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + .padding(.top, 5.0) + + HStack { + + Text(viewModel.transaction.blockHeight) + .font(Font(UIFont.barlowRegular(size: 15.0))) + .foregroundColor(Color(UIColor.darkGray)) + .padding(.leading, 20.0) + + Spacer() + + CopyButtonView(idString: viewModel.transaction.blockHeight) + .padding(.trailing, 20.0) + } + .padding(.bottom, 2.0) + + StandardDividerView() + } + .frame(height: dataRowHeight) + } + + //MARK: QR Image + Group { + + Spacer() + + VStack(alignment: .center, spacing: 1.0) { + + Image(uiImage: viewModel.qrImage) + .frame(width: kQRImageSide, + height: kQRImageSide, + alignment: .center).padding(.all, 2.0) + + Text(viewModel.addressText) + .font(Font(UIFont.barlowLight(size: 13.0))) + .foregroundColor(.black) + .frame(alignment: .center).padding(.all, 2.0) + } + .padding(.all, 8.0) + + Spacer() + } + + //MARK: Copy All Button + Group { + + Spacer() + + VStack(alignment: .center, spacing: 1.0) { + + Button(action: { + copiedData = "Amount:\(viewModel.amountText)\n\nFee:\(viewModel.feeText)\n\nAddress:\(viewModel.addressText)\n\nTxID: \(viewModel.transaction.hash)" + UIPasteboard.general.string = copiedData + + }) { + + Text(copiedData == "" ? S.TransactionDetails.copyAllDetails : S.TransactionDetails.copiedAll) + .animation(.easeInOut(duration: 1.0)) + .font(Font(UIFont.barlowSemiBold(size: 20.0))) + .padding(.all, 10.0) + .foregroundColor(.white) + .background(Color(UIColor.liteWalletBlue)) + .cornerRadius(4.0) + .overlay( + RoundedRectangle(cornerRadius: 4.0) + .stroke(Color(UIColor.liteWalletBlue)) + ) + } + } + .padding(.all, 8.0) + + Spacer() + } + + Spacer() + } + + } +} + diff --git a/loafwallet/TransactionTableViewCells.swift b/loafwallet/TransactionTableViewCells.swift deleted file mode 100644 index c5284758d..000000000 --- a/loafwallet/TransactionTableViewCells.swift +++ /dev/null @@ -1,311 +0,0 @@ -// -// TransactionTableViewCells.swift -// loafwallet -// -// Created by Kerry Washington on 11/17/19. -// Copyright © 2019 Litecoin Foundation. All rights reserved. - -import UIKit -import LocalAuthentication - -private let timestampRefreshRate: TimeInterval = 10.0 -let kNormalTransactionCellHeight: CGFloat = 70.0 -let kMaxTransactionCellHeight: CGFloat = 220.0 -let kProgressHeaderHeight: CGFloat = 50.0 -let kPromptCellHeight : CGFloat = 120.0 - -class TransactionTableViewCellv2 : UITableViewCell, Subscriber { - - @IBOutlet weak var staticCommentLabel: UILabel! - @IBOutlet weak var amountLabel: UILabel! - @IBOutlet weak var availabilityLabel: UILabel! - @IBOutlet weak var addressLabel: UILabel! - @IBOutlet weak var commentTextLabel: UILabel! - @IBOutlet weak var timedateLabel: UILabel! - @IBOutlet weak var arrowImageView: UIImageView! - @IBOutlet weak var staticTxIDLabel: UILabel! - @IBOutlet weak var txidStringLabel: UILabel! - @IBOutlet weak var staticAmountDetailLabel: UILabel! - @IBOutlet weak var startingBalanceLabel: UILabel! - @IBOutlet weak var endingBalanceLabel: UILabel! - @IBOutlet weak var staticBlockLabel: UILabel! - @IBOutlet weak var blockLabel: UILabel! - @IBOutlet weak var qrModalButton: UIButton! - @IBOutlet weak var cardView: UIView! - @IBOutlet weak var staticBackgroundView: UIView! - @IBOutlet weak var statusLabel: UILabel! - @IBOutlet weak var copyButton: UIButton! - - - @IBOutlet weak var dropArrowImageView: UIImageView! - @IBOutlet weak var expandCardView: UIView! - @IBOutlet weak var qrBackgroundView: UIView! - - var didReceiveLitecoin: Bool? - var showQRModalAction: (() -> ())? - var expandCell: (() -> Bool)? - var isExpanded: Bool = false - private var timer: Timer? = nil - private var transaction: Transaction? - - private class TransactionCellWrapper { - weak var target: TransactionTableViewCellv2? - init(target: TransactionTableViewCellv2) { - self.target = target - } - - @objc func timerDidFire() { - target?.updateTimestamp() - } - } - - @IBAction func didTapCopy(_ sender: Any) { - guard let transactionAddress = transaction?.toAddress else { - NSLog("ERROR: Address not set") - return - } - - UIPasteboard.general.string = transactionAddress - } - - //MARK: - Public - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupViews() - } - - deinit { - timer?.invalidate() - } - - func updateTimestamp() { - guard let tx = transaction else { return } - let timestampInfo = tx.timeSince - timedateLabel.text = timestampInfo.0 - if !timestampInfo.1 { - timer?.invalidate() - } - } - - func setupViews() { - //TODO: polish when successful compiling happens - - staticTxIDLabel.text = S.Transaction.txIDLabel.lowercased() - staticAmountDetailLabel.text = S.Transaction.amountDetailLabel.lowercased() - staticBlockLabel.text = S.Transaction.blockHeightLabel.lowercased() - staticCommentLabel.text = S.Transaction.commentLabel.lowercased() - - self.backgroundColor = .white - staticBackgroundView.backgroundColor = .liteWalletBlue - qrModalButton.setImage(UIImage(named: "genericqricon"), for: .normal) - } - - func setTransaction(_ transaction: Transaction, isLtcSwapped: Bool, rate: Rate, maxDigits: Int, isSyncing: Bool) { - - self.transaction = transaction - expandCardView.alpha = 0.0 - - amountLabel.attributedText = transaction.descriptionString(isLtcSwapped: isLtcSwapped, rate: rate, maxDigits: maxDigits) - addressLabel.text = String(format: transaction.direction.addressTextFormat, transaction.toAddress ?? "") - statusLabel.text = transaction.status - commentTextLabel.text = transaction.comment - blockLabel.text = transaction.blockHeight - txidStringLabel.text = transaction.hash - availabilityLabel.text = transaction.shouldDisplayAvailableToSpend ? S.Transaction.available : "" - arrowImageView.image = UIImage(named: "black-circle-arrow-right")?.withRenderingMode(.alwaysTemplate) - startingBalanceLabel.text = transaction.amountDetailsStartingBalanceString(isLtcSwapped: isLtcSwapped, rate: rate, rates: [rate], maxDigits: maxDigits) - endingBalanceLabel.text = transaction.amountDetailsEndingBalanceString(isLtcSwapped: isLtcSwapped, rate: rate, rates: [rate], maxDigits: maxDigits) - dropArrowImageView.image = UIImage(named: "modeDropArrow") - - if #available(iOS 11.0, *) { - - guard let textColor = UIColor(named: "labelTextColor") else { - NSLog("ERROR: Custom color not found") - return - } - - guard let backgroundColor = UIColor(named: "inverseBackgroundViewColor") else { - NSLog("ERROR: Custom color not found") - return - } - - amountLabel.textColor = textColor - addressLabel.textColor = textColor - commentTextLabel.textColor = textColor - statusLabel.textColor = textColor - timedateLabel.textColor = textColor - - staticCommentLabel.textColor = textColor - staticTxIDLabel.textColor = textColor - staticAmountDetailLabel.textColor = textColor - staticBlockLabel.textColor = textColor - - qrBackgroundView.backgroundColor = backgroundColor - - } else { - commentTextLabel.textColor = .darkText - statusLabel.textColor = .darkText - timedateLabel.textColor = .darkText - - staticCommentLabel.textColor = .darkText - staticTxIDLabel.textColor = .darkText - staticAmountDetailLabel.textColor = .darkText - staticBlockLabel.textColor = .darkText - - qrBackgroundView.backgroundColor = .white - } - - if transaction.status == S.Transaction.complete { - statusLabel.isHidden = false - } else { - statusLabel.isHidden = isSyncing - } - - let timestampInfo = transaction.timeSince - timedateLabel.text = timestampInfo.0 - if timestampInfo.1 { - timer = Timer.scheduledTimer(timeInterval: timestampRefreshRate, target: TransactionCellWrapper(target: self), selector: NSSelectorFromString("timerDidFire"), userInfo: nil, repeats: true) - } else { - timer?.invalidate() - } - timedateLabel.isHidden = !transaction.isValid - - let identity: CGAffineTransform = .identity - if transaction.direction == .received { - arrowImageView.transform = identity.rotated(by: π/2.0) - arrowImageView.tintColor = .txListGreen - } else { - arrowImageView.transform = identity.rotated(by: 3.0*π/2.0) - arrowImageView.tintColor = .cameraGuideNegative - } - - if transaction.direction == .received { - qrModalButton.isHidden = false - } else { - qrModalButton.isHidden = true - } - } - - override func setSelected(_ selected: Bool, animated: Bool) { - - - } - - override func setHighlighted(_ highlighted: Bool, animated: Bool) { - - } - - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - } - - @IBAction func didTapQRButtonAction(_ sender: Any) { - showQRModalAction?() - } -} - -enum PromptType { - case biometrics - case paperKey - case upgradePin - case recommendRescan - case noPasscode - case shareData - - static var defaultOrder: [PromptType] = { - return [.recommendRescan, .upgradePin, .paperKey, .noPasscode, .biometrics, .shareData] - }() - - - var title: String { - switch self { - case .biometrics: return LAContext.biometricType() == .face ? S.Prompts.FaceId.title : S.Prompts.TouchId.title - case .paperKey: return S.Prompts.PaperKey.title - case .upgradePin: return S.Prompts.SetPin.title - case .recommendRescan: return S.Prompts.RecommendRescan.title - case .noPasscode: return S.Prompts.NoPasscode.title - case .shareData: return S.Prompts.ShareData.title - } - } - - var name: String { - switch self { - case .biometrics: return "biometricsPrompt" - case .paperKey: return "paperKeyPrompt" - case .upgradePin: return "upgradePinPrompt" - case .recommendRescan: return "recommendRescanPrompt" - case .noPasscode: return "noPasscodePrompt" - case .shareData: return "shareDataPrompt" - } - } - - var body: String { - switch self { - case .biometrics: return LAContext.biometricType() == .face ? S.Prompts.FaceId.body : S.Prompts.TouchId.body - case .paperKey: return S.Prompts.PaperKey.body - case .upgradePin: return S.Prompts.SetPin.body - case .recommendRescan: return S.Prompts.RecommendRescan.body - case .noPasscode: return S.Prompts.NoPasscode.body - case .shareData: return S.Prompts.ShareData.body - } - } - - //This is the trigger that happens when the prompt is tapped - var trigger: TriggerName? { - switch self { - case .biometrics: return .promptBiometrics - case .paperKey: return .promptPaperKey - case .upgradePin: return .promptUpgradePin - case .recommendRescan: return .recommendRescan - case .noPasscode: return nil - case .shareData: return .promptShareData - } - } - - func shouldPrompt(walletManager: WalletManager, state: ReduxState) -> Bool { - - switch self { - case .biometrics: - return !UserDefaults.hasPromptedBiometrics && LAContext.canUseBiometrics && !UserDefaults.isBiometricsEnabled - case .paperKey: - return UserDefaults.walletRequiresBackup - case .upgradePin: - return walletManager.pinLength != 6 - case .recommendRescan: - return state.recommendRescan - case .noPasscode: - return !LAContext.isPasscodeEnabled - case .shareData: - return !UserDefaults.hasAquiredShareDataPermission && !UserDefaults.hasPromptedShareData - } - } -} - - -class PromptTableViewCell : UITableViewCell { - - @IBOutlet weak var closeButton: UIButton! - @IBOutlet weak var titleLabel: UILabel! - @IBOutlet weak var bodyLabel: UILabel! - @IBOutlet weak var tapButton: UIButton! - - var type: PromptType? = nil - var didClose: (() -> ())? - var didTap: (() -> ())? - - @IBAction func didTapAction(_ sender: Any) { - didTap?() - } - - @IBAction func closeAction(_ sender: Any) { - didClose?() - } - - override func awakeFromNib() { - super.awakeFromNib() - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - } -} diff --git a/loafwallet/TransactionsViewController.swift b/loafwallet/TransactionsViewController.swift index f330b5b1a..73ac639e1 100644 --- a/loafwallet/TransactionsViewController.swift +++ b/loafwallet/TransactionsViewController.swift @@ -10,8 +10,11 @@ import UIKit import SwiftUI import LocalAuthentication -private let promptDelay: TimeInterval = 0.6 -private let qrImageSize = 120.0 +private let promptDelay: TimeInterval = 0.6 +let kNormalTransactionCellHeight: CGFloat = 65.0 +let kProgressHeaderHeight: CGFloat = 50.0 +let kPromptCellHeight : CGFloat = 120.0 +let kQRImageSide: CGFloat = 110.0 class TransactionsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, Subscriber, Trackable { @@ -30,6 +33,7 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable transactions = allTransactions } } + private var rate: Rate? { didSet { reload() } } @@ -47,11 +51,11 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable } } } + var isLtcSwapped: Bool? { didSet { reload() } } - override func viewDidLoad() { setup() addSubscriptions() @@ -64,9 +68,11 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable assertionFailure("PEER MAANAGER Not initialized") return } - + self.tableView.register(HostingTransactionCell.self, forCellReuseIdentifier: "HostingTransactionCell") self.transactions = TransactionManager.sharedInstance.transactions self.rate = TransactionManager.sharedInstance.rate + + tableView.backgroundColor = .liteWalletBlue initSyncingHeaderView(completion: {}) attemptShowPrompt() @@ -78,110 +84,7 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable options: nil)?.first as? SyncProgressHeaderView completion() } - - private func addSubscriptions() { - - guard let store = self.store else { - NSLog("ERROR: Store not initialized") - return - } - - store.subscribe(self, selector: { $0.walletState.transactions != $1.walletState.transactions }, - callback: { state in - self.allTransactions = state.walletState.transactions - self.reload() - }) - - store.subscribe(self, selector: { $0.isLtcSwapped != $1.isLtcSwapped }, - callback: { self.isLtcSwapped = $0.isLtcSwapped }) - store.subscribe(self, selector: { $0.currentRate != $1.currentRate}, - callback: { self.rate = $0.currentRate }) - store.subscribe(self, selector: { $0.maxDigits != $1.maxDigits }, callback: {_ in - self.reload() - }) - - store.subscribe(self, selector: { $0.walletState.syncProgress != $1.walletState.syncProgress }, - callback: { state in - store.subscribe(self, name:.showStatusBar) { (didShowStatusBar) in - self.reload() //May fix where the action view persists after confirming pin - } - - if state.walletState.isRescanning { - self.initSyncingHeaderView(completion: { - self.syncingHeaderView?.isRescanning = state.walletState.isRescanning - self.syncingHeaderView?.progress = CGFloat(state.walletState.syncProgress) - self.syncingHeaderView?.headerMessage = state.walletState.syncState - self.syncingHeaderView?.noSendImageView.alpha = 1.0 - self.syncingHeaderView?.timestamp = state.walletState.lastBlockTimestamp - self.shouldBeSyncing = true - }) - } else if state.walletState.syncProgress > 0.95 { - self.shouldBeSyncing = false - self.syncingHeaderView = nil - } else { - self.initSyncingHeaderView(completion: { - self.syncingHeaderView?.progress = CGFloat(state.walletState.syncProgress) - self.syncingHeaderView?.headerMessage = state.walletState.syncState - self.syncingHeaderView?.timestamp = state.walletState.lastBlockTimestamp - self.syncingHeaderView?.noSendImageView.alpha = 0.0 - self.shouldBeSyncing = true - }) - } - self.reload() - }) - - store.subscribe(self, selector: { $0.walletState.syncState != $1.walletState.syncState }, - callback: { state in - guard let _ = self.walletManager?.peerManager else { - assertionFailure("PEER MANAGER Not initialized") - return - } - - if state.walletState.syncState == .success { - self.shouldBeSyncing = false - self.syncingHeaderView = nil - } - self.reload() - }) - - store.subscribe(self, selector: { $0.recommendRescan != $1.recommendRescan }, callback: { _ in - self.attemptShowPrompt() - }) - store.subscribe(self, selector: { $0.walletState.syncState != $1.walletState.syncState }, callback: { _ in - self.reload() - }) - store.subscribe(self, name: .didUpgradePin, callback: { _ in - if self.currentPromptType == .upgradePin { - self.currentPromptType = nil - } - }) - store.subscribe(self, name: .didEnableShareData, callback: { _ in - if self.currentPromptType == .shareData { - self.currentPromptType = nil - } - }) - store.subscribe(self, name: .didWritePaperKey, callback: { _ in - if self.currentPromptType == .paperKey { - self.currentPromptType = nil - } - }) - - store.subscribe(self, name: .didUpgradePin, callback: { _ in - print("DidUpgragePIN") - }) - - store.subscribe(self, name: .didWritePaperKey, callback: { _ in - print("DidWritePaperKey") - }) - store.subscribe(self, name: .txMemoUpdated(""), callback: { - guard let trigger = $0 else { return } - if case .txMemoUpdated(let txHash) = trigger { - self.reload(txHash: txHash) - } - }) - reload() - } - + private func attemptShowPrompt() { guard let walletManager = walletManager else { return } guard let store = self.store else { @@ -209,78 +112,31 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable self.tableView.reloadData() } } - - private func reload(txHash: String) { - self.transactions.enumerated().forEach { i, tx in - if tx.hash == txHash { - DispatchQueue.main.async { - self.tableView.beginUpdates() - self.tableView.reloadRows(at: [IndexPath(row: i, section: self.hasExtraSection ? 1 : 0)], with: .automatic) - self.tableView.endUpdates() - } - } - } - } - func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - - if shouldBeSyncing { - return self.syncingHeaderView - } - return nil - } - - func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - if shouldBeSyncing { return kProgressHeaderHeight } - return 0.0 - } - - // MARK: - Table view data source - func numberOfSections(in tableView: UITableView) -> Int { - return hasExtraSection ? 2 : 1 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - - if hasExtraSection && section == 0 { - return 1 - } else { - if transactions.count > 0 { - self.tableView.backgroundView = nil - return transactions.count - } else { - self.tableView.backgroundView = emptyMessageView() - self.tableView.separatorStyle = .none - return 0 - } - } - } - - func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - - if hasExtraSection && indexPath.section == 0 { - return kPromptCellHeight - } else { - if cellIsSelected(indexPath: indexPath) { - return kMaxTransactionCellHeight - } else { - return kNormalTransactionCellHeight - } - } - } - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if hasExtraSection && indexPath.section == 0 { return configurePromptCell(promptType: currentPromptType, indexPath: indexPath) } else { let transaction = transactions[indexPath.row] - let selectedIndex = selectedIndexes[indexPath] as? Bool - return configureTransactionCell(transaction: transaction, wasSelected: selectedIndex ?? false, indexPath: indexPath) + + guard let cell = tableView.dequeueReusableCell(withIdentifier: "HostingTransactionCell", for: indexPath) as? HostingTransactionCell else { + NSLog("ERROR No cell found") + return UITableViewCell() + } + + if let rate = rate, + let store = self.store, + let isLtcSwapped = self.isLtcSwapped { + let viewModel = TransactionCellViewModel(transaction: transaction, isLtcSwapped: isLtcSwapped, rate: rate, maxDigits: store.state.maxDigits, isSyncing: store.state.walletState.syncState != .success) + cell.set(rootView: TransactionCellView(viewModel: viewModel), parentController: self) + cell.selectionStyle = .default + } + + return cell } } - private func configurePromptCell(promptType: PromptType?, indexPath: IndexPath) -> PromptTableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "PromptTVC2", for: indexPath) as? PromptTableViewCell else { NSLog("ERROR No cell found") @@ -308,89 +164,25 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable return cell } - - private func configureTransactionCell(transaction:Transaction?, wasSelected: Bool?, indexPath: IndexPath) -> TransactionTableViewCellv2 { - - //TODO: Polish animation based on 'wasSelected' + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - guard let cell = tableView.dequeueReusableCell(withIdentifier: "TransactionTVC2", for: indexPath) as? TransactionTableViewCellv2 else { - NSLog("ERROR: No cell found") - return TransactionTableViewCellv2() - } + let transaction = transactions[indexPath.row] - if let transaction = transaction { - if transaction.direction == .received { - cell.showQRModalAction = { [unowned self] in - - if let addressString = transaction.toAddress, - let qrImage = UIImage.qrCode(data: addressString.data(using: .utf8) ?? Data(), color: CIColor(color: .black))?.resize(CGSize(width: qrImageSize, height: qrImageSize)), - let receiveLTCtoAddressModal = UIStoryboard.init(name: "Alerts", bundle: nil).instantiateViewController(withIdentifier: "LFModalReceiveQRViewController") as? LFModalReceiveQRViewController { - - receiveLTCtoAddressModal.providesPresentationContextTransitionStyle = true - receiveLTCtoAddressModal.definesPresentationContext = true - receiveLTCtoAddressModal.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext - receiveLTCtoAddressModal.modalTransitionStyle = UIModalTransitionStyle.crossDissolve - receiveLTCtoAddressModal.dismissQRModalAction = { [unowned self] in - self.dismiss(animated: true, completion: nil) - } - self.present(receiveLTCtoAddressModal, animated: true) { - receiveLTCtoAddressModal.receiveModalTitleLabel.text = S.TransactionDetails.receiveModaltitle - receiveLTCtoAddressModal.addressLabel.text = addressString - receiveLTCtoAddressModal.qrImageView.image = qrImage - } - } - } - } - - if let rate = rate, - let store = self.store, - let isLtcSwapped = self.isLtcSwapped { - cell.setTransaction(transaction, isLtcSwapped: isLtcSwapped, rate: rate, maxDigits: store.state.maxDigits, isSyncing: store.state.walletState.syncState != .success) - } + if let rate = rate, + let store = self.store, + let isLtcSwapped = self.isLtcSwapped { - cell.staticBlockLabel.text = S.TransactionDetails.blockHeightLabel - cell.staticCommentLabel.text = S.TransactionDetails.commentsHeader - cell.staticAmountDetailLabel.text = S.Transaction.amountDetailLabel - } - else { - assertionFailure("Transaction must exist") - } - return cell - } - - private func cellIsSelected(indexPath: IndexPath) -> Bool { - - let cellIsSelected = selectedIndexes[indexPath] as? Bool ?? false - return cellIsSelected - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - - tableView.deselectRow(at: indexPath, animated: true) - tableView.beginUpdates() - let isSelected = !self.cellIsSelected(indexPath: indexPath) - let selectedIndex = NSNumber(value: isSelected) - selectedIndexes[indexPath] = selectedIndex - - if let selectedCell = tableView.cellForRow(at: indexPath) as? TransactionTableViewCellv2 { - - let identity: CGAffineTransform = .identity + let viewModel = TransactionCellViewModel(transaction: transaction, isLtcSwapped: isLtcSwapped, rate: rate, maxDigits: store.state.maxDigits, isSyncing: store.state.walletState.syncState != .success) - if isSelected { - let newAlpha = 1.0 - UIView.animate(withDuration: 0.1, delay: 0.0, animations: { - selectedCell.expandCardView.alpha = CGFloat(newAlpha) - selectedCell.dropArrowImageView.transform = identity.rotated(by: π) - }) - } else { - let newAlpha = 0.0 - UIView.animate(withDuration: 0.1, delay: 0.0, animations: { - selectedCell.expandCardView.alpha = CGFloat(newAlpha) - selectedCell.dropArrowImageView.transform = identity.rotated(by: -4.0*π/2.0) - }) - } + let hostingController = UIHostingController(rootView: TransactionModalView(viewModel: viewModel)) + + hostingController.modalPresentationStyle = .formSheet + + self.present(hostingController, animated: true) { + tableView.cellForRow(at: indexPath)?.isSelected = false + } } - tableView.endUpdates() } private func emptyMessageView() -> UILabel { @@ -407,22 +199,168 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable return messageLabel } } - -//struct TransactionsSwiftUIView: UIViewControllerRepresentable { -// -// -// -// typealias UIViewControllerType = TransactionsViewController -// -// -// -// func makeUIViewController(context: UIViewControllerRepresentableContext) -> TransactionsSwiftUIView.UIViewControllerType { -// let viewModel = TransactionsViewModel(store: Store(), walletManager: WalletManager(store: Store())) -// -// return TransactionsViewController(viewModel: viewModel, store: ) -// } -// -// func updateUIViewController(_ uiViewController: TransactionsSwiftUIView.UIViewControllerType, context: UIViewControllerRepresentableContext) { -// // -// } -//} + +extension TransactionsViewController { + + // MARK: - Table view delegate source + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + + if hasExtraSection && indexPath.section == 0 { + return kPromptCellHeight + } else { + return kNormalTransactionCellHeight + } + } + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + + if shouldBeSyncing { + return self.syncingHeaderView + } + return nil + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + if shouldBeSyncing { return kProgressHeaderHeight } + return 0.0 + } + + + func numberOfSections(in tableView: UITableView) -> Int { + return hasExtraSection ? 2 : 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + + if hasExtraSection && section == 0 { + return 1 + } else { + if transactions.count > 0 { + self.tableView.backgroundView = nil + return transactions.count + } else { + self.tableView.backgroundView = emptyMessageView() + self.tableView.separatorStyle = .none + return 0 + } + } + } + + /// Update displayed transactions. Used mainly when the database needs an update + /// - Parameter txHash: String reprsentation of the TX + private func updateTransactions(txHash: String) { + self.transactions.enumerated().forEach { i, tx in + if tx.hash == txHash { + DispatchQueue.main.async { + self.tableView.beginUpdates() + + self.tableView.reloadRows(at: [IndexPath(row: i, section: self.hasExtraSection ? 1 : 0)], with: .automatic) + self.tableView.endUpdates() + } + } + } + } + + // MARK: - Subscription Methods + private func addSubscriptions() { + + guard let store = self.store else { + NSLog("ERROR: Store not initialized") + return + } + + store.subscribe(self, selector: { $0.walletState.transactions != $1.walletState.transactions }, + callback: { state in + self.allTransactions = state.walletState.transactions + self.reload() + }) + + store.subscribe(self, selector: { $0.isLtcSwapped != $1.isLtcSwapped }, + callback: { self.isLtcSwapped = $0.isLtcSwapped }) + store.subscribe(self, selector: { $0.currentRate != $1.currentRate}, + callback: { self.rate = $0.currentRate }) + store.subscribe(self, selector: { $0.maxDigits != $1.maxDigits }, callback: {_ in + self.reload() + }) + + store.subscribe(self, selector: { $0.walletState.syncProgress != $1.walletState.syncProgress }, + callback: { state in + store.subscribe(self, name:.showStatusBar) { (didShowStatusBar) in + self.reload() //May fix where the action view persists after confirming pin + } + + if state.walletState.isRescanning { + self.initSyncingHeaderView(completion: { + self.syncingHeaderView?.isRescanning = state.walletState.isRescanning + self.syncingHeaderView?.progress = CGFloat(state.walletState.syncProgress) + self.syncingHeaderView?.headerMessage = state.walletState.syncState + self.syncingHeaderView?.noSendImageView.alpha = 1.0 + self.syncingHeaderView?.timestamp = state.walletState.lastBlockTimestamp + self.shouldBeSyncing = true + }) + } else if state.walletState.syncProgress > 0.95 { + self.shouldBeSyncing = false + self.syncingHeaderView = nil + } else { + self.initSyncingHeaderView(completion: { + self.syncingHeaderView?.progress = CGFloat(state.walletState.syncProgress) + self.syncingHeaderView?.headerMessage = state.walletState.syncState + self.syncingHeaderView?.timestamp = state.walletState.lastBlockTimestamp + self.syncingHeaderView?.noSendImageView.alpha = 0.0 + self.shouldBeSyncing = true + }) + } + self.reload() + }) + + store.subscribe(self, selector: { $0.walletState.syncState != $1.walletState.syncState }, + callback: { state in + guard let _ = self.walletManager?.peerManager else { + assertionFailure("PEER MANAGER Not initialized") + return + } + + if state.walletState.syncState == .success { + self.shouldBeSyncing = false + self.syncingHeaderView = nil + } + self.reload() + }) + + store.subscribe(self, selector: { $0.recommendRescan != $1.recommendRescan }, callback: { _ in + self.attemptShowPrompt() + }) + + store.subscribe(self, selector: { $0.walletState.syncState != $1.walletState.syncState }, callback: { _ in + self.reload() + }) + + store.subscribe(self, name: .didUpgradePin, callback: { _ in + if self.currentPromptType == .upgradePin { + self.currentPromptType = nil + } + }) + + store.subscribe(self, name: .didEnableShareData, callback: { _ in + if self.currentPromptType == .shareData { + self.currentPromptType = nil + } + }) + + store.subscribe(self, name: .didWritePaperKey, callback: { _ in + if self.currentPromptType == .paperKey { + self.currentPromptType = nil + } + }) + + store.subscribe(self, name: .txMemoUpdated(""), callback: { + guard let trigger = $0 else { return } + if case .txMemoUpdated(let txHash) = trigger { + self.updateTransactions(txHash: txHash) + } + }) + reload() + } + +} diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index eabf375fb..cde4bacc7 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -238,6 +238,8 @@ enum S { static let notConfirmedBlockHeightLabel = NSLocalizedString("TransactionDetails.notConfirmedBlockHeightLabel", value: "**Not Confirmed**", comment: "eg. Confirmed in Block: Not Confirmed") static let staticTXIDLabel = NSLocalizedString("TransactionDetails.staticTXLabel", value: "**TXID:**", comment: "Label for TXID") static let priceTimeStampLabel = NSLocalizedString("TransactionDetails.priceTimeStampPrefix", value: "**as of**", comment: "Prefix for price") + static let copyAllDetails = NSLocalizedString("TransactionDetails.copyAllDetails", value: "**Copy all details**", comment: "Copy all details") + static let copiedAll = NSLocalizedString("TransactionDetails.copiedAll", value: "**Copied**", comment: "Copied") } //MARK: - Buy Center @@ -622,18 +624,6 @@ enum S { static let signing = NSLocalizedString("Import.Error.signing", value: "**Error signing transaction**", comment: "Import signing error message") } } - - //DEV: Removing eventually - // enum BitID { -// static let title = NSLocalizedString("BitID.title", value: "**BitID Authentication Request**", comment: "BitID Authentication Request alert view title") -// static let authenticationRequest = NSLocalizedString("BitID.authenticationRequest", value: "**%1$@ is requesting authentication using your Litecoin wallet**", comment: " is requesting authentication using your Litecoin wallet") -// static let deny = NSLocalizedString("BitID.deny", value: "**Deny**", comment: "Deny button label") -// static let approve = NSLocalizedString("BitID.approve", value: "**Approve**", comment: "Approve button label") -// static let success = NSLocalizedString("BitID.success", value: "**Successfully Authenticated**", comment: "BitID success alert title") -// static let error = NSLocalizedString("BitID.error", value: "**Authentication Error**", comment: "BitID error alert title") -// static let errorMessage = NSLocalizedString("BitID.errorMessage", value: "**Please check with the service. You may need to try again.**", comment: "BitID error alert messaage") - - // } enum SupportLitecoinFoundation { static let title = NSLocalizedString("SupportTheFoundation.title", value: "**Support the Litecoin Foundation**", comment: "Support the Litecoin Foundation") @@ -692,20 +682,7 @@ enum S { static let totalLabel = NSLocalizedString("Confirmation.totalLabel", value: "**Total Cost:**", comment: "Total Cost: ($5.00)") static let amountDetailLabel = NSLocalizedString("Confirmation.amountDetailLabel", value: "**Exchange details:**", comment: "$53.09/L + 1.07%") } - - enum BCH { - static let title = NSLocalizedString("BCH.title", value: "**Withdraw BCH**", comment: "Widthdraw BCH view title") - static let body = NSLocalizedString("BCH.body", value: "**Enter a destination BCH address below. All BCH in your wallet at the time of the fork (%1$@) will be sent.**", comment: "Send BCH view body.") - static let txHashHeader = NSLocalizedString("BCH.txHashHeader", value: "**BCH Transaction ID**", comment: "Tx Hash button header") - static let paymentProtocolError = NSLocalizedString("BCH.paymentProtocolError", value: "**Payment Protocol Requests are not supported for BCH transactions**", comment: "Attempted to scan unsupported qr code error message.") - static let noAddressError = NSLocalizedString("BCH.noAddressError", value: "**Please enter an address**", comment: "No address error message") - static let confirmationTitle = NSLocalizedString("BCH.confirmationTitle", value: "**Confirmation**", comment: "Confirmation alert title") - static let confirmationMessage = NSLocalizedString("BCH.confirmationMessage", value: "**Confirm sending %1$@ to %2$@**", comment: "Confirm sending <$5.00> to
?") - static let successMessage = NSLocalizedString("BCH.successMessage", value: "**BCH was successfully sent.**", comment: "BCH successfully sent alert message") - static let hashCopiedMessage = NSLocalizedString("BCH.hashCopiedMessage", value: "**Transaction ID copied**", comment: "Transaction ID copied message") - static let genericError = NSLocalizedString("BCH.genericError", value: "**Your account does not contain any BCH, or you received BCH after the fork.**", comment: "Generic bch erorr message") - } - + enum NodeSelector { static let manualButton = NSLocalizedString("NodeSelector.manualButton", value: "**Switch to Manual Mode**", comment: "Switch to manual mode button label") static let automaticButton = NSLocalizedString("NodeSelector.automaticButton", value: "**Switch to Automatic Mode**", comment: "Switch to automatic mode button label") diff --git a/loafwallet/src/Extensions/String+Additions.swift b/loafwallet/src/Extensions/String+Additions.swift index 2783c5eea..579e7738f 100644 --- a/loafwallet/src/Extensions/String+Additions.swift +++ b/loafwallet/src/Extensions/String+Additions.swift @@ -25,11 +25,7 @@ extension String { guard lengthOfBytes(using: .utf8) > 0 else { return false } return BRAddressIsValid(self) != 0 } - - var isValidBCHAddress: Bool { - return isValidAddress - } - + var sanitized: String { return applyingTransform(.toUnicodeName, reverse: false) ?? "" } diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 90e42bf76..9ff5a7817 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -73,57 +73,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Unable to retrieve API token"; -/* Send BCH view body. */ -"BCH.body" = "Enter a destination BCH address below. All BCH in your wallet at the time of the fork (%1$@) will be sent."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Confirm sending %1$@ to %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Confirmation"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Your account does not contain any BCH, or you received BCH after the fork."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transaction ID copied"; - -/* No address error message */ -"BCH.noAddressError" = "Please enter an address"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Payment Protocol Requests are not supported for BCH transactions"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH was successfully sent."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Withdraw BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH Transaction ID"; - -/* Approve button label */ -"BitID.approve" = "Approve"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ is requesting authentication using your Litecoin wallet"; - -/* Deny button label */ -"BitID.deny" = "Deny"; - -/* BitID error alert title */ -"BitID.error" = "Authentication Error"; - -/* BitID error alert messaage */ -"BitID.errorMessage" = "Please check with the service. You may need to try again."; - -/* BitID success alert title */ -"BitID.success" = "Successfully Authenticated"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID Authentication Request"; - /* buy button */ "Button.buy" = "buy"; @@ -1404,3 +1353,9 @@ /* Failed Login */ "LitecoinCard.failed.login" = "Login failed"; + +/* Copied */ +"TransactionDetails.copiedAll" = "Copied"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Copy all details"; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index 18f54d2e7..793e355bc 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Kunne ikke hente API-nøgle"; -/* Send BCH view body. */ -"BCH.body" = "Indtast en BCH destinationsadresse nedenfor. Alle BCH i din wallet ved fork-tidspunktet (%1$@) vil blive afsendt."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Bekræft afsendelse af %1$@ til %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Bekræftelse"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Din konto indeholder ikke nogle BCH eller du modtog BCH efter fork."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transaktions-ID kopieret"; - -/* No address error message */ -"BCH.noAddressError" = "Indtast venligst en adresse"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Betalingsprotokolanmodninger er ikke understøttet for BCH-transaktioner"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH blev afsendt uden problemer."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Tilbagetræk BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH transaktions-ID"; - -/* Approve button label */ -"BitID.approve" = "Godkend"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ anmoder om godkendelse ved hjælp af din Litecoin-wallet"; - -/* Deny button label */ -"BitID.deny" = "Afvis"; - -/* BitID error alert title */ -"BitID.error" = "Godkendelsesfejl"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Tjek venligst tjenesten. Det kan være nødvendigt at prøve igen."; - -/* BitID success alert title */ -"BitID.success" = "Godkendt uden problemer"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID godkendelsesanmodning"; - /* buy button */ "Button.buy" = "købe"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Memo"; +/* Copied */ +"TransactionDetails.copiedAll" = "Kopieret"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Kopier alle detaljer"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Dine transaktioner vil vises her."; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index 4b8c3d035..17e8368e2 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "API-Token konnte nicht abgerufen werden"; -/* Send BCH view body. */ -"BCH.body" = "Geben Sie unten eine Ziel-BCH-Adresse ein. Das gesamte BCH Guthaben aus Ihrem Wallet zur Zeit der Aufspaltung (%1$@) wird versendet."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Senden von %1$@ an %2$@ bestätigen"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Bestätigung"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Ihr Konto enthält kein BCH oder Sie haben BCH nach dem Fork erhalten."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transaktions-ID kopiert"; - -/* No address error message */ -"BCH.noAddressError" = "Bitte geben Sie die Adresse ein"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Zahlungsprotokoll-Anfragen werden bei BCH-Transaktionen nicht unterstützt"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH wurde erfolgreich versendet."; - -/* Widthdraw BCH view title */ -"BCH.title" = "BCH abheben"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH-Transaktions-ID"; - -/* Approve button label */ -"BitID.approve" = "Bestätigen"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ fordert die Authentifizierung über Ihr Litecoin-Wallet an"; - -/* Deny button label */ -"BitID.deny" = "Ablehnen"; - -/* BitID error alert title */ -"BitID.error" = "Authentifizierungsfehler"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Bitte den Service überprüfen. Es könnte ein erneuter Versuch erforderlich sein."; - -/* BitID success alert title */ -"BitID.success" = "Erfolgreich authentifiziert"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID-Authentifizierungsanfrage"; - /* buy button */ "Button.buy" = "kaufen"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Vermerk"; +/* Copied */ +"TransactionDetails.copiedAll" = "Kopiert"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Kopieren Sie alle Details"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Hier werden deine Transaktionen angezeigt."; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index e1ad9ca5d..e0d949f46 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Unable to retrieve API token"; -/* Send BCH view body. */ -"BCH.body" = "Enter a destination BCH address below. All BCH in your wallet at the time of the fork (%1$@) will be sent."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Confirm sending %1$@ to %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Confirmation"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Your account does not contain any BCH, or you received BCH after the fork."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transaction ID copied"; - -/* No address error message */ -"BCH.noAddressError" = "Please enter an address"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Payment Protocol Requests are not supported for BCH transactions"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH was successfully sent."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Withdraw BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH Transaction ID"; - -/* Approve button label */ -"BitID.approve" = "Approve"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ is requesting authentication using your Litecoin wallet"; - -/* Deny button label */ -"BitID.deny" = "Deny"; - -/* BitID error alert title */ -"BitID.error" = "Authentication Error"; - -/* BitID error alert messaage */ -"BitID.errorMessage" = "Please check with the service. You may need to try again."; - -/* BitID success alert title */ -"BitID.success" = "Successfully Authenticated"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID Authentication Request"; - /* buy button */ "Button.buy" = "buy"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Memo"; +/* Copied */ +"TransactionDetails.copiedAll" = "Copied"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Copy all details"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Your transactions will appear here."; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 88c662353..627a22750 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "No se puede recuperar el token de API"; -/* Send BCH view body. */ -"BCH.body" = "Introduce una dirección de destino BCH a continuación. Se enviarán todos los BCH de tu cartera en el momento del fork (%1$@)."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Confirmar enviando %1$@ a %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Confirmación"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Tu cuenta no contiene ningún BCH o recibiste BCH después del fork."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Se ha copiado el ID de la transacción"; - -/* No address error message */ -"BCH.noAddressError" = "Por favor, introduce una dirección"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "No se admiten solicitudes de protocolo de pago en transacciones BCH"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH se ha enviado correctamente."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Retirar BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "Identificador de transacción BCH"; - -/* Approve button label */ -"BitID.approve" = "Aprobar"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ está solicitando autenticación mediante tu cartera Litecoin"; - -/* Deny button label */ -"BitID.deny" = "Denegar"; - -/* BitID error alert title */ -"BitID.error" = "Error de autenticación"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Consulta con el servicio. Es posible que debas intentarlo de nuevo."; - -/* BitID success alert title */ -"BitID.success" = "Autenticado con éxito"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "Solicitud de autenticación de BitID"; - /* buy button */ "Button.buy" = "COMPRAR"; @@ -1166,6 +1115,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Memo"; +/* Copied */ +"TransactionDetails.copiedAll" = "Copiado"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Copiar todos los detalles"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Tus transacciones aparecerán aquí."; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index 05d276d1e..fcc3caf50 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Impossible de récupérer le jeton de l'API"; -/* Send BCH view body. */ -"BCH.body" = "Entrez une adresse BCH de destination ci-dessous. Tous les BCH dans votre portefeuille au moment où la fourchette (%1$@) seront envoyés."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Confirmer l'envoi de %1$@ à %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Confirmation"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Votre compte ne contient aucun BCH ou vous avez reçu le BCH après la fourchette."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "ID de transaction copiée"; - -/* No address error message */ -"BCH.noAddressError" = "Veuillez entrer une adresse"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Les demandes de protocole de paiement ne sont pas prises en charge pour les transactions BCH"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH envoyés avec succès."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Retirer les BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "ID de transaction BCH"; - -/* Approve button label */ -"BitID.approve" = "Approuver"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ requiert l'authentification en utilisant le portefeuille Litecoin"; - -/* Deny button label */ -"BitID.deny" = "Refuser"; - -/* BitID error alert title */ -"BitID.error" = "Erreur d'authentification"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Veuillez vérifier avec le service. Vous pourriez avoir à essayer de nouveau."; - -/* BitID success alert title */ -"BitID.success" = "Authentification réussie"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "Demande d'authentification BitID"; - /* buy button */ "Button.buy" = "ACHETER"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Mémo"; +/* Copied */ +"TransactionDetails.copiedAll" = "Copié"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Copiez tous les détails"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Vos transactions apparaîtront ici."; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 1638e5fb0..a0dc7870f 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Tidak mampu mendapatkan kembali bukti API"; -/* Send BCH view body. */ -"BCH.body" = "Masukan tujuan alamat BCH dibawah. Semua BCH di dompet Anda pada waktu untuk percabangan (%1$@) akan dikirim."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Konfirmasi pengiriman %1$@ to %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Mengkonfirmasi"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Akun Anda tidak mengandung BCH, atau Anda menerima BCH setelah percabangan."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "ID Transaksi tersalin"; - -/* No address error message */ -"BCH.noAddressError" = "Silahkan masukkan alamat"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Permintaan Protokol Pembayaran tidak didukung untuk transaksi BCH"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH berhasil terkirim."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Mengambil BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "ID transaksi BCH"; - -/* Approve button label */ -"BitID.approve" = "Menyetujui"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ meminta otentikasi menggunakan dompet Litecoin Anda"; - -/* Deny button label */ -"BitID.deny" = "Menyangkal"; - -/* BitID error alert title */ -"BitID.error" = "Salah Otentikasi"; - -/* BitID error alert messaage */ -"BitID.errorMessage" = "Silahkan periksa dengan layanan. Anda mungkin perlu coba lagi."; - -/* BitID success alert title */ -"BitID.success" = "Berhasil diotentikasi"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "Permintaan Otentikasi BitID"; - /* buy button */ "Button.buy" = "membeli"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Memo"; +/* Copied */ +"TransactionDetails.copiedAll" = "Disalin"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Salin semua detail"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Transaksi Anda akan muncul di sini."; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index fe500cb11..848d46033 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Impossibile recuperare il token API"; -/* Send BCH view body. */ -"BCH.body" = "Inserisci un indirizzo di destinazione BCH qui sotto. Verranno invitai tutti i BCH nel tuo portafogli al momento dell'intervallo (%1$@)."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Conferma l'invio di %1$@ a %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Conferma"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Il tuo account non contiene alcun BCH, oppure hai ricevuto BCH dopo l'intervallo."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "ID della transazione copiato"; - -/* No address error message */ -"BCH.noAddressError" = "Per favore inserisci e invia"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Le richieste di protocollo del pagamento non sono supportate per le transazioni in BCH"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH inviati con successo."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Ritira BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "ID transazione BCH"; - -/* Approve button label */ -"BitID.approve" = "Approva"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ richiede l'autenticazione usando il tuo portafogli Litecoin"; - -/* Deny button label */ -"BitID.deny" = "Nega"; - -/* BitID error alert title */ -"BitID.error" = "Errore di autenticazione"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Per favore verifica con il servizio. Potresti dover riprovare."; - -/* BitID success alert title */ -"BitID.success" = "Autenticato con successo"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "Richiesta autenticazione BitID"; - /* buy button */ "Button.buy" = "acquistare"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Promemoria"; +/* Copied */ +"TransactionDetails.copiedAll" = "Copiato"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Copia tutti i dettagli"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Le tue transazioni appariranno qui."; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index 2940abb76..77686bba3 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "APIトークンを取得できません"; -/* Send BCH view body. */ -"BCH.body" = "送金先のBCHアドレスを入力してください。フォーク時(%1$@)にウォレット内にあった全てのBCHが送られます。"; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "%1$@を%2$@に送金することを確認する"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "承認"; - -/* Generic bch erorr message */ -"BCH.genericError" = "アカウントにBCHがない、またはフォークの後にBCHを受け取っています。"; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "トランザクションIDをコピー済み"; - -/* No address error message */ -"BCH.noAddressError" = "アドレスを入力してください"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "BCHのトランザクションでペイメントプロトコルリクエストはサポートされていません。"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCHの送金に成功しました。"; - -/* Widthdraw BCH view title */ -"BCH.title" = "BCHを引き出す"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCHのトランザクションID"; - -/* Approve button label */ -"BitID.approve" = "承認する"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@がリテコインウォレットを使っての認証を求めています"; - -/* Deny button label */ -"BitID.deny" = "拒否する"; - -/* BitID error alert title */ -"BitID.error" = "認証エラー"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "サービスを確認してください。やり直さなければいけない可能性もあります。"; - -/* BitID success alert title */ -"BitID.success" = "認証成功"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID認証リクエスト"; - /* buy button */ "Button.buy" = "購入"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "メモ"; +/* Copied */ +"TransactionDetails.copiedAll" = "コピー"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "すべての詳細をコピーする"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "あなたの取引はこちらに表示されます。"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index a56848dc0..1c95452b2 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "API 토큰을 가져올 수 없습니다"; -/* Send BCH view body. */ -"BCH.body" = "아래의 목적지 BCH 주소를 입력하세요. 분기 시점(%1$@)에 귀하의 월렛에 있는 모든 BCH를 보냅니다."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "%1$@를 %2$@(으)로 보내기를 확인"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "확정"; - -/* Generic bch erorr message */ -"BCH.genericError" = "귀하의 계정에는 BCH가 없거나, 분기 이후에 BCH를 받으셨습니다."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transaction ID 복사됨"; - -/* No address error message */ -"BCH.noAddressError" = "주소를 입력해 주세요"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Payment Protocol Request는 BCH 트랜잭션에서 지원되지 않습니다"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH를 성공적으로 보냈습니다."; - -/* Widthdraw BCH view title */ -"BCH.title" = "BCH 인출"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH Transaction ID"; - -/* Approve button label */ -"BitID.approve" = "승인"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@(이)가 귀하의 Litecoin 월렛 이용에 대한 인증을 요청하고 있습니다."; - -/* Deny button label */ -"BitID.deny" = "거부"; - -/* BitID error alert title */ -"BitID.error" = "인증 오류"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "서비스 측에 확인해 주세요. 다시 시도해야 할 수도 있습니다."; - -/* BitID success alert title */ -"BitID.success" = "성공적으로 인증됨"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID 인증 요청"; - /* buy button */ "Button.buy" = "구입"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "메모"; +/* Copied */ +"TransactionDetails.copiedAll" = "복사 됨"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "모든 세부 사항 복사"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "귀하의 트랜잭션이 여기에 표시됩니다."; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index 18360417c..2199ef4f7 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Niet in staat op API teken te vinden"; -/* Send BCH view body. */ -"BCH.body" = "Voer hieronder een BCH bestemmingsadres in. Alle BCH die op het moment van de fork (%1$@) in in je portomonnee zitten, zullen worden gestuurd."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Sturen van %1$@ naar %2$@ bevestigen"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Bevestiging"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Je account bevat geen BCH of je hebt BCH ontvangen na de fork."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transactie-ID gekopieerd"; - -/* No address error message */ -"BCH.noAddressError" = "Voer alstublieft een adres in"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Betalingsprotocol-aanvragen worden niet ondersteund voor tranacties met BCH"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH succesvol verstuurd."; - -/* Widthdraw BCH view title */ -"BCH.title" = "BCH opnemen"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH Transactie-ID."; - -/* Approve button label */ -"BitID.approve" = "Keur goed"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ vraagt om authenticatie om je Litecoin-portemonnee te gebruiken"; - -/* Deny button label */ -"BitID.deny" = "Weigeren"; - -/* BitID error alert title */ -"BitID.error" = "Authenticatie Fout"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Vraag het na bij de service. Je moet het mogelijk opnieuw proberen."; - -/* BitID success alert title */ -"BitID.success" = "Succesvol geautenticeerd"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID Authenticatieverzoek"; - /* buy button */ "Button.buy" = "kopen"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Memo"; +/* Copied */ +"TransactionDetails.copiedAll" = "Gekopieerd"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Kopieer alle details"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Je transacties zullen hier verschijnen."; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index fc139c62d..6cc26cd1b 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -86,57 +86,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Não foi possível obter o token API"; -/* Send BCH view body. */ -"BCH.body" = "Introduza abaixo um endereço de destino da BCH. Toda a BCH que estiver na sua conta no momento da divisão (%1$@) será enviada."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Confirme o envio de %1$@ para %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Confirmação"; - -/* Generic bch erorr message */ -"BCH.genericError" = "A sua conta não contém qualquer BCH, ou recebeu as BCH depois da divisão."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "ID da transação copiado"; - -/* No address error message */ -"BCH.noAddressError" = "Por favor, introduza um endereço"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Não são suportados pedidos de protocolo de pagamento para transações de BCH"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "A BCH foi enviada com sucesso"; - -/* Widthdraw BCH view title */ -"BCH.title" = "Levantar BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "ID da transação de BCH"; - -/* Approve button label */ -"BitID.approve" = "Aprovar"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ está a solicitar autenticação utilizando a sua carteira de Litecoin"; - -/* Deny button label */ -"BitID.deny" = "Recusar"; - -/* BitID error alert title */ -"BitID.error" = "Erro de autenticação"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Por favor, verifique o serviço. Pode ser que precise de tentar novamente."; - -/* BitID success alert title */ -"BitID.success" = "Autenticado com sucesso"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "Pedido de autenticação BitID"; - /* buy button */ "Button.buy" = "COMPRAR"; @@ -1166,6 +1115,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Nota"; +/* Copied */ +"TransactionDetails.copiedAll" = "Copiado"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Copie todos os detalhes"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "As suas transações aparecerão aqui."; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index d6a608dc9..f1de22626 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Не удалось извлечь токен API"; -/* Send BCH view body. */ -"BCH.body" = "Введите адрес адресата BCH ниже. Вся сумма BCH в вашем кошельке во время форка (%1$@) будет отправлена."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Подтвердить отправку %1$@ на %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Подтверждение"; - -/* Generic bch erorr message */ -"BCH.genericError" = "На Вашем аккаунте нет BCH, или вы получили BCH после форка."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Идентификатор транзакции скопирован"; - -/* No address error message */ -"BCH.noAddressError" = "Пожалуйста, введите и адрес"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Запросы протокола платежей не поддерживаются для транзакций BCH"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH был успешно отправлен."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Снять BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "Идентификатор транзакции BCH"; - -/* Approve button label */ -"BitID.approve" = "Одобрить"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ запрашивает аутентификацию, используя ваш биткойн-кошелек"; - -/* Deny button label */ -"BitID.deny" = "Отказаться"; - -/* BitID error alert title */ -"BitID.error" = "Ошибка аутентификации"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Пожалуйста, обратитесь в эту службу. Возможно, вам придется попробовать еще раз."; - -/* BitID success alert title */ -"BitID.success" = "Аутентификация пройдена успешно"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "Запрос на аутентификацию BitID"; - /* buy button */ "Button.buy" = "купить"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Записка"; +/* Copied */ +"TransactionDetails.copiedAll" = "Скопировано"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Скопируйте все детали"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Ваши транзакции будут отображаться здесь."; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index c4031cf4e..d09ef78e8 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "Kan inte ta emot API-symbol"; -/* Send BCH view body. */ -"BCH.body" = "Ange mottagarens BCH-adress nedan. Alla BCH i din plånbok vid nästa fork (%1$@) kommer skickas."; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "Bekräfta skickar %1$@ till %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "Bekräftelse"; - -/* Generic bch erorr message */ -"BCH.genericError" = "Ditt konto har inte några BCH, eller så tar du emot BCH först efter nästa fork."; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "Transaktions-ID kopierat"; - -/* No address error message */ -"BCH.noAddressError" = "Var god ange en adress"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "Betalningsprotokollsbegäran stöds inte för BCH-transaktioner"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH skickades."; - -/* Widthdraw BCH view title */ -"BCH.title" = "Ta ut BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH transaktions-ID"; - -/* Approve button label */ -"BitID.approve" = "Godkänn"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ begär autentisering med hjälp av din Litecoin-plånbok"; - -/* Deny button label */ -"BitID.deny" = "Avslå"; - -/* BitID error alert title */ -"BitID.error" = "Autentiseringsfel"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "Var god kontrollera med tjänsten. Du kan behöva försöka igen."; - -/* BitID success alert title */ -"BitID.success" = "Autentiseringen lyckades"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitId autentiseringsförfrågan"; - /* buy button */ "Button.buy" = "köpa"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "Memo"; +/* Copied */ +"TransactionDetails.copiedAll" = "Kopierad"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Kopiera alla detaljer"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "Dina transaktioner visas här."; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index 5e84126e7..2c4f66d39 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "无法检索 API 令牌"; -/* Send BCH view body. */ -"BCH.body" = "在下方输入目标 BCH 地址。您钱包中此分叉 (%1$@) 时的所有 BCH 都将被发送。"; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "确认将 %1$@ 发送到 %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "确认"; - -/* Generic bch erorr message */ -"BCH.genericError" = "您的账户不包含任何 BCH,或您在分叉后才接收到 BCH。"; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "已拷贝交易 ID"; - -/* No address error message */ -"BCH.noAddressError" = "请输入地址"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "支付协议请求不支持 BCH 交易"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH 已成功发送。"; - -/* Widthdraw BCH view title */ -"BCH.title" = "取出 BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH 交易 ID"; - -/* Approve button label */ -"BitID.approve" = "批准"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ 正使用您的莱特币钱包请求验证"; - -/* Deny button label */ -"BitID.deny" = "拒绝"; - -/* BitID error alert title */ -"BitID.error" = "验证错误"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "请检查此服务。您可能需要重试。"; - -/* BitID success alert title */ -"BitID.success" = "验证成功"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "BitID 验证请求"; - /* buy button */ "Button.buy" = "购买"; @@ -433,6 +382,9 @@ /* Register */ "LitecoinCard.registerCard" = "寄存器"; +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "注册莱特币卡"; + /* Registering user... */ "LitecoinCard.registering.user" = "正在注册用户..."; @@ -451,6 +403,9 @@ /* First name */ "LitecoinCard.Registration.firstName" = "名字"; +/* identification */ +"LitecoinCard.Registration.identification" = "身份证明"; + /* kycIDNumber */ "LitecoinCard.Registration.kycIDNumber" = "了解你的顾客 证件类型"; @@ -1159,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "备忘录"; +/* Copied */ +"TransactionDetails.copiedAll" = "复制的"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "复制所有详细信息"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "您的交易将显示在这里。"; @@ -1380,9 +1341,3 @@ /* 1 of 3 */ "WritePaperPhrase.step" = "%1$d / %2$d"; - -/* Register for Litecoin Card */ -"LitecoinCard.registerCardPhrase" = ""; - -/* identification */ -"LitecoinCard.Registration.identification" = ""; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index 5622e8eab..f1e0b95b6 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -85,57 +85,6 @@ /* API Token error message */ "ApiClient.tokenError" = "無法擷取 API 權杖"; -/* Send BCH view body. */ -"BCH.body" = "在下方輸入目的地 BCH 地址。分叉(%1$@)之時錢包內所有的 BCH 都會送出。"; - -/* Confirm sending <$5.00> to
? */ -"BCH.confirmationMessage" = "確定送出 %1$@ 至 %2$@"; - -/* Confirmation alert title */ -"BCH.confirmationTitle" = "確認"; - -/* Generic bch erorr message */ -"BCH.genericError" = "您的帳戶內沒有任何 BCH,或您是在分叉後取得 BCH。"; - -/* Transaction ID copied message */ -"BCH.hashCopiedMessage" = "已複制交易 ID"; - -/* No address error message */ -"BCH.noAddressError" = "請輸入地位"; - -/* Attempted to scan unsupported qr code error message. */ -"BCH.paymentProtocolError" = "BCH 交易不支援付款組合要求"; - -/* BCH successfully sent alert message */ -"BCH.successMessage" = "BCH 已成功寄送。"; - -/* Widthdraw BCH view title */ -"BCH.title" = "提取 BCH"; - -/* Tx Hash button header */ -"BCH.txHashHeader" = "BCH 交易 ID"; - -/* Approve button label */ -"BitID.approve" = "許可"; - -/* is requesting authentication using your Litecoin wallet */ -"BitID.authenticationRequest" = "%1$@ 要求認證使用您的萊特幣錢包"; - -/* Deny button label */ -"BitID.deny" = "拒絕"; - -/* BitID error alert title */ -"BitID.error" = "認證錯誤"; - -/* BitID error alert messaage (The payment service you are trying to use isn't working. Please contact them, as you may need to try again) */ -"BitID.errorMessage" = "請檢查服務。您可能必須重試一次。"; - -/* BitID success alert title */ -"BitID.success" = "認證成功。"; - -/* BitID Authentication Request alert view title */ -"BitID.title" = "要求認證比特 ID"; - /* buy button */ "Button.buy" = "購買"; @@ -1165,6 +1114,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "備註"; +/* Copied */ +"TransactionDetails.copiedAll" = "複製的"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "複製所有詳細信息"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "您的交易會顯示於此。"; diff --git a/loafwallet/src/ViewModels/Transaction.swift b/loafwallet/src/ViewModels/Transaction.swift index 1d6066f54..efa5e60f5 100644 --- a/loafwallet/src/ViewModels/Transaction.swift +++ b/loafwallet/src/ViewModels/Transaction.swift @@ -106,7 +106,7 @@ class Transaction { } } - return "\(amountString)\n\n\(startingString)\n\(endingString)\n\n\(exchangeRateInfo)" + return "\(amountString)\n\(startingString)\n\(endingString)\n\(exchangeRateInfo)" } func amountDetailsAmountString(isLtcSwapped: Bool, rate: Rate, rates: [Rate], maxDigits: Int) -> String { @@ -219,7 +219,6 @@ class Transaction { } }() - // return: (timestampString, shouldStartTimer) var timeSince: (String, Bool) { if let cached = timeSinceCache { return cached diff --git a/loafwallet/src/Views/TransactionCells/MaskedShadow.swift b/loafwallet/src/Views/TransactionCells/MaskedShadow.swift deleted file mode 100644 index 746a54230..000000000 --- a/loafwallet/src/Views/TransactionCells/MaskedShadow.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// ShadowView.swift -// breadwallet -// -// Created by Adrian Corscadden on 2016-11-17. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import UIKit - -class MaskedShadow: UIView { - - var style: TransactionCellStyle = .middle { - didSet { - setNeedsLayout() - } - } - private let shadowSize: CGFloat = 8.0 - - override func layoutSubviews() { - - guard style != .single else { - layer.mask = nil - layer.shadowPath = UIBezierPath(rect: bounds).cgPath - return - } - - var shadowRect = bounds.insetBy(dx: 0, dy: -shadowSize) - var maskRect = bounds.insetBy(dx: -shadowSize, dy: 0) - - if style == .first { - maskRect.origin.y -= shadowSize - maskRect.size.height += shadowSize - shadowRect.origin.y += shadowSize - } - - if style == .last { - maskRect.size.height += shadowSize - shadowRect.size.height -= shadowSize - } - - let maskLayer = CAShapeLayer() - maskLayer.path = UIBezierPath(rect: maskRect).cgPath - layer.mask = maskLayer - layer.shadowPath = UIBezierPath(rect: shadowRect).cgPath - } -} diff --git a/loafwallet/src/Views/TransactionCells/RoundedContainer.swift b/loafwallet/src/Views/TransactionCells/RoundedContainer.swift deleted file mode 100644 index f17449f5c..000000000 --- a/loafwallet/src/Views/TransactionCells/RoundedContainer.swift +++ /dev/null @@ -1,45 +0,0 @@ - -// RoundedContainer.swift -// breadwallet -// -// Created by Adrian Corscadden on 2016-11-17. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import UIKit - -class RoundedContainer: UIView { - - var style: TransactionCellStyle = .middle { - didSet { - setNeedsLayout() - } - } - - override func layoutSubviews() { - - if #available(iOS 11.0, *) { - - guard let backgroundColor = UIColor(named: "lfBackgroundColor") else { - NSLog("ERROR: Custom color not found") - return - } - self.backgroundColor = backgroundColor - } - let maskLayer = CAShapeLayer() - let corners: UIRectCorner - switch style { - case .first: - corners = [.topLeft, .topRight] - case .last: - corners = [.bottomLeft, .bottomRight] - case .single: - corners = .allCorners - case .middle: - corners = [] - } - maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: 4.0, height: 4.0)).cgPath - layer.mask = maskLayer - } - -} diff --git a/loafwallet/src/Views/TransactionCells/TransactionTableViewCell.swift b/loafwallet/src/Views/TransactionCells/TransactionTableViewCell.swift deleted file mode 100644 index cdb3b351b..000000000 --- a/loafwallet/src/Views/TransactionCells/TransactionTableViewCell.swift +++ /dev/null @@ -1,228 +0,0 @@ -// -// TransactionTableViewCell.swift -// breadwallet -// -// Created by Adrian Corscadden on 2016-11-16. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import UIKit - -enum TransactionCellStyle { - case first - case middle - case last - case single -} - -private let timestampRefreshRate: TimeInterval = 10.0 - -class TransactionTableViewCell : UITableViewCell, Subscriber { - - private class TransactionTableViewCellWrapper { - weak var target: TransactionTableViewCell? - init(target: TransactionTableViewCell) { - self.target = target - } - - @objc func timerDidFire() { - target?.updateTimestamp() - } - } - - //MARK: - Public - override init(style: UITableViewCellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupViews() - } - - deinit { - timer?.invalidate() - } - - func setStyle(_ style: TransactionCellStyle) { - container.style = style - shadowView.style = style - if style == .last || style == .single { - innerShadow.isHidden = true - } else { - innerShadow.isHidden = false - } - } - - func setTransaction(_ transaction: Transaction, isLtcSwapped: Bool, rate: Rate, maxDigits: Int, isSyncing: Bool) { - self.transaction = transaction - transactionLabel.attributedText = transaction.descriptionString(isLtcSwapped: isLtcSwapped, rate: rate, maxDigits: maxDigits) - address.text = String(format: transaction.direction.addressTextFormat, transaction.toAddress ?? "") - status.text = transaction.status - comment.text = transaction.comment - availability.text = transaction.shouldDisplayAvailableToSpend ? S.Transaction.available : "" - - if #available(iOS 11.0, *) { - guard let textColor = UIColor(named: "labelTextColor") else { - NSLog("ERROR: Custom color not found") - return - } - transactionLabel.textColor = textColor - address.textColor = textColor - comment.textColor = textColor - status.textColor = textColor - timestamp.textColor = textColor - shadowView.layer.shadowColor = textColor.cgColor - - } else { - comment.textColor = .darkText - status.textColor = .darkText - timestamp.textColor = .grayTextTint - shadowView.backgroundColor = .clear - shadowView.layer.shadowColor = UIColor.black.cgColor - } - - if transaction.status == S.Transaction.complete { - status.isHidden = false - } else { - status.isHidden = isSyncing - } - - let timestampInfo = transaction.timeSince - timestamp.text = timestampInfo.0 - if timestampInfo.1 { - timer = Timer.scheduledTimer(timeInterval: timestampRefreshRate, target: TransactionTableViewCellWrapper(target: self), selector: NSSelectorFromString("timerDidFire"), userInfo: nil, repeats: true) - } else { - timer?.invalidate() - } - timestamp.isHidden = !transaction.isValid - - let identity: CGAffineTransform = .identity - if transaction.direction == .received { - arrow.transform = identity.rotated(by: π/2.0) - arrow.tintColor = .txListGreen - } else { - arrow.transform = identity.rotated(by: 3.0*π/2.0) - arrow.tintColor = .cameraGuideNegative - } - } - - let container = RoundedContainer() - - //MARK: - Private - private let transactionLabel = UILabel() - private let address = UILabel(font: UIFont.customBody(size: 13.0)) - private let status = UILabel(font: UIFont.customBody(size: 13.0)) - private let comment = UILabel.wrapping(font: UIFont.customBody(size: 13.0)) - private let timestamp = UILabel(font: UIFont.customMedium(size: 13.0)) - private let shadowView = MaskedShadow() - private let innerShadow = UIView() - private let topPadding: CGFloat = 19.0 - private var style: TransactionCellStyle = .first - private var transaction: Transaction? - private let availability = UILabel(font: .customBold(size: 13.0), color: .txListGreen) - private var timer: Timer? = nil - private let arrow = UIImageView(image: #imageLiteral(resourceName: "CircleArrow").withRenderingMode(.alwaysTemplate)) - - private func setupViews() { - addSubviews() - addConstraints() - setupStyle() - } - - private func addSubviews() { - contentView.addSubview(shadowView) - contentView.addSubview(container) - container.addSubview(innerShadow) - container.addSubview(transactionLabel) - container.addSubview(arrow) - container.addSubview(address) - container.addSubview(status) - container.addSubview(comment) - container.addSubview(timestamp) - container.addSubview(availability) - } - - private func addConstraints() { - shadowView.constrain(toSuperviewEdges: UIEdgeInsets(top: 0, left: C.padding[2], bottom: 0, right: -C.padding[2])) - container.constrain(toSuperviewEdges: UIEdgeInsets(top: 0, left: C.padding[2], bottom: 0, right: -C.padding[2])) - innerShadow.constrainBottomCorners(sidePadding: 0, bottomPadding: 0) - innerShadow.constrain([ - innerShadow.constraint(.height, constant: 1.0) ]) - arrow.constrain([ - arrow.trailingAnchor.constraint(equalTo: timestamp.leadingAnchor, constant: -4.0), - arrow.centerYAnchor.constraint(equalTo: timestamp.centerYAnchor), - arrow.heightAnchor.constraint(equalToConstant: 14.0), - arrow.widthAnchor.constraint(equalToConstant: 14.0)]) - transactionLabel.constrain([ - transactionLabel.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: C.padding[2]), - transactionLabel.constraint(.top, toView: container, constant: topPadding), - transactionLabel.trailingAnchor.constraint(lessThanOrEqualTo: timestamp.leadingAnchor, constant: -C.padding[1]) ]) - timestamp.setContentCompressionResistancePriority(UILayoutPriority.required, for: .horizontal) - timestamp.constrain([ - timestamp.constraint(.trailing, toView: container, constant: -C.padding[2]), - timestamp.constraint(.top, toView: container, constant: topPadding) ]) - - address.constrain([ - address.leadingAnchor.constraint(equalTo: transactionLabel.leadingAnchor), - address.topAnchor.constraint(equalTo: transactionLabel.bottomAnchor), - address.trailingAnchor.constraint(lessThanOrEqualTo: timestamp.leadingAnchor, constant: -C.padding[4])]) - address.setContentCompressionResistancePriority(UILayoutPriority.defaultLow, for: .horizontal) - - comment.constrain([ - comment.constraint(.leading, toView: container, constant: C.padding[2]), - comment.constraint(toBottom: address, constant: C.padding[1]), - comment.trailingAnchor.constraint(lessThanOrEqualTo: timestamp.leadingAnchor, constant: -C.padding[1]) ]) - status.constrain([ - status.constraint(.leading, toView: container, constant: C.padding[2]), - status.constraint(toBottom: comment, constant: C.padding[1]), - status.constraint(.trailing, toView: container, constant: -C.padding[2]) ]) - availability.constrain([ - availability.leadingAnchor.constraint(equalTo: status.leadingAnchor), - availability.topAnchor.constraint(equalTo: status.bottomAnchor), - availability.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -C.padding[2]) ]) - } - - private func setupStyle() { - backgroundColor = .clear - - comment.textColor = .darkText - status.textColor = .darkText - timestamp.textColor = .grayTextTint - - shadowView.backgroundColor = .clear - shadowView.layer.shadowOpacity = 0.5 - shadowView.layer.shadowRadius = 4.0 - shadowView.layer.shadowOffset = CGSize(width: 0, height: 0) - - innerShadow.backgroundColor = .secondaryShadow - - transactionLabel.numberOfLines = 0 - transactionLabel.lineBreakMode = .byWordWrapping - - address.lineBreakMode = .byTruncatingMiddle - address.numberOfLines = 1 - - } - - func updateTimestamp() { - guard let tx = transaction else { return } - let timestampInfo = tx.timeSince - timestamp.text = timestampInfo.0 - if !timestampInfo.1 { - timer?.invalidate() - } - } - - - override func setSelected(_ selected: Bool, animated: Bool) { - //intentional noop for now - //The default selected state doesn't play nicely - //with this custom cell - } - -// override func setHighlighted(_ highlighted: Bool, animated: Bool) { -// guard selectionStyle != .none else { container.backgroundColor = .white; return } -// container.backgroundColor = highlighted ? .secondaryShadow : .white -// } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} From 861094d90faadb4b18d1bf5003c03b02435ea318 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 25 Feb 2021 23:13:39 +0000 Subject: [PATCH 042/114] =?UTF-8?q?[Tech=20Debt]=20Added=20=E2=80=9CBalanc?= =?UTF-8?q?e=E2=80=9D=20label=20with=20localizations=20(#232)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added “Balance” label with localizations - Set the layout * update per comments --- loafwallet/Storyboards/Main.storyboard | 19 ++++++++++++++----- loafwallet/TabBarViewController.swift | 5 ++++- loafwallet/src/Constants/Strings.swift | 2 ++ .../Strings/Base.lproj/Localizable.strings | 3 +++ .../src/Strings/da.lproj/Localizable.strings | 3 +++ .../src/Strings/de.lproj/Localizable.strings | 3 +++ .../src/Strings/en.lproj/Localizable.strings | 3 +++ .../src/Strings/es.lproj/Localizable.strings | 3 +++ .../src/Strings/fr.lproj/Localizable.strings | 3 +++ .../src/Strings/id.lproj/Localizable.strings | 3 +++ .../src/Strings/it.lproj/Localizable.strings | 3 +++ .../src/Strings/ja.lproj/Localizable.strings | 3 +++ .../src/Strings/ko.lproj/Localizable.strings | 3 +++ .../src/Strings/nl.lproj/Localizable.strings | 3 +++ .../src/Strings/pt.lproj/Localizable.strings | 3 +++ .../src/Strings/ru.lproj/Localizable.strings | 3 +++ .../src/Strings/sv.lproj/Localizable.strings | 3 +++ .../Strings/zh-Hans.lproj/Localizable.strings | 3 +++ .../Strings/zh-Hant.lproj/Localizable.strings | 3 +++ 19 files changed, 68 insertions(+), 6 deletions(-) diff --git a/loafwallet/Storyboards/Main.storyboard b/loafwallet/Storyboards/Main.storyboard index dd20cc8e9..baf3bc3d1 100644 --- a/loafwallet/Storyboards/Main.storyboard +++ b/loafwallet/Storyboards/Main.storyboard @@ -29,7 +29,7 @@ - + @@ -66,7 +66,7 @@ - + + + - + @@ -125,6 +133,7 @@ + @@ -136,7 +145,7 @@ - + @@ -176,7 +185,7 @@ - + @@ -153,7 +153,7 @@ - + @@ -185,7 +185,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/loafwallet/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index 9f96d8002..119df4580 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -7,14 +7,7 @@ import UIKit import Foundation - -enum TabViewControllerIndex: Int { - case transactions = 0 - case send = 1 - case buy = 2 - case receive = 3 -} - + class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDelegate { let kInitialChildViewControllerIndex = 0 // TransactionsViewController @@ -68,6 +61,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel override func viewDidLoad() { super.viewDidLoad() + setupModels() setupViews() configurePriceLabels() addSubscriptions() @@ -93,6 +87,23 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel self.updateTimer = nil } + private func setupModels() { + + guard let store = self.store else { return } + + isLtcSwapped = store.state.isLtcSwapped + + if let rate = store.state.currentRate { + exchangeRate = rate + let placeholderAmount = Amount(amount: 0, rate: rate, maxDigits: store.state.maxDigits) + secondaryBalanceLabel = UpdatingLabel(formatter: placeholderAmount.localFormat) + primaryBalanceLabel = UpdatingLabel(formatter: placeholderAmount.ltcFormat) + } else { + secondaryBalanceLabel = UpdatingLabel(formatter: NumberFormatter()) + primaryBalanceLabel = UpdatingLabel(formatter: NumberFormatter()) + } + } + private func setupViews() { walletBalanceLabel.text = S.ManageWallet.balance + ":" @@ -312,14 +323,14 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel array.forEach { item in switch item.tag { - case 0: item.title = S.History.barItemTitle - case 1: item.title = S.Send.barItemTitle - case 2: item.title = S.LitecoinCard.barItemTitle - case 3: item.title = S.Receive.barItemTitle - case 4: item.title = S.BuyCenter.barItemTitle - default: - item.title = "NO-TITLE" - NSLog("ERROR: UITabbar item count is wrong") + case 0: item.title = S.History.barItemTitle + case 1: item.title = S.Send.barItemTitle + case 2: item.title = S.LitecoinCard.barItemTitle + case 3: item.title = S.Receive.barItemTitle + case 4: item.title = S.BuyCenter.barItemTitle + default: + item.title = "NO-TITLE" + NSLog("ERROR: UITabbar item count is wrong") } } } diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index 785f79a81..8461d08b4 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -397,6 +397,7 @@ enum S { static let litewalletEnvironment = NSLocalizedString("Settings.litewallet.environment", value: "**Litewallet Environment:**", comment: "Litewallet environment") static let socialLinks = NSLocalizedString("Settings.socialLinks", value: "**Social Links:**", comment: "Litewallet Social links") static let litewalletPartners = NSLocalizedString("Settings.litewallet.partners", value: "**Litewallet Partners:**", comment: "Litewallet Partners") + static let currentLocale = NSLocalizedString("Settings.currentLocale", value: "**Current Locale:**", comment: "Current Locale") } enum About { diff --git a/loafwallet/src/Extensions/UserDefaults+Additions.swift b/loafwallet/src/Extensions/UserDefaults+Additions.swift index 6053e5135..f435ec085 100644 --- a/loafwallet/src/Extensions/UserDefaults+Additions.swift +++ b/loafwallet/src/Extensions/UserDefaults+Additions.swift @@ -24,6 +24,9 @@ private let customNodePortKey = "customNodePortKey" private let hasPromptedShareDataKey = "hasPromptedShareDataKey" private let hasShownWelcomeKey = "hasShownWelcomeKey" private let didSeeTransactionCorruption = "DidSeeTransactionCorruption" +private let userIsInUSAKey = "userIsInUSAKey" + + extension UserDefaults { @@ -72,7 +75,13 @@ extension UserDefaults { } set { defaults.set(newValue, forKey: isLtcSwappedKey) } } - + + static var userIsInUSA: Bool { + get { return defaults.bool(forKey: userIsInUSAKey) + } + set { defaults.set(newValue, forKey: userIsInUSAKey) } + } + // // 2 - photons // 5 - lites diff --git a/loafwallet/src/FlowControllers/StartFlowPresenter.swift b/loafwallet/src/FlowControllers/StartFlowPresenter.swift index a9cbccb04..30fa3cf57 100644 --- a/loafwallet/src/FlowControllers/StartFlowPresenter.swift +++ b/loafwallet/src/FlowControllers/StartFlowPresenter.swift @@ -74,7 +74,6 @@ class StartFlowPresenter : Subscriber { didTapRecover: { [weak self] in guard let myself = self else { return } let recoverIntro = RecoverWalletIntroViewController(didTapNext: myself.pushRecoverWalletView) - myself.navigationController?.setTintableBackArrow() myself.navigationController?.setClearNavbar() myself.navigationController?.modalPresentationStyle = .fullScreen myself.navigationController?.setNavigationBarHidden(false, animated: false) diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 4dd7f65b8..fdd3e59a1 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -11,7 +11,6 @@ import LocalAuthentication import SwiftUI import SafariServices - class ModalPresenter : Subscriber, Trackable { //MARK: - Public @@ -246,11 +245,11 @@ class ModalPresenter : Subscriber, Trackable { completion: @escaping ()->Void) { let hostingViewController = UIHostingController(rootView: AlertFailureView(alertFailureType:.failedResolution, - errorMessage: errorMessage)) - + errorMessage: errorMessage)) + guard let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first, let failureAlertView = hostingViewController.view else { return } - + let size = window.bounds.size window.addSubview(failureAlertView) @@ -258,15 +257,15 @@ class ModalPresenter : Subscriber, Trackable { failureAlertView.constrain([ failureAlertView.constraint(.width, constant: size.width), failureAlertView.constraint(.height, constant: alertHeight + 50.0), - failureAlertView.constraint(.leading, toView: window, constant: nil), - topConstraint ]) + failureAlertView.constraint(.leading, toView: window, constant: nil), + topConstraint ]) window.layoutIfNeeded() UIView.spring(0.6, animations: { topConstraint?.constant = size.height - self.alertHeight window.layoutIfNeeded() }, completion: { _ in - + UIView.spring(0.6, delay: 5.0, animations: { topConstraint?.constant = size.height window.layoutIfNeeded() @@ -361,7 +360,7 @@ class ModalPresenter : Subscriber, Trackable { sendVC.onResolutionFailure = { [weak self] failureMessage in self?.presentFailureAlert(.failedResolution, errorMessage: failureMessage, completion: {}) } - + return root } @@ -398,13 +397,13 @@ class ModalPresenter : Subscriber, Trackable { let urlString = "https://litecoinfoundation.zendesk.com/hc/en-us" guard let url = URL(string: urlString) else { return } - + let vc = SFSafariViewController(url: url) self?.topViewController?.present(vc, animated: true, completion: nil) }) - + } - + menu.didTapGiveSupportLF = { [weak self, weak menu] in menu?.dismiss(animated: true, completion: { self?.presentSupportLF() @@ -516,6 +515,22 @@ class ModalPresenter : Subscriber, Trackable { guard let wm = self.walletManager else { print("NO WALLET MANAGER!"); return } settingsNav.pushViewController(DefaultCurrencyViewController(walletManager: wm, store: self.store), animated: true) }), + Setting(title: S.Settings.currentLocale, accessoryText: { + + // Get the current locale + let currentLocale = Locale.current + + if let regionCode = currentLocale.regionCode, + let displayName = currentLocale.localizedString(forRegionCode: regionCode) { + return displayName + } else { + return "" + } + + }, callback: { + let localeView = UIHostingController(rootView: LocaleChangeView(viewModel: LocaleChangeViewModel())) + settingsNav.pushViewController(localeView, animated: true) + }), Setting(title: S.Settings.sync, callback: { settingsNav.pushViewController(ReScanViewController(store: self.store), animated: true) }), @@ -563,8 +578,7 @@ class ModalPresenter : Subscriber, Trackable { view.backgroundColor = .whiteTint settingsNav.navigationBar.setBackgroundImage(view.imageRepresentation, for: .default) settingsNav.navigationBar.shadowImage = UIImage() - settingsNav.navigationBar.isTranslucent = false - settingsNav.setBlackBackArrow() + settingsNav.navigationBar.isTranslucent = false top.present(settingsNav, animated: true, completion: nil) } @@ -592,7 +606,7 @@ class ModalPresenter : Subscriber, Trackable { private func presentSupportLF() { let supportLFView = UIHostingController(rootView: SupportLitecoinFoundationView(viewModel: SupportLitecoinFoundationViewModel())) - + supportLFView.rootView.viewModel.didTapToDismiss = { supportLFView.dismiss(animated: true) { //TODO: Track in Analytics @@ -601,7 +615,7 @@ class ModalPresenter : Subscriber, Trackable { window.rootViewController?.present(supportLFView, animated: true, completion: nil) } - + private func presentSecurityCenter() { guard let walletManager = walletManager else { return } let securityCenter = SecurityCenterViewController(store: store, walletManager: walletManager) @@ -717,7 +731,7 @@ class ModalPresenter : Subscriber, Trackable { paperPhraseNavigationController.viewControllers = [start] vc.present(paperPhraseNavigationController, animated: true, completion: nil) } - + private func wipeWallet() { let group = DispatchGroup() let alert = UIAlertController(title: S.WipeWallet.alertTitle, message: S.WipeWallet.alertMessage, preferredStyle: .alert) @@ -998,3 +1012,4 @@ class SecurityCenterNavigationDelegate : NSObject, UINavigationControllerDelegat } } } + diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 36f69006d..c7197ad01 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1392,3 +1392,6 @@ /* Reset password detail */ "LitecoinCard.resetPasswordDetail" = "Enter the email address associated with your Litecoin Card account & look for an email with reset instructions."; + +/* Current Locale */ +"Settings.currentLocale" = "Current Locale:"; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index 4174938f7..879516b02 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Vis valuta"; +/* Current Locale */ +"Settings.currentLocale" = "Nuværende landestandard:"; + /* Join Early access label */ "Settings.earlyAccess" = "Tilmeld dig Early Access"; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index f8d8d4564..a1a15cb5c 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Anzeigewährung"; +/* Current Locale */ +"Settings.currentLocale" = "Aktuelles Gebietsschema:"; + /* Join Early access label */ "Settings.earlyAccess" = "Zum Early Access anmelden"; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index d1617e538..ec07c2f00 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* Default currency label */ "Settings.currency" = "Display Currency"; +/* Current Locale */ +"Settings.currentLocale" = "Current Locale:"; + /* Join Early access label */ "Settings.earlyAccess" = "Join Early Access"; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 2a78fa712..9df973516 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -929,6 +929,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Mostrar moneda"; +/* Current Locale */ +"Settings.currentLocale" = "Local actual:"; + /* Join Early access label */ "Settings.earlyAccess" = "Únete al acceso anticipado"; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index 6351133c4..030f6b7b1 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Afficher la devise"; +/* Current Locale */ +"Settings.currentLocale" = "Paramètres régionaux actuels:"; + /* Join Early access label */ "Settings.earlyAccess" = "Rejoignez l'accès anticipé"; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 8c72dd15f..07081a81a 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* Default currency label */ "Settings.currency" = "Mata uang tampilan"; +/* Current Locale */ +"Settings.currentLocale" = "Lokal Saat Ini:"; + /* Join Early access label */ "Settings.earlyAccess" = "Bergabunglah dengan Akses Dini"; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index 8d3e75639..a51ae988c 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Visualizza valuta"; +/* Current Locale */ +"Settings.currentLocale" = "Locale corrente:"; + /* Join Early access label */ "Settings.earlyAccess" = "Iscriviti all'Accesso Immediato"; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index d15b9df12..1d000cbc5 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "表示される通貨"; +/* Current Locale */ +"Settings.currentLocale" = "現在のロケール:"; + /* Join Early access label */ "Settings.earlyAccess" = "早期アクセスに参加"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index 6ebec1830..d4ef6d106 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "통화 보기"; +/* Current Locale */ +"Settings.currentLocale" = "현재 로케일 :"; + /* Join Early access label */ "Settings.earlyAccess" = "초기 버전을 사용해 보세요"; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index caff8be9c..85c1a6591 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Toon valuta"; +/* Current Locale */ +"Settings.currentLocale" = "Huidige landinstelling:"; + /* Join Early access label */ "Settings.earlyAccess" = "Doe Mee aan Early Access"; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index fcfe23060..8fb041f7f 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -929,6 +929,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Mostrar moeda"; +/* Current Locale */ +"Settings.currentLocale" = "Localidade atual:"; + /* Join Early access label */ "Settings.earlyAccess" = "Registe-se no Acesso Antecipado"; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index ac5a0ad21..02e95479e 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Отображать валюту"; +/* Current Locale */ +"Settings.currentLocale" = "Текущая локаль:"; + /* Join Early access label */ "Settings.earlyAccess" = "Присоединитесь к пользователям с ранним доступом"; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index 407201fa8..9c1167f1a 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "Visa valuta"; +/* Current Locale */ +"Settings.currentLocale" = "Aktuell lokal:"; + /* Join Early access label */ "Settings.earlyAccess" = "Använd Snabb tillgång"; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index dc544581d..098557edb 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "显示币种"; +/* Current Locale */ +"Settings.currentLocale" = "当前语言环境:"; + /* Join Early access label */ "Settings.earlyAccess" = "加入早期访问"; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index b64ef8687..de06924da 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -928,6 +928,9 @@ /* i.e. the currency which will be displayed */ "Settings.currency" = "顯示貨幣"; +/* Current Locale */ +"Settings.currentLocale" = "當前語言環境:"; + /* Join Early access label */ "Settings.earlyAccess" = "參加「先行體驗」"; diff --git a/loafwalletTests/Card Tests/CardTests.swift b/loafwalletTests/Card Tests/CardTests.swift new file mode 100644 index 000000000..8d04bc65b --- /dev/null +++ b/loafwalletTests/Card Tests/CardTests.swift @@ -0,0 +1,58 @@ +// +// CardTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 5/9/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// +// +import XCTest +import Firebase +@testable import loafwallet + +class CardTests: XCTestCase { + + var sharedAppDelegate = AppDelegate() + + func testCheckUserIsExUSA() throws { + + let 🇲🇽 = Locale(identifier: "mx_MX") + let 🇮🇩 = Locale(identifier: "id_ID") + let 🇷🇺 = Locale(identifier: "ru_RU") + let 🇧🇷 = Locale(identifier: "br_BR") + let 🇹🇷 = Locale(identifier: "tr_TR") + let 🇨🇳 = Locale(identifier: "cn_CN") + let 🇯🇵 = Locale(identifier: "jp_JP") + let 🇪🇸 = Locale(identifier: "es_ES") + let 🇩🇪 = Locale(identifier: "de_DE") + + let arrayOfLocales = [🇲🇽,🇮🇩,🇷🇺,🇧🇷,🇹🇷,🇨🇳,🇯🇵,🇪🇸,🇩🇪] + + arrayOfLocales.forEach { locale in + sharedAppDelegate.updateCurrentUserLocale(localeId: locale.identifier) + XCTAssertFalse(UserDefaults.userIsInUSA) + } + } + + func testCheckUserIsBilingualInUSA() throws { + + let 🇺🇸 = Locale(identifier: "en_US") + let 🇲🇽🇺🇸 = Locale(identifier: "mx_US") + let 🇮🇩🇺🇸 = Locale(identifier: "id_US") + let 🇷🇺🇺🇸 = Locale(identifier: "ru_US") + let 🇧🇷🇺🇸 = Locale(identifier: "br_US") + let 🇹🇷🇺🇸 = Locale(identifier: "tr_US") + let 🇨🇳🇺🇸 = Locale(identifier: "cn_US") + let 🇯🇵🇺🇸 = Locale(identifier: "jp_US") + let 🇪🇸🇺🇸 = Locale(identifier: "es_US") + let 🇩🇪🇺🇸 = Locale(identifier: "de_US") + + let arrayOfLocales = [🇺🇸,🇲🇽🇺🇸,🇮🇩🇺🇸,🇷🇺🇺🇸,🇧🇷🇺🇸,🇹🇷🇺🇸,🇨🇳🇺🇸,🇯🇵🇺🇸,🇪🇸🇺🇸,🇩🇪🇺🇸] + + arrayOfLocales.forEach { locale in + sharedAppDelegate.updateCurrentUserLocale(localeId: locale.identifier) + XCTAssertTrue(UserDefaults.userIsInUSA) + } + } +} + diff --git a/loafwalletTests/Legacy BRTests/DefaultFiatCurrencyTests.swift b/loafwalletTests/Legacy BRTests/DefaultFiatCurrencyTests.swift index f6b84c00b..d5ca15a54 100644 --- a/loafwalletTests/Legacy BRTests/DefaultFiatCurrencyTests.swift +++ b/loafwalletTests/Legacy BRTests/DefaultFiatCurrencyTests.swift @@ -9,17 +9,18 @@ import XCTest @testable import loafwallet class DefaultCurrencyTests : XCTestCase { + + let defaultLocalCurrency = Locale(identifier: "en_US") override func setUp() { UserDefaults.standard.removeObject(forKey: "defaultcurrency") } func testInitialValue() { - guard let localCurrency = Locale.current.currencyCode else { - XCTFail("We should have a local currency") - return - } - XCTAssertTrue(localCurrency == UserDefaults.defaultCurrencyCode, "Default currency should be equal to the local currency by default") + + XCTAssertTrue(defaultLocalCurrency.currencyCode == + UserDefaults.defaultCurrencyCode, + "Default currency should be equal to the local currency (USD) by default") } func testUpdateEUR() { From dd445b14a994aa5ac4f0243c735d0d53685bff28 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 15 May 2021 15:09:48 +0100 Subject: [PATCH 095/114] =?UTF-8?q?=F0=9F=A6=BA[Tech=20Debt]=20Added=20tem?= =?UTF-8?q?plates=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added templates fix template * fixed spike --- .github/ISSUE_TEMPLATE/bug_report.md | 30 ++++++++----------- .github/ISSUE_TEMPLATE/feature.md | 36 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 27 ----------------- .github/ISSUE_TEMPLATE/request.md | 23 +++++++++++++++ .github/ISSUE_TEMPLATE/spike.md | 9 ++++++ .github/ISSUE_TEMPLATE/tech_debt.md | 17 +++++++++++ .github/bug_report.md | 32 -------------------- .github/feature_request.md | 20 ------------- 8 files changed, 98 insertions(+), 96 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/feature.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/request.md create mode 100644 .github/ISSUE_TEMPLATE/spike.md create mode 100644 .github/ISSUE_TEMPLATE/tech_debt.md delete mode 100644 .github/bug_report.md delete mode 100644 .github/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e225bde25..da7927c6d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,14 +1,16 @@ --- -name: Bug report - Litewallet iOS -about: Create a report to help us improve Litewallet -title: 'Bug - Litewallet iOS' +name: 🦟[Bug Report] +about: An issue for when Litewallet:iOS is not operating as expected. +title: '🦟[Bug Report]' labels: 'bug' assignees: 'kcw-grunt' --- + + **Describe the bug** -A clear and concise description of what the bug is. + **To Reproduce** Steps to reproduce the behavior: @@ -17,19 +19,13 @@ Steps to reproduce the behavior: 3. Scroll down to '....' 4. See error -**Expected behavior** -A clear and concise description of what you expected to happen. - **Screenshots** -If applicable, add screenshots to help explain your problem. + -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Litewallet Version [e.g. 22] +**Observed Environment** + - OS version [e.g. _iOS 13.0_]: + - Litewallet Version [e.g. _v3.4.0_]: + - Device model:[e.g. _iPhone 11_]: -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - -**Additional context** -Add any other context about the problem here. +**Additional context or information** + diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 000000000..69f0d5ad7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,36 @@ +--- +name: 🥳[Feature] +about: An issue that improves Litewallet:iOS +title: '🥳[Feature]' +labels: 'enhancement' +assignees: 'kcw-grunt' + +--- + +## Overview + +### Why? +**Is your request related to a problem? Or, do you have an idea to improve the app? Please describe.** + + + +### What? +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + + +### Definition of Done +- [ ] Action 1 +- [ ] Action 2 +- [ ] Action N + +## UI Changes + +|**Before**|**After**| +|----------|---------| +||| \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 5768c576f..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Litewallet iOS Feature request -about: Suggest an idea for Litewallet -title: 'Litewallet Feature' -labels: 'enhancement' -assignees: 'kcw-grunt' - ---- -**Value of feature** -Add the bid of value of the work - -|**Feature Name**|**Value(Ł)**| -|----------------|------------| -|For example: Add glitter|20Ł| -||| - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/request.md b/.github/ISSUE_TEMPLATE/request.md new file mode 100644 index 000000000..bb12ccb41 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/request.md @@ -0,0 +1,23 @@ +--- +name: 💡[Request] +about: An issue that asks the Litewallet:iOS team if they could change the app. +title: '💡[Request]' +labels: 'request' +assignees: 'kcw-grunt' + +--- + +## Request overview + +### Why is it important? +**Is your request related to a problem? Or, do you have an idea to improve the app? Please describe.** + + +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/spike.md b/.github/ISSUE_TEMPLATE/spike.md new file mode 100644 index 000000000..775e2a842 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/spike.md @@ -0,0 +1,9 @@ +--- +name: 📌[Spike] +about: An issue where no code is written but some research and planning is done for Litewallet:iOS +title: '📌[Spike]' +labels: 'spike' +assignees: 'kcw-grunt' + +--- +## Subject \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/tech_debt.md b/.github/ISSUE_TEMPLATE/tech_debt.md new file mode 100644 index 000000000..7cf8f3a1f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tech_debt.md @@ -0,0 +1,17 @@ +--- +name: 🦺[Tech Debt] +about: An issue that maintains/strengthens the Litewallet:iOS code or system and **not** necessarily visible in the UI +title: '🦺[Tech Debt]' +labels: 'tech debt' +assignees: 'kcw-grunt' + +--- + +## Goal +**Describe the work to be done** + + +## Definition of Done +- [ ] Action 1 +- [ ] Action 2 +- [ ] Action N \ No newline at end of file diff --git a/.github/bug_report.md b/.github/bug_report.md deleted file mode 100644 index 6dd708f75..000000000 --- a/.github/bug_report.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots or GIFs** -If applicable, add screenshots or GIFs to help explain your problem. - -**Mobile device (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Litewallet Version [e.g. v2.7.1] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/feature_request.md b/.github/feature_request.md deleted file mode 100644 index 15c70fd2e..000000000 --- a/.github/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for Litewallet -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. From 92986e5c9df6932f2cfcdd10774f899a783907e7 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 17 May 2021 13:06:02 +0100 Subject: [PATCH 096/114] =?UTF-8?q?=F0=9F=A5=B3[Feature]=20Redesign=20unlo?= =?UTF-8?q?ck=20view=20(#50)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed price label from Header View - Extended tap area of the balance animation * removed dev loginviewcontroller storyboard * Added new lock screen SwiftUI view * Added localizations for the Lock Screen (Login) * Added SwiftUI : LockScreen HeaderView - Dev code fixes - Adjust layout * Added simple test for the Lock Screen symbol --- loafwallet.xcodeproj/project.pbxproj | 20 +++ loafwallet/Color+Extension.swift | 5 + loafwallet/LWAnalytics.swift | 2 +- loafwallet/LockScreenHeaderView.swift | 65 ++++++++ loafwallet/LockScreenHeaderViewModel.swift | 61 +++++++ loafwallet/NonUSTabBarViewController.swift | 23 +-- loafwallet/Storyboards/Main.storyboard | 155 ------------------ loafwallet/TabBarViewController.swift | 25 +-- loafwallet/src/Constants/Strings.swift | 1 + .../src/Extensions/UIColor+Extension.swift | 3 + .../Strings/Base.lproj/Localizable.strings | 3 + .../src/Strings/da.lproj/Localizable.strings | 3 + .../src/Strings/de.lproj/Localizable.strings | 3 + .../src/Strings/en.lproj/Localizable.strings | 3 + .../src/Strings/es.lproj/Localizable.strings | 3 + .../src/Strings/fr.lproj/Localizable.strings | 3 + .../src/Strings/id.lproj/Localizable.strings | 3 + .../src/Strings/it.lproj/Localizable.strings | 3 + .../src/Strings/ja.lproj/Localizable.strings | 3 + .../src/Strings/ko.lproj/Localizable.strings | 3 + .../src/Strings/nl.lproj/Localizable.strings | 3 + .../src/Strings/pt.lproj/Localizable.strings | 3 + .../src/Strings/ru.lproj/Localizable.strings | 3 + .../src/Strings/sv.lproj/Localizable.strings | 3 + .../Strings/zh-Hans.lproj/Localizable.strings | 3 + .../Strings/zh-Hant.lproj/Localizable.strings | 3 + .../ViewControllers/LoginViewController.swift | 92 ++++++++--- .../Lock Screen Tests/LockScreenTests.swift | 20 +++ 28 files changed, 297 insertions(+), 223 deletions(-) create mode 100644 loafwallet/LockScreenHeaderView.swift create mode 100644 loafwallet/LockScreenHeaderViewModel.swift create mode 100644 loafwalletTests/Lock Screen Tests/LockScreenTests.swift diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index b5b12adbe..620fa7263 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -315,6 +315,9 @@ C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */; }; C3D783B72565EA6B0004FF70 /* UnstoppableDomainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */; }; C3D783C02565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D783BF2565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift */; }; + C3EFA9A12650807B005C59B5 /* LockScreenHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3EFA9A02650807B005C59B5 /* LockScreenHeaderView.swift */; }; + C3EFA9A3265080FF005C59B5 /* LockScreenHeaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3EFA9A2265080FF005C59B5 /* LockScreenHeaderViewModel.swift */; }; + C3EFA9A62651A808005C59B5 /* LockScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3EFA9A52651A808005C59B5 /* LockScreenTests.swift */; }; C3F55645255A193D005F786F /* SupportLitecoinFoundationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F55644255A193D005F786F /* SupportLitecoinFoundationView.swift */; }; C3F55655255A195B005F786F /* SupportLitecoinFoundationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F55654255A195B005F786F /* SupportLitecoinFoundationViewModel.swift */; }; C3F7BCDC25FEC6AD00694C28 /* FailedAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F7BCD925FEC6AC00694C28 /* FailedAlertView.swift */; }; @@ -1498,6 +1501,9 @@ C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainView.swift; sourceTree = ""; }; C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainViewModel.swift; sourceTree = ""; }; C3D783BF2565ECF60004FF70 /* UnstoppableDomainViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnstoppableDomainViewModelTests.swift; sourceTree = ""; }; + C3EFA9A02650807B005C59B5 /* LockScreenHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenHeaderView.swift; sourceTree = ""; }; + C3EFA9A2265080FF005C59B5 /* LockScreenHeaderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenHeaderViewModel.swift; sourceTree = ""; }; + C3EFA9A52651A808005C59B5 /* LockScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenTests.swift; sourceTree = ""; }; C3F55644255A193D005F786F /* SupportLitecoinFoundationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportLitecoinFoundationView.swift; sourceTree = ""; }; C3F55654255A195B005F786F /* SupportLitecoinFoundationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportLitecoinFoundationViewModel.swift; sourceTree = ""; }; C3F7BCD925FEC6AC00694C28 /* FailedAlertView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FailedAlertView.swift; sourceTree = ""; }; @@ -2184,6 +2190,7 @@ 2465873723A5AAD100A32E9E /* loafwalletTests */ = { isa = PBXGroup; children = ( + C3EFA9A42651A7C4005C59B5 /* Lock Screen Tests */, C32DB42B264847D500017D26 /* Card Tests */, C3188E3126445E5E0008ADD1 /* File Tests */, C3B7C3EC255FF56100E98A64 /* Constants Tests */, @@ -3165,6 +3172,8 @@ C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */, C30029E125D0185500F08C2B /* StandardDividerView.swift */, C30029EA25D019BC00F08C2B /* CopyButtonView.swift */, + C3EFA9A02650807B005C59B5 /* LockScreenHeaderView.swift */, + C3EFA9A2265080FF005C59B5 /* LockScreenHeaderViewModel.swift */, ); name = "SwiftUI+UIKit"; sourceTree = ""; @@ -3202,6 +3211,14 @@ name = Unstoppable; sourceTree = ""; }; + C3EFA9A42651A7C4005C59B5 /* Lock Screen Tests */ = { + isa = PBXGroup; + children = ( + C3EFA9A52651A808005C59B5 /* LockScreenTests.swift */, + ); + path = "Lock Screen Tests"; + sourceTree = ""; + }; C3F55643255A1916005F786F /* SupportLitecoinFoundation */ = { isa = PBXGroup; children = ( @@ -4066,6 +4083,7 @@ 2494037623AD35C000369261 /* BuyWKWebVCTests.swift in Sources */, 24470E3223A5F5B100ADDA27 /* NSDataExtensionTests.swift in Sources */, 24470E2C23A5F43B00ADDA27 /* DefaultFiatCurrencyTests.swift in Sources */, + C3EFA9A62651A808005C59B5 /* LockScreenTests.swift in Sources */, 24470E4023A6004800ADDA27 /* WalletCreationTests.swift in Sources */, 24470E3823A5FEF200ADDA27 /* SpendingLimitTests.swift in Sources */, 24470E3E23A6000900ADDA27 /* WalletAuthenticationTests.swift in Sources */, @@ -4391,6 +4409,7 @@ C30899792616426800EE6A40 /* ForgotAlertViewModel.swift in Sources */, CEBF33041DDE17A600348FC6 /* Transaction.swift in Sources */, CEAA9E911DC0FDFE0066731D /* UIViewPropertyAnimator+BRWAdditions.swift in Sources */, + C3EFA9A12650807B005C59B5 /* LockScreenHeaderView.swift in Sources */, C3BD4A4A2597542700D97079 /* LoginCardAlertView.swift in Sources */, CEAA9EA01DC2F9F50066731D /* UIFont+BRWAdditions.swift in Sources */, C32DB42F26488CAA00017D26 /* NonUSTabBarViewController.swift in Sources */, @@ -4431,6 +4450,7 @@ CECCE5A51E02408300D99448 /* UIView+FrameChangeBlocking.swift in Sources */, 22A9A94F1DF61945000F0016 /* BRHTTPRouter.swift in Sources */, CE6DCC271E6108D50044257B /* EnterPhraseCell.swift in Sources */, + C3EFA9A3265080FF005C59B5 /* LockScreenHeaderViewModel.swift in Sources */, CE760EDD1E561DF900EFAC2B /* UpdatePinViewController.swift in Sources */, 22A9A9481DF61945000F0016 /* BRBitID.swift in Sources */, 24BA90C62410129E001E3825 /* FeeSelectorView.swift in Sources */, diff --git a/loafwallet/Color+Extension.swift b/loafwallet/Color+Extension.swift index 3e8b34029..e32caa69f 100644 --- a/loafwallet/Color+Extension.swift +++ b/loafwallet/Color+Extension.swift @@ -14,4 +14,9 @@ extension Color { static var liteWalletBlue: Color { //345D9D return Color(UIColor.liteWalletBlue) } + + static var liteWalletDarkBlue: Color { //163e7f + return Color(UIColor.liteWalletDarkBlue) + } + } diff --git a/loafwallet/LWAnalytics.swift b/loafwallet/LWAnalytics.swift index 70acc86a1..883a5013c 100644 --- a/loafwallet/LWAnalytics.swift +++ b/loafwallet/LWAnalytics.swift @@ -20,7 +20,7 @@ class LWAnalytics { properties?.forEach { key, value in parameters[key] = value } - + Analytics.logEvent(itemName.rawValue, parameters: parameters) } diff --git a/loafwallet/LockScreenHeaderView.swift b/loafwallet/LockScreenHeaderView.swift new file mode 100644 index 000000000..efa1a244c --- /dev/null +++ b/loafwallet/LockScreenHeaderView.swift @@ -0,0 +1,65 @@ +// +// LockScreenHeaderView.swift +// loafwallet +// +// Created by Kerry Washington on 5/15/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct LockScreenHeaderView: View { + + //MARK: - Combine Variables + @ObservedObject + var viewModel: LockScreenHeaderViewModel + + init(viewModel: LockScreenHeaderViewModel) { + self.viewModel = viewModel + } + + var body: some View { + + Color + .liteWalletDarkBlue + .opacity(0.9) + .edgesIgnoringSafeArea(.all) + .overlay( + VStack() { + Spacer() + Text(" 1 LTC = \(viewModel.currentValueInFiat)") + .font(Font(UIFont.barlowSemiBold(size: 16.0))) + .foregroundColor(.white) + + Text("\(S.History.currentLitecoinValue) \(viewModel.currencyCode)") + .font(Font(UIFont.barlowRegular(size: 14.0))) + .foregroundColor(Color.white.opacity(0.5)) + .padding(.bottom, 10) + }) + } +} + + +struct LockScreenHeaderView_Previews: PreviewProvider { + + static let store = Store() + static let viewModel = LockScreenHeaderViewModel(store: store) + + static var previews: some View { + + Group { + LockScreenHeaderView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhoneSE2)) + .previewDisplayName(DeviceType.Name.iPhoneSE2) + + LockScreenHeaderView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone8)) + .previewDisplayName(DeviceType.Name.iPhone8) + + LockScreenHeaderView(viewModel: viewModel) + .previewDevice(PreviewDevice(rawValue: DeviceType.Name.iPhone12ProMax)) + .previewDisplayName(DeviceType.Name.iPhone12ProMax) + } + } +} + diff --git a/loafwallet/LockScreenHeaderViewModel.swift b/loafwallet/LockScreenHeaderViewModel.swift new file mode 100644 index 000000000..b0da66dd9 --- /dev/null +++ b/loafwallet/LockScreenHeaderViewModel.swift @@ -0,0 +1,61 @@ +// +// LockScreenHeaderViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 5/15/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation + +class LockScreenHeaderViewModel: ObservableObject, Subscriber { + + //MARK: - Combine Variables + @Published + var currentValueInFiat: String = "" + + @Published + var currencyCode: String = "" + + //MARK: - Public Variables + var store: Store? + + init(store: Store) { + + self.store = store + + addSubscriptions() + fetchCurrentPrice() + } + + private func fetchCurrentPrice() { + + guard let currentRate = self.store?.state.currentRate else { + print("Error: Rate not fetched") + return + } + + // Price Label + let fiatRate = Double( round ( 100 * currentRate.rate / 100)) + let formattedFiatString = String(format: "%.02f", fiatRate) + currencyCode = currentRate.code + let currencySymbol = Currency.getSymbolForCurrencyCode(code: currencyCode) ?? "" + currentValueInFiat = String(currencySymbol + formattedFiatString) + } + + // MARK: - Add Subscriptions + private func addSubscriptions() { + + guard let store = self.store else { + NSLog("ERROR: Store not initialized") + return + } + + store.subscribe(self, selector: { $0.currentRate != $1.currentRate}, + callback: { _ in + self.fetchCurrentPrice() + }) + + } +} + diff --git a/loafwallet/NonUSTabBarViewController.swift b/loafwallet/NonUSTabBarViewController.swift index 9dfb48420..8ec4cb1a2 100644 --- a/loafwallet/NonUSTabBarViewController.swift +++ b/loafwallet/NonUSTabBarViewController.swift @@ -15,11 +15,7 @@ class NonUSTabBarViewController: UIViewController, Subscriber, Trackable, UITabB @IBOutlet weak var headerView: UIView! @IBOutlet weak var containerView: UIView! @IBOutlet weak var tabBar: UITabBar! - @IBOutlet weak var currentLTCPriceLabel: UILabel! @IBOutlet weak var settingsButton: UIButton! - @IBOutlet weak var timeStampLabel: UILabel! - @IBOutlet weak var timeStampStackView: UIStackView! - @IBOutlet weak var timeStampStackViewHeight: NSLayoutConstraint! @IBOutlet weak var walletBalanceLabel: UILabel! var primaryBalanceLabel: UpdatingLabel? @@ -175,7 +171,7 @@ class NonUSTabBarViewController: UIViewController, Subscriber, Trackable, UITabB currencyTapView.constrain([ currencyTapView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 0), - currencyTapView.trailingAnchor.constraint(equalTo: self.timeStampStackView.leadingAnchor, constant: 0), + currencyTapView.trailingAnchor.constraint(equalTo: self.settingsButton.leadingAnchor, constant: -C.padding[5]), currencyTapView.topAnchor.constraint(equalTo: primaryLabel.topAnchor, constant: 0), currencyTapView.bottomAnchor.constraint(equalTo: primaryLabel.bottomAnchor, constant: C.padding[1]) ]) @@ -281,23 +277,6 @@ class NonUSTabBarViewController: UIViewController, Subscriber, Trackable, UITabB secondaryLabel.transform = .identity primaryLabel.transform = transform(forView: primaryLabel) } - - // Time and Price Label - let timeText = S.TransactionDetails.priceTimeStampLabel + " " + dateFormatter.string(from: Date()) - let fiatRate = Double(round(100*rate.rate)/100) - let formattedFiatString = String(format: "%.02f", fiatRate) - let newPrice = Currency.getSymbolForCurrencyCode(code: rate.code)! + formattedFiatString - - self.currentLTCPriceLabel.text = " " - self.timeStampLabel.text = timeText - - // Transitions when the data changes - UIView.transition(with: self.currentLTCPriceLabel, - duration: 2.0, - options: .transitionFlipFromLeft, - animations: { [weak self] in - self?.currentLTCPriceLabel.text = newPrice - }, completion: nil) } /// Transform LTC and Fiat Balances diff --git a/loafwallet/Storyboards/Main.storyboard b/loafwallet/Storyboards/Main.storyboard index bf269338e..30c6f6e91 100644 --- a/loafwallet/Storyboards/Main.storyboard +++ b/loafwallet/Storyboards/Main.storyboard @@ -9,12 +9,6 @@ - - BarlowSemiCondensed-Bold - - - BarlowSemiCondensed-Light - BarlowSemiCondensed-Medium @@ -59,26 +53,6 @@ - - - - - - - - - -