Skip to content

Commit

Permalink
MOB-493 iOS - Adjust margin screen for isolated margin UI (#162)
Browse files Browse the repository at this point in the history
* MOB-483 Add isolated / cross margin mode button, Add target leverage button

* MOB-357 Margin Mode Selection Screen

* WIP

* MOB-359 Target Leverage Selection Screen

* MOB-493 Adjust margin screen for isolated margin UI
  • Loading branch information
ruixhuang authored May 10, 2024
1 parent 9274f6a commit 50f77bc
Show file tree
Hide file tree
Showing 20 changed files with 1,016 additions and 15 deletions.
11 changes: 5 additions & 6 deletions PlatformUI/PlatformUI/Components/TabGroup/TabItemViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ public class TabItemViewModel: PlatformViewModel, Equatable {
}

public enum TabItemContent: Equatable {
case text(String)
case text(String, EdgeInsets = EdgeInsets(top: 6, leading: 8, bottom: 6, trailing: 8))
case icon(UIImage)
case bar(PlatformViewModel)

public static func ==(lhs: TabItemContent, rhs: TabItemContent) -> Bool {
switch (lhs, rhs) {
case let (.text(leftText), .text(rightText)):
return leftText == rightText
case let (.text(leftText, leftInsets), .text(rightText, rightInsets)):
return leftText == rightText && leftInsets == rightInsets
case let (.icon(leftImage), .icon(rightImage)):
return leftImage.isEqual(rightImage)
default:
Expand Down Expand Up @@ -53,11 +53,10 @@ public class TabItemViewModel: PlatformViewModel, Equatable {
let templateColor: ThemeColor.SemanticColor = self.isSelected ? .textPrimary: .textTertiary
let borderWidth: CGFloat = 1
switch value {
case .text(let value):
case .text(let value, let edgeInsets):
return Text(value)
.themeFont(fontSize: .small)
.padding([.bottom, .top], 6)
.padding([.leading, .trailing], 8)
.padding(edgeInsets)
.themeStyle(styleKey: styleKey, parentStyle: style)
.borderAndClip(style: .capsule, borderColor: .layer6, lineWidth: borderWidth)
.wrappedInAnyView()
Expand Down
8 changes: 8 additions & 0 deletions dydx/dydxPresenters/dydxPresenters.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
0279656A29D795E8004DEB20 /* tabs_v4.json in Resources */ = {isa = PBXBuildFile; fileRef = 0279655B29D795E7004DEB20 /* tabs_v4.json */; };
0279656C29D795E8004DEB20 /* routing_swiftui.json in Resources */ = {isa = PBXBuildFile; fileRef = 0279656929D795E7004DEB20 /* routing_swiftui.json */; };
0279DE482BEBE76900F9ECF8 /* dydxTargetLeverageCtaButtonViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0279DE472BEBE76900F9ECF8 /* dydxTargetLeverageCtaButtonViewPresenter.swift */; };
0279DE792BEC472600F9ECF8 /* dydxAdjustMarginInputViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0279DE782BEC472600F9ECF8 /* dydxAdjustMarginInputViewBuilder.swift */; };
0279DE952BED63E100F9ECF8 /* dydxAdjustMarginCtaButtonViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0279DE942BED63E100F9ECF8 /* dydxAdjustMarginCtaButtonViewPresenter.swift */; };
027CA87229EDFC990069781A /* dydxTransferInputCtaButtonViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027CA87129EDFC990069781A /* dydxTransferInputCtaButtonViewPresenter.swift */; };
027CB28729EEFF910069781A /* dydxTransferStatusViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027CB28629EEFF910069781A /* dydxTransferStatusViewBuilder.swift */; };
027E1EF829CA27CD0098666F /* dydxSettingsLandingViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027E1EF729CA27CD0098666F /* dydxSettingsLandingViewBuilder.swift */; };
Expand Down Expand Up @@ -433,6 +435,8 @@
0279655B29D795E7004DEB20 /* tabs_v4.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = tabs_v4.json; sourceTree = "<group>"; };
0279656929D795E7004DEB20 /* routing_swiftui.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = routing_swiftui.json; sourceTree = "<group>"; };
0279DE472BEBE76900F9ECF8 /* dydxTargetLeverageCtaButtonViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxTargetLeverageCtaButtonViewPresenter.swift; sourceTree = "<group>"; };
0279DE782BEC472600F9ECF8 /* dydxAdjustMarginInputViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxAdjustMarginInputViewBuilder.swift; sourceTree = "<group>"; };
0279DE942BED63E100F9ECF8 /* dydxAdjustMarginCtaButtonViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxAdjustMarginCtaButtonViewPresenter.swift; sourceTree = "<group>"; };
027CA87129EDFC990069781A /* dydxTransferInputCtaButtonViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxTransferInputCtaButtonViewPresenter.swift; sourceTree = "<group>"; };
027CB28629EEFF910069781A /* dydxTransferStatusViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxTransferStatusViewBuilder.swift; sourceTree = "<group>"; };
027E1EF729CA27CD0098666F /* dydxSettingsLandingViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSettingsLandingViewBuilder.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -754,6 +758,7 @@
0279DE462BEBE75D00F9ECF8 /* Components */,
023AB3C32BEAD56A005230B2 /* dydxMarginModeViewBuilder.swift */,
023AB3C72BEAD5F3005230B2 /* dydxTargetLeverageViewBuilder.swift */,
0279DE782BEC472600F9ECF8 /* dydxAdjustMarginInputViewBuilder.swift */,
);
path = Margin;
sourceTree = "<group>";
Expand Down Expand Up @@ -1035,6 +1040,7 @@
isa = PBXGroup;
children = (
0279DE472BEBE76900F9ECF8 /* dydxTargetLeverageCtaButtonViewPresenter.swift */,
0279DE942BED63E100F9ECF8 /* dydxAdjustMarginCtaButtonViewPresenter.swift */,
);
path = Components;
sourceTree = "<group>";
Expand Down Expand Up @@ -1868,6 +1874,7 @@
023789ED28BD381C00F212E1 /* dydxPresenters.docc in Sources */,
0258B9E72991BC900098E1BE /* dydxNewsAlertsViewBuilder.swift in Sources */,
277E908B2B2118AE005CCBCB /* dydxRewardsHistoryViewPresenter.swift in Sources */,
0279DE952BED63E100F9ECF8 /* dydxAdjustMarginCtaButtonViewPresenter.swift in Sources */,
0230376F28C11BE600412B72 /* dydxMarketsViewBuilder.swift in Sources */,
023AB3C42BEAD56A005230B2 /* dydxMarginModeViewBuilder.swift in Sources */,
270BA8F32A6F278F009212EA /* dydxDebugThemeViewerBuilder.swift in Sources */,
Expand Down Expand Up @@ -1928,6 +1935,7 @@
021B68B12AD9B86600C5C3BF /* dydxSecurityViewPresenter.swift in Sources */,
024B43A229812DC700E35D54 /* dydxValidationViewPresenter.swift in Sources */,
024B44D42982D24A00E35D54 /* dydxTradeStatusViewBuilder.swift in Sources */,
0279DE792BEC472600F9ECF8 /* dydxAdjustMarginInputViewBuilder.swift in Sources */,
6496DC3E295E122B00174CE7 /* dydxTradeInputViewBuilder.swift in Sources */,
64A4DB9529664803008D8E20 /* dydxTradeInputEditPresenter.swift in Sources */,
0238FB6D296BD4E0002E1C1A /* dydxPortfolioChartViewPresenter.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@
"destination":"dydxPresenters.dydxTargetLeverageViewBuilder",
"presentation":"prompt"
},
"/trade/adjust_margin":{
"destination":"dydxPresenters.dydxAdjustMarginInputViewBuilder",
"presentation":"prompt"
},
"/transfer":{
"destination":"dydxPresenters.dydxTransferViewBuilder",
"presentation":"prompt"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ class dydxPortfolioPositionsViewPresenter: HostedViewPresenter<dydxPortfolioPosi
Router.shared?.navigate(to: RoutingRequest(path: "/market", params: ["market": market.id]), animated: true, completion: nil)
}
item.handler?.onCloseAction = {
Router.shared?.navigate(to: RoutingRequest(path: "/trade/close", params: ["marketId": "\(position.id)"]), animated: true, completion: nil)
Router.shared?.navigate(to: RoutingRequest(path: "/trade/close", params: ["marketId": market.id]), animated: true, completion: nil)
}
item.handler?.onMarginEditAction = {
Router.shared?.navigate(to: RoutingRequest(path: "/trade/adjust_margin", params: ["marketId": market.id]), animated: true, completion: nil)
}

return item
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// dydxAdjustMarginCtaButtonViewPresenter.swift
// dydxPresenters
//
// Created by Rui Huang on 09/05/2024.
//

import Utilities
import dydxViews
import PlatformParticles
import RoutingKit
import ParticlesKit
import PlatformUI

protocol dydxAdjustMarginCtaButtonViewPresenterProtocol: HostedViewPresenterProtocol {
var viewModel: dydxAdjustMarginCtaButtonViewModel? { get }
}

class dydxAdjustMarginCtaButtonViewPresenter: HostedViewPresenter<dydxAdjustMarginCtaButtonViewModel>, dydxAdjustMarginCtaButtonViewPresenterProtocol {
override init() {
super.init()

viewModel = dydxAdjustMarginCtaButtonViewModel()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//
// dydxAdjustMarginInputViewBuilder.swift
// dydxPresenters
//
// Created by Rui Huang on 08/05/2024.
//

import Utilities
import dydxViews
import PlatformParticles
import RoutingKit
import ParticlesKit
import PlatformUI
import dydxStateManager
import Abacus
import Combine
import dydxFormatter

public class dydxAdjustMarginInputViewBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
let presenter = dydxAdjustMarginInputViewPresenter()
let view = presenter.viewModel?.createView() ?? PlatformViewModel().createView()
return dydxAdjustMarginInputViewController(presenter: presenter, view: view, configuration: .default) as? T
}
}

private class dydxAdjustMarginInputViewController: HostingViewController<PlatformView, dydxAdjustMarginInputViewModel> {
override public func arrive(to request: RoutingRequest?, animated: Bool) -> Bool {
if request?.path == "/trade/adjust_margin", let marketId = parser.asString(request?.params?["marketId"]) {
let presenter = presenter as? dydxAdjustMarginInputViewPresenterProtocol
presenter?.marketId = marketId
return true
}
return false
}
}

private protocol dydxAdjustMarginInputViewPresenterProtocol: HostedViewPresenterProtocol {
var viewModel: dydxAdjustMarginInputViewModel? { get }
var marketId: String? { get set }
}

private class dydxAdjustMarginInputViewPresenter: HostedViewPresenter<dydxAdjustMarginInputViewModel>, dydxAdjustMarginInputViewPresenterProtocol {
private let ctaButtonPresenter = dydxAdjustMarginCtaButtonViewPresenter()

private lazy var childPresenters: [HostedViewPresenterProtocol] = [
ctaButtonPresenter
]

var marketId: String?

override init() {
let viewModel = dydxAdjustMarginInputViewModel()

ctaButtonPresenter.$viewModel.assign(to: &viewModel.$ctaButton)

super.init()

viewModel.marginPercentage?.percentageOptions = [
dydxAdjustMarginPercentagViewModel.PercentageOption(text: "10%", percentage: 0.1),
dydxAdjustMarginPercentagViewModel.PercentageOption(text: "25%", percentage: 0.25),
dydxAdjustMarginPercentagViewModel.PercentageOption(text: "50%", percentage: 0.5),
dydxAdjustMarginPercentagViewModel.PercentageOption(text: "75%", percentage: 0.75)
]

viewModel.amount?.label = DataLocalizer.localize(path: "APP.GENERAL.AMOUNT")
viewModel.amount?.placeHolder = "0.00"

viewModel.liquidationPrice?.before = dydxFormatter.shared.dollar(number: 1234.56, digits: 2)

self.viewModel = viewModel

attachChildren(workers: childPresenters)
}

override func start() {
super.start()

if let marketId = marketId {
Publishers
.CombineLatest(
AbacusStateManager.shared.state.market(of: marketId).compactMap { $0 },
AbacusStateManager.shared.state.assetMap)
.sink { [weak self] market, assetMap in
self?.updateState(market: market, assetMap: assetMap)
}
.store(in: &subscriptions)
}
}

private func updateState(market: PerpetualMarket, assetMap: [String: Asset]) {
let asset = assetMap[market.assetId]
viewModel?.sharedMarketViewModel = SharedMarketPresenter.createViewModel(market: market, asset: asset)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PlatformUI
import Abacus
import dydxStateManager
import dydxFormatter
import Combine

public class dydxTargetLeverageViewBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
Expand Down Expand Up @@ -44,19 +45,24 @@ private class dydxTargetLeverageViewPresenter: HostedViewPresenter<dydxTargetLev
]

override init() {
let viewModel = dydxTargetLeverageViewModel()

ctaButtonPresenter.$viewModel.assign(to: &viewModel.$ctaButton)

super.init()

viewModel = dydxTargetLeverageViewModel()
viewModel?.description = DataLocalizer.localize(path: "APP.TRADE.ADJUST_TARGET_LEVERAGE_DESCRIPTION")
viewModel.description = DataLocalizer.localize(path: "APP.TRADE.ADJUST_TARGET_LEVERAGE_DESCRIPTION")

viewModel?.leverageOptions = [
viewModel.leverageOptions = [
dydxTargetLeverageViewModel.LeverageTextAndValue(text: "1x", value: 1.0),
dydxTargetLeverageViewModel.LeverageTextAndValue(text: "2x", value: 2.0),
dydxTargetLeverageViewModel.LeverageTextAndValue(text: "5x", value: 5.0),
dydxTargetLeverageViewModel.LeverageTextAndValue(text: "10.0", value: 10.0),
dydxTargetLeverageViewModel.LeverageTextAndValue(text: "Max", value: 20.0)
]

self.viewModel = viewModel

attachChildren(workers: childPresenters)
}

Expand Down
Loading

0 comments on commit 50f77bc

Please sign in to comment.