shared-state
- implemented POC for server check in Zashi, adopted SDK with the feature [#1237] Choose the best server by testing responses from multiple server hosts - Logic has been updated to deliver all requirements - UI has been upgraded to reflect latest and new design [#1237] Choose the best server by testing responses from multiple server hosts - inverted tint if needed implemented for the progress view [#1237] Choose the best server by testing responses from multiple server hosts - Rebased [#937] Shielded transaction UI - The TransactionState has been extended to handle shielding - The UI for the transaction row has been extended to handle right states for all types of transactions, newly for shielding, shielded and shielding failed [#937] Shielded transaction UI - Rebased and updated to the latest API [#937] Shielded transaction UI - WIP [#937] Shielded transaction UI - Shileding UI updated to show amount the same way as sent/received - Shielding UI updated to show ID [#1337] update UI of the Settings and Advanced Settings screens - settings WIP [#1337] update UI of the Settings and Advanced Settings screens - Changelog updated - Design is finalized for both Settings and Advanced Settings design-system - POC done - All Colors added/implemented - first set of variables implemented design-system - Color names made unique - CurrencyConversion screen refactored to use new design system colors - Currency conversion colors removed from the catalogue design-system - Variables made for the Utilities (all of them are missing aliases in Figma so it's just prepared except a few I updated myself) - ServerSwitch refactored to use design system - error and primary tint updated to use design system design-system - Utility variables finished - Server switch refactored to the latest design system variables tca-deprecation-resolution - All reducers have been updated to use @Reducer macro - All scopes have been updated to use \. case path - All destinations have been updated to use new Bindings tca-deprecation-resolution - @DependencyClient macro used for all dependencies - Unit tests fixed shared-state - POC shared-state - Exchange rate is now handled by TCA's shared state shared-state - Hide balances feature has been refactored using TCA's shared state - It's no longer treated as "hide balances" but rather "hide sensitive data" because we will add a few more things to it besides balances in the near future - Previous approach with Combine's subject and TCA's dependency have been removed from Zashi shared-state - removed unused file shared-state - code cleanup shared-state - code cleanup shared-state - build fixed
This commit is contained in:
parent
126ca96ec9
commit
006b57fff7
|
@ -30,7 +30,6 @@ let package = Package(
|
|||
.library(name: "FeedbackGenerator", targets: ["FeedbackGenerator"]),
|
||||
.library(name: "FileManager", targets: ["FileManager"]),
|
||||
.library(name: "Generated", targets: ["Generated"]),
|
||||
.library(name: "HideBalances", targets: ["HideBalances"]),
|
||||
.library(name: "Home", targets: ["Home"]),
|
||||
.library(name: "ImportWallet", targets: ["ImportWallet"]),
|
||||
.library(name: "LocalAuthenticationHandler", targets: ["LocalAuthenticationHandler"]),
|
||||
|
@ -289,14 +288,6 @@ let package = Package(
|
|||
name: "Generated",
|
||||
resources: [.process("Resources")]
|
||||
),
|
||||
.target(
|
||||
name: "HideBalances",
|
||||
dependencies: [
|
||||
"UserDefaults",
|
||||
.product(name: "ComposableArchitecture", package: "swift-composable-architecture")
|
||||
],
|
||||
path: "Sources/Dependencies/HideBalances"
|
||||
),
|
||||
.target(
|
||||
name: "Home",
|
||||
dependencies: [
|
||||
|
@ -489,7 +480,6 @@ let package = Package(
|
|||
"ExchangeRate",
|
||||
"ExportLogs",
|
||||
"Generated",
|
||||
"HideBalances",
|
||||
"MnemonicClient",
|
||||
"Models",
|
||||
"NotEnoughFreeSpace",
|
||||
|
@ -695,7 +685,6 @@ let package = Package(
|
|||
"CurrencyConversionSetup",
|
||||
"ExchangeRate",
|
||||
"Generated",
|
||||
"HideBalances",
|
||||
"Home",
|
||||
"WalletStatusPanel",
|
||||
"SendConfirmation",
|
||||
|
@ -730,7 +719,6 @@ let package = Package(
|
|||
"BalanceFormatter",
|
||||
"DerivationTool",
|
||||
"Generated",
|
||||
"HideBalances",
|
||||
"NumberFormatter",
|
||||
"WalletStatusPanel",
|
||||
"SupportDataGenerator",
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// HideBalancesInterface.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 11.11.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ComposableArchitecture
|
||||
import Combine
|
||||
|
||||
extension DependencyValues {
|
||||
public var hideBalances: HideBalancesClient {
|
||||
get { self[HideBalancesClient.self] }
|
||||
set { self[HideBalancesClient.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
@DependencyClient
|
||||
public struct HideBalancesClient {
|
||||
public enum Constants {
|
||||
static let udHideBalances = "udHideBalances"
|
||||
}
|
||||
|
||||
public var prepare: @Sendable () -> Void
|
||||
public var value: @Sendable () -> CurrentValueSubject<Bool, Never> = { CurrentValueSubject(false) }
|
||||
public var updateValue: @Sendable (Bool) -> Void
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// HideBalancesLiveKey.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 11.11.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ComposableArchitecture
|
||||
import Combine
|
||||
import UserDefaults
|
||||
|
||||
extension HideBalancesClient: DependencyKey {
|
||||
public static var liveValue: Self {
|
||||
let storage = CurrentValueSubject<Bool, Never>(false)
|
||||
|
||||
return .init(
|
||||
prepare: {
|
||||
@Dependency(\.userDefaults) var userDefaults
|
||||
|
||||
if let value = userDefaults.objectForKey(Constants.udHideBalances) as? Bool {
|
||||
storage.value = value
|
||||
}
|
||||
},
|
||||
value: { storage },
|
||||
updateValue: {
|
||||
@Dependency(\.userDefaults) var userDefaults
|
||||
|
||||
userDefaults.setValue($0, Constants.udHideBalances)
|
||||
|
||||
storage.value = $0
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// HideBalancesTestKey.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 11.11.2023.
|
||||
//
|
||||
|
||||
import ComposableArchitecture
|
||||
import XCTestDynamicOverlay
|
||||
import Combine
|
||||
|
||||
extension HideBalancesClient: TestDependencyKey {
|
||||
public static let testValue = Self(
|
||||
prepare: unimplemented("\(Self.self).prepare", placeholder: {}()),
|
||||
value: unimplemented("\(Self.self).value", placeholder: .init(false)),
|
||||
updateValue: unimplemented("\(Self.self).updateValue", placeholder: {}())
|
||||
)
|
||||
}
|
||||
|
||||
extension HideBalancesClient {
|
||||
public static let noOp = Self(
|
||||
prepare: { },
|
||||
value: { .init(false) },
|
||||
updateValue: { _ in }
|
||||
)
|
||||
}
|
|
@ -64,5 +64,5 @@ public struct SDKSynchronizerClient {
|
|||
|
||||
public var refreshExchangeRateUSD: () -> Void
|
||||
|
||||
public var evaluateBestOf: ([LightWalletEndpoint], Double, Double, UInt64, Int, NetworkType) async -> [LightWalletEndpoint]
|
||||
public var evaluateBestOf: ([LightWalletEndpoint], Double, Double, UInt64, Int, NetworkType) async -> [LightWalletEndpoint] = { _,_,_,_,_,_ in [] }
|
||||
}
|
||||
|
|
|
@ -23,9 +23,7 @@ public struct BalancesView: View {
|
|||
@Perception.Bindable var store: StoreOf<Balances>
|
||||
let tokenName: String
|
||||
|
||||
@Dependency(\.hideBalances) var hideBalances
|
||||
@State var isHidden = false
|
||||
@State private var cancellable: AnyCancellable?
|
||||
@Shared(.appStorage(.sensitiveContent)) var isSensitiveContentHidden = false
|
||||
@State var walletStatus = WalletStatus.none
|
||||
|
||||
public init(store: StoreOf<Balances>, tokenName: String) {
|
||||
|
@ -94,18 +92,8 @@ public struct BalancesView: View {
|
|||
action: \.alert
|
||||
)
|
||||
)
|
||||
.onAppear {
|
||||
store.send(.onAppear)
|
||||
if !_XCTIsTesting {
|
||||
cancellable = hideBalances.value().sink { val in
|
||||
isHidden = val
|
||||
}
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
store.send(.onDisappear)
|
||||
cancellable?.cancel()
|
||||
}
|
||||
.onAppear { store.send(.onAppear) }
|
||||
.onDisappear { store.send(.onDisappear) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,7 +238,7 @@ extension BalancesView {
|
|||
shadowOffset: 6
|
||||
)
|
||||
.padding(.bottom, 15)
|
||||
.disabled(!store.isShieldableBalanceAvailable || store.isShieldingFunds || isHidden)
|
||||
.disabled(!store.isShieldableBalanceAvailable || store.isShieldingFunds || isSensitiveContentHidden)
|
||||
|
||||
Text("(\(ZatoshiStringRepresentation.feeFormat))")
|
||||
.font(.custom(FontFamily.Inter.semiBold.name, size: 11))
|
||||
|
|
|
@ -47,7 +47,6 @@ extension Root {
|
|||
switch action {
|
||||
case .initialization(.appDelegate(.didFinishLaunching)):
|
||||
state.appStartState = .didFinishLaunching
|
||||
hideBalances.prepare()
|
||||
// TODO: [#704], trigger the review request logic when approved by the team,
|
||||
// https://github.com/Electric-Coin-Company/zashi-ios/issues/704
|
||||
return .concatenate(
|
||||
|
|
|
@ -23,7 +23,6 @@ import BackgroundTasks
|
|||
import WalletStatusPanel
|
||||
import Utils
|
||||
import UserDefaults
|
||||
import HideBalances
|
||||
import ServerSetup
|
||||
import ExchangeRate
|
||||
|
||||
|
@ -134,7 +133,6 @@ public struct Root {
|
|||
@Dependency(\.derivationTool) var derivationTool
|
||||
@Dependency(\.diskSpaceChecker) var diskSpaceChecker
|
||||
@Dependency(\.exchangeRate) var exchangeRate
|
||||
@Dependency(\.hideBalances) var hideBalances
|
||||
@Dependency(\.mainQueue) var mainQueue
|
||||
@Dependency(\.mnemonic) var mnemonic
|
||||
@Dependency(\.numberFormatter) var numberFormatter
|
||||
|
|
|
@ -32,7 +32,7 @@ public struct SendFlow {
|
|||
|
||||
@Presents public var alert: AlertState<Action>?
|
||||
public var addMemoState: Bool
|
||||
public var currencyConversion: CurrencyConversion?
|
||||
@Shared(.inMemory(.exchangeRate)) public var currencyConversion: CurrencyConversion? = nil
|
||||
public var destination: Destination?
|
||||
public var isCurrencyConversionEnabled = false
|
||||
public var memoState: MessageEditor.State
|
||||
|
@ -140,7 +140,6 @@ public struct SendFlow {
|
|||
|
||||
public init(
|
||||
addMemoState: Bool,
|
||||
currencyConversion: CurrencyConversion? = nil,
|
||||
destination: Destination? = nil,
|
||||
memoState: MessageEditor.State,
|
||||
scanState: Scan.State,
|
||||
|
@ -148,7 +147,6 @@ public struct SendFlow {
|
|||
walletBalancesState: WalletBalances.State
|
||||
) {
|
||||
self.addMemoState = addMemoState
|
||||
self.currencyConversion = currencyConversion
|
||||
self.destination = destination
|
||||
self.memoState = memoState
|
||||
self.scanState = scanState
|
||||
|
|
|
@ -51,7 +51,7 @@ public struct Tabs {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public var addressDetailsState: AddressDetails.State
|
||||
public var balanceBreakdownState: Balances.State
|
||||
public var currencyConversionSetupState: CurrencyConversionSetup.State
|
||||
|
|
|
@ -16,7 +16,6 @@ import Home
|
|||
import SendFlow
|
||||
import Settings
|
||||
import UIComponents
|
||||
import HideBalances
|
||||
import SendConfirmation
|
||||
import CurrencyConversionSetup
|
||||
|
||||
|
@ -26,9 +25,8 @@ public struct TabsView: View {
|
|||
let tokenName: String
|
||||
@Namespace var tabsID
|
||||
|
||||
@Dependency(\.hideBalances) var hideBalances
|
||||
@State var areBalancesHidden = false
|
||||
|
||||
@Shared(.appStorage(.sensitiveContent)) var isSensitiveContentHidden = false
|
||||
|
||||
public init(store: StoreOf<Tabs>, tokenName: String, networkType: NetworkType) {
|
||||
self.store = store
|
||||
self.tokenName = tokenName
|
||||
|
@ -147,9 +145,6 @@ public struct TabsView: View {
|
|||
.navigationBarItems(leading: hideBalancesButton(tab: store.selectedTab))
|
||||
.zashiTitle { navBarView(store.selectedTab) }
|
||||
.walletStatusPanel()
|
||||
.onAppear {
|
||||
areBalancesHidden = hideBalances.value().value
|
||||
}
|
||||
.overlayPreferenceValue(BoundsPreferenceKey.self) { preferences in
|
||||
if store.isRateTooltipEnabled {
|
||||
GeometryReader { geometry in
|
||||
|
@ -192,11 +187,12 @@ public struct TabsView: View {
|
|||
Text(L10n.CurrencyConversion.title)
|
||||
.font(.custom(FontFamily.Inter.semiBold.name, size: 16))
|
||||
.foregroundColor(Design.Text.primary.color)
|
||||
.lineLimit(nil)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
}
|
||||
.padding(.trailing, 16)
|
||||
|
||||
Spacer()
|
||||
Spacer(minLength: 0)
|
||||
|
||||
Button {
|
||||
store.send(.currencyConversionCloseTapped)
|
||||
|
@ -281,12 +277,9 @@ public struct TabsView: View {
|
|||
func hideBalancesButton(tab: Tabs.State.Tab) -> some View {
|
||||
if tab == .account || tab == .send || tab == .balances {
|
||||
Button {
|
||||
var prevValue = hideBalances.value().value
|
||||
prevValue.toggle()
|
||||
areBalancesHidden = prevValue
|
||||
hideBalances.updateValue(areBalancesHidden)
|
||||
isSensitiveContentHidden.toggle()
|
||||
} label: {
|
||||
let image = areBalancesHidden ? Asset.Assets.eyeOff.image : Asset.Assets.eyeOn.image
|
||||
let image = isSensitiveContentHidden ? Asset.Assets.eyeOff.image : Asset.Assets.eyeOn.image
|
||||
image
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
|
|
|
@ -23,7 +23,7 @@ public struct WalletBalances {
|
|||
|
||||
@ObservableState
|
||||
public struct State: Equatable {
|
||||
public var currencyConversion: CurrencyConversion?
|
||||
@Shared(.inMemory(.exchangeRate)) public var currencyConversion: CurrencyConversion? = nil
|
||||
public var fiatCurrencyResult: FiatCurrencyResult?
|
||||
public var isAvailableBalanceTappable = true
|
||||
public var isExchangeRateFeatureOn = false
|
||||
|
@ -52,7 +52,6 @@ public struct WalletBalances {
|
|||
}
|
||||
|
||||
public init(
|
||||
currencyConversion: CurrencyConversion? = nil,
|
||||
fiatCurrencyResult: FiatCurrencyResult? = nil,
|
||||
isAvailableBalanceTappable: Bool = true,
|
||||
isExchangeRateFeatureOn: Bool = false,
|
||||
|
@ -64,7 +63,6 @@ public struct WalletBalances {
|
|||
totalBalance: Zatoshi = .zero,
|
||||
transparentBalance: Zatoshi = .zero
|
||||
) {
|
||||
self.currencyConversion = currencyConversion
|
||||
self.fiatCurrencyResult = fiatCurrencyResult
|
||||
self.isAvailableBalanceTappable = isAvailableBalanceTappable
|
||||
self.isExchangeRateFeatureOn = isExchangeRateFeatureOn
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// SharedStateKeys.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 05-09-2024
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension String {
|
||||
static var exchangeRate = "sharedStateKey_exchangeRate"
|
||||
static var sensitiveContent = "udHideBalances"
|
||||
}
|
|
@ -12,7 +12,6 @@ import Utils
|
|||
import ComposableArchitecture
|
||||
import BalanceFormatter
|
||||
import XCTestDynamicOverlay
|
||||
import HideBalances
|
||||
import Combine
|
||||
|
||||
public struct ZatoshiRepresentationView: View {
|
||||
|
@ -25,9 +24,7 @@ public struct ZatoshiRepresentationView: View {
|
|||
let isFee: Bool
|
||||
let couldBeHidden: Bool
|
||||
|
||||
@Dependency(\.hideBalances) var hideBalances
|
||||
@State var isHidden = false
|
||||
@State private var cancellable: AnyCancellable?
|
||||
@Shared(.appStorage(.sensitiveContent)) var isSensitiveContentHidden = false
|
||||
|
||||
public init(
|
||||
balance: Zatoshi,
|
||||
|
@ -71,20 +68,20 @@ public struct ZatoshiRepresentationView: View {
|
|||
.font(.custom(fontName, size: mostSignificantFontSize))
|
||||
} else {
|
||||
if format == .expanded {
|
||||
Text(couldBeHidden && isHidden
|
||||
Text(couldBeHidden && isSensitiveContentHidden
|
||||
? L10n.General.hideBalancesMost
|
||||
: zatoshiStringRepresentation.mostSignificantDigits
|
||||
)
|
||||
.font(.custom(fontName, size: mostSignificantFontSize))
|
||||
.conditionalStrikethrough(strikethrough)
|
||||
+ Text(couldBeHidden && isHidden
|
||||
+ Text(couldBeHidden && isSensitiveContentHidden
|
||||
? L10n.General.hideBalancesLeast
|
||||
: zatoshiStringRepresentation.leastSignificantDigits
|
||||
)
|
||||
.font(.custom(fontName, size: leastSignificantFontSize))
|
||||
.conditionalStrikethrough(strikethrough)
|
||||
} else {
|
||||
Text(couldBeHidden && isHidden
|
||||
Text(couldBeHidden && isSensitiveContentHidden
|
||||
? L10n.General.hideBalancesMostStandalone
|
||||
: zatoshiStringRepresentation.mostSignificantDigits
|
||||
)
|
||||
|
@ -93,16 +90,6 @@ public struct ZatoshiRepresentationView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
if !_XCTIsTesting {
|
||||
cancellable = hideBalances.value().sink { val in
|
||||
isHidden = val
|
||||
}
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
cancellable?.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,26 +12,16 @@ import Combine
|
|||
import Generated
|
||||
|
||||
struct HiddenIfSetModifier: ViewModifier {
|
||||
@Dependency(\.hideBalances) var hideBalances
|
||||
@State var isHidden = false
|
||||
@State private var cancellable: AnyCancellable?
|
||||
|
||||
@Shared(.appStorage(.sensitiveContent)) var isSensitiveContentHidden = false
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
VStack(spacing: 0) {
|
||||
if isHidden {
|
||||
if isSensitiveContentHidden {
|
||||
Text(L10n.General.hideBalancesMostStandalone)
|
||||
} else {
|
||||
content
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
cancellable = hideBalances.value().sink { val in
|
||||
isHidden = val
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
cancellable?.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@
|
|||
{
|
||||
"identity" : "swift-custom-dump",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/pointfreeco/swift-custom-dump.git",
|
||||
"location" : "https://github.com/pointfreeco/swift-custom-dump",
|
||||
"state" : {
|
||||
"revision" : "82645ec760917961cfa08c9c0c7104a57a0fa4b1",
|
||||
"version" : "1.3.3"
|
||||
|
@ -266,8 +266,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio.git",
|
||||
"state" : {
|
||||
"revision" : "4c4453b489cf76e6b3b0f300aba663eb78182fad",
|
||||
"version" : "2.70.0"
|
||||
"revision" : "9746cf80e29edfef2a39924a66731249223f42a3",
|
||||
"version" : "2.72.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -57,7 +57,6 @@ class AppInitializationTests: XCTestCase {
|
|||
store.dependencies.numberFormatter = .noOp
|
||||
store.dependencies.walletStatusPanel = .noOp
|
||||
store.dependencies.userDefaults = .noOp
|
||||
store.dependencies.hideBalances = .noOp
|
||||
store.dependencies.autolockHandler = .noOp
|
||||
store.dependencies.exchangeRate = .noOp
|
||||
|
||||
|
@ -144,7 +143,6 @@ class AppInitializationTests: XCTestCase {
|
|||
store.dependencies.numberFormatter = .noOp
|
||||
store.dependencies.walletStatusPanel = .noOp
|
||||
store.dependencies.userDefaults = .noOp
|
||||
store.dependencies.hideBalances = .noOp
|
||||
store.dependencies.autolockHandler = .noOp
|
||||
store.dependencies.exchangeRate = .noOp
|
||||
|
||||
|
@ -210,7 +208,6 @@ class AppInitializationTests: XCTestCase {
|
|||
store.dependencies.walletConfigProvider = .noOp
|
||||
store.dependencies.crashReporter = .noOp
|
||||
store.dependencies.walletStatusPanel = .noOp
|
||||
store.dependencies.hideBalances = .noOp
|
||||
|
||||
// Root of the test, the app finished the launch process and triggers the checks and initializations.
|
||||
await store.send(.initialization(.appDelegate(.didFinishLaunching))) { state in
|
||||
|
@ -250,7 +247,6 @@ class AppInitializationTests: XCTestCase {
|
|||
store.dependencies.walletConfigProvider = .noOp
|
||||
store.dependencies.crashReporter = .noOp
|
||||
store.dependencies.walletStatusPanel = .noOp
|
||||
store.dependencies.hideBalances = .noOp
|
||||
|
||||
// Root of the test, the app finished the launch process and triggers the checks and initializations.
|
||||
await store.send(.initialization(.appDelegate(.didFinishLaunching))) { state in
|
||||
|
|
|
@ -31,7 +31,6 @@ class BalanceBreakdownSnapshotTests: XCTestCase {
|
|||
.dependency(\.mainQueue, .immediate)
|
||||
.dependency(\.walletStatusPanel, .noOp)
|
||||
.dependency(\.diskSpaceChecker, .mockEmptyDisk)
|
||||
.dependency(\.hideBalances, .noOp)
|
||||
.dependency(\.exchangeRate, .noOp)
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ class HomeSnapshotTests: XCTestCase {
|
|||
.dependency(\.mainQueue, .immediate)
|
||||
.dependency(\.reviewRequest, .noOp)
|
||||
.dependency(\.walletStatusPanel, .noOp)
|
||||
.dependency(\.hideBalances, .noOp)
|
||||
.dependency(\.exchangeRate, .noOp)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue