Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add submitting and loading states for submission button
Browse files Browse the repository at this point in the history
mike-dydx committed Sep 13, 2024
1 parent 9282ce3 commit b87979c
Showing 10 changed files with 225 additions and 127 deletions.
4 changes: 4 additions & 0 deletions PlatformParticles/PlatformParticles.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
0271236928E545A50015D39F /* SwiftMessages in Frameworks */ = {isa = PBXBuildFile; productRef = 0271236828E545A50015D39F /* SwiftMessages */; };
27897DA02C93EA2800196F21 /* DismissPresentedAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27897D922C93EA2800196F21 /* DismissPresentedAction.swift */; };
27ED353A2AD5BD0900C159F5 /* BannerErrorAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27ED35392AD5BD0900C159F5 /* BannerErrorAlert.swift */; };
3101F9C52511303E00AC4010 /* ConfirmAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3101F9C42511303E00AC4010 /* ConfirmAction.swift */; };
3101F9C62511303E00AC4010 /* ConfirmAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3101F9C42511303E00AC4010 /* ConfirmAction.swift */; };
@@ -634,6 +635,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
27897D922C93EA2800196F21 /* DismissPresentedAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DismissPresentedAction.swift; sourceTree = "<group>"; };
27ED35392AD5BD0900C159F5 /* BannerErrorAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannerErrorAlert.swift; sourceTree = "<group>"; };
3101F9C42511303E00AC4010 /* ConfirmAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmAction.swift; sourceTree = "<group>"; };
3101F9C92511308E00AC4010 /* AuthLoginPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthLoginPresenter.swift; sourceTree = "<group>"; };
@@ -1168,6 +1170,7 @@
314B5FA223DCCE2800139EB3 /* ConfirmationAction.swift */,
3101F9C42511303E00AC4010 /* ConfirmAction.swift */,
3180B04E272B509400CCAB67 /* DismissAction.swift */,
27897D922C93EA2800196F21 /* DismissPresentedAction.swift */,
64AF47822817123C00EBFDC6 /* SafariAction.swift */,
);
path = _Actions;
@@ -2346,6 +2349,7 @@
3128DDF026B89CE80099B62E /* LikedTableViewListPresenter.swift in Sources */,
314B604D23DCCE2900139EB3 /* ListPresenterManager.swift in Sources */,
314B5FD123DCCE2900139EB3 /* PrivacyPermissionPresenter.swift in Sources */,
27897DA02C93EA2800196F21 /* DismissPresentedAction.swift in Sources */,
314B5FE323DCCE2900139EB3 /* ObjectPresenterCollectionViewCell.swift in Sources */,
314B5FE123DCCE2900139EB3 /* UIView+Xib.swift in Sources */,
3101F9C52511303E00AC4010 /* ConfirmAction.swift in Sources */,
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// DismissPresentedAction.swift
// PlatformParticles
//
// Created by Mike Maguire on 9/15/24.
// Copyright © 2024 dYdX. All rights reserved.
//

import ParticlesKit
import RoutingKit
import Utilities

public class DismissPresentedActionBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
let action = DismissPresentedAction()
return action as? T
}
}

private class DismissPresentedAction: NSObject, NavigableProtocol {
@objc open func navigate(to request: RoutingRequest?, animated: Bool, completion: RoutingCompletionBlock?) {
if request?.path == "/action/dismiss_presented" {
let viewController = UIViewController.topmost()
if viewController?.presentingViewController !== nil {
viewController?.dismiss(animated: true, completion: {
completion?(nil, true)
})
}
} else {
completion?(nil, false)
}
}
}
Original file line number Diff line number Diff line change
@@ -60,6 +60,9 @@
"/action/dismiss": {
"destination":"PlatformParticles.DismissActionBuilder"
},
"/action/dismiss_presented": {
"destination":"PlatformParticles.DismissPresentedActionBuilder"
},
"/action/order/cancel": {
"destination":"dydxPresenters.dydxCancelOrderActionBuilder"
},
Original file line number Diff line number Diff line change
@@ -29,11 +29,12 @@ private class dydxVaultDepositWithdrawConfirmationViewController: HostingViewCon

