Skip to content

Commit

Permalink
MOB-357 Margin Mode Selection Screen (#160)
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
  • Loading branch information
ruixhuang authored and mike-dydx committed Aug 20, 2024
1 parent a3829e8 commit 989ce10
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 21 deletions.
24 changes: 13 additions & 11 deletions PlatformUI/PlatformUI/Components/Icons/PlatformIcon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,20 @@ public class PlatformIconViewModel: PlatformViewModel {
)
} else {
let clippedView = Group {

ZStack {
ZStack {
view
.frame(width: size.width - spacing, height: size.height - spacing)
.clipped()
}
.frame(width: size.width, height: size.height)
.themeColor(background: background)
.clipShape(Circle())
.overlay(
Circle().stroke(borderColor?.color ?? .clear, lineWidth: 1)
)
Circle()
.fill(background.color)
.frame(width: size.width, height: size.height)
.themeColor(background: background)
.clipShape(Circle())
.overlay(
Circle().stroke(borderColor?.color ?? .clear, lineWidth: 1)
)

view
.frame(width: size.width - spacing, height: size.height - spacing)
.clipped()
}
.themeStyle(style: style)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@
},
"/trade/margin_type":{
"destination":"dydxPresenters.dydxMarginModeViewBuilder",
"presentation":"prompt"
"presentation":"half"
},
"/trade/target_leverage":{
"destination":"dydxPresenters.dydxTargetLeverageViewBuilder",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ public class dydxMarginModeViewBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
let presenter = dydxMarginModeViewPresenter()
let view = presenter.viewModel?.createView() ?? PlatformViewModel().createView()
return dydxMarginModeViewController(presenter: presenter, view: view, configuration: .default) as? T
// return HostingViewController(presenter: presenter, view: view) as? T
return dydxMarginModeViewController(presenter: presenter, view: view, configuration: .ignoreSafeArea) as? T
}
}

Expand All @@ -39,5 +38,20 @@ private class dydxMarginModeViewPresenter: HostedViewPresenter<dydxMarginModeVie
super.init()

