From 7c6e8b86521ff0297623a025b3b373f3f77fd552 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 19 Nov 2024 19:58:21 +0600 Subject: [PATCH] Hide Next Cards options when all cards are closed --- .../Utilities/UserDefaultsWrapper.swift | 1 + .../Model/HomePageContinueSetUpModel.swift | 75 +++++++++++-------- DuckDuckGo/HomePage/View/HomePageView.swift | 4 +- DuckDuckGo/Menus/MainMenuActions.swift | 3 + .../Model/AppearancePreferences.swift | 13 +++- .../View/PreferencesAppearanceView.swift | 2 +- 6 files changed, 62 insertions(+), 36 deletions(-) diff --git a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift index 5f2c958186..a3eb277f3d 100644 --- a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift +++ b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift @@ -133,6 +133,7 @@ public struct UserDefaultsWrapper { case homePageIsContinueSetupVisible = "home.page.is.continue.setup.visible" case continueSetUpCardsLastDemonstrated = "home.page.contiune.setup.last.demonstrated" case continueSetUpCardsNumberOfDaysDemonstrated = "home.page.contiune.setup.demo.days" + case continueSetUpCardsClosed = "home.page.contiune.setup.cards.closed" case homePageIsRecentActivityVisible = "home.page.is.recent.activity.visible" case homePageIsSearchBarVisible = "home.page.is.search.bar.visible" case homePageIsFirstSession = "home.page.is.first.session" diff --git a/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift b/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift index 30308ec465..c457c86b13 100644 --- a/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift +++ b/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift @@ -61,23 +61,36 @@ extension HomePage.Models { } } - @UserDefaultsWrapper(key: .homePageShowMakeDefault, defaultValue: true) - private var shouldShowMakeDefaultSetting: Bool + struct Settings { + @UserDefaultsWrapper(key: .homePageShowMakeDefault, defaultValue: true) + var shouldShowMakeDefaultSetting: Bool - @UserDefaultsWrapper(key: .homePageShowAddToDock, defaultValue: true) - private var shouldShowAddToDockSetting: Bool + @UserDefaultsWrapper(key: .homePageShowAddToDock, defaultValue: true) + var shouldShowAddToDockSetting: Bool - @UserDefaultsWrapper(key: .homePageShowImport, defaultValue: true) - private var shouldShowImportSetting: Bool + @UserDefaultsWrapper(key: .homePageShowImport, defaultValue: true) + var shouldShowImportSetting: Bool - @UserDefaultsWrapper(key: .homePageShowDuckPlayer, defaultValue: true) - private var shouldShowDuckPlayerSetting: Bool + @UserDefaultsWrapper(key: .homePageShowDuckPlayer, defaultValue: true) + var shouldShowDuckPlayerSetting: Bool - @UserDefaultsWrapper(key: .homePageShowEmailProtection, defaultValue: true) - private var shouldShowEmailProtectionSetting: Bool + @UserDefaultsWrapper(key: .homePageShowEmailProtection, defaultValue: true) + var shouldShowEmailProtectionSetting: Bool - @UserDefaultsWrapper(key: .homePageIsFirstSession, defaultValue: true) - private var isFirstSession: Bool + @UserDefaultsWrapper(key: .homePageIsFirstSession, defaultValue: true) + var isFirstSession: Bool + + func clear() { + _shouldShowMakeDefaultSetting.clear() + _shouldShowAddToDockSetting.clear() + _shouldShowImportSetting.clear() + _shouldShowDuckPlayerSetting.clear() + _shouldShowEmailProtectionSetting.clear() + _isFirstSession.clear() + } + } + + private let settings: Settings var isMoreOrLessButtonNeeded: Bool { return featuresMatrix.count > itemsRowCountWhenCollapsed @@ -87,7 +100,7 @@ extension HomePage.Models { return !featuresMatrix.isEmpty } - lazy var listOfFeatures = isFirstSession ? firstRunFeatures : randomisedFeatures + lazy var listOfFeatures = settings.isFirstSession ? firstRunFeatures : randomisedFeatures private var featuresMatrix: [[FeatureType]] = [[]] { didSet { @@ -113,6 +126,7 @@ extension HomePage.Models { self.duckPlayerPreferences = duckPlayerPreferences self.privacyConfigurationManager = privacyConfigurationManager self.subscriptionManager = subscriptionManager + self.settings = .init() refreshFeaturesMatrix() @@ -171,15 +185,15 @@ extension HomePage.Models { func removeItem(for featureType: FeatureType) { switch featureType { case .defaultBrowser: - shouldShowMakeDefaultSetting = false + settings.shouldShowMakeDefaultSetting = false case .dock: - shouldShowAddToDockSetting = false + settings.shouldShowAddToDockSetting = false case .importBookmarksAndPasswords: - shouldShowImportSetting = false + settings.shouldShowImportSetting = false case .duckplayer: - shouldShowDuckPlayerSetting = false + settings.shouldShowDuckPlayerSetting = false case .emailProtection: - shouldShowEmailProtectionSetting = false + settings.shouldShowEmailProtectionSetting = false } refreshFeaturesMatrix() } @@ -187,6 +201,9 @@ extension HomePage.Models { func refreshFeaturesMatrix() { var features: [FeatureType] = [] appendFeatureCards(&features) + if features.isEmpty { + AppearancePreferences.shared.continueSetUpCardsClosed = true + } featuresMatrix = features.chunked(into: itemsPerRow) } @@ -214,14 +231,14 @@ extension HomePage.Models { // Helper Functions @MainActor @objc private func newTabOpenNotification(_ notification: Notification) { - if !isFirstSession { + if !settings.isFirstSession { listOfFeatures = randomisedFeatures } #if DEBUG - isFirstSession = false + settings.isFirstSession = false #endif if OnboardingViewModel.isOnboardingFinished { - isFirstSession = false + settings.isFirstSession = false } } @@ -252,33 +269,27 @@ extension HomePage.Models { } private var shouldMakeDefaultCardBeVisible: Bool { - shouldShowMakeDefaultSetting && - !defaultBrowserProvider.isDefault + settings.shouldShowMakeDefaultSetting && !defaultBrowserProvider.isDefault } private var shouldDockCardBeVisible: Bool { #if !APPSTORE - shouldShowAddToDockSetting && - !dockCustomizer.isAddedToDock + settings.shouldShowAddToDockSetting && !dockCustomizer.isAddedToDock #else return false #endif } private var shouldImportCardBeVisible: Bool { - shouldShowImportSetting && - !dataImportProvider.didImport + settings.shouldShowImportSetting && !dataImportProvider.didImport } private var shouldDuckPlayerCardBeVisible: Bool { - shouldShowDuckPlayerSetting && - duckPlayerPreferences.duckPlayerModeBool == nil && - !duckPlayerPreferences.youtubeOverlayAnyButtonPressed + settings.shouldShowDuckPlayerSetting && duckPlayerPreferences.duckPlayerModeBool == nil && !duckPlayerPreferences.youtubeOverlayAnyButtonPressed } private var shouldEmailProtectionCardBeVisible: Bool { - shouldShowEmailProtectionSetting && - !emailManager.isSignedIn + settings.shouldShowEmailProtectionSetting && !emailManager.isSignedIn } } diff --git a/DuckDuckGo/HomePage/View/HomePageView.swift b/DuckDuckGo/HomePage/View/HomePageView.swift index b8f9391591..f4bf993166 100644 --- a/DuckDuckGo/HomePage/View/HomePageView.swift +++ b/DuckDuckGo/HomePage/View/HomePageView.swift @@ -104,7 +104,7 @@ extension HomePage.Views { .contextMenu(menuItems: sectionsVisibilityContextMenuItems) if settingsVisibilityModel.isSettingsVisible { - SettingsView(includingContinueSetUpCards: model.isContinueSetUpAvailable && !model.isContinueSetUpCardsViewOutdated, + SettingsView(includingContinueSetUpCards: model.isContinueSetUpAvailable && !model.isContinueSetUpCardsViewOutdated && !model.continueSetUpCardsClosed, isSettingsVisible: $settingsVisibilityModel.isSettingsVisible) .frame(width: Self.settingsPanelWidth) .transition(.move(edge: .trailing)) @@ -240,7 +240,7 @@ extension HomePage.Views { Toggle(UserText.newTabMenuItemShowSearchBar, isOn: $model.isSearchBarVisible) .toggleStyle(.checkbox) } - if model.isContinueSetUpAvailable && !model.isContinueSetUpCardsViewOutdated { + if model.isContinueSetUpAvailable && !model.isContinueSetUpCardsViewOutdated && !model.continueSetUpCardsClosed { Toggle(UserText.newTabMenuItemShowContinuteSetUp, isOn: $model.isContinueSetUpVisible) .toggleStyle(.checkbox) .visibility(continueSetUpModel.hasContent ? .visible : .gone) diff --git a/DuckDuckGo/Menus/MainMenuActions.swift b/DuckDuckGo/Menus/MainMenuActions.swift index 110028be07..098503cfde 100644 --- a/DuckDuckGo/Menus/MainMenuActions.swift +++ b/DuckDuckGo/Menus/MainMenuActions.swift @@ -771,7 +771,10 @@ extension MainViewController { AppearancePreferencesUserDefaultsPersistor().continueSetUpCardsLastDemonstrated = nil AppearancePreferencesUserDefaultsPersistor().continueSetUpCardsNumberOfDaysDemonstrated = 0 AppearancePreferences.shared.isContinueSetUpCardsViewOutdated = false + AppearancePreferences.shared.continueSetUpCardsClosed = false AppearancePreferences.shared.isContinueSetUpVisible = true + HomePage.Models.ContinueSetUpModel.Settings().clear() + NotificationCenter.default.post(name: NSApplication.didBecomeActiveNotification, object: NSApp) } @objc func debugShiftNewTabOpeningDate(_ sender: Any?) { diff --git a/DuckDuckGo/Preferences/Model/AppearancePreferences.swift b/DuckDuckGo/Preferences/Model/AppearancePreferences.swift index 796e43e8a5..43fc227272 100644 --- a/DuckDuckGo/Preferences/Model/AppearancePreferences.swift +++ b/DuckDuckGo/Preferences/Model/AppearancePreferences.swift @@ -31,6 +31,7 @@ protocol AppearancePreferencesPersistor { var isContinueSetUpVisible: Bool { get set } var continueSetUpCardsLastDemonstrated: Date? { get set } var continueSetUpCardsNumberOfDaysDemonstrated: Int { get set } + var continueSetUpCardsClosed: Bool { get set } var isRecentActivityVisible: Bool { get set } var isSearchBarVisible: Bool { get set } var showBookmarksBar: Bool { get set } @@ -62,6 +63,9 @@ struct AppearancePreferencesUserDefaultsPersistor: AppearancePreferencesPersisto @UserDefaultsWrapper(key: .continueSetUpCardsNumberOfDaysDemonstrated, defaultValue: 0) var continueSetUpCardsNumberOfDaysDemonstrated: Int + @UserDefaultsWrapper(key: .continueSetUpCardsClosed, defaultValue: false) + var continueSetUpCardsClosed: Bool + @UserDefaultsWrapper(key: .homePageIsRecentActivityVisible, defaultValue: true) var isRecentActivityVisible: Bool @@ -222,9 +226,15 @@ final class AppearancePreferences: ObservableObject { @Published var isContinueSetUpCardsViewOutdated: Bool + @Published var continueSetUpCardsClosed: Bool { + didSet { + persistor.continueSetUpCardsClosed = continueSetUpCardsClosed + } + } + var isContinueSetUpVisible: Bool { get { - return persistor.isContinueSetUpVisible && !isContinueSetUpCardsViewOutdated + return persistor.isContinueSetUpVisible && !persistor.continueSetUpCardsClosed && !isContinueSetUpCardsViewOutdated } set { persistor.isContinueSetUpVisible = newValue @@ -333,6 +343,7 @@ final class AppearancePreferences: ObservableObject { self.homePageNavigator = homePageNavigator self.dateTimeProvider = dateTimeProvider self.isContinueSetUpCardsViewOutdated = persistor.continueSetUpCardsNumberOfDaysDemonstrated >= Constants.dismissNextStepsCardsAfterDays + self.continueSetUpCardsClosed = persistor.continueSetUpCardsClosed currentThemeName = .init(rawValue: persistor.currentThemeName) ?? .systemDefault showFullURL = persistor.showFullURL favoritesDisplayMode = persistor.favoritesDisplayMode.flatMap(FavoritesDisplayMode.init) ?? .default diff --git a/DuckDuckGo/Preferences/View/PreferencesAppearanceView.swift b/DuckDuckGo/Preferences/View/PreferencesAppearanceView.swift index a796eb5caf..606e3955ab 100644 --- a/DuckDuckGo/Preferences/View/PreferencesAppearanceView.swift +++ b/DuckDuckGo/Preferences/View/PreferencesAppearanceView.swift @@ -108,7 +108,7 @@ extension Preferences { if addressBarModel.shouldShowAddressBar { ToggleMenuItem(UserText.newTabSearchBarSectionTitle, isOn: $model.isSearchBarVisible) } - if model.isContinueSetUpAvailable && !model.isContinueSetUpCardsViewOutdated { + if model.isContinueSetUpAvailable && !model.isContinueSetUpCardsViewOutdated && !model.continueSetUpCardsClosed { ToggleMenuItem(UserText.newTabSetUpSectionTitle, isOn: $model.isContinueSetUpVisible) } ToggleMenuItem(UserText.newTabFavoriteSectionTitle, isOn: $model.isFavoriteVisible).accessibilityIdentifier("Preferences.AppearanceView.showFavoritesToggle")