diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index f4e1068630..7f7abe48dc 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -703,6 +703,8 @@ 9F7CFF7F2C8A94F70012833E /* OnboardingView+AddressBarPositionContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7CFF7E2C8A94F70012833E /* OnboardingView+AddressBarPositionContent.swift */; }; 9F8007262C5261AF003EDAF4 /* MockPrivacyDataReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8007252C5261AF003EDAF4 /* MockPrivacyDataReporter.swift */; }; 9F8FE9492BAE50E50071E372 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 9F8FE9482BAE50E50071E372 /* Lottie */; }; + 9F96F73B2C9144D5009E45D5 /* Onboarding in Frameworks */ = {isa = PBXBuildFile; productRef = 9F96F73A2C9144D5009E45D5 /* Onboarding */; }; + 9F96F73F2C914C57009E45D5 /* OnboardingGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F96F73E2C914C57009E45D5 /* OnboardingGradient.swift */; }; 9F9A922E2C86A56B001D036D /* OnboardingManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9A922D2C86A56B001D036D /* OnboardingManager.swift */; }; 9F9A92312C86AAE9001D036D /* OnboardingDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9A92302C86AAE9001D036D /* OnboardingDebugView.swift */; }; 9F9A92342C86B42B001D036D /* AppIconPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9A92332C86B42B001D036D /* AppIconPicker.swift */; }; @@ -714,17 +716,16 @@ 9FB027192C26BC29009EA190 /* BrowsersComparisonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB027182C26BC29009EA190 /* BrowsersComparisonModel.swift */; }; 9FB0271B2C2927D0009EA190 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB0271A2C2927D0009EA190 /* OnboardingView.swift */; }; 9FB0271D2C293619009EA190 /* OnboardingIntroViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB0271C2C293619009EA190 /* OnboardingIntroViewModel.swift */; }; - 9FB893F82C784A1700332E5E /* Onboarding in Frameworks */ = {isa = PBXBuildFile; productRef = 9FB893F72C784A1700332E5E /* Onboarding */; }; 9FCFCD802C6AF56D006EB7A0 /* LaunchOptionsHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FCFCD7F2C6AF56D006EB7A0 /* LaunchOptionsHandlerTests.swift */; }; 9FCFCD812C6B020D006EB7A0 /* LaunchOptionsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FCFCD7D2C6AF52A006EB7A0 /* LaunchOptionsHandler.swift */; }; 9FCFCD852C75C91A006EB7A0 /* ProgressBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FCFCD842C75C91A006EB7A0 /* ProgressBarView.swift */; }; 9FDEC7B42C8FD62F00C7A692 /* OnboardingAddressBarPositionPickerViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7B32C8FD62F00C7A692 /* OnboardingAddressBarPositionPickerViewModelTests.swift */; }; - 9FDEC7BC2C91204900C7A692 /* AppIconPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7BB2C91204900C7A692 /* AppIconPickerViewModel.swift */; }; - 9FDEC7BF2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7BE2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift */; }; - 9FDEC7C12C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7C02C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift */; }; 9FDEC7B62C8FDFD600C7A692 /* OnboardingManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7B52C8FDFD600C7A692 /* OnboardingManagerMock.swift */; }; 9FDEC7B82C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7B72C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift */; }; 9FDEC7BA2C9006E000C7A692 /* BrowserComparisonModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7B92C9006E000C7A692 /* BrowserComparisonModelTests.swift */; }; + 9FDEC7BC2C91204900C7A692 /* AppIconPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7BB2C91204900C7A692 /* AppIconPickerViewModel.swift */; }; + 9FDEC7BF2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7BE2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift */; }; + 9FDEC7C12C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDEC7C02C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift */; }; 9FE05CEE2C36424E00D9046B /* OnboardingPixelReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE05CED2C36424E00D9046B /* OnboardingPixelReporter.swift */; }; 9FE05CF12C36468A00D9046B /* OnboardingPixelReporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE05CEF2C3642F900D9046B /* OnboardingPixelReporterTests.swift */; }; 9FE08BD32C2A5B88001D5EBC /* OnboardingTextStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE08BD22C2A5B88001D5EBC /* OnboardingTextStyles.swift */; }; @@ -2494,6 +2495,7 @@ 9F7CFF7C2C89B69A0012833E /* AppIconPickerViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconPickerViewModelTests.swift; sourceTree = ""; }; 9F7CFF7E2C8A94F70012833E /* OnboardingView+AddressBarPositionContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnboardingView+AddressBarPositionContent.swift"; sourceTree = ""; }; 9F8007252C5261AF003EDAF4 /* MockPrivacyDataReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPrivacyDataReporter.swift; sourceTree = ""; }; + 9F96F73E2C914C57009E45D5 /* OnboardingGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingGradient.swift; sourceTree = ""; }; 9F9A922D2C86A56B001D036D /* OnboardingManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingManager.swift; sourceTree = ""; }; 9F9A92302C86AAE9001D036D /* OnboardingDebugView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingDebugView.swift; sourceTree = ""; }; 9F9A92332C86B42B001D036D /* AppIconPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconPicker.swift; sourceTree = ""; }; @@ -2509,12 +2511,12 @@ 9FCFCD7F2C6AF56D006EB7A0 /* LaunchOptionsHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchOptionsHandlerTests.swift; sourceTree = ""; }; 9FCFCD842C75C91A006EB7A0 /* ProgressBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBarView.swift; sourceTree = ""; }; 9FDEC7B32C8FD62F00C7A692 /* OnboardingAddressBarPositionPickerViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAddressBarPositionPickerViewModelTests.swift; sourceTree = ""; }; - 9FDEC7BB2C91204900C7A692 /* AppIconPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconPickerViewModel.swift; sourceTree = ""; }; - 9FDEC7BE2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAddressBarPositionPicker.swift; sourceTree = ""; }; - 9FDEC7C02C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAddressBarPositionPickerViewModel.swift; sourceTree = ""; }; 9FDEC7B52C8FDFD600C7A692 /* OnboardingManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingManagerMock.swift; sourceTree = ""; }; 9FDEC7B72C9004D600C7A692 /* OnboardingIntroViewModel+Copy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnboardingIntroViewModel+Copy.swift"; sourceTree = ""; }; 9FDEC7B92C9006E000C7A692 /* BrowserComparisonModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserComparisonModelTests.swift; sourceTree = ""; }; + 9FDEC7BB2C91204900C7A692 /* AppIconPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconPickerViewModel.swift; sourceTree = ""; }; + 9FDEC7BE2C91264C00C7A692 /* OnboardingAddressBarPositionPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAddressBarPositionPicker.swift; sourceTree = ""; }; + 9FDEC7C02C9127F100C7A692 /* OnboardingAddressBarPositionPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAddressBarPositionPickerViewModel.swift; sourceTree = ""; }; 9FE05CED2C36424E00D9046B /* OnboardingPixelReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPixelReporter.swift; sourceTree = ""; }; 9FE05CEF2C3642F900D9046B /* OnboardingPixelReporterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPixelReporterTests.swift; sourceTree = ""; }; 9FE08BD22C2A5B88001D5EBC /* OnboardingTextStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTextStyles.swift; sourceTree = ""; }; @@ -3017,7 +3019,7 @@ F42D541D29DCA40B004C4FF1 /* DesignResourcesKit in Frameworks */, 85875B6129912A9900115F05 /* SyncUI in Frameworks */, F4D7F634298C00C3006C3AE9 /* FindInPageIOSJSSupport in Frameworks */, - 9FB893F82C784A1700332E5E /* Onboarding in Frameworks */, + 9F96F73B2C9144D5009E45D5 /* Onboarding in Frameworks */, 85D598872927F84C00FA3B1B /* Crashes in Frameworks */, D664C7DD2B28A02800CBFA76 /* StoreKit.framework in Frameworks */, ); @@ -4729,6 +4731,15 @@ path = ContextualOnboarding; sourceTree = ""; }; + 9F96F73D2C914C3D009E45D5 /* Background */ = { + isa = PBXGroup; + children = ( + 9F23B8002C2BC94400950875 /* OnboardingBackground.swift */, + 9F96F73E2C914C57009E45D5 /* OnboardingGradient.swift */, + ); + path = Background; + sourceTree = ""; + }; 9F9A922C2C86A560001D036D /* Manager */ = { isa = PBXGroup; children = ( @@ -4812,6 +4823,7 @@ 9FF7E9802C22A19800902BE5 /* OnboardingExperiment */ = { isa = PBXGroup; children = ( + 9F96F73D2C914C3D009E45D5 /* Background */, 9FDEC7BD2C9125EC00C7A692 /* AddressBarPositionPicker */, 9F9A92322C86B419001D036D /* AppIconPicker */, 9F9A922C2C86A560001D036D /* Manager */, @@ -4822,7 +4834,6 @@ 9FB027172C26BC0F009EA190 /* BrowsersComparison */, 9F23B7FF2C2BABE000950875 /* OnboardingIntro */, 9F5E5AAA2C3D0FAA00165F54 /* ContextualOnboarding */, - 9F23B8002C2BC94400950875 /* OnboardingBackground.swift */, 9FCFCD842C75C91A006EB7A0 /* ProgressBarView.swift */, ); path = OnboardingExperiment; @@ -6444,7 +6455,7 @@ CB941A6D2B96AB08000F9E7A /* PrivacyDashboard */, F1D43AF92B99C1D300BAB743 /* BareBonesBrowserKit */, 9F8FE9482BAE50E50071E372 /* Lottie */, - 9FB893F72C784A1700332E5E /* Onboarding */, + 9F96F73A2C9144D5009E45D5 /* Onboarding */, ); productName = DuckDuckGo; productReference = 84E341921E2F7EFB00BDBA6F /* DuckDuckGo.app */; @@ -7218,6 +7229,7 @@ BDE91CDE2C62B90F0005CB74 /* UnifiedFeedbackRootView.swift in Sources */, D65625A12C232F5E006EF297 /* SettingsDuckPlayerView.swift in Sources */, D6FEB8B52B74994000C3615F /* HeadlessWebViewCoordinator.swift in Sources */, + 9F96F73F2C914C57009E45D5 /* OnboardingGradient.swift in Sources */, 6FE1273D2C204C2500EB5724 /* FavoritesView.swift in Sources */, 8528AE81212F15D600D0BD74 /* AppRatingPrompt.xcdatamodeld in Sources */, 1E24295E293F57FA00584836 /* LottieView.swift in Sources */, @@ -10841,7 +10853,7 @@ repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 193.0.1; + version = 193.0.3; }; }; 9F8FE9472BAE50E50071E372 /* XCRemoteSwiftPackageReference "lottie-spm" */ = { @@ -11046,8 +11058,9 @@ package = 9F8FE9472BAE50E50071E372 /* XCRemoteSwiftPackageReference "lottie-spm" */; productName = Lottie; }; - 9FB893F72C784A1700332E5E /* Onboarding */ = { + 9F96F73A2C9144D5009E45D5 /* Onboarding */ = { isa = XCSwiftPackageProductDependency; + package = 98A16C2928A11BDE00A6C003 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Onboarding; }; B6DFE6D52BC7E47F00A9CE59 /* SwiftLintTool */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index fff3117345..ef85291655 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { - "revision" : "dc04bd2707bd64e743961d88675606c0ea4539b1", - "version" : "193.0.1" + "revision" : "c68e68a0036796628ffdea8d449e5df39ceceb4d", + "version" : "193.0.3" } }, { diff --git a/DuckDuckGo/OnboardingExperiment/OnboardingBackground.swift b/DuckDuckGo/OnboardingExperiment/Background/OnboardingBackground.swift similarity index 78% rename from DuckDuckGo/OnboardingExperiment/OnboardingBackground.swift rename to DuckDuckGo/OnboardingExperiment/Background/OnboardingBackground.swift index 716c0b210b..7e5b6fb531 100644 --- a/DuckDuckGo/OnboardingExperiment/OnboardingBackground.swift +++ b/DuckDuckGo/OnboardingExperiment/Background/OnboardingBackground.swift @@ -18,9 +18,9 @@ // import SwiftUI -import Onboarding struct OnboardingBackground: View { + @Environment(\.onboardingGradientType) private var gradientType @Environment(\.verticalSizeClass) private var vSizeClass @Environment(\.horizontalSizeClass) private var hSizeClass @Environment(\.colorScheme) private var colorScheme @@ -35,7 +35,7 @@ struct OnboardingBackground: View { .opacity(colorScheme == .light ? 0.5 : 0.3) .frame(width: proxy.size.width, height: proxy.size.height, alignment: alignment) .background( - OnboardingGradient() + OnboardingGradientView(type: gradientType) .ignoresSafeArea() ) } @@ -46,13 +46,26 @@ private enum Metrics { static let imageCentering = MetricBuilder(iPhone: .bottomLeading, iPad: .center) } - #Preview("Light Mode") { OnboardingBackground() + .onboardingGradient(.default) .preferredColorScheme(.light) } #Preview("Dark Mode") { OnboardingBackground() + .onboardingGradient(.default) + .preferredColorScheme(.dark) +} + +#Preview("Light Mode - Highlights") { + OnboardingBackground() + .onboardingGradient(.highlights) + .preferredColorScheme(.light) +} + +#Preview("Dark Mode - Highlights") { + OnboardingBackground() + .onboardingGradient(.highlights) .preferredColorScheme(.dark) } diff --git a/DuckDuckGo/OnboardingExperiment/Background/OnboardingGradient.swift b/DuckDuckGo/OnboardingExperiment/Background/OnboardingGradient.swift new file mode 100644 index 0000000000..c5b6fff5a6 --- /dev/null +++ b/DuckDuckGo/OnboardingExperiment/Background/OnboardingGradient.swift @@ -0,0 +1,79 @@ +// +// OnboardingGradient.swift +// DuckDuckGo +// +// Copyright © 2024 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI +import Onboarding + +struct OnboardingGradientView: View { + @Environment(\.colorScheme) private var colorScheme + + private let type: OnboardingGradientType + + init(type: OnboardingGradientType) { + self.type = type + } + + var body: some View { + switch (type, colorScheme) { + case (.default, .light): + linearLightGradient + case (.default, .dark): + linearDarkGradient + case (.highlights, _): + // If highlights experiment use new common gradient for iOS and macOS + OnboardingGradient() + @unknown default: + linearLightGradient + } + } + + private var linearLightGradient: some View { + gradient(colorStops: [ + .init(color: Color(red: 1, green: 0.9, blue: 0.87), location: 0.00), + .init(color: Color(red: 0.99, green: 0.89, blue: 0.87), location: 0.28), + .init(color: Color(red: 0.99, green: 0.89, blue: 0.87), location: 0.46), + .init(color: Color(red: 0.96, green: 0.87, blue: 0.87), location: 0.72), + .init(color: Color(red: 0.9, green: 0.84, blue: 0.92), location: 1.00), + ]) + } + + private var linearDarkGradient: some View { + gradient(colorStops: [ + .init(color: Color(red: 0.29, green: 0.19, blue: 0.25), location: 0.00), + .init(color: Color(red: 0.35, green: 0.23, blue: 0.32), location: 0.28), + .init(color: Color(red: 0.37, green: 0.25, blue: 0.38), location: 0.46), + .init(color: Color(red: 0.2, green: 0.15, blue: 0.32), location: 0.72), + .init(color: Color(red: 0.16, green: 0.15, blue: 0.34), location: 1.00), + ]) + } + + private func gradient(colorStops: [SwiftUI.Gradient.Stop]) -> some View { + LinearGradient( + stops: colorStops, + startPoint: UnitPoint(x: 0.5, y: 0), + endPoint: UnitPoint(x: 0.5, y: 1) + ) + } + +} + +enum OnboardingGradientType { + case `default` + case highlights +} diff --git a/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/NewTabDaxDialogFactory.swift b/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/NewTabDaxDialogFactory.swift index b4ff585bc7..7f6f068844 100644 --- a/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/NewTabDaxDialogFactory.swift +++ b/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/NewTabDaxDialogFactory.swift @@ -32,6 +32,10 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider { private let onboardingPixelReporter: OnboardingPixelReporting private let onboardingManager: OnboardingHighlightsManaging + private var gradientType: OnboardingGradientType { + onboardingManager.isOnboardingHighlightsEnabled ? .highlights : .default + } + init( delegate: OnboardingNavigationDelegate?, contextualOnboardingLogic: ContextualOnboardingLogic, @@ -57,7 +61,6 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider { createFinalDialog(onDismiss: onDismiss) default: EmptyView() - } } @@ -68,7 +71,7 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider { OnboardingTrySearchDialog(message: message, viewModel: viewModel) .onboardingDaxDialogStyle() } - .onboardingContextualBackgroundStyle() + .onboardingContextualBackgroundStyle(background: .illustratedGradient(gradientType)) .onFirstAppear { [weak self] in self?.onboardingPixelReporter.trackScreenImpression(event: .onboardingContextualTrySearchUnique) } @@ -80,7 +83,7 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider { OnboardingTryVisitingSiteDialog(logoPosition: .top, viewModel: viewModel) .onboardingDaxDialogStyle() } - .onboardingContextualBackgroundStyle() + .onboardingContextualBackgroundStyle(background: .illustratedGradient(gradientType)) .onFirstAppear { [weak self] in self?.onboardingPixelReporter.trackScreenImpression(event: .onboardingContextualTryVisitSiteUnique) } @@ -104,7 +107,7 @@ final class NewTabDaxDialogFactory: NewTabDaxDialogProvider { }) .onboardingDaxDialogStyle() } - .onboardingContextualBackgroundStyle() + .onboardingContextualBackgroundStyle(background: .illustratedGradient(gradientType)) .onFirstAppear { [weak self] in self?.contextualOnboardingLogic.setFinalOnboardingDialogSeen() self?.onboardingPixelReporter.trackScreenImpression(event: .daxDialogsEndOfJourneyNewTabUnique) diff --git a/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift b/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift index 570d4dc93e..04fa68f5df 100644 --- a/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift +++ b/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift @@ -50,6 +50,10 @@ final class ExperimentContextualDaxDialogsFactory: ContextualDaxDialogsFactory { private let contextualOnboardingSiteSuggestionsProvider: OnboardingSuggestionsItemsProviding private let onboardingManager: OnboardingHighlightsManaging + private var gradientType: OnboardingGradientType { + onboardingManager.isOnboardingHighlightsEnabled ? .highlights : .default + } + init( contextualOnboardingLogic: ContextualOnboardingLogic, contextualOnboardingSettings: ContextualOnboardingSettings = DefaultDaxDialogsSettings(), @@ -95,7 +99,7 @@ final class ExperimentContextualDaxDialogsFactory: ContextualDaxDialogsFactory { let viewWithBackground = rootView .onboardingDaxDialogStyle() - .onboardingContextualBackgroundStyle() + .onboardingContextualBackgroundStyle(background: .gradientOnly(gradientType)) let hostingController = UIHostingController(rootView: AnyView(viewWithBackground)) if #available(iOS 16.0, *) { hostingController.sizingOptions = [.intrinsicContentSize] diff --git a/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingIntroViewModel.swift b/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingIntroViewModel.swift index 8724b06879..419ea7daf1 100644 --- a/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingIntroViewModel.swift +++ b/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingIntroViewModel.swift @@ -19,12 +19,14 @@ import Foundation import Core +import Onboarding import class UIKit.UIApplication final class OnboardingIntroViewModel: ObservableObject { @Published private(set) var state: OnboardingView.ViewState = .landing let copy: Copy + let gradientType: OnboardingGradientType var onCompletingOnboardingIntro: (() -> Void)? private var introSteps: [OnboardingIntroStep] @@ -50,6 +52,7 @@ final class OnboardingIntroViewModel: ObservableObject { } copy = onboardingManager.isOnboardingHighlightsEnabled ? .highlights : .default + gradientType = onboardingManager.isOnboardingHighlightsEnabled ? .highlights : .default } func onAppear() { diff --git a/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView.swift b/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView.swift index 64a4d56622..cd834e55b2 100644 --- a/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView.swift +++ b/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView.swift @@ -19,7 +19,6 @@ import SwiftUI import Onboarding -import struct DuckUI.PrimaryButtonStyle // MARK: - OnboardingView @@ -57,6 +56,7 @@ struct OnboardingView: View { onboardingDialogView(state: viewState) } } + .onboardingGradient(model.gradientType) } private func onboardingDialogView(state: ViewState.Intro) -> some View { diff --git a/DuckDuckGo/OnboardingExperiment/Styles/DaxDialogStyles.swift b/DuckDuckGo/OnboardingExperiment/Styles/DaxDialogStyles.swift index ea123baec5..881e5fd721 100644 --- a/DuckDuckGo/OnboardingExperiment/Styles/DaxDialogStyles.swift +++ b/DuckDuckGo/OnboardingExperiment/Styles/DaxDialogStyles.swift @@ -33,16 +33,23 @@ extension OnboardingStyles { } struct BackgroundStyle: ViewModifier { + let backgroundType: OnboardingBackgroundType func body(content: Content) -> some View { ZStack { - OnboardingBackground() - .ignoresSafeArea(.keyboard) + switch backgroundType { + case let .illustratedGradient(gradientType): + OnboardingBackground() + .onboardingGradient(gradientType) + .ignoresSafeArea(.keyboard) + case let .gradientOnly(gradientType): + OnboardingGradientView(type: gradientType) + .ignoresSafeArea(.keyboard) + } content } } - } } @@ -57,8 +64,32 @@ extension View { modifier(OnboardingStyles.DaxDialogStyle()) } - func onboardingContextualBackgroundStyle() -> some View { - modifier(OnboardingStyles.BackgroundStyle()) + func onboardingContextualBackgroundStyle(background: OnboardingBackgroundType) -> some View { + modifier(OnboardingStyles.BackgroundStyle(backgroundType: background)) } } + +enum OnboardingBackgroundType { + case illustratedGradient(OnboardingGradientType) + case gradientOnly(OnboardingGradientType) +} + +enum OnboardingGradientTypeKey: EnvironmentKey { + static var defaultValue: OnboardingGradientType = .default +} + +extension EnvironmentValues { + var onboardingGradientType: OnboardingGradientType { + get { self[OnboardingGradientTypeKey.self] } + set { self[OnboardingGradientTypeKey.self] = newValue } + } +} + +extension View { + + func onboardingGradient(_ type: OnboardingGradientType) -> some View { + environment(\.onboardingGradientType, type) + } + +}