override public func arrive(to request: RoutingRequest?, animated: Bool) -> Bool {
let presenter = presenter as? dydxVaultDepositWithdrawConfirmationViewPresenterProtocol
presenter?.viewModel?.amount = request?.params?["amount"] as? Double
if request?.path == "/vault/deposit_confirm" {
presenter?.transferType = .deposit
presenter?.viewModel?.transferType = .deposit
return true
} else if request?.path == "/vault/withdraw_confirm" {
presenter?.transferType = .withdraw
presenter?.viewModel?.transferType = .withdraw
return true
} else {
return false
@@ -43,49 +44,52 @@ private class dydxVaultDepositWithdrawConfirmationViewController: HostingViewCon

private protocol dydxVaultDepositWithdrawConfirmationViewPresenterProtocol: HostedViewPresenterProtocol {
var viewModel: dydxVaultDepositWithdrawConfirmationViewModel? { get }
var transferType: VaultTransferType { get set }
}

private class dydxVaultDepositWithdrawConfirmationViewPresenter: HostedViewPresenter<dydxVaultDepositWithdrawConfirmationViewModel>, dydxVaultDepositWithdrawConfirmationViewPresenterProtocol {
var transferType: VaultTransferType = .deposit {
didSet {
viewModel?.transferType = transferType
}
}

static let slippageAcknowledgementThreshold = 1
static let slippageAcknowledgementThreshold = 1.0

override init() {

super.init()
self.viewModel = dydxVaultDepositWithdrawConfirmationViewModel(faqUrl: AbacusStateManager.shared.environment?.links?.vaultLearnMore ?? "")
}

let viewModel = dydxVaultDepositWithdrawConfirmationViewModel(transferType: transferType)
override func start() {
super.start()

guard let viewModel = viewModel else { return }

viewModel.slippage = 4.20

if transferType == .deposit {
viewModel.submitState = .enabled
} else {
viewModel.submitState = .loading
//TO-DO replace fetch slippage and update view model
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
guard let self = self else { return }
let requiresAcknowledgeHighSlippage = transferType == .withdraw && Double.random(in: 0...1.5) > Self.slippageAcknowledgementThreshold // replace random with actual slippage
viewModel.requiresAcknowledgeHighSlippage = requiresAcknowledgeHighSlippage
if requiresAcknowledgeHighSlippage && !viewModel.hasAcknowledgedHighSlippage {
self.viewModel?.submitState = .disabled
} else {
self.viewModel?.submitState = .enabled
viewModel.$transferType
.sink {[weak self] transferType in
switch transferType {
case .deposit:
viewModel.submitState = .enabled
case .withdraw:
viewModel.submitState = .loading
//TO-DO replace fetch slippage and update view model
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
guard let self = self else { return }
let requiresAcknowledgeHighSlippage = transferType == .withdraw && Double.random(in: 0...1.5) > Self.slippageAcknowledgementThreshold // replace random with actual slippage
viewModel.requiresAcknowledgeHighSlippage = requiresAcknowledgeHighSlippage
if requiresAcknowledgeHighSlippage && !viewModel.hasAcknowledgedHighSlippage {
self.viewModel?.submitState = .disabled
} else {
self.viewModel?.submitState = .enabled
}
}
}
}
}
.store(in: &subscriptions)

// handle slippage toggling
viewModel.$hasAcknowledgedHighSlippage
.sink {[weak self] hasAcknowledged in
guard let self = self else { return }
switch self.viewModel.submitState {
guard let viewModel = self?.viewModel, viewModel.requiresAcknowledgeHighSlippage else { return }
switch viewModel.submitState {
case .enabled, .disabled:
self.viewModel?.submitState = hasAcknowledged ? .enabled : .disabled
self.viewModel?.submitState = hasAcknowledged ? .enabled : .disabled
viewModel.submitState = hasAcknowledged ? .enabled : .disabled
case .submitting, .loading:
return
}
@@ -104,31 +108,22 @@ private class dydxVaultDepositWithdrawConfirmationViewPresenter: HostedViewPrese
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
if Int.random(in: 1...6) == 1 {
// success
Router.shared?.navigate(to: RoutingRequest(path: "/action/dismiss"), animated: true, completion: nil)
Router.shared?.navigate(to: RoutingRequest(path: "/action/dismiss_presented"), animated: true, completion: nil)
} else {
// failure
self?.viewModel?.isFirstSubmission = false
self?.viewModel?.submitState = .enabled
}
}
}

TODO: replace
viewModel.elevatedSlippageAmount = 4.20
viewModel.requiresAcknowledgeHighSlippage = true

self.viewModel = viewModel
}

override func start() {
super.start()


// TODO: replace with real hooks from abacus
update()
}

// TODO: replace with real data from abacus
func update() {
guard let viewModel = viewModel else { return }
let crossFreeCollateralReceiptItem = dydxReceiptChangeItemView(title: DataLocalizer.localize(path: "APP.GENERAL.CROSS_FREE_COLLATERAL"),
value: AmountChangeModel(before: AmountTextModel(amount: 30.01),
after: AmountTextModel(amount: 30.02)))
@@ -145,11 +140,11 @@ private class dydxVaultDepositWithdrawConfirmationViewPresenter: HostedViewPrese
value: AmountChangeModel(before: AmountTextModel(amount: 30.01),
after: AmountTextModel(amount: 30.02)))

switch transferType {
switch viewModel.transferType {
case .deposit:
viewModel?.receiptItems = [crossFreeCollateralReceiptItem, crossMarginUsageItem, yourVaultBalanceReceiptItem]
viewModel.receiptItems = [crossFreeCollateralReceiptItem, crossMarginUsageItem, yourVaultBalanceReceiptItem]
case .withdraw:
viewModel?.receiptItems = [crossFreeCollateralReceiptItem, yourVaultBalanceReceiptItem, estSlippageReceiptItem, expectedAmountReceivedItem]
viewModel.receiptItems = [crossFreeCollateralReceiptItem, yourVaultBalanceReceiptItem, estSlippageReceiptItem, expectedAmountReceivedItem]
}
}
}
Loading

0 comments on commit b87979c

Please sign in to comment.