From 02449d9d004160aea2a02841e4fe753fdb73b093 Mon Sep 17 00:00:00 2001 From: Chung Tran Date: Tue, 18 Jul 2023 10:30:24 +0700 Subject: [PATCH 1/6] feat: remove swiftdoc --- .../xcshareddata/swiftpm/Package.resolved | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 655a9b5679..864919b55d 100644 --- a/p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -379,24 +379,6 @@ "version": "1.0.4" } }, - { - "package": "SwiftDocCPlugin", - "repositoryURL": "https://github.com/apple/swift-docc-plugin", - "state": { - "branch": null, - "revision": "26ac5758409154cc448d7ab82389c520fa8a8247", - "version": "1.3.0" - } - }, - { - "package": "SymbolKit", - "repositoryURL": "https://github.com/apple/swift-docc-symbolkit", - "state": { - "branch": null, - "revision": "b45d1f2ed151d057b54504d653e0da5552844e34", - "version": "1.0.0" - } - }, { "package": "swift-nio", "repositoryURL": "https://github.com/apple/swift-nio.git", From f5447712afd6f46f6aa225638f37d7f2b44191c0 Mon Sep 17 00:00:00 2001 From: Chung Tran Date: Tue, 18 Jul 2023 15:13:48 +0700 Subject: [PATCH 2/6] feat: remove some unused structs --- .../Scenes/Main/Buy/ActivityIndicator.swift | 14 +++--- .../{View => }/AboutSolendSlideView.swift | 0 .../{View => }/AboutSolendView.swift | 0 .../ViewModel/AboutSolendViewModel.swift | 10 ---- .../ChooseSwapTokenCoordinator.swift | 4 +- .../ActionsPanel/ActionsPanelView.swift | 48 ------------------- 6 files changed, 9 insertions(+), 67 deletions(-) rename p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/{View => }/AboutSolendSlideView.swift (100%) rename p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/{View => }/AboutSolendView.swift (100%) delete mode 100644 p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/ViewModel/AboutSolendViewModel.swift diff --git a/p2p_wallet/Scenes/Main/Buy/ActivityIndicator.swift b/p2p_wallet/Scenes/Main/Buy/ActivityIndicator.swift index e7895ae49a..046a8cbd38 100644 --- a/p2p_wallet/Scenes/Main/Buy/ActivityIndicator.swift +++ b/p2p_wallet/Scenes/Main/Buy/ActivityIndicator.swift @@ -7,23 +7,23 @@ import SwiftUI -public struct ActivityIndicator: UIViewRepresentable { - public typealias UIView = UIActivityIndicatorView - public var isAnimating: Bool = true - public var configuration = { (_: UIView) in } +struct ActivityIndicator: UIViewRepresentable { + typealias UIView = UIActivityIndicatorView + var isAnimating: Bool = true + var configuration = { (_: UIView) in } - public init(isAnimating: Bool, configuration: ((UIView) -> Void)? = nil) { + init(isAnimating: Bool, configuration: ((UIView) -> Void)? = nil) { self.isAnimating = isAnimating if let configuration = configuration { self.configuration = configuration } } - public func makeUIView(context _: UIViewRepresentableContext) -> UIView { + func makeUIView(context _: UIViewRepresentableContext) -> UIView { UIView() } - public func updateUIView(_ uiView: UIView, context _: UIViewRepresentableContext) { + func updateUIView(_ uiView: UIView, context _: UIViewRepresentableContext) { isAnimating ? uiView.startAnimating() : uiView.stopAnimating() configuration(uiView) } diff --git a/p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/View/AboutSolendSlideView.swift b/p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/AboutSolendSlideView.swift similarity index 100% rename from p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/View/AboutSolendSlideView.swift rename to p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/AboutSolendSlideView.swift diff --git a/p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/View/AboutSolendView.swift b/p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/AboutSolendView.swift similarity index 100% rename from p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/View/AboutSolendView.swift rename to p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/AboutSolendView.swift diff --git a/p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/ViewModel/AboutSolendViewModel.swift b/p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/ViewModel/AboutSolendViewModel.swift deleted file mode 100644 index c2b37940b5..0000000000 --- a/p2p_wallet/Scenes/Main/InvestSolend/AboutSolend/ViewModel/AboutSolendViewModel.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// AboutSolendViewModel.swift -// p2p_wallet -// -// Created by Ivan on 05.10.2022. -// - -import Foundation - -class AboutSolendViewModel: ObservableObject {} diff --git a/p2p_wallet/Scenes/Main/Swap/ChooseSwapItem/ChooseSwapTokenCoordinator.swift b/p2p_wallet/Scenes/Main/Swap/ChooseSwapItem/ChooseSwapTokenCoordinator.swift index 813d38eb68..45d42bed61 100644 --- a/p2p_wallet/Scenes/Main/Swap/ChooseSwapItem/ChooseSwapTokenCoordinator.swift +++ b/p2p_wallet/Scenes/Main/Swap/ChooseSwapItem/ChooseSwapTokenCoordinator.swift @@ -1,7 +1,7 @@ import Combine +import KeyAppUI import SolanaSwift import SwiftUI -import KeyAppUI final class ChooseSwapTokenCoordinator: Coordinator { private let subject = PassthroughSubject() @@ -61,6 +61,6 @@ final class ChooseSwapTokenCoordinator: Coordinator { } @objc private func closeButtonTapped() { - self.close(token: nil) + close(token: nil) } } diff --git a/p2p_wallet/UI/SwiftUI/ActionsPanel/ActionsPanelView.swift b/p2p_wallet/UI/SwiftUI/ActionsPanel/ActionsPanelView.swift index 34f16e516a..b02c6a384b 100644 --- a/p2p_wallet/UI/SwiftUI/ActionsPanel/ActionsPanelView.swift +++ b/p2p_wallet/UI/SwiftUI/ActionsPanel/ActionsPanelView.swift @@ -1,55 +1,7 @@ -// -// ActionsPanelView.swift -// p2p_wallet -// -// Created by Ivan on 31.10.2022. -// - import Combine import KeyAppUI import SwiftUI -struct ActionsPanelBridgeView: View { - let actionsPublisher: AnyPublisher<[WalletActionType], Never> - let balancePublisher: AnyPublisher - let usdAmountPublisher: AnyPublisher - let action: (WalletActionType) -> Void - - @State private var actions = [WalletActionType]() - @State private var balance = "" - @State private var usdAmount = "" - - init( - actionsPublisher: AnyPublisher<[WalletActionType], Never>, - balancePublisher: AnyPublisher, - usdAmountPublisher: AnyPublisher? = nil, - action: @escaping (WalletActionType) -> Void - ) { - self.actionsPublisher = actionsPublisher - self.balancePublisher = balancePublisher - self.usdAmountPublisher = usdAmountPublisher ?? Empty().eraseToAnyPublisher() - self.action = action - } - - var body: some View { - ActionsPanelView( - actions: actions, - balance: balance, - usdAmount: usdAmount, - action: action - ) - .onReceive(balancePublisher) { balance in - self.balance = balance - } - .onReceive(usdAmountPublisher) { usdAmount in - self.usdAmount = usdAmount - } - .onReceive(actionsPublisher) { actions in - self.actions = actions - } - } -} - struct ActionsPanelView: View { let actions: [WalletActionType] let balance: String From 2035406cfa00a21b9dacaa4f125dc9707852d220 Mon Sep 17 00:00:00 2001 From: Chung Tran Date: Tue, 18 Jul 2023 15:24:31 +0700 Subject: [PATCH 3/6] feat: remove unused structs --- .../Common/Coordinator/Coordinator.swift | 4 - .../Common/Coordinator/SmartCoordinator.swift | 33 ----- p2p_wallet/Common/Models/DApps/DApp.swift | 18 --- .../Models/DApps/DAppChannelError.swift | 19 --- .../NotificationService.swift | 16 +-- .../Services/PriceAPIs/PricesStorage.swift | 18 --- .../Scenes/Main/Buy/BuyViewModel.Models.swift | 11 -- p2p_wallet/Scenes/Main/Buy/BuyViewModel.swift | 32 ++--- ...istTransactionItem+ParsedTransaction.swift | 130 ------------------ .../DepositSolendViewModel.swift | 38 +++-- .../EthereumAccountDataSource.swift | 58 -------- p2p_wallet/Scenes/Main/Sell/Sell+Models.swift | 4 - .../SellTransactionDetailsCoordinator.swift | 8 +- .../Subviews/RecipientSearchField.swift | 61 +------- .../DeviceShareMigrationCoordinator.swift | 5 - .../ICloudRestoreViewModel.swift | 6 +- .../ReAuthSocialSignInViewModel.swift | 6 - p2p_wallet/UI/SwiftUI/DelayedGesture.swift | 68 --------- .../FocusedTexts/FocusedTextView.swift | 69 ---------- .../UI/SwiftUI/SearchBar/SearchBar.swift | 65 --------- .../SwiftUI/SheetView/CustomSheetView.swift | 31 ----- .../UI/SwiftUI/SheetView/SheetManager.swift | 37 ----- .../SwiftUI/SheetView/SheetViewModifier.swift | 27 ---- 23 files changed, 44 insertions(+), 720 deletions(-) delete mode 100644 p2p_wallet/Common/Models/DApps/DApp.swift delete mode 100644 p2p_wallet/Common/Models/DApps/DAppChannelError.swift delete mode 100644 p2p_wallet/Scenes/Main/History/New/Model/RendableListTransactionItem+ParsedTransaction.swift delete mode 100644 p2p_wallet/Scenes/Main/NewHome/Subview/AccountList/DataSource/EthereumAccountDataSource.swift delete mode 100644 p2p_wallet/UI/SwiftUI/FocusedTexts/FocusedTextView.swift delete mode 100644 p2p_wallet/UI/SwiftUI/SearchBar/SearchBar.swift delete mode 100644 p2p_wallet/UI/SwiftUI/SheetView/CustomSheetView.swift delete mode 100644 p2p_wallet/UI/SwiftUI/SheetView/SheetManager.swift delete mode 100644 p2p_wallet/UI/SwiftUI/SheetView/SheetViewModifier.swift diff --git a/p2p_wallet/Common/Coordinator/Coordinator.swift b/p2p_wallet/Common/Coordinator/Coordinator.swift index 65f1822c53..00e3a956fa 100644 --- a/p2p_wallet/Common/Coordinator/Coordinator.swift +++ b/p2p_wallet/Common/Coordinator/Coordinator.swift @@ -1,10 +1,6 @@ import Combine import Foundation -enum CoordinatorError: Error { - case isAlreadyStarted -} - @MainActor open class Coordinator: NSObject { // MARK: - Properties diff --git a/p2p_wallet/Common/Coordinator/SmartCoordinator.swift b/p2p_wallet/Common/Coordinator/SmartCoordinator.swift index a388fadcdb..2357377e73 100644 --- a/p2p_wallet/Common/Coordinator/SmartCoordinator.swift +++ b/p2p_wallet/Common/Coordinator/SmartCoordinator.swift @@ -58,39 +58,6 @@ class SmartCoordinatorPushPresentation: SmartCoordinatorPresentation { } } -class SmartCoordinatorBottomSheetPresentation: SmartCoordinatorPresentation { - var presentingViewController: UIViewController - - private var subscriptions = [AnyCancellable]() - private let transition: PanelTransition = .init() - private let height: CGFloat - - init(from currentPresentation: SmartCoordinatorPresentation, height: CGFloat) { - presentingViewController = currentPresentation.presentingViewController - self.height = height - } - - init(_ presentingViewController: UIViewController, height: CGFloat) { - self.presentingViewController = presentingViewController - self.height = height - } - - func run(presentedViewController: UIViewController) { - // Prepare - transition.containerHeight = height - transition.dimmClicked - .sink(receiveValue: { _ in presentedViewController.dismiss(animated: true) }) - .store(in: &subscriptions) - - presentedViewController.view.layer.cornerRadius = 16 - presentedViewController.transitioningDelegate = transition - presentedViewController.modalPresentationStyle = .custom - - // Presentation - presentingViewController.present(presentedViewController, animated: true) - } -} - class SmartCoordinator: Coordinator { let presentation: SmartCoordinatorPresentation diff --git a/p2p_wallet/Common/Models/DApps/DApp.swift b/p2p_wallet/Common/Models/DApps/DApp.swift deleted file mode 100644 index ca614fba79..0000000000 --- a/p2p_wallet/Common/Models/DApps/DApp.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// DApp.swift -// p2p_wallet -// -// Created by Chung Tran on 26/11/2021. -// - -import Foundation - -struct DApp { - let name: String - let description: String - let url: String - - static var fake: DApp { - .init(name: "Fake DApp", description: "A fake dapp", url: "https://web.beardict.net/dapp/") - } -} diff --git a/p2p_wallet/Common/Models/DApps/DAppChannelError.swift b/p2p_wallet/Common/Models/DApps/DAppChannelError.swift deleted file mode 100644 index 8567189d09..0000000000 --- a/p2p_wallet/Common/Models/DApps/DAppChannelError.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// DAppChannelError.swift -// p2p_wallet -// -// Created by Chung Tran on 26/11/2021. -// - -import Foundation - -enum DAppChannelError { - static var platformIsNotReady = Self.createError(code: 400, message: "Platform is not ready") - static var canNotFindWalletAddress = Self.createError(code: 400, message: "Can not find wallet address") - static var invalidTransaction = Self.createError(code: 400, message: "Invalid transactions") - static var unauthorized = Self.createError(code: 400, message: "Unauthorized") - - private static func createError(code: Int, message: String) -> NSError { - NSError(domain: "DAppChannel", code: code, userInfo: [NSLocalizedDescriptionKey: message]) - } -} diff --git a/p2p_wallet/Common/Services/NotificationsService/NotificationService.swift b/p2p_wallet/Common/Services/NotificationsService/NotificationService.swift index d49cbf995f..7f17a33745 100644 --- a/p2p_wallet/Common/Services/NotificationsService/NotificationService.swift +++ b/p2p_wallet/Common/Services/NotificationsService/NotificationService.swift @@ -1,14 +1,12 @@ import AnalyticsManager +import BEPureLayout +import Combine import Foundation import KeyAppUI import Resolver import UIKit -import Combine -import BEPureLayout protocol NotificationService { - typealias DeviceTokenResponse = JsonRpcResponseDto - func sendRegisteredDeviceToken(_ deviceToken: Data, ethAddress: String?) async throws func deleteDeviceToken(ethAddress: String?) async throws func showInAppNotification(_ notification: InAppNotification) @@ -71,7 +69,7 @@ final class NotificationServiceImpl: NSObject, NotificationService { func sendRegisteredDeviceToken(_ deviceToken: Data, ethAddress: String? = nil) async throws { guard let publicKey = accountStorage.account?.publicKey.base58EncodedString else { return } let token = deviceToken.formattedDeviceToken - + let result = try await notificationRepository.sendDeviceToken(model: .init( deviceToken: token, clientId: publicKey, @@ -82,7 +80,7 @@ final class NotificationServiceImpl: NSObject, NotificationService { deviceModel: UIDevice.current.model ) )) - + print(result) Defaults.lastDeviceToken = deviceToken @@ -117,7 +115,7 @@ final class NotificationServiceImpl: NSObject, NotificationService { title: title ?? "😓", text: text ?? L10n.SomethingWentWrong.pleaseTryAgain ) - .showInKeyWindow() + .showInKeyWindow() } } @@ -127,7 +125,7 @@ final class NotificationServiceImpl: NSObject, NotificationService { title: title ?? "😓", text: text ?? L10n.SomethingWentWrong.pleaseTryAgain ) - .showInKeyWindow(autoHide: withAutoHidden) + .showInKeyWindow(autoHide: withAutoHidden) } } @@ -156,7 +154,7 @@ final class NotificationServiceImpl: NSObject, NotificationService { title: "😓", text: L10n.SomethingWentWrong.pleaseTryAgain ) - .showInKeyWindow() + .showInKeyWindow() } } diff --git a/p2p_wallet/Common/Services/PriceAPIs/PricesStorage.swift b/p2p_wallet/Common/Services/PriceAPIs/PricesStorage.swift index 2a7e0c4398..f2fb53e8ed 100644 --- a/p2p_wallet/Common/Services/PriceAPIs/PricesStorage.swift +++ b/p2p_wallet/Common/Services/PriceAPIs/PricesStorage.swift @@ -24,21 +24,3 @@ actor InMemoryPricesStorage: PricesStorage { self.prices = prices } } - -actor UserDefaultsPricesStorage: PricesStorage { - func retrievePrices() -> TokenPriceMap { - var prices: TokenPriceMap = [:] - let data = Defaults.prices - if !data.isEmpty, - let cachedPrices = try? PropertyListDecoder().decode(TokenPriceMap.self, from: data) - { - prices = cachedPrices - } - return prices - } - - func savePrices(_ prices: TokenPriceMap) { - guard let data = try? PropertyListEncoder().encode(prices) else { return } - Defaults.prices = data - } -} diff --git a/p2p_wallet/Scenes/Main/Buy/BuyViewModel.Models.swift b/p2p_wallet/Scenes/Main/Buy/BuyViewModel.Models.swift index 62030fb9be..e7b1f38f3d 100644 --- a/p2p_wallet/Scenes/Main/Buy/BuyViewModel.Models.swift +++ b/p2p_wallet/Scenes/Main/Buy/BuyViewModel.Models.swift @@ -3,17 +3,6 @@ import SolanaSwift import UIKit extension BuyViewModel { - struct TotalResult { - var total: String - var totalCurrency: Fiat - var token: Token - var fiat: Fiat - var tokenAmount: String - var fiatAmmount: String - } - - // MARK: - - struct BuyForm: Equatable { var token: Token var tokenAmount: Double? diff --git a/p2p_wallet/Scenes/Main/Buy/BuyViewModel.swift b/p2p_wallet/Scenes/Main/Buy/BuyViewModel.swift index 90d02ee42e..c6146b9135 100644 --- a/p2p_wallet/Scenes/Main/Buy/BuyViewModel.swift +++ b/p2p_wallet/Scenes/Main/Buy/BuyViewModel.swift @@ -3,11 +3,11 @@ import AnalyticsManager import Combine import Foundation import KeyAppUI +import Moonpay import Resolver import SolanaSwift import SwiftyUserDefaults import UIKit -import Moonpay let MoonpayLicenseURL = "https://www.moonpay.com/legal/licenses" @@ -16,9 +16,6 @@ private extension String { } final class BuyViewModel: ObservableObject { - - typealias IpInfo = Moonpay.Provider.IpAddressResponse - var coordinatorIO = CoordinatorIO() // MARK: - To View @@ -75,7 +72,7 @@ final class BuyViewModel: ObservableObject { private static let tokens: [Token] = [.usdc, .nativeSolana] private static let fiats: [Fiat] = [.eur, .gbp, .usd] private static let defaultToken = Token.usdc - + // MARK: - Init init( @@ -245,10 +242,10 @@ final class BuyViewModel: ObservableObject { self.areMethodsLoading = false } } - + getBuyAvailability() } - + private func getBuyAvailability() { Task { let ipInfo = try await moonpayProvider.ipAddresses() @@ -261,14 +258,14 @@ final class BuyViewModel: ObservableObject { } } } - + private func setNewCountryInfo(flag: String, title: String, isBuyAllowed: Bool) { guard !title.isEmpty else { state = .usual self.flag = .neutralFlag return } - + if isBuyAllowed { state = .usual } else { @@ -283,15 +280,15 @@ final class BuyViewModel: ObservableObject { analyticsManager.log(event: .buyBlockedScreenOpen) } self.flag = flag - self.countryTitle = title + countryTitle = title } - + // MARK: - From View - + func goBackClicked() { coordinatorIO.close.send() } - + func changeTheRegionClicked() { coordinatorIO.chooseCountry.send(SelectCountryViewModel.Model( flag: flag, @@ -299,7 +296,7 @@ final class BuyViewModel: ObservableObject { )) analyticsManager.log(event: .buyBlockedRegionClick) } - + func flagClicked() { coordinatorIO.chooseCountry.send(SelectCountryViewModel.Model( flag: flag, @@ -307,7 +304,7 @@ final class BuyViewModel: ObservableObject { )) analyticsManager.log(event: .buyChangeCountryClick) } - + // MARK: - @MainActor func didSelectPayment(_ payment: PaymentTypeItem) { @@ -570,13 +567,12 @@ final class BuyViewModel: ObservableObject { return true } } - + func countrySelected(_ country: SelectCountryViewModel.Model, buyAllowed: Bool) { setNewCountryInfo(flag: country.flag, title: country.title, isBuyAllowed: buyAllowed) } struct CoordinatorIO { - // To Coordinator let showDetail = PassthroughSubject<( Buy.ExchangeOutput, @@ -588,7 +584,7 @@ final class BuyViewModel: ObservableObject { let showFiatSelect = PassthroughSubject<[Fiat], Never>() let navigationSlidingPercentage = PassthroughSubject() let chooseCountry = PassthroughSubject() - + // From Coordinator let tokenSelected = CurrentValueSubject(nil) let fiatSelected = CurrentValueSubject(nil) diff --git a/p2p_wallet/Scenes/Main/History/New/Model/RendableListTransactionItem+ParsedTransaction.swift b/p2p_wallet/Scenes/Main/History/New/Model/RendableListTransactionItem+ParsedTransaction.swift deleted file mode 100644 index 1ea48ffc53..0000000000 --- a/p2p_wallet/Scenes/Main/History/New/Model/RendableListTransactionItem+ParsedTransaction.swift +++ /dev/null @@ -1,130 +0,0 @@ -import Foundation -import Resolver -import SolanaPricesAPIs -import SolanaSwift -import TransactionParser -import UIKit - -struct RendableListParsedTransactionItem: RendableListTransactionItem { - let trx: ParsedTransaction - - let priceService: PricesService - - var onTap: (() -> Void)? - - var id: String { - trx.signature ?? "" - } - - var date: Date { - trx.blockTime ?? Date() - } - - var status: RendableListTransactionItemStatus { - switch trx.status { - case .requesting, .processing: - return .pending - case .confirmed: - return .success - case .error: - return .failed - } - } - - var icon: RendableListTransactionItemIcon { - if let info = trx.info as? SwapInfo { - if - let sourceImage = info.source?.token.logoURI, - let sourceURL = URL(string: sourceImage), - let destinationImage = info.destination?.token.logoURI, - let destinationURL = URL(string: destinationImage) - - { - return .double(sourceURL, destinationURL) - } - } else if let info = trx.info as? TransferInfo { - if - let sourceImage = info.source?.token.logoURI, - let sourceURL = URL(string: sourceImage) - { - return .single(sourceURL) - } - } else if trx.info is CloseAccountInfo { - return .icon(.closeToken) - } else if trx.info is CreateAccountInfo { - return .icon(.transactionCreateAccount) - } - - return .icon(.planet) - } - - var title: String { - if let info = trx.info as? SwapInfo { - return "\(info.source?.token.symbol ?? "") to \(info.destination?.token.symbol ?? "")" - } else if let info = trx.info as? TransferInfo { - switch info.transferType { - case .send: - return "To \(RecipientFormatter.shortFormat(destination: info.destination?.pubkey ?? ""))" - default: - return "From \(RecipientFormatter.shortFormat(destination: info.destination?.pubkey ?? ""))" - } - } else if trx.info is CloseAccountInfo { - return "Close account" - } else if trx.info is CreateAccountInfo { - return "Create account" - } - - return "Unknown" - } - - var subtitle: String { - if trx.info is SwapInfo { - return "Swap" - } else if trx.info is TransferInfo { - return "Send" - } else if let info = trx.info as? CloseAccountInfo { - return RecipientFormatter.format(destination: info.closedWallet?.pubkey ?? "") - } else if let info = trx.info as? CreateAccountInfo { - return RecipientFormatter.format(destination: info.newWallet?.pubkey ?? "") - } - - return "Signature: \(RecipientFormatter.shortSignature(signature: trx.signature ?? ""))" - } - - var detail: (RendableListTransactionItemChange, String) { -// var symbol: String? -// if let info = trx.info as? SwapInfo { -// symbol = info.symbol -// } else if let info = trx.info as? TransferInfo { -// symbol = info.symbol -// } -// -// if let symbol { -// let priceService: PricesService = Resolver.resolve() -// let price = priceService.getCurrentPrice(for: symbol) -// return (price ?? 0 * trx.amount).fiatAmountFormattedString(customFormattForLessThan1E_2: true) -// } - - return (.unchanged, "") - } - - var subdetail: String { - if let info = trx.info as? SwapInfo { - if let amount = info.destinationAmount { - let amountText = amount.tokenAmountFormattedString(symbol: info.source?.token.symbol ?? "") - return "\(amountText)" - } - } else if let info = trx.info as? TransferInfo { - if let amount = info.amount { - let amountText = amount.tokenAmountFormattedString(symbol: info.source?.token.symbol ?? "") - switch info.transferType { - case .send: - return "\(amountText)" - default: - return "+\(amountText)" - } - } - } - return "" - } -} diff --git a/p2p_wallet/Scenes/Main/InvestSolend/DepositWithdraw/DepositSolendViewModel.swift b/p2p_wallet/Scenes/Main/InvestSolend/DepositWithdraw/DepositSolendViewModel.swift index aca5641617..4d7b85ea8b 100644 --- a/p2p_wallet/Scenes/Main/InvestSolend/DepositWithdraw/DepositSolendViewModel.swift +++ b/p2p_wallet/Scenes/Main/InvestSolend/DepositWithdraw/DepositSolendViewModel.swift @@ -6,10 +6,6 @@ import Resolver import SolanaSwift import Solend -enum DepositSolendViewModelError { - case invalidFeePayer -} - @MainActor class DepositSolendViewModel: ObservableObject { private let strategy: Strategy @@ -297,45 +293,45 @@ class DepositSolendViewModel: ObservableObject { func processFee(fee: SolendFeePaying) { let mint = Token.solendSupportedTokens - .first(where: {$0.symbol == fee.symbol})? + .first(where: { $0.symbol == fee.symbol })? .address ?? "" - + // Fee let transferFee = Double(fee.fee.transaction) / pow(10, Double(fee.decimals)) - let fiatTransferFee: Double = transferFee * (self.priceService.currentPrice(mint: mint)?.value ?? 0) + let fiatTransferFee: Double = transferFee * (priceService.currentPrice(mint: mint)?.value ?? 0) let rentFee = Double(fee.fee.accountBalances) / pow(10, Double(fee.decimals)) - let fiatRentFee: Double = rentFee * (self.priceService.currentPrice(mint: mint)?.value ?? 0) + let fiatRentFee: Double = rentFee * (priceService.currentPrice(mint: mint)?.value ?? 0) // Total - var total: Lamports = self.inputLamport - var fiatTotal: Double = self.tokenToAmount(amount: self.amountFrom(lamports: total)) + var total: Lamports = inputLamport + var fiatTotal: Double = tokenToAmount(amount: amountFrom(lamports: total)) if invest.asset.symbol == fee.symbol { total = total + fee.fee.transaction + fee.fee.accountBalances - fiatTotal = self.tokenToAmount(amount: self.amountFrom(lamports: total)) + fiatTotal = tokenToAmount(amount: amountFrom(lamports: total)) } else { fiatTotal = fiatTotal + fiatTransferFee + fiatRentFee } // Text label - let tokenAmount = self.amountFrom(lamports: total) - let fiatAmount = self.tokenToAmount(amount: self.amountFrom(lamports: total)) - let amountText = tokenAmount.tokenAmountFormattedString(symbol: self.invest.asset.symbol) + " (" + fiatAmount - .fiatAmountFormattedString(currency: self.fiat) + ")" - self.feeText = "\(L10n.excludingFeesYouLlDeposit) \(amountText)" + let tokenAmount = amountFrom(lamports: total) + let fiatAmount = tokenToAmount(amount: amountFrom(lamports: total)) + let amountText = tokenAmount.tokenAmountFormattedString(symbol: invest.asset.symbol) + " (" + fiatAmount + .fiatAmountFormattedString(currency: fiat) + ")" + feeText = "\(L10n.excludingFeesYouLlDeposit) \(amountText)" - self.detailItem.send( + detailItem.send( .init( - amount: self.amountFrom(lamports: inputLamport), - fiatAmount: self.tokenToAmount(amount: self.amountFrom(lamports: inputLamport)), + amount: amountFrom(lamports: inputLamport), + fiatAmount: tokenToAmount(amount: amountFrom(lamports: inputLamport)), transferFee: transferFee, fiatTransferFee: fiatTransferFee, fee: rentFee, fiatFee: fiatRentFee, total: invest.asset.symbol == fee.symbol ? tokenAmount : nil, fiatTotal: fiatTotal, - symbol: self.invest.asset.symbol, + symbol: invest.asset.symbol, feeSymbol: fee.symbol ) ) @@ -499,7 +495,7 @@ class DepositSolendViewModel: ObservableObject { deposits .map { asset, market, userDeposit in let mint = Token.solendSupportedTokens - .first(where: {$0.symbol == userDeposit?.symbol})? + .first(where: { $0.symbol == userDeposit?.symbol })? .address ?? "" return TokenToWithdrawView.Model( amount: userDeposit?.depositedAmount.double, diff --git a/p2p_wallet/Scenes/Main/NewHome/Subview/AccountList/DataSource/EthereumAccountDataSource.swift b/p2p_wallet/Scenes/Main/NewHome/Subview/AccountList/DataSource/EthereumAccountDataSource.swift deleted file mode 100644 index daee29735a..0000000000 --- a/p2p_wallet/Scenes/Main/NewHome/Subview/AccountList/DataSource/EthereumAccountDataSource.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// EthereumAccountStore.swift -// p2p_wallet -// -// Created by Giang Long Tran on 17.03.2023. -// - -import Foundation -import KeyAppBusiness -import KeyAppKitCore -import Web3 -import Wormhole - -class EthereumAccountsDataSource: ObservableObject { - struct Account { - let account: EthereumAccount - let isClaiming: Bool - } - - // This function aggregates Ethereum accounts with their corresponding Wormhole bundle status - static func aggregate( - accounts: [EthereumAccount], - claimUserActions: [WormholeClaimUserAction] - ) -> [Account] { - accounts.map { account in - // Get the corresponding Wormhole bundle status for this Ethereum account - let bundleStatus: WormholeClaimUserAction? = claimUserActions - .filter { - switch $0.status { - case .pending, .processing: - return true - default: - return false - } - } - .first { userAction in - switch (account.token.contractType, userAction.token.contractType) { - case (.native, .native): - // If the account is for the native token, check if the bundle token is nil - return true - - case let (.erc20(lhsContract), .erc20(rhsContract)): - // Check matching erc-20 tokens - return lhsContract == rhsContract - - default: - // Other cases - return false - } - } - - return Account( - account: account, - isClaiming: bundleStatus != nil - ) - } - } -} diff --git a/p2p_wallet/Scenes/Main/Sell/Sell+Models.swift b/p2p_wallet/Scenes/Main/Sell/Sell+Models.swift index e3bd11cfca..7ff94eae1e 100644 --- a/p2p_wallet/Scenes/Main/Sell/Sell+Models.swift +++ b/p2p_wallet/Scenes/Main/Sell/Sell+Models.swift @@ -6,7 +6,3 @@ enum SellNavigation { case showPending(transactions: [SellDataServiceTransaction], fiat: any ProviderFiat) case moonpayInfo } - -enum SellError: Error { - case invalidURL -} diff --git a/p2p_wallet/Scenes/Main/Sell/TransactionDetails/SellTransactionDetailsCoordinator.swift b/p2p_wallet/Scenes/Main/Sell/TransactionDetails/SellTransactionDetailsCoordinator.swift index 6ba1319d14..f050443b9b 100644 --- a/p2p_wallet/Scenes/Main/Sell/TransactionDetails/SellTransactionDetailsCoordinator.swift +++ b/p2p_wallet/Scenes/Main/Sell/TransactionDetails/SellTransactionDetailsCoordinator.swift @@ -7,16 +7,14 @@ import Combine import Foundation -import UIKit import Resolver -import Sell import SafariServices - -private typealias Result = SellTransactionDetailsCoorditor.Result +import Sell +import UIKit final class SellTransactionDetailsCoorditor: Coordinator { @Injected private var walletsRepository: WalletsRepository - + private let viewController: UIViewController private let strategy: Strategy private let transaction: SellDataServiceTransaction diff --git a/p2p_wallet/Scenes/Main/Send/RecipentSearch/Subviews/RecipientSearchField.swift b/p2p_wallet/Scenes/Main/Send/RecipentSearch/Subviews/RecipientSearchField.swift index 10382c71be..406cbfd7bc 100644 --- a/p2p_wallet/Scenes/Main/Send/RecipentSearch/Subviews/RecipientSearchField.swift +++ b/p2p_wallet/Scenes/Main/Send/RecipentSearch/Subviews/RecipientSearchField.swift @@ -38,7 +38,7 @@ struct RecipientSearchField: View { .frame(width: 12, height: 12) } else if text.isEmpty { Button { past() } - label: { + label: { Image(uiImage: Asset.Icons.past.image) .resizable() .frame(width: 18, height: 18) @@ -47,7 +47,7 @@ struct RecipientSearchField: View { .accessibilityIdentifier("RecipientSearchField.paste") } else { Button { text = "" } - label: { + label: { Image(uiImage: .crossIcon) .resizable() .frame(width: 12, height: 12) @@ -81,63 +81,6 @@ struct RecipientSearchField: View { } } -private struct RecipientTextField: UIViewRepresentable { - @Binding private var isFirstResponder: Bool - @Binding private var text: String - - init(text: Binding, isFirstResponder: Binding) { - _text = text - _isFirstResponder = isFirstResponder - } - - func makeUIView(context: Context) -> UITextField { - let view = UITextField() - view.addTarget( - context.coordinator, - action: #selector(context.coordinator.textViewDidChange), - for: .editingChanged - ) - return view - } - - func updateUIView(_ uiView: UITextField, context _: Context) { - if uiView.text != text { - uiView.text = text - } - if uiView.isFirstResponder, !isFirstResponder { - DispatchQueue.main.async { uiView.resignFirstResponder() } - } else if !uiView.isFirstResponder, isFirstResponder { - DispatchQueue.main.async { uiView.becomeFirstResponder() } - } - } - - func makeCoordinator() -> Coordinator { - Coordinator($text, isFirstResponder: $isFirstResponder) - } - - class Coordinator: NSObject, UITextFieldDelegate { - var text: Binding - var isFirstResponder: Binding - - init(_ text: Binding, isFirstResponder: Binding) { - self.text = text - self.isFirstResponder = isFirstResponder - } - - @objc func textViewDidChange(_ textField: UITextField) { - text.wrappedValue = textField.text ?? "" - } - - func textFieldDidBeginEditing(_: UITextField) { - isFirstResponder.wrappedValue = true - } - - func textFieldDidEndEditing(_: UITextField) { - isFirstResponder.wrappedValue = false - } - } -} - struct RecipientSearchField_Previews: PreviewProvider { static var previews: some View { RecipientSearchField( diff --git a/p2p_wallet/Scenes/Web3Auth/DeviceShare/Migration/DeviceShareMigrationCoordinator.swift b/p2p_wallet/Scenes/Web3Auth/DeviceShare/Migration/DeviceShareMigrationCoordinator.swift index 50c656366b..f8975c40e2 100644 --- a/p2p_wallet/Scenes/Web3Auth/DeviceShare/Migration/DeviceShareMigrationCoordinator.swift +++ b/p2p_wallet/Scenes/Web3Auth/DeviceShare/Migration/DeviceShareMigrationCoordinator.swift @@ -17,11 +17,6 @@ enum DeviceShareMigrationCoordinatorResult { } final class DeviceShareMigrationCoordinator: Coordinator { - enum Result { - case finish - case error(Error) - } - let result = PassthroughSubject() let navigationController: UINavigationController diff --git a/p2p_wallet/Scenes/Web3Auth/Onboarding/RestoreWallet/Steps/ICloudRestore/ICloudRestore/ICloudRestoreViewModel.swift b/p2p_wallet/Scenes/Web3Auth/Onboarding/RestoreWallet/Steps/ICloudRestore/ICloudRestore/ICloudRestoreViewModel.swift index 6f23b9c7a9..e5c917e269 100644 --- a/p2p_wallet/Scenes/Web3Auth/Onboarding/RestoreWallet/Steps/ICloudRestore/ICloudRestore/ICloudRestoreViewModel.swift +++ b/p2p_wallet/Scenes/Web3Auth/Onboarding/RestoreWallet/Steps/ICloudRestore/ICloudRestore/ICloudRestoreViewModel.swift @@ -1,13 +1,9 @@ import Combine +import Foundation import Onboarding import Resolver -import Foundation final class ICloudRestoreViewModel: BaseICloudRestoreViewModel, ObservableObject { - // MARK: - Declarations - - typealias SeedPhrase = String - // MARK: - Output events let back: PassthroughSubject, Never> = .init() diff --git a/p2p_wallet/Scenes/Web3Auth/Reauthentication/SubFlow/SocialShare/ReAuthSocialSignInViewModel.swift b/p2p_wallet/Scenes/Web3Auth/Reauthentication/SubFlow/SocialShare/ReAuthSocialSignInViewModel.swift index 97f57ae2ff..eb7c5da911 100644 --- a/p2p_wallet/Scenes/Web3Auth/Reauthentication/SubFlow/SocialShare/ReAuthSocialSignInViewModel.swift +++ b/p2p_wallet/Scenes/Web3Auth/Reauthentication/SubFlow/SocialShare/ReAuthSocialSignInViewModel.swift @@ -40,9 +40,3 @@ class ReAuthSocialSignInViewModel: BaseViewModel, ObservableObject { onClose.send() } } - -extension ReAuthSocialSignInViewModel { - enum Action { - case onContinue - } -} diff --git a/p2p_wallet/UI/SwiftUI/DelayedGesture.swift b/p2p_wallet/UI/SwiftUI/DelayedGesture.swift index 02fceb690b..68046826d6 100644 --- a/p2p_wallet/UI/SwiftUI/DelayedGesture.swift +++ b/p2p_wallet/UI/SwiftUI/DelayedGesture.swift @@ -1,73 +1,5 @@ import SwiftUI -extension View { - /// Sequences a gesture with a long press and attaches the result to the view, - /// which results in the gesture only receiving events after the long press - /// succeeds. - /// - /// Use this view modifier *instead* of `.gesture` to delay a gesture: - /// - /// ScrollView { - /// FooView() - /// .delayedGesture(someGesture, delay: 0.2) - /// } - /// - /// - Parameters: - /// - gesture: A gesture to attach to the view. - /// - mask: A value that controls how adding this gesture to the view - /// affects other gestures recognized by the view and its subviews. - /// - delay: A value that controls the duration of the long press that - /// must elapse before the gesture can be recognized by the view. - /// - action: An action to perform if a tap gesture is recognized - /// before the long press can be recognized by the view. - public func delayedGesture(_ gesture: T, - including mask: GestureMask = .all, - delay: TimeInterval = 0.25, - onTapGesture action: @escaping () -> Void = {}) -> some View { - self.modifier(DelaysTouches(duration: delay, action: action)) - .gesture(gesture, including: mask) - } - - /// Attaches a long press gesture to the view, which results in gestures with a - /// lower precedence only receiving events after the long press succeeds. - /// - /// Use this view modifier *before* `.gesture` to delay a gesture: - /// - /// ScrollView { - /// FooView() - /// .delayedInput(delay: 0.2) - /// .gesture(someGesture) - /// } - /// - /// - Parameters: - /// - delay: A value that controls the duration of the long press that - /// must elapse before lower precedence gestures can be recognized by - /// the view. - /// - action: An action to perform if a tap gesture is recognized - /// before the long press can be recognized by the view. - public func delayedInput(delay: TimeInterval = 0.25, - onTapGesture action: @escaping () -> Void = {}) -> some View { - self.modifier(DelaysTouches(duration: delay, action: action)) - } -} - - -private struct DelaysTouches: ViewModifier { - @State private var disabled = false - @State private var touchDownDate: Date? = nil - - var duration: TimeInterval - var action: () -> Void - - func body(content: Content) -> some View { - Button(action: action) { - content - } - .buttonStyle(DelaysTouchesButtonStyle(disabled: $disabled, duration: duration, touchDownDate: $touchDownDate)) - .disabled(disabled) - } -} - private struct DelaysTouchesButtonStyle: ButtonStyle { @Binding var disabled: Bool var duration: TimeInterval diff --git a/p2p_wallet/UI/SwiftUI/FocusedTexts/FocusedTextView.swift b/p2p_wallet/UI/SwiftUI/FocusedTexts/FocusedTextView.swift deleted file mode 100644 index 6ea4127548..0000000000 --- a/p2p_wallet/UI/SwiftUI/FocusedTexts/FocusedTextView.swift +++ /dev/null @@ -1,69 +0,0 @@ -import SwiftUI -import UIKit - -struct FocusedTextView: UIViewRepresentable { - @Binding private var isFirstResponder: Bool - @Binding private var text: String - private var configuration = { (_: UITextView) in } - - init( - text: Binding, - isFirstResponder: Binding, - configuration: @escaping (UITextView) -> Void = { _ in } - ) { - self.configuration = configuration - _text = text - _isFirstResponder = isFirstResponder - } - - func makeUIView(context: Context) -> UITextView { - let view = UITextView() - view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) - view.delegate = context.coordinator - return view - } - - func updateUIView(_ uiView: UITextView, context _: Context) { - uiView.text = text - configuration(uiView) - if uiView.isFirstResponder, !isFirstResponder { - DispatchQueue.main.async { uiView.resignFirstResponder() } - } else if !uiView.isFirstResponder, isFirstResponder { - DispatchQueue.main.async { uiView.becomeFirstResponder() } - } - } - - func makeCoordinator() -> Coordinator { - Coordinator($text, isFirstResponder: $isFirstResponder) - } - - class Coordinator: NSObject, UITextViewDelegate { - var text: Binding - var isFirstResponder: Binding - - init(_ text: Binding, isFirstResponder: Binding) { - self.text = text - self.isFirstResponder = isFirstResponder - } - - @objc func textViewDidChange(_ textField: UITextView) { - text.wrappedValue = textField.text ?? "" - } - - func textViewDidBeginEditing(_: UITextView) { - isFirstResponder.wrappedValue = true - } - - func textViewDidEndEditing(_: UITextView) { - isFirstResponder.wrappedValue = false - } - - func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool { - if text == "\n", textView.returnKeyType == .done { - isFirstResponder.wrappedValue = false - return false - } - return true - } - } -} diff --git a/p2p_wallet/UI/SwiftUI/SearchBar/SearchBar.swift b/p2p_wallet/UI/SwiftUI/SearchBar/SearchBar.swift deleted file mode 100644 index 3d1f24038d..0000000000 --- a/p2p_wallet/UI/SwiftUI/SearchBar/SearchBar.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// SearchBar.swift -// p2p_wallet -// -// Created by Ivan on 14.04.2023. -// - -import SwiftUI -import KeyAppUI - -struct SearchBar: View { - let placeholder: String - @Binding var text: String - @Binding var isSearching: Bool - - var body: some View { - HStack { - TextField(placeholder, text: $text) - .padding(7) - .padding(.horizontal, 25) - .background(Color(._767680)) - .cornerRadius(8) - .overlay( - HStack { - Image(systemName: "magnifyingglass") - .foregroundColor(.gray) - .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) - .padding(.leading, 8) - - if isSearching { - Button( - action: { - text = "" - }, - label: { - Image(systemName: "multiply.circle.fill") - .foregroundColor(.gray) - .padding(.trailing, 8) - } - ) - } - } - ) - .padding(.horizontal, 10) - .onTapGesture { - isSearching = true - } - if isSearching { - Button( - action: { - isSearching = false - UIApplication.shared.endEditing() - text = "" - }, - label: { - Text(L10n.cancel) - } - ) - .padding(.trailing, 10) - .transition(.move(edge: .trailing)) - .animation(.default) - } - } - } -} diff --git a/p2p_wallet/UI/SwiftUI/SheetView/CustomSheetView.swift b/p2p_wallet/UI/SwiftUI/SheetView/CustomSheetView.swift deleted file mode 100644 index cbb64a1106..0000000000 --- a/p2p_wallet/UI/SwiftUI/SheetView/CustomSheetView.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// PopupView.swift -// p2p_wallet -// -// Created by Ivan on 01.10.2022. -// - -import SwiftUI - -struct CustomSheetView: View { - let headerState: HeaderState - let close: () -> Void - - var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) - .sheetHeader(title: L10n.depositToEarnAYield, close: close) - .frame(maxWidth: .infinity) - .background(RoundedCorners(color: .white, tl: 20, tr: 20)) - .transition(.move(edge: .bottom)) - .previewLayout(.sizeThatFits) - } -} - -// MARK: - Header - -extension CustomSheetView { - enum HeaderState { - case none - case visible(title: String, withSeparator: Bool = true) - } -} diff --git a/p2p_wallet/UI/SwiftUI/SheetView/SheetManager.swift b/p2p_wallet/UI/SwiftUI/SheetView/SheetManager.swift deleted file mode 100644 index 42e2d0c523..0000000000 --- a/p2p_wallet/UI/SwiftUI/SheetView/SheetManager.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// SheetManager.swift -// p2p_wallet -// -// Created by Ivan on 01.10.2022. -// - -import Foundation - -final class SheetManager: ObservableObject { - @Published private(set) var action: Action = .notAvailable - - static var shared = SheetManager() - - private init() {} - - func present() { - guard !action.presented else { return } - action = .present - } - - func dismiss() { - action = .dismiss - } -} - -// MARK: - Action - -extension SheetManager { - enum Action { - case notAvailable - case present - case dismiss - - var presented: Bool { self == .present } - } -} diff --git a/p2p_wallet/UI/SwiftUI/SheetView/SheetViewModifier.swift b/p2p_wallet/UI/SwiftUI/SheetView/SheetViewModifier.swift deleted file mode 100644 index 3f3481ae34..0000000000 --- a/p2p_wallet/UI/SwiftUI/SheetView/SheetViewModifier.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// SheetViewModifier.swift -// p2p_wallet -// -// Created by Ivan on 01.10.2022. -// - -import Foundation -import SwiftUI - -struct SheetViewModifier: ViewModifier { - @ObservedObject private var manager = SheetManager.shared - let headerState: CustomSheetView.HeaderState - - func body(content: Content) -> some View { - content -// .overlay { -// if manager.action == .present { -// CustomSheetView(headerState: headerState) { -// withAnimation(.spring()) { -// manager.dismiss() -// } -// } -// } -// } - } -} From 2bb99ad331c941066a5f4bb0f9b83dc8c70292bf Mon Sep 17 00:00:00 2001 From: Chung Tran Date: Tue, 18 Jul 2023 15:30:27 +0700 Subject: [PATCH 4/6] feat: remove unused structs --- .../Common/Extensions/View+Extensions.swift | 4 + .../Common/Services/SystemVersion.swift | 20 -- .../UI/SwiftUI/SwipeCell/SwipeCellSUI.swift | 318 ------------------ .../SwipeCell/SwipeCellSUI_Model.swift | 86 ----- 4 files changed, 4 insertions(+), 424 deletions(-) delete mode 100644 p2p_wallet/Common/Services/SystemVersion.swift delete mode 100644 p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI.swift delete mode 100644 p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI_Model.swift diff --git a/p2p_wallet/Common/Extensions/View+Extensions.swift b/p2p_wallet/Common/Extensions/View+Extensions.swift index 55ff928e3b..659ee18464 100644 --- a/p2p_wallet/Common/Extensions/View+Extensions.swift +++ b/p2p_wallet/Common/Extensions/View+Extensions.swift @@ -11,6 +11,10 @@ extension View { func uiView() -> UIView { asViewController().view } + + func castToAnyView() -> AnyView { + AnyView(self) + } } // MARK: - Font diff --git a/p2p_wallet/Common/Services/SystemVersion.swift b/p2p_wallet/Common/Services/SystemVersion.swift deleted file mode 100644 index c3ffe40ae2..0000000000 --- a/p2p_wallet/Common/Services/SystemVersion.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// SystemVersion.swift -// p2p_wallet -// -// Created by Chung Tran on 05/03/2021. -// - -import Foundation - -struct SystemVersion { - static func isIOS13() -> Bool { - let os = ProcessInfo().operatingSystemVersion - switch (os.majorVersion, os.minorVersion, os.patchVersion) { - case let (x, _, _) where x == 13: - return true - default: - return false - } - } -} diff --git a/p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI.swift b/p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI.swift deleted file mode 100644 index e6941da364..0000000000 --- a/p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI.swift +++ /dev/null @@ -1,318 +0,0 @@ -// -// SwipeCellSUI.swift -// p2p_wallet -// -// Created by Ivan on 20.08.2022. -// - -import Foundation -import SwiftUI - -public struct SwipeCellModifier: ViewModifier { - var id: String - var cellWidth: CGFloat = UIScreen.main.bounds.width - var leadingSideGroup: [SwipeCellActionItem] = [] - var trailingSideGroup: [SwipeCellActionItem] = [] - @Binding var currentUserInteractionCellID: String? - var settings: SwipeCellSettings = .init() - - @State private var offsetX: CGFloat = 0 - - let generator = UINotificationFeedbackGenerator() - @State private var hapticFeedbackOccurred: Bool = false - @State private var openSideLock: SwipeGroupSide? - - public func body(content: Content) -> some View { - ZStack { - if self.leadingSideGroup.isEmpty == false && self.offsetX != 0 { - self.swipeToRevealArea(swipeItemGroup: self.leadingSideGroup, side: .leading) - } - - if self.trailingSideGroup.isEmpty == false && self.offsetX != 0 { - self.swipeToRevealArea(swipeItemGroup: self.trailingSideGroup, side: .trailing) - } - - content - .offset(x: self.offsetX) - .gesture(DragGesture(minimumDistance: 30, coordinateSpace: .local) - .onChanged(self.dragOnChanged(value:)).onEnded(dragOnEnded(value:))) - - }.frame(width: cellWidth) - .edgesIgnoringSafeArea(.horizontal) - .clipped() - .onChange(of: currentUserInteractionCellID) { _ in - if let currentDragCellID = self.currentUserInteractionCellID, currentDragCellID != self.id, - self.openSideLock != nil - { - // if this cell has an open side area and is not the cell being dragged, close the cell - self.setOffsetX(value: 0) - // reset the drag cell id to nil - self.currentUserInteractionCellID = nil - } - } - } - - internal func swipeToRevealArea(swipeItemGroup: [SwipeCellActionItem], side: SwipeGroupSide) -> some View { - HStack { - if side == .trailing { - Spacer() - } - ZStack { -// swipeItem.backgroundColor.frame(width: self.revealAreaWidth(side: side)) - HStack(spacing: 0) { - ForEach(swipeItemGroup) { item in - - Button { - self.setOffsetX(value: 0) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - item.actionCallback() - } - } label: { - self.buttonContentView(item: item, group: swipeItemGroup, side: side) - }.buttonStyle(BorderlessButtonStyle()) - } - } - }.opacity(self.swipeRevealAreaOpacity(side: side)) - - if side == .leading { - Spacer() - } - } - } - - internal func buttonContentView(item: SwipeCellActionItem, group: [SwipeCellActionItem], - side: SwipeGroupSide) -> some View - { - ZStack { - item.backgroundColor - - HStack { - if self.warnSwipeOutCondition(side: side, hasSwipeOut: item.swipeOutAction) && item - .swipeOutButtonView != nil - { - item.swipeOutButtonView!() - } else { - item.buttonView() - } - } - - }.frame(width: itemButtonWidth(item: item, itemGroup: group, side: side)) - } - - internal func menuWidth(side: SwipeGroupSide) -> CGFloat { - switch side { - case .leading: - return leadingSideGroup.map(\.buttonWidth).reduce(0, +) - case .trailing: - return trailingSideGroup.map(\.buttonWidth).reduce(0, +) - } - } - - // MARK: drag gesture - - internal func dragOnChanged(value: DragGesture.Value) { - let horizontalTranslation = value.translation.width - if nonDraggableCondition(horizontalTranslation: horizontalTranslation) { - return - } - - if openSideLock != nil { - // if one side is open, we need to add the menu width! - let menuWidth = openSideLock == .leading ? self.menuWidth(side: .leading) : self - .menuWidth(side: .trailing) - offsetX = menuWidth * openSideLock!.sideFactor + horizontalTranslation - triggerHapticFeedbackIfNeeded(horizontalTranslation: horizontalTranslation) - return - } - - triggerHapticFeedbackIfNeeded(horizontalTranslation: horizontalTranslation) - - if horizontalTranslation > 8 || horizontalTranslation < - -8 - { // makes sure the swipe cell doesn't open too easily - currentUserInteractionCellID = id - offsetX = horizontalTranslation - } else { - offsetX = 0 - } - } - - internal func nonDraggableCondition(horizontalTranslation: CGFloat) -> Bool { - offsetX == 0 && - (leadingSideGroup.isEmpty && horizontalTranslation > 0 || trailingSideGroup - .isEmpty && horizontalTranslation < 0) - } - - internal func dragOnEnded(value _: DragGesture.Value) { - let swipeOutTriggerValue = cellWidth * settings.swipeOutTriggerRatio - - if offsetX == 0 { - openSideLock = nil - } else if offsetX > 0 { - if leadingSideGroup.isEmpty == false { - if offsetX < settings - .openTriggerValue || (openSideLock == .leading && offsetX < menuWidth(side: .leading) * 0.8) - { - setOffsetX(value: 0) - } else if let leftItem = leadingSideGroup.filter({ $0.swipeOutAction == true }).first, - offsetX.magnitude > swipeOutTriggerValue - { - swipeOutAction(item: leftItem, sideFactor: 1) - } else { - lockSideMenu(side: .leading) - } - - } else { - // leading group emtpy - setOffsetX(value: 0) - } - } else if offsetX < 0 { - if trailingSideGroup.isEmpty == false { - if offsetX.magnitude < settings - .openTriggerValue || (openSideLock == .trailing && offsetX > -menuWidth(side: .trailing) * 0.8) - { - setOffsetX(value: 0) - } else if let rightItem = trailingSideGroup.filter({ $0.swipeOutAction == true }).first, - offsetX.magnitude > swipeOutTriggerValue - { - swipeOutAction(item: rightItem, sideFactor: -1) - } else { - lockSideMenu(side: .trailing) - } - - } else { - // trailing group emtpy - setOffsetX(value: 0) - } - } - } - - internal func triggerHapticFeedbackIfNeeded(horizontalTranslation: CGFloat) { - let side: SwipeGroupSide = horizontalTranslation > 0 ? .leading : .trailing - let group = side == .leading ? leadingSideGroup : trailingSideGroup - // let triggerValue = self.cellWidth * self.settings.swipeOutTriggerRatio - let swipeOutActionCondition = warnSwipeOutCondition(side: side, hasSwipeOut: true) - if let item = swipeOutItemWithHapticFeedback(group: group), hapticFeedbackOccurred == false, - swipeOutActionCondition == true - { - generator.notificationOccurred(item.swipeOutHapticFeedbackType!) - hapticFeedbackOccurred = true - } - } - - internal func swipeOutItemWithHapticFeedback(group: [SwipeCellActionItem]) -> SwipeCellActionItem? { - if let item = group.filter({ $0.swipeOutAction == true }).first { - if item.swipeOutHapticFeedbackType != nil { - return item - } - } - return nil - } - - internal func swipeOutAction(item: SwipeCellActionItem, sideFactor: CGFloat) { - if item.swipeOutIsDestructive { - let swipeOutWidth = cellWidth + 10 - setOffsetX(value: swipeOutWidth * sideFactor) - openSideLock = nil - } else { - setOffsetX(value: 0) // open side lock set in function! - } - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - item.actionCallback() - } - } - - internal func lockSideMenu(side: SwipeGroupSide) { - setOffsetX(value: side.sideFactor * menuWidth(side: side)) - openSideLock = side - hapticFeedbackOccurred = false - } - - internal func setOffsetX(value: CGFloat) { - withAnimation(.spring()) { - self.offsetX = value - } - if offsetX == 0 { - openSideLock = nil - hapticFeedbackOccurred = false - } - } - - internal func itemButtonWidth(item: SwipeCellActionItem, itemGroup: [SwipeCellActionItem], - side: SwipeGroupSide) -> CGFloat - { - // let defaultWidth = (self.offsetX.magnitude + addWidthMargin) / CGFloat(itemGroup.count) - let dynamicButtonWidth = self.dynamicButtonWidth(item: item, itemCount: itemGroup.count, side: side) - let triggerValue = cellWidth * settings.swipeOutTriggerRatio - let swipeOutActionCondition = side == .leading ? offsetX > triggerValue : offsetX < -triggerValue - - if item.swipeOutAction, swipeOutActionCondition { - return offsetX.magnitude + settings.addWidthMargin - } else if swipeOutActionCondition, item.swipeOutAction == false, - itemGroup.contains(where: { $0.swipeOutAction == true }) - { - return 0 - } else { - return dynamicButtonWidth - } - } - - internal func dynamicButtonWidth(item: SwipeCellActionItem, itemCount _: Int, side: SwipeGroupSide) -> CGFloat { - let menuWidth = self.menuWidth(side: side) - return (offsetX.magnitude + settings.addWidthMargin) * (item.buttonWidth / menuWidth) - } - - internal func warnSwipeOutCondition(side: SwipeGroupSide, hasSwipeOut: Bool) -> Bool { - if hasSwipeOut == false { - return false - } - let triggerValue = cellWidth * settings.swipeOutTriggerRatio - return (side == .trailing && offsetX < -triggerValue) || (side == .leading && offsetX > triggerValue) - } - - internal func swipeRevealAreaOpacity(side: SwipeGroupSide) -> Double { - switch side { - case .leading: - - return offsetX > 5 ? 1 : 0 - case .trailing: - return offsetX < -5 ? 1 : 0 - } - } -} - -public extension View { - /// swipe cell modifier - /// - Parameters: - /// - id: the string id of this cell. The default value is a uuid string. If you want to set the currentUserInteractionCellID yourself, e.g. for tap to close functionality, you need to override this id value with your own cell id. - /// - cellWidth: the width of the content view - typically a cell or row in a list under which the swipe to reveal menu should appear. - /// - leadingSideGroup: the button group on the leading side that shall appear when the user swipes the cell to the right - /// - trailingSideGroup: the button group on the trailing side that shall appear when the user swipes the cell to the left - /// - currentUserInteractionCellID: a Binding of an optional UUID that should be set either in the view model of the parent view in which the cells appear or as a State variable into the parent view itself. Don't assign it a value! - /// - settings: settings. can be omitted in which case the settings struct default values apply. - /// - Returns: the modified view of the view that can be swiped. - func swipeCell( - id: String = UUID().uuidString, - cellWidth: CGFloat = UIScreen.main.bounds.width, - leadingSideGroup: [SwipeCellActionItem] = [], - trailingSideGroup: [SwipeCellActionItem] = [], - currentUserInteractionCellID: Binding, - settings: SwipeCellSettings = SwipeCellSettings() - ) -> some View { - modifier(SwipeCellModifier( - id: id, - cellWidth: cellWidth, - leadingSideGroup: leadingSideGroup, - trailingSideGroup: trailingSideGroup, - currentUserInteractionCellID: currentUserInteractionCellID, - settings: settings - )) - } -} - -public extension View { - func castToAnyView() -> AnyView { - AnyView(self) - } -} diff --git a/p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI_Model.swift b/p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI_Model.swift deleted file mode 100644 index ca33479067..0000000000 --- a/p2p_wallet/UI/SwiftUI/SwipeCell/SwipeCellSUI_Model.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// SwipeCellSUI_Model.swift -// p2p_wallet -// -// Created by Ivan on 20.08.2022. -// - -import Foundation -import SwiftUI - -public enum SwipeGroupSide { - case leading, trailing - - var sideFactor: CGFloat { - switch self { - case .leading: - return 1 - - case .trailing: - return -1 - } - } -} - -public struct SwipeCellActionItem: Identifiable { - public var id: String - public var buttonView: () -> AnyView - public var swipeOutButtonView: (() -> AnyView)? - public var buttonWidth: CGFloat - public var backgroundColor: Color - public var swipeOutAction: Bool - public var swipeOutHapticFeedbackType: UINotificationFeedbackGenerator.FeedbackType? - public var swipeOutIsDestructive: Bool - // public var swipeOutButtonViewScaleFactor: CGFloat - public var actionCallback: () -> Void - - /** - Initializer - - Parameter id: Required to identify each buttin in the side menu. Default is a random uuid string. - - Parameter buttonView: The view in the foreground of the menu button. Make sure to set a maximum frame height less than the cell height! - - Parameter swipeOutButtonView: Alternative button view that is displayed only when the offset during swipe is beyond the swipe out trigger value. - - Parameter buttonWidth: Width of the button. The the open side menu width is calculated from the sum of all button widths. Default is 75. - - Parameter backgroundColor: The background colour of the the menu button. - - Parameter swipeOutAction: A Boolean that determines if a swipe out action is activated or not. Default is false. - - Parameter swipeOutHapticFeedbackType: If a swipeOutAction is activated, a haptic feedback will occur after the swipe out threshold is passed. Default is nil. - - Parameter swipeOutIsDestructive: A Boolean that determines if the swipe out is destructive. If true, the content cell view will be "move out of sight" once the swipe out is triggered. - */ - public init( - id: String = UUID().uuidString, - buttonView: @escaping () -> AnyView, - swipeOutButtonView: (() -> AnyView)? = nil, - buttonWidth: CGFloat = 75, - backgroundColor: Color, - swipeOutAction: Bool = false, - swipeOutHapticFeedbackType: UINotificationFeedbackGenerator.FeedbackType? = nil, - swipeOutIsDestructive: Bool = true, - actionCallback: @escaping () -> Void - ) { - self.id = id - self.buttonView = buttonView - self.swipeOutButtonView = swipeOutButtonView - self.buttonWidth = buttonWidth - self.backgroundColor = backgroundColor - self.swipeOutAction = swipeOutAction - self.swipeOutHapticFeedbackType = swipeOutHapticFeedbackType - self.swipeOutIsDestructive = swipeOutIsDestructive - self.actionCallback = actionCallback - } -} - -/// Swipe Cell Settings -public struct SwipeCellSettings { - /// initializer - public init(openTriggerValue: CGFloat = 60, swipeOutTriggerRatio: CGFloat = 0.7, addWidthMargin: CGFloat = 5) { - self.openTriggerValue = openTriggerValue - self.swipeOutTriggerRatio = swipeOutTriggerRatio - self.addWidthMargin = addWidthMargin - } - - /// minimum horizontal translation value necessary to open the side menu - public var openTriggerValue: CGFloat - /// the ratio of the total cell width that triggers a swipe out action (provided one action has swipe out activated) - public var swipeOutTriggerRatio: CGFloat = 0.7 - /// An additional value to add to the open menu width. This is useful if the cell has rounded corners. - public var addWidthMargin: CGFloat = 5 -} From 7ce83fd0960854af8bf5c989ad3b232cb48d43eb Mon Sep 17 00:00:00 2001 From: Chung Tran Date: Tue, 18 Jul 2023 15:35:50 +0700 Subject: [PATCH 5/6] feat: remove unused types --- .../Model/SupportedTokenMode.swift | 14 ---- .../ViewModel/SwapSettingsViewModel.swift | 32 ++++----- .../Scenes/Username/ReserveNameHandler.swift | 10 --- .../RoundedCorners/RoundedCorners.swift | 68 ------------------- 4 files changed, 12 insertions(+), 112 deletions(-) delete mode 100644 p2p_wallet/Scenes/Main/SupportedTokens/Model/SupportedTokenMode.swift delete mode 100644 p2p_wallet/Scenes/Username/ReserveNameHandler.swift delete mode 100644 p2p_wallet/UI/SwiftUI/RoundedCorners/RoundedCorners.swift diff --git a/p2p_wallet/Scenes/Main/SupportedTokens/Model/SupportedTokenMode.swift b/p2p_wallet/Scenes/Main/SupportedTokens/Model/SupportedTokenMode.swift deleted file mode 100644 index 2af5a555e4..0000000000 --- a/p2p_wallet/Scenes/Main/SupportedTokens/Model/SupportedTokenMode.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// SupportedTokenMode.swift -// p2p_wallet -// -// Created by Giang Long Tran on 07.03.2023. -// - -import Foundation - -enum SupportedTokenMode { - case normal - case search - case empty -} diff --git a/p2p_wallet/Scenes/Main/Swap/SwapSettings/ViewModel/SwapSettingsViewModel.swift b/p2p_wallet/Scenes/Main/Swap/SwapSettings/ViewModel/SwapSettingsViewModel.swift index 5a453b516c..ee045235ea 100644 --- a/p2p_wallet/Scenes/Main/Swap/SwapSettings/ViewModel/SwapSettingsViewModel.swift +++ b/p2p_wallet/Scenes/Main/Swap/SwapSettings/ViewModel/SwapSettingsViewModel.swift @@ -1,19 +1,14 @@ -import Combine -import Resolver import AnalyticsManager -import Jupiter +import Combine import Foundation - -protocol SwapSettingsViewModelIO: AnyObject { - var rowTapped: AnyPublisher { get } -} +import Jupiter +import Resolver final class SwapSettingsViewModel: BaseViewModel, ObservableObject { - // MARK: - Dependencies @Injected private var analyticsManager: AnalyticsManager - + // MARK: - Published properties @Published var currentState: JupiterSwapState @@ -23,27 +18,26 @@ final class SwapSettingsViewModel: BaseViewModel, ObservableObject { log(slippage: selectedSlippage) } } - // MARK: - Properties private let stateMachine: JupiterSwapStateMachine private let rowTappedSubject = PassthroughSubject() - + var info: JupiterSwapStateInfo { currentState.info } - + var isLoading: Bool { currentState.isSettingsLoading } - + var isLoadingOrRouteNotNil: Bool { isLoading || (currentState.route != nil) } - + // MARK: - Initializer - + init(stateMachine: JupiterSwapStateMachine) { // capture state machine self.stateMachine = stateMachine @@ -52,7 +46,7 @@ final class SwapSettingsViewModel: BaseViewModel, ObservableObject { // copy selected slippage self.selectedSlippage = (Double(stateMachine.currentState.slippageBps) / 100) .rounded(decimals: 2) - + super.init() bind() } @@ -69,16 +63,14 @@ final class SwapSettingsViewModel: BaseViewModel, ObservableObject { } // MARK: - Actions - + func rowClicked(identifier: SwapSettingsView.RowIdentifier) { rowTappedSubject.send(identifier) log(fee: identifier) } } -// MARK: - SwapSettingsViewModelIO - -extension SwapSettingsViewModel: SwapSettingsViewModelIO { +extension SwapSettingsViewModel { var rowTapped: AnyPublisher { rowTappedSubject.eraseToAnyPublisher() } diff --git a/p2p_wallet/Scenes/Username/ReserveNameHandler.swift b/p2p_wallet/Scenes/Username/ReserveNameHandler.swift deleted file mode 100644 index a96a6fda07..0000000000 --- a/p2p_wallet/Scenes/Username/ReserveNameHandler.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// ReserveNameHandler.swift -// p2p_wallet -// -// Created by Andrew Vasiliev on 08.12.2021. -// - -protocol ReserveNameHandler: AnyObject { - func handleName(_ name: String?) -} diff --git a/p2p_wallet/UI/SwiftUI/RoundedCorners/RoundedCorners.swift b/p2p_wallet/UI/SwiftUI/RoundedCorners/RoundedCorners.swift deleted file mode 100644 index 17ae12cfb0..0000000000 --- a/p2p_wallet/UI/SwiftUI/RoundedCorners/RoundedCorners.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// RoundedCorners.swift -// p2p_wallet -// -// Created by Ivan on 01.10.2022. -// - -import SwiftUI - -struct RoundedCorners: View { - var color: Color = .blue - var tl: CGFloat = 0.0 - var tr: CGFloat = 0.0 - var bl: CGFloat = 0.0 - var br: CGFloat = 0.0 - - var body: some View { - GeometryReader { geometry in - Path { path in - - let w = geometry.size.width - let h = geometry.size.height - - // Make sure we do not exceed the size of the rectangle - let tr = min(min(self.tr, h / 2), w / 2) - let tl = min(min(self.tl, h / 2), w / 2) - let bl = min(min(self.bl, h / 2), w / 2) - let br = min(min(self.br, h / 2), w / 2) - - path.move(to: CGPoint(x: w / 2.0, y: 0)) - path.addLine(to: CGPoint(x: w - tr, y: 0)) - path.addArc( - center: CGPoint(x: w - tr, y: tr), - radius: tr, - startAngle: Angle(degrees: -90), - endAngle: Angle(degrees: 0), - clockwise: false - ) - path.addLine(to: CGPoint(x: w, y: h - br)) - path.addArc( - center: CGPoint(x: w - br, y: h - br), - radius: br, - startAngle: Angle(degrees: 0), - endAngle: Angle(degrees: 90), - clockwise: false - ) - path.addLine(to: CGPoint(x: bl, y: h)) - path.addArc( - center: CGPoint(x: bl, y: h - bl), - radius: bl, - startAngle: Angle(degrees: 90), - endAngle: Angle(degrees: 180), - clockwise: false - ) - path.addLine(to: CGPoint(x: 0, y: tl)) - path.addArc( - center: CGPoint(x: tl, y: tl), - radius: tl, - startAngle: Angle(degrees: 180), - endAngle: Angle(degrees: 270), - clockwise: false - ) - path.closeSubpath() - } - .fill(self.color) - } - } -} From 89331899269a04af00624e67d28953d300beceeb Mon Sep 17 00:00:00 2001 From: Chung Tran Date: Tue, 18 Jul 2023 15:43:08 +0700 Subject: [PATCH 6/6] feat: add file back --- .../xcshareddata/swiftpm/Package.resolved | 482 ++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..e0f671b275 --- /dev/null +++ b/p2p_wallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,482 @@ +{ + "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "bfc0b6f81adc06ce5121eb23f628473638d67c5c", + "version" : "1.2022062300.0" + } + }, + { + "identity" : "amplitude-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/amplitude/Amplitude-iOS.git", + "state" : { + "revision" : "94160a550835e6f0a1df9fa76ab3902ac4648a9c", + "version" : "8.17.1" + } + }, + { + "identity" : "analytics-connector-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/amplitude/analytics-connector-ios.git", + "state" : { + "revision" : "d2f3ec4b022211a67d5d4509135d84359f7f8b8d", + "version" : "1.0.2" + } + }, + { + "identity" : "appauth-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/openid/AppAuth-iOS.git", + "state" : { + "revision" : "71cde449f13d453227e687458144bde372d30fc7", + "version" : "1.6.2" + } + }, + { + "identity" : "appsflyerframework", + "kind" : "remoteSourceControl", + "location" : "https://github.com/AppsFlyerSDK/AppsFlyerFramework", + "state" : { + "revision" : "a8e607ae6fc19b1e26f440cadf0dac28fd4c81ac", + "version" : "6.12.0" + } + }, + { + "identity" : "bepurelayout", + "kind" : "remoteSourceControl", + "location" : "https://github.com/p2p-org/BEPureLayout.git", + "state" : { + "branch" : "master", + "revision" : "9b4ab977660c8554d23a2d9b83b6ac6c6058b3b7" + } + }, + { + "identity" : "bigdecimal", + "kind" : "remoteSourceControl", + "location" : "https://github.com/p2p-org/BigDecimal.git", + "state" : { + "branch" : "main", + "revision" : "04d17040e4615fbfda3a882b9881f6841f4bf557" + } + }, + { + "identity" : "bigint", + "kind" : "remoteSourceControl", + "location" : "https://github.com/attaswift/BigInt.git", + "state" : { + "revision" : "0ed110f7555c34ff468e72e1686e59721f2b0da6", + "version" : "5.3.0" + } + }, + { + "identity" : "cryptoswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", + "state" : { + "revision" : "32f641cf24fc7abc1c591a2025e9f2f572648b0f", + "version" : "1.7.2" + } + }, + { + "identity" : "down", + "kind" : "remoteSourceControl", + "location" : "https://github.com/p2p-org/Down.git", + "state" : { + "branch" : "master", + "revision" : "eee1d66d7ef71b892e72c8bc8d84fcdfeaab1918" + } + }, + { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk.git", + "state" : { + "revision" : "a580250a9ff49ec38da5430cef20f88ddc831db2", + "version" : "10.12.0" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "0a226a8c50494c4cb877fbde27ab6374520a3354", + "version" : "10.12.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "98a00258d4518b7521253a70b7f70bb76d2120fe", + "version" : "9.2.4" + } + }, + { + "identity" : "googlesignin-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleSignIn-iOS", + "state" : { + "revision" : "9c9b36af86a4dd3da16048a36cf37351e63ccfe1", + "version" : "6.2.4" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "58d03d22beae762eaddbd30cb5a61af90d4b309f", + "version" : "7.11.3" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "f1b366129d1125be7db83247e003fc333104b569", + "version" : "1.50.2" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "5ccda3981422a84186387dbb763ba739178b529c", + "version" : "2.3.0" + } + }, + { + "identity" : "gtmappauth", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GTMAppAuth.git", + "state" : { + "revision" : "6dee0cde8a1b223737a5159e55e6b4ec16bbbdd9", + "version" : "1.3.1" + } + }, + { + "identity" : "intercom-ios-sp", + "kind" : "remoteSourceControl", + "location" : "https://github.com/intercom/intercom-ios-sp", + "state" : { + "revision" : "1031655ceb49a8c8975b0cb138fe3bed897d159e", + "version" : "15.0.3" + } + }, + { + "identity" : "jazziconswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/p2p-org/JazziconSwift.git", + "state" : { + "branch" : "master", + "revision" : "f9c9f898402db4e62d482f4c90670652c221fa12" + } + }, + { + "identity" : "keychain-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/evgenyneu/keychain-swift.git", + "state" : { + "revision" : "96fb84f45a96630e7583903bd7e08cf095c7a7ef", + "version" : "19.0.0" + } + }, + { + "identity" : "kingfisher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/onevcat/Kingfisher.git", + "state" : { + "revision" : "c1f60c63f356d364f4284ba82961acbe7de79bcc", + "version" : "7.8.1" + } + }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "0706abcc6b0bd9cedfbb015ba840e4a780b5159b", + "version" : "1.22.2" + } + }, + { + "identity" : "loggerswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/bigearsenal/LoggerSwift.git", + "state" : { + "branch" : "master", + "revision" : "8c4ecd6f97b667800a817481e472edd0c0460687" + } + }, + { + "identity" : "lokalise-ios-framework", + "kind" : "remoteSourceControl", + "location" : "https://github.com/lokalise/lokalise-ios-framework.git", + "state" : { + "revision" : "5bbc9ce346575266f96df271e4702c4a6fa57819", + "version" : "0.10.2" + } + }, + { + "identity" : "lottie-spm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/airbnb/lottie-spm.git", + "state" : { + "revision" : "c3852816c622ad35a03ed39c187c1644ece2382b", + "version" : "4.1.3" + } + }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", + "version" : "2.30909.0" + } + }, + { + "identity" : "phonenumberkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/marmelroy/PhoneNumberKit.git", + "state" : { + "revision" : "9bc965a326df8d5115f0b7bb77f09c542b8ec417", + "version" : "3.6.6" + } + }, + { + "identity" : "promisekit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mxcl/PromiseKit.git", + "state" : { + "revision" : "8a98e31a47854d3180882c8068cc4d9381bf382d", + "version" : "6.22.1" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "ec957ccddbcc710ccc64c9dcbd4c7006fcf8b73a", + "version" : "2.2.0" + } + }, + { + "identity" : "purelayout", + "kind" : "remoteSourceControl", + "location" : "https://github.com/PureLayout/PureLayout.git", + "state" : { + "revision" : "3bcbfe370f85b81254de4d6b9df3dd4a70d4ca89", + "version" : "3.1.8" + } + }, + { + "identity" : "reachability.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ashleymills/Reachability.swift.git", + "state" : { + "revision" : "c01bbdf2d633cf049ae1ed1a68a2020a8bda32e2", + "version" : "5.1.0" + } + }, + { + "identity" : "resolver", + "kind" : "remoteSourceControl", + "location" : "https://github.com/hmlongco/Resolver.git", + "state" : { + "revision" : "97de0b0320036607564af4a60025b48f8d041221", + "version" : "1.5.0" + } + }, + { + "identity" : "secp256k1.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Boilertalk/secp256k1.swift.git", + "state" : { + "revision" : "cd187c632fb812fd93711a9f7e644adb7e5f97f0", + "version" : "0.1.7" + } + }, + { + "identity" : "sentry-cocoa", + "kind" : "remoteSourceControl", + "location" : "https://github.com/getsentry/sentry-cocoa", + "state" : { + "revision" : "cf43eac1aa12017868c257ad3854ad87a5de0758", + "version" : "7.31.5" + } + }, + { + "identity" : "skeletonui", + "kind" : "remoteSourceControl", + "location" : "https://github.com/p2p-org/SkeletonUI.git", + "state" : { + "branch" : "master", + "revision" : "98225dbb0459477dfeac063e1c7d0750102325d1" + } + }, + { + "identity" : "skeletonview", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Juanpe/SkeletonView.git", + "state" : { + "revision" : "739a4f5d78731bebc48811c75fa9e1f4c4cef23e", + "version" : "1.30.4" + } + }, + { + "identity" : "solana-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/p2p-org/solana-swift", + "state" : { + "branch" : "v3.1", + "revision" : "39c0c632c017b731aea6f4e4ca1b90decdcd4937" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "6c89474e62719ddcc1e9614989fff2f68208fe10", + "version" : "1.1.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2", + "version" : "1.0.4" + } + }, + { + "identity" : "swift-nio", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio.git", + "state" : { + "revision" : "5f542894dd8efbd766d8adf73ef2f947b0cd5e21", + "version" : "2.56.0" + } + }, + { + "identity" : "swift-nio-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-extras.git", + "state" : { + "revision" : "0e0d0aab665ff1a0659ce75ac003081f2b1c8997", + "version" : "1.19.0" + } + }, + { + "identity" : "swift-nio-ssl", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-ssl.git", + "state" : { + "revision" : "e866a626e105042a6a72a870c88b4c531ba05f83", + "version" : "2.24.0" + } + }, + { + "identity" : "swift-nio-transport-services", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-transport-services.git", + "state" : { + "revision" : "41f4098903878418537020075a4d8a6e20a0b182", + "version" : "1.17.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics.git", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "f25867a208f459d3c5a06935dceb9083b11cd539", + "version" : "1.22.0" + } + }, + { + "identity" : "swift-snapshot-testing", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-snapshot-testing", + "state" : { + "revision" : "dc46eeb3928a75390651fac6c1ef7f93ad59a73b", + "version" : "1.11.1" + } + }, + { + "identity" : "swiftui-introspect", + "kind" : "remoteSourceControl", + "location" : "https://github.com/siteline/SwiftUI-Introspect.git", + "state" : { + "revision" : "f2616860a41f9d9932da412a8978fec79c06fe24", + "version" : "0.1.4" + } + }, + { + "identity" : "swiftyuserdefaults", + "kind" : "remoteSourceControl", + "location" : "https://github.com/sunshinejr/SwiftyUserDefaults.git", + "state" : { + "revision" : "f66bcd04088582c8fbb5cb8554d577e303bae396", + "version" : "5.3.0" + } + }, + { + "identity" : "task-retrying-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/bigearsenal/task-retrying-swift.git", + "state" : { + "branch" : "master", + "revision" : "208f1e8dfa93022a7d39ab5b334d5f43a934d4b1" + } + }, + { + "identity" : "tweetnacl-swiftwrap", + "kind" : "remoteSourceControl", + "location" : "https://github.com/bitmark-inc/tweetnacl-swiftwrap.git", + "state" : { + "revision" : "f8fd111642bf2336b11ef9ea828510693106e954", + "version" : "1.1.0" + } + }, + { + "identity" : "web3.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Boilertalk/Web3.swift.git", + "state" : { + "revision" : "4647a88ef5a85d92963512e0f7ebc78a66b6d850", + "version" : "0.8.3" + } + }, + { + "identity" : "websocket-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/websocket-kit", + "state" : { + "revision" : "53fe0639a98903858d0196b699720decb42aee7b", + "version" : "2.14.0" + } + } + ], + "version" : 2 +}