viewModel = dydxMarginModeViewModel()
viewModel?.market = "BTC-USD"
viewModel?.items = [
dydxMarginModeItemViewModel(title: DataLocalizer.localize(path: "APP.GENERAL.CROSS_MARGIN"),
detail: DataLocalizer.localize(path: "APP.GENERAL.CROSS_MARGIN_DESCRIPTION"),
isSelected: true,
selectedAction: {
Router.shared?.navigate(to: RoutingRequest(path: "/action/dismiss"), animated: true, completion: nil)
}),
dydxMarginModeItemViewModel(title: DataLocalizer.localize(path: "APP.GENERAL.ISOLATED_MARGIN"),
detail: DataLocalizer.localize(path: "APP.GENERAL.ISOLATED_MARGIN_DESCRIPTION"),
isSelected: false,
selectedAction: {
Router.shared?.navigate(to: RoutingRequest(path: "/action/dismiss"), animated: true, completion: nil)
})
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class dydxTradeInputMarginViewPresenter: HostedViewPresenter<dydxTradeInputMargi
// TODO: Fetch from Abacus
viewModel?.marginMode = DataLocalizer.localize(path: "APP.GENERAL.ISOLATED")
viewModel?.marginLeverage = "2x"

viewModel?.marginModeAction = {
Router.shared?.navigate(to: RoutingRequest(path: "/trade/margin_type"), animated: true, completion: nil)
}
Expand Down
115 changes: 109 additions & 6 deletions dydx/dydxViews/dydxViews/_v4/Trade/Margin/dydxMarginModeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,127 @@ import SwiftUI
import PlatformUI
import Utilities

public class dydxMarginModeItemViewModel: PlatformViewModel {
@Published public var title: String?
@Published public var detail: String?
@Published public var isSelected: Bool = false
@Published public var selectedAction: (() -> Void)?

private let cornerRadius: CGFloat = 8

public init(title: String? = nil, detail: String? = nil, isSelected: Bool = false, selectedAction: (() -> Void)? = nil) {
self.title = title
self.detail = detail
self.isSelected = isSelected
self.selectedAction = selectedAction
}

public override func createView(parentStyle: ThemeStyle = ThemeStyle.defaultStyle, styleKey: String? = nil) -> PlatformView {
PlatformView(viewModel: self, parentStyle: parentStyle, styleKey: styleKey) { [weak self] style in
guard let self = self else { return AnyView(PlatformView.nilView) }

let buttonContent = VStack(alignment: .leading, spacing: 8) {
HStack {
Text(self.title ?? "")
.themeFont(fontSize: .medium)
.themeColor(foreground: .textPrimary)

Spacer()

if self.isSelected {
self.createSelectedCheckmark(parentStyle: style)
} else {
self.createUnselectedCheckmark(parentStyle: style)
}
}

Text(self.detail ?? "")
.multilineTextAlignment(.leading)
.themeFont(fontSize: .small)
.themeColor(foreground: .textTertiary)
}
.padding(16)
.leftAligned()
.themeColor(background: self.isSelected ? ThemeColor.SemanticColor.layer1 : ThemeColor.SemanticColor.layer3)
.overlay(
RoundedRectangle(cornerRadius: cornerRadius)
.strokeBorder(self.isSelected ? ThemeColor.SemanticColor.colorPurple.color : ThemeColor.SemanticColor.textTertiary.color, lineWidth: 1)
)
.contentShape(RoundedRectangle(cornerRadius: cornerRadius))
.wrappedViewModel

return AnyView(
PlatformButtonViewModel(content: buttonContent,
type: PlatformButtonType.iconType,
action: self.selectedAction ?? {})
.createView(parentStyle: style)
)
}
}

private func createSelectedCheckmark(parentStyle: ThemeStyle) -> some View {
PlatformIconViewModel(type: .asset(name: "icon_checked", bundle: Bundle.dydxView),
clip: .circle(background: .colorPurple,
spacing: 12,
borderColor: nil),
size: CGSize(width: 20, height: 20),
templateColor: .textPrimary)
.createView(parentStyle: parentStyle)
}

private func createUnselectedCheckmark(parentStyle: ThemeStyle) -> some View {
Circle()
.fill(ThemeColor.SemanticColor.layer1.color)
.frame(width: 20, height: 20)
.overlay(
Circle().stroke(ThemeColor.SemanticColor.layer5.color, lineWidth: 1)
)
}
}

public class dydxMarginModeViewModel: PlatformViewModel {
@Published public var text: String?
@Published public var market: String?
@Published public var items: [dydxMarginModeItemViewModel] = []

public init() { }

public static var previewValue: dydxMarginModeViewModel {
let vm = dydxMarginModeViewModel()
vm.text = "Test String"
vm.market = "ETH-USD"
return vm
}

public override func createView(parentStyle: ThemeStyle = ThemeStyle.defaultStyle, styleKey: String? = nil) -> PlatformView {
PlatformView(viewModel: self, parentStyle: parentStyle, styleKey: styleKey) { [weak self] _ in
PlatformView(viewModel: self, parentStyle: parentStyle, styleKey: styleKey) { [weak self] style in
guard let self = self else { return AnyView(PlatformView.nilView) }

return AnyView(
Text(self.text ?? "")
)
let view = VStack(alignment: .leading, spacing: 20) {
HStack(spacing: 8) {
Text(DataLocalizer.localize(path: "APP.GENERAL.MARGIN_MODE"))
.themeColor(foreground: .textPrimary)

Text(self.market ?? "")
.themeColor(foreground: .textSecondary)

Spacer()
}
.themeFont(fontType: .plus, fontSize: .largest)
.padding(.top, 40)

VStack(alignment: .leading, spacing: 16) {
ForEach(self.items, id: \.id) { item in
item.createView(parentStyle: style)
}
}

Spacer()
}
.padding(.horizontal)
.themeColor(background: .layer3)
.makeSheet(sheetStyle: .fitSize)

// make it visible under the tabbar
return AnyView(view.ignoresSafeArea(edges: [.bottom]))
}
}
}
Expand Down

0 comments on commit 989ce10

Please sign in to comment.