Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions Features/Assets/Sources/Scenes/AssetScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,19 @@ public struct AssetScene: View {
)

if model.showStakedBalance {
stakeView
NavigationCustomLink(
with: ListItemView(title: model.stakeTitle, subtitle: model.assetDataModel.stakeBalanceTextWithSymbol),
action: { model.onSelectHeader(.stake) }
)
.accessibilityIdentifier("stake")
}

if model.showEarnBalance {
NavigationCustomLink(
with: ListItemView(title: model.earnTitle, subtitle: model.earnBalanceText),
action: { model.onSelectEarn() }
)
.accessibilityIdentifier("earn")
}

if model.showPendingUnconfirmedBalance {
Expand All @@ -128,6 +140,23 @@ public struct AssetScene: View {
.listRowInsets(.assetListRowInsets)
}

if model.showEarnButton {
Section {
NavigationCustomLink(
with: HStack(spacing: Spacing.medium) {
EmojiView(color: Colors.grayVeryLight, emoji: Emoji.WalletAvatar.moneyBag.rawValue)
.frame(size: .image.asset)
ListItemView(
title: model.earnTitle,
subtitle: model.earnAprText,
subtitleStyle: TextStyle(font: .callout, color: Colors.green)
)
},
action: { model.onSelectEarn() }
)
}
}

if model.showResources {
Section(model.resourcesTitle) {
ListItemView(
Expand Down Expand Up @@ -179,14 +208,6 @@ extension AssetScene {
imageSize: .list.image
)
}

private var stakeView: some View {
NavigationCustomLink(
with: ListItemView(title: model.stakeTitle, subtitle: model.assetDataModel.stakeBalanceTextWithSymbol),
action: { model.onSelectHeader(.stake) }
)
.accessibilityIdentifier("stake")
}

private var stakeViewEmpty: some View {
NavigationCustomLink(
Expand All @@ -202,4 +223,5 @@ extension AssetScene {
action: { model.onSelectHeader(.stake) }
)
}

}
30 changes: 29 additions & 1 deletion Features/Assets/Sources/ViewModels/AssetSceneViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public final class AssetSceneViewModel: Sendable {

var canOpenNetwork: Bool { assetDataModel.asset.type != .native }

var showBalances: Bool { assetDataModel.showBalances }
var showBalances: Bool { assetDataModel.showBalances || showEarnBalance }
private var showStakedBalanceTypes: [Primitives.BalanceType] = [.staked, .pending, .rewards]
var showStakedBalance: Bool { assetDataModel.isStakeEnabled || assetData.balances.contains(where: { showStakedBalanceTypes.contains($0.key) && $0.value > 0 }) }
var showReservedBalance: Bool { assetDataModel.hasReservedBalance }
Expand Down Expand Up @@ -132,6 +132,27 @@ public final class AssetSceneViewModel: Sendable {
return Localized.Stake.apr(CurrencyFormatter.percentSignLess.string(apr))
}

var earnTitle: String { Localized.Common.earn }

var earnAprText: String {
guard let apr = assetDataModel.earnApr else { return .empty }
return Localized.Stake.apr(CurrencyFormatter.percentSignLess.string(apr))
}

var showEarnButton: Bool {
assetData.metadata.isEarnEnabled && !wallet.isViewOnly && !showEarnBalance
}

var showEarnBalance: Bool {
assetData.balance.earn > 0
}

var earnBalanceText: String {
let balance = assetData.balance.earn
guard balance > 0 else { return "0" }
return ValueFormatter(style: .medium).string(balance, decimals: asset.decimals.asInt, currency: asset.symbol)
}

var priceItemViewModel: PriceListItemViewModel {
PriceListItemViewModel(
title: Localized.Asset.price,
Expand Down Expand Up @@ -300,6 +321,13 @@ extension AssetSceneViewModel {
onSelect(url: action.url)
}

func onSelectEarn() {
isPresentingSelectedAssetInput.wrappedValue = SelectedAssetInput(
type: .earn(assetData.asset),
assetAddress: assetData.assetAddress
)
}

func onSelectBuy() {
onSelectHeader(.buy)
}
Expand Down
21 changes: 12 additions & 9 deletions Features/Staking/Package.swift → Features/Stake/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,56 @@
import PackageDescription

let package = Package(
name: "Staking",
name: "Stake",
platforms: [
.iOS(.v17),
.macOS(.v15)
],
products: [
.library(
name: "Staking",
targets: ["Staking"]),
name: "Stake",
targets: ["Stake"]),
],
dependencies: [
.package(name: "Primitives", path: "../../Packages/Primitives"),
.package(name: "Components", path: "../../Packages/Components"),
.package(name: "GemstonePrimitives", path: "../../Packages/GemstonePrimitives"),
.package(name: "Localization", path: "../../Packages/Localization"),
.package(name: "ChainServices", path: "../../Packages/ChainServices"),
.package(name: "FeatureServices", path: "../../Packages/FeatureServices"),
.package(name: "Preferences", path: "../../Packages/Preferences"),
.package(name: "Store", path: "../../Packages/Store"),
.package(name: "InfoSheet", path: "../InfoSheet"),
.package(name: "PrimitivesComponents", path: "../../Packages/PrimitivesComponents"),
.package(name: "Formatters", path: "../../Packages/Formatters")

.package(name: "Formatters", path: "../../Packages/Formatters"),
.package(name: "Style", path: "../../Packages/Style"),
],
targets: [
.target(
name: "Staking",
name: "Stake",
dependencies: [
"Primitives",
"Components",
"GemstonePrimitives",
"Localization",
.product(name: "StakeService", package: "ChainServices"),
.product(name: "ExplorerService", package: "ChainServices"),
.product(name: "EarnService", package: "FeatureServices"),
"Preferences",
"Store",
"InfoSheet",
"PrimitivesComponents",
"Formatters"
"Formatters",
"Style",
],
path: "Sources"
),
.testTarget(
name: "StakingTests",
name: "StakeTests",
dependencies: [
.product(name: "PrimitivesTestKit", package: "Primitives"),
.product(name: "StakeServiceTestKit", package: "ChainServices"),
"Staking"
"Stake"
],
path: "Tests"
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import SwiftUI
import Components
import PrimitivesComponents

public struct StakeDetailScene: View {
private let model: StakeDetailSceneViewModel
public struct DelegationDetailScene: View {
private let model: DelegationDetailSceneViewModel

public init(model: StakeDetailSceneViewModel) {
public init(model: DelegationDetailSceneViewModel) {
self.model = model
}

public var body: some View {
List {
Section { } header: {
WalletHeaderView(
model: model.validatorHeaderViewModel,
model: model.headerViewModel,
isPrivacyEnabled: .constant(false),
balanceActionType: .none,
onHeaderAction: nil,
Expand All @@ -26,16 +26,16 @@ public struct StakeDetailScene: View {
.cleanListRow()

Section {
if let url = model.validatorUrl {
if let url = model.providerUrl {
SafariNavigationLink(url: url) {
ListItemView(title: model.validatorTitle, subtitle: model.validatorText)
ListItemView(title: model.providerTitle, subtitle: model.providerText)
}
} else {
ListItemView(title: model.validatorTitle, subtitle: model.validatorText)
ListItemView(title: model.providerTitle, subtitle: model.providerText)
}

if model.showValidatorApr {
ListItemView(title: model.aprTitle, subtitle: model.validatorAprText)
if model.showApr {
ListItemView(title: model.aprTitle, subtitle: model.aprText)
}

ListItemView(title: model.stateTitle, subtitle: model.stateText, subtitleStyle: model.stateTextStyle)
Expand All @@ -59,27 +59,11 @@ public struct StakeDetailScene: View {
}
}

//TODO: Remove NavigationCustomLink usage in favor of NavigationLink()
if model.showManage {
Section(model.manageTitle) {
if model.isStakeAvailable {
NavigationCustomLink(with: ListItemView(title: model.title)) {
model.onStakeAmountAction()
}
}
if model.isUnstakeAvailable {
NavigationCustomLink(with: ListItemView(title: model.unstakeTitle)) {
model.onUnstakeAction()
}
}
if model.isRedelegateAvailable {
NavigationCustomLink(with: ListItemView(title: model.redelegateTitle)) {
model.onRedelegateAction()
}
}
if model.isWithdrawStakeAvailable {
NavigationCustomLink(with: ListItemView(title: model.withdrawTitle)) {
model.onWithdrawAction()
ForEach(model.availableActions) { action in
NavigationCustomLink(with: ListItemView(title: model.actionTitle(action))) {
model.onSelectAction(action)
}
}
}
Expand Down
70 changes: 70 additions & 0 deletions Features/Stake/Sources/Scenes/EarnScene.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c). Gem Wallet. All rights reserved.

import SwiftUI
import Components
import Primitives
import Localization
import PrimitivesComponents

public struct EarnScene: View {
private let model: EarnSceneViewModel

public init(model: EarnSceneViewModel) {
self.model = model
}

public var body: some View {
List {
switch model.providersState {
case .noData:
Section {
ListItemView(title: Localized.Errors.noDataAvailable)
}
case .loading:
ListItemLoadingView()
.id(UUID())
case .data:
Section(model.assetTitle) {
ListItemView(
title: model.aprTitle,
subtitle: model.aprValue
)
}
case .error(let error):
ListItemErrorView(errorTitle: Localized.Errors.errorOccured, error: error)
}

if model.showDeposit {
Section(Localized.Common.manage) {
NavigationLink(value: model.depositDestination) {
ListItemView(title: Localized.Wallet.deposit)
}
}
}

Section(model.positionsSectionTitle) {
if model.hasPositions {
ForEach(model.positionModels) { delegation in
NavigationLink(value: delegation.delegation) {
DelegationView(delegation: delegation)
}
}
.listRowInsets(.assetListRowInsets)
} else if model.showEmptyState {
EmptyContentView(model: model.emptyContentModel)
.cleanListRow()
}
}
}
.listSectionSpacing(.compact)
.navigationTitle(model.title)
.refreshable {
await model.fetch()
}
.taskOnce {
Task {
await model.fetch()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ extension StakeScene {
.id(UUID())
case .data(let delegations):
ForEach(delegations) { delegation in
NavigationLink(value: delegation.navigationDestination) {
StakeDelegationView(delegation: delegation)
NavigationLink(value: model.navigationDestination(for: delegation)) {
DelegationView(delegation: delegation)
}
}
.listRowInsets(.assetListRowInsets)
Expand Down
9 changes: 9 additions & 0 deletions Features/Stake/Sources/Types/DelegationDetailAction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c). Gem Wallet. All rights reserved.

public enum DelegationDetailActionType: Hashable, Identifiable {
public var id: Self { self }

case stake, unstake, redelegate
case deposit
case withdraw
}
Loading