Skip to content

Commit

Permalink
Position info
Browse files Browse the repository at this point in the history
  • Loading branch information
ruixhuang committed Dec 27, 2024
1 parent 28108b1 commit 2744b71
Show file tree
Hide file tree
Showing 11 changed files with 349 additions and 9 deletions.
4 changes: 4 additions & 0 deletions dydx/dydxPresenters/dydxPresenters.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
027885E82D1DD67200366321 /* dydxSimpleUIMarketInfoViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885E72D1DD66500366321 /* dydxSimpleUIMarketInfoViewBuilder.swift */; };
027885F02D1DE14600366321 /* dydxSimpleUIMarketInfoHeaderViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885EF2D1DE14500366321 /* dydxSimpleUIMarketInfoHeaderViewPresenter.swift */; };
027885F42D1DEBF700366321 /* dydxSimpleUIMarketCandlesViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885F32D1DEBF600366321 /* dydxSimpleUIMarketCandlesViewPresenter.swift */; };
027885FC2D1E171C00366321 /* dydxSimpleUIMarketPositionViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885FB2D1E171B00366321 /* dydxSimpleUIMarketPositionViewPresenter.swift */; };
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 */; };
Expand Down Expand Up @@ -481,6 +482,7 @@
027885E72D1DD66500366321 /* dydxSimpleUIMarketInfoViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketInfoViewBuilder.swift; sourceTree = "<group>"; };
027885EF2D1DE14500366321 /* dydxSimpleUIMarketInfoHeaderViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketInfoHeaderViewPresenter.swift; sourceTree = "<group>"; };
027885F32D1DEBF600366321 /* dydxSimpleUIMarketCandlesViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketCandlesViewPresenter.swift; sourceTree = "<group>"; };
027885FB2D1E171B00366321 /* dydxSimpleUIMarketPositionViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketPositionViewPresenter.swift; sourceTree = "<group>"; };
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>"; };
Expand Down Expand Up @@ -1122,6 +1124,7 @@
children = (
027885EF2D1DE14500366321 /* dydxSimpleUIMarketInfoHeaderViewPresenter.swift */,
027885F32D1DEBF600366321 /* dydxSimpleUIMarketCandlesViewPresenter.swift */,
027885FB2D1E171B00366321 /* dydxSimpleUIMarketPositionViewPresenter.swift */,
);
path = components;
sourceTree = "<group>";
Expand Down Expand Up @@ -2122,6 +2125,7 @@
023789ED28BD381C00F212E1 /* dydxPresenters.docc in Sources */,
2751D6462C59643800B36F95 /* dydxVaultViewBuilder.swift in Sources */,
277E908B2B2118AE005CCBCB /* dydxRewardsHistoryViewPresenter.swift in Sources */,
027885FC2D1E171C00366321 /* dydxSimpleUIMarketPositionViewPresenter.swift in Sources */,
0279DE952BED63E100F9ECF8 /* dydxAdjustMarginCtaButtonViewPresenter.swift in Sources */,
0230376F28C11BE600412B72 /* dydxMarketsViewBuilder.swift in Sources */,
023AB3C42BEAD56A005230B2 /* dydxMarginModeViewBuilder.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class dydxPortfolioPositionsViewPresenter: HostedViewPresenter<dydxPortfolioPosi
} else {
item.liquidationPrice = DataLocalizer.localize(path: "APP.GENERAL.NONE")
}
item.entryPrice = dydxFormatter.shared.dollar(number: position.entryPrice.current?.doubleValue ?? 0, digits: configs.displayTickSizeDecimals?.intValue ?? 0)

item.unrealizedPnl = SignedAmountViewModel(amount: position.unrealizedPnl.current?.doubleValue ?? 0, displayType: .dollar, coloringOption: .allText)
item.unrealizedPnlPercent = dydxFormatter.shared.percent(number: position.unrealizedPnlPercent.current?.doubleValue, digits: 2) ?? ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// dydxSimpleUIMarketPositionViewPresenter.swift
// dydxPresenters
//
// Created by Rui Huang on 26/12/2024.
//

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

protocol dydxSimpleUIMarketPositionViewPresenterProtocol: HostedViewPresenterProtocol {
var viewModel: dydxSimpleUIMarketPositionViewModel? { get }
}

class dydxSimpleUIMarketPositionViewPresenter: HostedViewPresenter<dydxSimpleUIMarketPositionViewModel>, dydxSimpleUIMarketPositionViewPresenterProtocol {
@Published var marketId: String?

override init() {
super.init()

viewModel = dydxSimpleUIMarketPositionViewModel()
}

override func start() {
super.start()

Publishers
.CombineLatest4(AbacusStateManager.shared.state.selectedSubaccountPositions,
$marketId,
AbacusStateManager.shared.state.marketMap,
AbacusStateManager.shared.state.assetMap)
.sink { [weak self] position, marketId, marketMap, assetMap in
let position = position.first { position in
position.id == marketId &&
(position.side.current == Abacus.PositionSide.long_ || position.side.current == Abacus.PositionSide.short_)
}
self?.updatePositionSection(position: position, marketMap: marketMap, assetMap: assetMap)
}
.store(in: &subscriptions)
}

private func updatePositionSection(position: SubaccountPosition?, marketMap: [String: PerpetualMarket], assetMap: [String: Asset]) {
guard let position, let sharedOrderViewModel = dydxPortfolioPositionsViewPresenter.createPositionViewModelItem(position: position,
marketMap: marketMap,
assetMap: assetMap)
else {
viewModel?.side = nil // hide the view
return
}

viewModel?.symbol = sharedOrderViewModel.token?.symbol
viewModel?.unrealizedPNLAmount = sharedOrderViewModel.unrealizedPnl
viewModel?.size = sharedOrderViewModel.size
viewModel?.side = SideTextViewModel(side: sharedOrderViewModel.sideText.side, coloringOption: .withBackground)
viewModel?.liquidationPrice = sharedOrderViewModel.liquidationPrice
viewModel?.entryPrice = sharedOrderViewModel.entryPrice

viewModel?.logoUrl = sharedOrderViewModel.logoUrl
viewModel?.amount = dydxFormatter.shared.dollar(number: position.notionalTotal.current?.doubleValue, digits: 2)
viewModel?.funding = SignedAmountViewModel(amount: position.netFunding?.doubleValue, displayType: .dollar, coloringOption: .allText)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ private class dydxSimpleUIMarketInfoViewPresenter: HostedViewPresenter<dydxSimpl
private let statsPresenter = dydxMarketStatsViewPresenter()
private let configsPresenter = dydxMarketConfigsViewPresenter()
private let sharedMarketPresenter = SharedMarketPresenter()
private let positionPresenter = dydxSimpleUIMarketPositionViewPresenter()

private lazy var childPresenters: [HostedViewPresenterProtocol] = [
headerPresenter,
chartPresenter,
statsPresenter,
configsPresenter,
sharedMarketPresenter
sharedMarketPresenter,
positionPresenter
]

override init() {
Expand All @@ -65,6 +67,7 @@ private class dydxSimpleUIMarketInfoViewPresenter: HostedViewPresenter<dydxSimpl
statsPresenter.$viewModel.assign(to: &viewModel.$stats)
configsPresenter.$viewModel.assign(to: &viewModel.$configs)
sharedMarketPresenter.$viewModel.assign(to: &viewModel.resources.$sharedMarketViewModel)
positionPresenter.$viewModel.assign(to: &viewModel.$position)

super.init()

Expand All @@ -75,6 +78,7 @@ private class dydxSimpleUIMarketInfoViewPresenter: HostedViewPresenter<dydxSimpl
$marketId.assign(to: &statsPresenter.$marketId)
$marketId.assign(to: &configsPresenter.$marketId)
$marketId.assign(to: &sharedMarketPresenter.$marketId)
$marketId.assign(to: &positionPresenter.$marketId)

attachChildren(workers: childPresenters)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class dydxSimpleUIPortfolioViewPresenter: HostedViewPresenter<dydxSimpleUIPortfo
override func start() {
super.start()

AbacusStateManager.shared.setHistoricalPNLPeriod(period: HistoricalPnlPeriod.period90d)
AbacusStateManager.shared.setHistoricalPNLPeriod(period: HistoricalPnlPeriod.period30d)

loadingStartTime = Date()
Publishers.CombineLatest4(
Expand Down Expand Up @@ -102,7 +102,13 @@ class dydxSimpleUIPortfolioViewPresenter: HostedViewPresenter<dydxSimpleUIPortfo
}
let maxValue = chartEntries.max { $0.value < $1.value }?.value ?? 0
let minValue = chartEntries.min { $0.value < $1.value }?.value ?? 0
viewModel?.chart.entries = chartEntries

// only update when there is significant change
if chartEntries.count != viewModel?.chart.entries.count ||
abs((chartEntries.last?.value ?? 0) - (viewModel?.chart.entries.last?.value ?? 0)) > 1.0 {
viewModel?.chart.entries = chartEntries
}

viewModel?.chart.showYLabels = false
viewModel?.chart.valueLowerBoundOffset = (maxValue - minValue) * 0.8
}
Expand Down
4 changes: 4 additions & 0 deletions dydx/dydxViews/dydxViews.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
027885ED2D1DE12C00366321 /* dydxSimpleUIMarketInfoHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885EC2D1DE12C00366321 /* dydxSimpleUIMarketInfoHeaderView.swift */; };
027885F22D1DEBE300366321 /* dydxSimpleUIMarketCandlesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885F12D1DEBE300366321 /* dydxSimpleUIMarketCandlesView.swift */; };
027885F62D1E0C5500366321 /* dydxSimpleUIMarketCandlesResolutionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885F52D1E0C5500366321 /* dydxSimpleUIMarketCandlesResolutionsView.swift */; };
027885FA2D1E170900366321 /* dydxSimpleUIMarketPositionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027885F92D1E170900366321 /* dydxSimpleUIMarketPositionView.swift */; };
0279DE452BEBE75100F9ECF8 /* dydxTargetLeverageCtaButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0279DE442BEBE75100F9ECF8 /* dydxTargetLeverageCtaButtonView.swift */; };
0279DE6B2BEC471700F9ECF8 /* dydxAdjustMarginInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0279DE6A2BEC471700F9ECF8 /* dydxAdjustMarginInputView.swift */; };
0279DE872BED3F5400F9ECF8 /* dydxAdjustMarginDirectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0279DE862BED3F5400F9ECF8 /* dydxAdjustMarginDirectionView.swift */; };
Expand Down Expand Up @@ -511,6 +512,7 @@
027885EC2D1DE12C00366321 /* dydxSimpleUIMarketInfoHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketInfoHeaderView.swift; sourceTree = "<group>"; };
027885F12D1DEBE300366321 /* dydxSimpleUIMarketCandlesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketCandlesView.swift; sourceTree = "<group>"; };
027885F52D1E0C5500366321 /* dydxSimpleUIMarketCandlesResolutionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketCandlesResolutionsView.swift; sourceTree = "<group>"; };
027885F92D1E170900366321 /* dydxSimpleUIMarketPositionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketPositionView.swift; sourceTree = "<group>"; };
0279DE442BEBE75100F9ECF8 /* dydxTargetLeverageCtaButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxTargetLeverageCtaButtonView.swift; sourceTree = "<group>"; };
0279DE6A2BEC471700F9ECF8 /* dydxAdjustMarginInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxAdjustMarginInputView.swift; sourceTree = "<group>"; };
0279DE862BED3F5400F9ECF8 /* dydxAdjustMarginDirectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxAdjustMarginDirectionView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1283,6 +1285,7 @@
027885EC2D1DE12C00366321 /* dydxSimpleUIMarketInfoHeaderView.swift */,
027885F12D1DEBE300366321 /* dydxSimpleUIMarketCandlesView.swift */,
027885F52D1E0C5500366321 /* dydxSimpleUIMarketCandlesResolutionsView.swift */,
027885F92D1E170900366321 /* dydxSimpleUIMarketPositionView.swift */,
);
path = components;
sourceTree = "<group>";
Expand Down Expand Up @@ -2286,6 +2289,7 @@
027885F22D1DEBE300366321 /* dydxSimpleUIMarketCandlesView.swift in Sources */,
02FF0BD529AEB91900781EDA /* dydxWalletView.swift in Sources */,
024B44D12982D1FF00E35D54 /* dydxTradeStatusView.swift in Sources */,
027885FA2D1E170900366321 /* dydxSimpleUIMarketPositionView.swift in Sources */,
02A9B60E29005D5A00AE1516 /* AmountText.swift in Sources */,
02FCF0E728E795FA00D350CE /* HostedViewPresenter.swift in Sources */,
0258BA1D2992949D0098E1BE /* dydxProfileView.swift in Sources */,
Expand Down
26 changes: 23 additions & 3 deletions dydx/dydxViews/dydxViews/_v4/MarketInfo/dydxMarketInfoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,14 @@ public class dydxMarketInfoViewModel: PlatformViewModel {
stats?
.createView(parentStyle: parentStyle)
.frame(width: UIScreen.main.bounds.width)
.section(path: "APP.GENERAL.STATISTICS")
.sectionHeader(path: "APP.GENERAL.STATISTICS")
}

