From 8959173b1fc89bcede64c0073784d4a9450bc00b Mon Sep 17 00:00:00 2001 From: Brandon T Date: Tue, 4 Jul 2023 11:06:51 -0400 Subject: [PATCH] Add persistent private browsing alert for existing users Move AppState to the same location as delegates Open context menus like Safari to allow opening URLs in new windows Moved alert for existing users and updated text. Updated icons with leo-sfsymbol --- App/Client.xcodeproj/project.pbxproj | 4 +++ App/iOS/Delegates/AppDelegate.swift | 3 ++ .../iOS/Delegates}/AppState.swift | 13 ++++--- App/iOS/Delegates/SceneDelegate.swift | 11 ++++-- .../Browser/BrowserViewController.swift | 36 ++++++++++--------- ...serViewController+TabManagerDelegate.swift | 4 --- ...rViewController+WKNavigationDelegate.swift | 26 ++++++++++++-- ...ListViewController+TableViewDelegate.swift | 4 +-- .../PlaylistListViewController.swift | 12 +++---- .../Controllers/PlaylistViewController.swift | 18 +++++----- .../PlaylistCarplayManager.swift | 2 +- Sources/Brave/Frontend/Browser/Tab.swift | 1 - .../Tabs/TabBar/TabsBarViewController.swift | 5 --- .../Tabs/TabTray/TabTrayController.swift | 16 +++++++++ .../Brave/Frontend/ClientPreferences.swift | 4 ++- .../Brave/Frontend/Rewards/BraveRewards.swift | 2 +- .../OtherPrivacySettingsSectionView.swift | 20 ++++++----- Sources/BraveStrings/BraveStrings.swift | 4 +++ .../leo.window.symbolset/Contents.json | 11 ++++++ .../Contents.json | 11 ++++++ ...ookieNotificationBlockingConsentView.swift | 2 -- Tests/ClientTests/NavigationRouterTests.swift | 26 +++++++------- Tests/ClientTests/SearchEnginesTests.swift | 2 -- Tests/ClientTests/TabManagerTests.swift | 7 ++-- Tests/ClientTests/TabSessionTests.swift | 3 +- Tests/ClientTests/TestFavicons.swift | 2 +- package-lock.json | 14 ++++---- package.json | 2 +- 28 files changed, 172 insertions(+), 93 deletions(-) rename {Sources/Brave/States => App/iOS/Delegates}/AppState.swift (93%) create mode 100644 Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.symbolset/Contents.json create mode 100644 Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.tab-private.symbolset/Contents.json diff --git a/App/Client.xcodeproj/project.pbxproj b/App/Client.xcodeproj/project.pbxproj index 38fb6f7f048..94bde10100b 100644 --- a/App/Client.xcodeproj/project.pbxproj +++ b/App/Client.xcodeproj/project.pbxproj @@ -75,6 +75,7 @@ CA986FB4298C1254000C6DD8 /* BraveWidgetsModels in Frameworks */ = {isa = PBXBuildFile; productRef = CA986FB3298C1254000C6DD8 /* BraveWidgetsModels */; }; CAADEFE026E2707F0020DC4C /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAADEFDF26E2707F0020DC4C /* SceneDelegate.swift */; }; CAAE653D287C9FCF00FA44A3 /* CPTemplateApplicationSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAAE653C287C9FCF00FA44A3 /* CPTemplateApplicationSceneDelegate.swift */; }; + CABDE77F2A55DD1C00A388A4 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABDE77E2A55DD1C00A388A4 /* AppState.swift */; }; E6231C011B90A44F005ABB0D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = E6231C001B90A44F005ABB0D /* libz.tbd */; }; E6231C051B90A472005ABB0D /* libxml2.2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = E6231C041B90A472005ABB0D /* libxml2.2.tbd */; }; F84B22041A0910F600AAB793 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F84B21E51A0910F600AAB793 /* AppDelegate.swift */; }; @@ -315,6 +316,7 @@ CA0391F7271E143F000EB13C /* SingleStatWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleStatWidget.swift; sourceTree = ""; }; CAADEFDF26E2707F0020DC4C /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; CAAE653C287C9FCF00FA44A3 /* CPTemplateApplicationSceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPTemplateApplicationSceneDelegate.swift; sourceTree = ""; }; + CABDE77E2A55DD1C00A388A4 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; E6231C001B90A44F005ABB0D /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; E6231C041B90A472005ABB0D /* libxml2.2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.2.tbd; path = usr/lib/libxml2.2.tbd; sourceTree = SDKROOT; }; E62AC15F1E956AFC00843532 /* Dev.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Dev.entitlements; sourceTree = ""; }; @@ -606,6 +608,7 @@ children = ( CAAE653C287C9FCF00FA44A3 /* CPTemplateApplicationSceneDelegate.swift */, F84B21E51A0910F600AAB793 /* AppDelegate.swift */, + CABDE77E2A55DD1C00A388A4 /* AppState.swift */, CAADEFDF26E2707F0020DC4C /* SceneDelegate.swift */, ); path = Delegates; @@ -1040,6 +1043,7 @@ 2F4A572429E608C8003454F8 /* BrowserIntents.intentdefinition in Sources */, F84B22041A0910F600AAB793 /* AppDelegate.swift in Sources */, 27BEDCCC28AD37CE0073425E /* BraveWidgets.intentdefinition in Sources */, + CABDE77F2A55DD1C00A388A4 /* AppState.swift in Sources */, CAADEFE026E2707F0020DC4C /* SceneDelegate.swift in Sources */, CAAE653D287C9FCF00FA44A3 /* CPTemplateApplicationSceneDelegate.swift in Sources */, ); diff --git a/App/iOS/Delegates/AppDelegate.swift b/App/iOS/Delegates/AppDelegate.swift index 0e71961dcb6..ca3126b527b 100644 --- a/App/iOS/Delegates/AppDelegate.swift +++ b/App/iOS/Delegates/AppDelegate.swift @@ -176,6 +176,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { if isFirstLaunch { Preferences.PrivacyReports.ntpOnboardingCompleted.value = false + Preferences.Privacy.shouldShowPersistentPrivateBrowsingAlert.value = false + } else { + Preferences.Privacy.shouldShowPersistentPrivateBrowsingAlert.value = false } Preferences.General.isFirstLaunch.value = false diff --git a/Sources/Brave/States/AppState.swift b/App/iOS/Delegates/AppState.swift similarity index 93% rename from Sources/Brave/States/AppState.swift rename to App/iOS/Delegates/AppState.swift index 53055fc9af6..ca17be7eb82 100644 --- a/Sources/Brave/States/AppState.swift +++ b/App/iOS/Delegates/AppState.swift @@ -6,6 +6,7 @@ import Foundation import UIKit import BraveCore +import Brave import Data import RuntimeWarnings import Shared @@ -15,17 +16,21 @@ import Storage import BraveNews import os.log +private let adsRewardsLog = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "ads-rewards") + /// Class that does startup initialization /// Everything in this class can only be execute ONCE /// IE: BraveCore initialization, BuildChannel, Migrations, etc. public class AppState { + private let log = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "app-state") + public static let shared = AppState() public let braveCore: BraveCoreMain public let dau: DAU public let migration: Migration public let profile: Profile - public let rewards: BraveRewards + public let rewards: Brave.BraveRewards public let newsFeedDataSource: FeedDataSource private var didBecomeActive = false @@ -63,7 +68,7 @@ public class AppState { namespace: "TabManagerScreenshots", quality: UIConstants.screenshotQuality) } catch { - Logger.module.error("Failed to create an image store for files: \(self.profile.files.rootPath) and namespace: \"TabManagerScreenshots\": \(error.localizedDescription)") + log.error("Failed to create an image store for files: \(self.profile.files.rootPath) and namespace: \"TabManagerScreenshots\": \(error.localizedDescription)") } return nil }() @@ -193,14 +198,14 @@ public class AppState { } } - private static func migrateAdsConfirmations(for configruation: BraveRewards.Configuration) { + private static func migrateAdsConfirmations(for configuruation: Brave.BraveRewards.Configuration) { // To ensure after a user launches 1.21 that their ads confirmations, viewed count and // estimated payout remain correct. // // This hack is unfortunately neccessary due to a missed migration path when moving // confirmations from ledger to ads, we must extract `confirmations.json` out of ledger's // state file and save it as a new file under the ads directory. - let base = configruation.storageURL + let base = configuruation.storageURL let ledgerStateContainer = base.appendingPathComponent("ledger/random_state.plist") let adsConfirmations = base.appendingPathComponent("ads/confirmations.json") let fm = FileManager.default diff --git a/App/iOS/Delegates/SceneDelegate.swift b/App/iOS/Delegates/SceneDelegate.swift index 58cbe4baa59..d8223ac24fc 100644 --- a/App/iOS/Delegates/SceneDelegate.swift +++ b/App/iOS/Delegates/SceneDelegate.swift @@ -402,7 +402,7 @@ extension SceneDelegate { // Store the scene's activities let windowId: UUID let isPrivate: Bool - var userActivity = userActivity + let urlToOpen: URL? if let userActivity = userActivity { // Restore the scene with the WindowID from the User-Activity @@ -411,6 +411,7 @@ extension SceneDelegate { windowId = UUID(uuidString: windowIdString) ?? UUID() isPrivate = userActivity.userInfo?["isPrivate"] as? Bool == true privateBrowsingManager.isPrivateBrowsing = isPrivate + urlToOpen = userActivity.userInfo?["OpenURL"] as? URL // Create a new session window SessionWindow.createWindow(isPrivate: isPrivate, isSelected: true, uuid: windowId) @@ -427,6 +428,7 @@ extension SceneDelegate { windowId = windowUUID isPrivate = sceneIsPrivate privateBrowsingManager.isPrivateBrowsing = sceneIsPrivate + urlToOpen = scene.session.userInfo?["OpenURL"] as? URL scene.userActivity = BrowserState.userActivity(for: windowId, isPrivate: isPrivate) } else { @@ -461,6 +463,7 @@ extension SceneDelegate { isPrivate = false privateBrowsingManager.isPrivateBrowsing = false + urlToOpen = nil scene.userActivity = BrowserState.userActivity(for: windowId, isPrivate: false) scene.session.userInfo = ["WindowID": windowId.uuidString, @@ -476,7 +479,6 @@ extension SceneDelegate { rewards: rewards, migration: migration, crashedLastSession: crashedLastSession, - rewards: rewards, newsFeedDataSource: newsFeedDataSource, privateBrowsingManager: privateBrowsingManager ) @@ -509,6 +511,11 @@ extension SceneDelegate { currentTabSceneBrowser.moveTab(tabId: tabId, to: browserViewController) } } + + if let urlToOpen = urlToOpen { + browserViewController.loadViewIfNeeded() + browserViewController.switchToTabForURLOrOpen(urlToOpen, isPrivileged: false) + } return browserViewController } diff --git a/Sources/Brave/Frontend/Browser/BrowserViewController.swift b/Sources/Brave/Frontend/Browser/BrowserViewController.swift index 4f7aff68d03..a95e16c980c 100644 --- a/Sources/Brave/Frontend/Browser/BrowserViewController.swift +++ b/Sources/Brave/Frontend/Browser/BrowserViewController.swift @@ -281,7 +281,6 @@ public class BrowserViewController: UIViewController { rewards: BraveRewards, migration: Migration?, crashedLastSession: Bool, - rewards: BraveRewards, newsFeedDataSource: FeedDataSource, privateBrowsingManager: PrivateBrowsingManager ) { @@ -292,7 +291,6 @@ public class BrowserViewController: UIViewController { self.rewards = rewards self.migration = migration self.crashedLastSession = crashedLastSession - self.rewards = rewards self.privateBrowsingManager = privateBrowsingManager self.feedDataSource = newsFeedDataSource feedDataSource.historyAPI = braveCore.historyAPI @@ -1952,6 +1950,25 @@ public class BrowserViewController: UIViewController { } } } + + func openInNewWindow(url: URL?, isPrivate: Bool) { + let activity = BrowserState.userActivity(for: UUID(), isPrivate: isPrivate) + + if let url = url { + activity.addUserInfoEntries(from: ["OpenURL": url]) + } + + let options = UIScene.ActivationRequestOptions().then { + $0.requestingScene = view.window?.windowScene + } + + UIApplication.shared.requestSceneSessionActivation(nil, + userActivity: activity, + options: options, + errorHandler: { error in + Logger.module.error("Error creating new window: \(error)") + }) + } func clearHistoryAndOpenNewTab() { // When PB Only mode is enabled @@ -2496,21 +2513,6 @@ extension BrowserViewController: TabsBarViewControllerDelegate { func tabsBarDidSelectAddNewTab(_ isPrivate: Bool) { openBlankNewTab(attemptLocationFieldFocus: false, isPrivate: isPrivate) } - - func tabsBarDidSelectAddNewWindow(_ isPrivate: Bool) { - let activity = BrowserState.userActivity(for: UUID(), isPrivate: false) - - let options = UIScene.ActivationRequestOptions().then { - $0.requestingScene = view.window?.windowScene - } - - UIApplication.shared.requestSceneSessionActivation(nil, - userActivity: activity, - options: options, - errorHandler: { error in - Logger.module.error("Error creating new window: \(error)") - }) - } func tabsBarDidSelectTab(_ tabsBarController: TabsBarViewController, _ tab: Tab) { if tab == tabManager.selectedTab { return } diff --git a/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+TabManagerDelegate.swift b/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+TabManagerDelegate.swift index 758f6ad15bd..1d7e1018487 100644 --- a/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+TabManagerDelegate.swift +++ b/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+TabManagerDelegate.swift @@ -242,10 +242,6 @@ extension BrowserViewController: TabManagerDelegate { newTabMenuChildren.append(openNewTab) } addTabMenuChildren.append(openNewTab) - - addTabMenuChildren.append(UIAction(title: "New Window", image: UIImage(systemName: "window.horizontal.closed"), handler: UIAction.deferredActionHandler { [unowned self] _ in - self.tabsBarDidSelectAddNewWindow(privateBrowsingManager.isPrivateBrowsing) - })) var bookmarkMenuChildren: [UIAction] = [] diff --git a/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift b/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift index 307e074b482..bde445a8e04 100644 --- a/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift +++ b/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController+WKNavigationDelegate.swift @@ -990,7 +990,6 @@ extension BrowserViewController: WKUIDelegate { } openNewTabAction.accessibilityLabel = "linkContextMenu.openInNewTab" - actions.append(openNewTabAction) } @@ -1001,8 +1000,31 @@ extension BrowserViewController: WKUIDelegate { self.addTab(url: url, inPrivateMode: true, currentTab: currentTab) } openNewPrivateTabAction.accessibilityLabel = "linkContextMenu.openInNewPrivateTab" - actions.append(openNewPrivateTabAction) + + if UIApplication.shared.supportsMultipleScenes { + if !tabType.isPrivate { + let openNewWindowAction = UIAction( + title: Strings.openInNewWindowTitle, + image: UIImage(braveSystemNamed: "leo.window") + ) { _ in + self.openInNewWindow(url: url, isPrivate: false) + } + + openNewWindowAction.accessibilityLabel = "linkContextMenu.openInNewWindow" + actions.append(openNewWindowAction) + } + + let openNewPrivateWindowAction = UIAction( + title: Strings.openInNewPrivateWindowTitle, + image: UIImage(braveSystemNamed: "leo.window.tab-private") + ) { _ in + self.openInNewWindow(url: url, isPrivate: true) + } + + openNewPrivateWindowAction.accessibilityLabel = "linkContextMenu.openInNewPrivateWindow" + actions.append(openNewPrivateWindowAction) + } let copyAction = UIAction( title: Strings.copyLinkActionTitle, diff --git a/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController+TableViewDelegate.swift b/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController+TableViewDelegate.swift index c0f6d3af14e..f5b0fe7f207 100644 --- a/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController+TableViewDelegate.swift +++ b/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController+TableViewDelegate.swift @@ -149,7 +149,7 @@ extension PlaylistListViewController: UITableViewDelegate { handler: { [weak self] (action, view, completionHandler) in guard let self = self else { return } - let isPrivateBrowsing = self.privateBrowsingManager?.isPrivateBrowsing == true + let isPrivateBrowsing = self.isPrivateBrowsing let style: UIAlertController.Style = UIDevice.current.userInterfaceIdiom == .pad ? .alert : .actionSheet let alert = UIAlertController( @@ -244,7 +244,7 @@ extension PlaylistListViewController: UITableViewDelegate { // In Private-Browsing, we do not show "Open in New Tab", // we only show "Open in Private Tab" - let isPrivateBrowsing = self.privateBrowsingManager?.isPrivateBrowsing == true + let isPrivateBrowsing = self.isPrivateBrowsing if !isPrivateBrowsing { actions.append( UIAction( diff --git a/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController.swift b/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController.swift index ccf63578aa3..f28860a6bbc 100644 --- a/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController.swift +++ b/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistListViewController.swift @@ -48,7 +48,7 @@ class PlaylistListViewController: UIViewController { weak var delegate: PlaylistViewControllerDelegate? private let playerView: VideoView - let privateBrowsingManager: PrivateBrowsingManager? + let isPrivateBrowsing: Bool private var observers = Set() private var folderObserver: AnyCancellable? @@ -74,9 +74,9 @@ class PlaylistListViewController: UIViewController { $0.allowsSelectionDuringEditing = true } - init(playerView: VideoView, privateBrowsingManager: PrivateBrowsingManager?) { + init(playerView: VideoView, isPrivateBrowsing: Bool) { self.playerView = playerView - self.privateBrowsingManager = privateBrowsingManager + self.isPrivateBrowsing = isPrivateBrowsing super.init(nibName: nil, bundle: nil) } @@ -641,7 +641,7 @@ extension PlaylistListViewController { activityIndicator.isHidden = false let selectedCell = tableView.cellForRow(at: indexPath) as? PlaylistCell - playerView.setVideoInfo(videoDomain: item.pageSrc, videoTitle: item.pageTitle, isPrivateBrowsing: privateBrowsingManager?.isPrivateBrowsing == true) + playerView.setVideoInfo(videoDomain: item.pageSrc, videoTitle: item.pageTitle, isPrivateBrowsing: isPrivateBrowsing) PlaylistMediaStreamer.setNowPlayingMediaArtwork(image: selectedCell?.iconView.image) completion?(item) } @@ -756,7 +756,7 @@ extension PlaylistListViewController { if let url = URL(string: item.pageSrc) { self.dismiss(animated: true, completion: nil) - let isPrivateBrowsing = self.privateBrowsingManager?.isPrivateBrowsing == true + let isPrivateBrowsing = self.isPrivateBrowsing self.delegate?.openURLInNewTab( url, isPrivate: isPrivateBrowsing, @@ -829,7 +829,7 @@ extension PlaylistListViewController { let pageURL = URL(string: currentItem.pageSrc) { self.dismiss(animated: true) { - let isPrivateBrowsing = self.privateBrowsingManager?.isPrivateBrowsing == true + let isPrivateBrowsing = self.isPrivateBrowsing browser.tabManager.addTabAndSelect( URLRequest(url: pageURL), isPrivate: isPrivateBrowsing) diff --git a/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistViewController.swift b/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistViewController.swift index 7649791dea1..bb7effae2ec 100644 --- a/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistViewController.swift +++ b/Sources/Brave/Frontend/Browser/Playlist/Controllers/PlaylistViewController.swift @@ -49,12 +49,12 @@ class PlaylistViewController: UIViewController { private let player: MediaPlayer private let playerView = VideoView() private let mediaStreamer: PlaylistMediaStreamer - private let privateBrowsingManager: PrivateBrowsingManager? + private let isPrivateBrowsing: Bool private let splitController = UISplitViewController() private let folderController = PlaylistFolderController() - private lazy var listController = PlaylistListViewController(playerView: playerView, privateBrowsingManager: privateBrowsingManager) - private lazy var detailController = PlaylistDetailViewController(isPrivateBrowsing: privateBrowsingManager?.isPrivateBrowsing == true) + private lazy var listController = PlaylistListViewController(playerView: playerView, isPrivateBrowsing: isPrivateBrowsing) + private lazy var detailController = PlaylistDetailViewController(isPrivateBrowsing: isPrivateBrowsing) private var folderObserver: AnyCancellable? private var playerStateObservers = Set() @@ -70,14 +70,14 @@ class PlaylistViewController: UIViewController { mediaPlayer: MediaPlayer, initialItem: PlaylistInfo?, initialItemPlaybackOffset: Double, - privateBrowsingManager: PrivateBrowsingManager? + isPrivateBrowsing: Bool ) { self.openInNewTab = openInNewTab self.openPlaylistSettingsMenu = openPlaylistSettingsMenu self.player = mediaPlayer self.mediaStreamer = PlaylistMediaStreamer(playerView: playerView) - self.privateBrowsingManager = privateBrowsingManager + self.isPrivateBrowsing = isPrivateBrowsing self.folderSharingUrl = nil super.init(nibName: nil, bundle: nil) @@ -315,7 +315,7 @@ class PlaylistViewController: UIViewController { } if let item = PlaylistCarplayManager.shared.currentPlaylistItem { - playerView.setVideoInfo(videoDomain: item.pageSrc, videoTitle: item.pageTitle, isPrivateBrowsing: privateBrowsingManager?.isPrivateBrowsing == true) + playerView.setVideoInfo(videoDomain: item.pageSrc, videoTitle: item.pageTitle, isPrivateBrowsing: isPrivateBrowsing) } else { playerView.resetVideoInfo() } @@ -333,7 +333,7 @@ class PlaylistViewController: UIViewController { self.playerView.setVideoInfo( videoDomain: item.pageSrc, videoTitle: item.pageTitle, - isPrivateBrowsing: self.privateBrowsingManager?.isPrivateBrowsing == true) + isPrivateBrowsing: self.isPrivateBrowsing) } self.listController.highlightActiveItem() @@ -916,7 +916,7 @@ extension PlaylistViewController: VideoViewDelegate { self.playerView.setVideoInfo( videoDomain: item.pageSrc, videoTitle: item.pageTitle, - isPrivateBrowsing: self.privateBrowsingManager?.isPrivateBrowsing == true) + isPrivateBrowsing: self.isPrivateBrowsing) PlaylistMediaStreamer.setNowPlayingInfo(item, withPlayer: self.player) } catch { PlaylistMediaStreamer.clearNowPlayingInfo() @@ -964,7 +964,7 @@ extension PlaylistViewController: VideoViewDelegate { playerView.setVideoInfo( videoDomain: item.pageSrc, videoTitle: item.pageTitle, - isPrivateBrowsing: privateBrowsingManager?.isPrivateBrowsing == true) + isPrivateBrowsing: isPrivateBrowsing) PlaylistMediaStreamer.setNowPlayingInfo(item, withPlayer: self.player) return item diff --git a/Sources/Brave/Frontend/Browser/Playlist/Managers & Cache/PlaylistCarplayManager.swift b/Sources/Brave/Frontend/Browser/Playlist/Managers & Cache/PlaylistCarplayManager.swift index 07c8f1c27d4..ba490f69e0b 100644 --- a/Sources/Brave/Frontend/Browser/Playlist/Managers & Cache/PlaylistCarplayManager.swift +++ b/Sources/Brave/Frontend/Browser/Playlist/Managers & Cache/PlaylistCarplayManager.swift @@ -117,7 +117,7 @@ public class PlaylistCarplayManager: NSObject { mediaPlayer: mediaPlayer, initialItem: initialItem, initialItemPlaybackOffset: initialItemPlaybackOffset, - privateBrowsingManager: browserController?.privateBrowsingManager) + isPrivateBrowsing: browserController?.privateBrowsingManager.isPrivateBrowsing == true) self.mediaPlayer = mediaPlayer return playlistController } diff --git a/Sources/Brave/Frontend/Browser/Tab.swift b/Sources/Brave/Frontend/Browser/Tab.swift index f4c5ffdf967..1eafd4c6421 100644 --- a/Sources/Brave/Frontend/Browser/Tab.swift +++ b/Sources/Brave/Frontend/Browser/Tab.swift @@ -74,7 +74,6 @@ class Tab: NSObject { private(set) var type: TabType = .regular - var redirectURLs = [URL]() var isPrivate: Bool { diff --git a/Sources/Brave/Frontend/Browser/Tabs/TabBar/TabsBarViewController.swift b/Sources/Brave/Frontend/Browser/Tabs/TabBar/TabsBarViewController.swift index ca43f95b353..8eaa815557d 100644 --- a/Sources/Brave/Frontend/Browser/Tabs/TabBar/TabsBarViewController.swift +++ b/Sources/Brave/Frontend/Browser/Tabs/TabBar/TabsBarViewController.swift @@ -13,7 +13,6 @@ protocol TabsBarViewControllerDelegate: AnyObject { func tabsBarDidSelectTab(_ tabsBarController: TabsBarViewController, _ tab: Tab) func tabsBarDidLongPressAddTab(_ tabsBarController: TabsBarViewController, button: UIButton) func tabsBarDidSelectAddNewTab(_ isPrivate: Bool) - func tabsBarDidSelectAddNewWindow(_ isPrivate: Bool) func tabsBarDidChangeReaderModeVisibility(_ isHidden: Bool) } @@ -124,10 +123,6 @@ class TabsBarViewController: UIViewController { }) newTabMenu.append(openNewTab) - - newTabMenu.append(UIAction(title: "New Window", image: UIImage(systemName: "window.horizontal.closed"), handler: UIAction.deferredActionHandler { [unowned self] _ in - self.delegate?.tabsBarDidSelectAddNewWindow(isPrivateBrowsing) - })) plusButton.menu = UIMenu(title: "", identifier: nil, children: newTabMenu) privateModeCancellable = tabManager?.privateBrowsingManager diff --git a/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift b/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift index e194a3b9d43..0139e32059f 100644 --- a/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift +++ b/Sources/Brave/Frontend/Browser/Tabs/TabTray/TabTrayController.swift @@ -618,6 +618,22 @@ class TabTrayController: LoadingViewController { tabTrayView.collectionView.reloadData() navigationController?.setNavigationBarHidden(false, animated: false) } + + if Preferences.Privacy.shouldShowPersistentPrivateBrowsingAlert.value { + Preferences.Privacy.shouldShowPersistentPrivateBrowsingAlert.value = false + + let alert = UIAlertController(title: Strings.persistentPrivateBrowsingAlertTitle, message: Strings.persistentPrivateBrowsingAlertMessage, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: Strings.yes, style: .default) { [unowned self] _ in + Preferences.Privacy.persistentPrivateBrowsing.value = true + self.tabManager.saveAllTabs() + }) + + alert.addAction(UIAlertAction(title: Strings.no, style: .cancel) { _ in + Preferences.Privacy.persistentPrivateBrowsing.value = false + }) + + self.present(alert, animated: true) + } } else { tabTrayView.hidePrivateModeInfo() diff --git a/Sources/Brave/Frontend/ClientPreferences.swift b/Sources/Brave/Frontend/ClientPreferences.swift index 20ce2cbe033..56828a01c4b 100644 --- a/Sources/Brave/Frontend/ClientPreferences.swift +++ b/Sources/Brave/Frontend/ClientPreferences.swift @@ -126,7 +126,9 @@ extension Preferences { /// Forces all private tabs public static let privateBrowsingOnly = Option(key: "privacy.private-only", default: false) /// Whether or not private browsing tabs can be session restored (persistent private browsing) - public static let persistentPrivateBrowsing = Option(key: "privacy.private-browsing-persistence", default: false) + public static let persistentPrivateBrowsing = Option(key: "privacy.private-browsing-persistence", default: true) + /// Whether or not a persistent private browsing alert was shown to existing users + public static let shouldShowPersistentPrivateBrowsingAlert = Option(key: "privacy.private-browsing-persistence-alert", default: false) /// Blocks all cookies and access to local storage static let blockAllCookies = Option(key: "privacy.block-all-cookies", default: false) /// The toggles states for clear private data screen diff --git a/Sources/Brave/Frontend/Rewards/BraveRewards.swift b/Sources/Brave/Frontend/Rewards/BraveRewards.swift index e70e29f0e88..a7a00c9bbd3 100644 --- a/Sources/Brave/Frontend/Rewards/BraveRewards.swift +++ b/Sources/Brave/Frontend/Rewards/BraveRewards.swift @@ -306,7 +306,7 @@ extension BraveRewards { case staging } - var storageURL: URL + public var storageURL: URL public var environment: Environment public var adsBuildChannel: BraveAds.BuildChannelInfo = .init() public var isDebug: Bool? diff --git a/Sources/Brave/Frontend/Settings/Shields/OtherPrivacySettingsSectionView.swift b/Sources/Brave/Frontend/Settings/Shields/OtherPrivacySettingsSectionView.swift index f214e228fe4..99f8c1017e1 100644 --- a/Sources/Brave/Frontend/Settings/Shields/OtherPrivacySettingsSectionView.swift +++ b/Sources/Brave/Frontend/Settings/Shields/OtherPrivacySettingsSectionView.swift @@ -58,15 +58,17 @@ struct OtherPrivacySettingsSectionView: View { 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) + if !Preferences.Privacy.shouldShowPersistentPrivateBrowsingAlert.value { + 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) + } } } } diff --git a/Sources/BraveStrings/BraveStrings.swift b/Sources/BraveStrings/BraveStrings.swift index 1ac7a85c3aa..34836c8b4b5 100644 --- a/Sources/BraveStrings/BraveStrings.swift +++ b/Sources/BraveStrings/BraveStrings.swift @@ -141,6 +141,8 @@ extension Strings { bundle: .module, value: "An unknown error occurred while opening the Downloads folder in the Files app.", comment: "Error description when there is an error while navigating to Files App") + public static let openInNewWindowTitle = NSLocalizedString("OpenInNewWindowTitle", tableName: "BraveShared", bundle: .module, value: "Open in New Window", comment: "Context menu item for opening a link in a new window") + public static let openInNewPrivateWindowTitle = NSLocalizedString("OpenInNewPrivateWindowTitle", tableName: "BraveShared", bundle: .module, value: "Open in New Private Window", comment: "Context menu item for opening a link in a new private browsing window") } // MARK:- DefaultBrowserIntroCalloutViewController.swift @@ -1050,6 +1052,8 @@ extension Strings { public static let youtubeMediaQualityOn = NSLocalizedString("YoutubeMediaQualityOn", tableName: "BraveShared", bundle: .module, value: "Always enabled", comment: "Setting that enables high quality playback always") public static let showTabsBar = NSLocalizedString("ShowTabsBar", tableName: "BraveShared", bundle: .module, value: "Tabs Bar", comment: "Setting to show/hide the tabs bar") public static let privateBrowsingOnly = NSLocalizedString("PrivateBrowsingOnly", tableName: "BraveShared", bundle: .module, value: "Private Browsing Only", comment: "Setting to keep app in private mode") + public static let persistentPrivateBrowsingAlertTitle = NSLocalizedString("PersistentPrivateBrowsingAlertTitle", tableName: "BraveShared", bundle: .module, value: "Restore Private Tabs", comment: "Persistent private browsing alert title to existing users") + public static let persistentPrivateBrowsingAlertMessage = NSLocalizedString("PersistentPrivateBrowsingAlertMessage", tableName: "BraveShared", bundle: .module, value: "Allows Brave to restore private browsing tabs, even if you close / re-open the app", comment: "Persistent private browsing alert message to existing users") public static let persistentPrivateBrowsing = NSLocalizedString("PersistentPrivateBrowsing", tableName: "BraveShared", bundle: .module, value: "Persistent Private Browsing", comment: "Setting to allow the app to restore private browsing tabs") public static let shieldsDefaults = NSLocalizedString("ShieldsDefaults", tableName: "BraveShared", bundle: .module, value: "Brave Shields Global Defaults", comment: "Section title for adbblock, tracking protection, HTTPS-E, and cookies") public static let shieldsDefaultsFooter = NSLocalizedString("ShieldsDefaultsFooter", tableName: "BraveShared", bundle: .module, value: "These are the default Shields settings for new sites. Changing these won't affect your existing per-site settings.", comment: "Section footer for global shields defaults") diff --git a/Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.symbolset/Contents.json b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.symbolset/Contents.json new file mode 100644 index 00000000000..2f415ce6e4c --- /dev/null +++ b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.symbolset/Contents.json @@ -0,0 +1,11 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "idiom" : "universal" + } + ] +} diff --git a/Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.tab-private.symbolset/Contents.json b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.tab-private.symbolset/Contents.json new file mode 100644 index 00000000000..2f415ce6e4c --- /dev/null +++ b/Sources/DesignSystem/Icons/Symbols.xcassets/leo.window.tab-private.symbolset/Contents.json @@ -0,0 +1,11 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "idiom" : "universal" + } + ] +} diff --git a/Sources/Onboarding/ProductNotifications/CookieNotificationBlockingConsentView.swift b/Sources/Onboarding/ProductNotifications/CookieNotificationBlockingConsentView.swift index 93478e880b5..d5ace344006 100644 --- a/Sources/Onboarding/ProductNotifications/CookieNotificationBlockingConsentView.swift +++ b/Sources/Onboarding/ProductNotifications/CookieNotificationBlockingConsentView.swift @@ -148,8 +148,6 @@ public struct CookieNotificationBlockingConsentView: View { } } - - #if DEBUG struct CookieNotificationBlockingConsentView_Previews: PreviewProvider { static var previews: some View { diff --git a/Tests/ClientTests/NavigationRouterTests.swift b/Tests/ClientTests/NavigationRouterTests.swift index 3bd2315d979..193046acb00 100644 --- a/Tests/ClientTests/NavigationRouterTests.swift +++ b/Tests/ClientTests/NavigationRouterTests.swift @@ -9,16 +9,18 @@ import Preferences import XCTest class NavigationRouterTests: XCTestCase { + + private let privateBrowsingManager = PrivateBrowsingManager() override func setUp() { super.setUp() - PrivateBrowsingManager.shared.isPrivateBrowsing = false + privateBrowsingManager.isPrivateBrowsing = false Preferences.Privacy.privateBrowsingOnly.reset() } override func tearDown() { super.tearDown() - PrivateBrowsingManager.shared.isPrivateBrowsing = false + privateBrowsingManager.isPrivateBrowsing = false Preferences.Privacy.privateBrowsingOnly.reset() } @@ -38,7 +40,7 @@ class NavigationRouterTests: XCTestCase { return false } - guard let navItem = NavigationPath(url: appURL) else { + guard let navItem = NavigationPath(url: appURL, isPrivateBrowsing: self.privateBrowsingManager.isPrivateBrowsing) else { XCTFail("Invalid Navigation Path") return false } @@ -55,17 +57,17 @@ class NavigationRouterTests: XCTestCase { // Test URL with double escaped encoded characters (URL was encoded twice) XCTAssertTrue(testURLEncoding("http://google.com%3Fa%3D1%26b%3D2%26c%3Dfoo%2520bar")) - let emptyNav = NavigationPath(url: URL(string: "\(appScheme)://open-url?private=true")!) + let emptyNav = NavigationPath(url: URL(string: "\(appScheme)://open-url?private=true")!, isPrivateBrowsing: privateBrowsingManager.isPrivateBrowsing) XCTAssertEqual(emptyNav, NavigationPath.url(webURL: nil, isPrivate: true)) - let badNav = NavigationPath(url: URL(string: "\(appScheme)://open-url?url=blah")!) + let badNav = NavigationPath(url: URL(string: "\(appScheme)://open-url?url=blah")!, isPrivateBrowsing: privateBrowsingManager.isPrivateBrowsing) XCTAssertEqual(badNav, NavigationPath.url(webURL: URL(string: "blah"), isPrivate: false)) } func testSearchScheme() { let query = "Foo Bar".addingPercentEncoding(withAllowedCharacters: .alphanumerics)! let appURL = "\(appScheme)://search?q=" + query - let navItem = NavigationPath(url: URL(string: appURL)!)! + let navItem = NavigationPath(url: URL(string: appURL)!, isPrivateBrowsing: privateBrowsingManager.isPrivateBrowsing)! XCTAssertEqual(navItem, NavigationPath.text("Foo Bar")) } @@ -73,7 +75,7 @@ class NavigationRouterTests: XCTestCase { func testDefaultNavigationPath() { let url = URL(string: "https://duckduckgo.com")! let appURL = URL(string: "\(self.appScheme)://open-url?url=\(url.absoluteString.escape()!)")! - let path = NavigationPath(url: appURL)! + let path = NavigationPath(url: appURL, isPrivateBrowsing: privateBrowsingManager.isPrivateBrowsing)! XCTAssertEqual(path, NavigationPath.url(webURL: url, isPrivate: false)) } @@ -83,29 +85,29 @@ class NavigationRouterTests: XCTestCase { let url = URL(string: "https://duckduckgo.com")! let appURL = URL(string: "\(self.appScheme)://open-url?url=\(url.absoluteString.escape()!)")! - let path = NavigationPath(url: appURL)! + let path = NavigationPath(url: appURL, isPrivateBrowsing: privateBrowsingManager.isPrivateBrowsing)! // Should inheritely be private by default XCTAssertEqual(path, NavigationPath.url(webURL: url, isPrivate: true)) } func testNavigationPathAlreadyInPrivateBrowsingMode() { - PrivateBrowsingManager.shared.isPrivateBrowsing = true + privateBrowsingManager.isPrivateBrowsing = true let url = URL(string: "https://duckduckgo.com")! let appURL = URL(string: "\(self.appScheme)://open-url?url=\(url.absoluteString.escape()!)")! - let path = NavigationPath(url: appURL)! + let path = NavigationPath(url: appURL, isPrivateBrowsing: privateBrowsingManager.isPrivateBrowsing)! // Should inheritely be private by default XCTAssertEqual(path, NavigationPath.url(webURL: url, isPrivate: true)) } func testNavigationPathForcedRegularMode() { - PrivateBrowsingManager.shared.isPrivateBrowsing = true + privateBrowsingManager.isPrivateBrowsing = true let url = URL(string: "https://duckduckgo.com")! let appURL = URL(string: "\(self.appScheme)://open-url?url=\(url.absoluteString.escape()!)&private=false")! - let path = NavigationPath(url: appURL)! + let path = NavigationPath(url: appURL, isPrivateBrowsing: privateBrowsingManager.isPrivateBrowsing)! // Should be regular due to specified argument in the URL XCTAssertEqual(path, NavigationPath.url(webURL: url, isPrivate: false)) diff --git a/Tests/ClientTests/SearchEnginesTests.swift b/Tests/ClientTests/SearchEnginesTests.swift index be470b2502c..6a75ea6159e 100644 --- a/Tests/ClientTests/SearchEnginesTests.swift +++ b/Tests/ClientTests/SearchEnginesTests.swift @@ -26,8 +26,6 @@ class SearchEnginesTests: XCTestCase { Preferences.Search.defaultEngineName.reset() Preferences.Search.defaultPrivateEngineName.reset() Preferences.Search.yahooEngineMigrationCompleted.reset() - - PrivateBrowsingManager.shared.isPrivateBrowsing = false } func testIncludesExpectedEngines() { diff --git a/Tests/ClientTests/TabManagerTests.swift b/Tests/ClientTests/TabManagerTests.swift index 7f8493b5905..7b2c34f4727 100644 --- a/Tests/ClientTests/TabManagerTests.swift +++ b/Tests/ClientTests/TabManagerTests.swift @@ -107,18 +107,19 @@ open class MockTabManagerDelegate: TabManagerDelegate { let didAdd = MethodSpy(functionName: "tabManager(_:didAddTab:)") var manager: TabManager! + private let privateBrowsingManager = PrivateBrowsingManager() override func setUp() { super.setUp() DataController.shared.initializeOnce() let profile = MockProfile() - manager = TabManager(prefs: profile.prefs, rewards: nil, tabGeneratorAPI: nil) - PrivateBrowsingManager.shared.isPrivateBrowsing = false + manager = TabManager(windowId: UUID(), prefs: profile.prefs, rewards: nil, tabGeneratorAPI: nil, privateBrowsingManager: privateBrowsingManager) + privateBrowsingManager.isPrivateBrowsing = false } override func tearDown() { - PrivateBrowsingManager.shared.isPrivateBrowsing = false + privateBrowsingManager.isPrivateBrowsing = false super.tearDown() } diff --git a/Tests/ClientTests/TabSessionTests.swift b/Tests/ClientTests/TabSessionTests.swift index 3dbd52d6e92..b3b30b391ee 100644 --- a/Tests/ClientTests/TabSessionTests.swift +++ b/Tests/ClientTests/TabSessionTests.swift @@ -77,6 +77,7 @@ private class WebViewNavigationAdapter: NSObject, WKNavigationDelegate { @MainActor class TabSessionTests: XCTestCase { private var tabManager: TabManager! private let maxTimeout = 60.0 + private let privateBrowsingManager = PrivateBrowsingManager() override class func setUp() { super.setUp() @@ -89,7 +90,7 @@ private class WebViewNavigationAdapter: NSObject, WKNavigationDelegate { DataController.shared.initializeOnce() tabManager = { () -> TabManager in let profile = BrowserProfile(localName: "profile") - return TabManager(prefs: profile.prefs, rewards: nil, tabGeneratorAPI: nil) + return TabManager(windowId: UUID(), prefs: profile.prefs, rewards: nil, tabGeneratorAPI: nil, privateBrowsingManager: privateBrowsingManager) }() } diff --git a/Tests/ClientTests/TestFavicons.swift b/Tests/ClientTests/TestFavicons.swift index d70be03b8ec..fee90987000 100644 --- a/Tests/ClientTests/TestFavicons.swift +++ b/Tests/ClientTests/TestFavicons.swift @@ -28,7 +28,7 @@ import Favicon func testImageViewLoad() { let expectation = XCTestExpectation(description: "favicon.load") let imageView = UIImageView() - imageView.loadFavicon(for: URL(string: "http://www.google.de")!, monogramFallbackCharacter: nil) { _ in + imageView.loadFavicon(for: URL(string: "http://www.google.de")!, isPrivateBrowsing: false, monogramFallbackCharacter: nil) { _ in // Should be a default icon therefore not truly async XCTAssertNotNil(imageView.image) expectation.fulfill() diff --git a/package-lock.json b/package-lock.json index a50ff466451..caf22c88817 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@mozilla/readability": "^0.4.2", "brave-core-ios": "https://github.com/brave/brave-browser/releases/download/v1.57.13/brave-core-ios-1.57.13.tgz", - "leo-sf-symbols": "github:brave/leo-sf-symbols#60a41d77d4e58bd48284848a04ad3f9b79bf7daa", + "leo-sf-symbols": "github:brave/leo-sf-symbols#9d272b2fdccdfced7785ee3b527b33df5a33a989", "page-metadata-parser": "^1.1.3", "webpack-cli": "^4.8.0" }, @@ -783,9 +783,9 @@ } }, "node_modules/leo-sf-symbols": { - "version": "1.0.7", - "resolved": "git+ssh://git@github.com/brave/leo-sf-symbols.git#60a41d77d4e58bd48284848a04ad3f9b79bf7daa", - "integrity": "sha512-234URdy8AbdEYRQC+YybQ6JGQiKMztPgBTt6lILS64udhr/3nj0d6pT3xa4mqRhX6TYmSyFRTWxKUjZ2ZmI2SQ==", + "version": "1.0.9", + "resolved": "git+ssh://git@github.com/brave/leo-sf-symbols.git#9d272b2fdccdfced7785ee3b527b33df5a33a989", + "integrity": "sha512-pH1vv7MeTBfORv7rIX8lVBC+7Cs3xk8IRcVVcfZWGsDcza9l2AegWr56xYSGk2HyiTwBzsdMIBkEyOf64QXrlw==", "license": "MPL-2.0" }, "node_modules/loader-runner": { @@ -2055,9 +2055,9 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, "leo-sf-symbols": { - "version": "git+ssh://git@github.com/brave/leo-sf-symbols.git#60a41d77d4e58bd48284848a04ad3f9b79bf7daa", - "integrity": "sha512-234URdy8AbdEYRQC+YybQ6JGQiKMztPgBTt6lILS64udhr/3nj0d6pT3xa4mqRhX6TYmSyFRTWxKUjZ2ZmI2SQ==", - "from": "leo-sf-symbols@github:brave/leo-sf-symbols#60a41d77d4e58bd48284848a04ad3f9b79bf7daa" + "version": "git+ssh://git@github.com/brave/leo-sf-symbols.git#9d272b2fdccdfced7785ee3b527b33df5a33a989", + "integrity": "sha512-pH1vv7MeTBfORv7rIX8lVBC+7Cs3xk8IRcVVcfZWGsDcza9l2AegWr56xYSGk2HyiTwBzsdMIBkEyOf64QXrlw==", + "from": "leo-sf-symbols@github:brave/leo-sf-symbols#9d272b2fdccdfced7785ee3b527b33df5a33a989" }, "loader-runner": { "version": "4.2.0", diff --git a/package.json b/package.json index 4725d50cb23..8cbadc54525 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "dependencies": { "@mozilla/readability": "^0.4.2", "brave-core-ios": "https://github.com/brave/brave-browser/releases/download/v1.57.13/brave-core-ios-1.57.13.tgz", - "leo-sf-symbols": "github:brave/leo-sf-symbols#60a41d77d4e58bd48284848a04ad3f9b79bf7daa", + "leo-sf-symbols": "github:brave/leo-sf-symbols#9d272b2fdccdfced7785ee3b527b33df5a33a989", "page-metadata-parser": "^1.1.3", "webpack-cli": "^4.8.0" },