diff --git a/dydx/dydxPresenters/dydxPresenters/_v4/Portfolio/Components/dydxPortfolioPositionsViewPresenter.swift b/dydx/dydxPresenters/dydxPresenters/_v4/Portfolio/Components/dydxPortfolioPositionsViewPresenter.swift index 973fe8de..f10833fa 100644 --- a/dydx/dydxPresenters/dydxPresenters/_v4/Portfolio/Components/dydxPortfolioPositionsViewPresenter.swift +++ b/dydx/dydxPresenters/dydxPresenters/_v4/Portfolio/Components/dydxPortfolioPositionsViewPresenter.swift @@ -25,6 +25,10 @@ class dydxPortfolioPositionsViewPresenter: HostedViewPresenter(420.42), + let vaultApy = Optional(Double.random(in: -30...30)) { + viewModel.vaultBalance = dydxFormatter.shared.dollar(number: vaultBalance, digits: 2) + viewModel.vaultApy = vaultApy + } + } + .store(in: &subscriptions) } private func updatePositions(positions: [SubaccountPosition], marketMap: [String: PerpetualMarket], assetMap: [String: Asset]) { diff --git a/dydx/dydxPresenters/dydxPresenters/_v4/Vault/DepositsAndWithdrawals/dydxVaultDepositWithdrawConfirmationViewBuilder.swift b/dydx/dydxPresenters/dydxPresenters/_v4/Vault/DepositsAndWithdrawals/dydxVaultDepositWithdrawConfirmationViewBuilder.swift index b9b92cea..bf4f6640 100644 --- a/dydx/dydxPresenters/dydxPresenters/_v4/Vault/DepositsAndWithdrawals/dydxVaultDepositWithdrawConfirmationViewBuilder.swift +++ b/dydx/dydxPresenters/dydxPresenters/_v4/Vault/DepositsAndWithdrawals/dydxVaultDepositWithdrawConfirmationViewBuilder.swift @@ -68,7 +68,7 @@ private class dydxVaultDepositWithdrawConfirmationViewPresenter: HostedViewPrese guard let viewModel else { return } viewModel.amount = amount - viewModel.faqUrl = AbacusStateManager.shared.environment?.links?.vaultLearnMore ?? "" + viewModel.faqUrl = AbacusStateManager.shared.environment?.links?.vaultLearnMore viewModel.transferType = transferType initializeSubmitState() diff --git a/dydx/dydxViews/dydxViews/Media.xcassets/icon_token.imageset/Contents.json b/dydx/dydxViews/dydxViews/Media.xcassets/icon_chain.imageset/Contents.json similarity index 100% rename from dydx/dydxViews/dydxViews/Media.xcassets/icon_token.imageset/Contents.json rename to dydx/dydxViews/dydxViews/Media.xcassets/icon_chain.imageset/Contents.json diff --git a/dydx/dydxViews/dydxViews/Media.xcassets/icon_token.imageset/icon_token.pdf b/dydx/dydxViews/dydxViews/Media.xcassets/icon_chain.imageset/icon_token.pdf similarity index 100% rename from dydx/dydxViews/dydxViews/Media.xcassets/icon_token.imageset/icon_token.pdf rename to dydx/dydxViews/dydxViews/Media.xcassets/icon_chain.imageset/icon_token.pdf diff --git a/dydx/dydxViews/dydxViews/Themes/dydxStyle.json b/dydx/dydxViews/dydxViews/Themes/dydxStyle.json index 91af8781..1c746827 100644 --- a/dydx/dydxViews/dydxViews/Themes/dydxStyle.json +++ b/dydx/dydxViews/dydxViews/Themes/dydxStyle.json @@ -24,10 +24,10 @@ "_textColor": "color_red" }, "signed-plus-layer": { - "_layerColor": "#3ED9A433" + "_layerColor": "color_faded_green" }, "signed-minus-layer": { - "_layerColor": "#E4555533" + "_layerColor": "color_faded_red" }, "side-plus": { "_textColor": "color_green" diff --git a/dydx/dydxViews/dydxViews/_v4/Portfolio/Components/Sections/dydxPortfolioPositionsView.swift b/dydx/dydxViews/dydxViews/_v4/Portfolio/Components/Sections/dydxPortfolioPositionsView.swift index d0f3a1f9..9160e6e6 100644 --- a/dydx/dydxViews/dydxViews/_v4/Portfolio/Components/Sections/dydxPortfolioPositionsView.swift +++ b/dydx/dydxViews/dydxViews/_v4/Portfolio/Components/Sections/dydxPortfolioPositionsView.swift @@ -253,12 +253,17 @@ public class dydxPortfolioPositionsViewModel: PlatformViewModel { contentChanged?() } } - + @Published public var vaultBalance: String? + @Published public var vaultApy: Double? + @Published public var vaultTapAction: (() -> Void)? + public var contentChanged: (() -> Void)? init( positionItems: [dydxPortfolioPositionItemViewModel] = [], pendingPositionItems: [dydxPortfolioPendingPositionsItemViewModel] = [], + vaultBalance: String? = nil, + vaultApy: String? = nil, emptyText: String? = nil ) { self.positionItems = positionItems @@ -275,6 +280,7 @@ public class dydxPortfolioPositionsViewModel: PlatformViewModel { pendingPositionItems: [ .previewValue ], + vaultBalance: "324.320", emptyText: "empty") } @@ -314,16 +320,91 @@ public class dydxPortfolioPositionsViewModel: PlatformViewModel { } } + @ViewBuilder private var pendingPositionsView: AnyView? { - let unopenedItems = self.pendingPositionItems.map { $0.createView() } - return LazyVStack { - self.pendingPositionsHeader?.createView() + if !pendingPositionItems.isEmpty { + let unopenedItems = self.pendingPositionItems.map { $0.createView() } + LazyVStack { + self.pendingPositionsHeader?.createView() - ForEach(unopenedItems.indices, id: \.self) { index in - unopenedItems[index] + ForEach(unopenedItems.indices, id: \.self) { index in + unopenedItems[index] + } + } + .wrappedInAnyView() + } + } + + @ViewBuilder + public var apyAccessory: some View { + if let vaultApy, let vaultApyText = dydxFormatter.shared.percent(number: vaultApy, digits: 2) { + Text(vaultApyText) + .themeFont(fontSize: .smaller) + .padding(.horizontal, 4) + .padding(.vertical, 2) + .themeColor(foreground: vaultApy < 0 ? ThemeSettings.negativeColor : ThemeSettings.positiveColor) + .themeColor(background: vaultApy < 0 ? ThemeSettings.negativeColorLayer : ThemeSettings.positiveColorLayer) + .cornerRadius(4) + } + } + + public var megaVaultBalanceRowHeader: some View { + HStack(spacing: 0) { + Text(localizerPathKey: "APP.GENERAL.DETAILS") + .themeFont(fontType: .plus, fontSize: .small) + .themeColor(foreground: .textTertiary) + Spacer() + Text(localizerPathKey: "APP.VAULTS.YOUR_VAULT_BALANCE") + .themeFont(fontType: .plus, fontSize: .small) + .themeColor(foreground: .textTertiary) + } + .padding(.horizontal, 16) + } + + @ViewBuilder + public var megaVaultBalanceRow: some View { + if let vaultBalance { + HStack(spacing: 0) { + PlatformIconViewModel(type: .asset(name: "icon_chain", bundle: .dydxView), + clip: .noClip, + size: .init(width: 32, height: 32), + templateColor: nil) + .createView() + Color.clear.frame(width: 16) + Text(localizerPathKey: "APP.VAULTS.MEGAVAULT") + .themeFont(fontSize: .medium) + .themeColor(foreground: .textSecondary) + Color.clear.frame(width: 6) + apyAccessory + Spacer() + Text(vaultBalance) + .themeFont(fontSize: .small) + .themeColor(foreground: .textPrimary) + } + .padding(.all, 16) + .themeColor(background: .layer3) + .cornerRadius(16) + } + } + + @ViewBuilder + public var megaVaultSection: some View { + if dydxBoolFeatureFlag.isVaultEnabled.isEnabled { + VStack(spacing: 16) { + Text(localizerPathKey: "APP.VAULTS.MEGAVAULT") + .themeFont(fontType: .plus, fontSize: .larger) + .themeColor(foreground: .textPrimary) + .fixedSize() + .leftAligned() + VStack(spacing: 8) { + megaVaultBalanceRowHeader + megaVaultBalanceRow + } + } + .onTapGesture { [weak self] in + self?.vaultTapAction?() } } - .wrappedInAnyView() } public override func createView(parentStyle: ThemeStyle = ThemeStyle.defaultStyle, styleKey: String? = nil) -> PlatformView { @@ -335,6 +416,7 @@ public class dydxPortfolioPositionsViewModel: PlatformViewModel { VStack(spacing: 24) { self.openPositionsView self.pendingPositionsView + self.megaVaultSection } } ) diff --git a/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/VaultTransferType.swift b/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/VaultTransferType.swift index a007827c..c5fec848 100644 --- a/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/VaultTransferType.swift +++ b/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/VaultTransferType.swift @@ -42,8 +42,8 @@ public enum VaultTransferType: CaseIterable, RadioButtonContentDisplayable { var confirmTransferText: String { switch self { - case .deposit: return DataLocalizer.localize(path: "APP.GENERAL.CONFIRM_DEPOSIT") - case .withdraw: return DataLocalizer.localize(path: "APP.GENERAL.CONFIRM_WITHDRAW") + case .deposit: return DataLocalizer.localize(path: "APP.VAULTS.CONFIRM_DEPOSIT_CTA") + case .withdraw: return DataLocalizer.localize(path: "APP.VAULTS.CONFIRM_WITHDRAW_CTA") } } @@ -60,7 +60,7 @@ public enum VaultTransferType: CaseIterable, RadioButtonContentDisplayable { var transferDestinationImage: Image? { switch self { - case .deposit: return Image("icon_token", bundle: .dydxView) + case .deposit: return Image("icon_chain", bundle: .dydxView) case .withdraw: return nil } } diff --git a/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/dydxVaultDepositWithdrawConfirmationViewModel.swift b/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/dydxVaultDepositWithdrawConfirmationViewModel.swift index 5fec9538..73cfeea5 100644 --- a/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/dydxVaultDepositWithdrawConfirmationViewModel.swift +++ b/dydx/dydxViews/dydxViews/_v4/Vault/DepositAndWithdrawal/dydxVaultDepositWithdrawConfirmationViewModel.swift @@ -208,9 +208,9 @@ private struct VaultDepositWithdrawConfirmationView: View { if let faqUrl = viewModel.faqUrl, let slippage = viewModel.slippage, viewModel.requiresAcknowledgeHighSlippage { let withdrawalSlippageInlineAlertAttributedText = AttributedString(localizerPathKey: "APP.VAULTS.SLIPPAGE_WARNING", - params: ["LINK": DataLocalizer.localize(path: "APP.VAULTS.VAULT_FAQS"), + params: ["LINK": DataLocalizer.localize(path: "APP.VAULTS.MEGAVAULT_FAQS"), "AMOUNT": dydxFormatter.shared.percent(number: slippage, digits: 2) ?? "--"], - hyperlinks: ["APP.VAULTS.VAULT_FAQS": faqUrl], + hyperlinks: ["APP.VAULTS.MEGAVAULT_FAQS": faqUrl], foreground: .textPrimary) InlineAlertViewModel(.init(title: nil, body: withdrawalSlippageInlineAlertAttributedText, diff --git a/dydx/dydxViews/dydxViews/_v4/Vault/Landing/dydxVaultViewModel.swift b/dydx/dydxViews/dydxViews/_v4/Vault/Landing/dydxVaultViewModel.swift index 1a624d54..1f8e32c9 100644 --- a/dydx/dydxViews/dydxViews/_v4/Vault/Landing/dydxVaultViewModel.swift +++ b/dydx/dydxViews/dydxViews/_v4/Vault/Landing/dydxVaultViewModel.swift @@ -88,7 +88,7 @@ private struct dydxVaultView: View { } private var titleImage: some View { - PlatformIconViewModel(type: .asset(name: "icon_token", bundle: .dydxView), + PlatformIconViewModel(type: .asset(name: "icon_chain", bundle: .dydxView), clip: .noClip, size: .init(width: 40, height: 40), templateColor: nil) @@ -96,7 +96,7 @@ private struct dydxVaultView: View { } private var titleText: some View { - Text(DataLocalizer.shared?.localize(path: "APP.VAULTS.VAULT", params: nil) ?? "") + Text(DataLocalizer.shared?.localize(path: "APP.VAULTS.MEGAVAULT", params: nil) ?? "") .themeColor(foreground: .textPrimary) .themeFont(fontType: .plus, fontSize: .largest) }