diff --git a/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift b/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift index b9260ff9178f..6da43ac69969 100644 --- a/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift +++ b/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift @@ -12,6 +12,7 @@ import Combine import Data import SnapKit import BraveUI +import LocalAuthentication protocol TabTrayDelegate: AnyObject { /// Notifies the delegate that order of tabs on tab tray has changed. @@ -600,7 +601,12 @@ class TabTrayController: AuthenticationController { @objc func togglePrivateModeAction() { if !privateMode, Preferences.Privacy.privateBrowsingLock.value { - askForAuthentication(viewType: .tabTray) + askForAuthentication(viewType: .tabTray) { [weak self] success, error in + if !success, error == LAError.passcodeNotSet { + // If Pin code is not set in this device, private mode is enabled default + self?.toggleModeChanger() + } + } } else { toggleModeChanger() } diff --git a/Sources/Brave/Frontend/Settings/AdblockDebugMenuTableViewController.swift b/Sources/Brave/Frontend/Settings/Debug/AdblockDebugMenuTableViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/AdblockDebugMenuTableViewController.swift rename to Sources/Brave/Frontend/Settings/Debug/AdblockDebugMenuTableViewController.swift diff --git a/Sources/Brave/Frontend/Settings/Brave Search/BraveSearchDebugMenu.swift b/Sources/Brave/Frontend/Settings/Debug/Brave Search/BraveSearchDebugMenu.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Brave Search/BraveSearchDebugMenu.swift rename to Sources/Brave/Frontend/Settings/Debug/Brave Search/BraveSearchDebugMenu.swift diff --git a/Sources/Brave/Frontend/Settings/Brave Search/BraveSearchDebugMenuDetail.swift b/Sources/Brave/Frontend/Settings/Debug/Brave Search/BraveSearchDebugMenuDetail.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Brave Search/BraveSearchDebugMenuDetail.swift rename to Sources/Brave/Frontend/Settings/Debug/Brave Search/BraveSearchDebugMenuDetail.swift diff --git a/Sources/Brave/Frontend/Settings/Brave Search/BraveSearchLogEntry.swift b/Sources/Brave/Frontend/Settings/Debug/Brave Search/BraveSearchLogEntry.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Brave Search/BraveSearchLogEntry.swift rename to Sources/Brave/Frontend/Settings/Debug/Brave Search/BraveSearchLogEntry.swift diff --git a/Sources/Brave/Frontend/Settings/BraveCoreDebugSwitchesView.swift b/Sources/Brave/Frontend/Settings/Debug/BraveCoreDebugSwitchesView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/BraveCoreDebugSwitchesView.swift rename to Sources/Brave/Frontend/Settings/Debug/BraveCoreDebugSwitchesView.swift diff --git a/Sources/Brave/Frontend/Settings/LocalStateInspectorView.swift b/Sources/Brave/Frontend/Settings/Debug/LocalStateInspectorView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/LocalStateInspectorView.swift rename to Sources/Brave/Frontend/Settings/Debug/LocalStateInspectorView.swift diff --git a/Sources/Brave/Frontend/Settings/RetentionPreferencesDebugMenuViewController.swift b/Sources/Brave/Frontend/Settings/Debug/RetentionPreferencesDebugMenuViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/RetentionPreferencesDebugMenuViewController.swift rename to Sources/Brave/Frontend/Settings/Debug/RetentionPreferencesDebugMenuViewController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/QA/RewardsDebugSettingsViewController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/QA/RewardsDebugSettingsViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/QA/RewardsDebugSettingsViewController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/QA/RewardsDebugSettingsViewController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/QA/RewardsInternalsAutoContributeController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/QA/RewardsInternalsAutoContributeController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/QA/RewardsInternalsAutoContributeController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/QA/RewardsInternalsAutoContributeController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/QA/RewardsInternalsDebugViewController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/QA/RewardsInternalsDebugViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/QA/RewardsInternalsDebugViewController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/QA/RewardsInternalsDebugViewController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsContributionListController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsContributionListController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsContributionListController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsContributionListController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsContributionPublishersListController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsContributionPublishersListController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsContributionPublishersListController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsContributionPublishersListController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsLogController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsLogController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsLogController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsLogController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsPromotionListController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsPromotionListController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsPromotionListController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsPromotionListController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsSharable.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsSharable.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsSharable.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsSharable.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsShareController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsShareController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsShareController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsShareController.swift diff --git a/Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsViewController.swift b/Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Rewards Internals/RewardsInternalsViewController.swift rename to Sources/Brave/Frontend/Settings/Debug/Rewards Internals/RewardsInternalsViewController.swift diff --git a/Sources/Brave/Frontend/Settings/SandboxInspectorView.swift b/Sources/Brave/Frontend/Settings/Debug/SandboxInspectorView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/SandboxInspectorView.swift rename to Sources/Brave/Frontend/Settings/Debug/SandboxInspectorView.swift diff --git a/Sources/Brave/Frontend/Settings/VPNLogs.swift b/Sources/Brave/Frontend/Settings/Debug/VPNLogsViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/VPNLogs.swift rename to Sources/Brave/Frontend/Settings/Debug/VPNLogsViewController.swift diff --git a/Sources/Brave/Frontend/Settings/MediaSettingsView.swift b/Sources/Brave/Frontend/Settings/Display/MediaSettingsView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/MediaSettingsView.swift rename to Sources/Brave/Frontend/Settings/Display/MediaSettingsView.swift diff --git a/Sources/Brave/Frontend/Settings/NTPTableViewController.swift b/Sources/Brave/Frontend/Settings/Display/NTPTableViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/NTPTableViewController.swift rename to Sources/Brave/Frontend/Settings/Display/NTPTableViewController.swift diff --git a/Sources/Brave/Frontend/Settings/BraveRewardsSettingsViewController.swift b/Sources/Brave/Frontend/Settings/Features/BraveRewardsSettingsViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/BraveRewardsSettingsViewController.swift rename to Sources/Brave/Frontend/Settings/Features/BraveRewardsSettingsViewController.swift diff --git a/Sources/Brave/Frontend/Settings/PlaylistSettingsViewController.swift b/Sources/Brave/Frontend/Settings/Features/PlaylistSettingsViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/PlaylistSettingsViewController.swift rename to Sources/Brave/Frontend/Settings/Features/PlaylistSettingsViewController.swift diff --git a/Sources/Brave/Frontend/Settings/Shields/AdvancedShieldSettings.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/AdvancedShieldSettings.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Shields/AdvancedShieldSettings.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/AdvancedShieldSettings.swift diff --git a/Sources/Brave/Frontend/Settings/Shields/AdvancedShieldsSettingsView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/AdvancedShieldsSettingsView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Shields/AdvancedShieldsSettingsView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/AdvancedShieldsSettingsView.swift diff --git a/Sources/Brave/Frontend/Settings/Shields/ClearDataSectionView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ClearDataSectionView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Shields/ClearDataSectionView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ClearDataSectionView.swift diff --git a/Sources/Brave/Frontend/Settings/Clearables.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/Clearables.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Clearables.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/Clearables.swift diff --git a/Sources/Brave/Frontend/Settings/Shields/DefaultShieldsSectionView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/DefaultShieldsSectionView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Shields/DefaultShieldsSectionView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/DefaultShieldsSectionView.swift diff --git a/Sources/Brave/Frontend/Settings/FilterListAddURLView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListAddURLView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/FilterListAddURLView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListAddURLView.swift diff --git a/Sources/Brave/Frontend/Settings/FilterListsView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListsView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/FilterListsView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/FilterLists/FilterListsView.swift diff --git a/Sources/Brave/Frontend/Settings/ManageWebsiteDataView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ManageWebsiteDataView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/ManageWebsiteDataView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ManageWebsiteDataView.swift diff --git a/Sources/Brave/Frontend/Settings/Shields/OtherPrivacySettingsSectionView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/OtherPrivacySettingsSectionView.swift similarity index 78% rename from Sources/Brave/Frontend/Settings/Shields/OtherPrivacySettingsSectionView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/OtherPrivacySettingsSectionView.swift index f214e228fe4a..97c98aa393d8 100644 --- a/Sources/Brave/Frontend/Settings/Shields/OtherPrivacySettingsSectionView.swift +++ b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/OtherPrivacySettingsSectionView.swift @@ -53,26 +53,6 @@ struct OtherPrivacySettingsSectionView: View { }) ) }) - - if !Preferences.Privacy.privateBrowsingOnly.value { - OptionToggleView(title: Strings.persistentPrivateBrowsing, - subtitle: nil, - option: Preferences.Privacy.persistentPrivateBrowsing) { newValue in - Task { @MainActor in - if newValue { - settings.tabManager.saveAllTabs() - } else { - let tabs = settings.tabManager.allTabs.filter({ $0.isPrivate }) - SessionTab.deleteAll(tabIds: tabs.map({ $0.id })) - - if !settings.tabManager.privateBrowsingManager.isPrivateBrowsing { - settings.tabManager.willSwitchTabMode(leavingPBM: true) - } - } - } - } - } - ShieldToggleView( title: Strings.blockMobileAnnoyances, subtitle: nil, diff --git a/Sources/Brave/Frontend/Settings/PrivacyReportSettingsView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/PrivacyReportSettingsView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/PrivacyReportSettingsView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/PrivacyReportSettingsView.swift diff --git a/Sources/Brave/Frontend/Settings/Shields/ShieldLabelView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ShieldLabelView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Shields/ShieldLabelView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ShieldLabelView.swift diff --git a/Sources/Brave/Frontend/Settings/Shields/ShieldToggleView.swift b/Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ShieldToggleView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/Shields/ShieldToggleView.swift rename to Sources/Brave/Frontend/Settings/Features/ShieldsPrivacy/ShieldToggleView.swift diff --git a/Sources/Brave/Frontend/Settings/SearchCustomEngineViewController.swift b/Sources/Brave/Frontend/Settings/General/SearchEngines/SearchCustomEngineViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/SearchCustomEngineViewController.swift rename to Sources/Brave/Frontend/Settings/General/SearchEngines/SearchCustomEngineViewController.swift diff --git a/Sources/Brave/Frontend/Settings/SearchEnginePicker.swift b/Sources/Brave/Frontend/Settings/General/SearchEngines/SearchEnginePicker.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/SearchEnginePicker.swift rename to Sources/Brave/Frontend/Settings/General/SearchEngines/SearchEnginePicker.swift diff --git a/Sources/Brave/Frontend/Settings/SearchQuickEnginesViewController.swift b/Sources/Brave/Frontend/Settings/General/SearchEngines/SearchQuickEnginesViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/SearchQuickEnginesViewController.swift rename to Sources/Brave/Frontend/Settings/General/SearchEngines/SearchQuickEnginesViewController.swift diff --git a/Sources/Brave/Frontend/Settings/SearchSettingsTableViewController.swift b/Sources/Brave/Frontend/Settings/General/SearchEngines/SearchSettingsTableViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/SearchSettingsTableViewController.swift rename to Sources/Brave/Frontend/Settings/General/SearchEngines/SearchSettingsTableViewController.swift diff --git a/Sources/Brave/Frontend/Settings/ShortcutSettingsViewController.swift b/Sources/Brave/Frontend/Settings/General/ShortcutSettingsViewController.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/ShortcutSettingsViewController.swift rename to Sources/Brave/Frontend/Settings/General/ShortcutSettingsViewController.swift diff --git a/Sources/Brave/Frontend/Settings/WebsiteRedirectsSettingsView.swift b/Sources/Brave/Frontend/Settings/General/WebsiteRedirectsSettingsView.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/WebsiteRedirectsSettingsView.swift rename to Sources/Brave/Frontend/Settings/General/WebsiteRedirectsSettingsView.swift diff --git a/Sources/Brave/Frontend/Settings/PasscodeSettingsViewController.swift b/Sources/Brave/Frontend/Settings/PasscodeSettingsViewController.swift deleted file mode 100644 index 381a12705612..000000000000 --- a/Sources/Brave/Frontend/Settings/PasscodeSettingsViewController.swift +++ /dev/null @@ -1,89 +0,0 @@ -/* 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 LocalAuthentication -import Static -import SwiftKeychainWrapper -import Shared -import BraveUI -import Preferences -import UIKit - -class PasscodeSettingsViewController: TableViewController { - - init() { - super.init(style: .grouped) - } - - @available(*, unavailable) - required init?(coder aDecoder: NSCoder) { - fatalError() - } - - override func viewDidLoad() { - super.viewDidLoad() - - navigationItem.title = titleForTouchIDState - - tableView.accessibilityIdentifier = "PasscodeSettingsViewController.tableView" - tableView.separatorColor = .braveSeparator - tableView.backgroundColor = .braveGroupedBackground - } - - override func viewWillAppear(_ animated: Bool) { - reloadSections() - } - - func reloadSections() { - dataSource.sections = [ - .init( - rows: [.boolRow(title: titleForTouchIDState, option: Preferences.Privacy.lockWithPasscode)] - ) - ] - } - - private var deviceBiometryType: LABiometryType { - let context = LAContext() - if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) { - return context.biometryType - } - return .none - } - - var titleForTouchIDState: String { - switch deviceBiometryType { - case .faceID: - return Strings.authenticationFaceIDPasscodeSetting - case .touchID: - return Strings.authenticationTouchIDPasscodeSetting - case .none: - return Strings.authenticationPasscode - @unknown default: - return Strings.authenticationPasscode - } - } -} - -class DisabledCell: Value1Cell { - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - - selectionStyle = .none - textLabel?.textColor = .lightGray - } - - override var accessoryView: UIView? { - didSet { - if let control = accessoryView as? UIControl { - control.isEnabled = false - } - } - } - - @available(*, unavailable) - required init?(coder aDecoder: NSCoder) { - fatalError() - } -} diff --git a/Sources/Brave/Frontend/Settings/SettingsViewController.swift b/Sources/Brave/Frontend/Settings/SettingsViewController.swift index c8aeb242363c..f22291d32b45 100644 --- a/Sources/Brave/Frontend/Settings/SettingsViewController.swift +++ b/Sources/Brave/Frontend/Settings/SettingsViewController.swift @@ -449,6 +449,19 @@ class SettingsViewController: TableViewController { } tabs.rows.append(autoCloseTabsRow) + + if !Preferences.Privacy.privateBrowsingOnly.value { + let privateTabsRow = Row( + text: Strings.TabsSettings.privateTabsSettingsTitle, + selection: { [unowned self] in + let vc = UIHostingController(rootView: PrivateTabsView(tabManager: tabManager)) + self.navigationController?.pushViewController(vc, animated: true) + }, + image: UIImage(braveSystemNamed: "leo.product.private-window"), + accessory: .disclosureIndicator) + + tabs.rows.append(privateTabsRow) + } return tabs }() @@ -594,11 +607,6 @@ class SettingsViewController: TableViewController { detailText: Strings.Privacy.browserLockDescription, option: Preferences.Privacy.lockWithPasscode, image: UIImage(braveSystemNamed: "leo.biometric.login")), - .boolRow( - title: Strings.Privacy.privateBrowsingLock, - detailText: Strings.Privacy.privateBrowsingLockDescription, - option: Preferences.Privacy.privateBrowsingLock, - image: UIImage(braveSystemNamed: "leo.lock")), Row( text: Strings.Login.loginListNavigationTitle, selection: { [unowned self] in @@ -607,7 +615,7 @@ class SettingsViewController: TableViewController { windowProtection: self.windowProtection) loginsPasswordsViewController.settingsDelegate = self.settingsDelegate self.navigationController?.pushViewController(loginsPasswordsViewController, animated: true) - }, image: UIImage(braveSystemNamed: "leo.outside"), accessory: .disclosureIndicator), + }, image: UIImage(braveSystemNamed: "leo.outside"), accessory: .disclosureIndicator) ] ) }() diff --git a/Sources/Brave/Frontend/Settings/LocationViewPositionPickerCell.swift b/Sources/Brave/Frontend/Settings/Tabs/LocationViewPositionPickerCell.swift similarity index 100% rename from Sources/Brave/Frontend/Settings/LocationViewPositionPickerCell.swift rename to Sources/Brave/Frontend/Settings/Tabs/LocationViewPositionPickerCell.swift diff --git a/Sources/Brave/Frontend/Settings/Tabs/PrivateTabsView.swift b/Sources/Brave/Frontend/Settings/Tabs/PrivateTabsView.swift new file mode 100644 index 000000000000..44d0c0d5ff74 --- /dev/null +++ b/Sources/Brave/Frontend/Settings/Tabs/PrivateTabsView.swift @@ -0,0 +1,117 @@ +// 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 BraveStrings +import Preferences +import BraveUI +import Data +import LocalAuthentication + +struct PrivateTabsView: View { + enum AuthenticationType { + case faceID, touchID, pinCode, noAuthentication + } + + @ObservedObject var privateBrowsingOnly = Preferences.Privacy.privateBrowsingOnly + var tabManager: TabManager? + + private var localAuthenticationType: AuthenticationType { + let context = LAContext() + + if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) { + switch context.biometryType { + case .faceID: + return .faceID + case .touchID: + return .touchID + default: + return .noAuthentication + } + } + + var error: NSError? + let policyEvaluation = context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) + + if policyEvaluation { + return .pinCode + } + + return .noAuthentication + } + + private var browsingLockTitle: String { + var title: String + + switch localAuthenticationType { + case .faceID: + title = Strings.TabsSettings.privateBrowsingLockTitleFaceID + case .touchID: + title = Strings.TabsSettings.privateBrowsingLockTitleTouchID + default: + title = Strings.TabsSettings.privateBrowsingLockTitlePinCode + } + + return title + } + + var body: some View { + Form { + Section( + header: Text(Strings.TabsSettings.privateTabsSettingsTitle.uppercased()), + footer: privateBrowsingOnly.value ? Text("") : Text(Strings.TabsSettings.persistentPrivateBrowsingDescription)) { + if !privateBrowsingOnly.value { + OptionToggleView(title: Strings.TabsSettings.persistentPrivateBrowsingTitle, + subtitle: nil, + option: Preferences.Privacy.persistentPrivateBrowsing) { newValue in + Task { @MainActor in + if newValue { + tabManager?.saveAllTabs() + } else { + if let tabs = tabManager?.allTabs.filter({ $0.isPrivate }) { + SessionTab.deleteAll(tabIds: tabs.map({ $0.id })) + } + + if tabManager?.privateBrowsingManager.isPrivateBrowsing == true { + tabManager?.willSwitchTabMode(leavingPBM: true) + } + } + } + } + } + + switch localAuthenticationType { + case .faceID, .touchID, .pinCode: + OptionToggleView(title: browsingLockTitle, + subtitle: nil, + option: Preferences.Privacy.privateBrowsingLock) + case .noAuthentication: + Toggle(isOn: .constant(false)) { + VStack(alignment: .leading, spacing: 4) { + Text(browsingLockTitle) + .foregroundColor(Color(.bravePrimary)) + } + .opacity(0.25) + } + .disabled(true) + .listRowBackground(Color(.secondaryBraveGroupedBackground)) + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + } + } + .listRowBackground(Color(.secondaryBraveGroupedBackground)) + } + .navigationBarTitle(Strings.TabsSettings.privateTabsSettingsTitle) + .navigationBarTitleDisplayMode(.inline) + .listBackgroundColor(Color(UIColor.braveGroupedBackground)) + } +} + +#if DEBUG +struct PrivateTabsView_Previews: PreviewProvider { + static var previews: some View { + PrivateTabsView() + } +} +#endif diff --git a/Sources/Brave/Frontend/Widgets/LoadingViewController.swift b/Sources/Brave/Frontend/Widgets/LoadingViewController.swift index a49e6a3860c2..4e5f8012bcbc 100644 --- a/Sources/Brave/Frontend/Widgets/LoadingViewController.swift +++ b/Sources/Brave/Frontend/Widgets/LoadingViewController.swift @@ -70,8 +70,12 @@ public class AuthenticationController: LoadingViewController { } if !windowProtection.isPassCodeAvailable { - showSetPasscodeError(viewType: viewType) { + if viewType == .tabTray { completion?(false, LAError.passcodeNotSet) + } else { + showSetPasscodeError(viewType: viewType) { + completion?(false, LAError.passcodeNotSet) + } } } else { windowProtection.presentAuthenticationForViewController( @@ -91,7 +95,7 @@ public class AuthenticationController: LoadingViewController { alert.addAction( UIAlertAction(title: Strings.OKString, style: .default, handler: { _ in - completion() + completion() }) ) diff --git a/Sources/BraveStrings/BraveStrings.swift b/Sources/BraveStrings/BraveStrings.swift index fd3ee904328f..40fd463bcd5a 100644 --- a/Sources/BraveStrings/BraveStrings.swift +++ b/Sources/BraveStrings/BraveStrings.swift @@ -3340,16 +3340,6 @@ extension Strings { "BrowserLockDescription", tableName: "BraveShared", bundle: .module, value: "Unlock Brave with Touch ID, Face ID or system passcode.", comment: "Description for setting to enable the browser lock privacy feature") - public static let privateBrowsingLock = - NSLocalizedString( - "privacy.private.browsing.lock.title", tableName: "BraveShared", bundle: .module, - value: "Private Browsing Lock", - comment: "Title for setting to enable the private browsing lock privacy feature") - public static let privateBrowsingLockDescription = - NSLocalizedString( - "privacy.private.browsing.lock.description", tableName: "BraveShared", bundle: .module, - value: "Require Passcode to Unlock Private Browsing", - comment: "Description for setting to enable the browser lock privacy feature") public static let tabTraySetPasscodeAlertDescription = NSLocalizedString( "privacy.tab.tray.passcode.alert", @@ -3360,6 +3350,41 @@ extension Strings { } } +extension Strings { + public struct TabsSettings { + public static let privateTabsSettingsTitle = + NSLocalizedString( + "tabs.settings.privateTabsSettingsTitle", tableName: "BraveShared", bundle: .module, + value: "Private Tabs", + comment: "") + public static let privateBrowsingLockTitleFaceID = + NSLocalizedString( + "tabs.settings.privateBrowsingLockTitleFaceID", tableName: "BraveShared", bundle: .module, + value: "Require Face ID", + comment: "") + public static let privateBrowsingLockTitleTouchID = + NSLocalizedString( + "tabs.settings.privateBrowsingLockTitleTouchID", tableName: "BraveShared", bundle: .module, + value: "Require Touch ID", + comment: "") + public static let privateBrowsingLockTitlePinCode = + NSLocalizedString( + "tabs.settings.privateBrowsingLockTitlePinCode", tableName: "BraveShared", bundle: .module, + value: "Require Pin Code", + comment: "") + public static let persistentPrivateBrowsingTitle = + NSLocalizedString( + "tabs.settings.persistentPrivateBrowsingTitle", tableName: "BraveShared", bundle: .module, + value: "Keep Private Tabs", + comment: "") + public static let persistentPrivateBrowsingDescription = + NSLocalizedString( + "tabs.settings.persistentPrivateBrowsingTitle", tableName: "BraveShared", bundle: .module, + value: "Keep private browsing tabs open when you close the app, ensuring private browsing sessions continue seamlessly.", + comment: "") + } +} + extension Strings { public struct Login { public static let loginListEmptyScreenTitle =