From f4a13107439f945f28969f7f6c5eac6ec1cfa941 Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Wed, 18 Oct 2023 11:18:27 -0400 Subject: [PATCH 1/6] Use TabView for wallet instead of page controller. --- .../BraveWallet/Crypto/CryptoPagesView.swift | 263 ------------------ .../BraveWallet/Crypto/CryptoTabsView.swift | 187 +++++++++++++ Sources/BraveWallet/Crypto/CryptoView.swift | 2 +- .../leo.activity.symbolset/Contents.json | 11 + .../leo.coins.symbolset/Contents.json | 11 + .../leo.discover.symbolset/Contents.json | 11 + 6 files changed, 221 insertions(+), 264 deletions(-) delete mode 100644 Sources/BraveWallet/Crypto/CryptoPagesView.swift create mode 100644 Sources/BraveWallet/Crypto/CryptoTabsView.swift create mode 100644 Sources/DesignSystem/Icons/Symbols.xcassets/leo.activity.symbolset/Contents.json create mode 100644 Sources/DesignSystem/Icons/Symbols.xcassets/leo.coins.symbolset/Contents.json create mode 100644 Sources/DesignSystem/Icons/Symbols.xcassets/leo.discover.symbolset/Contents.json diff --git a/Sources/BraveWallet/Crypto/CryptoPagesView.swift b/Sources/BraveWallet/Crypto/CryptoPagesView.swift deleted file mode 100644 index 466cd15288a..00000000000 --- a/Sources/BraveWallet/Crypto/CryptoPagesView.swift +++ /dev/null @@ -1,263 +0,0 @@ -/* Copyright 2021 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 Foundation -import UIKit -import SwiftUI -import BraveCore -import PanModal -import BraveUI -import Strings - -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 - @State private var selectedPageIndex: Int = 0 - - private var isConfirmationButtonVisible: Bool { - if case .transactions(let txs) = cryptoStore.pendingRequest { - return !txs.isEmpty - } - return cryptoStore.pendingRequest != nil - } - - var body: some View { - _CryptoPagesView( - keyringStore: keyringStore, - cryptoStore: cryptoStore, - isShowingPendingRequest: $cryptoStore.isPresentingPendingRequest, - isConfirmationsButtonVisible: isConfirmationButtonVisible, - selectedIndexChanged: { selectedIndex in - selectedPageIndex = selectedIndex - } - ) - .onAppear { - // If a user chooses not to confirm/reject their requests we shouldn't - // do it again until they close and re-open wallet - if !fetchedPendingRequestsThisSession { - // Give the animation time - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - self.fetchedPendingRequestsThisSession = true - self.cryptoStore.prepare(isInitialOpen: true) - } - } - } - .ignoresSafeArea() - .navigationTitle(Strings.Wallet.cryptoTitle) - .navigationBarTitleDisplayMode(.inline) - .introspectViewController(customize: { vc in - vc.navigationItem.do { - let appearance: UINavigationBarAppearance = { - let appearance = UINavigationBarAppearance() - appearance.configureWithOpaqueBackground() - appearance.titleTextAttributes = [.foregroundColor: UIColor.braveLabel] - appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.braveLabel] - appearance.backgroundColor = .braveBackground - appearance.shadowColor = .clear - return appearance - }() - $0.standardAppearance = appearance - $0.compactAppearance = appearance - $0.scrollEdgeAppearance = appearance - } - }) - .background( - NavigationLink( - destination: Web3SettingsView( - settingsStore: cryptoStore.settingsStore, - networkStore: cryptoStore.networkStore, - keyringStore: keyringStore - ), - isActive: $isShowingSettings - ) { - Text(Strings.Wallet.settings) - } - .hidden() - ) - .background( - Color.clear - .sheet(isPresented: $cryptoStore.isPresentingAssetSearch) { - AssetSearchView( - keyringStore: keyringStore, - cryptoStore: cryptoStore, - userAssetsStore: cryptoStore.portfolioStore.userAssetsStore - ) - } - ) - .toolbar { - ToolbarItemGroup(placement: .navigationBarTrailing) { - Button(action: { - cryptoStore.isPresentingAssetSearch = true - }) { - Label(Strings.Wallet.searchTitle, systemImage: "magnifyingglass") - .labelStyle(.iconOnly) - .foregroundColor(Color(.braveBlurpleTint)) - } - 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 - var isConfirmationsButtonVisible: Bool - var selectedIndexChanged: (Int) -> Void - - func makeUIViewController(context: Context) -> CryptoPagesViewController { - CryptoPagesViewController( - keyringStore: keyringStore, - cryptoStore: cryptoStore, - isShowingPendingRequest: isShowingPendingRequest, - selectedIndexChanged: selectedIndexChanged - ) - } - func updateUIViewController(_ uiViewController: CryptoPagesViewController, context: Context) { - uiViewController.pendingRequestsButton.isHidden = !isConfirmationsButtonVisible - } - } -} - -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, - selectedIndexChanged: @escaping (Int) -> Void - ) { - self.keyringStore = keyringStore - self.cryptoStore = cryptoStore - self._isShowingPendingRequest = isShowingPendingRequest - self.selectedIndexChanged = selectedIndexChanged - super.init(selectedIndexChanged: selectedIndexChanged) - } - - @available(*, unavailable) - required init(coder: NSCoder) { - fatalError() - } - - override func viewDidLoad() { - super.viewDidLoad() - - title = Strings.Wallet.cryptoTitle - navigationItem.largeTitleDisplayMode = .never - view.backgroundColor = .braveGroupedBackground - - pages = [ - UIHostingController( - rootView: PortfolioView( - cryptoStore: cryptoStore, - keyringStore: keyringStore, - networkStore: cryptoStore.networkStore, - portfolioStore: cryptoStore.portfolioStore - ) - ).then { - $0.title = Strings.Wallet.portfolioPageTitle - }, - UIHostingController( - rootView: TransactionsActivityView( - store: cryptoStore.transactionsActivityStore, - networkStore: cryptoStore.networkStore - ) - ).then { - $0.title = Strings.Wallet.activityPageTitle - }, - UIHostingController( - rootView: AccountsView( - cryptoStore: cryptoStore, - keyringStore: keyringStore - ) - ).then { - $0.title = Strings.Wallet.accountsPageTitle - }, - UIHostingController( - rootView: MarketView( - cryptoStore: cryptoStore, - keyringStore: keyringStore - ) - ).then { - $0.title = Strings.Wallet.marketPageTitle - }, - ] - - view.addSubview(pendingRequestsButton) - pendingRequestsButton.snp.makeConstraints { - $0.trailing.equalToSuperview().inset(16) - $0.bottom.equalTo(view.safeAreaLayoutGuide).priority(.high) - $0.bottom.lessThanOrEqualTo(view).inset(8) - } - pendingRequestsButton.addTarget(self, action: #selector(tappedPendingRequestsButton), for: .touchUpInside) - } - - @objc private func tappedPendingRequestsButton() { - isShowingPendingRequest = true - } -} - -private class ConfirmationsButton: SpringButton { - private let imageView = UIImageView( - image: UIImage(braveSystemNamed: "leo.notification.dot")! - .applyingSymbolConfiguration(.init(pointSize: 18)) - ).then { - $0.tintColor = .white - } - - override init(frame: CGRect) { - super.init(frame: frame) - - backgroundColor = .braveBlurpleTint - addSubview(imageView) - - imageView.snp.makeConstraints { - $0.center.equalToSuperview() - } - snp.makeConstraints { - $0.width.equalTo(snp.height) - } - - layer.shadowColor = UIColor.black.cgColor - layer.shadowOffset = .init(width: 0, height: 1) - layer.shadowRadius = 1 - layer.shadowOpacity = 0.3 - - accessibilityLabel = Strings.Wallet.confirmTransactionsTitle - } - - override func layoutSubviews() { - super.layoutSubviews() - layer.cornerRadius = bounds.height / 2.0 - layer.shadowPath = UIBezierPath(ovalIn: bounds).cgPath - } - - override var intrinsicContentSize: CGSize { - .init(width: 36, height: 36) - } -} diff --git a/Sources/BraveWallet/Crypto/CryptoTabsView.swift b/Sources/BraveWallet/Crypto/CryptoTabsView.swift new file mode 100644 index 00000000000..da16b757daa --- /dev/null +++ b/Sources/BraveWallet/Crypto/CryptoTabsView.swift @@ -0,0 +1,187 @@ +/* Copyright 2021 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 Foundation +import UIKit +import SwiftUI +import BraveCore +import PanModal +import BraveUI +import Strings + +struct CryptoTabsView: View { + private enum Tab: Equatable, Hashable { + case portfolio + case activity + case accounts + case market + + @ViewBuilder var tabLabel: some View { + switch self { + case .portfolio: + Label(Strings.Wallet.portfolioPageTitle, braveSystemImage: "leo.coins") + case .activity: + Label(Strings.Wallet.activityPageTitle, braveSystemImage: "leo.activity") + case .accounts: + Label(Strings.Wallet.accountsPageTitle, braveSystemImage: "leo.user.accounts") + case .market: + Label(Strings.Wallet.marketPageTitle, braveSystemImage: "leo.discover") + } + } + } + + @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 + @State private var selectedTab: Tab = .portfolio + + private var isConfirmationButtonVisible: Bool { + if case .transactions(let txs) = cryptoStore.pendingRequest { + return !txs.isEmpty + } + return cryptoStore.pendingRequest != nil + } + + var body: some View { + TabView(selection: $selectedTab) { + PortfolioView( + cryptoStore: cryptoStore, + keyringStore: keyringStore, + networkStore: cryptoStore.networkStore, + portfolioStore: cryptoStore.portfolioStore + ) + .tabItem { + Tab.portfolio.tabLabel + } + .tag(Tab.portfolio) + + TransactionsActivityView( + store: cryptoStore.transactionsActivityStore, + networkStore: cryptoStore.networkStore + ) + .tabItem { + Tab.activity.tabLabel + } + .tag(Tab.activity) + + AccountsView( + cryptoStore: cryptoStore, + keyringStore: keyringStore + ) + .tabItem { + Tab.accounts.tabLabel + } + .tag(Tab.accounts) + + MarketView( + cryptoStore: cryptoStore, + keyringStore: keyringStore + ) + .tabItem { + Tab.market.tabLabel + } + .tag(Tab.market) + } + .overlay(alignment: .bottomTrailing, content: { + if isConfirmationButtonVisible { + Button(action: { + cryptoStore.isPresentingPendingRequest = true + }) { + Image(braveSystemName: "leo.notification.dot") + .font(.system(size: 18)) + .foregroundColor(.white) + .frame(width: 36, height: 36) + .background( + Color(uiColor: .braveBlurpleTint) + .clipShape(Circle()) + ) + } + .accessibilityLabel(Text(Strings.Wallet.confirmTransactionsTitle)) + .padding(.trailing, 16) + .padding(.bottom, 100) + } + }) + .onAppear { + // If a user chooses not to confirm/reject their requests we shouldn't + // do it again until they close and re-open wallet + if !fetchedPendingRequestsThisSession { + // Give the animation time + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + self.fetchedPendingRequestsThisSession = true + self.cryptoStore.prepare(isInitialOpen: true) + } + } + } + .ignoresSafeArea() + .navigationTitle(Strings.Wallet.cryptoTitle) + .navigationBarTitleDisplayMode(.inline) + .introspectViewController(customize: { vc in + vc.navigationItem.do { + let appearance: UINavigationBarAppearance = { + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.titleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.backgroundColor = .braveBackground + return appearance + }() + $0.standardAppearance = appearance + $0.compactAppearance = appearance + $0.scrollEdgeAppearance = appearance + } + }) + .background( + NavigationLink( + destination: Web3SettingsView( + settingsStore: cryptoStore.settingsStore, + networkStore: cryptoStore.networkStore, + keyringStore: keyringStore + ), + isActive: $isShowingSettings + ) { + Text(Strings.Wallet.settings) + } + .hidden() + ) + .background( + Color.clear + .sheet(isPresented: $cryptoStore.isPresentingAssetSearch) { + AssetSearchView( + keyringStore: keyringStore, + cryptoStore: cryptoStore, + userAssetsStore: cryptoStore.portfolioStore.userAssetsStore + ) + } + ) + .toolbar { + ToolbarItemGroup(placement: .navigationBarTrailing) { + Button(action: { + cryptoStore.isPresentingAssetSearch = true + }) { + Label(Strings.Wallet.searchTitle, systemImage: "magnifyingglass") + .labelStyle(.iconOnly) + .foregroundColor(Color(.braveBlurpleTint)) + } + 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: selectedTab == .portfolio, + isShowingSettings: $isShowingSettings, + keyringStore: keyringStore + ) + } + } +} diff --git a/Sources/BraveWallet/Crypto/CryptoView.swift b/Sources/BraveWallet/Crypto/CryptoView.swift index 12b0d0d928d..63dee105a13 100644 --- a/Sources/BraveWallet/Crypto/CryptoView.swift +++ b/Sources/BraveWallet/Crypto/CryptoView.swift @@ -313,7 +313,7 @@ private struct CryptoContainerView: View { var body: some View { UIKitNavigationView { - CryptoPagesView(cryptoStore: cryptoStore, keyringStore: keyringStore) + CryptoTabsView(cryptoStore: cryptoStore, keyringStore: keyringStore) .toolbar { toolbarDismissContent } diff --git a/Sources/DesignSystem/Icons/Symbols.xcassets/leo.activity.symbolset/Contents.json b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.activity.symbolset/Contents.json new file mode 100644 index 00000000000..2f415ce6e4c --- /dev/null +++ b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.activity.symbolset/Contents.json @@ -0,0 +1,11 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "idiom" : "universal" + } + ] +} diff --git a/Sources/DesignSystem/Icons/Symbols.xcassets/leo.coins.symbolset/Contents.json b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.coins.symbolset/Contents.json new file mode 100644 index 00000000000..2f415ce6e4c --- /dev/null +++ b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.coins.symbolset/Contents.json @@ -0,0 +1,11 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "idiom" : "universal" + } + ] +} diff --git a/Sources/DesignSystem/Icons/Symbols.xcassets/leo.discover.symbolset/Contents.json b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.discover.symbolset/Contents.json new file mode 100644 index 00000000000..2f415ce6e4c --- /dev/null +++ b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.discover.symbolset/Contents.json @@ -0,0 +1,11 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "idiom" : "universal" + } + ] +} From 497b649b185541782a16ea33e51107a4ef3f6dfa Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Wed, 18 Oct 2023 15:35:44 -0400 Subject: [PATCH 2/6] =?UTF-8?q?Navigation=20structure=20updates;=20each=20?= =?UTF-8?q?tab=20has=20it=E2=80=99s=20own=20`NavigationView`.=20Portfolio?= =?UTF-8?q?=20navigation=20bar=20matches=20Portfolio=20background=20&=20ha?= =?UTF-8?q?s=20no=20shadow=20until=20scrolled.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BraveWallet/Crypto/CryptoTabsView.swift | 207 ++++++++++++------ Sources/BraveWallet/Crypto/CryptoView.swift | 13 +- 2 files changed, 144 insertions(+), 76 deletions(-) diff --git a/Sources/BraveWallet/Crypto/CryptoTabsView.swift b/Sources/BraveWallet/Crypto/CryptoTabsView.swift index da16b757daa..313f2346ce8 100644 --- a/Sources/BraveWallet/Crypto/CryptoTabsView.swift +++ b/Sources/BraveWallet/Crypto/CryptoTabsView.swift @@ -11,8 +11,8 @@ import PanModal import BraveUI import Strings -struct CryptoTabsView: View { - private enum Tab: Equatable, Hashable { +struct CryptoTabsView: View { + private enum Tab: Equatable, Hashable, CaseIterable { case portfolio case activity case accounts @@ -34,9 +34,10 @@ struct CryptoTabsView: View { @ObservedObject var cryptoStore: CryptoStore @ObservedObject var keyringStore: KeyringStore + var toolbarDismissContent: DismissContent @State private var isShowingMainMenu: Bool = false - @State private var isShowingSettings: Bool = false + @State private var isTabShowingSettings: [Tab: Bool] = Tab.allCases.reduce(into: [Tab: Bool]()) { $0[$1] = false } @State private var isShowingSearch: Bool = false @State private var fetchedPendingRequestsThisSession: Bool = false @State private var selectedTab: Tab = .portfolio @@ -50,39 +51,93 @@ struct CryptoTabsView: View { var body: some View { TabView(selection: $selectedTab) { - PortfolioView( - cryptoStore: cryptoStore, - keyringStore: keyringStore, - networkStore: cryptoStore.networkStore, - portfolioStore: cryptoStore.portfolioStore - ) + NavigationView { + PortfolioView( + cryptoStore: cryptoStore, + keyringStore: keyringStore, + networkStore: cryptoStore.networkStore, + portfolioStore: cryptoStore.portfolioStore + ) + .navigationTitle(Strings.Wallet.portfolioPageTitle) + .navigationBarTitleDisplayMode(.inline) + .introspectViewController(customize: { vc in + vc.navigationItem.do { + // no shadow when content is at top. + let noShadowAppearance: UINavigationBarAppearance = { + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.titleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.backgroundColor = UIColor(braveSystemName: .pageBackground) + appearance.shadowColor = .clear + return appearance + }() + $0.scrollEdgeAppearance = noShadowAppearance + $0.compactScrollEdgeAppearance = noShadowAppearance + // shadow when content is scrolled behind navigation bar. + let shadowAppearance: UINavigationBarAppearance = { + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.titleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.backgroundColor = UIColor(braveSystemName: .pageBackground) + return appearance + }() + $0.standardAppearance = shadowAppearance + $0.compactAppearance = shadowAppearance + } + }) + .toolbar { sharedToolbarItems } + .background(settingsNavigationLink(for: .portfolio)) + } .tabItem { Tab.portfolio.tabLabel } .tag(Tab.portfolio) - TransactionsActivityView( - store: cryptoStore.transactionsActivityStore, - networkStore: cryptoStore.networkStore - ) + NavigationView { + TransactionsActivityView( + store: cryptoStore.transactionsActivityStore, + networkStore: cryptoStore.networkStore + ) + .navigationTitle(Strings.Wallet.activityPageTitle) + .navigationBarTitleDisplayMode(.inline) + .applyRegularNavigationAppearance() + .toolbar { sharedToolbarItems } + .background(settingsNavigationLink(for: .activity)) + } .tabItem { Tab.activity.tabLabel } .tag(Tab.activity) - AccountsView( - cryptoStore: cryptoStore, - keyringStore: keyringStore - ) + NavigationView { + AccountsView( + cryptoStore: cryptoStore, + keyringStore: keyringStore + ) + .navigationTitle(Strings.Wallet.accountsPageTitle) + .navigationBarTitleDisplayMode(.inline) + .applyRegularNavigationAppearance() + .toolbar { sharedToolbarItems } + .background(settingsNavigationLink(for: .accounts)) + } .tabItem { Tab.accounts.tabLabel } .tag(Tab.accounts) - MarketView( - cryptoStore: cryptoStore, - keyringStore: keyringStore - ) + NavigationView { + MarketView( + cryptoStore: cryptoStore, + keyringStore: keyringStore + ) + .navigationTitle(Strings.Wallet.marketPageTitle) + .navigationBarTitleDisplayMode(.inline) + .applyRegularNavigationAppearance() + .toolbar { sharedToolbarItems } + .background(settingsNavigationLink(for: .market)) + } .tabItem { Tab.market.tabLabel } @@ -119,36 +174,6 @@ struct CryptoTabsView: View { } } .ignoresSafeArea() - .navigationTitle(Strings.Wallet.cryptoTitle) - .navigationBarTitleDisplayMode(.inline) - .introspectViewController(customize: { vc in - vc.navigationItem.do { - let appearance: UINavigationBarAppearance = { - let appearance = UINavigationBarAppearance() - appearance.configureWithOpaqueBackground() - appearance.titleTextAttributes = [.foregroundColor: UIColor.braveLabel] - appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.braveLabel] - appearance.backgroundColor = .braveBackground - return appearance - }() - $0.standardAppearance = appearance - $0.compactAppearance = appearance - $0.scrollEdgeAppearance = appearance - } - }) - .background( - NavigationLink( - destination: Web3SettingsView( - settingsStore: cryptoStore.settingsStore, - networkStore: cryptoStore.networkStore, - keyringStore: keyringStore - ), - isActive: $isShowingSettings - ) { - Text(Strings.Wallet.settings) - } - .hidden() - ) .background( Color.clear .sheet(isPresented: $cryptoStore.isPresentingAssetSearch) { @@ -159,29 +184,73 @@ struct CryptoTabsView: View { ) } ) - .toolbar { - ToolbarItemGroup(placement: .navigationBarTrailing) { - Button(action: { - cryptoStore.isPresentingAssetSearch = true - }) { - Label(Strings.Wallet.searchTitle, systemImage: "magnifyingglass") - .labelStyle(.iconOnly) - .foregroundColor(Color(.braveBlurpleTint)) - } - 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: selectedTab == .portfolio, - isShowingSettings: $isShowingSettings, + isShowingSettings: Binding(get: { + self.isTabShowingSettings[selectedTab, default: false] + }, set: { isActive, _ in + self.isTabShowingSettings[selectedTab] = isActive + }), keyringStore: keyringStore ) } } + + @ToolbarContentBuilder private var sharedToolbarItems: some ToolbarContent { + ToolbarItemGroup(placement: .navigationBarTrailing) { + Button(action: { + cryptoStore.isPresentingAssetSearch = true + }) { + Label(Strings.Wallet.searchTitle, systemImage: "magnifyingglass") + .labelStyle(.iconOnly) + .foregroundColor(Color(.braveBlurpleTint)) + } + Button(action: { self.isShowingMainMenu = true }) { + Label(Strings.Wallet.otherWalletActionsAccessibilityTitle, braveSystemImage: "leo.more.horizontal") + .labelStyle(.iconOnly) + .foregroundColor(Color(.braveBlurpleTint)) + } + .accessibilityLabel(Strings.Wallet.otherWalletActionsAccessibilityTitle) + } + toolbarDismissContent + } + + private func settingsNavigationLink(for tab: Tab) -> some View { + NavigationLink( + destination: Web3SettingsView( + settingsStore: cryptoStore.settingsStore, + networkStore: cryptoStore.networkStore, + keyringStore: keyringStore + ), + isActive: Binding(get: { + self.isTabShowingSettings[tab, default: false] + }, set: { isActive, _ in + self.isTabShowingSettings[tab] = isActive + }) + ) { + Text(Strings.Wallet.settings) + } + .hidden() + } +} + +private extension View { + func applyRegularNavigationAppearance() -> some View { + introspectViewController(customize: { vc in + vc.navigationItem.do { + let appearance: UINavigationBarAppearance = { + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.titleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.braveLabel] + appearance.backgroundColor = .braveBackground + return appearance + }() + $0.standardAppearance = appearance + $0.compactAppearance = appearance + $0.scrollEdgeAppearance = appearance + } + }) + } } diff --git a/Sources/BraveWallet/Crypto/CryptoView.swift b/Sources/BraveWallet/Crypto/CryptoView.swift index 63dee105a13..d6284c1ba58 100644 --- a/Sources/BraveWallet/Crypto/CryptoView.swift +++ b/Sources/BraveWallet/Crypto/CryptoView.swift @@ -312,12 +312,11 @@ private struct CryptoContainerView: View { } var body: some View { - UIKitNavigationView { - CryptoTabsView(cryptoStore: cryptoStore, keyringStore: keyringStore) - .toolbar { - toolbarDismissContent - } - } + CryptoTabsView( + cryptoStore: cryptoStore, + keyringStore: keyringStore, + toolbarDismissContent: toolbarDismissContent + ) .background( Color.clear .sheet(item: $cryptoStore.buySendSwapDestination) { action in @@ -366,7 +365,7 @@ private struct CryptoContainerView: View { ) .environment( \.buySendSwapDestination, - Binding( + Binding( get: { [weak cryptoStore] in cryptoStore?.buySendSwapDestination }, set: { [weak cryptoStore] destination in if cryptoStore?.isPresentingAssetSearch == true { From 341fede806455b9a2ca180de1cdd6ed691628b26 Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Thu, 19 Oct 2023 09:55:03 -0400 Subject: [PATCH 3/6] Copy update --- Sources/BraveWallet/Crypto/CryptoTabsView.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/BraveWallet/Crypto/CryptoTabsView.swift b/Sources/BraveWallet/Crypto/CryptoTabsView.swift index 313f2346ce8..8af80292dec 100644 --- a/Sources/BraveWallet/Crypto/CryptoTabsView.swift +++ b/Sources/BraveWallet/Crypto/CryptoTabsView.swift @@ -58,7 +58,7 @@ struct CryptoTabsView: View { networkStore: cryptoStore.networkStore, portfolioStore: cryptoStore.portfolioStore ) - .navigationTitle(Strings.Wallet.portfolioPageTitle) + .navigationTitle(Strings.Wallet.wallet) .navigationBarTitleDisplayMode(.inline) .introspectViewController(customize: { vc in vc.navigationItem.do { @@ -100,7 +100,7 @@ struct CryptoTabsView: View { store: cryptoStore.transactionsActivityStore, networkStore: cryptoStore.networkStore ) - .navigationTitle(Strings.Wallet.activityPageTitle) + .navigationTitle(Strings.Wallet.wallet) .navigationBarTitleDisplayMode(.inline) .applyRegularNavigationAppearance() .toolbar { sharedToolbarItems } @@ -116,7 +116,7 @@ struct CryptoTabsView: View { cryptoStore: cryptoStore, keyringStore: keyringStore ) - .navigationTitle(Strings.Wallet.accountsPageTitle) + .navigationTitle(Strings.Wallet.wallet) .navigationBarTitleDisplayMode(.inline) .applyRegularNavigationAppearance() .toolbar { sharedToolbarItems } @@ -132,7 +132,7 @@ struct CryptoTabsView: View { cryptoStore: cryptoStore, keyringStore: keyringStore ) - .navigationTitle(Strings.Wallet.marketPageTitle) + .navigationTitle(Strings.Wallet.wallet) .navigationBarTitleDisplayMode(.inline) .applyRegularNavigationAppearance() .toolbar { sharedToolbarItems } From 3d786960d1427dcb31cadf500dfe5a88baef9b45 Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Thu, 19 Oct 2023 16:49:50 -0400 Subject: [PATCH 4/6] iOS 15 iPad fix --- Sources/BraveWallet/Crypto/CryptoTabsView.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/BraveWallet/Crypto/CryptoTabsView.swift b/Sources/BraveWallet/Crypto/CryptoTabsView.swift index 8af80292dec..6da78aaf0ef 100644 --- a/Sources/BraveWallet/Crypto/CryptoTabsView.swift +++ b/Sources/BraveWallet/Crypto/CryptoTabsView.swift @@ -90,6 +90,7 @@ struct CryptoTabsView: View { .toolbar { sharedToolbarItems } .background(settingsNavigationLink(for: .portfolio)) } + .navigationViewStyle(.stack) .tabItem { Tab.portfolio.tabLabel } @@ -106,6 +107,7 @@ struct CryptoTabsView: View { .toolbar { sharedToolbarItems } .background(settingsNavigationLink(for: .activity)) } + .navigationViewStyle(.stack) .tabItem { Tab.activity.tabLabel } @@ -122,6 +124,7 @@ struct CryptoTabsView: View { .toolbar { sharedToolbarItems } .background(settingsNavigationLink(for: .accounts)) } + .navigationViewStyle(.stack) .tabItem { Tab.accounts.tabLabel } @@ -138,6 +141,7 @@ struct CryptoTabsView: View { .toolbar { sharedToolbarItems } .background(settingsNavigationLink(for: .market)) } + .navigationViewStyle(.stack) .tabItem { Tab.market.tabLabel } From c30e143712dd734667bf030680c9c469032c4655 Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Fri, 20 Oct 2023 10:11:03 -0400 Subject: [PATCH 5/6] Fix shimmer causing navigation items to animate --- Sources/BraveUI/SwiftUI/Shimmer.swift | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Sources/BraveUI/SwiftUI/Shimmer.swift b/Sources/BraveUI/SwiftUI/Shimmer.swift index e856d1f9ca1..97098cd7ee5 100644 --- a/Sources/BraveUI/SwiftUI/Shimmer.swift +++ b/Sources/BraveUI/SwiftUI/Shimmer.swift @@ -38,16 +38,10 @@ private struct ShimmerViewModifier: ViewModifier { endPoint: points.1 ) .onAppear { - if #available(iOS 16, *) { + DispatchQueue.main.async { [self] in // Need this due to a SwiftUI bug… withAnimation(animation) { points = (.trailing, UnitPoint(x: 2, y: 0.5)) } - } else { - DispatchQueue.main.async { [self] in // Need this due to a SwiftUI bug… - withAnimation(animation) { - points = (.trailing, UnitPoint(x: 2, y: 0.5)) - } - } } } } From 492443cb1188d1df264df6c30ac6d7d220bfe4f1 Mon Sep 17 00:00:00 2001 From: Stephen Heaps Date: Fri, 20 Oct 2023 11:58:29 -0400 Subject: [PATCH 6/6] Address PR comments; unneeded imports & opaque tab bar. --- Sources/BraveWallet/Crypto/CryptoTabsView.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sources/BraveWallet/Crypto/CryptoTabsView.swift b/Sources/BraveWallet/Crypto/CryptoTabsView.swift index 6da78aaf0ef..f0f5b3f643c 100644 --- a/Sources/BraveWallet/Crypto/CryptoTabsView.swift +++ b/Sources/BraveWallet/Crypto/CryptoTabsView.swift @@ -6,8 +6,6 @@ import Foundation import UIKit import SwiftUI -import BraveCore -import PanModal import BraveUI import Strings @@ -147,6 +145,13 @@ struct CryptoTabsView: View { } .tag(Tab.market) } + .introspectTabBarController(customize: { tabBarController in + let appearance = UITabBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = UIColor(braveSystemName: .containerBackground) + tabBarController.tabBar.standardAppearance = appearance + tabBarController.tabBar.scrollEdgeAppearance = appearance + }) .overlay(alignment: .bottomTrailing, content: { if isConfirmationButtonVisible { Button(action: {