diff --git a/.maestro/shared/onboarding.yaml b/.maestro/shared/onboarding.yaml index 17bf8ffb35..2117d4205b 100644 --- a/.maestro/shared/onboarding.yaml +++ b/.maestro/shared/onboarding.yaml @@ -14,3 +14,13 @@ appId: com.duckduckgo.mobile.ios # - assertVisible: "Make DuckDuckGo your default browser." - tapOn: text: "Skip" + +- runFlow: + when: + visible: "Which color looks best on me?" + commands: + - assertVisible: "Next" + - tapOn: "Next" + - assertVisible: "Where should I put your address bar?" + - assertVisible: "Next" + - tapOn: "Next" diff --git a/Core/Debouncer.swift b/Core/Debouncer.swift new file mode 100644 index 0000000000..094737b956 --- /dev/null +++ b/Core/Debouncer.swift @@ -0,0 +1,66 @@ +// +// Debouncer.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 Foundation + +/// A class that provides a debouncing mechanism. +public final class Debouncer { + private let runLoop: RunLoop + private let mode: RunLoop.Mode + private var timer: Timer? + + /// Initializes a new instance of `Debouncer`. + /// + /// - Parameters: + /// - runLoop: The `RunLoop` on which the debounced actions will be scheduled. Defaults to the current run loop. + /// + /// - mode: The `RunLoop.Mode` in which the debounced actions will be scheduled. Defaults to `.default`. + /// + /// Use `RunLoop.main` for UI-related actions to ensure they run on the main thread. + public init(runLoop: RunLoop = .current, mode: RunLoop.Mode = .default) { + self.runLoop = runLoop + self.mode = mode + } + + /// Debounces the provided block of code, executing it after a specified time interval elapses. + /// - Parameters: + /// - dueTime: The time interval (in seconds) to wait before executing the block. + /// - block: The closure to execute after the due time has passed. + /// + /// If `dueTime` is less than or equal to zero, the block is executed immediately. + public func debounce(for dueTime: TimeInterval, block: @escaping () -> Void) { + timer?.invalidate() + + guard dueTime > 0 else { return block() } + + let timer = Timer(timeInterval: dueTime, repeats: false, block: { timer in + guard timer.isValid else { return } + block() + }) + + runLoop.add(timer, forMode: mode) + self.timer = timer + } + + /// Cancels any pending execution of the debounced block. + public func cancel() { + timer?.invalidate() + timer = nil + } +} diff --git a/Core/DefaultVariantManager.swift b/Core/DefaultVariantManager.swift index 5ce128d6ec..76f0f8475a 100644 --- a/Core/DefaultVariantManager.swift +++ b/Core/DefaultVariantManager.swift @@ -28,6 +28,8 @@ extension FeatureName { // public static let experimentalFeature = FeatureName(rawValue: "experimentalFeature") public static let newOnboardingIntro = FeatureName(rawValue: "newOnboardingIntro") + public static let newOnboardingIntroHighlights = FeatureName(rawValue: "newOnboardingIntroHighlights") + public static let contextualDaxDialogs = FeatureName(rawValue: "contextualDaxDialogs") } public struct VariantIOS: Variant { @@ -56,8 +58,9 @@ public struct VariantIOS: Variant { VariantIOS(name: "sd", weight: doNotAllocate, isIncluded: When.always, features: []), VariantIOS(name: "se", weight: doNotAllocate, isIncluded: When.always, features: []), - VariantIOS(name: "ma", weight: 1, isIncluded: When.always, features: []), - VariantIOS(name: "mb", weight: 1, isIncluded: When.always, features: [.newOnboardingIntro]), + VariantIOS(name: "ms", weight: 1, isIncluded: When.always, features: [.newOnboardingIntro]), + VariantIOS(name: "mu", weight: 1, isIncluded: When.always, features: [.newOnboardingIntro, .contextualDaxDialogs]), + VariantIOS(name: "mx", weight: 1, isIncluded: When.always, features: [.newOnboardingIntroHighlights, .contextualDaxDialogs]), returningUser ] diff --git a/Core/NSAttributedStringExtension.swift b/Core/NSAttributedStringExtension.swift index c4beb2b327..1660f27721 100644 --- a/Core/NSAttributedStringExtension.swift +++ b/Core/NSAttributedStringExtension.swift @@ -84,6 +84,26 @@ extension NSAttributedString { } } +// MARK: - AttributedString Helper Extensions + +public extension String { + + var attributed: NSAttributedString { + NSAttributedString(string: self) + } + + var nsRange: NSRange { + NSRange(startIndex..., in: self) + } + + func range(of string: String) -> NSRange { + (self as NSString).range(of: string) + } + +} + +// MARK: Helper Operators + /// Concatenates two `NSAttributedString` instances, returning a new `NSAttributedString`. /// /// - Parameters: @@ -115,11 +135,3 @@ public func + (lhs: NSAttributedString, rhs: String) -> NSAttributedString { public func + (lhs: String, rhs: NSAttributedString) -> NSAttributedString { NSAttributedString(string: lhs) + rhs } - -private extension String { - - var nsRange: NSRange { - NSRange(startIndex..., in: self) - } - -} diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 10c3a6b2c2..f9a6a04a9e 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -695,6 +695,9 @@ 98F3A1D8217B37010011A0D4 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F3A1D7217B37010011A0D4 /* Theme.swift */; }; 98F6EA472863124100720957 /* ContentBlockerRulesLists.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F6EA462863124100720957 /* ContentBlockerRulesLists.swift */; }; 98F78B8E22419093007CACF4 /* ThemableNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98F78B8D22419093007CACF4 /* ThemableNavigationController.swift */; }; + 9F16230B2CA0F0190093C4FC /* DebouncerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F16230A2CA0F0190093C4FC /* DebouncerTests.swift */; }; + 9F1061652C9C013F008DD5A0 /* DefaultVariantManager+Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F1061642C9C013F008DD5A0 /* DefaultVariantManager+Onboarding.swift */; }; + 9F1623092C9D14F10093C4FC /* DefaultVariantManagerOnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F1623082C9D14F10093C4FC /* DefaultVariantManagerOnboardingTests.swift */; }; 9F23B8012C2BC94400950875 /* OnboardingBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F23B8002C2BC94400950875 /* OnboardingBackground.swift */; }; 9F23B8032C2BCD0000950875 /* DaxDialogStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F23B8022C2BCD0000950875 /* DaxDialogStyles.swift */; }; 9F23B8062C2BE22700950875 /* OnboardingIntroViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F23B8052C2BE22700950875 /* OnboardingIntroViewModelTests.swift */; }; @@ -709,6 +712,7 @@ 9F5E5AAC2C3D0FCD00165F54 /* ContextualDaxDialogsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F5E5AAB2C3D0FCD00165F54 /* ContextualDaxDialogsFactory.swift */; }; 9F5E5AB02C3E4C6000165F54 /* ContextualOnboardingPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F5E5AAF2C3E4C6000165F54 /* ContextualOnboardingPresenter.swift */; }; 9F5E5AB22C3E606D00165F54 /* ContextualOnboardingPresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F5E5AB12C3E606D00165F54 /* ContextualOnboardingPresenterTests.swift */; }; + 9F678B892C9BAA4800CA0E19 /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F678B882C9BAA4800CA0E19 /* Debouncer.swift */; }; 9F6933192C59BB0300CD6A5D /* OnboardingPixelReporterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6933182C59BB0300CD6A5D /* OnboardingPixelReporterMock.swift */; }; 9F69331B2C5A16E200CD6A5D /* OnboardingDaxFavouritesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F69331A2C5A16E200CD6A5D /* OnboardingDaxFavouritesTests.swift */; }; 9F69331D2C5A191400CD6A5D /* MockTutorialSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F69331C2C5A191400CD6A5D /* MockTutorialSettings.swift */; }; @@ -2503,6 +2507,9 @@ 98F3A1D7217B37010011A0D4 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; 98F6EA462863124100720957 /* ContentBlockerRulesLists.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentBlockerRulesLists.swift; sourceTree = ""; }; 98F78B8D22419093007CACF4 /* ThemableNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemableNavigationController.swift; sourceTree = ""; }; + 9F16230A2CA0F0190093C4FC /* DebouncerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebouncerTests.swift; sourceTree = ""; }; + 9F1061642C9C013F008DD5A0 /* DefaultVariantManager+Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultVariantManager+Onboarding.swift"; sourceTree = ""; }; + 9F1623082C9D14F10093C4FC /* DefaultVariantManagerOnboardingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultVariantManagerOnboardingTests.swift; sourceTree = ""; }; 9F23B8002C2BC94400950875 /* OnboardingBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingBackground.swift; sourceTree = ""; }; 9F23B8022C2BCD0000950875 /* DaxDialogStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaxDialogStyles.swift; sourceTree = ""; }; 9F23B8052C2BE22700950875 /* OnboardingIntroViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingIntroViewModelTests.swift; sourceTree = ""; }; @@ -2517,6 +2524,7 @@ 9F5E5AAB2C3D0FCD00165F54 /* ContextualDaxDialogsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextualDaxDialogsFactory.swift; sourceTree = ""; }; 9F5E5AAF2C3E4C6000165F54 /* ContextualOnboardingPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextualOnboardingPresenter.swift; sourceTree = ""; }; 9F5E5AB12C3E606D00165F54 /* ContextualOnboardingPresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextualOnboardingPresenterTests.swift; sourceTree = ""; }; + 9F678B882C9BAA4800CA0E19 /* Debouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = ""; }; 9F6933182C59BB0300CD6A5D /* OnboardingPixelReporterMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPixelReporterMock.swift; sourceTree = ""; }; 9F69331A2C5A16E200CD6A5D /* OnboardingDaxFavouritesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingDaxFavouritesTests.swift; sourceTree = ""; }; 9F69331C2C5A191400CD6A5D /* MockTutorialSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTutorialSettings.swift; sourceTree = ""; }; @@ -4773,6 +4781,7 @@ 9F7CFF7C2C89B69A0012833E /* AppIconPickerViewModelTests.swift */, 9FDEC7B32C8FD62F00C7A692 /* OnboardingAddressBarPositionPickerViewModelTests.swift */, 9FDEC7B92C9006E000C7A692 /* BrowserComparisonModelTests.swift */, + 9F1623082C9D14F10093C4FC /* DefaultVariantManagerOnboardingTests.swift */, ); name = Onboarding; sourceTree = ""; @@ -4898,6 +4907,7 @@ 9F23B7FF2C2BABE000950875 /* OnboardingIntro */, 9F5E5AAA2C3D0FAA00165F54 /* ContextualOnboarding */, 9FCFCD842C75C91A006EB7A0 /* ProgressBarView.swift */, + 9F1061642C9C013F008DD5A0 /* DefaultVariantManager+Onboarding.swift */, ); path = OnboardingExperiment; sourceTree = ""; @@ -5901,6 +5911,7 @@ 56D855692BEA9169009F9698 /* CurrentDateProviding.swift */, 9FE08BD92C2A86D0001D5EBC /* URLOpener.swift */, 9FEA22312C3270BD006B03BF /* TimerInterface.swift */, + 9F678B882C9BAA4800CA0E19 /* Debouncer.swift */, ); name = Utilities; sourceTree = ""; @@ -6047,6 +6058,7 @@ 8341D804212D5DFB000514C2 /* HashExtensionTest.swift */, 1CB7B82223CEA28300AA24EA /* DateExtensionTests.swift */, 4BC21A2C272388BD00229F0E /* RunLoopExtensionTests.swift */, + 9F16230A2CA0F0190093C4FC /* DebouncerTests.swift */, ); name = Utilities; sourceTree = ""; @@ -7428,6 +7440,7 @@ 6FBF0F8B2BD7C0A900136CF0 /* AllProtectedCell.swift in Sources */, 9F4CC5242C4A4F0D006A96EB /* SwiftUITestUtilities.swift in Sources */, 6FDC64032C92F4D600DB71B3 /* NewTabPageSettingsPersistentStore.swift in Sources */, + 9F1061652C9C013F008DD5A0 /* DefaultVariantManager+Onboarding.swift in Sources */, 1E4F4A5A297193DE00625985 /* MainViewController+CookiesManaged.swift in Sources */, C12324C32C4697C900FBB26B /* AutofillBreakageReportTableViewCell.swift in Sources */, 8586A10D24CBA7070049720E /* FindInPageActivity.swift in Sources */, @@ -7892,6 +7905,7 @@ files = ( 8528AE84212FF9A100D0BD74 /* AppRatingPromptStorageTests.swift in Sources */, 569437312BE3F64400C0881B /* SyncErrorHandlerSyncPausedAlertsTests.swift in Sources */, + 9F16230B2CA0F0190093C4FC /* DebouncerTests.swift in Sources */, 1CB7B82323CEA28300AA24EA /* DateExtensionTests.swift in Sources */, 31C138A427A3352600FFD4B2 /* DownloadTests.swift in Sources */, 853A717820F645FB00FE60BC /* PixelTests.swift in Sources */, @@ -7947,6 +7961,7 @@ 5694372B2BE3F2D900C0881B /* SyncErrorHandlerTests.swift in Sources */, 987130C7294AAB9F00AB05E0 /* MenuBookmarksViewModelTests.swift in Sources */, 858650D32469BFAD00C36F8A /* DaxDialogTests.swift in Sources */, + 9F1623092C9D14F10093C4FC /* DefaultVariantManagerOnboardingTests.swift in Sources */, 31C138B227A4097800FFD4B2 /* DownloadTestsHelper.swift in Sources */, 1E1D8B5D2994FFE100C96994 /* AutoconsentMessageProtocolTests.swift in Sources */, 85C11E532090B23A00BFFEB4 /* UserDefaultsHomeRowReminderStorageTests.swift in Sources */, @@ -8285,6 +8300,7 @@ 9FCFCD812C6B020D006EB7A0 /* LaunchOptionsHandler.swift in Sources */, B652DF0D287C2A6300C12A9C /* PrivacyFeatures.swift in Sources */, F10E522D1E946F8800CE1253 /* NSAttributedStringExtension.swift in Sources */, + 9F678B892C9BAA4800CA0E19 /* Debouncer.swift in Sources */, 9887DC252354D2AA005C85F5 /* Database.swift in Sources */, F143C3171E4A99D200CFDE3A /* AppURLs.swift in Sources */, C1963863283794A000298D4D /* BookmarksCachingSearch.swift in Sources */, diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4febefbd6a..d8b3ac6978 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" : "cc3629fa16880e410e588a27a6b2426dcc140009", - "version" : "198.0.1" + "revision" : "4db50292abf1180d66da55cf83f75d37395df1f9", + "version" : "198.1.0" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/content-scope-scripts", "state" : { - "revision" : "4f0d109f13beec7e8beaf0bd5c0e2c1d528677f8", - "version" : "6.16.0" + "revision" : "2bed9e2963b2a9232452911d0773fac8b56416a1", + "version" : "6.17.0" } }, { diff --git a/DuckDuckGo/DaxDialogs.swift b/DuckDuckGo/DaxDialogs.swift index 99e16d85cb..8fc63f8e3a 100644 --- a/DuckDuckGo/DaxDialogs.swift +++ b/DuckDuckGo/DaxDialogs.swift @@ -44,8 +44,10 @@ protocol ContextualOnboardingLogic { func setSearchMessageSeen() func setFireEducationMessageSeen() + func clearedBrowserData() func setFinalOnboardingDialogSeen() func setPrivacyButtonPulseSeen() + func setDaxDialogDismiss() func canEnableAddFavoriteFlow() -> Bool // Temporary during Contextual Onboarding Experiment func enableAddFavoriteFlow() @@ -227,7 +229,7 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { } private var isNewOnboarding: Bool { - variantManager.isSupported(feature: .newOnboardingIntro) + variantManager.isContextualDaxDialogsEnabled } private var firstBrowsingMessageSeen: Bool { @@ -277,6 +279,7 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { var isEnabled: Bool { // skip dax dialogs in integration tests guard ProcessInfo.processInfo.environment["DAXDIALOGS"] != "false" else { return false } + guard variantManager.shouldShowDaxDialogs else { return false } return !settings.isDismissed } @@ -317,8 +320,7 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { func dismiss() { settings.isDismissed = true // Reset last shown dialog as we don't have to show it anymore. - removeLastShownDaxDialog() - removeLastVisitedOnboardingWebsite() + clearOnboardingBrowsingData() } func primeForUse() { @@ -448,11 +450,21 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { saveLastShownDaxDialog(specType: .fire) } + func clearedBrowserData() { + guard isNewOnboarding else { return } + setDaxDialogDismiss() + } + func setPrivacyButtonPulseSeen() { guard isNewOnboarding else { return } settings.privacyButtonPulseShown = true } + func setDaxDialogDismiss() { + guard isNewOnboarding else { return } + clearOnboardingBrowsingData() + } + func setFinalOnboardingDialogSeen() { guard isNewOnboarding else { return } settings.browsingFinalDialogShown = true @@ -543,8 +555,7 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { saveLastShownDaxDialog(specType: spec.type) saveLastVisitedOnboardingWebsite(url: privacyInfo.url) } else { - removeLastVisitedOnboardingWebsite() - removeLastShownDaxDialog() + clearOnboardingBrowsingData() } return spec @@ -561,6 +572,9 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { } func nextHomeScreenMessageNew() -> HomeScreenSpec? { + // Reset the last browsing information when opening a new tab so loading the previous website won't show again the Dax dialog + clearedBrowserData() + guard let homeScreenSpec = peekNextHomeScreenMessageExperiment() else { currentHomeSpec = nil return nil @@ -592,10 +606,14 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { if nextHomeScreenMessageOverride != nil { return nextHomeScreenMessageOverride } + guard isEnabled else { return nil } + // If the user has already seen the end of journey dialog we don't want to show any other NTP Dax dialog. + guard !finalDaxDialogSeen else { return nil } + // Check final first as if we skip anonymous searches we don't want to show this. - if settings.fireMessageExperimentShown && !finalDaxDialogSeen { + if settings.fireMessageExperimentShown { return .final } @@ -712,6 +730,11 @@ final class DaxDialogs: NewTabDialogSpecProvider, ContextualOnboardingLogic { return url1.isSameDuckDuckGoSearchURL(other: url2) } + + private func clearOnboardingBrowsingData() { + removeLastShownDaxDialog() + removeLastVisitedOnboardingWebsite() + } } extension URL { diff --git a/DuckDuckGo/HomeViewController.swift b/DuckDuckGo/HomeViewController.swift index 4cffd017af..71bb361a88 100644 --- a/DuckDuckGo/HomeViewController.swift +++ b/DuckDuckGo/HomeViewController.swift @@ -217,7 +217,7 @@ class HomeViewController: UIViewController, NewTabPage { func openedAsNewTab(allowingKeyboard: Bool) { collectionView.openedAsNewTab(allowingKeyboard: allowingKeyboard) - if !variantManager.isSupported(feature: .newOnboardingIntro) { + if !variantManager.isContextualDaxDialogsEnabled { // In the new onboarding this gets called twice (viewDidAppear in Tab) which then reset the spec to nil. presentNextDaxDialog() } @@ -258,7 +258,9 @@ class HomeViewController: UIViewController, NewTabPage { } func presentNextDaxDialog() { - if variantManager.isSupported(feature: .newOnboardingIntro) { + guard variantManager.shouldShowDaxDialogs else { return } + + if variantManager.isContextualDaxDialogsEnabled { showNextDaxDialogNew(dialogProvider: newTabDialogTypeProvider, factory: newTabDialogFactory) } else { showNextDaxDialog(dialogProvider: newTabDialogTypeProvider) @@ -266,7 +268,7 @@ class HomeViewController: UIViewController, NewTabPage { } func showNextDaxDialog() { - showNextDaxDialog(dialogProvider: newTabDialogTypeProvider) + presentNextDaxDialog() } func reloadFavorites() { diff --git a/DuckDuckGo/MainViewController+Segues.swift b/DuckDuckGo/MainViewController+Segues.swift index 324aaf1716..cd05ecddb1 100644 --- a/DuckDuckGo/MainViewController+Segues.swift +++ b/DuckDuckGo/MainViewController+Segues.swift @@ -35,7 +35,7 @@ extension MainViewController { var controller: (Onboarding & UIViewController)? - if DefaultVariantManager().isSupported(feature: .newOnboardingIntro) { + if DefaultVariantManager().isNewIntroFlow { controller = OnboardingIntroViewController(onboardingPixelReporter: contextualOnboardingPixelReporter) } else { let storyboard = UIStoryboard(name: "DaxOnboarding", bundle: nil) diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index dd9e7efeb5..5b1f33e12f 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -852,7 +852,7 @@ class MainViewController: UIViewController { hideNotificationBarIfBrokenSitePromptShown() wakeLazyFireButtonAnimator() - if DefaultVariantManager().isSupported(feature: .newOnboardingIntro) { + if variantManager.isContextualDaxDialogsEnabled { // Dismiss dax dialog and pulse animation when the user taps on the Fire Button. currentTab?.dismissContextualDaxFireDialog() ViewHighlighter.hideAll() @@ -2418,10 +2418,6 @@ extension MainViewController: TabDelegate { } } - func tabDidRequestForgetAll(tab: TabViewController) { - forgetAllWithAnimation(showNextDaxDialog: true) - } - func tabDidRequestFireButtonPulse(tab: TabViewController) { showFireButtonPulse() } @@ -2741,7 +2737,8 @@ extension MainViewController: AutoClearWorker { self.privacyProDataReporter.saveFireCount() // Ideally this should happen once data clearing has finished AND the animation is finished - if showNextDaxDialog { + // `showNextDaxDialog: true` only set from old onboarding FireDialog ActionSheet + if showNextDaxDialog && self.variantManager.shouldShowDaxDialogs { self.homeController?.showNextDaxDialog() } else if KeyboardSettings().onNewTab { let showKeyboardAfterFireButton = DispatchWorkItem { @@ -2751,8 +2748,8 @@ extension MainViewController: AutoClearWorker { self.showKeyboardAfterFireButton = showKeyboardAfterFireButton } - if self.variantManager.isSupported(feature: .newOnboardingIntro) { - DaxDialogs.shared.setFireEducationMessageSeen() + if self.variantManager.isContextualDaxDialogsEnabled { + DaxDialogs.shared.clearedBrowserData() } } } diff --git a/DuckDuckGo/NewTabPageViewController.swift b/DuckDuckGo/NewTabPageViewController.swift index fabd1ee3ed..c8ae9157bb 100644 --- a/DuckDuckGo/NewTabPageViewController.swift +++ b/DuckDuckGo/NewTabPageViewController.swift @@ -165,7 +165,9 @@ final class NewTabPageViewController: UIHostingController some View { configuration.label .fixedSize(horizontal: false, vertical: true) @@ -155,26 +167,13 @@ private struct AddressBarPostionButtonStyle: ButtonStyle { .lineLimit(nil) .padding() .frame(minWidth: 0, maxWidth: .infinity, minHeight: minHeight) - .background(backgroundColor(configuration.isPressed)) + .background(backgroundColor(configuration.isPressed || isSelected)) .cornerRadius(8) .contentShape(Rectangle()) // Makes whole button area tappable, when there's no background } - private func foregroundColor(_ isPressed: Bool) -> Color { - switch (colorScheme, isPressed) { - case (.dark, false): - return .blue30 - case (.dark, true): - return .blue20 - case (_, false): - return .blueBase - case (_, true): - return .blue70 - } - } - - private func backgroundColor(_ isPressed: Bool) -> Color { - switch (colorScheme, isPressed) { + private func backgroundColor(_ isHighlighted: Bool) -> Color { + switch (colorScheme, isHighlighted) { case (.light, true): return .blueBase.opacity(0.2) case (.dark, true): diff --git a/DuckDuckGo/OnboardingExperiment/AppIconPicker/AppIconPicker.swift b/DuckDuckGo/OnboardingExperiment/AppIconPicker/AppIconPicker.swift index 8ff955f2d0..2d1dd5ea4d 100644 --- a/DuckDuckGo/OnboardingExperiment/AppIconPicker/AppIconPicker.swift +++ b/DuckDuckGo/OnboardingExperiment/AppIconPicker/AppIconPicker.swift @@ -34,7 +34,7 @@ struct AppIconPicker: View { @StateObject private var viewModel = AppIconPickerViewModel() - let layout = [GridItem(.adaptive(minimum: Metrics.iconSize, maximum: Metrics.iconSize), spacing: Metrics.spacing)] + let layout = [GridItem(.adaptive(minimum: Metrics.iconSize), spacing: Metrics.spacing, alignment: .leading)] var body: some View { LazyVGrid(columns: layout, spacing: Metrics.spacing) { diff --git a/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/ContextualOnboardingDialogs.swift b/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/ContextualOnboardingDialogs.swift index ea4362b6f1..3a1633086f 100644 --- a/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/ContextualOnboardingDialogs.swift +++ b/DuckDuckGo/OnboardingExperiment/ContextualDaxDialogs/ContextualOnboardingDialogs.swift @@ -96,7 +96,7 @@ struct OnboardingFireButtonDialogContent: View { struct OnboardingFirstSearchDoneDialog: View { let cta = UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingGotItButton - let message: String + let message: NSAttributedString @State private var showNextScreen: Bool = false @@ -112,7 +112,7 @@ struct OnboardingFirstSearchDoneDialog: View { OnboardingTryVisitingSiteDialogContent(viewModel: viewModel) } else { ContextualDaxDialogContent( - message: NSAttributedString(string: message), + message: message, customActionView: AnyView( OnboardingCTAButton(title: cta) { gotItAction() @@ -248,7 +248,7 @@ struct OnboardingCTAButton: View { } #Preview("First Search Dialog") { - OnboardingFirstSearchDoneDialog(message: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage, shouldFollowUp: true, viewModel: OnboardingSiteSuggestionsViewModel(title: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASiteTitle, suggestedSitesProvider: OnboardingSuggestedSitesProvider(surpriseItemTitle: UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeTitle), pixelReporter: OnboardingPixelReporter()), gotItAction: {}) + OnboardingFirstSearchDoneDialog(message: NSAttributedString(string: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage), shouldFollowUp: true, viewModel: OnboardingSiteSuggestionsViewModel(title: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASiteTitle, suggestedSitesProvider: OnboardingSuggestedSitesProvider(surpriseItemTitle: UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeTitle), pixelReporter: OnboardingPixelReporter()), gotItAction: {}) .padding() } diff --git a/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift b/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift index 2ca605f244..c1463df1a1 100644 --- a/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift +++ b/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualDaxDialogsFactory.swift @@ -114,6 +114,17 @@ final class ExperimentContextualDaxDialogsFactory: ContextualDaxDialogsFactory { afterSearchPixelEvent: Pixel.Event, onSizeUpdate: @escaping () -> Void ) -> some View { + + func dialogMessage() -> NSAttributedString { + if onboardingManager.isOnboardingHighlightsEnabled { + let message = UserText.HighlightsOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage + let boldRange = message.range(of: "DuckDuckGo Search") + return message.attributed.with(attribute: .font, value: UIFont.daxBodyBold(), in: boldRange) + } else { + return UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage.attributed + } + } + let viewModel = OnboardingSiteSuggestionsViewModel(title: UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingTryASiteTitle, suggestedSitesProvider: contextualOnboardingSiteSuggestionsProvider, delegate: delegate, pixelReporter: contextualOnboardingPixelReporter) // If should not show websites search after searching inform the delegate that the user dimissed the dialog, otherwise let the dialog handle it. @@ -129,9 +140,7 @@ final class ExperimentContextualDaxDialogsFactory: ContextualDaxDialogsFactory { } } - let message = onboardingManager.isOnboardingHighlightsEnabled ? UserText.HighlightsOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage : UserText.DaxOnboardingExperiment.ContextualOnboarding.onboardingFirstSearchDoneMessage - - return OnboardingFirstSearchDoneDialog(message: message, shouldFollowUp: shouldFollowUpToWebsiteSearch, viewModel: viewModel, gotItAction: gotItAction) + return OnboardingFirstSearchDoneDialog(message: dialogMessage(), shouldFollowUp: shouldFollowUpToWebsiteSearch, viewModel: viewModel, gotItAction: gotItAction) .onFirstAppear { [weak self] in self?.contextualOnboardingPixelReporter.trackScreenImpression(event: afterSearchPixelEvent) } diff --git a/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualOnboardingPresenter.swift b/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualOnboardingPresenter.swift index c6d5542b78..fe830d287d 100644 --- a/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualOnboardingPresenter.swift +++ b/DuckDuckGo/OnboardingExperiment/ContextualOnboarding/ContextualOnboardingPresenter.swift @@ -47,7 +47,10 @@ final class ContextualOnboardingPresenter: ContextualOnboardingPresenting { } func presentContextualOnboarding(for spec: DaxDialogs.BrowsingSpec, in vc: TabViewOnboardingDelegate) { - if variantManager.isSupported(feature: .newOnboardingIntro) { + // Extra safety net + guard variantManager.shouldShowDaxDialogs else { return } + + if variantManager.isContextualDaxDialogsEnabled { presentExperimentContextualOnboarding(for: spec, in: vc) } else { presentControlContextualOnboarding(for: spec, in: vc) @@ -55,7 +58,7 @@ final class ContextualOnboardingPresenter: ContextualOnboardingPresenting { } func dismissContextualOnboardingIfNeeded(from vc: TabViewOnboardingDelegate) { - guard variantManager.isSupported(feature: .newOnboardingIntro), let daxContextualOnboarding = vc.daxContextualOnboardingController else { return } + guard variantManager.isContextualDaxDialogsEnabled, let daxContextualOnboarding = vc.daxContextualOnboardingController else { return } remove(daxController: daxContextualOnboarding, fromParent: vc) } diff --git a/DuckDuckGo/OnboardingExperiment/DefaultVariantManager+Onboarding.swift b/DuckDuckGo/OnboardingExperiment/DefaultVariantManager+Onboarding.swift new file mode 100644 index 0000000000..37909efc26 --- /dev/null +++ b/DuckDuckGo/OnboardingExperiment/DefaultVariantManager+Onboarding.swift @@ -0,0 +1,43 @@ +// +// DefaultVariantManager+Onboarding.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 Foundation +import BrowserServicesKit + +extension VariantManager { + + var isNewIntroFlow: Bool { + isSupported(feature: .newOnboardingIntro) || isSupported(feature: .newOnboardingIntroHighlights) + } + + var isOnboardingHighlightsExperiment: Bool { + isSupported(feature: .newOnboardingIntroHighlights) + } + + var shouldShowDaxDialogs: Bool { + // Disable Dax Dialogs if only feature supported is .newOnboardingIntro + guard let features = currentVariant?.features else { return true } + return !(features.count == 1 && features.contains(.newOnboardingIntro)) + } + + var isContextualDaxDialogsEnabled: Bool { + isSupported(feature: .contextualDaxDialogs) + } + +} diff --git a/DuckDuckGo/OnboardingExperiment/Manager/OnboardingManager.swift b/DuckDuckGo/OnboardingExperiment/Manager/OnboardingManager.swift index a3fc7d14a1..c504061045 100644 --- a/DuckDuckGo/OnboardingExperiment/Manager/OnboardingManager.swift +++ b/DuckDuckGo/OnboardingExperiment/Manager/OnboardingManager.swift @@ -32,17 +32,20 @@ protocol OnboardingHighlightsDebugging: OnboardingHighlightsManaging { final class OnboardingManager: OnboardingHighlightsManaging, OnboardingHighlightsDebugging { private var appDefaults: AppDebugSettings private let featureFlagger: FeatureFlagger + private let variantManager: VariantManager init( appDefaults: AppDebugSettings = AppDependencyProvider.shared.appSettings, - featureFlagger: FeatureFlagger = AppDependencyProvider.shared.featureFlagger + featureFlagger: FeatureFlagger = AppDependencyProvider.shared.featureFlagger, + variantManager: VariantManager = DefaultVariantManager() ) { self.appDefaults = appDefaults self.featureFlagger = featureFlagger + self.variantManager = variantManager } var isOnboardingHighlightsEnabled: Bool { - isLocalFlagEnabled && isFeatureFlagEnabled + variantManager.isOnboardingHighlightsExperiment || (isLocalFlagEnabled && isFeatureFlagEnabled) } var isLocalFlagEnabled: Bool { diff --git a/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView+AppIconPickerContent.swift b/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView+AppIconPickerContent.swift index 3d2f8e19bb..a85d4df605 100644 --- a/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView+AppIconPickerContent.swift +++ b/DuckDuckGo/OnboardingExperiment/OnboardingIntro/OnboardingView+AppIconPickerContent.swift @@ -66,7 +66,6 @@ extension OnboardingView { VStack(spacing: 24) { AppIconPicker() - .offset(x: Metrics.pickerLeadingOffset) // Remove left padding for the first item Button(action: action) { Text(UserText.HighlightsOnboardingExperiment.AppIconSelection.cta) diff --git a/DuckDuckGo/OnboardingExperiment/ProgressBarView.swift b/DuckDuckGo/OnboardingExperiment/ProgressBarView.swift index cebcc13db3..8a54b4e306 100644 --- a/DuckDuckGo/OnboardingExperiment/ProgressBarView.swift +++ b/DuckDuckGo/OnboardingExperiment/ProgressBarView.swift @@ -37,7 +37,7 @@ struct OnboardingProgressIndicator: View { VStack(spacing: OnboardingProgressMetrics.verticalSpacing) { HStack { Spacer() - Text("\(stepInfo.currentStep) / \(stepInfo.totalSteps)") + Text(verbatim: "\(stepInfo.currentStep) / \(stepInfo.totalSteps)") .onboardingProgressTitleStyle() .padding(.trailing, OnboardingProgressMetrics.textPadding) } @@ -144,7 +144,7 @@ struct ProgressBarGradient: View { let nextStep = stepInfo.currentStep < stepInfo.totalSteps ? stepInfo.currentStep + 1 : 1 stepInfo = OnboardingProgressIndicator.StepInfo(currentStep: nextStep, totalSteps: stepInfo.totalSteps) }, label: { - Text("Update Progress") + Text(verbatim: "Update Progress") }) } } diff --git a/DuckDuckGo/OnboardingHelpers/OnboardingSuggestedSearchesProvider.swift b/DuckDuckGo/OnboardingHelpers/OnboardingSuggestedSearchesProvider.swift index ca4b4fc628..ed71123a3c 100644 --- a/DuckDuckGo/OnboardingHelpers/OnboardingSuggestedSearchesProvider.swift +++ b/DuckDuckGo/OnboardingHelpers/OnboardingSuggestedSearchesProvider.swift @@ -21,6 +21,8 @@ import Foundation import Onboarding struct OnboardingSuggestedSearchesProvider: OnboardingSuggestionsItemsProviding { + private static let imageSearch = "!image " + private let countryAndLanguageProvider: OnboardingRegionAndLanguageProvider private let onboardingManager: OnboardingHighlightsManaging @@ -68,7 +70,9 @@ struct OnboardingSuggestedSearchesProvider: OnboardingSuggestionsItemsProviding private var option2: ContextualOnboardingListItem { var search: String - if country == "us" { + // ISO 3166-1 Region capitalized. + // https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html + if isUSCountry { search = UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOption2English } else { search = UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOption2International @@ -83,9 +87,9 @@ struct OnboardingSuggestedSearchesProvider: OnboardingSuggestionsItemsProviding private var surpriseMe: ContextualOnboardingListItem { let search = if onboardingManager.isOnboardingHighlightsEnabled { - UserText.HighlightsOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMe + Self.imageSearch + UserText.HighlightsOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMe } else { - country == "us" ? + isUSCountry ? UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeEnglish : UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeInternational } @@ -93,4 +97,10 @@ struct OnboardingSuggestedSearchesProvider: OnboardingSuggestionsItemsProviding return ContextualOnboardingListItem.surprise(title: search, visibleTitle: UserText.DaxOnboardingExperiment.ContextualOnboarding.tryASearchOptionSurpriseMeTitle) } + private var isUSCountry: Bool { + // ISO 3166-1 Region capitalized. + // https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html + country == "US" + } + } diff --git a/DuckDuckGo/TabDelegate.swift b/DuckDuckGo/TabDelegate.swift index 701386d5e6..90424e25fb 100644 --- a/DuckDuckGo/TabDelegate.swift +++ b/DuckDuckGo/TabDelegate.swift @@ -71,8 +71,6 @@ protocol TabDelegate: AnyObject { func tabContentProcessDidTerminate(tab: TabViewController) - func tabDidRequestForgetAll(tab: TabViewController) - func tabDidRequestFireButtonPulse(tab: TabViewController) func tabDidRequestPrivacyDashboardButtonPulse(tab: TabViewController, animated: Bool) diff --git a/DuckDuckGo/TabSwitcherViewController.swift b/DuckDuckGo/TabSwitcherViewController.swift index 8d41d58603..9a6aafd7d8 100644 --- a/DuckDuckGo/TabSwitcherViewController.swift +++ b/DuckDuckGo/TabSwitcherViewController.swift @@ -317,8 +317,27 @@ class TabSwitcherViewController: UIViewController { } @IBAction func onFirePressed(sender: AnyObject) { + + func presentForgetDataAlert() { + let alert = ForgetDataAlert.buildAlert(forgetTabsAndDataHandler: { [weak self] in + self?.forgetAll() + }) + + if let anchor = sender as? UIView { + self.present(controller: alert, fromView: anchor) + } else { + self.present(controller: alert, fromView: toolbar) + } + } + Pixel.fire(pixel: .forgetAllPressedTabSwitching) - let isNewOnboarding = DefaultVariantManager().isSupported(feature: .newOnboardingIntro) + let variantManager = DefaultVariantManager() + let isNewOnboarding = variantManager.isContextualDaxDialogsEnabled + + guard variantManager.shouldShowDaxDialogs else { + presentForgetDataAlert() + return + } if !isNewOnboarding && DaxDialogs.shared.shouldShowFireButtonPulse { @@ -328,15 +347,7 @@ class TabSwitcherViewController: UIViewController { if isNewOnboarding { ViewHighlighter.hideAll() } - let alert = ForgetDataAlert.buildAlert(forgetTabsAndDataHandler: { [weak self] in - self?.forgetAll() - }) - - if let anchor = sender as? UIView { - self.present(controller: alert, fromView: anchor) - } else { - self.present(controller: alert, fromView: toolbar) - } + presentForgetDataAlert() } } diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index 514b8931de..668ff0364a 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -186,6 +186,8 @@ class TabViewController: UIViewController { let syncService: DDGSyncing + private let daxDialogsDebouncer = Debouncer(mode: .common) + public var url: URL? { willSet { if newValue != url { @@ -985,7 +987,13 @@ class TabViewController: UIViewController { webView.scrollView.refreshControl = isEnabled ? refreshControl : nil } - private var didGoBackForward: Bool = false + private var didGoBackForward: Bool = false { + didSet { + if didGoBackForward { + contextualOnboardingPresenter.dismissContextualOnboardingIfNeeded(from: self) + } + } + } private func resetDashboardInfo() { if let url = url { @@ -1447,7 +1455,11 @@ extension TabViewController: WKNavigationDelegate { tabModel.link = link delegate?.tabLoadingStateDidChange(tab: self) - showDaxDialogOrStartTrackerNetworksAnimationIfNeeded() + // Present the Dax dialog with a delay to mitigate issue where user script detec trackers after the dialog is show to the user + // Debounce to avoid showing multiple animations on redirects. e.g. !image baby ducklings + daxDialogsDebouncer.debounce(for: 0.8) { [weak self] in + self?.showDaxDialogOrStartTrackerNetworksAnimationIfNeeded() + } Task { @MainActor in if await webView.isCurrentSiteReferredFromDuckDuckGo { @@ -1496,7 +1508,7 @@ extension TabViewController: WKNavigationDelegate { return } - if !DefaultVariantManager().isSupported(feature: .newOnboardingIntro) { + if !DefaultVariantManager().isContextualDaxDialogsEnabled { isShowingFullScreenDaxDialog = true } scheduleTrackerNetworksAnimation(collapsing: !spec.highlightAddressBar) @@ -3016,6 +3028,9 @@ extension TabViewController: ContextualOnboardingEventDelegate { } func didTapDismissContextualOnboardingAction() { + // Reset last visited onboarding site and last dax dialog shown. + contextualOnboardingLogic.setDaxDialogDismiss() + contextualOnboardingPresenter.dismissContextualOnboardingIfNeeded(from: self) } diff --git a/DuckDuckGo/TabsBarViewController.swift b/DuckDuckGo/TabsBarViewController.swift index 317efa98a9..2de9144342 100644 --- a/DuckDuckGo/TabsBarViewController.swift +++ b/DuckDuckGo/TabsBarViewController.swift @@ -104,7 +104,14 @@ class TabsBarViewController: UIViewController { self.present(controller: alert, fromView: fireButton) } - if DefaultVariantManager().isSupported(feature: .newOnboardingIntro) { + let variantManager = DefaultVariantManager() + + guard variantManager.shouldShowDaxDialogs else { + showClearDataAlert() + return + } + + if variantManager.isContextualDaxDialogsEnabled { delegate?.tabsBarDidRequestFireEducationDialog(self) showClearDataAlert() } else { @@ -322,7 +329,7 @@ extension MainViewController: TabsBarDelegate { } func tabsBarDidRequestFireEducationDialog(_ controller: TabsBarViewController) { - if DefaultVariantManager().isSupported(feature: .newOnboardingIntro) { + if DefaultVariantManager().isContextualDaxDialogsEnabled { currentTab?.dismissContextualDaxFireDialog() ViewHighlighter.hideAll() } else { diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index c8c2fe0910..d273f025ce 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -1393,7 +1393,7 @@ But if you *do* want a peek under the hood, you can find more information about enum AddressBarPosition { public static let title = NSLocalizedString("onboarding.highlights.addressBarPosition.title", value: "Where should I put your address bar?", comment: "The title of the onboarding dialog popup to select the preferred address bar position.") public static let topTitle = NSLocalizedString("onboarding.highlights.addressBarPosition.top.title", value: "Top", comment: "The title of the option to set the address bar to the top.") - public static let defaultOption = NSLocalizedString("onboarding.highlights.addressBarPosition.default", value: "(Default)", comment: "Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default)") + public static let defaultOption = NSLocalizedString("onboarding.highlights.addressBarPosition.default", value: "(default)", comment: "Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default)") public static let topMessage = NSLocalizedString("onboarding.highlights.addressBarPosition.top.message", value: "Easy to see", comment: "The message of the option to set the address bar to the top.") public static let bottomTitle = NSLocalizedString("onboarding.highlights.addressBarPosition.bottom.title", value: "Bottom", comment: "The title of the option to set the address bar to the bottom.") public static let bottomMessage = NSLocalizedString("onboarding.highlights.addressBarPosition.bottom.message", value: "Easy to reach", comment: "The message of the option to set the address bar to the bottom.") diff --git a/DuckDuckGo/bg.lproj/Localizable.strings b/DuckDuckGo/bg.lproj/Localizable.strings index 28f226f39d..080d97d50c 100644 --- a/DuckDuckGo/bg.lproj/Localizable.strings +++ b/DuckDuckGo/bg.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Разбрах!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Запомнете: Всеки път, когато сърфирате с мен, аз ще подрязвам крилцата на досадните реклами."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Това е DuckDuckGo Search! Поверителен. Бърз. По-малко реклами."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Търсенето в DuckDuckGo винаги е поверително."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "патенца"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Опитайте да посетите сайт!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Изберете своя браузър"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Блокиране на изскачащи прозорци за бисквитки"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Блокиране на досадни реклами"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Бързо изтриване на данните за сърфиране"; /* Message to highlight browser capability of private searches */ @@ -1792,6 +1804,56 @@ /* Subheader message for the screen to choose DuckDuckGo as default browser */ "onboarding.defaultBrowser.message" = "Отваряйте връзки без притеснения, всеки път."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "По-лесен достъп"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Отдолу"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Следващ"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(по подразбиране)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Къде да сложа адресната лента?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "По-добре се вижда"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Най-горе"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Следващ"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Изберете икона за приложенията:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Кой цвят изглежда най-добре на този фон?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Блокиране на заявки и изскачащи прозорци за бисквитки"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Блокиране на целеви реклами"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Бързо изтриване на данни за сърфиране"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Блокиране на тракерите на трети страни"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Защитите са активирани!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Пропускане"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Здравейте.\n\nГотови ли сте за по-бърз браузър, който осигурява защита?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Да го направим!"; diff --git a/DuckDuckGo/cs.lproj/Localizable.strings b/DuckDuckGo/cs.lproj/Localizable.strings index 089d695f78..b71418844a 100644 --- a/DuckDuckGo/cs.lproj/Localizable.strings +++ b/DuckDuckGo/cs.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Mám to!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Pamatujte: pokaždé, když internet procházíte s námi, příšerným reklamám přistřihneme křídla."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "To je vyhledávač DuckDuckGo Search! Soukromý. Rychlý. S méně reklamami."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Tvoje vyhledávání v DuckDuckGo je vždycky soukromé."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "malá káčátka"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Zkus přejít na nějaký web!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Vyber si prohlížeč"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokování vyskakovacích oken ohledně cookies"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokování reklam, které tě všude pronásledují"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Rychle vymaž údaje o procházení"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Ochrana osobních údajů je aktivní!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Otevírejte odkazy s klidem mysli, pokaždé."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Vždy po ruce"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Dole"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Další"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(výchozí)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Kam mám umístit váš adresní řádek?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Snadno viditelné"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Nahoru"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Další"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Vyberte si ikonu aplikace:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Která barva mi sluší nejvíc?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokování požadavků na soubory cookie a vyskakovacích oken"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokování cílených reklam"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Rychle vymazání údajů o prohlížení"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokovat trackery třetích stran"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Ochrana je aktivní!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Přeskočit"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Dobrý den.\n\nJsi připravený na rychlejší prohlížeč, který tě ochrání?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Pojďme na to!"; diff --git a/DuckDuckGo/da.lproj/Localizable.strings b/DuckDuckGo/da.lproj/Localizable.strings index b4a5cdd89d..299a8aa8b1 100644 --- a/DuckDuckGo/da.lproj/Localizable.strings +++ b/DuckDuckGo/da.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Forstået"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Husk: hver gang du browser med mig, mister en uhyggelig annonce sine vinger."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Det er DuckDuckGo Search! Privat. Hurtig. Færre annoncer."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Dine DuckDuckGo-søgninger er altid private."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "ællinger"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Prøv at besøge en hjemmeside!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Vælg din browser"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Bloker pop op-vinduer om cookies"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Bloker uhyggelige annoncer"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Ryd hurtigt browserdata"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Beskyttelse af privatlivet er aktiveret!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Åbne link med ro i sindet, hver gang."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Let at komme til"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Nederst"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Næste"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(standard)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Hvor skal jeg placere din adresselinje?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Let at se"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Top"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Næste"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Vælg dit app-ikon:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Hvilken farve klæder mig bedst?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Bloker cookie-anmodninger og popups"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Bloker målrettede annoncer"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Slet browserdata hurtigt"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Bloker tredjeparts-trackere"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Beskyttelse aktiveret!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Spring over"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Hej\n\nEr du klar til en hurtigere browser, der holder dig beskyttet?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Lad os gøre det!"; diff --git a/DuckDuckGo/de.lproj/Localizable.strings b/DuckDuckGo/de.lproj/Localizable.strings index 0b04f1dfcb..4368d10bc8 100644 --- a/DuckDuckGo/de.lproj/Localizable.strings +++ b/DuckDuckGo/de.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Verstanden."; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Hinweis: Jedes Mal, wenn du mit mir browst, verliert eine gruselige Anzeige ihren Schrecken."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Das ist die DuckDuckGo Search! Privat. Schnell. Weniger Werbung."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Deine Suchen über DuckDuckGo sind immer privat."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "Entenküken"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Versuche, eine Website zu besuchen!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Wähle deinen Browser"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Cookie-Pop-ups blockieren"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Aufdringliche Werbung blockieren"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Browserdaten schnell löschen"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Datenschutz aktiviert!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Öffne Links jederzeit sicher und ohne Sorge."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Leicht erreichbar"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Unten"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Weiter"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(standard)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Wo soll deine Adressleiste platziert werden?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Leicht erkennbar"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Nach oben"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Weiter"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Wähle dein App-Symbol aus:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Welche Farbe gefällt dir am besten?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Cookie-Anfragen und Popups blocken"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Gezielte Werbung blockieren"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Browserdaten schnell löschen"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blockiert Tracker von Drittanbietern"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Schutz aktiviert!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Überspringen"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Hallo.\n\nBereit für einen schnelleren Browser, der dich schützt?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Los geht's!"; diff --git a/DuckDuckGo/el.lproj/Localizable.strings b/DuckDuckGo/el.lproj/Localizable.strings index 6606ee33a3..8e74f39767 100644 --- a/DuckDuckGo/el.lproj/Localizable.strings +++ b/DuckDuckGo/el.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Το κατάλαβα!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Να θυμάστε: κάθε φορά που περιηγείστε μαζί μου, μια ανατριχιαστική διαφήμιση χάνει τη δύναμή της!"; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Αυτό είναι το DuckDuckGo Search! Ιδιωτικά. Γρήγορα. Λιγότερες διαφημίσεις."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Οι αναζητήσεις σας στο DuckDuckGo είναι πάντα ιδιωτικές."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "παπάκια"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Δοκιμάστε να επισκεφτείτε έναν ιστότοπο!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Επιλέξτε το πρόγραμμα περιήγησής σας"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Αποκλεισμός αναδυόμενων παραθύρων cookie"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Αποκλεισμός στοχευμένων διαφημίσεων"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Γρήγορη διαγραφή δεδομένων περιήγησης"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "H προστασία προσωπικών δεδομένων energopoi;huhke!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Ανοίξτε συνδέσμους με ηρεμία και ασφάλεια, κάθε φορά."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Εύκολη πρόσβαση"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Κάτω μέρος"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Επόμενο"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(προεπιλογή)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Πού πρέπει να τοποθετήσω τη γραμμή διευθύνσεών σας;"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Ευδιάκριτο"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Κορυφή"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Επόμενο"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Επιλέξτε το εικονίδιο της εφαρμογής σας:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Ποιο χρώμα μου ταιριάζει καλύτερα;"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Αποκλεισμός αιτημάτων και αναδυόμενων παραθύρων για cookie"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Αποκλεισμός στοχευμένων διαφημίσεων"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Γρήγορη διαγραφή δεδομένων περιήγησης"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Αποκλείστε εφαρμογές παρακολούθησης τρίτων"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Η προστασία ενεργοποιήθηκε!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Παράλειψη"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Γεια σας.\n\nΕίστε έτοιμοι για ένα ταχύτερο πρόγραμμα περιήγησης που σας διατηρεί προστατευμένους;"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Ας το δοκιμάσουμε!"; diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index 2d4b428f71..dfa29f18db 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -1872,7 +1872,7 @@ https://duckduckgo.com/mac"; "onboarding.highlights.addressBarPosition.cta" = "Next"; /* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ -"onboarding.highlights.addressBarPosition.default" = "(Default)"; +"onboarding.highlights.addressBarPosition.default" = "(default)"; /* The title of the onboarding dialog popup to select the preferred address bar position. */ "onboarding.highlights.addressBarPosition.title" = "Where should I put your address bar?"; diff --git a/DuckDuckGo/es.lproj/Localizable.strings b/DuckDuckGo/es.lproj/Localizable.strings index 1b75d2cac7..31d5b5ee75 100644 --- a/DuckDuckGo/es.lproj/Localizable.strings +++ b/DuckDuckGo/es.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Entendido"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Recuerda: cada vez que navegas conmigo corto las alas a un anuncio horrible."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "¡Eso es DuckDuckGo Search! Privado. Rápido. Menos anuncios."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Tus búsquedas en DuckDuckGo son siempre privadas."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "patitos"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "¡Intenta visitar un sitio!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Elige tu navegador"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Bloqueo de ventanas emergentes de cookies"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Bloqueo de anuncios escalofriantes"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Borra rápidamente los datos de navegación"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "¡Protecciones de privacidad activadas!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Abre los enlaces con tranquilidad, siempre."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Fácil de alcanzar"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Inferior"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Siguiente"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(predeterminado)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "¿Dónde debo poner tu barra de direcciones?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Fácil de ver"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Arriba"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Siguiente"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Elige el icono de tu aplicación:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "¿Qué color me queda mejor?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Bloqueo de las solicitudes de cookies y las ventanas emergentes"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Bloqueo de anuncios segmentados"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Borra rápidamente los datos de navegación"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Bloquea rastreadores de terceros"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "¡Protecciones activadas!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Omitir"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Hola.\n\n¿Todo listo para un navegador más rápido que mantiene tu protección?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "¡Adelante!"; diff --git a/DuckDuckGo/et.lproj/Localizable.strings b/DuckDuckGo/et.lproj/Localizable.strings index 1e72c63aec..bebcd22c02 100644 --- a/DuckDuckGo/et.lproj/Localizable.strings +++ b/DuckDuckGo/et.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Sain aru!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Pea meeles: iga kord kui minuga sirvid, kaotab jube reklaam oma tiivad."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "See on DuckDuckGo Search! Privaatne. Kiire. Vähem reklaame."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Sinu DuckDuckGo otsingud on alati privaatsed."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "pardipojad"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Proovi külastada saiti!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Vali oma brauser"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokeeri küpsiste hüpikaknad"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokeeri sihitud reklaamid"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Sirvimisandmete kiire kustutamine"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Privaatsuskaitsed on aktiveeritud!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Ava linke igal ajal, rahuliku meelega."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Kergesti ligipääsetav"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "All"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Järgmine"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(vaikimisi)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Kuhu soovid oma aadressiriba paigutada?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Kergesti märgatav"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Populaarseimad"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Järgmine"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Vali oma rakenduse ikoon:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Milline värv tundub kõige paremini sobivat?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokeeri küpsiste päringud ja hüpikaknad"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokeeri suunatud reklaamid"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Kustuta sirvimisandmed kiiresti"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokeeri kolmanda poole jälgurid"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Kaitsed aktiveeritud!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Jäta vahele"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Tere!\n\nKas oled valmis kasutama kiiremat brauserit, mis hoiab sind kaitstud?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Teeme ära!"; diff --git a/DuckDuckGo/fi.lproj/Localizable.strings b/DuckDuckGo/fi.lproj/Localizable.strings index f3689a274a..376b58b096 100644 --- a/DuckDuckGo/fi.lproj/Localizable.strings +++ b/DuckDuckGo/fi.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Selvä!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Muista, että joka kerta kun käytät minua selaamiseen, rasittavat mainokset katoavat."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Tämä on DuckDuckGo Search! Yksityinen. Nopea. Vähemmän mainoksia."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "DuckDuckGo-hakusi ovat aina yksityisiä."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "ankanpoikaset"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Siirry sivustolle!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Valitse selaimesi"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Estä evästeponnahdusikkunat"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Estä rasittavat mainokset"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Tyhjennä selaustiedot nopeasti"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Yksityisyyden suoja aktivoitu!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Avaa linkit ilman stressiä, joka kerta."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Helppo tavoittaa"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Alareuna"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Seuraava"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(oletus)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Mihin osoitepalkki pitäisi sijoittaa?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Helppo nähdä"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Suosituin"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Seuraava"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Valitse sovelluskuvake:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Mikä väri sopii minulle parhaiten?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Estä evästepyynnöt ja ponnahdusikkunat"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Estä kohdennetut mainokset"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Poista selaustiedot nopeasti"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Estä kolmannen osapuolen seuraimet"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Suojaukset aktivoitu!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Ohita"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Hei!\n\nOletko valmis käyttämään nopeampaa selainta, joka pitää sinut suojattuna?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Aloitetaan!"; diff --git a/DuckDuckGo/fr.lproj/Localizable.strings b/DuckDuckGo/fr.lproj/Localizable.strings index 5eaba8d70c..8d4427bb5a 100644 --- a/DuckDuckGo/fr.lproj/Localizable.strings +++ b/DuckDuckGo/fr.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "J'ai compris !"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Souvenez-vous : chaque fois que vous naviguez avec moi, des publicités intrusives disparaissent."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "C'est DuckDuckGo Search ! Privé. Rapide. Moins de publicités."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Vos recherches sur DuckDuckGo restent confidentielles."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "bébés canetons"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Essayez de visiter un site !"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Choisissez votre navigateur"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Bloquez les fenêtres contextuelles de cookies"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Bloquez les publicités douteuses"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Effacer rapidement les données de navigation"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Protections de la confidentialité activées !"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Des liens ouverts en toute tranquillité d'esprit, à chaque fois."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Facile d'accès"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "En bas"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Suivant"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(par défaut)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Où dois-je placer votre barre d'adresse ?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Facile à voir"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Haut de page"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Suivant"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Choisissez l'icône de votre application :"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Quelle couleur me va le mieux ?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Bloquez les demandes et les fenêtres contextuelles de cookies"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Bloquez les publicités ciblées"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Effacez rapidement les données de navigation"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Bloquer les traqueurs tiers"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Protections activées !"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Ignorer"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Bonjour.\n\nEnvie de profiter d'un navigateur plus rapide qui vous protège ?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "C'est parti !"; diff --git a/DuckDuckGo/hr.lproj/Localizable.strings b/DuckDuckGo/hr.lproj/Localizable.strings index e762b4d00f..c100cd7ce3 100644 --- a/DuckDuckGo/hr.lproj/Localizable.strings +++ b/DuckDuckGo/hr.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Shvaćam!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Zapamti: svaki put kada pregledavaš sa mnom grozna reklama gubi krila."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "To je DuckDuckGo Search! Privatno. Brzo. Manje oglasa."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Tvoja su DuckDuckGo pretraživanja uvijek privatna."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "pačići"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Pokušaj posjetiti web-mjesto!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Odaberi preglednik"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokiraj skočne prozore kolačića"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokiraj neželjene oglase"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Brzo izbriši podatke pregledavanja"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Zaštita privatnosti aktivirana!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Svaki put poveznice otvori spokojno."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Lako dostupno"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Dno"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Dalje"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(zadano)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Gdje trebam staviti tvoju adresnu traku?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Lako se vidi"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Vrh"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Dalje"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Odaberi ikonu aplikacije:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Koja boja izgleda najbolje na meni?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokiraj zahtjeve kolačića & skočne prozore"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokiraj ciljane oglase"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Brzo izbriši podatke o pregledavanju"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokiraj alate za praćenje trećih strana"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Zaštite aktivirane!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Preskoči"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Pozdrav.\n\nJesi li spreman za brži preglednik koji te štiti?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Učinimo to!"; diff --git a/DuckDuckGo/hu.lproj/Localizable.strings b/DuckDuckGo/hu.lproj/Localizable.strings index c6a6b91164..fbda3e6e8e 100644 --- a/DuckDuckGo/hu.lproj/Localizable.strings +++ b/DuckDuckGo/hu.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Megvan!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Ne feledd: minden alkalommal, amikor velem böngészel, egy undok hirdetés elveszíti az erejét."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Ez a DuckDuckGo Search! Privát. Gyors. Kevesebb hirdetés."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "A DuckDuckGo-kereséseid mindig privátak maradnak."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "kiskacsák"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Próbálj meg ellátogatni egy webhelyre!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Böngésző kiválasztása"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Felugró sütiablakok blokkolása"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Gyanús hirdetések blokkolása"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Böngészési adatok gyors törlése"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Adatvédelem aktiválva!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Nyugodtan kattints a linkekre, mindig."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Könnyen elérhető"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Alul"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Következő"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(alapértelmezett)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Hol helyezzem el a címsort?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Könnyen látható"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Fel"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Következő"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Válaszd ki az alkalmazás ikonját:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Melyik szín áll nekem a legjobban?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Sütikérelmek és felugró ablakok blokkolása"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Célzott hirdetések blokkolása"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Böngészési adatok gyors törlése"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Harmadik féltől származó nyomkövetők blokkolása"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Védelem aktiválva!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Kihagyás"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Üdv!\n\nFelkészültél egy gyorsabb böngészőre, amely védelmet nyújt neked?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Rajta, csináljuk!"; diff --git a/DuckDuckGo/it.lproj/Localizable.strings b/DuckDuckGo/it.lproj/Localizable.strings index 4f14d0d1d1..965c08a037 100644 --- a/DuckDuckGo/it.lproj/Localizable.strings +++ b/DuckDuckGo/it.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Ho capito!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Ricorda: quando navighi con me gli annunci inquietanti non possono seguirti."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "È DuckDuckGo Search! Privato. Veloce. Meno annunci."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Le tue ricerche su DuckDuckGo sono sempre private."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "anatroccoli"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Prova a visitare un sito!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Scegli il tuo browser"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blocca i popup dei cookie"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blocca gli annunci invasivi"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Elimina rapidamente i dati di navigazione"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Protezioni della privacy attivate!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Apri i collegamenti con la massima tranquillità, ogni volta."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Facile da raggiungere"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Parte inferiore"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Successivo"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(predefinito)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Dove devo mettere la barra degli indirizzi?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Facile da vedere"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Parte superiore"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Successivo"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Scegli l'icona della tua app:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Quale colore mi sta meglio?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blocca le richieste di cookie e i popup"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blocca gli annunci mirati"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Cancella rapidamente i dati di navigazione"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blocca i sistemi di tracciamento di terze parti"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Protezioni attivate!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Salta"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Ciao.\n\nVuoi un browser più veloce che ti garantisca protezione?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Continua"; diff --git a/DuckDuckGo/lt.lproj/Localizable.strings b/DuckDuckGo/lt.lproj/Localizable.strings index cc7383f995..772a8f8c00 100644 --- a/DuckDuckGo/lt.lproj/Localizable.strings +++ b/DuckDuckGo/lt.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Supratau!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Įsidėmėk: kiekvieną kartą, kai naršai su manimi, bauginantis skelbimas praranda galią."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Tai – „DuckDuckGo Search“! Privati. Sparti. Mažiau reklamų."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Jūsų „DuckDuckGo“ paieškos visada yra privačios."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "kūdikių ančiukai"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Pabandyk apsilankyti svetainėje!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Pasirinkite naršyklę"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokuoti slapukų iššokančiuosius langus"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokuokite taikomus skelbimus"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Greitai ištrinkite naršymo duomenis"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Privatumo apsaugos priemonės įjungtos!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Kiekvieną kartą be jaudulio atverkite nuorodas."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Lengvai pasiekiama"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Apačia"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Kitas"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(numatytasis)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Kur turėčiau nustatyti jūsų adreso juostą?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Lengva pamatyti"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Viršus"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Kitas"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Pasirinkti programos piktogramą:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Kuri spalva man labiausiai tinka?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokuoti slapukų užklausas ir iššokančiuosius langus"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokuoti tikslines reklamas"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Greitai ištrinkite naršymo duomenis"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokuoja trečiųjų šalių stebėjimo priemones"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Apsaugos priemonės įjungtos!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Praleisti"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Sveiki.\n\nPasiruošę greitesnei naršyklei, kuri jus apsaugo?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Pirmyn!"; diff --git a/DuckDuckGo/lv.lproj/Localizable.strings b/DuckDuckGo/lv.lproj/Localizable.strings index 6aa8661114..1332abd838 100644 --- a/DuckDuckGo/lv.lproj/Localizable.strings +++ b/DuckDuckGo/lv.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Sapratu!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Atceries: katru reizi, kad pārlūkosi kopā ar mani, kaitinošās reklāmas zaudēs savu spēku!"; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Tā ir DuckDuckGo Search meklēšana! Privāti. Ātri. Mazāk reklāmu."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Tavi DuckDuckGo meklējumi vienmēr ir privāti."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "mazi pīlēni"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Pamēģini apmeklēt kādu vietni!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Izvēlies pārlūku"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Bloķē sīkfailu uznirstošos logus"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Bloķē kaitinošas reklāmas"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Ātri izdzēs pārlūkošanas datus"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Privātuma aizsardzība ir aktivizēta!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Katru reizi atver saites bez raizēm."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Viegli pieejama"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Apakšā"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Nākamais"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(noklusējuma)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Kur novietot adreses joslu?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Viegli pamanāma"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Populārākie"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Nākamais"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Izvēlies lietotnes ikonu:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Kura krāsa man ir vispiemērotākā?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Bloķē sīkfailu pieprasījumus un uznirstošos logus"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Bloķē mērķtiecīgas reklāmas"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Ātri izdzēs pārlūkošanas datus"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Bloķē trešo pušu izsekotājus"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Aizsardzība ir aktivizēta!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Izlaist"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Sveiki!\n\nVai esi gatavs ātrākai pārlūkprogrammai, kas tevi aizsargā?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Aiziet!"; diff --git a/DuckDuckGo/nb.lproj/Localizable.strings b/DuckDuckGo/nb.lproj/Localizable.strings index 21b148b717..f36f0fb376 100644 --- a/DuckDuckGo/nb.lproj/Localizable.strings +++ b/DuckDuckGo/nb.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Skjønner!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Husk: Hver gang du surfer med meg, klippes vingene på en uhyggelig annonse."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Det er DuckDuckGo Search! Privat. Raskt. Færre annonser."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "DuckDuckGo-søkene dine er alltid private."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "andunger"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Prøv å besøke et nettsted!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Velg nettleseren din"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokker popup-vinduer om informasjonskapsler"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokker påtrengende annonser"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Slett nettleserdata raskt"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Personvern er aktivert!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Åpne lenker med ro i sinnet, hver gang."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Lett å nå"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Nederst"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Neste"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(standard)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Hvor skal jeg plassere adressefeltet?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Lett å se"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Topp"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Neste"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Velg appikonet ditt:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Hvilken farge passer best på meg?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokker forespørsler om informasjonskapsler og popup-vinduer"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokker målrettede annonser"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Slett nettleserdata raskt"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokker tredjepartssporere"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Beskyttelser er aktivert!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Hopp over"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Heisann.\n\nKlar for en raskere nettleser som holder deg beskyttet?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Sett i gang!"; diff --git a/DuckDuckGo/nl.lproj/Localizable.strings b/DuckDuckGo/nl.lproj/Localizable.strings index 3bad0bbe3b..3b91d4e02a 100644 --- a/DuckDuckGo/nl.lproj/Localizable.strings +++ b/DuckDuckGo/nl.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Ik snap het!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Denk eraan: elke keer als je met mij browset, verliest een enge advertentie zijn vleugels."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Dat is DuckDuckGo Search! Privé. Snel. Minder advertenties."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Je DuckDuckGo-zoekopdrachten zijn altijd privé."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "baby-eendjes"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Bezoek eens een site!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Kies je browser"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokkeer cookiepop-ups"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokkeer enge advertenties"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Wis browsegegevens in een handomdraai"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Privacybescherming geactiveerd!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Open links altijd met een gerust hart."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Gemakkelijk te bereiken"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Onderkant"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Volgende"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(standaard)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Waar moet ik je adresbalk plaatsen?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Gemakkelijk te zien"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Boven"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Volgende"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Kies het app-pictogram:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Welke kleur staat mij het beste?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokkeer cookieverzoeken en pop-ups"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokkeer gerichte advertenties"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Wis browsegegevens snel"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokkeer trackers van derden"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Bescherming geactiveerd!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Overslaan"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Hoi.\n\nKlaar voor een snellere browser die je beschermt?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Laten we het doen!"; diff --git a/DuckDuckGo/pl.lproj/Localizable.strings b/DuckDuckGo/pl.lproj/Localizable.strings index 24176d0cfd..365501da12 100644 --- a/DuckDuckGo/pl.lproj/Localizable.strings +++ b/DuckDuckGo/pl.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Rozumiem!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Pamiętaj: za każdym razem, gdy przeglądasz ze mną Internet, jakaś wścibska reklama przestaje działać."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "To DuckDuckGo Search! Prywatna. Szybka. Z mniejszą liczbą reklam."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Wyszukiwania w DuckDuckGo zawsze są prywatne."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "małe kaczuszki"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Spróbuj odwiedzić witrynę!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Wybierz przeglądarkę"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokuj wyskakujące okienka z informacją o plikach cookie"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokuj wścibskie reklamy"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Szybko usuwaj dane przeglądania"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Aktywowano ochronę prywatności!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Zawsze otwieraj linki ze spokojem."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Łatwy dostęp"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Dół"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Dalej"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(domyślne)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Gdzie umieścić pasek adresu?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Łatwy dostęp"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Do góry"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Dalej"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Wybierz ikonę aplikacji:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Który kolor będzie najlepszy?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokowanie wyskakujących okienek z informacją o plikach cookie"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokowanie ukierunkowanych reklam"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Szybkie usuwanie danych przeglądania"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokuj mechanizmy śledzące innych firm"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Ochrona aktywowana!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Pomiń"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Cześć!\n\nChcesz skorzystać z szybszej przeglądarki, która zapewni Ci ochronę?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Zróbmy to!"; diff --git a/DuckDuckGo/pt.lproj/Localizable.strings b/DuckDuckGo/pt.lproj/Localizable.strings index 808a4577a5..2fe4c8d1e2 100644 --- a/DuckDuckGo/pt.lproj/Localizable.strings +++ b/DuckDuckGo/pt.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Entendi!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Lembre-se: sempre que navega comigo, um anúncio estranho perde as suas asas."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "É o DuckDuckGo Search! Privado. Rápido. Menos anúncios."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "As tuas pesquisas no DuckDuckGo são sempre privadas."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "patinhos bebés"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Experimenta visitar um site!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Escolhe o teu navegador"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Bloquear pop-ups de cookies"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Bloquear anúncios assustadores"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Apaga rapidamente os dados de navegação"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Proteções de privacidade ativadas!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Abra links com tranquilidade, sempre."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Fácil de aceder"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Parte inferior"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Seguinte"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(predefinido)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Onde devo posicionar a barra de endereços?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Fácil de ver"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Topo"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Seguinte"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Escolhe o ícone da aplicação:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Que cor me fica melhor?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Bloquear pedidos de cookies e pop-ups"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Bloquear anúncios segmentados"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Eliminar dados de navegação rapidamente"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Bloqueia rastreadores de terceiros"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Proteções ativadas!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Ignorar"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Olá.\n\nPronto para um navegador mais rápido que te mantém protegido?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Vamos lá!"; diff --git a/DuckDuckGo/ro.lproj/Localizable.strings b/DuckDuckGo/ro.lproj/Localizable.strings index e544c45d0a..19f6124d9f 100644 --- a/DuckDuckGo/ro.lproj/Localizable.strings +++ b/DuckDuckGo/ro.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Am înțeles!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Reține: de fiecare dată când navighezi cu mine, o reclamă terifiantă își pierde aripile."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Acesta este DuckDuckGo Search! Privat. Rapid. Mai puține reclame."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Căutările tale DuckDuckGo sunt întotdeauna private."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "rățuște"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Încearcă să vizitezi un site!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Alege browserul"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blochează ferestrele pop-up privind modulele cookie"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blochează reclamele înfiorătoare"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Șterge rapid datele de navigare"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Măsurile de protecție a confidențialității au fost activate!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Deschide link-urile liniștit, de fiecare dată."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Ușor de accesat"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Partea de jos"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Următorul"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(implicit)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Unde ar trebui să îți pun bara de adrese?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Ușor de văzut"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Sus"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Următorul"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Alege pictograma aplicației:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Care culoare arată cel mai bine pentru mine?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blochează solicitările modulelor cookie și ferestrele pop-up"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blochează reclamele direcționate"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Șterge rapid datele de navigare"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blochează tehnologiile de urmărire externe"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Mecanismele de protecție au fost activate!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Ignorare"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Salut!\n\nEști gata pentru un browser mai rapid care îți asigură protecția?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Să începem!"; diff --git a/DuckDuckGo/ru.lproj/Localizable.strings b/DuckDuckGo/ru.lproj/Localizable.strings index 082fc1c61a..18fe1e3c3b 100644 --- a/DuckDuckGo/ru.lproj/Localizable.strings +++ b/DuckDuckGo/ru.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Понятно"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Бродить по сайтам с нами — значит подрезать крылья назойливой рекламе."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Это — DuckDuckGo Search. Надежно. Быстро. Меньше рекламы."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Ваши поисковые запросы в DuckDuckGo всегда конфиденциальны."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "утята"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Попробуйте посетить сайт!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Выбрать браузер"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Блокировка всплывающих окон куки"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Защита от надоедливой рекламы"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Быстрая очистка данных из браузера"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Защита конфиденциальности уже включена!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Открывайте ссылки, ни о чем не беспокоясь."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Легко использовать"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Внизу"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Далее"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(по умолчанию)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Где следует разместить адресную строку?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Легко заметить"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Вверх"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Далее"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Выберите иконку приложения:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Какой цвет мне идет?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Блокировка запросов и всплывающих окон куки"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Блокировка целевой рекламы"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Быстрое удаление данных из браузера"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Блокировка сторонних трекеров"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Защита включена"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Пропустить"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Привет!\n\nБыстрый и надежный браузер заказывали?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Поехали!"; diff --git a/DuckDuckGo/sk.lproj/Localizable.strings b/DuckDuckGo/sk.lproj/Localizable.strings index 7d3fc58141..c81d9cefc8 100644 --- a/DuckDuckGo/sk.lproj/Localizable.strings +++ b/DuckDuckGo/sk.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Rozumiem!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Pamätajte: zakaždým, keď prehliadate v našej aplikácii, divnej reklame pristrihávate krídla."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "To je DuckDuckGo Search! Súkromne. Rýchlo. Menej reklám."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Vaše vyhľadávania v službe DuckDuckGo sú vždy súkromné."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "malé kačiatka"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Skúste navštíviť stránku!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Vyberte si prehliadač"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokovanie vyskakovacích okien o súboroch cookie"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokovať nepríjemné reklamy"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Rýchle vymazanie údajov prehliadania"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Ochrana súkromia bola aktivovaná!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Vždy otvor odkazy s pokojom mysle."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Ľahko dosiahnuteľné"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Spodná časť"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Ďalšie"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(predvolené)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Kam mám umiestniť váš riadok s adresou?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Ľahko viditeľné"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Hore"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Ďalšie"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Vyberte ikonu aplikácie:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Ktorá farba na mne vyzerá najlepšie?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokovanie požiadaviek na súbory cookie & vyskakovacie okná"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokovanie cielených reklám"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Rýchlo vymažte údaje prehliadania"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokovať sledovanie tretími stranami"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Ochrany boli aktivované!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Preskočiť"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Dobrý deň.\n\nSte pripravení na rýchlejší prehliadač, ktorý vás ochráni?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Poďme na to!"; diff --git a/DuckDuckGo/sl.lproj/Localizable.strings b/DuckDuckGo/sl.lproj/Localizable.strings index 39f89204b9..7ba7bc5a30 100644 --- a/DuckDuckGo/sl.lproj/Localizable.strings +++ b/DuckDuckGo/sl.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Razumem!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Ne pozabi: vsakič, ko brskate z mano, grozljiv oglas izgubi krila."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "To je iskanje DuckDuckGo Search! Zasebno. Hitro. Z manj oglasi."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Vaša iskanja v DuckDuckGo so vedno zasebna."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "račke"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Poskusite obiskati spletno stran!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Izberite brskalnik"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blokirajte pojavna okna za piškotke"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blokirajte srhljive oglase"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Hitro izbrišite podatke brskanja"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Zaščite zasebnosti so aktivirane!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Bodite pomirjeni, ko odpirate povezave."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Preprosto dosegljivo"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Spodaj"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Naslednji"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(privzeto)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Kam naj postavim vašo naslovno vrstico?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Preprosto vidno"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Vrh"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Naslednji"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Izberite ikono aplikacije:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Katera barva mi najbolje pristaja?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blokiranje zahtev za piškotke in pojavna okna"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blokiranje ciljnih oglasov"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Hitro izbrišite podatke o brskanju"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blokirajte sledilnike tretjih oseb"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Zaščite so aktivirane!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Preskoči"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Pozdravljeni!\n\nSte pripravljeni na hitrejši brskalnik, ki vas zaščiti?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Pa začnimo!"; diff --git a/DuckDuckGo/sv.lproj/Localizable.strings b/DuckDuckGo/sv.lproj/Localizable.strings index 5385fcc294..8db82189fc 100644 --- a/DuckDuckGo/sv.lproj/Localizable.strings +++ b/DuckDuckGo/sv.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Jag förstår!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Kom ihåg: varje gång du surfar med mig förlorar en läskig annons sina vingar."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "Det är DuckDuckGo Search! Privat. Snabbt. Färre annonser."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "Dina DuckDuckGo-sökningar är alltid privata."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "ankungar"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Prova att besöka en webbplats!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Välj din webbläsare"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Blockera popup-fönster för cookies"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Blockera påträngande annonser"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Rensa snabbt surfdata"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Integritetsskydd aktiverat!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Sluta oroa dig varje gång du öppnar länkar."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Lätt att nå"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Botten"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Nästa"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(standard)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Var ska jag placera adressfältet?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Lätt att se"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Topp"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Nästa"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Välj appikon:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Vilken färg passar bäst på mig?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Blockera förfrågningar och popup-fönster för cookies"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Blockera riktade annonser"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Radera webbläsardata snabbt"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Blockera spårare från tredje part"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Skydd aktiverat!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Hoppa över"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Hej!\n\nÄr du redo för en snabbare webbläsare som också skyddar dig?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Vi kör!"; diff --git a/DuckDuckGo/tr.lproj/Localizable.strings b/DuckDuckGo/tr.lproj/Localizable.strings index e9453b557e..b74d0424a9 100644 --- a/DuckDuckGo/tr.lproj/Localizable.strings +++ b/DuckDuckGo/tr.lproj/Localizable.strings @@ -785,6 +785,18 @@ /* During onboarding steps this button is shown and takes either to the next steps or closes the onboarding. */ "contextual.onboarding.got-it.button" = "Anladım!"; +/* Message of the last screen of the onboarding to the browser app. */ +"contextual.onboarding.highlights.final-screen.message" = "Unutmayın: İnterneti benimle ne kadar çok gezerseniz rahatsız edici reklamları da o kadar az görürsünüz."; + +/* After the user performs their first search using the browser, this dialog explains the advantages of using DuckDuckGo */ +"contextual.onboarding.highlights.first-search-done.message" = "DuckDuckGo Search İşte Bu! Gizli. Hızlı. Daha az reklam."; + +/* Message of a popover on the browser that invites the user to try a search explaining that their searches are private */ +"contextual.onboarding.highlights.try-a-search.message" = "DuckDuckGo aramalarınız her zaman gizlidir."; + +/* Browser Search query for baby ducklings */ +"contextual.onboarding.highlights.try-search.surprise-me" = "ördek yavruları"; + /* Title of a popover on the new tab page browser that invites the user to try a visiting a website */ "contextual.onboarding.ntp.try-a-site.title" = "Bir siteyi ziyaret etmeyi deneyin!"; @@ -1772,13 +1784,13 @@ /* Button to change the default browser */ "onboarding.browsers.cta" = "Tarayıcınızı Seçin"; -/* Message to highlight browser capability of blocking cookie pop-ups */ +/* Message to highlight how the browser allows you to block cookie pop-ups */ "onboarding.browsers.features.cookiePopups.title" = "Çerez açılır pencerelerini engelle"; /* Message to highlight browser capability of blocking creepy ads */ "onboarding.browsers.features.creepyAds.title" = "Tekinsiz reklamları engelleyin"; -/* Message to highlight browser capability ofswiftly erase browsing data */ +/* Message to highlight browser capability of swiftly erase browsing data */ "onboarding.browsers.features.eraseBrowsingData.title" = "Tarama verilerini hızlıca silin"; /* Message to highlight browser capability of private searches */ @@ -1790,8 +1802,56 @@ /* The title of the dialog to show the privacy features that DuckDuckGo offers */ "onboarding.browsers.title" = "Gizlilik korumaları etkinleştirildi!"; -/* Subheader message for the screen to choose DuckDuckGo as default browser */ -"onboarding.defaultBrowser.message" = "Her zaman gönül rahatlığıyla açık bağlantılar."; +/* The message of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.message" = "Ulaşması kolay"; + +/* The title of the option to set the address bar to the bottom. */ +"onboarding.highlights.addressBarPosition.bottom.title" = "Alt"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.addressBarPosition.cta" = "Sonraki"; + +/* Indicates what address bar option (Top/Bottom) is the default one. E.g. Top (Default) */ +"onboarding.highlights.addressBarPosition.default" = "(varsayılan)"; + +/* The title of the onboarding dialog popup to select the preferred address bar position. */ +"onboarding.highlights.addressBarPosition.title" = "Adres çubuğu nereye yerleştirilsin?"; + +/* The message of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.message" = "Görmesi kolay"; + +/* The title of the option to set the address bar to the top. */ +"onboarding.highlights.addressBarPosition.top.title" = "Top"; + +/* The title of the CTA to progress to the next onboarding screen. */ +"onboarding.highlights.appIconSelection.cta" = "Sonraki"; + +/* The subheader of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.message" = "Uygulama simgenizi seçin:"; + +/* The title of the onboarding dialog popup to select the preferred App icon. */ +"onboarding.highlights.appIconSelection.title" = "Bana hangi renk daha çok yakışıyor?"; + +/* Message to highlight how the browser allows you to block cookie pop-ups */ +"onboarding.highlights.browsers.features.cookiePopups.title" = "Çerez isteklerini ve açılır pencereleri engelleyin"; + +/* Message to highlight browser capability of blocking creepy ads */ +"onboarding.highlights.browsers.features.creepyAds.title" = "Hedefli reklamları engelleyin"; + +/* Message to highlight browser capability of swiftly erase browsing data */ +"onboarding.highlights.browsers.features.eraseBrowsingData.title" = "Tarama verilerini hızlıca silin"; + +/* Message to highlight browser capability ofblocking 3rd party trackers */ +"onboarding.highlights.browsers.features.trackerBlocker.title" = "Üçüncü taraf izleyicileri engelleyin"; + +/* The title of the dialog to show the privacy features that DuckDuckGo offers */ +"onboarding.highlights.browsers.title" = "Korumalar etkinleştirildi!"; + +/* The title of the fire button CTA to skip erasing the data. */ +"onboarding.highlights.fireDialog.cta.skip" = "Atla"; + +/* The title of the onboarding dialog popup */ +"onboarding.highlights.intro.title" = "Merhaba.\n\nSizi koruyan daha hızlı bir tarayıcıya hazır mısınız?"; /* Button to continue the onboarding process */ "onboarding.intro.cta" = "Hadi Başlayalım!"; diff --git a/DuckDuckGoTests/ContextualOnboardingPresenterTests.swift b/DuckDuckGoTests/ContextualOnboardingPresenterTests.swift index ff95a620aa..83789d29b7 100644 --- a/DuckDuckGoTests/ContextualOnboardingPresenterTests.swift +++ b/DuckDuckGoTests/ContextualOnboardingPresenterTests.swift @@ -35,11 +35,11 @@ final class ContextualOnboardingPresenterTests: XCTestCase { } - func testWhenPresentContextualOnboardingAndVariantDoesNotSupportOnboardingIntroThenOldContextualOnboardingIsPresented() throws { + func testWhenPresentContextualOnboardingAndVariantDoesNotSupportContextualDaxDialogsThenOldContextualOnboardingIsPresented() throws { // GIVEN var variantManagerMock = MockVariantManager() variantManagerMock.isSupportedBlock = { feature in - feature != .newOnboardingIntro + feature != .contextualDaxDialogs } let sut = ContextualOnboardingPresenter(variantManager: variantManagerMock, daxDialogsFactory: contextualDaxDialogsFactory) let parent = TabViewControllerMock() @@ -57,11 +57,11 @@ final class ContextualOnboardingPresenterTests: XCTestCase { XCTAssertEqual(sender, DaxDialogs.BrowsingSpec.afterSearch) } - func testWhenPresentContextualOnboardingAndVariantSupportsNewOnboardingIntroThenThenNewContextualOnboardingIsPresented() { + func testWhenPresentContextualOnboardingAndVariantSupportsContextualDaxDialogsThenThenNewContextualOnboardingIsPresented() { // GIVEN var variantManagerMock = MockVariantManager() variantManagerMock.isSupportedBlock = { feature in - feature == .newOnboardingIntro + feature == .contextualDaxDialogs } let sut = ContextualOnboardingPresenter(variantManager: variantManagerMock, daxDialogsFactory: contextualDaxDialogsFactory) let parent = TabViewControllerMock() @@ -76,11 +76,34 @@ final class ContextualOnboardingPresenterTests: XCTestCase { XCTAssertNotNil(parent.capturedChild) } + func testWhenPresentContextualOnboardingAndVariantShouldNotShowContextualDialogsThenDoNothing() { + // GIVEN + var variantManagerMock = MockVariantManager() + variantManagerMock.currentVariant = MockVariant(features: [.newOnboardingIntro]) + let sut = ContextualOnboardingPresenter(variantManager: variantManagerMock, daxDialogsFactory: contextualDaxDialogsFactory) + let parent = TabViewControllerMock() + XCTAssertFalse(parent.didCallAddChild) + XCTAssertNil(parent.capturedChild) + XCTAssertFalse(parent.didCallPerformSegue) + XCTAssertNil(parent.capturedSegueIdentifier) + XCTAssertNil(parent.capturedSender) + + // WHEN + sut.presentContextualOnboarding(for: .afterSearch, in: parent) + + // THEN + XCTAssertFalse(parent.didCallAddChild) + XCTAssertNil(parent.capturedChild) + XCTAssertFalse(parent.didCallPerformSegue) + XCTAssertNil(parent.capturedSegueIdentifier) + XCTAssertNil(parent.capturedSender) + } + func testWhenPresentContextualOnboardingForFireEducational_andBarAtTheTop_TheMessageHandPointsInTheRightDirection() throws { // GIVEN var variantManagerMock = MockVariantManager() variantManagerMock.isSupportedBlock = { feature in - feature == .newOnboardingIntro + feature == .contextualDaxDialogs } let appSettings = AppSettingsMock() let sut = ContextualOnboardingPresenter(variantManager: variantManagerMock, daxDialogsFactory: contextualDaxDialogsFactory, appSettings: appSettings) @@ -98,7 +121,7 @@ final class ContextualOnboardingPresenterTests: XCTestCase { // GIVEN var variantManagerMock = MockVariantManager() variantManagerMock.isSupportedBlock = { feature in - feature == .newOnboardingIntro + feature == .contextualDaxDialogs } let appSettings = AppSettingsMock() appSettings.currentAddressBarPosition = .bottom @@ -113,12 +136,12 @@ final class ContextualOnboardingPresenterTests: XCTestCase { XCTAssertTrue(view.message.string.contains("👇")) } - func testWhenDismissContextualOnboardingAndVariantSupportsNewOnboardingIntroThenContextualOnboardingIsDismissed() { + func testWhenDismissContextualOnboardingAndVariantSupportsContextualDaxDialogsThenContextualOnboardingIsDismissed() { // GIVEN let expectation = self.expectation(description: #function) var variantManagerMock = MockVariantManager() variantManagerMock.isSupportedBlock = { feature in - feature == .newOnboardingIntro + feature == .contextualDaxDialogs } let sut = ContextualOnboardingPresenter(variantManager: variantManagerMock, daxDialogsFactory: contextualDaxDialogsFactory) let parent = TabViewControllerMock() @@ -140,13 +163,13 @@ final class ContextualOnboardingPresenterTests: XCTestCase { XCTAssertFalse(parent.daxDialogsStackView.arrangedSubviews.contains(daxController.view)) } - func testWhenDismissContextualOnboardingAndVariantDoesNotSupportsNewOnboardingIntroThenNothingHappens() { + func testWhenDismissContextualOnboardingAndVariantDoesNotSupportsContextualDaxDialogsThenNothingHappens() { // GIVEN let expectation = self.expectation(description: #function) expectation.isInverted = true var variantManagerMock = MockVariantManager() variantManagerMock.isSupportedBlock = { feature in - feature != .newOnboardingIntro + feature != .contextualDaxDialogs } let sut = ContextualOnboardingPresenter(variantManager: variantManagerMock, daxDialogsFactory: contextualDaxDialogsFactory) let parent = TabViewControllerMock() diff --git a/DuckDuckGoTests/DaxDialogTests.swift b/DuckDuckGoTests/DaxDialogTests.swift index 7bf98a7423..2c637ba23b 100644 --- a/DuckDuckGoTests/DaxDialogTests.swift +++ b/DuckDuckGoTests/DaxDialogTests.swift @@ -904,6 +904,23 @@ final class DaxDialog: XCTestCase { XCTAssertEqual(result, .final) } + func testWhenExperimentGroup_AndNextHomeScreenMessageNewIsCalled_ThenLastVisitedOnboardingWebsiteAndLastShownDaxDialogAreSetToNil() { + // GIVEN + let settings = InMemoryDaxDialogsSettings() + settings.lastShownContextualOnboardingDialogType = DaxDialogs.BrowsingSpec.fire.type.rawValue + settings.lastVisitedOnboardingWebsiteURLPath = "https://www.example.com" + let sut = makeExperimentSUT(settings: settings) + XCTAssertNotNil(settings.lastShownContextualOnboardingDialogType) + XCTAssertNotNil(settings.lastVisitedOnboardingWebsiteURLPath) + + // WHEN + _ = sut.nextHomeScreenMessageNew() + + // THEN + XCTAssertNil(settings.lastShownContextualOnboardingDialogType) + XCTAssertNil(settings.lastVisitedOnboardingWebsiteURLPath) + } + func testWhenExperimentGroup_AndCanEnableAddFavoritesFlowIsCalled_ThenReturnFalse() { // GIVEN let sut = makeExperimentSUT(settings: InMemoryDaxDialogsSettings()) @@ -1019,6 +1036,40 @@ final class DaxDialog: XCTestCase { XCTAssertNil(settings.lastVisitedOnboardingWebsiteURLPath) } + func testWhenExperimentGroup_AndSetDaxDialogDismiss_ThenLastVisitedOnboardingWebsiteAndLastShownDaxDialogAreSetToNil() { + // GIVEN + let settings = InMemoryDaxDialogsSettings() + settings.lastShownContextualOnboardingDialogType = DaxDialogs.BrowsingSpec.fire.type.rawValue + settings.lastVisitedOnboardingWebsiteURLPath = "https://www.example.com" + let sut = makeExperimentSUT(settings: settings) + XCTAssertNotNil(settings.lastShownContextualOnboardingDialogType) + XCTAssertNotNil(settings.lastVisitedOnboardingWebsiteURLPath) + + // WHEN + sut.setDaxDialogDismiss() + + // THEN + XCTAssertNil(settings.lastShownContextualOnboardingDialogType) + XCTAssertNil(settings.lastVisitedOnboardingWebsiteURLPath) + } + + func testWhenExperimentGroup_AndClearedBrowserDataIsCalled_ThenLastVisitedOnboardingWebsiteAndLastShownDaxDialogAreSetToNil() throws { + // GIVEN + let settings = InMemoryDaxDialogsSettings() + settings.lastShownContextualOnboardingDialogType = DaxDialogs.BrowsingSpec.fire.type.rawValue + settings.lastVisitedOnboardingWebsiteURLPath = "https://www.example.com" + let sut = makeExperimentSUT(settings: settings) + XCTAssertNotNil(settings.lastShownContextualOnboardingDialogType) + XCTAssertNotNil(settings.lastVisitedOnboardingWebsiteURLPath) + + // WHEN + sut.clearedBrowserData() + + // THEN + XCTAssertNil(settings.lastShownContextualOnboardingDialogType) + XCTAssertNil(settings.lastVisitedOnboardingWebsiteURLPath) + } + func testWhenExperimentGroup_AndIsEnabledIsFalse_AndReloadWebsite_ThenReturnNilBrowsingSpec() throws { // GIVEN let lastVisitedWebsitePath = "https://www.example.com" @@ -1036,6 +1087,32 @@ final class DaxDialog: XCTestCase { XCTAssertNil(result) } + func testWhenIsEnabledIsCalled_AndShouldShowDaxDialogsIsTrue_ThenReturnTrue() { + // GIVEN + var mockVariantManager = MockVariantManager() + mockVariantManager.currentVariant = MockVariant(features: [.newOnboardingIntro, .contextualDaxDialogs]) + let sut = DaxDialogs(settings: settings, entityProviding: entityProvider, variantManager: mockVariantManager) + + // WHEN + let result = sut.isEnabled + + // THEN + XCTAssertTrue(result) + } + + func testWhenIsEnabledIsCalled_AndShouldShowDaxDialogsIsFalse_ThenReturnFalse() { + // GIVEN + var mockVariantManager = MockVariantManager() + mockVariantManager.currentVariant = MockVariant(features: [.newOnboardingIntro]) + let sut = DaxDialogs(settings: settings, entityProviding: entityProvider, variantManager: mockVariantManager) + + // WHEN + let result = sut.isEnabled + + // THEN + XCTAssertFalse(result) + } + private func detectedTrackerFrom(_ url: URL, pageUrl: String) -> DetectedRequest { let entity = entityProvider.entity(forHost: url.host!) return DetectedRequest(url: url.absoluteString, @@ -1060,7 +1137,10 @@ final class DaxDialog: XCTestCase { } private func makeExperimentSUT(settings: DaxDialogsSettings) -> DaxDialogs { - let mockVariantManager = MockVariantManager(isSupportedReturns: true) + var mockVariantManager = MockVariantManager() + mockVariantManager.isSupportedBlock = { feature in + feature == .contextualDaxDialogs + } return DaxDialogs(settings: settings, entityProviding: entityProvider, variantManager: mockVariantManager) } } diff --git a/DuckDuckGoTests/DaxDialogsNewTabTests.swift b/DuckDuckGoTests/DaxDialogsNewTabTests.swift index 6561d1bed0..23f3617765 100644 --- a/DuckDuckGoTests/DaxDialogsNewTabTests.swift +++ b/DuckDuckGoTests/DaxDialogsNewTabTests.swift @@ -162,6 +162,18 @@ final class DaxDialogsNewTabTests: XCTestCase { XCTAssertNil(homeScreenMessage) } + func testIfFinalDialogShown_andBrowsingAfterSearchNotShown_OnNextHomeScreenMessageNew_ReturnsNil() { + // GIVEN + settings.browsingAfterSearchShown = false + settings.browsingFinalDialogShown = true + + // WHEN + let homeScreenMessage = daxDialogs.nextHomeScreenMessageNew() + + // THEN + XCTAssertNil(homeScreenMessage) + } + } class MockDaxDialogsSettings: DaxDialogsSettings { diff --git a/DuckDuckGoTests/DebouncerTests.swift b/DuckDuckGoTests/DebouncerTests.swift new file mode 100644 index 0000000000..eb1c2f21f1 --- /dev/null +++ b/DuckDuckGoTests/DebouncerTests.swift @@ -0,0 +1,81 @@ +// +// DebouncerTests.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 XCTest +@testable import Core + +final class DebouncerTests: XCTestCase { + private var sut: Debouncer! + + override func setUpWithError() throws { + try super.setUpWithError() + sut = Debouncer() + } + + override func tearDownWithError() throws { + sut = nil + try super.tearDownWithError() + } + + func testWhenDebounceThenTriggerBlockAfterDueTime() { + // GIVEN + let expectation = expectation(description: #function) + + // WHEN + sut.debounce(for: 0.05) { + // THEN + expectation.fulfill() + } + + wait(for: [expectation], timeout: 0.1) + } + + func testWhenCancelThenCancelBlockExecution() { + // GIVEN + let expectation = expectation(description: #function) + expectation.isInverted = true + sut.debounce(for: 0.03) { + // THEN + expectation.fulfill() + } + + // WHEN + sut.cancel() + + wait(for: [expectation], timeout: 0.1) + } + + func testWhenDebounceTwoBlocksThenCancelFirstTaskWhenSecondBlockIsScheduled() { + // GIVEN + let firstTaskExpectation = expectation(description: "FirstTask Completion") + firstTaskExpectation.isInverted = true + + let secondTaskExpectation = expectation(description: "Second Task Completion") + + // WHEN + sut.debounce(for: 0.05) { + firstTaskExpectation.fulfill() + } + sut.debounce(for: 0.02) { + secondTaskExpectation.fulfill() + } + + wait(for: [firstTaskExpectation, secondTaskExpectation], timeout: 0.1) + } +} diff --git a/DuckDuckGoTests/DefaultVariantManagerOnboardingTests.swift b/DuckDuckGoTests/DefaultVariantManagerOnboardingTests.swift new file mode 100644 index 0000000000..b9e460038d --- /dev/null +++ b/DuckDuckGoTests/DefaultVariantManagerOnboardingTests.swift @@ -0,0 +1,198 @@ +// +// DefaultVariantManagerOnboardingTests.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 XCTest +import BrowserServicesKit +@testable import Core +@testable import DuckDuckGo + +final class DefaultVariantManagerOnboardingTests: XCTestCase { + + // MARK: - Is New Intro Flow + + func testWhenIsNewIntroFlow_AndFeatureIsNewOnboardingIntro_ThenReturnTrue() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntro]) + + // WHEN + let result = sut.isNewIntroFlow + + // THEN + XCTAssertTrue(result) + } + + func testWhenIsNewIntroFlow_AndFeaturesContainNewOnboardingIntroHighlights_ThenReturnTrue() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntroHighlights]) + + // WHEN + let result = sut.isNewIntroFlow + + // THEN + XCTAssertTrue(result) + } + + func testWhenIsNewIntroFlow_AndFeaturesDoNotContainNewOnboardingIntroOrNewOnboardingIntroHighlights_ThenReturnFalse() { + // GIVEN + let sut = makeVariantManager(features: [.contextualDaxDialogs]) + + // WHEN + let result = sut.isNewIntroFlow + + // THEN + XCTAssertFalse(result) + } + + // MARK: - Is Onboarding Highlights + + func testWhenIsOnboardingHighlights_AndFeaturesContainOnboardingHighlights_ThenReturnTrue() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntroHighlights]) + + // WHEN + let result = sut.isOnboardingHighlightsExperiment + + // THEN + XCTAssertTrue(result) + } + + func testWhenIsOnboardingHighlights_AndFeaturesDoNotContainOnboardingHighlights_ThenReturnFalse() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntro, .contextualDaxDialogs]) + + // WHEN + let result = sut.isOnboardingHighlightsExperiment + + // THEN + XCTAssertFalse(result) + } + + func testWhenIsOnboardingHighlights_AndFeaturesIsEmpty_ThenReturnFalse() { + // GIVEN + let sut = makeVariantManager(features: []) + + // WHEN + let result = sut.isOnboardingHighlightsExperiment + + // THEN + XCTAssertFalse(result) + } + + // MARK: - Should Show Dax Dialogs + + func testWhenShouldShowDaxDialogs_AndFeaturesContainOnboardingIntro_ThenReturnFalse() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntro]) + + // WHEN + let result = sut.shouldShowDaxDialogs + + // THEN + XCTAssertFalse(result) + } + + func testWhenShouldShowDaxDialogs_AndFeaturesContainOnboardingIntroAndContextualDaxDialogs_ThenReturnTrue() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntro, .contextualDaxDialogs]) + + // WHEN + let result = sut.shouldShowDaxDialogs + + // THEN + XCTAssertTrue(result) + } + + func testWhenShouldShowDaxDialogs_AndFeaturesContainOnboardingHighlights_ThenReturnTrue() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntroHighlights]) + + // WHEN + let result = sut.shouldShowDaxDialogs + + // THEN + XCTAssertTrue(result) + } + + func testWhenShouldShowDaxDialogs_AndFeaturesIsEmpty_ThenReturnTrue() { + // GIVEN + let sut = makeVariantManager(features: []) + + // WHEN + let result = sut.shouldShowDaxDialogs + + // THEN + XCTAssertTrue(result) + } + + // MARK: - Is Contextual Dax Dialogs Enabled + + func testWhenIsContextualDaxDialogsEnabled_AndFeaturesContainContextualDaxDialogs_ThenReturnTrue() { + // GIVEN + let sut = makeVariantManager(features: [.contextualDaxDialogs]) + + // WHEN + let result = sut.isContextualDaxDialogsEnabled + + // THEN + XCTAssertTrue(result) + } + + func testWhenIsContextualDaxDialogsEnabled_AndFeaturesDoNotContainContextualDaxDialogs_ThenReturnFalse() { + // GIVEN + let sut = makeVariantManager(features: [.newOnboardingIntro, .newOnboardingIntroHighlights]) + + // WHEN + let result = sut.isContextualDaxDialogsEnabled + + // THEN + XCTAssertFalse(result) + } + + func testWhenIsContextualDaxDialogsEnabled_AndFeaturesIsEmpty_ThenReturnFalse() { + // GIVEN + let sut = makeVariantManager(features: []) + + // WHEN + let result = sut.isContextualDaxDialogsEnabled + + // THEN + XCTAssertFalse(result) + } + +} + +// MARK: Helpers + +private extension DefaultVariantManagerOnboardingTests { + + func makeVariantManager(features: [FeatureName]) -> DefaultVariantManager { + let mockStatisticStore = MockStatisticsStore() + mockStatisticStore.variant = #function + let variantManager = DefaultVariantManager( + variants: [VariantIOS(name: #function, weight: 1, isIncluded: VariantIOS.When.always, features: features)], + storage: mockStatisticStore, + rng: MockVariantRNG(returnValue: 500), + returningUserMeasurement: MockReturningUserMeasurement(), + variantNameOverride: MockVariantNameOverride() + ) + variantManager.assignVariantIfNeeded { _ in } + return variantManager + } + +} diff --git a/DuckDuckGoTests/HomeViewControllerDaxDialogTests.swift b/DuckDuckGoTests/HomeViewControllerDaxDialogTests.swift index 1f1db8b0ca..e9d3ebf36b 100644 --- a/DuckDuckGoTests/HomeViewControllerDaxDialogTests.swift +++ b/DuckDuckGoTests/HomeViewControllerDaxDialogTests.swift @@ -92,9 +92,9 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { hvc = nil } - func testWhenNewOnboarding_OnDidAppear_CorrectTypePassedToDialogFactory() throws { + func testWhenContextualDaxDialogsSupported_OnDidAppear_CorrectTypePassedToDialogFactory() throws { // GIVEN - variantManager.isSupported = true + variantManager.supportedFeatures = [.contextualDaxDialogs] let expectedSpec = randomDialogType() specProvider.specToReturn = expectedSpec @@ -102,16 +102,33 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { hvc.viewDidAppear(false) // THEN - XCTAssertEqual(self.variantManager.capturedFeatureName?.rawValue, FeatureName.newOnboardingIntro.rawValue) + XCTAssertEqual(self.variantManager.capturedFeatureName?.rawValue, FeatureName.contextualDaxDialogs.rawValue) XCTAssertFalse(self.specProvider.nextHomeScreenMessageCalled) XCTAssertTrue(self.specProvider.nextHomeScreenMessageNewCalled) XCTAssertEqual(self.dialogFactory.homeDialog, expectedSpec) XCTAssertNotNil(self.dialogFactory.onDismiss) } + func testWhenDaxDialogsAreNotEnabled_OnDidAppear_NothingHappens() throws { + // GIVEN + variantManager.currentVariant = MockVariant(features: [.newOnboardingIntro]) + let expectedSpec = randomDialogType() + specProvider.specToReturn = expectedSpec + + // WHEN + hvc.viewDidAppear(false) + + // THEN + XCTAssertNil(self.variantManager.capturedFeatureName) + XCTAssertFalse(self.specProvider.nextHomeScreenMessageCalled) + XCTAssertFalse(self.specProvider.nextHomeScreenMessageNewCalled) + XCTAssertNil(self.dialogFactory.homeDialog) + XCTAssertNil(self.dialogFactory.onDismiss) + } + func testWhenOldOnboarding_OnDidAppear_NothingPassedDialogFactory() throws { // GIVEN - variantManager.isSupported = false + variantManager.supportedFeatures = [] // WHEN hvc.viewDidAppear(false) @@ -123,9 +140,9 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { XCTAssertNil(dialogFactory.onDismiss) } - func testWhenNewOnboarding_OnOnboardingComplete_CorrectTypePassedToDialogFactory() throws { + func testWhenContextualDaxDialogsSupported_OnOnboardingComplete_CorrectTypePassedToDialogFactory() throws { // GIVEN - variantManager.isSupported = true + variantManager.supportedFeatures = [.contextualDaxDialogs] let expectedSpec = randomDialogType() specProvider.specToReturn = expectedSpec @@ -133,7 +150,7 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { hvc.onboardingCompleted() // THEN - XCTAssertEqual(self.variantManager.capturedFeatureName?.rawValue, FeatureName.newOnboardingIntro.rawValue) + XCTAssertEqual(self.variantManager.capturedFeatureName?.rawValue, FeatureName.contextualDaxDialogs.rawValue) XCTAssertFalse(self.specProvider.nextHomeScreenMessageCalled) XCTAssertTrue(self.specProvider.nextHomeScreenMessageNewCalled) XCTAssertEqual(self.dialogFactory.homeDialog, expectedSpec) @@ -142,7 +159,7 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { func testWhenOldOnboarding_OnOnboardingComplete_NothingPassedDialogFactory() throws { // GIVEN - variantManager.isSupported = false + variantManager.supportedFeatures = [] // WHEN hvc.onboardingCompleted() @@ -156,7 +173,7 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { func testWhenOldOnboarding_OnOpenedAsNewTab_NothingPassedDialogFactory() throws { // GIVEN - variantManager.isSupported = false + variantManager.supportedFeatures = [] // WHEN hvc.openedAsNewTab(allowingKeyboard: true) @@ -168,6 +185,30 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { XCTAssertNil(dialogFactory.onDismiss) } + func testWhenShowNextDaxDialog_AndShouldShowDaxDialogs_ThenReturnTrue() { + // GIVEN + variantManager.supportedFeatures = [] + + // WHEN + hvc.showNextDaxDialog() + + // THEN + XCTAssertTrue(specProvider.nextHomeScreenMessageCalled) + XCTAssertFalse(specProvider.nextHomeScreenMessageNewCalled) + } + + func testWhenShowNextDaxDialog_AndShouldNotShowDaxDialogs_ThenReturnFalse() { + // GIVEN + variantManager.currentVariant = MockVariant(features: [.newOnboardingIntro]) + + // WHEN + hvc.showNextDaxDialog() + + // THEN + XCTAssertFalse(specProvider.nextHomeScreenMessageCalled) + XCTAssertFalse(specProvider.nextHomeScreenMessageNewCalled) + } + private func randomDialogType() -> DaxDialogs.HomeScreenSpec { let specs: [DaxDialogs.HomeScreenSpec] = [.initial, .subsequent, .final, .addFavorite] return specs.randomElement()! @@ -177,14 +218,14 @@ final class HomeViewControllerDaxDialogTests: XCTestCase { class CapturingVariantManager: VariantManager { var currentVariant: Variant? var capturedFeatureName: FeatureName? - var isSupported = false + var supportedFeatures: [FeatureName] = [] func assignVariantIfNeeded(_ newInstallCompletion: (BrowserServicesKit.VariantManager) -> Void) { } func isSupported(feature: FeatureName) -> Bool { capturedFeatureName = feature - return isSupported + return supportedFeatures.contains(feature) } } @@ -233,3 +274,14 @@ class MockNewTabDialogSpecProvider: NewTabDialogSpecProvider { dismissCalled = true } } + +struct MockVariant: Variant { + var name: String = "" + var weight: Int = 0 + var isIncluded: () -> Bool = { false } + var features: [BrowserServicesKit.FeatureName] = [] + + init(features: [BrowserServicesKit.FeatureName]) { + self.features = features + } +} diff --git a/DuckDuckGoTests/MockTabDelegate.swift b/DuckDuckGoTests/MockTabDelegate.swift index 4b9fa4919c..3cd9a7c74c 100644 --- a/DuckDuckGoTests/MockTabDelegate.swift +++ b/DuckDuckGoTests/MockTabDelegate.swift @@ -76,8 +76,6 @@ final class MockTabDelegate: TabDelegate { func tabContentProcessDidTerminate(tab: DuckDuckGo.TabViewController) {} - func tabDidRequestForgetAll(tab: DuckDuckGo.TabViewController) {} - func tabDidRequestFireButtonPulse(tab: DuckDuckGo.TabViewController) { didRequestFireButtonPulseCalled = true } diff --git a/DuckDuckGoTests/OnboardingManagerTests.swift b/DuckDuckGoTests/OnboardingManagerTests.swift index ee456fb41d..b0f90803d5 100644 --- a/DuckDuckGoTests/OnboardingManagerTests.swift +++ b/DuckDuckGoTests/OnboardingManagerTests.swift @@ -25,17 +25,20 @@ final class OnboardingManagerTests: XCTestCase { private var sut: OnboardingManager! private var appSettingsMock: AppSettingsMock! private var featureFlaggerMock: MockFeatureFlagger! + private var variantManagerMock: MockVariantManager! override func setUpWithError() throws { try super.setUpWithError() appSettingsMock = AppSettingsMock() featureFlaggerMock = MockFeatureFlagger() - sut = OnboardingManager(appDefaults: appSettingsMock, featureFlagger: featureFlaggerMock) + variantManagerMock = MockVariantManager() + sut = OnboardingManager(appDefaults: appSettingsMock, featureFlagger: featureFlaggerMock, variantManager: variantManagerMock) } override func tearDownWithError() throws { appSettingsMock = nil featureFlaggerMock = nil + variantManagerMock = nil sut = nil try super.tearDownWithError() } @@ -119,4 +122,32 @@ final class OnboardingManagerTests: XCTestCase { // THEN XCTAssertTrue(result) } + + func testWhenIsOnboardingHiglightsEnabledAndVariantManagerSupportOnboardingHighlightsReturnTrue() { + // GIVEN + variantManagerMock.isSupportedBlock = { _ in true } + appSettingsMock.onboardingHighlightsEnabled = false + featureFlaggerMock.enabledFeatureFlags = [FeatureFlag.onboardingHighlights] + sut = OnboardingManager(appDefaults: appSettingsMock, featureFlagger: featureFlaggerMock, variantManager: variantManagerMock) + + // WHEN + let result = sut.isOnboardingHighlightsEnabled + + // THEN + XCTAssertTrue(result) + } + + func testWhenIsOnboardingHiglightsEnabledAndVariantManagerSupportOnboardingHighlightsReturnFalse() { + // GIVEN + variantManagerMock.isSupportedBlock = { _ in false } + appSettingsMock.onboardingHighlightsEnabled = false + featureFlaggerMock.enabledFeatureFlags = [FeatureFlag.onboardingHighlights] + sut = OnboardingManager(appDefaults: appSettingsMock, featureFlagger: featureFlaggerMock, variantManager: variantManagerMock) + + // WHEN + let result = sut.isOnboardingHighlightsEnabled + + // THEN + XCTAssertFalse(result) + } } diff --git a/DuckDuckGoTests/OnboardingSuggestedSearchesProviderTests.swift b/DuckDuckGoTests/OnboardingSuggestedSearchesProviderTests.swift index 59456d6edc..ced3c4b449 100644 --- a/DuckDuckGoTests/OnboardingSuggestedSearchesProviderTests.swift +++ b/DuckDuckGoTests/OnboardingSuggestedSearchesProviderTests.swift @@ -25,6 +25,7 @@ class OnboardingSuggestedSearchesProviderTests: XCTestCase { private var onboardingManagerMock: OnboardingManagerMock! let userText = UserText.DaxOnboardingExperiment.ContextualOnboarding.self let highlightsUserText = UserText.HighlightsOnboardingExperiment.ContextualOnboarding.self + static let imageSearch = "!image " override func setUpWithError() throws { try super.setUpWithError() @@ -37,7 +38,7 @@ class OnboardingSuggestedSearchesProviderTests: XCTestCase { } func testSearchesListForEnglishLanguageAndUsRegion() { - let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "us", languageCode: "en") + let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "US", languageCode: "en") let provider = OnboardingSuggestedSearchesProvider(countryAndLanguageProvider: mockProvider, onboardingManager: onboardingManagerMock) let expectedSearches = [ @@ -51,7 +52,7 @@ class OnboardingSuggestedSearchesProviderTests: XCTestCase { } func testSearchesListForNonEnglishLanguageAndNonUSRegion() { - let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "fr", languageCode: "fr") + let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "FR", languageCode: "fr") let provider = OnboardingSuggestedSearchesProvider(countryAndLanguageProvider: mockProvider, onboardingManager: onboardingManagerMock) let expectedSearches = [ @@ -65,7 +66,7 @@ class OnboardingSuggestedSearchesProviderTests: XCTestCase { } func testSearchesListForUSRegionAndNonEnglishLanguage() { - let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "us", languageCode: "es") + let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "US", languageCode: "es") let provider = OnboardingSuggestedSearchesProvider(countryAndLanguageProvider: mockProvider, onboardingManager: onboardingManagerMock) let expectedSearches = [ @@ -82,13 +83,13 @@ class OnboardingSuggestedSearchesProviderTests: XCTestCase { func testWhenHighlightsOnboardingAndSearchesListForEnglishLanguageAndUsRegionThenDoNotReturnOption3() { onboardingManagerMock.isOnboardingHighlightsEnabled = true - let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "us", languageCode: "en") + let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "US", languageCode: "en") let provider = OnboardingSuggestedSearchesProvider(countryAndLanguageProvider: mockProvider, onboardingManager: onboardingManagerMock) let expectedSearches = [ ContextualOnboardingListItem.search(title: userText.tryASearchOption1English), ContextualOnboardingListItem.search(title: userText.tryASearchOption2English), - ContextualOnboardingListItem.surprise(title: highlightsUserText.tryASearchOptionSurpriseMe, visibleTitle: "Surprise me!") + ContextualOnboardingListItem.surprise(title: Self.imageSearch + highlightsUserText.tryASearchOptionSurpriseMe, visibleTitle: "Surprise me!") ] XCTAssertEqual(provider.list, expectedSearches) @@ -96,13 +97,13 @@ class OnboardingSuggestedSearchesProviderTests: XCTestCase { func testWhenHighlightsOnboardingAndSearchesListForNonEnglishLanguageAndNonUSRegionThenDoNotReturnOption3() { onboardingManagerMock.isOnboardingHighlightsEnabled = true - let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "fr", languageCode: "fr") + let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "FR", languageCode: "fr") let provider = OnboardingSuggestedSearchesProvider(countryAndLanguageProvider: mockProvider, onboardingManager: onboardingManagerMock) let expectedSearches = [ ContextualOnboardingListItem.search(title: userText.tryASearchOption1International), ContextualOnboardingListItem.search(title: userText.tryASearchOption2International), - ContextualOnboardingListItem.surprise(title: highlightsUserText.tryASearchOptionSurpriseMe, visibleTitle: "Surprise me!") + ContextualOnboardingListItem.surprise(title: Self.imageSearch + highlightsUserText.tryASearchOptionSurpriseMe, visibleTitle: "Surprise me!") ] XCTAssertEqual(provider.list, expectedSearches) @@ -110,13 +111,13 @@ class OnboardingSuggestedSearchesProviderTests: XCTestCase { func testWhenHighlightsOnboardingAndSearchesListForUSRegionAndNonEnglishLanguageThenDoNotReturnOption3() { onboardingManagerMock.isOnboardingHighlightsEnabled = true - let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "us", languageCode: "es") + let mockProvider = MockOnboardingRegionAndLanguageProvider(regionCode: "US", languageCode: "es") let provider = OnboardingSuggestedSearchesProvider(countryAndLanguageProvider: mockProvider, onboardingManager: onboardingManagerMock) let expectedSearches = [ ContextualOnboardingListItem.search(title: userText.tryASearchOption1International), ContextualOnboardingListItem.search(title: userText.tryASearchOption2English), - ContextualOnboardingListItem.surprise(title: highlightsUserText.tryASearchOptionSurpriseMe, visibleTitle: "Surprise me!") + ContextualOnboardingListItem.surprise(title: Self.imageSearch + highlightsUserText.tryASearchOptionSurpriseMe, visibleTitle: "Surprise me!") ] XCTAssertEqual(provider.list, expectedSearches) diff --git a/DuckDuckGoTests/TabViewControllerDaxDialogTests.swift b/DuckDuckGoTests/TabViewControllerDaxDialogTests.swift index ac1a8d22df..5bafc76247 100644 --- a/DuckDuckGoTests/TabViewControllerDaxDialogTests.swift +++ b/DuckDuckGoTests/TabViewControllerDaxDialogTests.swift @@ -121,6 +121,17 @@ final class TabViewControllerDaxDialogTests: XCTestCase { XCTAssertTrue(onboardingPresenterMock.didCallDismissContextualOnboardingIfNeeded) } + func testWhenDidTapDismissActionIsCalledThenAskDaxDialogsLogicToSetDialogDismiss() { + // GIVEN + XCTAssertFalse(onboardingLogicMock.didCallSetDaxDialogDismiss) + + // WHEN + sut.didTapDismissContextualOnboardingAction() + + // THEN + XCTAssertTrue(onboardingLogicMock.didCallSetDaxDialogDismiss) + } + func testWhenDidAcknowledgedTrackersDialogIsCalledThenSetFireEducationMessageSeenIsCalledOnLogic() { // GIVEN XCTAssertFalse(onboardingLogicMock.didCallSetFireEducationMessageSeen) @@ -222,6 +233,8 @@ final class ContextualOnboardingLogicMock: ContextualOnboardingLogic { private(set) var didCallsetsetSearchMessageSeen = false private(set) var didCallCanEnableAddFavoriteFlow = false private(set) var didCallEnableAddFavoriteFlow = false + private(set) var didCallSetDaxDialogDismiss = false + private(set) var didCallClearedBrowserData = false var canStartFavoriteFlow = false @@ -255,7 +268,15 @@ final class ContextualOnboardingLogicMock: ContextualOnboardingLogic { func enableAddFavoriteFlow() { didCallEnableAddFavoriteFlow = true } - + + func setDaxDialogDismiss() { + didCallSetDaxDialogDismiss = true + } + + func clearedBrowserData() { + didCallClearedBrowserData = true + } + } extension WKNavigation {