private func createDetailsSection(parentStyle: ThemeStyle) -> some View {
resources
.createView(parentStyle: parentStyle)
.frame(width: UIScreen.main.bounds.width)
.section(path: "APP.GENERAL.DETAILS")
.sectionHeader(path: "APP.GENERAL.DETAILS")
}

private func createConfigsSection(parentStyle: ThemeStyle) -> some View {
Expand All @@ -151,9 +151,13 @@ public class dydxMarketInfoViewModel: PlatformViewModel {
}

extension View {
func section(path: String) -> some View {
func sectionHeader(path: String) -> some View {
self.modifier(SectionModifier(localizedStringPath: path))
}

func sectionHeader(header: @escaping (() -> some View)) -> some View {
self.modifier(SectionHeaderModifier(header: header))
}
}

private struct SectionModifier: ViewModifier {
Expand Down Expand Up @@ -182,6 +186,22 @@ private struct SectionModifier: ViewModifier {
}
}

private struct SectionHeaderModifier<Parent>: ViewModifier where Parent: View {
var header: (() -> Parent)

func body(content: Content) -> some View {
Section {
VStack(alignment: .leading) {
content
Spacer(minLength: 24)
}
} header: {
header()
.themeColor(background: .layer2)
}
}
}

#if DEBUG
struct dydxMarketInfoView_Previews_Dark: PreviewProvider {
@StateObject static var themeSettings = ThemeSettings.shared
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class dydxPortfolioPositionItemViewModel: PlatformViewModel {
@Published public var leverage: String?
@Published public var leverageIcon: LeverageRiskModel?
@Published public var liquidationPrice: String?
@Published public var entryPrice: String?
@Published public var indexPrice: String?
@Published public var unrealizedPnl: SignedAmountViewModel?
@Published public var unrealizedPnlPercent: String = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import dydxChart
import dydxFormatter

public class dydxLineChartViewModel: PlatformViewModel {
public struct Entry {
public struct Entry: Equatable {
public let date: Double
public let value: Double

Expand Down
Loading

0 comments on commit 2744b71

Please sign in to comment.