Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Fix #8089, #6538: Portfolio Settings / Menu View #8175

Merged
merged 3 commits into from
Oct 11, 2023
Merged
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
21 changes: 14 additions & 7 deletions Sources/BraveWallet/Crypto/Asset Details/AssetDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct AssetDetailView: View {
private var buySendSwapDestination: Binding<BuySendSwapDestination?>

@Environment(\.openURL) private var openWalletURL
@ObservedObject private var isShowingBalances = Preferences.Wallet.isShowingBalances

@ViewBuilder private var accountsBalanceView: some View {
Section(
Expand Down Expand Up @@ -69,13 +70,19 @@ struct AssetDetailView: View {
.font(.footnote)
.foregroundColor(Color(.secondaryBraveLabel))
} else {
VStack(alignment: .trailing) {
Text(showFiatPlaceholder ? "$0.00" : viewModel.fiatBalance)
.redacted(reason: showFiatPlaceholder ? .placeholder : [])
.shimmer(assetDetailStore.isLoadingPrice)
Text(showBalancePlaceholder ? "0.0000 \(assetDetailStore.assetDetailToken.symbol)" : "\(viewModel.balance) \(assetDetailStore.assetDetailToken.symbol)")
.redacted(reason: showBalancePlaceholder ? .placeholder : [])
.shimmer(assetDetailStore.isLoadingAccountBalances)
Group {
if isShowingBalances.value {
VStack(alignment: .trailing) {
Text(showFiatPlaceholder ? "$0.00" : viewModel.fiatBalance)
.redacted(reason: showFiatPlaceholder ? .placeholder : [])
.shimmer(assetDetailStore.isLoadingPrice)
Text(showBalancePlaceholder ? "0.0000 \(assetDetailStore.assetDetailToken.symbol)" : "\(viewModel.balance) \(assetDetailStore.assetDetailToken.symbol)")
.redacted(reason: showBalancePlaceholder ? .placeholder : [])
.shimmer(assetDetailStore.isLoadingAccountBalances)
}
} else {
Text("****")
}
}
.font(.footnote)
.foregroundColor(Color(.secondaryBraveLabel))
Expand Down
46 changes: 23 additions & 23 deletions Sources/BraveWallet/Crypto/CryptoPagesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ struct CryptoPagesView: View {
@ObservedObject var cryptoStore: CryptoStore
@ObservedObject var keyringStore: KeyringStore

@State private var isShowingMainMenu: Bool = false
@State private var isShowingSettings: Bool = false
@State private var isShowingSearch: Bool = false
@State private var fetchedPendingRequestsThisSession: Bool = false

@Environment(\.openURL) private var openWalletURL
@State private var selectedPageIndex: Int = 0

private var isConfirmationButtonVisible: Bool {
if case .transactions(let txs) = cryptoStore.pendingRequest {
Expand All @@ -33,7 +33,10 @@ struct CryptoPagesView: View {
keyringStore: keyringStore,
cryptoStore: cryptoStore,
isShowingPendingRequest: $cryptoStore.isPresentingPendingRequest,
isConfirmationsButtonVisible: isConfirmationButtonVisible
isConfirmationsButtonVisible: isConfirmationButtonVisible,
selectedIndexChanged: { selectedIndex in
selectedPageIndex = selectedIndex
}
)
.onAppear {
// If a user chooses not to confirm/reject their requests we shouldn't
Expand Down Expand Up @@ -97,42 +100,36 @@ struct CryptoPagesView: View {
.labelStyle(.iconOnly)
.foregroundColor(Color(.braveBlurpleTint))
}
Menu {
Button(action: {
keyringStore.lock()
}) {
Label(Strings.Wallet.lock, braveSystemImage: "leo.lock")
.imageScale(.medium) // Menu inside nav bar implicitly gets large
}
Button(action: { isShowingSettings = true }) {
Label(Strings.Wallet.settings, braveSystemImage: "leo.settings")
.imageScale(.medium) // Menu inside nav bar implicitly gets large
}
Divider()
Button(action: { openWalletURL(WalletConstants.braveWalletSupportURL) }) {
Label(Strings.Wallet.helpCenter, braveSystemImage: "leo.info.outline")
}
} label: {
Label(Strings.Wallet.otherWalletActionsAccessibilityTitle, systemImage: "ellipsis.circle")
Button(action: { self.isShowingMainMenu = true }) {
Label(Strings.Wallet.otherWalletActionsAccessibilityTitle, braveSystemImage: "leo.more.horizontal")
.labelStyle(.iconOnly)
.foregroundColor(Color(.braveBlurpleTint))
}
.accessibilityLabel(Strings.Wallet.otherWalletActionsAccessibilityTitle)
}
}
.sheet(isPresented: $isShowingMainMenu) {
MainMenuView(
isFromPortfolio: selectedPageIndex == 0,
isShowingSettings: $isShowingSettings,
keyringStore: keyringStore
)
}
}

private struct _CryptoPagesView: UIViewControllerRepresentable {
var keyringStore: KeyringStore
var cryptoStore: CryptoStore
var isShowingPendingRequest: Binding<Bool>
var isConfirmationsButtonVisible: Bool
var selectedIndexChanged: (Int) -> Void

func makeUIViewController(context: Context) -> CryptoPagesViewController {
CryptoPagesViewController(
keyringStore: keyringStore,
cryptoStore: cryptoStore,
isShowingPendingRequest: isShowingPendingRequest
isShowingPendingRequest: isShowingPendingRequest,
selectedIndexChanged: selectedIndexChanged
)
}
func updateUIViewController(_ uiViewController: CryptoPagesViewController, context: Context) {
Expand All @@ -145,18 +142,21 @@ private class CryptoPagesViewController: TabbedPageViewController {
private let keyringStore: KeyringStore
private let cryptoStore: CryptoStore
let pendingRequestsButton = ConfirmationsButton()
let selectedIndexChanged: (Int) -> Void

@Binding private var isShowingPendingRequest: Bool

init(
keyringStore: KeyringStore,
cryptoStore: CryptoStore,
isShowingPendingRequest: Binding<Bool>
isShowingPendingRequest: Binding<Bool>,
selectedIndexChanged: @escaping (Int) -> Void
) {
self.keyringStore = keyringStore
self.cryptoStore = cryptoStore
self._isShowingPendingRequest = isShowingPendingRequest
super.init(nibName: nil, bundle: nil)
self.selectedIndexChanged = selectedIndexChanged
super.init(selectedIndexChanged: selectedIndexChanged)
}

@available(*, unavailable)
Expand Down
173 changes: 173 additions & 0 deletions Sources/BraveWallet/Crypto/MainMenuView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/* Copyright 2023 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import SwiftUI
import Strings
import Preferences

struct MainMenuView: View {

let isFromPortfolio: Bool
@Binding var isShowingSettings: Bool
let keyringStore: KeyringStore

@ObservedObject private var isShowingBalances = Preferences.Wallet.isShowingBalances
@ObservedObject private var isShowingGraph = Preferences.Wallet.isShowingGraph
@ObservedObject private var isShowingNFTs = Preferences.Wallet.isShowingNFTsTab

@Environment(\.presentationMode) @Binding private var presentationMode
@Environment(\.openURL) private var openWalletURL

@ScaledMetric var rowHeight: CGFloat = 52
@State private var viewHeight: CGFloat = 0

var body: some View {
ScrollView {
LazyVStack(spacing: 0) {
Button(action: {
presentationMode.dismiss()
keyringStore.lock()
}) {
MenuRowView(
iconBraveSystemName: "leo.lock",
title: Strings.Wallet.lockWallet
)
}
.frame(height: rowHeight)

Button(action: {
isShowingSettings = true
presentationMode.dismiss()
}) {
MenuRowView(
iconBraveSystemName: "leo.settings",
title: Strings.Wallet.walletSettings
)
}
.frame(height: rowHeight)

if isFromPortfolio {
Divider()
portfolioSettings
}

Divider()
Button(action: {
openWalletURL(WalletConstants.braveWalletSupportURL)
}) {
MenuRowView(
iconBraveSystemName: "leo.help.outline",
title: Strings.Wallet.helpCenter,
accessoryContent: {
Image(braveSystemName: "leo.launch")
.imageScale(.large)
.foregroundColor(Color(braveSystemName: .buttonBackground))
}
)
}
.frame(height: rowHeight)
}
.padding(.vertical, 8)
.readSize { size in
self.viewHeight = size.height
}
}
.background(Color(braveSystemName: .containerBackground))
.osAvailabilityModifiers({ view in
if #available(iOS 16, *) {
view
.presentationDetents([
.height(viewHeight)
])
} else {
view
}
})
}

@ViewBuilder private var portfolioSettings: some View {
MenuRowView(
iconBraveSystemName: "leo.eye.on",
title: Strings.Wallet.balances,
accessoryContent: {
Toggle(isOn: $isShowingBalances.value) {
EmptyView()
}
.tint(Color(braveSystemName: .buttonBackground))
}
)
.frame(height: rowHeight)

MenuRowView(
iconBraveSystemName: "leo.graph",
title: Strings.Wallet.graph,
accessoryContent: {
Toggle(isOn: $isShowingGraph.value) {
EmptyView()
}
.tint(Color(braveSystemName: .buttonBackground))
}
)
.frame(height: rowHeight)

MenuRowView(
iconBraveSystemName: "leo.nft",
title: Strings.Wallet.nftsTab,
accessoryContent: {
Toggle(isOn: $isShowingNFTs.value) {
EmptyView()
}
.tint(Color(braveSystemName: .buttonBackground))
}
)
.frame(height: rowHeight)
}
}

#if DEBUG
struct MainMenuView_Previews: PreviewProvider {
static var previews: some View {
Color.white
.sheet(isPresented: .constant(true), content: {
MainMenuView(
isFromPortfolio: true,
isShowingSettings: .constant(false),
keyringStore: .previewStoreWithWalletCreated
)
})
}
}
#endif

private struct MenuRowView<AccessoryContent: View>: View {

let iconBraveSystemName: String
let title: String
let accessoryContent: () -> AccessoryContent

init(
iconBraveSystemName: String,
title: String,
accessoryContent: @escaping () -> AccessoryContent = { EmptyView() }
) {
self.iconBraveSystemName = iconBraveSystemName
self.title = title
self.accessoryContent = accessoryContent
}

var body: some View {
HStack(spacing: 12) {
Image(braveSystemName: iconBraveSystemName)
.imageScale(.medium)
.foregroundColor(Color(braveSystemName: .iconDefault))
Text(title)
nuo-xu marked this conversation as resolved.
Show resolved Hide resolved
.foregroundColor(Color(braveSystemName: .textPrimary))
Spacer()
accessoryContent()
}
.font(.callout.weight(.semibold))
.padding(.horizontal)
}
}
40 changes: 34 additions & 6 deletions Sources/BraveWallet/Crypto/Portfolio/PortfolioAssetView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import SwiftUI
import Preferences

struct PortfolioAssetView: View {
var image: AssetIconView
Expand All @@ -12,6 +13,27 @@ struct PortfolioAssetView: View {
let networkName: String
var amount: String
var quantity: String
let shouldHideBalance: Bool

@ObservedObject private var isShowingBalances = Preferences.Wallet.isShowingBalances

init(
image: AssetIconView,
title: String,
symbol: String,
networkName: String,
amount: String,
quantity: String,
shouldHideBalance: Bool = false
) {
self.image = image
self.title = title
self.symbol = symbol
self.networkName = networkName
self.amount = amount
self.quantity = quantity
self.shouldHideBalance = shouldHideBalance
}

var body: some View {
AssetView(
Expand All @@ -20,14 +42,20 @@ struct PortfolioAssetView: View {
symbol: symbol,
networkName: networkName,
accessoryContent: {
VStack(alignment: .trailing) {
Text(amount.isEmpty ? "0.0" : amount)
.fontWeight(.semibold)
Text(verbatim: "\(quantity) \(symbol)")
Group {
if shouldHideBalance && !isShowingBalances.value {
Text("****")
} else {
VStack(alignment: .trailing) {
Text(amount.isEmpty ? "0.0" : amount)
.fontWeight(.semibold)
Text(verbatim: "\(quantity) \(symbol)")
}
.multilineTextAlignment(.trailing)
}
}
.font(.footnote)
.foregroundColor(Color(.braveLabel))
.multilineTextAlignment(.trailing)
}
)
.accessibilityLabel("\(title), \(quantity) \(symbol), \(amount)")
Expand Down Expand Up @@ -97,7 +125,7 @@ struct AssetView<ImageView: View, AccessoryContent: View>: View {
let title: String
let symbol: String
let networkName: String
let accessoryContent: () -> AccessoryContent
@ViewBuilder var accessoryContent: () -> AccessoryContent

var body: some View {
HStack {
Expand Down
Loading