From 2b57e2a07f4dc0604857f4f281759b41de0d7f18 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 22 Aug 2020 23:44:21 +0100 Subject: [PATCH 01/35] Develop (#111) * 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 Co-authored-by: Mohamed Barry --- .gitignore | 3 +- Podfile | 4 +- loafwallet.xcodeproj/project.pbxproj | 66 +++++++++---------- loafwallet/AppDelegate.swift | 6 +- loafwallet/Info.plist | 3 - loafwallet/src/ApplicationController.swift | 13 ++-- loafwallet/src/Constants/Constants.swift | 4 +- .../src/Extensions/UIFont+BRWAdditions.swift | 8 +-- .../Import/StartImportViewController.swift | 31 +++++---- .../RootModals/SendViewController.swift | 3 +- .../ViewControllers/ScanViewController.swift | 4 +- 11 files changed, 71 insertions(+), 74 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/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 diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index ffcacf158..1481919af 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 */, ); @@ -5008,7 +5002,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 +5016,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 +5033,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 +5204,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 +5213,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 +5228,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 +5238,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 +5250,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 +5260,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 +5615,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 +5623,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 +5639,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 +5662,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 +5675,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 +5690,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 +5699,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 +5711,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 +5720,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 +5813,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 +5827,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 +5844,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 +5865,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 +5874,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 +5889,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 +5899,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 +5911,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 +5921,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 = ""; 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/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/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() { 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/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 { 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() - } - }) + }) + } }) }) } 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)] 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 f3b386d19d3679ff5724bb930e5957dc6543bd46 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 15 Oct 2020 00:32:09 +0100 Subject: [PATCH 02/35] [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 --- .github/bug_report.md | 32 +++++++++++++++++++ .github/feature_request.md | 20 ++++++++++++ .../loafwallet WatchKit App.xcscheme | 4 +-- 3 files changed, 54 insertions(+), 2 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 1c2ce4696..2b117aa58 100644 --- a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme +++ b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme @@ -96,7 +96,7 @@ + RemotePath = "/Litewallet"> + RemotePath = "/Litewallet"> Date: Fri, 30 Oct 2020 11:33:43 -0700 Subject: [PATCH 03/35] 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 --- NotificationServiceExtension/Info.plist | 31 - .../NotificationService.swift | 36 - Podfile | 7 - .../AppIcon.appiconset/CoinBlue100.png | Bin 3748 -> 0 bytes .../AppIcon.appiconset/CoinBlue1024.png | Bin 66442 -> 0 bytes .../AppIcon.appiconset/CoinBlue172.png | Bin 11889 -> 0 bytes .../AppIcon.appiconset/CoinBlue196.png | Bin 16292 -> 0 bytes .../AppIcon.appiconset/CoinBlue216.png | Bin 16488 -> 0 bytes .../AppIcon.appiconset/CoinBlue48.png | Bin 4507 -> 0 bytes .../AppIcon.appiconset/CoinBlue55.png | Bin 5136 -> 0 bytes .../AppIcon.appiconset/CoinBlue58.png | Bin 1612 -> 0 bytes .../AppIcon.appiconset/CoinBlue80.png | Bin 2206 -> 0 bytes .../AppIcon.appiconset/CoinBlue87.png | Bin 2335 -> 0 bytes .../AppIcon.appiconset/CoinBlue88.png | Bin 6034 -> 0 bytes .../AppIcon.appiconset/Contents.json | 92 -- .../Assets.xcassets/Contents.json | 6 - .../Base.lproj/Interface.storyboard | 82 -- loafwallet WatchKit App/Info.plist | 33 - .../LoadingIndicator.xcassets/Contents.json | 6 - .../LoadingIndicator1.imageset/Contents.json | 21 - .../LoadingIndicator1@2x.png | Bin 1715 -> 0 bytes .../LoadingIndicator10.imageset/Contents.json | 21 - .../LoadingIndicator10@2x.png | Bin 1715 -> 0 bytes .../LoadingIndicator11.imageset/Contents.json | 21 - .../LoadingIndicator11@2x.png | Bin 1715 -> 0 bytes .../LoadingIndicator12.imageset/Contents.json | 21 - .../LoadingIndicator12@2x.png | Bin 1728 -> 0 bytes .../LoadingIndicator13.imageset/Contents.json | 21 - .../LoadingIndicator13@2x.png | Bin 1716 -> 0 bytes .../LoadingIndicator14.imageset/Contents.json | 21 - .../LoadingIndicator14@2x.png | Bin 1685 -> 0 bytes .../LoadingIndicator15.imageset/Contents.json | 21 - .../LoadingIndicator15@2x.png | Bin 1706 -> 0 bytes .../LoadingIndicator16.imageset/Contents.json | 21 - .../LoadingIndicator16@2x.png | Bin 1709 -> 0 bytes .../LoadingIndicator17.imageset/Contents.json | 21 - .../LoadingIndicator17@2x.png | Bin 1705 -> 0 bytes .../LoadingIndicator18.imageset/Contents.json | 21 - .../LoadingIndicator18@2x.png | Bin 1724 -> 0 bytes .../LoadingIndicator19.imageset/Contents.json | 21 - .../LoadingIndicator19@2x.png | Bin 1699 -> 0 bytes .../LoadingIndicator2.imageset/Contents.json | 21 - .../LoadingIndicator2@2x.png | Bin 1715 -> 0 bytes .../LoadingIndicator20.imageset/Contents.json | 21 - .../LoadingIndicator20@2x.png | Bin 1737 -> 0 bytes .../LoadingIndicator21.imageset/Contents.json | 21 - .../LoadingIndicator21@2x.png | Bin 1728 -> 0 bytes .../LoadingIndicator22.imageset/Contents.json | 21 - .../LoadingIndicator22@2x.png | Bin 1724 -> 0 bytes .../LoadingIndicator23.imageset/Contents.json | 21 - .../LoadingIndicator23@2x.png | Bin 1708 -> 0 bytes .../LoadingIndicator24.imageset/Contents.json | 21 - .../LoadingIndicator24@2x.png | Bin 1750 -> 0 bytes .../LoadingIndicator25.imageset/Contents.json | 21 - .../LoadingIndicator25@2x.png | Bin 1692 -> 0 bytes .../LoadingIndicator26.imageset/Contents.json | 21 - .../LoadingIndicator26@2x.png | Bin 1731 -> 0 bytes .../LoadingIndicator27.imageset/Contents.json | 21 - .../LoadingIndicator27@2x.png | Bin 1704 -> 0 bytes .../LoadingIndicator28.imageset/Contents.json | 21 - .../LoadingIndicator28@2x.png | Bin 1705 -> 0 bytes .../LoadingIndicator29.imageset/Contents.json | 21 - .../LoadingIndicator29@2x.png | Bin 1727 -> 0 bytes .../LoadingIndicator3.imageset/Contents.json | 21 - .../LoadingIndicator3@2x.png | Bin 1742 -> 0 bytes .../LoadingIndicator30.imageset/Contents.json | 21 - .../LoadingIndicator30@2x.png | Bin 1717 -> 0 bytes .../LoadingIndicator4.imageset/Contents.json | 21 - .../LoadingIndicator4@2x.png | Bin 1747 -> 0 bytes .../LoadingIndicator5.imageset/Contents.json | 21 - .../LoadingIndicator5@2x.png | Bin 1707 -> 0 bytes .../LoadingIndicator6.imageset/Contents.json | 21 - .../LoadingIndicator6@2x.png | Bin 1683 -> 0 bytes .../LoadingIndicator7.imageset/Contents.json | 21 - .../LoadingIndicator7@2x.png | Bin 1740 -> 0 bytes .../LoadingIndicator8.imageset/Contents.json | 21 - .../LoadingIndicator8@2x.png | Bin 1709 -> 0 bytes .../LoadingIndicator9.imageset/Contents.json | 21 - .../LoadingIndicator9@2x.png | Bin 1738 -> 0 bytes .../da.lproj/Interface.strings | 21 - .../de.lproj/Interface.strings | 18 - .../en.lproj/Interface.strings | 18 - .../es.lproj/Interface.strings | 18 - .../fr.lproj/Interface.strings | 18 - .../id.lproj/Interface.strings | 18 - .../it.lproj/Interface.strings | 18 - .../ja.lproj/Interface.strings | 18 - .../ko.lproj/Interface.strings | 18 - .../nl.lproj/Interface.strings | 18 - .../pt.lproj/Interface.strings | 18 - .../ru.lproj/Interface.strings | 18 - .../sv.lproj/Interface.strings | 18 - .../zh-Hans.lproj/Interface.strings | 18 - .../zh-Hant.lproj/Interface.strings | 18 - .../Circular.imageset/Contents.json | 28 - .../Contents.json | 48 - .../Extra Large.imageset/Contents.json | 12 - .../Graphic Bezel.imageset/Contents.json | 12 - .../Graphic Circular.imageset/Contents.json | 12 - .../Graphic Corner.imageset/Contents.json | 12 - .../Contents.json | 12 - .../Modular.imageset/Contents.json | 28 - .../Utilitarian.imageset/Contents.json | 28 - .../BRAWWeakTimerTarget.swift | 43 - .../BalanceInterfaceController.swift | 59 - .../ComplicationController.swift | 56 - .../ExtensionDelegate.swift | 25 - loafwallet WatchKit Extension/Info.plist | 48 - .../NotificationController.swift | 43 - .../PushNotificationPayload.apns | 18 - .../ReceiveInterfaceController.swift | 28 - .../SharedConstants.swift | 33 - .../WatchDataManager.swift | 136 --- loafwallet.xcodeproj/project.pbxproj | 1012 ++--------------- .../xcschemes/Debug-loafwallet.xcscheme | 115 -- loafwallet/src/ApplicationController.swift | 7 +- loafwallet/src/Constants/Constants.swift | 89 +- loafwallet/src/Constants/Strings.swift | 4 - .../FlowControllers/MessageUIPresenter.swift | 16 +- loafwallet/src/ModalPresenter.swift | 7 +- loafwallet/src/Platform/BRWalletPlugin.swift | 1 - .../src/Watch/PhoneWCSessionManager.swift | 91 -- loafwallet/src/Watch/WatchData.swift | 72 -- loafwallet/src/Watch/WatchTransaction.swift | 44 - loafwalletUITests/Info.plist | 22 - .../MainNavigationVIewUITests.swift | 53 - loafwalletUITests/loafwalletUITests.swift | 36 - 127 files changed, 160 insertions(+), 3286 deletions(-) delete mode 100644 NotificationServiceExtension/Info.plist delete mode 100644 NotificationServiceExtension/NotificationService.swift delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue100.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue1024.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue172.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue196.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue216.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue48.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue55.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue58.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue80.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue87.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue88.png delete mode 100644 loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 loafwallet WatchKit App/Assets.xcassets/Contents.json delete mode 100644 loafwallet WatchKit App/Base.lproj/Interface.storyboard delete mode 100644 loafwallet WatchKit App/Info.plist delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator1.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator1.imageset/LoadingIndicator1@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator10.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator10.imageset/LoadingIndicator10@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator11.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator11.imageset/LoadingIndicator11@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator12.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator12.imageset/LoadingIndicator12@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator13.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator13.imageset/LoadingIndicator13@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator14.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator14.imageset/LoadingIndicator14@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator15.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator15.imageset/LoadingIndicator15@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator16.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator16.imageset/LoadingIndicator16@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator17.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator17.imageset/LoadingIndicator17@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator18.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator18.imageset/LoadingIndicator18@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator19.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator19.imageset/LoadingIndicator19@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator2.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator2.imageset/LoadingIndicator2@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator20.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator20.imageset/LoadingIndicator20@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator21.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator21.imageset/LoadingIndicator21@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator22.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator22.imageset/LoadingIndicator22@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator23.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator23.imageset/LoadingIndicator23@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator24.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator24.imageset/LoadingIndicator24@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator25.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator25.imageset/LoadingIndicator25@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator26.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator26.imageset/LoadingIndicator26@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator27.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator27.imageset/LoadingIndicator27@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator28.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator28.imageset/LoadingIndicator28@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator29.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator29.imageset/LoadingIndicator29@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator3.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator3.imageset/LoadingIndicator3@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator30.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator30.imageset/LoadingIndicator30@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator4.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator4.imageset/LoadingIndicator4@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator5.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator5.imageset/LoadingIndicator5@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator6.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator6.imageset/LoadingIndicator6@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator7.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator7.imageset/LoadingIndicator7@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator8.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator8.imageset/LoadingIndicator8@2x.png delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator9.imageset/Contents.json delete mode 100644 loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator9.imageset/LoadingIndicator9@2x.png delete mode 100644 loafwallet WatchKit App/da.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/de.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/en.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/es.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/fr.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/id.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/it.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/ja.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/ko.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/nl.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/pt.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/ru.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/sv.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/zh-Hans.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/zh-Hant.lproj/Interface.strings delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json delete mode 100644 loafwallet WatchKit Extension/BRAWWeakTimerTarget.swift delete mode 100644 loafwallet WatchKit Extension/BalanceInterfaceController.swift delete mode 100644 loafwallet WatchKit Extension/ComplicationController.swift delete mode 100644 loafwallet WatchKit Extension/ExtensionDelegate.swift delete mode 100644 loafwallet WatchKit Extension/Info.plist delete mode 100644 loafwallet WatchKit Extension/NotificationController.swift delete mode 100644 loafwallet WatchKit Extension/PushNotificationPayload.apns delete mode 100644 loafwallet WatchKit Extension/ReceiveInterfaceController.swift delete mode 100644 loafwallet WatchKit Extension/SharedConstants.swift delete mode 100644 loafwallet WatchKit Extension/WatchDataManager.swift delete mode 100644 loafwallet.xcodeproj/xcshareddata/xcschemes/Debug-loafwallet.xcscheme delete mode 100644 loafwallet/src/Watch/PhoneWCSessionManager.swift delete mode 100644 loafwallet/src/Watch/WatchData.swift delete mode 100644 loafwallet/src/Watch/WatchTransaction.swift delete mode 100644 loafwalletUITests/Info.plist delete mode 100644 loafwalletUITests/MainNavigationVIewUITests.swift delete mode 100644 loafwalletUITests/loafwalletUITests.swift diff --git a/NotificationServiceExtension/Info.plist b/NotificationServiceExtension/Info.plist deleted file mode 100644 index 44ac604d0..000000000 --- a/NotificationServiceExtension/Info.plist +++ /dev/null @@ -1,31 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - $(PRODUCT_NAME) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSExtension - - NSExtensionPointIdentifier - com.apple.usernotifications.service - NSExtensionPrincipalClass - $(PRODUCT_MODULE_NAME).NotificationService - - - diff --git a/NotificationServiceExtension/NotificationService.swift b/NotificationServiceExtension/NotificationService.swift deleted file mode 100644 index 5c682ae6e..000000000 --- a/NotificationServiceExtension/NotificationService.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// NotificationService.swift -// NotificationServiceExtension -// -// Created by ajv on 10/5/16. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import UserNotifications - -class NotificationService: UNNotificationServiceExtension { - - var contentHandler: ((UNNotificationContent) -> Void)? - var bestAttemptContent: UNMutableNotificationContent? - - override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { - self.contentHandler = contentHandler - bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) - - if let bestAttemptContent = bestAttemptContent { - // Modify the notification content here... - bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" - - contentHandler(bestAttemptContent) - } - } - - override func serviceExtensionTimeWillExpire() { - // Called just before the extension will be terminated by the system. - // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. - if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { - contentHandler(bestAttemptContent) - } - } - -} diff --git a/Podfile b/Podfile index 9559095cb..c8a3bf77d 100644 --- a/Podfile +++ b/Podfile @@ -16,9 +16,6 @@ def shared_pods # add after v2.6.0 pod 'SwiftLint' end -def shared_watchOS_pods -end - target 'loafwallet' do platform :ios, '12.0' shared_pods @@ -27,9 +24,5 @@ target 'loafwallet' do inherit! :search_paths end - target 'loafwalletUITests' do - inherit! :search_paths - end - end diff --git a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue100.png b/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue100.png deleted file mode 100644 index 0b189494687635b515bf250437e3c6d47cc2e240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3748 zcmZ`+c{tSV_x=bOh8jyXWZ%~}`J0B}kTMSll?Kv@9TKmmYy9speP zE$V^aq&{49Ha64)D1Xnh-kL0GgwfXs=??(^2>msh;3};kYLFoSW}?rqN_X)Rh^u`B zO|8a~1=G{E3jVxR6ynV>%QLiO7Z%#P=@QYH>f^FYKZk1JiId8%FyuFaRb^ItvS)}| z>>Fl^>fEE$a&gexDBY`w7sizTYh_Xi_4rtjjk?S39V>UTvj2Hd`BqRwe3?aDY&{29R^EoL3^;~Fv}1!%k&ZQ z&q2oVSDl6@1*JL5SI>e$d*0E-`|;Ioy1b5a*HW;^TO)e_z@y8_k}}5jtqde3Yz(m%-%XAscoGGwQt5zqW2m;JWU%uM+TTIA`q z&r-=B!R_9mJRPrP#I8z{5+Aj+Pb`q+K16zk6UpFKZhpWdQy2!J(*_+uQ)mXE0`G^t%4Y7=c%3BPWJV$+{v>^D{hxJ_n=m;Hc{?VSVp zreoelPoI<6!9}5(=J69kXuKfoftVZC7aKdAIB0*}_~?gt*O$A;7o}4MTBDA8r+xj1 zWLw~F7ls#UYOs>^vYyw@k^7^$BY>#be(j^>?SbsGfCjqaYCAXhl1W*;>ZWuyx`piRQA$~@4IwlTs>yz(Zam6*(!MzRh zuH*!qFs^jVuKT!5@=ogfZF+=2&KJtV(bhGuP#*nSO%tMciXS$1sXuD{MwE?@ysX@! z%zeZk6ng1;O`%47N@!p_uMTvf8zu}B&+B}{8W|C|{ij9+!T!@PmVDX3G5j2DJj)V$ zr;=Y!Iaxq$D%iGA7N7%yG0Ggw{!D!>-dKFo`&+xDHAJvP!WHLk$KT7@NfAj2;!93v z=Lfd(7Te#GA8Uw}YMvmoW0?jut}pN4M>KayqHkB>%V=iSMaskEq)GtbPVbz(vW7+k zG6&XZr741|e$qNmeyq8{+`s=#0a8vMcX*UB?oxxVGhzZzlW-;SC8xrJ+@T1X`+M%h z+8Rnw&(36qscWuO%ydBH$(GQyPpO9?xSUF{oc}68g&jfZZ%_7SHftZJIozDTRr%Fs zzGbj_%^?C$@6_0w`}&|3gRI_7An>IG9CmZ6SLfqqf5s$Q!r7tkRkxrN-ltWy?cM{p}N|>TP zn@{8ixmB>&g-u_V9o%S*{`Uk(a}$I!R(ExAU>7sa`vvd z5`xOEhi2v#bggNkUQ+s^jm@`?pQ}{r(;8*w6|g9EG8@TX?Z7?S4IYiY>T?AEScB$d zs_5$oZZZoMM%8A*_RRXcK0G*I^G_Ds+K(yO{%C{bd(r?f^yaC^I-@~xG|P4J4ZA?k zPgJcm$r@)h>+-jtM~r<-C}*pcVyD5Wx5|Cz-b;D$yTGkM?NW)lmNZ86!xM3a345;D z?@fX!S!^r~cjU2S<40+&a0dl*0J!}TeOBc+l_9RPeEPy?j$C16g4(-jQ<9r0@Zv|B z+`~;CYu9e=+Z?b4;Fy9PN%;ElbzBNJ`5|>isItvaPa@|LITbkTctb1-r z!k2NAW>+_m+<2JLI|C=r7)=cmgZz1xuKv~fP2&8fdMY^UoAK^WC4Ig68|ZDEDlR}V zzu0ZQqfAdxjVdu-Zxr0ahN$g+oEH4bzcH=)d0H4&gidOZ{GQ@W$PicL%wH+WE|530 zcMU?uXbx1e_icRoRYoPLT?tB<$usGh#3QGA#=w+GOYENsG_E58N*kLNiFte&A(hMF zDh8Wy2tReD9Qu{czpJ%16_BjZmS`l>>86-o9eNXZ1!?xfPGVEiCwgnE)DCqQ0Gcm0Iz^x#EZ-;1KJ!R|mh5Vt zHn=GC$SLzn%NX$nAp$ho*pFH4-dC&quj;eLAz=^+ZdN+&lh};g z;+V-P>i+@ZA9k*F5Y6=S+2jGY{w7%Cbg@ir-h`N%ci=|xwpb`Z_sI)n;@F-C(gEXE zum76YWpYO0D&GWqY?5F`ffy^|>DzTtp^7`IEL18jL$>9c^Sc{#ZJOXrF@)D>lpdI< zSMYSFWzFp~M>?^viRN`}&1_C0nsmd#f9w=F{n$T|NiaLhb8MpREuHa@xsq$z+~yX) zUU&XXc@f&FUBSLWHOC2W#hpHrt)?gCNYwZ}xIvoRbPwijaww4qFYPve-ab)v=eDG^ zdi-arVkwL$uZ0!IeC}GcUH2`Xfxb2YtB(A0np0ni!LgobFPhPKkw)?XL5!OY;=Bp za;&v=bP?gYC^1yAFBoP~u07{%A2Orfs$>n<4>{R2W)b?Ql*pR|F*R1+sg=rhmR?U= zA70x!)VGk#>$?YCJslB|v-nq>Vu${R`{`o4AUDauIyLpDH>uY%|7YiLp2@NIjft`6BPJ!g5WLK&O&-YLek%WExM_Ug1f{vN?xK|1)b7E; z^drOak}`~xOL3>jh}sILpK%i_7NphjQc_>`%Q4IFndwgL4U%2fjowR_b+U`yB!*2g zJoqZc?YZ2AGCvO*{2KGx?+0hcE$?Kdt8(*XG@y?&wmw^bQ@pZ4)Ki`?i<=% ziSnIz1tIwGtcRa{r^jyh2$hx0bzpXy@6~hA)`rZ@4Ih=wF8c74_Sjy!?q6x+@Y`>T zRw)FtV7cY;LzK4vZ1=~o|LkgH%0ji$uZbOGVX^3!1CD=18HE3wgTIxiWqUV;*yHJ7r=Zp~$T zx=_Mzl40{{(D&wwz#U^{AG}ofNz4b*U6%F~u%BIvmuT>-z^}oZ&-{Z$>o@!c)Z-<` zVe>Y&Elth*3S?fbe@^b}tId&%ytknb`xWJW?8hT60k<=RMSk&PaI$(J6iQxRjdO-N z&c|<%uDtcMnGGAFnQ8iTap={;c~3}TC zDRs4NdDFAXxOrb2+pBVU!u@=}2uEI1k&;z(m6uI)i)fpcjSB7?bH@4bgcmt2*!I}! zWQFPc&u!=Qvf3j-xMJ630(A-z3D8Fbpq&C-)mJqHNg?va*Q~ku5XFC}dOiKK4H6 zJa@m}^G`h2_0-kX?RMRt`+dLX>;3+`KGAwQs^qsBZvy~8uC4|%002Vpk`N%l2md=j zv`+l{$yq^L0RUWVP&3d5fIvCIGw?1b}T@0FcZC0Q%=S z-}I%yUl7@As=@%=zrXoyr77SY(&uXCz5u|__U|8FK(U-3c$4^ry0$X$3L()QQvBw& zVH~(3pbk?o3Ygu+_%~Tiy?hXuD75}G2t7Xb`i%-DfcKu8u!~dU%ctpNP3kGyxhILf zE7?a2+2Uu~Eq?Y~m&w82%hT+)MD(FIRa%i#oNAG{m$}@Lnk)i z(NVGgkloll!rrJ6CEN*%jBlIDLgzRn48m1Fp#Wfv(Xl|_f3ARaihmjb0C_S{761OY zu#)`m1s@^a|6JrpKK$PsUnu|S5c~wX@c+Frrbzj}7f=63t^a=!P#gbWC&2&Xe!~8A zlMD<4ML0|gt^$L3xT(P5D6Jj{Z}7NHr5n5i?goRqj%iS9tbH*%ERGQ{z0neS#8F_T z6T4Pqbk^(hR3n&!G_A+o3CM>c(;^rv0k?T-weNKc$S z@|I1v+|5KHBaq0ob%X`mZH2*ssLbek8x<88N=pSc6H5dDqTi?TbOGQw*KVKZL{!ul z$sb&7G=Z_TH5HeX;aL=n;pvY&wTx|PGS^+8 z2f`!~odZiE>FBL=)N*u$TVlqeD{zr8@B>W$<(OyDNUGW-Z?Vqy*GqwF+i&10hiU9a z2694%4B5Q#+Ub2IJPw9wwdKF2ja~)UiAWgor>7X1TcT$E^Rwyw#i$wo>VM3yjUqkO}dM5EKkMbw&F8z-&lOle5*%VY$%{lLZ7dok)PmY@JiYl z0YCF}K{#DMZ;v9%GGweQ(l$%7F`;q3aHKoAy8Bo4%@N1m5Z&GMmundU&nz07K7Xlv zKdRh3z2=aSXhqxn1jpm3dDp9ny>6EU&mF8ZUx~oX`sWi;{}fjx`EdkwWO9pd@!gD% zq=km&+KZCZ1T9+P{#Z7ewSvRtO-EN355M4V(lQo)`UxBmztpr=GePnm_Q{z*w(Gfx;4*z1w$Vby1U?^VOtp_+<90-QM-Og2R)Cj^2dN)28-ITcylYdZOg)@<`+S z*AjeV!%7pg!}x~VytDu?PY9L``7|Ulsoi8;Nrf)D)wRc_x+tYSZE)-8g%Cq7H+dW? zPKV=-LvL5@^4K)$!YG;@9$klYH55J7>hsV_Hy(2QKECr3?P%UhX6%bc)#h#8{&)YE z7o-1uD;v}IZjl{Mum3hMb!qXcc=V~Dmdz|rm)Hr((u!keP5E{#8>-rZ%=?d&nY_dvM{=o86RYK42tjrly>!K6s*{ts_>~A?t~o z{cQ^goEr=ZT6iK-mW{c)c<^<7$L7yY^QOvAIU5Qhw;pQeYZlZ*c;bgoX0y$1=GQ-Z zBiCYm+)e$etQVVu_3bW`&zxfCjt|`{3Ek+zop`t$S0mQ=#F#+={}opkKEJj`l~0mO z`w^=z*|11^VL@RTK`|+5>sCqe$tMO(d53H?#YxdK8g9D~P80GX>xigSzawe{_B_$deA7N&Mv}EU1ab)zN;s(q^Rk{sGRWqe9IwAIj6u8E`Ul^HL-^gan4f4}#jY@emEj0fD03$ui6Ld31ZSG42 zz524T-E--_V(66h=v_H7`Ew@HT##Ig6Q=S5l{I-_8f5z`zT}A>u0ma4XO`U@XDBuz zMlBBSN5Oy3!|LYv-SA8iT#(;+ItGSI7q0e-KMkyKPk(6p=}AB6_SA4i$RR- z>1$zHv=SrHHZ66&*Xws%&=w6l?Z%)U12N&r#=0RUoT;RE@+%;+3?q7C9*N&wajyMCs3g8zDTV0_XtD7NuK>+mmDe?{M%tC`VPyQe^zpu__nk!YXw*BPhyylzu($%u{J$NWE5iVyU3a86(pr=6= z_kKFB4p@CH+VZt(y50LSxjLAYeks8DD!)4i^E5{k><7re?7cm7dR$+Z(rjH>!)^R) zYi9MRbK>xr?cL~|2RjVBB|4T>vc@*lVs`rVQ+X?7dTgAiZVy=3fbuQxTGs*fI(N-; zB@5HN#X9@rZ^a+>n$Hv)x?D&CF}zSncOxE9CIH%AkG_ryVY0n4@BZ;$$R|brDv$m6 zE=VQe!~Jh!(tFE(!o~03zxwNj_jXx_=vXlmW|lb-#SR&)ZF-+-D&RiX;I#IA&ct)6 zDR{E(?5^gl*MC<^f{>xm7;*wYj{-EjEvwV_^Ich5)k(kIa*B}e;~7_6x|U2bzoCIg zH+qFs(Pg?!#J@UG@YD);wuJs9#c@J3A2l6ZSeR}t%1R5Kkj$KID%0fDTdh4L_Q|R> zP}!7~-l>E0^mW}GST{E%e%P%DFn-B8flTfgCLaJm$$_~u)0EYvX>pJ%n~*v0@rO3)z@z2O!6BNBYMncABO0`o zx{=c6pLa9~y;_YK&Q2AXf9SB$*})-x8c9t#6*kR9pHFi+=AQ7**1qb+ob%h%7QKn8 z^HYLzc0bW!BLXssL5m1(#BuMeI;e~o_hTGVdf7JKCgj|g4szOF?nL#xP~>HNT$@Sc z<>(gt(VI*DqY&J0#{4e-ZBFyoV})lfE8Eqdc3RFnb{5+jf+p+SsK>S+ImFFA{J%?^ zqO^vMqLDd9iMv@j{AjtEuV~oPOl3+NTk%%1vpsp*fKX(<5rzYnbBh?FNED{xyAm>F zZupc71>;RJrOAL6jwpVCE6+8)v_j7|oYn5RX9&1*L7-$=pGZj(n25rf-+;DgD4l$} z$qt!`Soe6e;J-Xe_O2$kNkm9;t<;$ZR+J^lDK=S!>c6;ZV#yygN(mDb5|Y{=sEy5R zu9WF0QfgdkIgvV>Kkj+6L;rF$ira#ptRjhqmlTj6{ug?Dw?v`T<+fK%AAxqK$ zYn|m?(ZZv&Jn*h?f5nQfxBm#zoi`tO-dnM6gY zO-{sRLb^D?AYcHkTK2li45xBgSHZl)5V+pCMxSWOjJ$o}pmJ3>j1?RyhTSRH>O z3bopEiz7YC(kRNwT&nH5;1nI?u>yuzZ_>w|`>s)1?+JlF)u51_%s(`41_!LXYzr&e zl%O^X{)fmAdI5@&z*w!eD-EV-s#`TDvvG12jDWC;IaD9&-HlqTguSAp_cr@lxEGS> zb+zd4_09jZ@V*j`GBq=TAsbwI1gw~ydqQk%LlypYY(a0fSGCsCRxmb!wHuS;ZxnnO zTQ6Zu(4>mxOzSWUID{8cQsTz6)~j4K_~!i6MfOtr+S~)nuP^jjW9L~jlhjSrBESW| z5`cN;nX%Y=)B5|@)LbQ+&isioK?mFQ#QfT(Ij$t_>@f2N{C$4F|IJK9WTuh&vKZae z`Y&{#$IA7Ch0hMhM;um>9)HknG0z)0KaXYn2gKunD=xkUp>ze6x!9?=g+?{Gc1Lg( z8i~mmwfykHTVb5qy}P@-pYK+FUuH$6C%cfU=QdCF?-%XpT5|MEgWvZoBS|>4_{L zD1B=!{wt{6KZXOY$<5wF8(v=UO0Ltgr9CLud^$&vCcCGvw*1-VGXy&KG||hZ;kZ5R z!`>^1#+xjpgZCW?P{{xOefL8`GR91fgovm>VlIlDZNys7L3;|O*vQDRHkCKR7VcQ{ zVJcREs8c#%FV1en4}jLHOGUnId5Wm2Mza0JuwQ!A6r8aI7*Eu)Hy(sQeTvp;F|rlqQ!G;A+d`2s|5 zXAPgMl;G)kWe!9PlE%iiNzj@9qVlquIihVbx|ckK@^DF2Aa) z*XPgX#@aHY6!k=Xx*<_`0N-sqApdT;ISF0!wt69#z<-D%WXih{?f>HFCbg8Pp|{9Y z;-m=W+3Yzvefc%sG;^!MD$`%?HhUc|T~!l5Xh(=rAWxwyyIhKwd>&21ghTQ2c(zk8gjry0*s(6Ik65`7Vo(q3pPY#DD24hPcCFD2BrmqG(15xRC!_Xy-H% z%epz)RbI2-c9LNuWq#EBK3$u}P7K;B1LXIT&_F90)R}rclhUvw*I#kNUURLkd&wSk zot30eKVm?HhY$$kbc8DmM++JzzpXb_>A3o_HY)8u>l>sNlMt*Ica0ZTH&XCJXZenH z3F4wg=HSU7?w|4J2Nj?*1{g zZa$hc9Wk8X%zDq+#T&63R69%$EJl1_v$M}I9C0-WUTP7;o%(wPytv*TX_ThokQJxf zc)kO;5P?b|7r1}rJi4xt+#XzY&J$E4>wh5JEbSVpSOHfc<$8tJIcE>?RqWQ{7aMec z8jAjYzx_NqXt6#h#Mwe;GFWe;$4(T;?_vcZxS;5<0#d>+IS{j6pb6&f)83D58WOji z>O=@9t_V8$0zEzTA|m5C#2%Tc<<7V52R*PkpL(z`Z5iDgr zih}X5Pm*DM>ACgI5l_Zh-UAI|arUWq*vup1FsZ)o^@y3?9}=9nX@Z5N>*}EP^M&&@ z`;0&iVXp8tJRqI~jE62q)k|vq#_{v55PI3`;bYa&L}O`Wjd(3(9gZ3JvtLU?WA`zN zeM4OO%gZ&2;OoAQ!&MW=kwW=5%dmUEm>L-HjOyFQ5%u`<83~q{*qRTrfp)D1q+O;E z)ryL@6r#XHE)5;LhEt!FrNt^c1G{kUd0E{rMx{>z4vivW9)`VrU5hX85Dl6a7A!nD_UKYP&}HaX2kwbqtNVszH&r)4ehd7D zMPw4vDY9{+CLVF%tJ;3JE!rT?u1p_&ZdV{c2|SIV(x;U`i~eXJ+Y0h~iCbY=tPdIY zff$I|gP~mJ3tIP7b9g`t7Ukknb@8_}A@u6L^YB`TK^${X&D#Vl@L4bp$;MSa#XUv! zYxx{;{Tp$j)Pml!hME8Oup4U|_AL_3o{8ZV<}b6+(~eudqvye!zVB#;-W6^3OjL}T z0%4IH-QBAM%9nREoe@XG=Qn%k+1a+Llqdt1F;0?vS-Sz5)~{_)oMZQG zn3;GaZID!CDpe(!r^I33ASkVpNSkSwr!b zNiaS9Pwxq6NIL7Y7ezatFz3u@%*2xsnV>S$9_7>`S@M_-PC$f+i&jje* z-NmmDBNUOmcZX-l6a}KcP3~gx zdPVKA`t$H&&|I%UjJ#yTS0=d;vGu3CodWT9`Ze^U#xgItEcv&wDPlm+U57iy-mBI; zU>AE=?r_Rq`f^NW=CRA_*kfATcF>+E9+ru?WwpLijgIrdH%sEu;u1TLQkg9nC*t&v z34melxqF=&-PL0=>$&p{%caoYoEtf&KKh}jM`tXU5p6kaNK4N1=DF^rY`f$!k7QduZ@&y!_&OP$?>oe*VPhoBJq?H|MiTvsVYqXO4+IdveNc~+Vvlt9 zpI#awz*PKFGn)I5HGxU-e^L8HW<|OFYCvOV@YY%^sB@)WN_VHMsLzx1z#n*ygYe2c z#JM={N-8lF_tndK-kikEah)lF3@GCOrOwiaqDASYAd)_Q2fFRgkJ1c3t`8-IY)@A7 zU)c+j0e>uBq1?n` zhO1NGzKn{>l?vDzZ4bV>C@z1W?lVH2SlTj)q(7kCeNX)#tz&R%SHRS2Wz2E z?}jgx2|ln-4MvU?sar+*hu!N^8|lkIuN>`gSUMQHS>zb~GXmf_@pN>rch1vY@tXmg zxho26U&8*{hjLR$EF14FU|s^0Kq}+HtuhaUY&R(aIh$KN6#~lkt`#bo7sNo5Cdwnp zp*ZSex6IH-9L8(+qU(H7x26Sy-^mQRY7&AJ0Tw*a%ovuujTD9BCsU!IP`T1=ZmIp-Sp zvdC%K8Q3|Md!$0N)*+;?Evr4(AeTs%pxvO{=^~X1#sYQjPEQadG?Bv{VckaRH^j1` ze~tyLcuc8(vpbf8D(SSe=cE!!Ad9^5m#e$7!M63cNFFJ~M-%oF5zGsNpKEb9ye>+R zSyt*~N$%pNL7#l9it?86cO4rb?9x_?7scM~eOaT|0V9qfqEHmTjiIZ{vfl-A9k^3L! z3q3wT8HDGJDeffgBRyP{R$WOi7~Ec^Gho+R7Js(%jT7gK`y(Uuq~;-nWr7rXhYV=? zXP9gQsBvsg<_x{HG|qxWPTKf(p;Mxc99Xv$GIJc#8XK8#^&O{w5`#AyEtwWvCO?mv z66=+Mx?P-&-{_xwJt%jzn^g1Q-a~CQ8Wy^%AK=hFp2;HBoh&B^{bmSP)6w93d{tag z0(YS#JV^id94aoDWJW0EAGG}{=Y8=*Ejgvg=rIGStS~q?>dRD~KDrFHzns*ZAHCW9 zjt&ZDqbjy$<0>P<51;|%eL@1x&}`yPy_b&2U+=9B~J%bOZo5Mu+9l+DN)4&`3K2(d=5Sxpb53vt@^_I6 zJWAm1wUdg1sE}Zx_POyVN00J?YwJZUB8#B!FpVq zl(+wNKu?phkVu+lG4WFyxr?Kpu_>u^^%4c34#0{-W6q@)E!9|sz8S@>%4ARRkt>+r zV+Ed4;samkpk(kQ5~{X<)op=L7j#b?myMBq?*5ur@jWYQw(k9d11t|o4Y}Cu#HLF*Lz{Oxc&85?MmmCl&7W{u#H8s{plW(ygOq3DfUy`6_Vz zMDB3^ zgAK9SDb@Q}abqri?9X#AOh@QN*GNKeZB8Toa%8)7m;~6XXb+(@?k-tJsrEUC?m5(i zu1sRz)3Fsy%$>ej#sdKH1haVY{Q&#xm^@6h>hDiaEqO~lFYig==bN(v^1i}_?4*}D zQogRM9hkv(-!>>yOvUC21vr8L^8=0V-j2yC;xCIdcHpcbO$4U%nFGiI>xD=`z6yL~ zaQs>Tn@EBFz@PLn=6vQ4ixZev4mefVwHW*L^DRdr5yv!%m;;+2`C+X=32D*%nTLRU zJ*nGF#PGX3$*VcU%Sc$j(0Su!h**J1{H1Y$@77N z8mhPTC0*oqT$NtSo_DW-U)Wzh71_=Y_ImfcR}EMSgEy{Otd3c5KZA~%xz&~U{m4SB z08ua@46|hyAs?B9V*PXFp8H7~l_1SU?_(U6S-|=cNtN_jkY+>j>(V%ONDlLXC&RBu zwued>5FrIEN(3)*8#(M1T*aEQqYO&5~3rj$Tg}Ke1ZXd z;)?!sdF4HQ)w$*&{Z4E*Of*zYUkPpNAXdlAQHf>!J7gsc3V* z^MgE?f{ZGPJTC*>8gF7*g4ZG)zNe35x$1Em#DPUR|96~P1fS1HVSS>0&?nPWN zgBw96py7Pt%DG&)L4j@S>W08}0P)wqT|$s5C+(Mr?LWsneiMB=QhYMNTMG9TamEZr zVKz~G1OqF;NDOM`KPZ`7Qc4I{AP$2L_5G$LRGikc!VGR=9S_YOHN&jyok?)seNItksn z6s1MpAEBTGDupQD4b_9nyXu>WB*z1`XXDFLDS~f0RXhB;OyMxIyIxO0lhJoOs#K4izCoLxli?23AxB-1cQ1i5 z8}Jn!)GYrxDcs@T47uxWQSFlWfw<=r^kAb%&Sq~1XH95X#2x&wxp79sSD#l|Y`PN! zxPy0i@#8-Ss(eD$W5+)wm`RH(O2ahHccbtrNKw#AV8V@)EBV^xcUM z9w%~!RX5j5m~|{PMMpD@U1$OXK=KO?g~777=i42Wt_5%>{`@w-a%CpyuD$__0H_5` zF>_%FE3AJ9X8tePc+y>-G+MAY0xl0DgIAk9ce1)`ZczT!);}XLfSwnaR1+M(4kSe{ zcU*V+a#f>xO!$qdA%nAg1mF|}A70m}m}3^YQZfJUp@sTDq2GA<)nIOFQ)^v^Ffe_% zoLLG!vqU^<)M%DGui3l=pCXSO{sI;mv(SaQO&o?EJ=f$%Dhy0e5CUanR;985-^`r}|WWTSZ`Z(2HL}UC%ySY!2ar&LjDrDE`9^VUY1^gLng*ghZUlwMz?9 z*;k~dq(%vz5CdU-&M>2a-tt~e$<43WJoLghyI0#vOa*i#bYQCHE%Mm!Ksc`FVSi=3 z<$P1G!9h+Iq7R0jXnHJ%UVEi&$FUdg>Nok&=Q{uynU}1YU^!x86QQ9jbOkQGo?7(S z1j&D_i#f^&s!r%lDzc`(D$IXrcMG6X`F&jK6>wD=ddWjTvuMttP7s5|bL)>9h^z7c z8G@nMjF$^Nt_frgT`;xo;Ol>OB;ytBb(D?RLE}CxoqeJ|5JM~vxBn%VTbsfV+dg2R z>QCa{$apb^#@sB;Hxacd*mXSwI`IdtFcgWS*kc>)kI5wV${Rb*RtCI%13yh?PPqND z7ehnGO4<1-!KPRI?K8gbC)x3{TNdqkix<65tkT*%fq)^o6Yasje2DK)a4+L{HC5bT zFjN$tU|w95Pc2!hP3-{YcgJO}_D%+bpfema&1L$BQz>z=V*$k8PR85ENya~-Z8l@^ zT>@r?EhE5zpBS5HgO`l*ieJXevonmBgg5R}TTA50k8tCohHo8K>Evx~E{H^|_A zC=~5P>thCc0L8_&9K4IaVd^*Nh21@WX4yixLHPX!L}IVfv|q;Qq+{1=5SU<_8T0a- zBC}ZHCQbNy#78xQnqr@)>Tejl#XhgiJ;e)9tq~}Fb=`&iWPLqM)8}b*HdiG!e<4IA z#BghJKt0H!nr|a`EdT9)z;PAmLmR*OVi7AgZ7l!yRhKCXe>h7uaq9?~pyeYituzA( zR%w5{{ct3yFOwz*X$tf%SF7J-p|(4{*QRx=k9m*Y=V6AOZDi!`&c)Y<)*jOTxq~!cg+-`xX+~O}RDW>q*ofAaLR&Q3 zoi2lLD+yxwHGYZOl-{ z7gK}0#3VdhSZ~0{Y=x8O76MuNAz7<2*O!^)@Z31`QiR7XsQr@Q`HC8c($RS>^Wp^I@2iZ0&)A{ zP3_Ntm|_hLc34a^B23BwB+R9W7#U#tQ<1C!wU9+#`~QKGmwe{8IDM#`M?UFG4fT6}Ad!K&f^5XDCbWLi{kcEe8c zaDOhrZtn$1dm{xAh5sOFM#>*1oE!qTfIwgSQR{OY>aW&Cdp0R67{BSQZ2?;W-;T?Z zu5kjMj4v59i6?}|(a}ej+|RFr{CF`9h|5sOZG{it^*;%|J2(rMc;Rq@<6(KV#zRar zFltiq5ix-wn3sT8T-d^J`?!E3bjXs9vF0z3Id%`T#Lq>ooLpoVa$bnIMo2dYzUrUw z;Gmb#itmyZW_xVf8nHaY)sI_2honU1q~r(Cbc6Gpu;xPe4EyZAj(&X9rq)p`!nW+1 zxXD5VR_t?yzz*bs(?>sJXgyQRTQn_HRVP_Q`b)z#3wA8mXL+&$N)H?tUcoinxa5vc zmEPbmN&-|#G$xKfCX@sa&AM zlcbAS*+qw5HPz4#|Mw9Q*0K@7qi*)C>;Ni<6{mVddwWW4b(+}fYsF3*h1Wq>)vPSZ zSH4VB6%V%pY0S@>v*3$z2Q5dpfkHw0gVnIv$|6>uBUHO)$5H9^gek0UJ)|iTZ=S

zNDLLs|% zsQ@<$3W~B?pXKA)IYi;P9JcF;@o;oGJR48XknFi>rueCyy7OOj@Dv7CIV~3$AQ#Rjyn7L`v6^7CTRa4I6F#qb4BVmr9MfFj;Jpy zbpmq?!q!d*+^Ol&p%K9SJ-6O$mNXe?_F1OC>dt=!f&ouJw&>)8OwHrt4cwvBgv@Y~I0$@a{E z8`zJ!Jv?OvVbd~hhuB8;l~bR2xn;*ppZg=iWGJ#JX-b%%0HjfF@!^xv_UIH3rGBT8!d}4#iX?!X>+4j(v;7nx%4Qr@6Y)A@BkL z(kwiDaKgxfl2`|pNo6z|q!N~$Z|gyrwb3&o|2 z$o9iV#j1N)r4W5lNd0?S1jd0lPv*IKgdx)%z#k+4?CWid`UDpvj+QWIPiA_lvMKts z0-oVdq?1%qGsx7sd-D6l94$SCR;KgjipvSh8uRz?6Hegdt?VFV8dNk$?Df)R-yqp{ z?^S9KlDAUe9*#extTzdjp7O7XAXaE)c=RmPcPRr4HSYIyzvHv8G`9a=r?+7u9EL4K?vZI^<~ic>$%v3B_qlG&gzQQ-%)>i0juI zkE0X8!Mi{2yci+SBm-9O}#3N87%p0tM#dF7Z?ys}GnOmSA&ZbME{{l=Gb6g5>b@qArQc0s6#{ ztLzL#;rQ%3o%2G%TscJr^)lxd38LLaCHHVs=?oHFYdvVWpBY8039!3PCVJ>#JxzG7 z>@+SYPm&iUYr7&j|KQ(x#To+}^H1(rUV(#PR|9+aybrMcK8b{WXsfM~-s|bth^Pqf z@oFI`&HCZsQBwUIaLcy`^qMPY75FL-lm)w7J}T?a$b9T65}oz43u)^NWVW zeYqDEHEopiLj%C`$^*gI7RiC0L;W9V>T!EY*Ib%(>S}F;+7CK&sQ*%mB&EFHy_hgv0*Dv?-5C0xtc;4iuiZq6ZHc7GNMP_^xj@cO^yJTgcwV zON$>1h!ZDlcyUIfn|Iwar6bwz8uLmr0OXGy`2EVioc_=(a^=nJE|fmthfQ+fpsKgjVg zRewA|prrk3(vn@t0gA(X4|3*V@>Of2{+o_3$O3CJ(`kHW*66xN4T;#FH59ea<>!1i z^52U_r&GCrv;r!jq)Xdc!nMr|+146=m&f!HRrsBAU<2^A1fHZOaoB+|RUJ7^gT?FJ+X799w+6jNmZ*;ae|53cB;0-+Ab9(u!KkzNcoSwa1hI{?C50)AbTlMQnE_ODL zC5MkAiA0Q`a~KrSLa=h=7;)oX+V1yxDY;yPGO6H%#r8pFQk2oJv6=L_dQVZRauauS zej{qPm(8^8F?400Nc-Vo-yn*ov`_YA!W$yoTPV{iN(cmyxvj&jW&QTP%DswEQcpw0 zAwlB_3QUt`{MfqMuO8k>r=)VYuyL=TlX%31?JRF^3@(BPL>C+)ktG$Y&bVD3XOL5I zYlEFz5oo;yE(is;3(oK8;+Ef?k@_CEp1Jgp6WWFfrZ95I?zVbOmNaOFGu{EJC0OF3 zMl2t+{F1X8P_B4OddDSL3kEOhB8#-SI%tn=TS=nH`43pSt$R1%P1PErd>L{0Mj%m} zgYHMyz558f^`z+c6s#<&L5J&)&DF zgc!qqXH}?B-T#R-#6Wtc7YT<|+NdK9MjMbemjjw8rq8zlFR(P#sJE^A?rRF1-Aww@ zbAK?Fro*EPXW%G**6h3mavmwBu~NiF(a|+`v~ruJpAIOOyp`!3v#iiOUyrqs6F;E0 zk;olYR;Q-Bs>n|OL4xtND1FPZX}|2jpo0gzq{2*yFw+aggn|WZgz$jJ1}ISygkiH4 z38x_2iiJUd&WCEYSjo@;3UxR|oLm~d8$H?Z<=0Na%Lk|HQBmQKp~LCPU^u_7Ex&Ef zm^yYwY>O2#%z9hhI1iG3VUDnAK+nRhryKSK4a=i=+zpQiVix(}0S&7tfpXw>5Z;b2 z>S%lKWaB*q@l}yZ`P9JRKPWtKNqSmbWkQ)^50F9BUoKQAw|w=>M%r3Fb%(Qe8`h_> zITP2M46%!)*Dc^2|k>6&h2n%N8P(3;HBh* za){0~zv=}EK(c15V4G%CF9hY3418AR@A8e0rFltp-biTlmn6$w>_*oP+B1;~%f~7KE>>>oqTeqzGju?p4*Qa` z><4`QoXI0A{n_>M?PRQ?-U+U}*<%VlNXC|NRpL_%&GE(OV>|78D)|d~$fe872C?fS z$~1WkjD1to+gR;oo5Jo6IrFBz(H$m<$KlZ>Bq14Ot~%Wy25dQip0D}V@#0Dw$kQOX zy!|wa%KYH9;-x^I>^Tan3CTGnwb~?m1M&yP3WLYQecF@^!3^~7@gjFoS6vrTZWKV) zohfnptq6*{7Q@sX9d9Zh0S8SnLn>ZgVAB!2&EZ zrBVh&ntdf2rThtk^$vX@6i=yX%9Ar|XnC%{ZnW7*os=Q}^dY!UWlXa!cfI^mNyc#G zhjp};&~KoOAg9C*teWY5ckAw0k%h=;t7Yn1-D{qfN{anJRj|eIl_9w~1L~o)_d_xdITXT*>-=Qi1 zbF@z5W6oN~UDjg4>%*RsK7jJE9Td<7avqU12H1{ZjMiH|m7%D1Sf}h( zw9$tOLkhwDOd=KMxg)AGDSS#QDjIJRH`l|RcSP-t=ixLu($5t5@bL04BW;@p(rCcs z)m~#(@&4~mVm;M}8R8vonC`x{E^J1>K~Je-JtBH@Z0j}qq4#Py<8~FuONLdf`K*1F z4SnuWml|ss^WPXgC6JYq<-`%vahgHQPr*@D&QNfEOa6mi{QyWVSZIAV1I{?3)Cj+> zF&aXt+QmddZf>5NSV!K~3!5?&ZhR4-@sD%@ikY=4CMWHhWtkjdx%-b#p&3+DAwWzX z0g(&4vRlmoj{&v#RYyad-%@Na2|@~wr}_jawCIk6wh_Q$56VcCz1aEAX$ZI>yR7zj zlV*AslnY4#Zb%zK*W@m{qwQx@6HtPuxAf$A-P=HFLy%vMf46u_&H8R&ndBl=TEg(r zs->PXhNAO+ErW!rIwST(lZ#l@`SvBZx<1JS3S91Yd@VLF^m1aW5=wO`qMT1$##TYA zDs7?hq{_NAWaT!b+f`b$6rPk)TYdz#8kuU(0l`jf!kXHM%8y&B?Jts}a%i;FMT7{$ zO4i==CA9{u{;-kp6)U=nHZ;Nl6L;a%N%oHxd=cl#%D1{n0pExBJ3&%2$Of9VmdCM# zWeYE}tBdj>)|-88UN!fV1|>S+Wzpfw`+{w0a{0`WYDaKMj?b9jls14VGzJGmB|5bl6CMqOW*c8`___)KWI{C1w>e( zKj6)>r@PIjL46;LTTS~GZNdWWRg#`JFPrl3P1k?QrX1S{V~{AYmymfL_>k}=2LGti zJOGyJ#Ne$L%Dxi%pGE@gJn-~XGbJplz-CW0R`SU8CGw8jx(ZuFZskYtz}6huVSEcK zcxI3W?DoW;Pn;E$>S&Fm`X-T0OOL+*jT&E0{d4NvDipi<@ZAidQ~7a2I~uCg2d?sX?KP&4r%?&{j^%N$L8D zT*9ofk`JDeKff5mpP+~OKza=Vm##Q=T3VviV1mM*_@Fd@!B(_joWPqMC4TGHA39`~ zD@j&*=y}RJ{*weUoky;cB*5@@R1{ws_OEk-j&WgT$adO*-VK4Ce`Zv9PQ*JFvo<&L zcSOCVU)E8XQGxGDbZnTmJceG0K=GQ4wH#dqS<&SOQhCxjR}Ud(gf5)ma!Te4n{ ztL;Vb1-L(jB#8xv3GwpP%aUmL(=oWK*f%OaCcm)+o8WCHASL>HeZD<2-dI1?d}Kk< zIrgO_PAzjNdda^~Hv-9^8iqH|31wru?FuFjZx=T)Z^$(Hya=d&SmQSg=o^;I<$7fo zVSPA|*qJ$`KK*j3;&dUFWE|()6&2N2`UAxK;9=2BEOApvjwl_~G28fG0+uCRn8Mvi z`C%}fFW&25xbLHyMCsCZe zJ0B20z7DBxbMoTX(5<(kv0GQx#$^RncrLZ6OyZME`cZFGufg$hA8h?imH=~y$Yq9& z!~@kkG7VWku5>&f;obFe2WZT?%wBL3WC$GW*_f!Jwxvb@3Lh0oQ| zG)Nj!l)VieTYPRB7Z=G_ly}kB3p%8@&x8IrF>%5$A~;+@I|6qAt+C$B=F|=$nIu{P z^bmDdc^cG`b1MrLEztvlVjl?1O9BrECVi-L1kZT!=b1}9x|6y)T@FD~(L$&6c=S$d>>im1G2ra8Na#qY$>OQY>Hq#nsc6D7cyjC?gI zo-EKY;rj`SJ zbf%IkB>G`r&U-{fY2ZpWV85Zy#_Hsk7lQRck2&)DDb$jTy$7XAG(U~Y7HEHg-HbdO zNEV3zrw~AZGe}(e{OaG~GSi5B$UV$dCX)1c0Cw1OnWV@s3~lWJ8rCKuI-}OvSM$dk z^)(M2pFjx1`e=++)B>v$Lf0>2OIQiL`Yr(c2?@A?A=P62Cn+E5>QQ4Qa;HfW5C@(m zYSH^7J@!+k+F(ER^?F}sF$0`A_5J1!d+Go=(nz?OesM8>Ob-rHS3Lf_ zeFJg^T1}~BpI4k4j^;M#nN04cw*TXZ1O%yQ$xa4+qesvD_JmVyBix47%*9UwH(ww? zM0i1*d0)j*A??deZw7zsixWmDF=3brxR}}mZvwmecjsIwn>$n%jHwmSXh82geD;ln z$xDzHC6CeFi?rgtHrAsuFP}g%1T*iEUSGc83Rv8FshTN zz=Cv7LOjt<&S|@)_b>z^gwR+>Xz)hXF4x8CND_wYDux5iM3W8x>l%Jyf)bTrOR~A< z5CV(vlaIfJmv84dj;k+T{b(cmNM9!;{4@C&cZ7uc_ljcX#QBb_s4-mW`UFTs|A&*d zGY%LDP^^Yf@<$9IAg#TxB*uFc6hs~r%#hMRUp!$7ME?h4@6EE zgL?iCP468@<^TSV-$q6qX_Ui%1^)Vvsg(hAk-2VxT3CfJcX!R!f&Xx z0aF10*Q2dlr$;9Bs)h78WRS1kO^`ugLH<+|4TpPO22u! z^N{w$LDFyI^pX=V+@k34h;QeSa|H^LK;dMft9NTAh9)uOy_VA~8V_3C|`xpN;Sa845~UFY)H$vzL(W*y9Y> z^PGMTwOdc^V)kbN2O&BcWHqDJ0X;Y2UNpW_Z2HyRUo}N#0-rV$EO-IE^siaovmG6u^>E+F@uvW?Oy-*fvpKhl>nFYMGA*Bf&%j1+ z10DBrxz>UgJ*zfEf_VslfL{J85iYKuzPV#Es@%Gn;M=UF_$tm8{@&A%pQqsB4^g#$ zBLM~d$q5jUC0yH6kZ?qs5)FXV0gQ4)hCchf%O4;DAhN$%0F-3069%$ddsm3?&o6;@ z22n?O20M-O*SEPe_?D|w{LUtIA5V8OA5rWncsIvoMB$pAp%Hs*vJWFInW4Xl(cR>G zYCGL^V16y)GDzR;+>R`Gkf~QJ3ZTskLaxkWhYS;II_Xsj@xShj=07JJR6c9L;t(yWrJ-qWSW#nbV zXE^l9l21vE4Txy8G0M7e=Z}Qb1y<{BKYe0Td5i1P6_DD$IRJOaVMMe@laFu$FKHm} zIwP^7oL;F>HPC=8qXn(nF_b@oiP)mB(f40R0>wXIee+}hbm_6d3A>z>xW48EgDdxp z+-4R5B0Y7stY@=&ugU1|3YF_nKzrTAOYnn@7aA}7;|p~R2DPa0Etm&=UwuUDg6Avu zika!@$?_!%06lHnZ)X%4)<+3DK8J*)jSTk|fhHFqd`BRreotIT_+N6^s`Hy=j}-b?qi~{8jHKLHl8twn*-nI6~Y`U95^*)FM?KKm8G+9gDjmM3{9ZkeR_*Nu?B z$sb8IttNfHJc-&G@G<8$8aanXlJTzGj%g=r)5XX<^##&c=m|Kf6CCDGl?#ruWjwwr zQC?dnVoPF;2BBL++LJqeGwN`=U8q!o2R1vhewN&%wl;s?!vLEMtmg{nr7sxpz$J0}KSG?XFZ}jRIdJ4CDDeD%G#lcv!Z*s^Z zF|j=2(53eZ`KtMa?GYkPfijQC!zDtFUv%j;=}Pc{)N(fkNZ8(6DBQU=90^fJVtX}H zIDdS8re@p{&=FL#RQaGirKON+3=~4<@F2i_FQthpYB%#o&qTakjs!9H9w}{p{j1R{ zq@(3qU*-xGadQiILdX`w1q-c*Qf8W})1#t1NloHelMv|>E&8Xx2SrKv&p2SWC2IBx zynFrVyj6qcTZ%Y?D%pD&Se182!;gM04i;ER-!l^h@g!R^R%UiWuio*rlDfExB!uM{ zhfBm>lz(0%pK6<6KGf0SttxQQdDcNk|5i2Lq7FZPry>oBc!-8G8f43jq&vNk*fZ%R zb23qVLl)%pqew#Vb{HFgg)JmsNQ+Ab%>C1SXx>Mz@{Rbth9>InS0xp%OzUSyuW8w2 zTG$lj6d@Bo)pi02PgQo{@wv7RtD4~8GgR{2d)x%=H>q-i;A)N~ugw#_2&fhu^ z;@OzXz9#hMczbBjN{r#I3Xx(a(vVM!w{|5~#7fst{C5$kl28%iF#awzK#M6;_Bk+U zOC*vSihmi66;NwS=q;8kv3e6!4`^7pc&zA-kEo1K{g=0L+H(2lL~GecHaNobKdbsY zuGzix*>ADSySpIA=?I9G0<^i{TkLptBME$y^qZ1WtH_jL$|hvYc-I#%(5i^t+x zhKor1U3#F(3t^+Y)bExZ{Q2bvrcX5gK|;I|Jv3cshsHXj+2JmWw47*QDHq<8;Udnx?2$KW zf&N10)g1Z&$*+k5)3m!DdD#y`Bo2r5!R3G)%*FGe{LWoE$fcM3dTv&+Jxc)pqp_+eyU5 z`2cZYT0*17-Qq5aAV5?E*bmxKPBYP;*Q>67awit2136ht+~IJ41{`jyB#Vy-1sXwd z3``zqJ4UlAUKuGV?kOme*u$^uSCdN$ThBBJ?8Qv(;(Cm<0$vvASh9WXN}A209I(Me z1yac0%KUW4|8N7}X7no}3_Pf^`(*W@wic5z@BL;dJ|5dx8>r1W`CV(2L;h1kU$k-o zS!7r2QHK8YH(JEv?8w;6H~MEI$O7hLGcz{M2UP!&{tqS%(1|y>ALjBM;gM5L1#L3w zueE)<{u`Kqz~P+>KBZXGn*7Qwlr=80yTW#w6fb&2C&c@*U&o3yBQC=s{lqql8xjh^ z-_!)!|AOF;?Tng$O6cVJe~HG>?{uR>ylLU>kymWd-I_OKCXtw8?Q<}^VhrDNDkcg( z`zJ){l79Se`wh;W`#nrM$ZvDhifaTBduia15QRPXIirOtdVgLhCt;sIFV|*FmVdeK z{^*A;HoRy>5>S2qmXnc|GxuyYA;kpysrO1rcxeL^udcw?OgVH%L2a2_6gh=c3WY>I zBv`1m$rZC~P1mfc7OTJKu3n4&@=}{N>H{l{Ddgl=F>i2mjl3L#h0zeP+E~rrl_(D! zu-HgAxRTX)CvR<(c&P$n!?99U9n?QuFACf+DCQ4TrjD@DKHNyD09YcGXLtjj;#=ff zy2hi0jcRODR{#$`k!-*c3vu&5fU5H3rX}v}C8m~Tzlg5@5vzSZp1Er?+HyUb!hX2! zm4y1VZ=-u){RaCy5YzDCRTG}rNd~PtiO^U4LXG%GK!{+1Kw2zdUF>JF@xk>I4{j@l zA-gQpS|^z@fvF6xEPI<;;vGJWA(Dj^Pl+hRt>skNryY0N3lS4UNJISX z#(tc#-0Y~YetudPth7y^E#havQdP*WKk( zVvH`b-6zG@VOX(b%txI$k3hXjfMJ95!v4iuJ4|Nw^Xw`Jmep}K>HjIh5J>u)*H_zU zeQFoq;$x1par)Q!19N=mM)Hy@Ho8Cbvf+;q^yw9^f{(_l1yA*N>!;2UzT53MbE)qY z``PRmwQz}!4FyGg8@Sz)`%Kjf4`|y$6n@*=|KtCvi1xo3!C}D`(f;oDB8&vx*)BkW z17vmYo~YdW`Dj5Mu1`w&sHaWmw2-)PY`A)~byK5vf6Ze!Lx#5DBTy-iS^=~Kpmelj z8S%J$RZ(Bej;HFCeAW3-yU&D->aXmJXAz>Jgm<;sIW>+Thy|COlvtcw49`KQ!M2t~?o0xfRBxSi^@JeU_|T>{w^P_Pf-J3ec@)C4`nn zS6`w9C&mt*coQ!Z1|f_q$;XFJKorp)?u$@N_Gkqd$aHnAWVy8x%H&;{3=cz&UI*|B zN+XMBPiL@t7-IA)=wH0IbS-ZBD6)0e`FWNhKjo}H_RfhZH;ytEQ(ZEXkTrbC9h z5+x7DG74pqqF4V6dMig*IH*QG00Ll8;#~2(nvG{C;h^p+a-ai(!~X?0>$*s)lqGf8Y3NJyEYajG8CR=O(KEUG~ zsI-+3K9L@PKEDq4g0JL=v48+agp>(w7;rW!=)gz7d?t3HX|=e?FDqGYQk6SgW=wjQ z8YI4eLqU_p76nK5?d#7zA#>s&w4!HI?8np{`zpvpmaWC!IsTV7$g5 zOU(oq6aicV=m!s{13E598dSouSHFOh<> zM6tG^obR^Rjluf@zv8I|4lA*%dL1IaZ*Kf-42=q}Al40lqfjsVuOw)_nfzNp8v|~X z(f4NTYBHnlob^hmxSP!~A&{=UYU*#(iQvi^aXNbDaw1$946wCtT}ySdXmH3W&vT~q zo@)a|$M$y3nCjpVqjne77A}A=Nu*2Lww2<)gF(?8MfsgaPtQ8*TelobD0+A2&nh#BlORGc5Pe-3GJ7oV$zZ8o|uc2;YQ=;HJMowc>Y z>)EzLaDY6`#c<|flbmmh7L#l5IZlnT9LL};6D#&&O!q%b`ZoFo770iMYR2Sw{m@bc> zd>CLEy#wZjZ~ff+kkDM6^g8lQ)BwbYzk#6Vcm4$I1`npHG#}u^$VY^{lu#!+`zlEo z`ilpxne+<1BYB$#Ts6%Ob5q_M= z!h7O{b=pY*I8l0*GjO)Vmmq?)*ByNt06{a*!;W8kzd{Va`XukiH5nihYk_NGcu1WX z2pR7Huh{nB`{ssVC=7DBl|J#qHx~?9Ml3t$4)m&m4s*CMx;hvQ7$Y^rV_;apGhp%o z&I@)kA0tr`zlg{N*fAh4t2fMS*fcLhN9{{Iba_2`p0PsZ0@noDFN8ulII!JJBQMag z=FD-mhen8r!KyN(g=B;LeViH@sjS_B@|0Sq*TC&0KSeOD<^)eOd|u5=2=@=H4=i~o zz+!*Q1zEjSP1-gX%x*;JonB@pasj0#G5~w?J4-*ejkA2WwlhuYM5DU$h!wR@svdUjQ*uh0%8Wd_)!LjI*;;{srH=DENO)(L5rgMqWuX043EoR-&JqdGp(-c7kF?-i=`9NNC^ieetBGVT=FkB1e7 zxPVd|S>?eT01!cZ$WdIB1I~LHg#KI`D7XVpyty#+MW|9q64JDmqkrnj`{@aB^EFdl z*yT3ZqPKBZbW~Il(IzJ++E=5uJsQjLoArt33&LAzYP_1m%LlA-^+A9fm(yVU+p*#K z1@mG+>OuECX*3b2w#Rjc-uIcCL&@y)%`!hAp@4jQ?_*BxdUy4XN9|0 zj!3@Rf6z~+26^)*$A6?7i1iguX%&a*fZ0Q$`~ZgvP2LS}?jJ^;g~4+hi-Q(#w9e;M z$U>wlT$pqXq@Q~d2!tzB#K4cC*;2H!`|F{>s#AXy7I!1d3hI4<4Rw)U&Kj>yct2Uh z;360h`sEqg!>RGAO6a0K^obQI_P6Vqsw!U$&FR%mHmjC~*K$o4<;p%<=ld5Iv?<10 zPrdcnFqU(&CWhke`DBCW3*X%h-RsmzFeMU4z$*l3PbV&`5g{&a#0yvM=$N_-ee#}w zGtz@QPts7Y>*6HpZHdBsdL2GxZglIni+*Wp5lCI|4|oA<9mW!g(ZcN9ArDDMAnmDM zc!4{EA&KqTi)kj(kcJkJHT_GfY7fSM25fm;p`D)comrVlRpfLn9ZXr^1UKjndB;!76A zWQ2W=*IeyX!v;v#qq->{r%2?Z`_yE1?)B4L~CY? z{_j4=OGJQsq+S+AcuOL1amVEAbAf3|jT#cCkc38XH)Li(jMr~@t*0x&qmmYCgz=#D zSXdG=xeO(KVzxCYWF}yqLuCujkO{c>sz^z(nEcmN9o5YqGO-7EmGC#;KM)ZpJ!eAL%viy}}yZ@?pdPwx$BJPt| zIY6HzI$PW4687WpXUmVle&I$Ny#?W_R?vRL|DbnsG_#7H&l5W<_+#lB->P;M_la{vzF#;c!UnKPqUr zV<8D3!KMcP!5vO;J!~NfS}C-ds}JGErRPM@r|U(`fdGU|dNF8PB*_%=BNCW}R~i-! zr>XYH!#%Zcdx>ELMl*GGmHg)D*z?S>UN&$)Taf4}e`*o-&M##MjjW6I+19xE%?Q zDxcCqKbdX$<^bb?`B;hVDsi(L@&ezw*GFwaVa9Ph53ZPPltay%3*2|Kk_H}F^5`Pl zHqi#0QXqCl&_HA%KUz@l(9A<`+K?r8vQpYwxEBg8V$u z4f=#6py2nw1Cng6K0Tp>9w*{Jk=y4_E5cOLH=>q9v8{*fBxPi)?n}Vp&{KkDe?$q< z3b35~wfZ8kkN&ACNpq$hy3*r#PJlidL363W5)8<_QH-B!kxzyD+%dfkAXtRopau-z zL|1FrJ#Fgco{_8@^bfWMc7ZkP?+A9zamYhTD13SrTO5`QkBe-rr6T&Z|DFxGXTgzO z`l_hwAJhM`-y5mJ)q=9M(^YSxFqDE&wWF$#>jmvpN89-FQMWzz610iIy4(*177MO9 zB6-|kNIB{GE_|-SqU~MJE`b=tpbP*fMrGy`c`k%cQr}I!E7s}loFpEICL@5(7TPp1 zdYwro>+cyJg<;jNti42A_X9tg8+<#+Ur1ou4boD=072HBnjo!*0ouK!uwid|zg)jv z0CxxUku#bSHBbF2(f>Qq^A^?qZ&D`ALlBJSOZw!Ln`b{$9#jFt7ZM1>0DYb}c6w4j zy3I7gPvGkMOWhzLB6(Z&J7S!?BlZg9t8A!sIy#FT{Q4T~SU%E_A9xqIS6#4IJ&IXR z`~%5F1|nQwzGYhPKc%N+UtZUu$-Sa+ue^}W>?zbdMa3p`Xx9o{)yqSB ztfjpq)WRri_ZXqgENo$ssq~Cgl9r&2&C_)-jwyvQvjDZ6Eo>htz8QHLiq{S&bdyij z`7Z+caFA|`R>gOqdJ2!)=iKUD&bXQL^(Kh_idmg8h1)4F)L!OVf+^Pr1j(FtqBZhvjiuTbTk2bHJ5Ujwl2-h|N_9ei9co zkh%CBe1{kkUhm-+=#n2UqZE?gtO>5$qP*Xr654onJx=S9Pyl>OZdyvtJeqwo3(}QE zYl`caSgfS;!VRFQ+dpI7S&{UXYw1_iBaeea&`Ew%Uj0KSQo>X*XA0E?=m~uA){d2! zQX_GQnO)y^FOfYhx+IEyqM4hdA?CR*6D@njk@?Y@WwoT2LOMG%ficD-hm@0PMv|+<|Yodgg~B;awF8GVmM*gUn=rD8P^{2BX{i zKyIy>aXc`Z72xzpik@{Xc!^M4Kn~cXe=C&VK8D_l@>C)8^MURh5c_Elzk?;oz{8g- zc$%DyykYtu{3Ar{6qtJa;qhp$+>iPyL;3f&s@L+@0NQt96_g*D&JT^yTuXAknk{U( zna$fuy<`Li5zdnf-e6w8YOMAnk)kpZdD-PchWrUABt9rqFKKFp_b>$?ZYZ+PE?x?e zv1xYzIhdQ%?UNfuZ0?sfySFw}jSC+s4+|yH!68MYZk5FX2u>oS2m{c^{gL~a#7wUG zp9-ekDlRdW%^=@(O~6iAa%8|W$OC)mplR$4O3$^u$?Yqm^sG-I67k!7`*#7`E7_|JO+mm2?zLmZ+Q2H2tsNm9sElpw^oDm82Iq1wF zeOn_usJWJu=obgZks}1SAxg^|GN_&^04SSYyHR-4CEy@zoq{&DE~z(#U3x<5wrLCx zH&5dbgkT{EdEJpQXJr>*a6GxF`mJ$-FZr+*{NCM%PhdY462Al3i;I;rmCtu-0@4bx zHfLYHZye_W6&?BTNGxJA1As&rY~1yFN$JcWq5z2*dhq`hYn#o}EzS(KjfD`Kg(N~N z(9iY6%vSXwuI^Wus&-^2TE~(-I(LIF#vCvXnRpzR&ITvc+2Akb?g7Is@D%_*!3Za6 z7C4||T7bu7&+++3ra51QPgzlM7xP)k(+s4LYuB>+RQjTH&q*Nfc98oTbmgCpJJ64^ z)e?heh|b-Fdx6DoK~vhYGBTyZhjR7D~{5bCnzzSKQ`-7rmQpxmC>UyD)kMEa42C>V*Pw zFpFE?E1~y)ks|JDdJ;vvHuJrLZzu;erYs1Uj<_#(o;>ua6c@E*XlbCtSBO@z$t3x1 znQ5S=1;G*7_Xf29iVv|(u%mI?luOVOhBfKc^(?U21b#5Z$@c$H0>N}fFOAhT9DQ1k zS+DT!b)x1>SiU$luww&iNe=p)bDiGRJ?GkssD>}*s8L`4PBg%}K(<-=>1@^%&VU|q zZImMosePDWYWR}>8zJ;_B}Cmz06~nJ?_(>_CE_Kk3e73?cL3mLOl z5D>;bRe~7Ki3K(x28f2g+S}U!0h*f0$i>0Jk#1mr2gUbdCISNb!`8uxP6Qj4NPD8) z00DK-T}z#+a-pY>{zYc;2(29+m5{+9kUAXLcgb);2*L!QQE+iFd0Bl; zO06F=lv%;<`~e4XI%)j*>Y9LzOklv@b-V_tr);;ERsVLYz}ecEd4t_HyEB*M-3BLQ zl(x=CkcG$;s5;=tz@oSgXa8}$4{o4ugi7E3f$9G;FMLz5*LX!qjpV+N$Cp(Xlo_=v@B&7u_CUK)S^gh1lFI5x z{yekc_IKGkQ&v%7lB%b)lDHpano>@Yhz*MX z{DZy|qcSrnz1ha&9>z}x){78E_!ttM9vIV>|_SYaLX`{5+wlspVI6@_y?qTKB# zwGq%Z4PU-sp8BV05=KD2q$tKF$^B`@UC;FA`pAvWzZMIGv0x#$JtU_(dM}^dFoDnR z&hP-Ok1}AhSUucvv*x%6#lQ+7>TCNV$Q5?$-%`$+t55|IJz49NMf>IQ3U`@_Nib4_ zDF?MCU{W$fmCF0^f)s{HD}iSjQ};T2a6(US=P0o8bHjR0>D0{G zfZVk);j{kW!++Z-(V1Dj#Q9kW2Z5SZ6Ya)3noZ>=mx+Gy0Y>@j!`WyCLlWL;6flh{ z-rup}nyhiz`$NMOicsfzMCi^15&kL>z3r@PXArl@*EsCo3j100Ip7Mfw#HJ;^3>G= z$bE`uPJh*x9tfFNe{3qHJFwvRGA=uq^xLd6h!fx9$i%J;%Ts5YL{+A40>Z)`1rcaL z1Wx*1VkiM3b28u~I2XAc9VU@~r|?F!9)4M>^d1J<3jh&q3ZROpCM51ko9{34QtMYS zZ9P$YcvivjX!`H3V{n$%dj6j4$UKtvLM?>hCdT%yFj=Lb;mreWxmIqFCs4P|cc`-g zUoGkQ1vFT#+H+4Fa-EnzNL|6xW0Sn^=&OJC1^7}eNFrFP?ny%=LF7Q{IppOtmO6KV05mt4KHx9>Hwi)pO)a3Wt9m_y>Q+Q z)}*L+@{NHd#=R($QPk42n^RGM9EFL~E3fMCVpEb&7%SNbbm}Q`5AbVicv`Y*^?lZ2 zPn{s}UX&HtmE_Qi|34jobI-lIgV!$OSrMX1@j59tqYKv8lmFk4|9*4xxl0Y)b%p5i zfFFUqigqbuqb~S~{8Rb&ZS)s`4FRO>qr<0}ZZcd;+nzmR=UlLB4{$CrYGDtI12$i1 z3GTa^pDt|fC2pEDy{qz=Pa`$tL))Ug${$hMxh$+Se?0?ju!hQ%nk_l;H?Cqo^fD&z zto~_wL{ZxGm<&vLVG&G9-mr+b#j&A##|Lr}P~}Yk=_r6aK?$Y%bGYd=u4ics)a(yv zv_vdNmV(}owwO(97MC~)7XQ>kZjF*_4K=rFG+d^2TYv6)vc?ZO7Xq{m@QEm92V1Idldo?{BuoLJ zS|*5Y9<{!CXX{#|iE0nO4(zmESD%#d0#4H6!A!%y<1yyrN}RT&^ZC$haaEqrYHld) zEOW7QrL_Rzb;>G|U+rr8jSJ7Aw@(BcYTV7vx=9{Aov!r)6+Mmm%M&7M!>_1kc)9{( zlTY3E?olPv?ys%B7?&Z?6N~eJwQz(7rQ>u(@D7BHFwj`(D?#(Yf0qYLFumPF7s3OR zFGYfTF@Lgg$g2Awjm+F&>GGlCe_X^0i}qlbv85?eD}pWZswoF>U$k$cbvNGwPK~rb z8(ilnue$+9V8Y5X1^1YYZp(A!B2!+kwK?7X>WY1(cP{rMA+1i$uKaKELJK+JPiTmK z<%dp=8+;Z2<#RP8vaKB)gmq5+r>3WgF>QBr)Yxgl7oIY5(2qDNbafNgfdq9Fuuh?cY$GdmYLt%OdMD<~fxE_~> zAd9|+6{xONaW_>@PB}&;p|nFML8HD~*Wr~e&Rz4eMqf@^_5y02xSKTjb-do+nCT)^ zs>z}g*u6_-rKX$?>dsML?$@|f43zUgBaAT7;StR`6YVNur9&fd>lxlG(64fYcidnA zyP?}2y1=l}^LzT#?x4G4t0o|av2nfbh&1xP<17w507Be>twt9`Et<~(-; zW$hcc{fcG+7Vp^Z(hdYx%0WW@B~T+ZSnIeOeDDhAi2+_3d<7y;-qots0WdZU8%Eo5 zex*)z8@$xsW9fOWX8b(=jS&NvjA_NY(=(1o+2hswKR5wrO0Fk&{gH@jz6-D!ef;7~ z1vE%-0HEGn>j!VR(8Y}s9@ib$q1BsD6?9_{Kz8~0XqcB$5$2TK=|50rC>#U&A}X2X zFgQq`SVg^c1J1frR_*d$`93oCk^kg43dEg3b1i!ZWmZ1(vQ=|u-IV&hQoGZVhOs>I zf#?tJeq@HWQ17=WlWr7WK@U~Xt^fT9ALt#_+Ae+R3jPHGNNKgR#_JNI5FN5Cpt9-p zXD$kH(K_Jo^u5igDz{N^&y1cM-g-}Oy72D#P@2n=(Yfu37a*9L$U?TVia=W5;-dK; z!VHyRQMKXVm^N_p%5T+te@5;k(AlcS01P|=1DDz0xSj;DQo#Vjv9gtaZRgvkvA3<( z7xd+3j6cyVj~R|$cni(7MqwR)M??74t4WAt1}(yy!S0=lAOMHe>NSeHZ&K+}c>$aO z84#lkD7OPik;UgvTBAz^wVK7YXr%d&A%chNO&rD))8RQK|0qRZdBLZD;OJZ-;GBd1 z-qR`andOXt;-UurW!8m^d15Np1+TOPF@4Qk)C2g9n|itIyu+28>;CL}-IWf(8(lRE zV~M9GHI6+-9~^s9Z+y)SRZB`|xdsV+AZqBA>C^NzobsMla3Q;f2t#06d=7)Y_6raE zK4Eaa~# z@6w=anmF#YEjdDwM3lbFF{ifJV&VL%s;{@2-{bVBy}9t^mlr1Mw|hqeL{*6C6!q6Ai|>_$y5u;tUqWq#q7hfq1J&s+cLbbW-fR@>^)jL_t%9#Selb8S>4Tvwj8$ z^@@9i-rxxNj-WrYzhncXxA{h;i=70(FImfCRhhQr)EK+9ZjBhYi^9xBC=Eh~8y!2# zG+Ekq50lMFi0~>lw9P<9tm#&Q8*DEn_N5A`?*yIy(6gKIJZ_5=T;>88tt$t#91Yu( z6@OD0E{70*Ot7O#>(mDmfAM9Wj0u;VNYP8|W0eC&37b|5bEuII#1Jg}Yh2cJ@Z290 z97>x6r%dvZf`><}2o7P$h(ijQ9$ty0hxSCgHouwF+uc3*6CsBRUkw((V7b-m>#=a42A}Y=^)vaFv^hIjt;FEi){Bc!I!CR{J|f#E4_$_ zTA3i>*Rj4@{ATXX)wiG%Qx5`(EY5{(18J{jY3h=3Ti201GuWR=-eOk0%)7PamXr5T zuHkr&sP3rny41)nD`{0!f*KQxH?Rl?+GXaY6X`WZ@Qsc#%&|mk95BiqlUp+%>})=j z$48mGA|gd4A1S1%76$-JruXfpx*1oYTU`RZuZYDjmbAuS8-c6Tx-%xyQjYnV>-Xv> zHB31X-C?0vhCy#~9S#})!cqfLNLmImi$}{CLHUu8jSKfxdOb>L&A5UHZ$u@>kryvW z9u>t`?@K~QUp!fxCCe6PGXCnEWWX+_Gg#scQRc-Aj1FZW&S`b~<1z+JZkgA8c(|j> z&qSFGNGA*7U5}1nCkZJqmQc7Dsgqi&pkB!TerLZXm`HKTmQUiF@_0Sk>D?E(uK#HH z^8EkH4Rgwi7fyv4&`V&*B0fgT{*yP*dGj!&x|G)V z++D_X$e}*<)e0jo-yMy^WJD$M##rDY+~s_E|HRqRK&4;fx=V1jmuxO(p0D+)E;LdK z&v~1=d@Yr>#AKXfG%o2YTCs1o$EaD<(gy2%V#|iXa7Jf%Qi`vIn zvXuQlxX`$S6!IJB$;ZDDuEH1EWSnT_x1R^o*;3f~Cs>e>S?A>_Zdf(0k;mxY&vs?v z9J)m-^|J8d_F^)>2ezATFeVx^Y+-zB)3WK4@u# z9z4!-d%F&~-1P?!P#w#A*O_hS?2HvX_c{xS2Idg2(%Hb$sGxf=c=_r9ZAiVH=DQY6 zx1ORGHC}I)TB!a6#02&9I(Yryj% z3A>a2^)rygLa+x3!oP+U0dp!oBDyej@e#|uo0+JM(G?caUyl$SnqSxoix9H>9aFbS z!Mz)Bwm3ZVe0Cfr!g+DO4DJ|&+i$(@He~20sG?QbV&*tu?sE3UT!4qcOi~a5wpmA0 zyQb$Fu({w9tETgrk9pBDT_Z%haz3gUGv}iE&ZTvOUDmTm@^)6Hbbw=jOY#h`WB?b5 zbl@Ma)R$fx8fqg`51#!kzG7Yl{aUJMqqbuMi!=x2aG!|yy)40hfOp5-7?iD9XOFFx z`H((Q-QD9dd~kjXt-s!BL&{wu@@I1u1^XN`2a~H{twopU#nk_RElZP9zxZQ=`AHsP z-hpb@Q~w#rbswar2x{RPHoIL~U1LIArO=gKqndIKTp(Rr+p~9O;&TR|F!H#vVJ>fQ z@@v&wa@y>GjSl<%&pv+!cBtOYV_{`)a$Ba=2WPoyaf_W1M`tP!K53Rg?BawH+KVQFLkV*ZT>1OILP+f zNg3|yx1w}WTex|B=DWTv8gvmW#fs7+d8()&G>NL$#cd*Cn?DyU{RCRl8B8$8%y-Mo z-Wgx4*d;_%xPfEi{^%S9k)ow;wJzZZreYNneX?VA))^fu!X^J@`PbKFEBT=9?Fp*1 zBFzz_m}j>&v_FlLW-PiSH`EQ*z#ug3(5L^+Bka+bv^TW*32vGZZQ3nMKTEgq&E)p& zEJ|-{-=o0*qdU*G)Zwig=l^c*FEP(Qr~f=zyiSPNNu$mFaWaVoSLaV~WXvX~6*+Hm z)TYeMPD`R`itgU(k9W#_$}biK*`$int8G+}|L+hoijjknu|U3k4u7fl6I8;ZEAeUf zhAYfAn}pb%f*r>GWUi}9mTg!|4owZ4iXpc=9J9$)de7`?W}5QuZRO0fSOqTbQk7@; z&!!BQbI1iR&6!Xz-z&5DGsQs(dx>{0yNzAYkNdZLQcD!F)J{-k4~Sd*-(fv1Yj^iD zU9*KCIthE@kKRJ~JJYMzdWS4Dl7u)`Cn}yh9OPdrPTLh`UvUz=*I``9=GDIS0nZjH zT7`)IV9%W^L@UzhwX}N5f50w%G_?LuJA;Fx6b)KSmQ~%_(Z<{$)u@u{I=%mgC`7j7 zs&CB2S5-V=M&q=@K|V%>U23;@hei#{QWgQCCt~|!eb^iLXc%|-{;M1Kf8pw zZppj(hneqO{B_Y@aARMKj3&hA|T!qjHG(Hf%XSG@ZPe{5P8GTOyF$>sbGf9jtkDl}~^Opj@E$@>?Y^)w}SYnXqf zLTc^me7w_G=Ml5;9Kx^=9C$ecI)J-|jSH;$QU&Ezo2OSFi26L_(XTdRD{>YV;vsRP z-LiN(ld9tDewB6AJ<;C!%2n@CA!B}mCPx0VJ)v7uB^=Ask226|0~h)8lOvw~4TYUQ zgH+4H3Cne=NpI|oT|`7#)GQ)7n;>0lg30?gsJ}t%0OM{Rnd=s1N+0piAi;>vN7KH3 zZ;E>z+a$MU?CWos_2 ziauM1IUlndJgRQQUF!Nd`oQc<;IFdkwu8r(K4bN>UK{1llW=Sm2pQX#yxB)|2ASP; z8uMQc;?vGIux$a>vO#M<-_xhSvi(?U>+Iy)qe87RnOkHp0r4Yc0F)mF2Gf%_`9M+# zIJLg98*pz&r;=+`y;@x2pxysiYCiqNerjM-i%P2G>ZjYEX?V9ZwHkWKJPI04~N~%8(q3Oq!MLhmp9acx; zV-;p*J)yAGRUx;ln=_TqJi3mPN*_f=KKl_<{w<981T|%T+@W-e5ZhYVdz*I9^wdnN z*g31%c3A=vFNx-*DSfYGk zWhEMg!AZ^uaDG)3ny`@Rw;WeuMrAB)_!pnTYxem=z~7>l-|LazZ~eBedRLp_2N$an zG8UV+lP$O5tea*vtq`5ZlJJ+s6(~2knU?vDL7+HH|A18x8g5<}tMCu5$Gj-;qJfGRCCOCb z>=Ue69V0zfn-sb_tcVoMS3^mAwQ4%&r>PFR;O=Qh0_ka!_i9r*i<_yO^v{{;;RiQA zqk8{XU@;MhO?M|_-`gO;9RbPa#b|JDM-nTB2|laS%L~`i`d^NuzM)lppSV@q#>q$} z|K-6Ph}8Nm%krJyzsYsvvGgtFs`LFD>h?&resW&jIXC5*E{_-=AKwgaALG~dA0({@&fHm&QA&{$uMUr$kv zWjgcE2LHjx#h~9Q?^f`SRs9F-gjHf>f}P+Uq+NyHZ@~dyRLXuyWf=zahbk}#SqySP z@$GueQbyTfMFJ{{2=5<-z(&{vz7Lz$x%UnPnKRGSIu6FD$mRLv-v7eJRQR9v zc+P8`WHCWukH)QmI@ogOv)ixl*qn$!;_^I(_JcKI|1VF;Yp+`5%@V+0gTyb{FS$sR zqx~7`az58k3zC5?vNC-umYMd+=Of-Kd?yMXnqYaW86;Q{UDkJS%WJ4VckW$8c4eOu z3dwefFf>+ag((^j*iXc}&a9niK>aPBicI#Y8~a3)^I%y#)p0`)?7a8BR&*3LqFa{t z=;LJxZ}@V*arQ)TF1xJZ$Q=lZ)^SfD{vjdE0FZ5^0aIY_p9z zy%;{(7qh7p)SB^)X+8F<-&Ew*Q}6WDb^igVWe|JE`*+)2ocgFp2DoKn~ zcfrRcVB>%mQmp9zFbeqAUz9)q=+!zZzG0#8bIj1FT5p4A>($!ST+F}h9hZF& z)mw#AUQYy75=O(2n~MU`6<9ZytG~3v3aeftdK~y|eqPPt2Bk`Eq?TQ6zZmqWr+-?lMFP&9@Vd9RxS4(0Uqqr+r@yA``0VH| z;~axJ!lVmd@D)4UsoOdPNB!b!Dgo#+)Y}{rj8F@>u9UETfh1^Q8YW@S{yvXFQm`=~ zMZK$2-OQ2VBR{mA{#-_h*NFpTl>JswG#cG;82~KQdH&Bv2Ni2oh(2CHb&DvzSBA3~&2!43a>~W0gd+#}%*^&gns%0SP@Z0l(nZQWz)K*!iEfZp|5SOA zmVLY}NLh$u?c;FLCA4eKSG%_TIs5-ex(bIVyQjM}NV#;QOG-#ADJ=^q4T^Nb(o#|a zf^_?$(kVztN_T_Q(%l^*At4>#<@fyo`|K0<-kCXb&KZ`DG-Un}5otuqs&IywroadJ zTObxBr(pVHtAucxyDyb&+^Xe}im0Bu&|d&rz;T6vt-Noq#E&{chpMa4%svya@m(%GSWdO5aZtt4Q9BEqv64g-Ub3ac7R^U9q!AkZ@C=5znB z=e)4@`x~!9)eJdUj5O{TA<1~8Wr@KtLhsO0DDMCHE7MTKR~u_}W#!HZz2^5CL&;rD zNRc?xfLQ2=aJq!1QXuaoDA!*>p|HvS+^SeW`~!e9c+%NbMbXjl2bol&GJ&QrEtXvF zLLBdgJ}+Eg-2lc-EaE{yEo{Ax6$_lLXkWo%I-db-LIS+vg0HKCig@1sU^#`WbB_%w zmb(o+gi;^*`GNXZ}KU5qL`;|ioNhX9-yHzFhg=ZYd-uF0iH-fyM zk+53j-iPp-kfdn#d=Tw;=cm$f+=v+6Gc!r8+P_@IgqpOAa6&R?cu6Dw{N`Bu=pCBgh!LKO-0IS>f>ZLE7Uo*>bI_8#f0>Z*<)%{RQg(}};65>(SfTv^(% z!9<}qsHQX)wkX!nF&R*PF+qR-4r4>U;`0fRH$%McZ_g#iPzn({&YZr*M_AZ)Rqg)p z?Jl(0PkRJvS=NruE*fb^t6s6Z2(JD6x*i)2{pS{^f>CBd%6s3}0kf&nXel1XW_=}p z2#x(L+O7R-)QULuWN_eY1p+}yZkmz)Jaz9(ysjs@FVci=Pv6B0eD8db=`Y`ovWY)C zd+lDr_$`YCHfZullg0D{C?_0KYZE((2>pSTCKYvA;%1YfC5+!-`+rF;>^TCYJDR&F zDts{eRyncIMyH|D@!#h~ad!E;zi-s`q@2A3q8pc+fi+)fQk2edB^U;PlS+i{|K~|p zb6$2)hF>5Mdn70^1F(eUAl91l$oUbY{kLji>YbK)_ZieY z-Itz!?g_e$%Sb%JfbeqVhPf}^LOjecL4tq&`P-03Ahyha8Z0vPKT{w{N``)co`FiD zhZJi5z#imaC2TSC(jHj8pi=H~0eoqbWKBTz`PlQd33 zhQ9_SbrGJt{#?uM=3lrl&RdxV%)6?XPj411<;fpeQy~#DZddhCwyc812}g(t(w5@& zai+jb6V>MP;c!)_A$sw+jU6m{2pB|IR(reeLMJLm>Hiyiw~*K$U9o?7gkqP21F%hP zb2Lwut62p2e(QUn`R{aQN@+8}*jCecT?Gk&&j3>ajhEM2XO3@anrT}W7NquHv0S9@wS9;terjF7_@-OgA^)&q5XA`80g79-3s+ z^rai63=%EibAY;j`fTSn=!{4V8(yray#)c%LG_#Gzi=bZf8%i@l?@d^L=f<{6Z5Un zdBLkuEy2UQhdvzFv~d9w&r5KGk7w=`twQOYQN;j8FrfK&cT_qz~)Oiakm!A2%m!C&4YrX$t^u+tKnmkYWi93cw+?1L@k}^|AH0e%kl2`ZIgwKkJ6+p!Y zYovwYaLp7Qmw&1~P@tpXJq2acDV=!LR%`E6jFGsjv+{r$kHbcOUiLa&sDVcjEo)XL zh3U1_94acDh`!&1hMp&47$IY{cka=luQJQTV@3q%) zRYD-g;N^xN0~$NyU27BPvpJFqF^?5^cBU<|Yxih^;FgJvN8)s~jO~nJ?rJ9~JCDbh zS|$8RxPcYRsZme<^aJr{43`a@9>w4m>qtz0Tu4FQ!i0y$M+IDBNd0Yusuad^; z2w7WpH#`HfuG77(PrFj@PEUf%xbO#^cMYu+VC@zb2;CA8yI<~h+fLxr@cjPG4yDH5 zyt7KtSYOZ)^nQPLXu$2F*^dFd9l&=FlM8vz>9AqFdcX^y)G;$Neh!uqY3=Y@>%4+v zUvtEt&{RRWB~`)V7My+VM7Dn{l#>oLdLxJbwV!oqgyDhMoU_i!$+i6UbR;J?IJFZ^9$EXum}|gg3fz>^m`jiq#?|D?$G>mEjyKW z@9!Z8w~MHR7_HS!hxeH4#*k&K6^3F@M|0~FrKV@}GnrfcmM#QKUU*Fduh;u#92BgZ z3a`LVCl*e;D9^wa8aN1s!qn^X{>gi4$e|9Lkdppc0L83+&W z)a?nmnhOt$qPptK4TUWK0wu@oe)VyJ9jPcjJ0|A8P85u%N^kpsW2wnBXuEn)9S(*N zzsiQyWrU6I9_hT_J=p+D<90wI6gYDoodoj%-x>}5Cr`~V;C-$+;m+65rFC+4(E`K` zLQl7C)rK)VRjJB`!z=Ee0qV{7{G~Vulw9_vBA<5{N^ZS;O@z&cNFSt zSZ^fRmk#rZT>x<6EQ#E8E}EREx+Zkn#-7o~d9Fx@##+`Py)uP`k4B4CIa6Xi zd~7PKZ8Z)+*@Qr_D~rxW>`@}FfkE@rPnJwKF9|QCAj6eW;V-V$jrFw^Y?_Jh$-=b^ zOibB>r<#7+%5p4^>?aGZIwF(VL^Pqmjsylj>V ztB4_EKB_`Lwn>69}!L;S(r4Vs|zRjzJA+Lc)9|#Dodh%7y~7u%?S%!AS7OHRrc z`I*q2C5Ks4(2R@Im>A?3a4ol03W9e*;^f`!WW1lS{~;2`1eU6tWz?)hG2`syM`Z+w zK@CZ#P~!RbpE>0zNKHZhFX_F!UZ^mb(W1$c?Xub+rnDHIZ1YoK%&aZaD_-nf_}`7P zci#c%H2MJs<4?b;w&d;#Q;rS-U7eF8d~;vJ4e>|44<16W3E{5oHVl0^+W?46`^ll=zL0D^C5M20Ms&Fi-($MR zJQ?p#mwz;srhZsk?<$PDx~k`hc^MsG%ROLIo;YM+u}PLuV9TxF(&$&)vOsVF>Y4bUTl=5uK_Tup&AjBSWAg6J!S^e+CL~c zaf|yMGv7}Gq75xSZ2u3(ncJ_@FgW*)^1zu4+JEGR#D!HpbF(WS7pukDp@!UO@4UEt zLCA2F@;d>2SYxsGE2BCE1+lI#cg6bJQSvnJvaF`k8s5-^f3fBM^M}h(M^Z9Q(7T)tJvR#Jx9qec77-&Bt01rHZ&5xg>AENW8$1Y&>`cG`Lq$x~q9n z?ESPwyMR%@a0!)8^UoCZJ1e5ZSPznM2JaOeZu};r0-M(U|D7f}i8}9ReI2#s_%@tL zLBz-Xg2ki|i9M&%fnZW8f=JVcrKUFNfc~7-Sj5LQD|x@Wxl-|}vvd5?bV=t^mvp-) zF`uX7RxMyxf%(>lViyy~u3i>MxaNdPA$G{s>``Vw|A{>usA9(ct~alhdC0#Zb4)u} zLkF%Y%4Qb$mz=Q)0>r{I#CdU#A+;aP*qEV&XEom6#7(Y=-99Fb&9A;VGV#07zFlAb zV>M(zXSJ%i`izqWs>!64Vt=5|7AQr!qDRs9veIqhAvEdnoz*G1<3*eBV3W_fk2edE zOj$2FFr<&A(e0ribXOm#{$aHL{=T9l8u~dkhp!y2%6{Deh6tQsz+*AN-J2-*;lA zr#|fEsCW?ojcqm5)H_b@3?9a3UKVcwS5$(gezeRPK2ouzIbE7`0?2X*_&A9_*JbW+ zdJkGQzEb-@k1EAk{S{MI{l2%(_itM=O$mE;A>p`Jm7C8srha!Ojerj7f>HQUCT=+- z^9MB?U&*n7asL3fptfwD07S4~&uuqTxoB*K`Jca~ZjB;SiM(p)OL;@6ekjwbyD z0( zK$dgK@N}{CosC#lqVi1)!r1Q^Ka1JMwdBp4^R?TIvR`^qlT9`BpRZ^ zg2T7@)pZ~vK6&EOQI(*{v)CsM;I(76=#@S*XJ(TJ$c6&3J65_W4H=;{#yf4 z-s!RUQ2)u-6;FefgDNtI7{s3h=m9#-wdZL2tzr%t7E9a0#^$nRy^TDg(nrQ)9m~xh z@|N%w16TMBDAy4d@^L(Hq z@X9YX0FBz0ueYvDAT$q1Exoo63U&>I`Iov!Q&FrOOA;XYh}5=?r37ZKnHM0Zw(_>z z$Vy)=b@~FnVG*p*{-S-cIuRj0$mgG81+wM)E}QXm+C5m2shcaLq4gVd)gnw<)qxmK zFQ78PqN|DiR{x+Y^=qI=3*GmhA0N(JPjN_2Dvn zoJA2z1tKuT*cz)HwJN4mX;I6`KHEQ!J|E&pF@{jwE0A00L^0QPpwAP)9~3xjoC9bT z4=>rZ)qeHp1muLOX|yV4R!ALu9RJN<%Bw+gZ=UWzP2ug>11TUUMDn?o%~<^V-0ZUI zO1O=M?F2{E#s}vx8K%4;$WQ7%x!bLPmAtpT3m3pw#iYH552%0WtuO4bNOUdnwY@ub zVr#~dv#7ImcHI5?f@+P*pZ0z%nNkOcA!+7X=C5ti9l(q!Q4i3Hr70<-m5}dCfn4l-joXM1qtcir-0VH*-YcjY zslxK)|Ci;np>}<|?Lqe@Wu?Hw4t$3PtV|J1x)t9uW(LkiAmd_y3t>w`LHN#IAC6!j z;l(K#Je9f`J>*>baW=I5zyF>P(AXAn| zBhRAbxBBq;1tU$_fX!WenY1sqphyvsBgK+NgCwVuZ+x11y2k|5>e}0g2icn-*nxi% z&hR%1bR5xZ8K7^Nkc(9|XwV<3;{~C*z$)*aEmlh3@K9k8MW7Gf;|!jX`mq^6iUH!h za_gc59)kudl%*Bv{j5JGt(yeW`VIxkjmh$l`+b9i__#K|!54+$Y*G|6aRxkiFy6&x$q4gL=1kzBZ5?7Gr`PsYqBy}^PX>B{YOIpE`qc`RC-N7 zbR|V+LZ~3i^g2Nm;_qIsE~HRAgp!O|rOhC`j{tfh@_xrf)ET&(Wnxi53u#gubOn{E zf(CHG72cfi8MYL)NSIP|qk0^$Jwvk~+dAB!b6)k{nFlH=Fqq;XheZIJbzSb<_M}iS z0)C{@_$I7KXrY6Vpmc2u3fHJy|CcfnG&1z+@)ZoklP3JHp0>{MzT(Cg6OLjo>%QDg z<&A7i6&JpoZ+ivfQqHY?h$cN|jx?j>)}OAh{uvnNZXkO21rGrGDym^!aw*zG_XB)h*keD0pb&h& zTO0=d3-)mtpwDA$4FZqi$!#n$T=wAtV)`EWbh=aGpi5gdqd|w8O_G=j*jy^{!uS`O z-&!{le+M%M62r{|D&D_TW6?1CwE7C-sP#3sjz9f=bbxA zG%P#uyhd$<^yFy*O!iU=d{(Htq;7+~Q)b?CYc!!(xDaFy7+7{yZ%Uyc*X9a sl5 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 A8UO$Q diff --git a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue196.png b/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue196.png deleted file mode 100644 index 58a2d630a7b127515ad286a03023f7cb678d347d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16292 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 diff --git a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue48.png b/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue48.png deleted file mode 100644 index c4abc6fbb9a4818d240e33ae5a2890f2657aeca3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4507 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 KMNUMnLSTZYq$z^{ diff --git a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue80.png b/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue80.png deleted file mode 100644 index 69f252d1d4292e4571ad9bd57f5ca97cb6bb0584..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2206 zcmZ`(c|6mPAO1)}@|ADC_5D>+@%4(RjZvL~}6e^XMkP4go9K$9> z%`L~aoMUsg8FOvJoU_Ak-#>qU{Qh{}&--~^ujkL_Nw&2%mpyp=AOHZemKLUVBDVb( zQsSc9*uO7NMEe6wtV{p^lPbgamJsRFJ{ERX01%}L0P%?cuq(3S7XaWX2mqG606_mU z033UQ_> zNUM;F1VjgClZ*O6c8#tDyCF23vcRr6F446WKSnEYWSh`R4d<+jE;%+Z6beV)+2s>P z=RM-E&}SIJ2xFVeODiYnc;vn>!*B2KW){|b6254=BYa+bq0O)LQ5GzN%QT&{EFP7$ z_sW<26x$Kpv4MpmC=l72-=y~T&(%DXt zX!;_@GY%sV3g?zMSN#fo6Y4Wj#JcwJj0%F58={Xg5C70?4XfDP-d*41-h5mhm(|uw znnO2JG@P?F?`Ai4PrWbgt!g5#Z*ffmiWb=$e7?XfruM<>Z&P%(YfNp?*WvQU5iXC9 zA7Nbb%pIq(9=~f$LUw{&a_&Y|^LPT*>eltZVrv*GrMRbsNZr`p?WZhs56vd!cIILS zEgzL}Hg@cuR)xODMPxLQCYKx{(Ac(dWNrTvd(-58v5{}V>>@`f6#6E7QFHu!<6)@| z6gfs^>3Zh6MAxL3OH#HNe!;?$qL8T4dQ#)MVZ^r7U zs$Y(gXmm4~Fv|FVB6!AO_3!036R8(mvJHI-0+PPw*A0??GkJW$MVD+miD4Ux8l$mH z1B=;f+k@kaS=D{fnJqdVNc!U1y%%+1?{WS~^+MsEflq#DDlQK@n1>yxX`zfxFNdc! zIfPfOuJ0t}{!GsA>KvF!M0P6MWZrmKvclPJ!v8L7AXR)Hc~{)S3W9H9J!xubYIbFMb_E(+>yuD_Gq}8SfZj1cw+t?) zFL2V!3B=KPEqA0zKrw~J>LoEKRMy#^?_g0Y#O~cPHw9ixC|Zbw^b-r0Pyo1~{4c~J zORk2COvx}yD>F&@e#rwMh0SXny`r*ZTAG?T-0fg}hPx~H{oU=^hx78+fcpK0k4!?L z{zO}q=dP_fnklkxHR>FT5967ILu`%PkT>mx4-FR1zJs)0_+G?oUbv!Bk0tzJz^rNA zQVeIrPDl8!4af0?vCr~W4A!r-Y$GE)5)VM~_pVDPTlT6|RH*gxR8*NdK?Bq?*I$*C z+`<<2*hP)6#%`YgWA`BB^1=TES6KvSGSikmDlkuJhkvN_YzX0{Zb!x@ru8ppfkNE* zN9OxUVeM(vR{CDB7@T;WLb8;Kntf^4b3*P%H{2G7n_kJ#?^Aa&c}136b00wnEcQIGG;-A-G}jk~wRBB$!?Vc{8QLJHB%2WL=m< zebpK#UWLe(uU|ze=hiRZXV=We`L7;6aJQ`0iKV{Oke%3I?04=+c2wW$xDE-Xsd~o4 zxtKOeg;c$2;*z0CPa)G!lvOWH9TJ}kOg>80l#i6}fv4OtXLH;hpKnAC-`6qf-G?hm z)}Dy4>xNoJD2K@flqP=&5}THhQ#|{tw064N#oE*w1Gu$1mds#fV{^NBZg8tJH&I3) z&#p8{UAvAAE4i=r>vHD~)%s|6L@&_HPsI{J#I^?eC&u0$+>lZ=q>RtCidEu(E zD{m*m=2!O47~YoHL%%8+f4`z61ApvwjVz`P6)PQeBN!auHgOKP@J2f6gS67e0q4@7 zN|vWgJQ|EaPvXJD{-1QGHt{YEv$nLq3m)%!s3<%* z3be2uo)%hD3De%Q1p5tvoS}fi&ydHo=OtY&DKU@@@bv&YLvNhgcwwjFK&;79f1mc5 z`oOoybNr{0Tt@L&9Wzo&aGZqXY)}tHd-M;6mJKVd{@!OTa+^EG{%U*S9)Qc;V8UR@ znDY~AHRj6W%xV{`@U=L(C=u;uddwtCxU({X7mVO4Q4iwy&W=qm$FQ2+jKu1YL3fYwJTU>uZ5Tzdi_bll~_4e*%vl a`v&^M|9`-sSxZ|K04&X{O{=eYz4$NrdX(Y- diff --git a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue87.png b/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue87.png deleted file mode 100644 index 0f076fdc93b15281b8bca437c693074655a59874..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2335 zcmZ`(c|6mNAOET(-A}0}$x|t%pRhS{rV>TS5k}5ow91hyi@72ct$K29&c`jo=1z0W z5yNQC*=%xeL^j8U`R)1h_s8$`dcQyK&-?v)z5o1t;>{o4KXUNwK>z@b7#ZqY3KjA% z59}4rd#A5C31y$>9n(7iP>DLU4HXso3vPy%rU3Bj3IIez0{~wbMa%<0AP4|hE&!mF z3IKolVj3)T0AMd*ZenGyySppc-DNMY_fr?}#Bp>vIWD{7RZ^25>Z?yez2EzvE33>pjU+amY}Bq|4i+T^9n9reK@y9D&=~-su{gi9{2Pyo*4O z(Mopd%Jvvl#|$Iy!pQX2?}Ibzn_HDFRL8JNusx=td2D+}P~Aqe4#rvsmsJtR2kC6j zH#Lg3=}LBJkC++?jm6*E(S&BtusKiT>XaQY@YvcJ7Kc1GZ|qxa>{HY?I#1|f>bU2q zIAC<#a=ww6^_>&yE?F8bS>VU$8_rp^9rUK2NpYk7*Aqr$fNVKY>wWOf94mtw>)wm_!K>VTUXmoib&%_bP@6khqjyNI*KW6rK9sZQZI z#Am{nZzH7Px$dFaC`_9!EO&WzKIAN94eWh_3YlR#oLe5Wt{UjJN73Q2CZ53Nvur1^hn+}RQMCN^BP zOi3;4^-ib{PitxTKEYY%<<(H`!t*{Bc5~PHLv&VBX;1&yJS@7(Cb(>CYiESP&Zr;< z|4o=-t=@Fc`Ma28i@@G+&b(}%gm0yS?9fvSzgO3IsDf@qyL8tmyg(rMPMJ=}_M!5- zevB{Jy~6(H@?K-wECNb5d0S)5r6@G9XLv3;gQ)JDNgA4U4#&0jO=>{1oWgMU*71$a zEeHZz-ZWa*K`*Kwdim*FZ99E?d*?}PEq!{~$g9u+S<(4pdU%5Up|JZ|e4V*}32$p> zZjo!^TYSSQ^HIgrQh~k*R^$)IPEOAc-|SViy32iW%wOv9cvDr6L?8 zU}rj=HTRqxOvPJ!c*?m$_oh`lo_T%n#-EmQ+F#@pZph;g=p2t%1?vwFn#*Y`Xc^`a zag?Lg+N7h}i;7ECl_91ZkwsgrH0_TEiw#ZJCnw+BU z#TQw5(=A(9ju;umnMrefZpR*#A~>HlP`Q4equQygnpCs90=>H>R-JezO%W7i@x!=E zMXy6djLJ9ZJ(ncwcU1hU*xdK-zQvPjorvQ;DK29?S|et(@*fT?ML*g2FMr2Txrmbk$q}N%ZasX|H~%r6;{&Ky!I9%w;3tQsTP`=%@#T?tPc{BXA^kTRgYK?5=)*7V`wunEK&&!@6+ zr#_JK&eS=&*iRMTrG_F zRHK*SX_q)}^(8!z;NQ(ODL5Q<`6TqG$jPSsjhOvaj`qP#&pTiVwFle?;!^#4kLhwN zf^c56ywn$9p2wGC*x6o`4&SzXHaIj<@-*Z;Xw76YGrR72FL;D|0#)j{$+u@AE!A|A zCP7m_SxT?Y){fg}B5b4?|4D^b&WQ>_-7+a1S?Y<(M$H*MhYDPN?G7GdRV*3c8Es5N z;}N2PlBCMrVBV=f?vU(J@M8_yIWV*wH8@Gx~-elp9)89p7%pO{1qFTL%Q6~k?o?Epr9Tq2uZ>Z z*ai00$Mmm(_7}aYKU%E?1``}6)u%N>zg|7p#y~dt@BMP#CYCedi9po}%yi%|e#IE{^E1nl}bTPs|SQ6#bMb zwT&(b!VmL3W$bNTq@@zv!oMYjonPX~7KAyQQ(k(3m(6BT??0X$q*9$t`Ne^Ky4**v zso=sp&>TVeD5%6|hw;HLJq#_$g0PouBh8z%kRg<1WPu<*xh8!kL&P!sW`DgO+}?OM zd$-6fiNYA7Q^qOunU{h;M#7m9`?-waEbT#WSfW3^MEE6T0}N~f+@S$5EjK@yPyl5R zSW^L{ssK{A0;_1LYG^5ggu509^kC{O>VFDeKJIW2#Q!g76O>hi1;EJQp*~j6CF;Mb CKiOdb diff --git a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue88.png b/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/CoinBlue88.png deleted file mode 100644 index d74a6c0f422e756999f4519160949e4642fb1f6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6034 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 diff --git a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/Contents.json b/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index b0152e2a1..000000000 --- a/loafwallet WatchKit App/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "images" : [ - { - "size" : "24x24", - "idiom" : "watch", - "filename" : "CoinBlue48.png", - "scale" : "2x", - "role" : "notificationCenter", - "subtype" : "38mm" - }, - { - "size" : "27.5x27.5", - "idiom" : "watch", - "filename" : "CoinBlue55.png", - "scale" : "2x", - "role" : "notificationCenter", - "subtype" : "42mm" - }, - { - "size" : "29x29", - "idiom" : "watch", - "filename" : "CoinBlue58.png", - "role" : "companionSettings", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "watch", - "filename" : "CoinBlue87.png", - "role" : "companionSettings", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "watch", - "filename" : "CoinBlue80.png", - "scale" : "2x", - "role" : "appLauncher", - "subtype" : "38mm" - }, - { - "size" : "44x44", - "idiom" : "watch", - "filename" : "CoinBlue88.png", - "scale" : "2x", - "role" : "appLauncher", - "subtype" : "40mm" - }, - { - "size" : "50x50", - "idiom" : "watch", - "filename" : "CoinBlue100.png", - "scale" : "2x", - "role" : "appLauncher", - "subtype" : "44mm" - }, - { - "size" : "86x86", - "idiom" : "watch", - "filename" : "CoinBlue172.png", - "scale" : "2x", - "role" : "quickLook", - "subtype" : "38mm" - }, - { - "size" : "98x98", - "idiom" : "watch", - "filename" : "CoinBlue196.png", - "scale" : "2x", - "role" : "quickLook", - "subtype" : "42mm" - }, - { - "size" : "108x108", - "idiom" : "watch", - "filename" : "CoinBlue216.png", - "scale" : "2x", - "role" : "quickLook", - "subtype" : "44mm" - }, - { - "size" : "1024x1024", - "idiom" : "watch-marketing", - "filename" : "CoinBlue1024.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/Assets.xcassets/Contents.json b/loafwallet WatchKit App/Assets.xcassets/Contents.json deleted file mode 100644 index da4a164c9..000000000 --- a/loafwallet WatchKit App/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/Base.lproj/Interface.storyboard b/loafwallet WatchKit App/Base.lproj/Interface.storyboard deleted file mode 100644 index 4511f1187..000000000 --- a/loafwallet WatchKit App/Base.lproj/Interface.storyboard +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loafwallet WatchKit App/Info.plist b/loafwallet WatchKit App/Info.plist deleted file mode 100644 index 23a5e621c..000000000 --- a/loafwallet WatchKit App/Info.plist +++ /dev/null @@ -1,33 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - Litewallet - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - - WKCompanionAppBundleIdentifier - com.litecoin.loafwallet - WKWatchKitApp - - - diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/Contents.json deleted file mode 100644 index da4a164c9..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator1.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator1.imageset/Contents.json deleted file mode 100644 index 95619943e..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator1.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator1@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator1.imageset/LoadingIndicator1@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator1.imageset/LoadingIndicator1@2x.png deleted file mode 100644 index 84ab9e97102c17b8b9b797216c964579e70e9a7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1715 zcmV;k22A;hP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka160bmi`B^wGc_#=r35GgLlF>J2UreX6LM24ZO_P+4G+B-rcja zlexKp|C***0AsKLb|;X&%qBF^TWgfLQbx;$1+kgydWvsaTyN{Vfm>~Y6?hBtnF zDuj_&c^`L=6I6W7&K7`V#=s@lS39o%(;6`#j%@t;62|%2Fbcmu4dTcS*(KIjyIVhU zBZhxYAQB#dGvI_qW9$Zd#Na*&WQ(z=iS<}EI6nohg8Se(css#s+9zNgtfZW?W?H1- zy8)hoFW?Zk$NC%n_uvi~rQ+>0kE1JK2RKo3t$ao-hXl--yyoG#06qXGNUr^i-K{WI z^_Yw2!EKNeB)0a7Yc7XG%=NiZd>Zk;3daG+i4t3T%r&Y~@dqat-32iLG;{LkUGg0= zuJ);cZ+V3MM=2&mZmuP`AA740*)^aMB4_ggALo4MjC=oB#pikO9pnVitgZX8Ci@Uc zy^sQzOJ2KnFC@b6L!b#bX45+Ez}LG1e?G@o{G1NsZH+Oy3A6%e>|#Y*?xZgDLTp>d z9Lz~k_LD5_KWGUOPC&Q~G>L0%RznUM!%=+XijPO2R22XEPqA2!<{(=HZ-6#=josD} zL8JqhJknBRWi#37&>s7bz)!HW{{w$#BVqoYVsRO0lI~)&lO!x$AXeGSl!_8we=!*r zWGfW}dYL3FTp-r{3IbhEh6UOGJE&>0caV7vO8#1k1%6Q58YD46x(&M2m}$1rx0oXT zsV2m^1;QFqGS0unCIVI82TjdfX@EF`?1QTAq?Ng=%@E0UCoPddTIE|zoplF8VzvDi zbFo3(>({*VTcagb+pl>^0@8WV+j&q8VSJy&YI`2!$RRF1QFOj)x5O$%+vY^kPX^MW zGil$KMW1->&ZJ`r5x@wj|Em%6VKqmb_5Z73mCWDB^9uj~|Nk&@SXcl60|ZG#K~(LT zPiquG5XCoZSdoYjh#GQAyd*g&ii)5FG@#@V&mQyx2p$DbegHiQ{<)~%b^Selwcd=D%FblH5v&(%&U80`bA02aH!iZ(no)4LK+=|8gw^rWyrcRGV+8o={) zVSzqJsSs=vsK8oghSlbAG-!`bczyyYGo;J*5B|b+lg{hFnz+^Oq=yF4p>Wk&rYq^x z{=HyOf^82V&}lGW&knf$96+GMAT5HeXAp%yCQ$Vn#6!`>cLyARqXxRxy=jmv9rV|& zK_WxYDqk_;%z#$wT2O}SnfheYx)bOAIY_NBG5h#etPyDNbr4DIf|xMNg2{GQ{QN)e ztz;cE=t`QT^!h9dVEujI3#4m&)m=$9K?m83k&I@JRg93`!c4+n-MyH5LIf_lo5$Y_ zq`X!kf#hSMCh@!OZr&5A*m)31^bventYgQ~wfL`l9^?h?eWD2YDJU^}oKW(0X$inR zm4V?wDCNZ}H#P<{!dQU4%54Au002ov JPDHLkV1i)157Phu diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator10.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator10.imageset/Contents.json deleted file mode 100644 index 025ade0f2..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator10.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator10@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator10.imageset/LoadingIndicator10@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator10.imageset/LoadingIndicator10@2x.png deleted file mode 100644 index e22f9634ca3c0346c5e8f6de6b729acd1b4b1d2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1715 zcmV;k22A;hP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka13CH9BY*$^0|iM$K~#7F?3vGM)<6`+YyDHHixw5^qPh@iQ7ZjJsM4Y!?p<`@ z1Gv#A5Zo5r`2ylf5Ot-#Vf>wvffy%~J7(raJ}n$3nYp>=-t$dvW~M7EGygSBvkJDr z4%ly@YxS+p9Nv8NB)PlVs1#~t{4 z4J-nT*?h#$FF$BM_S1We^ebBhu-L_lc98=!;#5%{OFU=%I4VlF6T*9i1-jAoAFkn0 zO;&&bza7 z&rFt<7Jum#m`o((YVmtxPfm3NcH@q2=E425(3vghtNBb1q0_%+-bG;;% zF?a`#z%TH};2Z4+a2Kp32@*$_!49yZxY`HUolQa<-~{fA;3KetxY|SPZU@l(8^YjY z;3jYh($)8xF_(gg0|&yn34Q{XC|!MT7~{WG7{V?AG|%MIyAYVG_b|9_faa&vC4}qQ zTQ5?`t^$n^E}NJ5IO9beU<}7P_zqkGX!`D}=pkAG&w(p>ZQmUgX@n7Rz6TlshHSpz zXLT?XjK)AKfW|J{qD`E#C=Vs>)Bi*x(4)ixT^}S3G$2ly={^Ds*?xA00@+Eh4>U7F zYxB@a8qrCdpTJPkKK;M(ce*zuI;G;&Ca$&H=_QQpAl5_RBY?)XzeIuTd>4D&Kw9Ki44yS0>zHgP zzxF`-#AdBaD4st9nsr5MZno0O8yBD)>$Rwlrgt~0@7(ca}=U&zvpU=t) z(r(4a)SAS7+1u1Zx z<7(lRmn%DjeE-#O1)%98IH{0rVyW6)4flUxvk++DH6hU4KCyw&>gYzGqKkALS$jl* zKt+D$JwmF_6p>OEiu?6t7#R@)W!q{*hE~sTL`uF{ttY!gks#7z5Lye(9CsuNt1dTY zCi(2m#CGbKqpplHL_@;SN3I#ds?Q}tNeLizk`$9(hxR41`3sDkRybDe$)*4R002ov JPDHLkV1nid9dZBw diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator11.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator11.imageset/Contents.json deleted file mode 100644 index 84e153a75..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator11.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator11@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator11.imageset/LoadingIndicator11@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator11.imageset/LoadingIndicator11@2x.png deleted file mode 100644 index 0e129f07861bf514353ff60ae1b506f1e6b526ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1715 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 W_FOu{6b)kl0000vKbrz diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator13.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator13.imageset/Contents.json deleted file mode 100644 index 22b05261e..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator13.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator13@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator13.imageset/LoadingIndicator13@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator13.imageset/LoadingIndicator13@2x.png deleted file mode 100644 index 2c6b99d8b2d12841833c1f040873c16508ccee03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 A$p8QV diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator16.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator16.imageset/Contents.json deleted file mode 100644 index fa41a9d68..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator16.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator16@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator16.imageset/LoadingIndicator16@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator16.imageset/LoadingIndicator16@2x.png deleted file mode 100644 index 9eb4485951caa4662c15baabc2a5377f3f340bd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1709 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 diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator18.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator18.imageset/Contents.json deleted file mode 100644 index 79c249cd6..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator18.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator18@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator18.imageset/LoadingIndicator18@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator18.imageset/LoadingIndicator18@2x.png deleted file mode 100644 index b879a22e4ebd85f0299c7f207e8f8d6ca3a4b3b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1724 zcmV;t21EIYP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka13MSoLaYD)0|!Y&K~#7F?3ur66+sln;|(Ga38-kHDa8A3HpTb1(WTvK&bgCNmQSYFMzeY zmp|f+j2ZAKwH*H8oq6?1dqWX&=x~@3hsd$;6f3e>}Zr3NEF3U0xk2a(CffJa@_e2q8Gp- zM4!!feB5gG2IVD~I*MA!;7<#N<`%0MA-kK+ScAVIQcr&ceaTzf-up!OeF(;iw6ZzG z*If`wI;Q>!euh^%j9vn(02aHhNn0Z+=4>Y0*2t0Y)TuLLL>RKY?RV%(8N$!NlDO68 z^$H0UjpX`-Qk#_n!LsCQ;Wnaz%}~Po_8OB7y*WC zHPMGRzclUwOVTkmXPzdr6^T`QnW3a(+b;(Lgls>7KtFS|6v1KxHl|R-BH9X8Yrs?i z(I!|30l^63N1~c$OSr6qEwBe(fR_!P(B1(Xpv=Q1&<+>_BZ{y6gx|(dsYC7|5WYqbU;7ZhE6H5x zd{qEx z2;aS1QK?Dx0BD5p`TQitrKrRS&g3`;o&ui$8rwBhdJ>%l-+`}qt?h#$kWAj^zd$oG zv_7A`Ni&S_ya!@NNXS71PQ1v;8ha&sD5s-b;egnCdd#g^e7_ir!gMzrqo!h!_ZwNwjN{n5#4(fCzO+oVd z%nG3We{Xgq5v%S>x*0{C?8PWXMvhhtm*3P#B3|9Sn0Z1ZF1nj1p3FHhua!$6i7_=N z@qgXjd^3uQo(EBcOt!9~WA7iB2WeVj*F6ui67P_F3^WVF))Phg%BQ@<=rKY{thprs z_hix*zM6?S??llEB(0DEyCCUIntmf-iYwKQY>xIdxz@oJ=>AOFPHe789QCV4L$s7I zCeGX!&G55Zat}baziQYCQ?4N>D`ZnxsdhhwOE3E@1qwVC1j<<)x<;Jp6$?=7hZ%vY zPSX9TI)ViPRr$^{!~|p2_iiLt}j#Q z{^ESOe0nw`DQ0gbzEj5>zW57aqu}f#*M$%wR0KlF5>0000Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka12ynuZ>sHIC_#_0(;;H9Ctwa#Aa!@NC#jh;SCTI#urR%HwFmRo{~g& zfG>cyzGEM;A*0NK9^yC=XLBYYjI231KPxAQUy6^}Ta!pi7F$2rY3qB26Tdzc!pNt* z#O!f`im%z(0+5XCXxJwH};otGEDM-USv)c22f z-uXndmE0(X{NIH`&UrCWLVb_@SXFh1K7o(`nl}0Ay=@awuXfbH_Z`swDTRcHwXL^f zO+G{R0ceDX+5ExBYMYFD@xv-UZva_aVghLT9<*cae1=Fy`WJ{LukHKd6XCb$bqD^Q z0gV7Dn=SmLzjPQK0IdKTyU?O7Gb!h6CbkpT9JI-zoJu^W|Divi6LkoG08Qdro5Kkb z8sLzb+Uv@d_aA{A0aCUvLa|=9L3SJb2ioK{cHb`v0uOM>7GSDNd)|8vQc36Z%R)a2 zgn7|K=To3bI>+Xuldxw8vC3X1M*xj&_hlSpTNMQQ+f#?m*NJtSeNRfH~rLmE>ELD5DLtc2L8xP_z;8wJr7 z^a%n6D__A*dMe|67d_6-rZ=xH8*GUvp6RxW|W$K0I6@4BaXGm6FpE_NS; zFPUszNypY7+81d{eD4DJd_()3c6-`=P$O{mjUuFFDK9a4tdQbsVGBT=OxksB6s`FAX{vd_RAp5KY3cMBsTG}TTpf-$V1gbho4jnUA0}JX1s}xlw#O zybLoLAy98ejZA98>5fPfkh-kfeshP_;bd2c2?EKE+$I}asy2s(s4mZq8A&l`GqF9} tBd7g3NI3h-we9mv{zjrnP002ovPDHLkV1mG8`xO8H diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator2.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator2.imageset/Contents.json deleted file mode 100644 index 1a6ada92f..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator2.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator2@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator2.imageset/LoadingIndicator2@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator2.imageset/LoadingIndicator2@2x.png deleted file mode 100644 index 9776ca42b90c48d4d694a495121001f47a2960d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1715 zcmV;k22A;hP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka16;%kwpRcE11L#EK~#7F?3q7n6+slmqmn#@fFMNcq!9%h?R{V>v4~(NijCNq zSV;s0|3FL%JMlBv_yufi{SG0m7D2RCtLN|H&a%$V&feMGxhqcthuNLEd(XKiyR)FTc4Gvo z_LLO51$+av=UeuQ4H@Mw=wXgCaX#-PjFCAf<*{;x_^srazd4DbWU}>(?Rvgvc;n}% z!Wem#4{`T6LnYVzECDD+)-OzwLAHh z8!`NI22t=LSO!Nm9uqg(BL?>|a0Z;vXzdhJkX)p_4W0sdWeZ+{N8mbGYf8?T=_C!` z6ubfQw)+l#7C5AR2X29-CcR1hB)R~$fior6-X-p|Pe9)UWPi=WaSpr(&X8EUPuvY( ztNNUakAQ0+W=Lr41=pPSiHbZ!P0+i6{PG#|4a7_djlJR;)l~5ZCl?7}$N){BJbGuV z2|3U9sX^|mp!z6}jSn=Ain?4bFAAqipT5Y?7TyKHKfVP-VxX`36cT&ovEwQz2 z4*FzLZYw-x{9(-yzXQViKvTFj=8DfD=Wz7iawUh{=_v-Z#eNKFE&Cul4t9aIcum~B zk|1yZ*96EqNfwhyoA$(i0BuF5jQ=3t$$-q?T@1>KQ&V(G%yuJT&jGaVgA@Zav9%>i zDHF2Q3(>khU2c>K+5bBzu*fY9!yxlHs3h-jfL_}@;ixmbfOOFPpd7|ja~A(lyZs-<|iQtGO(W(K-b-d(xqTAYTOPUo}EGtoqQI|5pvGV*W;+UjP6A|Nov+76JeO z0{lrtK~(LT&1w}v5QSs>iNr;M2FxO6A(Eg(5(&hRpdjwE$ifG3qfa2X4Y>0K#FZfG zN`1reJJ1dHPI~%h`X?jYz@anUHFc`a^wf0sU0PcFl~+>1qFc8)jy8Zqu%h_d zr`WB!J=O1p`vJHBRuEtN1-sL%sBrKQ_ylo{opR5;EaDM2!}%Qi0zOe(V{f@v*8 z0&NFLM;Z|4o5BKp_J#tPUN05cn3)l4v+pI%7$nY5AZ3PxZ2#cz&R|Fku7cRaW9^Ox z2{Q+XRco10(y8OaGajM(davHq+e(4LQQF@w6!JA<0nAZCCzzFN!dfPDk~ zuRiYzm+`hWNK*^aCSNglR=@!`1Lp(Km~2*D)1LmeUoj(4^>q-5iNhyMUohEj^+lrZ zO4dPDSJEW43;F`YUhg_YYP*s)v#82mOtTW{9&-6bW9R@)EPh3MyZhmH_mr zXkUPs)pP!d;*3aHXVL_$I$@J5)o$AO`Yl}T&ZPU~x+Vb4i0EH6u+_q^lrYxMjw`l) zpNVyyw%)HAebUrxg3}7wCRVDgc1n<%U$*^1pn!x3bY-ttAhc-=BT&;KJ&mjrqClV~ zpZSE4re}&sRTqlW%Q!J21gf^xNDO7V=7>~$vpU^uM@EK7MUOj1hB58i%uGtzo5^eL`tWHgm@t1?c}D7bLGGfYwRLhxRS9{0GzgRybTlLg@ei002ov JPDHLkV1g_-90&ja diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator20.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator20.imageset/Contents.json deleted file mode 100644 index 88ee2f7bb..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator20.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator20@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator20.imageset/LoadingIndicator20@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator20.imageset/LoadingIndicator20@2x.png deleted file mode 100644 index 9c6a0a961aeaca9c65edc7d398f570f5ce6d20f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1737 zcmV;)1~&PLP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka14W==9+vT|5Wg6%N$_DA*1bd9Vo{OOtQ+WJ@hx4WjNcV%Vd z&ulhZ2Mw5l!#U(y`qoDdZ#;UE-vUSA6?hYYjET+Gc#)34Ov3vhC5$ha*zS)Isy!u% z%JT6A(B4n&BQ|7|SB!rQgQ?jg_Abu-8mais}loVS(*{=6Th7-R&6~f4) ze2CfO1QlP)vjrfT2Ds#gYMc5$tq}v_^m%f{1f3d%U!MknWQQC}v}^xi{m6|N{yBk2 z_yV{F)-)PpH|i3De*>&)V(nyu^Yh>sya!*w?>TK9k2hJe%MSaDt>-5$~!WtNNZV zuY#8#B}i!O2j6+-6VX?7qlo`2;2}tf5*oYV$Ev!A=rsrlpy`vP_q0vKeYIB&d|w9b zr4$k()wkDuoab2Y*?`r#vvEwxk5mjBU4Ljb1}^5qtruz@Yv-NK(nfSk>J{N$g?7(EAC0W@}@qAfG2$97Pd~-x0#)A! zWiwYAAkHZJpsG7*W$tP-M6%sUOJtB%c^6Y>U0_J8w(nvtHi!p(n|FR|w8U!rHZMs) zI_P;&4Pn|oiP!c#$dNWxfDkA zzZxMQmVLy!0qXs$VVTU|#`OmP0RR8)3J;$E00SvWL_t*Tna^qzK@i4cG>Z6d4*^9% z!GlCW2n57~Q9P;m4^56jPQiTuPrib;;4_He#bYjBeTT)X7g4;br}0-X4YRw`-PJuc zol!RM(UY#~`l`O^>FJ(bT3Y~sWplJ%bw=zS!DV>h$6}gzaR_#VJ$L2L$<-SQbiQP2`B>k#^ zzsy1_VO*RomrtmLxBp)?LJ4SWBq=*&SD011tKt49d=>&lZW96>*drE6Z5U<*D!NDy zqw0h#5U9v&J|U&yxgwI~M)BqFD(sjM0*!#hW>I2H9W^?pHk{!UW`0;5PIX3^Ad>0l z4x_Y&6{em^DUX}@PJQMWRz*EzL&35pjX_8#v5C+Bx#nnerFhu_$UaFnlX4^x$hGv% fo!B)oEq(q1qhL@+%Z*O|00000NkvXXu0mjfKqeZF diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator21.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator21.imageset/Contents.json deleted file mode 100644 index 8d464ab4d..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator21.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator21@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator21.imageset/LoadingIndicator21@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator21.imageset/LoadingIndicator21@2x.png deleted file mode 100644 index 16dd653b74a604849403caf507a3a8ff6119996a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1728 zcma)+dpr{g8^>oh#!KYBa+!>w4<|OV7h^NCRgC2_MN<}sTsp2f?~2Wuxx9xWjx=N< z$0g$3n|2~Kaa0z$Er%_yiuWMR3Cr!Q&*%Jg{yNX+^LxI}^ZfsP@&g0>v^5WC0ssJQ z5)n^PlK3?cHDwQ3?(|baC6(fb1GEjBE-Dv|i^T9$0KmxlYg9-S_^R?~8iywbD+yHQ zYr&PV{gcXBl{owAoV}6;Bs@0wlFCwLZ@eMa;8|&vuCC8K%eHZUkjpo;~?CSi7 zO15-EdssK963Nsiz_mOpFY1D2LF*ULq?E}!@`6|C=`KtSZBxT!#J*or3@cW)#Y01b z*=q`h*;206#Zm9sJ4u)4SD*0_3Wp=A$$dgly?=t>Sz#I|Mh^o(pT+fw)}z>g%XXw- z4%s$Gz@S@nSn_{ona{cHujoWr7QH}6a&G9u83o1fs!ECRYES6LpCh0CK&#O_OSiMA z+i=77Ps$Tih=g^NWB2Xqtd9w`6um8YiC2n=tNG+#9G;hbO#ObXPNUzx2jo$U{ z>PyR>q}(Ht>vF5@u6si!j{v7sP#GPh)8A7nIxD9fBT@qqr78I)P02}YuLT_R39^)4RY(V<_* zW4Lr-Y55?mHO1&;>`Y$?HBo%d(Uq(2`O>}DrCJpKubUNc7%!)9B{v@Ozb$y^^cKu- z-zTSqbp8Tk{EA-V%)jeuv_uDMHv`^moc|QiauQZ`23@de9QRa88qi|}+YlBYQ{Db+7jTN3oqAoUPPkZ!hpC4{fC%W?%hS{;M67D)`^BqtEO|Vde*Er9|S8B#T}j zzJ->erNhI$Ev>D)Lx+#li0|bbjN<>iao;@uJF^5PDO_CsUyiIuuD`i&*LBlhVfeFZ zajRo4M(??SDe;61?UuA!CO4k~|K`gQjo3W^5e#SwsBq_yNE3092Hs%q7ljpEI%6(e9^3#Ysiy5+_yw-Iu4=D zVD%j6NL?$o_`NzN39IKqYnd?OBhcoMv&WOvqXVis0rK*8WNS2?ZN=e|)2*VfXe?gTXeY7tB>* zBK+peXc1wK0YKp%d>O>|E^6fyBoX~^-nrC8_=^NssO0&B>*Ev2?oU}uK{~*lG`$#C z-3$5S%?|TpP$PEpev$o({@pL8qT>=!o(wdYMTUtfAF6c*S?do|OKjB_!NkgFoPgJC zV(RYgTK}<6U0wNeG9J#_e@+kUAk@xoVBr}c#*;3v{xn}e9Mit9^Z#^&KSi$S0&{mR zk6Kb@cxlK2IyDc&3)~tF*Q#+&IoE$t;!p(N9``J)JPP`5AZ^p99Mm`)1KAqi=f4=N;C=h(+A3*K(d@$~y9}*bCs~@C^*k3hm7#ciZB0V_32Etk_3s41nYtfN#S^vHk!U C`XSZ; diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator22.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator22.imageset/Contents.json deleted file mode 100644 index 74dba2692..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator22.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator22@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator22.imageset/LoadingIndicator22@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator22.imageset/LoadingIndicator22@2x.png deleted file mode 100644 index afb66d8485177c83b6cc1d1c3beb79004f913976..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1724 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 diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator29.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator29.imageset/Contents.json deleted file mode 100644 index 704b19f35..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator29.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator29@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator29.imageset/LoadingIndicator29@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator29.imageset/LoadingIndicator29@2x.png deleted file mode 100644 index 6d4234934c322f9f9c86ee3b636252a888a77150..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1727 zcmV;w20;0VP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka16nO<6Jh`W113pCK~#7F?3uA^6hRcmLnK5cHbDpo7D4}k6bd#el0u9{unVLS zY+_-RKoUV43p*j`b=ug;*;z=EP6MKrnt#Mz*58Ahu*}WQzPX!uE2jq^vorJdeeZoc zJ3BKsHP!L2s;XJA2KKn**E1(aYD6vxJnnj<0Hj~dhJlDV*-~@@4N7&u= zV^!C=c^W(dF+oCo^3;}nBHD5;6ki4Wufp*i#6$`8?Q+kw@2|DaP1_(OfTm4ey<2q> z>czGi_+AF}S1BY!tnEoX*4Ast?gEVvF`GktT&a^$&%Rm3=T-0(#01dv-K)picn#47 z@Bze<*Y-X0iSYXvjJg&YI_|*N3!o98&E_+HF8c8f)iK%xS^+e6p-EdtQp(;;Y=@3H zXp>2~E%B882SbAR4G_Ktn#8p>_k9kj!y$8055$C$KCuZNZ_xe_qzKSv`z{pgSsP?? zK!%z&d5vB4XaX)-0*rKM&wXz}Thb~0Kk;|zOc4Kq&PAX}I>n~%^W>@%tE^>G1kl)C zZ;TJJr2+ySH4={5L9E{j2y~+{EXe+kpsI?FAoDq>@o6bKc%Zg(ki-P3$yZE~f2#?x zZUN1_qP2;C#RdWuUk9~jt~5ZLPS!z1SJKMd)nNQ)iuENUXMdF&7)e zS$Ff!Z;6svZFlpM1f*HdgGvZf_es2~!0tTAkwdxy`arXK4xT7FU!_Z8lu6s>M6sR> zq+^{)*L_)B6R+KwbSNPLkPYTMQ2nbB@?q5`F@m!HYFH)nH}d=e00960YWP&H0009D zNkl+qBIJ-7!pvN(yNeQ*REDWUc?a$8vpCn&-8 ztn<|o5^BF8dpE(%|0zt?(tHd;gbaRE<3xo);jNLbx$IvGD z1VX`E$6lI@P7uP+x4=Tcn9L9KY>v8u&;wv4z#>;HY2)V%j0GMu{>VbmyUYYV95tFK zfS*q@6LcJO1!I?h60BuqSY_S>jZPTE&yOHxg^bB6(O>qu#NZaN25yx*@*12tfUl}$ z#)6I=pLyNF*lq!WPP_&u4&dwW0tETX6O64^5Q*RW-XN%Y4#K7?_HD2SRPYIUR$s8f zWxQ?<5_1@>vWsCy_0|D+0(96Ng2p5>Sf9{ecNgmjDqaT>*bWF0vrLv`cb1nveKQc7 zghTSCI;dzRO+fm5mI<)_zc)Zq-AcM!MMchH5Tli2CBrATu#(VM_ble#5Qej!=Fz8> z8S`2B2$GJ4oW%c1?DbCb-73=VlI=bST}rmTpkw3NAy6fHt^$hFnOuA8IzR1q8 zdK{6`b*2QMPf1(8h7z$Gn|7n<2vUo|b)YwtbSKR`)if@+T$Nn?6>fK5A4ZCL? zi279n`6)Y>kI*wan)9#UVq2@X?5`SqgDKBAsL#|FXlnm{iZ4yhSrIhyS|I4$KCuzk z+8BnQs!6(ys3W|9peoyZgiGy-LQ>H}vAu{RJ%XTOM~z5V+7*YS?1$BMqfPV-lBVov zrs6QswRWa;D=Fq|CfS8+j&`Cc#NUbZK8BqEpHf VVmcO9+iL&-002ovPDHLkV1jj37XttQ diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator3.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator3.imageset/Contents.json deleted file mode 100644 index df32cec28..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator3.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator3@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator3.imageset/LoadingIndicator3@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator3.imageset/LoadingIndicator3@2x.png deleted file mode 100644 index 5def777f4013d3bd018d4520fc0835d10b0c67a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1742 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 LNkvXXu0mjfl?V-% diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator4.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator4.imageset/Contents.json deleted file mode 100644 index b20aa17ab..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator4.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator4@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator4.imageset/LoadingIndicator4@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator4.imageset/LoadingIndicator4@2x.png deleted file mode 100644 index f9efb87645f93744838ad3e58116f1f4a2af0209..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1747 zcmV;^1}yoBP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka16nO<6Jh`W113pCK~#7F?3poZ6hRcnlM@4il90v}f+Qr3B3KErG2#`HLTn<4 zIU)H30fUu(1UvCN*!Tr(ENuJ`!PX{-wkqfE;m)y{o0)yHxARs`5B|)~%-i>W@4vG% zvvUgzJ^#kz@eBqMtomt0rncKJtZ#DF-ntXwfc=VwJjAlV_u5^dXlWb}N? z)BJM+k?=Wi0W50d#jdwktcvxr#H)$5l?~1ZU=!Q}PrzY?1IkC>Hdu=}r_XefhHnSF z0iVGS@TSWZ1pzX5m?mP3bioXr;6{G~v^c~b=jb1}^ z9y|uAO7$sa7Dd zJu`A7aN1;2Zc03-|M`?4eglLLfF^OR%}t*}>Tt|_@M-#T5BB znh@&?pm}YyHtAKY5~%n-s4;V;0pj$s4=TEoR_3lYLnPasv_uAJk#8||))|Jxx&iFI z#awKVcKS8%{FW$*)%I&%l7O_+^Pm#K)O`}K?Rk(Rhj<;#bfV~dl`e@>CT*J&#d@u600960?prsw0009X zNkl#@B@q-9yOAgn&p-nW4FwfELK8@{aGFd(S=N@z~DV+UhU80!`DbgY)Slr;iBF3AhF> zrjOo6B=|XS9qfVw@U+Df+Q(oAY-S@67#J?%_z`>qzrdds-)TRA7a+|8CeRkx14a~A z`vAX7f%PPFC-+_O85lua?FoL*qmmQg4sZ!FWIN=Zt5J!UxS59Nte8VT+cxFRT>h))%PJNHOX!OA0b>mng=cfC0@dr9Jj#_;1a;c z_R=doiS&iq2d?6MZTG#BMmWLq82AV<=5tD%jZrE%-2}b@`1oa;wBe~qd93gd`zs%T z9wip&)@aft9pL#Uu|Qv)R7f@fnqYlKhOf^6YChbMuo5KlsJPUwfj*1{l+oNUW~XJ zIlf}p{N_dy@yhPSj9Mh#0lsUUzTd)bo>-c5LS8GIK#DQ^z7fG}+pU z4(&fO98F8?87Oxi)JeQW;;0iv?$@V0#pp3YD%QdhfIdyy!C$rnR!hh7?VbPt002ovPDHLkV1m_;AJG5+ diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator5.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator5.imageset/Contents.json deleted file mode 100644 index cdf5fd303..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator5.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator5@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator5.imageset/LoadingIndicator5@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator5.imageset/LoadingIndicator5@2x.png deleted file mode 100644 index d881f96d63fc7bf1b4e05d260db9015bf1e0d3a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1707 zcmV;c22}ZpP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka15DYyrZWHl0~kp}K~#7F?3ur66+slnV>F8R?-l_?!GMLRAP51mNDNj{G>Rsr zU=_R%V5N^>Cq9D+HYsgveTR_NMnqe+y8aIAfz8~R+1bp@S-Becn4Ouk=R4=i?EJfP za|8cPCX)rQ3^u`b19_IVg@MBxj-KR4U<}@aodBdyY(~RHIsh{XuY#B`u3%!jIzXuQ zlq9+ZTme$+TlNtfGRi2(5JyFv&5?vKBhcrwQbF8Oe9YdQL{ekmCVSBO*l^(2r$QK6 z%1ewM6;yo9&K7`VWKW~Xl`5C(|7(pH5JxtCrG!yGn?~W+r$HRqA!}l#%I*4*8!`NI z0+H}xa10zu(HOhIKCvd&vy{hEVm*)z&ga2Ja0@&DPZ~U?ybErC#gKFQOebmh*1%h^ z2Y!Oz4Zc!-08hcuP`tg`adZK!0~IA!u3&e{C7{h@nTO{p_y|;xShmVkG zukRu6ocD-Sa-;a%KI)HsRE?f`6lfm7iPpMlX6$$efnQa3F0%v&Os6^q$aCajxhQzvAzT;^Gd2s zd=+a1s=g1>1anKo8Dt++btj!Giu*ny+3utz07#cW>M|a(n>vfR$(5)Rr|nrxgNC^1 zX;9@?mCWDB^9KL`|Nj``Eb0IN0|ZG#K~(LT&uSDw5XO@j zCB$GrBVNQn5ElgrUP2OytmNV))fJ24*+Y zJyrcLv#^1W*>qP|ef4d3bx-fY!u&720##Klf$Ql#r}qfYYv3+eN$WxMSpN-Uke1);jh!~sTFYpPV>3gFRi9k~IcY!Z? zZQo;6&7;rSg{W=Nmy8UAiLDbcwKw25o&cANntJK!p3nZBg0 z{UawWf~{u|Xx|wyvIDOFG6=Niq(!j#45}*c3@ToO_)?a^2#mo|4f!l>%g%3;4*JX1 zAR$B0BD)xI*1$3N06sY&ePXlLB^2#%fwji??ESk~El~Dz5J_zVpD@#ciS4D`khUv1 z2W34;lawrsgfLU5sR8=4i!m*-gwO{B44A?_$k2M9`#f^Z1jR zV_8-%fyBo|P2&GUa0-0&#n)$hn{SDf>^=zcQfysGTicHtj?EL_W$%MpfunB}Aun5b zirLc$DZVZp0cb0Gqu3H@k>J61(u^H}Cb?8k=Yft`{ zvb>v#?Zh?5Y-Jq4mV~3PTm!<+-VlTezO*lq?FGl>P)XoUzFGhP002ovPDHLkV1n^L B4V(Y~ diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator6.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator6.imageset/Contents.json deleted file mode 100644 index a74518087..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator6.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator6@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator6.imageset/LoadingIndicator6@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator6.imageset/LoadingIndicator6@2x.png deleted file mode 100644 index e0671f4234b4ebdb3c38de52505d77b9bc73b277..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1683 zcmV;E25k9>P)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka13MSoLaYD)0|!Y&K~#7F?3uq#6+slnxkyNe1VdsVu|gZ6fS4GukwkBT1=?5= z?n7AVBUl+LIvW}uz{b*dAhZ_7NUJ`<<#)mkxz3%LJ+r%W)?6j|GIwUqp6{G*=id%< zb3Ol!$KwUC4GzFz1^F#)3q6O|A3e#hfDt$bA0v=Hv03Ra(jJ&eco(FE@dXpx-5x@< zrzBCCKE43j`hk7KhKw=_T8QIBoXwGhFtX<4Oe-gdUy6^}Ta!p?1pH*1)<=c|zdRMf z$X4FP=y8IIuh}^Qkc^yZTykBN+vQ)a5d-41*|}nZ&d!d8KypHkCEB$8(CGb^r}^gu zBH?+k2nHH?vFmM$!F>a)fhA3>jcjl}0C&Ix@C-b!uur)Mw!mu4Ien&!bQRMF%5(4& z{I2kg@)XFFUyQ|@)sCZeAR;(XQsqPJZu$hYnQZg$Y=Td~36d($uzTglnpMZaeUK6) z)HmdrHJ^yK5oo#~`_CN({J+Hi1xSe!>U+mC^S-~@IuFUT2??NSlc{%ml7xD(PmLTtBaa>d76kRw2y?Uzuj*KLr=b}S35W@Kn>9$gazepH-|F70{tGpI{C zr~eoJZUw@;YNB%)XcO1k?L`S&b`YzaWpV`2*ltC`f^4;bK*K0u%MN1wQ9z(4(Xb%< zKY}>_r35lxgQCGGI(VVBYmmeQsmU&;$iLQvSlb5DFeFynZ!s4e#GQW4JHI7LVwE$Q-PgQJ0@BXzgPhM& zC9&Gx2f0KbUI(pi6rHcqC2`u`D7u6o9)QMo($0@nS-nu3JLynT1d#P#jgSwkHexOR zUk$5d{zjfl00030|7brdi~s-v{YgYYRPC9+N*zHI#?^=*xhR4tSQ#5*p$MWj3dsdi z7@L$A??a?Y9>Gei>}=BH0cHD zg7O}`g8vyFDgS~VmN6SD&$VJhWJJ@{;64=2Bu|I=rkPD(K@38yf5azuL4%UHA zkgB#WeU{$6r1?e66Yv6bqExk=(PzqGW*HIV6LCzyht+26Z%m=kLG*-D;^2Y#PV{YceuSZFaRm zJsRP818hb}o$WvT%_}L<*a4=Ao7x>J19~>VRrWGC}|OFA%Z|%WkAmcxIRY^ z=s-z}VB-K;A~83?F_1HoKz>Wzw2~|hw5MHzgbYEGe8q?}2m0U=Tqz)J zVl!7I6!pJ=?HZ%A*MG$_fuiq&NNNx0geeOqwtHofsB2^&6m=&}QZjwY0+>D@SBR8$ zC!LL=C}%Ml1s>w$A`Xot{G~mMmo%TMcAks3yy>1lgFQ4)dqbCi6t*I&7E{PxI7cw>c1M;`+T`nf{uLA6kOx~SEDMhO&tQs?pT$mYkkj# zL#u7a0@b{pCZ|{pwRSWkP|`)Z9a&qjK%gX_c?(MIGex96a9xng{Z8ALp(i86iFVZR zq}HD9h!p&=+MetJF+rs79#hR|a~Ozfb8fPcWOFtX+o5ZY=GZ5SOv2t*u8F8N8wR1A dFYQw>e*;tySCgKU@*MyG002ovPDHLkV1maZ0*n9v diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator7.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator7.imageset/Contents.json deleted file mode 100644 index 32b0924ad..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator7.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator7@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator7.imageset/LoadingIndicator7@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator7.imageset/LoadingIndicator7@2x.png deleted file mode 100644 index 8400bdadb8cdf86a8ce42d2b73b3b9869a5b9a5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1740 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 D-A@M( diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator9.imageset/Contents.json b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator9.imageset/Contents.json deleted file mode 100644 index b416407c2..000000000 --- a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator9.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LoadingIndicator9@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator9.imageset/LoadingIndicator9@2x.png b/loafwallet WatchKit App/LoadingIndicator.xcassets/LoadingIndicator9.imageset/LoadingIndicator9@2x.png deleted file mode 100644 index 6a014bc341d230dd2afa2d0ac8c365e49ea022ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1738 zcmV;*1~vJKP)Px#32;bRa{vGqB>(^xB>_oNB=7(L032yVPgDQ^00IC20000003-ka04M+e03-ka z03-ka1694&4)Xv210hL7K~#7F?3urA)i4ys+gl-2gep-4L+Q}o0U?BnS_J(wbm)e7 z1cZdxncxi=m>Jl31K1c4uod3x_IFUMCXQntC-I56Q0bGe9glbPoqVoCp z0%-et_7NL0%3Cl%94F#(zDWopb571@nGc{e`5IJm#0D)S<1(F zdz_%+Yk5ill98ImB{x>PUH;J;F(A&6m8(n89-dwB0XRWo?Pu)HqRFQQaj*kof`rBn zxo6Y&UHR!dA^Z0o2mGJH@e{;E35~txo|*42+2oZy$KWGZe7poX0;Fs|`Fb?^kjZi^6P`ACjopI=iPxz( zdmY+y??;eII%oVB{;qo=UUnJ01~f_M*c@CkjQfjNrIyJNKx4bx86{*J1q3?mBpf(E ztUn3}wBH#PWdGkFs_~dW=5tVIFp2>lsO=miF+pmwiYf9>nh>k)DpmZ~&iiFFIu?ZsSdkji!-r{1aCO0n74%{#v(TDXMo z9BAsCkWJoh-X#Iy4yY%t`5inDaz0D7#A$mTG2Xw<)dc_m0RR8R>b7_Q00SCHL_t*T znLTS2K@^4)qmcx`A^{sMB9cOF1*;g)Dj=o_DFT9!2q9{rU=d9Ift~mtZ2SXhY$dhj z#nwh7wkB+zgF7&HvwL>Fc6N&!c$vL3XU==hyR-9^sj10ddIgH2xD4jObb9Y;Jrd&# zxB=$UdbYfkBzGyFfj#i9#9PW8@C4kly7c-;EUVx%_zC`jvl724zk=srHc5~;S_a#| zh@zDn*exU>4sZguyu>451kuV7b{hdS|GUt68pxZ_1gUF#L!Udr#DN{*TnB%FCQ4n~ zNBUgyrlr$kP$z&(oqT#r-lTyY;93Lrr&K3|R`{58*;G%f(w z#9i&SBQ#LE66*-GCGFdOuaOk8n;i)Bx{)xlfmlyE5a>~3SddLdP*JEODEl15OPK{L zK+bggCFEJ^)bkSUdFLP*T99U0#o$>4hu|3eXn?ed&0^iKr~U)*onth6eHAMO>U|Xm!&+#=rMwduM1lM>SWSB0@_Mt+D6!g-zXY^q{NY2d<%KdoizPqPh*lxRj$}E z+Rt#Uf;@N9HnDkz-0Qy@*vG6~O@dxn(M)`H33vDZ)vyUeo(WQR$W4ic*6)YJGRQs? zfm&V*0`>NZwS+c|W(3MQNe?4yk0=l*%QEi~((p_XDdk4-V0aluMub3}9W^3D8%}pb zN`6=!PIieRL8O-;bnoM|IZPC4e{RZ= g*-Uy}+UJP;93#C}M|+&CZU6uP07*qoM6N<$g2=-p`v3p{ diff --git a/loafwallet WatchKit App/da.lproj/Interface.strings b/loafwallet WatchKit App/da.lproj/Interface.strings deleted file mode 100644 index 69a615cca..000000000 --- a/loafwallet WatchKit App/da.lproj/Interface.strings +++ /dev/null @@ -1,21 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "받다"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "균형"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "받다"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "월렛 라벨 없음"; diff --git a/loafwallet WatchKit App/de.lproj/Interface.strings b/loafwallet WatchKit App/de.lproj/Interface.strings deleted file mode 100644 index 981fe3678..000000000 --- a/loafwallet WatchKit App/de.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Erhalten"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balance"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Benachrichtigungsetikett"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "Kein Brieftaschenetikett"; diff --git a/loafwallet WatchKit App/en.lproj/Interface.strings b/loafwallet WatchKit App/en.lproj/Interface.strings deleted file mode 100644 index ca3cdd306..000000000 --- a/loafwallet WatchKit App/en.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Receive"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balance"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "NoWallet Label"; diff --git a/loafwallet WatchKit App/es.lproj/Interface.strings b/loafwallet WatchKit App/es.lproj/Interface.strings deleted file mode 100644 index ac115f15d..000000000 --- a/loafwallet WatchKit App/es.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Recibir"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Equilibrar"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "Sin etiqueta de billetera"; diff --git a/loafwallet WatchKit App/fr.lproj/Interface.strings b/loafwallet WatchKit App/fr.lproj/Interface.strings deleted file mode 100644 index 9ab511249..000000000 --- a/loafwallet WatchKit App/fr.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Recevoir"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Équilibre"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Étiquette Álerte"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "Aucune étiquette de portefeuille"; diff --git a/loafwallet WatchKit App/id.lproj/Interface.strings b/loafwallet WatchKit App/id.lproj/Interface.strings deleted file mode 100644 index ca3cdd306..000000000 --- a/loafwallet WatchKit App/id.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Receive"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balance"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "NoWallet Label"; diff --git a/loafwallet WatchKit App/it.lproj/Interface.strings b/loafwallet WatchKit App/it.lproj/Interface.strings deleted file mode 100644 index bedc60681..000000000 --- a/loafwallet WatchKit App/it.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Ricevere"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Equilibrio"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "Nessuna etichetta del portafoglio"; diff --git a/loafwallet WatchKit App/ja.lproj/Interface.strings b/loafwallet WatchKit App/ja.lproj/Interface.strings deleted file mode 100644 index d7d05daa2..000000000 --- a/loafwallet WatchKit App/ja.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "受け取る"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "残高"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "ウォレットラベルなし"; diff --git a/loafwallet WatchKit App/ko.lproj/Interface.strings b/loafwallet WatchKit App/ko.lproj/Interface.strings deleted file mode 100644 index d9dc3c998..000000000 --- a/loafwallet WatchKit App/ko.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "받다"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "균형"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "경고 라벨"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "월렛 라벨 없음"; diff --git a/loafwallet WatchKit App/nl.lproj/Interface.strings b/loafwallet WatchKit App/nl.lproj/Interface.strings deleted file mode 100644 index 3510f8d16..000000000 --- a/loafwallet WatchKit App/nl.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Te ontvangen"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balans"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Waarschuwingslabel"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "Geen portemonnee-label"; diff --git a/loafwallet WatchKit App/pt.lproj/Interface.strings b/loafwallet WatchKit App/pt.lproj/Interface.strings deleted file mode 100644 index ca3cdd306..000000000 --- a/loafwallet WatchKit App/pt.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Receive"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balance"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "NoWallet Label"; diff --git a/loafwallet WatchKit App/ru.lproj/Interface.strings b/loafwallet WatchKit App/ru.lproj/Interface.strings deleted file mode 100644 index 0bd432fbd..000000000 --- a/loafwallet WatchKit App/ru.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Получать"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Баланс"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Оповещение Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "Нет бумажник"; diff --git a/loafwallet WatchKit App/sv.lproj/Interface.strings b/loafwallet WatchKit App/sv.lproj/Interface.strings deleted file mode 100644 index 96678cafb..000000000 --- a/loafwallet WatchKit App/sv.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "skicka"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balans"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "Ingen plånboksetikett"; diff --git a/loafwallet WatchKit App/zh-Hans.lproj/Interface.strings b/loafwallet WatchKit App/zh-Hans.lproj/Interface.strings deleted file mode 100644 index a606d72ee..000000000 --- a/loafwallet WatchKit App/zh-Hans.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "接收"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "平衡"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "警报标签"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "没有钱包标签"; diff --git a/loafwallet WatchKit App/zh-Hant.lproj/Interface.strings b/loafwallet WatchKit App/zh-Hant.lproj/Interface.strings deleted file mode 100644 index ca3cdd306..000000000 --- a/loafwallet WatchKit App/zh-Hant.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Receive"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balance"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "NoWallet Label"; diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json deleted file mode 100644 index aefef2914..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : "<=145" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">161" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">145" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">183" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Contents.json deleted file mode 100644 index 1571c7e53..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Contents.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "assets" : [ - { - "idiom" : "watch", - "filename" : "Circular.imageset", - "role" : "circular" - }, - { - "idiom" : "watch", - "filename" : "Extra Large.imageset", - "role" : "extra-large" - }, - { - "idiom" : "watch", - "filename" : "Graphic Bezel.imageset", - "role" : "graphic-bezel" - }, - { - "idiom" : "watch", - "filename" : "Graphic Circular.imageset", - "role" : "graphic-circular" - }, - { - "idiom" : "watch", - "filename" : "Graphic Corner.imageset", - "role" : "graphic-corner" - }, - { - "idiom" : "watch", - "filename" : "Graphic Large Rectangular.imageset", - "role" : "graphic-large-rectangular" - }, - { - "idiom" : "watch", - "filename" : "Modular.imageset", - "role" : "modular" - }, - { - "idiom" : "watch", - "filename" : "Utilitarian.imageset", - "role" : "utilitarian" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json deleted file mode 100644 index e011e3271..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json deleted file mode 100644 index e011e3271..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json deleted file mode 100644 index e011e3271..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json deleted file mode 100644 index e011e3271..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json deleted file mode 100644 index e011e3271..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json deleted file mode 100644 index aefef2914..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : "<=145" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">161" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">145" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">183" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json b/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json deleted file mode 100644 index aefef2914..000000000 --- a/loafwallet WatchKit Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : "<=145" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">161" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">145" - }, - { - "idiom" : "watch", - "scale" : "2x", - "screen-width" : ">183" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/loafwallet WatchKit Extension/BRAWWeakTimerTarget.swift b/loafwallet WatchKit Extension/BRAWWeakTimerTarget.swift deleted file mode 100644 index 7906a1b80..000000000 --- a/loafwallet WatchKit Extension/BRAWWeakTimerTarget.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// BRAWWeakTimerTarget.swift -// BreadWallet -// -// Created by Henry on 10/27/15. -// Copyright (c) 2015 Aaron Voisine -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import WatchKit - -class BRAWWeakTimerTarget: NSObject { - weak var target : AnyObject? = nil - var selector : Selector? = nil - - init(initTarget: AnyObject , initSelector : Selector) { - super.init() - target = initTarget - selector = initSelector - } - - @objc func timerDidFire() { - if target != nil && selector != nil && target!.responds(to: selector!) { - _ = target!.perform(selector!) - } - } -} diff --git a/loafwallet WatchKit Extension/BalanceInterfaceController.swift b/loafwallet WatchKit Extension/BalanceInterfaceController.swift deleted file mode 100644 index 187b84360..000000000 --- a/loafwallet WatchKit Extension/BalanceInterfaceController.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// InterfaceController.swift -// breadwallet WatchKit Extension -// -// Created by ajv on 10/5/16. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import WatchKit -import Foundation - - -class BalanceInterfaceController: WKInterfaceController { - - @IBOutlet var bitsBalance: WKInterfaceLabel! - @IBOutlet var localBalance: WKInterfaceLabel! - @IBOutlet var noWallet: WKInterfaceLabel! - @IBOutlet var loadingIndicator: WKInterfaceImage! - - override func awake(withContext context: Any?) { - super.awake(withContext: context) - } - - override func willActivate() { - // This method is called when watch view controller is about to be visible to user - super.willActivate() - - NotificationCenter.default.addObserver(self, selector: #selector(BalanceInterfaceController.runUpdate), name: .ApplicationDataDidUpdateNotification, object: nil) - - runUpdate() - } - - @objc func runUpdate() { - if let data = WatchDataManager.shared.data { - loadingIndicator.setHidden(true) - - if data.hasWallet { - bitsBalance.setText(data.balance) - localBalance.setText(data.localBalance) - noWallet.setText("") - } else { - noWallet.setText(S.Watch.noWalletWarning) - bitsBalance.setText("") - localBalance.setText("") - } - } else { - bitsBalance.setText("") - localBalance.setText("") - noWallet.setText("") - } - } - - - override func didDeactivate() { - // This method is called when watch view controller is no longer visible - super.didDeactivate() - } - -} diff --git a/loafwallet WatchKit Extension/ComplicationController.swift b/loafwallet WatchKit Extension/ComplicationController.swift deleted file mode 100644 index e12976130..000000000 --- a/loafwallet WatchKit Extension/ComplicationController.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// ComplicationController.swift -// breadwallet WatchKit Extension -// -// Created by ajv on 10/5/16. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import ClockKit - - -class ComplicationController: NSObject, CLKComplicationDataSource { - - // MARK: - Timeline Configuration - - func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) { - handler([.forward, .backward]) - } - - func getTimelineStartDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) { - handler(nil) - } - - func getTimelineEndDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) { - handler(nil) - } - - func getPrivacyBehavior(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationPrivacyBehavior) -> Void) { - handler(.showOnLockScreen) - } - - // MARK: - Timeline Population - - func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) { - // Call the handler with the current timeline entry - handler(nil) - } - - func getTimelineEntries(for complication: CLKComplication, before date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) { - // Call the handler with the timeline entries prior to the given date - handler(nil) - } - - func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) { - // Call the handler with the timeline entries after to the given date - handler(nil) - } - - // MARK: - Placeholder Templates - - func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) { - // This method will be called once per supported complication, and the results will be cached - handler(nil) - } - -} diff --git a/loafwallet WatchKit Extension/ExtensionDelegate.swift b/loafwallet WatchKit Extension/ExtensionDelegate.swift deleted file mode 100644 index a26109a1c..000000000 --- a/loafwallet WatchKit Extension/ExtensionDelegate.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// ExtensionDelegate.swift -// breadwallet WatchKit Extension -// -// Created by ajv on 10/5/16. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import WatchKit - -class ExtensionDelegate: NSObject, WKExtensionDelegate { - - func applicationDidFinishLaunching() { - // Perform any final initialization of your application. - } - - func applicationDidBecomeActive() { - WatchDataManager.shared.setupTimer() - WatchDataManager.shared.requestAllData() - } - - func applicationWillResignActive() { - WatchDataManager.shared.destroyTimer() - } -} diff --git a/loafwallet WatchKit Extension/Info.plist b/loafwallet WatchKit Extension/Info.plist deleted file mode 100644 index fd96f74d8..000000000 --- a/loafwallet WatchKit Extension/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - $(PRODUCT_NAME) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - CLKComplicationPrincipalClass - $(PRODUCT_MODULE_NAME).ComplicationController - CLKComplicationSupportedFamilies - - CLKComplicationFamilyModularSmall - CLKComplicationFamilyModularLarge - CLKComplicationFamilyUtilitarianSmall - CLKComplicationFamilyUtilitarianSmallFlat - CLKComplicationFamilyUtilitarianLarge - CLKComplicationFamilyCircularSmall - CLKComplicationFamilyExtraLarge - - NSExtension - - NSExtensionAttributes - - WKAppBundleIdentifier - com.litecoin.loafwallet.watchkitapp - - NSExtensionPointIdentifier - com.apple.watchkit - - WKExtensionDelegateClassName - $(PRODUCT_MODULE_NAME).ExtensionDelegate - - diff --git a/loafwallet WatchKit Extension/NotificationController.swift b/loafwallet WatchKit Extension/NotificationController.swift deleted file mode 100644 index 1ca1fc3d9..000000000 --- a/loafwallet WatchKit Extension/NotificationController.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// NotificationController.swift -// breadwallet WatchKit Extension -// -// Created by ajv on 10/5/16. -// Copyright © 2016 breadwallet LLC. All rights reserved. -// - -import WatchKit -import Foundation -import UserNotifications - - -class NotificationController: WKUserNotificationInterfaceController { - - override init() { - // Initialize variables here. - super.init() - - // Configure interface objects here. - } - - override func willActivate() { - // This method is called when watch view controller is about to be visible to user - super.willActivate() - } - - override func didDeactivate() { - // This method is called when watch view controller is no longer visible - super.didDeactivate() - } - - /* - override func didReceive(_ notification: UNNotification, withCompletion completionHandler: @escaping (WKUserNotificationInterfaceType) -> Swift.Void) { - // This method is called when a notification needs to be presented. - // Implement it if you use a dynamic notification interface. - // Populate your dynamic notification interface as quickly as possible. - // - // After populating your dynamic notification interface call the completion block. - completionHandler(.custom) - } - */ -} diff --git a/loafwallet WatchKit Extension/PushNotificationPayload.apns b/loafwallet WatchKit Extension/PushNotificationPayload.apns deleted file mode 100644 index e793a02b3..000000000 --- a/loafwallet WatchKit Extension/PushNotificationPayload.apns +++ /dev/null @@ -1,18 +0,0 @@ -{ - "aps": { - "alert": { - "body": "Test message", - "title": "Optional title" - }, - "category": "myCategory" - }, - - "WatchKit Simulator Actions": [ - { - "title": "First Button", - "identifier": "firstButtonAction" - } - ], - - "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." -} diff --git a/loafwallet WatchKit Extension/ReceiveInterfaceController.swift b/loafwallet WatchKit Extension/ReceiveInterfaceController.swift deleted file mode 100644 index 9bd377701..000000000 --- a/loafwallet WatchKit Extension/ReceiveInterfaceController.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// ReceiveInterfaceController.swift -// breadwallet -// -// Created by Adrian Corscadden on 2017-04-27. -// Copyright © 2017 breadwallet LLC. All rights reserved. -// - -import WatchKit -import UIKit -class ReceiveInterfaceController : WKInterfaceController { - - @IBOutlet var image: WKInterfaceImage! - @IBOutlet var label: WKInterfaceLabel! - - override func willActivate() { - // This method is called when watch view controller is about to be visible to user - super.willActivate() - - NotificationCenter.default.addObserver(self, selector: #selector(ReceiveInterfaceController.runUpdate), name: .ApplicationDataDidUpdateNotification, object: nil) - runUpdate() - } - - @objc func runUpdate() { - guard let data = WatchDataManager.shared.data else { return } - image.setImage(data.qrCode) - } -} diff --git a/loafwallet WatchKit Extension/SharedConstants.swift b/loafwallet WatchKit Extension/SharedConstants.swift deleted file mode 100644 index 1d4fbf84a..000000000 --- a/loafwallet WatchKit Extension/SharedConstants.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// SharedConstants.swift -// breadwallet -// -// Created by Adrian Corscadden on 2017-04-27. -// Copyright © 2017 breadwallet LLC. All rights reserved. -// - -import Foundation - -let AW_SESSION_RESPONSE_KEY = "AW_SESSION_RESPONSE_KEY" -let AW_SESSION_REQUEST_TYPE = "AW_SESSION_REQUEST_TYPE" -let AW_SESSION_QR_CODE_BITS_KEY = "AW_QR_CODE_BITS_KEY" - -let AW_SESSION_REQUEST_DATA_TYPE_KEY = "AW_SESSION_REQUEST_DATA_TYPE_KEY" - -let AW_APPLICATION_CONTEXT_KEY = "AW_APPLICATION_CONTEXT_KEY" -let AW_QR_CODE_BITS_KEY = "AW_QR_CODE_BITS_KEY" - -let AW_PHONE_NOTIFICATION_KEY = "AW_PHONE_NOTIFICATION_KEY" -let AW_PHONE_NOTIFICATION_TYPE_KEY = "AW_PHONE_NOTIFICATION_TYPE_KEY" - -enum AWSessionRequestDataType : Int { - case applicationContextData = 0 - case qrCodeBits -} - -enum AWSessionRequestType : Int { - case dataUpdateNotification = 0 - case fetchData - case qRCodeBits - case didWipe -} diff --git a/loafwallet WatchKit Extension/WatchDataManager.swift b/loafwallet WatchKit Extension/WatchDataManager.swift deleted file mode 100644 index 16310a6c2..000000000 --- a/loafwallet WatchKit Extension/WatchDataManager.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// WatchDataManager.swift -// breadwallet -// -// Created by Adrian Corscadden on 2017-04-27. -// Copyright © 2017 breadwallet LLC. All rights reserved. -// - -import WatchKit -import WatchConnectivity - -enum WalletStatus { - case unknown - case hasSetup - case notSetup -} - -extension Notification.Name { - static let ApplicationDataDidUpdateNotification = NSNotification.Name("ApplicationDataDidUpdateNotification") - static let WalletStatusDidChangeNotification = NSNotification.Name("WalletStatusDidChangeNotification") - static let WalletTxReceiveNotification = NSNotification.Name("WalletTxReceiveNotification") -} - -class WatchDataManager : NSObject { - - static let applicationContextDataFileName = "applicationContextDataV2.txt" - - let session = WCSession.default - var data: WatchData? - let timerFireInterval : TimeInterval = 1.0 - - var timer : Timer? - var walletStatus: WalletStatus { - guard let data = data else { return .unknown } - return data.hasWallet ? .hasSetup : .notSetup - } - - static let shared = WatchDataManager() - - private override init() { - super.init() - if data == nil { - unarchiveData() - } - session.delegate = self - session.activate() - } - - func setupTimer() { - destroyTimer() - let weakTimerTarget = BRAWWeakTimerTarget(initTarget: self, - initSelector: #selector(WatchDataManager.requestAllData)) - timer = Timer.scheduledTimer(timeInterval: timerFireInterval, target: weakTimerTarget, - selector: #selector(BRAWWeakTimerTarget.timerDidFire), - userInfo: nil, repeats: true) - } - - func destroyTimer() { - if let currentTimer : Timer = timer { - currentTimer.invalidate(); - timer = nil - } - } - - @objc func requestAllData() { - guard session.isReachable else { return } - - let message = [ - AW_SESSION_REQUEST_TYPE: AWSessionRequestType.fetchData.rawValue, - AW_SESSION_REQUEST_DATA_TYPE_KEY: AWSessionRequestDataType.applicationContextData.rawValue - ] - - session.sendMessage(message, replyHandler: { replyMessage in - if let data = replyMessage[AW_SESSION_RESPONSE_KEY] as? [String: Any] { - if let newData = WatchData(data: data) { - let previousAppleWatchData = self.data - let previousWalletStatus = self.walletStatus - self.data = newData - if previousAppleWatchData != self.data { - self.archiveData(newData) - NotificationCenter.default.post( - name: .ApplicationDataDidUpdateNotification, object: nil) - } - if self.walletStatus != previousWalletStatus { - NotificationCenter.default.post( - name: .WalletStatusDidChangeNotification, object: nil) - } - } - } - }, errorHandler: { error in - print("request all data error: \(error)") - }) - } - - func archiveData(_ appleWatchData: WatchData){ - NSKeyedArchiver.archiveRootObject(appleWatchData.toDictionary, toFile: dataFilePath.path) - } - - func unarchiveData() { - guard let newData = try? Data(contentsOf: dataFilePath) else { return } - guard let dictionary = NSKeyedUnarchiver.unarchiveObject(with: newData) as? [String: Any] else { return } - guard let watchData = WatchData(data: dictionary) else { return } - NotificationCenter.default.post( - name: .ApplicationDataDidUpdateNotification, object: nil) - self.data = watchData - } - - lazy var dataFilePath: URL = { - let filemgr = FileManager.default - let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) - let docsDir = dirPaths[0] as String - return URL(fileURLWithPath: docsDir).appendingPathComponent(WatchDataManager.applicationContextDataFileName) - }() - -} - -extension WatchDataManager : WCSessionDelegate { - - func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { - print("activation did complete") - requestAllData() - } - - func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) { - print("did receive application context: \(applicationContext)") - } - - func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) { - guard let response = message[AW_SESSION_RESPONSE_KEY] as? String else { return } - if response == "didWipe" { - try? FileManager.default.removeItem(at: dataFilePath) - NotificationCenter.default.post( - name: .ApplicationDataDidUpdateNotification, object: nil) - } - } -} diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 1481919af..4165c9f0d 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 1A6E7857B45EB99B94C7D011 /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B25BB297DA3149E915668DC /* 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 */; }; @@ -88,7 +87,6 @@ 24313CA723824F5800A83F69 /* Spend.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313C9923824F5800A83F69 /* Spend.storyboard */; }; 24313CAA23824F9800A83F69 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24313CA823824F9800A83F69 /* Main.storyboard */; }; 24393B5C23C259400075218D /* Phrase.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24393B5B23C259400075218D /* Phrase.storyboard */; }; - 24470E1F23A5D83500ADDA27 /* MainNavigationVIewUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E1E23A5D83500ADDA27 /* MainNavigationVIewUITests.swift */; }; 24470E2123A5DA9700ADDA27 /* APIManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2023A5DA9700ADDA27 /* APIManagerTests.swift */; }; 24470E2323A5DB7D00ADDA27 /* WalletManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2223A5DB7D00ADDA27 /* WalletManagerTests.swift */; }; 24470E2523A5EF0D00ADDA27 /* BRAPIClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E2423A5EF0D00ADDA27 /* BRAPIClientTests.swift */; }; @@ -107,7 +105,6 @@ 24470E4223A6007200ADDA27 /* WalletInfoTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E4123A6007200ADDA27 /* WalletInfoTest.swift */; }; 24470E4523A608A700ADDA27 /* AmountTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E4423A608A700ADDA27 /* AmountTests.swift */; }; 24470E4723A6B6E900ADDA27 /* MockSeeds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24470E4623A6B6E900ADDA27 /* MockSeeds.swift */; }; - 2465872923A5AAC200A32E9E /* loafwalletUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2465872823A5AAC200A32E9E /* loafwalletUITests.swift */; }; 2465873923A5AAD100A32E9E /* loafwalletTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2465873823A5AAD100A32E9E /* loafwalletTests.swift */; }; 24670EAE2368EDE7006093E0 /* LFColorPalette.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 24670EAC2368EDE7006093E0 /* LFColorPalette.xcassets */; }; 2485F7D023728C19005962F1 /* RELEASE_NOTES.md in Resources */ = {isa = PBXBuildFile; fileRef = 2485F7CE23728C19005962F1 /* RELEASE_NOTES.md */; }; @@ -131,21 +128,15 @@ 24B8FADF2163C4D400A155B1 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B8FADE2163C4D400A155B1 /* Currency.swift */; }; 24BA90C62410129E001E3825 /* FeeSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24BA90C52410129E001E3825 /* FeeSelectorView.swift */; }; 24D5F23822599C0B00225462 /* BarlowSemiCondensed-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F22522599C0900225462 /* BarlowSemiCondensed-Italic.ttf */; }; - 24D5F23922599C0B00225462 /* BarlowSemiCondensed-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F22522599C0900225462 /* BarlowSemiCondensed-Italic.ttf */; }; 24D5F23B22599C0B00225462 /* BarlowSemiCondensed-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F22622599C0A00225462 /* BarlowSemiCondensed-Bold.ttf */; }; - 24D5F23C22599C0B00225462 /* BarlowSemiCondensed-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F22622599C0A00225462 /* BarlowSemiCondensed-Bold.ttf */; }; 24D5F25022599C0B00225462 /* BarlowSemiCondensed-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F22D22599C0A00225462 /* BarlowSemiCondensed-Light.ttf */; }; - 24D5F25122599C0B00225462 /* BarlowSemiCondensed-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F22D22599C0A00225462 /* BarlowSemiCondensed-Light.ttf */; }; 24D5F25922599C0B00225462 /* BarlowSemiCondensed-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F23022599C0B00225462 /* BarlowSemiCondensed-Medium.ttf */; }; - 24D5F25A22599C0B00225462 /* BarlowSemiCondensed-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F23022599C0B00225462 /* BarlowSemiCondensed-Medium.ttf */; }; 24D5F25F22599C0B00225462 /* BarlowSemiCondensed-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F23222599C0B00225462 /* BarlowSemiCondensed-Regular.ttf */; }; - 24D5F26022599C0B00225462 /* BarlowSemiCondensed-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F23222599C0B00225462 /* BarlowSemiCondensed-Regular.ttf */; }; 24D5F26522599C0B00225462 /* BarlowSemiCondensed-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F23422599C0B00225462 /* BarlowSemiCondensed-SemiBold.ttf */; }; - 24D5F26622599C0B00225462 /* BarlowSemiCondensed-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 24D5F23422599C0B00225462 /* BarlowSemiCondensed-SemiBold.ttf */; }; 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 */; }; - 3E5D426C13A8F4B4B8DA5AF3 /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEB7C06FE9706FC71D63B8B5 /* Pods_loafwalletTests.framework */; }; + 35263D49B92F5A97F6D39C3F /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D0C100AED9E17445EEBE5D7 /* Pods_loafwalletTests.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 */; }; @@ -276,21 +267,11 @@ 75A2A7941DA5934300A983D8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2A7931DA5934300A983D8 /* AppDelegate.swift */; }; 75A2A79B1DA5934300A983D8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75A2A79A1DA5934300A983D8 /* Assets.xcassets */; }; 75A2A79E1DA5934300A983D8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75A2A79C1DA5934300A983D8 /* LaunchScreen.storyboard */; }; - 75A2A7B91DA5934300A983D8 /* loafwallet WatchKit App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 75A2A7B81DA5934300A983D8 /* loafwallet WatchKit App.app */; }; - 75A2A7BF1DA5934300A983D8 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75A2A7BD1DA5934300A983D8 /* Interface.storyboard */; }; - 75A2A7C11DA5934300A983D8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75A2A7C01DA5934300A983D8 /* Assets.xcassets */; }; - 75A2A7C81DA5934300A983D8 /* Litewallet.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 75A2A7C71DA5934300A983D8 /* Litewallet.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 75A2A7CF1DA5934300A983D8 /* BalanceInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2A7CE1DA5934300A983D8 /* BalanceInterfaceController.swift */; }; - 75A2A7D11DA5934300A983D8 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2A7D01DA5934300A983D8 /* ExtensionDelegate.swift */; }; - 75A2A7D31DA5934300A983D8 /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2A7D21DA5934300A983D8 /* NotificationController.swift */; }; - 75A2A7D51DA5934300A983D8 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2A7D41DA5934300A983D8 /* ComplicationController.swift */; }; - 75A2A7D71DA5934400A983D8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75A2A7D61DA5934300A983D8 /* Assets.xcassets */; }; 75A2A80A1DA5936F00A983D8 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */; }; 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, ); }; }; - 75A2A81F1DA5938500A983D8 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A2A81E1DA5938500A983D8 /* NotificationService.swift */; }; - 75A2A8231DA5938500A983D8 /* Litewallet.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 75A2A81C1DA5938500A983D8 /* Litewallet.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 75C735AA1DAA1B9C00251ECF /* libunbound.c in Sources */ = {isa = PBXBuildFile; fileRef = 755CD4121DAA0E3E0075898E /* libunbound.c */; }; + 9565EF20DD221C9D2F2A6AEB /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D3369965438F85DF214DE3F /* Pods_loafwallet.framework */; }; CE03EC741EF256AC0038E3A8 /* SimpleUTXO.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */; }; CE0CD1591DBFBCF5004023DA /* ModalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0CD1581DBFBCF5004023DA /* ModalPresenter.swift */; }; CE124CF81E67A8E500DFA146 /* TransactionDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE124CF71E67A8E500DFA146 /* TransactionDirection.swift */; }; @@ -316,9 +297,6 @@ CE25BF931DFDA7A600BC67B6 /* MessageUIPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE25BF921DFDA7A500BC67B6 /* MessageUIPresenter.swift */; }; CE27F9591E2C8EA300F7F7F2 /* Amount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE27F9581E2C8EA300F7F7F2 /* Amount.swift */; }; CE29901A1EFD6DE50093A0F2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE29901C1EFD6DE50093A0F2 /* Localizable.strings */; }; - CE30F0E61EB27844004B8EE5 /* PhoneWCSessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE30F0E51EB27844004B8EE5 /* PhoneWCSessionManager.swift */; }; - CE30F0E81EB27FA2004B8EE5 /* WatchDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE30F0E71EB27FA2004B8EE5 /* WatchDataManager.swift */; }; - CE30F0EA1EB282C8004B8EE5 /* SharedConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE30F0E91EB282C8004B8EE5 /* SharedConstants.swift */; }; 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 */; }; @@ -412,13 +390,6 @@ CECCE5B01E04AD7600D99448 /* DescriptionSendCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECCE5AF1E04AD7600D99448 /* DescriptionSendCell.swift */; }; CECCE5B21E04B00D00D99448 /* SendCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECCE5B11E04B00D00D99448 /* SendCell.swift */; }; CED341331EF5A5C00014912A /* InAppAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED341321EF5A5C00014912A /* InAppAlert.swift */; }; - CED811AA1EB2B2D1003A8D1E /* SharedConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE30F0E91EB282C8004B8EE5 /* SharedConstants.swift */; }; - CED811AC1EB2BCDE003A8D1E /* BRAWWeakTimerTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED811AB1EB2BCDE003A8D1E /* BRAWWeakTimerTarget.swift */; }; - CED811E01EB302DA003A8D1E /* WatchData.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE30F0EB1EB28542004B8EE5 /* WatchData.swift */; }; - CED811E11EB302DA003A8D1E /* WatchData.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE30F0EB1EB28542004B8EE5 /* WatchData.swift */; }; - CED811E21EB302DD003A8D1E /* WatchTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED811A51EB29692003A8D1E /* WatchTransaction.swift */; }; - CED811E31EB302E2003A8D1E /* WatchTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED811A51EB29692003A8D1E /* WatchTransaction.swift */; }; - CED811E51EB30846003A8D1E /* ReceiveInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED811E41EB30846003A8D1E /* ReceiveInterfaceController.swift */; }; CED82D4E1E575A5500507A9B /* _main.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED82D4D1E575A5500507A9B /* _main.swift */; }; CEE0EF521EBD14B60018DB36 /* PinTransitioningDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE0EF511EBD14B60018DB36 /* PinTransitioningDelegate.swift */; }; CEE1F5631DF13E5A00D733AD /* ModalHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE1F5621DF13E5A00D733AD /* ModalHeaderView.swift */; }; @@ -427,7 +398,6 @@ CEE20C341EA5B4550086F724 /* ArticleIds.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE20C331EA5B4550086F724 /* ArticleIds.swift */; }; CEE20C361EA5B4620086F724 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE20C351EA5B4620086F724 /* Constants.swift */; }; CEE20C381EA5B4680086F724 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE20C371EA5B4680086F724 /* Strings.swift */; }; - CEE513EF1EB6A84800D6E4D7 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE20C371EA5B4680086F724 /* Strings.swift */; }; CEE6282A1EA98B6D001035AA /* DispatchQueue+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE628291EA98B6D001035AA /* DispatchQueue+Additions.swift */; }; CEE659E71F65A936001FF29D /* RetryTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE659E61F65A936001FF29D /* RetryTimer.swift */; }; CEE659E91F664C73001FF29D /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE659E81F664C73001FF29D /* WelcomeViewController.swift */; }; @@ -454,8 +424,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 */; }; - CEFFA2D11EB3BD730085C5D1 /* LoadingIndicator.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CEFFA2D01EB3BD730085C5D1 /* LoadingIndicator.xcassets */; }; - F1701455AFB761EFE79BD928 /* Pods_loafwalletUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB6CD1E69EF1F6545C78C3C9 /* Pods_loafwalletUITests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -466,13 +434,6 @@ remoteGlobalIDString = 22A9A9951DF63426000F0016; remoteInfo = libbz2; }; - 2465872B23A5AAC200A32E9E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 75A2A7881DA5934300A983D8 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 75A2A78F1DA5934300A983D8; - remoteInfo = loafwallet; - }; 2465873B23A5AAD100A32E9E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 75A2A7881DA5934300A983D8 /* Project object */; @@ -515,20 +476,6 @@ remoteGlobalIDString = 759DA0D71DAC8668008CC49B; remoteInfo = submodules; }; - 75A2A7BA1DA5934300A983D8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 75A2A7881DA5934300A983D8 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 75A2A7B71DA5934300A983D8; - remoteInfo = "breadwallet WatchKit App"; - }; - 75A2A7C91DA5934300A983D8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 75A2A7881DA5934300A983D8 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 75A2A7C61DA5934300A983D8; - remoteInfo = "breadwallet WatchKit Extension"; - }; 75A2A8121DA5936F00A983D8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 75A2A7881DA5934300A983D8 /* Project object */; @@ -536,13 +483,6 @@ remoteGlobalIDString = 75A2A8071DA5936F00A983D8; remoteInfo = TodayExtension; }; - 75A2A8211DA5938500A983D8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 75A2A7881DA5934300A983D8 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 75A2A81B1DA5938500A983D8; - remoteInfo = NotificationServiceExtension; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -576,24 +516,12 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75A2A7DE1DA5934400A983D8 /* Embed App Extensions */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 13; - files = ( - 75A2A7C81DA5934300A983D8 /* Litewallet.appex in Embed App Extensions */, - ); - name = "Embed App Extensions"; - runOnlyForDeploymentPostprocessing = 0; - }; 75A2A7E21DA5934400A983D8 /* Embed Watch Content */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; dstSubfolderSpec = 16; files = ( - 75A2A7B91DA5934300A983D8 /* loafwallet WatchKit App.app in Embed Watch Content */, ); name = "Embed Watch Content"; runOnlyForDeploymentPostprocessing = 0; @@ -605,7 +533,6 @@ dstSubfolderSpec = 13; files = ( 75A2A8141DA5936F00A983D8 /* TodayExtension.appex in Embed App Extensions */, - 75A2A8231DA5938500A983D8 /* Litewallet.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -619,23 +546,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - CED811DF1EB30124003A8D1E /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 037B5B94E7FA6FA20B088B06 /* Pods-loafwallet.development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.development.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.development.xcconfig"; sourceTree = ""; }; - 050C51BB8D4B5751D2FB72B0 /* Pods-loafwalletUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletUITests.debug.xcconfig"; path = "Target Support Files/Pods-loafwalletUITests/Pods-loafwalletUITests.debug.xcconfig"; sourceTree = ""; }; - 07CFF1E5499AF0D6C65E799E /* Pods-LitewalletUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletUITests.release.xcconfig"; path = "Target Support Files/Pods-LitewalletUITests/Pods-LitewalletUITests.release.xcconfig"; sourceTree = ""; }; - 18009E4E15F57315ECD92458 /* Pods-loafwalletUITests.testflight.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletUITests.testflight.xcconfig"; path = "Target Support Files/Pods-loafwalletUITests/Pods-loafwalletUITests.testflight.xcconfig"; sourceTree = ""; }; + 0B0BFC3BB4EF3438E0FD95C9 /* 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 = ""; }; + 17FB6C0C7A4EDEE276391D9A /* 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 = ""; }; 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 = ""; }; @@ -838,7 +753,6 @@ 24375315238AE09900E1B2AE /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = ru; path = ru.lproj/BIP39Words.plist; sourceTree = ""; }; 24375316238AE09D00E1B2AE /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = sv; path = sv.lproj/BIP39Words.plist; sourceTree = ""; }; 24393B5B23C259400075218D /* Phrase.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Phrase.storyboard; sourceTree = ""; }; - 24470E1E23A5D83500ADDA27 /* MainNavigationVIewUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainNavigationVIewUITests.swift; sourceTree = ""; }; 24470E2023A5DA9700ADDA27 /* APIManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIManagerTests.swift; sourceTree = ""; }; 24470E2223A5DB7D00ADDA27 /* WalletManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletManagerTests.swift; sourceTree = ""; }; 24470E2423A5EF0D00ADDA27 /* BRAPIClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAPIClientTests.swift; sourceTree = ""; }; @@ -863,9 +777,6 @@ 2464B6DD238A543D00B2A2CB /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = ko; path = ko.lproj/BIP39Words.plist; sourceTree = ""; }; 2464B6DF238A586600B2A2CB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = es; path = es.lproj/BIP39Words.plist; sourceTree = ""; }; 2464B6E0238A60F200B2A2CB /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = it; path = it.lproj/BIP39Words.plist; sourceTree = ""; }; - 2465872623A5AAC200A32E9E /* loafwalletUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = loafwalletUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 2465872823A5AAC200A32E9E /* loafwalletUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = loafwalletUITests.swift; sourceTree = ""; }; - 2465872A23A5AAC200A32E9E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2465873623A5AAD000A32E9E /* loafwalletTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = loafwalletTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 2465873823A5AAD100A32E9E /* loafwalletTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = loafwalletTests.swift; sourceTree = ""; }; 2465873A23A5AAD100A32E9E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -880,7 +791,6 @@ 2494038023AF208F00369261 /* PromptModalViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromptModalViewController.swift; sourceTree = ""; }; 249C570423B51F9B009CB5A9 /* TransactionsViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsViewControllerTests.swift; sourceTree = ""; }; 249F976D236F86240045087A /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/LaunchScreen.strings; sourceTree = ""; }; - 249F976E236F86240045087A /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Interface.strings; sourceTree = ""; }; 249F9770236F862C0045087A /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/MainInterface.strings; sourceTree = ""; }; 24A6DCFA2230BD9000505F44 /* WipeEmptyWalletViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WipeEmptyWalletViewController.swift; sourceTree = ""; }; 24AF00FC221B331D00FF636F /* WarningConfirmation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = WarningConfirmation.storyboard; sourceTree = ""; }; @@ -893,9 +803,6 @@ 24B8FAD62162B6FB00A155B1 /* bitrefill_index.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = bitrefill_index.html; sourceTree = ""; }; 24B8FADB2162D29100A155B1 /* general.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = general.css; sourceTree = ""; }; 24B8FADE2163C4D400A155B1 /* Currency.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Currency.swift; sourceTree = ""; }; - 24B9621123BA64C100ECD938 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Interface.strings"; sourceTree = ""; }; - 24B9621323BA64C600ECD938 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Interface.strings; sourceTree = ""; }; - 24B9621523BA64CC00ECD938 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Interface.strings; sourceTree = ""; }; 24B9621723BA66CC00ECD938 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/MainInterface.strings; sourceTree = ""; }; 24B9621923BA66CE00ECD938 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/MainInterface.strings"; sourceTree = ""; }; 24B9621B23BA66CF00ECD938 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainInterface.strings; sourceTree = ""; }; @@ -910,16 +817,8 @@ 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 = ""; }; - 2CF8845B661B040CA0780C35 /* Pods_LitewalletUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LitewalletUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 42C95DFC249600E4FF4BB7BF /* 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 = ""; }; - 43EB895625E57A3652F2CDA7 /* Pods-loafwallet.testflight.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet.testflight.xcconfig"; path = "Target Support Files/Pods-loafwallet/Pods-loafwallet.testflight.xcconfig"; sourceTree = ""; }; - 47D2FBAC934B8B5B2AEFC0BB /* Pods-loafwallet-dev.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet-dev.testnet.xcconfig"; path = "Target Support Files/Pods-loafwallet-dev/Pods-loafwallet-dev.testnet.xcconfig"; sourceTree = ""; }; - 4DC5D617E98657960E9975A7 /* Pods-LitewalletUITests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletUITests.testnet.xcconfig"; path = "Target Support Files/Pods-LitewalletUITests/Pods-LitewalletUITests.testnet.xcconfig"; sourceTree = ""; }; - 52396A247C4B92980F0685C3 /* 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 = ""; }; - 57558A313C770C44283A9493 /* Pods-loafwalletTests.testflight.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.testflight.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.testflight.xcconfig"; sourceTree = ""; }; - 5E94046EDE103D41CF80E921 /* Pods-LitewalletTests.testflight.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletTests.testflight.xcconfig"; path = "Target Support Files/Pods-LitewalletTests/Pods-LitewalletTests.testflight.xcconfig"; sourceTree = ""; }; - 6170C566EBF26391A2161873 /* Pods-loafwallet-dev.development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet-dev.development.xcconfig"; path = "Target Support Files/Pods-loafwallet-dev/Pods-loafwallet-dev.development.xcconfig"; sourceTree = ""; }; - 646DF58AAF164153D75531F9 /* Pods-loafwalletUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletUITests.release.xcconfig"; path = "Target Support Files/Pods-loafwalletUITests/Pods-loafwalletUITests.release.xcconfig"; sourceTree = ""; }; + 39A1C8DFFA128099F0556A0E /* 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 = ""; }; + 51D52F10840D223E083B6EDA /* 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 = ""; }; 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 = ""; }; @@ -1500,69 +1399,29 @@ 75A2A79A1DA5934300A983D8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 75A2A79D1DA5934300A983D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 75A2A79F1DA5934300A983D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 75A2A7B81DA5934300A983D8 /* loafwallet WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "loafwallet WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 75A2A7BE1DA5934300A983D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; - 75A2A7C01DA5934300A983D8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 75A2A7C21DA5934300A983D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 75A2A7C71DA5934300A983D8 /* Litewallet.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Litewallet.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 75A2A7CD1DA5934300A983D8 /* PushNotificationPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushNotificationPayload.apns; sourceTree = ""; }; - 75A2A7CE1DA5934300A983D8 /* BalanceInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceInterfaceController.swift; sourceTree = ""; }; - 75A2A7D01DA5934300A983D8 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; - 75A2A7D21DA5934300A983D8 /* NotificationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationController.swift; sourceTree = ""; }; - 75A2A7D41DA5934300A983D8 /* ComplicationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComplicationController.swift; sourceTree = ""; }; - 75A2A7D61DA5934300A983D8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 75A2A7D81DA5934400A983D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75A2A7F21DA5935F00A983D8 /* Messages.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Messages.framework; path = System/Library/Frameworks/Messages.framework; sourceTree = SDKROOT; }; 75A2A8081DA5936F00A983D8 /* TodayExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TodayExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; }; 75A2A80F1DA5936F00A983D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; 75A2A8111DA5936F00A983D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 75A2A81C1DA5938500A983D8 /* Litewallet.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Litewallet.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 75A2A81E1DA5938500A983D8 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; - 75A2A8201DA5938500A983D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 75A2A8291DA59B2A00A983D8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Interface.strings; sourceTree = ""; }; 75A2A82B1DA59B2A00A983D8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A82E1DA59B2F00A983D8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Interface.strings; sourceTree = ""; }; 75A2A8301DA59B2F00A983D8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A8331DA59B3600A983D8 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Interface.strings"; sourceTree = ""; }; 75A2A8351DA59B3600A983D8 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainInterface.strings"; sourceTree = ""; }; - 75A2A8381DA59B3C00A983D8 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Interface.strings; sourceTree = ""; }; 75A2A83A1DA59B3C00A983D8 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A83D1DA59B4500A983D8 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Interface.strings; sourceTree = ""; }; 75A2A83F1DA59B4500A983D8 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A8421DA59B4B00A983D8 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Interface.strings; sourceTree = ""; }; 75A2A8441DA59B4B00A983D8 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A8471DA59B5100A983D8 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Interface.strings; sourceTree = ""; }; 75A2A8491DA59B5100A983D8 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A84C1DA59B5700A983D8 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Interface.strings; sourceTree = ""; }; 75A2A84E1DA59B5700A983D8 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A8561DA59B6A00A983D8 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Interface.strings; sourceTree = ""; }; 75A2A8581DA59B6A00A983D8 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A8601DA59BF500A983D8 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Interface.strings; sourceTree = ""; }; 75A2A8621DA59BF500A983D8 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/MainInterface.strings; sourceTree = ""; }; - 75A2A8651DA59BFB00A983D8 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Interface.strings; sourceTree = ""; }; 75A2A8671DA59BFB00A983D8 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MainInterface.strings; sourceTree = ""; }; 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; }; + 75D0209A7B6BC4A864CC724C /* 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 = ""; }; 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; - 7A946F2FC1F9479341B7353F /* Pods-loafwallet-dev.testflight.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet-dev.testflight.xcconfig"; path = "Target Support Files/Pods-loafwallet-dev/Pods-loafwallet-dev.testflight.xcconfig"; sourceTree = ""; }; - 8146711587AD66F803519982 /* 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 = ""; }; - 8B25BB297DA3149E915668DC /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 8B95A1AEEE7D31D323D4DCB6 /* 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 = ""; }; - 8F3B4C567B5FC1A88DB07ECF /* Pods-LitewalletUITests.testflight.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletUITests.testflight.xcconfig"; path = "Target Support Files/Pods-LitewalletUITests/Pods-LitewalletUITests.testflight.xcconfig"; sourceTree = ""; }; - 94052F386F817420CBAEF937 /* 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 = ""; }; - 967F3BC33B298B55B0C419B7 /* 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 = ""; }; - 9804D4AB3F7690F799C687E6 /* Pods-LitewalletUITests.development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletUITests.development.xcconfig"; path = "Target Support Files/Pods-LitewalletUITests/Pods-LitewalletUITests.development.xcconfig"; sourceTree = ""; }; - 9BDD1CB7431513E8E83E1742 /* Pods_LitewalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LitewalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9C9C005127F822BDD8DABB09 /* Pods-loafwalletUITests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletUITests.testnet.xcconfig"; path = "Target Support Files/Pods-loafwalletUITests/Pods-loafwalletUITests.testnet.xcconfig"; sourceTree = ""; }; - 9DF539BAA03709F987DC829B /* Pods-LitewalletTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletTests.release.xcconfig"; path = "Target Support Files/Pods-LitewalletTests/Pods-LitewalletTests.release.xcconfig"; sourceTree = ""; }; - AB6CD1E69EF1F6545C78C3C9 /* Pods_loafwalletUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - AEB7C06FE9706FC71D63B8B5 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - AEECB9B894818001FF003D73 /* Pods_loafwallet_dev.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet_dev.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B3154DD8B91FCA9927766D10 /* Pods-loafwalletTests.development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletTests.development.xcconfig"; path = "Target Support Files/Pods-loafwalletTests/Pods-loafwalletTests.development.xcconfig"; sourceTree = ""; }; - B58732AF816C61D45E38854A /* Pods-LitewalletTests.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletTests.testnet.xcconfig"; path = "Target Support Files/Pods-LitewalletTests/Pods-LitewalletTests.testnet.xcconfig"; sourceTree = ""; }; - CA899DA394C8724FC0E64E02 /* Pods-loafwallet-dev.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwallet-dev.release.xcconfig"; path = "Target Support Files/Pods-loafwallet-dev/Pods-loafwallet-dev.release.xcconfig"; sourceTree = ""; }; - CBABF1A5804716F9AB38C7CA /* Pods-loafwalletUITests.development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-loafwalletUITests.development.xcconfig"; path = "Target Support Files/Pods-loafwalletUITests/Pods-loafwalletUITests.development.xcconfig"; sourceTree = ""; }; + 8D3369965438F85DF214DE3F /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9D0C100AED9E17445EEBE5D7 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9F2DD187A660718095013AA0 /* 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 = ""; }; CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SimpleUTXO.swift; path = src/Models/SimpleUTXO.swift; sourceTree = ""; }; CE0CD1581DBFBCF5004023DA /* ModalPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = ModalPresenter.swift; path = src/ModalPresenter.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; CE0FC0F81F72417200E7C626 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; @@ -1599,10 +1458,6 @@ CE2990211EFD6F4B0093A0F2 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = ""; }; 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 = ""; }; - CE30F0E51EB27844004B8EE5 /* PhoneWCSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = PhoneWCSessionManager.swift; path = src/Watch/PhoneWCSessionManager.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - CE30F0E71EB27FA2004B8EE5 /* WatchDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WatchDataManager.swift; sourceTree = ""; }; - CE30F0E91EB282C8004B8EE5 /* SharedConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharedConstants.swift; sourceTree = ""; }; - CE30F0EB1EB28542004B8EE5 /* WatchData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WatchData.swift; path = src/Watch/WatchData.swift; 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 = ""; }; @@ -1704,9 +1559,6 @@ CECCE5AF1E04AD7600D99448 /* DescriptionSendCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DescriptionSendCell.swift; path = src/Views/SendViewCells/DescriptionSendCell.swift; sourceTree = ""; }; CECCE5B11E04B00D00D99448 /* SendCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SendCell.swift; path = src/Views/SendViewCells/SendCell.swift; sourceTree = ""; }; CED341321EF5A5C00014912A /* InAppAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InAppAlert.swift; path = src/Views/InAppAlert.swift; sourceTree = ""; }; - CED811A51EB29692003A8D1E /* WatchTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WatchTransaction.swift; path = src/Watch/WatchTransaction.swift; sourceTree = ""; }; - CED811AB1EB2BCDE003A8D1E /* BRAWWeakTimerTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BRAWWeakTimerTarget.swift; sourceTree = ""; }; - CED811E41EB30846003A8D1E /* ReceiveInterfaceController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReceiveInterfaceController.swift; sourceTree = ""; }; CED82D4D1E575A5500507A9B /* _main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = _main.swift; path = src/_main.swift; sourceTree = ""; }; CEE0EF511EBD14B60018DB36 /* PinTransitioningDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PinTransitioningDelegate.swift; path = src/ViewControllers/ViewControllerTransitions/PinTransitioningDelegate.swift; sourceTree = ""; }; CEE1F5621DF13E5A00D733AD /* ModalHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ModalHeaderView.swift; path = src/Views/ModalHeaderView.swift; sourceTree = ""; }; @@ -1743,18 +1595,9 @@ 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 = ""; }; - CEFFA2D01EB3BD730085C5D1 /* LoadingIndicator.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = LoadingIndicator.xcassets; sourceTree = ""; }; - FD7E1C41A63010282BF4F536 /* Pods-LitewalletTests.development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LitewalletTests.development.xcconfig"; path = "Target Support Files/Pods-LitewalletTests/Pods-LitewalletTests.development.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 1B54211CD65F63604952C654 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 22A9A9921DF63426000F0016 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1763,19 +1606,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2465872323A5AAC200A32E9E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F1701455AFB761EFE79BD928 /* Pods_loafwalletUITests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 2465873323A5AAD000A32E9E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3E5D426C13A8F4B4B8DA5AF3 /* Pods_loafwalletTests.framework in Frameworks */, + 35263D49B92F5A97F6D39C3F /* Pods_loafwalletTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1814,14 +1649,7 @@ 223DB21B1DF69F0F0076A151 /* libbz2.framework in Frameworks */, 752FB04D1DF8BF4B009086FB /* sqlite3.framework in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, - 1A6E7857B45EB99B94C7D011 /* Pods_loafwallet.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 75A2A7C41DA5934300A983D8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( + 9565EF20DD221C9D2F2A6AEB /* Pods_loafwallet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1833,13 +1661,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75A2A8191DA5938500A983D8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 75C735AC1DAA1C9F00251ECF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2281,16 +2102,6 @@ path = "Class Tests"; sourceTree = ""; }; - 2465872723A5AAC200A32E9E /* loafwalletUITests */ = { - isa = PBXGroup; - children = ( - 2465872823A5AAC200A32E9E /* loafwalletUITests.swift */, - 24470E1E23A5D83500ADDA27 /* MainNavigationVIewUITests.swift */, - 2465872A23A5AAC200A32E9E /* Info.plist */, - ); - path = loafwalletUITests; - sourceTree = ""; - }; 2465873723A5AAD100A32E9E /* loafwalletTests */ = { isa = PBXGroup; children = ( @@ -3066,11 +2877,7 @@ children = ( 75A2A7921DA5934300A983D8 /* loafwallet */, 2465873723A5AAD100A32E9E /* loafwalletTests */, - 2465872723A5AAC200A32E9E /* loafwalletUITests */, - 75A2A7BC1DA5934300A983D8 /* loafwallet WatchKit App */, - 75A2A7CB1DA5934300A983D8 /* loafwallet WatchKit Extension */, 75A2A80B1DA5936F00A983D8 /* TodayExtension */, - 75A2A81D1DA5938500A983D8 /* NotificationServiceExtension */, 75B6F52F1DA71DCC0031A93F /* Modules */, 75A2A7F11DA5935F00A983D8 /* Frameworks */, 75A2A7911DA5934300A983D8 /* Products */, @@ -3082,16 +2889,12 @@ isa = PBXGroup; children = ( 75A2A7901DA5934300A983D8 /* Litewallet.app */, - 75A2A7B81DA5934300A983D8 /* loafwallet WatchKit App.app */, - 75A2A7C71DA5934300A983D8 /* Litewallet.appex */, 75A2A8081DA5936F00A983D8 /* TodayExtension.appex */, - 75A2A81C1DA5938500A983D8 /* Litewallet.appex */, 755CD9C41DAA18420075898E /* libunbound.a */, 755CD9D11DAA197C0075898E /* libBRCore.a */, 75C735AF1DAA1C9F00251ECF /* libnettle.a */, 22A9A9961DF63426000F0016 /* libbz2.framework */, 752FB04A1DF8BE6B009086FB /* sqlite3.framework */, - 2465872623A5AAC200A32E9E /* loafwalletUITests.xctest */, 2465873623A5AAD000A32E9E /* loafwalletTests.xctest */, ); name = Products; @@ -3123,7 +2926,6 @@ 24306795238F3DDF00EBEA99 /* BartyCrouch */, 24AF00FB221B32EC00FF636F /* Storyboards */, CE20C90A1DBC59C500C8397A /* FlowControllers */, - CE30F0E41EB27821004B8EE5 /* Watch */, CEE20C321EA5B2EC0086F724 /* Constants */, 2412367B24035B7F00FFA499 /* Emitters */, CE20C8EF1DBAF6D300C8397A /* ViewControllers */, @@ -3146,43 +2948,6 @@ path = loafwallet; sourceTree = ""; }; - 75A2A7BC1DA5934300A983D8 /* loafwallet WatchKit App */ = { - isa = PBXGroup; - children = ( - 75A2A7BD1DA5934300A983D8 /* Interface.storyboard */, - 75A2A7C01DA5934300A983D8 /* Assets.xcassets */, - 75A2A7C21DA5934300A983D8 /* Info.plist */, - CEFFA2D01EB3BD730085C5D1 /* LoadingIndicator.xcassets */, - ); - path = "loafwallet WatchKit App"; - sourceTree = ""; - }; - 75A2A7CB1DA5934300A983D8 /* loafwallet WatchKit Extension */ = { - isa = PBXGroup; - children = ( - 75A2A7D01DA5934300A983D8 /* ExtensionDelegate.swift */, - 75A2A7CE1DA5934300A983D8 /* BalanceInterfaceController.swift */, - 75A2A7D21DA5934300A983D8 /* NotificationController.swift */, - 75A2A7D41DA5934300A983D8 /* ComplicationController.swift */, - CED811E41EB30846003A8D1E /* ReceiveInterfaceController.swift */, - CE30F0E71EB27FA2004B8EE5 /* WatchDataManager.swift */, - CE30F0E91EB282C8004B8EE5 /* SharedConstants.swift */, - CED811AB1EB2BCDE003A8D1E /* BRAWWeakTimerTarget.swift */, - 75A2A7D61DA5934300A983D8 /* Assets.xcassets */, - 75A2A7D81DA5934400A983D8 /* Info.plist */, - 75A2A7CC1DA5934300A983D8 /* Supporting Files */, - ); - path = "loafwallet WatchKit Extension"; - sourceTree = ""; - }; - 75A2A7CC1DA5934300A983D8 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 75A2A7CD1DA5934300A983D8 /* PushNotificationPayload.apns */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; 75A2A7F11DA5935F00A983D8 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -3198,12 +2963,8 @@ 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */, 75A2A7F21DA5935F00A983D8 /* Messages.framework */, 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */, - 8B25BB297DA3149E915668DC /* Pods_loafwallet.framework */, - AEECB9B894818001FF003D73 /* Pods_loafwallet_dev.framework */, - AEB7C06FE9706FC71D63B8B5 /* Pods_loafwalletTests.framework */, - AB6CD1E69EF1F6545C78C3C9 /* Pods_loafwalletUITests.framework */, - 9BDD1CB7431513E8E83E1742 /* Pods_LitewalletTests.framework */, - 2CF8845B661B040CA0780C35 /* Pods_LitewalletUITests.framework */, + 8D3369965438F85DF214DE3F /* Pods_loafwallet.framework */, + 9D0C100AED9E17445EEBE5D7 /* Pods_loafwalletTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -3226,15 +2987,6 @@ path = TodayExtension; sourceTree = ""; }; - 75A2A81D1DA5938500A983D8 /* NotificationServiceExtension */ = { - isa = PBXGroup; - children = ( - 75A2A81E1DA5938500A983D8 /* NotificationService.swift */, - 75A2A8201DA5938500A983D8 /* Info.plist */, - ); - path = NotificationServiceExtension; - sourceTree = ""; - }; 75B6F52F1DA71DCC0031A93F /* Modules */ = { isa = PBXGroup; children = ( @@ -3425,16 +3177,6 @@ name = Strings; sourceTree = ""; }; - CE30F0E41EB27821004B8EE5 /* Watch */ = { - isa = PBXGroup; - children = ( - CE30F0EB1EB28542004B8EE5 /* WatchData.swift */, - CED811A51EB29692003A8D1E /* WatchTransaction.swift */, - CE30F0E51EB27844004B8EE5 /* PhoneWCSessionManager.swift */, - ); - name = Watch; - sourceTree = ""; - }; CE3645461E7B40280079D0CF /* PinPadCells */ = { isa = PBXGroup; children = ( @@ -3594,33 +3336,12 @@ FEE036865998B9DFEEF3139A /* Pods */ = { isa = PBXGroup; children = ( - 037B5B94E7FA6FA20B088B06 /* Pods-loafwallet.development.xcconfig */, - 52396A247C4B92980F0685C3 /* Pods-loafwallet.testnet.xcconfig */, - 42C95DFC249600E4FF4BB7BF /* Pods-loafwallet.release.xcconfig */, - 43EB895625E57A3652F2CDA7 /* Pods-loafwallet.testflight.xcconfig */, - 6170C566EBF26391A2161873 /* Pods-loafwallet-dev.development.xcconfig */, - 47D2FBAC934B8B5B2AEFC0BB /* Pods-loafwallet-dev.testnet.xcconfig */, - CA899DA394C8724FC0E64E02 /* Pods-loafwallet-dev.release.xcconfig */, - 7A946F2FC1F9479341B7353F /* Pods-loafwallet-dev.testflight.xcconfig */, - B3154DD8B91FCA9927766D10 /* Pods-loafwalletTests.development.xcconfig */, - 967F3BC33B298B55B0C419B7 /* Pods-loafwalletTests.testnet.xcconfig */, - 8146711587AD66F803519982 /* Pods-loafwalletTests.release.xcconfig */, - 57558A313C770C44283A9493 /* Pods-loafwalletTests.testflight.xcconfig */, - CBABF1A5804716F9AB38C7CA /* Pods-loafwalletUITests.development.xcconfig */, - 9C9C005127F822BDD8DABB09 /* Pods-loafwalletUITests.testnet.xcconfig */, - 646DF58AAF164153D75531F9 /* Pods-loafwalletUITests.release.xcconfig */, - 18009E4E15F57315ECD92458 /* Pods-loafwalletUITests.testflight.xcconfig */, - FD7E1C41A63010282BF4F536 /* Pods-LitewalletTests.development.xcconfig */, - B58732AF816C61D45E38854A /* Pods-LitewalletTests.testnet.xcconfig */, - 9DF539BAA03709F987DC829B /* Pods-LitewalletTests.release.xcconfig */, - 5E94046EDE103D41CF80E921 /* Pods-LitewalletTests.testflight.xcconfig */, - 9804D4AB3F7690F799C687E6 /* Pods-LitewalletUITests.development.xcconfig */, - 4DC5D617E98657960E9975A7 /* Pods-LitewalletUITests.testnet.xcconfig */, - 07CFF1E5499AF0D6C65E799E /* Pods-LitewalletUITests.release.xcconfig */, - 8F3B4C567B5FC1A88DB07ECF /* Pods-LitewalletUITests.testflight.xcconfig */, - 94052F386F817420CBAEF937 /* Pods-loafwallet.debug.xcconfig */, - 8B95A1AEEE7D31D323D4DCB6 /* Pods-loafwalletTests.debug.xcconfig */, - 050C51BB8D4B5751D2FB72B0 /* Pods-loafwalletUITests.debug.xcconfig */, + 39A1C8DFFA128099F0556A0E /* Pods-loafwallet.debug.xcconfig */, + 9F2DD187A660718095013AA0 /* Pods-loafwallet.testnet.xcconfig */, + 17FB6C0C7A4EDEE276391D9A /* Pods-loafwallet.release.xcconfig */, + 0B0BFC3BB4EF3438E0FD95C9 /* Pods-loafwalletTests.debug.xcconfig */, + 51D52F10840D223E083B6EDA /* Pods-loafwalletTests.testnet.xcconfig */, + 75D0209A7B6BC4A864CC724C /* Pods-loafwalletTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -3680,30 +3401,11 @@ productReference = 22A9A9961DF63426000F0016 /* libbz2.framework */; productType = "com.apple.product-type.framework"; }; - 2465872523A5AAC200A32E9E /* loafwalletUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2465872D23A5AAC200A32E9E /* Build configuration list for PBXNativeTarget "loafwalletUITests" */; - buildPhases = ( - 13AEC33C056F17F5D9122796 /* [CP] Check Pods Manifest.lock */, - 2465872223A5AAC200A32E9E /* Sources */, - 2465872323A5AAC200A32E9E /* Frameworks */, - 2465872423A5AAC200A32E9E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 2465872C23A5AAC200A32E9E /* PBXTargetDependency */, - ); - name = loafwalletUITests; - productName = loafwalletUITests; - productReference = 2465872623A5AAC200A32E9E /* loafwalletUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; 2465873523A5AAD000A32E9E /* loafwalletTests */ = { isa = PBXNativeTarget; buildConfigurationList = 2465873D23A5AAD100A32E9E /* Build configuration list for PBXNativeTarget "loafwalletTests" */; buildPhases = ( - E0229A38B86837D985A5CAC5 /* [CP] Check Pods Manifest.lock */, + 851EE9FAFF1CDBF8F4BAD5F4 /* [CP] Check Pods Manifest.lock */, 2465873223A5AAD000A32E9E /* Sources */, 2465873323A5AAD000A32E9E /* Frameworks */, 2465873423A5AAD000A32E9E /* Resources */, @@ -3776,7 +3478,7 @@ isa = PBXNativeTarget; buildConfigurationList = 75A2A7E31DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet" */; buildPhases = ( - 99019425211CCCB309C62207 /* [CP] Check Pods Manifest.lock */, + 4C256FDD5564B94BFF10BA73 /* [CP] Check Pods Manifest.lock */, 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */, 24E179F223BDAF8000F928D9 /* Xcode custom warnings */, 75A2A78C1DA5934300A983D8 /* Sources */, @@ -3786,16 +3488,14 @@ 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, CEE0EF531EBF8C8A0018DB36 /* Icon Versioning */, - 0EFAC3B5E78B08742F671320 /* [CP] Embed Pods Frameworks */, 24E179F123BDAC2C00F928D9 /* Swift Lint Script */, + 2190D297B82EA6160376EC4C /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( 759DA0BD1DAC369C008CC49B /* PBXTargetDependency */, - 75A2A7BB1DA5934300A983D8 /* PBXTargetDependency */, 75A2A8131DA5936F00A983D8 /* PBXTargetDependency */, - 75A2A8221DA5938500A983D8 /* PBXTargetDependency */, 22A9A99C1DF63426000F0016 /* PBXTargetDependency */, 752FB04F1DF8BF5C009086FB /* PBXTargetDependency */, ); @@ -3804,42 +3504,6 @@ productReference = 75A2A7901DA5934300A983D8 /* Litewallet.app */; productType = "com.apple.product-type.application"; }; - 75A2A7B71DA5934300A983D8 /* loafwallet WatchKit App */ = { - isa = PBXNativeTarget; - buildConfigurationList = 75A2A7DF1DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet WatchKit App" */; - buildPhases = ( - 75A2A7B61DA5934300A983D8 /* Resources */, - 75A2A7DE1DA5934400A983D8 /* Embed App Extensions */, - 1B54211CD65F63604952C654 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 75A2A7CA1DA5934300A983D8 /* PBXTargetDependency */, - ); - name = "loafwallet WatchKit App"; - productName = "breadwallet WatchKit App"; - productReference = 75A2A7B81DA5934300A983D8 /* loafwallet WatchKit App.app */; - productType = "com.apple.product-type.application.watchapp2"; - }; - 75A2A7C61DA5934300A983D8 /* loafwallet WatchKit Extension */ = { - isa = PBXNativeTarget; - buildConfigurationList = 75A2A7DB1DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet WatchKit Extension" */; - buildPhases = ( - 75A2A7C31DA5934300A983D8 /* Sources */, - 75A2A7C41DA5934300A983D8 /* Frameworks */, - 75A2A7C51DA5934300A983D8 /* Resources */, - CED811DF1EB30124003A8D1E /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "loafwallet WatchKit Extension"; - productName = "breadwallet WatchKit Extension"; - productReference = 75A2A7C71DA5934300A983D8 /* Litewallet.appex */; - productType = "com.apple.product-type.watchkit2-extension"; - }; 75A2A8071DA5936F00A983D8 /* TodayExtension */ = { isa = PBXNativeTarget; buildConfigurationList = 75A2A8151DA5936F00A983D8 /* Build configuration list for PBXNativeTarget "TodayExtension" */; @@ -3857,23 +3521,6 @@ productReference = 75A2A8081DA5936F00A983D8 /* TodayExtension.appex */; productType = "com.apple.product-type.app-extension"; }; - 75A2A81B1DA5938500A983D8 /* NotificationServiceExtension */ = { - isa = PBXNativeTarget; - buildConfigurationList = 75A2A8241DA5938500A983D8 /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */; - buildPhases = ( - 75A2A8181DA5938500A983D8 /* Sources */, - 75A2A8191DA5938500A983D8 /* Frameworks */, - 75A2A81A1DA5938500A983D8 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = NotificationServiceExtension; - productName = NotificationServiceExtension; - productReference = 75A2A81C1DA5938500A983D8 /* Litewallet.appex */; - productType = "com.apple.product-type.app-extension"; - }; 75C735AE1DAA1C9F00251ECF /* nettle */ = { isa = PBXNativeTarget; buildConfigurationList = 75C735B51DAA1C9F00251ECF /* Build configuration list for PBXNativeTarget "nettle" */; @@ -3907,10 +3554,6 @@ CreatedOnToolsVersion = 8.1; ProvisioningStyle = Automatic; }; - 2465872523A5AAC200A32E9E = { - CreatedOnToolsVersion = 11.3; - TestTargetID = 75A2A78F1DA5934300A983D8; - }; 2465873523A5AAD000A32E9E = { CreatedOnToolsVersion = 11.3; TestTargetID = 75A2A78F1DA5934300A983D8; @@ -3949,29 +3592,14 @@ }; }; }; - 75A2A7B71DA5934300A983D8 = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; - 75A2A7C61DA5934300A983D8 = { - CreatedOnToolsVersion = 8.0; - LastSwiftMigration = 0900; - ProvisioningStyle = Automatic; - }; 75A2A8071DA5936F00A983D8 = { CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.ApplicationGroups.iOS = { enabled = 1; }; }; }; - 75A2A81B1DA5938500A983D8 = { - CreatedOnToolsVersion = 8.0; - LastSwiftMigration = 0900; - ProvisioningStyle = Automatic; - }; 75C735AE1DAA1C9F00251ECF = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; @@ -4006,12 +3634,8 @@ projectRoot = ""; targets = ( 75A2A78F1DA5934300A983D8 /* loafwallet */, - 75A2A7B71DA5934300A983D8 /* loafwallet WatchKit App */, 2465873523A5AAD000A32E9E /* loafwalletTests */, - 2465872523A5AAC200A32E9E /* loafwalletUITests */, - 75A2A7C61DA5934300A983D8 /* loafwallet WatchKit Extension */, 75A2A8071DA5936F00A983D8 /* TodayExtension */, - 75A2A81B1DA5938500A983D8 /* NotificationServiceExtension */, 755CD9C31DAA18420075898E /* unbound */, 755CD9D01DAA197C0075898E /* BRCore */, 75C735AE1DAA1C9F00251ECF /* nettle */, @@ -4030,13 +3654,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2465872423A5AAC200A32E9E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 2465873423A5AAD000A32E9E /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -4089,30 +3706,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75A2A7B61DA5934300A983D8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CEFFA2D11EB3BD730085C5D1 /* LoadingIndicator.xcassets in Resources */, - 24D5F26622599C0B00225462 /* BarlowSemiCondensed-SemiBold.ttf in Resources */, - 24D5F25122599C0B00225462 /* BarlowSemiCondensed-Light.ttf in Resources */, - 24D5F25A22599C0B00225462 /* BarlowSemiCondensed-Medium.ttf in Resources */, - 24D5F23C22599C0B00225462 /* BarlowSemiCondensed-Bold.ttf in Resources */, - 24D5F23922599C0B00225462 /* BarlowSemiCondensed-Italic.ttf in Resources */, - 75A2A7C11DA5934300A983D8 /* Assets.xcassets in Resources */, - 24D5F26022599C0B00225462 /* BarlowSemiCondensed-Regular.ttf in Resources */, - 75A2A7BF1DA5934300A983D8 /* Interface.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 75A2A7C51DA5934300A983D8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 75A2A7D71DA5934400A983D8 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 75A2A8061DA5936F00A983D8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -4122,17 +3715,10 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75A2A81A1DA5938500A983D8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 0EFAC3B5E78B08742F671320 /* [CP] Embed Pods Frameworks */ = { + 2190D297B82EA6160376EC4C /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -4149,24 +3735,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 13AEC33C056F17F5D9122796 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwalletUITests-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 = 2147483647; @@ -4217,16 +3785,20 @@ 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"; }; - 99019425211CCCB309C62207 /* [CP] Check Pods Manifest.lock */ = { + 4C256FDD5564B94BFF10BA73 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; 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", ); @@ -4235,37 +3807,41 @@ 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; }; - CEE0EF531EBF8C8A0018DB36 /* Icon Versioning */ = { + 851EE9FAFF1CDBF8F4BAD5F4 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "Icon Versioning"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-loafwalletTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/scripts/icon_versioning.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; }; - E0229A38B86837D985A5CAC5 /* [CP] Check Pods Manifest.lock */ = { + CEE0EF531EBF8C8A0018DB36 /* Icon Versioning */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Check Pods Manifest.lock"; + name = "Icon Versioning"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwalletTests-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; + shellScript = "\"${SRCROOT}/scripts/icon_versioning.sh\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -4277,15 +3853,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2465872223A5AAC200A32E9E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2465872923A5AAC200A32E9E /* loafwalletUITests.swift in Sources */, - 24470E1F23A5D83500ADDA27 /* MainNavigationVIewUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 2465873223A5AAD000A32E9E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4430,7 +3997,6 @@ 24313C782381E8F100A83F69 /* TabBarViewController.swift in Sources */, CEBF29301EF9D76F005C330A /* Environment.swift in Sources */, CEC6AA4D1DF0741100EE5AFD /* ModalDisplayable.swift in Sources */, - CED811E11EB302DA003A8D1E /* WatchData.swift in Sources */, CEE0EF521EBD14B60018DB36 /* PinTransitioningDelegate.swift in Sources */, CE45C1FD1E7650F5002C3847 /* KVStoreCoordinator.swift in Sources */, 754AE0BC1DFE8A46007FD001 /* BRCore.swift in Sources */, @@ -4526,7 +4092,6 @@ CE83DE2A1E9EB7F600D07636 /* SendAmountCell.swift in Sources */, 22A9A9521DF61945000F0016 /* BRKVStorePlugin.swift in Sources */, CEAFC8611E5D5B0500E4FD06 /* SegmentedButton.swift in Sources */, - CE30F0E61EB27844004B8EE5 /* PhoneWCSessionManager.swift in Sources */, 2427342D2381C21800E2D22F /* MainViewController.swift in Sources */, 7503773D1DF57428005EB8AE /* WalletManager+Auth.swift in Sources */, 22A9A9581DF61945000F0016 /* BRWebViewController.swift in Sources */, @@ -4589,7 +4154,6 @@ 22A9A94B1DF61945000F0016 /* BRCoding.swift in Sources */, 22A9A9561DF61945000F0016 /* BRWalletPlugin.swift in Sources */, CEF3E8361DE60222007C0A9E /* ModalNavigationController.swift in Sources */, - CED811E21EB302DD003A8D1E /* WatchTransaction.swift in Sources */, CEB909FA1E5FF242001804DC /* RecoverWalletIntroViewController.swift in Sources */, CE25BF911DF9ADE700BC67B6 /* UIImage+Utils.swift in Sources */, CEBF33041DDE17A600348FC6 /* Transaction.swift in Sources */, @@ -4622,7 +4186,6 @@ CEA3626A1E01150D0061FC0E /* CGContext+Additions.swift in Sources */, 22A9A9541DF61945000F0016 /* BRReplicatedKVStore.swift in Sources */, CE6B6B4A1E54C0CB00B31405 /* SecurityCenterCell.swift in Sources */, - CED811AA1EB2B2D1003A8D1E /* SharedConstants.swift in Sources */, CE36454C1E7B42850079D0CF /* PinPadCells.swift in Sources */, CE5F21D91E4A922700C47B8E /* DismissLoginAnimator.swift in Sources */, CECCE5A51E02408300D99448 /* UIView+FrameChangeBlocking.swift in Sources */, @@ -4641,24 +4204,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75A2A7C31DA5934300A983D8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CED811E51EB30846003A8D1E /* ReceiveInterfaceController.swift in Sources */, - CEE513EF1EB6A84800D6E4D7 /* Strings.swift in Sources */, - CED811AC1EB2BCDE003A8D1E /* BRAWWeakTimerTarget.swift in Sources */, - CE30F0E81EB27FA2004B8EE5 /* WatchDataManager.swift in Sources */, - 75A2A7D31DA5934300A983D8 /* NotificationController.swift in Sources */, - CED811E01EB302DA003A8D1E /* WatchData.swift in Sources */, - 75A2A7D51DA5934300A983D8 /* ComplicationController.swift in Sources */, - 75A2A7D11DA5934300A983D8 /* ExtensionDelegate.swift in Sources */, - CE30F0EA1EB282C8004B8EE5 /* SharedConstants.swift in Sources */, - 75A2A7CF1DA5934300A983D8 /* BalanceInterfaceController.swift in Sources */, - CED811E31EB302E2003A8D1E /* WatchTransaction.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 75A2A8041DA5936F00A983D8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4669,14 +4214,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 75A2A8181DA5938500A983D8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 75A2A81F1DA5938500A983D8 /* NotificationService.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 75C735AB1DAA1C9F00251ECF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4740,11 +4277,6 @@ target = 22A9A9951DF63426000F0016 /* libbz2 */; targetProxy = 22A9A99B1DF63426000F0016 /* PBXContainerItemProxy */; }; - 2465872C23A5AAC200A32E9E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 75A2A78F1DA5934300A983D8 /* loafwallet */; - targetProxy = 2465872B23A5AAC200A32E9E /* PBXContainerItemProxy */; - }; 2465873C23A5AAD100A32E9E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 75A2A78F1DA5934300A983D8 /* loafwallet */; @@ -4775,26 +4307,11 @@ target = 759DA0D71DAC8668008CC49B /* submodules */; targetProxy = 759DA0DF1DAC86C3008CC49B /* PBXContainerItemProxy */; }; - 75A2A7BB1DA5934300A983D8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 75A2A7B71DA5934300A983D8 /* loafwallet WatchKit App */; - targetProxy = 75A2A7BA1DA5934300A983D8 /* PBXContainerItemProxy */; - }; - 75A2A7CA1DA5934300A983D8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 75A2A7C61DA5934300A983D8 /* loafwallet WatchKit Extension */; - targetProxy = 75A2A7C91DA5934300A983D8 /* PBXContainerItemProxy */; - }; 75A2A8131DA5936F00A983D8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 75A2A8071DA5936F00A983D8 /* TodayExtension */; targetProxy = 75A2A8121DA5936F00A983D8 /* PBXContainerItemProxy */; }; - 75A2A8221DA5938500A983D8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 75A2A81B1DA5938500A983D8 /* NotificationServiceExtension */; - targetProxy = 75A2A8211DA5938500A983D8 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -4829,29 +4346,6 @@ name = LaunchScreen.storyboard; sourceTree = ""; }; - 75A2A7BD1DA5934300A983D8 /* Interface.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 75A2A7BE1DA5934300A983D8 /* Base */, - 75A2A8291DA59B2A00A983D8 /* fr */, - 75A2A82E1DA59B2F00A983D8 /* de */, - 75A2A8331DA59B3600A983D8 /* zh-Hans */, - 75A2A8381DA59B3C00A983D8 /* ja */, - 75A2A83D1DA59B4500A983D8 /* es */, - 75A2A8421DA59B4B00A983D8 /* it */, - 75A2A8471DA59B5100A983D8 /* nl */, - 75A2A84C1DA59B5700A983D8 /* ko */, - 75A2A8561DA59B6A00A983D8 /* da */, - 75A2A8601DA59BF500A983D8 /* sv */, - 75A2A8651DA59BFB00A983D8 /* ru */, - 249F976E236F86240045087A /* id */, - 24B9621123BA64C100ECD938 /* zh-Hant */, - 24B9621323BA64C600ECD938 /* pt */, - 24B9621523BA64CC00ECD938 /* en */, - ); - name = Interface.storyboard; - sourceTree = ""; - }; 75A2A80E1DA5936F00A983D8 /* MainInterface.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -4997,12 +4491,12 @@ }; 24470E0123A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 94052F386F817420CBAEF937 /* Pods-loafwallet.debug.xcconfig */; + baseConfigurationReference = 39A1C8DFFA128099F0556A0E /* Pods-loafwallet.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 252; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5016,7 +4510,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.8.0; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5028,31 +4522,9 @@ }; name = Debug; }; - 24470E0223A5BF3C00ADDA27 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - 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.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; - }; - name = Debug; - }; 24470E0323A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8B95A1AEEE7D31D323D4DCB6 /* Pods-loafwalletTests.debug.xcconfig */; + baseConfigurationReference = 0B0BFC3BB4EF3438E0FD95C9 /* Pods-loafwalletTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -5125,110 +4597,13 @@ }; name = Debug; }; - 24470E0423A5BF3C00ADDA27 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 050C51BB8D4B5751D2FB72B0 /* Pods-loafwalletUITests.debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = ZV7987N2ZC; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = loafwalletUITests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.2; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.loafwalletUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = loafwallet; - }; - name = Debug; - }; - 24470E0523A5BF3C00ADDA27 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CURRENT_PROJECT_VERSION = 5; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ZV7987N2ZC; - INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit Extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MARKETING_VERSION = 2.7.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp.watchkitextension; - PRODUCT_NAME = Litewallet; - SDKROOT = watchos; - SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; - }; - name = Debug; - }; 24470E0723A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 5; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 252; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5238,36 +4613,11 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.8.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 24470E0823A5BF3C00ADDA27 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ZV7987N2ZC; - INFOPLIST_FILE = NotificationServiceExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MARKETING_VERSION = 2.7.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.NotificationServiceExtension; - PRODUCT_NAME = Litewallet; - PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -5380,63 +4730,9 @@ }; name = Debug; }; - 2465872F23A5AAC200A32E9E /* Testnet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9C9C005127F822BDD8DABB09 /* Pods-loafwalletUITests.testnet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ZV7987N2ZC; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = loafwalletUITests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.2; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.loafwalletUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = loafwallet; - }; - name = Testnet; - }; - 2465873023A5AAC200A32E9E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 646DF58AAF164153D75531F9 /* Pods-loafwalletUITests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ZV7987N2ZC; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = loafwalletUITests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.2; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.loafwalletUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = loafwallet; - }; - name = Release; - }; 2465873F23A5AAD100A32E9E /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 967F3BC33B298B55B0C419B7 /* Pods-loafwalletTests.testnet.xcconfig */; + baseConfigurationReference = 51D52F10840D223E083B6EDA /* Pods-loafwalletTests.testnet.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -5464,7 +4760,7 @@ }; 2465874023A5AAD100A32E9E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8146711587AD66F803519982 /* Pods-loafwalletTests.release.xcconfig */; + baseConfigurationReference = 75D0209A7B6BC4A864CC724C /* Pods-loafwalletTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -5610,59 +4906,14 @@ }; name = Release; }; - 75A2A7DD1DA5934400A983D8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CURRENT_PROJECT_VERSION = 5; - DEVELOPMENT_TEAM = ZV7987N2ZC; - INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit Extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MARKETING_VERSION = 2.7.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp.watchkitextension; - PRODUCT_NAME = Litewallet; - SDKROOT = watchos; - SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; - }; - name = Release; - }; - 75A2A7E11DA5934400A983D8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - 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.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; - }; - name = Release; - }; 75A2A7E51DA5934400A983D8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 42C95DFC249600E4FF4BB7BF /* Pods-loafwallet.release.xcconfig */; + baseConfigurationReference = 17FB6C0C7A4EDEE276391D9A /* Pods-loafwallet.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 252; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5675,7 +4926,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.8.0; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5690,7 +4941,9 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 5; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 252; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5699,34 +4952,11 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.8.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 75A2A8261DA5938500A983D8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; - DEVELOPMENT_TEAM = ZV7987N2ZC; - INFOPLIST_FILE = NotificationServiceExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MARKETING_VERSION = 2.7.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.NotificationServiceExtension; - PRODUCT_NAME = Litewallet; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -5808,12 +5038,12 @@ }; CEA7E69C1F0AAA84001F8C27 /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 52396A247C4B92980F0685C3 /* Pods-loafwallet.testnet.xcconfig */; + baseConfigurationReference = 9F2DD187A660718095013AA0 /* Pods-loafwallet.testnet.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 252; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5827,7 +5057,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.8.0; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5839,57 +5069,13 @@ }; name = Testnet; }; - CEA7E69F1F0AAA84001F8C27 /* Testnet */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - 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.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; - }; - name = Testnet; - }; - CEA7E6A01F0AAA84001F8C27 /* Testnet */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CURRENT_PROJECT_VERSION = 5; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ZV7987N2ZC; - INFOPLIST_FILE = "$(SRCROOT)/loafwallet WatchKit Extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MARKETING_VERSION = 2.7.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.watchkitapp.watchkitextension; - PRODUCT_NAME = Litewallet; - SDKROOT = watchos; - SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; - }; - name = Testnet; - }; CEA7E6A21F0AAA84001F8C27 /* Testnet */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 5; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 252; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5899,35 +5085,11 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.7.1; + MARKETING_VERSION = 2.8.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Testnet; - }; - CEA7E6A31F0AAA84001F8C27 /* Testnet */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ZV7987N2ZC; - INFOPLIST_FILE = NotificationServiceExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MARKETING_VERSION = 2.7.1; - PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.NotificationServiceExtension; - PRODUCT_NAME = Litewallet; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; }; name = Testnet; }; @@ -6054,16 +5216,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2465872D23A5AAC200A32E9E /* Build configuration list for PBXNativeTarget "loafwalletUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 24470E0423A5BF3C00ADDA27 /* Debug */, - 2465872F23A5AAC200A32E9E /* Testnet */, - 2465873023A5AAC200A32E9E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 2465873D23A5AAD100A32E9E /* Build configuration list for PBXNativeTarget "loafwalletTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -6124,26 +5276,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 75A2A7DB1DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet WatchKit Extension" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 24470E0523A5BF3C00ADDA27 /* Debug */, - CEA7E6A01F0AAA84001F8C27 /* Testnet */, - 75A2A7DD1DA5934400A983D8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 75A2A7DF1DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet WatchKit App" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 24470E0223A5BF3C00ADDA27 /* Debug */, - CEA7E69F1F0AAA84001F8C27 /* Testnet */, - 75A2A7E11DA5934400A983D8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 75A2A7E31DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -6164,16 +5296,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 75A2A8241DA5938500A983D8 /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 24470E0823A5BF3C00ADDA27 /* Debug */, - CEA7E6A31F0AAA84001F8C27 /* Testnet */, - 75A2A8261DA5938500A983D8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 75C735B51DAA1C9F00251ECF /* Build configuration list for PBXNativeTarget "nettle" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/loafwallet.xcodeproj/xcshareddata/xcschemes/Debug-loafwallet.xcscheme b/loafwallet.xcodeproj/xcshareddata/xcschemes/Debug-loafwallet.xcscheme deleted file mode 100644 index 386076cc3..000000000 --- a/loafwallet.xcodeproj/xcshareddata/xcschemes/Debug-loafwallet.xcscheme +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loafwallet/src/ApplicationController.swift b/loafwallet/src/ApplicationController.swift index b637abf20..ce4439d35 100644 --- a/loafwallet/src/ApplicationController.swift +++ b/loafwallet/src/ApplicationController.swift @@ -31,7 +31,6 @@ class ApplicationController : Subscriber, Trackable { private var kvStoreCoordinator: KVStoreCoordinator? private var mainViewController: MainViewController? fileprivate var application: UIApplication? - private let watchSessionManager = PhoneWCSessionManager() private var urlController: URLController? private var defaultsUpdater: UserDefaultsUpdater? private var reachability = ReachabilityMonitor() @@ -216,8 +215,7 @@ class ApplicationController : Subscriber, Trackable { } } exchangeUpdater?.refresh(completion: { - self.watchSessionManager.walletManager = self.walletManager - self.watchSessionManager.rate = self.store.state.currentRate + // Update values }) } } @@ -268,8 +266,7 @@ class ApplicationController : Subscriber, Trackable { defaultsUpdater?.refresh() walletManager?.apiClient?.events?.up() exchangeUpdater?.refresh(completion: { - self.watchSessionManager.walletManager = self.walletManager - self.watchSessionManager.rate = self.store.state.currentRate + // Update values }) } diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index 1d9727300..eea3058d1 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -11,27 +11,27 @@ 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 - } - } + + 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" case _20202116_VRC = "VISIT_RECEIVE_CONTROLLER" case _20191105_DSL = "DID_SEND_LTC" - case _20191105_DULP = "DID_UPDATE_LTC_PRICE" + case _20191105_DULP = "DID_UPDATE_LTC_PRICE" case _20191105_DTBT = "DID_TAP_BUY_TAB" case _20200111_DEDG = "DID_ENTER_DISPATCH_GROUP" case _20200111_DLDG = "DID_LEAVE_DISPATCH_GROUP" @@ -49,10 +49,10 @@ enum CustomEvent: String { case _20200223_DD = "DID_DONATE" case _20200225_DCD = "DID_CANCEL_DONATE" case _20200301_DUDFPK = "DID_USE_DEFAULT_FEE_PER_KB" - + } - + struct Padding { subscript(multiplier: Int) -> CGFloat { get { @@ -60,7 +60,7 @@ struct Padding { } } } - + struct C { static let padding = Padding() struct Sizes { @@ -80,15 +80,72 @@ struct C { static let btcCurrencyCode = "LTC" static let null = "(null)" static let maxMemoLength = 250 - static let feedbackEmail = "iosagent+feeback@litecoinfoundation.net" + static let feedbackEmail = "feedback@litecoinfoundation.zendesk.com" + static let supportEmail = "support@litecoinfoundation.zendesk.com" + + static let reviewLink = "https://itunes.apple.com/app/loafwallet-litecoin-wallet/id1119332592?action=write-review" static var standardPort: Int { return E.isTestnet ? 19335 : 9333 } + + static let troubleshootingQuestions = """ + + + + + + + + + + + +
+
+ +
Please reply to this email with the following information so that we can prepare to help you solve your Litewallet issue.
+
+
1. What version of software running on your mobile device (e.g.; iOS 13.7 or iOS 14)?
+
+
+
2. What version of Litewallet software is on your mobile device (found on the login view)?
+
+
+
3. What type of iPhone do you have?
+
+
+
4. How we can help?
+
+
+
+
+ + + """ } struct AppVersion { static let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String static let versionNumber = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String static let string = "v." + versionNumber! + " (\(buildNumber!))" -} +} + diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index ae80d97ce..7d325550d 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -444,10 +444,6 @@ enum S { static let faq = NSLocalizedString("AccessibilityLabels.faq", value: "**Support Center**", comment: "Support center accessibiliy label") } - enum Watch { - static let noWalletWarning = NSLocalizedString("Watch.noWalletWarning", value: "**Open the Litewallet iPhone app to set up your wallet.**", comment: "'No wallet' warning for watch app") - } - enum Search { static let sent = NSLocalizedString("Search.sent", value: "**sent**", comment: "Sent filter label") static let received = NSLocalizedString("Search.received", value: "**received**", comment: "Received filter label") diff --git a/loafwallet/src/FlowControllers/MessageUIPresenter.swift b/loafwallet/src/FlowControllers/MessageUIPresenter.swift index 1bf598893..faaf2c671 100644 --- a/loafwallet/src/FlowControllers/MessageUIPresenter.swift +++ b/loafwallet/src/FlowControllers/MessageUIPresenter.swift @@ -13,8 +13,8 @@ class MessageUIPresenter: NSObject, Trackable { weak var presenter: UIViewController? - func presentMailCompose(bitcoinAddress: String, image: UIImage) { - presentMailCompose(string: "litecoin: \(bitcoinAddress)", image: image) + func presentMailCompose(litecoinAddress: String, image: UIImage) { + presentMailCompose(string: "litecoin: \(litecoinAddress)", image: image) } func presentMailCompose(bitcoinURL: String, image: UIImage) { @@ -43,6 +43,18 @@ class MessageUIPresenter: NSObject, Trackable { emailView.mailComposeDelegate = self present(emailView) } + + func presentSupportCompose() { + guard MFMailComposeViewController.canSendMail() else { showEmailUnavailableAlert(); return } + originalTitleTextAttributes = UINavigationBar.appearance().titleTextAttributes + UINavigationBar.appearance().titleTextAttributes = nil + let emailView = MFMailComposeViewController() + emailView.setSubject("Litewallet Support") + emailView.setToRecipients([C.supportEmail]) + emailView.setMessageBody(C.troubleshootingQuestions, isHTML: true) + emailView.mailComposeDelegate = self + present(emailView) + } func presentMailCompose(emailAddress: String) { guard MFMailComposeViewController.canSendMail() else { showEmailUnavailableAlert(); return } diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 975773ccf..8dd7d4715 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -330,7 +330,7 @@ class ModalPresenter : Subscriber, Trackable { receiveVC.presentEmail = { [weak self, weak root] address, image in guard let root = root else { return } self?.messagePresenter.presenter = root - self?.messagePresenter.presentMailCompose(bitcoinAddress: address, image: image) + self?.messagePresenter.presentMailCompose(litecoinAddress: address, image: image) } receiveVC.presentText = { [weak self, weak root] address, image in guard let root = root else { return } @@ -349,9 +349,10 @@ 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?.presentWebView("/support") + self?.messagePresenter.presenter = self?.topViewController + self?.messagePresenter.presentSupportCompose() }) } menu.didTapLock = { [weak self, weak menu] in diff --git a/loafwallet/src/Platform/BRWalletPlugin.swift b/loafwallet/src/Platform/BRWalletPlugin.swift index 53bbf753a..a9d01b954 100644 --- a/loafwallet/src/Platform/BRWalletPlugin.swift +++ b/loafwallet/src/Platform/BRWalletPlugin.swift @@ -216,7 +216,6 @@ class BRWalletPlugin: BRHTTPRouterPlugin, BRWebSocketClient, Trackable { d["no_wallet"] = walletManager.noWallet if let wallet = walletManager.wallet { d["receive_address"] = wallet.receiveAddress - //d["watch_only"] = TODO - add watch only } d["btc_denomination_digits"] = store.state.maxDigits d["local_currency_code"] = store.state.defaultCurrencyCode diff --git a/loafwallet/src/Watch/PhoneWCSessionManager.swift b/loafwallet/src/Watch/PhoneWCSessionManager.swift deleted file mode 100644 index 3ae4a9ff8..000000000 --- a/loafwallet/src/Watch/PhoneWCSessionManager.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// PhoneWCSessionManager.swift -// breadwallet -// -// Created by Adrian Corscadden on 2017-04-27. -// Copyright © 2017 breadwallet LLC. All rights reserved. -// - -import UIKit -import WatchConnectivity - -class PhoneWCSessionManager : NSObject { - private let session: WCSession - - var walletManager: WalletManager? - var rate: Rate? - - override init() { - session = WCSession.default - super.init() - session.delegate = self - session.activate() - listenForSeedChange() - } - - func listenForSeedChange() { - NotificationCenter.default.addObserver(forName: .WalletDidWipeNotification, object: nil, queue: nil, using: { _ in - self.session.sendMessage([AW_SESSION_RESPONSE_KEY: "didWipe"], replyHandler: nil, errorHandler: nil) - }) - } -} - -extension PhoneWCSessionManager : WCSessionDelegate { - - func watchData(forWalletManager: WalletManager, rate: Rate) -> WatchData? { - if let noWallet = walletManager?.noWallet, noWallet == true { - return WatchData(balance: "", localBalance: "", receiveAddress: "", latestTransaction: "", qrCode: UIImage(), transactions: [], hasWallet: false) - } - - guard let wallet = forWalletManager.wallet else { return nil } - - let amount = Amount(amount: wallet.balance, rate: rate, maxDigits: 2) //TODO - fix always bits on watch - - let image = UIImage.qrCode(data: "\(wallet.receiveAddress)".data(using: .utf8)!, color: CIColor(color: .black))? - .resize(CGSize(width: 136.0, height: 136.0))! - - return WatchData(balance: amount.bits, - localBalance: amount.localCurrency, - receiveAddress: wallet.receiveAddress, - latestTransaction: "Latest transaction", - qrCode: image!, - transactions: [], - hasWallet: !forWalletManager.noWallet) - } - - func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) { - guard let walletManager = walletManager else { return replyHandler(["error": "no wallet manager"])} - guard let rate = rate else { return replyHandler(["error": "rate not set"]) } - guard let rawRequestType = message[AW_SESSION_REQUEST_TYPE] as? Int else { return replyHandler(["error":"unknown request type"]) } - guard let requestType = AWSessionRequestType(rawValue: rawRequestType) else { return replyHandler(["error":"unknown request type"]) } - guard let rawDataType = message[AW_SESSION_REQUEST_DATA_TYPE_KEY] as? Int else { return replyHandler(["error":"unknown data type"]) } - guard let dataType = AWSessionRequestDataType(rawValue: rawDataType) else { return replyHandler(["error":"unknown data type"]) } - - if case .fetchData = requestType { - switch dataType { - case .applicationContextData: - if let data = watchData(forWalletManager: walletManager, rate: rate) { - replyHandler([AW_SESSION_RESPONSE_KEY: data.toDictionary]) - } else { - replyHandler(["error": "unable to generate data"]) - } - case .qrCodeBits: - replyHandler([:]) - } - } else { - replyHandler(["error":"unknown request type"]) - } - } - - func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { - print("did complete activation") - } - - func sessionDidBecomeInactive(_ session: WCSession) { - print("did become inactive") - } - - func sessionDidDeactivate(_ session: WCSession) { - print("did deactivate") - } -} diff --git a/loafwallet/src/Watch/WatchData.swift b/loafwallet/src/Watch/WatchData.swift deleted file mode 100644 index fac1605b9..000000000 --- a/loafwallet/src/Watch/WatchData.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -// WatchData.swift -// breadwallet -// -// Created by Adrian Corscadden on 2017-04-27. -// Copyright © 2017 breadwallet LLC. All rights reserved. -// - -import Foundation -import UIKit - -private enum Keys { - static let balance = "AW_DATA_BALANCE_KEY" - static let localBalance = "AW_DATA_BALANCE_LOCAL_KEY" - static let receiveAddress = "AW_DATA_RECEIVE_MONEY_ADDRESS" - static let qrCode = "AW_DATA_RECEIVE_MONEY_QR_CODE" - static let transactions = "AW_DATA_TRANSACTIONS" - static let latestTransaction = "AW_DATA_LATEST_TRANSACTION" - static let hasWallet = "AW_DATA_HAS_WALLET" -} - -struct WatchData { - let balance: String - let localBalance: String - let receiveAddress: String - let latestTransaction: String - let qrCode: UIImage - let transactions: [WatchTransaction] - let hasWallet: Bool - - var toDictionary: [String: Any] { - return [ - Keys.balance: balance, - Keys.localBalance: localBalance, - Keys.receiveAddress: receiveAddress, - Keys.latestTransaction: latestTransaction, - Keys.qrCode: NSKeyedArchiver.archivedData(withRootObject: qrCode), - Keys.transactions: [], - Keys.hasWallet: hasWallet - ] - } - - var description: String { - return "\(balance),\(localBalance),\(receiveAddress),\(transactions.count),\(latestTransaction),\(qrCode.size.height)" - } -} - -extension WatchData { - init?(data: [String: Any]) { - guard let balance = data[Keys.balance] as? String else { return nil } - guard let localBalance = data[Keys.localBalance] as? String else { return nil } - guard let receiveAddress = data[Keys.receiveAddress] as? String else { return nil } - guard let latestTransaction = data[Keys.latestTransaction] as? String else { return nil } - guard let qrData = data[Keys.qrCode] as? Data else { return nil } - guard let qrImage = NSKeyedUnarchiver.unarchiveObject(with: qrData) as? UIImage else { return nil } - guard let hasWallet = data[Keys.hasWallet] as? Bool else { return nil } - - self.balance = balance - self.localBalance = localBalance - self.receiveAddress = receiveAddress - self.latestTransaction = latestTransaction - self.qrCode = qrImage - self.hasWallet = hasWallet - transactions = [] //TODO - add transactions here - } -} - -extension WatchData : Equatable {} - -func ==(lhs: WatchData, rhs: WatchData) -> Bool { - return lhs.balance == rhs.balance && lhs.localBalance == rhs.localBalance && lhs.receiveAddress == rhs.receiveAddress && lhs.latestTransaction == rhs.latestTransaction && lhs.transactions == rhs.transactions && lhs.hasWallet == rhs.hasWallet -} diff --git a/loafwallet/src/Watch/WatchTransaction.swift b/loafwallet/src/Watch/WatchTransaction.swift deleted file mode 100644 index 60b1ccd9f..000000000 --- a/loafwallet/src/Watch/WatchTransaction.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// WatchTransaction.swift -// breadwallet -// -// Created by Adrian Corscadden on 2017-04-27. -// Copyright © 2017 breadwallet LLC. All rights reserved. -// - -import Foundation - -enum WatchTransactionType : Int32 { - case sent = 0 - case receive - case move - case invalid -} - -private enum Keys { - static let amount = "AW_TRANSACTION_DATA_AMOUNT_KEY" - static let localAmount = "AW_TRANSACTION_DATA_AMOUNT_IN_LOCAL_CURRENCY_KEY" - static let date = "AW_TRANSACTION_DATA_DATE_KEY" - static let type = "AW_TRANSACTION_DATA_TYPE_KEY" -} - -class WatchTransaction : NSObject, NSCoding { - let amount: String - let localAmount: String - let date: String - let type: WatchTransactionType - - required init(coder: NSCoder) { - amount = coder.decodeObject(forKey: Keys.amount) as! String - localAmount = coder.decodeObject(forKey: Keys.localAmount) as! String - date = coder.decodeObject(forKey: Keys.date) as! String - type = WatchTransactionType(rawValue: coder.decodeInt32(forKey: Keys.type))! - } - - func encode(with aCoder: NSCoder) { - aCoder.encode(amount, forKey: Keys.amount) - aCoder.encode(localAmount, forKey: Keys.localAmount) - aCoder.encode(date, forKey: Keys.date) - aCoder.encode(type.rawValue, forKey: Keys.type) - } -} diff --git a/loafwalletUITests/Info.plist b/loafwalletUITests/Info.plist deleted file mode 100644 index 7707eb9b5..000000000 --- a/loafwalletUITests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 2 - - diff --git a/loafwalletUITests/MainNavigationVIewUITests.swift b/loafwalletUITests/MainNavigationVIewUITests.swift deleted file mode 100644 index 02b3b8b14..000000000 --- a/loafwalletUITests/MainNavigationVIewUITests.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// MainNavigationVIewUITests.swift -// loafwalletUITests -// -// Created by Kerry Washington on 12/14/19. -// Copyright © 2019 Litecoin Foundation. All rights reserved. -// - -import XCTest - -class MainNavigationVIewUITests: XCTestCase { - - var app: XCUIApplication! - - override func setUp() { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testTabBarHistoryTab() { - let tabBarsQuery = app.tabBars - tabBarsQuery.buttons["History"].tap() - } - - func testTabBarReceiveTab() { - let tabBarsQuery = app.tabBars - tabBarsQuery.buttons["Receive"].tap() - } - - func testTabBarSendTab() { - let tabBarsQuery = app.tabBars - tabBarsQuery.buttons["Send"].tap() - } - - func testTabBarBuyTab() { - let tabBarsQuery = app.tabBars - tabBarsQuery.buttons["Buy"].tap() - } - - func testDisplayContentController() { - //contentController:UIViewController - ///TBD TabBarViewController: 350 - } - -} diff --git a/loafwalletUITests/loafwalletUITests.swift b/loafwalletUITests/loafwalletUITests.swift deleted file mode 100644 index 48b611009..000000000 --- a/loafwalletUITests/loafwalletUITests.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// loafwalletUITests.swift -// loafwalletUITests -// -// Created by Kerry Washington on 12/14/19. -// Copyright © 2019 Litecoin Foundation. All rights reserved. -// - -import XCTest - -class loafwalletUITests: XCTestCase { - - var app: XCUIApplication! - - override func setUp() { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testLaunchPerformance() { - if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { - // This measures how long it takes to launch your application. - measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) { - XCUIApplication().launch() - } - } - } -} From ef9e6e99f43352c606af0a37c9de443bd8fe522c Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 21 Nov 2020 13:48:09 +0000 Subject: [PATCH 04/35] [Release v2.8.2] Merge into Master (#153) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- .gitignore | 10 - .../el.lproj/MainInterface.strings | 3 - .../hu.lproj/MainInterface.strings | 3 - .../nb.lproj/MainInterface.strings | 3 - .../pl.lproj/MainInterface.strings | 3 - .../pt-BR.lproj/MainInterface.strings | 3 - .../tr.lproj/MainInterface.strings | 3 - Podfile | 7 +- README.md | 1 + .../ar.lproj/Interface.strings | 18 -- .../hu.lproj/Interface.strings | 18 -- .../nb.lproj/Interface.strings | 18 -- .../pl.lproj/Interface.strings | 18 -- .../pt-BR.lproj/Interface.strings | 18 -- .../tr.lproj/Interface.strings | 18 -- loafwallet.xcodeproj/project.pbxproj | 202 ++++++------ .../loafwallet WatchKit App.xcscheme | 144 --------- .../xcschemes/loafwallet.xcscheme | 100 ++++++ loafwallet/DonationSetupCell.swift | 62 ---- .../DynamicDonationViewController.swift | 230 -------------- .../Storyboards/DynamicDonation.storyboard | 288 ------------------ loafwallet/SupportLFViewModel.swift | 15 + .../SupportLitecoinFoundationView.swift | 91 ++++++ .../SupportLitecoinFoundationViewModel.swift | 28 ++ loafwallet/SupportSafariView.swift | 91 ++++++ loafwallet/SupportSafariViewModel.swift | 17 ++ loafwallet/TabBarViewController.swift | 3 +- loafwallet/TransactionTableViewCells.swift | 2 +- loafwallet/src/Constants/Constants.swift | 34 +-- loafwallet/src/Constants/Strings.swift | 8 +- .../src/Extensions/UIColor+Extension.swift | 2 +- .../FlowControllers/StartFlowPresenter.swift | 4 +- loafwallet/src/SimpleRedux.swift | 16 +- loafwallet/src/SimpleRedux/Actions.swift | 106 +++---- .../{State.swift => ReduxState.swift} | 8 +- .../Strings/Base.lproj/Localizable.strings | 3 + .../src/Strings/ar.lproj/Localizable.strings | 18 +- .../src/Strings/da.lproj/Localizable.strings | 18 +- .../src/Strings/de.lproj/Localizable.strings | 18 +- .../src/Strings/en.lproj/Localizable.strings | 18 +- .../src/Strings/es.lproj/Localizable.strings | 18 +- .../src/Strings/fr.lproj/Localizable.strings | 18 +- .../src/Strings/id.lproj/Localizable.strings | 18 +- .../src/Strings/it.lproj/Localizable.strings | 18 +- .../src/Strings/ja.lproj/Localizable.strings | 18 +- .../src/Strings/ko.lproj/Localizable.strings | 18 +- .../src/Strings/nl.lproj/Localizable.strings | 18 +- .../src/Strings/pt.lproj/Localizable.strings | 18 +- .../src/Strings/ru.lproj/Localizable.strings | 18 +- .../src/Strings/sv.lproj/Localizable.strings | 18 +- .../Strings/zh-Hans.lproj/Localizable.strings | 18 +- .../Strings/zh-Hant.lproj/Localizable.strings | 18 +- .../ConfirmationViewController.swift | 4 +- .../RootModals/SendViewController.swift | 88 ++---- loafwallet/src/ViewModels/Amount.swift | 12 +- .../src/Views/SendViewCells/AddressCell.swift | 4 +- .../SendViewCells/DescriptionSendCell.swift | 8 +- .../src/Views/SendViewCells/SendCell.swift | 4 +- ...portLitecoinFoundationViewModelTests.swift | 31 ++ .../Constants Tests/ConstantsTests.swift | 18 ++ .../Legacy BRTests/TouchIdEnabledTests.swift | 4 +- scripts/icon_versioning.sh | 139 --------- 62 files changed, 689 insertions(+), 1509 deletions(-) delete mode 100644 MessagesExtension/el.lproj/MainInterface.strings delete mode 100644 MessagesExtension/hu.lproj/MainInterface.strings delete mode 100644 MessagesExtension/nb.lproj/MainInterface.strings delete mode 100644 MessagesExtension/pl.lproj/MainInterface.strings delete mode 100644 MessagesExtension/pt-BR.lproj/MainInterface.strings delete mode 100644 MessagesExtension/tr.lproj/MainInterface.strings delete mode 100644 loafwallet WatchKit App/ar.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/hu.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/nb.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/pl.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/pt-BR.lproj/Interface.strings delete mode 100644 loafwallet WatchKit App/tr.lproj/Interface.strings delete mode 100644 loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme create mode 100644 loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme delete mode 100644 loafwallet/DonationSetupCell.swift delete mode 100644 loafwallet/DynamicDonationViewController.swift delete mode 100644 loafwallet/Storyboards/DynamicDonation.storyboard create mode 100644 loafwallet/SupportLFViewModel.swift create mode 100644 loafwallet/SupportLitecoinFoundationView.swift create mode 100644 loafwallet/SupportLitecoinFoundationViewModel.swift create mode 100644 loafwallet/SupportSafariView.swift create mode 100644 loafwallet/SupportSafariViewModel.swift rename loafwallet/src/SimpleRedux/{State.swift => ReduxState.swift} (95%) create mode 100644 loafwalletTests/Class Tests/SupportLitecoinFoundationViewModelTests.swift create mode 100644 loafwalletTests/Constants Tests/ConstantsTests.swift delete mode 100755 scripts/icon_versioning.sh diff --git a/.gitignore b/.gitignore index 3012330d3..0052f7bd7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,15 +7,6 @@ build/ DerivedData/ ## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ ## Other *.moved-aside @@ -65,5 +56,4 @@ fastlane/screenshots fastlane/test_output Screenshots/shots .DS_Store -*.xcscheme loafwallet/GoogleService-Info.plist diff --git a/MessagesExtension/el.lproj/MainInterface.strings b/MessagesExtension/el.lproj/MainInterface.strings deleted file mode 100644 index ef1f056cd..000000000 --- a/MessagesExtension/el.lproj/MainInterface.strings +++ /dev/null @@ -1,3 +0,0 @@ - -/* Class = "UILabel"; text = "Hello World"; ObjectID = "d1e-fi-ked"; */ -"d1e-fi-ked.text" = "Hello World"; diff --git a/MessagesExtension/hu.lproj/MainInterface.strings b/MessagesExtension/hu.lproj/MainInterface.strings deleted file mode 100644 index ef1f056cd..000000000 --- a/MessagesExtension/hu.lproj/MainInterface.strings +++ /dev/null @@ -1,3 +0,0 @@ - -/* Class = "UILabel"; text = "Hello World"; ObjectID = "d1e-fi-ked"; */ -"d1e-fi-ked.text" = "Hello World"; diff --git a/MessagesExtension/nb.lproj/MainInterface.strings b/MessagesExtension/nb.lproj/MainInterface.strings deleted file mode 100644 index ef1f056cd..000000000 --- a/MessagesExtension/nb.lproj/MainInterface.strings +++ /dev/null @@ -1,3 +0,0 @@ - -/* Class = "UILabel"; text = "Hello World"; ObjectID = "d1e-fi-ked"; */ -"d1e-fi-ked.text" = "Hello World"; diff --git a/MessagesExtension/pl.lproj/MainInterface.strings b/MessagesExtension/pl.lproj/MainInterface.strings deleted file mode 100644 index ef1f056cd..000000000 --- a/MessagesExtension/pl.lproj/MainInterface.strings +++ /dev/null @@ -1,3 +0,0 @@ - -/* Class = "UILabel"; text = "Hello World"; ObjectID = "d1e-fi-ked"; */ -"d1e-fi-ked.text" = "Hello World"; diff --git a/MessagesExtension/pt-BR.lproj/MainInterface.strings b/MessagesExtension/pt-BR.lproj/MainInterface.strings deleted file mode 100644 index ef1f056cd..000000000 --- a/MessagesExtension/pt-BR.lproj/MainInterface.strings +++ /dev/null @@ -1,3 +0,0 @@ - -/* Class = "UILabel"; text = "Hello World"; ObjectID = "d1e-fi-ked"; */ -"d1e-fi-ked.text" = "Hello World"; diff --git a/MessagesExtension/tr.lproj/MainInterface.strings b/MessagesExtension/tr.lproj/MainInterface.strings deleted file mode 100644 index ef1f056cd..000000000 --- a/MessagesExtension/tr.lproj/MainInterface.strings +++ /dev/null @@ -1,3 +0,0 @@ - -/* Class = "UILabel"; text = "Hello World"; ObjectID = "d1e-fi-ked"; */ -"d1e-fi-ked.text" = "Hello World"; diff --git a/Podfile b/Podfile index c8a3bf77d..074bfad4a 100644 --- a/Podfile +++ b/Podfile @@ -3,13 +3,10 @@ source 'https://github.com/CocoaPods/Specs.git' workspace 'loafwallet.xcworkspace' project 'loafwallet.xcodeproj', 'Debug' => :debug,'Release' => :release use_frameworks! - +platform :ios, '13.0' #Shared Cocopods def shared_pods - pod 'Alamofire', '~> 4.7' - pod 'SwiftyJSON', '~> 4.0' - pod 'CryptoSwift', '~> 1.0' pod 'Firebase/Crashlytics' pod 'Firebase/Analytics' @@ -17,7 +14,6 @@ def shared_pods end target 'loafwallet' do - platform :ios, '12.0' shared_pods target 'loafwalletTests' do @@ -25,4 +21,3 @@ target 'loafwallet' do end end - diff --git a/README.md b/README.md index cc531226f..0baf72249 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ Simplicity and ease-of-use is **Litewallet**'s core design principle. A simple r --- ## Litewallet Development: +[Status](https://app.bitrise.io/app/ba01fd2f1582d2df/status.svg?token=E0SYYWy-g0Fn4kEkqUo6kA) [![GitHub issues](https://img.shields.io/github/issues/litecoin-foundation/loafwallet-ios?style=plastic)](https://github.com/litecoin-foundation/loafwallet-ios/re-frame/issues) [![GitHub pull requests](https://img.shields.io/github/issues-pr/litecoin-foundation/loafwallet-ios?color=00ff00&style=plastic)](https://github.com/litecoin-foundation/loafwallet-ios/pulls) diff --git a/loafwallet WatchKit App/ar.lproj/Interface.strings b/loafwallet WatchKit App/ar.lproj/Interface.strings deleted file mode 100644 index ca3cdd306..000000000 --- a/loafwallet WatchKit App/ar.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "Receive"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "Balance"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "Alert Label"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "NoWallet Label"; diff --git a/loafwallet WatchKit App/hu.lproj/Interface.strings b/loafwallet WatchKit App/hu.lproj/Interface.strings deleted file mode 100644 index 59a6ebfc6..000000000 --- a/loafwallet WatchKit App/hu.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "**Receive**"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "**Balance**"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "**Alert Label**"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "**NoWallet Label**"; diff --git a/loafwallet WatchKit App/nb.lproj/Interface.strings b/loafwallet WatchKit App/nb.lproj/Interface.strings deleted file mode 100644 index 59a6ebfc6..000000000 --- a/loafwallet WatchKit App/nb.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "**Receive**"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "**Balance**"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "**Alert Label**"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "**NoWallet Label**"; diff --git a/loafwallet WatchKit App/pl.lproj/Interface.strings b/loafwallet WatchKit App/pl.lproj/Interface.strings deleted file mode 100644 index 59a6ebfc6..000000000 --- a/loafwallet WatchKit App/pl.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "**Receive**"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "**Balance**"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "**Alert Label**"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "**NoWallet Label**"; diff --git a/loafwallet WatchKit App/pt-BR.lproj/Interface.strings b/loafwallet WatchKit App/pt-BR.lproj/Interface.strings deleted file mode 100644 index 59a6ebfc6..000000000 --- a/loafwallet WatchKit App/pt-BR.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "**Receive**"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "**Balance**"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "**Alert Label**"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "**NoWallet Label**"; diff --git a/loafwallet WatchKit App/tr.lproj/Interface.strings b/loafwallet WatchKit App/tr.lproj/Interface.strings deleted file mode 100644 index 59a6ebfc6..000000000 --- a/loafwallet WatchKit App/tr.lproj/Interface.strings +++ /dev/null @@ -1,18 +0,0 @@ - -/* Class = "WKInterfaceController"; title = "Receive"; ObjectID = "9Xz-xI-XUr"; */ -"9Xz-xI-XUr.title" = "**Receive**"; - -/* Class = "WKInterfaceLabel"; text = "1,000"; ObjectID = "A9h-CR-kAQ"; */ -"A9h-CR-kAQ.text" = "1,000"; - -/* Class = "WKInterfaceController"; title = "Balance"; ObjectID = "AgC-eL-Hgc"; */ -"AgC-eL-Hgc.title" = "**Balance**"; - -/* Class = "WKInterfaceLabel"; text = "Alert Label"; ObjectID = "IdU-wH-bcW"; */ -"IdU-wH-bcW.text" = "**Alert Label**"; - -/* Class = "WKInterfaceLabel"; text = "$500"; ObjectID = "mB1-E9-tTW"; */ -"mB1-E9-tTW.text" = "$500"; - -/* Class = "WKInterfaceLabel"; text = "NoWallet Label"; ObjectID = "SUN-9p-WiB"; */ -"SUN-9p-WiB.text" = "**NoWallet Label**"; diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 4165c9f0d..91a0f3c61 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -66,11 +66,8 @@ 22E773041EE7813000397E0E /* Bonjour.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22E773031EE7813000397E0E /* Bonjour.swift */; }; 24016D8E23F887C3006A6791 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24016D8D23F887C2006A6791 /* GoogleService-Info.plist */; }; 24016D9023F913C1006A6791 /* LWAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24016D8F23F913C1006A6791 /* LWAnalytics.swift */; }; - 240A89B6235F7280005E2A2F /* DonationSetupCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240A89B4235F7280005E2A2F /* DonationSetupCell.swift */; }; 2427342D2381C21800E2D22F /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2427342B2381C21800E2D22F /* MainViewController.swift */; }; 24306797238F3DF900EBEA99 /* BartyCrouch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24306796238F3DF900EBEA99 /* BartyCrouch.swift */; }; - 2430A80D23FCCB47002463B5 /* DynamicDonation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2430A80C23FCCB47002463B5 /* DynamicDonation.storyboard */; }; - 2430A80F23FCCE1A002463B5 /* DynamicDonationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2430A80E23FCCE1A002463B5 /* DynamicDonationViewController.swift */; }; 24313C752381E73200A83F69 /* TransactionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C732381E73200A83F69 /* TransactionManager.swift */; }; 24313C782381E8F100A83F69 /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C762381E8F100A83F69 /* TabBarViewController.swift */; }; 24313C7B23820BC200A83F69 /* SendLTCViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24313C7923820BC200A83F69 /* SendLTCViewController.swift */; }; @@ -136,7 +133,6 @@ 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 */; }; - 35263D49B92F5A97F6D39C3F /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D0C100AED9E17445EEBE5D7 /* Pods_loafwalletTests.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 */; }; @@ -271,7 +267,13 @@ 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 */; }; - 9565EF20DD221C9D2F2A6AEB /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D3369965438F85DF214DE3F /* Pods_loafwallet.framework */; }; + BB66CB271F7F2FD1936AA04B /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FEAAB89A265CC043F53CC51 /* Pods_loafwalletTests.framework */; }; + 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 */; }; + 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 */; }; CE0CD1591DBFBCF5004023DA /* ModalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0CD1581DBFBCF5004023DA /* ModalPresenter.swift */; }; CE124CF81E67A8E500DFA146 /* TransactionDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE124CF71E67A8E500DFA146 /* TransactionDirection.swift */; }; @@ -291,7 +293,7 @@ CE20C90E1DBE52B000C8397A /* UIView+BRWAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE20C90D1DBE52B000C8397A /* UIView+BRWAdditions.swift */; }; CE20C9111DBE5B6F00C8397A /* Circle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE20C9101DBE5B6F00C8397A /* Circle.swift */; }; CE20C9171DBE6F2A00C8397A /* UIButton+BRWAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE20C9161DBE6F2A00C8397A /* UIButton+BRWAdditions.swift */; }; - CE20C9191DBE7B8200C8397A /* State.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE20C9181DBE7B8200C8397A /* State.swift */; }; + CE20C9191DBE7B8200C8397A /* ReduxState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE20C9181DBE7B8200C8397A /* ReduxState.swift */; }; CE25BF8D1DF3B8A500BC67B6 /* InViewAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE25BF8C1DF3B8A500BC67B6 /* InViewAlert.swift */; }; CE25BF911DF9ADE700BC67B6 /* UIImage+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE25BF901DF9ADE700BC67B6 /* UIImage+Utils.swift */; }; CE25BF931DFDA7A600BC67B6 /* MessageUIPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE25BF921DFDA7A500BC67B6 /* MessageUIPresenter.swift */; }; @@ -424,6 +426,7 @@ 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 */ @@ -549,8 +552,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 0B0BFC3BB4EF3438E0FD95C9 /* 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 = ""; }; - 17FB6C0C7A4EDEE276391D9A /* 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 = ""; }; + 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 = ""; }; @@ -723,13 +725,10 @@ 22E773031EE7813000397E0E /* Bonjour.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bonjour.swift; sourceTree = ""; }; 24016D8D23F887C2006A6791 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 24016D8F23F913C1006A6791 /* LWAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LWAnalytics.swift; sourceTree = ""; }; - 240A89B4235F7280005E2A2F /* DonationSetupCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DonationSetupCell.swift; sourceTree = ""; }; 2427342B2381C21800E2D22F /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 24306796238F3DF900EBEA99 /* BartyCrouch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BartyCrouch.swift; sourceTree = ""; }; 24306799238F479500EBEA99 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = ""; }; 2430679B238F5A2900EBEA99 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - 2430A80C23FCCB47002463B5 /* DynamicDonation.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = DynamicDonation.storyboard; sourceTree = ""; }; - 2430A80E23FCCE1A002463B5 /* DynamicDonationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicDonationViewController.swift; sourceTree = ""; }; 24313C732381E73200A83F69 /* TransactionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionManager.swift; sourceTree = ""; }; 24313C762381E8F100A83F69 /* TabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewController.swift; sourceTree = ""; }; 24313C7923820BC200A83F69 /* SendLTCViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendLTCViewController.swift; sourceTree = ""; }; @@ -817,8 +816,9 @@ 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 = ""; }; - 39A1C8DFFA128099F0556A0E /* 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 = ""; }; - 51D52F10840D223E083B6EDA /* 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 = ""; }; + 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; }; 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 = ""; }; @@ -1417,11 +1417,17 @@ 75A2A8671DA59BFB00A983D8 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MainInterface.strings; sourceTree = ""; }; 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; }; - 75D0209A7B6BC4A864CC724C /* 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 = ""; }; 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; - 8D3369965438F85DF214DE3F /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9D0C100AED9E17445EEBE5D7 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9F2DD187A660718095013AA0 /* 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 = ""; }; + 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 = ""; }; + 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 = ""; }; + 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 = ""; }; CE0CD1581DBFBCF5004023DA /* ModalPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = ModalPresenter.swift; path = src/ModalPresenter.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; CE0FC0F81F72417200E7C626 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; @@ -1443,7 +1449,7 @@ CE20C90D1DBE52B000C8397A /* UIView+BRWAdditions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+BRWAdditions.swift"; path = "src/Extensions/UIView+BRWAdditions.swift"; sourceTree = ""; }; CE20C9101DBE5B6F00C8397A /* Circle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Circle.swift; path = src/Views/Circle.swift; sourceTree = ""; }; CE20C9161DBE6F2A00C8397A /* UIButton+BRWAdditions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIButton+BRWAdditions.swift"; path = "src/Extensions/UIButton+BRWAdditions.swift"; sourceTree = ""; }; - CE20C9181DBE7B8200C8397A /* State.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = State.swift; path = src/SimpleRedux/State.swift; sourceTree = ""; }; + CE20C9181DBE7B8200C8397A /* ReduxState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ReduxState.swift; path = src/SimpleRedux/ReduxState.swift; sourceTree = ""; }; CE25BF8C1DF3B8A500BC67B6 /* InViewAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InViewAlert.swift; path = src/Views/InViewAlert.swift; sourceTree = ""; }; CE25BF901DF9ADE700BC67B6 /* UIImage+Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIImage+Utils.swift"; path = "src/Extensions/UIImage+Utils.swift"; sourceTree = ""; }; CE25BF921DFDA7A500BC67B6 /* MessageUIPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MessageUIPresenter.swift; path = src/FlowControllers/MessageUIPresenter.swift; sourceTree = ""; }; @@ -1610,7 +1616,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 35263D49B92F5A97F6D39C3F /* Pods_loafwalletTests.framework in Frameworks */, + BB66CB271F7F2FD1936AA04B /* Pods_loafwalletTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1649,7 +1655,7 @@ 223DB21B1DF69F0F0076A151 /* libbz2.framework in Frameworks */, 752FB04D1DF8BF4B009086FB /* sqlite3.framework in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, - 9565EF20DD221C9D2F2A6AEB /* Pods_loafwallet.framework in Frameworks */, + DC03CB1EE9228BC37FA36F54 /* Pods_loafwallet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2098,6 +2104,7 @@ 24470E4423A608A700ADDA27 /* AmountTests.swift */, 2494037523AD35C000369261 /* BuyWKWebVCTests.swift */, 249C570423B51F9B009CB5A9 /* TransactionsViewControllerTests.swift */, + C3B7C43E25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift */, ); path = "Class Tests"; sourceTree = ""; @@ -2105,6 +2112,7 @@ 2465873723A5AAD100A32E9E /* loafwalletTests */ = { isa = PBXGroup; children = ( + C3B7C3EC255FF56100E98A64 /* Constants Tests */, 24470E3923A5FF5700ADDA27 /* TestHelpers.swift */, 24470E4323A6088700ADDA27 /* Class Tests */, 24470E2823A5F2C000ADDA27 /* Legacy BRTests */, @@ -2139,7 +2147,6 @@ 24313C9323824F5700A83F69 /* Transactions.storyboard */, 24DFCE6723B89CDE001F17F8 /* Settings.storyboard */, 24AF00FC221B331D00FF636F /* WarningConfirmation.storyboard */, - 2430A80C23FCCB47002463B5 /* DynamicDonation.storyboard */, ); path = Storyboards; sourceTree = ""; @@ -2963,8 +2970,8 @@ 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */, 75A2A7F21DA5935F00A983D8 /* Messages.framework */, 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */, - 8D3369965438F85DF214DE3F /* Pods_loafwallet.framework */, - 9D0C100AED9E17445EEBE5D7 /* Pods_loafwalletTests.framework */, + 4241321F8719503196989C34 /* Pods_loafwallet.framework */, + 6FEAAB89A265CC043F53CC51 /* Pods_loafwalletTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -3010,6 +3017,23 @@ path = Modules/sqlite3; sourceTree = ""; }; + C3B7C3EC255FF56100E98A64 /* Constants Tests */ = { + isa = PBXGroup; + children = ( + C3B7C3ED255FF59200E98A64 /* ConstantsTests.swift */, + ); + path = "Constants Tests"; + sourceTree = ""; + }; + C3F55643255A1916005F786F /* SupportLitecoinFoundation */ = { + isa = PBXGroup; + children = ( + C3F55644255A193D005F786F /* SupportLitecoinFoundationView.swift */, + C3F55654255A195B005F786F /* SupportLitecoinFoundationViewModel.swift */, + ); + name = SupportLitecoinFoundation; + sourceTree = ""; + }; CE1E5F241EF081F300BD0F72 /* Import */ = { isa = PBXGroup; children = ( @@ -3058,7 +3082,6 @@ 1BEA7DDA2142CAA00081602F /* WebViewContainer.swift */, 24AF00FF221B349100FF636F /* WarningConfirmationViewController.swift */, 24D5F26D225A5BEA00225462 /* ContainerViewController.swift */, - 2430A80E23FCCE1A002463B5 /* DynamicDonationViewController.swift */, ); name = ViewControllers; sourceTree = ""; @@ -3103,7 +3126,7 @@ isa = PBXGroup; children = ( CE20C8FD1DBB133A00C8397A /* SimpleRedux.swift */, - CE20C9181DBE7B8200C8397A /* State.swift */, + CE20C9181DBE7B8200C8397A /* ReduxState.swift */, CE20C9001DBBFFF800C8397A /* Actions.swift */, ); name = SimpleRedux; @@ -3123,8 +3146,9 @@ CE20C90F1DBE5B5100C8397A /* Views */ = { isa = PBXGroup; children = ( + C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, + C3F55643255A1916005F786F /* SupportLitecoinFoundation */, 24BA90C52410129E001E3825 /* FeeSelectorView.swift */, - 240A89B4235F7280005E2A2F /* DonationSetupCell.swift */, CE6BCF5C1EE9E89A0029849C /* CustomTitleView.swift */, CED341321EF5A5C00014912A /* InAppAlert.swift */, CE3645461E7B40280079D0CF /* PinPadCells */, @@ -3267,6 +3291,7 @@ CEBF33021DDE177F00348FC6 /* ViewModels */ = { isa = PBXGroup; children = ( + C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */, CEBF33031DDE17A600348FC6 /* Transaction.swift */, CE27F9581E2C8EA300F7F7F2 /* Amount.swift */, CE124CF71E67A8E500DFA146 /* TransactionDirection.swift */, @@ -3336,12 +3361,12 @@ FEE036865998B9DFEEF3139A /* Pods */ = { isa = PBXGroup; children = ( - 39A1C8DFFA128099F0556A0E /* Pods-loafwallet.debug.xcconfig */, - 9F2DD187A660718095013AA0 /* Pods-loafwallet.testnet.xcconfig */, - 17FB6C0C7A4EDEE276391D9A /* Pods-loafwallet.release.xcconfig */, - 0B0BFC3BB4EF3438E0FD95C9 /* Pods-loafwalletTests.debug.xcconfig */, - 51D52F10840D223E083B6EDA /* Pods-loafwalletTests.testnet.xcconfig */, - 75D0209A7B6BC4A864CC724C /* Pods-loafwalletTests.release.xcconfig */, + 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 */, ); path = Pods; sourceTree = ""; @@ -3405,7 +3430,7 @@ isa = PBXNativeTarget; buildConfigurationList = 2465873D23A5AAD100A32E9E /* Build configuration list for PBXNativeTarget "loafwalletTests" */; buildPhases = ( - 851EE9FAFF1CDBF8F4BAD5F4 /* [CP] Check Pods Manifest.lock */, + ABD5154B4DB399A4A81559CD /* [CP] Check Pods Manifest.lock */, 2465873223A5AAD000A32E9E /* Sources */, 2465873323A5AAD000A32E9E /* Frameworks */, 2465873423A5AAD000A32E9E /* Resources */, @@ -3478,7 +3503,7 @@ isa = PBXNativeTarget; buildConfigurationList = 75A2A7E31DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet" */; buildPhases = ( - 4C256FDD5564B94BFF10BA73 /* [CP] Check Pods Manifest.lock */, + 156E4E7F04DB5E000B3A1A91 /* [CP] Check Pods Manifest.lock */, 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */, 24E179F223BDAF8000F928D9 /* Xcode custom warnings */, 75A2A78C1DA5934300A983D8 /* Sources */, @@ -3487,9 +3512,8 @@ 75A2A7E21DA5934400A983D8 /* Embed Watch Content */, 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, - CEE0EF531EBF8C8A0018DB36 /* Icon Versioning */, 24E179F123BDAC2C00F928D9 /* Swift Lint Script */, - 2190D297B82EA6160376EC4C /* [CP] Embed Pods Frameworks */, + 8B664BEE6304C1815A957FC6 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -3688,7 +3712,6 @@ CE473D7C1F042F1E00C0ACFD /* coinflip.aiff in Resources */, CE5E6C9A1EB9135000A476DB /* Icon.xcassets in Resources */, 24D5F25022599C0B00225462 /* BarlowSemiCondensed-Light.ttf in Resources */, - 2430A80D23FCCB47002463B5 /* DynamicDonation.storyboard in Resources */, 2494037F23AE0C7100369261 /* SyncProgressHeaderView.xib in Resources */, CE29901A1EFD6DE50093A0F2 /* Localizable.strings in Resources */, 24313C9F23824F5800A83F69 /* Animate.storyboard in Resources */, @@ -3718,21 +3741,26 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 2190D297B82EA6160376EC4C /* [CP] Embed Pods Frameworks */ = { + 156E4E7F04DB5E000B3A1A91 /* [CP] Check Pods Manifest.lock */ = { 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"; + 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; }; 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */ = { @@ -3785,29 +3813,24 @@ 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"; }; - 4C256FDD5564B94BFF10BA73 /* [CP] Check Pods Manifest.lock */ = { + 8B664BEE6304C1815A957FC6 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwallet-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); 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"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 851EE9FAFF1CDBF8F4BAD5F4 /* [CP] Check Pods Manifest.lock */ = { + ABD5154B4DB399A4A81559CD /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3827,21 +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; - }; - CEE0EF531EBF8C8A0018DB36 /* Icon Versioning */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Icon Versioning"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/scripts/icon_versioning.sh\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -3873,9 +3881,11 @@ 24470E3C23A5FFD700ADDA27 /* TouchIdEnabledTests.swift in Sources */, 24470E3023A5F55700ADDA27 /* BRHTTPServerTests.swift in Sources */, 24470E3A23A5FF5700ADDA27 /* TestHelpers.swift in Sources */, + C3B7C43F25620D4400E98A64 /* SupportLitecoinFoundationViewModelTests.swift in Sources */, 2465873923A5AAD100A32E9E /* loafwalletTests.swift in Sources */, 24470E3623A5FDE800ADDA27 /* PhraseTests.swift in Sources */, 24470E4523A608A700ADDA27 /* AmountTests.swift in Sources */, + C3B7C3EE255FF59200E98A64 /* ConstantsTests.swift in Sources */, 24470E2323A5DB7D00ADDA27 /* WalletManagerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4000,7 +4010,6 @@ CEE0EF521EBD14B60018DB36 /* PinTransitioningDelegate.swift in Sources */, CE45C1FD1E7650F5002C3847 /* KVStoreCoordinator.swift in Sources */, 754AE0BC1DFE8A46007FD001 /* BRCore.swift in Sources */, - 2430A80F23FCCE1A002463B5 /* DynamicDonationViewController.swift in Sources */, 22A9A94A1DF61945000F0016 /* BRCameraPlugin.swift in Sources */, 24306797238F3DF900EBEA99 /* BartyCrouch.swift in Sources */, CEC6AA3B1DEE4EB000EE5AFD /* CGRect+Additions.swift in Sources */, @@ -4031,7 +4040,6 @@ CEAA9EA81DC3342E0066731D /* PinView.swift in Sources */, CE1D84B61EAEB2F4002A5D7B /* UIBarButtonItem+Additions.swift in Sources */, CE4B6C1A1E219CA600CF935B /* WalletCoordinator.swift in Sources */, - 240A89B6235F7280005E2A2F /* DonationSetupCell.swift in Sources */, CE6D0E5C1E14BFA700137DF1 /* KeyboardNotificationInfo.swift in Sources */, CE20C8F21DBAF71500C8397A /* ApplicationController.swift in Sources */, 1B3F74231FFB106200CCA50C /* BiometricsSettingsViewController.swift in Sources */, @@ -4072,12 +4080,14 @@ CEE6282A1EA98B6D001035AA /* DispatchQueue+Additions.swift in Sources */, CEC6AA3D1DEE687000EE5AFD /* RadialGradientView.swift in Sources */, 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 */, CEE20C2F1EA3E5820086F724 /* BlinkingView.swift in Sources */, CEC6AA441DEFCDE900EE5AFD /* ModalViewController.swift in Sources */, 24313C8423820C4B00A83F69 /* ReceiveLTCViewController.swift in Sources */, + C3F55655255A195B005F786F /* SupportLitecoinFoundationViewModel.swift in Sources */, CEEC70831E90C07C00EF788E /* Setting.swift in Sources */, CE4B6C1C1E21A96D00CF935B /* LoadingProgressView.swift in Sources */, CE45C1F91E74B400002C3847 /* ManageWalletViewController.swift in Sources */, @@ -4110,6 +4120,7 @@ 2494037E23AE0C7100369261 /* SyncProgressHeaderView.swift in Sources */, CE5E6C941EB7964900A476DB /* WalletDisabledView.swift in Sources */, CEF3E8341DE57166007C0A9E /* AnimatableIcon.swift in Sources */, + C3F55645255A193D005F786F /* SupportLitecoinFoundationView.swift in Sources */, CEF61B161ED2056D00C7EA6A /* NumberFormatter+Additions.swift in Sources */, CEF3E8321DE55540007C0A9E /* CheckView.swift in Sources */, CECCE5A91E0378FB00D99448 /* PinPadViewController.swift in Sources */, @@ -4167,7 +4178,7 @@ CE6DCC301E6666470044257B /* NonScrollingCollectionView.swift in Sources */, 22A9A9471DF61945000F0016 /* BRAPIProxy.swift in Sources */, CE20C9011DBBFFF800C8397A /* Actions.swift in Sources */, - CE20C9191DBE7B8200C8397A /* State.swift in Sources */, + CE20C9191DBE7B8200C8397A /* ReduxState.swift in Sources */, CEEC70811E90C04700EF788E /* SeparatorCell.swift in Sources */, CE20C8FE1DBB133A00C8397A /* SimpleRedux.swift in Sources */, 22122B721F0B8996000E9AB9 /* BRAPIClient+Events.swift in Sources */, @@ -4183,6 +4194,7 @@ CE25BF931DFDA7A600BC67B6 /* MessageUIPresenter.swift in Sources */, CE20C90C1DBC59E600C8397A /* StartFlowPresenter.swift in Sources */, CE20C8FC1DBB0F3A00C8397A /* UIColor+Extension.swift in Sources */, + C3B7C3B9255EABBF00E98A64 /* SupportSafariViewModel.swift in Sources */, CEA3626A1E01150D0061FC0E /* CGContext+Additions.swift in Sources */, 22A9A9541DF61945000F0016 /* BRReplicatedKVStore.swift in Sources */, CE6B6B4A1E54C0CB00B31405 /* SecurityCenterCell.swift in Sources */, @@ -4475,7 +4487,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -4491,12 +4503,12 @@ }; 24470E0123A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 39A1C8DFFA128099F0556A0E /* Pods-loafwallet.debug.xcconfig */; + baseConfigurationReference = 93035AB774472BF9805FD3F9 /* Pods-loafwallet.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 252; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4505,12 +4517,12 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/loafwallet/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.0; + MARKETING_VERSION = 2.8.2; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4524,7 +4536,7 @@ }; 24470E0323A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0B0BFC3BB4EF3438E0FD95C9 /* Pods-loafwalletTests.debug.xcconfig */; + baseConfigurationReference = 9AA160F2A4C1674AC8595E65 /* Pods-loafwalletTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -4603,7 +4615,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 252; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4613,7 +4625,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.0; + MARKETING_VERSION = 2.8.2; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4732,7 +4744,7 @@ }; 2465873F23A5AAD100A32E9E /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 51D52F10840D223E083B6EDA /* Pods-loafwalletTests.testnet.xcconfig */; + baseConfigurationReference = 91361B2DF7CFBF96F66DE835 /* Pods-loafwalletTests.testnet.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -4760,7 +4772,7 @@ }; 2465874023A5AAD100A32E9E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 75D0209A7B6BC4A864CC724C /* Pods-loafwalletTests.release.xcconfig */; + baseConfigurationReference = 5551B367195CB66F70E7147C /* Pods-loafwalletTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -4893,7 +4905,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; @@ -4908,12 +4920,12 @@ }; 75A2A7E51DA5934400A983D8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 17FB6C0C7A4EDEE276391D9A /* Pods-loafwallet.release.xcconfig */; + baseConfigurationReference = 9C4905F581557D8FD607EB73 /* Pods-loafwallet.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 252; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -4921,12 +4933,12 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/loafwallet/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.0; + MARKETING_VERSION = 2.8.2; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4943,7 +4955,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 252; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -4952,7 +4964,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.0; + MARKETING_VERSION = 2.8.2; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5023,7 +5035,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -5038,12 +5050,12 @@ }; CEA7E69C1F0AAA84001F8C27 /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9F2DD187A660718095013AA0 /* Pods-loafwallet.testnet.xcconfig */; + baseConfigurationReference = 012F76A05D15F227D7C3EF9A /* Pods-loafwallet.testnet.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 252; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5052,12 +5064,12 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/loafwallet/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.0; + MARKETING_VERSION = 2.8.2; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5075,7 +5087,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 252; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5085,7 +5097,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.0; + MARKETING_VERSION = 2.8.2; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme deleted file mode 100644 index 2b117aa58..000000000 --- a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet WatchKit App.xcscheme +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme new file mode 100644 index 000000000..150bb23ca --- /dev/null +++ b/loafwallet.xcodeproj/xcshareddata/xcschemes/loafwallet.xcscheme @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/loafwallet/DonationSetupCell.swift b/loafwallet/DonationSetupCell.swift deleted file mode 100644 index 1c5c42345..000000000 --- a/loafwallet/DonationSetupCell.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// DonationSetupCell.swift -// loafwallet -// -// Created by Kerry Washington on 10/22/19. -// Copyright © 2019 Litecoin Foundation. All rights reserved. -// - -import Foundation -import UIKit - -class DonationSetupCell: UIView { - - static let defaultHeight: CGFloat = 72.0 - - init(store: Store, isLTCSwapped: Bool) { - self.store = store - self.isLTCSwapped = isLTCSwapped - donateButton = ShadowButton(title: S.Donate.title, type: .tertiary) - super.init(frame: .zero) - setupViews() - } - - let border = UIView(color: .secondaryShadow) - var isLTCSwapped: Bool - var donateButton = ShadowButton(title: S.Donate.title, type: .tertiary) - var didTapToDonate:(() -> ())? - private let store: Store - - private func setupViews() { - - addSubview(donateButton) - addSubview(border) - - donateButton.translatesAutoresizingMaskIntoConstraints = false - donateButton.addTarget(self, action: #selector(donateToLF), for: .touchUpInside) - - guard let fiatSymbol = store.state.currentRate?.currencySymbol else { return } - donateButton.title = String(format: S.Donate.title, isLTCSwapped ? "\(fiatSymbol)":"Ł") - - let viewsDictionary = ["donateButton": donateButton, "border": border] - var viewConstraints = [NSLayoutConstraint]() - - let constraintsHorizontal = NSLayoutConstraint.constraints(withVisualFormat: "H:|-25-[donateButton(190)]-25-|", options: [], metrics: nil, views: viewsDictionary) - viewConstraints += constraintsHorizontal - - let descriptionConstraintVertical = NSLayoutConstraint.constraints(withVisualFormat: "V:|-16-[donateButton]-16-|", options: [], metrics: nil, views: viewsDictionary) - - viewConstraints += descriptionConstraintVertical - border.constrainBottomCorners(height: 1.0) - NSLayoutConstraint.activate(viewConstraints) - } - - @objc func donateToLF() { - self.didTapToDonate?() - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} - diff --git a/loafwallet/DynamicDonationViewController.swift b/loafwallet/DynamicDonationViewController.swift deleted file mode 100644 index 41c309d97..000000000 --- a/loafwallet/DynamicDonationViewController.swift +++ /dev/null @@ -1,230 +0,0 @@ -// -// DynamicDonationViewController.swift -// loafwallet -// -// Created by Kerry Washington on 2/18/20. -// Copyright © 2020 Litecoin Foundation. All rights reserved. -// - -import Foundation -import UIKit -import LocalAuthentication -import FirebaseAnalytics - - -class DynamicDonationViewController: UIViewController, Subscriber { - - @IBOutlet weak var dialogView: UIView! - @IBOutlet weak var dialogTitle: UILabel! - - @IBOutlet weak var staticSendLabel: UILabel! - @IBOutlet weak var processingTimeLabel: UILabel! - - @IBOutlet weak var sendAmountLabel: UILabel! - @IBOutlet weak var donationAddressLabel: UILabel! - - @IBOutlet weak var staticAmountToDonateLabel: UILabel! - @IBOutlet weak var staticNetworkFeeLabel: UILabel! - @IBOutlet weak var staticTotalCostLabel: UILabel! - - @IBOutlet weak var networkFeeLabel: UILabel! - @IBOutlet weak var totalCostLabel: UILabel! - @IBOutlet weak var buttonsView: UIView! - @IBOutlet weak var containerView: UIView! - @IBOutlet weak var accountPickerView: UIPickerView! - @IBOutlet weak var donationSlider: UISlider! - @IBOutlet weak var decreaseDonationButton: UIButton! - @IBOutlet weak var increaseDonationButton: UIButton! - @IBOutlet weak var donationValueLabel: UILabel! - - - var cancelButton = ShadowButton(title: S.Button.cancel, type: .secondary) - var donateButton = ShadowButton(title: S.Donate.word, type: .flatLitecoinBlue, image: (LAContext.biometricType() == .face ? #imageLiteral(resourceName: "FaceId") : #imageLiteral(resourceName: "TouchId"))) - - var successCallback: (() -> Void)? - var cancelCallback: (() -> Void)? - - var store: Store? - var feeType: FeeType? - var senderClass: Sender? - var selectedRate: Rate? - var isUsingBiometrics: Bool = false - var balance: UInt64 = 0 - var finalDonationAmount = Satoshis(rawValue: kDonationAmount) - var finalDonationAddress = LWDonationAddress.litwalletHardware.address - var finalDonationMemo = LWDonationAddress.litwalletHardware.rawValue - - let selectionFeedbackGenerator = UISelectionFeedbackGenerator() - let impactFeedbackGenerator: ( - light: UIImpactFeedbackGenerator, - heavy: UIImpactFeedbackGenerator) = ( - UIImpactFeedbackGenerator(style: .light), - UIImpactFeedbackGenerator(style: .heavy) - ) - override func viewDidLoad() { - super.viewDidLoad() - configureViews() - configureDataAndFunction() - } - - private func configureViews() { - - selectionFeedbackGenerator.prepare() - impactFeedbackGenerator.light.prepare() - impactFeedbackGenerator.heavy.prepare() - dialogView.layer.cornerRadius = 6.0 - dialogView.layer.masksToBounds = true - - let blurEffect = UIBlurEffect(style: .dark) - let blurEffectView = UIVisualEffectView(effect: blurEffect) - blurEffectView.frame = view.bounds - blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] - view.addSubview(blurEffectView) - view.sendSubview(toBack: blurEffectView) - - dialogTitle.text = S.Donate.titleConfirmation - staticSendLabel.text = S.Confirmation.staticAddressLabel.capitalizingFirstLetter() - staticAmountToDonateLabel.text = S.Confirmation.donateLabel - staticNetworkFeeLabel.text = S.Confirmation.feeLabel - staticTotalCostLabel.text = S.Confirmation.totalLabel - donationAddressLabel.text = LWDonationAddress.litwalletHardware.address - - processingTimeLabel.text = String(format: S.Confirmation.processingAndDonationTime, "2.5-5") - - donationSlider.setValue(Float(kDonationAmount/balance), animated: true) - donationSlider.addTarget(self, action: #selector(sliderDidChange), for: .valueChanged) - donationSlider.minimumValue = Float(Double(kDonationAmount)/Double(balance)) - donationSlider.maximumValue = 1.0 - - let amount = Satoshis(rawValue: UInt64(kDonationAmount)) - updateDonationLabels(donationAmount: amount) - setupButtonLayouts() - } - - private func setupButtonLayouts() { - cancelButton.translatesAutoresizingMaskIntoConstraints = false - donateButton.translatesAutoresizingMaskIntoConstraints = false - buttonsView.addSubview(cancelButton) - buttonsView.addSubview(donateButton) - - let viewsDictionary = ["cancelButton": cancelButton, "donateButton": donateButton] - var viewConstraints = [NSLayoutConstraint]() - - let constraintsHorizontal = NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[cancelButton(170)]-8-[donateButton(170)]-10-|", options: [], metrics: nil, views: viewsDictionary) - viewConstraints += constraintsHorizontal - - let cancelConstraintVertical = NSLayoutConstraint.constraints(withVisualFormat: "V:|-[cancelButton]-|", options: [], metrics: nil, views: viewsDictionary) - viewConstraints += cancelConstraintVertical - - let sendConstraintVertical = NSLayoutConstraint.constraints(withVisualFormat: "V:|-[donateButton]-|", options: [], metrics: nil, views: viewsDictionary) - - viewConstraints += sendConstraintVertical - NSLayoutConstraint.activate(viewConstraints) - } - - private func configureDataAndFunction() { - - cancelButton.tap = strongify(self) { myself in - myself.cancelCallback?() - LWAnalytics.logEventWithParameters(itemName: ._20200225_DCD) - } - donateButton.tap = strongify(self) { myself in - myself.successCallback?() - } - - guard let store = store else { - NSLog("ERROR: Store not initialized") - return - } - - store.subscribe(self, selector: { $0.walletState.balance != $1.walletState.balance }, - callback: { - if let balance = $0.walletState.balance { - self.balance = balance - } - }) - } - - private func maxAmountLessFees() -> Float { - var adjustedBalance = Float(Double(balance)) - if let sender = senderClass { - let maxFee = sender.feeForTx(amount: balance) - adjustedBalance = Float(Double(balance) - Double(maxFee)) - } - return adjustedBalance - } - - private func updateDonationLabels(donationAmount: Satoshis) { - - guard let sender = senderClass else { - NSLog("ERROR: Sender not initialized") - return - } - guard let state = store?.state else { - NSLog("ERROR: State not initialized") - return - } - - self.finalDonationAmount = donationAmount - sendAmountLabel.text = DisplayAmount(amount: donationAmount, state: state, selectedRate: state.currentRate, minimumFractionDigits: 2).combinedDescription - let feeAmount = sender.feeForTx(amount: donationAmount.rawValue) - networkFeeLabel.text = DisplayAmount(amount:Satoshis(rawValue: feeAmount), state: state, selectedRate: state.currentRate, minimumFractionDigits: 2).combinedDescription.combinedFeeReplacingZeroFeeWithOneCent() - totalCostLabel.text = DisplayAmount(amount: donationAmount + Satoshis(rawValue: feeAmount), state: state, selectedRate: state.currentRate, minimumFractionDigits: 2).combinedDescription - donationValueLabel.text = totalCostLabel.text - } - - @objc func sliderDidChange() { - let newDonationValue = donationSlider.value*maxAmountLessFees() - updateDonationLabels(donationAmount: Satoshis(rawValue: UInt64(newDonationValue))) - selectionFeedbackGenerator.selectionChanged() - } - - @IBAction func reduceDonationAction(_ sender: Any) { - impactFeedbackGenerator.light.impactOccurred() - - if donationSlider.value >= Float(kDonationAmount/balance) { - let newValue = donationSlider.value - Float(Double(1000000)/Double(balance)) - if newValue >= donationSlider.minimumValue { - donationSlider.setValue(newValue, animated: true) - let newDonationValue = donationSlider.value*maxAmountLessFees() - updateDonationLabels(donationAmount: Satoshis(rawValue: UInt64(newDonationValue))) - } - } - } - - @IBAction func increaseDonationAction(_ sender: Any) { - impactFeedbackGenerator.heavy.impactOccurred() - - let newValue = donationSlider.value + Float( Double(1000000)/Double(balance)) - if newValue <= 1.0 { - donationSlider.setValue(newValue, animated: true) - let newDonationValue = donationSlider.value*maxAmountLessFees() - updateDonationLabels(donationAmount: Satoshis(rawValue: UInt64(newDonationValue))) - } - } -} - -extension DynamicDonationViewController: UIPickerViewDataSource, UIPickerViewDelegate { - - func numberOfComponents(in pickerView: UIPickerView) -> Int { - return 1 - } - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - return LWDonationAddress.allValues.count - } - - func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { - let title = S.Donate.toThe + " " + LWDonationAddress.allValues[row].rawValue - let label = UILabel() - label.textAlignment = .center - label.attributedText = NSAttributedString(string: title, attributes: [NSAttributedString.Key.font : UIFont.barlowRegular(size: 17), NSAttributedString.Key.foregroundColor: UIColor.black]) - return label - } - - func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { - self.donationAddressLabel.text = LWDonationAddress.allValues[row].address - self.finalDonationAddress = LWDonationAddress.allValues[row].address - self.finalDonationMemo = LWDonationAddress.allValues[row].rawValue - } -} diff --git a/loafwallet/Storyboards/DynamicDonation.storyboard b/loafwallet/Storyboards/DynamicDonation.storyboard deleted file mode 100644 index 2b8d6fa49..000000000 --- a/loafwallet/Storyboards/DynamicDonation.storyboard +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - - - BarlowSemiCondensed-Light - - - BarlowSemiCondensed-Medium - - - BarlowSemiCondensed-Regular - - - BarlowSemiCondensed-SemiBold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 a4df72bfb..66d3c36ef 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -6,8 +6,7 @@ // Copyright © 2019 Litecoin Foundation. All rights reserved. import UIKit -import Foundation -import SwiftyJSON +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..97b7394bc 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -9,22 +9,6 @@ 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" @@ -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 a53f610bf..604c0b7a1 100644 --- a/loafwallet/src/ViewModels/Amount.swift +++ b/loafwallet/src/ViewModels/Amount.swift @@ -46,7 +46,7 @@ struct Amount { format.isLenient = true format.numberStyle = .currency format.generatesDecimalNumbers = true - format.negativeFormat = format.positiveFormat.replacingCharacters(in: format.positiveFormat.range(of: "#")!, with: "-#") + format.negativePrefix = "-" guard let string = format.string(from: Double(amount)/100000000.0*rate.rate as NSNumber) else { return "" } return string } @@ -60,7 +60,7 @@ struct Amount { format.isLenient = true format.numberStyle = .currency format.generatesDecimalNumbers = true - format.negativeFormat = format.positiveFormat.replacingCharacters(in: format.positiveFormat.range(of: "#")!, with: "-#") + format.negativePrefix = "-" format.currencyCode = "LTC" switch maxDigits { @@ -89,7 +89,7 @@ struct Amount { format.isLenient = true format.numberStyle = .currency format.generatesDecimalNumbers = true - format.negativeFormat = format.positiveFormat.replacingCharacters(in: format.positiveFormat.range(of: "#")!, with: "-#") + format.negativePrefix = "-" format.currencySymbol = rate.currencySymbol return format } @@ -97,7 +97,7 @@ struct Amount { struct DisplayAmount { let amount: Satoshis - let state: State + let state: ReduxState let selectedRate: Rate? let minimumFractionDigits: Int? @@ -129,7 +129,7 @@ struct DisplayAmount { format.isLenient = true format.numberStyle = .currency format.generatesDecimalNumbers = true - format.negativeFormat = format.positiveFormat.replacingCharacters(in: format.positiveFormat.range(of: "#")!, with: "-#") + format.negativePrefix = "-" if let rate = selectedRate { format.currencySymbol = rate.currencySymbol } else if let rate = state.currentRate { @@ -146,7 +146,7 @@ struct DisplayAmount { format.isLenient = true format.numberStyle = .currency format.generatesDecimalNumbers = true - format.negativeFormat = format.positiveFormat.replacingCharacters(in: format.positiveFormat.range(of: "#")!, with: "-#") + format.negativePrefix = "-" format.currencyCode = "LTC" switch state.maxDigits { 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") } diff --git a/scripts/icon_versioning.sh b/scripts/icon_versioning.sh deleted file mode 100755 index f0a55780a..000000000 --- a/scripts/icon_versioning.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/bin/sh -export PATH=/opt/local/bin/:/opt/local/sbin:$PATH:/usr/local/bin: - -## BUILD NUMBERS - -git=`sh /etc/profile; which git` -branch=`"$git" rev-parse --abbrev-ref HEAD` -commit=`"$git" rev-parse --short HEAD` -version=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${INFOPLIST_FILE}"` -build_num=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_FILE}"` -DSYM_INFO_PLIST="${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist" - -## ICON VERSIONING - -convertPath=`which convert` -echo ${convertPath} -if [[ ! -f ${convertPath} || -z ${convertPath} ]]; then -echo "WARNING: Skipping Icon versioning, you need to install ImageMagick, you can use brew to simplify process: -brew install imagemagick" -exit 0; -fi - -gsPath=`which gs` -echo ${gsPath} -if [[ ! -f ${gsPath} || -z ${gsPath} ]]; then -echo "WARNING: Skipping Icon versioning, you need to install ghostscript (fonts) first, you can use brew to simplify process: -brew install ghostscript" -exit 0; -fi - -caption="${version}-(${build_num})\n${branch}\n${commit}" -echo $caption - -function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname \"$1\"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename \"$1\"`"; else echo "$cur_dir/`basename \"$1\"`"; fi; fi; popd > /dev/null; } - -function processIcon() { -base_file=$1 - -cd "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" -base_path=`find . -maxdepth 2 -name ${base_file}` - -real_path=$( abspath "${base_path}" ) -echo "base path ${real_path}" - -if [[ ! -f ${base_path} || -z ${base_path} ]]; then -return; -fi - -# TODO: if they are the same we need to fix it by introducing temp -target_file=`basename $base_path` -target_path="${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/${target_file}" - -base_tmp_normalizedFileName="${base_file%.*}-normalized.${base_file##*.}" -base_tmp_path=`dirname $base_path` -base_tmp_normalizedFilePath="${base_tmp_path}/${base_tmp_normalizedFileName}" - -stored_original_file="${base_tmp_normalizedFilePath}-tmp" -if [[ -f ${stored_original_file} ]]; then -echo "found previous file at path ${stored_original_file}, using it as base" -mv "${stored_original_file}" "${base_path}" -fi - -if [ $CONFIGURATION = "Release" ]; then -cp "${base_path}" "$target_path" -return 0; -fi - -echo "Reverting optimized PNG to normal" -# Normalize -echo "xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations -q ${base_path} ${base_tmp_normalizedFilePath}" -xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations -q "${base_path}" "${base_tmp_normalizedFilePath}" - -# move original pngcrush png to tmp file -echo "moving pngcrushed png file at ${base_path} to ${stored_original_file}" -#rm "$base_path" -mv "$base_path" "${stored_original_file}" - -# Rename normalized png's filename to original one -echo "Moving normalized png file to original one ${base_tmp_normalizedFilePath} to ${base_path}" -mv "${base_tmp_normalizedFilePath}" "${base_path}" - -width=`identify -format %w ${base_path}` -height=`identify -format %h ${base_path}` -band_height=$((($height * 47) / 100)) -band_position=$((0)) -text_position=$(($band_position - 3)) -point_size=$(((13 * $width) / 100)) - -echo "Image dimensions ($width x $height) - band height $band_height @ $band_position - point size $point_size" - -# -# blur band and text -# -convert ${base_path} -blur 10x8 /tmp/blurred.png -convert /tmp/blurred.png -gamma 0 -fill white -draw "rectangle 0,0,$width,$band_height" /tmp/mask.png -convert -size ${width}x${band_height} xc:none -fill 'rgba(0,0,0,0.2)' -draw "rectangle 0,0,$width,$band_height" /tmp/labels-base.png -convert -background none -size ${width}x${band_height} -pointsize $point_size -fill white -gravity center -gravity South caption:"$caption" /tmp/labels.png - -convert ${base_path} /tmp/blurred.png /tmp/mask.png -composite /tmp/temp.png - -rm /tmp/blurred.png -rm /tmp/mask.png - -# -# compose final image -# -filename=New${base_file} -convert /tmp/temp.png /tmp/labels-base.png -geometry +0+$band_position -composite /tmp/labels.png -geometry +0+$text_position -geometry +${w}-${h} -composite "${target_path}" - -# clean up -rm /tmp/temp.png -rm /tmp/labels-base.png -rm /tmp/labels.png - -echo "Overlayed ${target_path}" -} - -icon_count=`/usr/libexec/PlistBuddy -c "Print CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles" "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}" | wc -l` -last_icon_index=$((${icon_count} - 2)) - -i=0 -while [ $i -lt $last_icon_index ]; do -icon=`/usr/libexec/PlistBuddy -c "Print CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles:$i" "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"` - -if [[ $icon == *.png ]] || [[ $icon == *.PNG ]] -then -processIcon $icon -else -processIcon "${icon}.png" -processIcon "${icon}@2x.png" -processIcon "${icon}@3x.png" -fi -let i=i+1 -done - -processIcon "AppIcon72x72~ipad*" -processIcon "AppIcon72x72@2x~ipad*" -processIcon "AppIcon76x76~ipad*" -processIcon "AppIcon76x76@2x~ipad*" From 6883f6b00fee7d59fc7906a246f735804ebe79e5 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 5 Dec 2020 21:39:48 +0000 Subject: [PATCH 05/35] [Release v2.8.3] Merge into Master (#167) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * version bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov --- .gitignore | 1 + 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 - loafwallet.xcodeproj/project.pbxproj | 12 +-- loafwallet/BRAPIClient+Wallet.swift | 5 +- loafwallet/BuyWKWebViewController.swift | 4 +- .../SupportLitecoinFoundationView.swift | 88 +++++++++---------- .../SupportLitecoinFoundationViewModel.swift | 12 ++- loafwallet/SupportSafariView.swift | 5 +- loafwallet/ar.lproj/LaunchScreen.strings | 1 - loafwallet/id.lproj/LaunchScreen.strings | 1 - loafwallet/src/Constants/Constants.swift | 10 +++ 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 +- .../ViewControllers/AboutViewController.swift | 4 +- .../RootModals/MenuViewController.swift | 5 +- .../RootModals/SendViewController.swift | 28 +----- 55 files changed, 161 insertions(+), 140 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/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.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/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/SupportLitecoinFoundationView.swift b/loafwallet/SupportLitecoinFoundationView.swift index f9694228b..a07e269a7 100644 --- a/loafwallet/SupportLitecoinFoundationView.swift +++ b/loafwallet/SupportLitecoinFoundationView.swift @@ -8,11 +8,10 @@ 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 +21,63 @@ 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..b1cb36563 100644 --- a/loafwallet/SupportSafariView.swift +++ b/loafwallet/SupportSafariView.swift @@ -39,8 +39,7 @@ 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 @@ -57,7 +56,7 @@ struct SupportSafariView: UIViewRepresentable { } } }) - } + } } func makeUIView(context: Context) -> WKWebView { diff --git a/loafwallet/ar.lproj/LaunchScreen.strings b/loafwallet/ar.lproj/LaunchScreen.strings index 139597f9c..8b1378917 100644 --- a/loafwallet/ar.lproj/LaunchScreen.strings +++ b/loafwallet/ar.lproj/LaunchScreen.strings @@ -1,2 +1 @@ - diff --git a/loafwallet/id.lproj/LaunchScreen.strings b/loafwallet/id.lproj/LaunchScreen.strings index 139597f9c..8b1378917 100644 --- a/loafwallet/id.lproj/LaunchScreen.strings +++ b/loafwallet/id.lproj/LaunchScreen.strings @@ -1,2 +1 @@ - diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index 97b7394bc..8db925f08 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -45,6 +45,16 @@ 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/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index f7e33df56..4fe741355 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -423,7 +423,7 @@ enum S { enum MenuButton { static let security = NSLocalizedString("MenuButton.security", value: "**Security Center**", comment: "Menu button title") - static let support = NSLocalizedString("MenuButton.support", value: "**Support**", comment: "Menu button title") + static let support = NSLocalizedString("MenuButton.customer.support", value: "**Customer support**", comment: "Menu button title") static let settings = NSLocalizedString("MenuButton.settings", value: "**Settings**", comment: "Menu button title") static let lock = NSLocalizedString("MenuButton.lock", value: "**Lock Wallet**", comment: "Menu button title") static let buy = NSLocalizedString("MenuButton.buy", value: "**Buy Litecoin**", comment: "Buy Litecoin title") diff --git a/loafwallet/src/Controls/MenuButtonType.swift b/loafwallet/src/Controls/MenuButtonType.swift index 984527b66..f320b13af 100644 --- a/loafwallet/src/Controls/MenuButtonType.swift +++ b/loafwallet/src/Controls/MenuButtonType.swift @@ -11,6 +11,7 @@ import UIKit enum MenuButtonType { case security case support + case supportLF case settings case lock @@ -20,6 +21,8 @@ enum MenuButtonType { return S.MenuButton.security case .support: return S.MenuButton.support + case .supportLF: + return S.SupportLitecoinFoundation.title case .settings: return S.MenuButton.settings case .lock: @@ -33,6 +36,8 @@ enum MenuButtonType { return #imageLiteral(resourceName: "Shield") case .support: return #imageLiteral(resourceName: "FaqFill") + case .supportLF: + return #imageLiteral(resourceName: "BuyLitecoin") case .settings: return #imageLiteral(resourceName: "Settings") case .lock: diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index 8dd7d4715..843b67005 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -8,7 +8,7 @@ import UIKit import LocalAuthentication - +import SwiftUI class ModalPresenter : Subscriber, Trackable { @@ -355,6 +355,13 @@ class ModalPresenter : Subscriber, Trackable { 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) @@ -526,7 +533,27 @@ 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.dismiss(animated: true) { + //TODO: Track in Analytics + } + } + + window.rootViewController?.present(supportLFView, animated: true, completion: nil) + } + private func presentSecurityCenter() { guard let walletManager = walletManager else { return } let securityCenter = SecurityCenterViewController(store: store, walletManager: walletManager) diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 9b40160e3..014f4b229 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1266,3 +1266,6 @@ /* Support the Litecoin Foundation */ "SupportTheFoundation.title" = "Support the Litecoin Foundation"; + +/* Menu button title */ +"MenuButton.customer.support" = "Customer support"; diff --git a/loafwallet/src/Strings/ar.lproj/Localizable.strings b/loafwallet/src/Strings/ar.lproj/Localizable.strings index a672cd2e3..eb93508a3 100644 --- a/loafwallet/src/Strings/ar.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ar.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen website label */ "About.blog" = "Website"; @@ -1241,6 +1240,9 @@ /* Message for luxury fee */ "FeeSelector.luxuryMessage" = ""; +/* Menu button title */ +"MenuButton.customer.support" = ""; + /* Delete database title */ "WipeWallet.alertDeleteTitle" = ""; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index 3f7657a3d..c13e06dba 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blog"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Køb Litecoin"; +/* Menu button title */ +"MenuButton.customer.support" = "Kunde support"; + /* Menu button title */ "MenuButton.lock" = "Lås pung"; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index bcefc1ba4..d29a0be9c 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blog"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Litecoin kaufen"; +/* Menu button title */ +"MenuButton.customer.support" = "Kundendienst"; + /* Menu button title */ "MenuButton.lock" = "Wallet sperren"; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index 960ffc336..c8887d155 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen website label */ "About.blog" = "Website"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Buy Litecoin"; +/* Menu button title */ +"MenuButton.customer.support" = "Customer support"; + /* Menu button title */ "MenuButton.lock" = "Lock Wallet"; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 1ad53e09c..728f633f2 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blog"; @@ -426,6 +425,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Comprar Litecoins"; +/* Menu button title */ +"MenuButton.customer.support" = "Atención al cliente"; + /* Menu button title */ "MenuButton.lock" = "Bloquear cartera"; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index 8ad5c11bf..2abc1bb65 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blogue"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Acheter des Litecoins"; +/* Menu button title */ +"MenuButton.customer.support" = "Service client"; + /* Menu button title */ "MenuButton.lock" = "Verrouiller le portefeuille"; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 66fadc81d..2230dac22 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen website label */ "About.blog" = "Situs Web"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Membeli Litecoin"; +/* Menu button title */ +"MenuButton.customer.support" = "Dukungan pelanggan"; + /* Menu button title */ "MenuButton.lock" = "Dompet Kunci"; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index 75c6f7e89..1a0cdb4f4 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blog"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Acquista Litecoin"; +/* Menu button title */ +"MenuButton.customer.support" = "Servizio Clienti"; + /* Menu button title */ "MenuButton.lock" = "Blocca Portafoglio"; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index dd0bd9fce..3a796d833 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "ブログ"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "リテコインを購入"; +/* Menu button title */ +"MenuButton.customer.support" = "顧客サポート"; + /* Menu button title */ "MenuButton.lock" = "ウォレットにロックを設定する"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index fffd6620e..8608a3632 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "블로그"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Litecoin 구매"; +/* Menu button title */ +"MenuButton.customer.support" = "고객 지원"; + /* Menu button title */ "MenuButton.lock" = "지갑 잠그기"; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index 0bb354677..71b3aad49 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blog"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Litecoins Kopen"; +/* Menu button title */ +"MenuButton.customer.support" = "Klantenservice"; + /* Menu button title */ "MenuButton.lock" = "Portemonnee Vergrendelen"; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index 200fd59c3..9a8859099 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blog"; @@ -426,6 +425,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Comprar Litecoins"; +/* Menu button title */ +"MenuButton.customer.support" = "Suporte ao cliente"; + /* Menu button title */ "MenuButton.lock" = "Bloquear Carteira"; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index 7ab4875de..ac1ea27b4 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Блог"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Купить Litecoin"; +/* Menu button title */ +"MenuButton.customer.support" = "Служба поддержки"; + /* Menu button title */ "MenuButton.lock" = "Заблокировать кошелек"; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index fdc589c34..f329a32a5 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "Blogg"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "Köp Litecoin"; +/* Menu button title */ +"MenuButton.customer.support" = "Kundsupport"; + /* Menu button title */ "MenuButton.lock" = "Lås plånbok"; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index 96343cc7b..d6e20fd6a 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "博客"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "购买莱特币"; +/* Menu button title */ +"MenuButton.customer.support" = "客户支持"; + /* Menu button title */ "MenuButton.lock" = "锁住钱包"; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index e54c9a5dc..aede921a8 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -1,4 +1,3 @@ - /* About screen blog label */ "About.blog" = "部落格"; @@ -425,6 +424,9 @@ /* Buy Litecoin title */ "MenuButton.buy" = "購買萊特幣"; +/* Menu button title */ +"MenuButton.customer.support" = "客戶支持"; + /* Menu button title */ "MenuButton.lock" = "鎖定電子錢包"; 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") } } diff --git a/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift b/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift index 46fd998e5..e9677ff8e 100644 --- a/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/MenuViewController.swift @@ -13,13 +13,14 @@ class MenuViewController : UIViewController, Trackable { //MARK: - Public var didTapSecurity: (() -> 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..8a4daca80 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]) ]) @@ -176,22 +168,6 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self?.addressCell.textField.resignFirstResponder() } } - - 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 b90e23141e1bfaf4937ba3570b2256e5c51a77a5 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 21 Dec 2020 20:41:17 +0000 Subject: [PATCH 06/35] [Merge v2.9.0] into Master (#170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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” * version bump * Minor bugfix: reordered UD address lines to set the first responder…duh * build update * Resolve conflicts Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov --- .gitignore | 1 + Podfile | 4 +- Resources/Logo-Full-Mono@3x.png | Bin 0 -> 22766 bytes loafwallet.xcodeproj/project.pbxproj | 139 +++++-- .../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 | 20 +- loafwallet/SupportSafariViewModel.swift | 6 +- loafwallet/UnstoppableDomainView.swift | 117 ++++++ loafwallet/UnstoppableDomainViewModel.swift | 107 +++++ loafwallet/src/Constants/Constants.swift | 6 +- loafwallet/src/Constants/Strings.swift | 11 + .../Extensions/UserDefaults+Additions.swift | 5 - loafwallet/src/ModalPresenter.swift | 379 +++++++++--------- .../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 | 3 +- 49 files changed, 1144 insertions(+), 413 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..5ae720544 100644 --- a/Podfile +++ b/Podfile @@ -9,8 +9,8 @@ platform :ios, '13.0' 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 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 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..3304ec8b6 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 = ( @@ -3509,11 +3558,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 +3774,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 +3793,7 @@ /* Begin PBXShellScriptBuildPhase section */ 156E4E7F04DB5E000B3A1A91 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputFileListPaths = ( @@ -3765,7 +3815,7 @@ }; 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputPaths = ( @@ -3779,7 +3829,7 @@ }; 24E179F123BDAC2C00F928D9 /* Swift Lint Script */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 8; files = ( ); inputFileListPaths = ( @@ -3791,13 +3841,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 +3859,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 +3901,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 +3944,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 +4081,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 +4120,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 +4169,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 +4227,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 +4261,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 */, @@ -4508,7 +4583,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4522,7 +4597,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.9.0; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4615,7 +4690,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4625,7 +4700,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.9.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4925,7 +5000,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -4938,7 +5013,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.9.0; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4955,7 +5030,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -4964,7 +5039,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.9.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5055,7 +5130,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5069,7 +5144,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.9.0; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5087,7 +5162,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5097,7 +5172,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.8.3; + MARKETING_VERSION = 2.9.0; 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..2dcddc2f3 100644 --- a/loafwallet/SupportLitecoinFoundationView.swift +++ b/loafwallet/SupportLitecoinFoundationView.swift @@ -16,9 +16,6 @@ struct SupportLitecoinFoundationView: View { @ObservedObject var viewModel: SupportLitecoinFoundationViewModel - @State - var supportLTCAddress = "" - @State private var showSupportLFPage: Bool = false @@ -31,53 +28,67 @@ struct SupportLitecoinFoundationView: View { } var body: some View { - - VStack { - Spacer() + VStack { + 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) + } + } +} + +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") } - Spacer() } } diff --git a/loafwallet/SupportLitecoinFoundationViewModel.swift b/loafwallet/SupportLitecoinFoundationViewModel.swift index 1ce550ecf..5076a70a4 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..77514bd70 100644 --- a/loafwallet/SupportSafariView.swift +++ b/loafwallet/SupportSafariView.swift @@ -39,24 +39,8 @@ 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..a77738554 100644 --- a/loafwallet/SupportSafariViewModel.swift +++ b/loafwallet/SupportSafariViewModel.swift @@ -8,10 +8,6 @@ import Foundation -class SupportSafariViewModel: ObservableObject { - - @Published - var supportLTCAddress = "" - +class SupportSafariViewModel: ObservableObject { 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..a396560c9 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 { @@ -43,8 +46,7 @@ struct FoundationSupport { /// Litecoin Foundation main donation address: MVZj7gBRwcVpa9AAWdJm8A3HqTst112eJe /// 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..aed89a5d3 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() @@ -358,10 +358,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) @@ -374,7 +380,7 @@ class ModalPresenter : Subscriber, Trackable { } return root } - + private func presentLoginScan() { guard let top = topViewController else { return } let present = presentScan(parent: top) @@ -385,61 +391,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 +497,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 +524,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,25 +544,20 @@ 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 } } - + window.rootViewController?.present(supportLFView, animated: true, completion: nil) - + } private func presentSecurityCenter() { @@ -576,13 +582,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 +606,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 +638,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 +660,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 +675,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) @@ -691,24 +696,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 +740,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 +762,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 +776,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 +789,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 +804,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 +842,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 +856,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 +866,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 +880,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 +890,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 +912,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 +929,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 +944,5 @@ 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..b21b8e8cb 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,64 @@ 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 +133,11 @@ 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 +153,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.becomeFirstResponder() + self.addressCell.textField.isHidden = false + self.addressCell.textField.text = resolvedUDAddress + } } - + 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 +198,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 +228,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track } handleRequest(request) } - + @objc private func scanTapped() { descriptionCell.textView.resignFirstResponder() addressCell.textField.resignFirstResponder() @@ -221,12 +237,12 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self?.handleRequest(request) } } - + @objc private func sendTapped() { if addressCell.textField.isFirstResponder { - addressCell.textField.resignFirstResponder() + 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 +270,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 +291,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 +339,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 +385,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 +408,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 +429,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 +438,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 +456,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 +466,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..1d7dbe5aa 100644 --- a/loafwalletTests/Constants Tests/ConstantsTests.swift +++ b/loafwalletTests/Constants Tests/ConstantsTests.swift @@ -13,6 +13,5 @@ class ConstantsTests: XCTestCase { func testLFDonationAddressPage() throws { XCTAssertTrue(FoundationSupport.url.absoluteString == "https://lite-wallet.org/support_address.html" ) - } - + } } From a030aab8bda9c229f3c363c688974664a988e437 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 10 Jan 2021 01:46:58 +0000 Subject: [PATCH 07/35] [Merge v3.0.0] into Master (#183) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- Podfile | 3 +- TodayExtension/ar.lproj/MainInterface.strings | 14 - loafwallet.xcodeproj/project.pbxproj | 209 +- .../xcshareddata/swiftpm/Package.resolved | 16 + loafwallet/AnimatedCardView.swift | 66 + loafwallet/AnimatedCardViewModel.swift | 26 + loafwallet/AppDelegate.swift | 8 +- loafwallet/Assets.xcassets/Contents.json | 6 +- .../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 .../colorImageBlue.imageset/Contents.json | 21 + .../colorImageBlue.imageset/colorBlue.png | Bin 0 -> 1702 bytes .../Contents.json | 38 + .../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 | 277 +++ 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 | 213 ++ loafwallet/Storyboards/Alerts.storyboard | 130 +- loafwallet/Storyboards/Card.storyboard | 27 + loafwallet/Storyboards/Main.storyboard | 57 +- loafwallet/Storyboards/Spend.storyboard | 551 ----- .../XIBs/SyncProgressHeaderView.xib | 14 +- .../SupportLitecoinFoundationView.swift | 2 +- loafwallet/SupportSafariView.swift | 1 - loafwallet/TabBarViewController.swift | 37 +- loafwallet/TransactionsViewController.swift | 23 +- loafwallet/TransactionsViewModel.swift | 26 + loafwallet/UnstoppableDomainView.swift | 15 +- loafwallet/UnstoppableDomainViewModel.swift | 8 +- 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 | 19 +- loafwallet/src/Constants/Strings.swift | 89 +- 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 | 26 +- loafwallet/src/Sender.swift | 2 +- loafwallet/src/SimpleRedux/Actions.swift | 2 +- .../Strings/Base.lproj/Localizable.strings | 123 + .../src/Strings/ar.lproj/Localizable.strings | 1268 ---------- .../src/Strings/da.lproj/Localizable.strings | 120 + .../src/Strings/de.lproj/Localizable.strings | 120 + .../src/Strings/en.lproj/Localizable.strings | 120 + .../src/Strings/es.lproj/Localizable.strings | 120 + .../src/Strings/fr.lproj/Localizable.strings | 120 + .../src/Strings/id.lproj/Localizable.strings | 120 + .../src/Strings/it.lproj/Localizable.strings | 120 + .../src/Strings/ja.lproj/Localizable.strings | 120 + .../src/Strings/ko.lproj/Localizable.strings | 120 + .../src/Strings/nl.lproj/Localizable.strings | 120 + .../src/Strings/pt.lproj/Localizable.strings | 120 + .../src/Strings/ru.lproj/Localizable.strings | 120 + .../src/Strings/sv.lproj/Localizable.strings | 120 + .../Strings/zh-Hans.lproj/Localizable.strings | 120 + .../Strings/zh-Hant.lproj/Localizable.strings | 120 + .../Import/StartImportViewController.swift | 2 +- .../RootModals/SendViewController.swift | 42 +- .../UpdatePinViewController.swift | 4 +- loafwallet/src/Views/AlertView.swift | 35 +- loafwallet/src/Views/GradientView.swift | 14 + loafwallet/src/WalletManager.swift | 3 + .../AnimatedCardViewModelTests.swift | 27 + .../LoginViewModelTests.swift | 41 + .../RegistrationViewModelTests.swift | 92 + .../Constants Tests/ConstantsTests.swift | 2 +- 105 files changed, 4570 insertions(+), 4354 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%) 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 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 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/Podfile b/Podfile index 5ae720544..d148c1fc1 100644 --- a/Podfile +++ b/Podfile @@ -6,10 +6,11 @@ use_frameworks! platform :ios, '13.0' #Shared Cocopods -def shared_pods +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..643f23a39 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,37 @@ 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 */; }; + 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 */; }; 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 +405,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 +763,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 +817,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 +1442,36 @@ 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 = ""; }; + 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 = ""; }; 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 +1598,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 +1704,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 */, @@ -2107,6 +2153,7 @@ 24470E4323A6088700ADDA27 /* Class Tests */ = { isa = PBXGroup; children = ( + C345D81325A8D50600657E30 /* LitecoinCardTests */, 24470E4423A608A700ADDA27 /* AmountTests.swift */, 2494037523AD35C000369261 /* BuyWKWebVCTests.swift */, 249C570423B51F9B009CB5A9 /* TransactionsViewControllerTests.swift */, @@ -2150,7 +2197,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 +2233,6 @@ 24C516502158820E007CE038 /* Buy */ = { isa = PBXGroup; children = ( - 24B8FAC02160497B00A155B1 /* BuyCenterTableViewController.swift */, 24B8FAD12162B10200A155B1 /* BuyCenterWebViewController.swift */, 248BFE2323AAD53700CE1A71 /* BuyTableViewController.swift */, 248BFE2523AB302200CE1A71 /* BuyWKWebViewController.swift */, @@ -3026,15 +3072,30 @@ path = Modules/sqlite3; sourceTree = ""; }; + C3270B97259BF7BE0073DA7B /* CardModels */ = { + isa = PBXGroup; + children = ( + C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */, + ); + 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 = ( C35ABD08257404D2002BB9BB /* Partners */, C35ABD0925740518002BB9BB /* About */, - C3F55643255A1916005F786F /* SupportLitecoinFoundation */, C3D783A52565EA1E0004FF70 /* Unstoppable */, - C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, - C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */, C3D4379E2566EA3E00F423E1 /* LWActivityIndicator.swift */, ); name = "SwiftUI+UIKit"; @@ -3110,6 +3171,7 @@ 24C516502158820E007CE038 /* Buy */, CE760ED71E55F9E000EFAC2B /* SecurityCenter */, CE20C9061DBC587200C8397A /* StartViewController.swift */, + C32DAE9025929492003FC978 /* CardViewController.swift */, 2494038023AF208F00369261 /* PromptModalViewController.swift */, CEAA9E981DC262800066731D /* ConfirmPaperPhraseViewController.swift */, CEF3E8351DE60222007C0A9E /* ModalNavigationController.swift */, @@ -3139,6 +3201,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 +3211,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 +3260,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 +3272,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 +3296,7 @@ CEEC70801E90C04700EF788E /* SeparatorCell.swift */, CEEC70891E945E3B00EF788E /* UnEditableTextView.swift */, CEEC708D1E954AAB00EF788E /* AboutCell.swift */, + C3BD49C825954A1B00D97079 /* ForgotView.swift */, CEEC70911E95DA4400EF788E /* GradientSwitch.swift */, CE83DE291E9EB7F600D07636 /* SendAmountCell.swift */, CEE20C2C1EA288FA0086F724 /* UpdatingLabel.swift */, @@ -3235,8 +3304,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 +3332,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 +3415,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 +3641,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 +3653,9 @@ 752FB04F1DF8BF5C009086FB /* PBXTargetDependency */, ); name = loafwallet; + packageProductDependencies = ( + C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */, + ); productName = breadwallet; productReference = 75A2A7901DA5934300A983D8 /* Litewallet.app */; productType = "com.apple.product-type.application"; @@ -3702,6 +3785,9 @@ Base, ); mainGroup = 75A2A7871DA5934300A983D8; + packageReferences = ( + C30AFB4C2598FC1B00CDCF69 /* XCRemoteSwiftPackageReference "LitewalletPartnerAPI" */, + ); productRefGroup = 75A2A7911DA5934300A983D8 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -3773,7 +3859,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 +3913,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 +3971,7 @@ }; C3D1588125666B69009BD3BC /* Mark Dev Notes */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + buildActionMask = 12; files = ( ); inputFileListPaths = ( @@ -3915,9 +3983,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 */ @@ -3945,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 */, @@ -4078,6 +4149,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 +4177,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 +4204,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 +4229,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 +4247,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 +4273,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 +4304,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 +4317,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 +4328,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 +4337,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 +4348,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 +4357,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 +4369,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 +4377,7 @@ 222C42521E904C5000078EB5 /* AssociatedObject.swift in Sources */, CEB909F51E5FE63D001804DC /* EnterPhraseViewController.swift in Sources */, CE6D0F971DE8B73A00BD4BCF /* ModalTransitionDelegate.swift in Sources */, + C3BD4A5325975C6000D97079 /* View+Extension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4583,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 = ( @@ -4597,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; @@ -4690,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; @@ -4700,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 = ""; @@ -5000,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)/**", @@ -5013,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; @@ -5030,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; @@ -5039,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 = ""; @@ -5130,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 = ( @@ -5144,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; @@ -5162,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; @@ -5172,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 = ""; @@ -5394,6 +5484,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/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/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/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<6jY%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..9d00a6785 --- /dev/null +++ b/loafwallet/CardView.swift @@ -0,0 +1,277 @@ +// +// 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 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) { + + 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) + .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) + .autocapitalization(.none) + .keyboardType(.emailAddress) + + Divider().padding([.leading, .trailing], 20) + + HStack { + 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) + .padding(.top, 20) + .autocapitalization(.none) + .keyboardType(.asciiCapable) + + } 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) + .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(shouldEnableLogin.wrappedValue ? .white : Color(UIColor.litecoinSilver)) + .background(shouldEnableLogin.wrappedValue ? Color(UIColor.liteWalletBlue) : Color(UIColor.litecoinGray)) + .cornerRadius(4.0) + .overlay( + RoundedRectangle(cornerRadius:4) + .stroke(shouldEnableLogin.wrappedValue ? Color(UIColor.liteWalletBlue) : .gray, lineWidth: 1) + ) + } + .disabled(!shouldEnableLogin.wrappedValue) + .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..18c969706 --- /dev/null +++ b/loafwallet/RegistrationViewModel.swift @@ -0,0 +1,213 @@ +// +// 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) -> ()) { + + 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 + + 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 { + + guard let dataString = data as? String else { return false } + + switch dataType { + case .genericString: + return isGenericStringValid(genericString: dataString) + case .email: + return isEmailValid(emailString: dataString) + case .country: + return dataString == "US" ? true : false + case .mobileNumber: + return isMobileNumberValid(mobileString: dataString) + case .password: + return isPasswordValid(passwordString: dataString) + case .confirmation: + return isConfirmedValid(firstString: firstString, confirmingString: dataString) + } + } + + //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/SupportLitecoinFoundationView.swift b/loafwallet/SupportLitecoinFoundationView.swift index 2dcddc2f3..8df1a9ad3 100644 --- a/loafwallet/SupportLitecoinFoundationView.swift +++ b/loafwallet/SupportLitecoinFoundationView.swift @@ -12,6 +12,7 @@ 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 @@ -35,7 +36,6 @@ struct SupportLitecoinFoundationView: View { .frame(height: 300, alignment: .center) .padding([.bottom, .top], 10) - // Copy the LF Address and paste into the SendViewController Button(action: { diff --git a/loafwallet/SupportSafariView.swift b/loafwallet/SupportSafariView.swift index 77514bd70..7c9ed755f 100644 --- a/loafwallet/SupportSafariView.swift +++ b/loafwallet/SupportSafariView.swift @@ -40,7 +40,6 @@ struct SupportSafariView: UIViewRepresentable { /// - navigation: nil func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { } - } func makeUIView(context: Context) -> WKWebView { 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/UnstoppableDomainView.swift b/loafwallet/UnstoppableDomainView.swift index 12801dc92..aaec969be 100644 --- a/loafwallet/UnstoppableDomainView.swift +++ b/loafwallet/UnstoppableDomainView.swift @@ -17,6 +17,9 @@ struct UnstoppableDomainView: View { @State private var didReceiveLTCfromUD: Bool = false + @State + private var shouldDisableLookupButton: Bool = true + init(viewModel: UnstoppableDomainViewModel) { self.viewModel = viewModel } @@ -62,7 +65,7 @@ struct UnstoppableDomainView: View { .foregroundColor(Color(UIColor.secondaryButton)) .shadow(color:Color(UIColor.grayTextTint), radius: 3, x: 0, y: 4) .padding(.trailing, 18) - Text("Lookup") + Text(S.Send.UnstoppableDomains.lookup) .frame(width: 60, height: 30, alignment: .center) .font(Font(UIFont.customMedium(size: 15.0))) .foregroundColor(Color(UIColor.grayTextTint)) @@ -73,7 +76,15 @@ struct UnstoppableDomainView: View { .padding(.trailing, 18) } } - } + }.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 + + shouldDisableLookupButton = currentString.count < 4 + + }) + .disabled(shouldDisableLookupButton) } Spacer() diff --git a/loafwallet/UnstoppableDomainViewModel.swift b/loafwallet/UnstoppableDomainViewModel.swift index 49744535f..f442544da 100644 --- a/loafwallet/UnstoppableDomainViewModel.swift +++ b/loafwallet/UnstoppableDomainViewModel.swift @@ -25,11 +25,12 @@ class UnstoppableDomainViewModel: ObservableObject { //MARK: - Public Variables var didResolveUDAddress: ((String) -> 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/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 a396560c9..a6f5cf93f 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -55,7 +55,7 @@ struct APIServer { #else static let baseUrl = "https://api-prod.lite-wallet.org/" #endif -} +} struct Padding { subscript(multiplier: Int) -> CGFloat { @@ -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 0b159d9bd..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") @@ -99,7 +100,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") } } @@ -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,10 +467,13 @@ 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)") + 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)") @@ -493,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") @@ -569,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") @@ -605,9 +660,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/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 aed89a5d3..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 @@ -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 } @@ -549,17 +554,16 @@ 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 } } - window.rootViewController?.present(supportLFView, animated: true, completion: nil) } - + private func presentSecurityCenter() { guard let walletManager = walletManager else { return } let securityCenter = SecurityCenterViewController(store: store, walletManager: walletManager) @@ -626,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()) }))) @@ -675,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) @@ -742,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) } @@ -787,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) } @@ -859,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 @@ -944,5 +948,3 @@ class SecurityCenterNavigationDelegate : NSObject, UINavigationControllerDelegat } } } - - 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 25195ca00..90e42bf76 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1281,3 +1281,126 @@ /* 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!"; + +/* 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 ab4ba6291..000000000 --- a/loafwallet/src/Strings/ar.lproj/Localizable.strings +++ /dev/null @@ -1,1268 +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" = ""; - -/* 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" = ""; - -/* 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 e528ef11b..18f54d2e7 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "modtag"; +/* resetFields */ +"Button.resetFields" = "Nulstil felter"; + /* send button */ "Button.send" = "send"; @@ -403,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."; @@ -802,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"; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index 348a051ff..4b8c3d035 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "erhalten"; +/* resetFields */ +"Button.resetFields" = "Felder zurücksetzen"; + /* send button */ "Button.send" = "senden"; @@ -403,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"; @@ -802,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"; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index fbc59048b..e1ad9ca5d 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "receive"; +/* resetFields */ +"Button.resetFields" = "Reset fields"; + /* send button */ "Button.send" = "send"; @@ -403,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."; @@ -802,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"; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 7c7e197ef..88c662353 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "recibir"; +/* resetFields */ +"Button.resetFields" = "Reestablecer campos"; + /* send button */ "Button.send" = "Enviar"; @@ -404,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."; @@ -803,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"; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index f1a8dcb3e..05d276d1e 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "recevoir"; +/* resetFields */ +"Button.resetFields" = "Réinitialisation des champs"; + /* send button */ "Button.send" = "envoyer"; @@ -403,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."; @@ -802,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"; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 42573b3d6..1638e5fb0 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "menerima"; +/* resetFields */ +"Button.resetFields" = "Setel ulang bidang"; + /* send button */ "Button.send" = "kirim"; @@ -403,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."; @@ -802,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"; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index 774c68fda..fe500cb11 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "ricevi"; +/* resetFields */ +"Button.resetFields" = "Resettare i campi"; + /* send button */ "Button.send" = "invia"; @@ -403,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."; @@ -802,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"; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index f4ea3138d..2940abb76 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" = "送金に失敗しました"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "受取"; +/* resetFields */ +"Button.resetFields" = "フィールドをリセット"; + /* send button */ "Button.send" = "送金する"; @@ -403,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" = "位置情報サービスが無効化されています。"; @@ -802,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ドメインを入力してください"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index a9d0e2101..a56848dc0 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" = "보내기 실패함"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "받기"; +/* resetFields */ +"Button.resetFields" = "리셋 필드"; + /* send button */ "Button.send" = "보내기"; @@ -403,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" = "위치 서비스가 꺼졌습니다."; @@ -802,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 도메인을 입력하세요."; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index a536fb9dc..18360417c 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "ontvangen"; +/* resetFields */ +"Button.resetFields" = "Reset velden"; + /* send button */ "Button.send" = "versturen"; @@ -403,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."; @@ -802,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"; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index 8adb83b6c..fc139c62d 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"; @@ -152,6 +158,9 @@ /* receive button */ "Button.receive" = "receber"; +/* resetFields */ +"Button.resetFields" = "Limpar campos"; + /* send button */ "Button.send" = "enviar"; @@ -404,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."; @@ -803,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"; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index 63b81e63c..d6a608dc9 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" = "Ошибка отправки"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "получить"; +/* resetFields */ +"Button.resetFields" = "Очистить поля"; + /* send button */ "Button.send" = "отправить"; @@ -403,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" = "Сервисы определения местоположения отключены."; @@ -802,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"; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index cc2e9c21a..c4031cf4e 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"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "ta emot"; +/* resetFields */ +"Button.resetFields" = "Nollställ fält"; + /* send button */ "Button.send" = "skicka"; @@ -403,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."; @@ -802,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"; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index f3cd372e7..5e84126e7 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" = "发送失败"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "收到"; +/* resetFields */ +"Button.resetFields" = "重新设置领域"; + /* send button */ "Button.send" = "发送"; @@ -403,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" = "位置服务被禁用。"; @@ -802,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域"; @@ -1266,3 +1380,9 @@ /* 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 fb1c4f7ac..5622e8eab 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" = "寄出失敗"; @@ -151,6 +157,9 @@ /* receive button */ "Button.receive" = "接收"; +/* resetFields */ +"Button.resetFields" = "resetFields"; + /* send button */ "Button.send" = "寄出"; @@ -403,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" = "定位服務已停用。"; @@ -802,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域"; 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 b21b8e8cb..8df70c501 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 @@ -138,6 +139,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) + descriptionCell.didReturn = { textView in textView.resignFirstResponder() } @@ -178,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?) { @@ -221,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) @@ -245,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) } } @@ -358,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))"]) } } @@ -387,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) }) @@ -421,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 5a77ade05..46fbb2ca3 100644 --- a/loafwallet/src/Views/AlertView.swift +++ b/loafwallet/src/Views/AlertView.swift @@ -12,19 +12,22 @@ enum AlertType { case pinSet(callback: () -> Void) case paperKeySet(callback: () -> Void) case sendSuccess + case resolvedSuccess case addressesCopied case sweepSuccess(callback: () -> Void) 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.SecurityAlerts.resolvedSuccess case .addressesCopied: - return S.Alerts.copiedAddressesHeader + return S.SecurityAlerts.copiedAddressesHeader case .sweepSuccess: return S.Import.success } @@ -35,11 +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.SecurityAlerts.resolvedSuccessSubheader case .addressesCopied: - return S.Alerts.copiedAddressesSubheader + return S.SecurityAlerts.copiedAddressesSubheader case .sweepSuccess: return S.Import.successBody } @@ -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) + } +} 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") + } 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)) + + } + +} diff --git a/loafwalletTests/Constants Tests/ConstantsTests.swift b/loafwalletTests/Constants Tests/ConstantsTests.swift index 1d7dbe5aa..6e0ef22b2 100644 --- a/loafwalletTests/Constants Tests/ConstantsTests.swift +++ b/loafwalletTests/Constants Tests/ConstantsTests.swift @@ -13,5 +13,5 @@ class ConstantsTests: XCTestCase { func testLFDonationAddressPage() throws { XCTAssertTrue(FoundationSupport.url.absoluteString == "https://lite-wallet.org/support_address.html" ) - } + } } From c47a8101c8b2d2b354e8a4576d7056ce95a3001f Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 11 Jan 2021 19:13:48 +0000 Subject: [PATCH 08/35] [HOTFIX] Hide Card Tab (#191) * Hide Card Tab * added comments for v1 --- loafwallet.xcodeproj/project.pbxproj | 24 +++++++++++------------ loafwallet/Storyboards/Main.storyboard | 6 ++---- loafwallet/TabBarViewController.swift | 27 ++++++++++++++------------ 3 files changed, 29 insertions(+), 28 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..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 @@ -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 6a70cc0c1f7c21f459cd46354a13c5208ff4f5bc Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Fri, 15 Jan 2021 21:34:36 +0000 Subject: [PATCH 09/35] [Merge into Master] v3.1.1 (#194) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- loafwallet.xcodeproj/project.pbxproj | 145 +++++++++--------- loafwallet/ResolutionModel.swift | 38 ----- loafwallet/UnstoppableDomainView.swift | 3 +- loafwallet/UnstoppableDomainViewModel.swift | 128 +++++++++------- .../src/Views/SendViewCells/AddressCell.swift | 4 +- 5 files changed, 151 insertions(+), 167 deletions(-) delete mode 100644 loafwallet/ResolutionModel.swift diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 4313cdd44..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 */; }; @@ -283,7 +284,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 */; }; @@ -457,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 */ @@ -573,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 = ""; }; @@ -836,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 = ""; }; @@ -1438,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 = ""; }; @@ -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 = ""; }; @@ -1667,7 +1665,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BB66CB271F7F2FD1936AA04B /* Pods_loafwalletTests.framework in Frameworks */, + 8BFF92CC86553A47974D867D /* Pods_loafwalletTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1707,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; }; @@ -3025,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 = ""; @@ -3129,7 +3127,6 @@ isa = PBXGroup; children = ( C3D783A62565EA4A0004FF70 /* UnstoppableDomainView.swift */, - C35ABD4225741E19002BB9BB /* ResolutionModel.swift */, C3D783B62565EA6B0004FF70 /* UnstoppableDomainViewModel.swift */, ); name = Unstoppable; @@ -3491,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 = ""; @@ -3560,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 */, @@ -3633,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 */, @@ -3641,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 = ( ); @@ -3877,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; @@ -3931,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 = ( @@ -3968,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; @@ -3987,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 */ @@ -4155,7 +4153,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 */, @@ -4668,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 = ( @@ -4687,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; @@ -4701,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)"; @@ -4780,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; @@ -4790,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 = ""; @@ -4909,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; @@ -4937,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; @@ -5085,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)/**", @@ -5103,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; @@ -5120,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; @@ -5129,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 = ""; @@ -5215,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 = ( @@ -5234,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; @@ -5252,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; @@ -5262,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/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/UnstoppableDomainView.swift b/loafwallet/UnstoppableDomainView.swift index aaec969be..0993a900d 100644 --- a/loafwallet/UnstoppableDomainView.swift +++ b/loafwallet/UnstoppableDomainView.swift @@ -79,8 +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 f442544da..f129dbae7 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 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 - } + self.resolveUDAddress(domainName: searchString) } 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 ceae007aefa26462b99c7f531523ae0c53a996ae Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 27 Jan 2021 23:52:32 +0000 Subject: [PATCH 10/35] [Release v3.2.0] Merge into Main (#216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * [Merge into Develop] Release v3.1.1 (#195) * [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 * Update issue templates (#127) * Update issue templates * Update bug_report.md * Update feature_request.md Update with Litewallet data * [Tech Debt] Update readme.md (#174) * update readme.md * per review notes * Clean up the cocoapod installation (#196) - Remove Firebase pod - Added Firebase Swift package - Removed some old dead code * [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 * [Feature] Unhide Litecoin card prod v1 (#203) * Unhiding the Card tab * Update the LitewalletPartnerAPI Swift package version * set tab item name * [Bugfix] Firebase Swift package does not archive (#210) * Resolved package * Readded pods - Firebase Crashlytics - Firebase Analytics - Updated the Litewallet API package * adjusted the forgot button (#201) * [Tech Debt] Removed extra Web class (#204) * Removed extra Web class * removed unused vc * [Bugfix] Fix buywebview (#215) * Resolve Crash issue * Fixes the webview * Conflict resolved - SW resolved - TabBarViewController - Main Storyboard * package resolution * build bump Co-authored-by: Mohamed Barry Co-authored-by: Nikolay Spassov --- .github/ISSUE_TEMPLATE/bug_report.md | 35 +++ .github/ISSUE_TEMPLATE/feature_request.md | 27 +++ Gemfile | 2 - Gemfile.lock | 159 ------------- Podfile | 4 +- fastlane/Appfile | 7 - fastlane/Fastfile | 74 ------- loafwallet.xcodeproj/project.pbxproj | 141 ++++++------ .../xcshareddata/swiftpm/Package.resolved | 4 +- loafwallet/BuyTableViewController.swift | 11 +- loafwallet/BuyWKWebViewController.swift | 30 +-- loafwallet/Currency.swift | 53 ++--- loafwallet/Storyboards/Buy.storyboard | 51 +++-- loafwallet/Storyboards/Main.storyboard | 151 ++----------- loafwallet/TabBarViewController.swift | 208 ++++++++---------- loafwallet/src/ModalPresenter.swift | 12 +- .../src/Platform/BRWebViewController.swift | 35 +-- .../ViewControllers/WebViewContainer.swift | 113 ---------- pages/development.md | 30 +++ 19 files changed, 346 insertions(+), 801 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 Gemfile delete mode 100644 Gemfile.lock delete mode 100644 fastlane/Appfile delete mode 100644 fastlane/Fastfile delete mode 100644 loafwallet/src/ViewControllers/WebViewContainer.swift create mode 100644 pages/development.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. 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..2b9ebb14c 100644 --- a/Podfile +++ b/Podfile @@ -7,10 +7,10 @@ platform :ios, '13.0' #Shared Cocopods def shared_pods - pod 'Firebase/Crashlytics' - pod 'Firebase/Analytics' pod 'UnstoppableDomainsResolution', '~> 0.1.6' pod 'KeychainAccess', '~> 4.2' + pod 'Firebase/Analytics' + pod 'Firebase/Crashlytics' # add after v2.9.0 pod 'SwiftLint' end 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..a0c49c0b5 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -26,7 +26,6 @@ 1BBAEC901F80261D0047DEA8 /* BRMerkleBlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAEBFB1F80237B0047DEA8 /* BRMerkleBlock.c */; }; 1BBAEC911F8026250047DEA8 /* BRBIP32Sequence.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAEBED1F80237B0047DEA8 /* BRBIP32Sequence.c */; }; 1BBAEC921F80262A0047DEA8 /* BRWallet.c in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAEC071F80237B0047DEA8 /* BRWallet.c */; }; - 1BEA7DDB2142CAA00081602F /* WebViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BEA7DDA2142CAA00081602F /* WebViewContainer.swift */; }; 22122B721F0B8996000E9AB9 /* BRAPIClient+Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22122B711F0B8996000E9AB9 /* BRAPIClient+Events.swift */; }; 2218BD771E8F55430091D5E8 /* BRAPIClient+Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2218BD761E8F55430091D5E8 /* BRAPIClient+Assets.swift */; }; 222319B01F27985A00008F20 /* BRBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 222319AF1F27985A00008F20 /* BRBrowserViewController.swift */; }; @@ -56,7 +55,6 @@ 22A9A9551DF61945000F0016 /* BRTar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22A9A9411DF61945000F0016 /* BRTar.swift */; }; 22A9A9561DF61945000F0016 /* BRWalletPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22A9A9421DF61945000F0016 /* BRWalletPlugin.swift */; }; 22A9A9571DF61945000F0016 /* BRWebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22A9A9431DF61945000F0016 /* BRWebSocket.swift */; }; - 22A9A9581DF61945000F0016 /* BRWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22A9A9441DF61945000F0016 /* BRWebViewController.swift */; }; 22A9A9591DF61945000F0016 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22A9A9451DF61945000F0016 /* Extensions.swift */; }; 22A9A95E1DF61FD0000F0016 /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A9A95D1DF61FD0000F0016 /* PushKit.framework */; }; 22A9A9601DF61FD8000F0016 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A9A95F1DF61FD8000F0016 /* CoreLocation.framework */; }; @@ -267,7 +265,8 @@ 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 */; }; + 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 */; }; 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 */; }; @@ -700,7 +699,6 @@ 1BBAEC701F80237C0047DEA8 /* TODO */ = {isa = PBXFileReference; lastKnownFileType = text; path = TODO; sourceTree = ""; }; 1BBAEC711F80237C0047DEA8 /* test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = test.c; sourceTree = ""; }; 1BBAEC7D1F8025020047DEA8 /* BRCrypto.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = BRCrypto.c; sourceTree = ""; }; - 1BEA7DDA2142CAA00081602F /* WebViewContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WebViewContainer.swift; path = src/ViewControllers/WebViewContainer.swift; sourceTree = ""; }; 22122B711F0B8996000E9AB9 /* BRAPIClient+Events.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BRAPIClient+Events.swift"; sourceTree = ""; }; 2218BD761E8F55430091D5E8 /* BRAPIClient+Assets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "BRAPIClient+Assets.swift"; path = "src/Platform/BRAPIClient+Assets.swift"; sourceTree = ""; }; 222319AF1F27985A00008F20 /* BRBrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BRBrowserViewController.swift; path = src/Platform/BRBrowserViewController.swift; sourceTree = ""; }; @@ -729,7 +727,6 @@ 22A9A9411DF61945000F0016 /* BRTar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BRTar.swift; path = src/Platform/BRTar.swift; sourceTree = ""; }; 22A9A9421DF61945000F0016 /* BRWalletPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BRWalletPlugin.swift; path = src/Platform/BRWalletPlugin.swift; sourceTree = ""; }; 22A9A9431DF61945000F0016 /* BRWebSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BRWebSocket.swift; path = src/Platform/BRWebSocket.swift; sourceTree = ""; }; - 22A9A9441DF61945000F0016 /* BRWebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BRWebViewController.swift; path = src/Platform/BRWebViewController.swift; sourceTree = ""; }; 22A9A9451DF61945000F0016 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = src/Platform/Extensions.swift; sourceTree = ""; }; 22A9A95D1DF61FD0000F0016 /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = System/Library/Frameworks/PushKit.framework; sourceTree = SDKROOT; }; 22A9A95F1DF61FD8000F0016 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; @@ -834,10 +831,8 @@ 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 = ""; }; + 6008481CC5B78F1CF8F9EA57 /* 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 = ""; }; + 65B44EBCC7D4AFCDB8B91F8A /* 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 = ""; }; 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 +1432,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; }; - 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 = ""; }; + 96694FA018937A83E970CC55 /* 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 = ""; }; + 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 = ""; }; 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 +1645,8 @@ 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 = ""; }; + D25607DBC5E9F06B12996E3E /* 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 = ""; }; + D69FD9757DAE828E1DB3DC2D /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1665,7 +1662,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8BFF92CC86553A47974D867D /* Pods_loafwalletTests.framework in Frameworks */, + 92FB6A24C5F95B5239A226B4 /* Pods_loafwalletTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1705,7 +1702,7 @@ C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */, 752FB04D1DF8BF4B009086FB /* sqlite3.framework in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, - 1991125B1B86B90CA24B7286 /* Pods_loafwallet.framework in Frameworks */, + BC40800031AC198047C76D8C /* Pods_loafwallet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2001,7 +1998,6 @@ 22A9A9451DF61945000F0016 /* Extensions.swift */, 223DB2171DF691260076A151 /* BRSocketHelpers.c */, 223DB2181DF691260076A151 /* BRSocketHelpers.h */, - 22A9A9441DF61945000F0016 /* BRWebViewController.swift */, CE45C1FA1E74F89C002C3847 /* WalletInfo.swift */, 22A9A93D1DF61945000F0016 /* TxMetaData.swift */, 754AE0BD1DFE8E5A007FD001 /* module.modulemap */, @@ -3023,8 +3019,8 @@ 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */, 75A2A7F21DA5935F00A983D8 /* Messages.framework */, 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */, - 2661498DDE75925BFDA290AA /* Pods_loafwallet.framework */, - B994E2162ECCFE0BB90CC714 /* Pods_loafwalletTests.framework */, + D69FD9757DAE828E1DB3DC2D /* Pods_loafwallet.framework */, + 9AC86E61BB430C1275F605F8 /* Pods_loafwalletTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -3187,7 +3183,6 @@ CEE659E81F664C73001FF29D /* WelcomeViewController.swift */, 1B3F74211FFB106200CCA50C /* BiometricsSettingsViewController.swift */, 1B3F74221FFB106200CCA50C /* BiometricsSpendingLimitViewController.swift */, - 1BEA7DDA2142CAA00081602F /* WebViewContainer.swift */, 24AF00FF221B349100FF636F /* WarningConfirmationViewController.swift */, 24D5F26D225A5BEA00225462 /* ContainerViewController.swift */, ); @@ -3488,12 +3483,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 */, + 6008481CC5B78F1CF8F9EA57 /* Pods-loafwallet.debug.xcconfig */, + B1E980ED11476D536096EFFC /* Pods-loafwallet.testnet.xcconfig */, + A3E5444354AB8914A966CDC2 /* Pods-loafwallet.release.xcconfig */, + D25607DBC5E9F06B12996E3E /* Pods-loafwalletTests.debug.xcconfig */, + 65B44EBCC7D4AFCDB8B91F8A /* Pods-loafwalletTests.testnet.xcconfig */, + 96694FA018937A83E970CC55 /* Pods-loafwalletTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -3557,7 +3552,7 @@ isa = PBXNativeTarget; buildConfigurationList = 2465873D23A5AAD100A32E9E /* Build configuration list for PBXNativeTarget "loafwalletTests" */; buildPhases = ( - 539F95D1D2880CDB55F16CD2 /* [CP] Check Pods Manifest.lock */, + 5723028C3694917363D260E0 /* [CP] Check Pods Manifest.lock */, 2465873223A5AAD000A32E9E /* Sources */, 2465873323A5AAD000A32E9E /* Frameworks */, 2465873423A5AAD000A32E9E /* Resources */, @@ -3630,7 +3625,7 @@ isa = PBXNativeTarget; buildConfigurationList = 75A2A7E31DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet" */; buildPhases = ( - 421B6524385300316FBCCDF8 /* [CP] Check Pods Manifest.lock */, + 832DFB05CE15FD50F6854519 /* [CP] Check Pods Manifest.lock */, 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */, 24E179F223BDAF8000F928D9 /* Xcode custom warnings */, 75A2A78C1DA5934300A983D8 /* Sources */, @@ -3639,7 +3634,7 @@ 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, C3D1588125666B69009BD3BC /* Mark Dev Notes */, - CB23F16DD689CE4EDFBEB417 /* [CP] Embed Pods Frameworks */, + 0A6FE96D6D66CEA3039B3345 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -3874,6 +3869,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 0A6FE96D6D66CEA3039B3345 /* [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; + }; 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 12; @@ -3906,7 +3918,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 */ = { + 5723028C3694917363D260E0 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3921,14 +3933,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwallet-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-loafwalletTests-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; }; - 539F95D1D2880CDB55F16CD2 /* [CP] Check Pods Manifest.lock */ = { + 832DFB05CE15FD50F6854519 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3943,7 +3955,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwalletTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-loafwallet-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -3968,23 +3980,6 @@ 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 */ @@ -4167,7 +4162,6 @@ CEBF32F91DDD193500348FC6 /* TransactionTableViewCell.swift in Sources */, CEF3E82B1DE51612007C0A9E /* GradientCircle.swift in Sources */, CE124CFE1E68F57700DFA146 /* Async.swift in Sources */, - 1BEA7DDB2142CAA00081602F /* WebViewContainer.swift in Sources */, 2218BD771E8F55430091D5E8 /* BRAPIClient+Assets.swift in Sources */, 2228734D1E916F7C0044BA15 /* BRAPIClient+Features.swift in Sources */, 22A9A94D1DF61945000F0016 /* BRHTTPFileMiddleware.swift in Sources */, @@ -4251,7 +4245,6 @@ 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 */, CE27F9591E2C8EA300F7F7F2 /* Amount.swift in Sources */, CE1280F61EEA855C00D27649 /* Date+Additions.swift in Sources */, @@ -4652,12 +4645,13 @@ 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"; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -4665,12 +4659,12 @@ }; 24470E0123A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C2728A44EB43C7CCAA987B89 /* Pods-loafwallet.debug.xcconfig */; + baseConfigurationReference = 6008481CC5B78F1CF8F9EA57 /* Pods-loafwallet.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4684,7 +4678,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.1.1; + MARKETING_VERSION = 3.2.0; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4698,7 +4692,7 @@ }; 24470E0323A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A1C0235D73D79DA3FB4FFDF7 /* Pods-loafwalletTests.debug.xcconfig */; + baseConfigurationReference = D25607DBC5E9F06B12996E3E /* Pods-loafwalletTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -4777,7 +4771,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4787,7 +4781,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.1.1; + MARKETING_VERSION = 3.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4906,7 +4900,7 @@ }; 2465873F23A5AAD100A32E9E /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = ADB3C165455573400E04EC13 /* Pods-loafwalletTests.testnet.xcconfig */; + baseConfigurationReference = 65B44EBCC7D4AFCDB8B91F8A /* Pods-loafwalletTests.testnet.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -4934,7 +4928,7 @@ }; 2465874023A5AAD100A32E9E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 72359B62E9336B8B8C58C7B3 /* Pods-loafwalletTests.release.xcconfig */; + baseConfigurationReference = 96694FA018937A83E970CC55 /* Pods-loafwalletTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -5069,12 +5063,13 @@ 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"; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -5082,12 +5077,12 @@ }; 75A2A7E51DA5934400A983D8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 743B301179ED3019FA9E6247 /* Pods-loafwallet.release.xcconfig */; + baseConfigurationReference = A3E5444354AB8914A966CDC2 /* Pods-loafwallet.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5100,7 +5095,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.1.1; + MARKETING_VERSION = 3.2.0; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5117,7 +5112,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5126,7 +5121,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.1.1; + MARKETING_VERSION = 3.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5205,19 +5200,19 @@ SWIFT_INCLUDE_PATHS = "$(SDK_DIR)/usr/include $(SRCROOT)/Modules $(SRCROOT)/loafwallet/src/Platform"; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Testnet; }; CEA7E69C1F0AAA84001F8C27 /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 40524F4C990EE3717AE4D70C /* Pods-loafwallet.testnet.xcconfig */; + baseConfigurationReference = B1E980ED11476D536096EFFC /* Pods-loafwallet.testnet.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5231,7 +5226,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.1.1; + MARKETING_VERSION = 3.2.0; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5249,7 +5244,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 10; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5259,7 +5254,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.1.1; + MARKETING_VERSION = 3.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5488,7 +5483,7 @@ repositoryURL = "https://github.com/litecoin-foundation/LitewalletPartnerAPI.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.2.0; + minimumVersion = 0.5.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved b/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved index 48bb5fcc5..8af16a593 100644 --- a/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/litecoin-foundation/LitewalletPartnerAPI.git", "state": { "branch": null, - "revision": "3dc7a74f5c4a3dd054b5eaacfe68909e68e99766", - "version": "0.3.0" + "revision": "5fafe40f4eac370440d39192d73916a387b0f36e", + "version": "0.5.0" } } ] diff --git a/loafwallet/BuyTableViewController.swift b/loafwallet/BuyTableViewController.swift index c4d8cff5d..5728853eb 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" @@ -29,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() @@ -54,6 +52,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 +67,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..ce53d5dad 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() @@ -60,18 +63,18 @@ 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) 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 +122,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/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index 3c6fda719..1c52f3eac 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -14,9 +14,9 @@ enum TabViewControllerIndex: Int { case buy = 2 case receive = 3 } - + class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDelegate { - + let kInitialChildViewControllerIndex = 0 // TransactionsViewController @IBOutlet weak var headerView: UIView! @IBOutlet weak var containerView: UIView! @@ -26,9 +26,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel @IBOutlet weak var timeStampLabel: UILabel! @IBOutlet weak var timeStampStackView: UIStackView! @IBOutlet weak var timeStampStackViewHeight: NSLayoutConstraint! - - - + var primaryBalanceLabel: UpdatingLabel? var secondaryBalanceLabel: UpdatingLabel? private let largeFontSize: CGFloat = 24.0 @@ -40,11 +38,10 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel 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 updateTimer: Timer? var store: Store? var walletManager: WalletManager? @@ -68,14 +65,13 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel store.perform(action: RootModalActions.Present(modal: .menu)) } - override func viewDidLoad() { super.viewDidLoad() setupViews() configurePriceLabels() addSubscriptions() dateFormatter.setLocalizedDateFormatFromTemplate("MMM d, h:mm a") - + for (index, storyboardID) in self.storyboardIDs.enumerated() { let controller = UIStoryboard.init(name: storyboardNames[index], bundle: nil).instantiateViewController(withIdentifier: storyboardID) viewControllers.append(controller) @@ -98,36 +94,36 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel private func setupViews() { - if #available(iOS 11.0, *), - let backgroundColor = UIColor(named: "mainColor") { + if #available(iOS 11.0, *), + let backgroundColor = UIColor(named: "mainColor") { headerView.backgroundColor = backgroundColor tabBar.barTintColor = backgroundColor containerView.backgroundColor = backgroundColor self.view.backgroundColor = backgroundColor - } else { + } else { headerView.backgroundColor = .liteWalletBlue tabBar.barTintColor = .liteWalletBlue containerView.backgroundColor = .liteWalletBlue self.view.backgroundColor = .liteWalletBlue - } + } } private func configurePriceLabels() { - + //TODO: Debug the reizing of label...very important guard let primaryLabel = self.primaryBalanceLabel , - let secondaryLabel = self.secondaryBalanceLabel else { - NSLog("ERROR: Price labels not initialized") - return + let secondaryLabel = self.secondaryBalanceLabel else { + NSLog("ERROR: Price labels not initialized") + return } - + let priceLabelArray = [primaryBalanceLabel,secondaryBalanceLabel,equalsLabel] priceLabelArray.enumerated().forEach { (index, view) in view?.backgroundColor = .clear view?.textColor = .white } - + primaryLabel.font = UIFont.barlowSemiBold(size: largeFontSize) secondaryLabel.font = UIFont.barlowSemiBold(size: largeFontSize) @@ -136,10 +132,10 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel headerView.addSubview(secondaryLabel) headerView.addSubview(equalsLabel) headerView.addSubview(currencyTapView) - + secondaryLabel.constrain([ - secondaryLabel.constraint(.firstBaseline, toView: primaryLabel, constant: 0.0) ]) - + secondaryLabel.constraint(.firstBaseline, toView: primaryLabel, constant: 0.0) ]) + equalsLabel.translatesAutoresizingMaskIntoConstraints = false primaryLabel.translatesAutoresizingMaskIntoConstraints = false regularConstraints = [ @@ -148,50 +144,47 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel equalsLabel.firstBaselineAnchor.constraint(equalTo: primaryLabel.firstBaselineAnchor, constant: 0), equalsLabel.leadingAnchor.constraint(equalTo: primaryLabel.trailingAnchor, constant: C.padding[1]/2.0), secondaryLabel.leadingAnchor.constraint(equalTo: equalsLabel.trailingAnchor, constant: C.padding[1]/2.0), - ] - + ] + swappedConstraints = [ secondaryLabel.firstBaselineAnchor.constraint(equalTo: headerView.bottomAnchor, constant: -12), secondaryLabel.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: C.padding[1]*1.25), equalsLabel.firstBaselineAnchor.constraint(equalTo: secondaryLabel.firstBaselineAnchor, constant: 0), equalsLabel.leadingAnchor.constraint(equalTo: secondaryLabel.trailingAnchor, constant: C.padding[1]/2.0), primaryLabel.leadingAnchor.constraint(equalTo: equalsLabel.trailingAnchor, constant: C.padding[1]/2.0), - ] + ] if let isLTCSwapped = self.isLtcSwapped { NSLayoutConstraint.activate(isLTCSwapped ? self.swappedConstraints : self.regularConstraints) } currencyTapView.constrain([ - currencyTapView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 0), - currencyTapView.trailingAnchor.constraint(equalTo: self.timeStampStackView.leadingAnchor, constant: 0), - currencyTapView.topAnchor.constraint(equalTo: primaryLabel.topAnchor, constant: 0), - currencyTapView.bottomAnchor.constraint(equalTo: primaryLabel.bottomAnchor, constant: C.padding[1]) ]) - - let gr = UITapGestureRecognizer(target: self, action: #selector(currencySwitchTapped)) - currencyTapView.addGestureRecognizer(gr) + currencyTapView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 0), + currencyTapView.trailingAnchor.constraint(equalTo: self.timeStampStackView.leadingAnchor, constant: 0), + currencyTapView.topAnchor.constraint(equalTo: primaryLabel.topAnchor, constant: 0), + currencyTapView.bottomAnchor.constraint(equalTo: primaryLabel.bottomAnchor, constant: C.padding[1]) ]) + + let gr = UITapGestureRecognizer(target: self, action: #selector(currencySwitchTapped)) + currencyTapView.addGestureRecognizer(gr) } - + //MARK: - Adding Subscriptions private func addSubscriptions() { - - - guard let store = self.store else { NSLog("ERROR - Store not passed") return } guard let primaryLabel = self.primaryBalanceLabel , - let secondaryLabel = self.secondaryBalanceLabel else { - NSLog("ERROR: Price labels not initialized") - return + let secondaryLabel = self.secondaryBalanceLabel else { + NSLog("ERROR: Price labels not initialized") + return } store.subscribe(self, selector: { $0.walletState.syncProgress != $1.walletState.syncProgress }, callback: { _ in self.tabBar.selectedItem = self.tabBar.items?.first - }) - + }) + store.lazySubscribe(self, selector: { $0.isLtcSwapped != $1.isLtcSwapped }, callback: { self.isLtcSwapped = $0.isLtcSwapped }) @@ -205,7 +198,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel } self.exchangeRate = $0.currentRate - }) + }) store.lazySubscribe(self, selector: { $0.maxDigits != $1.maxDigits}, @@ -216,7 +209,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel primaryLabel.formatter = placeholderAmount.ltcFormat self.setBalances() } - }) + }) store.subscribe(self, selector: {$0.walletState.balance != $1.walletState.balance }, @@ -233,13 +226,13 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel return } guard let primaryLabel = self.primaryBalanceLabel, - let secondaryLabel = self.secondaryBalanceLabel else { - NSLog("ERROR: Price labels not initialized") - return + let secondaryLabel = self.secondaryBalanceLabel else { + NSLog("ERROR: Price labels not initialized") + return } - + let amount = Amount(amount: balance, rate: rate, maxDigits: store.state.maxDigits) - + if !hasInitialized { let amount = Amount(amount: balance, rate: exchangeRate!, maxDigits: store.state.maxDigits) NSLayoutConstraint.deactivate(isLTCSwapped ? self.regularConstraints : self.swappedConstraints) @@ -256,7 +249,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel if primaryLabel.isHidden { primaryLabel.isHidden = false } - + if secondaryLabel.isHidden { secondaryLabel.isHidden = false } @@ -277,9 +270,9 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel let fiatRate = Double(round(100*rate.rate)/100) let formattedFiatString = String(format: "%.02f", fiatRate) self.currentLTCPriceLabel.text = Currency.getSymbolForCurrencyCode(code: rate.code)! + formattedFiatString - + } - + private func transform(forView: UIView) -> CGAffineTransform { forView.transform = .identity //Must reset the view's transform before we calculate the next transform let scaleFactor: CGFloat = smallFontSize/largeFontSize @@ -290,7 +283,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel } override func viewWillAppear(_ animated: Bool) { - + super.viewWillAppear(animated) guard let array = self.tabBar.items else { @@ -301,68 +294,66 @@ 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 - //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") + 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") } } - } + } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.displayContentController(contentController: viewControllers[kInitialChildViewControllerIndex]) } - + func displayContentController(contentController:UIViewController) { //MARK: - Tab View Controllers Configuration switch NSStringFromClass(contentController.classForCoder) { - case "loafwallet.TransactionsViewController": - - guard let transactionVC = contentController as? TransactionsViewController else { - return - } - - transactionVC.store = self.store - transactionVC.walletManager = self.walletManager - transactionVC.isLtcSwapped = self.store?.state.isLtcSwapped - - //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.TransactionsViewController": + + guard let transactionVC = contentController as? TransactionsViewController else { + return + } + + transactionVC.store = self.store + 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 + case "loafwallet.BuyTableViewController": guard let buyVC = contentController as? BuyTableViewController else { return - } - buyVC.store = self.store - buyVC.walletManager = self.walletManager - - case "loafwallet.SendLTCViewController": - guard let sendVC = contentController as? SendLTCViewController else { - return - } - - sendVC.store = self.store - - case "loafwallet.ReceiveLTCViewController": - guard let receiveVC = contentController as? ReceiveLTCViewController else { - return - } - receiveVC.store = self.store - - default: - fatalError("Tab viewController not set") + } + buyVC.store = self.store + buyVC.walletManager = self.walletManager + + case "loafwallet.SendLTCViewController": + guard let sendVC = contentController as? SendLTCViewController else { + return + } + + sendVC.store = self.store + + case "loafwallet.ReceiveLTCViewController": + guard let receiveVC = contentController as? ReceiveLTCViewController else { + return + } + receiveVC.store = self.store + + default: + fatalError("Tab viewController not set") } self.exchangeRate = TransactionManager.sharedInstance.rate @@ -378,7 +369,7 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel contentController.view .removeFromSuperview() contentController.removeFromParentViewController() } - + func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { if let tempActiveController = activeController { @@ -397,11 +388,11 @@ extension TabBarViewController { guard let store = self.store else { return } guard let isLTCSwapped = self.isLtcSwapped else { return } guard let primaryLabel = self.primaryBalanceLabel, - let secondaryLabel = self.secondaryBalanceLabel else { - NSLog("ERROR: Price labels not initialized") - return + let secondaryLabel = self.secondaryBalanceLabel else { + NSLog("ERROR: Price labels not initialized") + return } - + UIView.spring(0.7, animations: { primaryLabel.transform = primaryLabel.transform.isIdentity ? self.transform(forView: primaryLabel) : .identity secondaryLabel.transform = secondaryLabel.transform.isIdentity ? self.transform(forView: secondaryLabel) : .identity @@ -413,8 +404,3 @@ extension TabBarViewController { store.perform(action: CurrencyChange.toggle()) } } - - - - - 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/Platform/BRWebViewController.swift b/loafwallet/src/Platform/BRWebViewController.swift index 71738f966..1078bf50b 100644 --- a/loafwallet/src/Platform/BRWebViewController.swift +++ b/loafwallet/src/Platform/BRWebViewController.swift @@ -35,42 +35,9 @@ import WebKit } var indexUrl: URL { - switch mountPoint { - case "/buy_simplex": - var appInstallDate: Date { - if let documentsFolder = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last { - if let installDate = try! FileManager.default.attributesOfItem(atPath: documentsFolder.path)[.creationDate] as? Date { - return installDate - } - } - return Date() - } - let walletAddress = walletManager.wallet?.receiveAddress - let currencyCode = Locale.current.currencyCode ?? "USD" - let uuid = UIDevice.current.identifierForVendor!.uuidString - - return URL(string: getSimplexParams(appInstallDate: appInstallDate, walletAddress: walletAddress, currencyCode: currencyCode, uuid: uuid))! - case "/buy_coinbase": - return URL(string: "https://api.loafwallet.org/buy")! - case "/support": - return URL(string: "https://api.loafwallet.org/support")! - case "/ea": - return URL(string: "https://api.loafwallet.org/ea")! - default: return URL(string: "http://127.0.0.1:\(server.port)\(mountPoint)")! - } } - - private func getSimplexParams(appInstallDate: Date?, walletAddress: String?, currencyCode: String?, uuid: String?) -> String { - guard let appInstallDate = appInstallDate else { return "" } - guard let walletAddress = walletAddress else { return "" } - let currencyCode = Currency.returnSimplexSupportedFiat(givenCode: currencyCode!) - guard let uuid = uuid else { return "" } - - let timestamp = Int(appInstallDate.timeIntervalSince1970) - return "https://buy.loafwallet.org/?address=\(walletAddress)&code=\(currencyCode)&idate=\(timestamp)&uid=\(uuid)" - } - + private let messageUIPresenter = MessageUIPresenter() init(partner: String?, mountPoint: String = "/", walletManager: WalletManager, store: Store, noAuthApiClient: BRAPIClient? = nil) { 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) - }) - } -} 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 692cebe7cba5610040b4caefa98e228de1805dad Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 11 Mar 2021 12:22:02 +0000 Subject: [PATCH 11/35] [Release v3.3.0] Merge into Main (#236) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * [Merge into Develop] Release v3.1.1 (#195) * [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 * Update issue templates (#127) * Update issue templates * Update bug_report.md * Update feature_request.md Update with Litewallet data * [Tech Debt] Update readme.md (#174) * update readme.md * per review notes * Clean up the cocoapod installation (#196) - Remove Firebase pod - Added Firebase Swift package - Removed some old dead code * [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 * [Feature] Unhide Litecoin card prod v1 (#203) * Unhiding the Card tab * Update the LitewalletPartnerAPI Swift package version * set tab item name * [Bugfix] Firebase Swift package does not archive (#210) * Resolved package * Readded pods - Firebase Crashlytics - Firebase Analytics - Updated the Litewallet API package * adjusted the forgot button (#201) * [Tech Debt] Removed extra Web class (#204) * Removed extra Web class * removed unused vc * [Bugfix] Fix buywebview (#215) * Resolve Crash issue * Fixes the webview * [Merge v3.2.0] into Develop (#217) * [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 Co-authored-by: Nikolay Spassov --- loafwallet.xcodeproj/project.pbxproj | 83 +-- 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 | 16 +- loafwallet/CHANGELOG.md | 22 + loafwallet/CardLoggedInView.swift | 1 + loafwallet/CardV1ToastView.swift | 86 ++++ loafwallet/CardView.swift | 9 + loafwallet/CopyButtonView.swift | 38 ++ loafwallet/HostingTransactionCell.swift | 46 ++ loafwallet/PartnersView.swift | 1 + loafwallet/PromptTableViewCell.swift | 105 ++++ loafwallet/RegistrationView.swift | 1 + loafwallet/StandardDividerView.swift | 25 + loafwallet/Storyboards/Main.storyboard | 13 +- .../Storyboards/Transactions.storyboard | 286 +---------- loafwallet/TabBarViewController.swift | 28 +- loafwallet/TransactionCellView.swift | 93 ++++ loafwallet/TransactionCellViewModel.swift | 119 +++++ loafwallet/TransactionModalView.swift | 250 ++++++++++ loafwallet/TransactionTableViewCells.swift | 311 ------------ loafwallet/TransactionsViewController.swift | 472 ++++++++---------- loafwallet/View+Extension.swift | 4 + loafwallet/src/Constants/Constants.swift | 2 + loafwallet/src/Constants/Strings.swift | 41 +- loafwallet/src/Controls/MenuButtonType.swift | 12 +- .../src/Extensions/String+Additions.swift | 6 +- loafwallet/src/ModalPresenter.swift | 25 +- .../Strings/Base.lproj/Localizable.strings | 72 +-- .../src/Strings/da.lproj/Localizable.strings | 72 +-- .../src/Strings/de.lproj/Localizable.strings | 72 +-- .../src/Strings/en.lproj/Localizable.strings | 72 +-- .../src/Strings/es.lproj/Localizable.strings | 72 +-- .../src/Strings/fr.lproj/Localizable.strings | 72 +-- .../src/Strings/id.lproj/Localizable.strings | 72 +-- .../src/Strings/it.lproj/Localizable.strings | 72 +-- .../src/Strings/ja.lproj/Localizable.strings | 72 +-- .../src/Strings/ko.lproj/Localizable.strings | 72 +-- .../src/Strings/nl.lproj/Localizable.strings | 72 +-- .../src/Strings/pt.lproj/Localizable.strings | 72 +-- .../src/Strings/ru.lproj/Localizable.strings | 72 +-- .../src/Strings/sv.lproj/Localizable.strings | 72 +-- .../Strings/zh-Hans.lproj/Localizable.strings | 84 +--- .../Strings/zh-Hant.lproj/Localizable.strings | 72 +-- .../RootModals/MenuViewController.swift | 10 +- loafwallet/src/ViewModels/Transaction.swift | 3 +- .../Views/TransactionCells/MaskedShadow.swift | 47 -- .../TransactionCells/RoundedContainer.swift | 45 -- .../TransactionTableViewCell.swift | 228 --------- 53 files changed, 1497 insertions(+), 2144 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/CHANGELOG.md create mode 100644 loafwallet/CardV1ToastView.swift 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..7d05026d5 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 */; }; @@ -276,6 +280,7 @@ 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 */; }; + C330B1C225EEF67600943FD8 /* CardV1ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C330B1C125EEF67600943FD8 /* CardV1ToastView.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 */; }; @@ -297,6 +302,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 +336,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 +404,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 +753,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 +1439,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 = ""; }; @@ -1444,6 +1452,7 @@ 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 = ""; }; + C330B1C125EEF67600943FD8 /* CardV1ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardV1ToastView.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 = ""; }; @@ -1453,6 +1462,7 @@ C35ABD322574073F002BB9BB /* PartnersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersViewModel.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 = ""; }; + C3ACF2DE25DED601008671D4 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; 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 = ""; }; @@ -1465,6 +1475,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 +1520,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 +1596,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 = ""; }; @@ -3000,6 +3008,7 @@ 24B523AF238A53DC0030594D /* BIP39Words.plist */, 2485F7CE23728C19005962F1 /* RELEASE_NOTES.md */, 24016D8D23F887C2006A6791 /* GoogleService-Info.plist */, + C3ACF2DE25DED601008671D4 /* CHANGELOG.md */, ); path = loafwallet; sourceTree = ""; @@ -3066,6 +3075,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 +3107,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 = ""; @@ -3289,6 +3312,7 @@ CEEC70891E945E3B00EF788E /* UnEditableTextView.swift */, CEEC708D1E954AAB00EF788E /* AboutCell.swift */, C3BD49C825954A1B00D97079 /* ForgotView.swift */, + C330B1C125EEF67600943FD8 /* CardV1ToastView.swift */, CEEC70911E95DA4400EF788E /* GradientSwitch.swift */, CE83DE291E9EB7F600D07636 /* SendAmountCell.swift */, CEE20C2C1EA288FA0086F724 /* UpdatingLabel.swift */, @@ -3395,10 +3419,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 +4178,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 +4191,8 @@ 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 */, + C330B1C225EEF67600943FD8 /* CardV1ToastView.swift in Sources */, 2228734F1E916FC30044BA15 /* BRAPIClient+Wallet.swift in Sources */, CEAA9EA81DC3342E0066731D /* PinView.swift in Sources */, CE1D84B61EAEB2F4002A5D7B /* UIBarButtonItem+Additions.swift in Sources */, @@ -4178,6 +4200,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 +4212,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 +4231,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 +4303,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 +4315,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 +4365,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 +4389,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 */, @@ -4664,7 +4689,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4678,7 +4703,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.2.0; + MARKETING_VERSION = 3.3.0; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4771,7 +4796,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4781,7 +4806,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.2.0; + MARKETING_VERSION = 3.3.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5082,7 +5107,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5095,7 +5120,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.2.0; + MARKETING_VERSION = 3.3.0; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5112,7 +5137,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5121,7 +5146,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.2.0; + MARKETING_VERSION = 3.3.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5212,7 +5237,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5226,7 +5251,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.2.0; + MARKETING_VERSION = 3.3.0; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5244,7 +5269,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5254,7 +5279,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.2.0; + MARKETING_VERSION = 3.3.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; 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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: View where Presenting: View { + + @Binding + var isShowingCardToast: Bool + + let presenting: Presenting + + var body: some View { + GeometryReader { (deviceSize: GeometryProxy) in + HStack{ + ZStack { + self.presenting.disabled(isShowingCardToast) + VStack { + Text(S.LitecoinCard.Disclaimer.title) + .font(Font(UIFont.barlowBold(size: 22.0))) + .foregroundColor(Color.white) + .padding([.top,.bottom], 20) + Text(S.LitecoinCard.Disclaimer.description) + .font(Font(UIFont.barlowMedium(size: 18.0))) + .multilineTextAlignment(.center) + .foregroundColor(Color.white) + .padding(.all, 10) + Text(S.LitecoinCard.Disclaimer.bullets) + .font(Font(UIFont.barlowSemiBold(size: 18.0))) + .foregroundColor(Color.white) + .padding(.all, 10) + Text(S.LitecoinCard.Disclaimer.referral) + .font(Font(UIFont.barlowMedium(size: 18.0))) + .multilineTextAlignment(.center) + .foregroundColor(Color.white) + .padding(.bottom, 20) + .padding([.leading,.trailing], 40) + + Divider().background(Color.white) + HStack { + Button(action: { + withAnimation { + self.isShowingCardToast.toggle() + } + }) { + Text(S.Button.ok) + .frame(minWidth:0, maxWidth: .infinity) + .padding() + .font(Font(UIFont.barlowBold(size: 20.0))) + .foregroundColor(Color.white) + } + } + } + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color.gray, lineWidth: 1.5) + ) + .background(Color(UIColor.liteWalletBlue)) + .cornerRadius(8) + .shadow(color: .black, radius: 10, x: 5, y: 5) + .opacity(self.isShowingCardToast ? 1 : 0) + } + } + } + } +} + +struct CardV1ToastView_Previews: PreviewProvider { + + + static var previews: some View { + VStack { + Spacer() + Text("") + .padding(.all, 10) + .cardV1ToastView(isShowingCardToast: .constant(true)) + Spacer() + } + } +} + + diff --git a/loafwallet/CardView.swift b/loafwallet/CardView.swift index 9d00a6785..504caa64e 100644 --- a/loafwallet/CardView.swift +++ b/loafwallet/CardView.swift @@ -12,6 +12,7 @@ import UIKit struct CardView: View { + //MARK: - Combine Variables @ObservedObject var viewModel: CardViewModel @@ -33,6 +34,9 @@ struct CardView: View { @State var didTapIForgot: Bool = false + @State + var didShowCardView: Bool = false + @State private var shouldShowRegistrationView: Bool = false @@ -232,7 +236,12 @@ struct CardView: View { animatedViewModel.dropOffset = -200 }.onReceive(NotificationCenter.default.publisher(for: NSNotification.Name.UIKeyboardWillHide)) { _ in animatedViewModel.dropOffset = 0 + }.onAppear(){ + didShowCardView = true } + .cardV1ToastView(isShowingCardToast: $didShowCardView) + .animation(.easeOut) + .transition(.scale) .forgotPasswordView(isShowingForgot: $didTapIForgot, emailString: $forgotEmailAddressInput, message: S.LitecoinCard.forgotPassword) diff --git a/loafwallet/CopyButtonView.swift b/loafwallet/CopyButtonView.swift new file mode 100644 index 000000000..0721b2b6f --- /dev/null +++ b/loafwallet/CopyButtonView.swift @@ -0,0 +1,38 @@ +// +// CopyButtonView.swift +// loafwallet +// +// Created by Kerry Washington on 2/7/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct CopyButtonView: View { + + var idString: String + + init(idString: String) { + self.idString = idString + } + var body: some View { + + Button(action: { + UIPasteboard.general.string = idString + }) { + Image(systemName: "doc.on.doc") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 15.0, + height: 30, + alignment: .center) + .foregroundColor(Color(UIColor.darkGray)) + } + } +} + +struct CopyButtonView_Previews: PreviewProvider { + static var previews: some View { + CopyButtonView(idString: "TEST") + } +} diff --git a/loafwallet/HostingTransactionCell.swift b/loafwallet/HostingTransactionCell.swift new file mode 100644 index 000000000..ae320bf09 --- /dev/null +++ b/loafwallet/HostingTransactionCell.swift @@ -0,0 +1,46 @@ +// +// HostingTransactionCell.swift +// loafwallet +// +// Created by Kerry Washington on 2/5/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI + +final class HostingTransactionCell: 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..04dcf1757 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/Main.storyboard b/loafwallet/Storyboards/Main.storyboard index dd20cc8e9..e51064663 100644 --- a/loafwallet/Storyboards/Main.storyboard +++ b/loafwallet/Storyboards/Main.storyboard @@ -29,7 +29,7 @@ - + @@ -66,7 +66,7 @@ - + + + @@ -125,6 +133,7 @@ + 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/TabBarViewController.swift b/loafwallet/TabBarViewController.swift index 1c52f3eac..9f96d8002 100644 --- a/loafwallet/TabBarViewController.swift +++ b/loafwallet/TabBarViewController.swift @@ -26,7 +26,8 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel @IBOutlet weak var timeStampLabel: UILabel! @IBOutlet weak var timeStampStackView: UIStackView! @IBOutlet weak var timeStampStackViewHeight: NSLayoutConstraint! - + @IBOutlet weak var walletBalanceLabel: UILabel! + var primaryBalanceLabel: UpdatingLabel? var secondaryBalanceLabel: UpdatingLabel? private let largeFontSize: CGFloat = 24.0 @@ -94,6 +95,8 @@ class TabBarViewController: UIViewController, Subscriber, Trackable, UITabBarDel private func setupViews() { + walletBalanceLabel.text = S.ManageWallet.balance + ":" + if #available(iOS 11.0, *), let backgroundColor = UIColor(named: "mainColor") { headerView.backgroundColor = backgroundColor @@ -220,6 +223,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 +270,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 +418,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/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/View+Extension.swift b/loafwallet/View+Extension.swift index 7733ecc34..a1506b293 100644 --- a/loafwallet/View+Extension.swift +++ b/loafwallet/View+Extension.swift @@ -40,5 +40,9 @@ extension View { presenting: self) } + func cardV1ToastView(isShowingCardToast: Binding) -> some View { + loafwallet.CardV1ToastView(isShowingCardToast: isShowingCardToast, + presenting: self) + } } 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 { diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index eabf375fb..c658e54a2 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -130,6 +130,14 @@ enum S { static let registrationSuccess = NSLocalizedString("LitecoinCard.registrationSuccess", value: "", comment: "Registration success") static let registrationFailure = NSLocalizedString("LitecoinCard.registrationFailure", value: "", comment: "Registration failure") + //MARK: - Disclaimer + enum Disclaimer { + static let title = NSLocalizedString("LitecoinCard.Disclaimer.title", value: "Beta Testing Litecoin Card", comment: "Beta Testing Litecoin Card") + static let description = NSLocalizedString("LitecoinCard.Disclaimer.description", value: "Description", comment: "Description of the status") + static let bullets = NSLocalizedString("LitecoinCard.Disclaimer.bullets", value: "bullets", comment: "Features and limitations") + static let referral = NSLocalizedString("LitecoinCard.Disclaimer.referral", value: "referral", comment: "Referral to the website") + } + //MARK: - Registration enum Registration { static let registerCardPhrase = NSLocalizedString("LitecoinCard.registerCardPhrase", value: "**Register for Litecoin Card**", comment: "Register for Litecoin Card") @@ -238,6 +246,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 @@ -304,6 +314,8 @@ enum S { static let textFieldLabel = NSLocalizedString("ManageWallet.textFeildLabel", value: "**Wallet Name**", comment: "Change Wallet name textfield label") static let description = NSLocalizedString("ManageWallet.description", value: "**Your wallet name only appears in your account transaction history and cannot be seen by anyone else.**", comment: "Manage wallet description text") static let creationDatePrefix = NSLocalizedString("ManageWallet.creationDatePrefix", value: "**You created your wallet on %1$@**", comment: "Wallet creation date prefix") + static let balance = NSLocalizedString("ManageWallet.balance", value: "**Balance**", comment: "Balance") + } enum AccountHeader { @@ -621,19 +633,7 @@ enum S { static let highFees = NSLocalizedString("Import.Error.highFees", value: "**Transaction fees would cost more than the funds available on this private key.**", comment: "High fees error message") 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 +692,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/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/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/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/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 90e42bf76..72629cec4 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,24 @@ /* Failed Login */ "LitecoinCard.failed.login" = "Login failed"; + +/* Copied */ +"TransactionDetails.copiedAll" = "Copied"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "Copy all details"; + +/* Balance */ +"ManageWallet.balance" = "Balance"; + +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- New Registration\n- Login (existing account)\n- No balance shown\n- No transfer\n- US Only"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin Card currently has limited functionality in Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Visit litecoin.getblockcard.com for full access"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin Card Beta"; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index 18f54d2e7..6ad68da66 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Kortbalance"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Ny registrering\n- Login (eksisterende konto)\n- Ingen balance vist\n- Ingen overførsel\n- Kun USA"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin Card har i øjeblikket begrænset funktionalitet i Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Besøg litecoin.getblockcard.com for fuld adgang"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin-kort Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Login mislykkedes"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "Fejlformet URI"; +/* Balance */ +"ManageWallet.balance" = "Balance"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Du lavede din pung den %1$@"; @@ -1165,6 +1129,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..77dbe0bab 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Kartenguthaben"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Neue Registrierung\n- In vorhandenen Account (einloggen)\n- Kein Saldo angezeigt\n- Keine Übertragung\n- Nur USA"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Die Litecoin Card verfügt derzeit über eingeschränkte Funktionen in Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Besuchen Sie litecoin.getblockcard.com für den vollständigen Zugriff"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin Card Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Anmeldung fehlgeschlagen"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "Fehlgestalteter URI"; +/* Balance */ +"ManageWallet.balance" = "Kontostand"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Du hast dein Wallet am %1$@ erstellt"; @@ -1165,6 +1129,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..9e3191028 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Card balance"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- New Registration\n- Login (existing account)\n- No balance shown\n- No transfer\n- US Only"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin Card currently has limited functionality in Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Visit litecoin.getblockcard.com for full access"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin Card Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Login failed"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "Malformed URI"; +/* Balance */ +"ManageWallet.balance" = "Balance"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "You created your wallet on %1$@"; @@ -1165,6 +1129,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..2fab64959 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"; @@ -419,6 +368,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Balance de tarjeta"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Nuevo registro\n- Ingrese cuenta existente)\n- No se muestra saldo\n- Sin transferencia\n- Estados Unidos solamente"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "La tarjeta Litecoin actualmente tiene una funcionalidad limitada en Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Visite litecoin.getblockcard.com para obtener acceso completo"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Tarjeta Litecoin Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "error de inicio de sesion"; @@ -530,6 +491,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "URI malformado"; +/* Balance */ +"ManageWallet.balance" = "Saldo"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Has creado una cartera en %1$@"; @@ -1166,6 +1130,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..cb53c821c 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Solde de la carte"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Nouvelle inscription\n- Connexion (compte existant)\n- Aucun solde affiché\n- Pas de transfert\n- États-Unis uniquement"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "La carte Litecoin a actuellement des fonctionnalités limitées dans Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Visitez litecoin.getblockcard.com pour un accès complet"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Bêta de la carte Litecoin"; + /* Failed Login */ "LitecoinCard.failed.login" = "Échec de la connexion"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "URI mal formé"; +/* Balance */ +"ManageWallet.balance" = "Solde"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Vous avez créé votre portefeuille sur %1$@"; @@ -1165,6 +1129,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..22b78ebb1 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Saldo kartu"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Pendaftaran baru\n- Masuk (akun yang ada)\n- Tidak ada saldo yang ditampilkan\n- Tidak ada transfer\n- Hanya AS"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Kartu Litecoin saat ini memiliki fungsi terbatas di Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Kunjungi litecoin.getblockcard.com untuk akses penuh"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Kartu Litecoin Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Gagal masuk"; @@ -529,6 +490,9 @@ /* Http error code */ "Malformed URI" = "URI cacat"; +/* Balance */ +"ManageWallet.balance" = "Saldo"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Anda membuat dompet Anda di %1$@"; @@ -1165,6 +1129,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..43803e034 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Saldo della carta"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Nuova registrazione\n- Log in in un account esistente)\n- Nessun saldo mostrato\n- Nessun trasferimento\n- Solo USA"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin Card ha attualmente funzionalità limitate in Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Visita litecoin.getblockcard.com per l'accesso completo"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin Card Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Accesso fallito"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "URI non valido"; +/* Balance */ +"ManageWallet.balance" = "Saldo"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Hai creato il tuo portafoglio il %1$@"; @@ -1165,6 +1129,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..e0671d1f1 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" = "購入"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "カード残高"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "-新規登録\n-ログイン(既存のアカウント)\n-残高は表示されていません\n-転送なし\n-米国のみ"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "ライトコインカードは現在、ライトウォレットの機能が制限されています。"; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "フルアクセスについては、litecoin.getblockcard.comにアクセスしてください"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "ライトコインカードベータ"; + /* Failed Login */ "LitecoinCard.failed.login" = "ログインに失敗しました"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "不正なURI"; +/* Balance */ +"ManageWallet.balance" = "残高"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "あなたは%1$@でご自身のウォレットを作成しました"; @@ -1165,6 +1129,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..1f337282c 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" = "구입"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "카드 잔액"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "-신규 등록\n-로그인 (기존 계정)\n-잔액이 표시되지 않음\n-환승 불가\n-미국 만"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "라이트 코인 카드는 현재 라이트 월렛에서 제한된 기능을 가지고 있습니다."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "전체 액세스를 위해 litecoin.getblockcard.com을 방문하십시오."; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "라이트 코인 카드 베타"; + /* Failed Login */ "LitecoinCard.failed.login" = "로그인 실패"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "잘못된 URI"; +/* Balance */ +"ManageWallet.balance" = "밸런스"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "귀하께서는 %1$@ 에 지갑을 만들었습니다"; @@ -1165,6 +1129,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..f7060a806 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Kaartsaldo"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Nieuwe registratie\n- Inloggen (bestaand account)\n- Geen saldo weergegeven\n- Geen overdracht\n- Alleen in de VS."; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin Card heeft momenteel beperkte functionaliteit in Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Bezoek litecoin.getblockcard.com voor volledige toegang"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin Card Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Inloggen mislukt"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "Misvormde URI"; +/* Balance */ +"ManageWallet.balance" = "Saldo"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Je hebt je portemonnee gecreëerd op %1$@"; @@ -1165,6 +1129,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..88c978409 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"; @@ -419,6 +368,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Saldo do cartão"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Novo registro\n- Entrar em uma conta existente)\n- Nenhum saldo mostrado\n- Sem transferência\n- Apenas estados unidos"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "O cartão Litecoin atualmente tem funcionalidade limitada no Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Visite litecoin.getblockcard.com para acesso total"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin Card Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Falha na autenticação"; @@ -530,6 +491,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "URI malformado"; +/* Balance */ +"ManageWallet.balance" = "Saldo"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Criou a sua carteira em %1$@"; @@ -1166,6 +1130,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..b00e040fd 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" = "купить"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Баланс карты"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Новая регистрация\n- Авторизация (существующая учетная запись)\n- Баланс не отображается\n- Без передачи\n- Только США"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin Card в настоящее время имеет ограниченную функциональность в Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Посетите litecoin.getblockcard.com для полного доступа"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Бета-версия карты Litecoin"; + /* Failed Login */ "LitecoinCard.failed.login" = "Ошибка входа"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "Неверно сформированный URI"; +/* Balance */ +"ManageWallet.balance" = "Баланс"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Вы создали ваш кошелек %1$@"; @@ -1165,6 +1129,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..379182bc0 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"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "Kortbalans"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "- Ny registrering\n- Inloggning (befintligt konto)\n- Ingen balans visas\n- Ingen överföring\n- Endast USA"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin Card har för närvarande begränsad funktionalitet i Litewallet."; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "Besök litecoin.getblockcard.com för fullständig åtkomst"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin-kort Beta"; + /* Failed Login */ "LitecoinCard.failed.login" = "Inloggningen misslyckades"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "Felaktig URI"; +/* Balance */ +"ManageWallet.balance" = "Balans"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "Du skapade din plånbok på %1$@"; @@ -1165,6 +1129,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..7d6f0a825 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" = "购买"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "卡余额"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "-新注册\n-登录(现有帐户\n-没有余额显示\n-没有转移\n-仅限美国"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin卡当前在Litewallet中具有有限的功能。"; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "访问litecoin.getblockcard.com以获取完全访问权限"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin卡测试版"; + /* Failed Login */ "LitecoinCard.failed.login" = "登录失败"; @@ -433,6 +394,9 @@ /* Register */ "LitecoinCard.registerCard" = "寄存器"; +/* Register for Litecoin Card */ +"LitecoinCard.registerCardPhrase" = "注册莱特币卡"; + /* Registering user... */ "LitecoinCard.registering.user" = "正在注册用户..."; @@ -451,6 +415,9 @@ /* First name */ "LitecoinCard.Registration.firstName" = "名字"; +/* identification */ +"LitecoinCard.Registration.identification" = "身份证明"; + /* kycIDNumber */ "LitecoinCard.Registration.kycIDNumber" = "了解你的顾客 证件类型"; @@ -523,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "URI格式错误"; +/* Balance */ +"ManageWallet.balance" = "平衡"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "您在%1$@上创建了您的钱包"; @@ -1159,6 +1129,12 @@ /* Memo section header */ "TransactionDetails.commentsHeader" = "备忘录"; +/* Copied */ +"TransactionDetails.copiedAll" = "复制的"; + +/* Copy all details */ +"TransactionDetails.copyAllDetails" = "复制所有详细信息"; + /* Empty transaction list message. */ "TransactionDetails.emptyMessage" = "您的交易将显示在这里。"; @@ -1380,9 +1356,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..72e8bebc8 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" = "購買"; @@ -418,6 +367,18 @@ /* Card balance */ "LitecoinCard.cardBalance" = "卡餘額"; +/* Features and limitations */ +"LitecoinCard.Disclaimer.bullets" = "-新註冊\n-登錄(現有帳戶)\n-沒有餘額顯示\n-沒有轉移\n-僅限美國"; + +/* Description of the status */ +"LitecoinCard.Disclaimer.description" = "Litecoin卡當前在Litewallet中具有有限的功能。"; + +/* Referral to the website */ +"LitecoinCard.Disclaimer.referral" = "訪問litecoin.getblockcard.com以獲取完全訪問權限"; + +/* Beta Testing Litecoin Card */ +"LitecoinCard.Disclaimer.title" = "Litecoin卡測試版"; + /* Failed Login */ "LitecoinCard.failed.login" = "登錄失敗"; @@ -529,6 +490,9 @@ /* No comment provided by engineer. */ "Malformed URI" = "URI格式錯誤"; +/* Balance */ +"ManageWallet.balance" = "平衡"; + /* Wallet creation date prefix */ "ManageWallet.creationDatePrefix" = "您在 %1$@ 建立了電子錢包"; @@ -1165,6 +1129,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/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: 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 0db91dea20e4e29678f45c636d4e3d2688f0d554 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 18 Apr 2021 01:14:51 +0100 Subject: [PATCH 12/35] =?UTF-8?q?=F0=9F=9A=80[Release=20v3.4.0]=20Merge=20?= =?UTF-8?q?into=20Main=20(#263)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * [Merge into Develop] Release v3.1.1 (#195) * [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 * Update issue templates (#127) * Update issue templates * Update bug_report.md * Update feature_request.md Update with Litewallet data * [Tech Debt] Update readme.md (#174) * update readme.md * per review notes * Clean up the cocoapod installation (#196) - Remove Firebase pod - Added Firebase Swift package - Removed some old dead code * [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 * [Feature] Unhide Litecoin card prod v1 (#203) * Unhiding the Card tab * Update the LitewalletPartnerAPI Swift package version * set tab item name * [Bugfix] Firebase Swift package does not archive (#210) * Resolved package * Readded pods - Firebase Crashlytics - Firebase Analytics - Updated the Litewallet API package * adjusted the forgot button (#201) * [Tech Debt] Removed extra Web class (#204) * Removed extra Web class * removed unused vc * [Bugfix] Fix buywebview (#215) * Resolve Crash issue * Fixes the webview * [Merge v3.2.0] into Develop (#217) * [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 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 Co-authored-by: Nikolay Spassov --- Podfile | 2 +- loafwallet.xcodeproj/project.pbxproj | 208 ++++++---- .../xcshareddata/swiftpm/Package.resolved | 4 +- loafwallet/AlertFailureView.swift | 60 +++ .../moonpay-logo.imageset/Contents.json | 21 + .../moonpay-logo.imageset/moonpay-logo.png | Bin 0 -> 4073 bytes loafwallet/BuyTableViewController.swift | 105 ++++- loafwallet/BuyWKWebViewController.swift | 103 ++--- loafwallet/CardLoggedInView.swift | 12 +- loafwallet/CardView.swift | 34 +- loafwallet/CardViewController.swift | 5 + loafwallet/CardViewModel.swift | 48 ++- loafwallet/CardWalletDetails.swift | 45 +++ loafwallet/DomainResolutionFailure.swift | 27 ++ loafwallet/EmptyTableViewCell.swift | 14 + loafwallet/FailedAlertView.swift | 42 ++ loafwallet/ForgotAlertViewModel.swift | 39 ++ loafwallet/ForgotView.swift | 79 +++- loafwallet/PartnerData.swift | 8 +- loafwallet/RegistrationViewModel.swift | 12 +- loafwallet/Storyboards/Buy.storyboard | 169 +++++++- .../Storyboards/Transactions.storyboard | 9 + loafwallet/TransactionsViewController.swift | 363 +++++++++++------- loafwallet/UIApplication+Extension.swift | 16 + loafwallet/UnstoppableDomainViewModel.swift | 28 +- loafwallet/src/Constants/Constants.swift | 2 +- loafwallet/src/Constants/Strings.swift | 12 +- loafwallet/src/ModalPresenter.swift | 45 ++- .../Strings/Base.lproj/Localizable.strings | 26 +- .../src/Strings/da.lproj/Localizable.strings | 20 +- .../src/Strings/de.lproj/Localizable.strings | 20 +- .../src/Strings/en.lproj/Localizable.strings | 20 +- .../src/Strings/es.lproj/Localizable.strings | 20 +- .../src/Strings/fr.lproj/Localizable.strings | 20 +- .../src/Strings/id.lproj/Localizable.strings | 20 +- .../src/Strings/it.lproj/Localizable.strings | 20 +- .../src/Strings/ja.lproj/Localizable.strings | 20 +- .../src/Strings/ko.lproj/Localizable.strings | 20 +- .../src/Strings/nl.lproj/Localizable.strings | 20 +- .../src/Strings/pt.lproj/Localizable.strings | 20 +- .../src/Strings/ru.lproj/Localizable.strings | 20 +- .../src/Strings/sv.lproj/Localizable.strings | 20 +- .../Strings/zh-Hans.lproj/Localizable.strings | 20 +- .../Strings/zh-Hant.lproj/Localizable.strings | 20 +- .../RootModals/SendViewController.swift | 7 + loafwallet/src/Views/AlertView.swift | 148 +++---- .../LitecoinCardTests/CardWalletTests.swift | 129 +++++++ 47 files changed, 1630 insertions(+), 492 deletions(-) create mode 100644 loafwallet/AlertFailureView.swift create mode 100644 loafwallet/Assets.xcassets/Partners/moonpay-logo.imageset/Contents.json create mode 100644 loafwallet/Assets.xcassets/Partners/moonpay-logo.imageset/moonpay-logo.png create mode 100644 loafwallet/CardWalletDetails.swift create mode 100644 loafwallet/DomainResolutionFailure.swift create mode 100644 loafwallet/EmptyTableViewCell.swift create mode 100644 loafwallet/FailedAlertView.swift create mode 100644 loafwallet/ForgotAlertViewModel.swift create mode 100644 loafwallet/UIApplication+Extension.swift create mode 100644 loafwalletTests/Class Tests/LitecoinCardTests/CardWalletTests.swift diff --git a/Podfile b/Podfile index 2b9ebb14c..a098efbb0 100644 --- a/Podfile +++ b/Podfile @@ -7,7 +7,7 @@ platform :ios, '13.0' #Shared Cocopods def shared_pods - pod 'UnstoppableDomainsResolution', '~> 0.1.6' + pod 'UnstoppableDomainsResolution', '~> 0.3.0' pod 'KeychainAccess', '~> 4.2' pod 'Firebase/Analytics' pod 'Firebase/Crashlytics' diff --git a/loafwallet.xcodeproj/project.pbxproj b/loafwallet.xcodeproj/project.pbxproj index 7d05026d5..17dac94cc 100644 --- a/loafwallet.xcodeproj/project.pbxproj +++ b/loafwallet.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 125EE14518C50D13A5D2D20C /* Pods_loafwallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D269CE1129DB450BA5594B69 /* 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 */; }; @@ -130,6 +131,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 */; }; + 739630821DA6F873BA57755B /* Pods_loafwalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEE1B45F7430F6BA698E4972 /* Pods_loafwalletTests.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 */; }; @@ -264,15 +266,15 @@ 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 */; }; - 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 */; }; + C308993F2616124800EE6A40 /* CardWalletTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C308993E2616124800EE6A40 /* CardWalletTests.swift */; }; + C30899792616426800EE6A40 /* ForgotAlertViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30899782616426800EE6A40 /* ForgotAlertViewModel.swift */; }; C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */ = {isa = PBXBuildFile; productRef = C30AFB4D2598FC1B00CDCF69 /* LitewalletPartnerAPI */; }; C30AFB642598FFB200CDCF69 /* PartnerAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */; }; + C316CF49261887FC00E4C09B /* UIApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C316CF48261887FC00E4C09B /* UIApplication+Extension.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 */; }; @@ -289,6 +291,7 @@ 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 */; }; + C39A71472608CB4300E7B640 /* EmptyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C39A71462608CB4300E7B640 /* EmptyTableViewCell.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 */; }; @@ -301,6 +304,7 @@ 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 */; }; + C3BF74D926114969001CE2BB /* CardWalletDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BF74D826114969001CE2BB /* CardWalletDetails.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 */; }; @@ -310,6 +314,10 @@ 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 */; }; + C3F7BCDC25FEC6AD00694C28 /* FailedAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F7BCD925FEC6AC00694C28 /* FailedAlertView.swift */; }; + C3F7BCDD25FEC6AD00694C28 /* DomainResolutionFailure.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F7BCDA25FEC6AC00694C28 /* DomainResolutionFailure.swift */; }; + C3F7BCDE25FEC6AD00694C28 /* AlertFailureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F7BCDB25FEC6AC00694C28 /* AlertFailureView.swift */; }; + C3F7BD0325FEC77100694C28 /* TransactionModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F7BD0225FEC77100694C28 /* TransactionModalView.swift */; }; CE03EC741EF256AC0038E3A8 /* SimpleUTXO.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */; }; CE0CD1591DBFBCF5004023DA /* ModalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0CD1581DBFBCF5004023DA /* ModalPresenter.swift */; }; CE124CF81E67A8E500DFA146 /* TransactionDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE124CF71E67A8E500DFA146 /* TransactionDirection.swift */; }; @@ -574,6 +582,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 05AEEC8F8E25C740ED8981CB /* 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 = ""; }; + 153E10D934A51A7F817FA6B0 /* 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,8 +844,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 = ""; }; - 6008481CC5B78F1CF8F9EA57 /* 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 = ""; }; - 65B44EBCC7D4AFCDB8B91F8A /* 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 = ""; }; + 5C15DA44F99E3C163A716207 /* 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 = ""; }; 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 = ""; }; @@ -1435,16 +1444,15 @@ 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; }; - 96694FA018937A83E970CC55 /* 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 = ""; }; - 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 = ""; }; + 88220266EF282D1F355BB238 /* 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 = ""; }; C30029E125D0185500F08C2B /* StandardDividerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardDividerView.swift; sourceTree = ""; }; C30029EA25D019BC00F08C2B /* CopyButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyButtonView.swift; sourceTree = ""; }; + C308993E2616124800EE6A40 /* CardWalletTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardWalletTests.swift; sourceTree = ""; }; + C30899782616426800EE6A40 /* ForgotAlertViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForgotAlertViewModel.swift; sourceTree = ""; }; C30AFB632598FFB200CDCF69 /* PartnerAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnerAPIManager.swift; sourceTree = ""; }; + C316CF48261887FC00E4C09B /* UIApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Extension.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 = ""; }; @@ -1461,6 +1469,7 @@ C35ABD222574070A002BB9BB /* PartnersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersView.swift; sourceTree = ""; }; C35ABD322574073F002BB9BB /* PartnersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartnersViewModel.swift; sourceTree = ""; }; C379F227259B9BF000B25883 /* RegistrationAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationAlertView.swift; sourceTree = ""; }; + C39A71462608CB4300E7B640 /* EmptyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyTableViewCell.swift; sourceTree = ""; }; C3A4647C259A646A00D74D81 /* DataValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataValidation.swift; sourceTree = ""; }; C3ACF2DE25DED601008671D4 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; }; C3B7C3B8255EABBF00E98A64 /* SupportSafariViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportSafariViewModel.swift; sourceTree = ""; }; @@ -1474,6 +1483,7 @@ 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 = ""; }; + C3BF74D826114969001CE2BB /* CardWalletDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardWalletDetails.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 = ""; }; @@ -1483,6 +1493,10 @@ 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 = ""; }; + C3F7BCD925FEC6AC00694C28 /* FailedAlertView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FailedAlertView.swift; sourceTree = ""; }; + C3F7BCDA25FEC6AC00694C28 /* DomainResolutionFailure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainResolutionFailure.swift; sourceTree = ""; }; + C3F7BCDB25FEC6AC00694C28 /* AlertFailureView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertFailureView.swift; sourceTree = ""; }; + C3F7BD0225FEC77100694C28 /* TransactionModalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionModalView.swift; sourceTree = ""; }; CE03EC731EF256AC0038E3A8 /* SimpleUTXO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SimpleUTXO.swift; path = src/Models/SimpleUTXO.swift; sourceTree = ""; }; CE0CD1581DBFBCF5004023DA /* ModalPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = ModalPresenter.swift; path = src/ModalPresenter.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; CE0FC0F81F72417200E7C626 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; @@ -1653,8 +1667,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 = ""; }; - D25607DBC5E9F06B12996E3E /* 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 = ""; }; - D69FD9757DAE828E1DB3DC2D /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D269CE1129DB450BA5594B69 /* Pods_loafwallet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwallet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DA0A9E434AE0804412FE6C43 /* 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 = ""; }; + EEE1B45F7430F6BA698E4972 /* Pods_loafwalletTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_loafwalletTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F0E743170D714EE124029E99 /* 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 */ @@ -1670,7 +1686,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 92FB6A24C5F95B5239A226B4 /* Pods_loafwalletTests.framework in Frameworks */, + 739630821DA6F873BA57755B /* Pods_loafwalletTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1710,7 +1726,7 @@ C30AFB4E2598FC1B00CDCF69 /* LitewalletPartnerAPI in Frameworks */, 752FB04D1DF8BF4B009086FB /* sqlite3.framework in Frameworks */, 759DA0BE1DAC36A3008CC49B /* libBRCore.a in Frameworks */, - BC40800031AC198047C76D8C /* Pods_loafwallet.framework in Frameworks */, + 125EE14518C50D13A5D2D20C /* Pods_loafwallet.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3028,8 +3044,8 @@ 75FEFD1B1DAED56E00203D3A /* libsqlite3.tbd */, 75A2A7F21DA5935F00A983D8 /* Messages.framework */, 75A2A8091DA5936F00A983D8 /* NotificationCenter.framework */, - D69FD9757DAE828E1DB3DC2D /* Pods_loafwallet.framework */, - 9AC86E61BB430C1275F605F8 /* Pods_loafwalletTests.framework */, + D269CE1129DB450BA5594B69 /* Pods_loafwallet.framework */, + EEE1B45F7430F6BA698E4972 /* Pods_loafwalletTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -3080,8 +3096,8 @@ children = ( C32142E925C97CD900BECCD0 /* TransactionCellView.swift */, C3C8973725CD6B9300241FBE /* HostingTransactionCell.swift */, - C321442A25CC2B2C00BECCD0 /* TransactionModalView.swift */, C32142F925C988C800BECCD0 /* TransactionCellViewModel.swift */, + C3F7BD0225FEC77100694C28 /* TransactionModalView.swift */, ); name = Transactions; sourceTree = ""; @@ -3090,6 +3106,7 @@ isa = PBXGroup; children = ( C3270B98259BF7F20073DA7B /* LitecoinCardUser.swift */, + C3BF74D826114969001CE2BB /* CardWalletDetails.swift */, ); name = CardModels; sourceTree = ""; @@ -3098,6 +3115,7 @@ isa = PBXGroup; children = ( C345D81425A8D52600657E30 /* LoginViewModelTests.swift */, + C308993E2616124800EE6A40 /* CardWalletTests.swift */, C345D83625A8D57E00657E30 /* AnimatedCardViewModelTests.swift */, C345D82425A8D54200657E30 /* RegistrationViewModelTests.swift */, ); @@ -3107,7 +3125,11 @@ C35ABD07257404C6002BB9BB /* SwiftUI+UIKit */ = { isa = PBXGroup; children = ( + C3F7BCD825FEC69B00694C28 /* Alerts */, C32142E825C97CB900BECCD0 /* Transactions */, + C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, + C3BD4A692597E1E900D97079 /* CardLoggedInView.swift */, + C3F55643255A1916005F786F /* SupportLitecoinFoundation */, C35ABD08257404D2002BB9BB /* Partners */, C35ABD0925740518002BB9BB /* About */, C3D783A52565EA1E0004FF70 /* Unstoppable */, @@ -3160,6 +3182,17 @@ name = SupportLitecoinFoundation; sourceTree = ""; }; + C3F7BCD825FEC69B00694C28 /* Alerts */ = { + isa = PBXGroup; + children = ( + C3F7BCDB25FEC6AC00694C28 /* AlertFailureView.swift */, + C3F7BCDA25FEC6AC00694C28 /* DomainResolutionFailure.swift */, + C3F7BCD925FEC6AC00694C28 /* FailedAlertView.swift */, + C30899782616426800EE6A40 /* ForgotAlertViewModel.swift */, + ); + name = Alerts; + sourceTree = ""; + }; CE1E5F241EF081F300BD0F72 /* Import */ = { isa = PBXGroup; children = ( @@ -3219,6 +3252,7 @@ C3BD4A5225975C6000D97079 /* View+Extension.swift */, C32DAE0625925B7E003FC978 /* Color+Extension.swift */, CE20C8FB1DBB0F3A00C8397A /* UIColor+Extension.swift */, + C316CF48261887FC00E4C09B /* UIApplication+Extension.swift */, CE20C90D1DBE52B000C8397A /* UIView+BRWAdditions.swift */, CE20C9161DBE6F2A00C8397A /* UIButton+BRWAdditions.swift */, CEAA9E901DC0FDFE0066731D /* UIViewPropertyAnimator+BRWAdditions.swift */, @@ -3274,9 +3308,6 @@ CE20C90F1DBE5B5100C8397A /* Views */ = { isa = PBXGroup; children = ( - C3B7C3C1255EAF1200E98A64 /* SupportSafariView.swift */, - C3BD4A692597E1E900D97079 /* CardLoggedInView.swift */, - C3F55643255A1916005F786F /* SupportLitecoinFoundation */, 24BA90C52410129E001E3825 /* FeeSelectorView.swift */, C32DC7AB2593B5C900A7FDB4 /* AnimatedCardView.swift */, CE6BCF5C1EE9E89A0029849C /* CustomTitleView.swift */, @@ -3420,6 +3451,7 @@ isa = PBXGroup; children = ( 24313C8523821B8C00A83F69 /* PromptTableViewCell.swift */, + C39A71462608CB4300E7B640 /* EmptyTableViewCell.swift */, ); name = TransactionCells; sourceTree = ""; @@ -3504,12 +3536,12 @@ FEE036865998B9DFEEF3139A /* Pods */ = { isa = PBXGroup; children = ( - 6008481CC5B78F1CF8F9EA57 /* Pods-loafwallet.debug.xcconfig */, - B1E980ED11476D536096EFFC /* Pods-loafwallet.testnet.xcconfig */, - A3E5444354AB8914A966CDC2 /* Pods-loafwallet.release.xcconfig */, - D25607DBC5E9F06B12996E3E /* Pods-loafwalletTests.debug.xcconfig */, - 65B44EBCC7D4AFCDB8B91F8A /* Pods-loafwalletTests.testnet.xcconfig */, - 96694FA018937A83E970CC55 /* Pods-loafwalletTests.release.xcconfig */, + F0E743170D714EE124029E99 /* Pods-loafwallet.debug.xcconfig */, + 5C15DA44F99E3C163A716207 /* Pods-loafwallet.testnet.xcconfig */, + 88220266EF282D1F355BB238 /* Pods-loafwallet.release.xcconfig */, + 05AEEC8F8E25C740ED8981CB /* Pods-loafwalletTests.debug.xcconfig */, + DA0A9E434AE0804412FE6C43 /* Pods-loafwalletTests.testnet.xcconfig */, + 153E10D934A51A7F817FA6B0 /* Pods-loafwalletTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -3573,7 +3605,7 @@ isa = PBXNativeTarget; buildConfigurationList = 2465873D23A5AAD100A32E9E /* Build configuration list for PBXNativeTarget "loafwalletTests" */; buildPhases = ( - 5723028C3694917363D260E0 /* [CP] Check Pods Manifest.lock */, + 6667AA56BFA4804A96E62DB8 /* [CP] Check Pods Manifest.lock */, 2465873223A5AAD000A32E9E /* Sources */, 2465873323A5AAD000A32E9E /* Frameworks */, 2465873423A5AAD000A32E9E /* Resources */, @@ -3646,16 +3678,16 @@ isa = PBXNativeTarget; buildConfigurationList = 75A2A7E31DA5934400A983D8 /* Build configuration list for PBXNativeTarget "loafwallet" */; buildPhases = ( - 832DFB05CE15FD50F6854519 /* [CP] Check Pods Manifest.lock */, + E85603DAE7C21FF2F41766D3 /* [CP] Check Pods Manifest.lock */, 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */, - 24E179F223BDAF8000F928D9 /* Xcode custom warnings */, + 24E179F223BDAF8000F928D9 /* [CP] Check Pods Manifest.lock */, 75A2A78C1DA5934300A983D8 /* Sources */, 75A2A78D1DA5934300A983D8 /* Frameworks */, 75A2A78E1DA5934300A983D8 /* Resources */, 75A2A8031DA5935F00A983D8 /* Embed App Extensions */, 22A9A9831DF63288000F0016 /* Embed Frameworks */, C3D1588125666B69009BD3BC /* Mark Dev Notes */, - 0A6FE96D6D66CEA3039B3345 /* [CP] Embed Pods Frameworks */, + 36D1EB58A4FF1ABB1FD7DD93 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -3890,23 +3922,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 0A6FE96D6D66CEA3039B3345 /* [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; - }; 2430679A238F538C00EBEA99 /* Update Localizable using BartyCrouch */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 12; @@ -3921,16 +3936,18 @@ 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"; }; - 24E179F223BDAF8000F928D9 /* Xcode custom warnings */ = { + 24E179F223BDAF8000F928D9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "Xcode custom warnings"; + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( @@ -3939,29 +3956,24 @@ 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"; }; - 5723028C3694917363D260E0 /* [CP] Check Pods Manifest.lock */ = { + 36D1EB58A4FF1ABB1FD7DD93 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwalletTests-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); 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"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-loafwallet/Pods-loafwallet-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 832DFB05CE15FD50F6854519 /* [CP] Check Pods Manifest.lock */ = { + 6667AA56BFA4804A96E62DB8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3976,7 +3988,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-loafwallet-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-loafwalletTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -4001,6 +4013,28 @@ 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"; }; + E85603DAE7C21FF2F41766D3 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + 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; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -4038,6 +4072,7 @@ 2465873923A5AAD100A32E9E /* loafwalletTests.swift in Sources */, C345D82525A8D54200657E30 /* RegistrationViewModelTests.swift in Sources */, 24470E3623A5FDE800ADDA27 /* PhraseTests.swift in Sources */, + C308993F2616124800EE6A40 /* CardWalletTests.swift in Sources */, 24470E4523A608A700ADDA27 /* AmountTests.swift in Sources */, C3B7C3EE255FF59200E98A64 /* ConstantsTests.swift in Sources */, 24470E2323A5DB7D00ADDA27 /* WalletManagerTests.swift in Sources */, @@ -4160,6 +4195,7 @@ 248BFE2423AAD53700CE1A71 /* BuyTableViewController.swift in Sources */, 24313C782381E8F100A83F69 /* TabBarViewController.swift in Sources */, CEBF29301EF9D76F005C330A /* Environment.swift in Sources */, + C39A71472608CB4300E7B640 /* EmptyTableViewCell.swift in Sources */, CEC6AA4D1DF0741100EE5AFD /* ModalDisplayable.swift in Sources */, CEE0EF521EBD14B60018DB36 /* PinTransitioningDelegate.swift in Sources */, CE45C1FD1E7650F5002C3847 /* KVStoreCoordinator.swift in Sources */, @@ -4186,6 +4222,7 @@ 2218BD771E8F55430091D5E8 /* BRAPIClient+Assets.swift in Sources */, 2228734D1E916F7C0044BA15 /* BRAPIClient+Features.swift in Sources */, 22A9A94D1DF61945000F0016 /* BRHTTPFileMiddleware.swift in Sources */, + C316CF49261887FC00E4C09B /* UIApplication+Extension.swift in Sources */, CE8644251F2C160200033129 /* ConfirmationViewController.swift in Sources */, CEE1F5631DF13E5A00D733AD /* ModalHeaderView.swift in Sources */, CE5F21DB1E4A93A500C47B8E /* LoginTransitionDelegate.swift in Sources */, @@ -4219,6 +4256,8 @@ CE25BF8D1DF3B8A500BC67B6 /* InViewAlert.swift in Sources */, 22A9A9511DF61945000F0016 /* TxMetaData.swift in Sources */, CE8CD8E11E31976800785E02 /* LoginViewController.swift in Sources */, + C3BF74D926114969001CE2BB /* CardWalletDetails.swift in Sources */, + C3F7BCDE25FEC6AD00694C28 /* AlertFailureView.swift in Sources */, CEC6AA391DEE10BA00EE5AFD /* UINavigationController+Extension.swift in Sources */, CECCE5B01E04AD7600D99448 /* DescriptionSendCell.swift in Sources */, CE44BA1B1F33BFC500392A1A /* NodeSelectorViewController.swift in Sources */, @@ -4249,6 +4288,7 @@ C30AFB642598FFB200CDCF69 /* PartnerAPIManager.swift in Sources */, CEE20C2F1EA3E5820086F724 /* BlinkingView.swift in Sources */, CEC6AA441DEFCDE900EE5AFD /* ModalViewController.swift in Sources */, + C3F7BCDC25FEC6AD00694C28 /* FailedAlertView.swift in Sources */, 24313C8423820C4B00A83F69 /* ReceiveLTCViewController.swift in Sources */, C3F55655255A195B005F786F /* SupportLitecoinFoundationViewModel.swift in Sources */, CEEC70831E90C07C00EF788E /* Setting.swift in Sources */, @@ -4283,6 +4323,7 @@ 24B8FADF2163C4D400A155B1 /* Currency.swift in Sources */, 222C42501E90492800078EB5 /* BRAPIClient+KV.swift in Sources */, 2494037E23AE0C7100369261 /* SyncProgressHeaderView.swift in Sources */, + C3F7BCDD25FEC6AD00694C28 /* DomainResolutionFailure.swift in Sources */, CE5E6C941EB7964900A476DB /* WalletDisabledView.swift in Sources */, CEF3E8341DE57166007C0A9E /* AnimatableIcon.swift in Sources */, C3F55645255A193D005F786F /* SupportLitecoinFoundationView.swift in Sources */, @@ -4315,7 +4356,6 @@ 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 +4380,7 @@ CEF3E8361DE60222007C0A9E /* ModalNavigationController.swift in Sources */, CEB909FA1E5FF242001804DC /* RecoverWalletIntroViewController.swift in Sources */, CE25BF911DF9ADE700BC67B6 /* UIImage+Utils.swift in Sources */, + C30899792616426800EE6A40 /* ForgotAlertViewModel.swift in Sources */, CEBF33041DDE17A600348FC6 /* Transaction.swift in Sources */, CEAA9E911DC0FDFE0066731D /* UIViewPropertyAnimator+BRWAdditions.swift in Sources */, 22E773041EE7813000397E0E /* Bonjour.swift in Sources */, @@ -4362,6 +4403,7 @@ CEEC70861E94397D00EF788E /* UserDefaults+Additions.swift in Sources */, 22A9A9501DF61945000F0016 /* BRHTTPServer.swift in Sources */, 22A9A9531DF61945000F0016 /* BRLinkPlugin.swift in Sources */, + C3F7BD0325FEC77100694C28 /* TransactionModalView.swift in Sources */, C3D783A72565EA4B0004FF70 /* UnstoppableDomainView.swift in Sources */, C379F228259B9BF000B25883 /* RegistrationAlertView.swift in Sources */, CE3D4C571EF5D5740016B1C8 /* ReachabilityMonitor.swift in Sources */, @@ -4684,12 +4726,12 @@ }; 24470E0123A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6008481CC5B78F1CF8F9EA57 /* Pods-loafwallet.debug.xcconfig */; + baseConfigurationReference = F0E743170D714EE124029E99 /* Pods-loafwallet.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -4703,7 +4745,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_SWIFT_FLAGS = "-DDebug $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -4717,7 +4759,7 @@ }; 24470E0323A5BF3C00ADDA27 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D25607DBC5E9F06B12996E3E /* Pods-loafwalletTests.debug.xcconfig */; + baseConfigurationReference = 05AEEC8F8E25C740ED8981CB /* Pods-loafwalletTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -4796,7 +4838,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -4806,7 +4848,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4925,7 +4967,7 @@ }; 2465873F23A5AAD100A32E9E /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 65B44EBCC7D4AFCDB8B91F8A /* Pods-loafwalletTests.testnet.xcconfig */; + baseConfigurationReference = DA0A9E434AE0804412FE6C43 /* Pods-loafwalletTests.testnet.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -4953,7 +4995,7 @@ }; 2465874023A5AAD100A32E9E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 96694FA018937A83E970CC55 /* Pods-loafwalletTests.release.xcconfig */; + baseConfigurationReference = 153E10D934A51A7F817FA6B0 /* Pods-loafwalletTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -5102,12 +5144,12 @@ }; 75A2A7E51DA5934400A983D8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A3E5444354AB8914A966CDC2 /* Pods-loafwallet.release.xcconfig */; + baseConfigurationReference = 88220266EF282D1F355BB238 /* Pods-loafwallet.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/**", @@ -5120,7 +5162,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5137,7 +5179,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -5146,7 +5188,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5232,12 +5274,12 @@ }; CEA7E69C1F0AAA84001F8C27 /* Testnet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B1E980ED11476D536096EFFC /* Pods-loafwallet.testnet.xcconfig */; + baseConfigurationReference = 5C15DA44F99E3C163A716207 /* Pods-loafwallet.testnet.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = loafwallet/loafwallet.entitlements; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; FRAMEWORK_SEARCH_PATHS = ( @@ -5251,7 +5293,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_SWIFT_FLAGS = "-DDebug -DTestnet $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet; PRODUCT_MODULE_NAME = loafwallet; @@ -5269,7 +5311,7 @@ CODE_SIGN_ENTITLEMENTS = TodayExtension/TodayExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ZV7987N2ZC; INFOPLIST_FILE = TodayExtension/Info.plist; @@ -5279,7 +5321,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; PRODUCT_BUNDLE_IDENTIFIER = com.litecoin.loafwallet.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5507,8 +5549,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/litecoin-foundation/LitewalletPartnerAPI.git"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.5.0; + kind = exactVersion; + version = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved b/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8af16a593..d44cb12f7 100644 --- a/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/loafwallet.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/litecoin-foundation/LitewalletPartnerAPI.git", "state": { "branch": null, - "revision": "5fafe40f4eac370440d39192d73916a387b0f36e", - "version": "0.5.0" + "revision": "945c891c9606c48de2266daf87e0303f8cf39ea8", + "version": "0.7.0" } } ] diff --git a/loafwallet/AlertFailureView.swift b/loafwallet/AlertFailureView.swift new file mode 100644 index 000000000..c24929059 --- /dev/null +++ b/loafwallet/AlertFailureView.swift @@ -0,0 +1,60 @@ +// +// AlertFailureView.swift +// loafwallet +// +// Created by Kerry Washington on 1/29/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import SwiftUI + +struct AlertFailureView: View { + + let alertFailureType: AlertFailureType + + let errorMessage: String + + init(alertFailureType: AlertFailureType, errorMessage: String) { + self.alertFailureType = alertFailureType + self.errorMessage = errorMessage + } + + var body: some View { + VStack { + Text(alertFailureType.header) + .foregroundColor(.white) + .font(Font(UIFont.barlowBold(size: 18.0))) + .padding() + + Divider() + .frame(maxHeight: 1.0) + .background(Color(UIColor.transparentWhite)) + + Image(systemName: "nosign") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 40, + height: 40, + alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) + .foregroundColor(.white) + .padding() + + Text(self.errorMessage.localizedCapitalized) + .foregroundColor(.white) + .font(Font(UIFont.barlowSemiBold(size: 16.0))) + .padding(.bottom, 60) + } + .background(Color(UIColor.gray)) + .cornerRadius(6.0) + } +} + +struct AlertFailureView_Previews: PreviewProvider { + + static let alert = AlertFailureType.failedResolution + static let errorMessage = "Test Error" + + static var previews: some View { + AlertFailureView(alertFailureType: alert, errorMessage: errorMessage) + } +} diff --git a/loafwallet/Assets.xcassets/Partners/moonpay-logo.imageset/Contents.json b/loafwallet/Assets.xcassets/Partners/moonpay-logo.imageset/Contents.json new file mode 100644 index 000000000..bab48e870 --- /dev/null +++ b/loafwallet/Assets.xcassets/Partners/moonpay-logo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "moonpay-logo.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/loafwallet/Assets.xcassets/Partners/moonpay-logo.imageset/moonpay-logo.png b/loafwallet/Assets.xcassets/Partners/moonpay-logo.imageset/moonpay-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b7efd99ef4763ae274f6c7d049689d90900f0074 GIT binary patch literal 4073 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 Z8e0X!5CuLLG|c*&H8(kgePHBq{(najylemf literal 0 HcmV?d00001 diff --git a/loafwallet/BuyTableViewController.swift b/loafwallet/BuyTableViewController.swift index 4f51db4d6..8893046b3 100644 --- a/loafwallet/BuyTableViewController.swift +++ b/loafwallet/BuyTableViewController.swift @@ -7,22 +7,47 @@ // import UIKit +import SafariServices -class BuyTableViewController: UITableViewController { - +class BuyTableViewController: UITableViewController, SFSafariViewControllerDelegate { + + //MARK: Moonpay UI + @IBOutlet weak var moonpayLogoImageView: UIImageView! + @IBOutlet weak var moonpayHeaderLabel: UILabel! + @IBOutlet weak var moonpayDetailsLabel: UILabel! + @IBOutlet weak var moonpayCellContainerView: UIView! + @IBOutlet weak var moonpaySegmentedControl: UISegmentedControl! + + @IBAction func didTapMoonpay(_ sender: Any) { + + let timestamp = Int(appInstallDate.timeIntervalSince1970) + + let urlString = APIServer.baseUrl + "moonpay/buy" + "?address=\(currentWalletAddress)&idate=\(timestamp)&uid=\(uuidString)&code=\(currencyCode)" + + guard let url = URL(string: urlString) else { return } + + let sfSafariVC = SFSafariViewController(url: url) + sfSafariVC.delegate = self + present(sfSafariVC, animated: true) + } + + //MARK: Simplex UI @IBOutlet weak var simplexLogoImageView: UIImageView! @IBOutlet weak var simplexHeaderLabel: UILabel! @IBOutlet weak var simplexDetailsLabel: UILabel! @IBOutlet weak var simplexCellContainerView: UIView! - - @IBOutlet weak var currencySegmentedControl: UISegmentedControl! + @IBOutlet weak var simplexCurrencySegmentedControl: UISegmentedControl! private var currencyCode: String = "USD" @IBAction func didTapSimplex(_ sender: Any) { - if let vcWKVC = UIStoryboard.init(name: "Buy", bundle: nil).instantiateViewController(withIdentifier: "BuyWKWebViewController") as? BuyWKWebViewController { + if let vcWKVC = UIStoryboard.init(name: "Buy", bundle: nil).instantiateViewController(withIdentifier: "BuyWKWebViewController") as? BuyWKWebViewController { vcWKVC.currencyCode = currencyCode + vcWKVC.currentWalletAddress = currentWalletAddress + vcWKVC.uuidString = uuidString + vcWKVC.timestamp = Int(appInstallDate.timeIntervalSince1970) + addChildViewController(vcWKVC) self.view.addSubview(vcWKVC.view) vcWKVC.didMove(toParentViewController: self) @@ -41,10 +66,10 @@ class BuyTableViewController: UITableViewController { NSLog("ERROR: Storyboard not initialized") } } - + var store: Store? var walletManager: WalletManager? - let mountPoint = "" + override func viewDidLoad() { super.viewDidLoad() @@ -54,16 +79,33 @@ class BuyTableViewController: UITableViewController { tableView.tableHeaderView = thinHeaderView tableView.tableFooterView = UIView() - 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() + moonpaySegmentedControl.addTarget(self, action: #selector(didChangeCurrencyMoonpay), for: .valueChanged) + moonpaySegmentedControl.selectedSegmentIndex = PartnerFiatOptions.usd.index + moonpaySegmentedControl.selectedSegmentTintColor = .white + moonpaySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: .normal) + moonpaySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.liteWalletBlue], for: .selected) + + simplexCurrencySegmentedControl.addTarget(self, action: #selector(didChangeCurrencySimplex), for: .valueChanged) + simplexCurrencySegmentedControl.selectedSegmentIndex = PartnerFiatOptions.usd.index + simplexCurrencySegmentedControl.selectedSegmentTintColor = .white + simplexCurrencySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: .normal) + simplexCurrencySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.liteWalletBlue], for: .selected) + + setupWkVCData() } - private func setupData() { - let simplexData = Partner.partnerDataArray()[0] + private func setupWkVCData() { + + let moonpayData = Partner.partnerDataArray()[0] + moonpayLogoImageView.image = moonpayData.logo + moonpayHeaderLabel.text = moonpayData.headerTitle + moonpayDetailsLabel.text = moonpayData.details + moonpayCellContainerView.layer.cornerRadius = 6.0 + moonpayCellContainerView.layer.borderColor = UIColor.white.cgColor + moonpayCellContainerView.layer.borderWidth = 1.0 + moonpayCellContainerView.clipsToBounds = true + + let simplexData = Partner.partnerDataArray()[1] simplexLogoImageView.image = simplexData.logo simplexHeaderLabel.text = simplexData.headerTitle simplexDetailsLabel.text = simplexData.details @@ -73,11 +115,38 @@ class BuyTableViewController: UITableViewController { simplexCellContainerView.clipsToBounds = true } - @objc private func didChangeCurrency() { - if let code = PartnerFiatOptions(rawValue: currencySegmentedControl.selectedSegmentIndex)?.description { + + private let uuidString : String = { + return UIDevice.current.identifierForVendor?.uuidString ?? "" + }() + + private let currentWalletAddress : String = { + return WalletManager.sharedInstance.wallet?.receiveAddress ?? "" + }() + + private let appInstallDate : Date = { + if let documentsFolder = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last { + if let installDate = try! FileManager.default.attributesOfItem(atPath: documentsFolder.path)[.creationDate] as? Date { + return installDate + } + } + return Date() + }() + + @objc private func didChangeCurrencyMoonpay() { + if let code = PartnerFiatOptions(rawValue: moonpaySegmentedControl.selectedSegmentIndex)?.description { + self.currencyCode = code + } else { + print("Error: Code not found: \(moonpaySegmentedControl.selectedSegmentIndex)") + } + } + + @objc private func didChangeCurrencySimplex() { + if let code = PartnerFiatOptions(rawValue: simplexCurrencySegmentedControl.selectedSegmentIndex)?.description { self.currencyCode = code } else { - print("Error: Code not found: XXXX\(currencySegmentedControl.selectedSegmentIndex)") + print("Error: Code not found: \(simplexCurrencySegmentedControl.selectedSegmentIndex)") } } } + diff --git a/loafwallet/BuyWKWebViewController.swift b/loafwallet/BuyWKWebViewController.swift index ce53d5dad..a4c58d5ab 100644 --- a/loafwallet/BuyWKWebViewController.swift +++ b/loafwallet/BuyWKWebViewController.swift @@ -8,6 +8,8 @@ import UIKit import WebKit +import SafariServices + class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler { @@ -17,34 +19,24 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe @IBOutlet weak var currentAddressButton: UIButton! @IBOutlet weak var copiedLabel: UILabel! - var didDismissChildView: (() -> ())? - - private let uuidString : String = { - return UIDevice.current.identifierForVendor?.uuidString ?? "" - }() - private let currentWalletAddress : String = { - return WalletManager.sharedInstance.wallet?.receiveAddress ?? "" - }() - - private let appInstallDate : Date = { - if let documentsFolder = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last { - if let installDate = try! FileManager.default.attributesOfItem(atPath: documentsFolder.path)[.creationDate] as? Date { - return installDate - } - } - return Date() - }() + var didDismissChildView: (() -> ())? - private let wkProcessPool = WKProcessPool() + var uuidString: String = "" - var partnerPrefixString: String? + var currentWalletAddress: String = "" + var timestamp: Int = 0 + + var appInstallDate: Date = Date() + + private let wkProcessPool = WKProcessPool() + var currencyCode: String = "USD" override func viewDidLoad() { super.viewDidLoad() setupSubViews() - loadRequest() + loadSimplexRequest() } private func setupSubViews() { @@ -54,34 +46,34 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe copiedLabel.alpha = 0.0 } - func loadRequest() { + func loadSimplexRequest() { + + let urlString: String = APIServer.baseUrl + "?address=\(currentWalletAddress)&code=\(currencyCode)&idate=\(timestamp)&uid=\(uuidString)" + + guard let url = URL(string: urlString) else { + NSLog("ERROR: URL not initialized") + return + } + let request = URLRequest(url: url) + let contentController = WKUserContentController() contentController.add(self, name: "callback") - + let config = WKWebViewConfiguration() 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 wkWebView = WKWebView(frame:wkWithFooter, configuration: config) - wkWebView.navigationDelegate = self - wkWebView.allowsBackForwardNavigationGestures = true - wkWebView.contentMode = .scaleAspectFit - wkWebView.autoresizesSubviews = true - wkWebView.autoresizingMask = [.flexibleHeight, .flexibleWidth] - self.wkWebContainerView.addSubview(wkWebView) - - 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 - } - - let request = URLRequest(url: url) - wkWebView.load(request) + let setupWkWebView = WKWebView(frame:wkWithFooter, configuration: config) + setupWkWebView.navigationDelegate = self + setupWkWebView.allowsBackForwardNavigationGestures = true + setupWkWebView.contentMode = .scaleAspectFit + setupWkWebView.autoresizesSubviews = true + setupWkWebView.autoresizingMask = [.flexibleHeight, .flexibleWidth] + self.wkWebContainerView.addSubview(setupWkWebView) + setupWkWebView.load(request) } @IBAction func didTapCurrentAddressButton(_ sender: Any) { @@ -97,10 +89,6 @@ class BuyWKWebViewController: UIViewController, WKNavigationDelegate, WKScriptMe @IBAction func backAction(_ sender: Any) { didDismissChildView?() } - - func closeNow() { - didDismissChildView?() - } } extension BuyWKWebViewController { @@ -109,14 +97,7 @@ extension BuyWKWebViewController { open func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { - if let url = navigationAction.request.url?.absoluteString { - let mutableurl = url - if mutableurl.contains("/close") { - DispatchQueue.main.async { - self.closeNow() - } - } - } + return decisionHandler(.allow) } @@ -125,22 +106,8 @@ extension BuyWKWebViewController { if complete != nil { } }) } + + func userContentController(_ userContentController: WKUserContentController, + didReceive message: WKScriptMessage) { } - func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - guard let response = message.body as? String else { return } - print(response) - guard let url = URL(string: "https://checkout.simplexcc.com/payments/new") else { return } - - var req = URLRequest(url: url) - req.httpBody = Data(response.utf8) - req.httpMethod = "POST" - - DispatchQueue.main.async { - let vc = BRBrowserViewController() - vc.load(req) - self.addChildViewController(vc) - self.wkWebContainerView.addSubview(vc.view) - vc.didMove(toParentViewController: self) - } - } } diff --git a/loafwallet/CardLoggedInView.swift b/loafwallet/CardLoggedInView.swift index a3c77e7ec..46905f340 100644 --- a/loafwallet/CardLoggedInView.swift +++ b/loafwallet/CardLoggedInView.swift @@ -19,6 +19,9 @@ struct CardLoggedInView: View { @State private var shouldLogout: Bool = false + + @State + var balanceText = "" init(viewModel: CardViewModel) { self.viewModel = viewModel @@ -70,14 +73,19 @@ struct CardLoggedInView: View { maxWidth: geometry.size.width * 0.4, alignment: .center) - Text("$") + Text(balanceText) .frame(minWidth: 0, maxWidth: .infinity, alignment: .center) .padding() .font(Font(UIFont.barlowBold(size: 40.0))) - .foregroundColor(Color(UIColor.litecoinGray)) + .foregroundColor(Color(UIColor.darkGray)) .background(Color(UIColor.white)) + .onReceive(viewModel.$walletDetails) { newWalletDetails in + + guard let availableBalance = newWalletDetails?.availableBalance else { return } + self.balanceText = "Ł" + String(format:"%6.4f",availableBalance) + } Spacer() } diff --git a/loafwallet/CardView.swift b/loafwallet/CardView.swift index 504caa64e..f72b503d3 100644 --- a/loafwallet/CardView.swift +++ b/loafwallet/CardView.swift @@ -52,15 +52,6 @@ struct CardView: View { @State 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) { self.viewModel = viewModel @@ -106,14 +97,7 @@ 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)) + .foregroundColor(.black) .font(Font(UIFont.barlowSemiBold(size:18.0))) .accentColor(Color(UIColor.liteWalletBlue)) .padding(.leading, 20) @@ -124,14 +108,7 @@ 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)) + .foregroundColor(.black) .font(Font(UIFont.barlowSemiBold(size:18.0))) .accentColor(Color(UIColor.liteWalletBlue)) .padding(.leading, 20) @@ -199,15 +176,14 @@ struct CardView: View { .padding() .font(Font(UIFont.barlowMedium(size: 16.0))) .padding([.leading, .trailing], 16) - .foregroundColor(shouldEnableLogin.wrappedValue ? .white : Color(UIColor.litecoinSilver)) - .background(shouldEnableLogin.wrappedValue ? Color(UIColor.liteWalletBlue) : Color(UIColor.litecoinGray)) + .foregroundColor(.white) + .background(Color(UIColor.liteWalletBlue)) .cornerRadius(4.0) .overlay( RoundedRectangle(cornerRadius:4) - .stroke(shouldEnableLogin.wrappedValue ? Color(UIColor.liteWalletBlue) : .gray, lineWidth: 1) + .stroke(Color(UIColor.liteWalletBlue), lineWidth: 1) ) } - .disabled(!shouldEnableLogin.wrappedValue) .padding([.leading, .trailing], 16) // Registration button diff --git a/loafwallet/CardViewController.swift b/loafwallet/CardViewController.swift index c19b535be..64e166443 100644 --- a/loafwallet/CardViewController.swift +++ b/loafwallet/CardViewController.swift @@ -68,6 +68,11 @@ class CardViewController: UIViewController { .addObserver(forName: NSNotification.Name.LitecoinCardLoginNotification, object: nil, queue: nil) { _ in + + self.viewModel.fetchCardWalletDetails { + print("Logged in updated wallet values") + } + self.updateLoginStatusFromViewModel() } diff --git a/loafwallet/CardViewModel.swift b/loafwallet/CardViewModel.swift index 89bf7a353..c3a1c4809 100644 --- a/loafwallet/CardViewModel.swift +++ b/loafwallet/CardViewModel.swift @@ -9,10 +9,10 @@ import Foundation import SwiftUI import KeychainAccess - + class CardViewModel: ObservableObject { - + //MARK: - Login Status @Published var isLoggedIn: Bool = false @@ -20,6 +20,50 @@ class CardViewModel: ObservableObject { @Published var isNotRegistered: Bool = true + //MARK: - Combine Variables + @Published + var walletDetails: CardWalletDetails? + init() { } + func fetchCardWalletDetails(completion: @escaping () -> Void) { + + let cardService = "com.litecoincard.service" + let keychain = Keychain(service: cardService) + + guard let token = (try? keychain.getString("token")) as? String else { + print("Error: Token not found") + return + } + + guard let userID = (try? keychain.getString("userID")) as? String else { + print("Error: UserID not found") + return + } + + PartnerAPI.shared.getWalletDetails(userID: userID, token: token) { detailsDict in + + //Only reteives the data element there is the metadata and the result as well + guard let data = detailsDict?["data"] as? [String: Any] else { + print("Error: Data dict not found") + return + } + + do { + + let jsonData = try JSONSerialization.data(withJSONObject: data, options:[]) + + let decoder = JSONDecoder() + + let walletDetails = try? decoder.decode(CardWalletDetails.self, from: jsonData) + + DispatchQueue.main.async { + self.walletDetails = walletDetails + } + } catch { + print("Error: Incomplete dictionary data from partner API") + LWAnalytics.logEventWithParameters(itemName:._20210405_TAWDF) + } + } + } } diff --git a/loafwallet/CardWalletDetails.swift b/loafwallet/CardWalletDetails.swift new file mode 100644 index 000000000..62708b20c --- /dev/null +++ b/loafwallet/CardWalletDetails.swift @@ -0,0 +1,45 @@ +// +// CardWalletDetails.swift +// loafwallet +// +// Created by Kerry Washington on 3/29/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation + +struct CardWalletDetails: Decodable { + + var balance: Float? + var ltcAddress: String? + var createdAt: String? + var updatedAt: String? + var availableBalance: Float? + var withdrawableBalance: Float? + var spendableBalance: Float? + + enum CodingKeys: String, CodingKey { + case balance = "balance" + case ltcAddress = "ltc_address" + case createdAt = "created_at" + case updatedAt = "updated_at" + case availableBalance = "available_balance" + case withdrawableBalance = "withdrawable_balance" + case spendableBalance = "spendable_balance" + } + + init(from decoder: Decoder) throws { + + let container = try decoder.container(keyedBy: CodingKeys.self) + + balance = try? container.decode(Float.self, forKey: .balance) + ltcAddress = try? container.decode(String.self, forKey: .ltcAddress) + createdAt = try? container.decode(String.self, forKey: .createdAt) + updatedAt = try? container.decode(String.self, forKey: .updatedAt) + availableBalance = try? container.decode(Float.self, forKey: .availableBalance) + withdrawableBalance = try? container.decode(Float.self, forKey: .withdrawableBalance) + spendableBalance = try? container.decode(Float.self, forKey: .spendableBalance) + } +} + + diff --git a/loafwallet/DomainResolutionFailure.swift b/loafwallet/DomainResolutionFailure.swift new file mode 100644 index 000000000..3e810b941 --- /dev/null +++ b/loafwallet/DomainResolutionFailure.swift @@ -0,0 +1,27 @@ +// +// DomainResolutionFailure.swift +// loafwallet +// +// Created by Kerry Washington on 1/29/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation +import UnstoppableDomainsResolution + +struct DomainResolutionFailure { + + init() {} + + func messageWith(error: ResolutionError) -> String { + + switch error { + case .unregisteredDomain,.unsupportedDomain, + .recordNotFound,.recordNotSupported, + .unspecifiedResolver: + return String(format: S.Send.UnstoppableDomains.lookupDomainError, 0) + default: + return String(format: S.Send.UnstoppableDomains.udSystemError, 10) + } + } +} diff --git a/loafwallet/EmptyTableViewCell.swift b/loafwallet/EmptyTableViewCell.swift new file mode 100644 index 000000000..f6b376786 --- /dev/null +++ b/loafwallet/EmptyTableViewCell.swift @@ -0,0 +1,14 @@ +// +// EmptyTableViewCell.swift +// loafwallet +// +// Created by Kerry Washington on 3/22/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation +import UIKit + +class EmptyTableViewCell: UITableViewCell { + +} diff --git a/loafwallet/FailedAlertView.swift b/loafwallet/FailedAlertView.swift new file mode 100644 index 000000000..a9e41f349 --- /dev/null +++ b/loafwallet/FailedAlertView.swift @@ -0,0 +1,42 @@ +// +// FailedAlertView.swift +// loafwallet +// +// Created by Kerry Washington on 1/29/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// +import UIKit + +enum AlertFailureType { + + case failedResolution + + var header: String { + switch self { + case .failedResolution: + return S.Send.UnstoppableDomains.lookupFailureHeader + } + } + + var subheader: String { + switch self { + case .failedResolution: + return S.SecurityAlerts.resolvedSuccessSubheader + } + } + + var icon: UIView { + return CheckView() + } +} + +extension AlertFailureType : Equatable {} + +func ==(lhs: AlertFailureType, rhs: AlertFailureType) -> Bool { + switch (lhs, rhs) { + case (.failedResolution, .failedResolution): + return true + default: + return false + } +} diff --git a/loafwallet/ForgotAlertViewModel.swift b/loafwallet/ForgotAlertViewModel.swift new file mode 100644 index 000000000..dd2975a0d --- /dev/null +++ b/loafwallet/ForgotAlertViewModel.swift @@ -0,0 +1,39 @@ +// +// ForgotAlertViewModel.swift +// loafwallet +// +// Created by Kerry Washington on 4/1/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation +import SwiftUI +import LitewalletPartnerAPI + +class ForgotAlertViewModel: ObservableObject { + + //MARK: - Combine Variables + @Published + var emailString: String = "" + + @Published + var detailMessage: String = S.LitecoinCard.resetPasswordDetail + + init() { } + + func resetPassword(completion: @escaping () -> Void) { + + PartnerAPI.shared.forgotPassword(email: emailString) { (responseMessage, code) in + + DispatchQueue.main.async { + self.detailMessage = "\(code): " + responseMessage + completion() + } + } + } + + func shouldDismissView(completion: @escaping () -> Void) { + completion() + } +} + diff --git a/loafwallet/ForgotView.swift b/loafwallet/ForgotView.swift index 1a55533aa..296e105af 100644 --- a/loafwallet/ForgotView.swift +++ b/loafwallet/ForgotView.swift @@ -8,6 +8,10 @@ import SwiftUI struct ForgotAlertView: View where Presenting: View { + //MARK: - Combine Variables + @ObservedObject + var viewModel = ForgotAlertViewModel() + @Binding var isShowingForgot: Bool @@ -18,6 +22,12 @@ struct ForgotAlertView: View where Presenting: View { var mainMessage: String + @State + var detailMessage: String = S.LitecoinCard.resetPasswordDetail + + @State + var didCheckEmailAddress: Bool = false + var body: some View { GeometryReader { (deviceSize: GeometryProxy) in HStack{ @@ -25,28 +35,72 @@ struct ForgotAlertView: View where Presenting: View { ZStack { self.presenting.disabled(isShowingForgot) VStack { - Text(S.LitecoinCard.resetPassword) - .font(Font(UIFont.barlowBold(size: 20.0))) - .padding() + + //Dismiss button + Button(action: { + viewModel.shouldDismissView { + self.isShowingForgot.toggle() + UIApplication.shared.endEditing() + } + + }) { + Image("whiteCross") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 15, + height: 15) + } + .frame(minWidth: 0,maxWidth: .infinity, alignment: .trailing) + + Text(S.LitecoinCard.forgotPassword) + .font(Font(UIFont.barlowSemiBold(size: 21.0))) + .padding(.bottom, 8) .foregroundColor(Color.white) - Text(S.LitecoinCard.visitToReset) - .font(Font(UIFont.barlowMedium(size: 18.0))) + Text(detailMessage) + .font(Font(UIFont.barlowRegular(size: 18.0))) .foregroundColor(Color.white) - .padding(.all, 10) + .multilineTextAlignment(.leading) + .padding(.bottom, 12) + .padding([.leading, .trailing], 8) + .onReceive(viewModel.$detailMessage, perform: { updatedMessage in + detailMessage = updatedMessage + }) + + TextField(emailString, text: didCheckEmailAddress ? .constant("") : $viewModel.emailString) + .font(Font(UIFont.barlowMedium(size: 16.0))) + .textFieldStyle(RoundedBorderTextFieldStyle()) + .keyboardType(.emailAddress) + .autocapitalization(.none) + .disableAutocorrection(true) + .padding(.all, 8) - Divider().background(Color.white) HStack { + + // Reset password button Button(action: { withAnimation { - self.isShowingForgot.toggle() + viewModel.resetPassword { + DispatchQueue.main.asyncAfter(deadline: .now() + 2.5, execute: { + self.isShowingForgot.toggle() + UIApplication.shared.endEditing() + didCheckEmailAddress = true + detailMessage = S.LitecoinCard.resetPasswordDetail + }) + } } }) { - Text(S.Button.ok) + Text(S.LitecoinCard.resetPassword) .frame(minWidth:0, maxWidth: .infinity) - .padding() .font(Font(UIFont.barlowBold(size: 20.0))) .foregroundColor(Color.white) + .padding(.all, 8) + .overlay( + RoundedRectangle(cornerRadius:4) + .stroke(Color(UIColor.white), lineWidth: 1) + ) + .padding([.leading, .trailing], 20) + .padding([.top,.bottom], 10) } } } @@ -58,7 +112,7 @@ struct ForgotAlertView: View where Presenting: View { .background(Color(UIColor.liteWalletBlue)) .cornerRadius(8) .frame( - width: deviceSize.size.width * 0.8, + width: deviceSize.size.width * 0.85, height: deviceSize.size.height * 0.9 ) .shadow(color: .black, radius: 10, x: 5, y: 5) @@ -84,6 +138,3 @@ struct ForgotAlertView_Previews: PreviewProvider { } } - - - diff --git a/loafwallet/PartnerData.swift b/loafwallet/PartnerData.swift index d8fb43283..9f21f46ef 100644 --- a/loafwallet/PartnerData.swift +++ b/loafwallet/PartnerData.swift @@ -8,11 +8,6 @@ import Foundation import UIKit - - -enum PartnerPrefix: String { - case simplex = "_simplex" -} struct Partner { @@ -21,8 +16,9 @@ struct Partner { let details: String static func partnerDataArray() -> [Partner] { + let moonpay = Partner(logo: UIImage(named: "moonpay-logo")!, headerTitle: S.BuyCenter.Cells.moonpayTitle, details: S.BuyCenter.Cells.moonpayFinancialDetails) let simplex = Partner(logo: UIImage(named: "simplexLogo")!, headerTitle: S.BuyCenter.Cells.simplexTitle, details: S.BuyCenter.Cells.simplexFinancialDetails) - return [simplex] + return [moonpay, simplex] } //TODO: Uncomment as integration progresses, kcw-grunt diff --git a/loafwallet/RegistrationViewModel.swift b/loafwallet/RegistrationViewModel.swift index 18c969706..ae9380251 100644 --- a/loafwallet/RegistrationViewModel.swift +++ b/loafwallet/RegistrationViewModel.swift @@ -164,15 +164,11 @@ class RegistrationViewModel: ObservableObject { } /// Password Validator - /// - Parameter passwordString: 6 - 10 chars + /// - Parameter passwordString: 6 chars minimum /// - Returns: Bool func isPasswordValid(passwordString: String) -> Bool { - guard passwordString != "" else { - return false - } - - guard (passwordString.count >= 6 && passwordString.count <= 10) else { + guard passwordString.count >= 6 else { return false } @@ -208,6 +204,4 @@ class RegistrationViewModel: ObservableObject { return true } } -} - - +} \ No newline at end of file diff --git a/loafwallet/Storyboards/Buy.storyboard b/loafwallet/Storyboards/Buy.storyboard index 67ebe4c6e..ce4be875f 100644 --- a/loafwallet/Storyboards/Buy.storyboard +++ b/loafwallet/Storyboards/Buy.storyboard @@ -31,28 +31,147 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -75,6 +194,12 @@ + @@ -113,7 +238,7 @@ - + @@ -165,8 +290,13 @@ - + + + + + + @@ -185,9 +315,9 @@ - + - + + + + + + + + + + + @@ -274,6 +415,8 @@ + + diff --git a/loafwallet/Storyboards/Transactions.storyboard b/loafwallet/Storyboards/Transactions.storyboard index 6c37e230b..6a66ca7d2 100644 --- a/loafwallet/Storyboards/Transactions.storyboard +++ b/loafwallet/Storyboards/Transactions.storyboard @@ -112,6 +112,15 @@ + + + + + + + + + diff --git a/loafwallet/TransactionsViewController.swift b/loafwallet/TransactionsViewController.swift index 73ac639e1..c879b2ba2 100644 --- a/loafwallet/TransactionsViewController.swift +++ b/loafwallet/TransactionsViewController.swift @@ -10,11 +10,13 @@ import UIKit import SwiftUI import LocalAuthentication -private let promptDelay: TimeInterval = 0.6 let kNormalTransactionCellHeight: CGFloat = 65.0 let kProgressHeaderHeight: CGFloat = 50.0 +let kDormantHeaderHeight: CGFloat = 1.0 let kPromptCellHeight : CGFloat = 120.0 let kQRImageSide: CGFloat = 110.0 +let kFiveYears: Double = 157680000.0 +let kTodaysEpochTime: TimeInterval = Date().timeIntervalSince1970 class TransactionsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, Subscriber, Trackable { @@ -38,10 +40,6 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable didSet { reload() } } - private var hasExtraSection: Bool { - return currentPromptType != nil - } - private var currentPromptType: PromptType? { didSet { if currentPromptType != nil && oldValue == nil { @@ -65,26 +63,41 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable guard let _ = walletManager else { NSLog("ERROR - Wallet manager not initialized") - assertionFailure("PEER MAANAGER Not initialized") + assertionFailure("PEER MANAGER Not initialized") return } + + guard let reduxState = self.store?.state else { + return + } + self.tableView.register(HostingTransactionCell.self, forCellReuseIdentifier: "HostingTransactionCell") self.transactions = TransactionManager.sharedInstance.transactions self.rate = TransactionManager.sharedInstance.rate - tableView.backgroundColor = .liteWalletBlue - initSyncingHeaderView(completion: {}) + initSyncingHeaderView(reduxState: reduxState, completion: { }) attemptShowPrompt() } - private func initSyncingHeaderView(completion: @escaping () -> Void) { + + /// Calls the Syncing HeaderView + /// - Parameters: + /// - reduxState: Current ReduxState + /// - completion: Signals the initialzation of the view + private func initSyncingHeaderView(reduxState: ReduxState, completion: @escaping () -> Void) { self.syncingHeaderView = Bundle.main.loadNibNamed("SyncProgressHeaderView", owner: self, options: nil)?.first as? SyncProgressHeaderView + self.syncingHeaderView?.isRescanning = reduxState.walletState.isRescanning + self.syncingHeaderView?.progress = 0.02 // Small value to show user it is in process + self.syncingHeaderView?.headerMessage = reduxState.walletState.syncState + self.syncingHeaderView?.noSendImageView.alpha = 1.0 + self.syncingHeaderView?.timestamp = reduxState.walletState.lastBlockTimestamp + completion() } - + private func attemptShowPrompt() { guard let walletManager = walletManager else { return } guard let store = self.store else { @@ -106,85 +119,23 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable currentPromptType = nil } } - - private func reload() { - DispatchQueue.main.async { - self.tableView.reloadData() - } - } - - 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] - - 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") - return PromptTableViewCell() - } - - cell.type = promptType - cell.titleLabel.text = promptType?.title - cell.bodyLabel.text = promptType?.body - cell.didClose = { [weak self] in - self?.saveEvent("prompt.\(String(describing: promptType?.name)).dismissed") - self?.currentPromptType = nil - self?.reload() - } - - cell.didTap = { [weak self] in - - if let store = self?.store, - let trigger = self?.currentPromptType?.trigger { - store.trigger(name: trigger) - } - self?.saveEvent("prompt.\(String(describing: self?.currentPromptType?.name)).trigger") - self?.currentPromptType = nil - } - - return cell - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - - let transaction = transactions[indexPath.row] - - 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) - - let hostingController = UIHostingController(rootView: TransactionModalView(viewModel: viewModel)) - - hostingController.modalPresentationStyle = .formSheet - - self.present(hostingController, animated: true) { - tableView.cellForRow(at: indexPath)?.isSelected = false + /// 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: 1)], with: .automatic) + self.tableView.endUpdates() } + } } } + /// Empty Message View as a placeholder + /// - Returns: a UILabel private func emptyMessageView() -> UILabel { let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: self.tableView.bounds.size.width, height: self.tableView.bounds.size.height)) let messageLabel = UILabel(frame: rect) @@ -198,16 +149,93 @@ class TransactionsViewController: UIViewController, UITableViewDelegate, UITable self.tableView.separatorStyle = .none return messageLabel } -} - -extension TransactionsViewController { - - // MARK: - Table view delegate source - + + /// Dyanmic Update Progress View: Advances the progress bar + /// - Parameters: + /// - syncProgress: The state of the initial Sync Progress + /// - lastBlockTimestamp: Corresponding timestamp + /// - Returns: CGFloat value + private func updateProgressView(syncProgress: CGFloat, lastBlockTimestamp: Double) -> CGFloat { + + ///DEV: HACK if the previous value is the same add a ration + /// The problem is the progress needs to go to o to 1 . + var progressValue: CGFloat = 0.0 + let num = lastBlockTimestamp - kFiveYears + let den = kTodaysEpochTime - kFiveYears + if syncProgress == 0.05 { + progressValue = abs(CGFloat(num) / CGFloat(den)) + } else { + progressValue = syncProgress + } + + return progressValue + } + + // MARK: - Table view data / delegate source + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + switch indexPath.section { + case 0: + + if currentPromptType != nil { + return configurePromptCell(promptType: currentPromptType, indexPath: indexPath) + } + return EmptyTableViewCell() + + default: + let transaction = transactions[indexPath.row] + + 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 + } + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + + if indexPath.section == 1 { + let transaction = transactions[indexPath.row] + + 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) + + let hostingController = UIHostingController(rootView: TransactionModalView(viewModel: viewModel)) + + hostingController.modalPresentationStyle = .formSheet + + self.present(hostingController, animated: true) { + + + // Notes of bugfix: https://github.com/litecoin-foundation/loafwallet-ios/pull/247 + // Refactored the class to have two section and make sure the row never extends outside the transaction count. + + if indexPath.row < self.transactions.count { + tableView.cellForRow(at: indexPath)?.isSelected = false + } + } + } + } + } + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - if hasExtraSection && indexPath.section == 0 { - return kPromptCellHeight + if indexPath.section == 0 { + return currentPromptType != nil ? kPromptCellHeight : kDormantHeaderHeight } else { return kNormalTransactionCellHeight } @@ -215,25 +243,31 @@ extension TransactionsViewController { func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - if shouldBeSyncing { + if shouldBeSyncing && section == 0 { return self.syncingHeaderView } return nil } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - if shouldBeSyncing { return kProgressHeaderHeight } - return 0.0 + + var sectionHeight = 0.0 + switch section { + case 0: + sectionHeight = Double(shouldBeSyncing ? kProgressHeaderHeight : kDormantHeaderHeight) + return CGFloat(sectionHeight) + default: return 0.0 + } } func numberOfSections(in tableView: UITableView) -> Int { - return hasExtraSection ? 2 : 1 + return 2 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if hasExtraSection && section == 0 { + if section == 0 { return 1 } else { if transactions.count > 0 { @@ -246,22 +280,43 @@ extension TransactionsViewController { } } } - - /// 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: - UITableView Support Methods + 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") + return PromptTableViewCell() + } + + cell.type = promptType + cell.titleLabel.text = promptType?.title + cell.bodyLabel.text = promptType?.body + cell.didClose = { [weak self] in + self?.saveEvent("prompt.\(String(describing: promptType?.name)).dismissed") + self?.currentPromptType = nil + self?.reload() + } + + cell.didTap = { [weak self] in + + if let store = self?.store, + let trigger = self?.currentPromptType?.trigger { + store.trigger(name: trigger) } + self?.saveEvent("prompt.\(String(describing: self?.currentPromptType?.name)).trigger") + self?.currentPromptType = nil + } + + return cell + } + + private func reload() { + DispatchQueue.main.async { + self.tableView.reloadData() } } + // MARK: - Subscription Methods private func addSubscriptions() { @@ -270,97 +325,119 @@ extension TransactionsViewController { return } + + // MARK: - Wallet State: Transactions store.subscribe(self, selector: { $0.walletState.transactions != $1.walletState.transactions }, callback: { state in self.allTransactions = state.walletState.transactions self.reload() }) + // MARK: - Wallet State: isLTCSwapped store.subscribe(self, selector: { $0.isLtcSwapped != $1.isLtcSwapped }, callback: { self.isLtcSwapped = $0.isLtcSwapped }) + + // MARK: - Wallet State: CurrentRate store.subscribe(self, selector: { $0.currentRate != $1.currentRate}, callback: { self.rate = $0.currentRate }) + + // MARK: - Wallet State: Max Digits 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 - } + // MARK: - Wallet State: Sync Progress + store.subscribe(self, selector: { $0.walletState.lastBlockTimestamp != $1.walletState.lastBlockTimestamp }, + callback: { reduxState in - 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 - }) + guard let syncView = self.syncingHeaderView else { return } + + syncView.isRescanning = reduxState.walletState.isRescanning + if (syncView.isRescanning || (reduxState.walletState.syncState == .syncing)) { + syncView.progress = CGFloat(self.updateProgressView(syncProgress: + CGFloat(reduxState.walletState.syncProgress), lastBlockTimestamp: Double(reduxState.walletState.lastBlockTimestamp))) + syncView.headerMessage = reduxState.walletState.syncState + syncView.noSendImageView.alpha = 1.0 + + syncView.timestamp = reduxState.walletState.lastBlockTimestamp + self.shouldBeSyncing = true + + if reduxState.walletState.syncProgress >= 0.99 { + self.shouldBeSyncing = false + self.syncingHeaderView = nil + } } + self.reload() - }) + }) + // MARK: - Wallet State: Show Status Bar + store.subscribe(self, name:.showStatusBar) { (didShowStatusBar) in + //DEV: May fix where the action view persists after confirming pin + self.reload() + } + + // MARK: - Wallet State: Sync State store.subscribe(self, selector: { $0.walletState.syncState != $1.walletState.syncState }, - callback: { state in + callback: { reduxState in + guard let _ = self.walletManager?.peerManager else { assertionFailure("PEER MANAGER Not initialized") return } - if state.walletState.syncState == .success { + if reduxState.walletState.syncState == .syncing { + self.shouldBeSyncing = true + self.initSyncingHeaderView(reduxState: reduxState, completion: { + self.syncingHeaderView?.isRescanning = reduxState.walletState.isRescanning + self.syncingHeaderView?.progress = 0.02 // Small value to show user it is in process + self.syncingHeaderView?.headerMessage = reduxState.walletState.syncState + self.syncingHeaderView?.noSendImageView.alpha = 1.0 + self.syncingHeaderView?.timestamp = reduxState.walletState.lastBlockTimestamp + }) + } + + if reduxState.walletState.syncState == .success { self.shouldBeSyncing = false self.syncingHeaderView = nil } self.reload() }) + // MARK: - Subscription: Recommend Rescan 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() - }) - + // MARK: - Subscription: Did Upgrade PIN store.subscribe(self, name: .didUpgradePin, callback: { _ in if self.currentPromptType == .upgradePin { self.currentPromptType = nil } }) + // MARK: - Subscription: Did Enable Share Data store.subscribe(self, name: .didEnableShareData, callback: { _ in if self.currentPromptType == .shareData { self.currentPromptType = nil } }) + // MARK: - Subscription: Did Write Paper Key store.subscribe(self, name: .didWritePaperKey, callback: { _ in if self.currentPromptType == .paperKey { self.currentPromptType = nil } }) - + + // MARK: - Subscription: Memo Updated 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/UIApplication+Extension.swift b/loafwallet/UIApplication+Extension.swift new file mode 100644 index 000000000..c2244f64d --- /dev/null +++ b/loafwallet/UIApplication+Extension.swift @@ -0,0 +1,16 @@ +// +// UIApplication+Extension.swift +// loafwallet +// +// Created by Kerry Washington on 4/3/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import Foundation +import UIKit + +extension UIApplication { + func endEditing() { + sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) + } +} diff --git a/loafwallet/UnstoppableDomainViewModel.swift b/loafwallet/UnstoppableDomainViewModel.swift index f129dbae7..82137cf41 100644 --- a/loafwallet/UnstoppableDomainViewModel.swift +++ b/loafwallet/UnstoppableDomainViewModel.swift @@ -10,7 +10,7 @@ import Foundation import SwiftUI import Combine import UnstoppableDomainsResolution - + class UnstoppableDomainViewModel: ObservableObject { //MARK: - Combine Variables @@ -27,10 +27,11 @@ class UnstoppableDomainViewModel: ObservableObject { var didResolveUDAddress: ((String) -> Void)? var shouldClearAddressField: (() -> Void)? + + var didFailToResolve: ((String) -> Void)? //MARK: - Private Variables - private var ltcAddress = "" - + private var ltcAddress = "" private var dateFormatter: DateFormatter? { didSet { @@ -56,7 +57,7 @@ class UnstoppableDomainViewModel: ObservableObject { properties: ["start_time": timestamp]) - self.resolveUDAddress(domainName: searchString) + self.resolveUDAddress(domainName: searchString) } private func resolveUDAddress(domainName: String) { @@ -95,25 +96,29 @@ class UnstoppableDomainViewModel: ObservableObject { self.didResolveUDAddress?(self.ltcAddress) self.isDomainResolving = false } - + case .failure(let error): - + print(error) + let errorMessage = DomainResolutionFailure().messageWith(error: error) let timestamp: String = self.dateFormatter?.string(from: Date()) ?? "" LWAnalytics.logEventWithParameters(itemName: CustomEvent._20201121_FRIA, properties: ["failure_time": timestamp, + "error_message":errorMessage, "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, + DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: { - print("Expected LTC Address, but got \(error.localizedDescription)") + + self.didFailToResolve?(error.localizedDescription) + + self.didFailToResolve?(errorMessage) + self.isDomainResolving = false - self.isDomainResolving = false - - }) + }) } group.leave() } @@ -133,3 +138,4 @@ class UnstoppableDomainViewModel: ObservableObject { } } } + diff --git a/loafwallet/src/Constants/Constants.swift b/loafwallet/src/Constants/Constants.swift index 213a21fbc..706919c54 100644 --- a/loafwallet/src/Constants/Constants.swift +++ b/loafwallet/src/Constants/Constants.swift @@ -38,7 +38,7 @@ enum CustomEvent: String { case _20201121_DRIA = "DID_RESOLVE_IPFS_ADDRESS" case _20201121_FRIA = "FAILED_RESOLVE_IPFS_ADDRESS" case _20200207_DTHB = "DID_TAP_HEADER_BALANCE" - + case _20210405_TAWDF = "TERNIO_API_WALLET_DETAILS_FAILURE" } struct FoundationSupport { diff --git a/loafwallet/src/Constants/Strings.swift b/loafwallet/src/Constants/Strings.swift index c658e54a2..785f79a81 100644 --- a/loafwallet/src/Constants/Strings.swift +++ b/loafwallet/src/Constants/Strings.swift @@ -101,6 +101,9 @@ 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") + static let lookupFailureHeader = NSLocalizedString("Send.UnstoppableDomains.lookupFailureHeader", value: "**LookupFailureHeader**", comment: "lookupFailureHeader") + static let lookupDomainError = NSLocalizedString("Send.UnstoppableDomains.lookupDomainError", value: "**LookupDomainError**", comment: "LookupDomainError") + static let udSystemError = NSLocalizedString("Send.UnstoppableDomains.udSystemError", value: "**UDSystemError**", comment: "UDSystemError") } } @@ -121,8 +124,9 @@ enum S { 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 resetPassword = NSLocalizedString("LitecoinCard.resetPassword", value: "**Reset password**", comment: "Reset password") + static let resetPasswordDetail = NSLocalizedString("LitecoinCard.resetPasswordDetail", value: "**Enter the email that you used to register for your Litecoin Card and check for an email from support@litecoin.getblockcard.com.**", comment: "Reset password detail") 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...") @@ -255,6 +259,8 @@ enum S { 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") enum Cells { + static let moonpayTitle = NSLocalizedString("BuyCenter.moonpayTitle", value: "**Moonpay**", comment: "Moonpay Title") + static let moonpayFinancialDetails = NSLocalizedString("BuyCenter.moonpayFinancialDetails", value: "**• Point 1 XXXXX\n• Point 2 XXXXn• XXX Point 3**", comment: "Moonpay buy financial details") static let simplexTitle = NSLocalizedString("BuyCenter.simplexTitle", value: "**Simplex**", comment: "Simplex Title") static let simplexFinancialDetails = NSLocalizedString("BuyCenter.simplexFinancialDetails", value: "**• Get Litecoin in 5 mins!\n• Buy Litecoin via credit card\n• Passport or State ID**", comment: "Simplex buy financial details") static let changellyTitle = NSLocalizedString("BuyCenter.changellyTitle", value: "**Changelly**", comment: "Changelly Title") @@ -633,8 +639,8 @@ enum S { static let highFees = NSLocalizedString("Import.Error.highFees", value: "**Transaction fees would cost more than the funds available on this private key.**", comment: "High fees error message") static let signing = NSLocalizedString("Import.Error.signing", value: "**Error signing transaction**", comment: "Import signing error message") } - } - + } + enum SupportLitecoinFoundation { static let title = NSLocalizedString("SupportTheFoundation.title", value: "**Support the Litecoin Foundation**", comment: "Support the Litecoin Foundation") } diff --git a/loafwallet/src/ModalPresenter.swift b/loafwallet/src/ModalPresenter.swift index cabb3f522..a57551837 100644 --- a/loafwallet/src/ModalPresenter.swift +++ b/loafwallet/src/ModalPresenter.swift @@ -217,7 +217,7 @@ class ModalPresenter : Subscriber, Trackable { window.layoutIfNeeded() }, completion: { _ in alertView.animate() - UIView.spring(0.6, delay: 2.0, animations: { + UIView.spring(0.6, delay: 3.0, animations: { topConstraint?.constant = size.height window.layoutIfNeeded() }, completion: { _ in @@ -235,7 +235,44 @@ class ModalPresenter : Subscriber, Trackable { alertView.removeFromSuperview() }) }) - } + } + + private func presentFailureAlert(_ type: AlertFailureType, + errorMessage: String, + completion: @escaping ()->Void) { + + let hostingViewController = UIHostingController(rootView: AlertFailureView(alertFailureType:.failedResolution, + 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) + + let topConstraint = failureAlertView.constraint(.top, toView: window, constant: size.height) + failureAlertView.constrain([ + failureAlertView.constraint(.width, constant: size.width), + failureAlertView.constraint(.height, constant: alertHeight + 50.0), + 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() + }, completion: { _ in + //TODO - Make these callbacks generic + completion() + failureAlertView.removeFromSuperview() + }) + }) + } private func rootModalViewController(_ type: RootModal) -> UIViewController? { switch type { @@ -317,6 +354,10 @@ class ModalPresenter : Subscriber, Trackable { self?.presentAlert(.resolvedSuccess, completion: {}) } + sendVC.onResolutionFailure = { [weak self] failureMessage in + self?.presentFailureAlert(.failedResolution, errorMessage: failureMessage, completion: {}) + } + return root } diff --git a/loafwallet/src/Strings/Base.lproj/Localizable.strings b/loafwallet/src/Strings/Base.lproj/Localizable.strings index 72629cec4..36f69006d 100644 --- a/loafwallet/src/Strings/Base.lproj/Localizable.strings +++ b/loafwallet/src/Strings/Base.lproj/Localizable.strings @@ -1360,11 +1360,8 @@ /* Copy all details */ "TransactionDetails.copyAllDetails" = "Copy all details"; -/* Balance */ -"ManageWallet.balance" = "Balance"; - /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- New Registration\n- Login (existing account)\n- No balance shown\n- No transfer\n- US Only"; +"LitecoinCard.Disclaimer.bullets" = "- Registration & Login\n- Available card balance\n- Reset password\n- No transfer to Litewallet\n- US Only"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin Card currently has limited functionality in Litewallet."; @@ -1374,3 +1371,24 @@ /* Beta Testing Litecoin Card */ "LitecoinCard.Disclaimer.title" = "Litecoin Card Beta"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Lookup failed"; + +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Sorry, domain was not found. [Error: %2$d]"; + +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "System lookup problem. [Error: %2$d]"; + +/* Balance */ +"ManageWallet.balance" = "Balance"; + +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Buy LTC with many fiat pairs\n• Pay with multiple methods\n• Global payment provider"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Enter the email address associated with your Litecoin Card account & look for an email with reset instructions."; diff --git a/loafwallet/src/Strings/da.lproj/Localizable.strings b/loafwallet/src/Strings/da.lproj/Localizable.strings index 6ad68da66..4174938f7 100755 --- a/loafwallet/src/Strings/da.lproj/Localizable.strings +++ b/loafwallet/src/Strings/da.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Købe Litecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Køb LTC med mange fiat-par\n• Betal med flere metoder\n• Global betalingsudbyder"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Få Litecoin inden for 5 minutter! \n • Køb Litecoin via kreditkort \n • Pas eller stats-ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Kortbalance"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Ny registrering\n- Login (eksisterende konto)\n- Ingen balance vist\n- Ingen overførsel\n- Kun USA"; +"LitecoinCard.Disclaimer.bullets" = "- Registrering og login\n- Tilgængelig kortsaldo\n- Nulstil adgangskode\n- Ingen overførsel til Litewallet\n- Kun USA"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin Card har i øjeblikket begrænset funktionalitet i Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Nulstille kodeord"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Indtast den e-mail-adresse, der er knyttet til din Litecoin Card-konto, og se efter en e-mail med nulstillingsinstruktioner."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Besøg https://litecoin.dashboard.getblockcard.com/password/forgot for at nulstille din adgangskode."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Kig op"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Beklager, domænet blev ikke fundet. [Fejl: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Opslag mislykkedes"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Indtast et .crypto- eller .zil-domæne"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Problem med systemopslag. [Fejl: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin adresser er kun beregnet til en enkelt anvendelse."; diff --git a/loafwallet/src/Strings/de.lproj/Localizable.strings b/loafwallet/src/Strings/de.lproj/Localizable.strings index 77dbe0bab..f8d8d4564 100755 --- a/loafwallet/src/Strings/de.lproj/Localizable.strings +++ b/loafwallet/src/Strings/de.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Kaufen Sie Łitecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Kaufen Sie LTC mit vielen Fiat-Paaren.\n• Bezahlen Sie mit mehreren Methoden.\n• Globaler Zahlungsanbieter"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Holen Sie sich Litecoin in 5 Minuten!\n• Kaufen Sie Litecoin per Kreditkarte\n• Reisepass oder Staatsausweis."; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Kartenguthaben"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Neue Registrierung\n- In vorhandenen Account (einloggen)\n- Kein Saldo angezeigt\n- Keine Übertragung\n- Nur USA"; +"LitecoinCard.Disclaimer.bullets" = "- Registratie en inlogge\n- Beschikbaar kaartsaldo\n- Wachtwoord opnieuw instelle\n- Geen overdracht naar Litewallet\n- Alleen in de USA."; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Die Litecoin Card verfügt derzeit über eingeschränkte Funktionen in Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Passwort zurücksetzen"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Geben Sie die E-Mail-Adresse ein, die Ihrem Litecoin Card-Konto zugeordnet ist, und suchen Sie nach einer E-Mail mit Anweisungen zum Zurücksetzen."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Besuchen Sie https://litecoin.dashboard.getblockcard.com/password/forgot, um Ihr Passwort zurückzusetzen."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Nachsehen"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Entschuldigung, Domain wurde nicht gefunden. [Error: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Lookup failed"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Geben Sie eine .crypto- oder .zil-Domain ein"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "System-Lookup-Problem. [Error: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin-Adressen sind lediglich zur einmaligen Benutzung vorgesehen."; diff --git a/loafwallet/src/Strings/en.lproj/Localizable.strings b/loafwallet/src/Strings/en.lproj/Localizable.strings index 9e3191028..d1617e538 100644 --- a/loafwallet/src/Strings/en.lproj/Localizable.strings +++ b/loafwallet/src/Strings/en.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Buy Łitecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Buy LTC with many fiat pairs\n• Pay with multiple methods\n• Global payment provider"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Get Litecoin in 5 mins!\n• Buy Litecoin via credit card\n• Passport or State ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Card balance"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- New Registration\n- Login (existing account)\n- No balance shown\n- No transfer\n- US Only"; +"LitecoinCard.Disclaimer.bullets" = "- Registration & Login\n- Available card balance\n- Reset password\n- No transfer to Litewallet\n- US Only"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin Card currently has limited functionality in Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Reset password"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Enter the email address associated with your Litecoin Card account & look for an email with reset instructions."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Visit https://litecoin.dashboard.getblockcard.com/password/forgot\nto reset your password."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Lookup"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Sorry, domain was not found. [Error:%2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Lookup failed"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Enter a .crypto or .zil domain"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "System lookup problem. [Error:%2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin addresses are intended for single use only."; diff --git a/loafwallet/src/Strings/es.lproj/Localizable.strings b/loafwallet/src/Strings/es.lproj/Localizable.strings index 2fab64959..2a78fa712 100755 --- a/loafwallet/src/Strings/es.lproj/Localizable.strings +++ b/loafwallet/src/Strings/es.lproj/Localizable.strings @@ -140,6 +140,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Comprar Łitecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Compre LTC con muchos pares fiat\n• Pague con múltiples métodos\n• Proveedor de pago global"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• ¡Obtenga Litecoin en 5 minutos! \n • Compre Litecoin con tarjeta de crédito \n • Pasaporte o identificación del estado"; @@ -369,7 +375,7 @@ "LitecoinCard.cardBalance" = "Balance de tarjeta"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Nuevo registro\n- Ingrese cuenta existente)\n- No se muestra saldo\n- Sin transferencia\n- Estados Unidos solamente"; +"LitecoinCard.Disclaimer.bullets" = "- Registro e inicio de sesión\n- Saldo de tarjeta disponible\n- Restablecer contraseña\n- Sin transferencia a Litewallet\n- Estados Unidos solamente"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "La tarjeta Litecoin actualmente tiene una funcionalidad limitada en Litewallet."; @@ -479,6 +485,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Restablecer la contraseña"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Ingrese la dirección de correo electrónico asociada con su cuenta de tarjeta Litecoin y busque un correo electrónico con instrucciones para restablecer."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Visita https://litecoin.dashboard.getblockcard.com/password/forgot para restablecer tu contraseña."; @@ -887,9 +896,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Buscar"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Lo sentimos, no se encontró el dominio. [Error: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Búsqueda fallida"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Ingrese un dominio .crypto o .zil"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Problema de búsqueda del sistema. [Error: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Las direcciones Litecoin están diseñadas para un solo uso."; diff --git a/loafwallet/src/Strings/fr.lproj/Localizable.strings b/loafwallet/src/Strings/fr.lproj/Localizable.strings index cb53c821c..6351133c4 100755 --- a/loafwallet/src/Strings/fr.lproj/Localizable.strings +++ b/loafwallet/src/Strings/fr.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Acheter Litecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Achetez des LTC avec de nombreuses paires de fiat\n• Payez avec plusieurs méthodes\n• Fournisseur de paiement mondial"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Obtenez du Litecoin en 5 minutes! \n • Achetez du Litecoin par carte de crédit \n • Passeport ou identifiant d'État"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Solde de la carte"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Nouvelle inscription\n- Connexion (compte existant)\n- Aucun solde affiché\n- Pas de transfert\n- États-Unis uniquement"; +"LitecoinCard.Disclaimer.bullets" = "- Inscription et connexion\n- Solde de la carte disponible\n- Réinitialiser le mot de passe\n- Aucun transfert vers Litewallet\n- États-Unis uniquement"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "La carte Litecoin a actuellement des fonctionnalités limitées dans Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Réinitialiser le mot de passe"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Entrez l'adresse e-mail associée à votre compte Litecoin Card et recherchez un e-mail avec des instructions de réinitialisation."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Visitez le site https://litecoin.dashboard.getblockcard.com/password/forgot pour réinitialiser votre mot de passe."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Chercher"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Désolé, le domaine est introuvable. [Erreur: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "La recherche a échoué"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Entrez un domaine .crypto ou .zil"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Problème de recherche système. [Erreur: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Les adresses Litecoin sont destinées à une utilisation unique."; diff --git a/loafwallet/src/Strings/id.lproj/Localizable.strings b/loafwallet/src/Strings/id.lproj/Localizable.strings index 22b78ebb1..8c72dd15f 100644 --- a/loafwallet/src/Strings/id.lproj/Localizable.strings +++ b/loafwallet/src/Strings/id.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Membeli Łitecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Beli LTC dengan banyak pasangan fiat\n• Bayar dengan berbagai metode\n• Penyedia pembayaran global"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Gunakan ID atau Paspor \n • Membeli Litecoin dengan kartu kredit \n • Membeli dengan USD atau EUR"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Saldo kartu"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Pendaftaran baru\n- Masuk (akun yang ada)\n- Tidak ada saldo yang ditampilkan\n- Tidak ada transfer\n- Hanya AS"; +"LitecoinCard.Disclaimer.bullets" = "- Pendaftaran & Login\n- Saldo kartu yang tersedia\n- Reset kata sandi\n- Tidak ada transfer ke Litewallet\n- AS Sudah"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Kartu Litecoin saat ini memiliki fungsi terbatas di Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Setel ulang kata sandi"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Masukkan alamat email yang terkait dengan akun Kartu Litecoin Anda & cari email dengan instruksi reset."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Kunjungi https://litecoin.dashboard.getblockcard.com/password/forgot untuk mengatur ulang kata sandi Anda."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Lihatlah"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Masalah sistem, domain tidak ditemukan. [Kesalahan: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Pencarian gagal"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Masukkan domain .crypto atau .zil"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Masalah pencarian sistem. [Kesalahan: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Alamat Litecoin hanya ditujukan untuk penggunaan tunggal."; diff --git a/loafwallet/src/Strings/it.lproj/Localizable.strings b/loafwallet/src/Strings/it.lproj/Localizable.strings index 43803e034..8d3e75639 100755 --- a/loafwallet/src/Strings/it.lproj/Localizable.strings +++ b/loafwallet/src/Strings/it.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Acquista Łitecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Acquista LTC con molte coppie fiat\n• Paga con più metodi\n• Fornitore globale di pagamenti"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Ottieni Litecoin in 5 minuti! \n • Acquista Litecoin tramite carta di credito \n • Passaporto o carta d'identità"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Saldo della carta"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Nuova registrazione\n- Log in in un account esistente)\n- Nessun saldo mostrato\n- Nessun trasferimento\n- Solo USA"; +"LitecoinCard.Disclaimer.bullets" = "- Registrazione e accesso\n- Saldo della carta disponibile\n- Reimposta password\n- Nessun trasferimento a Litewallet\n- Solo negli Stati Uniti"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin Card ha attualmente funzionalità limitate in Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Resetta la password"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Inserisci l'indirizzo e-mail associato al tuo account Litecoin Card e cerca un'e-mail con le istruzioni per il ripristino."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Visita https://litecoin.dashboard.getblockcard.com/password/forgot per reimpostare la tua password."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Consultare"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Spiacenti, il dominio non è stato trovato. [Errore: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Ricerca non riuscita"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Inserisci un dominio .crypto o .zil"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Problema di ricerca nel sistema. [Errore: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Gli indirizzi Litecoin dovrebbero essere utilizzati una sola volta."; diff --git a/loafwallet/src/Strings/ja.lproj/Localizable.strings b/loafwallet/src/Strings/ja.lproj/Localizable.strings index e0671d1f1..d15b9df12 100755 --- a/loafwallet/src/Strings/ja.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ja.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Litecoin を購入する"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "•多くの法定紙幣ペアでLTCを購入する\n•複数の方法で支払う\n•グローバル決済プロバイダー"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "•5分でLitecoinを入手!\n •クレジットカードでLitecoinを購入 \n•パスポートまたは州ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "カード残高"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "-新規登録\n-ログイン(既存のアカウント)\n-残高は表示されていません\n-転送なし\n-米国のみ"; +"LitecoinCard.Disclaimer.bullets" = "-登録とログイン\n-利用可能なカード残高\n- パスワードを再設定する\n-Litewalletへの転送なし\n-米国のみ"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "ライトコインカードは現在、ライトウォレットの機能が制限されています。"; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "パスワードを再設定する"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "ライトコインカードアカウントに関連付けられているメールアドレスを入力し、リセット手順が記載されたメールを探します。"; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "https://litecoin.dashboard.getblockcard.com/password/forgot にアクセスしてパスワードをリセットしてください。"; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "調べる"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "申し訳ありませんが、ドメインが見つかりませんでした。 [エラー: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "ルックアップに失敗しました"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = ".cryptoまたは.zilドメインを入力してください"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "システムルックアップの問題。 [エラー: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "リテコインアドレスは、個人利用のみを想定しています。"; diff --git a/loafwallet/src/Strings/ko.lproj/Localizable.strings b/loafwallet/src/Strings/ko.lproj/Localizable.strings index 1f337282c..6ebec1830 100755 --- a/loafwallet/src/Strings/ko.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ko.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Łitecoin 구매"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• 많은 법정 화폐 쌍으로 LTC 구매\n• 여러 방법으로 지불\n• 글로벌 지불 공급자"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "5 분 안에 Litecoin을 받으십시오! \n • 신용 카드를 통해 Litecoin을 구매하십시오 \n • 여권 또는 주 ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "카드 잔액"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "-신규 등록\n-로그인 (기존 계정)\n-잔액이 표시되지 않음\n-환승 불가\n-미국 만"; +"LitecoinCard.Disclaimer.bullets" = "-등록 및 로그인\n-사용 가능한 카드 잔액\n- 암호를 재설정\n-Litewallet으로 양도 불가\n-미국 만 해당"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "라이트 코인 카드는 현재 라이트 월렛에서 제한된 기능을 가지고 있습니다."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "암호를 재설정"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "라이트 코인 카드 계정과 연결된 이메일 주소를 입력하고 재설정 지침이있는 이메일을 찾으십시오."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "https://litecoin.dashboard.getblockcard.com/password/forgot을 방문하여 암호를 재설정하십시오."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "조회"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "죄송합니다. 도메인을 찾을 수 없습니다. [오류 : %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "조회 실패"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = ".crypto 또는 .zil 도메인을 입력하세요."; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "시스템 조회 문제입니다. [오류 : %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin 주소는 일회용입니다."; diff --git a/loafwallet/src/Strings/nl.lproj/Localizable.strings b/loafwallet/src/Strings/nl.lproj/Localizable.strings index f7060a806..caff8be9c 100755 --- a/loafwallet/src/Strings/nl.lproj/Localizable.strings +++ b/loafwallet/src/Strings/nl.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Koop Litecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Koop LTC met veel fiat-paren\n• Betaal met meerdere methoden\n• Wereldwijde betalingsprovider"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Krijg Litecoin in 5 minuten! \n • Koop Litecoin via creditcard \n • Paspoort of staat ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Kaartsaldo"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Nieuwe registratie\n- Inloggen (bestaand account)\n- Geen saldo weergegeven\n- Geen overdracht\n- Alleen in de VS."; +"LitecoinCard.Disclaimer.bullets" = "- Registratie en inloggen\n- Beschikbaar kaartsaldo\n- Wachtwoord opnieuw instellen\n- Geen overdracht naar Litewallet\n- Alleen in de USA."; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin Card heeft momenteel beperkte functionaliteit in Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Wachtwoord opnieuw instellen"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Voer het e-mailadres in dat is gekoppeld aan uw Litecoin Card-account en zoek een e-mail met resetinstructies."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Ga naar https://litecoin.dashboard.getblockcard.com/password/forgot om uw wachtwoord te resetten."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Opzoeken"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Sorry, het domein is niet gevonden. [Fout: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Opzoeken mislukt"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Voer een .crypto- of .zil-domein in"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Systeem opzoeken probleem. [Fout: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin adressen zijn alleen bedoeld voor enkel gebruik."; diff --git a/loafwallet/src/Strings/pt.lproj/Localizable.strings b/loafwallet/src/Strings/pt.lproj/Localizable.strings index 88c978409..fcfe23060 100755 --- a/loafwallet/src/Strings/pt.lproj/Localizable.strings +++ b/loafwallet/src/Strings/pt.lproj/Localizable.strings @@ -140,6 +140,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Comprar Łitecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Compre LTC com muitos pares fiat\n• Pague com vários métodos\n• Provedor de pagamento global"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Obtenha Litecoin em 5 minutos! \n • Compre Litecoin via cartão de crédito \n • Passaporte ou ID do estado"; @@ -369,7 +375,7 @@ "LitecoinCard.cardBalance" = "Saldo do cartão"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Novo registro\n- Entrar em uma conta existente)\n- Nenhum saldo mostrado\n- Sem transferência\n- Apenas estados unidos"; +"LitecoinCard.Disclaimer.bullets" = "- Registro e login\n- Saldo do cartão disponível\n- Redefinir senha\n- Sem transferência para Litewallet\n- Somente nos EUA"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "O cartão Litecoin atualmente tem funcionalidade limitada no Litewallet."; @@ -479,6 +485,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Redefinir senha"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Digite o endereço de e-mail associado à sua conta do cartão Litecoin e procure um e-mail com as instruções de reinicialização."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Visite https://litecoin.dashboard.getblockcard.com/password/forgot para redefinir a sua palavra-passe."; @@ -887,9 +896,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Pesquisa"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Desculpe, o domínio não foi encontrado. [Erro: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Pesquisa falhou"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Insira um domínio .crypto ou .zil"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Problema de pesquisa do sistema. [Erro: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Os endereços de Litecoin destinam-se apenas a uma única utilização."; diff --git a/loafwallet/src/Strings/ru.lproj/Localizable.strings b/loafwallet/src/Strings/ru.lproj/Localizable.strings index b00e040fd..ac5a0ad21 100755 --- a/loafwallet/src/Strings/ru.lproj/Localizable.strings +++ b/loafwallet/src/Strings/ru.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Купить Litecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Покупайте LTC с помощью множества фиатных пар\n• Оплачивайте несколькими способами\n• Глобальный платежный провайдер"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Получить Litecoin за 5 минут! \n • Купить Litecoin с помощью кредитной карты \n • Паспорт или удостоверение личности штата"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Баланс карты"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Новая регистрация\n- Авторизация (существующая учетная запись)\n- Баланс не отображается\n- Без передачи\n- Только США"; +"LitecoinCard.Disclaimer.bullets" = "- Регистрация и вход\n- Доступный баланс карты\n- Сброс пароля\n- Без перевода на Litewallet\n- Только США"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin Card в настоящее время имеет ограниченную функциональность в Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Сброс пароля"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Введите адрес электронной почты, связанный с вашей учетной записью Litecoin Card, и найдите письмо с инструкциями по сбросу."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Посетите https://litecoin.dashboard.getblockcard.com/password/forgot, чтобы сбросить пароль."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Искать"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "К сожалению, домен не найден. [Ошибка: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Ошибка поиска"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Введите домен .crypto или .zil"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Проблема с поиском в системе. [Ошибка: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Биткойн-адреса предназначены исключительно для однократного использования."; diff --git a/loafwallet/src/Strings/sv.lproj/Localizable.strings b/loafwallet/src/Strings/sv.lproj/Localizable.strings index 379182bc0..407201fa8 100755 --- a/loafwallet/src/Strings/sv.lproj/Localizable.strings +++ b/loafwallet/src/Strings/sv.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "Köp Litecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "• Köp LTC med många fiatpar\n• Betala med flera metoder\n• Global betalningsleverantör"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• Skaffa Litecoin inom 5 minuter! \n • Köp Litecoin via kreditkort \n • Pass eller statligt ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "Kortbalans"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "- Ny registrering\n- Inloggning (befintligt konto)\n- Ingen balans visas\n- Ingen överföring\n- Endast USA"; +"LitecoinCard.Disclaimer.bullets" = "- Registrering & inloggning\n- Tillgängligt kortsaldo\n- Återställ lösenord\n- Ingen överföring till Litewallet\n- Endast USA"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin Card har för närvarande begränsad funktionalitet i Litewallet."; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "Återställ lösenord"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "Ange e-postadressen som är kopplad till ditt Litecoin-kortkonto och leta efter ett e-postmeddelande med återställningsinstruktioner."; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "Besök https://litecoin.dashboard.getblockcard.com/password/forgot för att återställa ditt lösenord."; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "Slå upp"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "Tyvärr hittades inte domänen. [Fel: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "Sökningen misslyckades"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "Ange en .crypto- eller .zil-domän"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "Problem med systemuppslag. [Fel: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "Litecoin-adresser är avsedda för engångsanvändning."; diff --git a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings index 7d6f0a825..dc544581d 100755 --- a/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hans.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "购买 Łitecoin"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "•购买具有许多法定货币对的LTC\n•以多种方式支付\n•全球支付提供商"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "• 5分钟内获得Litecoin!\n •通过信用卡购买Litecoin \n •护照或州ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "卡余额"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "-新注册\n-登录(现有帐户\n-没有余额显示\n-没有转移\n-仅限美国"; +"LitecoinCard.Disclaimer.bullets" = "-注册和登录\n-可用卡余额\n-重置密码\n-不能转移到Litewallet\n-仅限美国"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin卡当前在Litewallet中具有有限的功能。"; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "重设密码"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "输入与您的Litecoin卡帐户关联的电子邮件地址,并查找包含重置说明的电子邮件。"; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "请访问 https://litecoin.dashboard.getblockcard.com/password/forgot 重置您的密码。"; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "抬头"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "抱歉,找不到域。 [错误: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "查找失败"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "输入.crypto或.zil域"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "系统查找问题。 [错误: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "莱特币地址仅供一次性使用。"; diff --git a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings index 72e8bebc8..b64ef8687 100755 --- a/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings +++ b/loafwallet/src/Strings/zh-Hant.lproj/Localizable.strings @@ -139,6 +139,12 @@ /* Buy Modal Title */ "BuyCenter.ModalTitle" = "購買萊特幣"; +/* Moonpay buy financial details */ +"BuyCenter.moonpayFinancialDetails" = "•購買具有許多法定貨幣對的LTC\n•以多種方式支付\n•全球支付提供商"; + +/* Moonpay Title */ +"BuyCenter.moonpayTitle" = "Moonpay"; + /* Simplex buy financial details */ "BuyCenter.simplexFinancialDetails" = "•5分鐘內獲得Litecoin!\n •通過信用卡購買Litecoin \n •護照或州ID"; @@ -368,7 +374,7 @@ "LitecoinCard.cardBalance" = "卡餘額"; /* Features and limitations */ -"LitecoinCard.Disclaimer.bullets" = "-新註冊\n-登錄(現有帳戶)\n-沒有餘額顯示\n-沒有轉移\n-僅限美國"; +"LitecoinCard.Disclaimer.bullets" = "-註冊和登錄\n-可用卡餘額\n-重置密碼\n-不能轉移到Litewallet\n-僅限美國"; /* Description of the status */ "LitecoinCard.Disclaimer.description" = "Litecoin卡當前在Litewallet中具有有限的功能。"; @@ -478,6 +484,9 @@ /* Reset Litecoin card password */ "LitecoinCard.resetPassword" = "重設密碼"; +/* Reset password detail */ +"LitecoinCard.resetPasswordDetail" = "輸入與您的Litecoin卡帳戶關聯的電子郵件地址,並查找包含重置說明的電子郵件。"; + /* Litecoin card visit */ "LitecoinCard.visit.toReset" = "訪問https://litecoin.dashboard.getblockcard.com/password/forgot重設密碼。"; @@ -886,9 +895,18 @@ /* Lookup */ "Send.UnstoppableDomains.lookup" = "抬頭"; +/* LookupDomainError */ +"Send.UnstoppableDomains.lookupDomainError" = "抱歉,找不到域。 [錯誤: %2$d]"; + +/* lookupFailureHeader */ +"Send.UnstoppableDomains.lookupFailureHeader" = "查找失敗"; + /* Enter to match domain name to LTC Address */ "Send.UnstoppableDomains.placeholder" = "輸入.crypto或.zil域"; +/* UDSystemError */ +"Send.UnstoppableDomains.udSystemError" = "系統查找問題。 [錯誤: %2$d]"; + /* Adress already used alert message - first part */ "Send.UsedAddress.firstLine" = "萊特幣位址專供一次性使用。"; diff --git a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift index 8df70c501..a187fabd0 100644 --- a/loafwallet/src/ViewControllers/RootModals/SendViewController.swift +++ b/loafwallet/src/ViewControllers/RootModals/SendViewController.swift @@ -25,6 +25,7 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track var presentVerifyPin: ((String, @escaping VerifyPinCallback)->Void)? var onPublishSuccess: (()->Void)? var onResolvedSuccess: (()->Void)? + var onResolutionFailure: ((String)->Void)? var parentView: UIView? //ModalPresentable var initialAddress: String? var isPresentedFromLock = false @@ -200,6 +201,12 @@ class SendViewController : UIViewController, Subscriber, ModalPresentable, Track self.onResolvedSuccess?() self.addressCell.textField.text = resolvedUDAddress } + + } + + unstoppableCell.rootView.viewModel.didFailToResolve = { errorMessage in + // Toast the failure + self.onResolutionFailure?(errorMessage) } } diff --git a/loafwallet/src/Views/AlertView.swift b/loafwallet/src/Views/AlertView.swift index 46fbb2ca3..df69d3ecc 100644 --- a/loafwallet/src/Views/AlertView.swift +++ b/loafwallet/src/Views/AlertView.swift @@ -15,41 +15,52 @@ enum AlertType { case resolvedSuccess case addressesCopied case sweepSuccess(callback: () -> Void) - + + //Failure(s) + case failedResolution + var header: String { switch self { - case .pinSet: - return S.SecurityAlerts.pinSet - case .paperKeySet: - return S.SecurityAlerts.paperKeySet - case .sendSuccess: - return S.SecurityAlerts.sendSuccess - case .resolvedSuccess: - return S.SecurityAlerts.resolvedSuccess - case .addressesCopied: - return S.SecurityAlerts.copiedAddressesHeader - case .sweepSuccess: - return S.Import.success + case .pinSet: + return S.SecurityAlerts.pinSet + case .paperKeySet: + return S.SecurityAlerts.paperKeySet + case .sendSuccess: + return S.SecurityAlerts.sendSuccess + case .resolvedSuccess: + return S.SecurityAlerts.resolvedSuccess + case .addressesCopied: + return S.SecurityAlerts.copiedAddressesHeader + case .sweepSuccess: + return S.Import.success + + // Failure(s) + case .failedResolution: + return S.SecurityAlerts.sendFailure } } - + var subheader: String { switch self { - case .pinSet: - return "" - case .paperKeySet: - return S.SecurityAlerts.paperKeySetSubheader - case .sendSuccess: - return S.SecurityAlerts.sendSuccessSubheader - case .resolvedSuccess: - return S.SecurityAlerts.resolvedSuccessSubheader - case .addressesCopied: - return S.SecurityAlerts.copiedAddressesSubheader - case .sweepSuccess: - return S.Import.successBody + case .pinSet: + return "" + case .paperKeySet: + return S.SecurityAlerts.paperKeySetSubheader + case .sendSuccess: + return S.SecurityAlerts.sendSuccessSubheader + case .resolvedSuccess: + return S.SecurityAlerts.resolvedSuccessSubheader + case .addressesCopied: + return S.SecurityAlerts.copiedAddressesSubheader + case .sweepSuccess: + return S.Import.successBody + + // Failure(s) + case .failedResolution: + return S.SecurityAlerts.resolvedSuccessSubheader } } - + var icon: UIView { return CheckView() } @@ -59,20 +70,25 @@ extension AlertType : Equatable {} func ==(lhs: AlertType, rhs: AlertType) -> Bool { switch (lhs, rhs) { - case (.pinSet(_), .pinSet(_)): - return true - case (.paperKeySet(_), .paperKeySet(_)): - return true - case (.sendSuccess, .sendSuccess): - return true - case (.resolvedSuccess, .resolvedSuccess): + case (.pinSet(_), .pinSet(_)): + return true + case (.paperKeySet(_), .paperKeySet(_)): + return true + case (.sendSuccess, .sendSuccess): + return true + case (.resolvedSuccess, .resolvedSuccess): return true - case (.addressesCopied, .addressesCopied): - return true - case (.sweepSuccess(_), .sweepSuccess(_)): - return true - default: - return false + case (.addressesCopied, .addressesCopied): + return true + case (.sweepSuccess(_), .sweepSuccess(_)): + return true + + // Failure(s) + case (.failedResolution, .failedResolution): + return true + + default: + return false } } @@ -85,75 +101,75 @@ class AlertView : UIView, SolidColorDrawable { private let icon: UIView private let iconSize: CGFloat = 96.0 private let separatorYOffset: CGFloat = 48.0 - + init(type: AlertType) { self.type = type - self.icon = type.icon - + self.icon = type.icon super.init(frame: .zero) layer.cornerRadius = 6.0 layer.masksToBounds = true setupSubviews() } - + func animate() { guard let animatableIcon = icon as? AnimatableIcon else { return } animatableIcon.animate() } - + private func setupSubviews() { addSubview(header) addSubview(subheader) addSubview(icon) addSubview(separator) - + setData() addConstraints() } - + private func setData() { header.text = type.header header.textAlignment = .center - header.font = UIFont.barlowBold(size: 16.0) + header.font = UIFont.barlowBold(size: 18.0) header.textColor = .white - + icon.backgroundColor = .clear separator.backgroundColor = .transparentWhite - + subheader.text = type.subheader subheader.textAlignment = .center subheader.font = UIFont.barlowSemiBold(size: 16.0) subheader.textColor = .white } - + private func addConstraints() { - + //NB - In this alert view, constraints shouldn't be pinned to the bottom //of the view because the bottom actually extends off the bottom of the screen a bit. //It extends so that it still covers up the underlying view when it bounces on screen. - + header.constrainTopCorners(sidePadding: C.padding[2], topPadding: C.padding[2]) separator.constrain([ - separator.constraint(.height, constant: 1.0), - separator.constraint(.width, toView: self, constant: 0.0), - separator.constraint(.top, toView: self, constant: separatorYOffset), - separator.constraint(.leading, toView: self, constant: nil) ]) + separator.constraint(.height, constant: 1.0), + separator.constraint(.width, toView: self, constant: 0.0), + separator.constraint(.top, toView: self, constant: separatorYOffset), + separator.constraint(.leading, toView: self, constant: nil) ]) icon.constrain([ - icon.constraint(.centerX, toView: self, constant: nil), - icon.constraint(.centerY, toView: self, constant: nil), - icon.constraint(.width, constant: iconSize), - icon.constraint(.height, constant: iconSize) ]) + icon.constraint(.centerX, toView: self, constant: nil), + icon.constraint(.centerY, toView: self, constant: nil), + icon.constraint(.width, constant: iconSize), + icon.constraint(.height, constant: iconSize) ]) subheader.constrain([ - subheader.constraint(.leading, toView: self, constant: C.padding[2]), - subheader.constraint(.trailing, toView: self, constant: -C.padding[2]), - subheader.constraint(toBottom: icon, constant: C.padding[3]) ]) + subheader.constraint(.leading, toView: self, constant: C.padding[2]), + subheader.constraint(.trailing, toView: self, constant: -C.padding[2]), + subheader.constraint(toBottom: icon, constant: C.padding[3]) ]) } - + override func draw(_ rect: CGRect) { drawColor(color: .liteWalletBlue, rect) } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } + diff --git a/loafwalletTests/Class Tests/LitecoinCardTests/CardWalletTests.swift b/loafwalletTests/Class Tests/LitecoinCardTests/CardWalletTests.swift new file mode 100644 index 000000000..7f32b308c --- /dev/null +++ b/loafwalletTests/Class Tests/LitecoinCardTests/CardWalletTests.swift @@ -0,0 +1,129 @@ +// +// CardWalletTests.swift +// loafwalletTests +// +// Created by Kerry Washington on 4/1/21. +// Copyright © 2021 Litecoin Foundation. All rights reserved. +// + +import XCTest +import Foundation +import SwiftUI +@testable import loafwallet + +class CardWalletTests: XCTestCase { + + var viewModel: CardViewModel! + + let mockWalletDetailsResponseData = + """ + { + "user_id": "fbabf1bc-1b32-40e6-b072-a0127c026a86", + "tern_address": "GBI6LADAXTIEOVRTQURCCBP77OVYOI7WBLSMEUXXHWUX7UJRUB4DIXET", + "balance": 0.335425, + "btc_address": "moEStpdJy3WXgvrM4UMEPJpG6cJkPiuJ8u", + "eth_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", + "bch_address": "bchtest:qrn7u2kpkf6lrudytt74z6qadvse3t6whs370a3pnk", + "ltc_address": "mnUMriUAdmfXbodgbmKgrYsDHbEcu51XxJ", + "created_at": "2020-07-12 23:38:05", + "updated_at": "2020-07-12 23:38:05", + "xrp_tag": 983056520, + "xlm_memo": 503240710, + "bank_balance": null, + "bank_pending_balance": null, + "bank_account_number": null, + "available_balance": 0.335425, + "available_balance_usd": 0, + "withdrawable_balance": 0, + "withdrawable_balance_usd": 0, + "spendable_balance": 0, + "spendable_balance_usd": 0, + "bat_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", + "usdc_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", + "usdt_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", + "pax_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", + "tusd_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", + "dai_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", + "tern_memo": 503240710, + "xlm_address": "GBI6LADAXTIEOVRTQURCCBP77OVYOI7WBLSMEUXXHWUX7UJRUB4DIXET", + "xrp_address": "rE8xLDU9d4UCtqtiH5Tz8aRHMNfq7PQH8c", + "ach_routing_number": null, + "ach_account_status": null + } + """.data(using: .utf8) + + override func setUp() { + super.setUp() + viewModel = CardViewModel() + } + + func testDecodeWalletDetails() throws { + + do { + + let decoder = JSONDecoder() + + guard let data = mockWalletDetailsResponseData else { + return + } + + let walletDetails = try? decoder.decode(CardWalletDetails.self, from: data) + + XCTAssertNotNil(walletDetails) + + } catch { + XCTFail("Decoding failed") + } + + } + +} + +// DEV: Raw data from user/user_ID/wallet +// Reference in case the schema changes +// { +// "data": { +// "user_id": "fbabf1bc-1b32-40e6-b072-a0127c026a86", +// "tern_address": "GBI6LADAXTIEOVRTQURCCBP77OVYOI7WBLSMEUXXHWUX7UJRUB4DIXET", +// "balance": 0, +// "btc_address": "moEStpdJy3WXgvrM4UMEPJpG6cJkPiuJ8u", +// "eth_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", +// "bch_address": "bchtest:qrn7u2kpkf6lrudytt74z6qadvse3t6whs370a3pnk", +// "ltc_address": "mnUMriUAdmfXbodgbmKgrYsDHbEcu51XxJ", +// "created_at": "2020-07-12 23:38:05", +// "updated_at": "2020-07-12 23:38:05", +// "xrp_tag": 983056520, +// "xlm_memo": 503240710, +// "bank_balance": null, +// "bank_pending_balance": null, +// "bank_account_number": null, +// "available_balance": 0, +// "available_balance_usd": 0, +// "withdrawable_balance": 0, +// "withdrawable_balance_usd": 0, +// "spendable_balance": 0, +// "spendable_balance_usd": 0, +// "bat_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", +// "usdc_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", +// "usdt_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", +// "pax_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", +// "tusd_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", +// "dai_address": "0x08598f771bd2481026369552DdDEE52d2c32AA01", +// "tern_memo": 503240710, +// "xlm_address": "GBI6LADAXTIEOVRTQURCCBP77OVYOI7WBLSMEUXXHWUX7UJRUB4DIXET", +// "xrp_address": "rE8xLDU9d4UCtqtiH5Tz8aRHMNfq7PQH8c", +// "ach_routing_number": null, +// "ach_account_status": null +// }, +// "meta": { +// "version": "1.0.2", +// "received": null, +// "executed": 1617288226373 +// }, +// "response": { +// "code": 200, +// "errors": {}, +// "message": "OK" +// } +// } + From 43f30a8eeacdc764aa9513d7645ece65c4505d4e Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 6 Jun 2021 13:47:51 +0100 Subject: [PATCH 13/35] Create GitHub Action: push-to-release-email (#56) * Create GitHub-actions-push-demo.yml * Changes the demo script * Added more data to script * Added Gmail agent * fixed formatting issues * Change the agent email * Changes the filter * Fixed formatting errors --- .github/workflows/push-to-release-email.yml | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/push-to-release-email.yml diff --git a/.github/workflows/push-to-release-email.yml b/.github/workflows/push-to-release-email.yml new file mode 100644 index 000000000..b2ec646fb --- /dev/null +++ b/.github/workflows/push-to-release-email.yml @@ -0,0 +1,43 @@ +name: Email notfication for upcoming release +on: + push: + branches: + - release +jobs: + send_email: + runs-on: ubuntu-latest + name: send_email + steps: + - name: Send email + # You may pin to the exact commit or the version. + # uses: dawidd6/action-send-mail@98b61f505d216dafd844f3bfca5b2972df822dab + uses: dawidd6/action-send-mail@v3.1.0 + with: + # Required mail server address: + server_address: smtp.gmail.com + # Required mail server port: + server_port: 465 + # Required mail server username: + username: ${{secrets.MAIL_AGENT_USERNAME}} + # Required mail server password: + password: ${{secrets.MAIL_AGENT_PASSWORD}} + # Required mail subject: + subject: Litewallet iOS Release almost ready + # Required recipients' addresses: + to: kerry.washington@gmail.com # oritabak@gmail.com, + # Required sender full name (address can be skipped): + from: # Litewallet iOS Github Repo + # Optional whether this connection use TLS (default is true if server_port is 465) + secure: true + # Optional plain body: + body: Build job of ${{github.repository}} completed successfully! + # Optional HTML body read from file: + html_body: file://README.html + # Optional carbon copy recipients: + cc: kerry.washington.uk@gmail.com + # Optional recipient of the email response: + reply_to: litecoin.foundation.mobile.agent@gmail.com + # Optional unsigned/invalid certificates allowance: + ignore_cert: true + # Optional converting Markdown to HTML (set content_type to text/html too): + convert_markdown: true From 6b3c6c4a1959266824eff093b78c984ec3ad847f Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 8 Jun 2021 15:17:10 +0100 Subject: [PATCH 14/35] =?UTF-8?q?=F0=9F=9A=80[Release=20v3.5.0]=20Merge=20?= =?UTF-8?q?into=20Main=20(#55)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * [Merge into Develop] Release v3.1.1 (#195) * [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 * Update issue templates (#127) * Update issue templates * Update bug_report.md * Update feature_request.md Update with Litewallet data * [Tech Debt] Update readme.md (#174) * update readme.md * per review notes * Clean up the cocoapod installation (#196) - Remove Firebase pod - Added Firebase Swift package - Removed some old dead code * [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 * [Feature] Unhide Litecoin card prod v1 (#203) * Unhiding the Card tab * Update the LitewalletPartnerAPI Swift package version * set tab item name * [Bugfix] Firebase Swift package does not archive (#210) * Resolved package * Readded pods - Firebase Crashlytics - Firebase Analytics - Updated the Litewallet API package * adjusted the forgot button (#201) * [Tech Debt] Removed extra Web class (#204) * Removed extra Web class * removed unused vc * [Bugfix] Fix buywebview (#215) * Resolve Crash issue * Fixes the webview * [Merge v3.2.0] into Develop (#217) * [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 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 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 -