diff --git a/.cron.yml b/.cron.yml index df4d6f8a5..ab804ac12 100644 --- a/.cron.yml +++ b/.cron.yml @@ -36,4 +36,6 @@ jobs: type: decision-task treeherder-symbol: legacy-api-ui target-tasks-method: legacy_api_ui_tests - when: [] # temporarily unscheduled + when: + - {hour: 11, minute: 0} + - {hour: 20, minute: 0} diff --git a/.experimenter.yaml b/.experimenter.yaml index 6ae24eaa4..60a6fb64a 100644 --- a/.experimenter.yaml +++ b/.experimenter.yaml @@ -37,6 +37,9 @@ messaging: messages: type: json description: A growable collection of messages + notification-config: + type: json + description: Configuration of the notification worker for all notification messages. on-control: type: string description: What should be displayed when a control message is selected. @@ -71,6 +74,14 @@ nimbus-validation: settings-title: type: string description: The title of displayed in the Settings screen and app menu. +pre-permission-notification-prompt: + description: A feature that shows the pre-permission notification prompt. + hasExposure: true + exposureDescription: "" + variables: + enabled: + type: boolean + description: "if true, the pre-permission notification prompt is shown to the user." re-engagement-notification: description: A feature that shows the re-enagement notification if the user is inactive. hasExposure: true diff --git a/.github/disabled_workflows/build-contributor-pr.yml b/.github/disabled_workflows/build-contributor-pr.yml index 42da01b41..665c437b9 100644 --- a/.github/disabled_workflows/build-contributor-pr.yml +++ b/.github/disabled_workflows/build-contributor-pr.yml @@ -3,7 +3,7 @@ on: [pull_request] jobs: run-build: runs-on: ubuntu-20.04 - if: github.event.pull_request.head.repo.full_name != github.repository && github.actor != 'MickeyMoz' + if: ${{ false }} steps: - name: Checkout repository uses: actions/checkout@v2 @@ -108,7 +108,6 @@ jobs: run-ui: runs-on: macos-11 if: ${{ false }} - timeout-minutes: 60 strategy: matrix: diff --git a/.github/disabled_workflows/update-ac.yml b/.github/disabled_workflows/update-ac.yml index 952b16c30..b5166de71 100644 --- a/.github/disabled_workflows/update-ac.yml +++ b/.github/disabled_workflows/update-ac.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: "Update Android-Components" - uses: mozilla-mobile/relbot@master + uses: mozilla-mobile/relbot@5.0.2 if: github.repository == 'mozilla-mobile/fenix' with: project: fenix diff --git a/app/build.gradle b/app/build.gradle index 97ed32ad1..c803e7f6a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,7 +47,7 @@ android { buildConfigField "String", "GIT_HASH", "\"\"" // see override in release builds for why it's blank. // This should be the "public" base URL of AMO. buildConfigField "String", "AMO_BASE_URL", "\"https://addons.mozilla.org\"" - buildConfigField "String", "AMO_COLLECTION_NAME", "\"7dfae8669acc4312a65e8ba5553036\"" + buildConfigField "String", "AMO_COLLECTION_NAME", "\"Extensions-for-Android\"" buildConfigField "String", "AMO_COLLECTION_USER", "\"mozilla\"" // These add-ons should be excluded for Mozilla Online builds. buildConfigField "String[]", "MOZILLA_ONLINE_ADDON_EXCLUSIONS", @@ -59,7 +59,8 @@ android { "\"foxyproxy@eric.h.jung\"," + "\"{73a6fe31-595d-460b-a920-fcc0f8843232}\"," + "\"jid1-BoFifL9Vbdl2zQ@jetpack\"," + - "\"woop-NoopscooPsnSXQ@jetpack\"" + + "\"woop-NoopscooPsnSXQ@jetpack\"," + + "\"adnauseam@rednoise.org\"" + "}" // This should be the base URL used to call the AMO API. buildConfigField "String", "AMO_SERVER_URL", "\"https://services.addons.mozilla.org\"" @@ -260,7 +261,7 @@ android { } composeOptions { - kotlinCompilerExtensionVersion = Versions.androidx_compose_compiler + kotlinCompilerExtensionVersion = FenixVersions.androidx_compose_compiler } } @@ -506,150 +507,149 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { } dependencies { - jnaForTest Deps.jna + jnaForTest FenixDependencies.jna testImplementation files(configurations.jnaForTest.copyRecursive().files) - implementation Deps.mozilla_browser_engine_gecko - - implementation Deps.kotlin_stdlib - implementation Deps.kotlin_coroutines - implementation Deps.kotlin_coroutines_android - testImplementation Deps.kotlin_coroutines_test - implementation Deps.androidx_appcompat - implementation Deps.androidx_constraintlayout - implementation Deps.androidx_coordinatorlayout - implementation Deps.google_accompanist_drawablepainter - implementation Deps.google_accompanist_insets - - implementation Deps.sentry - - implementation Deps.mozilla_compose_awesomebar - - implementation Deps.mozilla_concept_awesomebar - implementation Deps.mozilla_concept_base - implementation Deps.mozilla_concept_engine - implementation Deps.mozilla_concept_menu - implementation Deps.mozilla_concept_push - implementation Deps.mozilla_concept_storage - implementation Deps.mozilla_concept_sync - implementation Deps.mozilla_concept_toolbar - implementation Deps.mozilla_concept_tabstray - - implementation Deps.mozilla_browser_domains - implementation Deps.mozilla_browser_icons - implementation Deps.mozilla_browser_menu - implementation Deps.mozilla_browser_menu2 - implementation Deps.mozilla_browser_session_storage - implementation Deps.mozilla_browser_state - implementation Deps.mozilla_browser_storage_sync - implementation Deps.mozilla_browser_tabstray - implementation Deps.mozilla_browser_thumbnails - implementation Deps.mozilla_browser_toolbar - - implementation Deps.mozilla_feature_addons - implementation Deps.mozilla_feature_accounts - implementation Deps.mozilla_feature_app_links - implementation Deps.mozilla_feature_autofill - implementation Deps.mozilla_feature_awesomebar - implementation Deps.mozilla_feature_contextmenu - implementation Deps.mozilla_feature_customtabs - implementation Deps.mozilla_feature_downloads - implementation Deps.mozilla_feature_intent - implementation Deps.mozilla_feature_media - implementation Deps.mozilla_feature_prompts - implementation Deps.mozilla_feature_push - implementation Deps.mozilla_feature_privatemode - implementation Deps.mozilla_feature_pwa - implementation Deps.mozilla_feature_qr - implementation Deps.mozilla_feature_search - implementation Deps.mozilla_feature_session - implementation Deps.mozilla_feature_syncedtabs - implementation Deps.mozilla_feature_toolbar - implementation Deps.mozilla_feature_tabs - implementation Deps.mozilla_feature_findinpage - implementation Deps.mozilla_feature_logins - implementation Deps.mozilla_feature_site_permissions - implementation Deps.mozilla_feature_readerview - implementation Deps.mozilla_feature_tab_collections - implementation Deps.mozilla_feature_recentlyclosed - implementation Deps.mozilla_feature_top_sites - implementation Deps.mozilla_feature_share - implementation Deps.mozilla_feature_accounts_push - implementation Deps.mozilla_feature_webauthn - implementation Deps.mozilla_feature_webcompat - implementation Deps.mozilla_feature_webnotifications - implementation Deps.mozilla_feature_webcompat_reporter - - implementation Deps.mozilla_service_pocket - implementation Deps.mozilla_service_contile - implementation Deps.mozilla_service_digitalassetlinks - implementation Deps.mozilla_service_sync_autofill - implementation Deps.mozilla_service_sync_logins - implementation Deps.mozilla_service_firefox_accounts - implementation(Deps.mozilla_service_glean) - implementation Deps.mozilla_service_location - implementation Deps.mozilla_service_nimbus - - implementation Deps.mozilla_support_extensions - implementation Deps.mozilla_support_base - implementation Deps.mozilla_support_rusterrors - implementation Deps.mozilla_support_images - implementation Deps.mozilla_support_ktx - implementation Deps.mozilla_support_rustlog - implementation Deps.mozilla_support_utils - implementation Deps.mozilla_support_locale - - implementation Deps.mozilla_ui_colors - implementation Deps.mozilla_ui_icons - implementation Deps.mozilla_lib_publicsuffixlist - implementation Deps.mozilla_ui_widgets - implementation Deps.mozilla_ui_tabcounter - - implementation Deps.mozilla_lib_crash - implementation Deps.lib_crash_sentry - implementation Deps.mozilla_lib_state - implementation Deps.mozilla_lib_dataprotect - debugImplementation Deps.leakcanary - forkDebugImplementation Deps.leakcanary - - implementation Deps.androidx_annotation - implementation Deps.androidx_compose_ui - implementation Deps.androidx_compose_ui_tooling - implementation Deps.androidx_compose_foundation - implementation Deps.androidx_compose_material - implementation Deps.androidx_legacy - implementation Deps.androidx_biometric - implementation Deps.androidx_paging - implementation Deps.androidx_preference - implementation Deps.androidx_fragment - implementation Deps.androidx_navigation_fragment - implementation Deps.androidx_navigation_ui - implementation Deps.androidx_recyclerview - implementation Deps.androidx_lifecycle_common - implementation Deps.androidx_lifecycle_livedata - implementation Deps.androidx_lifecycle_process - implementation Deps.androidx_lifecycle_runtime - implementation Deps.androidx_lifecycle_viewmodel - implementation Deps.androidx_core - implementation Deps.androidx_core_ktx - implementation Deps.androidx_transition - implementation Deps.androidx_work_ktx - implementation Deps.androidx_datastore - implementation Deps.protobuf_javalite - implementation Deps.google_material - - androidTestImplementation Deps.uiautomator + implementation FenixDependencies.mozilla_browser_engine_gecko + + implementation FenixDependencies.kotlin_stdlib + implementation FenixDependencies.kotlin_coroutines + implementation FenixDependencies.kotlin_coroutines_android + testImplementation FenixDependencies.kotlin_coroutines_test + implementation FenixDependencies.androidx_appcompat + implementation FenixDependencies.androidx_constraintlayout + implementation FenixDependencies.androidx_coordinatorlayout + implementation FenixDependencies.google_accompanist_drawablepainter + implementation FenixDependencies.google_accompanist_insets + + implementation FenixDependencies.sentry + + implementation FenixDependencies.mozilla_compose_awesomebar + + implementation FenixDependencies.mozilla_concept_awesomebar + implementation FenixDependencies.mozilla_concept_base + implementation FenixDependencies.mozilla_concept_engine + implementation FenixDependencies.mozilla_concept_menu + implementation FenixDependencies.mozilla_concept_push + implementation FenixDependencies.mozilla_concept_storage + implementation FenixDependencies.mozilla_concept_sync + implementation FenixDependencies.mozilla_concept_toolbar + implementation FenixDependencies.mozilla_concept_tabstray + + implementation FenixDependencies.mozilla_browser_domains + implementation FenixDependencies.mozilla_browser_icons + implementation FenixDependencies.mozilla_browser_menu + implementation FenixDependencies.mozilla_browser_menu2 + implementation FenixDependencies.mozilla_browser_session_storage + implementation FenixDependencies.mozilla_browser_state + implementation FenixDependencies.mozilla_browser_storage_sync + implementation FenixDependencies.mozilla_browser_tabstray + implementation FenixDependencies.mozilla_browser_thumbnails + implementation FenixDependencies.mozilla_browser_toolbar + + implementation FenixDependencies.mozilla_feature_addons + implementation FenixDependencies.mozilla_feature_accounts + implementation FenixDependencies.mozilla_feature_app_links + implementation FenixDependencies.mozilla_feature_autofill + implementation FenixDependencies.mozilla_feature_awesomebar + implementation FenixDependencies.mozilla_feature_contextmenu + implementation FenixDependencies.mozilla_feature_customtabs + implementation FenixDependencies.mozilla_feature_downloads + implementation FenixDependencies.mozilla_feature_intent + implementation FenixDependencies.mozilla_feature_media + implementation FenixDependencies.mozilla_feature_prompts + implementation FenixDependencies.mozilla_feature_push + implementation FenixDependencies.mozilla_feature_privatemode + implementation FenixDependencies.mozilla_feature_pwa + implementation FenixDependencies.mozilla_feature_qr + implementation FenixDependencies.mozilla_feature_search + implementation FenixDependencies.mozilla_feature_session + implementation FenixDependencies.mozilla_feature_syncedtabs + implementation FenixDependencies.mozilla_feature_toolbar + implementation FenixDependencies.mozilla_feature_tabs + implementation FenixDependencies.mozilla_feature_findinpage + implementation FenixDependencies.mozilla_feature_logins + implementation FenixDependencies.mozilla_feature_site_permissions + implementation FenixDependencies.mozilla_feature_readerview + implementation FenixDependencies.mozilla_feature_tab_collections + implementation FenixDependencies.mozilla_feature_recentlyclosed + implementation FenixDependencies.mozilla_feature_top_sites + implementation FenixDependencies.mozilla_feature_share + implementation FenixDependencies.mozilla_feature_accounts_push + implementation FenixDependencies.mozilla_feature_webauthn + implementation FenixDependencies.mozilla_feature_webcompat + implementation FenixDependencies.mozilla_feature_webnotifications + implementation FenixDependencies.mozilla_feature_webcompat_reporter + + implementation FenixDependencies.mozilla_service_pocket + implementation FenixDependencies.mozilla_service_contile + implementation FenixDependencies.mozilla_service_digitalassetlinks + implementation FenixDependencies.mozilla_service_sync_autofill + implementation FenixDependencies.mozilla_service_sync_logins + implementation FenixDependencies.mozilla_service_firefox_accounts + implementation(FenixDependencies.mozilla_service_glean) + implementation FenixDependencies.mozilla_service_location + implementation FenixDependencies.mozilla_service_nimbus + + implementation FenixDependencies.mozilla_support_extensions + implementation FenixDependencies.mozilla_support_base + implementation FenixDependencies.mozilla_support_rusterrors + implementation FenixDependencies.mozilla_support_images + implementation FenixDependencies.mozilla_support_ktx + implementation FenixDependencies.mozilla_support_rustlog + implementation FenixDependencies.mozilla_support_utils + implementation FenixDependencies.mozilla_support_locale + + implementation FenixDependencies.mozilla_ui_colors + implementation FenixDependencies.mozilla_ui_icons + implementation FenixDependencies.mozilla_lib_publicsuffixlist + implementation FenixDependencies.mozilla_ui_widgets + implementation FenixDependencies.mozilla_ui_tabcounter + + implementation FenixDependencies.mozilla_lib_crash + implementation FenixDependencies.lib_crash_sentry + implementation FenixDependencies.mozilla_lib_state + implementation FenixDependencies.mozilla_lib_dataprotect + debugImplementation FenixDependencies.leakcanary + + implementation FenixDependencies.androidx_annotation + implementation FenixDependencies.androidx_compose_ui + implementation FenixDependencies.androidx_compose_ui_tooling + implementation FenixDependencies.androidx_compose_foundation + implementation FenixDependencies.androidx_compose_material + implementation FenixDependencies.androidx_legacy + implementation FenixDependencies.androidx_biometric + implementation FenixDependencies.androidx_paging + implementation FenixDependencies.androidx_preference + implementation FenixDependencies.androidx_fragment + implementation FenixDependencies.androidx_navigation_fragment + implementation FenixDependencies.androidx_navigation_ui + implementation FenixDependencies.androidx_recyclerview + implementation FenixDependencies.androidx_lifecycle_common + implementation FenixDependencies.androidx_lifecycle_livedata + implementation FenixDependencies.androidx_lifecycle_process + implementation FenixDependencies.androidx_lifecycle_runtime + implementation FenixDependencies.androidx_lifecycle_viewmodel + implementation FenixDependencies.androidx_core + implementation FenixDependencies.androidx_core_ktx + implementation FenixDependencies.androidx_transition + implementation FenixDependencies.androidx_work_ktx + implementation FenixDependencies.androidx_datastore + implementation FenixDependencies.protobuf_javalite + implementation FenixDependencies.google_material + + androidTestImplementation FenixDependencies.uiautomator androidTestImplementation "tools.fastlane:screengrab:2.0.0" // This Falcon version is added to maven central now required for Screengrab implementation 'com.jraska:falcon:2.2.0' - androidTestImplementation Deps.androidx_compose_ui_test + androidTestImplementation FenixDependencies.androidx_compose_ui_test - androidTestImplementation Deps.espresso_core, { + androidTestImplementation FenixDependencies.espresso_core, { exclude group: 'com.android.support', module: 'support-annotations' } - androidTestImplementation(Deps.espresso_contrib) { + androidTestImplementation(FenixDependencies.espresso_contrib) { exclude module: 'appcompat-v7' exclude module: 'support-v4' exclude module: 'support-annotations' @@ -659,36 +659,36 @@ dependencies { exclude module: 'protobuf-lite' } - androidTestImplementation Deps.androidx_test_core - androidTestImplementation Deps.espresso_idling_resources - androidTestImplementation Deps.espresso_intents + androidTestImplementation FenixDependencies.androidx_test_core + androidTestImplementation FenixDependencies.espresso_idling_resources + androidTestImplementation FenixDependencies.espresso_intents - androidTestImplementation Deps.tools_test_runner - androidTestImplementation Deps.tools_test_rules - androidTestUtil Deps.orchestrator - androidTestImplementation Deps.espresso_core, { + androidTestImplementation FenixDependencies.tools_test_runner + androidTestImplementation FenixDependencies.tools_test_rules + androidTestUtil FenixDependencies.orchestrator + androidTestImplementation FenixDependencies.espresso_core, { exclude group: 'com.android.support', module: 'support-annotations' } - androidTestImplementation Deps.androidx_junit - androidTestImplementation Deps.androidx_test_extensions - androidTestImplementation Deps.androidx_work_testing - androidTestImplementation Deps.androidx_benchmark_junit4 - androidTestImplementation Deps.mockwebserver - testImplementation Deps.mozilla_support_test - testImplementation Deps.mozilla_support_test_libstate - testImplementation Deps.androidx_junit - testImplementation Deps.androidx_test_extensions - testImplementation Deps.androidx_work_testing - testImplementation (Deps.robolectric) { + androidTestImplementation FenixDependencies.androidx_junit + androidTestImplementation FenixDependencies.androidx_test_extensions + androidTestImplementation FenixDependencies.androidx_work_testing + androidTestImplementation FenixDependencies.androidx_benchmark_junit4 + androidTestImplementation FenixDependencies.mockwebserver + testImplementation FenixDependencies.mozilla_support_test + testImplementation FenixDependencies.mozilla_support_test_libstate + testImplementation FenixDependencies.androidx_junit + testImplementation FenixDependencies.androidx_test_extensions + testImplementation FenixDependencies.androidx_work_testing + testImplementation (FenixDependencies.robolectric) { exclude group: 'org.apache.maven' } testImplementation 'org.apache.maven:maven-ant-tasks:2.1.3' - implementation Deps.mozilla_support_rusthttp + implementation FenixDependencies.mozilla_support_rusthttp - androidTestImplementation Deps.mockk_android - testImplementation Deps.mockk + androidTestImplementation FenixDependencies.mockk_android + testImplementation FenixDependencies.mockk // For the initial release of Glean 19, we require consumer applications to // depend on a separate library for unit tests. This will be removed in future releases. @@ -702,9 +702,9 @@ protobuf { // See https://github.com/mozilla-mobile/fenix/issues/22321 protoc { if (osdetector.os == "osx") { - artifact = "${Deps.protobuf_compiler}:osx-x86_64" + artifact = "${FenixDependencies.protobuf_compiler}:osx-x86_64" } else { - artifact = Deps.protobuf_compiler + artifact = FenixDependencies.protobuf_compiler } } diff --git a/app/metrics.yaml b/app/metrics.yaml index 18050c1b6..08e349c4e 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -141,15 +141,15 @@ events: include: add_to_homescreen, add_to_top_sites, addons_manager, back, bookmark, bookmarks, desktop_view_off, desktop_view_on, downloads, - find_in_page, forward, help, history, library, new_private_tab, - new_tab, open_in_app, open_in_fenix, quit, reader_mode_appearance, - reader_mode_off, reader_mode_on, reload, remove_from_top_sites, - save_to_collection, set_default_browser, settings, share, stop, - sync_account, and sync_tabs. + find_in_page, forward, history, new_tab, open_in_app, open_in_fenix, + quit, reader_mode_appearance, reload, remove_from_top_sites, + save_to_collection, set_default_browser, settings, share, stop, and + sync_account. type: string bugs: - https://github.com/mozilla-mobile/fenix/issues/1024 - https://github.com/mozilla-mobile/fenix/issues/19923 + - https://bugzilla.mozilla.org/show_bug.cgi?id=1808689 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/1214#issue-264756708 - https://github.com/mozilla-mobile/fenix/pull/5098#issuecomment-529658996 @@ -871,6 +871,74 @@ onboarding: metadata: tags: - Onboarding + notif_ppp_impression: + type: event + description: | + Notification pre permission prompt was shown to the user. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1810115 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28529 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 124 + metadata: + tags: + - Notifications + - Onboarding + notif_ppp_close_click: + type: event + description: | + User clicked the close button on the notification pre permission prompt. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1810115 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28529 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 124 + metadata: + tags: + - Notifications + - Onboarding + notif_ppp_positive_btn_click: + type: event + description: | + User clicked the positive button on notification pre permission prompt. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1810115 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28529 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 124 + metadata: + tags: + - Notifications + - Onboarding + notif_ppp_negative_btn_click: + type: event + description: | + User clicked the negative button on notification pre permission prompt. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1810115 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28529 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 124 + metadata: + tags: + - Notifications + - Onboarding search_shortcuts: selected: @@ -890,9 +958,10 @@ search_shortcuts: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Search @@ -1032,11 +1101,12 @@ login_dialog: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -1051,11 +1121,12 @@ login_dialog: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -1070,11 +1141,12 @@ login_dialog: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -1089,11 +1161,12 @@ login_dialog: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -1243,11 +1316,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Bookmarks @@ -1326,11 +1400,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - PWA @@ -1350,11 +1425,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - PWA @@ -1416,12 +1492,13 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - technical - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Settings @@ -1442,12 +1519,13 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - technical - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Settings @@ -1469,11 +1547,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - technical notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Telemetry @@ -1495,11 +1574,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Telemetry @@ -1521,11 +1601,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Telemetry @@ -1547,11 +1628,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Telemetry @@ -1570,11 +1652,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Toolbar @@ -1593,11 +1676,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Tabs @@ -1616,11 +1700,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Tabs @@ -1639,11 +1724,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Discovery @@ -1691,11 +1777,12 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Tabs @@ -1772,11 +1859,12 @@ metrics: data_reviews: - https://github.com/mozilla-mobile/fenix/pull/22163#issuecomment-957636802 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 unit: integer default_wallpaper: type: boolean @@ -2063,11 +2151,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Settings @@ -2114,11 +2203,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - TrackingProtection @@ -2164,11 +2254,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Settings @@ -2187,11 +2278,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Settings @@ -2210,11 +2302,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Settings @@ -2258,11 +2351,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Sync @@ -2284,11 +2378,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Settings @@ -2307,11 +2402,12 @@ preferences: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Search @@ -2514,12 +2610,13 @@ search.default_engine: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - technical - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 bookmarks_management: open: @@ -2966,11 +3063,12 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Toolbar @@ -2987,11 +3085,12 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Toolbar @@ -3009,11 +3108,12 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Sync @@ -3029,11 +3129,12 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Sync @@ -3116,12 +3217,13 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - technical - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Accounts @@ -3138,12 +3240,13 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - technical - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Accounts @@ -3160,12 +3263,13 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - technical - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Accounts @@ -3181,11 +3285,12 @@ sync_auth: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Sync @@ -3203,11 +3308,12 @@ sync_account: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Toolbar @@ -3224,11 +3330,12 @@ sync_account: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Toolbar @@ -3245,11 +3352,12 @@ sync_account: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - SendTab @@ -3265,11 +3373,12 @@ sync_account: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - SendTab @@ -3287,11 +3396,12 @@ history: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - History @@ -3307,11 +3417,12 @@ history: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - History @@ -3327,11 +3438,12 @@ history: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - History @@ -3411,11 +3523,12 @@ history: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - History @@ -4778,11 +4891,12 @@ search_widget: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Search @@ -4798,11 +4912,12 @@ search_widget: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Search @@ -4821,11 +4936,12 @@ tracking_protection: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - TrackingProtection @@ -4841,11 +4957,12 @@ tracking_protection: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - TrackingProtection @@ -4861,11 +4978,12 @@ tracking_protection: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - TrackingProtection @@ -4882,11 +5000,12 @@ tracking_protection: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - TrackingProtection @@ -4902,11 +5021,12 @@ tracking_protection: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - TrackingProtection @@ -4929,11 +5049,12 @@ tracking_protection: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - TrackingProtection @@ -5017,11 +5138,12 @@ tab: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 no_lint: - COMMON_PREFIX metadata: @@ -5039,11 +5161,12 @@ tab: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5061,11 +5184,12 @@ media_notification: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5081,11 +5205,12 @@ media_notification: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5103,11 +5228,12 @@ media_state: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5123,11 +5249,12 @@ media_state: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5143,11 +5270,12 @@ media_state: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5162,11 +5290,12 @@ media_state: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5181,11 +5310,12 @@ media_state: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Media @@ -5224,11 +5354,12 @@ logins: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -5244,11 +5375,12 @@ logins: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -5264,11 +5396,12 @@ logins: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -5290,11 +5423,12 @@ logins: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -5310,11 +5444,12 @@ logins: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -5330,11 +5465,12 @@ logins: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -5350,11 +5486,12 @@ logins: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Logins @@ -5372,11 +5509,12 @@ voice_search: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Search @@ -5434,11 +5572,12 @@ top_sites: data_reviews: - https://github.com/mozilla-mobile/fenix/pull/20705 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - Search @@ -5612,11 +5751,12 @@ top_sites: data_reviews: - https://github.com/mozilla-mobile/fenix/pull/21845#issuecomment-944608568 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 baidu_top_site_removed: type: event description: | @@ -5626,11 +5766,12 @@ top_sites: data_reviews: - https://github.com/mozilla-mobile/fenix/pull/21845#issuecomment-944608568 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 open_contile_top_site: type: event description: | @@ -5639,11 +5780,12 @@ top_sites: - https://github.com/mozilla-mobile/fenix/issues/23526 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/23541 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 open_contile_in_private_tab: type: event description: | @@ -5653,11 +5795,12 @@ top_sites: - https://github.com/mozilla-mobile/fenix/issues/23526 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/23541 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 contile_settings: type: event description: | @@ -5667,11 +5810,12 @@ top_sites: - https://github.com/mozilla-mobile/fenix/issues/23526 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/23541 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 contile_sponsors_and_privacy: type: event description: | @@ -5681,11 +5825,12 @@ top_sites: - https://github.com/mozilla-mobile/fenix/issues/23526 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/23541 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 context_id: type: uuid description: | @@ -5888,11 +6033,12 @@ pocket: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - PocketIntegration @@ -6810,11 +6956,12 @@ autoplay: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - SitePermissions @@ -6836,11 +6983,12 @@ autoplay: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - SitePermissions @@ -6932,6 +7080,72 @@ cookie_banners: metadata: tags: - Privacy&Security + visited_re_engagement_dialog: + type: event + description: An user visited the cookie banner re-engagement dialog + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1797593 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28405#issuecomment-1372489596 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 118 + metadata: + tags: + - Privacy&Security + opt_out_re_engagement_dialog: + type: event + description: | + An user opt out the cookie banner re-engagement + dialog by clicking the X button + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1797593 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28405#issuecomment-1372489596 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 118 + metadata: + tags: + - Privacy&Security + not_now_re_engagement_dialog: + type: event + description: | + An user clicked the not now button on + the cookie banner re-engagement dialog + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1797593 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28405#issuecomment-1372489596 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 118 + metadata: + tags: + - Privacy&Security + allow_re_engagement_dialog: + type: event + description: | + An user clicked the dismiss banner button + on the cookie banner re-engagement dialog + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1797593 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/28405#issuecomment-1372489596 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: 118 + metadata: + tags: + - Privacy&Security site_permissions: prompt_shown: type: event @@ -7377,11 +7591,12 @@ synced_tabs: - https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789 - https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 metadata: tags: - SyncTabs @@ -7906,11 +8121,12 @@ recent_bookmarks: data_reviews: - https://github.com/mozilla-mobile/fenix/pull/20316#issuecomment-888291843 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 show_all_bookmarks: type: counter lifetime: application @@ -7925,11 +8141,12 @@ recent_bookmarks: data_reviews: - https://github.com/mozilla-mobile/fenix/pull/20316#issuecomment-888291843 - https://github.com/mozilla-mobile/fenix/pull/23453#issuecomment-1024694220 + - https://github.com/mozilla-mobile/fenix/pull/28502 data_sensitivity: - interaction notification_emails: - android-probes@mozilla.com - expires: 111 + expires: 124 recent_bookmarks_count: type: quantity description: | diff --git a/app/src/androidTest/assets/pages/trackingPage.html b/app/src/androidTest/assets/pages/trackingPage.html index a0a53c954..ee57fc3ee 100644 --- a/app/src/androidTest/assets/pages/trackingPage.html +++ b/app/src/androidTest/assets/pages/trackingPage.html @@ -13,31 +13,31 @@

Level 1 (Basic) List

social-track-digest256:

+ src="https://social-track-digest256.dummytracker.org/test_not_blocked.png" alt="social not blocked" + onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='social blocked'">

ads-track-digest256:

+ onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='ads blocked'">

analytics-track-digest256:

+ onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='analytics blocked'">

Fingerprinting:

test not run


Cryptomining: not blocked + src="https://base-cryptomining-track-digest256.dummytracker.org/test_not_blocked.png" alt="Cryptomining not blocked" + onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='Cryptomining blocked'">

Cookie blocking diff --git a/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt index 700dd438a..0adf507fd 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt @@ -28,6 +28,7 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before import org.junit.BeforeClass +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -143,6 +144,7 @@ class BaselinePingTest { return null } + @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807288") @Test fun validateBaselinePing() { // Wait for the app to be idle/ready. diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt index f404e990e..eb0888984 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt @@ -4,6 +4,8 @@ package org.mozilla.fenix.helpers +import org.mozilla.fenix.helpers.TestHelper.getSponsoredShortcutTitle + object Constants { // Device or AVD requires a Google Services Android OS installation @@ -28,4 +30,18 @@ object Constants { "Bing" to "firefox&pc=MOZB&form=MOZMBA", "DuckDuckGo" to "t=fpas", ) + + val firstSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(2) } + val secondSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(3) } + + // Expected for en-us defaults + val defaultTopSitesList by lazy { + mapOf( + "Google" to "Google", + "First sponsored shortcut" to firstSponsoredShortcutTitle, + "Second sponsored shortcut" to secondSponsoredShortcutTitle, + "Top Articles" to "Top Articles", + "Wikipedia" to "Wikipedia", + ) + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/MatcherHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/MatcherHelper.kt new file mode 100644 index 000000000..e00026ab2 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/MatcherHelper.kt @@ -0,0 +1,85 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.helpers + +import androidx.test.uiautomator.UiObject +import androidx.test.uiautomator.UiSelector +import org.junit.Assert.assertTrue +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime +import org.mozilla.fenix.helpers.TestHelper.mDevice + +/** + * Helper for querying and interacting with items based on their matchers. + */ +object MatcherHelper { + + fun itemWithResId(resourceId: String) = + mDevice.findObject(UiSelector().resourceId(resourceId)) + + fun itemContainingText(itemText: String) = + mDevice.findObject(UiSelector().textContains(itemText)) + + fun itemWithDescription(description: String) = + mDevice.findObject(UiSelector().descriptionContains(description)) + + fun checkedItemWithResId(resourceId: String, isChecked: Boolean) = + mDevice.findObject(UiSelector().resourceId(resourceId).checked(isChecked)) + + fun checkedItemWithResIdAndText(resourceId: String, text: String, isChecked: Boolean) = + mDevice.findObject( + UiSelector() + .resourceId(resourceId) + .textContains(text) + .checked(isChecked), + ) + + fun itemWithResIdAndDescription(resourceId: String, description: String) = + mDevice.findObject(UiSelector().resourceId(resourceId).descriptionContains(description)) + + fun itemWithResIdAndText(resourceId: String, text: String) = + mDevice.findObject(UiSelector().resourceId(resourceId).text(text)) + + fun assertItemWithResIdExists(vararg appItems: UiObject) { + for (appItem in appItems) { + assertTrue(appItem.waitForExists(waitingTime)) + } + } + + fun assertItemContainingTextExists(vararg appItems: UiObject) { + for (appItem in appItems) { + assertTrue(appItem.waitForExists(waitingTime)) + } + } + + fun assertItemWithDescriptionExists(vararg appItems: UiObject) { + for (appItem in appItems) { + assertTrue(appItem.waitForExists(waitingTime)) + } + } + + fun assertCheckedItemWithResIdExists(vararg appItems: UiObject) { + for (appItem in appItems) { + assertTrue(appItem.waitForExists(waitingTime)) + } + } + + fun assertCheckedItemWithResIdAndTextExists(vararg appItems: UiObject) { + for (appItem in appItems) { + assertTrue(appItem.waitForExists(waitingTime)) + } + } + + fun assertItemWithResIdAndDescriptionExists(vararg appItems: UiObject) { + for (appItem in appItems) { + assertTrue(appItem.waitForExists(waitingTime)) + } + } + + fun assertItemWithResIdAndTextExists(vararg appItems: UiObject) { + for (appItem in appItems) { + assertTrue(appItem.waitForExists(waitingTime)) + } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt index 6d9282635..7b63cdc1e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt @@ -445,4 +445,25 @@ object TestHelper { clipBoard.setPrimaryClip(clipData) } + + /** + * Returns sponsored shortcut title based on the index. + */ + fun getSponsoredShortcutTitle(position: Int): String { + val sponsoredShortcut = mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/top_site_item") + .index(position - 1), + ).getChild( + UiSelector() + .resourceId("$packageName:id/top_site_title"), + ).text + + return sponsoredShortcut + } + + fun verifyLightThemeApplied(expected: Boolean) = + assertFalse("Light theme not selected", expected) + + fun verifyDarkThemeApplied(expected: Boolean) = assertTrue("Dark theme not selected", expected) } diff --git a/app/src/androidTest/java/org/mozilla/fenix/screenshots/MenuScreenShotTest.kt b/app/src/androidTest/java/org/mozilla/fenix/screenshots/MenuScreenShotTest.kt index e73dfd640..7318bcb13 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/screenshots/MenuScreenShotTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/screenshots/MenuScreenShotTest.kt @@ -17,7 +17,6 @@ import androidx.test.uiautomator.Until import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R @@ -164,7 +163,6 @@ class MenuScreenShotTest : ScreenshotTest() { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun tabMenuTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt index 4499583a3..b7543cabe 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -36,16 +36,18 @@ class CollectionTest { private val collectionName = "First Collection" @get:Rule - val composeTestRule = AndroidComposeTestRule( - // disabling these features to have better visibility of Collections, - // and to avoid multiple matches on tab items - HomeActivityIntentTestRule( - isPocketEnabled = false, - isJumpBackInCFREnabled = false, - isRecentTabsFeatureEnabled = false, - isRecentlyVisitedFeatureEnabled = false, - ), - ) { it.activity } + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule( + isHomeOnboardingDialogEnabled = false, + isJumpBackInCFREnabled = false, + isRecentTabsFeatureEnabled = false, + isRecentlyVisitedFeatureEnabled = false, + isPocketEnabled = false, + isWallpaperOnboardingEnabled = false, + isTCPCFREnabled = false, + ), + ) { it.activity } @Before fun setUp() { @@ -63,7 +65,6 @@ class CollectionTest { @SmokeTest @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun createFirstCollectionTest() { val firstWebPage = getGenericAsset(mockWebServer, 1) val secondWebPage = getGenericAsset(mockWebServer, 2) @@ -76,7 +77,6 @@ class CollectionTest { }.submitQuery(secondWebPage.url.toString()) { mDevice.waitForIdle() }.goToHomescreen { - swipeToBottom() }.clickSaveTabsToCollectionButton { longClickTab(firstWebPage.title) selectTab(secondWebPage.title, numOfTabs = 2) @@ -96,7 +96,6 @@ class CollectionTest { @SmokeTest @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun verifyExpandedCollectionItemsTest() { val webPage = getGenericAsset(mockWebServer, 1) val webPageUrl = webPage.url.host.toString() @@ -146,7 +145,6 @@ class CollectionTest { @SmokeTest @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun openAllTabsInCollectionTest() { val firstTestPage = getGenericAsset(mockWebServer, 1) val secondTestPage = getGenericAsset(mockWebServer, 2) @@ -179,7 +177,6 @@ class CollectionTest { @SmokeTest @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun shareCollectionTest() { val firstWebsite = getGenericAsset(mockWebServer, 1) val secondWebsite = getGenericAsset(mockWebServer, 2) @@ -204,11 +201,10 @@ class CollectionTest { } } - @SmokeTest - @Test // Test running on beta/release builds in CI: // caution when making changes to it, so they don't block the builds - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") + @SmokeTest + @Test fun deleteCollectionTest() { val webPage = getGenericAsset(mockWebServer, 1) @@ -231,9 +227,8 @@ class CollectionTest { } } - @Test // open a webpage, and add currently opened tab to existing collection - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") + @Test fun mainMenuSaveToExistingCollection() { val firstWebPage = getGenericAsset(mockWebServer, 1) val secondWebPage = getGenericAsset(mockWebServer, 2) @@ -260,7 +255,6 @@ class CollectionTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun verifyAddTabButtonOfCollectionMenu() { val firstWebPage = getGenericAsset(mockWebServer, 1) val secondWebPage = getGenericAsset(mockWebServer, 2) @@ -287,7 +281,6 @@ class CollectionTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun renameCollectionTest() { val webPage = getGenericAsset(mockWebServer, 1) @@ -308,7 +301,6 @@ class CollectionTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun createSecondCollectionTest() { val webPage = getGenericAsset(mockWebServer, 1) @@ -331,7 +323,6 @@ class CollectionTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun removeTabFromCollectionTest() { val webPage = getGenericAsset(mockWebServer, 1) @@ -354,7 +345,6 @@ class CollectionTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun swipeLeftToRemoveTabFromCollectionTest() { val testPage = getGenericAsset(mockWebServer, 1) @@ -381,7 +371,6 @@ class CollectionTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun swipeRightToRemoveTabFromCollectionTest() { val testPage = getGenericAsset(mockWebServer, 1) @@ -493,7 +482,7 @@ class CollectionTest { homeScreen { verifySnackBarText("Collection deleted") - clickUndoCollectionDeletion("UNDO") + clickUndoSnackBarButton() verifyCollectionIsDisplayed(collectionName, true) } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt index 6545f4adc..03518169f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt @@ -33,7 +33,7 @@ class DownloadFileTypesTest(fileName: String) { @JvmStatic @Parameterized.Parameters fun downloadList() = listOf( - "washington.pdf", + "smallZip.zip", "MyDocument.docx", "audioSample.mp3", "textfile.txt", diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt index 95ea1083f..8bd4dc94e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt @@ -8,7 +8,6 @@ import androidx.core.net.toUri import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest @@ -165,7 +164,6 @@ class EnhancedTrackingProtectionTest { } } - @Ignore("Permanent failure: https://github.com/mozilla-mobile/fenix/issues/27312") @Test fun testStrictVisitSheetDetails() { appContext.settings().setStrictETP() @@ -182,7 +180,11 @@ class EnhancedTrackingProtectionTest { navigationToolbar { }.enterURLAndEnterToBrowser(trackingProtectionTest.url) { - verifyTrackingProtectionWebContent("blocked") + verifyTrackingProtectionWebContent("social blocked") + verifyTrackingProtectionWebContent("ads blocked") + verifyTrackingProtectionWebContent("analytics blocked") + verifyTrackingProtectionWebContent("Fingerprinting blocked") + verifyTrackingProtectionWebContent("Cryptomining blocked") } enhancedTrackingProtection { }.openEnhancedTrackingProtectionSheet { @@ -197,7 +199,6 @@ class EnhancedTrackingProtectionTest { } } - @Ignore("Permanent failure: https://github.com/mozilla-mobile/fenix/issues/27312") @SmokeTest @Test fun customTrackingProtectionSettingsTest() { @@ -217,7 +218,13 @@ class EnhancedTrackingProtectionTest { // browsing a basic page to allow GV to load on a fresh run }.enterURLAndEnterToBrowser(genericWebPage.url) { }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(trackingPage.url) {} + }.enterURLAndEnterToBrowser(trackingPage.url) { + verifyTrackingProtectionWebContent("social blocked") + verifyTrackingProtectionWebContent("ads blocked") + verifyTrackingProtectionWebContent("analytics blocked") + verifyTrackingProtectionWebContent("Fingerprinting blocked") + verifyTrackingProtectionWebContent("Cryptomining blocked") + } enhancedTrackingProtection { }.openEnhancedTrackingProtectionSheet { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt index e28888505..51feef55c 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt @@ -155,81 +155,6 @@ class HomeScreenTest { } } - @Test - fun dismissOnboardingUsingSettingsTest() { - homeScreen { - verifyWelcomeHeader() - }.openThreeDotMenu { - }.openSettings { - verifyGeneralHeading() - }.goBack { - verifyExistingTopSitesList() - } - } - - @Test - fun dismissOnboardingUsingBookmarksTest() { - homeScreen { - verifyWelcomeHeader() - }.openThreeDotMenu { - }.openBookmarks { - verifyBookmarksMenuView() - navigateUp() - } - homeScreen { - verifyExistingTopSitesList() - } - } - - @Test - fun dismissOnboardingUsingHelpTest() { - activityTestRule.activityRule.applySettingsExceptions { - it.isJumpBackInCFREnabled = false - it.isWallpaperOnboardingEnabled = false - } - - homeScreen { - verifyWelcomeHeader() - }.openThreeDotMenu { - }.openHelp { - verifyHelpUrl() - }.goBack { - verifyExistingTopSitesList() - } - } - - @Test - fun dismissOnboardingWithPageLoadTest() { - activityTestRule.activityRule.applySettingsExceptions { - it.isJumpBackInCFREnabled = false - it.isWallpaperOnboardingEnabled = false - } - - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) - - homeScreen { - verifyWelcomeHeader() - } - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.goToHomescreen { - verifyExistingTopSitesList() - } - } - - @Test - fun toolbarTapDoesntDismissOnboardingTest() { - homeScreen { - verifyWelcomeHeader() - }.openSearch { - verifyScanButton() - verifySearchEngineButton() - verifyKeyboardVisibility() - }.dismissSearchBar { - verifyWelcomeHeader() - } - } - @Test fun verifyPocketHomepageStoriesTest() { activityTestRule.activityRule.applySettingsExceptions { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt index 3f602610f..8b853a349 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt @@ -65,7 +65,7 @@ class NavigationToolbarTest { }.enterURLAndEnterToBrowser(nextWebPage.url) { verifyUrl(nextWebPage.url.toString()) }.openThreeDotMenu { - }.goBack { + }.goToPreviousPage { mDevice.waitForIdle() verifyUrl(defaultWebPage.url.toString()) } @@ -84,7 +84,7 @@ class NavigationToolbarTest { mDevice.waitForIdle() verifyUrl(nextWebPage.url.toString()) }.openThreeDotMenu { - }.goBack { + }.goToPreviousPage { mDevice.waitForIdle() verifyUrl(defaultWebPage.url.toString()) } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt new file mode 100644 index 000000000..ad0467ba5 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt @@ -0,0 +1,223 @@ +package org.mozilla.fenix.ui + +import android.content.res.Configuration +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.HomeActivityTestRule +import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestHelper.verifyDarkThemeApplied +import org.mozilla.fenix.helpers.TestHelper.verifyLightThemeApplied +import org.mozilla.fenix.ui.robots.homeScreen +import org.mozilla.fenix.ui.robots.navigationToolbar + +class OnboardingTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer + private val privacyNoticeLink = "mozilla.org/en-US/privacy/firefox" + + @get:Rule + val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides() + + @Before + fun setUp() { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + + private fun getUITheme(): Boolean { + val mode = + activityTestRule.activity.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) + + return when (mode) { + Configuration.UI_MODE_NIGHT_YES -> true // dark theme is set + Configuration.UI_MODE_NIGHT_NO -> false // dark theme is not set, using light theme + else -> false // default option is light theme + } + } + + // Verifies the first run onboarding screen + @SmokeTest + @Test + fun firstRunScreenTest() { + homeScreen { + verifyHomeScreenAppBarItems() + verifyHomeScreenWelcomeItems() + verifyChooseYourThemeCard( + isDarkThemeChecked = false, + isLightThemeChecked = false, + isAutomaticThemeChecked = true, + ) + verifyToolbarPlacementCard(isBottomChecked = true, isTopChecked = false) + verifySignInToSyncCard() + verifyPrivacyProtectionCard(isStandardChecked = true, isStrictChecked = false) + verifyPrivacyNoticeCard() + verifyStartBrowsingSection() + verifyNavigationToolbarItems("0") + } + } + + // Verifies the functionality of the onboarding Start Browsing button + @SmokeTest + @Test + fun startBrowsingButtonTest() { + homeScreen { + verifyStartBrowsingButton() + }.clickStartBrowsingButton { + verifySearchView() + } + } + + @Test + fun dismissOnboardingUsingSettingsTest() { + homeScreen { + verifyWelcomeHeader() + }.openThreeDotMenu { + }.openSettings { + verifyGeneralHeading() + }.goBack { + verifyExistingTopSitesList() + } + } + + @Test + fun dismissOnboardingUsingBookmarksTest() { + homeScreen { + verifyWelcomeHeader() + }.openThreeDotMenu { + }.openBookmarks { + verifyBookmarksMenuView() + navigateUp() + } + homeScreen { + verifyExistingTopSitesList() + } + } + + @Test + fun dismissOnboardingUsingHelpTest() { + homeScreen { + verifyWelcomeHeader() + }.openThreeDotMenu { + }.openHelp { + verifyHelpUrl() + }.goBack { + verifyExistingTopSitesList() + } + } + + @Test + fun toolbarTapDoesntDismissOnboardingTest() { + homeScreen { + verifyWelcomeHeader() + }.openSearch { + verifyScanButton() + verifySearchEngineButton() + verifyKeyboardVisibility() + }.dismissSearchBar { + verifyWelcomeHeader() + } + } + + @Test + fun dismissOnboardingWithPageLoadTest() { + val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + homeScreen { + verifyWelcomeHeader() + } + navigationToolbar { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + }.goToHomescreen { + verifyExistingTopSitesList() + } + } + + @Test + fun chooseYourThemeCardTest() { + homeScreen { + verifyChooseYourThemeCard( + isDarkThemeChecked = false, + isLightThemeChecked = false, + isAutomaticThemeChecked = true, + ) + clickLightThemeButton() + verifyChooseYourThemeCard( + isDarkThemeChecked = false, + isLightThemeChecked = true, + isAutomaticThemeChecked = false, + ) + verifyLightThemeApplied(getUITheme()) + clickDarkThemeButton() + verifyChooseYourThemeCard( + isDarkThemeChecked = true, + isLightThemeChecked = false, + isAutomaticThemeChecked = false, + ) + verifyDarkThemeApplied(getUITheme()) + clickAutomaticThemeButton() + verifyChooseYourThemeCard( + isDarkThemeChecked = false, + isLightThemeChecked = false, + isAutomaticThemeChecked = true, + ) + verifyLightThemeApplied(getUITheme()) + } + } + + @Test + fun pickYourToolbarPlacementCardTest() { + homeScreen { + verifyToolbarPlacementCard(isBottomChecked = true, isTopChecked = false) + clickTopToolbarPlacementButton() + verifyToolbarPosition(defaultPosition = false) + clickBottomToolbarPlacementButton() + verifyToolbarPosition(defaultPosition = true) + } + } + + @Test + fun privacyProtectionByDefaultCardTest() { + homeScreen { + verifyPrivacyProtectionCard(isStandardChecked = true, isStrictChecked = false) + clickStrictTrackingProtectionButton() + verifyPrivacyProtectionCard(isStandardChecked = false, isStrictChecked = true) + clickStandardTrackingProtectionButton() + verifyPrivacyProtectionCard(isStandardChecked = true, isStrictChecked = false) + } + } + + @Test + fun pickUpWhereYouLeftOffCardTest() { + homeScreen { + verifySignInToSyncCard() + }.clickSignInButton { + verifyTurnOnSyncMenu() + } + } + + @Test + fun youControlYourDataCardTest() { + homeScreen { + verifyPrivacyNoticeCard() + }.clickPrivacyNoticeButton { + verifyUrl(privacyNoticeLink) + }.goBack { + verifyPrivacyNoticeCard() + } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt index 4cf9c8584..6bb3ce444 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt @@ -1,6 +1,7 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest @@ -45,6 +46,7 @@ class PwaTest { } } + @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/28212") @SmokeTest @Test fun emailLinkPWATest() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt index 9a8a2b103..268d28206 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt @@ -141,7 +141,7 @@ class ReaderViewTest { verifyReaderViewDetected(true) }.openThreeDotMenu { verifyReaderViewAppearance(false) - }.close { } + }.closeBrowserMenuToBrowser { } } @Test diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt index 0176c12ff..ebd8af34a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt @@ -10,6 +10,8 @@ import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu +import org.mozilla.fenix.helpers.TestHelper.verifyDarkThemeApplied +import org.mozilla.fenix.helpers.TestHelper.verifyLightThemeApplied import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt index 4e3e897be..ebcba8243 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt @@ -17,6 +17,7 @@ import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestAssetHelper @@ -53,6 +54,7 @@ class SettingsPrivacyTest { @Before fun setUp() { mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + appContext.settings().userOptOutOfReEngageCookieBannerDialog = true mockWebServer = MockWebServer().apply { dispatcher = AndroidAssetDispatcher() start() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt index 5708ff37c..8670d956f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt @@ -98,53 +98,81 @@ class SettingsSearchTest { @Test fun toggleSearchBookmarksAndHistoryTest() { - // Bookmarks 2 websites, toggles the bookmarks and history search settings off, - // then verifies if the websites do not show in the suggestions. val page1 = getGenericAsset(mockWebServer, 1) val page2 = getGenericAsset(mockWebServer, 2) navigationToolbar { }.enterURLAndEnterToBrowser(page1.url) { + }.openTabDrawer { + closeTab() + } + + homeScreen { + }.openSearch { + typeSearch("test") + verifyFirefoxSuggestResults( + activityTestRule, + "test", + "Firefox Suggest", + "Test_Page_1", + ) + }.clickSearchSuggestion("Test_Page_1") { verifyUrl(page1.url.toString()) - }.openThreeDotMenu { - }.bookmarkPage { }.openTabDrawer { closeTab() } + navigationToolbar { }.enterURLAndEnterToBrowser(page2.url) { - verifyUrl(page2.url.toString()) }.openThreeDotMenu { }.bookmarkPage { }.openTabDrawer { closeTab() } - // Verifies that bookmarks & history suggestions are shown + + homeScreen { + }.openThreeDotMenu { + }.openHistory { + verifyHistoryListExists() + clickDeleteHistoryButton("Test_Page_2") + } + + exitMenu() + homeScreen { }.openSearch { typeSearch("test") - expandSearchSuggestionsList() - verifyFirefoxSuggestResults(activityTestRule, "Firefox Suggest") - verifyFirefoxSuggestResults(activityTestRule, "Test_Page_1") - verifyFirefoxSuggestResults(activityTestRule, "Test_Page_2") - }.dismissSearchBar { + verifyFirefoxSuggestResults( + activityTestRule, + "test", + "Firefox Suggest", + "Test_Page_2", + ) + }.clickSearchSuggestion("Test_Page_2") { + verifyUrl(page2.url.toString()) + }.openTabDrawer { + closeTab() + } + + homeScreen { }.openThreeDotMenu { }.openSettings { }.openSearchSubMenu { - // Disables the search bookmarks & history settings - verifySearchBookmarks() - switchSearchBookmarksToggle() switchSearchHistoryToggle() - exitMenu() + switchSearchBookmarksToggle() } - // Verifies that bookmarks and history suggestions are not shown + + exitMenu() + homeScreen { }.openSearch { typeSearch("test") - expandSearchSuggestionsList() - verifyNoSuggestionsAreDisplayed(activityTestRule, "Firefox Suggest") - verifyNoSuggestionsAreDisplayed(activityTestRule, "Test_Page_1") - verifyNoSuggestionsAreDisplayed(activityTestRule, "Test_Page_2") + verifyNoSuggestionsAreDisplayed( + activityTestRule, + "Firefox Suggest", + "Test_Page_1", + "Test_Page_2", + ) } } @@ -453,6 +481,7 @@ class SettingsSearchTest { "eBay", "Wikipedia", ) + scrollToSearchEngineSettings(activityTestRule) }.clickSearchEngineSettings(activityTestRule) { toggleShowSearchShortcuts() verifyShowSearchEnginesToggleState(false) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index 8d0077f7e..0868e1336 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -17,7 +17,6 @@ import mozilla.components.concept.engine.mediasession.MediaSession import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.IntentReceiverActivity @@ -106,36 +105,6 @@ class SmokeTest { featureSettingsHelper.resetAllFeatureFlags() } - // Verifies the first run onboarding screen - @Test - fun firstRunScreenTest() { - homeScreen { - verifyHomeScreenAppBarItems() - verifyHomeScreenWelcomeItems() - verifyChooseYourThemeCard( - isDarkThemeChecked = false, - isLightThemeChecked = false, - isAutomaticThemeChecked = true, - ) - verifyToolbarPlacementCard(isBottomChecked = true, isTopChecked = false) - verifySignInToSyncCard() - verifyPrivacyProtectionCard(isStandardChecked = true, isStrictChecked = false) - verifyPrivacyNoticeCard() - verifyStartBrowsingSection() - verifyNavigationToolbarItems("0") - } - } - - // Verifies the functionality of the onboarding Start Browsing button - @Test - fun startBrowsingButtonTest() { - homeScreen { - verifyStartBrowsingButton() - }.clickStartBrowsingButton { - verifySearchView() - } - } - /* Verifies the nav bar: - opening a web page - the existence of nav bar items @@ -172,7 +141,7 @@ class SmokeTest { }.enterURLAndEnterToBrowser(defaultWebPage.url) { waitForPageToLoad() }.openThreeDotMenu { - verifyPageThreeDotMainMenuItems() + verifyPageThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false) } } @@ -283,7 +252,7 @@ class SmokeTest { }.openThreeDotMenu { expandMenu() }.openAddToHomeScreen { - verifyShortcutNameField("Test_Page_1") + verifyShortcutTextFieldTitle("Test_Page_1") addShortcutName(shortcutTitle) clickAddShortcutButton() clickAddAutomaticallyButton() @@ -524,7 +493,6 @@ class SmokeTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun shareTabsFromTabsTrayTest() { val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) @@ -572,7 +540,6 @@ class SmokeTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun privateTabsTrayWithOpenedTabTest() { val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -582,7 +549,6 @@ class SmokeTest { homeScreen { }.openNavigationToolbar { }.enterURLAndEnterToBrowser(website.url) { - mDevice.waitForIdle() }.openTabDrawer { verifyNormalBrowsingButtonIsSelected(false) verifyPrivateBrowsingButtonIsSelected(true) @@ -592,7 +558,8 @@ class SmokeTest { verifyExistingTabList() verifyExistingOpenTabs(website.title) verifyCloseTabsButton(website.title) - verifyOpenedTabThumbnail() + // Disabled step due to ongoing tabs tray compose refactoring, see: https://github.com/mozilla-mobile/fenix/issues/21318 + // verifyOpenedTabThumbnail() verifyPrivateBrowsingNewTabButton() } } @@ -772,7 +739,6 @@ class SmokeTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun tabMediaControlButtonTest() { val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt new file mode 100644 index 000000000..86c8a006d --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt @@ -0,0 +1,252 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before +import org.junit.Ignore +import org.junit.Rule +import org.junit.Test +import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.Constants.defaultTopSitesList +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestHelper +import org.mozilla.fenix.helpers.TestHelper.exitMenu +import org.mozilla.fenix.helpers.TestHelper.getSponsoredShortcutTitle +import org.mozilla.fenix.ui.robots.homeScreen + +/** + * Tests Sponsored shortcuts functionality + */ + +class SponsoredShortcutsTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer + private val defaultSearchEngine = "Amazon.com" + private lateinit var sponsoredShortcutTitle: String + private lateinit var sponsoredShortcutTitle2: String + + @get:Rule + val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) + + @Before + fun setUp() { + TestHelper.appContext.settings().userOptOutOfReEngageCookieBannerDialog = true + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + + // Expected for en-us defaults + @SmokeTest + @Test + fun verifySponsoredShortcutsListTest() { + homeScreen { + defaultTopSitesList.values.forEach { value -> + verifyExistingTopSitesTabs(value) + } + }.openThreeDotMenu { + }.openCustomizeHome { + verifySponsoredShortcutsCheckBox(true) + clickSponsoredShortcuts() + verifySponsoredShortcutsCheckBox(false) + }.goBack { + verifyNotExistingSponsoredTopSitesList() + } + } + + @Test + fun openSponsoredShortcutTest() { + homeScreen { + sponsoredShortcutTitle = getSponsoredShortcutTitle(2) + }.openSponsoredShortcut(sponsoredShortcutTitle) { + verifyUrl(sponsoredShortcutTitle) + } + } + + @Test + fun openSponsoredShortcutInPrivateBrowsingTest() { + homeScreen { + sponsoredShortcutTitle = getSponsoredShortcutTitle(2) + }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { + }.openTopSiteInPrivateTab { + verifyUrl(sponsoredShortcutTitle) + } + } + + @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25926") + @Test + fun verifySponsorsAndPrivacyLinkTest() { + homeScreen { + sponsoredShortcutTitle = getSponsoredShortcutTitle(2) + }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { + }.clickSponsorsAndPrivacyButton { + verifyUrl("support.mozilla.org/en-US/kb/sponsor-privacy") + } + } + + @Test + fun verifySponsoredShortcutsSettingsOptionTest() { + homeScreen { + sponsoredShortcutTitle = getSponsoredShortcutTitle(2) + }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { + }.clickSponsoredShortcutsSettingsButton { + verifyHomePageView() + } + } + + @Test + fun verifySponsoredShortcutsDetailsTest() { + homeScreen { + sponsoredShortcutTitle = getSponsoredShortcutTitle(2) + sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3) + + verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2) + verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3) + } + } + + // The default search engine should not be displayed as a sponsored shortcut + @Test + fun defaultSearchEngineIsNotDisplayedAsSponsoredShortcutTest() { + val sponsoredShortcutTitle = "Amazon" + + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openSearchSubMenu { + changeDefaultSearchEngine(defaultSearchEngine) + } + + exitMenu() + + homeScreen { + verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle, 2) + verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle, 3) + } + } + + // 1 sponsored shortcut should be displayed if there are 7 pinned top sites + @Test + fun verifySponsoredShortcutsListWithSevenPinnedSitesTest() { + val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) + val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) + val fourthWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 4) + + homeScreen { + sponsoredShortcutTitle = getSponsoredShortcutTitle(2) + sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3) + + verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2) + verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + verifyPageContent(firstWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifyExistingTopSitesTabs(firstWebPage.title) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(secondWebPage.url) { + verifyPageContent(secondWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifyExistingTopSitesTabs(secondWebPage.title) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(thirdWebPage.url) { + verifyPageContent(thirdWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifyExistingTopSitesTabs(thirdWebPage.title) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(fourthWebPage.url) { + verifyPageContent(fourthWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2) + verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle2, 3) + } + } + + // No sponsored shortcuts should be displayed if there are 8 pinned top sites + @Test + fun verifySponsoredShortcutsListWithEightPinnedSitesTest() { + val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) + val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) + val fourthWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 4) + val fifthWebPage = TestAssetHelper.getLoremIpsumAsset(mockWebServer) + + homeScreen { + sponsoredShortcutTitle = getSponsoredShortcutTitle(2) + sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3) + + verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2) + verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + verifyPageContent(firstWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifyExistingTopSitesTabs(firstWebPage.title) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(secondWebPage.url) { + verifyPageContent(secondWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifyExistingTopSitesTabs(secondWebPage.title) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(thirdWebPage.url) { + verifyPageContent(thirdWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifyExistingTopSitesTabs(thirdWebPage.title) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(fourthWebPage.url) { + verifyPageContent(fourthWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifyExistingTopSitesTabs(fourthWebPage.title) + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(fifthWebPage.url) { + verifyPageContent(fifthWebPage.content) + }.openThreeDotMenu { + expandMenu() + }.addToFirefoxHome { + }.goToHomescreen { + verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle, 2) + verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle2, 3) + } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt index 69761496f..7dc240959 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -234,7 +234,6 @@ class TabbedBrowsingTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun verifyPrivateTabUndoSnackBarTest() { val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -314,7 +313,6 @@ class TabbedBrowsingTest { } @Test - @Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087") fun verifyOpenTabDetails() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -328,7 +326,8 @@ class TabbedBrowsingTest { verifyTabsTrayCounter() verifyExistingTabList() verifyNormalBrowsingNewTabButton() - verifyOpenedTabThumbnail() + // Disabled step due to ongoing tabs tray compose refactoring, see: https://github.com/mozilla-mobile/fenix/issues/21318 + // verifyOpenedTabThumbnail() verifyExistingOpenTabs(defaultWebPage.title) verifyCloseTabsButton(defaultWebPage.title) }.openTab(defaultWebPage.title) { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt index a27ddc7b6..f3f47f6d0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt @@ -11,6 +11,7 @@ import org.junit.Rule import org.junit.Test import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityTestRule +import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.ui.robots.homeScreen /** @@ -44,50 +45,155 @@ class ThreeDotMenuMainTest { fun homeThreeDotMenuItemsTest() { homeScreen { }.openThreeDotMenu { - verifyBookmarksButton() - verifyHistoryButton() - verifyDownloadsButton() - verifyAddOnsButton() - // Disabled step due to https://github.com/mozilla-mobile/fenix/issues/26788 - // verifySyncSignInButton() - verifyDesktopSite() - verifyWhatsNewButton() - verifyHelpButton() - verifyCustomizeHomeButton() - verifySettingsButton() - }.openSettings { - verifySettingsView() + verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false) + }.openBookmarks { + verifyBookmarksMenuView() }.goBack { }.openThreeDotMenu { - }.openCustomizeHome { - verifyHomePageView() + }.openHistory { + verifyHistoryMenuView() + }.goBack { + }.openThreeDotMenu { + }.openDownloadsManager { + verifyEmptyDownloadsList() }.goBack { }.openThreeDotMenu { + }.openAddonsManagerMenu { + verifyAddonsItems() + }.goBack { + }.openThreeDotMenu { + }.openSyncSignIn { + verifyTurnOnSyncMenu() + }.goBack { + // Desktop toggle + }.openThreeDotMenu { + }.switchDesktopSiteMode { + } + homeScreen { + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled = true) + }.openWhatsNew { + verifyWhatsNewURL() + }.goToHomescreen { + }.openThreeDotMenu { }.openHelp { verifyHelpUrl() - }.openTabDrawer { - closeTab() + }.goToHomescreen { + }.openThreeDotMenu { + }.openCustomizeHome { + verifyHomePageView() + }.goBack { + }.openThreeDotMenu { + }.openSettings { + verifySettingsView() } + } + // Verifies the list of items in the homescreen's 3 dot main menu in private browsing + @Test + fun privateHomeThreeDotMenuItemsTest() { homeScreen { + }.togglePrivateBrowsingMode() + homeScreen { + }.openThreeDotMenu { + verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false) + }.openBookmarks { + verifyBookmarksMenuView() + }.goBack { + }.openThreeDotMenu { + }.openHistory { + verifyHistoryMenuView() + }.goBack { }.openThreeDotMenu { + }.openDownloadsManager { + verifyEmptyDownloadsList() + }.goBack { + }.openThreeDotMenu { + }.openAddonsManagerMenu { + verifyAddonsItems() + }.goBack { + }.openThreeDotMenu { + }.openSyncSignIn { + verifyTurnOnSyncMenu() + }.goBack { + // Desktop toggle + }.openThreeDotMenu { + }.switchDesktopSiteMode { + } + homeScreen { + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled = true) }.openWhatsNew { verifyWhatsNewURL() - }.openTabDrawer { - closeTab() + }.goToHomescreen { + }.openThreeDotMenu { + }.openHelp { + verifyHelpUrl() + }.goToHomescreen { + }.openThreeDotMenu { + }.openCustomizeHome { + verifyHomePageView() + }.goBack { + }.openThreeDotMenu { + }.openSettings { + verifySettingsView() } + } + + @Test + fun setDesktopSiteBeforePageLoadTest() { + val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4) homeScreen { }.openThreeDotMenu { - }.openBookmarks { - verifyBookmarksMenuView() - }.closeMenu { + verifyDesktopSiteModeEnabled(false) + }.switchDesktopSiteMode { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(true) + }.closeBrowserMenuToBrowser { + clickLinkMatchingText("Link 1") + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(true) + }.closeBrowserMenuToBrowser { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + longClickLink("Link 2") + clickContextOpenLinkInNewTab() + snackBarButtonClick() + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(false) } + } + + @Test + fun privateBrowsingSetDesktopSiteBeforePageLoadTest() { + val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4) + + homeScreen { + }.togglePrivateBrowsingMode() homeScreen { }.openThreeDotMenu { - }.openHistory { - verifyHistoryMenuView() + verifyDesktopSiteModeEnabled(false) + }.switchDesktopSiteMode { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(true) + }.closeBrowserMenuToBrowser { + clickLinkMatchingText("Link 1") + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(true) + }.closeBrowserMenuToBrowser { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + longClickLink("Link 2") + clickContextOpenLinkInPrivateTab() + snackBarButtonClick() + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(false) } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt index 12fef0855..43e632a0a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt @@ -9,12 +9,12 @@ import androidx.test.uiautomator.UiDevice import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.Constants.defaultTopSitesList import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset @@ -67,7 +67,7 @@ class TopSitesTest { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { expandMenu() - verifyAddToTopSitesButton() + verifyAddToShortcutsButton() }.addToFirefoxHome { verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) }.goToHomescreen { @@ -84,7 +84,7 @@ class TopSitesTest { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { expandMenu() - verifyAddToTopSitesButton() + verifyAddToShortcutsButton() }.addToFirefoxHome { verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) }.goToHomescreen { @@ -111,7 +111,7 @@ class TopSitesTest { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { expandMenu() - verifyAddToTopSitesButton() + verifyAddToShortcutsButton() }.addToFirefoxHome { verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) }.goToHomescreen { @@ -134,7 +134,7 @@ class TopSitesTest { waitForPageToLoad() }.openThreeDotMenu { expandMenu() - verifyAddToTopSitesButton() + verifyAddToShortcutsButton() }.addToFirefoxHome { verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) }.goToHomescreen { @@ -156,7 +156,7 @@ class TopSitesTest { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { expandMenu() - verifyAddToTopSitesButton() + verifyAddToShortcutsButton() }.addToFirefoxHome { verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) }.goToHomescreen { @@ -169,6 +169,28 @@ class TopSitesTest { } } + @Test + fun verifyUndoRemoveTopSite() { + val defaultWebPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + }.openThreeDotMenu { + expandMenu() + verifyAddToShortcutsButton() + }.addToFirefoxHome { + verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) + }.goToHomescreen { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(defaultWebPage.title) + }.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) { + verifyTopSiteContextMenuItems() + }.removeTopSite { + clickUndoSnackBarButton() + verifyExistingTopSitesTabs(defaultWebPage.title) + } + } + @Test fun verifyRemoveTopSiteFromMainMenu() { val defaultWebPage = getGenericAsset(mockWebServer, 1) @@ -177,7 +199,7 @@ class TopSitesTest { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { expandMenu() - verifyAddToTopSitesButton() + verifyAddToShortcutsButton() }.addToFirefoxHome { verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) }.goToHomescreen { @@ -192,21 +214,15 @@ class TopSitesTest { } } + // Expected for en-us defaults @Test - fun verifyDefaultTopSitesLocale_EN() { - // en-US defaults - val defaultTopSites = arrayOf( - "Top Articles", - "Wikipedia", - "Google", - ) - + fun verifyDefaultTopSitesList() { homeScreen { }.dismissOnboarding() homeScreen { verifyExistingTopSitesList() - defaultTopSites.forEach { item -> - verifyExistingTopSitesTabs(item) + defaultTopSitesList.values.forEach { value -> + verifyExistingTopSitesTabs(value) } } } @@ -236,71 +252,4 @@ class TopSitesTest { verifyEmptyHistoryView() } } - - @SmokeTest - @Test - fun verifySponsoredShortcutsListTest() { - homeScreen { - var sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - var sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3) - - verifyExistingSponsoredTopSitesTabs(sponsoredShortcutTitle, 2) - verifyExistingSponsoredTopSitesTabs(sponsoredShortcutTitle2, 3) - }.openThreeDotMenu { - }.openCustomizeHome { - verifySponsoredShortcutsCheckBox(true) - clickSponsoredShortcuts() - verifySponsoredShortcutsCheckBox(false) - }.goBack { - verifyNotExistingSponsoredTopSitesList() - } - } - - @Test - fun openSponsoredShortcutTest() { - var sponsoredShortcutTitle = "" - - homeScreen { - sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openSponsoredShortcut(sponsoredShortcutTitle) { - verifyUrl(sponsoredShortcutTitle) - } - } - - @Test - fun openSponsoredShortcutInPrivateBrowsingTest() { - var sponsoredShortcutTitle = "" - - homeScreen { - sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { - }.openTopSiteInPrivateTab { - verifyUrl(sponsoredShortcutTitle) - } - } - - @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25926") - @Test - fun verifySponsoredShortcutsSponsorsAndPrivacyOptionTest() { - var sponsoredShortcutTitle = "" - - homeScreen { - sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { - }.clickSponsorsAndPrivacyButton { - verifyUrl("support.mozilla.org/en-US/kb/sponsor-privacy") - } - } - - @Test - fun verifySponsoredShortcutsSettingsOptionTest() { - var sponsoredShortcutTitle = "" - - homeScreen { - sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { - }.clickSponsoredShortcutsSettingsButton { - verifyHomePageView() - } - } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt index a79e0de65..7f98007af 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt @@ -6,24 +6,22 @@ package org.mozilla.fenix.ui.robots import android.os.Build import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.clearText -import androidx.test.espresso.action.ViewActions.typeText import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until -import org.hamcrest.CoreMatchers.allOf import org.junit.Assert.assertTrue import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.mDevice +import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.click -import org.mozilla.fenix.helpers.ext.waitNotNull import java.util.regex.Pattern /** @@ -37,18 +35,15 @@ class AddToHomeScreenRobot { fun clickAddPrivateBrowsingShortcutButton() = addPrivateBrowsingShortcutButton().click() - fun addShortcutName(title: String) { - mDevice.waitNotNull(Until.findObject(By.text("Add to Home screen")), waitingTime) - shortcutNameField() - .perform(clearText()) - .perform(typeText(title)) - } + fun addShortcutName(title: String) = shortcutTextField.setText(title) - fun verifyShortcutNameField(expectedText: String) = assertShortcutNameField(expectedText) + fun verifyShortcutTextFieldTitle(title: String) = assertItemContainingTextExists(shortcutTitle(title)) - fun clickAddShortcutButton() = addButton().click() + fun clickAddShortcutButton() = + confirmAddToHomeScreenButton.clickAndWaitForNewWindow(waitingTime) - fun clickCancelShortcutButton() = cancelAddToHomeScreenButton().click() + fun clickCancelShortcutButton() = + cancelAddToHomeScreenButton.click() fun clickAddAutomaticallyButton() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -106,22 +101,6 @@ fun addToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenR return AddToHomeScreenRobot.Transition() } -private fun shortcutNameField() = onView(withId(R.id.shortcut_text)) - -private fun assertShortcutNameField(expectedText: String) { - onView( - allOf( - withId(R.id.shortcut_text), - withText(expectedText), - ), - ) - .check(matches(isCompletelyDisplayed())) -} - -private fun addButton() = onView((withText("ADD"))) - -private fun cancelAddToHomeScreenButton() = onView((withText("CANCEL"))) - private fun addAutomaticallyButton() = mDevice.findObject(UiSelector().textContains("add automatically")) @@ -134,3 +113,12 @@ private fun noThanksPrivateBrowsingShortcutButton() = onView(withId(R.id.cfr_neg private fun assertNoThanksPrivateBrowsingShortcutButton() = noThanksPrivateBrowsingShortcutButton() .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + +private val cancelAddToHomeScreenButton = + itemWithResId("$packageName:id/cancel_button") +private val confirmAddToHomeScreenButton = + itemWithResId("$packageName:id/add_button") +private val shortcutTextField = + itemWithResId("$packageName:id/shortcut_text") +private fun shortcutTitle(title: String) = + itemWithResIdAndText("$packageName:id/shortcut_text", title) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt index 27e3b1fb4..45020245a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt @@ -258,6 +258,13 @@ class BookmarksRobot { SettingsTurnOnSyncRobot().interact() return SettingsTurnOnSyncRobot.Transition() } + + fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + goBackButton().click() + + HomeScreenRobot().interact() + return HomeScreenRobot.Transition() + } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index 7a5d4341e..a32380d59 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -44,6 +44,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION import org.mozilla.fenix.helpers.Constants.RETRY_COUNT +import org.mozilla.fenix.helpers.MatcherHelper import org.mozilla.fenix.helpers.SessionLoadedIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong @@ -911,22 +912,32 @@ class BrowserRobot { } fun openTabDrawer(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { - mDevice.waitForObjects( - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/mozac_browser_toolbar_browser_actions"), - ), - waitingTime, - ) - - tabsCounter().click() - - mDevice.waitForObjects( - mDevice.findObject( - UiSelector().resourceId("$packageName:id/new_tab_button"), - ), - waitingTime, - ) + for (i in 1..RETRY_COUNT) { + try { + mDevice.waitForObjects( + mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/mozac_browser_toolbar_browser_actions"), + ), + waitingTime, + ) + + tabsCounter().click() + assertTrue( + MatcherHelper.itemWithResId("$packageName:id/new_tab_button") + .waitForExists(waitingTime), + ) + + break + } catch (e: AssertionError) { + if (i == RETRY_COUNT) { + throw e + } else { + mDevice.waitForIdle() + } + } + } + assertTrue(MatcherHelper.itemWithResId("$packageName:id/new_tab_button").waitForExists(waitingTime)) TabDrawerRobot().interact() return TabDrawerRobot.Transition() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt index b6a993c7f..b48c5644b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ui.robots import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.hasContentDescription import androidx.compose.ui.test.hasText +import androidx.compose.ui.test.isDialog import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTouchInput @@ -15,6 +16,7 @@ import androidx.compose.ui.test.swipeRight import androidx.test.espresso.Espresso.onView import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.action.ViewActions.pressImeActionButton +import androidx.test.espresso.matcher.RootMatchers import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.uiautomator.By import androidx.test.uiautomator.UiScrollable @@ -23,10 +25,12 @@ import androidx.test.uiautomator.Until import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText +import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.ext.waitNotNull class CollectionRobot { @@ -57,7 +61,8 @@ class CollectionRobot { // names a collection saved from tab drawer fun typeCollectionNameAndSave(collectionName: String) { collectionNameTextField().text = collectionName - mDevice.findObject(UiSelector().textContains("OK")).click() + addCollectionButtonPanel.waitForExists(waitingTime) + addCollectionOkButton.click() } fun verifyTabsSelectedCounterText(numOfTabs: Int) { @@ -289,3 +294,7 @@ private fun backButton() = mDevice.findObject( UiSelector().resourceId("$packageName:id/back_button"), ) +private val addCollectionButtonPanel = + itemWithResId("$packageName:id/buttonPanel") + +private val addCollectionOkButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt index 52f87e576..502853662 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt @@ -123,6 +123,13 @@ class DownloadRobot { BrowserRobot().interact() return BrowserRobot.Transition() } + + fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + goBackButton().click() + + HomeScreenRobot().interact() + return HomeScreenRobot.Transition() + } } } @@ -195,3 +202,5 @@ private fun assertDownloadedFileIcon() = mDevice.findObject(UiSelector().resourceId("$packageName:id/favicon")) .exists(), ) + +private fun goBackButton() = onView(withContentDescription("Navigate up")) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index b74d1b313..2de155b53 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -37,7 +37,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withHint import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiObject import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until @@ -54,6 +53,16 @@ import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.helpers.Constants.LISTS_MAXSWIPES import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION +import org.mozilla.fenix.helpers.MatcherHelper.assertCheckedItemWithResIdExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndDescriptionExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists +import org.mozilla.fenix.helpers.MatcherHelper.checkedItemWithResId +import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndDescription +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper.appContext @@ -76,15 +85,15 @@ class HomeScreenRobot { " service provider, it makes it easier to keep what you do online private from anyone" + " else who uses this device." - fun verifyNavigationToolbar() = assertAppItemsWithResourceId(navigationToolbar) + fun verifyNavigationToolbar() = assertItemWithResIdExists(navigationToolbar) fun verifyFocusedNavigationToolbar() = assertFocusedNavigationToolbar() - fun verifyHomeScreen() = assertAppItemsWithResourceId(homeScreen) + fun verifyHomeScreen() = assertItemWithResIdExists(homeScreen) fun verifyHomeScreenAppBarItems() = - assertAppItemsWithResourceId(homeScreen, privateBrowsingButton, homepageWordmark) + assertItemWithResIdExists(homeScreen, privateBrowsingButton, homepageWordmark) fun verifyHomeScreenWelcomeItems() = - assertAppItemsContainingText(welcomeHeader, welcomeSubHeader) + assertItemContainingTextExists(welcomeHeader, welcomeSubHeader) fun verifyChooseYourThemeCard( isDarkThemeChecked: Boolean, @@ -92,28 +101,37 @@ class HomeScreenRobot { isAutomaticThemeChecked: Boolean, ) { scrollToElementByText(getStringResource(R.string.onboarding_theme_picker_header)) - assertAppItemsContainingText( + assertItemContainingTextExists( chooseThemeHeader, chooseThemeText, darkThemeDescription, lightThemeDescription, ) - assertAppItemsStateWithResourceId( + assertCheckedItemWithResIdExists( darkThemeToggle(isDarkThemeChecked), lightThemeToggle(isLightThemeChecked), automaticThemeToggle(isAutomaticThemeChecked), ) - assertAppItemsWithResourceIdAndDescription(automaticThemeDescription) + assertItemWithResIdAndDescriptionExists(automaticThemeDescription) } + fun clickLightThemeButton() = + itemWithResId("$packageName:id/theme_light_radio_button").click() + + fun clickDarkThemeButton() = + itemWithResId("$packageName:id/theme_dark_radio_button").click() + + fun clickAutomaticThemeButton() = + itemWithResId("$packageName:id/theme_automatic_radio_button").click() + fun verifyToolbarPlacementCard(isBottomChecked: Boolean, isTopChecked: Boolean) { scrollToElementByText(getStringResource(R.string.onboarding_toolbar_placement_header_1)) - assertAppItemsContainingText(toolbarPlacementHeader, toolbarPlacementDescription) - assertAppItemsStateWithResourceId( + assertItemContainingTextExists(toolbarPlacementHeader, toolbarPlacementDescription) + assertCheckedItemWithResIdExists( toolbarPlacementBottomRadioButton(isBottomChecked), toolbarPlacementTopRadioButton(isTopChecked), ) - assertAppItemsWithResourceId( + assertItemWithResIdExists( toolbarPlacementBottomImage, toolbarPlacementBottomTitle, toolbarPlacementTopImage, @@ -121,48 +139,60 @@ class HomeScreenRobot { ) } + fun clickTopToolbarPlacementButton() = + itemWithResId("$packageName:id/toolbar_top_radio_button").click() + + fun clickBottomToolbarPlacementButton() = + itemWithResId("$packageName:id/toolbar_bottom_radio_button").click() + fun verifySignInToSyncCard() { scrollToElementByText(getStringResource(R.string.onboarding_account_sign_in_header)) - assertAppItemsContainingText(startSyncHeader, startSyncDescription) - assertAppItemsWithResourceId(signInButton) + assertItemContainingTextExists(startSyncHeader, startSyncDescription) + assertItemWithResIdExists(signInButton) } fun verifyPrivacyProtectionCard(isStandardChecked: Boolean, isStrictChecked: Boolean) { - scrollToElementByText(getStringResource(R.string.onboarding_tracking_protection_header)) - assertAppItemsContainingText(privacyProtectionHeader, privacyProtectionDescription) - assertAppItemsStateWithResourceId( + scrollToElementByText(getStringResource(R.string.onboarding_privacy_notice_header_1)) + assertItemContainingTextExists(privacyProtectionHeader, privacyProtectionDescription) + assertCheckedItemWithResIdExists( standardTrackingProtectionToggle(isStandardChecked), strictTrackingProtectionToggle(isStrictChecked), ) } + fun clickStandardTrackingProtectionButton() = + itemWithResId("$packageName:id/tracking_protection_standard_option").click() + + fun clickStrictTrackingProtectionButton() = + itemWithResId("$packageName:id/tracking_protection_strict_default").click() + fun verifyPrivacyNoticeCard() { scrollToElementByText(getStringResource(R.string.onboarding_privacy_notice_header_1)) - assertAppItemsContainingText(privacyNoticeHeader, privacyNoticeDescription) - assertAppItemsWithResourceId(privacyNoticeButton) + assertItemContainingTextExists(privacyNoticeHeader, privacyNoticeDescription) + assertItemWithResIdExists(privacyNoticeButton) } fun verifyStartBrowsingSection() { scrollToElementByText(getStringResource(R.string.onboarding_finish)) - assertAppItemsWithResourceId(startBrowsingButton) - assertAppItemsContainingText(conclusionHeader) + assertItemWithResIdExists(startBrowsingButton) + assertItemContainingTextExists(conclusionHeader) } fun verifyNavigationToolbarItems(numberOfOpenTabs: String) { - assertAppItemsWithResourceId(navigationToolbar, menuButton) - assertAppItemsWithResourceIdAndText(tabCounter(numberOfOpenTabs)) + assertItemWithResIdExists(navigationToolbar, menuButton) + assertItemWithResIdAndTextExists(tabCounter(numberOfOpenTabs)) } - fun verifyHomePrivateBrowsingButton() = assertAppItemsWithResourceId(privateBrowsingButton) - fun verifyHomeMenuButton() = assertAppItemsWithResourceId(menuButton) + fun verifyHomePrivateBrowsingButton() = assertItemWithResIdExists(privateBrowsingButton) + fun verifyHomeMenuButton() = assertItemWithResIdExists(menuButton) fun verifyTabButton() = assertTabButton() fun verifyCollectionsHeader() = assertCollectionsHeader() fun verifyNoCollectionsText() = assertNoCollectionsText() - fun verifyHomeWordmark() = assertAppItemsWithResourceId(homepageWordmark) + fun verifyHomeWordmark() = assertItemWithResIdExists(homepageWordmark) fun verifyHomeComponent() = assertHomeComponent() fun verifyDefaultSearchEngine(searchEngine: String) = verifySearchEngineIcon(searchEngine) fun verifyTabCounter(numberOfOpenTabs: String) = - assertAppItemsWithResourceIdAndText(tabCounter(numberOfOpenTabs)) + assertItemWithResIdAndTextExists(tabCounter(numberOfOpenTabs)) fun verifyKeyboardVisible() = assertKeyboardVisibility(isExpectedToBeVisible = true) fun verifyWallpaperImageApplied(isEnabled: Boolean) { @@ -184,11 +214,14 @@ class HomeScreenRobot { } // First Run elements - fun verifyWelcomeHeader() = assertAppItemsContainingText(welcomeHeader) - fun verifyAccountsSignInButton() = assertAppItemsWithResourceId(signInButton) + fun verifyWelcomeHeader() = assertItemContainingTextExists(welcomeHeader) + fun verifyAccountsSignInButton() { + scrollToElementByText(getStringResource(R.string.onboarding_account_sign_in_header)) + assertItemWithResIdExists(signInButton) + } fun verifyStartBrowsingButton() { scrollToElementByText(getStringResource(R.string.onboarding_finish)) - assertAppItemsWithResourceId(startBrowsingButton) + assertItemWithResIdExists(startBrowsingButton) } // Upgrading users onboarding dialog @@ -233,9 +266,24 @@ class HomeScreenRobot { fun verifyExistingTopSitesList() = assertExistingTopSitesList() fun verifyNotExistingTopSitesList(title: String) = assertNotExistingTopSitesList(title) + fun verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle: String, position: Int) = + assertFalse( + mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/top_site_item") + .index(position - 1), + ).getChild( + UiSelector() + .textContains(sponsoredShortcutTitle), + ).waitForExists(waitingTime), + ) fun verifyNotExistingSponsoredTopSitesList() = assertSponsoredTopSitesNotDisplayed() fun verifyExistingTopSitesTabs(title: String) = assertExistingTopSitesTabs(title) - fun verifyExistingSponsoredTopSitesTabs(sponsoredShortcutTitle: String, position: Int) = assertSponsoredTopSiteIsDisplayed(sponsoredShortcutTitle, position) + fun verifySponsoredShortcutDetails(sponsoredShortcutTitle: String, position: Int) { + assertSponsoredShortcutLogoIsDisplayed(position) + assertSponsoredShortcutTitle(sponsoredShortcutTitle, position) + assertSponsoredSubtitleIsDisplayed(position) + } fun verifyTopSiteContextMenuItems() = assertTopSiteContextMenuItems() fun verifyJumpBackInSectionIsDisplayed() = assertJumpBackInSectionIsDisplayed() @@ -293,14 +341,7 @@ class HomeScreenRobot { mDevice.waitNotNull(findObject(By.text(expectedText)), waitingTime) } - fun clickUndoCollectionDeletion(expectedText: String) { - onView( - allOf( - withId(R.id.snackbar_btn), - withText(expectedText), - ), - ).click() - } + fun clickUndoSnackBarButton() = undoSnackBarButton.click() fun clickFirefoxLogo() = homepageWordmark.click() @@ -429,19 +470,6 @@ class HomeScreenRobot { } } - fun getSponsoredShortcutTitle(position: Int): String { - val sponsoredShortcut = mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/top_site_item") - .index(position - 1), - ).getChild( - UiSelector() - .resourceId("$packageName:id/top_site_title"), - ).text - - return sponsoredShortcut - } - fun verifyJumpBackInMessage() { assertTrue( mDevice.findObject( @@ -683,6 +711,7 @@ class HomeScreenRobot { } fun clickSaveTabsToCollectionButton(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + scrollToElementByText(getStringResource(R.string.no_collections_description2)) saveTabsToCollectionButton().click() TabDrawerRobot().interact() @@ -780,6 +809,20 @@ class HomeScreenRobot { BrowserRobot().interact() return BrowserRobot.Transition() } + + fun clickSignInButton(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition { + signInButton.clickAndWaitForNewWindow(waitingTimeShort) + + SyncSignInRobot().interact() + return SyncSignInRobot.Transition() + } + + fun clickPrivacyNoticeButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + privacyNoticeButton.clickAndWaitForNewWindow(waitingTimeShort) + + BrowserRobot().interact() + return BrowserRobot.Transition() + } } } @@ -874,10 +917,17 @@ private fun assertExistingTopSitesTabs(title: String) { .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } -private fun assertSponsoredTopSiteIsDisplayed(sponsoredShortcutTitle: String, position: Int) { - assertSponsoredShortcutTitle(sponsoredShortcutTitle, position) - assertSponsoredSubtitleIsDisplayed(position) -} +private fun assertSponsoredShortcutLogoIsDisplayed(position: Int) = + assertTrue( + mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/top_site_item") + .index(position - 1), + ).getChild( + UiSelector() + .resourceId("$packageName:id/favicon_card"), + ).waitForExists(waitingTime), + ) private fun assertSponsoredSubtitleIsDisplayed(position: Int) = assertTrue( @@ -891,7 +941,7 @@ private fun assertSponsoredSubtitleIsDisplayed(position: Int) = ).waitForExists(waitingTime), ) -private fun assertSponsoredShortcutTitle(sponsoredShortcutTitle: String, position: Int) { +private fun assertSponsoredShortcutTitle(sponsoredShortcutTitle: String, position: Int) = assertTrue( mDevice.findObject( UiSelector() @@ -902,7 +952,6 @@ private fun assertSponsoredShortcutTitle(sponsoredShortcutTitle: String, positio .textContains(sponsoredShortcutTitle), ).waitForExists(waitingTime), ) -} private fun assertNotExistingTopSitesList(title: String) { mDevice.findObject(UiSelector().text(title)).waitUntilGone(waitingTime) @@ -1010,125 +1059,82 @@ private fun sponsoredShortcut(sponsoredShortcutTitle: String) = private fun storyByTopicItem(composeTestRule: ComposeTestRule, position: Int) = composeTestRule.onNodeWithTag("pocket.categories").onChildAt(position - 1) -private fun appItemWithResourceId(resourceId: String) = - mDevice.findObject(UiSelector().resourceId(resourceId)) - -private fun appItemContainingText(itemText: String) = - mDevice.findObject(UiSelector().textContains(itemText)) - -private fun appItemStateWithResourceId(resourceId: String, state: Boolean) = - mDevice.findObject(UiSelector().resourceId(resourceId).checked(state)) - -private fun appItemWithResourceIdAndDescription(resourceId: String, description: String) = - mDevice.findObject(UiSelector().resourceId(resourceId).descriptionContains(description)) - -private fun appItemWithResourceIdAndText(resourceId: String, text: String) = - mDevice.findObject(UiSelector().resourceId(resourceId).text(text)) - -private fun assertAppItemsWithResourceId(vararg appItems: UiObject) { - for (appItem in appItems) { - assertTrue(appItem.waitForExists(waitingTime)) - } -} - -private fun assertAppItemsContainingText(vararg appItems: UiObject) { - for (appItem in appItems) { - assertTrue(appItem.waitForExists(waitingTime)) - } -} - -private fun assertAppItemsStateWithResourceId(vararg appItems: UiObject) { - for (appItem in appItems) { - assertTrue(appItem.waitForExists(waitingTime)) - } -} - -private fun assertAppItemsWithResourceIdAndDescription(vararg appItems: UiObject) { - for (appItem in appItems) { - assertTrue(appItem.waitForExists(waitingTime)) - } -} - -private fun assertAppItemsWithResourceIdAndText(vararg appItems: UiObject) { - for (appItem in appItems) { - assertTrue(appItem.waitForExists(waitingTime)) - } -} - private val homeScreen = - appItemWithResourceId("$packageName:id/homeLayout") + itemWithResId("$packageName:id/homeLayout") private val privateBrowsingButton = - appItemWithResourceId("$packageName:id/privateBrowsingButton") + itemWithResId("$packageName:id/privateBrowsingButton") private val homepageWordmark = - appItemWithResourceId("$packageName:id/wordmark") -private val welcomeHeader = appItemContainingText(getStringResource(R.string.onboarding_header_2)) + itemWithResId("$packageName:id/wordmark") +private val welcomeHeader = itemContainingText(getStringResource(R.string.onboarding_header_2)) private val welcomeSubHeader = - appItemContainingText(getStringResource(R.string.onboarding_message)) + itemContainingText(getStringResource(R.string.onboarding_message)) private val chooseThemeHeader = - appItemContainingText(getStringResource(R.string.onboarding_theme_picker_header)) + itemContainingText(getStringResource(R.string.onboarding_theme_picker_header)) private val chooseThemeText = - appItemContainingText(getStringResource(R.string.onboarding_theme_picker_description_2)) + itemContainingText(getStringResource(R.string.onboarding_theme_picker_description_2)) private val darkThemeDescription = - appItemContainingText(getStringResource(R.string.onboarding_theme_dark_title)) + itemContainingText(getStringResource(R.string.onboarding_theme_dark_title)) private val lightThemeDescription = - appItemContainingText(getStringResource(R.string.onboarding_theme_light_title)) + itemContainingText(getStringResource(R.string.onboarding_theme_light_title)) private val automaticThemeDescription = - appItemWithResourceIdAndDescription( + itemWithResIdAndDescription( "$packageName:id/clickable_region_automatic", "${getStringResource(R.string.onboarding_theme_automatic_title)} ${getStringResource(R.string.onboarding_theme_automatic_summary)}", ) private fun darkThemeToggle(isChecked: Boolean) = - appItemStateWithResourceId("$packageName:id/theme_dark_radio_button", isChecked) + checkedItemWithResId("$packageName:id/theme_dark_radio_button", isChecked) private fun lightThemeToggle(isChecked: Boolean) = - appItemStateWithResourceId("$packageName:id/theme_light_radio_button", isChecked) + checkedItemWithResId("$packageName:id/theme_light_radio_button", isChecked) private fun automaticThemeToggle(isChecked: Boolean) = - appItemStateWithResourceId("$packageName:id/theme_automatic_radio_button", isChecked) + checkedItemWithResId("$packageName:id/theme_automatic_radio_button", isChecked) private val toolbarPlacementHeader = - appItemContainingText(getStringResource(R.string.onboarding_toolbar_placement_header_1)) + itemContainingText(getStringResource(R.string.onboarding_toolbar_placement_header_1)) private val toolbarPlacementDescription = - appItemContainingText(getStringResource(R.string.onboarding_toolbar_placement_description)) + itemContainingText(getStringResource(R.string.onboarding_toolbar_placement_description)) private fun toolbarPlacementBottomRadioButton(isChecked: Boolean) = - appItemStateWithResourceId("$packageName:id/toolbar_bottom_radio_button", isChecked) + checkedItemWithResId("$packageName:id/toolbar_bottom_radio_button", isChecked) private fun toolbarPlacementTopRadioButton(isChecked: Boolean) = - appItemStateWithResourceId("$packageName:id/toolbar_top_radio_button", isChecked) + checkedItemWithResId("$packageName:id/toolbar_top_radio_button", isChecked) private val toolbarPlacementBottomImage = - appItemWithResourceId("$packageName:id/toolbar_bottom_image") + itemWithResId("$packageName:id/toolbar_bottom_image") private val toolbarPlacementBottomTitle = - appItemWithResourceId("$packageName:id/toolbar_bottom_title") + itemWithResId("$packageName:id/toolbar_bottom_title") private val toolbarPlacementTopTitle = - appItemWithResourceId("$packageName:id/toolbar_top_title") + itemWithResId("$packageName:id/toolbar_top_title") private val toolbarPlacementTopImage = - appItemWithResourceId("$packageName:id/toolbar_top_image") + itemWithResId("$packageName:id/toolbar_top_image") private val startSyncHeader = - appItemContainingText(getStringResource(R.string.onboarding_account_sign_in_header)) + itemContainingText(getStringResource(R.string.onboarding_account_sign_in_header)) private val startSyncDescription = - appItemContainingText(getStringResource(R.string.onboarding_manual_sign_in_description)) + itemContainingText(getStringResource(R.string.onboarding_manual_sign_in_description)) private val signInButton = - appItemWithResourceId("$packageName:id/fxa_sign_in_button") + itemWithResId("$packageName:id/fxa_sign_in_button") private val privacyProtectionHeader = - appItemContainingText(getStringResource(R.string.onboarding_tracking_protection_header)) + itemContainingText(getStringResource(R.string.onboarding_tracking_protection_header)) private val privacyProtectionDescription = - appItemContainingText(getStringResource(R.string.onboarding_tracking_protection_description)) + itemContainingText(getStringResource(R.string.onboarding_tracking_protection_description)) private fun standardTrackingProtectionToggle(isChecked: Boolean) = - appItemStateWithResourceId("$packageName:id/tracking_protection_standard_option", isChecked) + checkedItemWithResId("$packageName:id/tracking_protection_standard_option", isChecked) private fun strictTrackingProtectionToggle(isChecked: Boolean) = - appItemStateWithResourceId("$packageName:id/tracking_protection_strict_default", isChecked) + checkedItemWithResId("$packageName:id/tracking_protection_strict_default", isChecked) private val privacyNoticeHeader = - appItemContainingText(getStringResource(R.string.onboarding_privacy_notice_header_1)) + itemContainingText(getStringResource(R.string.onboarding_privacy_notice_header_1)) private val privacyNoticeDescription = - appItemContainingText(getStringResource(R.string.onboarding_privacy_notice_description)) + itemContainingText(getStringResource(R.string.onboarding_privacy_notice_description)) private val privacyNoticeButton = - appItemWithResourceId("$packageName:id/read_button") + itemWithResId("$packageName:id/read_button") private val startBrowsingButton = - appItemWithResourceId("$packageName:id/finish_button") + itemWithResId("$packageName:id/finish_button") private val conclusionHeader = - appItemContainingText(getStringResource(R.string.onboarding_conclusion_header)) + itemContainingText(getStringResource(R.string.onboarding_conclusion_header)) private val navigationToolbar = - appItemWithResourceId("$packageName:id/toolbar") + itemWithResId("$packageName:id/toolbar") private val menuButton = - appItemWithResourceId("$packageName:id/menuButton") + itemWithResId("$packageName:id/menuButton") private fun tabCounter(numberOfOpenTabs: String) = - appItemWithResourceIdAndText("$packageName:id/counter_text", numberOfOpenTabs) + itemWithResIdAndText("$packageName:id/counter_text", numberOfOpenTabs) +private val undoSnackBarButton = + itemWithResId("$packageName:id/snackbar_btn") val deleteFromHistory = onView( diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt index eae28eb86..bb0db4dc7 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt @@ -46,6 +46,7 @@ import org.mozilla.fenix.helpers.TestHelper.getStringResource import org.mozilla.fenix.helpers.TestHelper.isPackageInstalled import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestHelper.waitForObjects import org.mozilla.fenix.helpers.click /** @@ -110,31 +111,40 @@ class SearchRobot { } } - fun verifyFirefoxSuggestResults(rule: ComposeTestRule, searchSuggestion: String) { + fun verifyFirefoxSuggestResults(rule: ComposeTestRule, searchTerm: String, vararg searchSuggestions: String) { rule.waitForIdle() for (i in 1..RETRY_COUNT) { try { - rule.onNodeWithTag("mozac.awesomebar.suggestions") - .performScrollToNode(hasText(searchSuggestion)) - .assertExists() + for (searchSuggestion in searchSuggestions) { + mDevice.waitForObjects(mDevice.findObject(UiSelector().textContains(searchSuggestion))) + rule.onNodeWithTag("mozac.awesomebar.suggestions") + .performScrollToNode(hasText(searchSuggestion)) + .assertExists() + } + break } catch (e: AssertionError) { if (i == RETRY_COUNT) { throw e } else { - expandSearchSuggestionsList() + mDevice.pressBack() + homeScreen { + }.openSearch { + typeSearch(searchTerm) + } } } } } - fun verifyNoSuggestionsAreDisplayed(rule: ComposeTestRule, searchSuggestion: String) { + fun verifyNoSuggestionsAreDisplayed(rule: ComposeTestRule, vararg searchSuggestions: String) { rule.waitForIdle() - - assertFalse( - mDevice.findObject(UiSelector().textContains(searchSuggestion)) - .waitForExists(waitingTime), - ) + for (searchSuggestion in searchSuggestions) { + assertFalse( + mDevice.findObject(UiSelector().textContains(searchSuggestion)) + .waitForExists(waitingTime), + ) + } } fun verifyAllowSuggestionsInPrivateModeDialog() { @@ -282,10 +292,6 @@ class SearchRobot { assertTranslatedFocusedNavigationToolbar(toolbarHintString) fun verifySearchEngineShortcuts(rule: ComposeTestRule, vararg searchEngines: String) { - mDevice.findObject( - UiSelector().resourceId("$packageName:id/awesome_bar"), - ).swipeUp(1) - for (searchEngine in searchEngines) { rule.waitForIdle() rule.onNodeWithText(searchEngine).assertIsDisplayed() @@ -365,14 +371,21 @@ class SearchRobot { rule: ComposeTestRule, interact: SettingsSubMenuSearchRobot.() -> Unit, ): SettingsSubMenuSearchRobot.Transition { - rule.onNodeWithText("Search engine settings") - .assertIsDisplayed() - .assertHasClickAction() - .performClick() + rule.onNodeWithText("Search engine settings").performClick() SettingsSubMenuSearchRobot().interact() return SettingsSubMenuSearchRobot.Transition() } + + fun clickSearchSuggestion(searchSuggestion: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + mDevice.findObject(UiSelector().textContains(searchSuggestion)).also { + it.waitForExists(waitingTime) + it.clickAndWaitForNewWindow(waitingTimeShort) + } + + BrowserRobot().interact() + return BrowserRobot.Transition() + } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt index f133d03d8..f85402855 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt @@ -4,6 +4,9 @@ package org.mozilla.fenix.ui.robots +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.matcher.RootMatchers +import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.uiautomator.UiSelector import org.junit.Assert.assertTrue import org.mozilla.fenix.R @@ -12,6 +15,7 @@ import org.mozilla.fenix.helpers.TestHelper.getStringResource import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText +import org.mozilla.fenix.helpers.click class SettingsSubMenuAutofillRobot { @@ -22,14 +26,10 @@ class SettingsSubMenuAutofillRobot { deleteAddressButton.waitForExists(waitingTime) deleteAddressButton.click() } - fun clickCancelDeleteAddressButton() { - cancelDeleteAddressButton.waitForExists(waitingTime) - cancelDeleteAddressButton.click() - } - fun clickConfirmDeleteAddressButton() { - confirmDeleteAddressButton.waitForExists(waitingTime) - confirmDeleteAddressButton.click() - } + fun clickCancelDeleteAddressButton() = cancelDeleteAddressButton.click() + + fun clickConfirmDeleteAddressButton() = confirmDeleteAddressButton.click() + fun clickSubRegionOption(subRegion: String) { subRegionOption(subRegion).waitForExists(waitingTime) subRegionOption(subRegion).click() @@ -81,10 +81,7 @@ class SettingsSubMenuAutofillRobot { deleteCreditCardButton.click() } - fun clickConfirmDeleteCreditCardButton() { - confirmDeleteCreditCardButton.waitForExists(waitingTime) - confirmDeleteCreditCardButton.click() - } + fun clickConfirmDeleteCreditCardButton() = confirmDeleteCreditCardButton.click() fun clickExpiryMonthOption(expiryMonth: String) { expiryMonthOption(expiryMonth).waitForExists(waitingTime) @@ -142,8 +139,8 @@ private val phoneTextInput = mDevice.findObject(UiSelector().resourceId("$packag private val emailTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/email_input")) private val saveButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/save_button")) private val deleteAddressButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/delete_address_button")) -private val cancelDeleteAddressButton = mDevice.findObject(UiSelector().resourceId("android:id/button2")) -private val confirmDeleteAddressButton = mDevice.findObject(UiSelector().resourceId("android:id/button1")) +private val cancelDeleteAddressButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog()) +private val confirmDeleteAddressButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()) private val addCreditCardButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_add_credit_card))) private val manageSavedCardsButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_manage_saved_cards))) @@ -153,8 +150,8 @@ private val expiryMonthDropDown = mDevice.findObject(UiSelector().resourceId("$p private val expiryYearDropDown = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_year_drop_down")) private val savedCreditCardNumber = mDevice.findObject(UiSelector().resourceId("$packageName:id/credit_card_logo")) private val deleteCreditCardButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/delete_credit_card_button")) -private val confirmDeleteCreditCardButton = mDevice.findObject(UiSelector().resourceId("android:id/button1")) -private val securedCreditCardsLaterButton = mDevice.findObject(UiSelector().resourceId("android:id/button2")) +private val confirmDeleteCreditCardButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()) +private val securedCreditCardsLaterButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog()) private fun savedAddress(firstName: String) = mDevice.findObject(UiSelector().textContains(firstName)) private fun subRegionOption(subRegion: String) = mDevice.findObject(UiSelector().textContains(subRegion)) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt index 96616f114..24235e179 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt @@ -20,8 +20,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import org.hamcrest.CoreMatchers.allOf import org.hamcrest.Matchers.endsWith -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.TestHelper.getStringResource import org.mozilla.fenix.helpers.TestHelper.hasCousin @@ -35,11 +33,6 @@ class SettingsSubMenuCustomizeRobot { fun verifyThemes() = assertThemes() - fun verifyLightThemeApplied(expected: Boolean) = - assertFalse("Light theme not selected", expected) - - fun verifyDarkThemeApplied(expected: Boolean) = assertTrue("Dark theme not selected", expected) - fun selectDarkMode() = darkModeToggle().click() fun selectLightMode() = lightModeToggle().click() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SiteSecurityRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SiteSecurityRobot.kt index 54a96f66e..1ad88c91f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SiteSecurityRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SiteSecurityRobot.kt @@ -6,6 +6,11 @@ package org.mozilla.fenix.ui.robots +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.RootMatchers +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.uiautomator.UiSelector import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import org.junit.Assert.assertTrue @@ -50,8 +55,8 @@ private fun assertSecureConnectionSubMenu(pageTitle: String = "", url: String = private fun assertClearSiteDataPrompt(url: String) { assertTrue(clearSiteDataPrompt(url).waitForExists(waitingTime)) - assertTrue(cancelClearSiteDataButton.waitForExists(waitingTime)) - assertTrue(deleteSiteDataButton.waitForExists(waitingTime)) + cancelClearSiteDataButton.check(matches(isDisplayed())) + deleteSiteDataButton.check(matches(isDisplayed())) } private fun quickActionSheet() = @@ -145,5 +150,5 @@ private fun clearSiteDataPrompt(url: String) = .textContains(url), ) -private val cancelClearSiteDataButton = mDevice.findObject(UiSelector().resourceId("android:id/button2")) -private val deleteSiteDataButton = mDevice.findObject(UiSelector().resourceId("android:id/button1")) +private val cancelClearSiteDataButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog()) +private val deleteSiteDataButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index 89088f6a9..057882873 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -14,9 +14,7 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.UiController import androidx.test.espresso.ViewAction import androidx.test.espresso.action.GeneralLocation -import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.longClick import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers @@ -32,7 +30,6 @@ import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until.findObject import com.google.android.material.bottomsheet.BottomSheetBehavior -import junit.framework.AssertionFailedError import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue import org.hamcrest.CoreMatchers.allOf @@ -115,7 +112,7 @@ class TabDrawerRobot { var retries = 0 // number of retries before failing, will stop at 2 while (!tabItem(title).waitUntilGone(waitingTimeShort) && retries < 3 ) { - tab(title).perform(ViewActions.swipeRight()) + tab(title).swipeRight(3) retries++ } } @@ -124,7 +121,7 @@ class TabDrawerRobot { var retries = 0 // number of retries before failing, will stop at 2 while (!tabItem(title).waitUntilGone(waitingTimeShort) && retries < 3 ) { - tab(title).perform(ViewActions.swipeLeft()) + tab(title).swipeLeft(3) retries++ } } @@ -149,75 +146,14 @@ class TabDrawerRobot { snackBarButton.click() } - fun verifyTabMediaControlButtonState(action: String) { - try { - mDevice.findObject( - UiSelector().resourceId("$packageName:id/tab_tray_empty_view"), - ).waitUntilGone(waitingTime) - - mDevice.findObject( - UiSelector().resourceId("$packageName:id/tab_tray_grid_item"), - ).waitForExists(waitingTime) - - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/play_pause_button") - .descriptionContains(action), - ).waitForExists(waitingTime) - - assertTrue( - mDevice.findObject(UiSelector().descriptionContains(action)) - .waitForExists(waitingTime), - ) - } catch (e: AssertionFailedError) { - // In some cases the tab media button isn't updated after performing an action on it - println("Failed to update the state of the tab media button") - - // Let's dismiss the tabs tray and try again - mDevice.pressBack() - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/toolbar"), - ).waitForExists(waitingTime) - - browserScreen { - }.openTabDrawer { - // Click again the tab media button - tabMediaControlButton().click() - - mDevice.findObject( - UiSelector().resourceId("$packageName:id/tab_tray_empty_view"), - ).waitUntilGone(waitingTime) - - mDevice.findObject( - UiSelector().resourceId("$packageName:id/tab_tray_grid_item"), - ).waitForExists(waitingTime) - - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/play_pause_button") - .descriptionContains(action), - ).waitForExists(waitingTime) - - assertTrue( - mDevice.findObject(UiSelector().descriptionContains(action)) - .waitForExists(waitingTime), - ) - } - } - } + fun verifyTabMediaControlButtonState(action: String) = + assertTrue(tabMediaControlButton(action).waitForExists(waitingTime)) fun clickTabMediaControlButton(action: String) { - mDevice.waitNotNull( - Until.findObjects( - By - .res("$packageName:id/play_pause_button") - .descContains(action), - ), - waitingTime, - ) - - tabMediaControlButton().click() + tabMediaControlButton(action).also { + it.waitForExists(waitingTime) + it.click() + } } fun clickSelectTabsOption() { @@ -245,7 +181,10 @@ class TabDrawerRobot { waitingTime, ) - tab(title).perform(longClick()) + tab(title).also { + it.waitForExists(waitingTime) + it.longClick() + } } fun createCollection( @@ -449,8 +388,8 @@ fun tabDrawer(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { return TabDrawerRobot.Transition() } -private fun tabMediaControlButton() = - mDevice.findObject(UiSelector().resourceId("$packageName:id/play_pause_button")) +private fun tabMediaControlButton(action: String) = + mDevice.findObject(UiSelector().descriptionContains(action)) private fun closeTabButton() = mDevice.findObject(UiSelector().descriptionContains("Close tab")) @@ -459,9 +398,9 @@ private fun assertCloseTabsButton(title: String) = assertTrue( mDevice.findObject( UiSelector() - .resourceId("$packageName:id/mozac_browser_tabstray_close") - .descriptionContains("Close tab $title"), - ).waitForExists(waitingTime), + .descriptionContains("Close tab"), + ).getFromParent(UiSelector().textContains(title)) + .waitForExists(waitingTime), ) private fun normalBrowsingButton() = onView( @@ -622,12 +561,7 @@ private val tabsList = // This Espresso tab selector is used for actions that UIAutomator doesn't handle very well: swipe and long-tap private fun tab(title: String) = - onView( - allOf( - withId(R.id.mozac_browser_tabstray_title), - withText(title), - ), - ) + mDevice.findObject(UiSelector().textContains(title)) // This tab selector is used for actions that involve waiting and asserting the existence of the view private fun tabItem(title: String) = diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt index 4e95e10e9..74f750e42 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt @@ -16,21 +16,27 @@ import androidx.test.espresso.matcher.RootMatchers import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.hasDescendant -import androidx.test.espresso.matcher.ViewMatchers.isChecked -import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiObjectNotFoundException import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.hamcrest.Matchers.allOf -import org.hamcrest.Matchers.not import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.RETRY_COUNT +import org.mozilla.fenix.helpers.MatcherHelper.assertCheckedItemWithResIdAndTextExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists +import org.mozilla.fenix.helpers.MatcherHelper.checkedItemWithResIdAndText +import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText +import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong import org.mozilla.fenix.helpers.TestHelper.getStringResource @@ -45,20 +51,12 @@ import org.mozilla.fenix.helpers.ext.waitNotNull @Suppress("ForbiddenComment") class ThreeDotMenuMainRobot { fun verifyShareAllTabsButton() = assertShareAllTabsButton() - fun verifySettingsButton() = assertSettingsButton() - fun verifyCustomizeHomeButton() = assertCustomizeHomeButton() - fun verifyAddOnsButton() = assertAddOnsButton() - fun verifyHistoryButton() = assertHistoryButton() - fun verifyBookmarksButton() = assertBookmarksButton() - fun verifySyncSignInButton() = assertSyncSignInButton() - fun verifyHelpButton() = assertHelpButton() + fun verifySettingsButton() = assertItemContainingTextExists(settingsButton()) + fun verifyHistoryButton() = assertItemContainingTextExists(historyButton) fun verifyThreeDotMenuExists() = threeDotMenuRecyclerViewExists() - fun verifyForwardButton() = assertForwardButton() - fun verifyAddBookmarkButton() = assertAddBookmarkButton() + fun verifyAddBookmarkButton() = assertItemWithResIdAndTextExists(addBookmarkButton) fun verifyEditBookmarkButton() = assertEditBookmarkButton() - fun verifyRefreshButton() = assertRefreshButton() fun verifyCloseAllTabsButton() = assertCloseAllTabsButton() - fun verifyShareButton() = assertShareButton() fun verifyReaderViewAppearance(visible: Boolean) = assertReaderViewAppearanceButton(visible) fun expandMenu() { @@ -66,49 +64,61 @@ class ThreeDotMenuMainRobot { } fun verifyShareTabButton() = assertShareTabButton() - fun verifySaveCollection() = assertSaveCollectionButton() fun verifySelectTabs() = assertSelectTabsButton() - fun verifyFindInPageButton() = assertFindInPageButton() - fun verifyWhatsNewButton() = assertWhatsNewButton() - fun verifyAddToTopSitesButton() = assertAddToTopSitesButton() + fun verifyFindInPageButton() = assertItemContainingTextExists(findInPageButton) + fun verifyAddToShortcutsButton() = assertItemContainingTextExists(addToShortcutsButton) fun verifyRemoveFromShortcutsButton() = assertRemoveFromShortcutsButton() - fun verifyAddToMobileHome() = assertAddToMobileHome() - fun verifyDesktopSite() = assertDesktopSite() - fun verifyDownloadsButton() = assertDownloadsButton() fun verifyShareTabsOverlay() = assertShareTabsOverlay() - fun verifyNewTabButton() = assertNormalBrowsingNewTabButton() - fun verifyReportSiteIssueButton() = assertReportSiteIssueButton() - fun verifyDesktopSiteModeEnabled(state: Boolean) { + fun verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled: Boolean) { expandMenu() - if (state) { - desktopSiteButton().check(matches(isChecked())) - } else { - desktopSiteButton().check(matches(not(isChecked()))) - } + assertCheckedItemWithResIdAndTextExists(desktopSiteToggle(isRequestDesktopSiteEnabled)) + } + + fun verifyPageThreeDotMainMenuItems(isRequestDesktopSiteEnabled: Boolean) { + expandMenu() + assertItemContainingTextExists( + normalBrowsingNewTabButton, + bookmarksButton, + historyButton, + downloadsButton, + addOnsButton, + syncAndSaveDataButton, + findInPageButton, + desktopSiteButton, + reportSiteIssueButton, + addToHomeScreenButton, + addToShortcutsButton, + saveToCollectionButton, + settingsButton(), + ) + assertCheckedItemWithResIdAndTextExists(addBookmarkButton) + assertCheckedItemWithResIdAndTextExists(desktopSiteToggle(isRequestDesktopSiteEnabled)) + assertItemWithDescriptionExists( + backButton, + forwardButton, + shareButton, + refreshButton, + ) } - fun verifyPageThreeDotMainMenuItems() { - verifyNewTabButton() - verifyBookmarksButton() - verifyAddBookmarkButton() - verifyHistoryButton() - verifyDownloadsButton() - verifyAddOnsButton() - verifySyncSignInButton() - threeDotMenuRecyclerView().perform(swipeUp()) - verifyFindInPageButton() - verifyDesktopSite() - threeDotMenuRecyclerView().perform(swipeUp()) - verifyReportSiteIssueButton() - verifyAddToTopSitesButton() - verifyAddToMobileHome() - verifySaveCollection() - verifySettingsButton() - verifyShareButton() - verifyForwardButton() - verifyRefreshButton() + fun verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled: Boolean) { + assertItemContainingTextExists( + bookmarksButton, + historyButton, + downloadsButton, + addOnsButton, + // Disabled step due to https://github.com/mozilla-mobile/fenix/issues/26788 + // syncAndSaveDataButton, + desktopSiteButton, + whatsNewButton, + helpButton, + customizeHomeButton, + settingsButton(), + ) + + assertCheckedItemWithResIdAndTextExists(desktopSiteToggle(isRequestDesktopSiteEnabled)) } private fun assertShareTabsOverlay() { @@ -164,7 +174,7 @@ class ThreeDotMenuMainRobot { fun openDownloadsManager(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { threeDotMenuRecyclerView().perform(swipeDown()) - downloadsButton().click() + downloadsButton.click() DownloadRobot().interact() return DownloadRobot.Transition() @@ -173,7 +183,7 @@ class ThreeDotMenuMainRobot { fun openSyncSignIn(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition { threeDotMenuRecyclerView().perform(swipeDown()) mDevice.waitNotNull(Until.findObject(By.text("Sync and save data")), waitingTime) - syncSignInButton().click() + syncAndSaveDataButton.click() SyncSignInRobot().interact() return SyncSignInRobot.Transition() @@ -183,7 +193,7 @@ class ThreeDotMenuMainRobot { threeDotMenuRecyclerView().perform(swipeDown()) mDevice.waitNotNull(Until.findObject(By.text("Bookmarks")), waitingTime) - bookmarksButton().click() + bookmarksButton.click() assertTrue(mDevice.findObject(UiSelector().resourceId("$packageName:id/bookmark_list")).waitForExists(waitingTime)) BookmarksRobot().interact() @@ -193,7 +203,7 @@ class ThreeDotMenuMainRobot { fun openHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { threeDotMenuRecyclerView().perform(swipeDown()) mDevice.waitNotNull(Until.findObject(By.text("History")), waitingTime) - historyButton().click() + historyButton.click() HistoryRobot().interact() return HistoryRobot.Transition() @@ -201,7 +211,7 @@ class ThreeDotMenuMainRobot { fun bookmarkPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { mDevice.waitNotNull(Until.findObject(By.text("Bookmarks")), waitingTime) - addBookmarkButton().click() + addBookmarkButton.click() BrowserRobot().interact() return BrowserRobot.Transition() @@ -217,7 +227,7 @@ class ThreeDotMenuMainRobot { fun openHelp(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { mDevice.waitNotNull(Until.findObject(By.text("Help")), waitingTime) - helpButton().click() + helpButton.click() BrowserRobot().interact() return BrowserRobot.Transition() @@ -232,7 +242,7 @@ class ThreeDotMenuMainRobot { waitingTime, ) - customizeHomeButton().click() + customizeHomeButton.click() mDevice.findObject( UiSelector().resourceId("$packageName:id/recycler_view"), @@ -243,35 +253,27 @@ class ThreeDotMenuMainRobot { } fun goForward(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - forwardButton().click() + forwardButton.click() BrowserRobot().interact() return BrowserRobot.Transition() } - fun goBack(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - backButton().click() + fun goToPreviousPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + backButton.click() BrowserRobot().interact() return BrowserRobot.Transition() } fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { - shareButton().click() + shareButton.click() mDevice.waitNotNull(Until.findObject(By.text("ALL ACTIONS")), waitingTime) ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() } - fun close(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - // Close three dot - mDevice.pressBack() - - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() - } - fun closeBrowserMenuToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { // Close three dot mDevice.pressBack() @@ -281,8 +283,7 @@ class ThreeDotMenuMainRobot { } fun refreshPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - assertRefreshButton() - refreshButton().click() + refreshButton.click() BrowserRobot().interact() return BrowserRobot.Transition() @@ -298,7 +299,7 @@ class ThreeDotMenuMainRobot { fun openReportSiteIssue(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { threeDotMenuRecyclerView().perform(swipeUp()) threeDotMenuRecyclerView().perform(swipeUp()) - reportSiteIssueButton().click() + reportSiteIssueButton.click() BrowserRobot().interact() return BrowserRobot.Transition() @@ -308,7 +309,7 @@ class ThreeDotMenuMainRobot { threeDotMenuRecyclerView().perform(swipeUp()) threeDotMenuRecyclerView().perform(swipeUp()) mDevice.waitNotNull(Until.findObject(By.text("Find in page")), waitingTime) - findInPageButton().click() + findInPageButton.click() FindInPageRobot().interact() return FindInPageRobot.Transition() @@ -316,7 +317,7 @@ class ThreeDotMenuMainRobot { fun openWhatsNew(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { mDevice.waitNotNull(Until.findObject(By.text("What’s new")), waitingTime) - whatsNewButton().click() + whatsNewButton.click() BrowserRobot().interact() return BrowserRobot.Transition() @@ -332,7 +333,26 @@ class ThreeDotMenuMainRobot { } fun addToFirefoxHome(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - addToTopSitesButton().click() + for (i in 1..RETRY_COUNT) { + try { + addToShortcutsButton.also { + it.waitForExists(waitingTime) + it.click() + } + + break + } catch (e: UiObjectNotFoundException) { + if (i == RETRY_COUNT) { + throw e + } else { + mDevice.pressBack() + navigationToolbar { + }.openThreeDotMenu { + expandMenu() + } + } + } + } BrowserRobot().interact() return BrowserRobot.Transition() @@ -346,8 +366,7 @@ class ThreeDotMenuMainRobot { } fun openAddToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { - mDevice.waitNotNull(Until.findObject(By.text("Add to Home screen")), waitingTime) - addToHomeScreenButton().click() + addToHomeScreenButton.clickAndWaitForNewWindow(waitingTime) AddToHomeScreenRobot().interact() return AddToHomeScreenRobot.Transition() @@ -368,7 +387,7 @@ class ThreeDotMenuMainRobot { threeDotMenuRecyclerView().perform(swipeUp()) mDevice.waitNotNull(Until.findObject(By.text("Save to collection")), waitingTime) - saveCollectionButton().click() + saveToCollectionButton.click() CollectionRobot().interact() return CollectionRobot.Transition() } @@ -396,7 +415,7 @@ class ThreeDotMenuMainRobot { fun switchDesktopSiteMode(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { threeDotMenuRecyclerView().perform(swipeUp()) threeDotMenuRecyclerView().perform(swipeUp()) - desktopSiteButton().click() + desktopSiteButton.click() BrowserRobot().interact() return BrowserRobot.Transition() @@ -417,61 +436,10 @@ private fun threeDotMenuRecyclerViewExists() { threeDotMenuRecyclerView().check(matches(isDisplayed())) } -private fun settingsButton(localizedText: String = getStringResource(R.string.browser_menu_settings)) = - mDevice.findObject(UiSelector().text(localizedText)) - -private fun assertSettingsButton() = assertTrue(settingsButton().waitForExists(waitingTime)) - -private fun customizeHomeButton() = - onView( - allOf( - withId(R.id.text), - withText(R.string.browser_menu_customize_home_1), - ), - ) - -private fun assertCustomizeHomeButton() = - customizeHomeButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun addOnsButton() = onView(allOf(withText("Add-ons"))) -private fun assertAddOnsButton() { - onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeDown()) - addOnsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -} - -private fun historyButton() = onView(allOf(withText(R.string.library_history))) -private fun assertHistoryButton() = historyButton() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun bookmarksButton() = onView(allOf(withText(R.string.library_bookmarks))) -private fun assertBookmarksButton() = bookmarksButton() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun syncSignInButton() = onView(withText("Sync and save data")) -private fun assertSyncSignInButton() = syncSignInButton().check(matches(isDisplayed())) - -private fun helpButton() = onView(allOf(withText(R.string.browser_menu_help))) -private fun assertHelpButton() = helpButton() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun forwardButton() = mDevice.findObject(UiSelector().description("Forward")) -private fun assertForwardButton() = assertTrue(forwardButton().waitForExists(waitingTime)) - -private fun backButton() = mDevice.findObject(UiSelector().description("Back")) - -private fun addBookmarkButton() = onView(allOf(withId(R.id.checkbox), withText("Add"))) -private fun assertAddBookmarkButton() { - onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeUp()) - addBookmarkButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -} - private fun editBookmarkButton() = onView(withText("Edit")) private fun assertEditBookmarkButton() = editBookmarkButton() .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -private fun refreshButton() = mDevice.findObject(UiSelector().description("Refresh")) -private fun assertRefreshButton() = assertTrue(refreshButton().waitForExists(waitingTime)) - private fun stopLoadingButton() = onView(ViewMatchers.withContentDescription("Stop")) private fun closeAllTabsButton() = onView(allOf(withText("Close all tabs"))).inRoot(RootMatchers.isPlatformPopup()) @@ -482,36 +450,10 @@ private fun shareTabButton() = onView(allOf(withText("Share all tabs"))).inRoot( private fun assertShareTabButton() = shareTabButton() .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -private fun shareButton() = mDevice.findObject(UiSelector().description("Share")) -private fun assertShareButton() = assertTrue(shareButton().waitForExists(waitingTime)) - -private fun saveCollectionButton() = onView(allOf(withText("Save to collection"))).inRoot(RootMatchers.isPlatformPopup()) -private fun assertSaveCollectionButton() = saveCollectionButton() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - private fun selectTabsButton() = onView(allOf(withText("Select tabs"))).inRoot(RootMatchers.isPlatformPopup()) private fun assertSelectTabsButton() = selectTabsButton() .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -private fun reportSiteIssueButton() = onView(withText("Report Site Issue…")) -private fun assertReportSiteIssueButton() = reportSiteIssueButton().check(matches(isDisplayed())) - -private fun findInPageButton() = onView(allOf(withText("Find in page"))) - -private fun assertFindInPageButton() = findInPageButton() - -private fun whatsNewButton() = onView( - allOf( - withText("What’s new"), - withEffectiveVisibility(Visibility.VISIBLE), - ), -) - -private fun assertWhatsNewButton() = whatsNewButton() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun addToHomeScreenButton() = onView(withText("Add to Home screen")) - private fun readerViewAppearanceToggle() = mDevice.findObject(UiSelector().text("Customize reader view")) @@ -532,21 +474,9 @@ private fun assertReaderViewAppearanceButton(visible: Boolean) { } } -private fun addToTopSitesButton() = - onView(allOf(withText(R.string.browser_menu_add_to_shortcuts))) - private fun removeFromShortcutsButton() = onView(allOf(withText(R.string.browser_menu_remove_from_shortcuts))) -private fun assertAddToTopSitesButton() { - onView(withId(R.id.mozac_browser_menu_recyclerView)) - .perform( - RecyclerViewActions.scrollTo( - hasDescendant(withText(R.string.browser_menu_add_to_shortcuts)), - ), - ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -} - private fun assertRemoveFromShortcutsButton() { onView(withId(R.id.mozac_browser_menu_recyclerView)) .perform( @@ -556,26 +486,8 @@ private fun assertRemoveFromShortcutsButton() { ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } -private fun addToMobileHomeButton() = - onView(allOf(withText(R.string.browser_menu_add_to_homescreen))) - -private fun assertAddToMobileHome() { - onView(withId(R.id.mozac_browser_menu_recyclerView)) - .perform( - RecyclerViewActions.scrollTo( - hasDescendant(withText(R.string.browser_menu_add_to_homescreen)), - ), - ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -} - private fun installPWAButton() = mDevice.findObject(UiSelector().text("Install")) -private fun desktopSiteButton() = onView(withId(R.id.switch_widget)) -private fun assertDesktopSite() { - threeDotMenuRecyclerView().perform(swipeUp()) - desktopSiteButton().check(matches(isDisplayed())) -} - private fun openInAppButton() = onView( allOf( @@ -584,15 +496,9 @@ private fun openInAppButton() = ), ) -private fun downloadsButton() = onView(withText(R.string.library_downloads)) -private fun assertDownloadsButton() { - onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeDown()) - downloadsButton().check(matches(isDisplayed())) -} - private fun clickAddonsManagerButton() { onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeDown()) - addOnsButton().check(matches(isCompletelyDisplayed())).click() + addOnsButton.click() } private fun shareAllTabsButton() = @@ -605,4 +511,45 @@ private fun assertShareAllTabsButton() { ) } -private fun assertNormalBrowsingNewTabButton() = onView(withText("New tab")).check(matches(isDisplayed())) +private val bookmarksButton = + itemContainingText(getStringResource(R.string.library_bookmarks)) +private val historyButton = + itemContainingText(getStringResource(R.string.library_history)) +private val downloadsButton = + itemContainingText(getStringResource(R.string.library_downloads)) +private val addOnsButton = + itemContainingText(getStringResource(R.string.browser_menu_add_ons)) +private val desktopSiteButton = + itemContainingText(getStringResource(R.string.browser_menu_desktop_site)) +private fun desktopSiteToggle(state: Boolean) = + checkedItemWithResIdAndText( + "$packageName:id/switch_widget", + getStringResource(R.string.browser_menu_desktop_site), + state, + ) +private val whatsNewButton = + itemContainingText(getStringResource(R.string.browser_menu_whats_new)) +private val helpButton = + itemContainingText(getStringResource(R.string.browser_menu_help)) +private val customizeHomeButton = + itemContainingText(getStringResource(R.string.browser_menu_customize_home_1)) +private fun settingsButton(localizedText: String = getStringResource(R.string.browser_menu_settings)) = + itemContainingText(localizedText) +private val syncAndSaveDataButton = + itemContainingText(getStringResource(R.string.sync_menu_sync_and_save_data)) +private val normalBrowsingNewTabButton = + itemContainingText(getStringResource(R.string.library_new_tab)) +private val addBookmarkButton = + itemWithResIdAndText( + "$packageName:id/checkbox", + getStringResource(R.string.browser_menu_add), + ) +private val findInPageButton = itemContainingText(getStringResource(R.string.browser_menu_find_in_page)) +private val reportSiteIssueButton = itemContainingText("Report Site Issue") +private val addToHomeScreenButton = itemContainingText(getStringResource(R.string.browser_menu_add_to_homescreen)) +private val addToShortcutsButton = itemContainingText(getStringResource(R.string.browser_menu_add_to_shortcuts)) +private val saveToCollectionButton = itemContainingText(getStringResource(R.string.browser_menu_save_to_collection_2)) +private val backButton = itemWithDescription(getStringResource(R.string.browser_menu_back)) +private val forwardButton = itemWithDescription(getStringResource(R.string.browser_menu_forward)) +private val shareButton = itemWithDescription(getStringResource(R.string.share_button_content_description)) +private val refreshButton = itemWithDescription(getStringResource(R.string.browser_menu_refresh)) diff --git a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt index 302ae0828..2ca133cf2 100644 --- a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt +++ b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt @@ -28,6 +28,7 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromAbout(R.id.aboutFragment), FromTrackingProtection(R.id.trackingProtectionFragment), FromHttpsOnlyMode(R.id.httpsOnlyFragment), + FromCookieBanner(R.id.cookieBannerFragment), FromTrackingProtectionDialog(R.id.trackingProtectionPanelDialogFragment), FromSavedLoginsFragment(R.id.savedLoginsFragment), FromAddNewDeviceFragment(R.id.addNewDeviceFragment), diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index ac0756e5d..45281fdad 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -67,10 +67,15 @@ object FeatureFlags { */ const val saveToPDF = true + /** + * Enables the notification pre permission prompt. + */ + const val notificationPrePermissionPromptEnabled = true + /** * Enables storage maintenance feature. * * Feature flag tracking: https://github.com/mozilla-mobile/fenix/issues/27759 * */ - val storageMaintenanceFeature = Config.channel.isNightlyOrDebug + val storageMaintenanceFeature = Config.channel.isNightlyOrDebug || Config.channel.isBeta } diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 9be427851..317ab34fb 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -61,6 +61,7 @@ import mozilla.components.support.webextensions.WebExtensionSupport import org.mozilla.fenix.GleanMetrics.Addons import org.mozilla.fenix.GleanMetrics.AndroidAutofill import org.mozilla.fenix.GleanMetrics.CustomizeHome +import org.mozilla.fenix.GleanMetrics.Events.marketingNotificationAllowed import org.mozilla.fenix.GleanMetrics.GleanBuildInfo import org.mozilla.fenix.GleanMetrics.Metrics import org.mozilla.fenix.GleanMetrics.PerfStartup @@ -73,14 +74,16 @@ import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.components.metrics.MetricServiceType import org.mozilla.fenix.components.metrics.MozillaProductDetector import org.mozilla.fenix.components.toolbar.ToolbarPosition +import org.mozilla.fenix.ext.areNotificationsEnabledSafe import org.mozilla.fenix.ext.containsQueryParameters import org.mozilla.fenix.ext.getCustomGleanServerUrlIfAvailable import org.mozilla.fenix.ext.isCustomEngine import org.mozilla.fenix.ext.isKnownSearchDomain +import org.mozilla.fenix.ext.isNotificationChannelEnabled import org.mozilla.fenix.ext.setCustomEndpointIfAvailable import org.mozilla.fenix.ext.settings import org.mozilla.fenix.nimbus.FxNimbus -import org.mozilla.fenix.onboarding.ensureMarketingChannelExists +import org.mozilla.fenix.onboarding.MARKETING_CHANNEL_ID import org.mozilla.fenix.perf.MarkersActivityLifecycleCallbacks import org.mozilla.fenix.perf.ProfilerMarkerFactProcessor import org.mozilla.fenix.perf.StartupTimeline @@ -203,6 +206,11 @@ open class FenixApplication : LocaleAwareApplication(), Provider { ProfilerMarkerFactProcessor.create { components.core.engine.profiler }.register() run { + // Make sure the engine is initialized and ready to use. + components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { + components.core.engine.warmUp() + } + // We need to always initialize Glean and do it early here. initializeGlean() @@ -213,10 +221,6 @@ open class FenixApplication : LocaleAwareApplication(), Provider { components.strictMode.enableStrictMode(true) warmBrowsersCache() - // Make sure the engine is initialized and ready to use. - components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { - components.core.engine.warmUp() - } initializeWebExtensionSupport() if (FeatureFlags.storageMaintenanceFeature) { // Make sure to call this function before registering a storage worker @@ -252,6 +256,8 @@ open class FenixApplication : LocaleAwareApplication(), Provider { ProcessLifecycleOwner.get().lifecycle.addObserver(TelemetryLifecycleObserver(components.core.store)) + components.analytics.metricsStorage.tryRegisterAsUsageRecorder(this) + downloadWallpapers() } @@ -368,16 +374,6 @@ open class FenixApplication : LocaleAwareApplication(), Provider { } } - // For Android 13 or above, prompt the user for notification permission at the start. - // Regardless if the user accepts or denies the permission prompt, the prompt will occur only once. - fun queueNotificationPermissionRequest() { - if (SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - queue.runIfReadyOrQueue { - ensureMarketingChannelExists(this) - } - } - } - initQueue() // We init these items in the visual completeness queue to avoid them initing in the critical @@ -387,7 +383,6 @@ open class FenixApplication : LocaleAwareApplication(), Provider { queueReviewPrompt() queueRestoreLocale() queueStorageMaintenance() - queueNotificationPermissionRequest() } private fun startMetricsIfEnabled() { @@ -749,14 +744,11 @@ open class FenixApplication : LocaleAwareApplication(), Provider { defaultWallpaper.set(isDefaultTheCurrentWallpaper) - @Suppress("TooGenericExceptionCaught") - try { - notificationsAllowed.set( - NotificationManagerCompat.from(applicationContext).areNotificationsEnabled(), - ) - } catch (e: Exception) { - Logger.warn("Failed to check if notifications are enabled", e) - } + val notificationManagerCompat = NotificationManagerCompat.from(applicationContext) + notificationsAllowed.set(notificationManagerCompat.areNotificationsEnabledSafe()) + marketingNotificationAllowed.set( + notificationManagerCompat.isNotificationChannelEnabled(MARKETING_CHANNEL_ID), + ) } with(AndroidAutofill) { diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index e58f8f542..88ccfc91d 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -28,6 +28,7 @@ import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting.Companion.PROTECTED import androidx.appcompat.app.ActionBar import androidx.appcompat.widget.Toolbar +import androidx.core.app.NotificationManagerCompat import androidx.lifecycle.lifecycleScope import androidx.navigation.NavDestination import androidx.navigation.NavDirections @@ -67,6 +68,7 @@ import mozilla.components.support.ktx.android.content.share import mozilla.components.support.ktx.kotlin.isUrl import mozilla.components.support.ktx.kotlin.toNormalizedUrl import mozilla.components.support.locale.LocaleAwareAppCompatActivity +import mozilla.components.support.utils.ManufacturerCodes import mozilla.components.support.utils.SafeIntent import mozilla.components.support.utils.toSafeIntent import mozilla.components.support.webextensions.WebExtensionPopupFeature @@ -84,12 +86,14 @@ import org.mozilla.fenix.components.metrics.BreadcrumbsRecorder import org.mozilla.fenix.databinding.ActivityHomeBinding import org.mozilla.fenix.exceptions.trackingprotection.TrackingProtectionExceptionsFragmentDirections import org.mozilla.fenix.ext.alreadyOnDestination +import org.mozilla.fenix.ext.areNotificationsEnabledSafe import org.mozilla.fenix.ext.breadcrumb import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.setNavigationIcon import org.mozilla.fenix.ext.settings import org.mozilla.fenix.home.HomeFragmentDirections +import org.mozilla.fenix.home.intent.AssistIntentProcessor import org.mozilla.fenix.home.intent.CrashReporterIntentProcessor import org.mozilla.fenix.home.intent.DefaultBrowserIntentProcessor import org.mozilla.fenix.home.intent.HomeDeepLinkIntentProcessor @@ -102,9 +106,11 @@ import org.mozilla.fenix.library.bookmarks.DesktopFolders import org.mozilla.fenix.library.history.HistoryFragmentDirections import org.mozilla.fenix.library.historymetadata.HistoryMetadataGroupFragmentDirections import org.mozilla.fenix.library.recentlyclosed.RecentlyClosedFragmentDirections +import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.onboarding.DefaultBrowserNotificationWorker import org.mozilla.fenix.onboarding.FenixOnboarding import org.mozilla.fenix.onboarding.ReEngagementNotificationWorker +import org.mozilla.fenix.onboarding.ensureMarketingChannelExists import org.mozilla.fenix.perf.MarkersActivityLifecycleCallbacks import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks import org.mozilla.fenix.perf.Performance @@ -115,6 +121,7 @@ import org.mozilla.fenix.perf.StartupTimeline import org.mozilla.fenix.perf.StartupTypeTelemetry import org.mozilla.fenix.search.SearchDialogFragmentDirections import org.mozilla.fenix.session.PrivateNotificationService +import org.mozilla.fenix.settings.CookieBannersFragmentDirections import org.mozilla.fenix.settings.HttpsOnlyFragmentDirections import org.mozilla.fenix.settings.SettingsFragmentDirections import org.mozilla.fenix.settings.TrackingProtectionFragmentDirections @@ -132,7 +139,6 @@ import org.mozilla.fenix.theme.DefaultThemeManager import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.trackingprotection.TrackingProtectionPanelDialogFragmentDirections import org.mozilla.fenix.utils.BrowsersCache -import org.mozilla.fenix.utils.ManufacturerCodes import org.mozilla.fenix.utils.Settings import java.lang.ref.WeakReference @@ -182,6 +188,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { listOf( HomeDeepLinkIntentProcessor(this), SpeechProcessingIntentProcessor(this, components.core.store), + AssistIntentProcessor(), StartSearchIntentProcessor(), OpenBrowserIntentProcessor(this, ::getIntentSessionId), OpenSpecificTabIntentProcessor(this), @@ -317,6 +324,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { } } + showNotificationPermissionPromptIfRequired() + components.backgroundServices.accountManagerAvailableQueue.runIfReadyOrQueue { lifecycleScope.launch(IO) { // If we're authenticated, kick-off a sync and a device state refresh. @@ -334,6 +343,30 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { StartupTimeline.onActivityCreateEndHome(this) // DO NOT MOVE ANYTHING BELOW HERE. } + /** + * On Android 13 or above, prompt the user for notification permission at the start. + * Show the pre permission dialog to the user once if the notification are not enabled. + */ + private fun showNotificationPermissionPromptIfRequired() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && + !NotificationManagerCompat.from(applicationContext).areNotificationsEnabledSafe() && + settings().numberOfAppLaunches <= 1 + ) { + // Recording the exposure event here to capture all users who met all criteria to receive + // the pre permission notification prompt + FxNimbus.features.prePermissionNotificationPrompt.recordExposure() + + if (settings().notificationPrePermissionPromptEnabled) { + if (!settings().isNotificationPrePermissionShown) { + navHost.navController.navigate(NavGraphDirections.actionGlobalHomeNotificationPermissionDialog()) + } + } else { + // This will trigger the notification permission system dialog as app targets sdk 32. + ensureMarketingChannelExists(applicationContext) + } + } + } + private fun checkAndExitPiP() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInPictureInPictureMode && intent != null) { // Exit PiP mode @@ -848,6 +881,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { HistoryMetadataGroupFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromTrackingProtectionExceptions -> TrackingProtectionExceptionsFragmentDirections.actionGlobalBrowser(customTabSessionId) + BrowserDirection.FromCookieBanner -> + CookieBannersFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromHttpsOnlyMode -> HttpsOnlyFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromAbout -> diff --git a/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt index 7c009bc30..abd007e29 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt @@ -243,7 +243,12 @@ class InstalledAddonDetailsFragment : Fragment() { val shouldCreatePrivateSession = (activity as HomeActivity).browsingModeManager.mode.isPrivate - components.useCases.tabsUseCases.addTab(settingUrl, private = shouldCreatePrivateSession) + // If the addon settings page is already open in a tab, select that one + components.useCases.tabsUseCases.selectOrAddTab( + url = settingUrl, + private = shouldCreatePrivateSession, + ignoreFragment = true, + ) InstalledAddonDetailsFragmentDirections.actionGlobalBrowser(null) } else { diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index a76cb5a64..57b267608 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -15,11 +15,14 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.state.TabSessionState +import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.thumbnails.BrowserThumbnails import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.concept.engine.permission.SitePermissions @@ -28,9 +31,11 @@ import mozilla.components.feature.contextmenu.ContextMenuCandidate import mozilla.components.feature.readerview.ReaderViewFeature import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tabs.WindowFeature +import mozilla.components.lib.state.ext.consumeFlow import mozilla.components.service.glean.private.NoExtras import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.base.feature.ViewBoundFeatureWrapper +import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged import org.mozilla.fenix.GleanMetrics.ReaderMode import org.mozilla.fenix.R import org.mozilla.fenix.components.FenixSnackbar @@ -43,6 +48,7 @@ import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.runIfFragmentIsAttached import org.mozilla.fenix.ext.settings import org.mozilla.fenix.nimbus.FxNimbus +import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog.CookieBannerReEngagementDialogUtils import org.mozilla.fenix.shortcut.PwaOnboardingObserver import org.mozilla.fenix.theme.ThemeManager @@ -173,6 +179,9 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { view = view, ) } + if (!context.settings().shouldUseCookieBanner && !context.settings().userOptOutOfReEngageCookieBannerDialog) { + observeCookieBannerHandlingState(context.components.core.store) + } } override fun onUpdateToolbarForConfigurationChange(toolbar: BrowserToolbarView) { @@ -370,12 +379,17 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { useCase.containsException(tab.id) { hasTrackingProtectionException -> lifecycleScope.launch(Dispatchers.Main) { val cookieBannersStorage = requireComponents.core.cookieBannersStorage - val hasCookieBannerException = withContext(Dispatchers.IO) { - cookieBannersStorage.hasException( - tab.content.url, - tab.content.private, - ) - } + val hasCookieBannerException = + if (requireContext().settings().shouldUseCookieBanner) { + withContext(Dispatchers.IO) { + cookieBannersStorage.hasException( + tab.content.url, + tab.content.private, + ) + } + } else { + false + } runIfFragmentIsAttached { val isTrackingProtectionEnabled = tab.trackingProtection.enabled && !hasTrackingProtectionException @@ -476,4 +490,22 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { internal fun updateLastBrowseActivity() { requireContext().settings().lastBrowseActivity = System.currentTimeMillis() } + + private fun observeCookieBannerHandlingState(store: BrowserStore) { + consumeFlow(store) { flow -> + flow.mapNotNull { state -> + state.findCustomTabOrSelectedTab(customTabSessionId) + }.ifAnyChanged { tab -> + arrayOf( + tab.cookieBanner, + ) + }.collect { + CookieBannerReEngagementDialogUtils.tryToShowReEngagementDialog( + settings = requireContext().settings(), + status = it.cookieBanner, + navController = findNavController(), + ) + } + } + } } diff --git a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt index 63b98c17c..b6b22fc5b 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt @@ -22,8 +22,10 @@ import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.ReleaseChannel import org.mozilla.fenix.components.metrics.AdjustMetricsService +import org.mozilla.fenix.components.metrics.DefaultMetricsStorage import org.mozilla.fenix.components.metrics.GleanMetricsService import org.mozilla.fenix.components.metrics.MetricController +import org.mozilla.fenix.components.metrics.MetricsStorage import org.mozilla.fenix.experiments.createNimbus import org.mozilla.fenix.ext.settings import org.mozilla.fenix.gleanplumb.CustomAttributeProvider @@ -31,6 +33,7 @@ import org.mozilla.fenix.gleanplumb.NimbusMessagingStorage import org.mozilla.fenix.gleanplumb.OnDiskMessageMetadataStorage import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.perf.lazyMonitored +import org.mozilla.fenix.utils.BrowsersCache import org.mozilla.geckoview.BuildConfig.MOZ_APP_BUILDID import org.mozilla.geckoview.BuildConfig.MOZ_APP_VENDOR import org.mozilla.geckoview.BuildConfig.MOZ_APP_VERSION @@ -115,6 +118,14 @@ class Analytics( ) } + val metricsStorage: MetricsStorage by lazyMonitored { + DefaultMetricsStorage( + context = context, + settings = context.settings(), + checkDefaultBrowser = { BrowsersCache.all(context).isDefaultBrowser }, + ) + } + val metrics: MetricController by lazyMonitored { MetricController.create( listOf( diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index 9fec84140..f932fbb60 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -31,5 +31,20 @@ sealed class Event { * Event recording the first time Firefox is used 3 days in a row in the first week of install. */ object FirstWeekSeriesActivity : GrowthData("20ay7u") + + /** + * Event recording that usage time has reached a threshold. + */ + object UsageThreshold : GrowthData("m66prt") + + /** + * Event recording the first time Firefox has been resumed in a 24 hour period. + */ + object FirstAppOpenForDay : GrowthData("41hl22") + + /** + * Event recording the first time a URI is loaded in Firefox in a 24 hour period. + */ + object FirstUriLoadForDay : GrowthData("ja86ek") } } diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt index 6b1f94994..b9cddaa53 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.components.metrics import androidx.annotation.VisibleForTesting import mozilla.components.browser.menu.facts.BrowserMenuFacts +import mozilla.components.browser.toolbar.facts.ToolbarFacts import mozilla.components.concept.awesomebar.AwesomeBar import mozilla.components.feature.autofill.facts.AutofillFacts import mozilla.components.feature.awesomebar.facts.AwesomeBarFacts @@ -42,6 +43,7 @@ import org.mozilla.fenix.GleanMetrics.BrowserSearch import org.mozilla.fenix.GleanMetrics.ContextMenu import org.mozilla.fenix.GleanMetrics.ContextualMenu import org.mozilla.fenix.GleanMetrics.CreditCards +import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.LoginDialog import org.mozilla.fenix.GleanMetrics.MediaNotification import org.mozilla.fenix.GleanMetrics.MediaState @@ -147,6 +149,9 @@ internal class ReleaseMetricController( else -> Unit } } + Component.BROWSER_TOOLBAR to ToolbarFacts.Items.MENU -> { + Events.toolbarMenuVisible.record(NoExtras()) + } Component.FEATURE_CONTEXTMENU to ContextMenuFacts.Items.ITEM -> { metadata?.get("item")?.let { item -> contextMenuAllowList[item]?.let { extraKey -> diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsMiddleware.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsMiddleware.kt index 83a1320f0..6e5bc48a8 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsMiddleware.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsMiddleware.kt @@ -28,6 +28,7 @@ class MetricsMiddleware( is AppAction.ResumedMetricsAction -> { metrics.track(Event.GrowthData.SetAsDefault) metrics.track(Event.GrowthData.FirstWeekSeriesActivity) + metrics.track(Event.GrowthData.UsageThreshold) } else -> Unit } diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsStorage.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsStorage.kt index 7cb678a8a..cfa9121a9 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsStorage.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsStorage.kt @@ -4,11 +4,14 @@ package org.mozilla.fenix.components.metrics +import android.app.Activity +import android.app.Application import android.content.Context import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import mozilla.components.support.utils.ext.getPackageInfoCompat +import org.mozilla.fenix.android.DefaultActivityLifecycleCallbacks import org.mozilla.fenix.ext.settings import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.utils.Settings @@ -29,6 +32,18 @@ interface MetricsStorage { * Updates locally-stored state for an [event] that has just been sent. */ suspend fun updateSentState(event: Event) + + /** + * Will try to register this as a recorder of app usage based on whether usage recording is still + * needed. It will measure usage by to monitoring lifecycle callbacks from [application]'s + * activities and should update local state using [updateUsageState]. + */ + fun tryRegisterAsUsageRecorder(application: Application) + + /** + * Update local state with a [usageLength] measurement. + */ + fun updateUsageState(usageLength: Long) } internal class DefaultMetricsStorage( @@ -62,6 +77,20 @@ internal class DefaultMetricsStorage( Event.GrowthData.SerpAdClicked -> { currentTime.duringFirstMonth() && !settings.adClickGrowthSent } + Event.GrowthData.UsageThreshold -> { + !settings.usageTimeGrowthSent && + settings.usageTimeGrowthData > usageThresholdMillis + } + Event.GrowthData.FirstAppOpenForDay -> { + currentTime.afterFirstDay() && + currentTime.duringFirstMonth() && + settings.resumeGrowthLastSent.hasBeenMoreThanDaySince() + } + Event.GrowthData.FirstUriLoadForDay -> { + currentTime.afterFirstDay() && + currentTime.duringFirstMonth() && + settings.uriLoadGrowthLastSent.hasBeenMoreThanDaySince() + } } } @@ -76,9 +105,29 @@ internal class DefaultMetricsStorage( Event.GrowthData.SerpAdClicked -> { settings.adClickGrowthSent = true } + Event.GrowthData.UsageThreshold -> { + settings.usageTimeGrowthSent = true + } + Event.GrowthData.FirstAppOpenForDay -> { + settings.resumeGrowthLastSent = System.currentTimeMillis() + } + Event.GrowthData.FirstUriLoadForDay -> { + settings.uriLoadGrowthLastSent = System.currentTimeMillis() + } + } + } + + override fun tryRegisterAsUsageRecorder(application: Application) { + // Currently there is only interest in measuring usage during the first day of install. + if (!settings.usageTimeGrowthSent && System.currentTimeMillis().duringFirstDay()) { + application.registerActivityLifecycleCallbacks(UsageRecorder(this)) } } + override fun updateUsageState(usageLength: Long) { + settings.usageTimeGrowthData += usageLength + } + private fun updateDaysOfUse() { val daysOfUse = settings.firstWeekDaysOfUseGrowthData val currentDate = Calendar.getInstance(Locale.US) @@ -121,6 +170,12 @@ internal class DefaultMetricsStorage( calendar.timeInMillis = this } + private fun Long.hasBeenMoreThanDaySince() = System.currentTimeMillis() - this > dayMillis + + private fun Long.afterFirstDay() = this > getInstalledTime() + dayMillis + + private fun Long.duringFirstDay() = this < getInstalledTime() + dayMillis + private fun Long.duringFirstWeek() = this < getInstalledTime() + fullWeekMillis private fun Long.duringFirstMonth() = this < getInstalledTime() + shortestMonthMillis @@ -129,6 +184,28 @@ internal class DefaultMetricsStorage( calendar.add(Calendar.DAY_OF_MONTH, 1) } + /** + * This will store app usage time to disk, based on Resume and Pause lifecycle events. Currently, + * there is only interest in usage during the first day after install. + */ + internal class UsageRecorder( + private val metricsStorage: MetricsStorage, + ) : DefaultActivityLifecycleCallbacks { + private val activityStartTimes: MutableMap = mutableMapOf() + + override fun onActivityResumed(activity: Activity) { + super.onActivityResumed(activity) + activityStartTimes[activity.componentName.toString()] = System.currentTimeMillis() + } + + override fun onActivityPaused(activity: Activity) { + super.onActivityPaused(activity) + val startTime = activityStartTimes[activity.componentName.toString()] ?: return + val elapsedTimeMillis = System.currentTimeMillis() - startTime + metricsStorage.updateUsageState(elapsedTimeMillis) + } + } + companion object { private const val dayMillis: Long = 1000 * 60 * 60 * 24 private const val shortestMonthMillis: Long = dayMillis * 28 @@ -137,6 +214,9 @@ internal class DefaultMetricsStorage( // of the 7th day after install private const val fullWeekMillis: Long = dayMillis * 8 + // The usage threshold we are interested in is currently 340 seconds. + private const val usageThresholdMillis = 1000 * 340 + /** * Determines whether events should be tracked based on some general criteria: * - user has installed as a result of a campaign diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenter.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenter.kt index 128b4ea04..e52d2fc26 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenter.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenter.kt @@ -11,12 +11,14 @@ import androidx.compose.material.Text import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp +import androidx.navigation.findNavController import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.transformWhile import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab +import mozilla.components.browser.state.selector.selectedTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.lib.state.ext.flowScoped @@ -29,6 +31,7 @@ import org.mozilla.fenix.compose.cfr.CFRPopupProperties import org.mozilla.fenix.ext.components import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils.SumoTopic.TOTAL_COOKIE_PROTECTION +import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog.CookieBannerReEngagementDialogUtils import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.utils.Settings @@ -111,6 +114,7 @@ class BrowserToolbarCFRPresenter( true -> TrackingProtection.tcpCfrExplicitDismissal.record(NoExtras()) false -> TrackingProtection.tcpCfrImplicitDismissal.record(NoExtras()) } + tryToShowCookieBannerDialogIfNeeded() }, ) { Text( @@ -137,4 +141,15 @@ class BrowserToolbarCFRPresenter( TrackingProtection.tcpCfrShown.record(NoExtras()) } } + + @VisibleForTesting + internal fun tryToShowCookieBannerDialogIfNeeded() { + browserStore.state.selectedTab?.let { tab -> + CookieBannerReEngagementDialogUtils.tryToShowReEngagementDialog( + settings = settings, + status = tab.cookieBanner, + navController = toolbar.findNavController(), + ) + } + } } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt index 52652c9ee..77e8205ab 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt @@ -42,6 +42,7 @@ abstract class ToolbarIntegration( toolbar, store, sessionId, + context.settings().showUnifiedSearchFeature, ToolbarFeature.UrlRenderConfiguration( context.components.publicSuffixList, ThemeManager.resolveAttribute(R.attr.textPrimary, context), diff --git a/app/src/main/java/org/mozilla/fenix/compose/Divider.kt b/app/src/main/java/org/mozilla/fenix/compose/Divider.kt index 67e71db87..54edc84d9 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/Divider.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/Divider.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.compose -import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -16,8 +15,8 @@ import androidx.compose.foundation.layout.width import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -39,8 +38,7 @@ fun Divider( * An example of a vertical divider. */ @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun VerticalDividerPreview() { FirefoxTheme { Box( @@ -74,8 +72,7 @@ private fun VerticalDividerPreview() { * An example of divider usage in a list menu. */ @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun HorizontalDividerPreview() { FirefoxTheme { Box( diff --git a/app/src/main/java/org/mozilla/fenix/compose/ListItemTabLarge.kt b/app/src/main/java/org/mozilla/fenix/compose/ListItemTabLarge.kt index dd3f1feeb..81dcd8787 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/ListItemTabLarge.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/ListItemTabLarge.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.compose -import android.content.res.Configuration import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -22,9 +21,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -167,8 +166,7 @@ fun ListItemTabSurface( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun ListItemTabLargePreview() { FirefoxTheme { ListItemTabLarge( @@ -180,8 +178,7 @@ private fun ListItemTabLargePreview() { } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun ListItemTabSurfacePreview() { FirefoxTheme { ListItemTabSurface( @@ -197,8 +194,7 @@ private fun ListItemTabSurfacePreview() { } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun ListItemTabSurfaceWithCustomBackgroundPreview() { FirefoxTheme { ListItemTabSurface( diff --git a/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt b/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt index e7b221543..e94b73947 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.compose -import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -26,10 +25,10 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.mozilla.fenix.R +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.button.PrimaryButton import org.mozilla.fenix.theme.FirefoxTheme @@ -199,8 +198,7 @@ data class MessageCardColors( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun MessageCardPreview() { FirefoxTheme { Box( @@ -219,8 +217,7 @@ private fun MessageCardPreview() { } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun MessageCardWithoutTitlePreview() { FirefoxTheme { Box( @@ -238,8 +235,7 @@ private fun MessageCardWithoutTitlePreview() { } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun MessageCardWithButtonLabelPreview() { FirefoxTheme { Box( diff --git a/app/src/main/java/org/mozilla/fenix/compose/SelectableChip.kt b/app/src/main/java/org/mozilla/fenix/compose/SelectableChip.kt index fc715d55e..fc80427d1 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/SelectableChip.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/SelectableChip.kt @@ -25,6 +25,7 @@ import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -74,8 +75,7 @@ fun SelectableChip( } @Composable -@Preview(uiMode = UI_MODE_NIGHT_YES) -@Preview(uiMode = UI_MODE_NIGHT_NO) +@LightDarkPreview private fun SelectableChipPreview() { FirefoxTheme { Row( diff --git a/app/src/main/java/org/mozilla/fenix/compose/annotation/LightDarkPreview.kt b/app/src/main/java/org/mozilla/fenix/compose/annotation/LightDarkPreview.kt new file mode 100644 index 000000000..a074263a3 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/compose/annotation/LightDarkPreview.kt @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.compose.annotation + +import android.content.res.Configuration +import androidx.compose.ui.tooling.preview.Preview + +/** + * A wrapper annotation for the two uiMode that are commonly used + * in Compose preview functions. + */ +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +annotation class LightDarkPreview diff --git a/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt b/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt index 7a9d802df..fef4e8e7a 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.compose.button -import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -21,9 +20,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.mozilla.fenix.R +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -183,8 +182,7 @@ fun DestructiveButton( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun ButtonPreview() { FirefoxTheme { Column( diff --git a/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt b/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt index 78118946f..a8dc241e7 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt @@ -4,14 +4,13 @@ package org.mozilla.fenix.compose.button -import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.tooling.preview.Preview +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme import java.util.Locale @@ -44,8 +43,7 @@ fun TextButton( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun TextButtonPreview() { FirefoxTheme { Box(Modifier.background(FirefoxTheme.colors.layer1)) { diff --git a/app/src/main/java/org/mozilla/fenix/compose/tabstray/MediaImage.kt b/app/src/main/java/org/mozilla/fenix/compose/tabstray/MediaImage.kt index 6ad763025..7ce0d3844 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/tabstray/MediaImage.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/tabstray/MediaImage.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.compose.tabstray -import android.content.res.Configuration import androidx.appcompat.content.res.AppCompatResources import androidx.compose.foundation.Image import androidx.compose.foundation.clickable @@ -14,13 +13,13 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.google.accompanist.drawablepainter.rememberDrawablePainter import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.createTab import mozilla.components.concept.engine.mediasession.MediaSession.PlaybackState import org.mozilla.fenix.R +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -55,8 +54,7 @@ fun MediaImage( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun ImagePreview() { FirefoxTheme { MediaImage( diff --git a/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabGridItem.kt b/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabGridItem.kt index c5981a985..39d7bb2f0 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabGridItem.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabGridItem.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.compose.tabstray -import android.content.res.Configuration import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background @@ -38,7 +37,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextDirection -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.text.BidiFormatter @@ -49,6 +47,7 @@ import org.mozilla.fenix.compose.Divider import org.mozilla.fenix.compose.Favicon import org.mozilla.fenix.compose.HorizontalFadingEdgeBox import org.mozilla.fenix.compose.ThumbnailCard +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -231,8 +230,7 @@ private fun Thumbnail( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun TabGridItemPreview() { FirefoxTheme { TabGridItem( @@ -249,8 +247,7 @@ private fun TabGridItemPreview() { } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun TabGridItemSelectedPreview() { FirefoxTheme { TabGridItem( @@ -265,8 +262,7 @@ private fun TabGridItemSelectedPreview() { } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun TabGridItemMultiSelectedPreview() { FirefoxTheme { TabGridItem( diff --git a/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabListItem.kt b/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabListItem.kt index c1b72665f..44324ebad 100644 --- a/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabListItem.kt +++ b/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabListItem.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.compose.tabstray -import android.content.res.Configuration import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable @@ -25,13 +24,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.createTab import org.mozilla.fenix.R import org.mozilla.fenix.compose.ThumbnailCard +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.ext.toShortUrl import org.mozilla.fenix.theme.FirefoxTheme @@ -168,8 +167,7 @@ private fun Thumbnail( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun TabListItemPreview() { FirefoxTheme { TabListItem( @@ -183,8 +181,7 @@ private fun TabListItemPreview() { } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun SelectedTabListItemPreview() { FirefoxTheme { TabListItem( diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt index 7657256f6..1c37b776e 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt @@ -167,8 +167,11 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler val cookieBannersStorage = requireComponents.core.cookieBannersStorage requireComponents.useCases.trackingProtectionUseCases.containsException(tab.id) { contains -> lifecycleScope.launch(Dispatchers.IO) { - val hasException = + val hasException = if (requireContext().settings().shouldUseCookieBanner) { cookieBannersStorage.hasException(tab.content.url, tab.content.private) + } else { + false + } withContext(Dispatchers.Main) { runIfFragmentIsAttached { val directions = ExternalAppBrowserFragmentDirections diff --git a/app/src/main/java/org/mozilla/fenix/ext/NotificationManagerCompat.kt b/app/src/main/java/org/mozilla/fenix/ext/NotificationManagerCompat.kt new file mode 100644 index 000000000..779126d4e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/ext/NotificationManagerCompat.kt @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ext + +import android.os.Build +import androidx.core.app.NotificationChannelCompat +import androidx.core.app.NotificationManagerCompat + +/** + * Returns whether notifications are enabled, catches any exception that was thrown from + * [NotificationManagerCompat.areNotificationsEnabled] and returns false. + */ +@Suppress("TooGenericExceptionCaught") +fun NotificationManagerCompat.areNotificationsEnabledSafe(): Boolean { + return try { + areNotificationsEnabled() + } catch (e: Exception) { + false + } +} + +/** + * If the channel does not exist or is null, this returns false. + * If the channel exists with importance more than [NotificationManagerCompat.IMPORTANCE_NONE] and + * notifications are enabled for the app, this returns true. + * On <= SDK 26, this checks if notifications are enabled for the app. + * + * @param channelId the id of the notification channel to check. + * @return true if the channel is enabled, false otherwise. + */ +fun NotificationManagerCompat.isNotificationChannelEnabled(channelId: String): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = getNotificationChannelSafe(channelId) + if (channel == null) { + false + } else { + areNotificationsEnabledSafe() && channel.importance != NotificationManagerCompat.IMPORTANCE_NONE + } + } else { + areNotificationsEnabledSafe() + } +} + +/** + * Returns the notification channel with the given [channelId], or null if the channel does not + * exist, catches any exception that was thrown by + * [NotificationManagerCompat.getNotificationChannelCompat] and returns null. + * + * @param channelId the id of the notification channel to check. + */ +@Suppress("TooGenericExceptionCaught") +private fun NotificationManagerCompat.getNotificationChannelSafe(channelId: String): NotificationChannelCompat? { + return try { + getNotificationChannelCompat(channelId) + } catch (e: Exception) { + null + } +} diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 2ba1f24db..594198a29 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -362,7 +362,7 @@ class HomeFragment : Fragment() { } UnifiedSearch.searchMenuTapped.record(NoExtras()) - searchSelectorMenu.menuController.show(anchor = it, orientation = orientation, forceOrientation = true) + searchSelectorMenu.menuController.show(anchor = it, orientation = orientation) } } @@ -418,7 +418,6 @@ class HomeFragment : Fragment() { pocketStoriesController = DefaultPocketStoriesController( homeActivity = activity, appStore = components.appStore, - navController = findNavController(), ), ) diff --git a/app/src/main/java/org/mozilla/fenix/home/collections/Collection.kt b/app/src/main/java/org/mozilla/fenix/home/collections/Collection.kt index 7f3a2942d..89ecc645c 100644 --- a/app/src/main/java/org/mozilla/fenix/home/collections/Collection.kt +++ b/app/src/main/java/org/mozilla/fenix/home/collections/Collection.kt @@ -62,17 +62,15 @@ private val expandedCollectionShape = RoundedCornerShape(topStart = 8.dp, topEnd * @param menuItems List of [CollectionMenuItem] to be shown in a menu. * @param onToggleCollectionExpanded Invoked when the user clicks on the collection. * @param onCollectionShareTabsClicked Invoked when the user clicks to share the collection. - * @param onCollectionMenuOpened Invoked when the user clicks to open a menu for the collection. */ @Composable -@Suppress("LongParameterList", "LongMethod") +@Suppress("LongMethod") fun Collection( collection: TabCollection, expanded: Boolean, menuItems: List, onToggleCollectionExpanded: (TabCollection, Boolean) -> Unit, onCollectionShareTabsClicked: (TabCollection) -> Unit, - onCollectionMenuOpened: () -> Unit, ) { var isMenuExpanded by remember(collection) { mutableStateOf(false) } val isExpanded by remember(collection) { mutableStateOf(expanded) } @@ -131,7 +129,6 @@ fun Collection( IconButton( onClick = { isMenuExpanded = !isMenuExpanded - onCollectionMenuOpened() }, ) { Icon( @@ -165,7 +162,6 @@ private fun CollectionDarkPreview() { menuItems = emptyList(), onToggleCollectionExpanded = { _, _ -> }, onCollectionShareTabsClicked = {}, - onCollectionMenuOpened = {}, ) } } @@ -180,7 +176,6 @@ private fun CollectionDarkExpandedPreview() { menuItems = emptyList(), onToggleCollectionExpanded = { _, _ -> }, onCollectionShareTabsClicked = {}, - onCollectionMenuOpened = {}, ) } } @@ -195,7 +190,6 @@ private fun CollectionLightPreview() { menuItems = emptyList(), onToggleCollectionExpanded = { _, _ -> }, onCollectionShareTabsClicked = {}, - onCollectionMenuOpened = {}, ) } } @@ -210,7 +204,6 @@ private fun CollectionLightExpandedPreview() { menuItems = emptyList(), onToggleCollectionExpanded = { _, _ -> }, onCollectionShareTabsClicked = {}, - onCollectionMenuOpened = {}, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/collections/CollectionItem.kt b/app/src/main/java/org/mozilla/fenix/home/collections/CollectionItem.kt index fda2c0dc1..998569dd4 100644 --- a/app/src/main/java/org/mozilla/fenix/home/collections/CollectionItem.kt +++ b/app/src/main/java/org/mozilla/fenix/home/collections/CollectionItem.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.home.collections import android.content.Context -import android.content.res.Configuration import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -35,7 +34,6 @@ import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.drawscope.clipRect import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.dp import mozilla.components.browser.state.state.recover.RecoverableTab @@ -43,6 +41,7 @@ import mozilla.components.concept.engine.Engine import mozilla.components.feature.tab.collections.Tab import org.mozilla.fenix.R.drawable import org.mozilla.fenix.R.string +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.list.FaviconListItem import org.mozilla.fenix.ext.toShortUrl import org.mozilla.fenix.theme.FirefoxTheme @@ -191,8 +190,7 @@ private fun Modifier.clipTop() = this.then( ) @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun TabInCollectionPreview() { FirefoxTheme { Column { diff --git a/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt index 99bdf63e7..4dafd56eb 100644 --- a/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt @@ -67,7 +67,6 @@ class CollectionViewHolder( menuItems = menuItems, onToggleCollectionExpanded = interactor::onToggleCollectionExpanded, onCollectionShareTabsClicked = interactor::onCollectionShareTabsClicked, - onCollectionMenuOpened = interactor::onCollectionMenuOpened, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/intent/AssistIntentProcessor.kt b/app/src/main/java/org/mozilla/fenix/home/intent/AssistIntentProcessor.kt new file mode 100644 index 000000000..d17fb27a6 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/home/intent/AssistIntentProcessor.kt @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.home.intent + +import android.content.Intent +import androidx.navigation.NavController +import androidx.navigation.navOptions +import org.mozilla.fenix.NavGraphDirections +import org.mozilla.fenix.R +import org.mozilla.fenix.components.metrics.MetricsUtils +import org.mozilla.fenix.ext.nav + +/** + * Long pressing home button should also open to the search fragment if Fenix is set as the + * assist app + */ +class AssistIntentProcessor : HomeIntentProcessor { + override fun process(intent: Intent, navController: NavController, out: Intent): Boolean { + if (intent.action != Intent.ACTION_ASSIST) { + return false + } + + val directions = NavGraphDirections.actionGlobalSearchDialog( + sessionId = null, + // Will follow this up with adding `ASSIST` as a search source. + // https://bugzilla.mozilla.org/show_bug.cgi?id=1808043 + searchAccessPoint = MetricsUtils.Source.NONE, + ) + + val options = navOptions { + popUpTo(R.id.homeFragment) + } + + navController.nav(null, directions, options) + + return true + } +} diff --git a/app/src/main/java/org/mozilla/fenix/home/pocket/PocketCategoriesViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/pocket/PocketCategoriesViewHolder.kt index 5e7a0d620..9b4b540f7 100644 --- a/app/src/main/java/org/mozilla/fenix/home/pocket/PocketCategoriesViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/pocket/PocketCategoriesViewHolder.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.home.pocket -import android.content.res.Configuration import android.view.View import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column @@ -15,7 +14,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView @@ -23,6 +21,7 @@ import mozilla.components.lib.state.ext.observeAsComposableState import org.mozilla.fenix.R import org.mozilla.fenix.components.components import org.mozilla.fenix.compose.ComposeViewHolder +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.home.HomeSectionHeader import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.wallpapers.WallpaperState @@ -127,8 +126,7 @@ private fun PocketTopics( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun PocketCategoriesViewHolderPreview() { FirefoxTheme { PocketTopics( diff --git a/app/src/main/java/org/mozilla/fenix/home/pocket/PocketRecommendationsHeaderViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/pocket/PocketRecommendationsHeaderViewHolder.kt index 9438349df..43343622b 100644 --- a/app/src/main/java/org/mozilla/fenix/home/pocket/PocketRecommendationsHeaderViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/pocket/PocketRecommendationsHeaderViewHolder.kt @@ -6,7 +6,6 @@ package org.mozilla.fenix.home.pocket -import android.content.res.Configuration import android.view.View import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box @@ -18,7 +17,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView @@ -26,6 +24,7 @@ import mozilla.components.lib.state.ext.observeAsComposableState import org.mozilla.fenix.R import org.mozilla.fenix.components.components import org.mozilla.fenix.compose.ComposeViewHolder +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -79,8 +78,7 @@ class PocketRecommendationsHeaderViewHolder( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun PocketRecommendationsFooterViewHolderPreview() { FirefoxTheme { Box(modifier = Modifier.background(color = FirefoxTheme.colors.layer1)) { diff --git a/app/src/main/java/org/mozilla/fenix/home/pocket/PocketStoriesController.kt b/app/src/main/java/org/mozilla/fenix/home/pocket/PocketStoriesController.kt index 0a660e56e..7ad295aae 100644 --- a/app/src/main/java/org/mozilla/fenix/home/pocket/PocketStoriesController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/pocket/PocketStoriesController.kt @@ -4,8 +4,6 @@ package org.mozilla.fenix.home.pocket -import androidx.annotation.VisibleForTesting -import androidx.navigation.NavController import mozilla.components.service.glean.private.NoExtras import mozilla.components.service.pocket.PocketStory import mozilla.components.service.pocket.PocketStory.PocketRecommendedStory @@ -15,7 +13,6 @@ import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.GleanMetrics.Pings import org.mozilla.fenix.GleanMetrics.Pocket import org.mozilla.fenix.HomeActivity -import org.mozilla.fenix.R import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.appstate.AppAction @@ -73,12 +70,10 @@ interface PocketStoriesController { * * @param homeActivity [HomeActivity] used to open URLs in a new tab. * @param appStore [AppStore] from which to read the current Pocket recommendations and dispatch new actions on. - * @param navController [NavController] used for navigation. */ internal class DefaultPocketStoriesController( private val homeActivity: HomeActivity, private val appStore: AppStore, - private val navController: NavController, ) : PocketStoriesController { override fun handleStoryShown( storyShown: PocketStory, @@ -153,7 +148,6 @@ internal class DefaultPocketStoriesController( storyClicked: PocketStory, storyPosition: Pair, ) { - dismissSearchDialogIfDisplayed() homeActivity.openToBrowserAndLoad(storyClicked.url, true, BrowserDirection.FromHome) when (storyClicked) { @@ -179,21 +173,12 @@ internal class DefaultPocketStoriesController( } override fun handleLearnMoreClicked(link: String) { - dismissSearchDialogIfDisplayed() homeActivity.openToBrowserAndLoad(link, true, BrowserDirection.FromHome) Pocket.homeRecsLearnMoreClicked.record(NoExtras()) } override fun handleDiscoverMoreClicked(link: String) { - dismissSearchDialogIfDisplayed() homeActivity.openToBrowserAndLoad(link, true, BrowserDirection.FromHome) Pocket.homeRecsDiscoverClicked.record(NoExtras()) } - - @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - internal fun dismissSearchDialogIfDisplayed() { - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/controller/RecentBookmarksController.kt b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/controller/RecentBookmarksController.kt index b2eb61dbf..3bea45e16 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/controller/RecentBookmarksController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/controller/RecentBookmarksController.kt @@ -4,8 +4,6 @@ package org.mozilla.fenix.home.recentbookmarks.controller -import androidx.annotation.VisibleForTesting -import androidx.annotation.VisibleForTesting.Companion.PRIVATE import androidx.navigation.NavController import mozilla.appservices.places.BookmarkRoot import mozilla.components.concept.engine.EngineSession @@ -13,7 +11,6 @@ import mozilla.components.concept.engine.EngineSession.LoadUrlFlags.Companion.AL import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.GleanMetrics.RecentBookmarks import org.mozilla.fenix.HomeActivity -import org.mozilla.fenix.R import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.home.HomeFragmentDirections @@ -40,11 +37,6 @@ interface RecentBookmarksController { * @see [RecentBookmarksInteractor.onRecentBookmarkRemoved] */ fun handleBookmarkRemoved(bookmark: RecentBookmark) - - /** - * @see [RecentBookmarksInteractor.onRecentBookmarkLongClicked] - */ - fun handleBookmarkLongClicked() } /** @@ -57,7 +49,6 @@ class DefaultRecentBookmarksController( ) : RecentBookmarksController { override fun handleBookmarkClicked(bookmark: RecentBookmark) { - dismissSearchDialogIfDisplayed() activity.openToBrowserAndLoad( searchTermOrURL = bookmark.url!!, newTab = true, @@ -69,7 +60,6 @@ class DefaultRecentBookmarksController( override fun handleShowAllBookmarksClicked() { RecentBookmarks.showAllBookmarks.add() - dismissSearchDialogIfDisplayed() navController.navigate( HomeFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id), ) @@ -78,15 +68,4 @@ class DefaultRecentBookmarksController( override fun handleBookmarkRemoved(bookmark: RecentBookmark) { appStore.dispatch(AppAction.RemoveRecentBookmark(bookmark)) } - - override fun handleBookmarkLongClicked() { - dismissSearchDialogIfDisplayed() - } - - @VisibleForTesting(otherwise = PRIVATE) - fun dismissSearchDialogIfDisplayed() { - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/interactor/RecentBookmarksInteractor.kt b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/interactor/RecentBookmarksInteractor.kt index f5b2bafba..810da7e14 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/interactor/RecentBookmarksInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/interactor/RecentBookmarksInteractor.kt @@ -33,9 +33,4 @@ interface RecentBookmarksInteractor { * @param bookmark The bookmark that has been removed. */ fun onRecentBookmarkRemoved(bookmark: RecentBookmark) - - /** - * Called when the user long clicks a recent bookmark. - */ - fun onRecentBookmarkLongClicked() } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarks.kt b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarks.kt index b97beae8a..ac13dcd8b 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarks.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarks.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.home.recentbookmarks.view -import android.content.res.Configuration import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -43,7 +42,6 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import mozilla.components.browser.icons.compose.Loader import mozilla.components.browser.icons.compose.Placeholder @@ -51,6 +49,7 @@ import mozilla.components.browser.icons.compose.WithIcon import mozilla.components.ui.colors.PhotonColors import org.mozilla.fenix.components.components import org.mozilla.fenix.compose.Image +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.inComposePreview import org.mozilla.fenix.home.recentbookmarks.RecentBookmark import org.mozilla.fenix.theme.FirefoxTheme @@ -70,7 +69,6 @@ private val imageModifier = Modifier * @param menuItems List of [RecentBookmarksMenuItem] shown when long clicking a [RecentBookmarkItem] * @param backgroundColor The background [Color] of each bookmark. * @param onRecentBookmarkClick Invoked when the user clicks on a recent bookmark. - * @param onRecentBookmarkLongClick Invoked when the user long clicks on a recent bookmark. */ @OptIn(ExperimentalComposeUiApi::class) @Composable @@ -79,7 +77,6 @@ fun RecentBookmarks( menuItems: List, backgroundColor: Color, onRecentBookmarkClick: (RecentBookmark) -> Unit = {}, - onRecentBookmarkLongClick: () -> Unit = {}, ) { LazyRow( modifier = Modifier.semantics { @@ -95,7 +92,6 @@ fun RecentBookmarks( menuItems = menuItems, backgroundColor = backgroundColor, onRecentBookmarkClick = onRecentBookmarkClick, - onRecentBookmarkLongClick = onRecentBookmarkLongClick, ) } } @@ -108,7 +104,6 @@ fun RecentBookmarks( * @param menuItems The list of [RecentBookmarksMenuItem] shown when long clicking on the recent bookmark item. * @param backgroundColor The background [Color] of the recent bookmark item. * @param onRecentBookmarkClick Invoked when the user clicks on the recent bookmark item. - * @param onRecentBookmarkLongClick Invoked when the user long clicks on the recent bookmark item. */ @OptIn( ExperimentalFoundationApi::class, @@ -120,7 +115,6 @@ private fun RecentBookmarkItem( menuItems: List, backgroundColor: Color, onRecentBookmarkClick: (RecentBookmark) -> Unit = {}, - onRecentBookmarkLongClick: () -> Unit = {}, ) { var isMenuExpanded by remember { mutableStateOf(false) } @@ -130,10 +124,7 @@ private fun RecentBookmarkItem( .combinedClickable( enabled = true, onClick = { onRecentBookmarkClick(bookmark) }, - onLongClick = { - onRecentBookmarkLongClick() - isMenuExpanded = true - }, + onLongClick = { isMenuExpanded = true }, ), shape = cardShape, backgroundColor = backgroundColor, @@ -276,8 +267,7 @@ private fun RecentBookmarksMenu( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun RecentBookmarksPreview() { FirefoxTheme { RecentBookmarks( diff --git a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksHeaderViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksHeaderViewHolder.kt index ad6687474..1e9cbe78c 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksHeaderViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksHeaderViewHolder.kt @@ -14,7 +14,6 @@ import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.LifecycleOwner -import androidx.navigation.findNavController import org.mozilla.fenix.R import org.mozilla.fenix.compose.ComposeViewHolder import org.mozilla.fenix.compose.home.HomeSectionHeader @@ -38,13 +37,6 @@ class RecentBookmarksHeaderViewHolder( composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0) } - private fun dismissSearchDialogIfDisplayed() { - val navController = itemView.findNavController() - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } - @Composable override fun Content() { Column { @@ -54,7 +46,6 @@ class RecentBookmarksHeaderViewHolder( headerText = stringResource(R.string.recently_saved_title), description = stringResource(R.string.recently_saved_show_all_content_description_2), onShowAllClick = { - dismissSearchDialogIfDisplayed() interactor.onShowAllBookmarksClicked() }, ) diff --git a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksViewHolder.kt index 8ea83ce60..13912bd04 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksViewHolder.kt @@ -48,7 +48,6 @@ class RecentBookmarksViewHolder( onClick = { bookmark -> interactor.onRecentBookmarkRemoved(bookmark) }, ), ), - onRecentBookmarkLongClick = interactor::onRecentBookmarkLongClicked, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/controller/RecentSyncedTabController.kt b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/controller/RecentSyncedTabController.kt index 8b34dc08a..e8632ce1a 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/controller/RecentSyncedTabController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/controller/RecentSyncedTabController.kt @@ -25,11 +25,6 @@ interface RecentSyncedTabController { */ fun handleRecentSyncedTabClick(tab: RecentSyncedTab) - /** - * @see [RecentSyncedTabInteractor.onRecentSyncedTabLongClick] - */ - fun handleRecentSyncedTabLongClick() - /** * @see [RecentSyncedTabInteractor.onRecentSyncedTabClicked] */ @@ -71,12 +66,6 @@ class DefaultRecentSyncedTabController( ) } - override fun handleRecentSyncedTabLongClick() { - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } - override fun handleRecentSyncedTabRemoved(tab: RecentSyncedTab) { appStore.dispatch(AppAction.RemoveRecentSyncedTab(tab)) } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/interactor/RecentSyncedTabInteractor.kt b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/interactor/RecentSyncedTabInteractor.kt index 579e9c61b..602047e05 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/interactor/RecentSyncedTabInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/interactor/RecentSyncedTabInteractor.kt @@ -17,11 +17,6 @@ interface RecentSyncedTabInteractor { */ fun onRecentSyncedTabClicked(tab: RecentSyncedTab) - /** - * Called when opening the dropdown menu on a recent synced tab by long press. - */ - fun onRecentSyncedTabLongClick() - /** * Opens the tabs tray to the synced tab page. Called when a user clicks on the "See all synced * tabs" button. diff --git a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTab.kt b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTab.kt index df401b1e7..2edeaf3b1 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTab.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTab.kt @@ -63,7 +63,6 @@ import org.mozilla.fenix.theme.FirefoxTheme * @param onRecentSyncedTabClick Invoked when the user clicks on the recent synced tab. * @param onSeeAllSyncedTabsButtonClick Invoked when user clicks on the "See all" button in the synced tab card. * @param onRemoveSyncedTab Invoked when user clicks on the "Remove" dropdown menu option. - * @param onRecentSyncedTabLongClick Invoked when user long presses the recent synced tab. */ @OptIn(ExperimentalFoundationApi::class) @Suppress("LongMethod", "LongParameterList") @@ -76,7 +75,6 @@ fun RecentSyncedTab( onRecentSyncedTabClick: (RecentSyncedTab) -> Unit, onSeeAllSyncedTabsButtonClick: () -> Unit, onRemoveSyncedTab: (RecentSyncedTab) -> Unit, - onRecentSyncedTabLongClick: () -> Unit, ) { var isDropdownExpanded by remember { mutableStateOf(false) } @@ -91,10 +89,7 @@ fun RecentSyncedTab( .height(180.dp) .combinedClickable( onClick = { tab?.let { onRecentSyncedTabClick(tab) } }, - onLongClick = { - onRecentSyncedTabLongClick() - isDropdownExpanded = true - }, + onLongClick = { isDropdownExpanded = true }, ), shape = RoundedCornerShape(8.dp), backgroundColor = backgroundColor, @@ -292,7 +287,6 @@ private fun LoadedRecentSyncedTab() { onRecentSyncedTabClick = {}, onSeeAllSyncedTabsButtonClick = {}, onRemoveSyncedTab = {}, - onRecentSyncedTabLongClick = {}, ) } } @@ -307,7 +301,6 @@ private fun LoadingRecentSyncedTab() { onRecentSyncedTabClick = {}, onSeeAllSyncedTabsButtonClick = {}, onRemoveSyncedTab = {}, - onRecentSyncedTabLongClick = {}, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTabViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTabViewHolder.kt index 75b681285..be8e612bc 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTabViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTabViewHolder.kt @@ -77,7 +77,6 @@ class RecentSyncedTabViewHolder( onRecentSyncedTabClick = recentSyncedTabInteractor::onRecentSyncedTabClicked, onSeeAllSyncedTabsButtonClick = recentSyncedTabInteractor::onSyncedTabShowAllClicked, onRemoveSyncedTab = recentSyncedTabInteractor::onRemovedRecentSyncedTab, - onRecentSyncedTabLongClick = recentSyncedTabInteractor::onRecentSyncedTabLongClick, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt b/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt index f344a81f0..1ec51d665 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt @@ -4,8 +4,6 @@ package org.mozilla.fenix.home.recenttabs.controller -import androidx.annotation.VisibleForTesting -import androidx.annotation.VisibleForTesting.Companion.PRIVATE import androidx.navigation.NavController import mozilla.components.browser.state.store.BrowserStore import mozilla.components.feature.tabs.TabsUseCases.SelectTabUseCase @@ -29,11 +27,6 @@ interface RecentTabController { */ fun handleRecentTabClicked(tabId: String) - /** - * @see [RecentTabInteractor.onRecentTabLongClicked] - */ - fun handleRecentTabLongClicked() - /** * @see [RecentTabInteractor.onRecentTabShowAllClicked] */ @@ -69,12 +62,7 @@ class DefaultRecentTabsController( navController.navigate(R.id.browserFragment) } - override fun handleRecentTabLongClicked() { - dismissSearchDialogIfDisplayed() - } - override fun handleRecentTabShowAllClicked() { - dismissSearchDialogIfDisplayed() RecentTabs.showAllClicked.record(NoExtras()) navController.navigate(HomeFragmentDirections.actionGlobalTabsTrayFragment()) } @@ -82,11 +70,4 @@ class DefaultRecentTabsController( override fun handleRecentTabRemoved(tab: RecentTab.Tab) { appStore.dispatch(AppAction.RemoveRecentTab(tab)) } - - @VisibleForTesting(otherwise = PRIVATE) - fun dismissSearchDialogIfDisplayed() { - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } } diff --git a/app/src/main/java/org/mozilla/fenix/home/recenttabs/interactor/RecentTabInteractor.kt b/app/src/main/java/org/mozilla/fenix/home/recenttabs/interactor/RecentTabInteractor.kt index 3fe6a2e9d..e8e2df8a7 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recenttabs/interactor/RecentTabInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recenttabs/interactor/RecentTabInteractor.kt @@ -17,11 +17,6 @@ interface RecentTabInteractor { */ fun onRecentTabClicked(tabId: String) - /** - * Called when the user long clicks on a recent tab. - */ - fun onRecentTabLongClicked() - /** * Show the tabs tray. Called when a user clicks on the "Show all" button besides the recent * tabs. diff --git a/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabViewHolder.kt index f53bd1f61..b00fec10f 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabViewHolder.kt @@ -50,7 +50,6 @@ class RecentTabViewHolder( recentTabs = recentTabs.value ?: emptyList(), backgroundColor = wallpaperState.wallpaperCardColor, onRecentTabClick = { recentTabInteractor.onRecentTabClicked(it) }, - onRecentTabLongClick = { recentTabInteractor.onRecentTabLongClicked() }, menuItems = listOf( RecentTabMenuItem( title = stringResource(id = R.string.recent_tab_menu_item_remove), diff --git a/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabs.kt b/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabs.kt index b731b8f39..c3b769720 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabs.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabs.kt @@ -6,7 +6,6 @@ package org.mozilla.fenix.home.recenttabs.view -import android.content.res.Configuration import android.graphics.Bitmap import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image @@ -49,7 +48,6 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import mozilla.components.browser.icons.compose.Loader @@ -62,6 +60,7 @@ import mozilla.components.ui.colors.PhotonColors import org.mozilla.fenix.components.components import org.mozilla.fenix.compose.Image import org.mozilla.fenix.compose.ThumbnailCard +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.inComposePreview import org.mozilla.fenix.home.recenttabs.RecentTab import org.mozilla.fenix.theme.FirefoxTheme @@ -81,7 +80,6 @@ fun RecentTabs( menuItems: List, backgroundColor: Color = FirefoxTheme.colors.layer2, onRecentTabClick: (String) -> Unit = {}, - onRecentTabLongClick: () -> Unit = {}, ) { Column( modifier = Modifier @@ -100,7 +98,6 @@ fun RecentTabs( menuItems = menuItems, backgroundColor = backgroundColor, onRecentTabClick = onRecentTabClick, - onRecentTabLongClick = onRecentTabLongClick, ) } } @@ -126,7 +123,6 @@ private fun RecentTabItem( menuItems: List, backgroundColor: Color, onRecentTabClick: (String) -> Unit = {}, - onRecentTabLongClick: () -> Unit = {}, ) { var isMenuExpanded by remember { mutableStateOf(false) } @@ -137,10 +133,7 @@ private fun RecentTabItem( .combinedClickable( enabled = true, onClick = { onRecentTabClick(tab.state.id) }, - onLongClick = { - onRecentTabLongClick() - isMenuExpanded = true - }, + onLongClick = { isMenuExpanded = true }, ), shape = RoundedCornerShape(8.dp), backgroundColor = backgroundColor, @@ -363,8 +356,7 @@ private fun PlaceHolderTabIcon(modifier: Modifier) { ) } -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview @Composable private fun RecentTabsPreview() { val tab = RecentTab.Tab( diff --git a/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabsHeaderViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabsHeaderViewHolder.kt index ce6c17bd3..08bca13de 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabsHeaderViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabsHeaderViewHolder.kt @@ -14,7 +14,6 @@ import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.LifecycleOwner -import androidx.navigation.findNavController import org.mozilla.fenix.R import org.mozilla.fenix.compose.ComposeViewHolder import org.mozilla.fenix.compose.home.HomeSectionHeader @@ -37,13 +36,6 @@ class RecentTabsHeaderViewHolder( composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0) } - private fun dismissSearchDialogIfDisplayed() { - val navController = itemView.findNavController() - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } - @Composable override fun Content() { Column { @@ -53,7 +45,6 @@ class RecentTabsHeaderViewHolder( headerText = stringResource(R.string.recent_tabs_header), description = stringResource(R.string.recent_tabs_show_all_content_description_2), onShowAllClick = { - dismissSearchDialogIfDisplayed() interactor.onRecentTabShowAllClicked() }, ) diff --git a/app/src/main/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsController.kt b/app/src/main/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsController.kt index b769db94f..0db9077b0 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsController.kt @@ -4,8 +4,6 @@ package org.mozilla.fenix.home.recentvisits.controller -import androidx.annotation.VisibleForTesting -import androidx.annotation.VisibleForTesting.Companion.PRIVATE import androidx.navigation.NavController import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -60,11 +58,6 @@ interface RecentVisitsController { * @param highlightUrl Url of the [RecentHistoryHighlight] to remove. */ fun handleRemoveRecentHistoryHighlight(highlightUrl: String) - - /** - * Callback for when the user long clicks on a recent visit. - */ - fun handleRecentVisitLongClicked() } /** @@ -83,7 +76,6 @@ class DefaultRecentVisitsController( * Shows the history fragment. */ override fun handleHistoryShowAllClicked() { - dismissSearchDialogIfDisplayed() navController.navigate( HomeFragmentDirections.actionGlobalHistoryFragment(), ) @@ -144,18 +136,4 @@ class DefaultRecentVisitsController( storage.deleteHistoryMetadataForUrl(highlightUrl) } } - - /** - * Dismiss the search dialog if displayed. - */ - override fun handleRecentVisitLongClicked() { - dismissSearchDialogIfDisplayed() - } - - @VisibleForTesting(otherwise = PRIVATE) - fun dismissSearchDialogIfDisplayed() { - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractor.kt b/app/src/main/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractor.kt index ff6d6d2e3..f6f1b10df 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractor.kt @@ -44,9 +44,4 @@ interface RecentVisitsInteractor { * @param highlightUrl [RecentHistoryHighlight.url] of the item to remove. */ fun onRemoveRecentHistoryHighlight(highlightUrl: String) - - /** - * Called when opening the dropdown menu on a recent visit by long press. - */ - fun onRecentVisitLongClicked() } diff --git a/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisited.kt b/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisited.kt index c67ca0592..a0cdd04ec 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisited.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisited.kt @@ -70,7 +70,6 @@ private const val VISITS_PER_COLUMN = 3 * @param menuItems List of [RecentVisitMenuItem] shown long clicking a [RecentlyVisitedItem]. * @param backgroundColor The background [Color] of each item. * @param onRecentVisitClick Invoked when the user clicks on a recent visit. - * @param onRecentVisitLongClick Invoked when the user long clicks on a recent visit. */ @OptIn(ExperimentalComposeUiApi::class) @Composable @@ -79,7 +78,6 @@ fun RecentlyVisited( menuItems: List, backgroundColor: Color = FirefoxTheme.colors.layer2, onRecentVisitClick: (RecentlyVisitedItem, Int) -> Unit = { _, _ -> }, - onRecentVisitLongClick: () -> Unit = {}, ) { Card( modifier = Modifier.fillMaxWidth(), @@ -116,7 +114,6 @@ fun RecentlyVisited( onRecentVisitClick = { onRecentVisitClick(it, pageIndex + 1) }, - onRecentVisitLongClick = { onRecentVisitLongClick() }, ) is RecentHistoryGroup -> RecentlyVisitedHistoryGroup( recentVisit = recentVisit, @@ -126,7 +123,6 @@ fun RecentlyVisited( onRecentVisitClick = { onRecentVisitClick(it, pageIndex + 1) }, - onRecentVisitLongClick = { onRecentVisitLongClick() }, ) } } @@ -144,13 +140,11 @@ fun RecentlyVisited( * @param clickableEnabled Whether click actions should be invoked or not. * @param showDividerLine Whether to show a divider line at the bottom. * @param onRecentVisitClick Invoked when the user clicks on a recent visit. - * @param onRecentVisitClick Invoked when the user long clicks on a recently visited group. */ @OptIn( ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class, ) -@Suppress("LongParameterList") @Composable private fun RecentlyVisitedHistoryGroup( recentVisit: RecentHistoryGroup, @@ -158,7 +152,6 @@ private fun RecentlyVisitedHistoryGroup( clickableEnabled: Boolean, showDividerLine: Boolean, onRecentVisitClick: (RecentHistoryGroup) -> Unit = { _ -> }, - onRecentVisitLongClick: () -> Unit = {}, ) { var isMenuExpanded by remember { mutableStateOf(false) } @@ -167,10 +160,7 @@ private fun RecentlyVisitedHistoryGroup( .combinedClickable( enabled = clickableEnabled, onClick = { onRecentVisitClick(recentVisit) }, - onLongClick = { - onRecentVisitLongClick() - isMenuExpanded = true - }, + onLongClick = { isMenuExpanded = true }, ) .size(268.dp, 56.dp) .semantics { @@ -233,13 +223,11 @@ private fun RecentlyVisitedHistoryGroup( * @param clickableEnabled Whether click actions should be invoked or not. * @param showDividerLine Whether to show a divider line at the bottom. * @param onRecentVisitClick Invoked when the user clicks on a recent visit. - * @param onRecentVisitLongClick Invoked when the user long clicks on a recent visit highlight. */ @OptIn( ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class, ) -@Suppress("LongParameterList") @Composable private fun RecentlyVisitedHistoryHighlight( recentVisit: RecentHistoryHighlight, @@ -247,7 +235,6 @@ private fun RecentlyVisitedHistoryHighlight( clickableEnabled: Boolean, showDividerLine: Boolean, onRecentVisitClick: (RecentHistoryHighlight) -> Unit = { _ -> }, - onRecentVisitLongClick: () -> Unit = {}, ) { var isMenuExpanded by remember { mutableStateOf(false) } @@ -256,10 +243,7 @@ private fun RecentlyVisitedHistoryHighlight( .combinedClickable( enabled = clickableEnabled, onClick = { onRecentVisitClick(recentVisit) }, - onLongClick = { - onRecentVisitLongClick() - isMenuExpanded = true - }, + onLongClick = { isMenuExpanded = true }, ) .size(268.dp, 56.dp) .semantics { diff --git a/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisitedViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisitedViewHolder.kt index 7f7a6a4df..78c5c78d8 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisitedViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recentvisits/view/RecentlyVisitedViewHolder.kt @@ -80,7 +80,6 @@ class RecentlyVisitedViewHolder( } } }, - onRecentVisitLongClick = { interactor.onRecentVisitLongClicked() }, ) } diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt index b58db17dd..5f9b12aef 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt @@ -41,7 +41,6 @@ import org.mozilla.fenix.GleanMetrics.TopSites import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.BrowserAnimator -import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.collections.SaveCollectionStep import org.mozilla.fenix.components.AppStore @@ -178,11 +177,6 @@ interface SessionControlController { */ fun handleRemoveCollectionsPlaceholder() - /** - * @see [CollectionInteractor.onCollectionMenuOpened] and [TopSiteInteractor.onTopSiteMenuOpened] - */ - fun handleMenuOpened() - /** * @see [MessageCardInteractor.onMessageClicked] */ @@ -248,13 +242,7 @@ class DefaultSessionControlController( ) } - override fun handleMenuOpened() { - dismissSearchDialogIfDisplayed() - } - override fun handleCollectionOpenTabClicked(tab: ComponentTab) { - dismissSearchDialogIfDisplayed() - restoreUseCase.invoke( activity, engine, @@ -307,7 +295,6 @@ class DefaultSessionControlController( } override fun handleCollectionShareTabsClicked(collection: TabCollection) { - dismissSearchDialogIfDisplayed() showShareFragment( collection.title, collection.tabs.map { ShareData(url = it.url, title = it.title) }, @@ -337,7 +324,6 @@ class DefaultSessionControlController( } override fun handlePrivateBrowsingLearnMoreClicked() { - dismissSearchDialogIfDisplayed() activity.openToBrowserAndLoad( searchTermOrURL = SupportUtils.getGenericSumoURLForTopic(PRIVATE_BROWSING_MYTHS), newTab = true, @@ -403,8 +389,6 @@ class DefaultSessionControlController( } override fun handleSelectTopSite(topSite: TopSite, position: Int) { - dismissSearchDialogIfDisplayed() - TopSites.openInNewTab.record(NoExtras()) when (topSite) { @@ -501,12 +485,6 @@ class DefaultSessionControlController( return url } - private fun dismissSearchDialogIfDisplayed() { - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigateUp() - } - } - override fun handleStartBrowsingClicked() { hideOnboarding() } @@ -648,14 +626,6 @@ class DefaultSessionControlController( appStore.dispatch( AppAction.ModeChange(Mode.fromBrowsingMode(newMode)), ) - - if (navController.currentDestination?.id == R.id.searchDialogFragment) { - navController.navigate( - BrowserFragmentDirections.actionGlobalSearchDialog( - sessionId = null, - ), - ) - } } } diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt index f2dbdbce1..f2f7e851d 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt @@ -133,11 +133,6 @@ interface CollectionInteractor { * User has removed the collections placeholder from home. */ fun onRemoveCollectionsPlaceholder() - - /** - * User has opened collection 3 dot menu. - */ - fun onCollectionMenuOpened() } interface ToolbarInteractor { @@ -228,11 +223,6 @@ interface TopSiteInteractor { * "Our sponsors & your privacy" top site menu item. */ fun onSponsorPrivacyClicked() - - /** - * Called when top site menu is opened. - */ - fun onTopSiteMenuOpened() } interface MessageCardInteractor { @@ -367,14 +357,6 @@ class SessionControlInteractor( controller.handleRemoveCollectionsPlaceholder() } - override fun onCollectionMenuOpened() { - controller.handleMenuOpened() - } - - override fun onTopSiteMenuOpened() { - controller.handleMenuOpened() - } - override fun onRecentTabClicked(tabId: String) { recentTabController.handleRecentTabClicked(tabId) } @@ -383,10 +365,6 @@ class SessionControlInteractor( recentTabController.handleRecentTabShowAllClicked() } - override fun onRecentTabLongClicked() { - recentTabController.handleRecentTabLongClicked() - } - override fun onRemoveRecentTab(tab: RecentTab.Tab) { recentTabController.handleRecentTabRemoved(tab) } @@ -395,10 +373,6 @@ class SessionControlInteractor( recentSyncedTabController.handleRecentSyncedTabClick(tab) } - override fun onRecentSyncedTabLongClick() { - recentSyncedTabController.handleRecentSyncedTabLongClick() - } - override fun onSyncedTabShowAllClicked() { recentSyncedTabController.handleSyncedTabShowAllClicked() } @@ -419,10 +393,6 @@ class SessionControlInteractor( recentBookmarksController.handleBookmarkRemoved(bookmark) } - override fun onRecentBookmarkLongClicked() { - recentBookmarksController.handleBookmarkLongClicked() - } - override fun onHistoryShowAllClicked() { recentVisitsController.handleHistoryShowAllClicked() } @@ -445,10 +415,6 @@ class SessionControlInteractor( recentVisitsController.handleRemoveRecentHistoryHighlight(highlightUrl) } - override fun onRecentVisitLongClicked() { - recentVisitsController.handleRecentVisitLongClicked() - } - override fun openCustomizeHomePage() { controller.handleCustomizeHomeTapped() } diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt index ad63ce4ca..a015a69eb 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt @@ -54,7 +54,6 @@ class TopSiteItemViewHolder( init { itemView.setOnLongClickListener { - interactor.onTopSiteMenuOpened() TopSites.longPress.record(TopSites.LongPressExtra(topSite.name())) val topSiteMenu = TopSiteItemMenu( diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/toolbar/ToolbarView.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/toolbar/ToolbarView.kt index eaa8b3ddb..3c1d02eae 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/toolbar/ToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/toolbar/ToolbarView.kt @@ -81,6 +81,8 @@ class ToolbarView( false } + setDefaultIcon() + setOnEditListener( object : mozilla.components.concept.toolbar.Toolbar.OnEditListener { override fun onCancelEditing(): Boolean { @@ -110,7 +112,9 @@ class ToolbarView( view.editMode() isInitialized = true } + } + private fun setDefaultIcon() { val bookmarkSearchIcon = AppCompatResources.getDrawable(context, R.drawable.ic_bookmarks_menu) diff --git a/app/src/main/java/org/mozilla/fenix/library/history/toolbar/ToolbarView.kt b/app/src/main/java/org/mozilla/fenix/library/history/toolbar/ToolbarView.kt index e6679e1c4..1b7a80779 100644 --- a/app/src/main/java/org/mozilla/fenix/library/history/toolbar/ToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/library/history/toolbar/ToolbarView.kt @@ -81,6 +81,8 @@ class ToolbarView( false } + setDefaultIcon() + setOnEditListener( object : mozilla.components.concept.toolbar.Toolbar.OnEditListener { override fun onCancelEditing(): Boolean { @@ -110,7 +112,9 @@ class ToolbarView( view.editMode() isInitialized = true } + } + private fun setDefaultIcon() { val historySearchIcon = AppCompatResources.getDrawable(context, R.drawable.ic_history) historySearchIcon?.let { diff --git a/app/src/main/java/org/mozilla/fenix/onboarding/HomeNotificationPermissionDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/onboarding/HomeNotificationPermissionDialogFragment.kt new file mode 100644 index 000000000..858c9bafa --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/onboarding/HomeNotificationPermissionDialogFragment.kt @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.onboarding + +import android.annotation.SuppressLint +import android.content.pm.ActivityInfo +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.fragment.app.DialogFragment +import com.google.accompanist.insets.ProvideWindowInsets +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.onboarding.view.NotificationPermissionDialogScreen +import org.mozilla.fenix.theme.FirefoxTheme + +/** + * Dialog displaying notification pre-permission prompt. + */ +class HomeNotificationPermissionDialogFragment : DialogFragment() { + + @SuppressLint("SourceLockedOrientationActivity") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NO_TITLE, R.style.HomeOnboardingDialogStyle) + activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + + override fun onDestroy() { + super.onDestroy() + activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View = ComposeView(requireContext()).apply { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + setContent { + ProvideWindowInsets { + FirefoxTheme { + NotificationPermissionDialogScreen( + onDismiss = ::onDismiss, + grantNotificationPermission = { + ensureMarketingChannelExists(context.applicationContext) + onDismiss() + }, + ) + } + } + } + } + + private fun onDismiss() { + dismiss() + context?.settings()?.isNotificationPrePermissionShown = true + } +} diff --git a/app/src/main/java/org/mozilla/fenix/onboarding/MarketingNotificationHelper.kt b/app/src/main/java/org/mozilla/fenix/onboarding/MarketingNotificationHelper.kt index 980f1d95c..dd03aaa53 100644 --- a/app/src/main/java/org/mozilla/fenix/onboarding/MarketingNotificationHelper.kt +++ b/app/src/main/java/org/mozilla/fenix/onboarding/MarketingNotificationHelper.kt @@ -8,13 +8,11 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.os.Build -import androidx.core.app.NotificationManagerCompat -import org.mozilla.fenix.GleanMetrics.Events.marketingNotificationAllowed import org.mozilla.fenix.R // Channel ID was not updated when it was renamed to marketing. Thus, we'll have to continue // to use this ID as the marketing channel ID -private const val MARKETING_CHANNEL_ID = "org.mozilla.fenix.default.browser.channel" +const val MARKETING_CHANNEL_ID = "org.mozilla.fenix.default.browser.channel" // For notification that uses the marketing notification channel, IDs should be unique. const val DEFAULT_BROWSER_NOTIFICATION_ID = 1 @@ -26,7 +24,6 @@ const val RE_ENGAGEMENT_NOTIFICATION_ID = 2 * Returns the channel id to be used for notifications. */ fun ensureMarketingChannelExists(context: Context): String { - var channelEnabled = true if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val notificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager @@ -43,18 +40,7 @@ fun ensureMarketingChannelExists(context: Context): String { notificationManager.createNotificationChannel(channel) } - - channelEnabled = channel.importance != NotificationManager.IMPORTANCE_NONE - } - - @Suppress("TooGenericExceptionCaught") - val notificationsEnabled = try { - NotificationManagerCompat.from(context).areNotificationsEnabled() - } catch (e: Exception) { - false } - marketingNotificationAllowed.set(notificationsEnabled && channelEnabled) - return MARKETING_CHANNEL_ID } diff --git a/app/src/main/java/org/mozilla/fenix/onboarding/view/NotificationPermissionDialogScreen.kt b/app/src/main/java/org/mozilla/fenix/onboarding/view/NotificationPermissionDialogScreen.kt new file mode 100644 index 000000000..e39a535be --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/onboarding/view/NotificationPermissionDialogScreen.kt @@ -0,0 +1,233 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.onboarding.view + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.google.accompanist.insets.navigationBarsPadding +import com.google.accompanist.insets.statusBarsPadding +import mozilla.components.service.glean.private.NoExtras +import org.mozilla.fenix.GleanMetrics.Onboarding +import org.mozilla.fenix.R +import org.mozilla.fenix.compose.button.PrimaryButton +import org.mozilla.fenix.compose.button.SecondaryButton +import org.mozilla.fenix.theme.FirefoxTheme + +/** + * Model containing data for the [NotificationPermissionPage]. + * + * @param image [DrawableRes] displayed on the page. + * @param title [StringRes] of the permission headline text. + * @param description [StringRes] of the permission body text. + * @param primaryButtonText [StringRes] of the primary button text. + * @param secondaryButtonText [StringRes] of the secondary button text. + * @param onRecordImpressionEvent Callback for recording impression event. + */ +private data class NotificationPermissionPageState( + @DrawableRes val image: Int, + @StringRes val title: Int, + @StringRes val description: Int, + @StringRes val primaryButtonText: Int, + @StringRes val secondaryButtonText: Int? = null, + val onRecordImpressionEvent: () -> Unit, +) + +/** + * A screen for displaying notification pre permission prompt. + * + * @param onDismiss Invoked when the user clicks on the close or the negative button. + * @param grantNotificationPermission Invoked when the user clicks on the positive button. + */ +@Composable +fun NotificationPermissionDialogScreen( + onDismiss: () -> Unit, + grantNotificationPermission: () -> Unit, +) { + NotificationPermissionContent( + notificationPermissionPageState = NotificationPageState, + onDismiss = { + onDismiss() + Onboarding.notifPppCloseClick.record(NoExtras()) + }, + onPrimaryButtonClick = { + grantNotificationPermission() + Onboarding.notifPppPositiveBtnClick.record(NoExtras()) + }, + onSecondaryButtonClick = { + onDismiss() + Onboarding.notifPppNegativeBtnClick.record(NoExtras()) + }, + ) +} + +@Composable +private fun NotificationPermissionContent( + notificationPermissionPageState: NotificationPermissionPageState, + onDismiss: () -> Unit, + onPrimaryButtonClick: () -> Unit, + onSecondaryButtonClick: () -> Unit, + modifier: Modifier = Modifier, +) { + BoxWithConstraints(Modifier.fillMaxSize()) { + val boxWithConstraintsScope = this + Column( + modifier = modifier + .background(FirefoxTheme.colors.layer1) + .fillMaxSize() + .padding(bottom = 32.dp) + .statusBarsPadding() + .navigationBarsPadding(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + IconButton( + onClick = onDismiss, + modifier = Modifier.align(Alignment.End), + ) { + Icon( + painter = painterResource(id = R.drawable.mozac_ic_close), + contentDescription = stringResource(R.string.content_description_close_button), + tint = FirefoxTheme.colors.iconPrimary, + ) + } + + NotificationPermissionPage( + pageState = notificationPermissionPageState, + onPrimaryButtonClick = onPrimaryButtonClick, + onSecondaryButtonClick = onSecondaryButtonClick, + modifier = Modifier + .weight(1f) + .fillMaxWidth() + .padding(horizontal = 16.dp) + .verticalScroll(rememberScrollState()), + imageModifier = Modifier + .height(boxWithConstraintsScope.maxHeight.times(IMAGE_HEIGHT_RATIO)), + ) + } + } +} + +/** + * A page for displaying Notification Permission Content. + * + * @param pageState The page content that's displayed. + * @param onPrimaryButtonClick Invoked when the user clicks the primary button. + * @param onSecondaryButtonClick Invoked when the user clicks the secondary button. + * @param modifier The modifier to be applied to the Composable. + */ +@Composable +private fun NotificationPermissionPage( + pageState: NotificationPermissionPageState, + onPrimaryButtonClick: () -> Unit, + onSecondaryButtonClick: () -> Unit, + modifier: Modifier = Modifier, + imageModifier: Modifier = Modifier, +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceEvenly, + ) { + Image( + painter = painterResource(id = pageState.image), + contentDescription = null, + modifier = imageModifier, + ) + + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = stringResource( + id = pageState.title, + formatArgs = arrayOf(stringResource(R.string.app_name)), + ), + color = FirefoxTheme.colors.textPrimary, + textAlign = TextAlign.Center, + style = FirefoxTheme.typography.headline5, + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Text( + text = stringResource( + id = pageState.description, + formatArgs = arrayOf(stringResource(R.string.app_name)), + ), + color = FirefoxTheme.colors.textSecondary, + textAlign = TextAlign.Center, + style = FirefoxTheme.typography.body2, + ) + } + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(top = 16.dp), + ) { + PrimaryButton( + text = stringResource(id = pageState.primaryButtonText), + onClick = onPrimaryButtonClick, + ) + + if (pageState.secondaryButtonText != null) { + Spacer(modifier = Modifier.height(8.dp)) + SecondaryButton( + text = stringResource(id = pageState.secondaryButtonText), + onClick = onSecondaryButtonClick, + ) + } + } + } + + LaunchedEffect(pageState) { + pageState.onRecordImpressionEvent() + } +} + +private val NotificationPageState = NotificationPermissionPageState( + image = R.drawable.ic_notification_permission, + title = R.string.onboarding_home_enable_notifications_title, + description = R.string.onboarding_home_enable_notifications_description, + primaryButtonText = R.string.onboarding_home_enable_notifications_positive_button, + secondaryButtonText = R.string.onboarding_home_enable_notifications_negative_button, + onRecordImpressionEvent = { Onboarding.notifPppImpression.record(NoExtras()) }, +) + +private const val IMAGE_HEIGHT_RATIO = 0.4f + +@Preview +@Composable +private fun NotificationPermissionScreenPreview() { + FirefoxTheme { + NotificationPermissionDialogScreen( + grantNotificationPermission = {}, + onDismiss = { }, + ) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/onboarding/view/Onboarding.kt b/app/src/main/java/org/mozilla/fenix/onboarding/view/Onboarding.kt index 61dd88e84..24092167e 100644 --- a/app/src/main/java/org/mozilla/fenix/onboarding/view/Onboarding.kt +++ b/app/src/main/java/org/mozilla/fenix/onboarding/view/Onboarding.kt @@ -164,7 +164,7 @@ private fun OnboardingWelcomeBottomContent( @Composable private fun OnboardingWelcomeContent() { Column( - modifier = Modifier.padding(horizontal = 16.dp), + modifier = Modifier.padding(horizontal = 16.dp, vertical = 32.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Image( @@ -195,7 +195,7 @@ private fun OnboardingWelcomeContent() { @Composable private fun OnboardingSyncSignInContent() { Column( - modifier = Modifier.padding(horizontal = 16.dp), + modifier = Modifier.padding(horizontal = 16.dp, vertical = 32.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Image( diff --git a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt index 470f90f0b..c226dcff9 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt @@ -18,9 +18,9 @@ import androidx.annotation.VisibleForTesting.Companion.PRIVATE import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import mozilla.components.support.ktx.android.os.resetAfter +import mozilla.components.support.utils.ManufacturerCodes import org.mozilla.fenix.Config import org.mozilla.fenix.components.Components -import org.mozilla.fenix.utils.ManufacturerCodes import java.util.concurrent.Executors import java.util.concurrent.atomic.AtomicLong @@ -168,13 +168,13 @@ open class StrictModeManager( * To add a new manufacturer to the list, log "Build.MANUFACTURER" from the device to get the * exact name of the manufacturer. */ -private val strictModeExceptionList = setOf(ManufacturerCodes.HUAWEI, ManufacturerCodes.ONE_PLUS) +private fun isInStrictModeExceptionList() = ManufacturerCodes.isHuawei || ManufacturerCodes.isOnePlus private fun StrictMode.ThreadPolicy.Builder.penaltyDeathWithIgnores(): StrictMode.ThreadPolicy.Builder { // This workaround was added before we realized we can ignored based on violation contents // (see code below). This solution - blanket disabling StrictMode on some manufacturers - isn't // great so, if we have time, we should consider reimplementing these fixes using the methods below. - if (Build.MANUFACTURER in strictModeExceptionList) { + if (isInStrictModeExceptionList()) { return this } diff --git a/app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt b/app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt index f77fd1f45..5383b0970 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt @@ -9,7 +9,7 @@ import android.os.StrictMode import android.os.strictmode.Violation import androidx.annotation.RequiresApi import mozilla.components.support.base.log.logger.Logger -import org.mozilla.fenix.utils.ManufacturerCodes +import mozilla.components.support.utils.ManufacturerCodes private const val FCQN_EDM_STORAGE_PROVIDER_BASE = "com.android.server.enterprise.storage.EdmStorageProviderBase" private const val INSTRUMENTED_HOOKS_CLASS = "com.android.tools.deploy.instrument.InstrumentationHooks" diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt b/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt index 763561886..1164a3d50 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt @@ -72,6 +72,7 @@ class SearchDialogController( private val clearToolbarFocus: () -> Unit, private val focusToolbar: () -> Unit, private val clearToolbar: () -> Unit, + private val dismissDialogAndGoBack: () -> Unit, ) : SearchController { override fun handleUrlCommitted(url: String, fromHomeScreen: Boolean) { @@ -135,6 +136,7 @@ class SearchDialogController( override fun handleEditingCancelled() { clearToolbarFocus() + dismissDialogAndGoBack() } override fun handleTextChanged(text: String) { diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt index e9799a155..f2f8fc7f0 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt @@ -20,6 +20,7 @@ import android.os.Bundle import android.speech.RecognizerIntent import android.text.style.StyleSpan import android.view.LayoutInflater +import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.view.ViewStub @@ -47,6 +48,7 @@ import kotlinx.coroutines.launch import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.state.state.searchEngines +import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.menu.candidate.DrawableMenuIcon @@ -66,6 +68,7 @@ import mozilla.components.support.ktx.android.content.hasCamera import mozilla.components.support.ktx.android.content.isPermissionGranted import mozilla.components.support.ktx.android.content.res.getSpanned import mozilla.components.support.ktx.android.net.isHttpOrHttps +import mozilla.components.support.ktx.android.view.findViewInHierarchy import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.kotlin.toNormalizedUrl import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged @@ -82,6 +85,7 @@ import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.databinding.FragmentSearchDialogBinding import org.mozilla.fenix.databinding.SearchSuggestionsHintBinding import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.getRectWithScreenLocation import org.mozilla.fenix.ext.increaseTapArea import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings @@ -101,7 +105,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { private var _binding: FragmentSearchDialogBinding? = null private val binding get() = _binding!! - private lateinit var interactor: SearchDialogInteractor + @VisibleForTesting internal lateinit var interactor: SearchDialogInteractor private lateinit var store: SearchDialogFragmentStore private lateinit var toolbarView: ToolbarView private lateinit var inlineAutocompleteEditText: InlineAutocompleteEditText @@ -117,6 +121,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { private val qrFeature = ViewBoundFeatureWrapper() private val speechIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH) + private var isPrivateButtonClicked = false private var dialogHandledAction = false private var searchSelectorAlreadyAdded = false private var qrButtonAction: Toolbar.Action? = null @@ -162,6 +167,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { } @SuppressWarnings("LongMethod") + @SuppressLint("ClickableViewAccessibility") override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -206,6 +212,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { clearToolbar = { inlineAutocompleteEditText.setText("") }, + dismissDialogAndGoBack = ::dismissDialogAndGoBack, ), ) @@ -260,13 +267,31 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { requireComponents.core.engine.speculativeCreateSession(isPrivate) + // Handle the scenario in which the user selects another search engine before starting a search. + maybeSelectShortcutEngine(args.searchEngine) + when (getPreviousDestination()?.destination?.id) { R.id.homeFragment -> { // When displayed above home, dispatches the touch events to scrim area to the HomeFragment binding.searchWrapper.background = ColorDrawable(Color.TRANSPARENT) dialog?.window?.decorView?.setOnTouchListener { _, event -> + when (event?.action) { + MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> { + isPrivateButtonClicked = isTouchingPrivateButton(event.x, event.y) + } + MotionEvent.ACTION_UP -> { + if (!isTouchingPrivateButton( + event.x, + event.y, + ) && !isPrivateButtonClicked + ) { + findNavController().popBackStack() + isPrivateButtonClicked = false + } + } + else -> isPrivateButtonClicked = false + } requireActivity().dispatchTouchEvent(event) - // toolbarView.view.displayMode() false } } @@ -456,6 +481,33 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { } } + /** + * Check whether the search engine identified by [selectedSearchEngineId] is the default search engine + * and if not update the search state to reflect that a different search engine is currently selected. + * + * @param selectedSearchEngineId Id of the search engine currently selected for next searches. + */ + @VisibleForTesting + internal fun maybeSelectShortcutEngine(selectedSearchEngineId: String?) { + if (selectedSearchEngineId == null) return + + val searchState = requireComponents.core.store.state.search + searchState.searchEngines.firstOrNull { + it.id == selectedSearchEngineId + }?.let { selectedSearchEngine -> + if (selectedSearchEngine != searchState.selectedOrDefaultSearchEngine) { + interactor.onSearchShortcutEngineSelected(selectedSearchEngine) + } + } + } + + private fun isTouchingPrivateButton(x: Float, y: Float): Boolean { + val view = parentFragmentManager.primaryNavigationFragment?.view?.findViewInHierarchy { + it.id == R.id.privateBrowsingButton + } ?: return false + return view.getRectWithScreenLocation().contains(x.toInt(), y.toInt()) + } + private fun hideClipboardSection() { binding.fillLinkFromClipboard.isVisible = false binding.fillLinkDivider.isVisible = false @@ -585,24 +637,29 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { true } else -> { - // In case we're displaying search results, we wouldn't have navigated to home, and - // so we don't need to navigate "back to" browser fragment. - // See mirror of this logic in BrowserToolbarController#handleToolbarClick. - if (store.state.searchTerms.isBlank()) { - val args by navArgs() - args.sessionId?.let { - findNavController().navigate( - SearchDialogFragmentDirections.actionGlobalBrowser(null), - ) - } - } - view?.hideKeyboard() - dismissAllowingStateLoss() + dismissDialogAndGoBack() true } } } + private fun dismissDialogAndGoBack() { + // In case we're displaying search results, we wouldn't have navigated to home, and + // so we don't need to navigate "back to" browser fragment. + // See mirror of this logic in BrowserToolbarController#handleToolbarClick. + if (store.state.searchTerms.isBlank()) { + val args by navArgs() + args.sessionId?.let { + findNavController().navigate( + SearchDialogFragmentDirections.actionGlobalBrowser(null), + ) + } + } + + view?.hideKeyboard() + dismissAllowingStateLoss() + } + private fun historyStorageProvider(): HistoryStorage? { return if (requireContext().settings().shouldShowHistorySuggestions) { requireComponents.core.historyStorage @@ -758,6 +815,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { toolbarView.view.addEditActionStart( SearchSelectorToolbarAction( store = store, + defaultSearchEngine = requireComponents.core.store.state.search.selectedOrDefaultSearchEngine, menu = searchSelectorMenu, ), ) @@ -811,7 +869,10 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { } private fun updateQrButton(searchFragmentState: SearchFragmentState) { - when (searchFragmentState.searchEngineSource.searchEngine == searchFragmentState.defaultEngine) { + val searchEngine = searchFragmentState.searchEngineSource.searchEngine + when ( + searchEngine?.isGeneral == true || searchEngine?.type == SearchEngine.Type.CUSTOM + ) { true -> { if (qrButtonAction == null) { qrButtonAction = IncreasedTapAreaActionDecorator( diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt index 1a1b32aa8..8d2adfcec 100644 --- a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt @@ -10,6 +10,7 @@ import androidx.core.graphics.BlendModeCompat.SRC_IN import androidx.core.graphics.drawable.toBitmap import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.state.state.searchEngines +import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.concept.awesomebar.AwesomeBar import mozilla.components.concept.engine.EngineSession import mozilla.components.feature.awesomebar.provider.BookmarksStorageSuggestionProvider @@ -176,6 +177,7 @@ class AwesomeBarView( BrowsingMode.Normal -> false BrowsingMode.Private -> true }, + suggestionsHeader = getSearchEngineSuggestionsHeader(), ) defaultSearchActionProvider = @@ -184,6 +186,7 @@ class AwesomeBarView( searchUseCase = searchUseCase, icon = searchBitmap, showDescription = false, + suggestionsHeader = getSearchEngineSuggestionsHeader(), ) shortcutsEnginePickerProvider = @@ -207,6 +210,25 @@ class AwesomeBarView( searchSuggestionProviderMap = HashMap() } + private fun getSearchEngineSuggestionsHeader(): String? { + val searchState = activity.components.core.store.state.search + var searchEngine = searchState.selectedOrDefaultSearchEngine?.name + + if (!searchEngine.isNullOrEmpty()) { + searchEngine = when (searchEngine) { + GOOGLE_SEARCH_ENGINE_NAME -> activity.getString( + R.string.google_search_engine_suggestion_header, + ) + else -> activity.getString( + R.string.other_default_search_engine_suggestion_header, + searchEngine, + ) + } + } + + return searchEngine + } + fun update(state: SearchFragmentState) { // Do not make suggestions based on user's current URL unless it's a search shortcut if (state.query.isNotEmpty() && state.query == state.url && !state.showSearchShortcuts) { @@ -355,6 +377,8 @@ class AwesomeBarView( companion object { // Maximum number of suggestions returned. const val METADATA_SUGGESTION_LIMIT = 3 + + const val GOOGLE_SEARCH_ENGINE_NAME = "Google" } } diff --git a/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelector.kt b/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelector.kt index d3fef7e32..fbfff3e90 100644 --- a/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelector.kt +++ b/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelector.kt @@ -8,7 +8,6 @@ import android.content.Context import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.LayoutInflater -import android.view.ViewGroup import android.widget.RelativeLayout import org.mozilla.fenix.databinding.SearchSelectorBinding @@ -22,21 +21,9 @@ internal class SearchSelector @JvmOverloads constructor( ) : RelativeLayout(context, attrs, defStyle) { private val binding = SearchSelectorBinding.inflate(LayoutInflater.from(context), this) - private var marginTop: Int = 0 - - override fun setLayoutParams(params: ViewGroup.LayoutParams?) { - if (params is MarginLayoutParams) { - params.topMargin = marginTop - } - super.setLayoutParams(params) - } fun setIcon(icon: Drawable?, contentDescription: String?) { binding.icon.setImageDrawable(icon) binding.icon.contentDescription = contentDescription } - - fun setTopMargin(margin: Int) { - marginTop = margin - } } diff --git a/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarAction.kt b/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarAction.kt index b8f7c76dc..8d5ae7989 100644 --- a/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarAction.kt +++ b/app/src/main/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarAction.kt @@ -36,6 +36,7 @@ import org.mozilla.fenix.search.SearchDialogFragmentStore */ class SearchSelectorToolbarAction( private val store: SearchDialogFragmentStore, + private val defaultSearchEngine: SearchEngine?, private val menu: SearchSelectorMenu, ) : Toolbar.Action { private var updateIconJob: Job? = null @@ -43,7 +44,17 @@ class SearchSelectorToolbarAction( override fun createView(parent: ViewGroup): View { val context = parent.context + // Only search engines with type APPLICATION (tabs, history, bookmarks) will have a valid icon at this time. + // For other search engines show the icon of the default search engine which should be shown in the selector. + val initialSearchEngine = store.state.searchEngineSource.searchEngine ?: defaultSearchEngine return SearchSelector(context).apply { + initialSearchEngine?.let { + this.setIcon( + icon = initialSearchEngine.getScaledIcon(this.context), + contentDescription = initialSearchEngine.name, + ) + } + setOnClickListener { val orientation = if (context.settings().shouldUseBottomToolbar) { Orientation.UP @@ -52,10 +63,12 @@ class SearchSelectorToolbarAction( } UnifiedSearch.searchMenuTapped.record(NoExtras()) - menu.menuController.show(anchor = it, orientation = orientation, forceOrientation = true) + menu.menuController.show(anchor = it, orientation = orientation) } - setTopMargin(resources.getDimensionPixelSize(R.dimen.search_engine_engine_icon_top_margin)) + val topPadding = resources.getDimensionPixelSize(R.dimen.search_engine_engine_icon_top_margin) + setPadding(0, topPadding, 0, 0) + setBackgroundResource( context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless), ) diff --git a/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt b/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt index 07d7a2649..9ec51c0c1 100644 --- a/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt @@ -12,6 +12,7 @@ import androidx.appcompat.content.res.AppCompatResources import androidx.core.content.ContextCompat import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.toolbar.BrowserToolbar +import mozilla.components.concept.toolbar.Toolbar import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.content.res.resolveAttribute import mozilla.components.support.ktx.android.view.hideKeyboard @@ -135,7 +136,12 @@ class ToolbarView( // we have the most up to date text interactor.onTextChanged(view.url.toString()) - view.editMode() + // If search terms are displayed, move the cursor to the end instead of selecting all text. + if (settings.showUnifiedSearchFeature && searchState.searchTerms.isNotBlank()) { + view.editMode(cursorPlacement = Toolbar.CursorPlacement.END) + } else { + view.editMode() + } isInitialized = true } @@ -149,6 +155,13 @@ class ToolbarView( Core.TABS_SEARCH_ENGINE_ID -> context.getString(R.string.tab_search_hint) else -> context.getString(R.string.application_search_hint) } + SearchEngine.Type.BUNDLED -> { + if (!searchEngine.isGeneral) { + context.getString(R.string.application_search_hint) + } else { + context.getString(R.string.search_hint) + } + } else -> context.getString(R.string.search_hint) } diff --git a/app/src/main/java/org/mozilla/fenix/settings/CookieBannersFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/CookieBannersFragment.kt index 56a0d4988..350b26041 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/CookieBannersFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/CookieBannersFragment.kt @@ -7,9 +7,9 @@ package org.mozilla.fenix.settings import android.os.Bundle import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SwitchPreference +import androidx.preference.SwitchPreferenceCompat import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode.DISABLED -import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode.REJECT_OR_ACCEPT_ALL +import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode.REJECT_ALL import mozilla.components.concept.engine.Settings import org.mozilla.fenix.GleanMetrics.CookieBanners import org.mozilla.fenix.R @@ -37,14 +37,16 @@ class CookieBannersFragment : PreferenceFragmentCompat() { } private fun setupPreferences() { - requirePreference(R.string.pref_key_cookie_banner_v1).apply { + requirePreference(R.string.pref_key_cookie_banner_v1).apply { + summary = + getString(R.string.reduce_cookie_banner_summary_1, getString(R.string.app_name)) onPreferenceChangeListener = object : SharedPreferenceUpdater() { override fun onPreferenceChange( preference: Preference, newValue: Any?, ): Boolean { val (mode, metricTag) = if (newValue == true) { - REJECT_OR_ACCEPT_ALL to "reject_or_accept_all" + REJECT_ALL to "reject_all" } else { DISABLED to "disabled" } diff --git a/app/src/main/java/org/mozilla/fenix/settings/CookieBannersSwitchPreference.kt b/app/src/main/java/org/mozilla/fenix/settings/CookieBannersSwitchPreference.kt new file mode 100644 index 000000000..36e5599b2 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/CookieBannersSwitchPreference.kt @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.settings + +import android.content.Context +import android.util.AttributeSet +import org.mozilla.fenix.ext.settings + +/** + * Cookie banners switch preference with a learn more link. + */ +class CookieBannersSwitchPreference(context: Context, attrs: AttributeSet?) : + LearnMoreSwitchPreference(context, attrs) { + + override fun getLearnMoreUrl(): String { + return SupportUtils.getGenericSumoURLForTopic( + SupportUtils.SumoTopic.COOKIE_BANNER, + ) + } + + override fun getSwitchValue(): Boolean { + return context.settings().shouldUseCookieBanner + } +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/LearnMoreSwitchPreference.kt b/app/src/main/java/org/mozilla/fenix/settings/LearnMoreSwitchPreference.kt new file mode 100644 index 000000000..40316aa10 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/LearnMoreSwitchPreference.kt @@ -0,0 +1,83 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.settings + +import android.content.Context +import android.util.AttributeSet +import android.widget.TextView +import androidx.appcompat.widget.SwitchCompat +import androidx.core.view.isVisible +import androidx.preference.PreferenceViewHolder +import androidx.preference.SwitchPreferenceCompat +import org.mozilla.fenix.BrowserDirection +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.asActivity + +/** + * A [SwitchPreferenceCompat] that include a learn more link. + */ +abstract class LearnMoreSwitchPreference(context: Context, attrs: AttributeSet?) : + SwitchPreferenceCompat(context, attrs) { + + init { + layoutResource = R.layout.preference_switch_learn_more + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + holder.itemView.isClickable = false + val switch = holder.findViewById(R.id.learn_more_switch) as SwitchCompat + + switch.run { + isChecked = getSwitchValue() + setOnCheckedChangeListener { _, isChecked -> + onPreferenceChangeListener.onPreferenceChange( + this@LearnMoreSwitchPreference, + isChecked, + ) + } + } + + getDescription()?.let { + val summaryView = holder.findViewById(android.R.id.summary) as TextView + summaryView.text = it + summaryView.isVisible = true + } + + val learnMoreLink = holder.findViewById(R.id.link) as TextView + learnMoreLink.paint?.isUnderlineText = true + learnMoreLink.setOnClickListener { + it.context.asActivity()?.let { activity -> + (activity as HomeActivity).openToBrowserAndLoad( + searchTermOrURL = getLearnMoreUrl(), + newTab = true, + from = BrowserDirection.FromCookieBanner, + ) + } + } + + val backgroundDrawableArray = + context.obtainStyledAttributes(intArrayOf(R.attr.selectableItemBackground)) + val backgroundDrawable = backgroundDrawableArray.getDrawable(0) + backgroundDrawableArray.recycle() + learnMoreLink.background = backgroundDrawable + } + + /** + * Returns the description to be used the UI. + */ + open fun getDescription(): String? = null + + /** + * Returns the URL that should be used when the learn more link is clicked. + */ + abstract fun getLearnMoreUrl(): String + + /** + * Indicates the value which the switch widget should show. + */ + abstract fun getSwitchValue(): Boolean +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt index 0e838b59a..1ac089403 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt @@ -55,6 +55,7 @@ object SupportUtils { SMARTBLOCK("smartblock-enhanced-tracking-protection"), SPONSOR_PRIVACY("sponsor-privacy"), HTTPS_ONLY_MODE("https-only-mode-firefox-android"), + COOKIE_BANNER("cookie-banner-reduction-firefox-android"), } enum class MozillaPage(internal val path: String) { diff --git a/app/src/main/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStore.kt b/app/src/main/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStore.kt index 45cc0adbd..cb000dae5 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStore.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStore.kt @@ -60,7 +60,7 @@ private fun localeSettingsStateReducer( ): LocaleSettingsState { return when (action) { is LocaleSettingsAction.Select -> { - state.copy(selectedLocale = action.selectedItem) + state.copy(selectedLocale = action.selectedItem, searchedLocaleList = state.localeList) } is LocaleSettingsAction.Search -> { val searchedItems = state.localeList.filter { diff --git a/app/src/main/java/org/mozilla/fenix/settings/creditcards/CreditCardEditorFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/creditcards/CreditCardEditorFragment.kt index 36b5da0a6..b71f5a631 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/creditcards/CreditCardEditorFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/creditcards/CreditCardEditorFragment.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.settings.creditcards +import android.annotation.SuppressLint import android.content.DialogInterface import android.os.Bundle import android.view.Menu @@ -56,6 +57,7 @@ class CreditCardEditorFragment : private lateinit var interactor: CreditCardEditorInteractor + @SuppressLint("ClickableViewAccessibility") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -81,10 +83,20 @@ class CreditCardEditorFragment : creditCardEditorView = CreditCardEditorView(binding, interactor) creditCardEditorView.bind(creditCardEditorState) - binding.cardNumberInput.apply { - requestFocus() - placeCursorAtEnd() - showKeyboard() + binding.apply { + cardNumberInput.apply { + requestFocus() + placeCursorAtEnd() + showKeyboard() + } + expiryMonthDropDown.setOnTouchListener { view, _ -> + view?.hideKeyboard() + false + } + expiryYearDropDown.setOnTouchListener { view, _ -> + view?.hideKeyboard() + false + } } } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteBrowsingDataFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteBrowsingDataFragment.kt index ca3068e1c..a35a3436c 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteBrowsingDataFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteBrowsingDataFragment.kt @@ -114,8 +114,8 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da updateItemCounts() } - private fun updateDeleteButton() { - val enabled = getCheckboxes().any { it.isChecked } + private fun updateDeleteButton(deleteInProgress: Boolean = false) { + val enabled = getCheckboxes().any { it.isChecked } && !deleteInProgress binding.deleteData.isEnabled = enabled binding.deleteData.alpha = if (enabled) ENABLED_ALPHA else DISABLED_ALPHA @@ -167,6 +167,7 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da } private fun startDeletion() { + updateDeleteButton(deleteInProgress = true) binding.progressBar.visibility = View.VISIBLE binding.deleteBrowsingDataWrapper.isEnabled = false binding.deleteBrowsingDataWrapper.isClickable = false @@ -174,6 +175,7 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da } private fun finishDeletion() { + updateDeleteButton(deleteInProgress = false) val popAfter = binding.openTabsItem.isChecked binding.progressBar.visibility = View.GONE binding.deleteBrowsingDataWrapper.isEnabled = true diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ConnectionDetailsController.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ConnectionDetailsController.kt index 94969e246..b29d60358 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ConnectionDetailsController.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ConnectionDetailsController.kt @@ -17,6 +17,7 @@ import mozilla.components.concept.engine.permission.SitePermissions import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.runIfFragmentIsAttached +import org.mozilla.fenix.ext.settings /** * [ConnectionDetailsController] controller. @@ -50,8 +51,11 @@ class DefaultConnectionDetailsController( getCurrentTab()?.let { tab -> context.components.useCases.trackingProtectionUseCases.containsException(tab.id) { contains -> ioScope.launch { - val hasException = + val hasException = if (context.settings().shouldUseCookieBanner) { cookieBannersStorage.hasException(tab.content.url, tab.content.private) + } else { + false + } withContext(Dispatchers.Main) { fragment.runIfFragmentIsAttached { navController().popBackStack() diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/ProtectionsView.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/ProtectionsView.kt index 175e60de8..e397e9dc5 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/ProtectionsView.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/ProtectionsView.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.settings.quicksettings.protections -import android.content.res.Configuration import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.VisibleForTesting @@ -24,10 +23,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.view.isVisible import org.mozilla.fenix.R +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.databinding.QuicksettingsProtectionsPanelBinding import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.trackingprotection.ProtectionsState @@ -168,8 +167,7 @@ private fun CookieBannerItem( } @Composable -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun CookieBannerItemPreview() { FirefoxTheme { Box(Modifier.background(FirefoxTheme.colors.layer1)) { diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerDetailsController.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerDetailsController.kt index 1da84b5a4..2d3b33886 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerDetailsController.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerDetailsController.kt @@ -5,6 +5,8 @@ package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners import android.content.Context +import androidx.annotation.VisibleForTesting +import androidx.core.net.toUri import androidx.fragment.app.Fragment import androidx.navigation.NavController import kotlinx.coroutines.CoroutineScope @@ -14,14 +16,17 @@ import kotlinx.coroutines.withContext import mozilla.components.browser.state.selector.findTabOrCustomTab import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.cookiehandling.CookieBannersStorage import mozilla.components.concept.engine.permission.SitePermissions import mozilla.components.feature.session.SessionUseCases +import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.service.glean.private.NoExtras import org.mozilla.fenix.GleanMetrics.CookieBanners import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.runIfFragmentIsAttached +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.trackingprotection.ProtectionsAction import org.mozilla.fenix.trackingprotection.ProtectionsStore @@ -60,14 +65,19 @@ class DefaultCookieBannerDetailsController( private val gravity: Int, private val getCurrentTab: () -> SessionState?, private val reload: SessionUseCases.ReloadUrlUseCase, + private val engine: Engine = context.components.core.engine, + private val publicSuffixList: PublicSuffixList = context.components.publicSuffixList, ) : CookieBannerDetailsController { override fun handleBackPressed() { getCurrentTab()?.let { tab -> context.components.useCases.trackingProtectionUseCases.containsException(tab.id) { contains -> ioScope.launch { - val hasException = + val hasException = if (context.settings().shouldUseCookieBanner) { cookieBannersStorage.hasException(tab.content.url, tab.content.private) + } else { + false + } withContext(Dispatchers.Main) { fragment.runIfFragmentIsAttached { navController().popBackStack() @@ -105,6 +115,7 @@ class DefaultCookieBannerDetailsController( ) CookieBanners.exceptionRemoved.record(NoExtras()) } else { + clearSiteData(tab) cookieBannersStorage.addException(uri = tab.content.url, privateBrowsing = tab.content.private) CookieBanners.exceptionAdded.record(NoExtras()) } @@ -116,4 +127,19 @@ class DefaultCookieBannerDetailsController( reload(tab.id) } } + + @VisibleForTesting + internal suspend fun clearSiteData(tab: SessionState) { + val host = tab.content.url.toUri().host.orEmpty() + val domain = publicSuffixList.getPublicSuffixPlusOne(host).await() + withContext(Dispatchers.Main) { + engine.clearData( + host = domain, + data = Engine.BrowsingData.select( + Engine.BrowsingData.AUTH_SESSIONS, + Engine.BrowsingData.ALL_SITE_DATA, + ), + ) + } + } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsView.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsView.kt index c73c777ec..c8e3dee69 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsView.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsView.kt @@ -8,6 +8,11 @@ import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.VisibleForTesting +import androidx.core.net.toUri +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.plus import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.support.ktx.kotlin.toShortUrl import org.mozilla.fenix.R @@ -24,6 +29,7 @@ import org.mozilla.fenix.trackingprotection.ProtectionsState class CookieBannerHandlingDetailsView( container: ViewGroup, private val context: Context, + private val ioScope: CoroutineScope, private val publicSuffixList: PublicSuffixList, val interactor: CookieBannerDetailsInteractor, ) { @@ -45,14 +51,22 @@ class CookieBannerHandlingDetailsView( @VisibleForTesting internal fun bindTitle(url: String, isCookieBannerHandlingEnabled: Boolean) { - val stringID = - if (isCookieBannerHandlingEnabled) { - R.string.reduce_cookie_banner_details_panel_title_off_for_site - } else { - R.string.reduce_cookie_banner_details_panel_title_on_for_site + ioScope.launch { + val host = url.toUri().host.orEmpty() + val domain = publicSuffixList.getPublicSuffixPlusOne(host).await() + + launch(Dispatchers.Main) { + val stringID = + if (isCookieBannerHandlingEnabled) { + R.string.reduce_cookie_banner_details_panel_title_off_for_site + } else { + R.string.reduce_cookie_banner_details_panel_title_on_for_site + } + val data = domain ?: url + val shortUrl = data.toShortUrl(publicSuffixList) + binding.title.text = context.getString(stringID, shortUrl) } - val shortUrl = url.toShortUrl(publicSuffixList) - binding.title.text = context.getString(stringID, shortUrl) + } } @VisibleForTesting @@ -61,9 +75,10 @@ class CookieBannerHandlingDetailsView( if (isCookieBannerHandlingEnabled) { R.string.reduce_cookie_banner_details_panel_description_off_for_site } else { - R.string.reduce_cookie_banner_details_panel_description_on_for_site + R.string.reduce_cookie_banner_details_panel_description_on_for_site_1 } - binding.details.text = context.getString(stringID, context.getString(R.string.app_name)) + val appName = context.getString(R.string.app_name) + binding.details.text = context.getString(stringID, appName) } @VisibleForTesting diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerPanelDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerPanelDialogFragment.kt index 4eb56ad19..84a2c7302 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerPanelDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerPanelDialogFragment.kt @@ -85,6 +85,7 @@ class CookieBannerPanelDialogFragment : FenixDialogFragment() { cookieBannersView = CookieBannerHandlingDetailsView( context = requireContext(), + ioScope = viewLifecycleOwner.lifecycleScope + Dispatchers.IO, container = binding.cookieBannerDetailsInfoLayout, publicSuffixList = requireComponents.publicSuffixList, interactor = DefaultCookieBannerDetailsInteractor(controller), diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialog.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialog.kt new file mode 100644 index 000000000..6df129811 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialog.kt @@ -0,0 +1,83 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.ui.platform.ComposeView +import androidx.fragment.app.DialogFragment +import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode.REJECT_ALL +import mozilla.components.concept.engine.Settings +import mozilla.telemetry.glean.private.NoExtras +import org.mozilla.fenix.GleanMetrics.CookieBanners +import org.mozilla.fenix.R +import org.mozilla.fenix.components.FenixSnackbar +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.getRootView +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.theme.FirefoxTheme + +/** + * Displays a cookie banner dialog fragment that contains the dialog compose and his logic. + */ +class CookieBannerReEngagementDialog : DialogFragment() { + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View = ComposeView(requireContext()).apply { + CookieBanners.visitedReEngagementDialog.record(NoExtras()) + + setContent { + FirefoxTheme { + val cookieBannerDialogSelectedVariant = + CookieBannerReEngagementDialogUtils.getCookieBannerDialogVariants(requireContext()) + CookieBannerReEngagementDialogCompose( + dialogTitle = cookieBannerDialogSelectedVariant.title, + dialogText = cookieBannerDialogSelectedVariant.message, + allowButtonText = cookieBannerDialogSelectedVariant.positiveTextButton, + declineButtonText = getString(R.string.reduce_cookie_banner_dialog_not_now_button), + onAllowButtonClicked = { + CookieBanners.allowReEngagementDialog.record(NoExtras()) + requireContext().settings().shouldUseCookieBanner = true + getEngineSettings().cookieBannerHandlingModePrivateBrowsing = REJECT_ALL + getEngineSettings().cookieBannerHandlingMode = REJECT_ALL + reload() + requireContext().getRootView()?.let { + FenixSnackbar.make( + view = it, + duration = FenixSnackbar.LENGTH_LONG, + isDisplayedWithBrowserToolbar = true, + ) + .setText(getString(R.string.reduce_cookie_banner_dialog_snackbar_text)) + .show() + } + dismiss() + }, + onNotNowButtonClicked = { + CookieBanners.notNowReEngagementDialog.record(NoExtras()) + dismiss() + }, + onCloseButtonClicked = { + requireContext().settings().userOptOutOfReEngageCookieBannerDialog = true + CookieBanners.optOutReEngagementDialog.record(NoExtras()) + dismiss() + }, + ) + } + } + } + + private fun getEngineSettings(): Settings { + return requireContext().components.core.engine.settings + } + + private fun reload() { + return requireContext().components.useCases.sessionUseCases.reload() + } +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialogCompose.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialogCompose.kt new file mode 100644 index 000000000..0b1e8e63e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialogCompose.kt @@ -0,0 +1,156 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog + +import android.content.res.Configuration.UI_MODE_NIGHT_NO +import android.content.res.Configuration.UI_MODE_NIGHT_YES +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import org.mozilla.fenix.R +import org.mozilla.fenix.theme.FirefoxTheme +import org.mozilla.fenix.theme.defaultTypography + +@Composable +@Preview(uiMode = UI_MODE_NIGHT_YES) +@Preview(uiMode = UI_MODE_NIGHT_NO) +private fun CookieBannerReEngagementDialogComposePreview() { + FirefoxTheme { + CookieBannerReEngagementDialogCompose( + dialogTitle = "Cookie banners begone!", + dialogText = + "Automatically reject cookie requests, when possible. Otherwise, " + + "accept all cookies to dismiss cookie banners.", + onAllowButtonClicked = {}, + onNotNowButtonClicked = {}, + onCloseButtonClicked = {}, + allowButtonText = "Dismiss banners", + declineButtonText = "NOT NOW", + ) + } +} + +/** + * Displays the cookie banner reducer dialog + */ +@Suppress("LongParameterList", "LongMethod") +@Composable +fun CookieBannerReEngagementDialogCompose( + dialogTitle: String, + dialogText: String, + allowButtonText: String, + declineButtonText: String, + onCloseButtonClicked: () -> Unit, + onAllowButtonClicked: () -> Unit, + onNotNowButtonClicked: () -> Unit, +) { + Dialog( + properties = DialogProperties(dismissOnBackPress = true, dismissOnClickOutside = false), + onDismissRequest = onNotNowButtonClicked, + ) { + Surface( + color = Color.Transparent, + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .clip(RoundedCornerShape(8.dp)) + .background(color = FirefoxTheme.colors.layer1), + ) { + Column { + Row( + modifier = Modifier + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + modifier = Modifier.padding( + top = 24.dp, + start = 24.dp, + end = 24.dp, + bottom = 8.dp, + ), + color = FirefoxTheme.colors.textPrimary, + text = dialogTitle, + style = defaultTypography.headline7, + ) + IconButton( + modifier = Modifier + .size(48.dp), + onClick = onCloseButtonClicked, + ) { + Icon( + painter = painterResource(R.drawable.mozac_ic_close), + contentDescription = stringResource(R.string.content_description_close_button), + tint = FirefoxTheme.colors.iconPrimary, + ) + } + } + Text( + modifier = Modifier.padding(horizontal = 24.dp), + color = FirefoxTheme.colors.textPrimary, + fontSize = 16.sp, + text = dialogText, + style = defaultTypography.body1, + ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(end = 24.dp, bottom = 12.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy( + space = 8.dp, + alignment = Alignment.End, + ), + ) { + TextButton( + onClick = onNotNowButtonClicked, + shape = MaterialTheme.shapes.large, + ) { + Text( + text = declineButtonText.uppercase(), + fontSize = 14.sp, + style = MaterialTheme.typography.button, + ) + } + TextButton( + onClick = onAllowButtonClicked, + shape = MaterialTheme.shapes.large, + ) { + Text( + text = allowButtonText.uppercase(), + fontSize = 14.sp, + style = MaterialTheme.typography.button, + ) + } + } + } + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialogUtils.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialogUtils.kt new file mode 100644 index 000000000..154b7eca8 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/dialog/CookieBannerReEngagementDialogUtils.kt @@ -0,0 +1,106 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog + +import android.content.Context +import androidx.navigation.NavController +import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingStatus +import org.mozilla.fenix.R +import org.mozilla.fenix.browser.BrowserFragmentDirections +import org.mozilla.fenix.ext.nav +import org.mozilla.fenix.nimbus.CookieBannersSection +import org.mozilla.fenix.nimbus.FxNimbus +import org.mozilla.fenix.utils.Settings + +private const val CONTROL_VARIANT = 0 +private const val VARIANT_ONE = 1 +private const val VARIANT_TWO = 2 + +/** + * An utility object for interacting with the re-engagement cookie banner dialog. + */ +object CookieBannerReEngagementDialogUtils { + /** + * Returns a the current [CookieBannerDialogVariant] to the given nimbus experiment. + */ + fun getCookieBannerDialogVariants(context: Context): CookieBannerDialogVariant { + val textVariant = + FxNimbus.features.cookieBanners.value().sectionsEnabled[CookieBannersSection.DIALOG_TEXT_VARIANT] + return when (textVariant) { + CONTROL_VARIANT -> CookieBannerDialogVariant( + title = context.getString(R.string.reduce_cookie_banner_control_experiment_dialog_title), + message = context.getString( + R.string.reduce_cookie_banner_control_experiment_dialog_body_1, + ), + positiveTextButton = context.getString( + R.string.reduce_cookie_banner_control_experiment_dialog_change_setting_button, + ), + ) + VARIANT_ONE -> CookieBannerDialogVariant( + title = context.getString(R.string.reduce_cookie_banner_variant_1_experiment_dialog_title), + message = context.getString( + R.string.reduce_cookie_banner_variant_1_experiment_dialog_body_1, + context.getString(R.string.app_name), + ), + positiveTextButton = context.getString( + R.string.reduce_cookie_banner_variant_1_experiment_dialog_change_setting_button, + ), + ) + VARIANT_TWO -> CookieBannerDialogVariant( + title = context.getString(R.string.reduce_cookie_banner_variant_2_experiment_dialog_title), + message = context.getString( + R.string.reduce_cookie_banner_variant_2_experiment_dialog_body_1, + context.getString(R.string.app_name), + ), + positiveTextButton = context.getString( + R.string.reduce_cookie_banner_variant_2_experiment_dialog_change_setting_button, + ), + ) + else -> { + CookieBannerDialogVariant( + title = context.getString(R.string.reduce_cookie_banner_control_experiment_dialog_title), + message = context.getString( + R.string.reduce_cookie_banner_control_experiment_dialog_body_1, + ), + positiveTextButton = context.getString( + R.string.reduce_cookie_banner_control_experiment_dialog_change_setting_button, + ), + ) + } + } + } + + /** + * Tries to show the re-engagement cookie banner dialog, when the right conditions are met, o + * otherwise the dialog won't show. + */ + fun tryToShowReEngagementDialog( + settings: Settings, + status: CookieBannerHandlingStatus, + navController: NavController, + ) { + if (status == CookieBannerHandlingStatus.DETECTED && + settings.shouldCookieBannerReEngagementDialog() + ) { + settings.lastInteractionWithReEngageCookieBannerDialogInMs = System.currentTimeMillis() + settings.cookieBannerDetectedPreviously = true + val directions = + BrowserFragmentDirections.actionBrowserFragmentToCookieBannerDialogFragment() + navController.nav(R.id.browserFragment, directions) + } + } + + /** + * Data class for cookie banner dialog variant + * @property title of the dialog + * @property message of the dialog + * @property positiveTextButton indicates the text of the positive button of the dialog + */ + data class CookieBannerDialogVariant( + val title: String, + val message: String, + val positiveTextButton: String, + ) +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/search/RadioSearchEngineListPreference.kt b/app/src/main/java/org/mozilla/fenix/settings/search/RadioSearchEngineListPreference.kt index 0d7de56af..25ee8e924 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/search/RadioSearchEngineListPreference.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/search/RadioSearchEngineListPreference.kt @@ -83,7 +83,7 @@ class RadioSearchEngineListPreference @JvmOverloads constructor( engine = engine, layoutInflater = layoutInflater, res = context.resources, - allowDeletion = state.searchEngines.size > 1, + allowDeletion = state.searchEngines.count { it.type != SearchEngine.Type.APPLICATION } > 1, isSelected = engine == state.selectedOrDefaultSearchEngine, ) diff --git a/app/src/main/java/org/mozilla/fenix/share/SaveToPDFItem.kt b/app/src/main/java/org/mozilla/fenix/share/SaveToPDFItem.kt index 728a4d627..3d59c6931 100644 --- a/app/src/main/java/org/mozilla/fenix/share/SaveToPDFItem.kt +++ b/app/src/main/java/org/mozilla/fenix/share/SaveToPDFItem.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.share -import android.content.res.Configuration import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -21,6 +20,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.mozilla.fenix.R +import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme /** @@ -61,8 +61,7 @@ fun SaveToPDFItem( @Composable @Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) +@LightDarkPreview private fun SaveToPDFItemPreview() { FirefoxTheme { SaveToPDFItem {} diff --git a/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt b/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt index 0574448ac..e33ca0097 100644 --- a/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt @@ -31,6 +31,7 @@ import org.mozilla.fenix.databinding.FragmentShareBinding import org.mozilla.fenix.ext.getRootView import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.theme.FirefoxTheme +import org.mozilla.fenix.theme.Theme class ShareFragment : AppCompatDialogFragment() { @@ -122,7 +123,7 @@ class ShareFragment : AppCompatDialogFragment() { isVisible = true setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { - FirefoxTheme { + FirefoxTheme(theme = Theme.getTheme(allowPrivateTheme = false)) { SaveToPDFItem { shareInteractor.onSaveToPDF(tabId = args.sessionId) } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/FloatingActionButtonBinding.kt b/app/src/main/java/org/mozilla/fenix/tabstray/FloatingActionButtonBinding.kt index f4d5a5209..2ea7f3111 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/FloatingActionButtonBinding.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/FloatingActionButtonBinding.kt @@ -7,7 +7,6 @@ package org.mozilla.fenix.tabstray import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.map import mozilla.components.lib.state.helpers.AbstractBinding import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged @@ -21,7 +20,7 @@ import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor class FloatingActionButtonBinding( private val store: TabsTrayStore, private val actionButton: ExtendedFloatingActionButton, - private val browserTrayInteractor: BrowserTrayInteractor, + private val interactor: BrowserTrayInteractor, ) : AbstractBinding(store) { override suspend fun onState(flow: Flow) { @@ -46,7 +45,7 @@ class FloatingActionButtonBinding( contentDescription = context.getString(R.string.add_tab) setIconResource(R.drawable.ic_new) setOnClickListener { - browserTrayInteractor.onFabClicked(false) + interactor.onFabClicked(false) } } } @@ -58,7 +57,7 @@ class FloatingActionButtonBinding( contentDescription = context.getString(R.string.add_private_tab) setIconResource(R.drawable.ic_new) setOnClickListener { - browserTrayInteractor.onFabClicked(true) + interactor.onFabClicked(true) } } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt index 51538d9c0..79f6b27a7 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt @@ -15,11 +15,9 @@ import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.prompt.ShareData import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.glean.private.NoExtras -import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.GleanMetrics.Collections import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.TabsTray -import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.collections.CollectionsDialog import org.mozilla.fenix.collections.show import org.mozilla.fenix.components.TabCollectionStorage @@ -28,7 +26,6 @@ import org.mozilla.fenix.home.HomeFragment import org.mozilla.fenix.tabstray.ext.getTabSessionState import org.mozilla.fenix.tabstray.ext.isActiveDownload import kotlin.coroutines.CoroutineContext -import mozilla.components.browser.storage.sync.Tab as SyncTab /** * An interactor that helps with navigating to different parts of the app from the tabs tray. @@ -85,11 +82,6 @@ interface NavigationInteractor { * Used when adding [TabSessionState]s as bookmarks. */ fun onSaveToBookmarks(tabs: Collection) - - /** - * Called when clicking on a SyncedTab item. - */ - fun onSyncedTabClicked(tab: SyncTab) } /** @@ -98,7 +90,6 @@ interface NavigationInteractor { @Suppress("LongParameterList", "TooManyFunctions") class DefaultNavigationInteractor( private val context: Context, - private val activity: HomeActivity, private val browserStore: BrowserStore, private val navController: NavController, private val dismissTabTray: () -> Unit, @@ -244,15 +235,4 @@ class DefaultNavigationInteractor( showBookmarkSnackbar(tabs.size) } - - override fun onSyncedTabClicked(tab: SyncTab) { - Events.syncedTabOpened.record(NoExtras()) - - dismissTabTray() - activity.openToBrowserAndLoad( - searchTermOrURL = tab.active().url, - newTab = true, - from = BrowserDirection.FromTabsTray, - ) - } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsController.kt b/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsController.kt new file mode 100644 index 000000000..27336f634 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsController.kt @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.tabstray + +import mozilla.components.browser.storage.sync.Tab + +/** + * Controller for handling any actions on synced tabs in the tabs tray. + */ +interface SyncedTabsController { + /** + * Handles a synced tab item click. + * + * @param tab The synced [Tab] that was clicked. + */ + fun handleSyncedTabClicked(tab: Tab) +} diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsInteractor.kt new file mode 100644 index 000000000..153a0f48d --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsInteractor.kt @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.tabstray + +import mozilla.components.browser.storage.sync.Tab + +/** + * Interactor for responding to any actions on synced tabs in the tabs tray. + */ +interface SyncedTabsInteractor { + /** + * Invoked when the user clicks on a synced [Tab]. + * + * @param tab The synced [Tab] that was clicked. + */ + fun onSyncedTabClicked(tab: Tab) +} diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt index 56a61f095..31cefa7e6 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt @@ -10,16 +10,20 @@ import mozilla.components.browser.state.action.DebugAction import mozilla.components.browser.state.action.LastAccessAction import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.selector.getNormalOrPrivateTabs +import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.browser.storage.sync.Tab import mozilla.components.concept.base.profiler.Profiler import mozilla.components.concept.engine.mediasession.MediaSession.PlaybackState import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.lib.state.DelicateAction import mozilla.telemetry.glean.private.NoExtras -import org.mozilla.fenix.GleanMetrics.Tab +import org.mozilla.fenix.BrowserDirection +import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.TabsTray +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager @@ -28,8 +32,12 @@ import org.mozilla.fenix.ext.DEFAULT_ACTIVE_DAYS import org.mozilla.fenix.home.HomeFragment import org.mozilla.fenix.tabstray.ext.isActiveDownload import java.util.concurrent.TimeUnit +import org.mozilla.fenix.GleanMetrics.Tab as GleanTab -interface TabsTrayController { +/** + * Controller for handling any actions in the tabs tray. + */ +interface TabsTrayController : SyncedTabsController { /** * Called to open a new tab. @@ -107,8 +115,25 @@ interface TabsTrayController { fun handleMediaClicked(tab: SessionState) } +/** + * Default implementation of [TabsTrayController]. + * + * @property activity [HomeActivity] used to perform top-level app actions. + * @property trayStore [TabsTrayStore] used to read/update the [TabsTrayState]. + * @property browserStore [BrowserStore] used to read/update the current [BrowserState]. + * @property browsingModeManager [BrowsingModeManager] used to read/update the current [BrowsingMode]. + * @property navController [NavController] used to navigate away from the tabs tray. + * @property navigateToHomeAndDeleteSession Lambda used to return to the Homescreen and delete the current session. + * @property navigationInteractor [NavigationInteractor] used to perform navigation actions with side effects. + * @property tabsUseCases Use case wrapper for interacting with tabs. + * @property selectTabPosition Lambda used to scroll the tabs tray to the desired position. + * @property dismissTray Lambda used to dismiss/minimize the tabs tray. + * @property showUndoSnackbarForTab Lambda used to display an UNDO Snackbar. + * @property showCancelledDownloadWarning Lambda used to display a cancelled download warning. + */ @Suppress("TooManyFunctions", "LongParameterList") class DefaultTabsTrayController( + private val activity: HomeActivity, private val trayStore: TabsTrayStore, private val browserStore: BrowserStore, private val browsingModeManager: BrowsingModeManager, @@ -121,7 +146,6 @@ class DefaultTabsTrayController( private val dismissTray: () -> Unit, private val showUndoSnackbarForTab: (Boolean) -> Unit, internal val showCancelledDownloadWarning: (downloadCount: Int, tabId: String?, source: String?) -> Unit, - ) : TabsTrayController { override fun handleOpeningNewTab(isPrivate: Boolean) { @@ -279,12 +303,12 @@ class DefaultTabsTrayController( override fun handleMediaClicked(tab: SessionState) { when (tab.mediaSessionState?.playbackState) { PlaybackState.PLAYING -> { - Tab.mediaPause.record(NoExtras()) + GleanTab.mediaPause.record(NoExtras()) tab.mediaSessionState?.controller?.pause() } PlaybackState.PAUSED -> { - Tab.mediaPlay.record(NoExtras()) + GleanTab.mediaPlay.record(NoExtras()) tab.mediaSessionState?.controller?.play() } else -> throw AssertionError( @@ -292,4 +316,15 @@ class DefaultTabsTrayController( ) } } + + override fun handleSyncedTabClicked(tab: Tab) { + Events.syncedTabOpened.record(NoExtras()) + + dismissTray() + activity.openToBrowserAndLoad( + searchTermOrURL = tab.active().url, + newTab = true, + from = BrowserDirection.FromTabsTray, + ) + } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt index 2730893f8..262f51a8d 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt @@ -197,7 +197,6 @@ class TabsTrayFragment : AppCompatDialogFragment() { navigationInteractor = DefaultNavigationInteractor( context = requireContext(), - activity = activity, tabsTrayStore = tabsTrayStore, browserStore = requireComponents.core.store, navController = findNavController(), @@ -213,6 +212,7 @@ class TabsTrayFragment : AppCompatDialogFragment() { ) tabsTrayController = DefaultTabsTrayController( + activity = activity, trayStore = tabsTrayStore, browserStore = requireComponents.core.store, browsingModeManager = activity.browsingModeManager, @@ -332,7 +332,7 @@ class TabsTrayFragment : AppCompatDialogFragment() { feature = FloatingActionButtonBinding( store = tabsTrayStore, actionButton = fabButtonBinding.newTabButton, - browserTrayInteractor = browserTrayInteractor, + interactor = browserTrayInteractor, ), owner = this, view = view, diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt index a5721ecce..a51aaa439 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt @@ -5,8 +5,12 @@ package org.mozilla.fenix.tabstray import mozilla.components.browser.state.state.TabSessionState +import mozilla.components.browser.storage.sync.Tab -interface TabsTrayInteractor { +/** + * Interactor for responding to all user actions in the tabs tray. + */ +interface TabsTrayInteractor : SyncedTabsInteractor { /** * Set the current tray item to the clamped [position]. * @@ -53,7 +57,7 @@ interface TabsTrayInteractor { } /** - * Interactor to be called for any tabs tray user actions. + * Default implementation of [TabsTrayInteractor]. * * @property controller [TabsTrayController] to which user actions can be delegated for actual app update. */ @@ -91,4 +95,8 @@ class DefaultTabsTrayInteractor( override fun onInactiveDebugClicked(tabs: Collection) { controller.forceTabsAsInactive(tabs) } + + override fun onSyncedTabClicked(tab: Tab) { + controller.handleSyncedTabClicked(tab) + } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TrayPagerAdapter.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TrayPagerAdapter.kt index f61f05d6a..5d28ff074 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TrayPagerAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TrayPagerAdapter.kt @@ -91,7 +91,7 @@ class TrayPagerAdapter( ) }, tabsTrayStore = tabsTrayStore, - navigationInteractor = navInteractor, + interactor = tabsTrayInteractor, ) } else -> throw IllegalStateException("Unknown viewType.") diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolder.kt index ed5d0ca4e..07449ad93 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolder.kt @@ -73,7 +73,7 @@ abstract class AbstractBrowserTabViewHolder( internal val urlView: TextView? = itemView.findViewById(R.id.mozac_browser_tabstray_url) private val playPauseButtonView: ImageButton = itemView.findViewById(R.id.play_pause_button) - abstract val browserTrayInteractor: BrowserTrayInteractor + abstract val interactor: BrowserTrayInteractor abstract val thumbnailSize: Int override var tab: TabSessionState? = null @@ -102,10 +102,10 @@ abstract class AbstractBrowserTabViewHolder( updateMediaState(tab) if (selectionHolder != null) { - setSelectionInteractor(tab, selectionHolder, browserTrayInteractor) + setSelectionInteractor(tab, selectionHolder, interactor) } else { itemView.setOnClickListener { - browserTrayInteractor.onTabSelected(tab, featureName) + interactor.onTabSelected(tab, featureName) } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabViewHolder.kt index d2cf75591..7c412ae28 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabViewHolder.kt @@ -25,7 +25,7 @@ sealed class BrowserTabViewHolder(itemView: View) : RecyclerView.ViewHolder(item * A RecyclerView ViewHolder implementation for "tab" items with grid layout. * * @param imageLoader [ImageLoader] used to load tab thumbnails. - * @param browserTrayInteractor [BrowserTrayInteractor] handling tabs interactions in a tab tray. + * @param interactor [BrowserTrayInteractor] handling tabs interactions in a tab tray. * @param store [TabsTrayStore] containing the complete state of tabs tray and methods to update that. * @param selectionHolder [SelectionHolder]<[TabSessionState]> for helping with selecting * any number of displayed [TabSessionState]s. @@ -34,7 +34,7 @@ sealed class BrowserTabViewHolder(itemView: View) : RecyclerView.ViewHolder(item */ class GridViewHolder( imageLoader: ImageLoader, - override val browserTrayInteractor: BrowserTrayInteractor, + override val interactor: BrowserTrayInteractor, store: TabsTrayStore, selectionHolder: SelectionHolder? = null, itemView: View, @@ -79,7 +79,7 @@ sealed class BrowserTabViewHolder(itemView: View) : RecyclerView.ViewHolder(item * A RecyclerView ViewHolder implementation for "tab" items with list layout. * * @param imageLoader [ImageLoader] used to load tab thumbnails. - * @param browserTrayInteractor [BrowserTrayInteractor] handling tabs interactions in a tab tray. + * @param interactor [BrowserTrayInteractor] handling tabs interactions in a tab tray. * @param store [TabsTrayStore] containing the complete state of tabs tray and methods to update that. * @param selectionHolder [SelectionHolder]<[TabSessionState]> for helping with selecting * any number of displayed [TabSessionState]s. @@ -88,7 +88,7 @@ sealed class BrowserTabViewHolder(itemView: View) : RecyclerView.ViewHolder(item */ class ListViewHolder( imageLoader: ImageLoader, - override val browserTrayInteractor: BrowserTrayInteractor, + override val interactor: BrowserTrayInteractor, store: TabsTrayStore, selectionHolder: SelectionHolder? = null, itemView: View, diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt index 8e5464bdb..e8c96761e 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt @@ -19,7 +19,6 @@ import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.components import org.mozilla.fenix.compose.ComposeViewHolder import org.mozilla.fenix.tabstray.TabsTrayFragment -import org.mozilla.fenix.tabstray.TabsTrayInteractor import org.mozilla.fenix.tabstray.TabsTrayState import org.mozilla.fenix.tabstray.TabsTrayStore import org.mozilla.fenix.tabstray.TrayPagerAdapter @@ -32,8 +31,7 @@ import org.mozilla.fenix.GleanMetrics.TabsTray as TabsTrayMetrics * @param composeView [ComposeView] which will be populated with Jetpack Compose UI content. * @param lifecycleOwner [LifecycleOwner] to which this Composable will be tied to. * @param tabsTrayStore [TabsTrayStore] used to listen for changes to [TabsTrayState.inactiveTabs]. - * @param tabsTrayInteractor [TabsTrayInteractor] used to handle deleting all inactive tabs. - * @param inactiveTabsInteractor [InactiveTabsInteractor] used to respond to interactions with the inactive tabs header + * @param interactor [InactiveTabsInteractor] used to respond to interactions with the inactive tabs header * and the auto close dialog. */ @Suppress("LongParameterList") @@ -41,7 +39,7 @@ class InactiveTabViewHolder( composeView: ComposeView, lifecycleOwner: LifecycleOwner, private val tabsTrayStore: TabsTrayStore, - private val inactiveTabsInteractor: InactiveTabsInteractor, + private val interactor: InactiveTabsInteractor, ) : ComposeViewHolder(composeView, lifecycleOwner) { @Composable @@ -63,19 +61,19 @@ class InactiveTabViewHolder( inactiveTabs = inactiveTabs, expanded = expanded, showAutoCloseDialog = showAutoClosePrompt, - onHeaderClick = { inactiveTabsInteractor.onHeaderClicked(!expanded) }, - onDeleteAllButtonClick = inactiveTabsInteractor::onDeleteAllInactiveTabsClicked, + onHeaderClick = { interactor.onInactiveTabsHeaderClicked(!expanded) }, + onDeleteAllButtonClick = interactor::onDeleteAllInactiveTabsClicked, onAutoCloseDismissClick = { - inactiveTabsInteractor.onCloseClicked() + interactor.onAutoCloseDialogCloseButtonClicked() showAutoClosePrompt = !showAutoClosePrompt }, onEnableAutoCloseClick = { - inactiveTabsInteractor.onEnabledAutoCloseClicked() + interactor.onEnableAutoCloseClicked() showAutoClosePrompt = !showAutoClosePrompt showConfirmationSnackbar() }, - onTabClick = inactiveTabsInteractor::onTabClicked, - onTabCloseClick = inactiveTabsInteractor::onTabClosed, + onTabClick = interactor::onInactiveTabClicked, + onTabCloseClick = interactor::onInactiveTabClosed, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt index 2fbae6769..f731f7903 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt @@ -35,7 +35,7 @@ class InactiveTabsAdapter( composeView = ComposeView(parent.context), lifecycleOwner = lifecycleOwner, tabsTrayStore = tabsTrayStore, - inactiveTabsInteractor = inactiveTabsInteractor, + interactor = inactiveTabsInteractor, ) } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt index 5c64d5568..f92064eb9 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt @@ -21,35 +21,40 @@ import org.mozilla.fenix.GleanMetrics.TabsTray as TabsTrayMetrics interface InactiveTabsController { /** - * Opens the given inactive tab. + * Opens the provided inactive tab. + * + * @param tab [TabSessionState] that was clicked. */ - fun openInactiveTab(tab: TabSessionState) + fun handleInactiveTabClicked(tab: TabSessionState) /** - * Closes the given inactive tab. + * Closes the provided inactive tab. + * + * @param tab [TabSessionState] that was clicked. */ - fun closeInactiveTab(tab: TabSessionState) + fun handleCloseInactiveTabClicked(tab: TabSessionState) /** - * Updates the inactive card to be expanded to display all the tabs, or collapsed with only - * the title showing. + * Expands or collapses the inactive tabs section. + * + * @param expanded true when the tap should expand the inactive section. */ - fun updateCardExpansion(isExpanded: Boolean) + fun handleInactiveTabsHeaderClicked(expanded: Boolean) /** - * Dismiss the auto-close dialog. + * Dismisses the inactive tabs auto-close dialog. */ - fun dismissAutoCloseDialog() + fun handleInactiveTabsAutoCloseDialogDismiss() /** - * Enable the auto-close feature with the "after a month" setting. + * Enables the inactive tabs auto-close feature with a default time period. */ - fun enableInactiveTabsAutoClose() + fun handleEnableInactiveTabsAutoCloseClicked() /** - * Delete all inactive tabs. + * Deletes all inactive tabs. */ - fun deleteAllInactiveTabs() + fun handleDeleteAllInactiveTabsClicked() } /** @@ -69,29 +74,29 @@ class DefaultInactiveTabsController( private val showUndoSnackbar: (Boolean) -> Unit, ) : InactiveTabsController { - override fun openInactiveTab(tab: TabSessionState) { + override fun handleInactiveTabClicked(tab: TabSessionState) { TabsTrayMetrics.openInactiveTab.add() } - override fun closeInactiveTab(tab: TabSessionState) { + override fun handleCloseInactiveTabClicked(tab: TabSessionState) { TabsTrayMetrics.closeInactiveTab.add() } - override fun updateCardExpansion(isExpanded: Boolean) { - appStore.dispatch(UpdateInactiveExpanded(isExpanded)) + override fun handleInactiveTabsHeaderClicked(expanded: Boolean) { + appStore.dispatch(UpdateInactiveExpanded(expanded)) - when (isExpanded) { + when (expanded) { true -> TabsTrayMetrics.inactiveTabsExpanded.record(NoExtras()) false -> TabsTrayMetrics.inactiveTabsCollapsed.record(NoExtras()) } } - override fun dismissAutoCloseDialog() { + override fun handleInactiveTabsAutoCloseDialogDismiss() { markDialogAsShown() TabsTrayMetrics.autoCloseDimissed.record(NoExtras()) } - override fun enableInactiveTabsAutoClose() { + override fun handleEnableInactiveTabsAutoCloseClicked() { markDialogAsShown() settings.closeTabsAfterOneMonth = true settings.closeTabsAfterOneWeek = false @@ -100,7 +105,7 @@ class DefaultInactiveTabsController( TabsTrayMetrics.autoCloseTurnOnClicked.record(NoExtras()) } - override fun deleteAllInactiveTabs() { + override fun handleDeleteAllInactiveTabsClicked() { TabsTrayMetrics.closeAllInactiveTabs.record(NoExtras()) browserStore.state.potentialInactiveTabs.map { it.id }.let { tabsUseCases.removeTabs(it) diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt index b92cc82e2..e22548e9c 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt @@ -10,55 +10,51 @@ import org.mozilla.fenix.tabstray.TrayPagerAdapter /** * Interactor for all things related to inactive tabs in the tabs tray. */ -interface InactiveTabsInteractor : InactiveTabsAutoCloseDialogInteractor { +interface InactiveTabsInteractor { /** - * Invoked when the header is clicked. + * Invoked when the inactive tabs header is clicked. * - * @param activated true when the tap should expand the inactive section. + * @param expanded true when the tap should expand the inactive section. */ - fun onHeaderClicked(activated: Boolean) + fun onInactiveTabsHeaderClicked(expanded: Boolean) /** * Invoked when an inactive tab is clicked. * * @param tab [TabSessionState] that was clicked. */ - fun onTabClicked(tab: TabSessionState) + fun onInactiveTabClicked(tab: TabSessionState) /** * Invoked when an inactive tab is closed. * * @param tab [TabSessionState] that was closed. */ - fun onTabClosed(tab: TabSessionState) + fun onInactiveTabClosed(tab: TabSessionState) /** * Invoked when the user clicks on the delete all inactive tabs button. */ fun onDeleteAllInactiveTabsClicked() -} - -/** - * Interactor for the auto-close dialog in the inactive tabs section. - */ -interface InactiveTabsAutoCloseDialogInteractor { /** - * Invoked when the close button is clicked. + * Invoked when the user clicks the close button in the auto close dialog. */ - fun onCloseClicked() + fun onAutoCloseDialogCloseButtonClicked() /** - * Invoked when the dialog is clicked. + * Invoked when the user clicks to enable the inactive tab auto-close feature. */ - fun onEnabledAutoCloseClicked() + fun onEnableAutoCloseClicked() } /** * Interactor to be called for any user interactions with the Inactive Tabs feature. * - * @param controller [InactiveTabsController] todo. - * @param browserInteractor [BrowserTrayInteractor] used to respond to interactions with specific inactive tabs. + * @param controller An instance of [InactiveTabsController] which will be delegated for all + * user interactions. + * @param browserInteractor [BrowserTrayInteractor] used to respond to interactions with specific + * inactive tabs. */ class DefaultInactiveTabsInteractor( private val controller: InactiveTabsController, @@ -66,39 +62,39 @@ class DefaultInactiveTabsInteractor( ) : InactiveTabsInteractor { /** - * See [InactiveTabsInteractor.onHeaderClicked]. + * See [InactiveTabsInteractor.onInactiveTabsHeaderClicked]. */ - override fun onHeaderClicked(activated: Boolean) { - controller.updateCardExpansion(activated) + override fun onInactiveTabsHeaderClicked(expanded: Boolean) { + controller.handleInactiveTabsHeaderClicked(expanded) } /** - * See [InactiveTabsAutoCloseDialogInteractor.onCloseClicked]. + * See [InactiveTabsInteractor.onAutoCloseDialogCloseButtonClicked]. */ - override fun onCloseClicked() { - controller.dismissAutoCloseDialog() + override fun onAutoCloseDialogCloseButtonClicked() { + controller.handleInactiveTabsAutoCloseDialogDismiss() } /** - * See [InactiveTabsAutoCloseDialogInteractor.onEnabledAutoCloseClicked]. + * See [InactiveTabsInteractor.onEnableAutoCloseClicked]. */ - override fun onEnabledAutoCloseClicked() { - controller.enableInactiveTabsAutoClose() + override fun onEnableAutoCloseClicked() { + controller.handleEnableInactiveTabsAutoCloseClicked() } /** - * See [InactiveTabsInteractor.onTabClicked]. + * See [InactiveTabsInteractor.onInactiveTabClicked]. */ - override fun onTabClicked(tab: TabSessionState) { - controller.openInactiveTab(tab) + override fun onInactiveTabClicked(tab: TabSessionState) { + controller.handleInactiveTabClicked(tab) browserInteractor.onTabSelected(tab, TrayPagerAdapter.INACTIVE_TABS_FEATURE_NAME) } /** - * See [InactiveTabsInteractor.onTabClosed]. + * See [InactiveTabsInteractor.onInactiveTabClosed]. */ - override fun onTabClosed(tab: TabSessionState) { - controller.closeInactiveTab(tab) + override fun onInactiveTabClosed(tab: TabSessionState) { + controller.handleCloseInactiveTabClicked(tab) browserInteractor.onTabClosed(tab, TrayPagerAdapter.INACTIVE_TABS_FEATURE_NAME) } @@ -106,6 +102,6 @@ class DefaultInactiveTabsInteractor( * See [InactiveTabsInteractor.onDeleteAllInactiveTabsClicked]. */ override fun onDeleteAllInactiveTabsClicked() { - controller.deleteAllInactiveTabs() + controller.handleDeleteAllInactiveTabsClicked() } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt index c0e7bf5cf..27fdcfcf1 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.platform.ComposeView import androidx.recyclerview.widget.RecyclerView import mozilla.components.lib.state.ext.observeAsComposableState import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.tabstray.NavigationInteractor +import org.mozilla.fenix.tabstray.SyncedTabsInteractor import org.mozilla.fenix.tabstray.TabsTrayState import org.mozilla.fenix.tabstray.TabsTrayStore import org.mozilla.fenix.tabstray.syncedtabs.SyncedTabsList @@ -21,12 +21,12 @@ import org.mozilla.fenix.theme.Theme * * @param composeView Root ComposeView passed-in from TrayPagerAdapter. * @param tabsTrayStore Store used as a Composable State to listen for changes to [TabsTrayState.syncedTabs]. - * @param navigationInteractor The lambda for handling clicks on synced tabs. + * @param interactor [SyncedTabsInteractor] used to respond to interactions with synced tabs. */ class SyncedTabsPageViewHolder( private val composeView: ComposeView, private val tabsTrayStore: TabsTrayStore, - private val navigationInteractor: NavigationInteractor, + private val interactor: SyncedTabsInteractor, ) : AbstractPageViewHolder(composeView) { fun bind() { @@ -36,7 +36,7 @@ class SyncedTabsPageViewHolder( SyncedTabsList( syncedTabs = tabs ?: emptyList(), taskContinuityEnabled = composeView.context.settings().enableTaskContinuityEnhancements, - onTabClick = navigationInteractor::onSyncedTabClicked, + onTabClick = interactor::onSyncedTabClicked, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractor.kt b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractor.kt index 3fae2c02d..daf8f7dd8 100644 --- a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractor.kt @@ -17,6 +17,7 @@ import mozilla.components.concept.engine.permission.SitePermissions import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.runIfFragmentIsAttached +import org.mozilla.fenix.ext.settings /** * Interactor for the tracking protection panel @@ -53,8 +54,11 @@ class TrackingProtectionPanelInteractor( getCurrentTab()?.let { tab -> context.components.useCases.trackingProtectionUseCases.containsException(tab.id) { contains -> ioScope.launch { - val hasException = + val hasException = if (context.settings().shouldUseCookieBanner) { cookieBannersStorage.hasException(tab.content.url, tab.content.private) + } else { + false + } withContext(Dispatchers.Main) { fragment.runIfFragmentIsAttached { navController().popBackStack() diff --git a/app/src/main/java/org/mozilla/fenix/utils/ManufacturerCodes.kt b/app/src/main/java/org/mozilla/fenix/utils/ManufacturerCodes.kt deleted file mode 100644 index b1800fc87..000000000 --- a/app/src/main/java/org/mozilla/fenix/utils/ManufacturerCodes.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.utils - -import android.os.Build - -/** - * A listing of codes returned by [android.os.Build.MANUFACTURER] for different manufacturers. - * While we try to get the casing accurate, it may be good to use .equals(str, ignoreCase = true) - * to do the comparison. - */ -object ManufacturerCodes { - const val HUAWEI: String = "HUAWEI" - private const val LG = "LGE" - const val ONE_PLUS: String = "OnePlus" - private const val SAMSUNG = "samsung" - - val isLG get() = Build.MANUFACTURER.equals(LG, ignoreCase = true) - val isSamsung get() = Build.MANUFACTURER.equals(SAMSUNG, ignoreCase = true) - val isHuawei get() = Build.MANUFACTURER.equals(HUAWEI, ignoreCase = true) -} diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index d0c884794..4dd7aca57 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -544,11 +544,51 @@ class Settings(private val appContext: Context) : PreferencesHolder { var shouldUseCookieBanner by lazyFeatureFlagPreference( appContext.getPreferenceKey(R.string.pref_key_cookie_banner_v1), featureFlag = true, - default = { cookieBannersSection[CookieBannersSection.FEATURE_SETTING_VALUE] == true }, + default = { cookieBannersSection[CookieBannersSection.FEATURE_SETTING_VALUE] == 1 }, + ) + + var userOptOutOfReEngageCookieBannerDialog by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_cookie_banner_re_engage_dialog_dismissed), + default = false, + ) + + var lastInteractionWithReEngageCookieBannerDialogInMs by longPreference( + appContext.getPreferenceKey( + R.string.pref_key_cookie_banner_re_engage_dialog_last_interaction_in_ms, + ), + default = 0L, + ) + + var cookieBannerDetectedPreviously by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_cookie_banner_first_banner_detected), + default = false, ) val shouldShowCookieBannerUI: Boolean - get() = cookieBannersSection[CookieBannersSection.FEATURE_UI] == true + get() = cookieBannersSection[CookieBannersSection.FEATURE_UI] == 1 + + /** + * Indicates after how many hours a cookie banner dialog should be shown again + */ + @VisibleForTesting + internal val timerForCookieBannerDialog: Long + get() = 60 * 60 * 1000L * + (cookieBannersSection[CookieBannersSection.DIALOG_RE_ENGAGE_TIME] ?: 4) + + /** + * Indicates if we should should show the cookie banner dialog that invites the user to turn-on + * the setting. + */ + fun shouldCookieBannerReEngagementDialog(): Boolean { + val shouldShowDialog = + shouldShowCookieBannerUI && !userOptOutOfReEngageCookieBannerDialog && !shouldUseCookieBanner + return if (!shouldShowTotalCookieProtectionCFR && shouldShowDialog) { + !cookieBannerDetectedPreviously || + timeNowInMillis() - lastInteractionWithReEngageCookieBannerDialogInMs >= timerForCookieBannerDialog + } else { + false + } + } /** * Declared as a function for performance purposes. This could be declared as a variable using @@ -1318,7 +1358,7 @@ class Settings(private val appContext: Context) : PreferencesHolder { get() = FxNimbus.features.mr2022.value().sectionsEnabled - private val cookieBannersSection: Map + private val cookieBannersSection: Map get() = FxNimbus.features.cookieBanners.value().sectionsEnabled @@ -1464,6 +1504,23 @@ class Settings(private val appContext: Context) : PreferencesHolder { default = setOf(), ) + /** + * Indicates if notification pre permission prompt feature is enabled. + */ + var notificationPrePermissionPromptEnabled by lazyFeatureFlagPreference( + key = appContext.getPreferenceKey(R.string.pref_key_notification_pre_permission_prompt_enabled), + default = { FxNimbus.features.prePermissionNotificationPrompt.value(appContext).enabled }, + featureFlag = FeatureFlags.notificationPrePermissionPromptEnabled, + ) + + /** + * Indicates if notification permission prompt has been shown to the user. + */ + var isNotificationPrePermissionShown by booleanPreference( + key = appContext.getPreferenceKey(R.string.pref_key_is_notification_pre_permission_prompt_shown), + default = false, + ) + /** * Get the current mode for how https-only is enabled. */ @@ -1482,8 +1539,12 @@ class Settings(private val appContext: Context) : PreferencesHolder { */ fun getCookieBannerHandling(): CookieBannerHandlingMode { return when (shouldUseCookieBanner) { - true -> CookieBannerHandlingMode.REJECT_OR_ACCEPT_ALL - false -> CookieBannerHandlingMode.DISABLED + true -> CookieBannerHandlingMode.REJECT_ALL + false -> if (shouldShowCookieBannerUI && !userOptOutOfReEngageCookieBannerDialog) { + CookieBannerHandlingMode.DETECT_ONLY + } else { + CookieBannerHandlingMode.DISABLED + } } } @@ -1506,4 +1567,24 @@ class Settings(private val appContext: Context) : PreferencesHolder { key = appContext.getPreferenceKey(R.string.pref_key_growth_ad_click_sent), default = false, ) + + var usageTimeGrowthData by longPreference( + key = appContext.getPreferenceKey(R.string.pref_key_growth_usage_time), + default = -1, + ) + + var usageTimeGrowthSent by booleanPreference( + key = appContext.getPreferenceKey(R.string.pref_key_growth_usage_time_sent), + default = false, + ) + + var resumeGrowthLastSent by longPreference( + key = appContext.getPreferenceKey(R.string.pref_key_growth_resume_last_sent), + default = 0, + ) + + var uriLoadGrowthLastSent by longPreference( + key = appContext.getPreferenceKey(R.string.pref_key_growth_uri_load_last_sent), + default = 0, + ) } diff --git a/app/src/main/res/drawable/ic_launcher_monochrome.xml b/app/src/main/res/drawable/ic_launcher_monochrome.xml new file mode 100644 index 000000000..764616943 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_monochrome.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_notification_permission.xml b/app/src/main/res/drawable/ic_notification_permission.xml new file mode 100644 index 000000000..d905cc570 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_permission.xml @@ -0,0 +1,542 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/preference_switch_learn_more.xml b/app/src/main/res/layout/preference_switch_learn_more.xml new file mode 100644 index 000000000..c43c3d1e1 --- /dev/null +++ b/app/src/main/res/layout/preference_switch_learn_more.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/settings_studies.xml b/app/src/main/res/layout/settings_studies.xml index 63877c4d7..c9314e935 100644 --- a/app/src/main/res/layout/settings_studies.xml +++ b/app/src/main/res/layout/settings_studies.xml @@ -16,7 +16,6 @@ android:layout_marginStart="@dimen/top_bar_alignment_margin_start" android:clickable="false" android:focusable="false" - android:importantForAccessibility="no" android:textAppearance="@style/ListItemTextStyle" android:textSize="16sp" app:layout_constraintEnd_toStartOf="@id/studies_switch" @@ -28,7 +27,6 @@ android:id="@+id/studiesDescription" android:layout_width="0dp" android:layout_height="wrap_content" - android:importantForAccessibility="no" android:text="@string/preference_experiments_summary_2" android:textColor="?attr/textSecondary" android:textColorLink="?textAccent" diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 7353dbd1f..1084c2408 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 7353dbd1f..1084c2408 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index d0591a92c..01508c31c 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -33,6 +33,10 @@ android:id="@+id/action_global_home_onboarding_dialog" app:destination="@id/homeOnboardingDialogFragment" /> + + +

+ @@ -259,6 +267,9 @@ + + diff --git a/app/src/main/res/raw/initial_experiments.json b/app/src/main/res/raw/initial_experiments.json index 4364d7289..d7d0d63be 100644 --- a/app/src/main/res/raw/initial_experiments.json +++ b/app/src/main/res/raw/initial_experiments.json @@ -2,35 +2,93 @@ "data": [ { "schemaVersion": "1.10.0", - "slug": "android-reengagment-notifications-release", - "id": "android-reengagment-notifications-release", + "slug": "android-pre-permission-prompt-experiment", + "id": "android-pre-permission-prompt-experiment", + "arguments": {}, + "application": "org.mozilla.firefox_beta", + "appName": "fenix", + "appId": "org.mozilla.firefox_beta", + "channel": "beta", + "userFacingName": "Android Pre-Permission Prompt Experiment - QA", + "userFacingDescription": "If we show the pre-permission prompt to opt in to notifications for new users, then users will be more likely to opt in to receiving notifications.", + "isEnrollmentPaused": false, + "isRollout": false, + "bucketConfig": { + "randomizationUnit": "nimbus_id", + "namespace": "fenix-pre-permission-notification-prompt-beta-1", + "start": 0, + "count": 10000, + "total": 10000 + }, + "featureIds": [ + "pre-permission-notification-prompt" + ], + "probeSets": [], + "outcomes": [], + "branches": [ + { + "slug": "control", + "ratio": 1, + "feature": { + "featureId": "pre-permission-notification-prompt", + "enabled": true, + "value": { + "enabled": false + } + } + }, + { + "slug": "treatment-a", + "ratio": 1, + "feature": { + "featureId": "pre-permission-notification-prompt", + "enabled": true, + "value": { + "enabled": true + } + } + } + ], + "targeting": "((is_already_enrolled) || (((android_sdk_version|versionCompare('33') >= 0) && is_first_run) && (app_version|versionCompare('110.!') >= 0)))", + "startDate": "2023-01-19", + "enrollmentEndDate": "2023-01-26", + "endDate": null, + "proposedDuration": 28, + "proposedEnrollment": 7, + "referenceBranch": "control", + "featureValidationOptOut": false + }, + { + "schemaVersion": "1.10.0", + "slug": "android-pre-permission-prompt-experiment-release", + "id": "android-pre-permission-prompt-experiment-release", "arguments": {}, "application": "org.mozilla.firefox", "appName": "fenix", "appId": "org.mozilla.firefox", "channel": "release", - "userFacingName": "Android Reengagment Notifications Release", - "userFacingDescription": "Re engagement notifications on Android", + "userFacingName": "Android Pre-Permission Prompt Experiment - Release", + "userFacingDescription": "If we show the pre-permission prompt to opt in to notifications for new users, then users will be more likely to opt in to receiving notifications.", "isEnrollmentPaused": false, "isRollout": false, "bucketConfig": { "randomizationUnit": "nimbus_id", - "namespace": "fenix-re-engagement-notification-release-1", + "namespace": "fenix-pre-permission-notification-prompt-release-1", "start": 0, "count": 10000, "total": 10000 }, "featureIds": [ - "re-engagement-notification" + "pre-permission-notification-prompt" ], "probeSets": [], "outcomes": [], "branches": [ { - "slug": "control-no-notification", + "slug": "control", "ratio": 1, "feature": { - "featureId": "re-engagement-notification", + "featureId": "pre-permission-notification-prompt", "enabled": true, "value": { "enabled": false @@ -38,10 +96,10 @@ } }, { - "slug": "treatment-notification", + "slug": "treatment-a", "ratio": 1, "feature": { - "featureId": "re-engagement-notification", + "featureId": "pre-permission-notification-prompt", "enabled": true, "value": { "enabled": true @@ -49,83 +107,71 @@ } } ], - "targeting": "((is_already_enrolled) || ((isFirstRun == 'true') && (app_version|versionCompare('109.!') >= 0)))", - "startDate": "2022-12-08", - "enrollmentEndDate": "2023-01-05", + "targeting": "((is_already_enrolled) || (((android_sdk_version|versionCompare('33') >= 0) && is_first_run) && (app_version|versionCompare('110.!') >= 0)))", + "startDate": "2023-01-31", + "enrollmentEndDate": "2023-02-08", "endDate": null, - "proposedDuration": 56, - "proposedEnrollment": 28, - "referenceBranch": "control-no-notification", + "proposedDuration": 28, + "proposedEnrollment": 8, + "referenceBranch": "control", "featureValidationOptOut": false }, { "schemaVersion": "1.10.0", - "slug": "firefox-android-mr-2022-new-user-onboarding", - "id": "firefox-android-mr-2022-new-user-onboarding", + "slug": "android-reengagment-notifications-release", + "id": "android-reengagment-notifications-release", "arguments": {}, "application": "org.mozilla.firefox", "appName": "fenix", "appId": "org.mozilla.firefox", "channel": "release", - "userFacingName": "Firefox Android 2022 New User Onboarding", - "userFacingDescription": "Firefox Android 2022 New User Onboarding experiment", + "userFacingName": "Android Reengagment Notifications Release", + "userFacingDescription": "Re engagement notifications on Android", "isEnrollmentPaused": true, "isRollout": false, "bucketConfig": { "randomizationUnit": "nimbus_id", - "namespace": "fenix-mr2022-release-1", + "namespace": "fenix-re-engagement-notification-release-1", "start": 0, - "count": 1500, + "count": 10000, "total": 10000 }, "featureIds": [ - "mr2022" + "re-engagement-notification" ], "probeSets": [], "outcomes": [], "branches": [ { - "slug": "control", + "slug": "control-no-notification", "ratio": 1, "feature": { - "featureId": "mr2022", + "featureId": "re-engagement-notification", "enabled": true, "value": { - "sections-enabled": { - "home-onboarding-dialog-new-users": false, - "home-onboarding-dialog-existing-users": false, - "sync-cfr": false, - "wallpapers-selection-tool": false, - "jump-back-in-cfr": false - } + "enabled": false } } }, { - "slug": "treatment-a", + "slug": "treatment-notification", "ratio": 1, "feature": { - "featureId": "mr2022", + "featureId": "re-engagement-notification", "enabled": true, "value": { - "sections-enabled": { - "home-onboarding-dialog-new-users": true, - "home-onboarding-dialog-existing-users": true, - "sync-cfr": true, - "wallpapers-selection-tool": true, - "jump-back-in-cfr": true - } + "enabled": true } } } ], - "targeting": "((is_already_enrolled) || ((days_since_install < 7) && (app_version|versionCompare('106.!') >= 0)))", - "startDate": "2022-10-05", - "enrollmentEndDate": "2022-11-01", + "targeting": "((is_already_enrolled) || ((isFirstRun == 'true') && (app_version|versionCompare('109.!') >= 0)))", + "startDate": "2022-12-08", + "enrollmentEndDate": "2023-01-31", "endDate": null, - "proposedDuration": 73, - "proposedEnrollment": 24, - "referenceBranch": "control", + "proposedDuration": 56, + "proposedEnrollment": 28, + "referenceBranch": "control-no-notification", "featureValidationOptOut": false }, { diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 673bfcf10..b9cfb5f12 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -64,11 +64,11 @@ - Дадайце цэтлік, каб адкрываць прыватныя карткі з хатняга экрана. + Дадайце цэтлік, каб адкрываць прыватныя карткі з хатняга экрана. Запусціце наступную прыватную картку адным націскам. - Дадаць цэтлік + Дадаць цэтлік Дадаць на хатні экран @@ -167,6 +167,8 @@ Спыніць Дадаткі + + Інфармацыя аб уліковым запісе Няма дадаткаў @@ -258,7 +260,7 @@ Налады пошуку - Гэтым разам шукаць: + Гэтым разам шукаць: Гэтым разам шукаць у: @@ -287,6 +289,18 @@ Закрыць + + + Апавяшчэнні дапамогуць вам зрабіць больш з %s + + Сінхранізуйце свае карткі паміж прыладамі, кіруйце сцягваннямі, атрымлівайце парады, як максімальна выкарыстоўваць ахову прыватнасці %s, і многае іншае. + + Працягнуць + + Не зараз + Адкрыць новую картку %1$s @@ -340,14 +354,22 @@ Памяншэнне колькасці банераў кукі Памяншаць колькасць банераў кукі + + Выключана + + Уключана - Firefox аўтаматычна спрабуе адхіліць запыты кукаў на банерах файлаў cookie. Калі выбар адхілення недаступны, Firefox можа прыняць усе кукі, каб закрыць банер. + Firefox аўтаматычна спрабуе адхіліць запыты кукаў на банерах файлаў cookie. Калі выбар адхілення недаступны, Firefox можа прыняць усе кукі, каб закрыць банер. + + %1$s аўтаматычна спрабуе адхіліць запыты файлаў кукі на банерах кукі. Выключана для гэтага сайта Уключана для гэтага сайта + + Сайт зараз не падтрымліваецца Уключыць памяншэнне колькасці банераў кукі для %1$s? @@ -356,14 +378,54 @@ %1$s выдаліць файлы кукі гэтага сайта і абновіць старонку. Выдаленне ўсіх файлаў кукі можа прывесці да выхаду з сістэмы або ачышчэння кошыка для пакупак. - %1$s можа паспрабаваць аўтаматычна адхіліць запыты на файлы кукі. Калі варыянт адхілення недаступны, %2$s можа прыняць усе файлы кукі, каб закрыць банер. + %1$s можа паспрабаваць аўтаматычна адхіліць запыты на файлы кукі. Калі варыянт адхілення недаступны, %2$s можа прыняць усе файлы кукі, каб закрыць банер. + + + %1$s можа паспрабаваць аўтаматычна адхіляць запыты на файлы кукі. + + %1$s спрабуе аўтаматычна адхіляць усе запыты файлаў кукі на сайтах, якія падтрымліваюцца. + + Банеры з кукамі зніклі! + + Аўтаматычна адхіляць запыты на файлы кукі, калі гэта магчыма. У адваротным выпадку прымаць усе файлы кукі, каб закрыць банеры файлаў кукі. + + Аўтаматычна адхіляць запыты на кукі, калі гэта магчыма. + + Дазволіць %1$s аўтаматычна адхіляць запыты на кукі, калі гэта магчыма? + + Не зараз + + Адхіляць банеры + + Вы ўбачыце менш запытаў пра кукі + + + Бачыць менш выплыўных акон пра кукі + + Аўтаматычна адказваць на выплыўныя вокны файлаў кукі для прагляду сайтаў без адцягнення ўвагі. %1$s будзе адхіляць усе запыты, калі гэта магчыма, або прымаць усе, калі не. + + Аўтаматычна адказваць на выплыўныя вокны файлаў кукі для прагляду сайтаў без адцягнення ўвагі. %1$s будзе адхіляць усе запыты, калі гэта магчыма. + + Адхіліць выплыўныя вокны + + Памяншэнне колькасці банераў кукі + + Дазволіць %1$s адхіляць запыты сайтаў на згоду на кукі, калі гэта магчыма, або прымаць доступ да файлаў кукі, калі гэта немагчыма? + + Дазволіць %1$s адхіляць запыты сайтаў на згоду на кукі, калі гэта магчыма? + + Дазволіць Аўтаматычна спрабуе падключацца да сайтаў з выкарыстаннем пратаколу шыфравання HTTPS для павышэння бяспекі. - Уключаны - + Уключаны + Выключаны + + Уключана ва ўсіх картках + + Уключана ў прыватных картках Даведацца больш @@ -441,6 +503,11 @@ Абвесткі + + Дазволена + + Не дазволена + Уласная калекцыя дадаткаў @@ -458,14 +525,12 @@ - Перайсці назад да + Пераход назад да Нядаўнія закладкі Нядаўна наведаныя - - Pocket Гісторыі, якія прымушаюць задумацца @@ -725,6 +790,13 @@ Закрываць праз месяц + + Адкрываць на хатняй старонцы + + Адкрываць на апошняй картцы + + Адкрываць на хатняй старонцы праз чатыры гадзіны + Перамяшчаць старыя карткі ў неактыўныя @@ -994,9 +1066,15 @@ Выняткі - Уключана + Уключана Выключана + + Стандартная + + Строгая + + Адмысловая Дазволіць гук і відэа @@ -1753,7 +1831,7 @@ Пошукавы радок - Змяніць запыт на “%s”. Прыклад:\nhttps://www.google.com/search?q=%s + Змяніць запыт на “%s”. Прыклад:\nhttps://www.google.com/search?q=%s Інфармацыя аб дададзенай пошукавай сістэме @@ -1960,8 +2038,6 @@ Гісторыі па тэмах Даведайцеся больш - - Працуе на Pocket. Пры падтрымцы %s. diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 4fd786902..0504718b0 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -16,6 +16,14 @@ Desactiva la navegació privada Escriviu una cerca o adreça + + Cerca en l’historial + + Cerca en les adreces d’interès + + Cerca en les pestanyes + + Escriviu els termes de la cerca Les pestanyes obertes es mostraran aquí. @@ -39,11 +47,7 @@ - Adreces d’interès recents - - Adreces d’interès desades recentment - - Mostra-ho tot + Desades recentment Mostra totes les adreces d’interès desades @@ -61,10 +65,14 @@ - Afegiu una drecera per obrir pestanyes privades des de la pantalla d’inici. + Afegiu una drecera per obrir pestanyes privades des de la pantalla d’inici. + + Inicia la següent pestanya privada amb un sol toc. - Afegeix una drecera - + Afegeix una drecera + + Afegeix a la pantalla d’inici + No, gràcies @@ -75,6 +83,15 @@ Descarta + + Descarta + + + + La funció de privadesa més potent fins ara aïlla els elements de seguiment entre llocs. + + Més informació sobre la protecció total de galetes + Es necessita accés a la càmera. Aneu als paràmetres de l’Android, toqueu els permisos i trieu permetre. @@ -122,17 +139,13 @@ Mostra el botó de totes les pestanyes recents - - La vostra cerca de «%1$s» - - %d llocs Mostra totes les pestanyes sincronitzades Dispositiu sincronitzat + + Elimina Elimina @@ -158,6 +171,8 @@ Atura Complements + + Informació del compte No hi ha cap complement @@ -239,8 +254,6 @@ El %s compartirà tot allò que escriviu a la barra d’adreces amb el motor de cerca per defecte. - - Més informació Cerca amb %s @@ -250,27 +263,45 @@ Paràmetres de cerca + + Aquesta vegada, cerca amb: + + Aquesta vegada, cerca en: + - - Què hi ha de nou a %1$s - - Ara és més fàcil continuar des d’on ho havíeu deixat. - - Pàgina d’inici del %1$s personalitzada - - Accediu a les pestanyes obertes, a les adreces d’interès i a l’historial de navegació. - - Pestanyes clares i organitzades - - Reduïu el caos de pestanyes amb un disseny millorat i tancament automàtic. - - Cerques recents - - - Recupereu les cerques recents des de la pàgina d’inici i des de les pestanyes. - - - Amb la pàgina d’inici del Firefox personalitzada, ara és més fàcil continuar des d’on ho havíeu deixat. Hi trobareu les pestanyes, les adreces d’interès i els resultats de cerca recents. + + Descobriu la vostra pàgina d’inici personalitzada. Les pestanyes recents, les adreces d’interès i els resultats de les cerques es mostraran aquí. + + Us donem la benvinguda a una Internet més personal + + Més colors. Millor privadesa. El mateix compromís amb les persones per sobre dels beneficis. + + + Passar d’una pantalla a l’altra és més fàcil que mai + + Ara en la pantalla d’inici hi apareixen les pestanyes dels altres dispositius, per a continuar des d’on ho havíeu deixat. + + Primers passos + + Inicia la sessió + + Omet + + Les pestanyes s’estan sincronitzant! Continueu des d’on ho havíeu deixat en l’altre dispositiu. + + Tanca + + + + Les notificacions us ajuden a fer més coses amb el %s + + Sincronitzeu les vostres pestanyes entre dispositius, gestioneu les baixades, obteniu consells per treure el màxim profit de la protecció de privadesa del %s i molt més. + + Continua + + Ara no @@ -323,12 +354,83 @@ Afegeix una drecera de navegació privada Mode només HTTPS + + + Reducció de bàners de galetes + + Redueix els bàners de galetes + + + Desactivada + + Activada + + El Firefox intenta rebutjar automàticament les sol·licituds de galetes que es mostren com a bàners de galetes. Si no hi ha l’opció de rebutjar-les, el Firefox podria acceptar totes les galetes per tancar el bàner. + + El %1$s intenta rebutjar automàticament les sol·licituds de galetes que es mostren com a bàners de galetes. + + Desactivada en aquest lloc + + Activada en aquest lloc + + Aquest lloc no és compatible ara per ara + + Voleu activar la reducció de bàners de galetes per a %1$s? + + Voleu desactivar la reducció de bàners de galetes per a %1$s? + + El %1$s esborrarà les galetes d’aquest lloc i actualitzarà la pàgina. En esborrar totes les galetes, pot ser que se us tanquin les sessions o que se us buidin els carros de la compra. + + El %1$s pot intentar rebutjar automàticament les sol·licituds de galetes. Si no hi ha l’opció de rebutjar-les, el %2$s podria acceptar totes les galetes per tancar el bàner. + + El %1$s pot intentar rebutjar automàticament les sol·licituds de galetes. + + El %1$s intenta rebutjar automàticament totes les sol·licituds de galetes de tots els llocs compatibles. + + Adeu als bàners de galetes! + + Rebutja automàticament les sol·licituds de galetes, quan sigui possible. Si no es pot, accepta totes les galetes per tancar els bàners de galetes. + + Rebutja automàticament les sol·licituds de galetes, quan sigui possible. + + Voleu permetre que el %1$s rebutgi automàticament les sol·licituds de galetes quan sigui possible? + + Ara no + + + Tanca els bàners + + + Veureu menys sol·licituds de galetes + + Vegeu menys finestres emergents de galetes + + Respon automàticament les finestres emergents de galetes per a una navegació sense distraccions. El %1$s rebutjarà totes les sol·licituds, si és possible; si no, les acceptarà totes. + + Respon automàticament les finestres emergents de galetes per a una navegació sense distraccions. El %1$s rebutjarà totes les sol·licituds, si és possible. + + Tanca les finestres emergents + + Reducció de bàners de galetes + + + Voleu permetre que el %1$s rebutgi la sol·licitud de consentiment de galetes d’un lloc si és possible o que accepti l’accés a les galetes quan no sigui possible? + + + Voleu permetre que el %1$s rebutgi la sol·licitud de consentiment de galetes d’un lloc, si és possible? + + Permet + Intenta connectar-se als llocs mitjançant el protocol de xifratge HTTPS automàticament per millorar la seguretat. - Activat - + Activat + Desactivat + + Activat en totes les pestanyes + + Activat en pestanyes privades Més informació @@ -362,7 +464,7 @@ Personalitza - Sincronitzeu les adreces d’interès, l’historial i molt més amb el vostre compte del Firefox + Inicieu la sessió per sincronitzar pestanyes, adreces d’interès, contrasenyes i més. Compte del Firefox @@ -406,6 +508,11 @@ Notificacions + + Permès + + No permès + Col·lecció de complements personalitzada @@ -428,9 +535,13 @@ Visitat recentment - - Pocket + + Articles suggerents + + Articles recomanats pel %s + + Articles patrocinats Fons de pantalla @@ -444,12 +555,28 @@ Mostra - - Canvieu el fons de pantalla tocant el logotip de la pàgina d’inici del Firefox - - - Logotip del Firefox: canvieu el fons de pantalla, botó + + No s’ha pogut baixar el fons de pantalla + + Torna-ho a provar + + No s’ha pogut canviar el fons de pantalla + + Més informació + + %s clàssic + + Edició limitada + + La nova col·lecció Veus independents. %s + + La nova col·lecció Veus independents. + + Afegiu-hi un toc de color + + Trieu un fons de pantalla que us representi. + + Descobriu més fons de pantalla @@ -531,9 +658,8 @@ Permet a Mozilla instal·lar i executar estudis - - Activa la sincronització - + + Sincronitza i desa les dades Inicieu la sessió per tornar a connectar @@ -592,6 +718,17 @@ Tanca + + Voleu obrir %d pestanyes? + + Obrir tantes pestanyes pot fer que el %s vagi més lent mentre es carreguen les pàgines. Esteu segur que voleu continuar? + + Obre les pestanyes + + Cancel·la + %d lloc @@ -621,10 +758,6 @@ Llista Graella - - Cerca en grups - - Agrupa els llocs relacionats Tanca les pestanyes @@ -657,6 +790,13 @@ Tanca-les al cap d’un mes + + Obre en la pàgina d’inici + + Obre en la darrera pestanya + + Obre en la pàgina d’inici després de quatre hores + Mou les pestanyes antigues a inactives @@ -728,8 +868,6 @@ Menú de pestanyes obertes Desa les pestanyes a la col·lecció - - Menú de pestanya Suprimeix la col·lecció @@ -749,9 +887,6 @@ %1$s (mode privat) - - Altres pestanyes - Escriviu els termes de la cerca @@ -780,11 +915,6 @@ No hi ha informació d’historial - - Sincronitzat d’altres dispositius - - D’altres dispositius - S’han eliminat les baixades @@ -834,6 +964,10 @@ Obre en una pestanya nova Obre en una pestanya privada + + Obre-ho tot en pestanyes noves + + Obre-ho tot en pestanyes privades Suprimeix @@ -927,9 +1061,15 @@ Excepcions - Activada + Activada Desactivada + + Estàndard + + Estricta + + Personalitzada Permet àudio i vídeo @@ -1011,6 +1151,10 @@ Comparteix + + Desa com a PDF + + No s’ha pogut generar el PDF Envia a un dispositiu @@ -1022,10 +1166,10 @@ Copia al porta-retalls S\'ha copiat al porta-retalls - - Inicia sessió per sincronitzar Inicia la sessió al Sync + + Sincronitza i desa les dades Envia a tots els dispositius @@ -1061,6 +1205,12 @@ %1$s is a placeholder that will be replaced by the app name (Fenix). --> Fes que el %1$s sigui el navegador per defecte + + Proveu la navegació privada + + Navegueu sense desar cap galeta ni historial en el %1$s + S’ha suprimit la col·lecció @@ -1072,8 +1222,6 @@ S’han tancat les pestanyes S’han desat les adreces d’interès - - S’ha afegit als llocs principals S\'ha afegit a les dreceres @@ -1154,8 +1302,18 @@ Surt - - Això suprimirà totes les dades de navegació. + + Interval de temps per suprimir + + + Suprimeix l’historial (inclou l’historial sincronitzat d’altres dispositius), les galetes i altres dades de navegació. + + Darrera hora + + Avui i ahir + + Tot + El %s suprimirà les dades de navegació seleccionades. @@ -1167,8 +1325,8 @@ S’estan suprimint les dades de navegació… - - Això suprimirà tots els elements. + + Voleu suprimir tots els llocs de «%s»? Cancel·la @@ -1176,51 +1334,23 @@ S’ha suprimit el grup - - - El Firefox Preview ara és el Firefox Nightly - - El Firefox Nightly s’actualitza cada nit i té característiques noves experimentals. - Tot i això, pot ser menys estable. Baixeu el navegador beta per a una experiència més estable. - - - Baixeu el Firefox per a l’Android Beta - - - El Firefox Nightly s’ha traslladat - - Aquesta aplicació ja no rebrà actualitzacions de seguretat. Deixeu d’usar-la i canvieu al nou Nightly. - \n\nPer a transferir les adreces d’interès, els inicis de sessió i l’historial a una altra aplicació, creeu un compte del Firefox. - - Canvia al nou Nightly - - - El Firefox Nightly s’ha traslladat - - Aquesta aplicació ja no rebrà actualitzacions de seguretat. Obteniu el nou Nightly i deixeu d’usar aquesta aplicació. - \n\nPer a transferir les adreces d’interès, els inicis de sessió i l’historial a una altra aplicació, creeu un compte del Firefox. - - Baixeu el nou Nightly - - - Us donem la benvinguda al %s - - - Sincronitzeu el Firefox entre dispositius - - Sincronitzeu el %1$s entre dispositius - - Importeu les adreces d’interès, l’historial i les contrasenyes al %1$s d’aquest dispositiu. - - Registre + + Us donem la benvinguda a una Internet millor + + Un navegador creat per a les persones i no per al lucre. + + Continueu des d’on ho deixeu + + Sincronitzeu les pestanyes i les contrasenyes entre dispositius per passar d’una pantalla a una altra de forma transparent. + + Inicia la sessió La sincronització està activada - - Privadesa sempre activa - - El %1$s bloca automàticament les empreses que, en secret, us fan el seguiment mentre navegueu. + + Protecció de la privadesa per defecte + + La protecció total de galetes impedeix que els seguidors utilitzin les galetes per a perseguir-vos d’un lloc web a l’altre. Estàndard (per defecte) @@ -1231,16 +1361,17 @@ Bloca més elements de seguiment i fa que les pàgines es carreguin més ràpidament, però podria causar problemes amb algunes funcions de la pàgina. Trieu la ubicació de la barra d’eines - - Tingueu la barra d’eines a mà. La podeu mantenir a la part inferior o moure-la a dalt. - - La vostra privadesa - - Hem dissenyat el %s per donar-vos el control sobre tot allò que compartiu en línia i que compartiu amb nosaltres. + + Manteniu-la a la part inferior o moveu-la a la part superior. + + Teniu el control de les vostres dades + + El Firefox us dona el control sobre tot allò que compartiu en línia i que compartiu amb nosaltres. Mostra l’avís de privadesa + + Esteu a punt per obrir una Internet espectacular? Comença a navegar @@ -1328,6 +1459,8 @@ Totes les galetes de tercers (pot fer que alguns llocs web no funcionin) Totes les galetes (farà que alguns llocs web no funcionin) + + Aïlla les galetes entre llocs Contingut que fa seguiment @@ -1350,8 +1483,12 @@ Limita la capacitat de les xarxes socials de fer-vos el seguiment de la vostra activitat a Internet. Galetes de seguiment entre llocs + + Galetes entre llocs Bloca les galetes que les empreses de publicitat i d’anàlisi utilitzen per recollir les vostres dades de navegació en molts llocs web. + + La protecció total de galetes aïlla les galetes del lloc on us trobeu, de manera que els elements de seguiment, com ara les xarxes de publicitat, no les poden utilitzar per a seguir-vos d’un lloc a l’altre. Miners de criptomonedes @@ -1549,6 +1686,12 @@ Afegeix una adreça Gestiona les adreces + + + Desa i emplena automàticament les adreces + + Inclou informació com números, adreces electròniques i adreces d’enviament + Afegeix una targeta @@ -1600,18 +1743,28 @@ Afegeix una adreça + + Edita l’adreça Gestiona les adreces - - Nom complet + + Nom + + Segon nom + + Cognoms Adreça postal Ciutat - + Estat + + Província Codi postal + + País o regió Telèfon @@ -1623,6 +1776,17 @@ Suprimeix l’adreça + + Segur que voleu suprimir aquesta adreça? + + Suprimeix + + Cancel·la + + Desa l’adreça + + Suprimeix l’adreça + Afegeix un motor de cerca @@ -1643,7 +1807,7 @@ Cadena de cerca que s’utilitzarà - Substituïu la consulta per «%s». Per exemple:\nhttps://www.google.com/search?q=%s + Substituïu la consulta per «%s». Per exemple:\nhttps://www.google.com/search?q=%s Detalls del motor de cerca personalitzat @@ -1663,19 +1827,6 @@ S’ha suprimit %s - - Us donem la benvinguda al nou %s - - Us espera un navegador redissenyat de cap a peus, amb millores de rendiment i funcionalitat que us ajudaran a ser més productius a Internet.\n\nEspereu mentre actualitzem el %s amb: - - S’està actualitzant el %s… - - Inicia el %s - - La migració ha acabat - - Contrasenyes - Per a permetre-ho: @@ -1704,10 +1855,6 @@ No hi ha cap excepció de lloc Segur que voleu suprimir aquesta adreça d’interès? - - Afegeix als llocs principals - - Elimina dels llocs principals Afegeix a les dreceres @@ -1771,8 +1918,6 @@ No teniu cap pestanya oberta al Firefox dels altres dispositius. - - No teniu cap pestanya oberta a %1$s en els altres dispositius. Vegeu una llista de les pestanyes que teniu obertes en altres dispositius. @@ -1787,12 +1932,8 @@ Redueix el grup de pestanyes sincronitzades - - S’ha arribat al límit de llocs principals S\'ha arribat al límit de dreceres - - Per afegir un lloc principal nou, primer cal que n’elimineu algun altre. Manteniu premut el lloc i seleccioneu eliminar-lo. Per a afegir una nova drecera, primer cal que n’elimineu alguna altra. Manteniu premut el lloc i seleccioneu eliminar-lo. @@ -1802,8 +1943,6 @@ Dreceres Nom - - Nom del lloc principal Nom de la drecera @@ -1824,6 +1963,11 @@ Tanca totes les pestanyes inactives + + Amplia les pestanyes inactives + + Redueix les pestanyes inactives + Voleu tancar-les automàticament al cap d’un mes? @@ -1835,6 +1979,14 @@ Tancament automàtic activat + + + Suggeriments del Firefox + + Cerca de Google + + Cerca amb %s + Feu que els enllaços dels llocs web, del correu electrònic i dels missatges s’obrin automàticament en el Firefox. @@ -1857,15 +2009,28 @@ Articles per tema Descobriu-ne més - - Amb tecnologia del Pocket. + + Funciona amb el %s. Part de la família Firefox. %s Més informació + + Patrocinat + Activa la telemetria per a enviar dades. Ves als paràmetres + + + + reduir + + ampliar + + obrir l’enllaç per obtenir més informació sobre aquesta col·lecció + + llegir l’article diff --git a/app/src/main/res/values-ceb/strings.xml b/app/src/main/res/values-ceb/strings.xml index 3f5e16b7e..d9f750ab4 100644 --- a/app/src/main/res/values-ceb/strings.xml +++ b/app/src/main/res/values-ceb/strings.xml @@ -18,12 +18,8 @@ Ang imong abri nga tabs makita dinhi. Ang imong mga private tab makita dinhi. - - 1 ang abli nga tab. i-Tap para mobalhin ug mga tab. - - %1$s ang abli nga mga tab. i-Tap para mobalhin ug mga tab. %1$d napili @@ -36,37 +32,14 @@ Gawas sa multiselect mode i-Save ang napiling tabs padulong sa collection - - Napili %1$s - - Wala gipili %1$s - - Gawas na sa multiselect mode - - Nakasulod na sa multiselect mode, pili ug tabs aron magsave sa collection Napili - - - Bagong nasave - - Bag-ong nabookmark - - Bag-ong nasave nga bookmarks - - Ipakita tanan - - Ipakita ang nasave nga bookmarks button - %1$s hinimo sa @fork-maintainers. - - - Ania ka sa private session - + @@ -76,21 +49,16 @@ Mga tinuohan bahin sa private browsing - - i-Delete ang session - Dugang ug shortcut pag-abri ug mga private tab gikan sa imong Home screen. + Dugang ug shortcut pag-abri ug mga private tab gikan sa imong Home screen. - Dugang ug shortcut - + Dugang ug shortcut + Salamat na lang - - - Ma-set nimo ang Firefox nga automatic mo-abri ug link sa mga apps. Adto sa settings @@ -111,17 +79,16 @@ i-Dismiss - Ang mga tab nga wala nimo malantaw sulod sa duha ka-semana mabutang dinhi. + Ang mga tab nga wala nimo malantaw sulod sa duha ka-semana mabutang dinhi. - i-Off sulod sa settings + i-Off sulod sa settings + Bag-o nga tab Bag-o nga pribadong tab - - Nag-unang mga site @@ -129,32 +96,15 @@ Ipakita tanan - - Ipakita tanan bag-ong mga tab nga button - - Imong gipangita alang sa \"%1$s\" - - Mga Site: %1$s - - Milabay nga eksplorasyon - - Bagong nabisita + Bagong nabisita i-Remove - - Ipakita tanan kanhi mga eksplorasyon nga button - - - Abrihi ang Tabs Balik @@ -163,16 +113,10 @@ i-Refresh Hunong - - i-Bookmark - - Usba ang bookmark Mga Add-on - - Mga Extension Wala’y mga add-on dinhi @@ -189,20 +133,14 @@ Dugang sa Home screen i-Install - - Na-sync nga mga tab i-Sync usab Pangitaa sa page - - Private tab i-Save sa collection i-Share - - i-Share sa Ablihi sa %1$s @@ -218,29 +156,19 @@ i-Close ang reader view i-Open sa app - - Appearance i-Customize ang reader view i-Add i-Edit - - i-Customize ang home Home screen - - Dili makakonek. Dili mailhan ang URL scheme. - Pinili nga sinultian - - i-Search Sunda ang device language @@ -249,12 +177,8 @@ i-Scan - - Mga setting sa search engine - - Karon, search gamit ang: Pun-a ang link gikan sa clipboard @@ -265,38 +189,11 @@ i-Allow ang search suggestions sulod sa private sessions? Ang %s magbutyag sa tanan nimo gitype sulod sa address bar gamit imong default nga search engine. - - Dugang pagtuon Pangitaon %1$s Pangitaa pinaagi sa address bar - - - Mga kabag-ohan sa Firefox - - Gipasayon na karon ang pag-balik kung asa ka mibiya. - - Personal nga Firefox homepage - - Adto sa imong mga abri nga tab, mga bookmark, ug browsing history. - - Limpyo, han-ay nga mga tab - - i-Plastar ang katag nga mga tab gamit ang mas maayong layout ug mga auto-closing tab. - - Bag-ohay nga mga search - - Bisitaha imong bag-ong mga search gikan sa imong homepage ug mga tab. - - - Ang imong personal nga Firefox homepage karon sayon na mopadayon kung asa ka nibiya. Pangitaa imong bag-ong mga tab, mga bookmark, ug mga search result. - - - - Abri ug bag-ong Firefox tab - i-Search @@ -308,49 +205,21 @@ Mga Setting - - Basics - - - - - - - - - - - - - - + + i-Rate sa Google Play - - Hatag ug feedback Mahitungod sa %1$s - - Mga Katungod - - Mga Password - - Mga credit card ug address Itakda isip default browser - - - - Privacy ug seguridad Panugot sa site - - i-Open ang mga link sa pribadong tab @@ -361,46 +230,17 @@ Kung naay pagtugot, makit-an ang mga private tab kung daghan apps ang giabrihan. Dugang ug shortcut sa private browsing - - + Custom nga server sa Firefox Account Custom nga Sync server Nausab ang Firefox Account/Sync server. Kamulong gina-quit ang application para maapply ang nausab … - - - - - - - - - - - - - - - - i-Sync ang mga bookmark, history, ug uban pa sa imong Firefox Account - - i-Reconnect para mapadayon ang pag-sync - - - - - - - - - - - - + + Remote debugging pinaagi sa USB @@ -419,26 +259,9 @@ Pangitaa sa mga bookmark Pangitaa sa synced tabs - - - - Abrihi ang mga link sulod sa mga app - - - - - - - - - - - - - - + Ngalan sa Collection @@ -449,15 +272,9 @@ Sulod balik - - Bagong nasave - - Bag-ong nabookmark - Bagong nabisita - - + Bagong nabisita @@ -470,22 +287,16 @@ Sync na karon Pili unsay i-sync - - Mga Bookmark Mga Login Abrihi ang Tabs - - Ngalan sa device Ang ngalan sa device dapat dili blanko. - - Pakyas ang sync. Niagi nga success: %s @@ -510,24 +321,13 @@ Mga pahibalo sa mga tab nga nadawat gikan sa ubang mga Firefox device. Tab nga nadawat - - Mga Tab nadawat Tab gikan sa %s - - - - - - - - i-Block ang content ug mga script nga motrack kanimo online + Mga Exception - - Walay Tracking Protection ani nga mga website i-On para sa tanan site @@ -535,8 +335,6 @@ Dugang pagtuon - - Usage ug technical data diff --git a/app/src/main/res/values-co/strings.xml b/app/src/main/res/values-co/strings.xml index 2e1b946f8..2e81a2325 100644 --- a/app/src/main/res/values-co/strings.xml +++ b/app/src/main/res/values-co/strings.xml @@ -68,11 +68,11 @@ - Aghjunghjite un accurtatoghju per apre unghjette private da u vostru screnu d’accolta. + Aghjunghjite un accurtatoghju per apre unghjette private da u vostru screnu d’accolta. Aprite a prossima unghjetta privata in un solu tuccà - Aghjunghje un accurtatoghju + Aghjunghje un accurtatoghju Aghjunghje à u screnu d’accolta @@ -174,6 +174,8 @@ Piantà Moduli addiziunali + + Infurmazione nant’à u contu Nisunu modulu quì @@ -262,7 +264,7 @@ Preferenze di ricerca - Sta volta, ricercà cù : + Sta volta, ricercà cù : Sta volta, ricercà cù : @@ -291,6 +293,18 @@ Chjode + + + E nutificazioni vi aiutanu à fane di più cù %s + + Sincrunizate l’unghjette trà i vostri apparechji, urganizate i scaricamenti, ottinite cunsiglii per sfruttà u più bellu di a prutezzione di a vita privata da %s, è ancu di più. + + Cuntinuà + + Micca subitu + Apre una nova unghjetta in %1$s @@ -347,13 +361,21 @@ Riduce e striscie di canistrelli + + Disattivata + + Attivata - Firefox prova autumaticamente di righjittà e dumande di canistrelli quandu ci hè striscie di canistrelli. S’è alcuna ozzione di righjettu ùn hè micca dispunibule, Firefox pò accettà tutti i canistrelli per chjode a striscia. + Firefox prova autumaticamente di righjittà e dumande di canistrelli quandu ci hè striscie di canistrelli. S’è alcuna ozzione di righjettu ùn hè micca dispunibule, Firefox pò accettà tutti i canistrelli per chjode a striscia. + + %1$s prova autumaticamente di righjittà e dumande di canistrelli quandu ci hè striscie di canistrelli. Disattivata per stu situ Attivata per stu situ + + Attualmente u situ ùn hè micca accettatu Attivà a riduzzione di e striscie di cannistrelli per %1$s ? @@ -362,14 +384,53 @@ %1$s squasserà i canistrelli di stu situ è attualizerà a pagina. A squassatura di tutti i canistrelli puderia discunnettevi o viutà e sporte di comprera. - %1$s pò pruvà di righjittà autumaticamente e dumande di canistrelli. S’è alcuna ozzione di righjettu ùn hè micca dispunibule, %2$s pò accettà tutti i canistrelli per chjode a striscia. + %1$s pò pruvà di righjittà autumaticamente e dumande di canistrelli. S’è alcuna ozzione di righjettu ùn hè micca dispunibule, %2$s pò accettà tutti i canistrelli per chjode a striscia. + + + %1$s pò pruvà di righjittà autumaticamente e dumande di canistrelli. + + %1$s prova autumaticamente di righjittà tutte e dumande di canistrelli nant’à i siti accettati. + + E striscie di cannistrelli fora ! + + Righjetta autumaticamente e dumande di canistrelli quand’ellu hè pussibule. Osinnò, accetteghja tutti i canistrelli per chjode e striscie di canistrelli. + + Righjetta autumaticamente e dumande di canistrelli quand’ellu hè pussibule + + Permette à %1$s di righjettà autumaticamente e dumande di canistrelli quand’ellu hè pussibule ? + + Micca subitu + + Righjittà e striscie + + Viderete menu richieste di cannistrelli + + Vede menu finestre inoppurtune di cannistrelli + + Risponde autumaticamente à e finestre inoppurtune di cannistrelli per una navigazione senza distrazzione. %1$s righjitterà tutte e dumande, s’ellu hè pussibule, osinnò l’accetterà tutte. + + Risponde autumaticamente à e finestre inoppurtune di cannistrelli per una navigazione senza distrazzione. %1$s righjitterà tutte e dumande, s’ellu hè pussibule. + + Righjittà e finestre inoppurtune + + Riduzzione di e striscie di cannistrelli + + Permette à %1$s di ricusà una dumanda d’accunsentu da un situ à i canistrelli, s’ellu hè pussibule, o accettà l’accessu à i canistrelli quand’ellu ùn hè micca pussibule ? + + Permette à %1$s di ricusà una dumanda d’accunsentu da un situ à i canistrelli, s’ellu hè pussibule ? + + Permette Tentativu autumaticu di cunnessione à i siti impieghendu u protocollu di cifratura HTTPS per aumentà a sicurità. - Attivata - + Attivata + Disattivata + + Attivatu in tutte l’unghjette + + Attivatu in l’unghjette private Sapene di più @@ -449,6 +510,11 @@ Nutificazioni + + Permesse + + Micca permesse + Cullezzione persunalizata di moduli addiziunale @@ -472,8 +538,6 @@ Visitati pocu fà - - Pocket Storie chì facenu riflette @@ -734,6 +798,14 @@ Chjusura dopu un mese + + Apre a pagina d’accolta + + Apre l’ultima unghjetta + + + Apre a pagina d’accolta dopu quattru ore + Dispiazzà e vechje unghjette in a sezzione inattiva @@ -1002,9 +1074,15 @@ Eccezzioni - Attivata + Attivata Disattivata + + Classica + + Severa + + Persunalizata Permette l’audio è a video @@ -1742,7 +1820,7 @@ Catena di ricerca à impiegà - Rimpiazzà i termi di a ricerca da « %s ». Esempiu :\nhttps://www.google.com/search?q=%s + Rimpiazzà i termi di a ricerca da « %s ». Esempiu :\nhttps://www.google.com/search?q=%s Detaglii di u mutore di ricerca persunalizatu @@ -1946,8 +2024,6 @@ Storie da l’articulu Scoprene di più - - Funziuneghja grazia à Pocket. Funziuneghja grazia à %s. diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 44a65df96..b0b046eb5 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -67,10 +67,12 @@ - Vytvořte si zástupce pro otevření anonymního panelu z domovské obrazovky. + Vytvořte si zástupce pro otevření anonymního panelu z domovské obrazovky. - Přidat zkratku - + Přidat zkratku + + Přidat na domovskou obrazovku + Ne, děkuji @@ -82,8 +84,11 @@ Zavřít - Zavřít + Zavřít + + + Naše doposud nejmocnější funkce ochrany osobních údajů izoluje sledovací prvky třetích stran. Zjistit více o úplné ochraně před cookies @@ -138,6 +143,8 @@ Synchronizované zařízení + + Odebrat Odebrat @@ -164,6 +171,8 @@ Zastaví načítání stránky Doplňky + + Informace o účtu Žádné doplňky @@ -256,15 +265,33 @@ Nastavení vyhledávání + + + Seznamte se se svou přizpůsobenou domovskou stránkou. Zobrazí se vám na ní nedávné panely, záložky a výsledky vyhledávání. + + Vítejte na osobnějším internetu + + Více barev. Lepší soukromí. Stále stejné nadřazení lidí nad ziskem. + + Přepínání obrazovek je jednodušší než kdy jindy + + Na své domovské stránce pokračujte s panely z jiných zařízení přesně tam, kde jste přestali. Začít Přihlásit se Přeskočit + + Vaše panely se synchronizují! Na druhém zařízení pokračujte tam, kde jste skončili. Zavřít + + Pokračovat + + Teď ne + Otevřít nový panel v aplikaci %1$s @@ -315,12 +342,51 @@ Režim „pouze HTTPS“ + + Omezení cookie lišt + + Vypnuto + + Zapnuto + + Vypnuto pro tento web + + Zapnuto pro tento web + + Chcete zapnout omezení cookie lišt pro %1$s? + + Chcete vypnout omezení cookie lišt pro %1$s? + + Cookie lišty jsou fuč! + + Automaticky odmítat požadavky na cookies, kdykoliv je to možné. + + Chcete aplikaci %1$s povolit automaticky odmítat požadavky na cookies, kdykoliv je to možné? + + Teď ne + + Zavírat bannery + + Uvidíte méně požadavků na cookies + + Zobrazovat méně cookie lišt + + Zavírat vyskakovací okna + + Omezení cookie lišt + + Povolit + Pro zvýšení zabezpečení se automaticky pokusí připojit k webům pomocí šifrovacího protokolu HTTPS. - Zapnuto - + Zapnuto + Vypnuto + + Zapnuto pro všechny panely + + Zapnuto pro anonymní panely Zjistit více @@ -399,6 +465,11 @@ Oznámení + + Povoleno + + Není povoleno + Vlastní sbírka doplňků @@ -421,8 +492,6 @@ Nedávno navštívené - - Pocket Podnětné články @@ -441,14 +510,26 @@ Zobrazit + + Tapetu se nepodařilo stáhnout Zkusit znovu + + Tapetu se nepodařilo změnit Zjistit více + + Klasický %s Limitovaná edice + + Nová sbírka Nezávislé hlasy. %s + + Nová sbírka Nezávislé hlasy. Zkuste barevný nádech + + Vyberte si tapetu, která vás vyjadřuje. Podívejte se na další tapety @@ -598,6 +679,9 @@ Otevřít %d panelů? + + Otevření tolika panelů může aplikaci %s zpomalit. Opravdu chcete pokračovat? Otevřít panely @@ -664,6 +748,13 @@ Zavírat po měsíci + + Otevře domovskou stránku + + Otevře poslední panel + + Otevře domovskou stránku po 4 hodinách + Přesun neaktivních panelů @@ -937,10 +1028,16 @@ Výjimky - Zapnuta + Zapnuta Vypnuta + + Standardní + + Přísná + + Vlastní Povolit zvuk i video @@ -1024,6 +1121,8 @@ Sdílet Uložit jako PDF + + PDF se nepodařilo vygenerovat Poslat do zařízení @@ -1034,8 +1133,6 @@ Zkopírovat do schránky Zkopírováno do schránky - - Přihlásit se k synchronizaci Přihlásit ke službě Sync @@ -1077,6 +1174,12 @@ %1$s is a placeholder that will be replaced by the app name (Fenix). --> Nastavit %1$s jako můj výchozí prohlížeč + + Vyzkoušejte anonymní prohlížení + + Prohlížejte web bez ukládání cookies a historie v aplikaci %1$s + Sbírka odstraněna @@ -1169,6 +1272,8 @@ Časové období mazání + + Odstraní historii (včetně synchronizované historie z ostatních zařízení), cookies a související data. Poslední hodina @@ -1188,17 +1293,28 @@ Mazání soukromých dat… + + Smazat všechny stránky v %s Zrušit + + + Vítá vás lepší internet Prohlížeč postavený pro lidi, ne pro peníze. + + Pokračujte tam, kde jste skončili + + Synchronizujte panely a hesla mezi zařízeními pro bezproblémové přepínání obrazovky. Přihlásit se Synchronizace je zapnutá Ochrana soukromí již ve výchozím nastavení + + Představujeme úplnou ochranu před cookies, které slouží k vašemu sledování napříč webovými stránkami. Standardní (výchozí) @@ -1209,11 +1325,17 @@ Blokuje více sledovacích prvků. Zrychlí i načítání stránek, ale může omezit jejich fungování. Vyberte si umístění nástrojové lišty + + Dole, nebo nahoře. + + Vaše data jsou prostě vaše Firefox vám dává kontrolu nad tím, co sdílíte online a co sdílíte s námi. Přečíst zásady ochrany osobních údajů + + Jste připraveni otevřít úžasný internet? Začít prohlížet @@ -1221,7 +1343,7 @@ Vyberte si vzhled - Šetřete baterku i své oči povolením tmavého režimu. + Povolením tmavého režimu šetřete baterku i své oči. Automatický @@ -1300,6 +1422,8 @@ Všechny cookies třetích stran (může omezit fungování některých stránek) Všechny cookies (omezí fungování některých stránek) + + Izolovat cross-site cookies Sledující obsah @@ -1326,6 +1450,8 @@ Cross-site cookies Blokuje cookies, které používají reklamní sítě a firmy ke sběru informací z mnoha serverů na internetu. + + Úplná ochrana před cookies izoluje cookies pro web, na němž se nacházíte, aby vás sledující subjekty nemohly sledovat napříč stránkami. Těžba kryptoměn @@ -1640,7 +1766,7 @@ Řetězec používaný pro vyhledávání - Dotaz nahraďte „%s“. Příklad: \nhttps://www.google.com/search?q=%s + Dotaz nahraďte „%s“. Příklad: \nhttps://www.google.com/search?q=%s Podrobnosti vlastního vyhledávače @@ -1810,6 +1936,13 @@ Automatické zavírání povoleno + + + Návrhy od Firefoxu + + + Vyhledání na Googlu + Nastavte si automatické otevírání odkazů, e-mailů a zpráv ve Firefoxu. @@ -1832,8 +1965,6 @@ Články podle témat Objevte více - - Službu poskytuje Pocket. Součást rodiny Firefoxu. %s @@ -1846,7 +1977,6 @@ Pro odesílání dat povolte telemetrii. Přejít do nastavení - Návrhy od Firefoxu diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index a4ce3f20e..f7a0c8aa1 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -66,11 +66,11 @@ - Ychwanegu llwybr byr i agor tabiau preifat o’ch sgrin Cartref. + Ychwanegu llwybr byr i agor tabiau preifat o’ch sgrin Cartref. Agor y tab preifat nesaf gydag un tap. - Ychwanegu llwybr byr + Ychwanegu llwybr byr Ychwanegu i’r sgrin Cartref @@ -171,6 +171,8 @@ Atal Ychwanegion + + Manylion cyfrif Dim ychwanegion yma @@ -259,7 +261,7 @@ Gosodiadau chwilio - Chwiliad y tro yma: + Chwiliad y tro yma: Y tro hwn chwiliwch yn: @@ -287,6 +289,18 @@ Cau + + + Mae hysbysiadau yn eich helpu i wneud mwy gyda %s + + Cydweddu eich tabiau rhwng dyfeisiau, rheoli llwythi, cael awgrymiadau ar wneud y gorau o ddiogelwch preifatrwydd %s, a mwy. + + Parhau + + Nid nawr + Agor tab %1$s newydd @@ -342,14 +356,22 @@ Gostyngiad Baner Cwcis Lleihau baneri cwcis + + Diffodd + + Ymlaen - Mae Firefox yn ceisio gwrthod ceisiadau cwcis ar faneri cwcisyn awtomatig. Os nad oes dewis gwrthod ar gael, gall Firefox dderbyn pob cwci er mwyn cau’r faner. + Mae Firefox yn ceisio gwrthod ceisiadau cwcis ar faneri cwcisyn awtomatig. Os nad oes dewis gwrthod ar gael, gall Firefox dderbyn pob cwci er mwyn cau’r faner. + + Mae %1$s yn ceisio gwrthod ceisiadau cwci ar faneri cwci yn awtomatig. Diffodd ar gyfer y wefan hon Ymlaen ar gyfer y wefan hon + + Nid yw’r wefan yn cael ei chefnogi ar hyn o bryd Troi Llai o Faneri Cwcis ymlaen ar %1$s? @@ -357,14 +379,54 @@ Bydd %1$s yn clirio cwcis y wefan hon ac yn adnewyddu’r dudalen. Gall clirio pob cwci eich allgofnodi neu wagio eich certiau siopa. - Gall %1$s geisio gwrthod ceisiadau cwcis yn awtomatig. Os nad oes dewis gwrthod ar gael, gall %2$s dderbyn pob cwci er mwyn cau’r faner. + Gall %1$s geisio gwrthod ceisiadau cwcis yn awtomatig. Os nad oes dewis gwrthod ar gael, gall %2$s dderbyn pob cwci er mwyn cau’r faner. + + + Gall %1$s geisio gwrthod ceisiadau cwcis yn awtomatig. + + Mae %1$s yn ceisio gwrthod yn awtomatig pob cais cwci ar wefannau sy’n cael eu cefnogi. + + Gwaredu baneri cwcis! + + Gwrthod ceisiadau cwcis yn awtomatig, pan fo modd. Fel arall, derbyn pob cwci i ddiystyru baneri cwcis. + + + Gwrthod ceisiadau cwcis yn awtomatig, pan fo modd. + + Caniatáu i %1$s wrthod ceisiadau cwcis yn awtomatig pan fo modd? + + Nid Nawr + + Cau baneri + + Fe welwch lai o geisiadau cwcis + + Gweld llai o lamlenni cwci + + Atebwch ffenestri llamlenni cwci yn awtomatig er mwyn gallu pori heb eich poeni. Bydd %1$s yn gwrthod pob cais os yn bosib, neu’n derbyn pob un os nad. + + Atebwch ffenestri llamlenni cwci yn awtomatig er mwyn gallu pori heb eich poeni. Bydd %1$s yn gwrthod pob cais os yn bosib. + + Cau Llamlenni + + Llai o Faneri Cwcis + + Caniatáu i %1$s wrthod cais caniatâd cwci gwefan os yn bosibl neu dderbyn mynediad cwci pan nad yw’n bosibl? + + Caniatáu i %1$s wrthod cais caniatâd cwci gwefan os yn bosibl? + + Caniatáu Yn ceisio cysylltu’n awtomatig â gwefannau gan ddefnyddio’r protocol amgryptio HTTPS am fwy o ddiogelwch. - Ymlaen - + Ymlaen + Diffodd + + Ymlaen ym mhob tab + + Ymlaen mewn tabiau preifat Dysgu rhagor @@ -443,6 +505,11 @@ Hysbysiadau + + Caniatáu + + Dim caniatáu + Casgliad Ychwanegion Cyfaddas @@ -465,8 +532,6 @@ Ymwelwyd yn ddiweddar - - Pocket Straeon sy’n procio’r meddwl @@ -721,6 +786,13 @@ Cau ar ôl mis + + Agor ar y dudalen cartref + + Agor ar y tab olaf + + Agor ar y dudalen cartref ar ôl pedair awr + Symud hen dabiau i anweithredol @@ -988,9 +1060,15 @@ Eithriadau - Ymlaen + Ymlaen Diffodd + + Safonol + + Llym + + Cyfaddas Caniatáu sain a fideo @@ -1726,7 +1804,7 @@ Llinyn chwilio i’w ddefnyddio - Disodli’r ymholiad â “%s”. Enghraifft:\nhttps://www.google.com/search?q=%s + Disodli’r ymholiad â “%s”. Enghraifft:\nhttps://www.google.com/search?q=%s Manylion peiriant chwilio cyfaddas @@ -1927,8 +2005,6 @@ Straeon yn ôl pwnc Darganfod rhagor - - Wedi’i bweru gan Pocket. Wedi’i bweru gan %s. diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 35764b0cb..47f71e3e1 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -65,11 +65,11 @@ - Tilføj en genvej til at åbne private faneblade fra din startskærm. + Tilføj en genvej til at åbne private faneblade fra din startskærm. Åbn næste private faneblad med et enkelt tryk. - Tilføj genvej + Tilføj genvej Føj til startskærm @@ -171,6 +171,8 @@ Stop Tilføjelser + + Kontooplysninger Her er ingen tilføjelser @@ -259,7 +261,7 @@ Søgeindstillinger - Søg denne gang med: + Søg denne gang med: Søg denne gang i: @@ -287,6 +289,18 @@ Luk + + + Meddelelser hjælper dig med at gøre mere med %s + + Synkroniser dine faneblade mellem enheder, håndter filhentninger, få tips til at få mest muligt ud af privatlivsbeskyttelse i %s og meget mere. + + Fortsæt + + Ikke nu + Åbn et nyt %1$s-faneblad @@ -342,13 +356,21 @@ Reducer cookie-bannere + + Fra + + Til - Firefox forsøger automatisk at afvise cookie-anmodninger på cookie-bannere. Hvis ingen afvisningsmulighed er tilgængelig, kan Firefox acceptere alle cookies for at lukke banneret. + Firefox forsøger automatisk at afvise cookie-anmodninger på cookie-bannere. Hvis ingen afvisningsmulighed er tilgængelig, kan Firefox acceptere alle cookies for at lukke banneret. + + %1$s forsøger automatisk at afvise cookie-anmodninger på cookie-bannere. Slået fra for dette websted Slået til for dette websted + + Webstedet understøttes ikke i øjeblikket Vil du slå reduktion af cookie-bannere til for %1$s? @@ -357,14 +379,53 @@ %1$s vil rydde dette websteds cookies og genindlæse siden. Rydning af alle cookies kan logge dig ud eller tømme indkøbskurve. - %1$s kan forsøge automatisk at afvise cookie-anmodninger. Hvis der ikke er mulighed for dette, kan %2$s acceptere alle cookies for at lukke banneret. + %1$s kan forsøge automatisk at afvise cookie-anmodninger. Hvis der ikke er mulighed for dette, kan %2$s acceptere alle cookies for at lukke banneret. + + + %1$s kan forsøge automatisk at afvise cookie-anmodninger. + + %1$s forsøger automatisk at afvise alle cookie-anmodninger på understøttede websteder. + + Slut med cookie-bannere! + + Afvis automatisk cookie-anmodninger, når det er muligt. Ellers skal du acceptere alle cookies for at lukke cookie-bannere. + + Afvis automatisk cookie-anmodninger, når det er muligt. + + Tillad %1$s at automatisk afvise cookie-anmodninger, når det er muligt? + + Ikke nu + + Avis bannere + + Du vil få vist færre cookie-anmodninger + + Se færre pop op-beskeder om cookies + + Besvar automatisk cookie pop op-beskeder, så du kan surfe uden forstyrrelser. %1$s vil afvise alle forespørgsler, når det er muligt eller acceptere alle, hvis det ikke er muligt. + + Besvar automatisk cookie pop op-beskeder, så du kan surfe uden forstyrrelser. %1$s vil afvise alle forespørgsler, når det er muligt. + + Afvis pop op-beskeder om cookies + + Reduktion af cookie-bannere + + Tillad %1$s at afvise et websteds anmodning om samtykke til anvendelse af cookies, hvis det er muligt - eller at acceptere cookies, når det ikke er muligt? + + Tillad %1$s at afvise et websteds anmodning om samtykke til anvendelse af cookies, når det er muligt? + + Tillad Forsøger automatisk at oprette forbindelse til websteder ved hjælp af krypteringsprotokollen HTTPS for øget sikkerhed. - Til - + Til + Fra + + Aktiveret i alle faneblade + + Aktiveret i private faneblade Læs mere @@ -441,6 +502,11 @@ Meddelelser + + Tilladt + + Ikke tilladt + Tilpasset tilføjelses-samling @@ -464,9 +530,6 @@ a section where users see a list of tabs that they have visited in the past few days --> Besøgt for nylig - - Pocket - Tankevækkende historier @@ -721,6 +784,13 @@ Luk efter en måned + + Åbn på startside + + Åbn på seneste faneblad + + Åbn på startside efter fire timers inaktivitet + Flyt gamle faneblade til afsnittet Inaktive faneblade @@ -983,9 +1053,15 @@ Undtagelser - Til + Til Fra + + Standard + + Striks + + Tilpasset Tillad lyd og video @@ -1718,7 +1794,7 @@ Søgestreng der skal anvendes - Erstat forespørgslen med “%s”, Eksempel: \n https://www.google.com/search?q=%s + Erstat forespørgslen med “%s”, Eksempel: \n https://www.google.com/search?q=%s Detaljer om tilpasset søgetjeneste @@ -1917,8 +1993,6 @@ Historier efter emne Opdag mere - - Leveret af Pocket. Leveret af %s. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 0cc3f5dbc..482e8b62f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -69,11 +69,11 @@ - Fügen Sie eine Verknüpfung hinzu, um private Tabs vom Startbildschirm aus zu öffnen. + Fügen Sie eine Verknüpfung hinzu, um private Tabs vom Startbildschirm aus zu öffnen. Starten Sie den nächsten privaten Tab mit einem Fingertipp. - Verknüpfung hinzufügen + Verknüpfung hinzufügen Zum Startbildschirm hinzufügen @@ -174,6 +174,8 @@ Anhalten Add-ons + + Kontoinformationen Hier sind keine Add-ons @@ -265,7 +267,7 @@ Sucheinstellungen - Dieses Mal suchen: + Dieses Mal suchen: Dieses Mal suchen in: @@ -294,6 +296,18 @@ Schließen + + + Benachrichtigungen helfen Ihnen, mehr aus %s zu machen + + Synchronisieren Sie Ihre Tabs zwischen Geräten, verwalten Sie Downloads, erhalten Sie Tipps, wie Sie den Datenschutz von %s am besten nutzen können, und mehr. + + Fortsetzen + + Nicht jetzt + Neuen %1$s-Tab öffnen @@ -349,13 +363,21 @@ Reduzierung von Cookie-Bannern Cookie-Banner reduzieren + + Aus + + Ein - Firefox versucht automatisch, Cookie-Anfragen auf Cookie-Bannern abzulehnen. Wenn keine Ablehnungsoption verfügbar ist, akzeptiert Firefox möglicherweise alle Cookies, um das Banner zu schließen. + Firefox versucht automatisch, Cookie-Anfragen auf Cookie-Bannern abzulehnen. Wenn keine Ablehnungsoption verfügbar ist, akzeptiert Firefox möglicherweise alle Cookies, um das Banner zu schließen. + + %1$s versucht automatisch, Cookie-Anforderungen auf Cookie-Bannern abzulehnen. Für diese Website deaktiviert Für diese Website aktiviert + + Website derzeit nicht unterstützt Cookie-Banner-Reduzierung für %1$s aktivieren? @@ -363,14 +385,53 @@ %1$s löscht die Cookies dieser Webseite und aktualisiert die Seite. Das Löschen aller Cookies kann Sie abmelden oder Warenkörbe leeren. - %1$s kann versuchen, Cookie-Anfragen automatisch abzulehnen. Wenn keine Ablehnungsoption verfügbar ist, akzeptiert %2$s möglicherweise alle Cookies, um das Banner zu schließen. + %1$s kann versuchen, Cookie-Anfragen automatisch abzulehnen. Wenn keine Ablehnungsoption verfügbar ist, akzeptiert %2$s möglicherweise alle Cookies, um das Banner zu schließen. + + + %1$s kann versuchen, Cookie-Anfragen automatisch abzulehnen. + + %1$s versucht, alle Cookie-Anfragen auf unterstützten Websites automatisch abzulehnen. + + Weg mit Cookie-Bannern! + + Cookie-Anfragen werden nach Möglichkeit automatisch abgelehnt. Andernfalls werden alle Cookies akzeptiert, um Cookie-Banner zu schließen. + + Cookie-Anfragen nach Möglichkeit automatisch ablehnen. + + %1$s erlauben, Cookie-Anfragen nach Möglichkeit automatisch abzulehnen? + + Nicht jetzt + + Banner schließen + + Sie sehen weniger Cookie-Anfragen + + Weniger Cookie-Pop-ups sehen + + Beantworten Sie automatisch Cookie-Popups, um ablenkungsfrei zu Surfen. %1$s wird nach Möglichkeit alle Anfragen ablehnen oder alle akzeptieren, wenn dies nicht möglich ist. + + Beantworten Sie automatisch Cookie-Popups, um ablenkungsfrei zu Surfen. %1$s wird nach Möglichkeit alle Anfragen ablehnen. + + Pop-ups schließen + + Reduzierung von Cookie-Bannern + + %1$s erlauben, die Cookie-Zustimmungsanfrage einer Webseite nach Möglichkeit abzulehnen, oder den Cookie-Zugriff zu akzeptieren, wenn dies nicht möglich ist? + + %1$s erlauben, die Cookie-Zustimmungsanfrage einer Website nach Möglichkeit abzulehnen? + + Erlauben Automatisch versuchen, eine Verbindung zu Websites herzustellen, die das HTTPS-Verschlüsselungsprotokoll verwenden, um die Sicherheit zu erhöhen. - Ein - + Ein + Aus + + In allen Tabs aktiviert + + In privaten Tabs aktiviert Weitere Informationen @@ -449,6 +510,11 @@ Benachrichtigungen + + Erlaubt + + Nicht erlaubt + Benutzerdefinierte Add-on-Sammlung @@ -471,8 +537,6 @@ Kürzlich besucht - - Pocket Geschichten, die zum Nachdenken anregen @@ -732,6 +796,13 @@ Nach einem Monat schließen + + Auf der Startseite öffnen + + Auf dem letzten Tab öffnen + + Nach vier Stunden auf der Startseite öffnen + Alte Tabs zu „inaktiv“ verschieben @@ -1004,10 +1075,16 @@ Ausnahmen - Ein + Ein Aus + + Standard + + Streng + + Benutzerdefiniert Audio und Video erlauben @@ -1763,7 +1840,7 @@ Zu verwendender Such-String - Anfrage durch „%s“ ersetzen. Beispiel:\nhttps://www.google.com/search?q=%s + Anfrage durch „%s“ ersetzen. Beispiel:\nhttps://www.google.com/search?q=%s Details zur benutzerdefinierten Suchmaschine @@ -1963,8 +2040,6 @@ Geschichten nach Thema Mehr entdecken - - Bereitgestellt von Pocket Unterstützt durch %s. diff --git a/app/src/main/res/values-dsb/strings.xml b/app/src/main/res/values-dsb/strings.xml index 20b83c3ee..8ca3c03e9 100644 --- a/app/src/main/res/values-dsb/strings.xml +++ b/app/src/main/res/values-dsb/strings.xml @@ -14,6 +14,12 @@ Priwatny modus znjemóžniś Pytaś abo adresu zapódaś + + Historiju pśepytaś + + Cytańske znamjenja pśepytaś + + Rejtariki pśepytaś Pytańske wuraze zapódaś @@ -39,8 +45,6 @@ - Nejnowše cytańske znamjenja - Njedawno skłaźone Wšykne skłaźone cytańske znamjenja pokazaś @@ -62,10 +66,12 @@ - Pśidajśo skrotconku, aby priwatne rejtariki ze swójeje startoweje wobrazowki wócynił. + Pśidajśo skrotconku, aby priwatne rejtariki ze swójeje startoweje wobrazowki wócynił. - Skrotconku pśidaś - + Skrotconku pśidaś + + Startowej wobrazowce pśidaś + Ně, źěkujom se @@ -250,39 +256,19 @@ Pytańske nastajenja - - - Nowe funkcije a změny w %1$s - - Jo něnto lažčej tam pókšacowaś, źož sćo pśestał. - - Personalizěrowany startowy bok %1$s - - Pśejźćo k swójim wócynjonym rejtarikam, cytańskim znamjenjam a pśeglědowańskej historiji. - - Pśeglědne, organizěrowane rejtariki - - Wótwónoźćo rejtarikowy barłog pśez pólěpšone wugótowanje a awtomatiski zacynjajuce rejtariki. - - Nejnowše pytanja - - - Wótwołśo znowego swóje nejnowše pytanja ze swójogo startowego boka a rejtarikow. - - - Waša personalizěrowany startowy bok Firefox něnto wólažcujo tam pókšacowaś, źož sćo pśestał. Namakajśo swóje nejnowše rejtariki, cytańske znamjenja a pytańske wuslědki. + + Tenraz pytaś: + + Tenraz pytaś w: + Póznajśo swój personalizěrowany bok. Nejnowše rejtariki, cytańske znamjenja a pytańske wuslědki se how zjawiju. - Witajśo k njewótwisnemu internetoju - Witajśo k wěcej wósobinskemu internetoju Wěcej barwow. Lěpša priwatnosć. Samska angažěrowanosć za luźi njeźiwajucy na wudobytki. - Skócćo wó telefona do laptopa a slědk - Pśešaltowanje mjazy wobrazowkami jo lažke ako do togo Pókšacujśo, źož sćo pśestał – něnto z rejtarikami drugich rědow na swójom startowem boku. @@ -298,6 +284,11 @@ Zacyniś + + Dalej + + Nic něnto + Nowy rejtarik %1$s wócyniś @@ -348,11 +339,37 @@ Skrotconku za priwatny modus pśidaś Modus Jano-HTTPS + + + Reducěrowanje cookiejowych chórgojow + + Cookieje chórgoje reducěrowaś + + Za toś to sedło znjemóžnjony + + Za toś to sedło zmóžnjony + + Reducěrowanje cookiejowych chórgojow za %1$s zmóžniś? + + Reducěrowanje cookiejowych chórgojow za %1$s znjemóžniś? + + Nic něnto + + Chórgoje zachyśiś + + Mjenjej cookiejowych wuskokujucych woknow wiźeś + + Wuskokujuce wokna zachyśiś + + Reducěrowanje cookiejowych chórgojow + + Dowóliś + Wopytujo z pomocu koděrowańskego protokola HTTPS za pówušonu wěstotu awtomatiski ze sedłami zwězaś. - Zašaltowany - + Zašaltowany + Wušaltowany Dalšne informacije @@ -453,9 +470,11 @@ Pśed krotkim woglědane - - Pocket + + Tšojeńka, kótarež k rozmyslowanju pógnuwaju + + Nastawki spěchowane wót %s Sponserowane tšojeńka @@ -635,6 +654,14 @@ Zacyniś + + Slědujucu licbu rejtarikow wócyniś? %d + + Rejtarki wócyniś + + Pśetergnuś + %d sedło @@ -866,6 +893,10 @@ W nowem rejtariku wócyniś W nowem priwatnem rejtariku wócyniś + + Wšykne w nowych rejtarikach wócyniś + + Wšykne w nowych priwatnych rejtarikach wócyniś Lašowaś @@ -959,7 +990,7 @@ Wuwześa - Zašaltowany + Zašaltowany Wušaltowany @@ -1045,6 +1076,8 @@ Źěliś Ako PDF składowaś + + PDF njedajo se napóraś Rědoju pósłaś @@ -1055,8 +1088,6 @@ Do mjazywótkłada kopěrowaś Do mjazyskłada kopěrowane - - Pla Sync pśizjawiś Pla Sync pśizjawiś @@ -1096,6 +1127,12 @@ %1$s is a placeholder that will be replaced by the app name (Fenix). --> %1$s k wašomu standardnemu wobglědowakoju cyniś + + Wopytajśo priwatny modus + + Pśeglědujśo z %1$s bźez skłaźonych cookiejow abo historije + Zběrka jo se wulašowała @@ -1216,32 +1253,18 @@ Kupka so se wulašowała - - Witajśo k %s! - Witajśo k lěpšemu internetoju Wobglědowak za luźi, nic za wudobytk. - - Firefox mjazy rědami synchronizěrowaś Cyńśo tam dalej, źož sćo pśestał - - Pśinjasćo cytańske znamjenja, historiju a gronidła k %1$s na toś tom rěźe. - - Registrěrowaś Pśizjawiś Synchronizacija jo zmóžnjona - - Priwatnosć pśecej aktiwna Šćit priwatnosći pó standarźe - - %1$s awtomatiski pśedewześam zawoborujo, wam kšajźu pó webje slědowaś. Standard @@ -1252,18 +1275,11 @@ Blokěrujo dalšne pśeslědowaki, aby se boki malsnjej zacytali, ale někotare boki snaź korektnje njefunkcioněruju. Wubjeŕśo poziciju za swóju symbolowu rědku - - Pozicioněrujśo symbolowu rědku w swójej bliskosći. Wobchowajśo ju dołojce abo pśesuńśo ju górjej. Dołojce wóstajiś abo górjej pśesunuś. - - Waša priwatnosć Kontrolěrujośo swóje daty - - Smy %s wuwili, aby wam kontrolu wó tom dali, co online źěliśo a co z nami. Firefox wam kontrolu wó tom dajo, co online źěliśo a co z nami. @@ -1710,7 +1726,7 @@ Pytański wuraz, kótaryž ma se wužywaś - Napšašowanje z „%s“ wuměniś. Pśikład: \nhttps://www.google.com/search?q=%s + Napšašowanje z „%s“ wuměniś. Pśikład: \nhttps://www.google.com/search?q=%s Drobnostki swójskeje pytnice @@ -1880,6 +1896,15 @@ Awtomatiske zacynjanje zmóžnjone + + + Naraźenja Firefox + + + Pytanje z Google + + Z %s pytaś + Nastajśo wótkaze z websedłow, mejlkow a powěsćow, aby se awtomatiski we Firefox wócynili. @@ -1902,12 +1927,10 @@ Tšojeńka pó temje Wěcej wuslěźiś - - Wót Pocket spěchowany + + Spěchowany wót %s. Źěl swójźby Firefox. %s - - Sponsorowany @@ -1916,7 +1939,6 @@ Zmóžniśo telemetriju, aby daty słał. K nastajenjam - Naraźenja Firefox @@ -1925,4 +1947,6 @@ pokazaś wocyńśo wótkaz, aby wěcej wó toś tej zběrce zgónił + + nastawk cytaś diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index b99cb8b7a..bdf42b965 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -71,11 +71,11 @@ - Προσθέστε συντόμευση για άνοιγμα ιδιωτικών καρτελών από την αρχική οθόνη. + Προσθέστε συντόμευση για άνοιγμα ιδιωτικών καρτελών από την αρχική οθόνη. Εκκινήστε την επόμενη ιδιωτική καρτέλα με ένα πάτημα. - Προσθήκη συντόμευσης + Προσθήκη συντόμευσης Προσθήκη στην αρχική οθόνη @@ -90,7 +90,7 @@ Απόρριψη - Απόρριψη + Απόρριψη @@ -176,6 +176,8 @@ Διακοπή Πρόσθετα + + Πληροφορίες λογαριασμού Δεν βρέθηκαν πρόσθετα @@ -266,7 +268,7 @@ Ρυθμίσεις αναζήτησης - Αυτήν τη φορά, αναζήτηση: + Αυτήν τη φορά, αναζήτηση: Αυτήν τη φορά, αναζήτηση σε: @@ -294,6 +296,11 @@ Κλείσιμο + + Συνέχεια + + Όχι τώρα + Άνοιγμα νέας καρτέλας %1$s @@ -350,7 +357,7 @@ Μείωση μπάνερ cookie - Το Firefox προσπαθεί αυτόματα να απορρίψει τα αιτήματα cookie σε μπάνερ cookie. Εάν δεν διατίθεται επιλογή απόρριψης, το Firefox μπορεί να αποδεχτεί όλα τα cookies για να απορρίψει το μπάνερ. + Το Firefox προσπαθεί αυτόματα να απορρίψει τα αιτήματα cookie σε μπάνερ cookie. Εάν δεν διατίθεται επιλογή απόρριψης, το Firefox μπορεί να αποδεχτεί όλα τα cookies για να απορρίψει το μπάνερ. Ανενεργή για αυτόν τον ιστότοπο @@ -364,13 +371,20 @@ Το %1$s θα απαλείψει τα cookies του ιστοτόπου και θα ανανεώσει τη σελίδα. Η απαλοιφή όλων των cookies ενδέχεται να σας αποσυνδέσει ή να αδειάσει τα καλάθια αγορών. - Το %1$s προσπαθεί αυτόματα να απορρίψει τα αιτήματα cookie. Εάν δεν διατίθεται επιλογή απόρριψης, το %2$s μπορεί να αποδεχτεί όλα τα cookies για να απορρίψει το μπάνερ. + Το %1$s προσπαθεί αυτόματα να απορρίψει τα αιτήματα cookie. Εάν δεν διατίθεται επιλογή απόρριψης, το %2$s μπορεί να αποδεχτεί όλα τα cookies για να απορρίψει το μπάνερ. + + + Όχι τώρα + + Θα βλέπετε λιγότερα αιτήματα cookie + + Μείωση μπάνερ cookie Προσπαθεί αυτόματα να συνδεθεί σε ιστοτόπους με το πρωτόκολλο κρυπτογράφησης HTTPS για αυξημένη ασφάλεια. - Ενεργή - + Ενεργή + Ανενεργή Μάθετε περισσότερα @@ -472,8 +486,6 @@ Πρόσφατες επισκέψεις - - Pocket Άρθρα που σας βάζουν σε σκέψεις @@ -732,6 +744,9 @@ Κλείσιμο μετά από έναν μήνα + + Άνοιγμα στην αρχική σελίδα + Μετακίνηση παλαιών καρτελών στις ανενεργές @@ -997,7 +1012,7 @@ Εξαιρέσεις - Ενεργό + Ενεργό Ανενεργό @@ -1748,7 +1763,7 @@ Νήμα αναζήτησης προς χρήση - Αντικαταστήστε το ερώτημα με “%s”. Παράδειγμα:\nhttps://www.google.com/search?q=%s + Αντικαταστήστε το ερώτημα με “%s”. Παράδειγμα:\nhttps://www.google.com/search?q=%s Λεπτομέρειες προσαρμοσμένης μηχανής αναζήτησης @@ -1951,8 +1966,6 @@ Άρθρα ανά θέμα Ανακαλύψτε περισσότερα - - Με την υποστήριξη του Pocket. Με την υποστήριξη του %1$s. diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index dad6f4bf5..396742df1 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -65,11 +65,11 @@ - Add a shortcut to open private tabs from your Home screen. + Add a shortcut to open private tabs from your Home screen. Launch next private tab in one tap. - Add shortcut + Add shortcut Add to Home screen @@ -170,6 +170,8 @@ Stop Add-ons + + Account info No add-ons here @@ -258,7 +260,7 @@ Search settings - This time search: + This time search: This time search in: @@ -287,6 +289,18 @@ Close + + + Notifications help you do more with %s + + Synchronise your tabs between devices, manage downloads, get tips about making the most of %s’s privacy protection, and more. + + Continue + + Not now + Open a new %1$s tab @@ -341,13 +355,21 @@ Cookie Banner Reduction Reduce cookie banners + + Off + + On - Firefox automatically tries to reject cookie requests on cookie banners. If a reject option isn’t available, Firefox may accept all cookies to dismiss the banner. + Firefox automatically tries to reject cookie requests on cookie banners. If a reject option isn’t available, Firefox may accept all cookies to dismiss the banner. + + %1$s automatically tries to reject cookie requests on cookie banners. Off for this site On for this site + + Site currently not supported Turn on Cookie Banner Reduction for %1$s? @@ -355,14 +377,54 @@ %1$s will clear this site’s cookies and refresh the page. Clearing all cookies may sign you out or empty shopping carts. - %1$s can try to automatically reject cookie requests. If a reject option isn’t available, %2$s may accept all cookies to dismiss the banner. + %1$s can try to automatically reject cookie requests. If a reject option isn’t available, %2$s may accept all cookies to dismiss the banner. + + + %1$s can try to automatically reject cookie requests. + + %1$s tries to automatically reject all cookie requests on supported sites. + + Cookie banners begone! + + Automatically reject cookie requests, when possible. Otherwise, accept all cookies to dismiss cookie banners. + + Automatically reject cookie requests, when possible. + + Allow %1$s to automatically reject cookie requests when possible? + + Not Now + + Dismiss banners + + You’ll see fewer cookie requests + + See fewer cookie pop-ups + + Automatically answer cookie pop-ups for distraction-free browsing. %1$s will reject all requests if possible, or accept all if not. + + Automatically answer cookie pop-ups for distraction-free browsing. %1$s will reject all requests if possible. + + Dismiss Pop-ups + + Cookie Banner Reduction + + + Allow %1$s to decline a site’s cookie consent request if possible or accept cookie access when not possible? + + Allow %1$s to decline a site’s cookie consent request if possible? + + Allow Automatically attempts to connect to sites using HTTPS encryption protocol for increased security. - On - + On + Off + + On in all tabs + + On in private tabs Learn more @@ -441,6 +503,11 @@ Notifications + + Allowed + + Not allowed + Custom Add-on collection @@ -463,8 +530,6 @@ Recently visited - - Pocket Thought-provoking stories @@ -720,6 +785,13 @@ Close after one month + + Open on homepage + + Open on last tab + + Open on homepage after four hours + Move old tabs to inactive @@ -984,9 +1056,15 @@ Exceptions - On + On Off + + Standard + + Strict + + Custom Allow audio and video @@ -1719,7 +1797,7 @@ Search string to use - Replace query with “%s”. Example:\nhttps://www.google.com/search?q=%s + Replace query with “%s”. Example:\nhttps://www.google.com/search?q=%s Custom search engine details @@ -1919,8 +1997,6 @@ Stories by topic Discover more - - Powered by Pocket Powered by %s. diff --git a/app/src/main/res/values-es-rAR/strings.xml b/app/src/main/res/values-es-rAR/strings.xml index cca2808fa..b4e53750e 100644 --- a/app/src/main/res/values-es-rAR/strings.xml +++ b/app/src/main/res/values-es-rAR/strings.xml @@ -66,11 +66,11 @@ - Agregá un atajo para abrir pestañas privadas desde tu pantalla de inicio. + Agregá un atajo para abrir pestañas privadas desde tu pantalla de inicio. Abrir la siguiente pestaña privada con un solo toque. - Agregar atajo + Agregar atajo Agregar a pantalla de inicio @@ -172,6 +172,8 @@ Detener Complementos + + Información de la cuenta No hay complementos aquí @@ -256,7 +258,7 @@ %s va a compartir todo lo que escribas en la barra de direcciones con tu motor de búsqueda predeterminado. - Buscar %s + Buscar en %s Buscar directamente desde la barra de direcciones @@ -264,7 +266,7 @@ Configuración de búsqueda - Esta vez buscá: + Esta vez buscar: Esta vez, buscar en: @@ -294,6 +296,19 @@ Cerrar + + + Las notificaciones te ayudan a hacer más con %s + + + Sincronizá tus pestañas entre dispositivos, administrá descargas, obtené consejos sobre cómo aprovechar al máximo la protección de privacidad de %s y más. + + Continuar + + No ahora + Abrir una nueva pestaña de %1$s @@ -345,16 +360,24 @@ Modo solo HTTPS - Reducción de pancarta de cookies + Reducción de mensajes de cookies - Reducir las pancartas de cookies + Reducir mensajes de cookies + + Desactivado + + Activado - Firefox intenta rechazar automáticamente las solicitudes de cookies en las pancartas de cookies. Si una opción de rechazo no está disponible, Firefox puede aceptar todas las cookies para descartar la pancarta. + Firefox intenta rechazar automáticamente las solicitudes de cookies en los mensajes de cookies. Si una opción de rechazo no está disponible, Firefox puede aceptar todas las cookies para descartar el mensaje. + + %1$s intenta rechazar automáticamente las solicitudes de cookies en las pancartas de cookies. Desactivada para este sitio Habilitada para este sitio + + Sitio actualmente no soportado ¿Habilitar reducción de mensajes de cookies para %1$s? @@ -362,14 +385,53 @@ %1$s borrará las cookies de este sitio y actualizará la página. Borrar todas las cookies puede cerrar la sesión o vaciar los carritos de compras. - %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s puede aceptar todas las cookies para descartar el mensaje. + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s puede aceptar todas las cookies para descartar el mensaje. + + + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. + + %1$s puede intentar rechazar automáticamente todos los pedidos de cookies en sitios soportados. + + ¡Los mensajes de cookies se fueron! + + Rechazar automáticamente los pedidos de cookies cuando sea posible. De otra manera, aceptar todas las cookies para descartar los mensajes de cookies. + + Rechazar automáticamente las solicitudes de cookies cuando sea posible. + + ¿Permitir que %1$s automáticamente rechace lospedidos de cookies cuando sea pposible? + + No ahora + + Descartar mensajes + + Vas a ver menos pedidos de cookies + + Ver menos emergentes de cookies + + Responder automáticamente a las ventanas emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible o aceptará todas si no. + + Responder automáticamente a las ventanas emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible. + + Descartar emergentes + + Reducción de mensajes de cookies + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible o acepte el acceso de cookies cuando no sea posible? + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible? + + Permitir Intenta conectarse automáticamente a sitios usando el protocolo de cifrado HTTPS para mayor seguridad. - Activado - + Activado + Desactivado + + Sí, en todas las pestañas + + Sí, en pestañas privadas Conocer más @@ -448,6 +510,11 @@ Notificaciones + + Permitido + + No permitido + Colección personalizada de complementos @@ -470,8 +537,6 @@ Visitados recientemente - - Pocket Historias que te hacen reflexionar @@ -735,6 +800,13 @@ Cerrar después de un mes + + Abrir en la página de inicio + + Abrir en la última pestaña + + Abrir en la página de inicio después de cuatro horas + Mover pestañas antiguas a inactivas @@ -1006,10 +1078,16 @@ Excepciones - Activado + Activado Desactivada + + Estándar + + Estricta + + Personalizada Permitir audio y video @@ -1753,7 +1831,7 @@ Cadena de búsqueda para usar - Reemplazar la consulta con "%s". Ejemplo:\n https://www.google.com/search?q=%s + Reemplazar la consulta con "%s". Ejemplo:\n https://www.google.com/search?q=%s Detalles del motor de búsqueda personalizado @@ -1956,8 +2034,6 @@ Historias por tema Descubrir más - - Desarrollado por Pocket. Impulsado por %s. @@ -1981,5 +2057,5 @@ abrir enlace para conocer más sobre esta colección - + leer el artículo diff --git a/app/src/main/res/values-es-rCL/strings.xml b/app/src/main/res/values-es-rCL/strings.xml index a65c60b62..5f7aed7c2 100644 --- a/app/src/main/res/values-es-rCL/strings.xml +++ b/app/src/main/res/values-es-rCL/strings.xml @@ -65,11 +65,11 @@ - Añade un acceso directo para abrir pestañas privadas desde tu pantalla de inicio. + Añade un acceso directo para abrir pestañas privadas desde tu pantalla de inicio. Iniciar la siguiente pestaña privada con un solo toque. - Añadir acceso directo + Añadir acceso directo Añadir a la pantalla de inicio @@ -171,6 +171,8 @@ Detener Complementos + + Información de la cuenta No hay complementos aquí @@ -259,7 +261,7 @@ Buscar ajustes - Esta vez buscar: + Esta vez buscar: Esta vez buscar en: @@ -288,6 +290,18 @@ Cerrar + + + Las notificaciones te ayudan a hacer más con %s + + Sincroniza tus pestañas entre dispositivos, administra descargas, obtén consejos sobre cómo aprovechar al máximo la protección de privacidad de %s y más. + + Continuar + + Ahora no + Abrir una nueva pestaña de %1$s @@ -342,13 +356,21 @@ Reducción de anuncios de cookies Reducir los anuncios de cookies + + No + + - Firefox intenta rechazar automáticamente las solicitudes de cookies en los anuncios de cookies. Si una opción de rechazo no está disponible, Firefox podría aceptar todas las cookies para cerrar el anuncio. + Firefox intenta rechazar automáticamente las solicitudes de cookies en los anuncios de cookies. Si una opción de rechazo no está disponible, Firefox podría aceptar todas las cookies para cerrar el anuncio. + + %1$s intenta rechazar automáticamente las solicitudes de cookies en los anuncios de cookies. ACTIVADA para este sitio Activada para este sitio + + Sitio actualmente no soportado ¿Activar la reducción de anuncios de cookies para %1$s? @@ -356,14 +378,53 @@ %1$s borrará las cookies de este sitio y recargará la página. Borrar todas las cookies puede cerrar tu sesión o vaciar los carritos de compras. - %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s podría aceptar todas las cookies para cerrar el anuncio. + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s podría aceptar todas las cookies para cerrar el anuncio. + + + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. + + %1$s intenta rechazar automáticamente todas las solicitudes de cookies en sitios soportados. + + ¡Se acabaron los anuncios de cookies! + + Rechaza automáticamente las solicitudes de cookies, cuando sea posible. De lo contrario, acepta todas las cookies para descartar los anuncios de cookies. + + Rechaza automáticamente las solicitudes de cookies, cuando sea posible. + + Permitir a %1$s rechazar automáticamente las solicitudes de cookies, cuando sea posible. + + Ahora no + + Ocultar anuncios + + Verás menos solicitudes de cookies + + Ver menos ventanas emergentes de cookies + + Responde automáticamente las ventanas emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible, o aceptará todas si no. + + Responde automáticamente las ventanas emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible. + + Descartar ventanas emergentes + + Reducción de anuncios de cookies + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible o acepte las cookies cuando no sea posible? + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible? + + Permitir Intenta conectarse automáticamente a sitios utilizando el protocolo de cifrado HTTPS para mayor seguridad. - - + + No + + Sí, en todas las pestañas + + Sí, en pestañas privadas Aprender más @@ -442,6 +503,11 @@ Notificaciones + + Permitido + + No permitido + Colección de complementos personalizada @@ -464,8 +530,6 @@ Visitados recientemente - - Pocket Historias que te hacen reflexionar @@ -722,6 +786,13 @@ Cerrar después de un mes + + Abrir en la página de inicio + + Abrir en la última pestaña + + Abrir en la página de inicio después de cuatro horas + Mover pestañas antiguas a inactivas @@ -987,9 +1058,15 @@ Excepciones - + No + + Estándar + + Estricta + + Personalizada Permitir audio y video @@ -1726,7 +1803,7 @@ Cadena de búsqueda a usar - Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s + Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s Detalles del motor de búsqueda personalizado @@ -1926,8 +2003,6 @@ Historias por tema Descubrir más - - Impulsado por Pocket. Con la tecnología de %s. diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 762110e46..a12bbb7c2 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -68,11 +68,11 @@ - Añadir un acceso directo para abrir pestañas privadas desde la pantalla de inicio. + Añadir un acceso directo para abrir pestañas privadas desde la pantalla de inicio. Lanza lla siguiente pestaña privada con un solo toque. - Agregar acceso directo + Agregar acceso directo Añadir a la pantalla de inicio @@ -174,6 +174,8 @@ Detener Complementos + + Información de la cuenta No hay complementos aquí @@ -265,7 +267,7 @@ Configuración de búsquedas - Buscar esta vez: + Buscar esta vez: Esta vez buscar en: @@ -294,6 +296,18 @@ Cerrar + + + Las notificaciones te ayudan a hacer más con %s + + Sincroniza tus pestañas entre dispositivos, administra descargas, obtén consejos sobre cómo aprovechar al máximo la protección de privacidad de %s y más. + + Continuar + + Ahora no + Abrir una pestaña nueva de %1$s @@ -350,13 +364,21 @@ Reducción de avisos de cookies Reducir los avisos de cookies + + Desactivado + + Activado - Firefox intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies. Si no está disponible una opción de rechazo, Firefox podría aceptar todas las cookies para cerrar el aviso. + Firefox intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies. Si no está disponible una opción de rechazo, Firefox podría aceptar todas las cookies para cerrar el aviso. + + %1$s intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies. Desactivada para este sitio Activada para este sitio + + Sitio actualmente no compatible ¿Activar la reducción de aviso de cookies para %1$s? @@ -364,14 +386,53 @@ %1$s borrará las cookies de este sitio y recargará la página. Borrar todas las cookies puede cerrar tu sesión o vaciar los carritos de compras. - %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s podría aceptar todas las cookies para cerrar el aviso. + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s podría aceptar todas las cookies para cerrar el aviso. + + + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. + + %1$s intenta rechazar automáticamente las solicitudes de cookies en sitios compatibles. + + ¡Se acabaron los avisos de cookies! + + Rechazar automáticamente las solicitudes de cookies cuando sea posible. En caso contrario, aceptar todas las cookies para descartar los avisos de cookies. + + Rechazar automáticamente las solicitudes de cookies, cuando sea posible. + + ¿Permitir que %1$s rechace automáticamente las solicitudes de cookies cuando sea posible? + + Ahora no + + Descartar avisos + + Verás menos solicitudes de cookies + + Ver menos avisos emergentes de cookies + + Responder automáticamente a los avisos emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible o aceptará todas si no lo es. + + Responder automáticamente a los avisos emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible. + + Descartar emergentes + + Reducción de avisos de cookies + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible o acepte el acceso de cookies cuando no sea posible? + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible? + + Permitir Intenta conectarse automáticamente a sitios utilizando el protocolo de cifrado HTTPS para mayor seguridad. - Activado - + Activado + Desactivado + + Activado en todas las pestañas + + Activado en las pestañas privadas Saber más @@ -450,6 +511,11 @@ Notificaciones + + Permitido + + No permitido + Colección de complementos personalizada @@ -472,8 +538,6 @@ Visitados recientemente - - Pocket Historias que te hacen reflexionar @@ -732,6 +796,13 @@ Cerrar después de un mes + + Abrir en la página de inicio + + Abrir en la última pestaña + + Abrir en la página de inicio después de cuatro horas + Mover las pestañas antiguas a inactivas @@ -1000,10 +1071,16 @@ Excepciones - Activada + Activada Desactivada + + Estándar + + Estricto + + Personalizado Permitir audio y vídeo @@ -1765,7 +1842,7 @@ Cadena de búsqueda a usar - Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s + Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s Detalles del buscador personalizado @@ -1966,8 +2043,6 @@ Historias por tema Descubrir más - - Desarrollado por Pocket. Impulsado por %s. diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index 1d281283c..f89fef110 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -63,11 +63,11 @@ - Agregar un acceso directo para abrir pestañas privadas desde su pantalla de inicio. + Agregar un acceso directo para abrir pestañas privadas desde su pantalla de inicio. Inicia la siguiente pestaña privada con un toque. - Agregar acceso directo + Agregar acceso directo Agregar a la pantalla de inicio @@ -82,7 +82,7 @@ Descartar - Descartar + Descartar @@ -170,6 +170,8 @@ Detener Complementos + + Información de la cuenta No hay complementos aquí @@ -259,7 +261,7 @@ Ajustes de búsqueda - Busca esta vez: + Busca esta vez: Esta vez buscar en: @@ -288,6 +290,18 @@ Cerrar + + + Las notificaciones te ayudan a hacer más con %s + + Sincroniza tus pestañas entre dispositivos, administra descargas, obtén consejos sobre cómo aprovechar al máximo la protección de privacidad de %s y más. + + Continuar + + Ahora no + Abrir una nueva pestaña en %1$s @@ -344,12 +358,16 @@ Reducir banners de cookies - Firefox intenta rechazar automáticamente las solicitudes de cookies en los banners de cookies. Si una opción de rechazo no está disponible, Firefox puede aceptar todas las cookies para descartar el banner. + Firefox intenta rechazar automáticamente las solicitudes de cookies en los banners de cookies. Si una opción de rechazo no está disponible, Firefox puede aceptar todas las cookies para descartar el banner. + + %1$s intenta rechazar automáticamente las solicitudes de cookies en los banners de cookies. Desactivar para este sitio Activar para este sitio + + Sitio actualmente no soportado ¿Activar la reducción de banner de cookies para %1$s? @@ -358,14 +376,43 @@ %1$s borrará las cookies de este sitio y actualizará la página. Borrar todas las cookies puede cerrar tu sesión o vaciar los carritos de compras. - %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s puede aceptar todas las cookies para descartar el banner. + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s puede aceptar todas las cookies para descartar el banner. + + + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. + + %1$s intenta rechazar automáticamente todas las solicitudes de cookies en los sitios admitidos. + + Rechazar automáticamente las solicitudes de cookies, cuando sea posible. De lo contrario, aceptar todas las cookies para descartar los banners de cookies. + + Rechazar automáticamente las solicitudes de cookies, cuando sea posible. + + ¿Permitir que %1$s rechace automáticamente las solicitudes de cookies cuando sea posible? + + Ahora no + + Descartar banners + + Verás menos solicitudes de cookies + + Ver menos ventanas emergentes de cookies + + Descartar ventanas emergentes + + Reducción de banner de cookies + + Permitir Intentar conectarse automáticamente a sitios que utilizan el protocolo de encriptación HTTPS para mayor seguridad. - Activado - + Activado + Desactivado + + Activado en todas las pestañas + + Activado en pestañas privadas Saber más @@ -443,6 +490,11 @@ Notificaciones + + Permitido + + No permitido + Colección de complementos personalizada @@ -466,9 +518,6 @@ a section where users see a list of tabs that they have visited in the past few days --> Visitados recientemente - - Pocket - Historias que invitan a la reflexión @@ -725,6 +774,13 @@ Cerrar después de un mes + + Abrir en la página de inicio + + Abrir en la última pestaña + + Abrir en la página de inicio después de cuatro horas + Mover pestañas antiguas a inactivas @@ -989,9 +1045,15 @@ Excepciones - Activada + Activada Desactivada + + Estándar + + Estricto + + Personalizado Permitir audio y video @@ -1729,7 +1791,7 @@ Cadena de búsqueda a usar - Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s + Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s Detalles del motor de búsqueda personalizado @@ -1931,8 +1993,6 @@ Historias por tema Descubrir más - - Desarrollado por Pocket. Impulsado por %s. diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 762110e46..a12bbb7c2 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -68,11 +68,11 @@ - Añadir un acceso directo para abrir pestañas privadas desde la pantalla de inicio. + Añadir un acceso directo para abrir pestañas privadas desde la pantalla de inicio. Lanza lla siguiente pestaña privada con un solo toque. - Agregar acceso directo + Agregar acceso directo Añadir a la pantalla de inicio @@ -174,6 +174,8 @@ Detener Complementos + + Información de la cuenta No hay complementos aquí @@ -265,7 +267,7 @@ Configuración de búsquedas - Buscar esta vez: + Buscar esta vez: Esta vez buscar en: @@ -294,6 +296,18 @@ Cerrar + + + Las notificaciones te ayudan a hacer más con %s + + Sincroniza tus pestañas entre dispositivos, administra descargas, obtén consejos sobre cómo aprovechar al máximo la protección de privacidad de %s y más. + + Continuar + + Ahora no + Abrir una pestaña nueva de %1$s @@ -350,13 +364,21 @@ Reducción de avisos de cookies Reducir los avisos de cookies + + Desactivado + + Activado - Firefox intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies. Si no está disponible una opción de rechazo, Firefox podría aceptar todas las cookies para cerrar el aviso. + Firefox intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies. Si no está disponible una opción de rechazo, Firefox podría aceptar todas las cookies para cerrar el aviso. + + %1$s intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies. Desactivada para este sitio Activada para este sitio + + Sitio actualmente no compatible ¿Activar la reducción de aviso de cookies para %1$s? @@ -364,14 +386,53 @@ %1$s borrará las cookies de este sitio y recargará la página. Borrar todas las cookies puede cerrar tu sesión o vaciar los carritos de compras. - %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s podría aceptar todas las cookies para cerrar el aviso. + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. Si una opción de rechazo no está disponible, %2$s podría aceptar todas las cookies para cerrar el aviso. + + + %1$s puede intentar rechazar automáticamente las solicitudes de cookies. + + %1$s intenta rechazar automáticamente las solicitudes de cookies en sitios compatibles. + + ¡Se acabaron los avisos de cookies! + + Rechazar automáticamente las solicitudes de cookies cuando sea posible. En caso contrario, aceptar todas las cookies para descartar los avisos de cookies. + + Rechazar automáticamente las solicitudes de cookies, cuando sea posible. + + ¿Permitir que %1$s rechace automáticamente las solicitudes de cookies cuando sea posible? + + Ahora no + + Descartar avisos + + Verás menos solicitudes de cookies + + Ver menos avisos emergentes de cookies + + Responder automáticamente a los avisos emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible o aceptará todas si no lo es. + + Responder automáticamente a los avisos emergentes de cookies para navegar sin distracciones. %1$s rechazará todas las solicitudes si es posible. + + Descartar emergentes + + Reducción de avisos de cookies + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible o acepte el acceso de cookies cuando no sea posible? + + ¿Permitir que %1$s rechace la solicitud de consentimiento de cookies de un sitio si es posible? + + Permitir Intenta conectarse automáticamente a sitios utilizando el protocolo de cifrado HTTPS para mayor seguridad. - Activado - + Activado + Desactivado + + Activado en todas las pestañas + + Activado en las pestañas privadas Saber más @@ -450,6 +511,11 @@ Notificaciones + + Permitido + + No permitido + Colección de complementos personalizada @@ -472,8 +538,6 @@ Visitados recientemente - - Pocket Historias que te hacen reflexionar @@ -732,6 +796,13 @@ Cerrar después de un mes + + Abrir en la página de inicio + + Abrir en la última pestaña + + Abrir en la página de inicio después de cuatro horas + Mover las pestañas antiguas a inactivas @@ -1000,10 +1071,16 @@ Excepciones - Activada + Activada Desactivada + + Estándar + + Estricto + + Personalizado Permitir audio y vídeo @@ -1765,7 +1842,7 @@ Cadena de búsqueda a usar - Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s + Reemplazar la consulta con “%s”. Ejemplo:\n https://www.google.com/search?q=%s Detalles del buscador personalizado @@ -1966,8 +2043,6 @@ Historias por tema Descubrir más - - Desarrollado por Pocket. Impulsado por %s. diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index b907e1ea7..723a9067e 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -67,11 +67,11 @@ - Gehitu lasterbidea fitxa pribatuak zure hasierako pantailatik irekitzeko. + Gehitu lasterbidea fitxa pribatuak zure hasierako pantailatik irekitzeko. Sakatu behin hurrengo fitxa pribatua abiarazteko. - Gehitu lasterbidea + Gehitu lasterbidea Gehitu hasierako pantailan @@ -86,7 +86,7 @@ Baztertu - Baztertu + Baztertu @@ -171,6 +171,8 @@ Gelditu Gehigarriak + + Kontuaren informazioa Gehigarririk ez hemen @@ -263,7 +265,7 @@ Bilaketa-ezarpenak - Oraingoan, bilatu: + Oraingoan, bilatu: Oraingoan, bilatu honekin: @@ -291,6 +293,18 @@ Itxi + + + Jakinarazpenek %s(r)i zuku gehiago ateratzen laguntzen dute + + Sinkronizatu zure fitxak gailuen artean, kudeatu deskargak, jaso aholkuak %s(r)en pribatutasun-babesari zuku gehien ateratzeko, eta gehiago. + + Jarraitu + + Une honetan ez + Ireki %1$s fitxa berria @@ -346,13 +360,21 @@ Murriztu cookie iragarki-bandak + + Desaktibatuta + + Aktibatuta - Firefox automatikoki saiatzen da cookie iragarki-bandetako eskaerak ukatzen. Ukatzeko aukera ez badago erabilgarri, Firefoxek cookie guztiak onar litzake iragarki-banda baztertzeko. + Firefox automatikoki saiatzen da cookie iragarki-bandetako eskaerak ukatzen. Ukatzeko aukera ez badago erabilgarri, Firefoxek cookie guztiak onar litzake iragarki-banda baztertzeko. + + Cookie iragarki-bandetako eskaerak automatikoki ukatzen saiatzen da %1$s. Desaktibatuta gune honetarako Aktibatuta gune honetarako + + Une honetan gune honetarako euskarririk ez Aktibatu cookie iragarki-banden murrizpena %1$s gunerako? @@ -360,14 +382,54 @@ %1$s(e)k gune honetako cookieak garbitu eta orria berrituko du. Cookie guztiak garbitzean, saioak amaitu edo erosketa-orgak hustu litezke. - %1$s saia daiteke cookie iragarki-bandetako eskaerak automatikoki ukatzen. Ukatzeko aukera ez badago erabilgarri, %2$s(e)k cookie guztiak onar litzake iragarki-banda baztertzeko. + %1$s saia daiteke cookie iragarki-bandetako eskaerak automatikoki ukatzen. Ukatzeko aukera ez badago erabilgarri, %2$s(e)k cookie guztiak onar litzake iragarki-banda baztertzeko. + + + %1$s automatikoki saia daiteke cookie-eskaerak ukatzen. + + Cookie eskaerak automatikoki ukatzen saiatzen da %1$s. + + Cookie iragarki-bandak kanpora! + + Ahal bada, ukatu automatikoki cookie eskaerak. Bestela, onartu cookie guztiak iragarki-bandak baztertzeko. + + Ahal bada, automatikoki ukatu cookie eskaerak. + + Baimendu %1$s(r)i ahal duenean cookie eskaerak automatikoki ukatzen? + + Une honetan ez + + Baztertu iragarki-bandak + + Cookie eskaera gutxiago ikusiko dituzu + + Ikusi cookie laster-leiho gutxiago + + + Erantzun automatikoki cookie laster-leihoak distraziorik gabe nabigatzeko. Ahal bada, eskaera guztiak ukatuko ditu %1$s(e)k, edo ezin bada, guztiak onartuko ditu. + + Erantzun automatikoki cookie laster-leihoak distraziorik gabe nabigatzeko. Ahal bada, eskaera guztiak ukatuko ditu %1$s(e)k. + + Baztertu laster-leihoak + + Cookie iragarki-banden murrizpena + + Baimendu %1$s(e)k gune baten cookie onespen-eskaera ukatzea edo ezin bada, baimendu cookietarako sarbidea? + + Baimendu %1$s(e)k ahal bada gune bateko cookie onespen-eskaera ukatzea? + + Baimendu Automatikoki saiatzen da guneetara konektatzen HTTPS zifratze-protokoloa erabiliz, segurtasun gehiago lortzeko. - Aktibatuta - + Aktibatuta + Desaktibatuta + + Fitxa guztietan aktibatuta + + Fitxa pribatuetan aktibatuta Argibide gehiago @@ -446,6 +508,11 @@ Jakinarazpenak + + Baimenduta + + Ez dago baimenduta + Gehigarrien bilduma pertsonalizatua @@ -468,8 +535,6 @@ Bisitatutako azkenak - - Pocket Hausnartzeko moduko istorioak @@ -730,6 +795,13 @@ Itxi hilabete ondoren + + Ireki hasiera-orrian + + Ireki azken fitxan + + Ireki hasiera-orrian lau ordu ondoren + Eraman fitxa zaharrak inaktiboetara @@ -995,10 +1067,16 @@ Salbuespenak - Aktibatuta + Aktibatuta Desaktibatuta + + Oinarrizkoa + + Zorrotza + + Pertsonalizatua Baimendu audioa eta bideoa @@ -1736,7 +1814,7 @@ Erabili beharreko bilaketa-katea - Ordezkatu galdera-katea "%s" testuarekin. Adibidez:\nhttps://www.google.com/search?q=%s + Ordezkatu galdera-katea "%s" testuarekin. Adibidez:\nhttps://www.google.com/search?q=%s Bilaketa-motor pertsonalizatuaren xehetasunak @@ -1937,8 +2015,6 @@ Gaiaren araberako istorioak Aurkitu gehiago - - Pocket-ek hornitua. %s(e)k hornitua. diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 68192241e..aff27de2f 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -20,11 +20,6 @@ زبانه‌های خصوصی شما در اینجا نشان داده می‌شوند. - - 1 زبانهٔ باز. برای تغییر زبانه‌ها ضربه بزنید. - - %1$s زبانهٔ باز. برای تغییر زبانه‌ها ضربه بزنید. - %1$d زبانه انتخاب شد @@ -37,50 +32,28 @@ از حالت چند انتخابی خارج شوید ذخیره‌سازی زبانه‌های انتخاب شده داخل مجموعه - - %1$s انتخاب شد - - انتخاب نشدند %1$s - - از حالت چند انتخابی خارج شوید - - شما وارد حالت چند انتخابی شده‌اید،‌ جهت ذخیره‌ سازی زبانه ها در مجموعه آن‌ها را انتخاب کنید انتخاب شده - - نشانک‌گذاری‌های اخیرا ذخیره شده - - نمایش همه - - نمایش دکمه همه نشانک‌گذاری‌های ذخیره شده - %1$s توسط موزیلا تولید شده است. - - شما در یک جلسه خصوصی هستید %1$s جست‌وجوها و تاریخچه مرور شما را هنگام خروج از برنامه یا بستن زبانه‌های خصوصی پاک می‌کند. در حالی که اینکار شما را برای وب‌سایت‌ها یا خدمات دهنده اینترنت ناشناس نمی‌کند، این کار مخفی کردن فعالیت‌های آنلاین شما را برای هرکس دیگری که از این دستگاه استفاده می‌کند را ساده‌تر می‌کند. باورهای غلط و رایج در مورد مرور خصوصی - - حذف جلسه - یک میان‌بر برای بازکردن زبانه‌های خصوصی از صفحهٔ خانه، اضافه کنید. + یک میان‌بر برای بازکردن زبانه‌های خصوصی از صفحهٔ خانه، اضافه کنید. - افزودن میان‌بر - + افزودن میان‌بر + نه، ممنون - - - شما می‌توانید Firefox را برای بازکردن خودکار پیوندهای درون برنامه‌ها، تنظیم کنید. برو به تنظیمات @@ -108,9 +81,6 @@ زبانهٔ خصوصی جدید - - سایت‌های برتر - برگردید به داخل @@ -118,8 +88,6 @@ نمایش همه - - زبانه‌های باز عقب @@ -128,14 +96,8 @@ نوسازی توقف - - نشانک - - ویرایش نشانک افزونه‌ها - - افزونه‌ها هیچ افزونه‌ای اینجا نیست @@ -152,20 +114,14 @@ افزودن به صفحه خانگی نصب - - زبانه‌های همگام شده همگام‌سازی مجدد پیدا کردن در صفحه - - زبانهٔ خصوصی افزودن به مجموعه اشتراک‌گذاری - - اشتراک‌گذاری با… بازکردن در %1$s @@ -181,8 +137,6 @@ بستن نمای مطالعه باز کردن در برنامه - - ظاهر سفارشی‌سازی نمای مطالعه @@ -195,15 +149,9 @@ صفحه خانگی - - اتصال امکان پذیر نیست. طرح آدرس غیرقابل تشخیص است. - انتخاب زبان - - جست‌وجو زبان دستگاه را دنبال کنید @@ -216,8 +164,6 @@ موتور جست‌وجو تنظیمات موتور جستجو - - این بار بگرد با: تکمیل پیوند از بُریده‌دان @@ -228,17 +174,12 @@ پیشنهادات جستجو در نشست‌های خصوصی مجاز است؟ %s هرچیزی را که در نوار آدرس وارد نوشته‌اید را به موتور جست‌وجو ارسال می‌کند. - - بیشتر بدانید جست‌وجو در %s مستقیماً از نوار آدرس جستجو کنید - - - بازکردن یک زبانه فایرفاکس جدید جست‌وجو @@ -250,8 +191,6 @@ تنظیمات - - پایه عمومی @@ -262,27 +201,15 @@ جستجو نوار آدرس - - راهنما امتیاز دادن در Google Play - - ارسال بازخورد درباره %1$s - - حقوق شما - - گذرواژه‌ها - - کارت‌های اعتباری و آدرس‌ها تبدیل به مرورگر پیش‌فرض پیشرفته - - حریم خصوصی حریم خصوصی و امنیت @@ -297,6 +224,7 @@ در صورت اجازه، هنگام باز شدن چندین برنامه، زبانه‌های خصوصی نیز قابل مشاهده خواهند بود افزودن میان‌بر مرور خصوصی + دسترسی‌پذیری @@ -307,8 +235,6 @@ سرور حساب/همگام‌سازی فایرفاکس اصلاح شده است. ترک برنامه موجب اعمال تغییرات خواهد شد… حساب کاربری - - وارد شدن نوار ابزار @@ -317,8 +243,6 @@ اشارات سفارشی‌سازی - - شروع به همگام سازی نشانک‌ها،‌ گذرواژه ها و چیزهای بیشتر با حساب فایرفاکس شما. حساب فایرفاکس @@ -329,10 +253,6 @@ انتخاب داده‌ها جمع آوری داده ها - - اطلاعیه حریم‌شخصی - - ابزارهای توسعه‌دهندگان رفع اشکال از راه دور به واسطه‌ی USB @@ -385,9 +305,6 @@ بازدید‌های اخیر - - جستجوهای اخیر @@ -442,22 +359,12 @@ اعلانها برای زبانه دریافت شده از سایر دستگاه های Firefox. زبانه دریافت شد - - زبانه‌ها دریافت شدند زبانه از %s - - محافظت در برابر ردگیری - - محافظت در برابر ردگیری - - محتوا و اسکریپت هایی را که شما را به صورت آنلاین ردیابی می کنند ، مسدود کنید استثناها - - محاظفت در برابر دنبال شدن برای این پایگاه اینترنتی خاموش شده است برای همه‌ی سایت‌ها روشن شود @@ -465,40 +372,19 @@ بیشتر بدانید - - دور سنجی میزان استفاده و داده فنی به اشتراک‌گذاری کارایی، کاربرد، سخت‌افزار و اطلاعات سفارشی‌سازی در مورد مرورگر شما با موزیلا به ما کمک می کند تا %1$s بهتری داشته باشیم ارزیابی داده - - به اشتراک‌ گذاری داده‌هایی در خصوص ویژیگی که شما در %1$s با Leanplum تیم فروش موبایل ما. داده‌های کاربردی اولیه را با Adjust، فراهم‌کنندهٔ بازریابی سیستم موبایل ما، اشتراک بگذارید مطالعات به موزیلا اجازه دهید تا افزونه‌های مطالعاتی را نصب و اجرا کند - - آزمون ها - - به موزیلا اجازه می دهم داده های ویژگی های آزمایشی را نصب و جمع آوری کند - - گزارشگر فروپاشی - - سرویس موقعیت مکانی موزیلا - - گزارش سلامت %s - - - - روشن کردن همگام سازی - - کد جفت گیری در فایرفاکس رومیزی را اسکن کنید - - ورود + برای اتصال مجدد وارد شوید @@ -507,10 +393,6 @@ firefox.com/pair را اسکن کنید]]> - - بازکردن دوربین - - انصراف @@ -539,10 +421,6 @@ برای باز کردن زبانه‌ها، نوار ابزار را به سمت بالا بکشید - - جلسات - - تصاویر صفحه بارگیری‌ها @@ -559,16 +437,8 @@ تاریخچه زبانهٔ جدید - - پیدا کردن در صفحه - - فهرست خواندن - - جست‌وجو تنظیمات - - مورد تاریخ در فهرست بستن @@ -601,10 +471,6 @@ فهرستی شبکه‌ای - - گروه‌های جستجو - - قرار دادن سایت‌های مرتبط در یک گروه بستن زبانه‌ها @@ -634,8 +500,6 @@ فعال - - فایرفاکس ممکن است هر از گاهی تحقیقاتی رو نصب و اجرا کند. بیشتر بدانید @@ -652,8 +516,6 @@ زبانه‌های باز - جلسه خصوصی - برگه خصوصی زبانه‌های همگام‌سازی شده @@ -665,12 +527,6 @@ خصوصی هم‌گام‌سازی - - زبانه‌های باز - - افزودن به مجموعه - - انتخاب به اشتراک‌گذار همه‌ی زبانه‌ها @@ -683,12 +539,6 @@ تنظیمات سربرگ بستن همه‌ی زبانه‌ها - - زبانه جدید - - برو به خانه - - تغییر حالت زبانه نشانک‌گذاری @@ -707,29 +557,10 @@ بستن زبانه%s بازکردن فهرست زبانه‌ها - - بستن تمامی زبانه‌ها - - - به اشتراک‌گذار زبانه‌ها ذخیره زبانه‌ها در مجموعه - - فهرست زبانه - - به اشتراک گذاری زبانه - - - حذف - - ذخیره - - اشتراک‌گذاری - - تصویر نشست جاری - - افزودن به مجموعه + حذف مجموعه @@ -748,34 +579,21 @@ %1$s( حالت خصوصی) - - ذخیره - - حذف تاریخچه - - آیا مطمئن هستید می‌خواهید تاریخچه مرور خود را پاک کنید؟ تاریخچه حذف شد. %1$sحذف شد - - پاک کردن حذف %1$d انتخاب شد - - حذف %1$d مورد امروز دیروز - - 24 ساعت گذشته 7 روز گذشته @@ -797,8 +615,6 @@ %1$d انتخاب شد - - باز کردن حذف @@ -807,8 +623,6 @@ متاسفیم. %1$s نمی‌تواند این صفحه را بار کند. - - می توانید این برگه را در زیر بازیابی یا بسته کنید. ارسال گزارش خرابی ها به موزیلا @@ -816,25 +630,11 @@ بازآوری زبانه‌ - - گزینه‌های جلسه - - - اشتراک گذاری جلسه - - - منوی نشانک‌ - - ویرایش نشانک - - انتخاب پوشه آيا از حذف اين پوشه مطمئن هستيد؟ %s موارد انتخاب شده را حذف می کند. - - %1$s حذف شد افزودن پوشه @@ -843,8 +643,6 @@ ویرایش ویرایش - - انتخاب رونوشت برداشتن @@ -893,8 +691,6 @@ برگردان - - مجوزها برو به تنظیمات پیشنهاد شده - - مدیریت مجوزهای پایگاه اینترنتی پاک کردن مجوزها @@ -936,7 +730,7 @@ استثناها - روشن + روشن خاموش @@ -1012,25 +806,19 @@ - ارسال و اشتراک‌گذاری - اشتراک‌گذاری اشتراک‌گذاری - - اشتراک‌گذاری یک پیوند ارسال به دستگاه همه عمل‌ها به تازگی استفاده شده - - برای همگام‌سازی وارد شوید برای همگام‌سازی وارد شوید - + ارسال به همه دستگاه‌ها اتصال مجدد برای همگام‌سازی @@ -1054,18 +842,8 @@ اتصال به دستگاه دیگر… - - نشستِ مرور ناشناس - - زبانه های خصوصی را حذف کنید بستن زبانه‌های خصوصی - - باز کردن - - حذف و باز کنید - - قدرت گرفته توسط بازاریابی @@ -1081,36 +859,20 @@ مجموعه حذف شده مجموعه تغییرنام یافته - - زبانه حذف شده - - زبانه‌های حذف شده زبانه بسته شده زبانه‌های بسته شده - - زبانه بسته شد! نشانک‌ها ذخیره شدند! - - نما - - به سایت های برتر اضافه شد! زبانه خصوصی بسته شد زبانه‌های خصوصی بسته شدند - - زبانه‌های خصوصی حذف شدند برگردان - سایت حذف شد - - برگردان - - تایید + سایت حذف شد به %1$s اجازه دهید%2$s باز کند @@ -1155,11 +917,6 @@ %d نشانی‌ها - - تاریخچه - - %d صفحه‌ها کوکی‌ها @@ -1177,14 +934,10 @@ داده‌های مرور را در هنگام خروج حذف کنید - هنگام انتخاب "ترک" از فهرست اصلی ، داده های مرور را بطور خودکار حذف می کند - هنگام انتخاب \"ترک\" از فهرست اصلی ، داده های مرور را بطور خودکار حذف می کند خروج - - با این کار همه داده های مرور شما حذف می شود. %s اطلاعات مرور شده انتخاب شده را حذف می کند. @@ -1196,82 +949,21 @@ در حال حذف اطلاعات… - - - فایرفاکس پیش نمایش هم اکنون Firefox Nightly می‌باشد - - Firefox Nightly هر شب به روز می شود و ویژیگی های جدیدی را تجربی می‌کند. -        با این وجود ، ممکن است پایداری کمتری داشته باشد. برای یک تجربه پایدار ، مرورگر بتا ما را بارگیری کنید. - - - دریافت فایرفاکس نسخه بتا برای اندروید - - - Firefox Nightly منتقل شده است - - این برنامه دیگر به روزرسانی های امنیتی را دریافت نمی کند. Nightly جدید را دریافت کنید و استفاده از این برنامه را متوقف کنید. -        \ n \ n برای انتقال نشانک ها ، ورود به سیستم و تاریخچه مرور خود به برنامه دیگری ، یک حساب فایرفاکس ایجاد کنید. - - تغییر به Nightly جدید - - - Firefox Nightly منتقل شده است - - این برنامه دیگر به روزرسانی های امنیتی را دریافت نمی کند. دریافت Nightly جدید و استفاده از این برنامه را متوقف کنید. -        \ n \ n برای انتقال نشانک ها ، ورود به سیستم و تاریخ خود به برنامه دیگری ، یک حساب Firefox ایجاد کنید. - - دریافت Nightly جدید - - - - به %s خوش‌ آمدید! - - پیش از این حساب داشته‌اید؟ - - همگام‌سازی Firefox بین دستگاه‌ها - + نشانک‌ها، تاریخچه و گذرواژه‌های خود را به Firefox در این دستگاه بیاورید. - - شما به عنوان%s در یک مرورگر دیگر Firefox در این تلفن وارد شده اید. آیا می خواهید با این حساب وارد شوید؟ - - بله،‌ من را وارد کن - - در حال ورود به… - - ثبت نام کردن - - از سیستم خارج شوید همگام سازی روشن است - - ورود شکست خورد - - همیشه در حال حفاظت از حریم‌خصوصی - - Firefox به طور خودکار شرکت‌ها را از پیگیری مخفیانهٔ شما در وب دور می‌کند. استاندارد (پیش فرض) تعادل بین کارآیی و حریم‌خصوصی. بارگیری صفحات با سرعتی عادی. - سختگیرانه (توصیه می‌شود) - شدید مسدودسازی ردیاب‌های بیشتر، اما برخی امکانات داخل صفحات ممکن است از کار بیافتند. محل قرارگیری نوار ابزار خود را انتخاب کنید - - نوار ابزار را در دسترس قرار دهید. آن را پایین نگه دارید، یا به بالا انتقال دهید. - - حریم‌ خصوصی شما - - ما%s طراحی کرده ایم تا بتوانیم بر آنچه به صورت انلاین یا با ما اشتراک می گذارید کنترل داشته باشید. اعلامیه حریم خصوصی ما را بخوانید @@ -1312,8 +1004,6 @@ به جای آن از ایمیل استفاده کنید یکی ایجاد کنید.]]> - - فایرفاکس همگام سازی با حساب شما را متوقف خواهد کرد، ولی هیچ کدوم از اطلاعات شما بر روی این مرورگر حذف نخواهد شد. %s همگام سازی با حساب شما را متوقف خواهد کرد، ولی هیچ کدوم از داده‌های شما بر روی این مرورگر حذف نخواهد شد. @@ -1370,8 +1060,6 @@ تمام زبانه‌ها تنها در پنجره‌های ناشناس باز کن - - فقط در برگه های سفارشی باز کردن استخراج کننده‌های رمزارزها @@ -1411,10 +1099,6 @@ بازگشت به عقب - - حقوق شما - - کتابخانه های منبع بازی که ما استفاده می کنیم چه چیزی در%s جدید است - 1زبانه - - زبانه‌های %d - نسخه‌برداری @@ -1496,10 +1175,6 @@ همگام‌سازی ورود‌ها همگام‌سازی اطلاعات ورودها بین دستگاه‌ها - - اتصال مجدد - - برای همگام‌سازی وارد شوید ورودهای ذخیره شده @@ -1517,37 +1192,17 @@ حذف تمام استثاناها جست‌وجو در اطلاعات ورودها - - الفبایی - - به تازگی استفاده شده پایگاه نام کاربری گذرواژه - - دوباره پین خود را وارد کنید - - برای مشاهده ورود به سیستم ذخیره شده قفل را باز کنید - - این اتصال امن نیست. اطلاعاتی که اینجا وارد می‌شوند ممکن است در معرض خطر باشند. - - بیشتر بدانید - - آیا می خواهید%s ورود به سیستم ذخیره کنید؟ - - ذخیره - - ذخیره نشود گذرواژه به کلیپ‌بورد ریخته شد نام کاربری به کلیپ بورد ریخته شد - - آدرس به داخل کلیپ بورد ریخته شد رونوشت گذرواژه @@ -1556,8 +1211,6 @@ رونوشت نام کاربری پاک کردن نام‌کاربری - - رونوشت از سایت باز کردن سایت در مرورگر @@ -1588,7 +1241,6 @@ مرتب سازی بر روی فهرست ورود - کارت‌های اعتباری @@ -1603,6 +1255,7 @@ اضافه کردن کارت اعتباری مدیریت کارت‌های ذخیره شده + اضافه کردن کارت @@ -1617,8 +1270,6 @@ تاریخ انقضا به سال نام روی کارت - - نام مستعار کارت حذف کارت @@ -1627,7 +1278,7 @@ ذخیره ذخیره - + انصراف @@ -1672,19 +1323,13 @@ رشته جست‌و‌جو برای استفاده - درخواست را با “%s” جایگزین کنید. مثال: \nhttps://www.google.com/search?q=%s - - بیشتر بدانید + درخواست را با “%s” جایگزین کنید. مثال: \nhttps://www.google.com/search?q=%s جزئیات موتور جست‌وجو سفارشی - - در مورد پیوند بیشتر بدانید نام موتور جست‌وجو را وارد کنید - - موتور جستجو با نام“%s” از قبل موجود است. یک رشته جست‌وجو وارد کنید @@ -1698,20 +1343,6 @@ %s پاک شد - - به %s جدید خوش آمدید - - - یک مرورگر کاملا مجددا طراحی شده ، با عملکرد و ویژگی های بهبود یافته برای کمک به شما در انجام هر چه بیشتر فعالیت آنلاین ، در انتظار است. \ n \ n لطفاً صبر کنید تا %s را با شما به روز کنیم - - به روزرسانی %s… - - شروع %s - - مهاجرت تکمیل شد - - گذرواژه‌ها - برای اجازه دادن به آن: @@ -1729,12 +1360,8 @@ آیا مطمئن هستید که می خواهید این مجوز را برای این سایت پاک کنید؟ هیچ سایتی استثنائی وجود ندارد - - مقالات برتر آیا از حذف این نشانک مطمئن هستید؟ - - اضافه کردن به سایت های برتر تایید شده توسط:%1$s @@ -1748,16 +1375,12 @@ حذف گزینه های ورود - - قسمت متن قابل ویرایش برای نام کاربری ورود به سیستم. قسمت متن قابل ویرایش برای کلمه عبور ورود به سیستم. تغییرات را برای ورود به سیستم ذخیره کنید - - لغو تغییرات ویرایش @@ -1787,19 +1410,12 @@ بدون زبانهٔ باز - - - حد نصاب سایت‌های برتر شما پر شده است - - برای افزودن یک سایت برتر جدید، یکی را حذف کنید. سایت را لمس و نگه دارید و سپس حذف را انتخاب کنید. باشه،‌ متوجه شدم نام - - نامِ سایتِ برتر - + تایید انصراف @@ -1807,12 +1423,6 @@ برگه های غیر فعال - - برگه ها برای %s در اینجا موجود است. پس از آن زمان ، برگه ها به طور خودکار بسته می شوند. - - 30 روز - - 1 هفته پیوندهای وب سایت‌ها، ایمیل‌ها و پیام‌ها را تنظیم کنید تا به طور خودکار در Firefox باز شوند. @@ -1831,4 +1441,5 @@ بیشتر بدانید - + + diff --git a/app/src/main/res/values-ff/strings.xml b/app/src/main/res/values-ff/strings.xml index 44b372e2a..201a8f11c 100644 --- a/app/src/main/res/values-ff/strings.xml +++ b/app/src/main/res/values-ff/strings.xml @@ -1,9 +1,10 @@ - + Cuuriɗum %s %s (Cuuriɗum) + Cuɓe Goɗɗe @@ -13,40 +14,92 @@ Ñif banngagol suturo Yiilo walla naatnu ñiiɓirde - - Alaa tabbe udditiiɗe + + Aslol njiilaw + + Yiylo maantore + + Tabbe njiilaw + + Naatnu kelme jiyleteeɗe Tabbe maa udditiiɗe maa kollire ɗoo. + + Ɓeydu leemannde hesere + + Innde + + Danndu to leemannde + + Danndu tabbe labaaɗe to leemannde + + + + Danndaaɗi sakket + + Hollu maantore danndaaɗe fof + + Ittu + Ko @fork-maintainers jibini %1$s - - - Ngonɗaa ko e rogere heeriinde Tinndi goowaaɗi baɗte banngogol suturo - - Momtu rogere ndee - + - Ɓeydu sodorde ngam udditde tabbe e Jaɓɓorgo maa. + Ɓeydu sodorde ngam udditde tabbe e Jaɓɓorgo maa. + + Hurminir tabre aroore fiyannde wootere. - Ɓeydu sodorde - + Ɓeydu sodorde + Alaa, mi yaafiima + + + Juɓtorɗe jiytol + + Tabbe ɗe a ƴeewaani e nder jonte ɗiɗi maa ndirtine gaay. + + Uddu e jaajol caggal lewru? + + %1$s ena waawi uddude tabbe ɗe a yillaaki e lewru ɓennundu nduu. + + Tabbere hesere Tabbere suuriinde hesere - - Lowe dowrowe + + + + Artu ɗo ngonno-ɗaa + + + Hollu fof + + Hollu tabbe cakkitiiɗe fof + + Yiy tabbe ceŋondiraaɗe + + Kaɓirgol ceŋondirangol + + Ittu + + + + Jillaaɗe sakket + + + Hollu jillanɗe ɓennuɗe fof - - Uddit tabbe Caggal @@ -55,10 +108,6 @@ Hesɗitin Dartin - - Maantorol - - Taƴto Maantorol Ɓeyditte @@ -79,35 +128,26 @@ Aaf Yiytu e Hello - - Tabbere suuriinde - - Tabbere hesere - - Jaŋto caɗeele lowre + + Danndu to leemannde Lollin - - Lollin e... Uddit e %1$s - + Jiytol tarorde Uddit e jaaɓnirgal - - Mbaydi - - Horiima seŋaade. Eɓɓoore URL ndee heftinotaako. + + Heertin jiytol taroowo + + Heertin jaɓɓorgo Ɗemngal cuɓangal - - Yiylo Rew e ɗemngal kaɓirgal ngal @@ -116,14 +156,10 @@ Niiwto - - Codorɗe + + Yiylorde Teelte yiylorde - - Yiylo e: - - Ngol laawol, yiylo e: Yamir @@ -132,17 +168,31 @@ Yamir basiye njiilaw nder doge cuuriiɗe? %s maa lollin kala ko tappuɗaa e palal ñiiɓirde maa e yiylorde maa woowaande ndee. - - Ɓeydu humpito + + + Yiylo %s + + Yiylo beƴ e palal ñiiɓirɗe ngal + + + + Yiy ɗoo tabbe maa keertinaaɗe. Tabbe cakkitiiɗe, maantore, e njaltudi njiylaw ɗoo njiyetee. + + Ɓamtu ɗo dartino-ɗaa e tabbe iwɗe e kaɓirɗi goɗɗi gonɗi jooni e jaɓɓorgo maa. + + + Tabbe maa ko canngoɗinaaɗe! Fuɗɗo ɗoon ɗo darnunu-ɗaa e kaɓirgol maa goɗngol. + + Uddit tabbere hesre %1$s Yiylo Yiylo geese ɗee - Njiilaw daande + Njiilaw sawto @@ -157,26 +207,16 @@ Yiylo Palal ñiiɓirɗe - - Ballal - - Hokku duttinal + + Ɓetto to Google Play Baɗte %1$s - - Hakkeeji maa - - Pinle - - Karte banke e ñiiɓirɗe Waɗtu wanngorde woowaande Ceeɓtore - - Suturo Suturo e kisal @@ -187,8 +227,13 @@ Uddit jokke e tabbere suuriinde Yamir nokitte yaynirde e banngogol suturo + + So yamiraama, tabbe cuuriiɗe ne maa njiyo so tabbe keewɗe ena udditii Ɓeydu sodorde banngogol suturo + + + Ñifol Keɓogol @@ -199,16 +244,16 @@ Konte Firefox/ sarworde Sync waylaama. Uddugol jaaɓnirgal ngal ngam jamminde bayle… Konte - - Seŋo Palal kuutorɗe Siŋkoore + + Hello jaɓɓorgo + + Beese junngo Heertin - - Yahdin maantore, aslol, e goɗɗe e konte maa Firefox Konte Firefox @@ -219,32 +264,78 @@ Cuɓe keɓe Ƴettugol keɓe - - Tintinol suturo - - Kuutorɗe topayɓe - - Hollu codorɗe njiilaw + + Buggitagol goɗɗungol rewde e USB + + Hollu jiylorɗe Hollu wasiyaaji njiilaw + + Hollu jiilaw sawto Hoolu e doge keeriiɗe + + Hollu wasiyaaji ɗakkitorde Yiylo aslol banngogol Yiylo maantore + + Yiylo tabbe ceŋondiraaɗe Teelte konte + + Timmin binndi URL e jaajol Uddit jokke e nder jaaɓnirɗe + + Toppitorde gaawte yaasiire Ɓeyditte + + Yamiraama + + Yamiraaka + + + + Artu ɗo ngonno-ɗaa + + Maantore sakket + + Jillaaɗe sakket + + Daarti barjinaaɗe + + Ɗeeri ɓalal + + Codorɗe barjinaaɗi + + + + Temre ɗeerol ɓalal: %1$s + + Deɗol ɓalal hesɗitinaama! + + Hollir + + Horiima aawtaade wallpaper + + Fuɗɗito + + Horiima waylude ɗerol ɓalal + + Ɓeydu humpito + + Gaadanteejo %s + - Yahdin jooni + Sanngoɗin jooni Suɓo ko njahdintaa @@ -253,6 +344,8 @@ Maantore Ceŋorɗe + + Uddit tabbe Seŋto @@ -275,6 +368,9 @@ and the third is the device model. --> %1$s dow %2$s%3$s + + Karte banke + Heɓii tabbe @@ -282,20 +378,12 @@ Tintine ngam tabbe keɓaaɗe e kaɓirɗe Firefox goɗɗe. Tabbere heɓaama - - Tabbe keɓaama Tabbere e %s - - Ndeenka Dewindol - - Ndeenka Dewindol Paltooje - - Ndeenka Dewindol ko ko ñifi e ɗee lowe geese Hurmin ngam lowe ɗee fof @@ -304,39 +392,17 @@ Ɓeydu humpito - - Ñifaama e kuuɓal, yah to teelte ngam huɓɓude ɗum. - Kuutorogol e keɓe karalle - - Ina yamira Mozilla yo aaf etee ƴetta keɓe ngam fannuuji ƴeewndorɗi - - Jaŋtorde Kooke - - Jaŋtol cellal %s - - - Huɓɓu Sync - - Niiwto kod denndingol e ordinateer Firefox - - Seŋo + + Sanngoɗin ngam daɗnude keɓe maa Seŋo ngam seŋaade kadi Momtu konte - - - firefox.com/pair nder Firefox e ordinateer maa ngam heɓde kod QR maa.]]> - - Uddit kameraa - - Haaytu - Dow @@ -352,11 +418,17 @@ Rew e siŋkoore kaɓirgal ngal + + + Fooɗ ngam hesɗitinde + + Woro ngam suuɗde palal + + Fittu palal kuutorɗe faya bannge ngam addude tabbe goɗɗe + + Fittu palal kuutorɗe ngam udditde tabbe + - - Doge - - Nokitte yaynirde Gaawte @@ -371,83 +443,162 @@ Maantore Goɗɗe Aslol - - Doggol Taro - - Yiylo + + Tabbere hesere Teelte - - Dosol geɗon aslol Uddu + + Uddit tabbe %d? + + Uddit tabbe + + Haaytu + + + lowre %d + + + Lowe %d + + + Tabbe uddaaɗe sakket + + Hollu aslol fof + + %d tabbe + + %d tabbere + + Alaa tabbe uddaaɗe sakket njiytaa + + + + Tabbe + + Jiytol tabbe + + Doggol + + Tigilde + + Uddu tabbe + + Hay sahaa + + Caggal ñalawma gooto + + + Caggal yontere wootere + + Caggal lewru wooturu + + + Uddu tabbe udditiiɗe e jaajol + + + + Yaynirde udditorde + + Hello jaɓɓorgo + + Tabbere sakkitiinde + + Jaɓɓorgo ɓaawo waktuuji nayi ɗe ndilaaka + + + Uddir junngol + + Uddu caggal ñalawma gooto + + Uddu caggal yontere wootere + + Uddu caggal lewru wooturu + + Uddit e hello jaɓɓorgo + + Uddit e hello sakkitiingo + + Uddit e hello jaɓɓorgo caggal waktuuji nayi + + + + Dirtin tabbe ɓooyɗe to dooyiiɗe + + Tabbe ɗe a yillaaki e nder jonte ɗiɗi maa ndirtine to lowre dooyorde toh. + + + Ena hurmi + Uddit tabbe - - Rogere heeriinde Tabbe cuuriiɗe + + Tabbe synckaaɗe Ɓeydu tabbere + + Ɓeydu tabbere hesere + + Cuuriɗum + + Sanngoɗin + + Lollin tabbe fof + + Tabbe uddaaɗe sakket + + Uddaaɗe sakket + + Teelte konte + + Teelte tabbere + + Uddu tabbe fof + + Maantorol + + Uddu + + Danndu tabbe labaaɗe + + Dosol tabbe labaaɗe + + Suɓo tabbe Uddu tabbere Uddu tabbe %s Uddit dosol tabbe - - Uddu tabbe fof - - Lollin tabbe - - Dosol tabbere - - Lollin tabbere - - Momtu - - Danndu - - Lollin - - Natal rogere wonaande + + Danndu tabbe to leemannde Uddit tabbe - Momtu + Momtu - Momtu aslol - - Aɗa yenanaa yiɗde momtude aslol maa? Aslol momtaama Momtaama %1$s - - Momtu - - Natto - - Lollin - - Uddit nder tabbere hesere - - Uddit nder tabbere suuriinde - + Momtu suɓaama %1$d - - Momtu %1$d geɗon - - Waktuuji 24 ɓennuɗi ɗii Balɗe 7 ɓennuɗe ɗee @@ -457,11 +608,20 @@ Ɗoo alaa aslol + + + + Gaawte Momtaama + + Alaa piille gaawtaaɗe + + %1$d labaama + + Njaafoɗaa. %1$s waawaa loowde ngoo hello. - - Aɗa waawi etaade artirde walla uddude ndee tabbere les ɗoo. Neldu jaŋte kooki to Mozilla @@ -469,36 +629,17 @@ Artir tabbe - - Cuɓe rogere - - - Lollin rogere - - - Dosol maantorol - - Taƴto Maantorol - - - Suɓo runngere Aɗa yenanaa yiɗde momtude ndee runngere? - - Momtaama %1$s Ɓeydu runngere - - Maantorol sosaama. Maantorol danndaama! YAƳTO Taƴto - - Suɓo Natto @@ -507,6 +648,8 @@ Uddit nder tabbere hesere Uddit nder tabbere suuriinde + + Uddit fof e tabbe kese Momtu @@ -539,14 +682,12 @@ Momtaama %1$s - + Maantore momtaama FIRTU - - Jamirooje Yah to Teelte Basiyaaɗi - - Toppito jamirooje lowre Momtu jamirooje @@ -583,18 +722,24 @@ Paltooje - Kuɓɓol + Kuɓɓol Ñifol - + + Gaadanteejo + Yamir ojoo e widewoo + + Yamir ojoo e widewoo Daaƴ ojoo e widewoo e keɓe cinndel tan Ojoo e widewoo maa taroy e WI-FI - + Daaƴ ojoo tan - + + Daaƴ ojoo tan + Daaƴ ojoo e widewoo Kuɓɓol @@ -617,6 +762,8 @@ %d tabbere suɓaa Tabbe ndanndaama! + + Leemannde danndaama! Tabbere danndaama! @@ -626,22 +773,24 @@ - Neldu etee lollin - Lollin Lollin - - Lollin jokkol + + Horiima ɓestinde PDF Neldu to Kaɓirgol Golle fof Huutoraama ko ɓooyaani + + Natto faade ɗakkitorde Seŋo ngam yahdinde + + Sanngoɗin ngam daɗnude keɓe Neldu to masiŋon kon fof @@ -664,41 +813,23 @@ Seŋ Masiŋ Goɗɗo… - - Rogoere banngogol suturo - - Momtu tabbe cuuriiɗe Uddu tabbe cuuriiɗe - - Uddit - - - Momtude e udditde - - Tabbere momtaama - - Tabbe momtaama + Tabbere uddaama Tabbe uddaama - - Ɓeydaama e lowe dowrowe! + + Maantore ndanndaama! Tabbere suuriinde uddaama Tabbe cuuriinde uddaama - - Tabbe cuuriiɗe momtaama FIRTU Lowre momtaama - - Firtu - - Teeŋtin Yamir %1$s uddita %2$s @@ -708,21 +839,33 @@ HAƊ Aɗa yenanaa yiɗde momtude %1$s? + + Momtude ndee tabbere maa momtor leemannde ndee fof. Aɗa waawi sosde leemanɗe kese nde katonjinɗaa kala. + + Momtu %1$s? Momtu - - Haaytu Ñiiɓirde geese nattaama + + Ɗum ko jubbannde binndi. Waɗiraa ko ngam hollirde no binndi ɗii mbayata so a ɓeydii walla a ustii darnde alkule ɗee e ngol teeltol. Mawnin walla famɗin binndol e lowe geese + + Darnde alkule + + + Darnde alkule jaajre + + Darnde alkule maa yahdu e teelte Android maa. Daaƴ ngam waylude darnde alkule les ɗoo. + Momtu keɓe banngogol - Tabbe udditiiɗe + Tabbe udditiiɗe %d tabbe @@ -730,11 +873,6 @@ %d ñiiɓirɗe - - Aslol - - %d kelle Kuukiije @@ -744,21 +882,17 @@ Nate e piile mogginaaɗe Jamirooje lowre + + Gaawte Momtu keɓe banngogol Momtu keɓe banngogol nde nguddataa - Ina momta keɓe banngogol ɗoon e ɗoon so a suɓiima "Uddu" e dosol dowrowol ngol - Ina momta keɓe banngogol ɗoon e ɗoon so a suɓiima \"Uddu\" e dosol dowrowol ngol - - Aslol banngogol Uddu - - Ɗuum momtoytu keɓe banngogol maa fof %s momtoytu keɓe banngogol cuɓaaɗe ɗee. @@ -770,87 +904,15 @@ Momtugol keɓe banngogol… - - - Firefox Preview wontii Firefox Nightly - - Firefox Nightly ina heɓa kesɗitine jamma fof etee ina jogii fannuuji ƴeewndorɗi kesi. - Kono noon, haɗum waawi ŋakkude deeƴde. Aawto wanngorde amen beta ngam kuutorgol ɓurngol deeƴde. - - Heɓ wanngorde Mozilla Firefox - - - Firefox Nightly dirtii - - - Faatu e Nightly keso oo - - - Firefox Nightly dirtii - - Heɓ Nightly keso oo - - - - A Jaɓɓaama e %s! - - Aɗa jogii konte kisa? - - Jaŋngu anndude %s - - Yiy ko hesɗi - - Aɗa jogii naamnal baɗte %s ŋeñtaaɗo oo? Aɗa yiɗi anndu ko waylii? - - Heɓ jaabawuuji ɗoo - - Heɓ ko ɓuri moƴƴude e %s. - - A seŋiima hono %s e wanngotde Firefox woɗnde e ngel noddirgel. Aɗa yiɗi seŋoraade ɗee konte? - - Eey, seŋam - - Nana seŋoo... - + Seŋo e Firefox - - Heddo ceŋtiiɗo - - Horiima Seŋaade - + Reen hoore maa - - %s ina walla haɗde lowe geese ndewindo maa e ceŋogol. - Gaadanteejo - - - Ina daaƴa rewindotooɓe famarɓe kono ina yamira kelle yo loow no haanirta - - Eto banngogol junngo wooto e palal kuutorɗe les ngal walla dirtin ngal faade dow. - - Wanngo e suturo - - Uddit tabbere suuriinde laawol gootol: Ñoƴƴu maandel %s ngel. - - Uddit tabbe cuuriiɗe kala sahaa: Hesɗitin teelte banngogol maa suturo. - - Uddit teelte - - Suturo maa + Gaadanteejo (goowaaɗo) Tar tintinol suturo amen - - Uddu Fuɗɗo wanngaade @@ -884,8 +946,8 @@ Seŋoro kameraa maa Huutoro ɗoo iimeel - - Maa Firefox dartin jahdingol e konte maa, kono momtataa hay wootere e keɓe banngogol maa e ngal kaɓirgal gal. + + Sos konte ngam sanngoɗinde Firefox hakkunde kaɓirɗi.]]> Maa %s dartin jahdingol e konte maa, kono momtataa hay wootere e keɓe banngogol maa e ngal kaɓirgal gal. @@ -908,9 +970,7 @@ Ɓeydu humpito - Gaadanteejo - - Gaadanteejo (basiyaaɗo) + Gaadanteejo (goowaaɗo) Ƴagguɗo @@ -930,13 +990,12 @@ Nder tabbe ɗee fof E tabbe cuuriiɗe tan + Faddaama Yamiraama Dewindagol loowdi - - Hakkeeji maa Ko hesɗi e %s @@ -951,11 +1010,6 @@ Deftorɗi ɗi min kuutortoo - - tabbere 1 - - %d tabbe - Natto @@ -981,14 +1035,17 @@ Naamno danndude Hoto danndu abada - - Huɓɓii - - Ñifii - - Seŋo kadi - - Seŋo e Sync + + + Humpit e jaajol e %1$s + + Humpit e jaajol e jaaɓɗe goɗɗe + + + Ɓeydu innde kuutoro + + + Sanngoɗin inɗe kuutoro e kaɓirɗi goɗɗi Ceŋorɗe danndaaɗe @@ -1001,28 +1058,16 @@ Ceŋorɗe e pinle ndanndetaake ngam ɗee lowe. Yiylo Ceŋorɗe - - Huutoraama ko ɓooyaani Lowre Innde kuutoro Finnde - - Ɓeydu humpito - - Aɗa yiɗi %s dannda ndee seŋorde? - - Danndu - - Hoto danndu Natto finnde Natto innde kuutoro - - Natto lowre Hollu finnde @@ -1033,11 +1078,79 @@ Hisnu ceŋorɗe maa e pinle maa So ɓooyii + + Lonngo lowre geese fof ɓadoo + + Hurmin ngam yamirde ɓottugol e lonngo, haa e lowe kaɗooje ndee weesre. Innde (A-Z) Sakkitii huutoreede + + + Humpit e jaajol + + Karte banke + + Danndekarte kadi kebbina e jaajol + + Keɓe e gannaaɗe + + Sanngoɗin karte e kaɓiri goɗɗi + + Sanngoɗin karte + + Ɓeydu karte banke + + Toppito karte danndaaɗe + + + Dannde kadi kumpitaa ñiiɓirɗe e jaajol + + + Ɓeydu kartal + + Taƴto kartal + + Tonngoode Kartal + + Ña,gu Kiiɗtugol + + Lewru Ñalngu Kiiɗtugol + + Hitaande Ñalngu Kiiɗtugol + + Innde wonnde e Karte + + Momtu kartal + + Momtu kartal + + Aɗa yenanaa yiɗde momtude ngal kartal banke? + + Momtu + + Danndu + + Danndu + + Haaytu + + Karte danndaaɗe + + Tiiɗno naatnu tonngoode kartal banke moƴƴere + + Tiiɗno humpit ngol gallol + + Soktu ngam yiyde karte maa danndaaɗe + + Hisnu karte maa banke + + + Ɓeydu yiylorde + + Taƴto yiylorde Ɓeydu @@ -1051,9 +1164,12 @@ Goɗɗo Innde - - Ɓeydu humpito + + Binndi njiylaw kuutorteeɗi + + + Naatnu innde yiylorde %s Sosaa @@ -1061,32 +1177,69 @@ Momtaama %s - - Nana hesɗitina %s… - - Fuɗɗo %s - - Pinle - Yamirde ɗum: 1. Yah to teelte Android - - Ceŋagol Kisnangol - - Ceŋagol ngol hisaani Aɗa yananaa yiɗde momtude ɗee jamirooje e ɗee lowe? - - Binndanɗe dowrowe - - Ɓeydu e lowe dowrowe Momtu Aɗa yenanaa yiɗde momtude ndee seŋorde? Momtu + + + Gallol binndi taƴtottoongal wonande ñiiɓirde geese innde ndee. + + Ɓeydu innde kuutoro hesere + + Finnde ena waɗɗii + + Innde kuutoro ena waɗɗii + + Innde lowre ena waɗɗii + + Njiilaw sawto + + Haal jooni + + + https://www.yeru.com + + Ñiiɓirde geese ena foti waɗde "https://" or "http://" + + Innde lowre jaalɗunde ena waɗɗii + + + + Seŋ kaɓirgol goɗngol. + + + Yiy doggol tabbe iwɗe e kaɓirɗi maa goɗɗi. + + + Seŋo nga sanngoɗine + + Alaa tabbe udditiiɗe + + + Codorɗe + + Teelte + + + Barjinaaɗi + + + + Uddu e jaajol caggal lewru? + + Firefox ena waawi uddude tabbe ɗe a yillaaki e lewru ɓennundu nduu. + + + Barjinaaɗi + diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 66779dd6a..f40ede68c 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -67,11 +67,11 @@ - Lisää pikakuvake avataksesi yksityisiä välilehtiä aloitusnäytöltä. + Lisää pikakuvake avataksesi yksityisiä välilehtiä aloitusnäytöltä. Avaa seuraava yksityinen välilehti yhdellä napautuksella. - Lisää pikavalinta + Lisää pikavalinta Lisää aloitusnäytölle @@ -173,6 +173,8 @@ Pysäytä Lisäosat + + Tilin tiedot Ei lisäosia täällä @@ -265,7 +267,7 @@ Hakuasetukset - Tällä kertaa hae: + Tällä kertaa hae: Tällä kertaa hae: @@ -294,6 +296,18 @@ Sulje + + + Ilmoitukset auttavat sinua tekemään enemmän %silla + + Synkronoi välilehdet laitteiden välillä, hallitse latauksia, hanki vinkkejä %sin yksityisyyden suojan hyödyntämiseen liittyen ja paljon muuta. + + Jatka + + Ei nyt + Avaa uusi %1$s-välilehti @@ -350,13 +364,21 @@ Evästeilmoitusten vähennys Vähennä evästeisiin liittyviä ilmoituksia + + Pois + + Päällä - Firefox yrittää automaattisesti hylätä evästeilmoituksissa olevat evästepyynnöt. Jos hylkäysvaihtoehto ei ole käytettävissä, Firefox voi hyväksyä kaikki evästeet ilmoituksen poistamiseksi näkyvistä. + Firefox yrittää automaattisesti hylätä evästeilmoituksissa olevat evästepyynnöt. Jos hylkäysvaihtoehto ei ole käytettävissä, Firefox voi hyväksyä kaikki evästeet ilmoituksen poistamiseksi näkyvistä. + + %1$s yrittää hylätä automaattisesti evästeilmoituksissa olevat evästepyynnöt. Ei käytössä tällä sivustolla Käytössä tällä sivustolla + + Sivusto ei ole tuettu tällä hetkellä Haluatko ottaa evästeilmoitusten vähennystoiminnon käyttöön sivustolla %1$s? @@ -364,14 +386,53 @@ %1$s poistaa tämän sivuston evästeet ja päivittää sivun. Kaikkien evästeiden poistaminen saattaa kirjata sinut ulos tai tyhjentää ostoskorit. - %1$s voi yrittää automaattisesti hylätä evästepyynnöt. Jos hylkäysvaihtoehto ei ole käytettävissä, %2$s voi hyväksyä kaikki evästeet evästeilmoitusten poistamiseksi näkyvistä. + %1$s voi yrittää automaattisesti hylätä evästepyynnöt. Jos hylkäysvaihtoehto ei ole käytettävissä, %2$s voi hyväksyä kaikki evästeet evästeilmoitusten poistamiseksi näkyvistä. + + + %1$s voi yrittää hylätä automaattisesti evästepyynnöt. + + %1$s yrittää hylätä kaikki evästepyynnöt automaattisesti tuetuilla sivustoilla. + + Evästeilmoitukset poistukaa! + + Hylkää evästepyynnöt automaattisesti, jos mahdollista. Muussa tapauksessa hyväksy kaikki evästeet hylätäksesi evästeilmoitukset. + + Hylkää evästepyynnöt automaattisesti, jos mahdollista. + + Saako %1$s hylätä evästepyynnöt automaattisesti, kun mahdollista? + + Ei nyt + + Hylkää ilmoitukset + + Näet vähemmän evästepyyntöjä + + Näytä vähemmän evästeilmoituksia + + Vastaa automaattisesti evästeiden ponnahduspyyntöihin häiriöttömän selaamisen varmistamiseksi. %1$s hylkää kaikki pyynnöt, jos mahdollista, tai hyväksyy kaikki, jos hylkääminen ei ole mahdollista. + + Vastaa automaattisesti evästeiden ponnahduspyyntöihin häiriöttömän selaamisen varmistamiseksi. %1$s hylkää kaikki pyynnöt, jos mahdollista. + + Hylkää ponnahduspyynnöt + + Evästeilmoitusten vähennys + + Saako %1$s hylätä sivuston evästeen suostumuspyynnön, jos mahdollista, tai hyväksyä evästeiden käytön, jos hylkääminen ei ole mahdollista? + + Sallitko %1$sin hylätä sivuston evästeen suostumuspyynnön, jos mahdollista? + + Salli Yrittää muodostaa automaattisesti yhteyden sivustoihin käyttämällä salattua HTTPS-protokollaa turvallisuuden parantamiseksi. - Päällä - + Päällä + Pois + + Kaikissa välilehdissä + + Yksityisissä välilehdissä Lue lisää @@ -450,6 +511,11 @@ Ilmoitukset + + Sallittu + + Ei sallittu + Mukautettu lisäosakokoelma @@ -472,8 +538,6 @@ Äskettäin vierailtu - - Pocket Ajatuksia herättäviä tarinoita @@ -733,6 +797,13 @@ Sulje kuukauden kuluttua + + Avaa etusivu + + Avaa viimeisin välilehti + + Avaa etusivu neljän tunnin kuluttua + Siirrä vanhat välilehdet passiivisiksi @@ -1001,10 +1072,16 @@ Poikkeukset - Päällä + Päällä Pois + + Vakio + + Tiukka + + Mukautettu Salli ääni ja video @@ -1748,7 +1825,7 @@ Käytettävä hakujono - Korvaa kysely käyttäen ”%s”. Esimerkki:\nhttps://www.google.com/search?q=%s + Korvaa kysely käyttäen ”%s”. Esimerkki:\nhttps://www.google.com/search?q=%s Mukautetun hakukoneen tiedot @@ -1950,8 +2027,6 @@ Tarinoita aiheittain Löydä lisää - - Taustavoimana Pocket. Mahdollistajana %s. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4fa8989c9..386b13811 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -66,11 +66,11 @@ - Ajoutez un raccourci pour ouvrir des onglets privés depuis votre écran d’accueil. + Ajoutez un raccourci pour ouvrir des onglets privés depuis votre écran d’accueil. Lancez le prochain onglet privé d’un seul doigt. - Ajouter un raccourci + Ajouter un raccourci Ajouter à l’écran d’accueil @@ -172,6 +172,8 @@ Arrêter Modules complémentaires + + Informations du compte Aucun module ici @@ -263,7 +265,7 @@ Paramètres de recherche - Pour cette recherche : + Pour cette recherche : Pour cette recherche : @@ -292,6 +294,18 @@ Fermer + + + Les notifications vous aident à en faire plus avec %s + + Synchronisez les onglets entre vos appareils, gérez les téléchargements, obtenez des conseils pour tirer le meilleur parti de la protection de la vie privée de %s, et bien plus. + + Continuer + + Plus tard + Ouvrir un nouvel onglet %1$s @@ -347,13 +361,21 @@ Réduction des bannières de cookies Réduire les bannières de cookies + + Désactivée + + Activée - Firefox essaie automatiquement de refuser les demandes de dépôt de cookies quand une bannière de cookies s’affiche. Si aucune option de rejet n’est disponible, Firefox peut accepter tous les cookies pour fermer la bannière. + Firefox essaie automatiquement de refuser les demandes de dépôt de cookies quand une bannière de cookies s’affiche. Si aucune option de rejet n’est disponible, Firefox peut accepter tous les cookies pour fermer la bannière. + + %1$s essaie automatiquement de refuser les demandes de dépôt de cookies quand une bannière de cookies s’affiche. Désactivée pour ce site Activée pour ce site + + Site actuellement non pris en charge Activer la réduction des bannières de cookies pour %1$s ? @@ -361,14 +383,54 @@ %1$s effacera les cookies de ce site et actualisera la page. La suppression de tous les cookies peut vous déconnecter ou vider les paniers d’achats. - %1$s peut essayer automatiquement de refuser les demandes de dépôt de cookies. Si aucune option de rejet n’est disponible, %2$s peut accepter tous les cookies pour fermer la bannière. + %1$s peut essayer automatiquement de refuser les demandes de dépôt de cookies. Si aucune option de rejet n’est disponible, %2$s peut accepter tous les cookies pour fermer la bannière. + + + %1$s peut essayer automatiquement de refuser les demandes de dépôt de cookies. + + %1$s peut essayer de refuser automatiquement les demandes de dépôt de cookies sur les sites compatibles. + + Finies les bannières de cookies ! + + Rejette automatiquement les demandes de cookies, lorsque cela est possible. Sinon, accepte tous les cookies pour supprimer les bannières de cookies. + + Rejette automatiquement les demandes de cookies, lorsque cela est possible. + + Autoriser %1$s à rejeter automatiquement les demandes de cookies, lorsque cela est possible ? + + Plus tard + + Fermer les bannières + + Vous verrez moins de demandes de cookies + + Voir moins de popups de cookies + + Répond automatiquement aux popups de cookies pour une navigation sans distraction. %1$s rejettera toutes les demandes si possible, ou les acceptera toutes dans le cas contraire. + + Répond automatiquement aux popups de cookies pour une navigation sans distraction. %1$s rejettera toutes les demandes si possible. + + Rejeter les fenêtres popup + + Réduction des bannières de cookies + + + Autoriser %1$s à refuser la demande de consentement aux cookies d’un site si possible ou à accepter l’accès aux cookies lorsque ce n’est pas possible ? + + Autoriser %1$s à refuser la demande de consentement aux cookies d’un site si possible ? + + Autoriser Essayer de se connecter automatiquement aux sites en utilisant le protocole de chiffrement HTTPS pour une sécurité accrue. - Activé - + Activé + Désactivé + + Activé dans tous les onglets + + Activé dans les onglets privés En savoir plus @@ -447,6 +509,11 @@ Notifications + + Autorisées + + Non autorisées + Collection de modules personnalisée @@ -469,8 +536,6 @@ Visités récemment - - Pocket Des articles qui font réfléchir @@ -730,6 +795,13 @@ Fermeture après un mois + + Ouvrir la page d’accueil + + Ouvrir le dernier onglet + + Ouvrir la page d’accueil après quatre heures + Déplacer les onglets inactifs @@ -999,10 +1071,16 @@ Exceptions - Activée + Activée Désactivée + + Standard + + Stricte + + Personnalisée Autoriser l’audio et la vidéo @@ -1758,7 +1836,7 @@ Chaîne de recherche à utiliser - Remplacer les termes de la recherche par « %s ». Par exemple :\nhttps://www.google.com/search?q=%s + Remplacer les termes de la recherche par « %s ». Par exemple :\nhttps://www.google.com/search?q=%s Détails du moteur de recherche personnalisé @@ -1959,8 +2037,6 @@ Articles par sujet En découvrir davantage - - Fonctionne grâce à Pocket. Mis en avant par %s. diff --git a/app/src/main/res/values-fur/strings.xml b/app/src/main/res/values-fur/strings.xml new file mode 100644 index 000000000..e10e5057a --- /dev/null +++ b/app/src/main/res/values-fur/strings.xml @@ -0,0 +1,1944 @@ + + + + %s privât + + %s (Privât) + + + + Altris opzions + + Abilite la navigazion privade + + Disabilite la navigazion privade + + Cîr o inserìs une direzion + + Cîr te cronologjie + + Cîr tai segnelibris + + Cîr tes schedis + + Inserìs i tiermins di ricercje + + Lis tôs schedis viertis a vignaran mostradis achì. + + + + Lis tôs schedis privadis a vignaran mostradis achì. + + %1$d selezionadis + + Zonte gnove racuelte + + Non + + Selezione racuelte + + Jes de modalitât di selezion multiple + + Salve lis schedis selezionadis intune racuelte + + Selezionade + + + + Zontâts di resint + + Mostre ducj i segnelibris salvâts + + Gjave + + + %1$s al è prodot di Mozilla. + + + + + + %1$s al nete la cronologjie di ricercje e di navigazion des tôs schedis privadis cuant che tu lis sieris o tu jessis de aplicazion. Ancje se chest no ti rint anonim sui sîts web o al to furnidôr di servizis internet, al rint plui sempliç tignî privât ce che tu fasis in rêt, a chei altris che a doprin chest dispositîf. + + Falsis crodincis su la navigazion privade + + + + + Zonte une scurte par vierzi schedis privadis de tô schermade principâl. + + Vierç la prossime schede privade intune sole tocjade. + + Zonte scurte + + Zonte a schermade principâl + + No graciis + + + + Tu puedis configurâ %1$s par vierzi in automatic i colegaments tes aplicazions. + + Va aes impostazions + + Scarte + + + Siere + + + + La nestre plui fuarte funzion di protezion de riservatece mai realizade e isole lis spiis inter-sît. + + Plui informazions su la Protezion Totâl dai Cookies + + + Al covente l’acès ae fotocjamare. Va tes impostazions di Android, va te schede dai permès e tocje permet. + + Va aes impostazions + + + + Siere + + + Stabilìs che lis schedis viertis che no son stadis visualizadis tal ultin dì, setemane o mês, si sierin in automatic. + + Visualize opzions + + Siere + + Lis schedis che no tu visualizis par dôs setemanis a vegnin spostadis achì. + + Disative tes impostazions + + Sierâ in automatic dopo un mês? + + + + %1$s al pues sierâ lis schedis che no tu âs visualizât tal ultin mês. + + Siere + + + Ative il sierâ automatic + + + + + Gnove schede + + Gnove schede privade + + + + Torne a cheste schede + + Mostre dutis + + Boton par mostrâ dutis lis schedis resintis + + Viôt dutis lis schedis sincronizadis + + Dispositîf sincronizât + + Gjave + + Gjave + + + + Visitâts di resint + + Gjave + + Visualize dutis lis esplorazions fatis + + + + Indaûr + + Indenant + + Inzorne + + Ferme + + Components adizionâi + + Nissun component adizionâl achì + + Jutori + + Novitâts + + Impostazions + + Librarie + + Sît di scritori + + Zonte a schermade principâl + + Instale + + Torne sincronize + + Cjate te pagjine + + Salve intune racuelte + + Condivît + + Vierç in %1$s + + + + AL FUNZIONE GRACIE A %1$s + + Al funzione gracie a %1$s + + Viodude di leture + + Siere la viodude di leture + + Vierç intune aplicazion + + Personalize viodude di leture + + Zonte + + Modifiche + + Personalize pagjine iniziâl + + + Schermade principâl + + + + Lenghe selezionade + + Dopre lenghe dal dispositîf + + Cîr lenghe + + + + Scansione + + Motôr di ricercje + + Impostazions motôr di ricercje + + Tache il link des notis + + Permet + + No sta permeti + + Permeti sugjeriments di ricercje tes sessions privadis? + + %s al condividarà cul motôr di ricercje predefinît dut ce che tu scrivis te sbare de direzion. + + Cîr in %s + + Cîr dret de sbare de direzion + + Impostazions ricercje + + Cheste volte cîr cun: + + Cheste volte cîr in: + + + + Scuvierç la tô pagjine iniziâl personalizade. Lis schedis resintis, i segnelibris e i risultâts des ricercjis a vignaran fûr achì. + + Benvignût intun internet plui personâl + + + + Plui colôrs. Riservatece miorade. Stesse dedizion ae int invezit che ai profits. + + Passâ di un schermi a chel altri al è plui facil di simpri + + Ripie di dulà che tu jeris restât cu lis schedis di altris dispositîfs, cumò disponibil dret de tô pagjine iniziâl. + + Scomence + + Jentre + + Salte + + Sincronizazion des schedis in vore! Ripie di dulà che tu jeris restât sul altri dispositîf. + + Siere + + + + Vierç intune gnove schede in %1$s + + Cîr + + Cîr tal web + + Ricercje vocâl + + + + Impostazions + + Gjenerâl + + Informazions + + Motôr di ricercje predefinît + + Ricercje + + Sbare de direzion + + Valute su Google Play + + Informazions su %1$s + + Met come navigadôr predefinît + + Avanzadis + + Riservatece e sigurece + + Permès dai sîts + + Navigazion privade + + Vierç i colegaments intun barcon privât + + Permet la cature di schermadis te navigazion privade + + Se permetût, lis schedis privadis a saran visibilis ancje cuant che a son viertis plui aplicazions + + Zonte scurte navigazion privade + + Modalitât dome-HTTPS + + + Riduzion strisson pai cookies + + Ridûs i strissons pai cookies + + + + Firefox al cîr in automatic di refudâ lis richiestis dai cookies cuant che al ven visualizât un strisson pai cookies. Se la opzion par refudâju no je disponibile, Firefox al podarès acetâ ducj i cookies par sierâ il strisson. + + Disative par chest sît + + Ative par chest sît + + Ativâ la riduzion strisson dai cookies par %1$s? + + Disativâ la riduzion strisson dai cookies par %1$s? + + %1$s al netarà vie i cookies di chest sît e al inzornarà la pagjine. Al è pussibil che netant vie ducj i cookies tu vegnis disconetût dal sît opûr che i carei des spesis a sedin disvuedâts. + + %1$s al pues cirî di refudâ in automatic lis richiestis dai cookies. Se no je disponibile une opzion par refudâju, %2$s al podarès acetâ ducj i cookies par sierâ il strisson. + + + Al cîr di conetisi in automatic ai sîts doprant il protocol di cifradure HTTPS par vê une sigurece miorade. + + Ativade + + Disativave + + Plui informazions + + Ative in dutis lis schedis + + Ative dome in schedis privadis + + Version sigure dal sît no disponibile + + Al è probabil che il sît web nol supuarti HTTPS. + + + + Dut câs al è ancje pussibil che al sedi un tentatîf di atac. Se tu continuis su chest sît web, no tu varessis di inserî nissune informazion sensibile. Se tu continuis, la modalitât dome-HTTPS e vignarà disativade in mût temporani par chest sît. + + Acessibilitât + + Servidôr personalizât pal account Firefox + + Servidôr personalizât par Sync + + Serivdôr par Firefox Account/Sync modificât. La aplicazion e vignarà sierade par aplicâ lis modifichis… + + Account + + Sbare dai struments + + Teme + + Pagjine iniziâl + + Mots + + Personalize + + Jentre par sincronizâ schedis, segnelibris, passwords e altri. + + Account Firefox + + + + Torne conet par ripiâ la sincronizazion + + Lenghe + + + + Sielte di dâts + + Racuelte di dâts + + Debug di lontan vie USB + + Visualize motôrs di ricercje + + Mostre sugjeriments di ricercje + + Mostre ricercje vocâl + + Mostre in sessions privadis + + Mostre sugjeriments des notis + + Cîr te cronologjie di navigazion + + Cîr tai segnelibris + + Cîr tes schedis sincronizadis + + Impostazions account + + Complete in automatic i URLs + + Vierç i links tes aplicazions + + Gjestôr esterni dai discjariaments + + Components adizionâi + + Notifichis + + + + Racuelte personalizade di components adizionai + + Va ben + + Anule + + Non de racuelte + + Proprietari de racuelte (ID utent) + + + + Racuelte di components adizionâi modificade. La aplicazion e vignarà sierade par aplicâ lis modifichis… + + + + Ripie di chi + + Segnelibris resints + + Visitâts di resint + + Pocket + + + + Storiis che a fasin pensâ + + Articui selezionâts di %s + + Storiis sponsorizadis + + Fonts + + Scurtis sponsorizadis + + + + + Element fonts: %1$s + + Fonts inzornât! + + Visualize + + Impussibil discjamâ il fonts + + Torne prove + + Impussibil cambiâ il fonts + + Plui informazions + + %s classic + + Edizion limitade + + La gnove racuelte di Vôs indipendentis. %s + + La gnove racuelte di Vôs indipendentis. + + Prove une man di colôr + + Sielç il fonts che ti ispire. + + Scuvierç altris fonts + + + + Il component adizionâl nol è supuartât + + Il component adizionâ al è za instalât + + + + Sincronize cumò + + Sielç ce sincronizâ + + Cronologjie + + Segnelibris + + Credenziâls + + Schedis viertis + + Disconet + + Non dispositîf + + Tu scugnis inserî un non pal dispositîf. + + Daûr a sincronizâ… + + Sincronizazion falide. Ultime lade a bon fin: %s + + Sincronizazion falide. Ultime sincronizazion: mai + + Ultime sincronizazion: %s + + Ultime sincronizazion: mai + + %1$s su %2$s %3$s + + Cjartis di credit + + Recapits + + + + + Schedis ricevudis + + Notifichis pes schedis ricevudis di altris dispositîfs Firefox. + + Schede ricevude + + Schede di %s + + + + Ecezions + + Ative par ducj i sîts + + + + Lis ecezions ti permetin di disabilitâ par cierts sîts la protezion da lis spiis. + + Plui informazions + + + Dâts tecnics e di utilizazion + + Al condivît cun Mozilla informazions su prestazions, utilizazion, hardware e personalizazions dal navigadôr par judânus a miorâ %1$s + + Dâts di comercializazion + + Al condivît i dâts di utilizazion di base cun Adjust, il nestri furnidôr di comercializazion mobile + + Studis + + Al permet a Mozilla di instalâ e puartâ indenant studis + + + + Sincronize e salve i tiei dâts + + Jentre par tornâ a conetiti + + + + Gjave account + + + + firefox.com/pair]]> + + + + Superiôr + + Inferiôr + + + + Clâr + + Scûr + + Stabilît dal sparagn energjetic + + Va daûr dal teme dal dispositîf + + + + Tire par inzornâ + + Scor par platâ la sbare dai struments + + Scor la sbare dai struments in bande par cambiâ schede + + Scor la sbare dai struments in alt par vierzi lis schedis + + + + Discjamâts + + Segnelibris + + Segnelibris di scritori + + Menù segnelibris + + Sbare dai segnelibris + + Altris segnelibris + + Cronologjie + + Gnove schede + + Impostazions + + Siere + + + Vierzi %d schedis? + + Vierzint cussì tantis schedis tu podaressis morestâ %s dilunc il cjariament des pagjinis. Continuâ distès? + + Vierç schedis + + Anule + + + %d sît + + %d sîts + + + Schedis sieradis di resint + + Mostre cronologjie complete + + %d schedis + + %d schede + + Nissune schede sierade di resint achì + + + + Schedis + + Viodude schedis + + Liste + + Gridele + + Siere schedis + + + + A man + + Dopo un dì + + Dopo une setemane + + Dopo un mês + + Siere in automatic lis schedis viertis + + + + Schermade di vierzidure + + Pagjine iniziâl + + Ultime schede + + + + Pagjine iniziâl dopo cuatri oris di inativitât + + Siere a man + + Siere dopo un dì + + Siere dopo une setemane + + Siere dopo un mês + + + + Sposte lis schedis vecjis te sezion inativis + + Lis schedis che no tu visualizis di dôs setemanis a vegnin spostadis te sezion inativis. + + + + Gjave + + Atîfs + + %1$s al pues instalâ e puartâ indenant studis di cuant in cuant. + + Plui informazions + + La aplicazion e jessarà par aplicâ lis modifichis + + Va ben + + Anule + + Daûr a sierâ la aplicazion par aplicâ lis modifichis… + + + + Schedis viertis + + Schedis privadis + + Schedis sincronizadis + + Zonte schede + + Zonte schede privade + + Privade + + Sincronize + + Condivît dutis lis schedis + + Schedis sieradis di resint + + Sieradis di resint + + Impostazions account + + Impostazions schedis + + Siere dutis lis schedis + + Segnelibri + + Siere + + Condivît lis schedis selezionadis + + Menù schedis selezionadis + + Gjave schede de racuelte + + Selezione schedis + + Siere schede + + Siere schede %s + + Menù schedis viertis + + Salve schedis intune racuelte + + Elimine racuelte + + Cambie non ae racuelte + + Vierç schedis + + Non de racuelte + + + + Cambie non + + Gjave + + Elimine de cronologjie + + %1$s (modalitât privade) + + + + Inserìs i tiermins di ricercje + + Scancele la cronologjie + + Cronologjie eliminade + + %1$s eliminât + + Elimine + + %1$d selezionâts + + Vuê + + Îr + + Ultins 7 dîs + + Ultins 30 dîs + + Plui vecjos + + Nissune cronologjie achì + + + + Discjariaments gjavâts + + %1$s gjavât + + Nissun file discjariât + + + + %1$d selezionâts + + Gjave + + + + + Nus displâs. %1$s nol rive a cjariâ chê pagjine. + + Invie la segnalazion di colàs a Mozilla + + Siere schede + + + Ripristine schede + + + + Eliminâ pardabon cheste cartele? + + %s al eliminarà i elements selezionâts. + + Anule + + Zonte cartele + + Segnelibri salvât! + + MODIFICHE + + Modifiche + + Copie + + Condivît + + Vierç intune gnove schede + + Vierç intune schede privade + + Vierç ducj in gnovis schedis + + Vierç ducj in schedis privadis + + Elimine + + Salve + + %1$d selezionâts + + Modifiche segnelibri + + Modifiche cartele + + Jentre par viodi i segnelibris sincronizâts + + URL + + CARTELE + + NON + + Zonte cartele + + Selezione cartele + + Il titul al è obligatori + + URL no valit + + Nissun segnelibri achì + + Eliminât %1$s + + Segnelibris eliminâts + + Daûr a eliminâ lis cartelis selezionadis + + + ANULE + + Inserìs i tiermins di ricercje + + + + Va aes impostazions + + Sfuei des impostazions rapidis + + Racomandade + + Nete permès + + Va ben + + Anule + + Nete permès + + Va ben + + Anule + + Nete i permès su ducj i sîts + + Riproduzion automatiche + + Fotocjamare + + Microfon + + Posizion + + Notifiche + + Archiviazion permanente + + Cookies inter-sît + + Contignûts protets di DRM + + Domande il permès + + Blocât + + Permetût + + Blocât di Android + + Ecezions + + Ativade + + Disativade + + Permet audio e video + + Permet audio e video + + Bloche audio e video dome su dâts mobii + + Audio e video a saran riprodots cul Wi-Fi + + Bloche dome l’audio + + Bloche dome l’audio + + Bloche audio e video + + Bloche audio e video + + + Ativât + + Disativât + + Ativât + + Disativât + + + + Racueltis + + Menù racuelte + + + Tire dongje i argoments che ti interessin.\nMet dongje lis ricercjis, i sîts e lis schedis similis par doprâlis in mût svelt plui indenant. + + + Selezione schedis + + Selezione racuelte + + Non racuelte + + Zonte gnove racuelte + + Selezione dut + + Deselezione dut + + Selezione lis schedis di salvâ + + %d schedis selezionadis + + %d schede selezionade + + Schedis salvadis! + + Racuelte salvade! + + Schede salvade! + + Siere + + Salve + + Visualize + + Va ben + + Anule + + + Racuelte %d + + + + Condivît + + Condivît + + Salve come PDF + + Impussibil gjenerâ il PDF + + Invie a dispositîf + + Dutis lis azions + + Dopradis di resint + + Copie intes notis + + Copiât intes notis + + Jentre par sincronizâ + + Sincronize e salve i dâts + + Mande a ducj i dispositîfs + + Torne conet a Sync + + Fûr rêt + + Conet un altri dispositîf + + Par inviâ une schede, jentre in Firefox su almancul un altri dispositîf. + + Capît + + + Impussibil condividi cun cheste aplicazion + + Mande a dispositîf + + Nissun dispositîf conetût + + Plui informazions sul mandâ schedis… + + Conet un altri dispositîf… + + + + Siere lis schedis privadis + + Comercializazion + + %1$s al è svelt e riservât + + Met %1$s come to navigadôr predefinît + + Prove la navigazion privade + + + Navighe cence salvâ cookies o cronologjie in %1$s + + + + Racuelte eliminade + + Cambiât non ae racuelte + + Schede sierade + + Schedis sieradis + + Segnelibris salvâts! + + Zontât aes scurtis! + + Schede privade sierade + + Schedis privadis sieradis + + ANULE + + Sît gjavât + + Permet a %1$s di vierzi %2$s + + PERMET + + DINEE + + Direzion web no valide. + + Va ben + + Eliminâ pardabon %1$s? + + La eliminazion di cheste schede e eliminarà dute la racuelte. Tu puedis creâ gnovis racueltis cuant che tu vûs. + + Eliminâ %1$s? + + Elimine + + + Daûr a jentrâ in modalitât plen schermi + + + URL copiât + + Chest al è un test di esempli. Al è achì par mostrâti cemût che il test al vignarà fûr cuant che tu aumentis o tu diminuissis la dimension dai caratars cun cheste impostazion. + + Rint plui grant o plui piçul il test sui sîts web + + Dimension caratars + + + Dimensionament automatic dai caratars + + La dimension dai caratars e corispuindarà a chê des tôs impostazions di Android. Disative par gjestî la dimension dai caratars in maniere separade di chi. + + + Elimine i dâts di navigazion + + Schedis viertis + + %d schedis + + Cronologjie di navigazion e dâts dai sîts + + %d direzions + + Cookies + + Tu vignarâs disconetût de plui part dai sîts + + + Imagjins e files te memorie cache + + Libere spazi di archiviazion + + Permès dai sîts + + Discjamâts + + Elimine dâts di navigazion + + Elimine i dâts di navigazion ae jessude + + Elimine in automatic i dâts di navigazion cuant che tu selezionis “Jes” dal menù principâl + + Jes + + + Dade di timp par eliminâ + + Al gjave la cronologjie (includude la cronologjie sincronizade di altris dispositîfs), i cookies e altris dâts di navigazion. + + Ultime ore + + Vuê e îr + + Dut + + + %s al eliminarà i dâts di navigazion selezionâts. + + Anule + + Elimine + + Dâts di navigazion eliminâts + + Daûr a eliminâ i dâts di navigazion… + + + Elimine ducj i sîts in “%s” + + Anule + + Elimine + + Grup eliminât + + + + Benvignûts intun internet miôr + + Un navigadôr realizât pe int, no pai profits. + + Ripie di dulà che tu jeris restât + + Sincronize lis schedis e lis passwords tra i tiei dispositîfs par passâ di un schermi a chel altri cence interuzions. + + Jentre + + Sincronizazion ative + + Progjetât pe protezion de riservatece + + Caraterizât cu la Protezion totâl dai cookies par fermâ lis spiis dal doprâ i cookies che a stan daûr aes tôs ativitâts in rêt intant che tu visitis i sîts. + + Standard (predefinît) + + + Belançât tra riservatece e prestazions. Lis pagjinis a vignaran cjamadis normalmentri. + + Restritîf + + Al bloche plui spiis, duncje lis pagjinis si cjariaran plui sveltis, ma al è pussibil che cualchi funzionalitât te pagjine no funzioni. + + Sielç la posizion de sbare dai struments + + Tegnile in bas, o spostile in alt. + + Tu tu controlis i tiei dâts + + + Firefox ti da il control su ce che tu condividis in rêt e ce che tu condividis cun nô. + + Lei la nestre informative su la riservatece + + Desideristu scuvierzi lis maraveis di internet? + + Scomence a navigâ + + + + Sielç il to teme + + Sparagne batarie e i tiei voi cu la modalitât scure. + + + Automatic + + Si adate aes impostazions dal to dispositîf + + Teme scûr + + Teme clâr + + + Schedis mandadis! + + Schede mandade! + + Impussibil mandâ + + TORNE PROVE + + Scansione il codiç + + https://firefox.com/pair]]> + + Pront par scansionâ + + Jentre cu la fotocjamare + + Dopre invezit la e-mail + + Cree un par sincronizâ Firefox tra i varis dispositîfs.]]> + + %s no si sincronizarà plui cul to account, ma nol eliminarà nissun dai tiei dâts di navigazion su chest sît. + + Disconet + + Anule + + Impussibil modificâ lis cartelis predefinidis + + + + Impostazions di protezion + + Protezion miorade da lis spiis + + Navighe cence vê nissun che ti stâ daûr + + + Ten i tiei dâts par to cont. %s ti protêç di tantis des plui comuns spiis che ti stan daûr a ce che tu fasis in rêt. + + Plui informazions + + Standard (predefinide) + + Belançade tra riservatece e prestazions. Lis pagjinis a vignaran cjamadis normalmentri. + + Elements blocâts de protezion standard da lis spiis + + Restritive + + Al bloche plui spiis, duncje lis pagjinis si cjariaran plui sveltis, ma al è pussibil che cualchi funzionalitât te pagjine no funzioni. + + Elements blocâts de protezion restritive da lis spiis + + Personalizade + + Sielç cualis spiis (trackers) e scripts blocâ. + + Elements blocâts de protezion personalizade da lis spiis + + + Cookies + + Spiis (trackers) inter-sît e di social media + + Cookies dai sîts no visitâts + + Ducj i cookies di tiercis parts (al pues causâ malfunzionaments dai sîts web) + + Ducj i cookies (al causarà malfunzionaments dai sîts web) + + Isole i cookies inter-sît + + Contignûts che a spiin + + In dutis lis schedis + + Dome in schedis privadis + + Minadôrs di criptomonede + + Rilevadôrs di stamp numeric + + Detais + + Blocâts + + Permetûts + + Spiis (trackers) dai social media + + Al limite lis capacitâts dai social networks di spiâ lis tôs ativitâts di navigazion sul web. + + Cookies inter-sît che a spiin + + Cookies inter-sît + + + Al bloche i cookies che lis rêts publicitariis e lis compagniis di analisi a doprin par tirâ dongje i dâts di navigazion cuant che tu passis di un sît a chel altri. + + La Protezion totâl dai cookies e isole il sît che tu stâs visitant, cussì che lis spiis come chês des rêts publicitariis no puedin doprâju par stâti daûr di un sît a chel altri. + + Minadôrs di criptomonede + + Al impedìs ai scripts malevui di vê acès al to dispositîf par produsi monede digjitâl. + + Rilevadôrs di stamp numeric + + Al ferme la racuelte di dâts identificatîfs univocs sul to dispositîf che a puedin jessi utii par spiâti e stâti daûr. + + Contignûts che ti spiin + + Al ferme il cjariament di publicitâts esternis, videos e altris contignûts che a contegnin codiç che ti spie. Al pues influençâ cualchi funzionalitât dal sît web. + + Lis protezions a son ATIVIS par chest sît + + + Lis protezions a son DISATIVADIS par chest sît + + La protezion miorade da lis spiis e je disativade par chescj sîts web + + Torne indaûr + + Novitâts in %s + + %s | Librariis OSS + + Spiis che a indreçin + + Al nete vie i cookies configurâts par indreçâ a sîts web cognossûts pal lôr spiâ. + + Cualchi spie indicade chi sot e je stade sblocade in mût parziâl su cheste pagjine parcè che tu âs interagjît cun lôr *. + + Plui informazions + + + Supuart + + Colàs + + Informative su la riservatece + + I tiei dirits + + Informazions su la licence + + Librariis dopradis + + + Menù di debug: %1$d clic(s) restants par abilitâ + Menù di debug abilitât + + + + Copie + + Tache e va + + Tache + + URL copiât intes notis + + + Zonte a schermade principâl + + Anule + + Zonte + + Va al sît web + + Non de scurte + + Al è pussibil zontâ chest sît web ae schermade principâl dal dispositîf par doprâle cun plui sveltece, tant che e fos une aplicazion. + + + Credenziâls e passwords + + Salve credenziâls e passwords + + Domande prime di salvâ + + No sta salvâ mai + + Compile in automatic in %1$s + + Compile e salve i nons utent e lis passwords tai sîts web intant che tu dopris %1$s. + + Compile in automatic in altris aplicazions + + Compile i nons utent e lis passwords in altris aplicazions dal to dispositîf. + + Zonte credenziâl + + + Sincronize lis credenziâls + + Sincronize lis credenziâls tra dispositîfs + + Credenziâls salvadis + + Lis credenziâls che tu salvis o sincronizis su %s a vignaran fûr achì. + + Plui informazions su Sync. + + Ecezions + + Lis credenziâls e lis passwords che no tu âs salvât a vignaran fûr achì. + + + Lis credenziâls e lis passwords no vignaran salvadis par chescj sîts. + + Elimine dutis lis ecezions + + Cîr credenziâls + + Sît + + Non utent + + Password + + Password copiade intes notis + + Non utent copiât intes notis + + Copie password + + Nete password + + Copie non utent + + Scancele non utent + + Scancele non dal servidôr + + Vierç sît tal navigadôr + + Mostre password + + Plate password + + Sbloche par visualizâ lis credenziâls salvadis + + Protêç lis tôs credenziâls di acès + + Configure une secuence di bloc, PIN o password par protezi lis tôs credenziâls e lis passwords salvadis, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâlis. + + Plui indenant + + Configure cumò + + Sbloche il dispositîf + + Zoom su ducj i sîts web + + Abilite par permeti la funzion “Pice pal zoom“, ancje sui sîts web che a impedissin chest mot. + + Non (A-Z) + + Ultime doprade + + Ordene il menù des credenziâls + + + + Compilazion automatiche + + Recapits + + Cjartis di credit + + Salve e compile in automatic lis cjartis + + + I dâts a son cifrâts + + Sincronize lis cjartis tra plui dispositîfs + + Sincronize cjartis di credit + + Zonte cjarte di credit + + Gjestìs cjartis salvadis + + Zonte recapit + + Gjestìs recapits + + Salve e compile in automatic i recapits + + Includi informazions come numars, e-mail e recapits di spedizion + + + Zonte cjarte + + Modifiche cjarte + + Numar de cjarte + + Date di scjadince + + Mês de date di scjadince + + An de date di scjadince + + Non su la cjarte + + Elimine cjarte + + Elimine cjarte + + Eliminâ pardabon cheste cjarte di credit? + + Elimine + + Salve + + Salve + + Anule + + Cjartis salvadis + + Inserìs un numar di cjarte di credit valit + + Compile chest cjamp + + Sbloche par visualizâ lis cjartis di credit salvadis + + Protêç lis tôs cjartis di credit + + + Configure une secuence di bloc, PIN o password par protezi lis tôs cjartis di credit salvadis, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâlis. + + Configure cumò + + Plui indenant + + Sbloche il dispositîf + + Sbloche par doprâ lis informazions des cjartis di credit memorizadis + + Zonte recapit + + Modifiche recapit + + Gjestìs recapits + + Non + + Secont non + + Cognon + + Recapit + + Citât + + Stât + + Provincie + + Codiç postâl + + Paîs o regjon + + Telefon + + E-mail + + Salve + + Anule + + Elimine recapit + + Eliminâ pardabon chest recapit? + + Elimine + + Anule + + Salve recapit + + Elimine recapit + + + Zonte motôr di ricercje + + Modifiche motôr di ricercje + + Zonte + + Salve + + Modifiche + + Elimine + + + Altri + + Non + + Stringhe di ricercje di doprâ + + Sostituìs il test de ricercje cun “%s”. Esempli:\nhttps://www.google.com/search?q=%s + + Detais dal motôr di ricercje personalizât + + + Inserìs il non dal motôr di ricercje + + Inserìs une stringhe di ricercje + + Verifiche che la stringhe di ricercje e corispuindi al formât di esempli + + Erôr tal conetisi a “%s” + + %s creât + + %s salvât + + %s eliminât + + + Par permetilu: + + 1. Vierç lis impostazions di Android + + Permès]]> + + %1$s su Permet]]> + + + La conession e je sigure + + La conession no je sigure + + Nete vie i cookies e i dâts dai sîts + + + %s?]]> + + Netâ vie pardabon ducj i permès par ducj i sîts? + + Netâ vie pardabon ducj i permès par chest sît? + + Netâ vie pardabon chest permès par chest sît? + + Nissune ecezion pai sîts + + Eliminâ pardabon chest segnelibri? + + Zonte aes scurtis + + Gjave des scurtis + + Verificât di: %1$s + + Elimine + + Modifiche + + Eliminâ pardabon cheste credenziâl? + + Elimine + + Anule + + Opzions credenziâls + + Il cjamp di test modificabil pe direzion web de credenziâl. + + Il cjamp di test modificabil pal non utent de credenziâl. + + Il cjamp di test modificabil pe password de credenziâl. + + Salve lis modifichis ae credenziâl. + + Modifiche + + Zonte gnove credenziâl + + Password necessarie + + Non utent necessari + + Non servidôr necessari + + Ricercje vocâl + + Cjacare cumò + + E esist za une credenziâl cun chel non utent + + https://www.esempli.com + + La direzion web e scugne contignî “https://” o “http://” + + Al è necessari un non di servidôr valit + + + + Conet un altri dispositîf. + + Torne a eseguî l’acès. + + Ative la sincronizazion des schedis. + + No tu âs nissune schede vierte in Firefox tai altris dispositîfs. + + Visualize une liste di schedis dai tiei altris dispositîfs. + + Jentre par sincronizâ + + Nissune schede vierte + + + Slargje il grup des schedis sincronizadis + + Comprim il grup des schedis sincronizadis + + + + Rivât al limit pes scurtis + + Par zontâ une gnove scurte, tu ‘nd âs di gjavâ une. Tocje e ten fracât il sît e selezione gjave. + + Va ben, capît + + Scurtis + + Non + + Non de scurte + + Va ben + + Anule + + Impostazions + + I nestris patrocinadôrs e la tô riservatece + + Sponsorizât + + + + Schedis inativis + + Siere dutis lis schedis inativis + + Slargje lis schedis inativis + + Comprim lis schedis inativis + + + + Sierâ in automatic dopo un mês? + + Firefox al pues sierâ lis schedis che no tu âs visualizât tal ultin mês. + + ATIVE SIER IN AUTOMATIC + + Sierâ in automatic ativât + + + + Firefox Suggest + + Ricercje Google + + Ricercje %s + + + Configure i colegaments di sîts web, e-mails e messaçs in mût che a vegnin vierts in automatic cun Firefox. + + + Elimine + + + Fâs clic par vê plui detais + + + Va sù + + + Siere + + + + Storiis che a fasin pensâ + + Storiis par argoment + + Scuvierç altris storiis + + Cun tecnologjie Pocket. + + Cun tecnologjie %s. + + Part de famee Firefox. %s + + Plui informazions + + Sponsorizade + + + Ative la telemetrie par inviâ dâts. + + Va aes impostazions + + + + comprim + + slargje + + vierç il colegament par vê plui informazions su cheste racuelte + + lei l’articul + diff --git a/app/src/main/res/values-fy-rNL/strings.xml b/app/src/main/res/values-fy-rNL/strings.xml index 0492930f4..657f95ace 100644 --- a/app/src/main/res/values-fy-rNL/strings.xml +++ b/app/src/main/res/values-fy-rNL/strings.xml @@ -67,11 +67,11 @@ - Foegje in fluchtoets ta om priveeljepblêden fan jo startskerm út te iepenjen. + Foegje in fluchtoets ta om priveeljepblêden fan jo startskerm út te iepenjen. Start it folgjende priveeljepblêd mei ien tik. - Fluchtoets tafoegje + Fluchtoets tafoegje Tafoegje oan startskerm @@ -172,6 +172,8 @@ Stopje Add-ons + + Accountynformaasje Gjin add-ons hjir @@ -262,7 +264,7 @@ Sykynstellingen - Diskear sykje yn: + Diskear sykje yn: Diskear sykje yn: @@ -291,6 +293,18 @@ Slute + + + Meldingen helpe jo mear te dwaan mei %s + + Syngronisearje jo ljepblêden tusken apparaten, behear downloads, krij tips oer it optimaal benutten fan de privacybeskerming fan %s en mear. + + Trochgean + + No net + In nij %1$s-ljepblêd iepenje @@ -345,13 +359,21 @@ Reduksje fan cookiebanners Cookiebanners redusearje + + Ut + + Oan - Firefox probearret automatysk cookie-oanfragen op cookiebanners te wegerjen. As der gjin wegeringsopsje beskikber is, akseptearret Firefox mooglik alle cookies om de banner te sluten. + Firefox probearret automatysk cookie-oanfragen op cookiebanners te wegerjen. As der gjin wegeringsopsje beskikber is, akseptearret Firefox mooglik alle cookies om de banner te sluten. + + %1$s probearret automatysk cookiefersiken op cookiebanners te wegerjen. Ut foar dizze website Oan foar dizze website + + Website wurdt op dit stuit net stipe Reduksje fan cookiebanners ynskeakelje foar %1$s? @@ -359,14 +381,54 @@ %1$s wisket de cookies foar dizze website en fernijt de side. As alle cookies wiske wurde, wurde jo mooglik ôfmeld of wurde winkelweintsjes lege. - %1$s kin probearje om automatysk cookie-oanfragen te wegerjen. As der gjin wegeringsopsje beskikber is, akseptearret %2$s mooglik alle cookies om de banner te sluten. + %1$s kin probearje om automatysk cookie-oanfragen te wegerjen. As der gjin wegeringsopsje beskikber is, akseptearret %2$s mooglik alle cookies om de banner te sluten. + + + %1$s kin probearje om cookiefersiken automatysk te wegerjen. + + %1$s probearret alle cookiefersiken op stipe websites automatysk te wegerjen. + + Farwel cookiebanners! + + Wegerje automatysk cookiefersiken, wannear mooglik. Akseptearje oars alle cookies om cookiebanners fuort te heljen. + + Cookiefersiken automatysk wegerje, wannear mooglik. + + %1$s tastean om cookiefersiken wannear mooglik automatysk te wegerjen? + + No net + + Banners fuorthelje + + Jo sille minder cookie-oanfragen sjen + + Sjoch minder cookie-pop-ups + + + Beäntwurdzje automatysk cookie-pop-ups foar navigearjen sûnder ôflieding. %1$s sil wannear mooglik alle fersiken ôfwize, of akseptearret se allegearre as dit net kin. + + Beäntwurdzje automatysk cookie-pop-ups foar navigearjen sûnder ôflieding. %1$s sil wannear mooglik alle fersiken ôf. + + Pop-ups slute + + Reduksje fan cookiebanners + + %1$s tastean om it tastimmingfersyk foar cookies fan in website wannear mooglik te wegerjen of om cookie-tagong te akseptearjen wannear dit net mooglik is? + + %1$s tastean it tastimmingfersyk foar cookies fan in website te wegerjen, wannear mooglik? + + Tastean Probearret foar in bettere befeiliging automatysk mei it HTTPS-fersiferingsprotokol ferbining te meitsjen mei websites. - Oan - + Oan + Ut + + Oan yn alle ljepblêden + + Oan yn priveeljepblêden Mear ynfo @@ -445,6 +507,11 @@ Notifikaasjes + + Tastien + + Net tastien + Oanpaste add-onkolleksje @@ -467,8 +534,6 @@ Koartlyn besocht - - Pocket Ferhalen dy’t ta neitinken stimme @@ -723,6 +788,13 @@ Nei in moanne slute + + Op startside iepenje + + Op lêste ljepblêd iepenje + + Op startside iepenje nei fjouwer oeren + Alde ljepblêden nei ynaktyf ferpleatse @@ -985,9 +1057,15 @@ Utsûnderingen - Oan + Oan Ut + + Standert + + Strang + + Oanpast Audio en fideo tastean @@ -1726,7 +1804,7 @@ Te brûken sykterm - Sykfraach ferfange troch ‘%s’. Bygelyks: \nhttps://www.google.com/search?q=%s + Sykfraach ferfange troch ‘%s’. Bygelyks: \nhttps://www.google.com/search?q=%s Details oanpaste sykmasine @@ -1928,8 +2006,6 @@ Ferhalen op ûnderwerp Mear ûntdekke - - Mooglik makke troch Pocket. Mooglik makke troch %s. diff --git a/app/src/main/res/values-gn/strings.xml b/app/src/main/res/values-gn/strings.xml index 6c4b1d5fa..c7fe5f152 100644 --- a/app/src/main/res/values-gn/strings.xml +++ b/app/src/main/res/values-gn/strings.xml @@ -67,12 +67,12 @@ - Embojuaju jeike pya’eha embojuruja hag̃ua tendayke ñemi ne mba’erechaha ñepyrũgua guive. + Embojuaju jeike pya’eha embojuruja hag̃ua tendayke ñemi ne mba’erechaha ñepyrũgua guive. Emoñepyrũ tendayke ñemigua peteĩ jekutúpe. - Embojuaju jeike pya’eha + Embojuaju jeike pya’eha Embojuaju mba’erechaha ñepyrũháre @@ -173,6 +173,8 @@ Pyta Moĩmbaha + + Mba’ete marandu Ndaipóri moĩmbaha ápe @@ -263,7 +265,7 @@ Mba’epytyvõrã jeheka - Eheka peteĩjey: + Eheka peteĩjey: Ko’ág̃a eheka amo: @@ -291,6 +293,15 @@ Mboty + + + Marandu’i ne pytyvõta ejapovéta %s ndive + + Ku’ejey + + Ani ko’ág̃a + Embojuruja tendayke pyahu %1$s mba’e @@ -347,13 +358,19 @@ Emomichĩ kookie banner + + Mboguepyre + + Hendypyre - Firefox omboykese ijehegui kookie mba’ejerure kookie banner ndive. Ndaipóriramo emboykekuaa hag̃ua, Firefox omoneĩkuaa opaite kookie omboyke hag̃ua pe banner. + Firefox omboykese ijehegui kookie mba’ejerure kookie banner ndive. Ndaipóriramo emboykekuaa hag̃ua, Firefox omoneĩkuaa opaite kookie omboyke hag̃ua pe banner. Ogue ko tendápe Hendy ko tendápe + + Tenda ko’ág̃a ojokupyty’ỹva ¿Emyandy kookie ñemurã momichĩ %1$s peg̃uarã? @@ -362,14 +379,35 @@ %1$s omboguéta kookie ko tendagua ha omyanyhẽjeýta kuatiarogue. Emboguepaitérõ kookie ombotykuaa ne rembiapo térã omonandi ne mba’ejoguakue. - %1$s omboykese ijehegui kookie mba’ejerure. Ndaipórirõ jeporavorã emboykekuaa hag̃ua, %2$s omoneĩkuaa opaite kookie omboty hag̃ua pe ñemurã. + %1$s omboykese ijehegui kookie mba’ejerure. Ndaipórirõ jeporavorã emboykekuaa hag̃ua, %2$s omoneĩkuaa opaite kookie omboty hag̃ua pe ñemurã. + + + ¡Opáma banners kookie rehegua! + + Ani ko’ág̃a + + Emboyke banners + + Ehecha’ivéta kookie mba’ejerure + + Ehecha’ive kookie ovetã iñapysẽva + + Emboyke ovetã iñapysẽva + + Kookie Banner Ñemomichĩ + + Moneĩ Eñeha’ã eike hag̃ua tendakuérape eipurúvo pe taperekoite HTTPS ipapapýva tekorosãverã. - Hendy - + Hendy + Mboguepyre + + Hendýma opaite tendayképe + + Hendýma tendayke ñemíme Kuaave @@ -446,6 +484,11 @@ Ñemomarandu + + Moneĩmbyre + + Oñemoneĩ’ỹva + Moĩmbaha aty momba’epyre @@ -469,8 +512,6 @@ Ojeikeramohague - - Pocket Tembiasakue nemyakãngetáva @@ -734,6 +775,14 @@ Emboty peteĩ jasy rire + + Ijuruja kuatiarogue ñepyrũme + + + Embojuruja tendayke pahápe + + Ijuruja kuatiarogue ñepyrũme irundy aravo rire + Eguerova tendayke ituja ha ojepuru’ỹva @@ -1005,9 +1054,15 @@ Oĩ’ỹva - Hendypyre + Hendypyre Mboguepyre + + Ypykue + + Mbaretépe + + Mboavapyre Emoneĩ mba’epu ha ta’ãngamýi @@ -1766,7 +1821,7 @@ Jehekaha juajuha eipurútava - Emoambue porandu “%s” ndive. Techapyrã:https://www.google.com/search?q=%s + Emoambue porandu “%s” ndive. Techapyrã:https://www.google.com/search?q=%s Mba’emimi jehekaha mongu’eha mboavapyre @@ -1971,8 +2026,6 @@ Tembiasakue téma rehegua Ejuhukuaave - - Pocket omoheñoipyre. Omboguatáva %s. diff --git a/app/src/main/res/values-hsb/strings.xml b/app/src/main/res/values-hsb/strings.xml index 7dbfe53e6..b48817a66 100644 --- a/app/src/main/res/values-hsb/strings.xml +++ b/app/src/main/res/values-hsb/strings.xml @@ -66,10 +66,14 @@ - Přidajće zwjazanje, zo byšće priwatne rajtarki ze swojeje startoweje wobrazowki wočinił. + Přidajće zwjazanje, zo byšće priwatne rajtarki ze swojeje startoweje wobrazowki wočinił. + + Startujće přichodny priwatny rajtark z jednym podótkom. - Zwjazanje přidać - + Zwjazanje přidać + + Startowej wobrazowce přidać + Ně, dźakuju so @@ -167,6 +171,8 @@ Zastajić Přidatki + + Kontowe informacije Žane přidatki tu @@ -255,7 +261,7 @@ Pytanske nastajenja - Tónkróć pytać: + Tónkróć pytać: Tónkróć pytać w: @@ -283,6 +289,15 @@ Začinić + + + Zdźělenki wam pomhaja, wjace z %s činić + + Dale + + Nic nětko + Nowy rajtark %1$s wočinić @@ -339,12 +354,58 @@ Plackowe chorhoje redukować + + Wupinjeny + + Zapinjeny + + Za tute sydło znjemóžnjeny + + Za tute sydło zmóžnjeny + + Sydło so tuchwilu njepodpěruje + + Redukowanje plackowych chorhojow za %1$s zmóžnić? + + Redukowanje plackowych chorhojow za %1$s znjemóžnić? + + %1$s móže plackowe naprašowanja awtomatisce wotpokazać. + + %1$s pospytuje wšě plackowe naprašowanja na podpěranych sydłach awtomatisce wotpokazać. + + Preč z plackowymi chorhojemi! + + Plackowe naprašowanje awtomatisce wotpokazać, jeli móžno. + + %1$s dowolić, plackowe naprašowanja awtomatisce wotpokazać, jeli móžno? + + Nic nětko + + Chorhoje zaćisnyć + + + Budźeće mjenje plackowych naprašowanjow widźeć + + Mjenje plackowych wuskakowacych woknow widźeć + + Wuskakowace wokna zaćisnyć + + Redukowanje plackowych chorhojow + + %1$s dowolić, próstwu sydła wo přizwolenje plackoweho wobsaha wotpokazać, jeli móžno, abo přistup přez plack akceptować, jeli móžno njeje? + + Dowolić + Pospytuje z pomocu zaklučowanskeho protokola HTTPS za powyšenu wěstotu awtomatisce ze sydłami zwjazać. - Zapinjeny - + Zapinjeny + Wupinjeny + + We wšěch rajtarkach zmóžnjene + + W priwatnych rajtarkach zmóžnjene Dalše informacije @@ -422,6 +483,11 @@ Zdźělenki + + Dowoleny + + Njedowoleny + Swójska přidatkowa zběrka @@ -444,8 +510,6 @@ Njedawno wopytane - - Pocket Stawiznički, kotrež k přemyslowanju pohonjeja @@ -703,6 +767,13 @@ Po jednym měsacu začinić + + Na startowej stronje wočinić + + Na poslednim rajtarku wočinić + + Po štyrjoch hodźinach na startowej stronje wočinić + Stare rajtarki do „inaktiwne“ přesunyć @@ -750,7 +821,7 @@ Runje začinjene rajtarki - + Njedawno začinjene Kontowe nastajenja @@ -970,9 +1041,15 @@ Wuwzaća - Zapinjeny + Zapinjeny Wupinjeny + + Standard + + Striktny + + Swójski Awdio a widejo dowolić @@ -1068,8 +1145,6 @@ Do mjezyskłada kopěrować Do mjezyskłada kopěrowane - - Pola Sync přizjewić Pola Sync přizjewić @@ -1712,7 +1787,7 @@ Pytanski wuraz, kotryž ma so wužiwać - Naprašowanje z „%s“ wuměnić. Přikład: \nhttps://www.google.com/search?q=%s + Naprašowanje z „%s“ wuměnić. Přikład: \nhttps://www.google.com/search?q=%s Podrobnosće swójskeje pytawy @@ -1881,6 +1956,15 @@ Awtomatiske začinjenje zmóžnjene + + + Namjety Firefox + + + Pytanje z Google + + Z %s pytać + Nastajće wotkazy z websydłow, mejlkow a powěsćow, zo bychu so awtomatisce we Firefox wočinili. @@ -1903,8 +1987,6 @@ Stawiznički po temje Wjace wotkryć - - Wot Pocket spěchowany Spěchowany wot %s. @@ -1919,7 +2001,6 @@ Zmóžńće telemetriju, zo byšće daty słał. K nastajenjam - Namjety Firefox diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 6b6c31a65..e0180183f 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -66,11 +66,11 @@ - Indítóikon hozzáadása, amely privát lapokat nyit meg a Kezdőképernyőről. + Indítóikon hozzáadása, amely privát lapokat nyit meg a Kezdőképernyőről. Indítsa el a következő privát lapot egy koppintással. - Indítóikon hozzáadása + Indítóikon hozzáadása Kezdőképernyőhöz adás @@ -171,6 +171,8 @@ Leállítás Kiegészítők + + Fiókinformáció Nincsenek kiegészítők @@ -262,7 +264,7 @@ Keresési beállítások - Ezúttal keresés ezzel: + Ezúttal keresés ezzel: Ezúttal keresés ebben: @@ -291,6 +293,18 @@ Bezárás + + + Az értesítések segítségével még többet tehet a %s alkalmazással + + Szinkronizálhatja lapjait az eszközök között, kezelheti a letöltéseket, tippeket kaphat a %s adatvédelmi funkcióinak maximális kihasználásához stb. + + Folytatás + + Most nem + Új %1$s lap megnyitása @@ -345,13 +359,21 @@ Sütibannerek számának csökkentése A sütibannerek számának csökkentése + + Ki + + Be - A Firefox automatikusan megpróbálja elutasítani a sütibannereken megjelenő sütikéréseket. Ha nem áll rendelkezésre elutasítási lehetőség, akkor a Firefox minden sütit elfogadhat a banner elrejtéséhez. + A Firefox automatikusan megpróbálja elutasítani a sütibannereken megjelenő sütikéréseket. Ha nem áll rendelkezésre elutasítási lehetőség, akkor a Firefox minden sütit elfogadhat a banner elrejtéséhez. + + A %1$s automatikusan megpróbálja elutasítani a sütibannereken lévő sütikéréseket. Kikapcsolva erre az oldalra Bekapcsolva erre az oldalra + + A webhely jelenleg nem támogatott Bekapcsolja a sütibanner-csökkentést a következőnél: %1$s? @@ -359,14 +381,53 @@ A %1$s törli a webhely sütijeit, és frissíti az oldalt. Az összes süti törlésével kijelentkezhet, vagy kiürítheti a kosarait. - A %1$s automatikusan megpróbálhatja elutasítani a sütikéréseket. Ha nem áll rendelkezésre elutasítási lehetőség, akkor a %2$s minden sütit elfogadhat a banner elrejtéséhez. + A %1$s automatikusan megpróbálhatja elutasítani a sütikéréseket. Ha nem áll rendelkezésre elutasítási lehetőség, akkor a %2$s minden sütit elfogadhat a banner elrejtéséhez. + + + A %1$s megpróbálhatja automatikusan elutasítani a sütikéréseket. + + A %1$s automatikusan megpróbálja elutasítani az összes sütikérést a támogatott oldalakon. + + Elég a sütibannerekből! + + Automatikusan elutasítja a sütikéréseket, ha az lehetséges. Ellenkező esetben elfogad minden sütit a sütibannerek eltüntetéséhez. + + A sütikérések automatikus elutasítása, ha lehetséges. + + Engedélyezi, hogy a %1$s automatikusan elutasítsa a sütikéréseket, ha lehetséges? + + Most nem + + Bannerek eltüntetése + + Kevesebb sütikérést fog látni + + Lásson kevesebb sütikkel kapcsolatos felugró ablakot + + Automatikusan megválaszolja a sütik felugró ablakait a zavaró tényezőktől mentes böngészés érdekében. A %1$s elutasítja az összes kérést, ha az lehetséges, vagy elfogadja az összeset, ha nem. + + Automatikusan megválaszolja a sütik felugró ablakait a zavaró tényezőktől mentes böngészés érdekében. A %1$s elutasítja az összes kérést, ha az lehetséges. + + Felugró ablakok eltüntetése + + Sütibannerek számának csökkentése + + Engedélyezi a %1$s számára, hogy ha lehetséges, akkor elutasítsa a webhelyek sütikhez való hozzájárulási kéréseit, vagy elfogadja azokat, ha ez nem lehetséges? + + Engedélyezi a %1$s számára, hogy elutasítsa egy webhely sütikérését, ha lehetséges? + + Engedélyezés Automatikusan HTTPS titkosítási protokoll használatával próbál meg csatlakozni a webhelyekhez a fokozott biztonság érdekében. - Be - + Be + Ki + + Az összes lapon + + Csak privát lapokon További tudnivalók @@ -445,6 +506,11 @@ Értesítések + + Engedélyezett + + Nem engedélyezett + Egyéni kiegészítőgyűjtemény @@ -467,8 +533,6 @@ Nemrég felkeresett - - Pocket Elgondolkodtató történetek @@ -728,6 +792,13 @@ Bezárás egy hónap után + + Megnyitás a kezdőlapon + + Megnyitás az utolsó lapon + + Megnyitás a kezdőlapon négy óra után + Régi lapok áthelyezése az inaktívak közé @@ -994,10 +1065,16 @@ Kivételek - Be + Be Ki + + Szokásos + + Szigorú + + Egyéni Hang és videó engedélyezése @@ -1740,7 +1817,7 @@ Használandó keresőkifejezés - A keresés cseréje erre: „%s”. Példa:\nhttps://www.google.com/search?q=%s + A keresés cseréje erre: „%s”. Példa:\nhttps://www.google.com/search?q=%s Egyéni keresőszolgáltatás részletei @@ -1941,8 +2018,6 @@ Történetek téma szerint Folytassa a felfedezést - - A motorháztető alatt: Pocket. A motorháztető alatt: %s. diff --git a/app/src/main/res/values-hy-rAM/strings.xml b/app/src/main/res/values-hy-rAM/strings.xml index b925f4c70..1ebbe3015 100644 --- a/app/src/main/res/values-hy-rAM/strings.xml +++ b/app/src/main/res/values-hy-rAM/strings.xml @@ -64,11 +64,11 @@ - Ավելացնել դյուրանցում՝ Տնային էկրանից գաղտնի ներդիրները բացելու համար: + Ավելացնել դյուրանցում՝ Տնային էկրանից գաղտնի ներդիրները բացելու համար: Գործարկեք հաջորդ անձնական ներդիրը մեկ հպումով: - Ավելացնել դյուրանցում + Ավելացնել դյուրանցում Ավելացնել Տուն էկրանին @@ -170,6 +170,8 @@ Կանգնեցնել Հավելումներ + + Հաշվի տվյալներ Հավելումներ չկան @@ -259,7 +261,7 @@ Որոնման կարգավորում - Այս անգամվա որոնում. + Այս անգամվա որոնում. Այս անգամվա որոնումը՝ @@ -287,6 +289,18 @@ Փակել + + + Ծանուցումներն օգնում են ձեզ ավելին անել %s-ի հետ + + Համաժամացրեք ձեր ներդիրները սարքերի միջև, կառավարեք ներբեռնումները, ստացեք խորհուրդներ %s-ի գաղտնիության պաշտպանությունից առավելագույնս օգտագործելու մասին և այլն: + + Շարունակել + + Ոչ հիմա + Բացել նոր %1$s ներդիր @@ -341,13 +355,21 @@ Թխուկների դրոշակի կրճատում Նվազեցնել թխուկների պաստառները + + Անջ. + + Միաց. - Firefox-ը ինքնաբար կերպով փորձում է մերժել թխուկների խնդրանքները թխուկների պաստառների վրա: Եթե մերժման տարբերակն անհասանելի է, Firefox-ը կարող է ընդունել բոլոր թխուկները՝ դրոշակը հեռացնելու համար: + Firefox-ը ինքնաբար կերպով փորձում է մերժել թխուկների խնդրանքները թխուկների պաստառների վրա: Եթե մերժման տարբերակն անհասանելի է, Firefox-ը կարող է ընդունել բոլոր թխուկները՝ դրոշակը հեռացնելու համար: + + %1$s-ն ինքնաբար փորձում է մերժել թխուկների հարցումները թխուկների ցուցանակների վրա: Անջատված է այս կայքի համար Միացված է այս կայքի համար + + Կայքը ներկայումս չի աջակցվում Միացնե՞լ Cookie Banner կրճատումը %1$s-ի համար: @@ -355,14 +377,53 @@ %1$s-ը կջնջի այս կայքի թխուկները և կթարմացնի էջը: Բոլոր թխուկները մաքրելը կարող է դուրս գրել Ձեզ կամ դատարկել գնումների զամբյուղները: - %1$s-ը ինքնաբար կերպով փորձում է մերժել թխուկների խնդրանքները: Եթե մերժման ընտրանքն անհասանելի է, %2$s-ը կարող է ընդունել բոլոր թխուկները՝ բաները բաց թողնելու համար: + %1$s-ը ինքնաբար կերպով փորձում է մերժել թխուկների խնդրանքները: Եթե մերժման ընտրանքն անհասանելի է, %2$s-ը կարող է ընդունել բոլոր թխուկները՝ բաները բաց թողնելու համար: + + + %1$s-ը կարող է փորձել ինքնաբար կերպով մերժել թխուկների հարցումները: + + %1$s-ը փորձում է ինքնաբար մերժել թխուկների հարցումները աջակցվող կայքերում: + + Թխուկների ցուցապաստառները վերացել են: + + Հնարավորության դեպքում ինքնաբերաբար մերժել թխուկների հարցումները: Հակառակ դեպքում, ընդունել բոլոր թխուկները՝ թխուկների պաստառները մերժելու համար: + + Հնարավորության դեպքում ինքնաբերաբար մերժել թխուկների հարցումները: + + Թույլատրե՞լ %1$s-ին ինքնաբար մերժել թխուկների հարցումները, երբ դա հնարավոր է: + + Ոչ հիմա + + Անտեսել պաստառները + + Դուք կտեսնեք ավելի քիչ թխուկների հարցումներ + + Տեսնել ավելի քիչ թխուկների ելնող պատուհաններ + + Ինքնաբար պատասխանել թխուկների ելնող պատուհաններին՝ առանց շեղումների զննումների համար: %1$s-ը կմերժի բոլոր հարցումները, եթե հնարավոր է, կամ կընդունի բոլորը, եթե ոչ: + + Ինքնաբար պատասխանել թխուկների ելնող պատուհաններին՝ առանց շեղումների զննումների համար: %1$s-ը կմերժի բոլոր հարցումները, եթե հնարավոր է: + + Բաց թողնել ելնող պատուհանները + + Թխուկների դրոշակի կրճատում + + Թույլատրե՞լ %1$s-ին մերժել կայքի թխուկների թույլտվության հարցումը, եթե հնարավոր է, կամ ընդունել թխուկների մուտքը, երբ դա հնարավոր չէ: + + Թույլատրե՞լ %1$s-ին մերժել կայքի թխուկների թույլտվության հարցումը, եթե հնարավոր է: + + Թույլատրել Ինքնաշխատ կերպով փորձում է միանալ կայքերին՝ օգտագործելով HTTPS գաղտնագրման արձանագրությունը՝ անվտանգության բարձրացման համար: - Միաց. - + Միաց. + Անջ. + + Բոլոր ներդիրներում + + Բոլոր Գաղտնի ներդիրներում Իմանալ ավելին @@ -441,6 +502,11 @@ Ծանուցումներ + + Թույլատրված + + Չթույլատրված + Հավելումների հատուկ հավաքածու @@ -463,8 +529,6 @@ Վերջերս այցելած - - Pocket Մտահանգման պատմություններով @@ -720,6 +784,13 @@ Փակել մեկ ամիս անց + + Բացեք գլխավոր էջում + + Բացեք վերջին ներդիրում + + Բացեք գլխավոր էջում չորս ժամ հետո + Տեղափոխել հին ներդիրները անգործուն @@ -984,10 +1055,16 @@ Բացառություններ - Միաց. + Միաց. Անջ. + + Ստանդարտ + + Խիստ + + Հարմարեցված Թույլատրել ձայնանյութը և տեսանյութը @@ -1725,7 +1802,7 @@ Օգտագործվող որոնման տողը - Հարցումը փոխարինել “%s”-ով: Օրինակ՝ \nhttps://www.google.com/search?q=%s + Հարցումը փոխարինել “%s”-ով: Օրինակ՝ \nhttps://www.google.com/search?q=%s Հարմարեցված որոնիչի մանրամասներ @@ -1925,8 +2002,6 @@ Պատմություններ ըստ թեմայի Բացահայտի՛ր ավելին - - Pocket-ի կողմից: Աշխատում է %s-ի կողմից: diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index 765772e45..34a64a69c 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -9,7 +9,7 @@ - + Altere optiones Activar le navigation private @@ -66,11 +66,11 @@ - Adde un accesso directe pro aperir schedas private desde tu schermo initial. + Adde un accesso directe pro aperir schedas private desde tu schermo initial. Lancear le proxime scheda in privato in un tocco. - Adder via-breve + Adder via-breve Adder al pagina initial @@ -172,6 +172,8 @@ Stoppar Additivos + + Informationes del conto Nulle additivos hic @@ -262,7 +264,7 @@ Parametros de recerca - Iste vice cercar per: + Iste vice cercar per: Iste vice cercar in: @@ -291,6 +293,19 @@ Clauder + + + Le notificationes te adjuta a facer plus con %s + + Synchronisa tu schedas inter apparatos, gere le discargamentos, recipe le suggestiones re maximisar le protection del confidentialitate de %s e altero ancora. + + + Continuar + + Non ora + Aperir un nove scheda %1$s @@ -303,7 +318,7 @@ - + Parametros General @@ -347,13 +362,21 @@ Reducer banners pro le cookie + + Disactivar + + Activar - Firefox automaticamente proba a rejectar requestas de cookies sur banners pro cookies. Si un option pro rejectar non es disponibile, Firefox pote acceptar tote le cookies pro dimitter le banner. + Firefox automaticamente proba a rejectar requestas de cookies sur banners pro cookies. Si un option pro rejectar non es disponibile, Firefox pote acceptar tote le cookies pro dimitter le banner. + + %1$s automaticamente prova a rejectar le requestas de cookies sur banners pro cookies. Disactivar pro iste sito Activar pro iste sito + + Sito actualmente non supportate Activar le reduction de banner pro cookie pro %1$s? @@ -361,14 +384,54 @@ %1$s clarara le cookies de iste sito e actualisara le pagina. Clarar tote le cookies pote clauder tu connexion o vacuar tu carrettos de compras. - %1$s pote probar automaticamente a rejectar requestas de cookies. Si un option pro rejectar non es disponibile, %2$s pote acceptar tote le cookies pro dimitter le banner. + %1$s pote probar automaticamente a rejectar requestas de cookies. Si un option pro rejectar non es disponibile, %2$s pote acceptar tote le cookies pro dimitter le banner. + + + %1$s pote tentar de rejectar automaticamente le requestas de cookies. + + %1$s tenta rejectar automaticamente tote le requestas de cookies sur le sitos supportate. + + Bandieras pro cookies adeo! + + Rejectar automaticamente requestas de cookies, quando possibile. Alteremente, acceptar tote le cookies pro dimitter le bandieras pro cookies. + + Rejectar automaticamente requestas de cookies, quando possibile. + + Permitter a %1$s de rejectar automaticamente requestas de cookies, quando possibile? + + Non ora + + + Dimitter le bandieras + + Tu videra minus requestas de cookies + + Vider minus quadros resaltante de cookies + + Responde automaticamente al quadros resaltante de cookies pro navigar libere de distractiones. %1$s rejectara tote le requestas si possibile, o acceptara tote si non. + + Responder automaticamente al quadros resaltante de cookies pro navigar libere de distractiones. %1$s rejectara tote le requestas si possibile, o los acceptara tote si non. + + Dimitter le quadros resaltante + + Reduction de banner pro le cookie + + Permitter a %1$s de refusar le requesta de consenso al cookies de un sito si possibile o acceptar le accesso de cookies quando impossibile? + + Permitter a %1$s de declinar le requesta de consenso de cookie del sito si possibile? + + Permitter Automaticamente tenta de connecter se al sitos per le protocollo de cryptation HTTPS pro major securitate. - Activar - + Activar + Disactivar + + Sur tote le schedas + + Sur tote le schedas private Pro saper plus @@ -446,6 +509,11 @@ Notificationes + + Permittite + + Non permittite + Collection de additivos personalisate @@ -470,8 +538,6 @@ Visitate recentemente - - Pocket Historias que face pensar @@ -519,8 +585,9 @@ Le additivo non es supportate + - + Additivo jam installate @@ -744,6 +811,13 @@ Clauder depost un mense + + Aperir sur le pagina initial + + Aperir sur le ultime scheda + + Aperir sur le pagina initial post quatro horas + Move le schedas vetule a inactive @@ -1018,9 +1092,15 @@ Exceptiones - Active + Active Inactive + + Standard + + Stricte + + Personalisate Permitter audio e video @@ -1781,7 +1861,7 @@ Catena de recerca a usar - Replaciar le recerca con “%s”. Exemplo:\nhttps://www.google.com/search?q=%s + Replaciar le recerca con “%s”. Exemplo:\nhttps://www.google.com/search?q=%s Detalios del motor de recerca personalisate @@ -1982,8 +2062,6 @@ Historia per argumento Discoperi plus - - Potentiate per Pocket Potentiate per %s. diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index ec3cb3b4e..7a4a59305 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -67,11 +67,11 @@ - Tambahkan pintasan untuk membuka tab privat dari layar Beranda Anda. + Tambahkan pintasan untuk membuka tab privat dari layar Beranda Anda. Luncurkan tab pribadi berikutnya dengan sekali ketuk. - Tambahkan pintasan + Tambahkan pintasan Tambahkan ke Beranda @@ -171,6 +171,8 @@ Hentikan Pengaya + + Info akun Tidak ada pengaya di sini @@ -264,7 +266,7 @@ Setelan pencarian - Kali ini temukan dengan: + Kali ini temukan dengan: Kali ini, cari di: @@ -293,6 +295,18 @@ Tutup + + + Notifikasi membantu Anda lakukan lebih banyak hal dengan %s + + Sinkronkan tab Anda antar perangkat, kelola unduhan, dapatkan kiat tentang memanfaatkan perlindungan privasi %s, dan banyak lagi. + + Lanjutkan + + Jangan sekarang + Buka di tab %1$s baru @@ -349,14 +363,22 @@ Pengurangan Spanduk Kuki Kurangi spanduk kuki + + Nonaktif + + Aktif - Firefox secara otomatis mencoba menolak permintaan kuki di spanduk kuki. Jika opsi menolak tidak tersedia, Firefox akan menerima semua kuki untuk menutup spanduk tersebut. + Firefox secara otomatis mencoba menolak permintaan kuki di spanduk kuki. Jika opsi menolak tidak tersedia, Firefox akan menerima semua kuki untuk menutup spanduk tersebut. + + %1$s secara otomatis coba menolak permintaan kuki di spanduk kuki. Nonaktif untuk situs ini Aktif untuk situs ini + + Saat ini, situs tidak didukung Aktifkan Pengurangan Spanduk Kuki untuk %1$s? @@ -364,14 +386,53 @@ %1$s akan menghapus kuki situs ini dan menyegarkan laman ini. Membersihkan semua kuki dapat membuat Anda keluar dari suatu situs atau mengosongkan keranjang belanja. - %1$s dapat mencoba menolak permintaan kuki secara otomatis. Jika opsi menolak tidak tersedia, %2$s dapat menerima semua kuki untuk menutup spanduk tersebut. + %1$s dapat mencoba menolak permintaan kuki secara otomatis. Jika opsi menolak tidak tersedia, %2$s dapat menerima semua kuki untuk menutup spanduk tersebut. + + + %1$s dapat mencoba menolak permintaan kuki secara otomatis. + + %1$s mencoba secara otomatis menolak semua permintaan kuki di situs yang didukung. + + Lenyapkan spanduk kuki! + + Secara otomatis menolak permintaan kuki, jika memungkinkan. Jika tidak, terima semua kuki untuk menghilangkan spanduk kuki. + + Secara otomatis menolak permintaan kuki, jika memungkinkan. + + Izinkan %1$s untuk secara otomatis menolak permintaan kuki? + + Jangan sekarang + + Tutup spanduk + + Anda akan melihat lebih sedikit permintaan kuki + + Lihat lebih sedikit pop-up kuki + + Otomatis menjawab pop-up kuki untuk mendapatkan penjelajahan bebas gangguan. %1$s akan menolak semua permintaan kuki jika memungkinkan, atau menerima semua jika tidak. + + Otomatis menjawab pop-up kuki untuk mendapatkan penjelajahan bebas gangguan. %1$s akan menolak semua permintaan kuki jika memungkinkan. + + Tutup Pop-up + + Pengurangan Spanduk Kuki + + Izinkan %1$s untuk menolak permintaan persetujuan kuki dari situs jika memungkinkan atau menerima akses kuki jika tidak dimungkinkan? + + Izinkan %1$s untuk menolak permintaan persetujuan kuki dari situs jika memungkinkan? + + Izinkan Secara otomatis mencoba terhubung ke situs menggunakan protokol enkripsi HTTPS untuk meningkatkan keamanan. - Nyala - + Nyala + Mati + + Aktif di semua tab + + Aktif di tab pribadi Pelajari lebih lanjut @@ -450,6 +511,11 @@ Notifikasi + + Diizinkan + + Tidak diizinkan + Koleksi Pengaya ubahsuai @@ -472,8 +538,6 @@ Baru dikunjungi - - Pocket Cerita yang menggugah pikiran @@ -731,6 +795,13 @@ Tutup setelah satu bulan + + Buka di beranda + + Buka di tab terakhir + + Buka di beranda setelah empat jam + Pindahkan tab lama menjadi nonaktif @@ -997,10 +1068,16 @@ Kekecualian - Aktif + Aktif Nonaktif + + Standar + + Ketat + + Khusus Izinkan audio dan video @@ -1023,7 +1100,7 @@ Nonaktif - + Aktif Mati @@ -1737,7 +1814,7 @@ String pencarian untuk digunakan - Ganti kueir dengan “%s”. Contoh:\nhttps://www.google.com/search?q=%s + Ganti kueir dengan “%s”. Contoh:\nhttps://www.google.com/search?q=%s Rincian mesin pencari kustom @@ -1938,8 +2015,6 @@ Cerita berdasarkan topik Temukan lebih banyak - - Diberdayakan oleh Pocket. Diberdayakan oleh %s. diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index a3c5b6ea6..2f2864ad5 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -66,11 +66,11 @@ - Bæta flýtileið til að opa huliðsflipa frá upphafsskjánum þínum. + Bæta flýtileið til að opa huliðsflipa frá upphafsskjánum þínum. Ræstu næsta huliðsflipa með einni snertingu. - Bæta við flýtileið + Bæta við flýtileið Bæta við á upphafsskjá @@ -169,6 +169,8 @@ Stöðva Viðbætur + + Upplýsingar um reikning Engar viðbætur hér @@ -259,7 +261,7 @@ Leitarstillingar - Leita núna með: + Leita núna með: Leita núna í: @@ -287,6 +289,18 @@ Loka + + + Tilkynningar hjálpa þér að gera meira með %s + + Samstilltu flipa á milli tækja, stýrðu niðurhali, fáðu ábendingar um að nýta persónuvernd %s sem best og fleira. + + Halda áfram + + Ekki núna + Opna nýjan %1$s-flipa @@ -342,13 +356,21 @@ Fækkun vefkökuborða Fækka vefkökuborðum + + Óvirkt + + Virkt - Firefox reynir sjálfkrafa að hafna vefkökubeiðnum á vefkökuborðum. Ef ekki er boðið upp á að hafna vefkökum getur Firefox samþykkt allar vefkökur til að hafna borðanum. + Firefox reynir sjálfkrafa að hafna vefkökubeiðnum á vefkökuborðum. Ef ekki er boðið upp á að hafna vefkökum getur Firefox samþykkt allar vefkökur til að hafna borðanum. + + %1$s reynir sjálfkrafa að hafna vefkökubeiðnum á vefkökuborðum. Slökkt fyrir þetta vefsvæði Kveikt fyrir þetta vefsvæði + + Vefsvæðið er ekki stutt í augnablikinu Viltu kveikja á fækkun vefkökuborða fyrir %1$s? @@ -357,14 +379,53 @@ %1$s mun hreinsa vefkökur þessa vefsvæðis og endurlesa síðuna. Að hreinsa allar vefkökur gæti skráð þig út eða tæmt innkaupakörfur. - %1$s reynir sjálfkrafa að hafna vefkökubeiðnum á vefkökuborðum. Ef ekki er boðið upp á að hafna vefkökum getur %2$s samþykkt allar vefkökur til að hafna borðanum. + %1$s reynir sjálfkrafa að hafna vefkökubeiðnum á vefkökuborðum. Ef ekki er boðið upp á að hafna vefkökum getur %2$s samþykkt allar vefkökur til að hafna borðanum. + + + %1$s getur reynt að hafna sjálfkrafa beiðnum um vefkökur. + + %1$s reynir að hafna sjálfkrafa beiðnum um vefkökur á þeim vefsvæðum þar sem það er hægt. + + Vefkökuborðar fyrir bí! + + Hafna sjálfkrafa beiðnum um vefkökur, þegar það sé mögulegt. Annars skal samþykkja allar vefkökur til að afgreiða vefkökuborða. + + Hafna sjálfkrafa beiðnum um vefkökur, þegar mögulegt er. + + Leyfa %1$s að hafna sjálfkrafa beiðnum um vefkökur, þegar mögulegt er? + + Ekki núna + + Hunsa borða + + Þú munt sjá færri beiðnir um vefkökur + + Sjá færri sprettglugga fyrir vefkökur + + Svara sjálfkrafa sprettgluggum fyrir vefkökur til að vafra án truflana. %1$s mun hafna öllum beiðnum ef slíkt er í boði, eða samþykkja allar ef ekki. + + Svara sjálfkrafa sprettgluggum fyrir vefkökur til að vafra án truflana. %1$s mun hafna öllum beiðnum ef slíkt er mögulegt. + + Afgreiða sprettglugga + + Fækkun vefkökuborða + + Á að leyfa %1$s að hafna beiðni um samþykki á vefkökum ef mögulegt er eða að samþykkja aðgang að vefkökum þegar það er ekki hægt? + + Leyfa %1$s að hafna beiðni vefsvæðis um að samþykkja vefkökur ef mögulegt er? + + Leyfa Reynir sjálfkrafa að tengjast vefsvæðum með HTTPS dulritunareglum til að auka öryggi. - Virkt - + Virkt + Óvirkt + + Virkt í öllum flipum + + Virkt í huliðsflipum Frekari upplýsingar @@ -441,6 +502,11 @@ Tilkynningar + + Leyft + + Ekki leyft + Sérsniðið viðbótasafn @@ -464,8 +530,6 @@ Nýlega heimsótt - - Pocket Umhugsunarverðar sögur @@ -722,6 +786,13 @@ Loka eftir einn mánuð + + Opna á upphafssíðu + + Opna á síðasta flipa + + Opna á upphafssíðu eftir fjórar klukkustundir + Færa gamla flipa í óvirka @@ -984,9 +1055,15 @@ Undanþágur - Virkt + Virkt Óvirkt + + Staðlað + + Strangt + + Sérsniðið Leyfa hljóð og myndskeið @@ -1722,7 +1799,7 @@ Leitarstrengur sem á að nota - Skipta út fyrirspurninni með “%s”. Dæmi:\nhttps://www.google.com/search?q=%s + Skipta út fyrirspurninni með “%s”. Dæmi:\nhttps://www.google.com/search?q=%s Upplýsingar um sérsniðnar leitarvélar @@ -1922,8 +1999,6 @@ Sögur eftir efni Uppgötva meira - - Keyrt með Pocket. Keyrt með %s. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 03b3e819a..e0f0cef8c 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -66,11 +66,11 @@ - Aggiungi una scorciatoia per aprire schede anonime dalla schermata principale. + Aggiungi una scorciatoia per aprire schede anonime dalla schermata principale. Apri la prossima scheda anonima con un solo tocco. - Agg. scorciatoia + Agg. scorciatoia Agg. a schermata principale @@ -171,6 +171,8 @@ Interrompi Componenti aggiuntivi + + Informazioni sull’account Nessun componente aggiuntivo @@ -263,7 +265,7 @@ Impostazioni ricerca - Questa volta cerca con: + Questa volta cerca con: Questa volta cerca in: @@ -292,6 +294,18 @@ Chiudi + + + Le notifiche ti aiutano a ottenere di più da %s + + Sincronizza le schede tra dispositivi, gestisci download, ottieni suggerimenti per sfruttare al meglio la protezione della privacy di %s e molto altro ancora. + + Continua + + Non adesso + Apri una nuova scheda in %1$s @@ -348,13 +362,21 @@ Riduzione banner per i cookie Riduci i banner per i cookie + + Disattivata + + Attiva - Firefox cerca automaticamente di rifiutare le richieste di cookie quando viene visualizzato un banner per i cookie. Se l’opzione per rifiutarli non è disponibile, Firefox potrebbe accettare tutti i cookie per chiudere il banner. + Firefox cerca automaticamente di rifiutare le richieste di cookie quando viene visualizzato un banner per i cookie. Se l’opzione per rifiutarli non è disponibile, Firefox potrebbe accettare tutti i cookie per chiudere il banner. + + %1$s cerca automaticamente di rifiutare le richieste di cookie quando viene visualizzato un banner per i cookie. Disattivata per questo sito Attiva per questo sito + + Sito attualmente non supportato Attivare la riduzione banner per i cookie su %1$s? @@ -362,14 +384,53 @@ %1$s eliminerà i cookie per questo sito e aggiornerà la pagina. L’eliminazione dei cookie potrebbe disconnetterti dal sito o svuotare eventuali carrelli in sospeso. - %1$s può cercare di rifiutare automaticamente le richieste di cookie. Se l’opzione per rifiutarli non è disponibile, %2$s potrebbe accettare tutti i cookie per chiudere il banner. + %1$s può cercare di rifiutare automaticamente le richieste di cookie. Se l’opzione per rifiutarli non è disponibile, %2$s potrebbe accettare tutti i cookie per chiudere il banner. + + + %1$s può cercare di rifiutare automaticamente le richieste di cookie. + + %1$s cerca di rifiutare automaticamente le richieste di cookie nei siti supportati. + + Stop ai banner per i cookie + + Rifiuta automaticamente le richieste per i cookie, se possibile. In caso contrario accetta tutti i cookie per chiudere i banner. + + Rifiuta automaticamente le richieste per i cookie, se possibile. + + Consentire a %1$s di rifiutare automaticamente le richieste per i cookie, se possibile? + + Non adesso + + Chiudi banner + + Vedrai meno richieste per i cookie + + Liberati dei pop-up per i cookie + + Rispondi automaticamente ai pop-up per i cookie per una navigazione senza distrazioni. %1$s rifiuterà tutte le richieste, se possibile, o le accetterà tutte in caso contrario. + + Rispondi automaticamente alle richieste nei pop-up per i cookie per navigare senza distrazioni. %1$s rifiuterà tutte le richieste, se possibile. + + Chiudi pop-up + + Riduzione banner per i cookie + + Consentire a %1$s di rifiutare la richiesta di consenso per i cookie da parte di un sito o accettare i cookie se questo non fosse possibile? + + Consentire a %1$s di rifiutare la richiesta di consenso per i cookie da parte di un sito, se possibile? + + Consenti Tenta automaticamente la connessione ai siti utilizzando il protocollo di crittografia HTTPS per una maggiore sicurezza. - Attiva - + Attiva + Disattivata + + Attiva in tutte le schede + + Attiva nelle schede anonime Ulteriori informazioni @@ -449,6 +510,11 @@ Notifiche + + Consentite + + Non consentite + Raccolta di componenti aggiuntivi personalizzata @@ -472,8 +538,6 @@ Visitati di recente - - Pocket Storie che fanno riflettere @@ -735,6 +799,13 @@ Chiudi dopo un mese + + Apri pagina iniziale + + Apri scheda più recente + + Apri pagina iniziale dopo quattro ore + Sposta le vecchie schede nella sezione Inattive @@ -1005,10 +1076,16 @@ Eccezioni - Attiva + Attiva Disattivata + + Normale + + Restrittiva + + Personalizzata Consenti audio e video @@ -1769,7 +1846,7 @@ Stringa di ricerca da utilizzare - Sostituire la chiave di ricerca con “%s”. Esempio:\nhttps://www.google.com/search?q=%s + Sostituire la chiave di ricerca con “%s”. Esempio:\nhttps://www.google.com/search?q=%s Informazioni sul motore di ricerca personalizzato @@ -1971,8 +2048,6 @@ Storie per argomento Scopri altre storie - - Sviluppato con tecnologia Pocket Con tecnologia %s. diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 1a4906a91..5eca5d25c 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -66,11 +66,11 @@ - ניתן להוסיף קיצור דרך לפתיחת לשוניות פרטיות ממסך הבית. + ניתן להוסיף קיצור דרך לפתיחת לשוניות פרטיות ממסך הבית. פתיחת הלשונית הפרטית הבאה בהקשה אחת. - הוספת קיצור דרך + הוספת קיצור דרך הוספה למסך הבית @@ -171,6 +171,8 @@ עצירה תוספות + + מידע על החשבון אין תוספות כאן @@ -259,7 +261,7 @@ הגדרות חיפוש - הפעם לחפש את: + הפעם לחפש את: הפעם לחפש ב: @@ -288,6 +290,18 @@ סגירה + + + התראות עוזרות לך לעשות יותר עם %s + + סנכרון הלשוניות שלך בין מכשירים, ניהול הורדות, קבלת טיפים להפקת המירב מהגנת הפרטיות של %s ועוד. + + המשך + + לא כעת + פתיחת לשונית %1$s חדשה @@ -338,12 +352,21 @@ מצב HTTPS בלבד + + כבוי עבור אתר זה + + פעיל עבור אתר זה + מנסה להתחבר באופן אוטומטי לאתרים באמצעות פרוטוקול ההצפנה HTTPS לצורך אבטחה מוגברת. - פעיל - + פעיל + כבוי + + פעיל בכל האתרים + + פעיל בלשוניות פרטיות מידע נוסף @@ -422,6 +445,11 @@ התרעות + + מורשות + + לא מורשות + אוסף תוספות מותאם אישית @@ -446,8 +474,6 @@ נצפו לאחרונה - - Pocket סיפורים מעוררי מחשבה @@ -677,7 +703,7 @@ מסך הפתיחה - דף הבית + מסך הבית הלשונית האחרונה @@ -691,6 +717,13 @@ סגירה לאחר חודש אחד + + פתיחה במסך הבית + + פתיחה בלשונית האחרונה + + פתיחה במסך הבית לאחר 4 שעות + העברת לשוניות ישנות ללא פעילות @@ -958,10 +991,16 @@ חריגות - פעילה + פעילה כבויה + + רגיל + + מחמיר + + מותאם אישית לאפשר שמע ווידאו @@ -1700,7 +1739,7 @@ מחרוזת חיפוש לשימוש - יש להחליף את השאילתה עם ״%s״. לדוגמה:\nhttps://www.google.com/search?q=%s + יש להחליף את השאילתה עם ״%s״. לדוגמה:\nhttps://www.google.com/search?q=%s פרטי מנוע חיפוש מותאם אישית @@ -1901,8 +1940,6 @@ סיפורים לפי נושאים לגלות עוד - - מופעל באמצעות Pocket מופעל על־ידי %s. diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 505bc2f2f..f3d27612b 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -69,11 +69,11 @@ - プライベートタブを開くショートカットをホーム画面に追加します。 + プライベートタブを開くショートカットをホーム画面に追加します。 タップ 1 回で次のプライベートタブを開きます。 - 追加する + 追加する ホーム画面に追加 @@ -88,7 +88,7 @@ 閉じる - 閉じる + 閉じる @@ -175,6 +175,8 @@ 中止 アドオン + + アカウント情報 アドオンがありません @@ -266,7 +268,7 @@ 検索設定 - 今回の検索: + 今回の検索: 今回だけ使う検索エンジン: @@ -295,6 +297,18 @@ 閉じる + + + 通知は %s を活用するのに役立ちます + + 端末間でタブを共有したり、ダウンロードを管理したり、%s のプライバシー保護機能を最大限に活用するためのヒントを入手できます。 + + 続ける + + 後で + %1$s の新しいタブで開く @@ -351,14 +365,22 @@ Cookie バナーを減らす + + オフ + + オン - Firefox が自動的に Cookie バナーによる Cookie 要求を拒否しようとします。拒否オプションが利用できない場合、すべての Cookie を受け入れてバナーを閉じることがあります。 + Firefox が自動的に Cookie バナーによる Cookie 要求を拒否しようとします。拒否オプションが利用できない場合、すべての Cookie を受け入れてバナーを閉じることがあります。 + + %1$s が自動的に Cookie バナー上の Cookie 要求を拒否しようとします。 このサイトでオフ このサイトでオン + + 現在サポートされていないサイトです %1$s で Cookie バナー削減を有効にしますか? @@ -366,14 +388,55 @@ %1$s はこのサイトの Cookie を消去してページを読み込み直します。すべての Cookie を消去すると、ログアウトしたり、ショッピングカートが空になったりする場合があります。 - %1$s が自動的に Cookie 要求を拒否しようとします。拒否オプションが利用できない場合、%2$s がすべての Cookie を受け入れてバナーを閉じることがあります。 + %1$s が自動的に Cookie 要求を拒否しようとします。拒否オプションが利用できない場合、%2$s がすべての Cookie を受け入れてバナーを閉じることがあります。 + + + %1$s は自動的に Cookie 要求を拒否することができます。 + + %1$s はサポートされたサイト上の Cookie 要求を自動的に拒否しようとします。 + + Cookie バナーよ、去れ! + + Cookie 要求を可能な限り自動的に拒否します。拒否できない場合は、Cookie を受け入れてバナーを閉じます。 + + 可能な限り自動的に Cookie 要求を拒否します。 + + 可能な場合、%1$s に自動的に Cookie 要求を拒否させますか? + + 後で + + バナーを閉じる + + + Cookie 要求が少なくなります + + Cookie ポップアップを減らす + + + 目障りな Cookie ポップアップに自動的に応答します。%1$s が可能な限りすべての要求を拒否します。拒否できない場合はすべてを受け入れます。 + + 目障りな Cookie ポップアップに自動的に応答します。%1$s が可能な限りすべての要求を拒否します。 + + ポップアップを閉じる + + Cookie バナーの削減 + + 可能な場合、サイトの Cookie 同意要求を %1$s に拒否させ、そうでない場合は Cookie を受け入れますか? + + 可能な場合、サイトの Cookie 同意要求を %1$s に拒否させますか? + + 許可 セキュリティ強化のため、自動的に HTTPS 暗号化プロトコルを使用してサイトへの接続を試行します。 - オン - + オン + オフ + + すべてのタブに適用 + + プライベートタブに適用 詳細情報 @@ -452,6 +515,11 @@ 通知 + + 許可されています + + 許可されていません + カスタムアドオンコレクション @@ -474,8 +542,6 @@ 最近訪れたサイト - - Pocket 示唆に富むストーリー @@ -733,6 +799,13 @@ 1 か月後に閉じる + + ホームページ上に開く + + 最後のタブ上に開く + + 4 時間後、ホームページ上に開きます + 古いタブを休止中に移動する @@ -1003,10 +1076,16 @@ 例外設定 - オン + オン オフ + + 標準 + + 厳格 + + カスタム 音声と動画の再生を許可 @@ -1753,7 +1832,7 @@ 検索クエリー文字列 - クエリーを “%s” に置き換えます。例:\nhttps://www.google.com/search?q=%s + クエリーを “%s” に置き換えます。例:\nhttps://www.google.com/search?q=%s カスタム検索エンジンの詳細 @@ -1955,8 +2034,6 @@ トピック別のストーリー より詳しく - - Powered by Pocket. %s による提供です。 diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index e9be5e13b..48f0a6fb5 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -63,11 +63,11 @@ - დაამატეთ მალსახმობი, პირადი ჩანართების მთავარი ეკრანიდან გახსნისთვის. + დაამატეთ მალსახმობი, პირადი ჩანართების მთავარი ეკრანიდან გახსნისთვის. გახსენით მომდევნო პირადი ჩანართი ერთი შეხებით. - მალსახმობის დამატება + მალსახმობის დამატება მთავარ ეკრანზე დამატება @@ -166,6 +166,8 @@ შეჩერება დამატებები + + ანგარიშის შესახებ დამატებები არ არის @@ -254,7 +256,7 @@ ძიების პარამეტრები - საძიებოდ გამოიყენეთ: + საძიებოდ გამოიყენეთ: საძიებოდ გამოიყენეთ: @@ -283,6 +285,18 @@ დახურვა + + + შეტყობინებები შეძლებთ, უკეთ გამოიყენოთ %s + + დაასინქრონეთ ჩანართები მოწყობილობებს შორის, მართეთ ჩამოტვირთვები, მიიღეთ რჩევები, როგორ გამოიყენოთ %s სრულყოფილად პირადულობის დაცვით და ა.შ. + + განაგრძეთ + + ახლა არა + ახალი %1$s-ჩანართის გახსნა @@ -339,13 +353,21 @@ ფუნთუშის მოთხოვნების შემცირება შეამცირეთ ფუნთუშის მოთხოვნები + + გამორთ. + + ჩართ. - Firefox თავადვე შეეცდება უარყოს ფუნთუშის მოთხოვნები საიტზე ამომხტარ აბრებზე. თუ უარყოფა ვერ ხერხდება, Firefox ყველა ფუნთუშაზე თანხმობით მოიცილებს ამომხტომ აბრას. + Firefox თავადვე შეეცდება უარყოს ფუნთუშის მოთხოვნები საიტზე ამომხტარ აბრებზე. თუ უარყოფა ვერ ხერხდება, Firefox ყველა ფუნთუშაზე თანხმობით მოიცილებს ამომხტომ აბრას. + + %1$s თავად ეცდება უარყოს ფუნთუშების მოთხოვები და მოაცილოს აბრები. გამორთ. ამ საიტზე ჩართ. ამ საიტზე + + ეს საიტი ჯერ არაა მხარდაჭერილი ჩაირთოს ფუნთუშის მოთხოვნების შემცირება საიტზე %1$s? @@ -353,14 +375,54 @@ %1$s გაასუფთავებს ამ საიტის ფუნთუშებს და განაახლებს გვერდს. ყველა ფუნთუშის წაშლით შეიძლება გამოხვიდეთ ანგარიშებიდან და დაცარიელდეს საყიდლების კალათა. - %1$s თავადვე შეეცდება უარყოს ფუნთუშის მოთხოვნები. თუ უარყოფა ვერ ხერხდება, %2$s ყველა ფუნთუშაზე თანხმობით მოიცილებს ამომხტომ აბრას. + %1$s თავადვე შეეცდება უარყოს ფუნთუშის მოთხოვნები. თუ უარყოფა ვერ ხერხდება, %2$s ყველა ფუნთუშაზე თანხმობით მოიცილებს ამომხტომ აბრას. + + + %1$s ეცდება ავტომატურად უარყოს ფუნთუშების მოთხოვნები. + + %1$s ეცდება ავტომატურად უარყოს ფუნთუშების ყველა მოთხოვნა მხარდაჭერილ საიტებზე. + + ფუნთუშის მოთხოვნის აბრებო, აქშა! + + მოთხოვნილი ფუნთუშები იმთავითვე უარყოფილი იქნება. თუ უარყოფა ვერ ხერხდება, ყველა ფუნთუშაზე თანხმობით მოცილდება ამომხტომი აბრები. + + ფუნთუშების მოთხოვნის ავტომატური უაროფა, როცა კი შესაძლებელია. + + ნების დართვა, რომ %1$s თავადვე უარყოფდეს ფუნთუშების მოთხოვნას, როცა კი შესაძლებელია. + + ახლა არა + + აბრების არიდება + + უფრო იშვიათად იხილავთ ფუნთუშის მოთხოვნებს + + იხილეთ ნაკლები ამომხტარი მოთხოვნები + + + თავადვე უპასუხებს ფუნთუშის ამომხტარ მოთხოვნებს, გვერდების შეუფერხებლად მონახულებისთვის. %1$s შეეცდება, უარყოს ყველა მოთხოვნა, თუ არადა თანხმობით მოიცილებს. + + თავადვე უპასუხებს ფუნთუშის ამომხტარ მოთხოვნებს, გვერდების შეუფერხებლად მონახულებისთვის. %1$s შეეცდება, უარყოს ყველა მოთხოვნა, როცა კი შესაძლებელია. + + ამომხტომების არიდება + + ფუნთუშის მოთხოვნების შემცირება + + ნების დართვა, რომ %1$s თავადვე უარყოფდეს საიტის მიერ ფუნთუშების მოთხოვნას, როცა კი შესაძლებელი იქნება, ანდა თანხმობით იცილებდეს. + + ნების დართვა, რომ %1$s თავადვე უარყოფდეს საიტის ფუნთუშების მოთხოვნებს, როცა კი შესაძლებელია. + + ნებართვა თავადვე შეეცდება დაუკავშირდეს საიტებს დაშიფრული HTTPS-ოქმით, მეტი უსაფრთხოებისთვის. - ჩართ. - + ჩართ. + გამორთ. + + ყველა ჩანართში + + პირად ჩანართებში ვრცლად @@ -380,7 +442,7 @@ დასინქრონების მითითებული სერვერი - შეცვალა Firefox-ანგარიშის/სინქრონიზაციის სერვერი. პროგრამის დატოვება ცვლილებების ასასახად… + შეცვალა Firefox-ანგარიშის/სინქრონიზაციის სერვერი. პროგრამა დაიხურება ცვლილებების ასახვისთვის… ანგარიში @@ -438,6 +500,11 @@ შეტყობინებები + + ნებადართული + + შეზღუდული + შერჩეული დამატებების კრებული @@ -450,7 +517,7 @@ კრებულის მფლობელი (მომხმარებლის ID) - დამატებების კრებული შეიცვალა. დატოვეთ პროგრამა ცვლილებების ასასახად… + დამატებების კრებული შეიცვალა. პროგრამა დაიხურება ცვლილებების ასახვისთვის… @@ -460,8 +527,6 @@ ბოლოს ნანახი - - Pocket მეტად დამაფიქრებელი ამბები @@ -720,6 +785,13 @@ ერთ თვეში დახურვა + + საწყისი გვერდის გახსნა + + ბოლო ჩანართის გახსნა + + საწყისი გვერდის გახსნა ოთხი საათის შემდგომ + ძველი ჩანართების უქმეებში გადატანა @@ -984,9 +1056,15 @@ გამონაკლისები - ჩართ. + ჩართ. გამორთ. + + საშუალო + + მკაცრი + + მორგებული ხმისა და ვიდეოს დაშვება @@ -1728,7 +1806,7 @@ საძიებო ფრაზა - მიუთითეთ „%s“ საძიებო ტექსტად. მაგალითი:\nhttps://www.google.com/search?q=%s + მიუთითეთ „%s“ საძიებო ტექსტად. მაგალითი:\nhttps://www.google.com/search?q=%s მორგებული საძიებო სისტემის შესახებ @@ -1930,8 +2008,6 @@ ამბები თემატურად აღმოაჩინეთ მეტი - - უზრუნველყოფს Pocket. უზრუნველყოფს %s. diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index 9fb92520a..a78d7a277 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -69,11 +69,11 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara - Rnu anegzum akken ad teldiḍ iccaren usligen seg ugdil agejdan. + Rnu anegzum akken ad teldiḍ iccaren usligen seg ugdil agejdan. Senker iccer uslig uḍfir s yiwen usiti kan. - Rnu anegzum + Rnu anegzum Rnu ɣer ugdil agejdan @@ -174,6 +174,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Seḥbes Izegrar + + Talut n umiḍan Ulac izegrar da @@ -263,7 +265,7 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Nadi ismenyifen - Tura nadi wagi: + Tura nadi wagi: I unadi-a: @@ -292,6 +294,16 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Mdel + + + Ilɣa ttɛawanen ad tgeḍ ugar akked %s + + + Kemmel + + Mačči tura + Ldi-t iccer amaynut %1$s @@ -347,13 +359,19 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Asenqes n yiɣarracen n yinagan n tuqqna Senqes iɣarracen n yinagan n tuqqna + + Yensa + + Yermed - Firefox yettaɛraḍ s wudem awurman ad yegdel issutar n yinagan n tuqqna mi ara d-iban uɣerrac n yinagan. Ma yella ulac taxtiṛt n ugdal, Firefox yezmer ad yeqbel meṛṛa inagan n tuqqna i umdal n uɣarrac. + Firefox yettaɛraḍ s wudem awurman ad yegdel issutar n yinagan n tuqqna mi ara d-iban uɣerrac n yinagan. Ma yella ulac taxtiṛt n ugdal, Firefox yezmer ad yeqbel meṛṛa inagan n tuqqna i umdal n uɣarrac. Sens i usmel-a Rme i usmel-a + + Asmel-a ur yettusefrak ara akka tura Rmed asenqes n yiɣerracen n yinagan n tuqqna i %1$s? @@ -362,14 +380,47 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara %1$s ad isfeḍ inagan n tuqqna n usmel-a syen ad issesfer asebter. Asfaḍ meṛṛa n yinagan n tuqqna yezmer ad ak·am-isseḥbes tuqqna neɣ ad yenɣel tiqecwalin n tiɣtin. - %1$s yezmer ad yeɛreḍ s wudem awurman ad yegdel issutar n yinagan n tuqqna. Ma yella ulac taxtiṛt n ugdal, %2$s yezmer ad yeqbel meṛṛa inagan n tuqqna i umdal n uɣarrac. + %1$s yezmer ad yeɛreḍ s wudem awurman ad yegdel issutar n yinagan n tuqqna. Ma yella ulac taxtiṛt n ugdal, %2$s yezmer ad yeqbel meṛṛa inagan n tuqqna i umdal n uɣarrac. + + + %1$s yezmer ad yeɛreḍ s wudem awurman ad yagi issutar n yinagan n tuqqna. + + %1$s yettaɛraḍ s wudem awurman ad yagi issutar n yinagan n tuqqna deg yismal i ten-yessefraken. + + Dayen iɣarracen n yinagan n tuqqna! + + Yettagi issutar n yinagan n tuqqna s wudem awurman, mi ara yili wamek. Neɣ, iqebbel inagan n tuqqna i waken ad yekkes iɣarracen. + + Yettagi s wudem awurman issutar n yinagan n tuqqna mi ara tettunefk tegnit. + + Sireg %1$s s ugdal awurman n yissutar n yinagan n tuqqna mi ara tettunefk tegnit? + + Mačči tura + + Mdel iɣarracen + + Ad twaliḍ drus n yissutar n yinagan n tuqqna + + Wali cwiṭ n yisfuyla udhimen n yinagan n tuqqna + + Mdel isfuyla udhimen + + Asenqes n yiɣarracen n yinagan n tuqqna + + Sireg %1$s i tugin n usssuter n uqbal n yinagan n tuqqna ma yella wamek? + + Sireg Ɛreḍ ad teqqneḍ s wudem awurman ɣer yismal s useqdec n uneggaf n uwgelhen HTTPS i tɣellist ɛlayen. - Yermed - + Yermed + Yensa + + Rmed deg meṛṛa accaren + + Rmed deg yiccer uslig Issin ugar @@ -448,6 +499,11 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Ilɣa + + Ittusireg + + Ur yettusireg ara + Sagen tagrumma n yizegrar @@ -471,8 +527,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Yemmẓer melmi kan - - Pocket Tiqsiḍin i ijebbden lwelha @@ -735,6 +789,14 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Mdel seld yiwen wayyur + + Ldi deg ugejdan + + Ldi deg yiccer aneggaru + + + Ldi deg usebtar agejdan seld ukkuẓ n yisragen + Senkez accaren iqburen ɣer irurmiden @@ -1003,9 +1065,15 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Tisuraf - Irmed + Irmed Insa + + Alugen + + Uḥris + + Sagen Sireg ameslaw d uvidyu @@ -1746,7 +1814,7 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Aḍris ara tnadiḍ - Beddel aḍris n unadi “%s”. Amedya: \nhttps://www.google.com/search?q=%s + Beddel aḍris n unadi “%s”. Amedya: \nhttps://www.google.com/search?q=%s Talqayt ɣef umsedday n unadi udmawan @@ -1951,8 +2019,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Smizzwer s usentel Issin ugar - - Sɣur Pocket. Ddaw leɛnaya n %s. diff --git a/app/src/main/res/values-kk/strings.xml b/app/src/main/res/values-kk/strings.xml index 2b5f80c9d..6200005d7 100644 --- a/app/src/main/res/values-kk/strings.xml +++ b/app/src/main/res/values-kk/strings.xml @@ -63,12 +63,12 @@ - Үй экранынан жекелік беттерді ашу үшін жарлықты қосыңыз. + Үй экранынан жекелік беттерді ашу үшін жарлықты қосыңыз. Келесі жекелік бетін бір шерту арқылы ашыңыз. - Жарлықты қосу + Жарлықты қосу Үй экранына қосу @@ -169,6 +169,8 @@ Тоқтату Қосымшалар + + Тіркелгі ақпараты Осында қосымшалар жоқ @@ -257,7 +259,7 @@ Іздеу баптаулары - Бұл жолы іздеу: + Бұл жолы іздеу: Бұл жолы келесі жерде іздеу: @@ -286,6 +288,18 @@ Жабу + + + Хабарландырулар %s арқылы көбірек жұмыс бітіруге көмектеседі + + Беттерді құрылғылар арасында синхрондаңыз, жүктемелерді басқарыңыз, %s жекелігін қорғау мүмкіндігін барынша пайдалану туралы кеңестер алыңыз және т.б. + + Жалғастыру + + Қазір емес + Жаңа %1$s бетін ашу @@ -293,8 +307,9 @@ Іздеу Интернетте іздеу + - + Дауыстық іздеу @@ -304,7 +319,7 @@ Осы туралы - + Негізгі іздеу жүйесі Іздеу @@ -340,14 +355,22 @@ Cookie баннерлерін азайту Cookie баннерлерін азайту + + Сөндірулі + + Іске қосулы - Firefox cookie баннерлеріндегі cookie сұрауларын автоматты түрде қабылдамау әрекетін жасайды. Қабылдамау опциясы қол жетімді болмаса, Firefox баннерді жабу үшін барлық cookie файлдарын қабылдауы мүмкін. + Firefox cookie баннерлеріндегі cookie сұрауларын автоматты түрде қабылдамау әрекетін жасайды. Қабылдамау опциясы қол жетімді болмаса, Firefox баннерді жабу үшін барлық cookie файлдарын қабылдауы мүмкін. + + %1$s cookie баннерлеріндегі cookie сұрауларын автоматты түрде қабылдамау әрекетін жасайды. Бұл сайт үшін сөндірілген Бұл сайт үшін іске қосылған + + Сайтқа ағымдағы уақытта қолдау жоқ %1$s үшін cookie баннерлерін азайту мүмкіндігін іске қосу керек пе? @@ -356,14 +379,56 @@ %1$s осы сайттың cookie файлдарын тазартып, бетті жаңартады. Барлық cookie файлдарын тазарту салдарынан сіз сайттан шығуыңыз мүмкін немесе дүкен себеттері тазартылуы мүмкін. - %1$s cookie сұрауларын автоматты түрде тайдыру әрекетін жасайды. Тайдыру опциясы қол жетімді болмаса, %2$s баннерді жабу үшін барлық cookie файлдарын қабылдауы мүмкін. + %1$s cookie сұрауларын автоматты түрде тайдыру әрекетін жасайды. Тайдыру опциясы қол жетімді болмаса, %2$s баннерді жабу үшін барлық cookie файлдарын қабылдауы мүмкін. + + + %1$s cookie сұрауларын автоматты түрде қабылдамау әрекетін жасай алады. + + %1$s қолдау көрсетілетін сайттардағы барлық cookie сұрауларын автоматты түрде қабылдамау әрекетін жасайды. + + Cookie баннерлері жоғалсын! + + Cookie сұрауларын мүмкіндігінше автоматты түрде тайдыру. Болмаса, cookie баннерлерін жабу үшін барлық cookie файлдарын қабылдау. + + Мүмкіндігінше cookie сұрауларын автоматты түрде қабылдамау. + + %1$s үшін cookie сұрауларын мүмкіндігінше автоматты түрде қабылдамау рұқсатын беру керек пе? + + Қазір емес + + + Баннерлерді тайдыру + + Сіз азырақ cookie сұрауларын көресіз + + + Азырақ cookie қалқымалы терезелерін көру + + Мазасыз шолу үшін cookie файлдарының қалқымалы терезелеріне автоматты түрде жауап беру. %1$s барлық сұрауларды мүмкіндігінше тайдырады, ал болмаса, барлығын қабылдайды. + + Мазасыз шолу үшін cookie файлдарының қалқымалы терезелеріне автоматты түрде жауап беру. %1$s барлық сұрауларды мүмкіндігінше қабылдамайды. + + Қалқымалы терезелерді тайдыру + + Cookie баннерлерін азайту + + + %1$s сайтына cookie файлына рұқсат сұрауын тайдыру, немесе мүмкін болмаса, cookie файлдарына рұқсатын беру керек пе? + + Мүмкін болса, %1$s үшін сайтының cookie файлына рұқсат сұрауын қабылдамауға рұқсат бересіз бе? + + Рұқсат ету Қауіпсіздікті арттыру үшін сайттарға HTTPS шифрлеу хаттамасын пайдаланып автоматты түрде қосылу әрекетін жасайды. - Іске қосулы - + Іске қосулы + Сөндірулі + + Барлық беттерде + + Жекелік беттерінде Көбірек білу @@ -440,6 +505,11 @@ Хабарламалар + + Рұқсат етілген + + Рұқсат етілмеген + Таңдауыңызша қосымшалар жинағы @@ -462,8 +532,6 @@ Жуырда қаралған - - Pocket Ойландыратын әңгімелер @@ -717,6 +785,14 @@ Бір айдан кейін жабу + + Үй бетінде ашу + + Соңғы бетте ашу + + + Үй бетінде төрт сағаттан кейін ашу + Ескі беттерді белсенді емес күйге жылжыту @@ -980,9 +1056,15 @@ Ережеден бөлек - Іске қосулы + Іске қосулы Сөндірулі + + Қалыпты + + Қатаң + + Таңдауыңызша Аудио мен видеоны рұқсат ету @@ -1725,7 +1807,7 @@ Қолданылатын іздеу жолы - Сұранымды "%s" жолымен алмастырыңыз. Мысалы:\nhttps://www.google.com/search?q=%s + Сұранымды "%s" жолымен алмастырыңыз. Мысалы:\nhttps://www.google.com/search?q=%s Таңдауыңызша іздеу жүйесінің ақпараты @@ -1925,8 +2007,6 @@ Тақырып бойынша әңгімелер Көбірек шолу - - Pocket негізінде. %s негізінде. diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index 1a630c875..56219a302 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -66,11 +66,11 @@ - Ji bo ku tu ji ekrana xwe ya Destpêkê hilpekîneke veşartî vekî, kurterêyekê tevlî bike. + Ji bo ku tu ji ekrana xwe ya Destpêkê hilpekîneke veşartî vekî, kurterêyekê tevlî bike. Hilpekîna din a veşartî bi destdanekê veke. - Kurterêyê tevlî bike + Kurterêyê tevlî bike Tevlî ekrana destpêkê bike @@ -173,6 +173,8 @@ Rawestîne Pêvek + + Agahiyên hesêb Ti pêvek li vir tune @@ -220,7 +222,7 @@ Serast bike - Serûpelê taybet bike + Serrûpelê taybet bike Ekrana sereke @@ -262,14 +264,14 @@ Eyarên lêgerînê - Lêgerîna niha: + Lêgerîna niha: Bi vê bigere: - Serûpela xwe ya taybet nas bike. Tu yê li virê hilpekîn, bijare û encamên lêgerînên xwe yên dawiyê bibînî. + Serrûpela xwe ya taybet nas bike. Tu yê li virê hilpekîn, bijare û encamên lêgerînên xwe yên dawiyê bibînî. Tu bi xêr hatiyî înterneteke kesanetir @@ -290,6 +292,15 @@ Bigire + + + Bi xêra agahdariyan bi %sê re zêdetir tiştan bike + + Bidomîne + + Ne niha + Hilpekînek nû ya %1$s `ê veke @@ -346,7 +357,7 @@ Agahdariyên xurekan kêm bike - Firefox bi awayekî otomatîk hewl dide ku daxwazên xurekan ên di agahdariyên xurekan de red bike. Heke vebijarka redkirinê ne berdest be, dibe ku Firefox ji bo girtina agahdariyê hemû xurekan qebûl bike. + Firefox bi awayekî otomatîk hewl dide ku daxwazên xurekan ên di agahdariyên xurekan de red bike. Heke vebijarka redkirinê ne berdest be, dibe ku Firefox ji bo girtina agahdariyê hemû xurekan qebûl bike. Ji bo vê malperê girtî ye @@ -359,14 +370,23 @@ %1$s ew ê hemû xurekên malperê paqij bike û malperê nû bike. Paqijkirina hemû xurekan dibe ku têketina te bigire û sepeta te ya danûstandinê vala bike. - %1$s, dikare bi awayekî otomatîk daxwazên xurekan red bike. Heke vebijarka redkirinê ne berdest be, dibe ku %2$s ji bo girtina agahdariyê hemû xurekan qebûl bike. + %1$s, dikare bi awayekî otomatîk daxwazên xurekan red bike. Heke vebijarka redkirinê ne berdest be, dibe ku %2$s ji bo girtina agahdariyê hemû xurekan qebûl bike. + + + Ne niha + + Destûrê bide Ji bo ewlekariya zêdetir hewlê bide ku bi protokola şîfrekirî ya HTTPSê bi awayekî xweber têkeve malperan. - Vekirî - + Vekirî + Girtî + + Di hemû hilpekînan de vekirî + + Di hilpekînên veşartî de vekirî Agahiyên zêdetir @@ -394,7 +414,7 @@ Rûkar - Serûpel + Serrûpel Hereketên tiliyan @@ -442,6 +462,11 @@ Danezan + + Destûr hat dayîn + + Destûr nehat dayîn + Koleksiyona pêvekên taybet @@ -465,8 +490,6 @@ Seredanên dawî - - Pocket Gotarên balkêş @@ -719,7 +742,7 @@ Hilpekîna dawiyê - Serûpelê piştî çar saetan neçalak + Serrûpelê piştî çar saetan neçalak Manûelê bigire @@ -729,6 +752,13 @@ Piştî mehekê bigire + + Serrûpelê veke + + Hilpekîna dawî veke + + Piştî çar saetan serrûpelê veke + Hilpekînên kevn veguheze neçalakê @@ -993,9 +1023,15 @@ Istisna - Vekirî + Vekirî Girtî + + Standard + + Tund + + Taybet Destûrê bide deng û vîdyoyê @@ -1732,7 +1768,7 @@ Rêzika lêgerînê ya ji bo bikaranînê - Lêpirsînê bi “%s”ê pev biguherîne. Mînak:\nhttps://www.google.com/search?q=%s + Lêpirsînê bi “%s”ê pev biguherîne. Mînak:\nhttps://www.google.com/search?q=%s Hûrgiliyên motora lêgerînê ya taybet @@ -1930,8 +1966,6 @@ Gotarên li gorî sernavan Zêdetir keşf bike - - Bi piştgiriya Pocketê. Bihêzkirin ji aliyê %sê. diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 23d0f0618..d6c5b56a2 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -71,11 +71,11 @@ - 홈 화면에서 사생활 보호 탭을 열기 위한 바로 가기 추가. + 홈 화면에서 사생활 보호 탭을 열기 위한 바로 가기 추가. 한 번 눌러 다음 사생활 보호 탭을 시작합니다. - 바로 가기 추가 + 바로 가기 추가 홈 화면에 추가 @@ -176,6 +176,8 @@ 중지 부가 기능 + + 계정 정보 부가 기능 없음 @@ -267,7 +269,7 @@ 검색 설정 - 이번만 검색: + 이번만 검색: 이번만 검색: @@ -296,6 +298,18 @@ 닫기 + + + 알림은 %s로 더 많은 작업을 수행하는 데 도움이 됩니다. + + 기기 간에 탭을 동기화하고, 다운로드를 관리하고, %s의 개인 정보 보호를 최대한 활용하는 방법에 대한 팁을 얻으세요. + + 계속 + + 나중에 + 새 %1$s 탭 열기 @@ -351,13 +365,21 @@ 쿠키 배너 감소 쿠키 배너 줄이기 + + 꺼짐 + + 켜짐 - Firefox는 자동으로 쿠키 배너에서 쿠키 요청을 거부하려고 시도합니다. 거부 옵션을 사용할 수 없는 경우, Firefox는 배너를 닫기 위해 모든 쿠키를 허용할 수 있습니다. + Firefox는 자동으로 쿠키 배너에서 쿠키 요청을 거부하려고 시도합니다. 거부 옵션을 사용할 수 없는 경우, Firefox는 배너를 닫기 위해 모든 쿠키를 수락할 수 있습니다. + + %1$s는 자동으로 쿠키 배너에서 쿠키 요청을 거부하려고 시도합니다. 이 사이트에서 꺼짐 이 사이트에서 켜짐 + + 현재 지원되지 않는 사이트 %1$s에 대해 쿠키 배너 감소를 켜시겠습니까? @@ -366,14 +388,55 @@ %1$s는 이 사이트의 쿠키를 지우고 페이지를 새로 고침합니다. 모든 쿠키를 삭제하면 로그아웃되거나 장바구니가 비워질 수 있습니다. - %1$s는 자동으로 쿠키 요청을 거부하려고 시도합니다. 거부 옵션을 사용할 수 없는 경우, %2$s는 배너를 닫기 위해 모든 쿠키를 허용할 수 있습니다. + %1$s는 자동으로 쿠키 요청을 거부하려고 시도합니다. 거부 옵션을 사용할 수 없는 경우, %2$s는 배너를 닫기 위해 모든 쿠키를 수락할 수 있습니다. + + + %1$s는 쿠키 요청을 자동으로 거부할 수 있습니다. + + %1$s는 지원되는 사이트에서 모든 쿠키 요청을 자동으로 거부하려고 시도합니다. + + 쿠키 배너가 사라졌습니다! + + 가능한 경우 쿠키 요청을 자동으로 거부합니다. 그렇지 않으면 배너를 닫기 위해 모든 쿠키를 수락합니다. + + 가능한 경우 쿠키 요청을 자동으로 거부합니다. + + 가능한 경우 %1$s가 자동으로 쿠키 요청을 거부하도록 허용하시겠습니까? + + 나중에 + + 배너 닫기 + + + 쿠키 요청이 더 적게 표시됩니다. + + 쿠키 팝업 덜 보기 + + 방해받지 않는 탐색을 위해 쿠키 팝업에 자동으로 응답합니다. %1$s는 가능한 경우 모든 요청을 거부하고 그렇지 않은 경우 모두 수락합니다. + + + 방해받지 않는 탐색을 위해 쿠키 팝업에 자동으로 응답합니다. %1$s는 가능한 경우 모든 요청을 거부합니다. + + 팝업 닫기 + + 쿠키 배너 감소 + + 가능한 경우 %1$s가 사이트의 쿠키 동의 요청을 거부하거나 가능하지 않은 경우 쿠키 액세스를 수락하도록 허용하시겠습니까? + + 가능한 경우 %1$s가 사이트의 쿠키 동의 요청을 거부하도록 허용하시겠습니까? + + 허용 보안 강화를 위해 HTTPS 암호화 프로토콜을 사용하여 사이트에 자동으로 연결을 시도합니다. - 켜짐 - + 켜짐 + 꺼짐 + + 모든 탭에서 켜짐 + + 사생활 보호 탭에서 켜짐 더 알아보기 @@ -452,6 +515,11 @@ 알림 + + 허용됨 + + 허용되지 않음 + 사용자 지정 부가 기능 모음집 @@ -474,8 +542,6 @@ 최근에 방문함 - - 포켓 생각하게 하는 이야기 @@ -735,6 +801,13 @@ 한 달 후 닫기 + + 홈페이지에서 열기 + + 마지막 탭에서 열기 + + 4시간 후 홈페이지에서 열기 + 이전 탭을 비활성으로 이동 @@ -1009,10 +1082,16 @@ 예외 목록 - 켜짐 + 켜짐 꺼짐 + + 표준 + + 엄격 + + 사용자 지정 오디오 및 비디오 허용 @@ -1777,7 +1856,7 @@ 사용할 검색 문자열 - 쿼리를 “%s”로 바꾸세요. 예:\nhttps://www.google.com/search?q=%s + 쿼리를 “%s”로 바꾸세요. 예:\nhttps://www.google.com/search?q=%s 사용자 지정 검색 엔진 상세 정보 @@ -1980,8 +2059,6 @@ 주제별 이야기 더 발견하기 - - 포켓 제공 %s 제공. diff --git a/app/src/main/res/values-lij/strings.xml b/app/src/main/res/values-lij/strings.xml index cb0299f34..344d5d6a6 100644 --- a/app/src/main/res/values-lij/strings.xml +++ b/app/src/main/res/values-lij/strings.xml @@ -31,10 +31,10 @@ - Azonzi \'n scorsaieu pe arvî i feuggi privæ da-a pagina prinçipâ. + Azonzi \'n scorsaieu pe arvî i feuggi privæ da-a pagina prinçipâ. - Azonzi scorsaieu - + Azonzi scorsaieu + No graçie @@ -116,8 +116,6 @@ Permette i conseggi de riçerca inte sescioin privæ? Tutto quello che scrivi inta bara di indirissi de %s saiâ condivizo co-o motô de riçerca predefinio. - - Atre informaçioin Çerca @@ -162,6 +160,7 @@ Permetti e föto do schermo inta navegaçion privâ Azonzi scorsaieu navegaçion privâ + Acesibilitæ @@ -178,8 +177,6 @@ Tema Personalizza - - Scincronizza segnalibbri, poule segrete e atro co-o teu conto Firefox. Conto Firefox @@ -272,10 +269,6 @@ Dæti de marketing - - - Açendi Sync - Acedi pe conetite torna @@ -349,8 +342,6 @@ Menû feuggi averti Sarva feuggi in coleçion - - Menû feuggio Scancella coleçion @@ -486,7 +477,7 @@ Eceçioin - Açeizo + Açeizo Asmòrtou @@ -557,7 +548,7 @@ Deuviæ de fresco Acedi a Sync - + Manda a tutti i dispoxitivi Conetti torna a Sync @@ -593,8 +584,6 @@ Feuggio serou Feuggi seræ - - Azonto a-i megio sciti! Feuggio privou serou @@ -663,8 +652,6 @@ Sciòrti - - Questo o scanceliâ tutti i dæti de navegaçion %s o scanceliâ i dæti de navegaçion seleçionæ. @@ -677,36 +664,6 @@ Scancella dæti navegaçion… - - - Firefox Preview oua se ciamma Firefox Nightly - - Firefox Nightly o vegne agiornou tutte e neutti e-o l\'à de carateristiche sperimentâ. - A ògni mòddo, o peu ese meno stabile. Scarega o nòstro navegatô beta pe avei ciù stabilitæ. - - Descarega Firefox pe Android Beta - - - Firefox Nightly o s\'é mesciou - - - Sta app a no riçeiviâ ciù agiornamenti de seguessa. No deuviâ ciù sta app e passa a-o neuvo Nightly. - \n\nPe trasferî i teu segnalibbri, acessi e stöia in sce \'n atra app, crea \'n conto Firefox. - - Passa a-o neuvo Nightly - - - Firefox Nightly o s\'é mesciou - - Sta app a no riçeiviâ ciù agiornamenti de seguessa. No deuviâ ciù sta app e passa a-o neuvo Nightly. - \n\nPe trasferî i teu segnalibbri, acessi e stöia in sce \'n atra app, crea \'n conto Firefox. - - Piggite o neuvo Nightly - - - - Benvegnuo in %s! Sincronizaçion ativa @@ -714,8 +671,6 @@ Restritivo - - A teu privacy Lezzi a nòstra informativa in sciâ privacy @@ -973,7 +928,7 @@ Stringa de riçerca da deuviâ - Cangia a ciave de riçerca con “%s”. Ezenpio:\nhttps://www.google.com/search?q=%s + Cangia a ciave de riçerca con “%s”. Ezenpio:\nhttps://www.google.com/search?q=%s Informaçioin in sciô motô de riçerca personalizou @@ -993,19 +948,6 @@ %s scancelou - - Benvegnuo into %s tutto neuvo - - O t\'aspeta un navegatô riprogetou conpletamente, con de megio prestaçioin e fonçioin pe agiutate in linia.\n\nPe piaxei aspeta tanto che agiornemmo %s con - - Agiornamento de %s… - - Xeua %s - - Migraçion conpletâ - - Poule segrete - Pe permetilo: @@ -1025,8 +967,6 @@ Nisciunn-a eceçion pe-i sciti T\'ê seguo de voei scancelâ sto segnalibbro? - - Azonto a-i megio sciti! Verificou da: %1$s @@ -1056,8 +996,6 @@ Çerca co-a voxe Parla oua - - @@ -1073,9 +1011,6 @@ Acedi a Sync - - - T\'ê seguo arivou a-o limite mascimo pe-i megio sciti Va ben, ò capio diff --git a/app/src/main/res/values-lo/strings.xml b/app/src/main/res/values-lo/strings.xml index cdbca83bb..8ecce6c9a 100644 --- a/app/src/main/res/values-lo/strings.xml +++ b/app/src/main/res/values-lo/strings.xml @@ -63,11 +63,11 @@ - ເພີ່ມທາງລັດເພື່ອເປີດແຖບສ່ວນຕົວຈາກໜ້າຈໍຫລັກຂອງທ່ານ. + ເພີ່ມທາງລັດເພື່ອເປີດແຖບສ່ວນຕົວຈາກໜ້າຈໍຫລັກຂອງທ່ານ. ເປີດໃຊ້ແຖບສ່ວນຕົວຕໍ່ໄປໃນແທັບດຽວ. - ເພີ່ມທາງລັດ + ເພີ່ມທາງລັດ ເພີ່ມເຂົ້າໄປຫນ້າຈໍຫລັກ @@ -168,6 +168,8 @@ Add-ons + + ຂໍ້ມູນບັນຊີ ບໍ່ມີ add-ons ຢູ່ທີ່ນີ້ @@ -257,7 +259,7 @@ ການຕັ້ງຄ່າການຄົ້ນຫາ - ເວລານີ້ຄົ້ນຫາ: + ເວລານີ້ຄົ້ນຫາ: ເວລານີ້ຄົ້ນຫາໃນ: @@ -287,6 +289,18 @@ ປິດ + + + ການແຈ້ງເຕືອນຊ່ວຍໃຫ້ທ່ານເຮັດໄດ້ຫຼາຍຂຶ້ນກັບ %s + + ຊິ້ງແຖບຂອງທ່ານລະຫວ່າງອຸປະກອນ, ຈັດການການດາວໂຫຼດ, ຮັບຄໍາແນະນໍາກ່ຽວກັບການໃຊ້ປະໂຫຍດສູງສຸດຈາກການປົກປ້ອງຄວາມເປັນສ່ວນຕົວຂອງ %s ແລະອື່ນໆອີກ. + + ສືບຕໍ່ + + ບໍ່ແມ່ນຕອນນີ້ + ເປີດແຖບ %1$s ໃໝ່ @@ -341,13 +355,21 @@ ການຫຼຸດປ້າຍໂຄສະນາຄຸກກີ ຫຼຸດປ້າຍໂຄສະນາຄຸກກີ + + ປິດ + + ເປີດ - Firefox ພະຍາຍາມປະຕິເສດການຮ້ອງຂໍຄຸກກີໃນປ້າຍໂຄສະນາຄຸກກີອັດຕະໂນມັດ. ຖ້າທາງເລືອກການປະຕິເສດບໍ່ສາມາດໃຊ້ໄດ້, Firefox ອາດຈະຍອມຮັບ cookies ທັງຫມົດເພື່ອປິດປ້າຍໂຄສະນາ. + Firefox ພະຍາຍາມປະຕິເສດການຮ້ອງຂໍຄຸກກີໃນປ້າຍໂຄສະນາຄຸກກີອັດຕະໂນມັດ. ຖ້າທາງເລືອກການປະຕິເສດບໍ່ສາມາດໃຊ້ໄດ້, Firefox ອາດຈະຍອມຮັບ cookies ທັງຫມົດເພື່ອປິດປ້າຍໂຄສະນາ. + + %1$s ພະຍາຍາມປະຕິເສດການຮ້ອງຂໍຄຸກກີໂດຍອັດຕະໂນມັດໃນປ້າຍໂຄສະນາຄຸກກີ. ປິດສໍາລັບເວັບໄຊທ໌ນີ້ ເປິດສຳລັບເວັບໄຊນີ້ + + ຕອນນີ້ບໍ່ຮອງຮັບເວັບໄຊ ເປີດໃຊ້ການຫຼຸດປ້າຍໂຄສະນາຄຸກກີສຳລັບ %1$s ບໍ? @@ -355,14 +377,53 @@ %1$s ຈະລຶບລ້າງຄຸກກີ້ຂອງເວັບໄຊນີ້ ແລະໂຫຼດໜ້ານີ້ຄືນໃໝ່. ການລຶບລ້າງຄຸກກີ້ທັງໝົດອາດເຮັດໃຫ້ເຈົ້າອອກຈາກລະບົບ ຫຼືກະຕ່າຊື້ເຄື່ອງຫວ່າງເປົ່າ. - %1$s ສາມາດພະຍາຍາມປະຕິເສດການຮ້ອງຂໍຄຸກກີໂດຍອັດຕະໂນມັດ. ຖ້າຕົວເລືອກການປະຕິເສດບໍ່ສາມາດໃຊ້ໄດ້, %2$s ອາດຈະຍອມຮັບ cookies ທັງໝົດເພື່ອປິດປ້າຍໂຄສະນາ. + %1$s ສາມາດພະຍາຍາມປະຕິເສດການຮ້ອງຂໍຄຸກກີໂດຍອັດຕະໂນມັດ. ຖ້າຕົວເລືອກການປະຕິເສດບໍ່ສາມາດໃຊ້ໄດ້, %2$s ອາດຈະຍອມຮັບ cookies ທັງໝົດເພື່ອປິດປ້າຍໂຄສະນາ. + + + %1$s ສາມາດພະຍາຍາມປະຕິເສດການຮ້ອງຂໍຄຸກກີໂດຍອັດຕະໂນມັດ. + + %1$s ພະຍາຍາມປະຕິເສດຄຳຮ້ອງຂໍຄຸກກີທັງໝົດໃນເວັບໄຊທີ່ຮອງຮັບໂດຍອັດຕະໂນມັດ. + + ປ້າຍໂຄສະນາຄຸກກີເລີ່ມແລ້ວ! + + ປະຕິເສດການຮ້ອງຂໍຄຸກກີໂດຍອັດຕະໂນມັດ, ເມື່ອເປັນໄປໄດ້. ຖ້າບໍ່ດັ່ງນັ້ນ, ຍອມຮັບ cookies ທັງໝົດເພື່ອປິດປ້າຍໂຄສະນາຄຸກກີ. + + ປະຕິເສດການຮ້ອງຂໍຄຸກກີໂດຍອັດຕະໂນມັດ, ເມື່ອເປັນໄປໄດ້. + + ອະນຸຍາດໃຫ້ %1$s ປະຕິເສດຄຳຮ້ອງຂໍຄຸກກີໂດຍອັດຕະໂນມັດເມື່ອເປັນໄປໄດ້ບໍ? + + ບໍ່​ແມ່ນ​ຕອນ​ນີ້ + + ປິດປ້າຍໂຄສະນາ + + ທ່ານຈະເຫັນຄຳຮ້ອງຂໍຄຸກກີໜ້ອຍລົງ + + ເບິ່ງປັອບອັບຄຸກກີໜ້ອຍລົງ + + ຕອບອັດຕະໂນມັດຄຸກກີປັອບອັບສໍາລັບການທ່ອງເວັບທີ່ບໍ່ມີສິ່ງລົບກວນ. %1$s ຈະປະຕິເສດການຮ້ອງຂໍທັງໝົດຖ້າເປັນໄປໄດ້, ຫຼືຍອມຮັບທັງໝົດຖ້າບໍ່ແມ່ນ. + + ຕອບອັດຕະໂນມັດຄຸກກີປັອບອັບສໍາລັບການທ່ອງເວັບທີ່ບໍ່ມີສິ່ງລົບກວນ. %1$s ຈະປະຕິເສດການຮ້ອງຂໍທັງໝົດຖ້າເປັນໄປໄດ້. + + ປິດປັອບອັບ + + ການຫຼຸດປ້າຍໂຄສະນາຄຸກກີ + + ອະນຸຍາດໃຫ້ %1$s ປະຕິເສດການຮ້ອງຂໍການຍິນຍອມເຫັນດີຈາກຄຸກກີຂອງເວັບໄຊຖ້າເປັນໄປໄດ້ ຫຼືຍອມຮັບການເຂົ້າເຖິງຄຸກກີເມື່ອບໍ່ເປັນໄປໄດ້ບໍ? + + ອະນຸຍາດໃຫ້ %1$s ປະຕິເສດການຮ້ອງຂໍການຍິນຍອມເຫັນດີຈາກຄຸກກີຂອງເວັບໄຊຖ້າເປັນໄປໄດ້ບໍ? + + ອະນຸຍາດ ພະຍາຍາມເຊື່ອມຕໍ່ຫາເວັບໄຊໂດຍອັດຕະໂນມັດໂດຍໃຊ້ໂປຣໂຕຄໍການເຂົ້າລະຫັດ HTTPS ເພື່ອຄວາມປອດໄພທີ່ເພີ່ມຂຶ້ນ. - ເປີດ - + ເປີດ + ປິດ + + ເປີດຢູ່ໃນແຖບທັງໝົດ + + ເປີດຢູ່ໃນແຖບສ່ວນຕົວ ຮຽນຮູ້ເພີ່ມເຕີມ @@ -441,6 +502,11 @@ ການແຈ້ງເຕືອນ + + ອະນຸຍາດ + + ບໍ່​ອະ​ນຸ​ຍາດ + ປັບແຕ່ງການເກັບສະສົມ Add-on @@ -464,8 +530,6 @@ ຫາກໍ່ເຂົ້າໄປເບິງມື້ກີ້ນີ້ - - Pocket ເລື່ອງທີ່ກະຕຸ້ນຄວາມຄິດ @@ -730,6 +794,13 @@ ປິດຫຼັງຈາກໜຶ່ງເດືອນ + + ເປີດຢູ່ໃນຫນ້າທໍາອິດ + + ເປີດໃນແຖບສຸດທ້າຍ + + ເປີດໃນຫນ້າທໍາອິດຫຼັງຈາກສີ່ຊົ່ວໂມງ + ຍ້າຍແຖບເກົ່າໄປເປັນແຖບທີບໍ່ມີການເຄື່ອນໄຫວ @@ -998,9 +1069,15 @@ ຂໍ້ຍົກເວັ້ນ - ເປີດ + ເປີດ ປິດ + + ມາດຕະຖານ + + ເຂັ້ມງວດ + + ປັບແຕ່ງ ອະນຸຍາດໃຫ້ເປີດສຽງ ແລະ ວີດີໂອ @@ -1761,7 +1838,7 @@ ຂໍ້ຄວາມທີ່ຈະໃຊ້ໃນການຄົ້ນຫາ - ແທນທີ່ຄິວລີດ້ວຍ “%s”. ຕົວຢ່າ: \nhttps://www.google.com/search?q=%s + ແທນທີ່ຄິວລີດ້ວຍ “%s”. ຕົວຢ່າ: \nhttps://www.google.com/search?q=%s ດັດແກ້ລາຍລະອຽດເຄື່ອງມືການຄົ້ນຫາ @@ -1960,8 +2037,6 @@ ເລື່ອງຕາມຫົວຂໍ້ ຄົ້ນຫາເພີ່ມເຕີມ - - ຂັບເຄື່ອນໂດຍ Pocket. ຂັບເຄື່ອນໂດຍ %s. diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index bf6b98364..63fd581fe 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -65,12 +65,16 @@ - Legg til en snarvei for å åpne private faner fra startskjermen. + Legg til en snarvei for å åpne private faner fra startskjermen. + + Åpne neste private fane med ett trykk. - Legg til snarvei + Legg til snarvei - + + Legg til på startskjermen + Nei takk @@ -82,7 +86,7 @@ Ignorer - Lukk + Lukk @@ -169,6 +173,8 @@ Stopp Tillegg + + Kontoinformasjon Ingen utvidelser her @@ -259,7 +265,7 @@ Søkeinnstillinger - Søk denne gangen med: + Søk denne gangen med: Søk denne gangen i: @@ -287,6 +293,19 @@ Lukk + + + Varsler hjelper deg å gjøre mer med %s + + + Synkroniser fanene dine mellom enheter, behandle nedlastinger, få tips om hvordan du får mest mulig ut av %s sitt personvern, og mer. + + Fortsett + + Ikke nå + Åpne en ny %1$s-fane @@ -338,18 +357,79 @@ Kun-HTTPS-modus - Redusering av infoskapselbanner + Redusering av infoskapselbannere Reduser infoskapselbannere + + Av + + - Firefox prøver automatisk å avvise infokapselforespørsler på infoskapselbannere. Hvis et avvisningsalternativ ikke er tilgjengelig, kan Firefox godta alle infokapsler for å avvise banneret. + Firefox prøver automatisk å avvise infokapselforespørsler på infoskapselbannere. Hvis et avvisningsalternativ ikke er tilgjengelig, kan Firefox godta alle infokapsler for å avvise banneret. + + + %1$s prøver automatisk å avvise infokapselforespørsler på infoskapselbannere. + + Av for dette nettstedet + + På for dette nettstedet + + Nettstedet støttes for øyeblikket ikke + + Vil du slå på reduksjon av infoskapselbannere for %1$s? + + Vil du slå av reduksjon av infoskapselbannere for %1$s? + + %1$s vill slette infokapsler og oppdatere siden. Sletting av alle infokapsler kan føre til at du blir logget ut eller at handlekurver blir tømt. + + %1$s kan forsøke å automatisk avslå infokapselforespørsler. Hvis avslag ikke er ett alternativ, kan %2$s godta alle infokapsler for å fjerne banneret. + + + %1$s kan prøve å automatisk avvise infokapselforespørsler. + + %1$s prøver å automatisk avvise alle infokapselforespørsler på støttede nettsteder. + + Fjern infoskapselbannere! + + Avvis automatisk forespørsler om infokapsler, når det er mulig. Ellers godta alle infokapsler for å avvise infoskapselbannere. + + Avvis automatisk forespørsler om infokapsler, når det er mulig. + + Vil du tillate %1$s å automatisk avvise forespørsler om infokapsler når det er mulig? + + Ikke nå + + Avvis bannere + + Du vil se færre forespørsler om infokapsler + + Se færre sprettoppvinduer for infokapsler + + Svar automatisk på sprettoppvindu for infokapsler for distraksjonsfri surfing. %1$s vil avvise alle forespørsler hvis mulig, eller godta alle hvis ikke. + + Svar automatisk på sprettoppvindu for infokapsler for distraksjonsfri surfing. %1$s vil avvise alle forespørsler hvis mulig. + + Avvis sprettoppvinduer + + Redusering av infoskapselbannere + + + Vil du tillate %1$s å avslå et nettsteds forespørsel om samtykke for infokapsler hvis mulig, eller godta tilgang til infokapsler når det ikke er mulig? + + Vil du tillate %1$s å avslå et nettsteds forespørsel om samtykke for infokapsler hvis mulig? + + Tillat Forsøker automatisk å koble til nettsteder ved hjelp av HTTPS-krypteringsprotokollen for økt sikkerhet. - - + + Av + + På i alle faner + + På i private faner Les mer @@ -427,6 +507,11 @@ Varslinger + + Tillatt + + Ikke tillatt + Tilpasset tilleggssamling @@ -450,8 +535,6 @@ Nylig besøkt - - Pocket Tankevekkende artikler @@ -710,6 +793,13 @@ Lukk etter en måned + + Åpne på startsiden + + Åpne på siste fane + + Åpne på startsiden etter fire timer + Flytt gamle faner til inaktive @@ -976,9 +1066,15 @@ Unntak - + Av + + Standard + + Streng + + Tilpasset Tillat lyd og video @@ -1075,8 +1171,6 @@ Kopier til utklippstavle Kopiert til utklippstavle - - Logg inn for å synkronisere Logg inn på Sync @@ -1730,7 +1824,7 @@ Søkestreng å bruke - Bytt ut spørringen med «%s». Eksempel:\nhttps://www.google.com/search?q=%s + Bytt ut spørringen med «%s». Eksempel:\nhttps://www.google.com/search?q=%s Detaljer om tilpasset søketjeneste @@ -1901,6 +1995,15 @@ Automatisk lukking aktivert + + + Firefox-forslag + + + Google-søk + + %s-søk + Angi at lenker fra nettsteder, e-postmeldinger og meldinger skal åpnes automatisk i Firefox. @@ -1923,8 +2026,6 @@ Artikler etter emne Oppdag mer - - Drevet av Pocket. Drevet av %1$s. @@ -1939,7 +2040,6 @@ Aktiver telemetri for å sende data. Gå til innstillinger - Firefox-forslag diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index d289f2205..8d0cdd6a8 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -71,11 +71,11 @@ - Voeg een snelkoppeling toe om privétabbladen vanuit uw startscherm te openen. + Voeg een snelkoppeling toe om privétabbladen vanuit uw startscherm te openen. Start het volgende privétabblad met één tik. - Snelkoppeling toevoegen + Snelkoppeling toevoegen Toevoegen aan startscherm @@ -176,6 +176,8 @@ Stoppen Add-ons + + Accountinformatie Geen add-ons hier @@ -267,7 +269,7 @@ Zoekinstellingen - Deze keer zoeken met: + Deze keer zoeken met: Deze keer zoeken in: @@ -296,6 +298,18 @@ Sluiten + + + Meldingen helpen u meer te doen met %s + + Synchroniseer uw tabbladen tussen apparaten, beheer downloads, ontvang tips over het optimaal benutten van de privacybescherming van %s en meer. + + Doorgaan + + Niet nu + Een nieuw %1$s-tabblad openen @@ -350,13 +364,21 @@ Reductie van cookiebanners Cookiebanners reduceren + + Uit + + Aan - Firefox probeert automatisch cookie-aanvragen op cookiebanners te weigeren. Als er geen weigeringsoptie beschikbaar is, accepteert Firefox mogelijk alle cookies om de banner te sluiten. + Firefox probeert automatisch cookie-aanvragen op cookiebanners te weigeren. Als er geen weigeringsoptie beschikbaar is, accepteert Firefox mogelijk alle cookies om de banner te sluiten. + + %1$s probeert automatisch cookieverzoeken op cookiebanners te weigeren. Uit voor deze website Aan voor deze website + + Website wordt momenteel niet ondersteund Reductie van cookiebanners inschakelen voor %1$s? @@ -364,14 +386,53 @@ %1$s wist de cookies voor deze website en vernieuwt de pagina. Als alle cookies worden gewist, wordt u mogelijk afgemeld of worden winkelwagentjes geleegd. - %1$s kan proberen om automatisch cookie-aanvragen te weigeren. Als er geen weigeringsoptie beschikbaar is, accepteert %2$s mogelijk alle cookies om de banner te sluiten. + %1$s kan proberen om automatisch cookie-aanvragen te weigeren. Als er geen weigeringsoptie beschikbaar is, accepteert %2$s mogelijk alle cookies om de banner te sluiten. + + + %1$s kan proberen cookieverzoeken automatisch te weigeren. + + %1$s probeert alle cookieverzoeken op ondersteunde websites automatisch te weigeren. + + Vaarwel cookiebanners! + + Weiger automatisch cookieverzoeken, indien mogelijk. Accepteer anders alle cookies om cookiebanners te verwijderen. + + Cookieverzoeken automatisch weigeren, indien mogelijk. + + %1$s toestaan om cookieverzoeken indien mogelijk automatisch te weigeren? + + Niet nu + + Banners verwijderen + + U ziet minder cookieverzoeken + + Zie minder cookie-pop-ups + + Beantwoord automatisch cookie-pop-ups voor navigeren zonder afleiding. %1$s wijst indien mogelijk alle verzoeken af, of accepteert ze allemaal als dit niet kan. + + Beantwoord automatisch cookie-pop-ups voor navigeren zonder afleiding. %1$s wijst indien mogelijk alle verzoeken af. + + Pop-ups sluiten + + Reductie van cookiebanners + + %1$s toestaan om het toestemmingsverzoek voor cookies van een website indien mogelijk te weigeren of om cookietoegang te accepteren wanneer dit niet mogelijk is? + + %1$s toestaan het verzoek om toestemming voor cookies van een website te weigeren, indien mogelijk? + + Toestaan Probeert voor een betere beveiliging automatisch middels het HTTPS-versleutelingsprotocol verbinding te maken met websites. - Aan - + Aan + Uit + + Aan in alle tabbladen + + Aan in privétabbladen Meer info @@ -450,6 +511,11 @@ Notificaties + + Toegestaan + + Niet toegestaan + Aangepaste add-oncollectie @@ -472,8 +538,6 @@ Onlangs bezocht - - Pocket Verhalen die tot nadenken stemmen @@ -732,6 +796,13 @@ Na een maand sluiten + + Op startpagina openen + + Op laatste tabblad openen + + Op startpagina openen na vier uur + Oude tabbladen naar inactief verplaatsen @@ -997,10 +1068,16 @@ Uitzonderingen - Aan + Aan Uit + + Standaard + + Streng + + Aangepast Audio en video toestaan @@ -1739,7 +1816,7 @@ Te gebruiken zoekterm - Zoekvraag vervangen door ‘%s’. Bijvoorbeeld: \nhttps://www.google.com/search?q=%s + Zoekvraag vervangen door ‘%s’. Bijvoorbeeld: \nhttps://www.google.com/search?q=%s Details aangepaste zoekmachine @@ -1940,8 +2017,6 @@ Verhalen op onderwerp Meer ontdekken - - Mogelijk gemaakt door Pocket. Mogelijk gemaakt door %s. diff --git a/app/src/main/res/values-nn-rNO/strings.xml b/app/src/main/res/values-nn-rNO/strings.xml index f30f18ba2..99d0e0086 100644 --- a/app/src/main/res/values-nn-rNO/strings.xml +++ b/app/src/main/res/values-nn-rNO/strings.xml @@ -68,9 +68,11 @@ - Legg til ein snarveg for å opne private faner frå startskjermen. + Legg til ein snarveg for å opne private faner frå startskjermen. + + Opne neste private fane med eitt trykk. - Legg til snarveg + Legg til snarveg Legg til på startskjermen @@ -85,7 +87,7 @@ Ignorer - Ignorer + Ignorer @@ -173,6 +175,8 @@ Stopp Tillegg + + Kontoinformasjon Ingen tillegg her @@ -261,7 +265,10 @@ Søkjeinnstillingar - Søk denne gongen med: + Søk denne gongen med: + + + Søk denne gongen i: @@ -287,6 +294,11 @@ Lat att + + Hald fram + + Ikkje no + Opne ei ny %1$s-fane @@ -342,19 +354,50 @@ Redusering av infoskapselbanner Reduser infoskapselbanner + + Av + + - Firefox prøver automatisk å avvise infokapselførespurnadar på infoskapselbanner. Dersom eit avvisningsalternativ ikkje er tilgjengeleg, kan Firefox godta alle infokapslar for å avvise banneret. + Firefox prøver automatisk å avvise infokapselførespurnadar på infoskapselbanner. Dersom eit avvisningsalternativ ikkje er tilgjengeleg, kan Firefox godta alle infokapslar for å avvise banneret. Av for denne nettstaden På for denne nettstaden + + Vill du aktivere reduksjon av infokapselbanner for %1$s? + + Vil du deaktivere reduksjon av infokapselbanner for %1$s? + + %1$s vill slette infokapslar og oppdatere sida. Sletting av alle infokapslar kan føre til at du blir logga ut eller at handlekorger vert tømde. + + %1$s kan prøve å automatisk avslå infokapselførespurnadar. Dersom avslag ikkje er eit alternativ, kan %2$s godta alle infokapslar for å fjerne banneret. + + %1$s kan prøve å automatisk avvise infokapselførespurnadar. + + Fjern infoskapselbanner! + + Ikkje no + + Sjå færre sprettoppvindauge for infokapslar + + Avvis sprettoppvindauge + + Redusering av infoskapselbanner + + Tillat + Prøver automatisk å kople til nettstadar ved hjelp av HTTPS-krypteringsprotokollen for auka sikkerheit. - - + + Av + + På i alle faner + + På i private faner Les meir @@ -433,6 +476,11 @@ Varsel + + Tillate + + Ikkje tillate + Tilpassa tilleggssamling @@ -455,8 +503,6 @@ Nyleg besøkte - - Pocket Tankevekkjande artiklar @@ -718,6 +764,9 @@ Lat att etter ein månad + + Opne siste fane + Flytt gamle faner til inaktive @@ -984,9 +1033,15 @@ Unntak - + Av + + Standard + + Streng + + Tilpassa Tillat lyd og video @@ -1733,7 +1788,7 @@ Søkjestreng å bruke - Byt ut spørjinga med «%s». Eksempel:\nhttps://www.google.com/search?q=%s + Byt ut spørjinga med «%s». Eksempel:\nhttps://www.google.com/search?q=%s Detaljar om tilpassa søkjeteneste @@ -1938,8 +1993,6 @@ Artiklar etter emne Oppdag meir - - Levert av Pocket. Driven av %s. diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index f2fdc7489..f997662db 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -64,11 +64,11 @@ - Apondre un acorchi per dobrir d’onglets privats de l’ecran d’acuèlh estant. + Apondre un acorchi per dobrir d’onglets privats de l’ecran d’acuèlh estant. Lançar un onglet privat d’una tòca. - Apondre un acorchi + Apondre un acorchi Apondre a l’ecran d’acuèlh @@ -170,6 +170,8 @@ Arrestar Moduls + + Informacion compte Cap d’extension aquí @@ -259,7 +261,7 @@ Paramètres de recèrca - Aqueste còp cercar : + Aqueste còp cercar : Aqueste còp cercar amb : @@ -288,6 +290,18 @@ Tampar + + + Las notificacions vos ajudan a ne far mai amb %s + + Sincronizar los onglets entre vòstres aparelhs, gerissètz los telecargaments, obtenètz de conselhs per trapar çò melhor de la proteccion de la vida privada de %s e encara mai. + + Contunhar + + Mai tard + Dobrir dins un onglet %1$s novèl @@ -343,13 +357,21 @@ Reduccion de las bandièras de cookies Reduire las bandièras de cookies + + Desactivada + + Activada - Firefox ensaja automaticament de regetar las demandas de cookies de las bandièras de cookies. Se l’opcion de refús es pas disponibla, Firefox accèpta totes las cookies per tampar la bandièra. + Firefox ensaja automaticament de regetar las demandas de cookies de las bandièras de cookies. Se l’opcion de refús es pas disponibla, Firefox accèpta totes las cookies per tampar la bandièra. + + %1$s ensaja de regetar automaticament las demandas de cookies de las banièras de cookies. Desactivada per aqueste site Activada per aqueste site + + Site actualament pas pres en carga Activar la reduccion de las bandièras de cookies per %1$s ? @@ -359,14 +381,54 @@ %1$s escafarà los cookies d’aqueste site e actualizarà la pagina. La supression de totes los cookies pòt vos desconnectar o voidar los panièrs de crompa. - %1$s pòt ensajar de regetar automaticament las demandas de cookies de las bandièras de cookies. Se l’opcion de refús es pas disponibla, %2$s accèpta totes las cookies per tampar la bandièra. + %1$s pòt ensajar de regetar automaticament las demandas de cookies de las bandièras de cookies. Se l’opcion de refús es pas disponibla, %2$s accèpta totes las cookies per tampar la bandièra. + + + %1$s pòt ensajar de refusar automaticament las demandas de cookies. + + %1$s ensaja de regetar automaticament totas las demandas de cookies suls sites compatibles. + + Fòra las bandièras de cookies ! + + Regèta automaticament las demandas de cookies, quand es possible. Autrament, accèpta totes los cookies per suprimir las bandièras de cookies. + + + Regèta automaticament las demandas de cookies, quand es possible. + + Autorizar %1$s a regetar automaticament las demandas de cookies, quand es possible ? + + Mai tard + + Tampar las bandièras + + Veiretz mens de demandas de cookies + + Veire mens de fenèstras sorgissentas de cookies + + Respondre automaticament als cookies de fenèstras sorgissentas per una navegacion sens distraccion. %1$s regetarà totas las demandas se possible, o las acceptarà totas dins lo cas contrari. + + Respondre automaticament als cookies de fenèstras sorgissentas per una navegacion sens distraccion. %1$s regetarà totas las demandas se possible. + + Regetar las fenèstras sorgissentas + + Reduccion de las bandièras de cookies + + Permetre a %1$s de refusar la demanda de consentiment als cookies d’un site se possible o acceptar l’accès als cookies quand es pas possible ? + + Autorizar %1$s a regetar la demanda de consentiment pels cookies d’un site s’es possible ? + + Autorizar Ensaja automaticament de se connectar als sites amb lo chiframent HTTPS per una seguretat melhorada. - Activat - + Activat + Desactivat + + Per totes los onglets + + Pels onglets privats Ne saber mai @@ -444,6 +506,11 @@ Notificacions + + Autorizadas + + Non autorizadas + Colleccion de moduls personalizada @@ -468,8 +535,6 @@ Visitats fa res - - Pocket Articles suggerits @@ -630,7 +695,7 @@ Tirar per actualizar - Desfilar per amagar la barra d’aisinas + Defilar per amagar la barra d’aisinas Cambiar d’onglet en lisant la barra d’aisinas cap las costats @@ -732,6 +797,13 @@ Tampar aprèp un mes + + Dobrir la pagina d’acuèlh + + Dobrir lo darrièr onglet + + Dobrir la pagina d’acuèlh après quatre oras + Passar los onglets ancians a inactius @@ -1004,9 +1076,15 @@ Excepcions - Activada + Activada Desactivada + + Estandarda + + Estricta + + Personalizada Autorizar l’àudio e la vidèo @@ -1760,7 +1838,7 @@ Cadena de recèrca d’utilizar - Remplaçar los tèrmes de la recèrca per « %s ». Per exemple :\nhttps://www.google.com/search?q=%s + Remplaçar los tèrmes de la recèrca per « %s ». Per exemple :\nhttps://www.google.com/search?q=%s Detalhs del motor de recèrca personalizat @@ -1964,8 +2042,6 @@ Articles per tèma Ne descobrir mai - - Propulsat per Pocket. Fonciona gràcia a %s. diff --git a/app/src/main/res/values-pa-rIN/strings.xml b/app/src/main/res/values-pa-rIN/strings.xml index 7ffa0e58d..577898048 100644 --- a/app/src/main/res/values-pa-rIN/strings.xml +++ b/app/src/main/res/values-pa-rIN/strings.xml @@ -70,11 +70,11 @@ - ਤੁਹਾਡੀ ਮੁੱਖ ਸਕਰੀਨ ਤੋਂ ਨਿੱਜੀ ਟੈਬਾਂ ਖੋਲ੍ਹਣ ਲਈ ਸ਼ਾਰਟਕੱਟ ਜੋੜੋ। + ਤੁਹਾਡੀ ਮੁੱਖ ਸਕਰੀਨ ਤੋਂ ਨਿੱਜੀ ਟੈਬਾਂ ਖੋਲ੍ਹਣ ਲਈ ਸ਼ਾਰਟਕੱਟ ਜੋੜੋ। ਅਗਲੀ ਨਿੱਜੀ ਟੈਬ ਨੂੰ ਇੱਕੋ ਠੂੰਗੇ ਨਾਲ ਚਾਲੂ ਕਰ ਦਿਓ। - ਸ਼ਾਰਟਕੱਟ ਜੋੜੋ + ਸ਼ਾਰਟਕੱਟ ਜੋੜੋ ਮੁੱਖ ਸਕਰੀਨ ‘ਤੇ ਜੋੜੋ @@ -176,6 +176,8 @@ ਰੋਕੋ ਐਡ-ਆਨ + + ਖਾਤਾ ਜਾਣਕਾਰੀ ਕੋਈ ਐਡ-ਆਨ ਨਹੀਂ ਹੈ @@ -267,7 +269,7 @@ ਖੋਜ ਸੈਟਿੰਗਾਂ - ਇਹ ਸਮਾਂ ਖੋਜ: + ਇਹ ਸਮਾਂ ਖੋਜ: ਇਸ ਵਾਰ ਇਸ ਵਿੱਚ ਖੋਜੋ: @@ -296,6 +298,18 @@ ਬੰਦ ਕਰੋ + + + ਨੋਟੀਫ਼ਿਕੇਸ਼ਨ ਤੁਹਾਨੂੰ %s ਨਾਲ ਹੋਰ ਕਰਨ ਦੀ ਮਦਦ ਕਰਦੇ ਹਨ + + ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਆਪਣੀਆਂ ਟੈਬਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋ, ਡਾਊਨਲੋਡ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ, %s ਦੀ ਪਰਦੇਦਾਰੀ ਸੁਰੱਖਿਆ ਦਾ ਪੂਰਾ ਫ਼ਾਇਦਾ ਲੈਣ ਲਈ ਗੁਰ ਲਵੋ ਅਤੇ ਹੋਰ + + ਜਾਰੀ ਰੱਖੋ + + ਹੁਣੇ ਨਹੀਂ + ਨਵੀਂ %1$s ਟੈਬ ਖੋਲ੍ਹੋ @@ -351,14 +365,22 @@ ਕੂਕੀਜ਼ ਬੈਨਰ ਘਟਾਓ + + ਬੰਦ + + ਚਾਲੂ - Firefox ਆਪਣੇ-ਆਪ ਕੂਕੀਜ਼ ਬੈਨਰ ਲਈ ਕੂਕੀਜ਼ ਬੇਨਤੀਆਂ ਨੂੰ ਇਨਕਾਰ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ ਕਰਦਾ ਹੈ। ਜੇ ਇਨਕਾਰ ਕਰਨ ਦੀ ਚੋਣ ਨਹੀਂ ਮੌਜੂਦ ਹੁੰਦੀ ਤਾਂ Firefox ਬੈਨਰ ਨੂੰ ਖਾਰਜ ਕਰਨ ਵਾਸਤੇ ਸਾਰੇ ਕੂਕੀਜ਼ ਨੂੰ ਮਨਜ਼ੂਰ ਵੀ ਕਰ ਸਕਦਾ ਹੈ। + Firefox ਆਪਣੇ-ਆਪ ਕੂਕੀਜ਼ ਬੈਨਰ ਲਈ ਕੂਕੀਜ਼ ਬੇਨਤੀਆਂ ਨੂੰ ਇਨਕਾਰ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ ਕਰਦਾ ਹੈ। ਜੇ ਇਨਕਾਰ ਕਰਨ ਦੀ ਚੋਣ ਨਹੀਂ ਮੌਜੂਦ ਹੁੰਦੀ ਤਾਂ Firefox ਬੈਨਰ ਨੂੰ ਖਾਰਜ ਕਰਨ ਵਾਸਤੇ ਸਾਰੇ ਕੂਕੀਜ਼ ਨੂੰ ਮਨਜ਼ੂਰ ਵੀ ਕਰ ਸਕਦਾ ਹੈ। + + %1$s ਕੂਕੀ ਬੈਨਰਾਂ ਤੋਂ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪਹੀ ਰੱਦ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ। ਇਸ ਸਾਈਟ ਲਈ ਬੰਦ ਇਸ ਸਾਈਟ ਲਈ ਚਾਲੂ + + ਸਾਈਟ ਇਸ ਵੇਲੇ ਸਹਾਇਕ ਨਹੀਂ ਹੈ %1$s ਲਈ ਕੁਕੀ ਬੈਨਰ ਘਟਾਉਣੇ ਚਾਲੂ ਕਰਨੇ ਹਨ? @@ -367,14 +389,55 @@ %1$s ਇਸ ਸਾਈਟ ਦੀਆਂ ਕੁਕੀਆਂ ਨੂੰ ਸਾਫ਼ ਕਰ ਕੇ ਵਰਕੇ ਨੂੰ ਸੱਜਰਾ ਕਰ ਦੇਵੇਗਾ। ਸਾਰੀਆਂ ਕੁਕੀਆਂ ਨੂੰ ਸਾਫ਼ ਕਰਨ ਨਾਲ ਤੁਸੀਂ ਸਾਈਨ ਆਊਟ ਹੋ ਸਕਦੇ ਹੋ ਜਾਂ ਖਰੀਦਦਾਰੀ ਵਾਲੀ ਟੋਕਰੀ ਖਾਲੀ ਹੋ ਸਕਦੀ ਹੈ। - %1$s ਆਪਣੇ-ਆਪ ਕੁਕੀਆਂ ਦੀਆਂ ਬੇਨਤੀਆਂ ਨੂੰ ਨਾਮੰਨਜੂਰ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ ਕਰ ਸਕਦਾ ਹੈ। ਜੇ ਨਾਮੰਨਜੂਰ ਕਰਨ ਦੀ ਚੋਣ ਮੌਜੂਦ ਨਹੀਂ ਹੁੰਦੀ ਤਾਂ ਝੰਡੀ ਨੂੰ ਖਾਰਜ ਕਰਨ ਵਾਸਤੇ %2$s ਸਾਰੀਆਂ ਕੁਕੀਆਂ ਨੂੰ ਮੰਨਜ਼ੂਰ ਵੀ ਕਰ ਸਕਦਾ ਹੈ। + %1$s ਆਪਣੇ-ਆਪ ਕੁਕੀਆਂ ਦੀਆਂ ਬੇਨਤੀਆਂ ਨੂੰ ਨਾਮੰਨਜੂਰ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ ਕਰ ਸਕਦਾ ਹੈ। ਜੇ ਨਾਮੰਨਜੂਰ ਕਰਨ ਦੀ ਚੋਣ ਮੌਜੂਦ ਨਹੀਂ ਹੁੰਦੀ ਤਾਂ ਝੰਡੀ ਨੂੰ ਖਾਰਜ ਕਰਨ ਵਾਸਤੇ %2$s ਸਾਰੀਆਂ ਕੁਕੀਆਂ ਨੂੰ ਮੰਨਜ਼ੂਰ ਵੀ ਕਰ ਸਕਦਾ ਹੈ। + + + %1$s ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪ ਹੀ ਰੱਦ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ ਕਰ ਸਕਦਾ ਹੈ। + + %1$s ਸਹਾਇਤਾ ਪ੍ਰਾਪਤ ਸਾਈਟਾਂ ਉੱਤੇ ਸਾਰੀਆਂ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪ ਰੱਦ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ। + + ਕੂਕੀ ਬੈਨਰ ਕਰੋ ਰਵਾਨਾ! + + ਜਦੋਂ ਵੀ ਮੌਕਾ ਹੋਵੇ ਤਾਂ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ ਖ਼ਾਰਜ ਕਰ ਦਿਓ। +ਨਹੀਂ ਤਾਂ ਕੂਕੀ ਬੈਨਰ ਨੂੰ ਖਾਰਜ ਕਰਨ ਲਈ ਸਾਰੇ ਕੂਕੀ ਮਨਜ਼ੂਰ ਕਰੋ। + + ਜਦੋਂ ਵੀ ਸੰਭਵ ਹੋਵੇ ਤਾਂ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪ ਹੀ ਰੱਦ ਕਰੋ। + + ਜਦੋਂ ਵੀ ਸੰਭਵ ਹੋਵੇ ਤਾਂ %1$s ਨੂੰ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪ ਹੀ ਰੱਦ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ? + + ਹੁਣੇ ਨਹੀਂ + + ਬੈਨਰਾਂ ਨੂੰ ਖ਼ਾਰਜ ਕਰੋ + + ਤੁਸੀਂ ਬਹੁਤ ਘੱਟ ਕੂਕੀ ਬੇਨਤੀਆਂ ਵੇਖੋਗੇ + + ਘੱਟ ਕੂਕੀ ਪੌਪ-ਅੱਪ ਵੇਖੋ + + + ਰੁਕਾਵਟ ਰਹਿਤ ਬਰਾਊਜ਼ ਕਰਨ ਲਈ ਕੂਕੀ ਪੌਪ-ਅੱਪ ਨੂੰ ਆਪਣੇ-ਆਪ ਜਵਾਬ ਦਿਓ। ਜਦੋਂ ਮੌਕੇ ਹੋਵੇਗਾ ਤਾਂ %1$s ਸਭ ਬੇਨਤੀਆਂ ਨੂੰ ਰੱਦ ਕਰੇਗਾ ਜਾਂ ਜੇ ਨਹੀ ਹੋਵੇਗਾ ਤਾਂ ਸਭ ਨੂੰ ਮਨਜ਼ੂਰ ਕਰੇਗਾ। + + ਰੁਕਾਵਟ ਰਹਿਤ ਬਰਾਊਜ਼ ਕਰਨ ਲਈ ਕੂਕੀ ਪੌਪ-ਅੱਪ ਨੂੰ ਆਪਣੇ-ਆਪ ਜਵਾਬ ਦਿਓ। ਜਦੋਂ ਸੰਭਵ ਹੋਵੇ ਤਾਂ %1$s ਸਭ ਬੇਨਤੀਆਂ ਨੂੰ ਰੱਦ ਕਰੇਗਾ। + + ਪੌਪ-ਅੱਪ ਖ਼ਾਰਜ ਕਰੋ + + ਕੂਕੀ ਬੈਨਰ ਘਟਾਉਣਾ + + %1$s ਨੂੰ ਜਦ ਵੀ ਮੌਕੇ ਹੋਵੇ ਤਾਂ ਸਾਈਟ ਦੇ ਕੂਕੀ ਸਹਿਮਤੀ ਬੇਨਤੀ ਲਈ ਰੱਦ ਕਰਨ ਜਾਂ ਜੇ ਨਾ ਹੋ ਸਕੇ ਤਾਂ ਕੂਕੀ ਪਹੁੰਚ ਨੂੰ ਮਨਜ਼ੂਰ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ? + + ਜਦੋਂ ਵੀ ਸੰਭਵ ਹੋਵੇ ਤਾਂ %1$s ਨੂੰ ਸਾਈਟ ਦੇ ਕੂਕੀ ਸਹਿਮਤੀ ਬੇਨਤੀ ਲਈ ਇਨਕਾਰ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ? + + ਮਨਜ਼ੂਰ ਵਾਧਾ ਕੀਤੀ ਸੁਰੱਖਿਆ ਲਈ HTTPS ਇੰਕ੍ਰਿਪਸ਼ਨ ਪਰੋਟੋਕਾਲ ਵਰਤ ਕੇ ਸਾਈਟਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਦੀ ਆਪਣੇ-ਆਪ ਕੋਸ਼ਿਸ਼ ਕਰੋ। - ਚਾਲੂ - + ਚਾਲੂ + ਬੰਦ + + ਸਭ ਟੈਬਾਂ ਉੱਤੇ + + ਨਿੱਜੀ ਟੈਬਾਂ ਉੱਤੇ ਹੋਰ ਜਾਣੋ @@ -453,6 +516,11 @@ ਨੋਟੀਫਿਕੇਸ਼ਨ + + ਇਜਾਜ਼ਤ ਦਿੱਤੇ + + ਇਜ਼ਾਜਤ ਨਹੀ ਹੈ + ਕਸਟਮ ਐਡ-ਆਨ ਭੰਡਾਰ @@ -477,8 +545,6 @@ ਤਾਜ਼ਾ ਖੋਲ੍ਹੇ ਗਏ - - Pocket ਸੋਚਣ ਲਈ ਮਜ਼ਬੂਰ ਕਰਨ ਵਾਲੇ ਲੇਖ @@ -741,6 +807,13 @@ ਇੱਕ ਮਹੀਨੇ ਬਾਅਦ ਬੰਦ ਕਰੋ + + ਮੁੱਖ-ਸਕਰੀਨ ਉੱਤੇ ਖੋਲ੍ਹੋ + + ਪਿਛਲੀ ਟੈਬ ਉੱਤੇ ਖੋਲ੍ਹੋ + + ਚਾਰ ਘੰਟਿਆਂ ਬਾਅਦੇ ਮੁੱਖ-ਸਫ਼਼ੇ ਉੱਤੇ ਖੋਲ੍ਹੋ + ਪੁਰਾਣੀਆਂ ਟੈਬਾਂ ਨੂੰ ਨਾ-ਸਰਗਰਮ ਵਿੱਚ ਭੇਜੋ @@ -1005,10 +1078,16 @@ ਛੋਟਾਂ - ਚਾਲੂ + ਚਾਲੂ ਬੰਦ + + ਮਿਆਰੀ + + ਸਖ਼ਤ + + ਕਸਟਮ ਆਡੀਓ ਅਤੇ ਵੀਡਿਓ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ @@ -1750,7 +1829,7 @@ ਵਰਤਣ ਲਈ ਖੋਜ ਸਤਰ - “%s” ਨਾਲ ਕਿਊਰੀ ਨੂੰ ਤਬਦੀਲ ਕਰੋ। ਮਿਸਾਲ ਵਜੋਂ:\nhttps://www.google.com/search?q=%s + “%s” ਨਾਲ ਕਿਊਰੀ ਨੂੰ ਤਬਦੀਲ ਕਰੋ। ਮਿਸਾਲ ਵਜੋਂ:\nhttps://www.google.com/search?q=%s ਕਸਟਮ ਖੋਜ ਇੰਜਣ ਵੇਰਵੇ @@ -1950,8 +2029,6 @@ ਵਿਸ਼ੇ ਮੁਤਾਬਕ ਲੇਖ ਹੋਰ ਲੱਭੋ - - Pocket ਵਲੋਂ ਇਖ਼ਤਿਆਰ %s ਦੀ ਸਹਾਇਤਾ ਨਾਲ diff --git a/app/src/main/res/values-pa-rPK/strings.xml b/app/src/main/res/values-pa-rPK/strings.xml new file mode 100644 index 000000000..e180a2c1c --- /dev/null +++ b/app/src/main/res/values-pa-rPK/strings.xml @@ -0,0 +1,647 @@ + + + + نجی %s + + + + %s (نجی) + + + + ہور چوݨاں + + نجی ورتوں چالو کرو + + نجی ورتوں چالو نہ کرو + + پتہ پایو + + پچھلیاں کھوجاں + + اتے پتے دی کھوج + + ٹیب دی کھوج + + کھوج دی لکھت پایو + + تہاڈیاں کھلھیاں ٹیباں نوں اتھے وکھایا جاۓگا۔ + + تہاڈیاں نجی ٹیباں نوں اتھے وکھایا جاۓگا۔ + + %1$d چݨیاں + + نواں مجموعہ شامل کرو + + ناں + + مجموعہ چݨو + + + بہو چوݨ ڈھنگ وچھوں باہر جاؤ + + چݨیاں ٹیباں نوں مجموعے چ سمبھالو + + چݨی + + + + حالیہ سمبھالے پتے + + سارے رکھ لاۓ اتے پتے ویکھو + + ہٹاؤ + + + %1$s ایپ موزلے ولوں تیار کیتی اے۔ + + + + + جدوں تسیں ساریاں نجی ٹیباں نوں بند کردے او یا ایپ توں باہر جاندے او تاں %1$s تہاڈی کھوج تے ورتوں دی تاریخ نوں ساف کردا اے۔ حالاں‌کہ ایہہ تہانوں سائٹاں یا تہاڈے اینٹرنیٹ دیݨ والے لئی اݨپچھاتا نہیں بݨاوندا، پر ایس نال ایس فون نوں ورتے والے کسے توں وی تہاڈے ولوں آن‌لائین کیتے نوں نجی رکھݨا ہور سوکھا ہو جاندا اے۔ + + نجی ورتوں بارے عام فرضی گلاں + + + + + تہاڈی مکھ سکرین توں نجی ٹیباں کھولھݨ لئی شارٹ کٹ جوڑو۔ + + اگلی نجی ٹیب نوں اکو ٹھونگے نال چالو کر دیو۔ + + شارٹ کٹ جوڑو + + مکھ سکرین تے جوڑو + + نہیں، شکریہ + + + + تسیں ایپاں وچ پتے آپݨے آپ کھولھݨ لئی %1$s پا لا سکدے او۔ + + سیٹنگاں نوں جاؤ + + بند کرو + + + بند کرو + + + سیٹنگاں نوں جاؤ + + بند کرو + + + چوݨاں ویکھو + + بند کرو + + سیٹنگاں چ بند کرو + + بند کرو + + + + + نویں ٹیب کھولھو + + نجی ٹیب کھولھو + + + سبھ ویکھو + + ہٹاؤ + + ہٹاؤ + + + ہٹاؤ + + + + پچھے + + اگے + + روکو + + وادھے والے + + مدد + + سیٹنگاں + + لائبریری + + اینسٹال کرو + + سانجھا کرو + + %1$s نال کھولھو + + پتہ پایو + + سودھو + + + + + چݨی بولی + + کھوج دی بولی + + + اجازت دیو + + اجازت نہ دیو + + + %s کھوج + + + کھوج دیاں سیٹنگاں + + ہݨے ایہہ کھوجو – + + ہݨے ایہنوں کھوجو – + + + شروع کریئے + + لوگ‌این کرو + + اگلے تے چلو + + بند کرو + + + کھوج + + ویب دی کھوج + + + + سیٹنگاں + + عام + + بارے + + مول کھوج والا + + کھوج + + + + پتے دی پٹی + + ایپ دکان تے درجہ دیو + + %1$s بارے + + + اضافی + + + چالو + + بند + + ہور جاݨو + + کھاتہ + + سند پٹی + + روپ ریکھا + + مکھ صفحہ + + اشارے + + چݨندا کرو + + جدوں لوگ‌این کیتا ٹیباں، اتے پتے، پاس‌ورڈ تے ہور ملا جا سکدے ہن۔ + + فائرفاکس کھاتہ + + بولی + + ڈیٹا چوݨاں + + + وادھے والے + + + اطلاع نامے + + + ٹھیک اے + + رد کرو + + + پتیاں دا جیب + + + ویکھو + + + فیر کرو + + ہور جاݨو + + + تریخ + + پتے + + + ہور جاݨو + + + گھوکھاں + + + + اُتے + + ہیٹھاں + + + + روشنی + + ہنیرا + + + + + ڈاؤن‌لوڈ + + تریخ + + نویں ٹیب کھولھو + + سیٹنگاں + + بند کرو + + + رد کرو + + + %d ٹیباں + + %d ٹیب + + + + ٹیباں + + ٹیب دا نظارہ + + فہرست + + گرڈ + + ٹیباں نوں بند کرو + + کدے نہیں + + + اک دن بعد + + اک ہفتے بعد + + اک مہینے بعد + + + مکھ صفحہ + + + + ہٹاؤ + + ہور جاݨو + + ٹھیک اے + + رد کرو + + + نویں ٹیب کھولھو + + نجی ٹیب کھولھو + + نجی + + اتا پتہ + + بند کرو + + ٹیباں چݨو + + ٹیب بند کرو + + %s ٹیب بند کرو + + + ناں بدلو + + ہٹاؤ + + + %1$s مٹا گیا + + مٹاؤ + + + + %1$d چݨیاں + + اج + + کل + + + پچھلے ۷ دن + + پچھلے ۳۰ دن + + پراݨے + + + %1$d چݨیاں + + ہٹاؤ + + + + ٹیب بند کرو + + + رد کرو + + فولڈر پایو + + سودھو + + سودھو + + کاپی کرو + + سانجھا کرو + + نویں ٹیب چ کھولھو + + نجی ٹیب چ کھولھو + + مٹاؤ + + + سامبھو + + پتہ + + فولڈر + + ناں + + فولڈر پایو + + %1$s مٹا گیا + + + موڑو + + + ٹھیک اے + + رد کرو + + ٹھیک اے + + رد کرو + + کیمرہ + + مائیکروفون + + چالو + + بند + + + چالو + + بند + + + چالو + + بند + + + ٹیباں چݨو + + مجموعہ چݨو + + سبھ چݨو + + بند کرو + + سامبھو + + ویکھو + + ٹھیک اے + + رد کرو + + + + سانجھا کرو + + سانجھا کرو + + آفلائن + + + موڑو + + اجازت دیو + + اجازت نہ دیو + + ایس پتے نال مسئلہ ہو گیا۔ + + ٹھیک اے + + + مٹاؤ + + + فونٹ دا آکار + + + آپݨے آپ فونٹ دے آکار بدلݨے + + + %d ٹیباں + + %d پتے + + ڈاؤن‌لوڈ + + باہر نکل جاؤ + + + رد کرو + + مٹاؤ + + + رد کرو + + مٹاؤ + + + لوگ‌این کرو + + + خود بخود + + + رد کرو + + + ہور جاݨو + + چݨیا + + + پیڑاں راکھے + + ویروے + + پیڑاں راکھے + + ہور جاݨو + + + + کاپی کرو + + + رد کرو + + + پتہ پایو + + + کھاتے چ کھوجو + + سائٹ + + + ورتنوالے دا ناں + + پاس‌ورڈ + + + مٹاؤ + + سانجھا کرو + + سانجھا کرو + + رد کرو + + پتے نوں سودھو + + شہر + + راج + + صوبہ + + دیش یا علاقہ + + فون نمبر + + ای‌میل دا پٹہ + + سامبھو + + رد کرو + + پتہ مٹاؤ + + مٹاؤ + + رد کرو + + پتہ مٹاؤ + + + پتہ پایو + + سانجھا کرو + + سودھو + + مٹاؤ + + + ہور + + ناں + + + %1$s مٹا گیا + + + مٹاؤ + + سودھو + + مٹاؤ + + رد کرو + + + سودھو + + + ناں + + ٹھیک اے + + رد کرو + + + سیٹنگاں + + + ہٹاؤ + + + بند کرو + + + ہور جاݨو + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 6b2f9db38..4313cb758 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -67,11 +67,11 @@ - Dodaj skrót, aby otwierać prywatne karty z ekranu głównego. + Dodaj skrót, aby otwierać prywatne karty z ekranu głównego. Otwieraj kolejne prywatne karty jednym stuknięciem. - Dodaj skrót + Dodaj skrót Dodaj do ekranu głównego @@ -86,7 +86,7 @@ Zamknij - Zamknij + Zamknij @@ -171,6 +171,8 @@ Zatrzymaj Dodatki + + Informacje o koncie Nie ma żadnych dodatków @@ -262,7 +264,7 @@ Ustawienia wyszukiwania - Tym razem szukaj: + Tym razem szukaj: Tym razem szukaj w: @@ -290,6 +292,18 @@ Zamknij + + + Dzięki powiadomieniom lepiej wykorzystasz przeglądarkę %s + + Synchronizuj karty między urządzeniami, zarządzaj pobieranymi plikami, otrzymuj wskazówki, jak najlepiej wykorzystać ochronę prywatności w przeglądarce %s i nie tylko. + + Kontynuuj + + Nie teraz + Otwórz nową kartę w przeglądarce %1$s @@ -343,14 +357,22 @@ Ograniczanie informacji o ciasteczkach - Ogranicz informacje o ciasteczkach + Ograniczanie informacji o ciasteczkach + + Wyłączone + + Włączone - Firefox automatycznie próbuje odrzucać prośby o akceptację ciasteczek. Jeśli nie ma możliwości odrzucenia, Firefox może zaakceptować wszystkie ciasteczka, aby zamknąć prośbę. + Firefox automatycznie próbuje odrzucać prośby o akceptację ciasteczek. Jeśli nie ma możliwości odrzucenia, Firefox może zaakceptować wszystkie ciasteczka, aby zamknąć prośbę. + + %1$s automatycznie próbuje odrzucać prośby o akceptację ciasteczek. Wyłączone na tej witrynie Włączone na tej witrynie + + Witryna obecnie nie jest obsługiwana Włączyć ograniczanie informacji o ciasteczkach na witrynie %1$s? @@ -359,14 +381,54 @@ %1$s usunie ciasteczka tej witryny i odświeży stronę. Usunięcie wszystkich ciasteczek może spowodować wylogowanie ze strony lub opróżnienie koszyka w sklepie. - %1$s może próbować automatycznie odrzucać prośby o akceptację ciasteczek. Jeśli nie ma możliwości odrzucenia, %2$s może zaakceptować wszystkie ciasteczka, aby zamknąć prośbę. + %1$s może próbować automatycznie odrzucać prośby o akceptację ciasteczek. Jeśli nie ma możliwości odrzucenia, %2$s może zaakceptować wszystkie ciasteczka, aby zamknąć prośbę. + + + %1$s może próbować automatycznie odrzucać prośby o akceptację ciasteczek. + + %1$s próbuje automatycznie odrzucać wszystkie prośby o akceptację ciasteczek na obsługiwanych witrynach. + + Koniec z komunikatami o ciasteczkach! + + Automatycznie odrzucaj prośby o akceptację ciasteczek, jeśli to możliwe. W przeciwnym razie akceptuj wszystkie ciasteczka, aby zamykać prośby. + + Automatycznie odrzucaj prośby o akceptację ciasteczek, jeśli to możliwe. + + Czy pozwolić przeglądarce %1$s automatycznie odrzucać prośby o akceptację ciasteczek, kiedy to możliwe? + + Nie teraz + + Odrzucaj prośby o akceptację ciasteczek + + Będziesz widzieć mniej próśb o akceptację ciasteczek + + Zmniejsz liczbę komunikatów o ciasteczkach + + + Automatycznie odpowiadaj na komunikaty o ciasteczkach, aby nie odrywać się od przeglądania. %1$s odrzuci wszystkie prośby, jeśli to możliwe, lub zaakceptuje je, jeśli nie. + + Automatycznie odpowiadaj na komunikaty o ciasteczkach, aby nie odrywać się od przeglądania. %1$s odrzuci wszystkie prośby, jeśli to możliwe. + + Odrzucaj komunikaty o ciasteczkach + + Ograniczanie informacji o ciasteczkach + + Czy pozwolić przeglądarce %1$s odrzucać prośby witryny o zgodę na ciasteczka, jeśli to możliwe, lub akceptować ciasteczka, kiedy się nie da? + + Czy pozwolić przeglądarce %1$s odrzucać prośby witryny o zgodę na ciasteczka, jeśli to możliwe? + + Pozwól Automatycznie próbuje łączyć się ze stronami za pomocą protokołu szyfrowania HTTPS w celu zwiększenia bezpieczeństwa. - Włączony - + Włączony + Wyłączony + + Włączony we wszystkich kartach + + Włączony w prywatnych kartach Więcej informacji @@ -445,6 +507,11 @@ Powiadomienia + + Dozwolone + + Niedozwolone + Inna kolekcja dodatków @@ -468,8 +535,6 @@ Ostatnio odwiedzone - - Pocket Artykuły skłaniające do myślenia @@ -727,6 +792,13 @@ Zamykane po miesiącu + + Otwieranie na stronie startowej + + Otwieranie na ostatniej karcie + + Otwieranie na stronie startowej po czterech godzinach + Przenoszenie starych kart do nieaktywnych @@ -992,10 +1064,16 @@ Wyjątki - Włączona + Włączona Wyłączona + + Standardowa + + Ścisła + + Własna Zezwalaj na dźwięk i wideo @@ -1735,7 +1813,7 @@ Używany ciąg wyszukiwania - Wyszukiwany tekst zastąp „%s”. Przykład:\nhttps://www.google.pl/search?q=%s + Wyszukiwany tekst zastąp „%s”. Przykład:\nhttps://www.google.pl/search?q=%s Informacje o dodanej wyszukiwarce @@ -1935,8 +2013,6 @@ Artykuły według tematu Odkryj więcej - - Dostarczane przez Pocket. Dostarczane przez %s. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 1efafd867..ee5e47ade 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -65,11 +65,11 @@ - Adicione um atalho na tela inicial do dispositivo para abrir abas privativas. + Adicione um atalho na tela inicial do dispositivo para abrir abas privativas. Aba a próxima aba privativa com apenas um toque. - Adicionar atalho + Adicionar atalho Adicionar à tela inicial do dispositivo @@ -171,6 +171,8 @@ Parar Extensões + + Informações da conta Nenhuma extensão aqui @@ -261,7 +263,7 @@ Configurações da pesquisa - Desta vez pesquisar: + Desta vez pesquisar: Desta vez, pesquisar em: @@ -290,6 +292,18 @@ Fechar + + + Notificações ajudam você a aproveitar mais o %s + + Sincronize suas abas entre dispositivos, gerencie arquivos baixados, receba dicas de como aproveitar ao máximo a proteção de privacidade do %s e muito mais. + + Avançar + + Agora não + Abrir nova aba no %1$s @@ -344,13 +358,21 @@ Redução de avisos de cookies Reduzir avisos de cookies + + Desativado + + Ativado - O Firefox tenta rejeitar automaticamente solicitações de cookies em avisos de cookies. Se não estiver disponível uma opção de rejeição, o Firefox pode aceitar todos os cookies para descartar o aviso. + O Firefox tenta rejeitar automaticamente solicitações de cookies em avisos de cookies. Se não estiver disponível uma opção de rejeição, o Firefox pode aceitar todos os cookies para descartar o aviso. + + O %1$s tenta rejeitar automaticamente solicitações de cookies em avisos de cookies. Desativado neste site Ativado neste site + + Site atualmente não suportado Ativar redução de avisos de cookies em %1$s? @@ -359,14 +381,55 @@ O %1$s irá limpar os cookies deste site e atualizar a página. Limpar todos os cookies pode encerrar a sessão de acesso no site ou esvaziar carrinhos de compras. - O %1$s pode tentar rejeitar solicitações de cookies automaticamente. Se não estiver disponível uma opção de rejeição, o %2$s pode aceitar todos os cookies para descartar o aviso. + O %1$s pode tentar rejeitar solicitações de cookies automaticamente. Se não estiver disponível uma opção de rejeição, o %2$s pode aceitar todos os cookies para descartar o aviso. + + + O %1$s pode tentar rejeitar solicitações de cookies automaticamente. + + O %1$s tenta rejeitar automaticamente todas as solicitações de cookies em sites suportados. + + Chega de avisos de cookies! + + Rejeite automaticamente solicitações de cookies, quando possível. Caso contrário, aceite todos os cookies para descartar avisos de cookies. + + Rejeite automaticamente solicitações de cookies, quando possível. + + Permitir que o %1$s rejeite automaticamente solicitações de cookies quando possível? + + Agora não + + + Descartar avisos + + Aparecerão menos solicitações de cookies + + Ver menos avisos de cookies + + + Responda automaticamente a avisos de cookies para ter uma navegação sem distrações. O %1$s rejeitará todas as solicitações, se possível, caso contrário aceitará todas. + + Responda automaticamente a avisos de cookies para ter uma navegação sem distrações. O %1$s rejeitará todas as solicitações, se possível. + + Descartar avisos + + Redução de avisos de cookies + + Permitir que o %1$s recuse pedidos de consentimento de cookies de um site, se possível, ou aceite o acesso a cookies quando não for possível? + + Permitir que o %1$s recuse a solicitação de consentimento de cookies de um site, se possível? + + Permitir Tentar se conectar com sites usando automaticamente o protocolo de criptografia HTTPS para maior segurança. - Ativado - + Ativado + Desativado + + Ativado em todas as abas + + Ativado em abas privativas Saiba mais @@ -444,6 +507,11 @@ Notificações + + Permitido + + Não permitido + Coleção personalizada de extensões @@ -466,8 +534,6 @@ Visitado recentemente - - Pocket Histórias que instigam o pensamento @@ -724,6 +790,13 @@ Fechar após um mês sem uso + + Abrir na página inicial + + Abrir na aba mais recente + + Abrir na página inicial após quatro horas sem atividade + Mover abas antigas para inativas @@ -990,9 +1063,15 @@ Exceções - Ativada + Ativada Desativada + + Normal + + Rigoroso + + Personalizado Permitir áudio e vídeo @@ -1737,7 +1816,7 @@ Código de pesquisa a ser usado - Substitua a consulta por “%s”. Por exemplo:\nhttps://www.google.com/search?q=%s + Substitua a consulta por “%s”. Por exemplo:\nhttps://www.google.com/search?q=%s Detalhes do mecanismo de pesquisa personalizado @@ -1939,8 +2018,6 @@ Histórias por tópico Descubra mais - - Proporcionado pelo Pocket. Com tecnologia %s. diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index e8f726e96..14ca121bf 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -67,11 +67,11 @@ - Adicionar um atalho para abrir separadores privados ao seu ecrã inicial. + Adicionar um atalho para abrir separadores privados ao seu ecrã inicial. Iniciar o próximo separador privado com um toque. - Adicionar atalho + Adicionar atalho Adicionar ao ecrã inicial @@ -172,6 +172,8 @@ Parar Extras + + Informações da conta Sem extras aqui @@ -261,7 +263,7 @@ Definições de pesquisa - Pesquisa neste momento: + Pesquisa neste momento: Desta vez pesquisar em: @@ -290,6 +292,18 @@ Fechar + + + As notificações ajudam a fazer mais com o %s + + Sincronize os seus separadores entre dispositivos, gira transferências, obtenha dicas sobre como aproveitar ao máximo a proteção de privacidade do %s e muito mais. + + Continuar + + Agora não + Abrir um novo separador do %1$s @@ -344,13 +358,21 @@ Redução de Faixas de Cookies Reduzir faixas de cookies + + Desligado + + Ligado - O Firefox tenta rejeitar automaticamente pedidos de cookies em faixas de cookies. Se uma opção de rejeição não estiver disponível, o Firefox poderá aceitar todos os cookies para esconder a faixa. + O Firefox tenta rejeitar automaticamente pedidos de cookies em faixas de cookies. Se uma opção de rejeição não estiver disponível, o Firefox poderá aceitar todos os cookies para esconder a faixa. + + O %1$s tenta rejeitar automaticamente pedidos de cookies em faixas de cookies. Desativado para este site Ativado para este site + + Site atualmente não suportado Ativar Redução de Faixa de Cookie para %1$s? @@ -358,14 +380,53 @@ %1$s limpará os cookies deste site e atualizará a página. A limpeza de todos os cookies pode fazer com que se desconecte da sessão ou esvazie os carrinhos de compras. - %1$s pode tentar rejeitar pedidos de cookies automaticamente. Se uma opção de rejeição não estiver disponível, %2$s poderá aceitar todos os cookies para descartar a faixa. + %1$s pode tentar rejeitar pedidos de cookies automaticamente. Se uma opção de rejeição não estiver disponível, %2$s poderá aceitar todos os cookies para descartar a faixa. + + + O %1$s pode tentar rejeitar pedidos de cookies automaticamente. + + O %1$s tenta rejeitar automaticamente todos os pedidos de cookies em sites suportados. + + Desapareçam faixas de cookies! + + Rejeita automaticamente os pedidos de cookies, quando possível. Caso contrário, aceita todos os cookies para descartar as faixas de cookies. + + Rejeite automaticamente pedidos de cookies, quando for possível. + + Deixar que o %1$s rejeite pedidos de cookies automaticamente, sempre que for possível? + + Agora não + + Rejeitar faixas + + Verá menos pedidos de cookies + + Ver menos pop-ups de cookies + + Responde automaticamente a pop-ups de cookies para uma navegação sem distrações. %1$s rejeitará todos os pedidos, se possível, ou aceitará todos, caso contrário. + + Responda automaticamente a pop-ups de cookies para uma navegação sem distrações. O %1$s irá rejeitar todos os pedidos, se for possível. + + Descartar pop-ups + + Redução de Faixas de Cookies + + Permitir que %1$s recuse o pedido de consentimento de cookies de um site, se possível, ou aceite o acesso ao cookie quando não for possível? + + Deixar que o %1$s recuse pedidos de consentimento de cookies para um site, se for possível? + + Permitir Automaticamente tenta conectar-se a sites utilizando o protocolo de encriptação HTTPS para uma melhor segurança. - Ligado - + Ligado + Desligado + + Ligado em todos os separadores + + Ligado em separadores privados Saber mais @@ -443,6 +504,11 @@ Notificações + + Permitido + + Não permitido + Coleção personalizada de extras @@ -465,8 +531,6 @@ Visualizados recentemente - - Pocket Histórias que fazem pensar @@ -725,6 +789,14 @@ Fechar depois um mês + + Abrir na página principal + + Abrir no último separador + + + Abrir na página inicial após quatro horas + Mover separadores antigos para inativos @@ -989,9 +1061,15 @@ Exceções - Ativada + Ativada Desativada + + Padrão + + Restrito + + Personalizado Permitir áudio e vídeo @@ -1733,7 +1811,7 @@ Termo de pesquisa a utilizar - Substitua a consulta por “%s”. Exemplo: \nhttps://www.google.com/search?q=%s + Substitua a consulta por “%s”. Exemplo: \nhttps://www.google.com/search?q=%s Detalhes do motor de pesquisa personalizado @@ -1934,8 +2012,6 @@ Histórias por tópico Descobrir mais - - Com tecnologia do Pocket. Suportado por %s. diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0d16455ef..62a8d9db0 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -69,11 +69,11 @@ - Добавьте ярлык, чтобы открывать приватные вкладки с домашнего экрана. + Добавьте ярлык, чтобы открывать приватные вкладки с домашнего экрана. Запустите следующую приватную вкладку одним касанием. - Добавить ярлык + Добавить ярлык Добавить на Домашний экран @@ -89,7 +89,7 @@ Пропустить - Убрать + Убрать @@ -178,6 +178,8 @@ Дополнения + + Ваша учётка Дополнения отсутствуют @@ -269,7 +271,7 @@ Настройки поиска - В этот раз искать: + В этот раз искать: В этот раз искать в: @@ -298,6 +300,18 @@ Закрыть + + + Уведомления помогают вам делать больше с %s + + Синхронизируйте вкладки между устройствами, управляйте загрузками, получайте советы о том, как максимально эффективно использовать защиту конфиденциальности %s, и многое другое. + + Продолжить + + Не сейчас + Открыть новую вкладку %1$s @@ -354,13 +368,21 @@ Снижать число уведомлений о куках + + Отключено + + Включено - Firefox автоматически пытается отклонить запросы на установку кук при показе уведомлений о них. Если вариант отклонения недоступен, Firefox может принять все куки, чтобы скрыть уведомление. + Firefox автоматически пытается отклонить запросы на установку кук при показе уведомлений о них. Если вариант отклонения недоступен, Firefox может принять все куки, чтобы скрыть уведомление. + + %1$s автоматически пытается отклонить запросы кук в уведомлениях о куках. Отключено для этого сайта Включено для этого сайта + + В настоящее время сайт не поддерживается Включить Снижение количества уведомлений о куках для %1$s? @@ -368,14 +390,53 @@ %1$s удалит куки этого сайта и обновит страницу. Удаление всех кук может привести к выходу из системы или к пропаже покупок из корзины. - %1$s может попытаться автоматически отклонить запросы на использование кук. Если вариант отклонения недоступен, %2$s может принять все куки, чтобы скрыть уведомление. + %1$s может попытаться автоматически отклонить запросы на использование кук. Если вариант отклонения недоступен, %2$s может принять все куки, чтобы скрыть уведомление. + + + %1$s может попытаться автоматически отклонить запросы кук. + + %1$s пытается автоматически отклонить все запросы кук на поддерживаемых сайтах. + + Уведомления о куках исчезли! + + Автоматически отклонять запросы кук, когда это возможно. В противном случае принять все куки, чтобы скрыть уведомления о куках. + + Автоматически отклонять запросы кук, когда это возможно. + + Разрешить %1$s по возможности автоматически отклонять запросы кук? + + Не сейчас + + Скрывать уведомления + + Вы увидите меньше запросов на принятие кук + + Меньше всплывающих окон о куках + + Автоматически отвечать на всплывающие окна о куках, чтобы не отвлекаться от просмотра. %1$s будет отклонять все запросы, если это возможно, или принимать все, если нет. + + Автоматически отвечать на уведомления о куках, чтобы не отвлекаться от просмотра. %1$s будет отклонять все запросы, если это возможно. + + Скрывать всплывающие окна + + Снижение числа уведомлений о куках + + Разрешить %1$s отклонять запрос согласия сайта на использование кук, если это возможно, или принимать доступ к кукам, когда это невозможно? + + Разрешить %1$s по возможности отклонять запрос согласия сайта на куки? + + Разрешить Автоматически пытаться подключиться к сайтам через протокол шифрования HTTPS для повышения безопасности. - Вкл. - + Вкл. + Откл. + + Включено во всех вкладках + + Включено в приватных вкладках Подробнее @@ -391,11 +452,11 @@ Специальные возможности - Пользовательский сервер Аккаунта Firefox + Пользовательский сервер аккаунта Firefox Пользовательский сервер Синхронизации - Сервер Аккаунта/Синхронизации Firefox был изменён. Закрываем приложение, чтобы применить изменения… + Сервер аккаунтов/синхронизации Firefox был изменён. Закрываем приложение, чтобы применить изменения… Аккаунт @@ -439,7 +500,7 @@ Поиск облачных вкладок - Настройки Аккаунта + Настройки аккаунта Автозаполнение сетевых адресов @@ -454,6 +515,11 @@ Уведомления + + Разрешены + + Не разрешены + Собственный сборник дополнений @@ -476,8 +542,6 @@ Недавно посещённые - - Pocket Истории, наводящие на размышления @@ -735,6 +799,13 @@ Закрывать через месяц + + Открывать на домашней странице + + Открывать на последней вкладке + + Открывать на домашней странице через четыре часа + Перемещать старые вкладки в неактивные @@ -781,7 +852,7 @@ Недавно закрытые - Настройки Аккаунта + Настройки аккаунта Настройки вкладок @@ -1002,10 +1073,16 @@ Исключения - Включена + Включена Отключена + + Стандартная + + Строгая + + Персональная Разрешить звук и видео @@ -1757,7 +1834,7 @@ Используемая поисковая строка - Замените строку запроса на “%s”. Пример:\nhttps://www.google.com/search?q=%s + Замените строку запроса на “%s”. Пример:\nhttps://www.google.com/search?q=%s Сведения о выбранной поисковой системе @@ -1958,8 +2035,6 @@ Истории по темам Узнайте больше - - С использованием Pocket. При поддержке %s. diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml index ec3571fa9..0ef2da1a9 100644 --- a/app/src/main/res/values-sat/strings.xml +++ b/app/src/main/res/values-sat/strings.xml @@ -62,11 +62,11 @@ - ᱟᱢᱟᱜ ᱚᱲᱟᱜ ᱤᱥᱠᱨᱤᱱ ᱠᱷᱚᱱ ᱱᱤᱡᱮᱨᱟᱜ ᱴᱮᱵᱽ ᱡᱷᱤᱡᱽ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱢᱤᱫᱴᱟᱹᱝ ᱠᱷᱟᱴᱚᱢᱟᱪᱷᱟ ᱥᱮᱞᱮᱫᱽ ᱛᱟᱞᱟᱝ ᱢᱮ ᱾ + ᱟᱢᱟᱜ ᱚᱲᱟᱜ ᱤᱥᱠᱨᱤᱱ ᱠᱷᱚᱱ ᱱᱤᱡᱮᱨᱟᱜ ᱴᱮᱵᱽ ᱡᱷᱤᱡᱽ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱢᱤᱫᱴᱟᱹᱝ ᱠᱷᱟᱴᱚᱢᱟᱪᱷᱟ ᱥᱮᱞᱮᱫᱽ ᱛᱟᱞᱟᱝ ᱢᱮ ᱾ ᱢᱤᱫᱴᱟᱝ ᱴᱤᱯᱟᱹᱣ ᱛᱮ ᱤᱱᱟᱹ ᱛᱟᱭᱚᱢᱟᱜ ᱯᱨᱟᱭᱵᱷᱮᱴ ᱴᱟᱵ ᱮᱦᱚᱵ ᱢᱮ ᱾ - ᱠᱷᱟᱴᱚᱢᱟᱪᱷᱟ ᱥᱮᱞᱮᱫᱽ ᱢᱮ + ᱠᱷᱟᱴᱚᱢᱟᱪᱷᱟ ᱥᱮᱞᱮᱫᱽ ᱢᱮ ᱚᱲᱟᱜ ᱥᱠᱨᱤᱱ ᱨᱮ ᱥᱮᱞᱮᱫᱽ ᱢᱮ @@ -171,6 +171,8 @@ ᱛᱤᱸᱜᱩ ᱮᱰ-ᱟᱸᱱᱥ + + ᱠᱷᱟᱛᱟ ᱵᱤᱵᱨᱚᱬ ᱱᱚᱰᱮ ᱮᱰ-ᱟᱸᱱᱥ ᱠᱚ ᱵᱟᱹᱱᱩᱜᱼᱟ @@ -261,7 +263,7 @@ ᱥᱮᱸᱫᱽᱨᱟ ᱥᱟᱡᱟᱣ ᱠᱚ - ᱱᱤᱭᱟᱹ ᱚᱠᱛᱚ ᱥᱮᱸᱫᱽᱨᱟ : + ᱱᱤᱭᱟᱹ ᱚᱠᱛᱚ ᱥᱮᱸᱫᱽᱨᱟ : ᱱᱤᱛᱚᱜ ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮ : @@ -289,6 +291,11 @@ ᱵᱚᱸᱫᱚᱭ ᱢᱮ + + ᱞᱮᱛᱟᱲ + + ᱱᱤᱛᱚᱜ ᱫᱚ ᱵᱟᱝᱟ + ᱱᱟᱶᱟ ᱴᱮᱵᱽ %1$s ᱡᱷᱤᱡᱽ ᱢᱮ @@ -343,7 +350,7 @@ ᱠᱩᱠᱤ ᱵᱮᱱᱚᱨ ᱠᱷᱟᱴᱚᱭ ᱢᱮ - ᱠᱩᱠᱤ ᱵᱮᱱᱚᱨ ᱨᱮ Firefox ᱫᱚ ᱟᱡ ᱛᱮᱜᱮ ᱠᱩᱠᱤ ᱱᱮᱦᱚᱨ ᱠᱚ ᱵᱟᱫ ᱜᱤᱰᱤ ᱠᱟᱜᱼᱟᱭ ᱾ ᱡᱩᱫᱤ ᱵᱟᱫ ᱜᱤᱫᱤ ᱚᱯᱥᱚᱱ ᱨᱮ ᱵᱟᱹᱱᱩᱜ ᱠᱷᱟᱱ, Firefox ᱫᱚ ᱵᱮᱱᱚᱨ ᱢᱮᱴᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱡᱷᱚᱛᱚ ᱠᱩᱠᱤ ᱦᱮᱥᱤᱭᱟᱹᱨ ᱩᱛᱟᱹᱨ ᱟᱭ ᱾ + ᱠᱩᱠᱤ ᱵᱮᱱᱚᱨ ᱨᱮ Firefox ᱫᱚ ᱟᱡ ᱛᱮᱜᱮ ᱠᱩᱠᱤ ᱱᱮᱦᱚᱨ ᱠᱚ ᱵᱟᱫ ᱜᱤᱰᱤ ᱠᱟᱜᱼᱟᱭ ᱾ ᱡᱩᱫᱤ ᱵᱟᱫ ᱜᱤᱫᱤ ᱚᱯᱥᱚᱱ ᱨᱮ ᱵᱟᱹᱱᱩᱜ ᱠᱷᱟᱱ, Firefox ᱫᱚ ᱵᱮᱱᱚᱨ ᱢᱮᱴᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱡᱷᱚᱛᱚ ᱠᱩᱠᱤ ᱦᱮᱥᱤᱭᱟᱹᱨ ᱩᱛᱟᱹᱨ ᱟᱭ ᱾ ᱱᱚᱶᱟ ᱥᱟᱭᱤᱴ ᱞᱟᱹᱜᱤᱫ ᱵᱚᱱᱫ ᱜᱮᱭᱟ @@ -358,13 +365,16 @@ %1$s ᱫᱚ ᱱᱚᱶᱟ ᱥᱟᱭᱤᱴᱟᱜ ᱠᱩᱠᱤ ᱠᱚ ᱢᱮᱴᱟᱣᱟᱭ ᱟᱨ ᱥᱟᱦᱴᱟ ᱯᱷᱟᱨᱪᱟ ᱜᱚᱫ ᱠᱟᱜᱼᱟᱭ ᱾ ᱡᱷᱚᱛᱚ ᱠᱩᱠᱤ ᱠᱚ ᱢᱮᱴᱟᱣ ᱞᱮᱠᱷᱟᱱ ᱟᱢ ᱵᱟᱦᱨᱮ ᱛᱮ ᱚᱰᱚᱠᱚᱜᱼᱟᱢ ᱟᱨᱵᱟᱝ ᱠᱤᱨᱤᱧ ᱵᱚᱥᱛᱟ ᱫᱚ ᱠᱷᱟᱹᱞᱤᱜ ᱛᱟᱢᱟᱸ ᱾ - %1$s ᱫᱚ ᱟᱡ ᱛᱮᱜᱮ ᱠᱩᱠᱤ ᱱᱮᱦᱚᱨ ᱠᱚ ᱵᱟᱫ ᱜᱤᱰᱤ ᱫᱟᱲᱮᱭᱟᱜᱼᱟᱭ ᱾ ᱡᱩᱫᱤ ᱵᱟᱫ ᱜᱤᱫᱤ ᱚᱯᱥᱚᱱ ᱨᱮ ᱵᱟᱹᱱᱩᱜ ᱠᱷᱟᱱ, %2$s ᱫᱚ ᱵᱮᱱᱚᱨ ᱢᱮᱴᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱡᱷᱚᱛᱚ ᱠᱩᱠᱤ ᱦᱮᱥᱤᱭᱟᱹᱨ ᱩᱛᱟᱹᱨ ᱟᱭ ᱾ + %1$s ᱫᱚ ᱟᱡ ᱛᱮᱜᱮ ᱠᱩᱠᱤ ᱱᱮᱦᱚᱨ ᱠᱚ ᱵᱟᱫ ᱜᱤᱰᱤ ᱫᱟᱲᱮᱭᱟᱜᱼᱟᱭ ᱾ ᱡᱩᱫᱤ ᱵᱟᱫ ᱜᱤᱫᱤ ᱚᱯᱥᱚᱱ ᱨᱮ ᱵᱟᱹᱱᱩᱜ ᱠᱷᱟᱱ, %2$s ᱫᱚ ᱵᱮᱱᱚᱨ ᱢᱮᱴᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱡᱷᱚᱛᱚ ᱠᱩᱠᱤ ᱦᱮᱥᱤᱭᱟᱹᱨ ᱩᱛᱟᱹᱨ ᱟᱭ ᱾ + + + ᱠᱩᱠᱤ ᱵᱮᱱᱚᱨ ᱠᱚ ᱪᱟᱞᱟᱣ ᱮᱱᱟ! ᱵᱮᱰᱷᱟᱣ ᱠᱟᱱᱟ ᱨᱩᱠᱷᱤᱭᱟᱹ ᱞᱟᱹᱜᱤᱫ ᱛᱮ HTTPS ᱫᱟᱱᱟᱝ ᱵᱮᱵᱷᱟᱨ ᱛᱮ ᱥᱟᱭᱤᱴ ᱠᱚ ᱥᱟᱞᱟᱜ ᱟᱡ ᱛᱮ ᱡᱩᱲᱟᱹᱣ ᱵᱤᱲᱟᱹᱣ ᱾ - ᱪᱟᱹᱞᱩ - + ᱪᱟᱹᱞᱩ + ᱵᱚᱸᱫᱚ ᱰᱷᱮᱨ ᱥᱮᱬᱟᱭ ᱢᱮ @@ -464,8 +474,6 @@ ᱱᱤᱛᱚᱜᱟᱜ ᱦᱤᱨᱤᱭᱟᱜ - - ᱯᱚᱠᱮᱴ ᱢᱚᱱᱮᱼᱜᱷᱟᱱᱴᱟ ᱠᱟᱹᱦᱱᱤᱠᱚ @@ -992,7 +1000,7 @@ ᱪᱷᱟᱰᱟ ᱠᱚ - ᱪᱟᱹᱞᱩ + ᱪᱟᱹᱞᱩ ᱵᱚᱸᱫᱚ @@ -1737,7 +1745,7 @@ ᱵᱮᱵᱷᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱥᱴᱨᱭᱸᱜ ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮ - “%s” ᱥᱟᱞᱟᱜ ᱠᱣᱮᱨᱭ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾ ᱡᱮᱢᱚᱱ:\nhttps://www.google.com/search?q=%s + “%s” ᱥᱟᱞᱟᱜ ᱠᱣᱮᱨᱭ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾ ᱡᱮᱢᱚᱱ:\nhttps://www.google.com/search?q=%s ᱠᱩᱥᱤᱭᱟᱜ ᱥᱮᱸᱫᱽᱨᱟ ᱤᱧᱡᱤᱱ ᱨᱮᱭᱟᱜ ᱵᱤᱵᱨᱚᱬ @@ -1936,8 +1944,6 @@ ᱦᱟᱛᱟᱢ ᱞᱮᱠᱟᱛᱮ ᱠᱟᱹᱦᱱᱤ ᱠᱚ ᱟᱨᱦᱚᱸ ᱯᱟᱱᱛᱮ ᱧᱟᱢ ᱢᱮ - - ᱜᱚᱲᱚᱤᱭᱟᱹ Pocket %1$s ᱫᱟᱨᱟᱭ ᱛᱮ ᱫᱟᱲᱮ ᱮᱢ ᱾ diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml new file mode 100644 index 000000000..113615887 --- /dev/null +++ b/app/src/main/res/values-sc/strings.xml @@ -0,0 +1,1619 @@ + + + + %s privadu + + %s (nav. privada) + + + + Àteras optziones + + Permite sa navigatzione privada + + Disativa sa navigatzione privada + + Chirca o inserta·nche un’indiritzu + + Chirca in sa cronologia + + Chirca in sinnalibros + + Chirca ischedas + + Inserta is tèrmines de chirca + + Is ischedas abertas tuas ant a èssere ammustradas inoghe. + + Is ischedas privadas tuas ant a èssere ammustradas inoghe. + + %1$d seletzionada + + Agiunghe una colletzione noa + + Nòmine + + Seletziona una colletzione + + Sarva is ischedas seletzionadas a sa colletzione + + Seletzionadu + + + + Sarvadas de reghente + + Ammustra totu is sinnalibros sarvados + + Boga + + + %1$s est prodotu dae Mozilla. + + + Mitos fitianos subra de sa navigatzione privada + + + + + Agiunghe unu curtzadòrgiu pro abèrrere is ischedas privadas dae s’ischermu printzipale tuo. + + Aberi in s’ischeda privada imbeniente cun unu tocu ebbia. + + Agiunghe unu curtzadòrgiu + + Agiunghe a s’ischermu printzipale + + No, gràtzias + + + + Podes cunfigurare %1$s pro chi abèrgiat in automàticu is ligòngios in is aplicatziones. + + Bae a sa cunfiguratzione + + Iscarta + + + Iscarta + + + Atzessu rechestu a sa fotocàmera. Bae a sa cunfiguratzione de Android, toca is permissos e sèbera permite. + + Bae a sa cunfiguratzione + + Iscarta + + + Ammustra is optziones + + Iscarta + + Is ischedas chi no apas visualizadu in duas chidas ant a èssere mòvidas inoghe. + + Disativa in sa cunfiguratzione + + Boles serrare in automàticu a pustis de unu mese? + + %1$s podet serrare is ischedas chi no apas visualizadu in s’ùrtimu mese. + + Serra + + + Ativa sa serrada in automàticu + + + + + Ischeda noa + + Ischeda privada noa + + + + Torra a s’ischeda + + Ammustra totu + + Ammustra su butone de totu is ischedas reghentes + + Ammustra totu is ischedas sincronizadas + + Dispositivu sincronizadu + + Boga + + Boga + + + + Bisitadas de reghente + + Boga + + + Ammustra totu is esploratziones coladas + + + + A coa + + In antis + + Atualiza + + Firma + + Cumplementos + + Nissunu cumplementu inoghe + + Agiudu + + Novidades + + Cunfiguratzione + + Biblioteca + + Situ de iscrivania + + Agiunghe a s’ischermu printzipale + + Installa + + Torra a sincronizare + + Chirca in sa pàgina + + Sarva in una colletzione + + Cumpartzi + + Aberi in %1$s + + FUNTZIONAT GRÀTZIAS A %1$s + + Funtzionat gràtzias a %1$s + + Modalidade de letura + + Serra sa visualizatzione de letura + + Aberi in s’aplicatzione + + Personaliza sa visualizatzione de letura + + Agiunghe + + Modìfica + + Personaliza sa pàgina printzipale + + + + + Ischermu printzipale + + + + Lìngua seletzionada + + Sighi sa lìngua de su dispositivu + + Chirca una lìngua + + + + Iscansiona + + Motore de chirca + + Cunfiguratzione de su motore de chirca + + Imprea su ligòngiu in punta de billete + + Permite + + Non permitas + + Boles ammustrare cussìgios de chirca in is sessiones privadas? + + Chirca %s + + Chirca deretu dae sa barra de indiritzos + + Cunfiguratzione de chirca + + Custa borta, chirca cun: + + Custa borta, chirca cun: + + + + Iscoberi sa personalizatzione de sa pàgina printzipale. Is ischedas reghentes, sinnalibros e resurtados de chirca ant a èssere ammustrados inoghe. + + Ti donamus su benebènnidu a un’internet mègius + + Cumintza + + Identìfica·ti + + Brinca + + Sincronizatzione de is ischedas tuas in cursu. Torra in ue fias in s’àteru dispositivu. + + Serra + + + + Aberi in un’ischeda de %1$s noa + + Chirca + + Chirca in rete + + Chirca cun sa boghe + + + + Cunfiguratzione + + Generale + + Informatziones + + Motore de chirca predefinidu + + Chirca + + Barra de indiritzos + + Subra de %1$s + + Cunfigura comente navigadore predefinidu + + Avantzadas + + Riservadesa e seguresa + + Permissos de is sitos + + Navigatzione privada + + Aberi ligòngios in un’ischeda privada noa + + Permite is caturas de ischermu in sa navigatzione privada + + Agiunghe unu curtzadòrgiu de navigatzione privada + + Modalidade «isceti HTTPS» + + + Disativadu pro custu situ + + Ativu pro custu situ + + + Ativu + + Disativadu + + Àteras informatziones + + Permite in totu is ischedas + + Permite isceti in is ischedas privadas + + Situ seguru non disponìbile + + Est probàbile chi su situ web non siat cumpatìbile cun HTTPS. + + Atzessibilidade + + Serbidore de contos de Firefox personalizadu + + Serbidore de Sync personalizadu + + Contu + + Barra de ainas + + Tema + + Pàgina printzipale + + Gestos + + Personaliza + + Intra pro sincronizare ischedas, sinnalibros, craes e àteru. + + Contu de Firefox + + Torra a connètere pro sighire cun sa sincronizatzione + + Lìngua + + Sèberu de is datos + + Còllida de datos + + Curretzione de faddinas pro mèdiu de USB + + Ammustra is motores de chirca + + Ammustra cussìgios de chirca + + Ammustra chirca de boghe + + Ammustra in sessiones privadas + + Ammustra cussìgios de punta de billete + + Chirca in sa cronologia de navigatzione + + Chirca in is sinnalibros + + Chirca ischedas sincronizadas + + Cunfiguratzione de su contu + + Cumpletamentu de URL in automàticu + + Aberi is ligòngios in is aplicatziones + + Gestore de iscarrigamentos esternu + + Cumplementos + + Notìficas + + + + Colletzione de cumplementos personalizada + + AB + + Annulla + + + Nòmine de sa colletzione + + + + Torra a s’ischeda + + Sinnalibros reghentes + + Bisitadas de reghente + + Pocket + + Artìculos seletzionados dae %s + + Istòrias patrotzinadas + + Isfundos de ischermu + + Curtzadòrgios patrotzinados + + + + Elementu de isfundu de ischermu: %1$s + + Isfundu de ischermu atualizadu. + + Visualiza + + Impossìbile iscarrigare s’isfundu de ischermu + + Torra a proare + + Impossìbile modificare s’isfundu de ischermu + + Àteras informatziones + + %s clàssicu + + Editzione limitada + + Sa colletzione noa de boghes indipendentes. %s + + Sa colletzione noa de boghes indipendentes. + + Proa un’istrichiddu de colore + + + Sèbera un’isfundu de ischermu chi ti rapresentat. + + + Iscoberi àteros isfundos de ischermu + + + + Cumplementu non cumpatìbile + + Su cumplementu est giai installadu + + + + Sincroniza immoe + + Sèbera ite boles sincronizare + + Cronologia + + Sinnalibros + + Credentziales + + Ischedas abertas + + Serra sa sessione + + Nòmine de su dispositivu + + + + Su nùmene de su dispositivu non podet èssere bòidu. + + Sincronizende… + + Faddina in sa sincronizatzione. Ùrtima sincronizatzione curreta: %s + + Faddina in sa sincronizatzione. Ùrtima sincronizatzione curreta: mai + + Ùrtima sincronizatzione: %s + + Ùrtima sincronizatzione: mai + + %1$s in %2$s %3$s + + Cartas de crèditu + + Indiritzos + + + + Ischedas retzidas + + Notìficas pro ischedas retzidas dae àteros dispositivos Firefox. + + Ischeda retzida + + Ischeda dae %s + + + + Etzetziones + + Ativa pro totu is sitos + + Àteras informatziones + + + Impreu e datos tècnicos + + Istùdios + + + + Sincroniza e sarva datos + + Identìfica·ti pro torrare a connètere + + Boga custu contu + + + + firefox.com/pair]]> + + + + Superiore + + Inferiore + + + + Craru + + Iscuru + + Sighi su nòmine de su dispositivu + + + + Iscurre pro atualizare + + Iscurre pro cuare sa barra de ainas + + + Càmbia de ischeda cun iscurrimentu laterale + + Iscurre sa barra de ainas in artu pro abèrrere ischedas + + + + Iscarrigamentos + + Sinnalibros + + Sinnalibros de iscrivania + + Menù de is sinnalibros + + Barra de is sinnalibros + + Àteros sinnalibros + + Cronologia + + Ischeda noa + + Cunfiguratzione + + Serra + + + Boles abèrrere %d ischedas? + + Ischedas abertas + + Annulla + + + %d situ + + %d sitos + + + Ischedas serradas de reghente + + Ammustra totu sa cronologia + + %d ischedas + + %d ischeda + + Nissuna ischeda serrada de reghente inoghe + + + + Ischedas + + Visualizatzione de ischedas + + Lista + + Grìllia + + Serra is ischedas + + Mai + + A pustis de una die + + A pustis de una chida + + A pustis de unu mese + + Serrada de is ischedas in automàticu + + + + Ischermu de abertura + + Pàgina printzipale + + Ùrtima ischeda + + Pàgina printzipale a pustis de 4 oras de inatividade + + Serra a manu + + Serra a pustis de una die + + Serra a pustis de una chida + + Serra a pustis de unu mese + + + + Move is ischedas betzas a is inativas + + + Is ischedas chi no apas visualizadu in duas chidas ant a èssere mòvidas a sa setzione de inativas. + + + + Boga + + Ativos + + %1$s podet installare e aviare istùdios ònnia tantu. + + Àteras informatziones + + AB + + Annulla + + + + Ischedas abertas + + Ischedas privadas + + Ischedas sincronizadas + + Agiunghe un’ischeda + + Agiunghe un’ischeda privada + + Privada + + Sincroniza + + Cumpartzi totu is ischedas + + Ischedas serradas de reghente + + Serradas de reghente + + Cunfiguratzione de su contu + + Cunfiguratzione de ischeda + + Serra totu is ischedas + + Agiunghe a is sinnalibros + + Serra + + Cumpartzi is ischedas seletzionadas + + Menù de ischedas seletzionadas + + Seletziona is ischedas + + Serra s’ischeda + + Serra s’ischeda %s + + Aberi su menù de is ischedas + + Aberi is ischedas + + Torra a nominare + + Boga + + Cantzella dae sa cronologia + + %1$s (modalidade privada) + + + + Inserta is tèrmines de chirca + + Cantzella sa cronologia + + Cronologia cantzellada + + %1$s cantzelladu + + Cantzella + + %1$d seletzionada + + Oe + + Erisero + + Ùrtimas 7 dies + + Ùrtimas 30 dies + + Prus betzu + + Nissuna cronologia inoghe + + + + Iscarrigamentos cantzellados + + %1$s cantzelladu + + Nissunu archìviu cantzelladu + + %1$d seletzionada + + Boga + + + + Serra s’ischeda + + + Annulla + + Agiunghe una cartella + + Sinnalibru sarvadu. + + + MODÌFICA + + Modìfica + + Còpia + + Cumpartzi + + Aberi in un’ischeda noa + + Aberi in un’ischeda privada noa + + Aberi totu in ischedas noas + + Aberi totu in ischedas privadas + + Cantzella + + Sarva + + %1$d seletzionada + + Modìfica su sinnalibru + + Modìfica sa cartella + + Identìfica·ti pro bìdere is sinnalibros sincronizados + + URL + + CARTELLA + + NÒMINE + + Agiunghe una cartella + + Seletziona una cartella + + Depet tènnere unu tìtulu + + URL non vàlidu + + Nissunu sinnalibru inoghe + + %1$s cantzelladu + + Sinnalibros cantzellados + + Cantzellende is cartellas seletzionadas + + ISCONTZA + + Inserta is tèrmines de chirca + + + + Bae a sa cunfiguratzione + + Cussigiadu + + Cantzella is permissos + + AB + + Annulla + + Cantzella su permissu + + AB + + Annulla + + Cantzella is permissos pro totu is sitos + + Riprodutzione in automàticu + + Fotocàmera + + Micròfonu + + Positzione + + Notìfica + + Archiviatzione permantente + + Testimòngios intre-sitos + + Cuntenutu controlladu dae DRM + + Blocadu + + Permìtidu + + Blocadu dae Android + + Etzetziones + + Ativu + + Disativadu + + Permite àudio e vìdeu + + Permite àudio e vìdeu + + Bloca isceti s’àudio + + Bloca isceti s’àudio + + Bloca àudio e vìdeu + + Bloca àudio e vìdeu + + Ativu + + Disativadu + + Ativu + + Disativadu + + + Seletziona is ischedas + + Agiunghe una colletzione noa + + Seletziona totu + + Seletziona is ischedas de sarvare + + %d ischedas sarvadas + + %d ischeda sarvada + + Ischedas sarvadas. + + Ischeda sarvada. + + Serra + + Sarva + + Visualiza + + AB + + Annulla + + + + Cumpartzi + + Cumpartzi + + Sarva comente PDF + + Impossìbile generare su PDF + + Imbia a su dispositivu + + Totu is atziones + + Impreadu de reghente + + Còpia in punta de billete + + Copiadu in punta de billete + + Identìfica·ti a Sync + + Sincroniza e sarva datos + + Imbia a totu is dispositivos + + Torra a colllegare a Sync + + In foras de lìnia + + Connete un’àteru dispositivu + + Apo cumprèndidu + + Imbia a su dispositivu + + Nissunu dispositivu connètidu + + Àteras informatziones subra de s’imbiu de ischedas… + + Connete un’àteru dispositivu… + + + + Serra is ischedas privadas + + %1$s est lestru e privadu + + Imprea %1$s comente navigadore predefinidu + + Prova sa navigatzione privada + + + Ischeda serrada + + Ischedas serradas + + Sinnalibros sarvados. + + Agiuntu a is curtzadòrgios. + + Ischeda privada serrada + + Ischedas privadas serradas + + ISCONTZA + + Situ bogadu + + Permite chi %1$s abèrgiat %2$s + + PERMITE + + REFUDA + + Indiritzu web non vàlidu. + + AB + + Seguru chi boles cantzellare %1$s? + + Boles cantzellare %1$s? + + Cantzella + + URL copiadu + + Mannària de su caràtere + + + Mannària de su caràtere in automàticu + + + Cantzella is datos de navigatzione + + Ischedas abertas + + %d ischedas + + Cronologia de navigatzione e datos de is sitos + + %d indiritzos + + Testimòngios + + Permissos de is sitos + + Iscarrigamentos + + + Cantzella is datos de navigatzione + + Cantzella is datos de navigatzione e essi + + Essi + + + Ùrtima ora + + Oe e erisero + + Totu + + + %s at a cantzellare is datos de navigatzione seletzionados. + + Annulla + + Cantzella + + Datos de navigatzione cantzellados + + Cantzellende is datos de navigatzione… + + + Cantzella totu is sitos in «%s» + + Annulla + + Cantzella + + Grupu cantzelladu + + + + Ti donamus su benebènnidu a un’internet mègius + + Identìfica·ti + + Sincronizatzione ativa + + Amparu de riservadesa predefinidu + + Istàndard (predefinidu) + + Restrinta + + Controllas is datos tuos + + Cumintza a navigare + + + + Sèbera unu tema + + Automàticu + + Tema iscuru + + Tema craru + + + Ischedas imbiadas. + + Ischeda imbiada. + + Impossìbile imbiare + + TORRA A PROARE + + Iscansiona su còdighe + + https://firefox.com/pair]]> + + Iscansiona + + Identìfica·ti cun sa càmera + + Imprea sa posta eletrònica + + Crea·nde unu pro sincronizare Firefox intre dispositivos.]]> + + %s at a firmare sa sincronizatzione de su contu tuo ma non s’ant a cantzellare is datos de navigatzione de custu dispositivu. + + Disconnete + + Annulla + + Impossìbile modificare is cartellas predefinidas + + + + Cunfiguratzione de protetzione + + Amparu megioradu contra sa sighidura + + Nàviga chene sighiduras + + Ampara is datos tuos. %s amparat dae is sighidores prus currentes chi sighint su chi ses faghende in lìnia. + + Àteras informatziones + + Istàndard (predefinidu) + + Echilìbriu intre amparu e rendimentu. Is pàginas s’ant a carrigare cun normalidade. + + Restrinta + + Personalizada + + Sèbera cale elementos de sighidura e scripts depent èssere blocados. + + + Testimòngios + + Sighidores intre sitos e de retes sotziales + + Testimòngios de sitos web chi no as bisitadu + + Totu is testimòngios de àteras partes (diat pòdere causare chi unos cantos sitos non funtzionent) + + Totu is testimòngios (unos cantos sitos no ant a funtzionare) + + Cuntenutu chi ti sighit + + In totu is ischedas + + Isceti in is ischedas privadas + + Cripto-minadores + + Generadores de imprentas digitales + + Detàllios + + Blocadu + + Permìtidu + + Elementos de sighidura de retes sotziales + + Testimòngios de sighimentu intre sitos + + Testimòngios intre-sitos + + Cripto-minadores + + Generadores de imprentas digitales + + Cuntenutu de sighidura + + Amparu ativu pro custu situ + + Amparu disativadu pro custu situ + + Sa protetzione megiorada contra sa sighidura est disativada pro custos sitos + + Novidades de %s + + %s | Bibliotecas de còdighe abertu + + Unos cantos de is sighidores sinnalados in bàsciu sunt istados isblocados in parte, ca nche as interagidu *. + + Àteras informatziones + + + Assistèntzia + + Faddinas + + Avisu de riservadesa + + Connosche is deretos tuos + + Informatziones de sa lissèntzia + + Bibliotecas chi impreamus + + + + Còpia + + Incolla e bae + + Incolla + + URL copiadu in punta de billete + + + Agiunghe a s’ischermu printzipale + + Annulla + + Agiunghe + + Sighi a su situ + + + Credentziales e craes + + Sarva credentziales e craes + + Pregunta·mi·ddu + + Non sarves mai + + Cumpletamentu automàticu in %1$s + + Cumpleta e salva nòmines de utente e craes in sitos cando impreas %1$s. + + Cumpletamentu automàticu in àteras aplicatziones + + Cumpleta nòmines de utente e craes in àteras aplicatziones de su dispositivu tuo. + + Agiunghe credentziale + + + Sincronizatzione de credentziales + + Sincronizatzione de credentziales intre dispositivos + + Credentziales sarvadas + + Is credentziales chi as a sarvare o sincronizare cun %s ant a èssere ammustradas inoghe. + + Leghe àteru subra de Sync. + + Etzetziones + + Is credentziales e is craes non sarvadas ant a èssere ammustradas inoghe. + + No ant a èssere sarvadas is credentziales e is craes de custos sitos. + + Cantzella totu is etzetziones + + Chirca credentziales + + Situ + + Nòmine de utente + + Crae + + Crae copiada in punta de billete + + Nòmine de utente copiadu in punta de billete + + Còpia sa crae + + Cantzella sa crae + + Còpia su nòmine de utente + + Cantzella su nòmine de utente + + Aberi su situ in su navigadore + + Ammustra sa crae + + Cua sa crae + + Isbloca pro bìdere is credentziales sarvadas tuas + + Ampara is credentziales e is craes tuas + + Cunfigura una secuèntzia de blocu, PIN o crae pro amparare is credentziales e is craes tuas de s’atzessu de àtera gente chi tèngiat su dispositivu tuo. + + A pustis + + Cunfigura immoe + + Isbloca su disposivitu tuo + + Nòmine (A-Z) + + Ùrtimu impreu + + + + Cumpletamentu automàticu + + Indiritzos + + Cartas de crèditu + + Sarva e cumpleta in automàticu is cartas + + Is datos sunt tzifrados + + Sincronizatzione de cartas intre dispositivos + + Sincronizatzione de cartas + + Agiunghe una carta de crèditu + + Gesti is cartas + + Agiunghe un’indiritzu + + Gesti is indiritzos + + + Sarva e cumpleta in automàticu is indiritzos + + Include datos comente nùmeros, indiritzos eletrònicos e indiritzos de ispeditzione + + + Agiunghe una carta + + Modìfica sa carta + + Nùmeru de carta + + Data de iscadèntzia + + Mese de sa data iscadèntzia + + Annu de sa data de iscadèntzia + + Nòmine in sa carta + + Cantzella sa carta + + Cantzella sa carta + + Seguru chi boles cantzellare custa carta de crèditu? + + Cantzella + + Sarva + + Sarva + + Annulla + + Cartas sarvadas + + Inserta unu nùmeru de carta vàlidu + + Cumpila custu campu + + Isbloca pro bìdere is cartas sarvadas tuas + + Cunfigura immoe + + A pustis + + Isbloca su disposivitu tuo + + Agiunghe un’indiritzu + + Modìfica s’indiritzu + + Gesti is indiritzos + + Nòmine + + Segundu nòmine + + Sangunadu + + Indiritzu postale + + Tzitade + + Istadu + + Provìntzia + + Còdighe postale + + Paisu o regione + + Telèfonu + + Indiritzu de posta eletrònica + + Sarva + + Annulla + + Cantzella s’indiritzu + + Seguru chi boles cantzellare custu indiritzu? + + Cantzella + + Annulla + + Sarva s’indiritzu + + Cantzella s’indiritzu + + + Agiunghe unu motore de chirca + + Modìfica motore de chirca + + Agiunghe + + Sarva + + Modìfica + + Cantzella + + + Àteru + + Nòmine + + Cadena de chirca + + Sostitui sa chirca cun «%s». Esempru: \nhttps://www.google.com/search?q=%s + + Detàllios de su motore de chirca personalizadu + + + Inserta su nòmine de su motore de chirca + + Inserta una cadena de chirca + + Verìfica chi sa cadena de chirca currispondet a su formadu de esempru + + Faddina in sa connessione cun «%s» + + %s creadu + + %s sarvadu + + %1$s cantzelladu + + + Pro ddu permìtere: + + 1. Bae a sa cunfiguratzione de Android + + Permissos]]> + + %1$s]]> + + + Sa connessione est segura + + Sa connessione no est segura + + Isbòida is testimòngios e is datos de is sitos + + + %s?]]> + + Seguru chi boles cantzellare is permissos pro totu is sitos? + + Seguru chi boles cantzellare is permissos pro custu situ? + + Seguru chi boles cantzellare custu permissu pro custu situ? + + Nissuna etzetzione de situ + + Seguru chi boles cantzellare custu sinnalibru? + + Agiunghe a is curtzadòrgios + + Boga dae is curtzadòrgios + + Averiguadu dae: %1$s + + Cantzella + + Modìfica + + Seguru chi boles cantzellare custa credentziale? + + Cantzella + + Annulla + + Optziones de credentziales + + Sarva is modìficas a sa credentziale. + + Modìfica + + Agiunghe una credentziale noa + + Crae rechesta + + Nòmine de utente rechestu + + Chirca cun sa boghe + + Chistiona immoe + + Esistit giai una credentziale cun custu nòmine + + https://www.esempru.com + + S’indiritzu web depet cuntènnere «https://» o «http://» + + + + Connete un’àteru dispositivu. + + Identìfica·ti a sync + + Nissuna ischeda aberta + + + AB, apo cumprèndidu + + Curtzadòrgios + + Nòmine + + Nòmine de su curtzadòrgiu + + AB + + Annulla + + Cunfiguratzione + + Is patrotzinadores nostros e sa riservadesa tua + + Patrotzinadu + + + + Ischedas inativas + + Serra is ischedas inativas + + + + Boles serrare in automàticu a pustis de unu mese? + + Firefox podet serrare is ischedas chi no apas visualizadu in s’ùrtimu mese. + + ATIVA SA SERRADA AUTOMÀTICA + + Serrada automàtica ativa + + + + Firefox cussìgiat + + Chirca de Google + + Chirca cun %s + + + Boga + + + Incarca inoghe pro àteros detàllios + + + Nàviga in artu + + + Serra + + + Artìculos pro tema + + Iscoberi·nde àteros + + Parte de sa famìlia de Firefox. %s + + Àteras informatziones + + Patrotzinadu + + + Bae a sa cunfiguratzione + + + + mìnima + + ismànnia + + leghe s’artìculu + diff --git a/app/src/main/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml index 425206ef0..1730274d5 100644 --- a/app/src/main/res/values-si/strings.xml +++ b/app/src/main/res/values-si/strings.xml @@ -65,11 +65,11 @@ - ඔබගේ මුල් තිරයෙන් පෞද්. පටිති විවෘත කිරීමට කෙටි මඟක් යොදන්න. + ඔබගේ මුල් තිරයෙන් පෞද්. පටිති විවෘත කිරීමට කෙටි මඟක් යොදන්න. එක් තට්ටුවකින් ඊළඟ පෞද්. පටිත්ත අරින්න. - කෙටිමඟක් යොදන්න + කෙටිමඟක් යොදන්න මුල් තිරයට යොදන්න @@ -166,6 +166,8 @@ නවතන්න එක්කහු + + ගිණුමේ තොරතුරු මෙහි එක්කහු නැත @@ -251,7 +253,7 @@ සෙවුම් සැකසුම් - මෙවර සෙවීම: + මෙවර සෙවීම: මෙවර සෙවීම: @@ -282,6 +284,18 @@ වසන්න + + + ඔබට %s සමඟ බොහෝ දෑ කිරීමට දැනුම්දීම් උපකාරී වේ + + උපාංග අතර පටිති සමමුහූර්තය, බාගැනීම් කළමනාකරණය, %s හි පෞද්ගලිකත්‍ව රැකවරණයෙන් උපරිම ප්‍රයෝජන ගැනීමට ඉඟි, සහ තවත් බොහෝ දෑ. + + ඉදිරියට + + දැන් නොවේ + නව %1$s පටිත්තක් අරින්න @@ -334,30 +348,77 @@ HTTPS-පමණි ප්‍රකාරය - දත්තකඩ විස්තරය අවකරණය + දත්තකඩ පතාක අවකරණය - දත්තකඩ කවුළු අවම කරන්න + දත්තකඩ පතාක අවම කරන්න + + අක්‍රිය + + සක්‍රිය - දත්තකඩ කවුළුවල දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේප කිරීමට ෆයර්ෆොක්ස් උත්සාහ කරන නමුත් ප්‍රතික්‍ෂේප විකල්පයක් නැති නම්, කවුළුව සැඟවීමට දත්තකඩ සියල්ල පිළිගනු ඇත. + දත්තකඩ පතාකවල දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේප කිරීමට ෆයර්ෆොක්ස් උත්සාහ කරන නමුත් ප්‍රතික්‍ෂේප විකල්පයක් නැති නම්, පතාකය සැඟවීමට දත්තකඩ සියල්ල පිළිගනු ඇත. + + %1$s ස්වයංක්‍රීයව දත්තකඩ පතාකවල දත්තකඩ ඉල්ලීම් ප්‍රතික්‍ෂේප කිරීමට උත්සාහ කරයි. මෙම අඩවියට අක්‍රියයි මෙම අඩවියට සක්‍රියයි + + අඩවියට සහාය නොදක්වයි - %1$s සඳහා දත්තකඩ අවකරණය සක්‍රිය කරන්නද? + %1$s සඳහා දත්තකඩ පතාක අවකරණය සක්‍රිය කරන්නද? - %1$s සඳහා දත්තකඩ අවකරණය අක්‍රිය කරන්නද? + %1$s සඳහා දත්තකඩ පතාක අවකරණය අක්‍රිය කරන්නද? %1$s මෙම අඩවියේ දත්තකඩ ඉවත් කර පිටුව නැවුම් කරයි. සියළුම දත්තකඩ මැකීමෙන් බඩු කරත්ත හිස් වීමට හෝ ඔබව නික්මවීමට ඉඩ ඇත. - දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේප කිරීමට %1$s උත්සාහ කරන නමුත් ප්‍රතික්‍ෂේප විකල්පයක් නැති නම්, %2$s මගින් කවුළුව සැඟවීමට දත්තකඩ සියල්ල පිළිගනු ඇත. + දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේප කිරීමට %1$s උත්සාහ කරන නමුත් ප්‍රතික්‍ෂේප විකල්පයක් නැති නම්, %2$s මගින් පතාකය සැඟවීමට දත්තකඩ සියල්ල පිළිගනු ඇත. + + + %1$s සඳහා දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේපයට තැත් කිරීමට හැකිය. + + %1$s සහාය දක්වන අඩවිවල තිබෙන සියළුම දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේප කිරීමට උත්සාහ කරයි. + + දත්තකඩ පතාක ඉවරයි! + + හැකි විට දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේප කරයි. නොඑසේ නම්, දත්තකඩ පතාක ඉවතලීමට සියළු දත්තකඩ පිළිගනියි. + + හැකි විට දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේප කරන්න. + + %1$s සඳහා හැකි විට දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ප්‍රතික්‍ෂේපයට ඉඩ දෙනවාද? + + දැන් නොවේ + + පතාක ඉවතලන්න + + ඔබ දත්තකඩ ඉල්ලීම් අඩුවෙන් දකිනු ඇත + + දත්තකඩ උත්පතන අඩුවෙන් දකින්න + + බාධාවකින් තොර පිරික්සීමකට දත්තකඩ උත්පතන සඳහා ස්වයංක්‍රීයව පිළිතුරු දෙයි. %1$s හැකි නම් සියළුම ඉල්ලීම් ප්‍රතික්‍ෂේප කරයි, නැතහොත් පිළිගනියි. + + බාධාවකින් තොර පිරික්සීමකට දත්තකඩ උත්පතන සඳහා ස්වයංක්‍රීයව පිළිතුරු දෙයි. %1$s හැකි නම් සියළුම ඉල්ලීම් ප්‍රතික්‍ෂේප කරයි. + + උත්පතන ඉවතලන්න + + දත්තකඩ පතාක අවකරණය + + %1$s සඳහා හැකි නම් අඩවියක දත්තකඩ ඉල්ලීම ප්‍රතික්‍ෂේප කිරීමට හෝ නොහැකි විට දත්තකඩ ප්‍රවේශය පිළිගන්නට ඉඩ දෙනවාද? + + %1$s සඳහා හැකි නම් අඩවියක දත්තකඩ ඉල්ලීම ප්‍රතික්‍ෂේප කිරීමට ඉඩ දෙනවාද? + + ඉඩ දෙන්න ඉහළ ආරක්‍ෂාවක් සඳහා HTTPS සංකේතන කෙටුම්පත භාවිතයෙන් අඩවි වෙත ස්වයංක්‍රීයව සම්බන්ධ වීමට තැත් කරයි. - සක්‍රිය - + සක්‍රිය + අක්‍රිය + + සියළු පටිතිවලට සක්‍රියයි + + පෞද්. පටිතිවලට සක්‍රියයි තව දැනගන්න @@ -433,6 +494,11 @@ දැනුම්දීම් + + ඉඩ දුන් + + ඉඩ නොදේ + අභිරුචි එක්කහු එකතුව @@ -457,8 +523,6 @@ a section where users see a list of tabs that they have visited in the past few days --> මෑතදී ගොඩවැදුණු - පොකට් - සිතුවිලි අවුස්සන කතා %s මගින් ලිපි බලගැන්වේ @@ -720,6 +784,13 @@ මාසයකට පසු වසන්න + + මුල් පිටුව පෙන්වන්න + + අවසාන පටිත්ත අරින්න + + පැය හතරකට පසු මුල් පිටුව පෙන්වන්න + පරණ පටිති අක්‍රිය වෙත දමන්න @@ -978,9 +1049,15 @@ හැරදැමීම් - සක්‍රිය + සක්‍රිය අක්‍රිය + + සම්මත + + දැඩි + + අභිරුචි ශ්‍රව්‍ය හා දෘශ්‍ය සඳහා ඉඩදෙන්න @@ -1709,7 +1786,7 @@ භාවිතයට සෙවුම් තන්තුව - “%s” සමඟ විමසුම ප්‍රතිස්ථාපනය කරන්න. නිදසුන:\nhttps://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%s + “%s” සමඟ විමසුම ප්‍රතිස්ථාපනය කරන්න. නිදසුන:\nhttps://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=%s අභිරුචි සෙවුම් යන්ත්‍රයේ විස්තර @@ -1900,8 +1977,6 @@ මාතෘකාව අනුව කතා තව සොයා ගන්න - - පොකට් මගින් බලගැන්වේ. %s මගින් බලගැන්වේ. diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 45dd1d206..bd035271d 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -66,11 +66,11 @@ - Pridať odkaz na otvorenie súkromného prehliadania na domovskú obrazovku. + Pridať odkaz na otvorenie súkromného prehliadania na domovskú obrazovku. Spustite ďalšiu súkromnú kartu jedným ťuknutím. - Pridať skratku + Pridať skratku Pridať na Úvodnú obrazovku @@ -171,6 +171,8 @@ Zastaviť Doplnky + + Informácie o účte Nemáte žiadne doplnky @@ -263,7 +265,7 @@ Hľadať v nastaveniach - Tentokrát hľadať: + Tentokrát hľadať: Tentokrát hľadať v: @@ -293,6 +295,18 @@ Zavrieť + + + Upozornenia vám pomôžu vyťažiť a aplikácie %s ešte viac + + Synchronizujte svoje karty medzi zariadeniami, spravujte sťahovanie, získajte tipy, ako čo najlepšie využiť ochranu súkromia prehliadača %s a ďalšie. + + Pokračovať + + Teraz nie + Otvoriť novú kartu %1$su @@ -349,13 +363,21 @@ Zníženie počtu bannerov súborov cookie Znižovať počet bannerov súborov cookie + + Vypnuté + + Zapnuté - Firefox sa automaticky pokúša odmietnuť žiadosti o uloženie súborov cookie na informačných banneroch súborov cookie. Ak možnosť odmietnutia nie je k dispozícii, Firefox môže akceptovať všetky súbory cookie, aby oznámenie zavrel. + Firefox sa automaticky pokúša odmietnuť žiadosti o uloženie súborov cookie na informačných banneroch súborov cookie. Ak možnosť odmietnutia nie je k dispozícii, Firefox môže akceptovať všetky súbory cookie, aby oznámenie zavrel. + + %1$s sa automaticky pokúša odmietnuť žiadosti o súbory cookie na banneroch súborov cookie. Vypnuté pre túto stránku Zapnuté pre túto stránku + + Stránka momentálne nie je podporovaná Zapnúť znižovanie počtu bannerov súborov cookie pre %1$s? @@ -363,14 +385,54 @@ %1$s vymaže súbory cookie tohto webu a obnoví stránku. Vymazanie všetkých súborov cookie vás môže odhlásiť zo stránky alebo vyprázdniť nákupné košíky. - %1$s sa môže pokúsiť odmietnuť žiadosti o uloženie súborov cookie. Ak možnosť odmietnutia nie je k dispozícii, %2$s môže akceptovať všetky súbory cookie, aby oznámenie zavrel. + %1$s sa môže pokúsiť odmietnuť žiadosti o uloženie súborov cookie. Ak možnosť odmietnutia nie je k dispozícii, %2$s môže akceptovať všetky súbory cookie, aby oznámenie zavrel. + + + %1$s sa môže pokúsiť automaticky odmietnuť žiadosti o súbory cookie. + + %1$s sa pokúša automaticky odmietnuť všetky žiadosti o súbory cookie na podporovaných stránkach. + + Bannery k súborom cookie sú preč! + + + Automaticky odmietajte žiadosti o súbory cookie, ak je to možné. V opačnom prípade akceptujte všetky súbory cookie, aby vás bannery súborov cookie viac neotravovali. + + Automaticky odmietať žiadosti o súbory cookie, ak je to možné. + + Povoliť aplikácii %1$s automaticky odmietať žiadosti o súbory cookie, ak je to možné? + + Teraz nie + + Zavrieť bannery + + Uvidíte menej žiadostí o súbory cookie + + Uvidíte menej vyskakovacích okien súborov cookie + + Automaticky odpovedajte na vyskakovacie okná so súbormi cookie pre prehliadanie bez rozptyľovania. %1$s odmietne všetky žiadosti, ak je to možné, a ak nie je, tak ich prijme. + + Automaticky odpovedajte na vyskakovacie okná a bannery so žiadosťami o použitie súborov cookie a prehliadajte bez rozptyľovania. %1$s odmietne všetky žiadosti, kde to bude možné. + + Zavrieť vyskakovacie okná + + Zníženie počtu bannerov súborov cookie + + Povoliť aplikácii %1$s odmietnuť žiadosť stránky o súhlas so súbormi cookie, ak je to možné, alebo akceptovať prístup k súborom cookie, ak to nie je možné? + + Povoliť aplikácii %1$s odmietnuť žiadosť webu o súhlas so súbormi cookie, ak je to možné? + + Povoliť Automaticky sa pokúša pripojiť k stránkam pomocou šifrovacieho protokolu HTTPS na zvýšenie bezpečnosti. - Zapnutý - + Zapnutý + Vypnutý + + Zapnuté na všetkých kartách + + Zapnuté na súkromných kartách Ďalšie informácie @@ -449,6 +511,11 @@ Upozornenia + + Povolené + + Zakázané + Vlastná kolekcia doplnkov @@ -473,8 +540,6 @@ Nedávno navštívené - - Pocket Príbehy na zamyslenie @@ -732,6 +797,13 @@ Zavrieť po jednom mesiaci + + Otvárať na domovskej stránke + + Otvoriť na naposledy použitej karte + + Po štyroch hodinách otvoriť na domovskej stránke + Presúvať staré karty medzi neaktívne @@ -996,10 +1068,16 @@ Výnimky - Zapnutá + Zapnutá Vypnutá + + Štandardná + + Prísna + + Vlastná Povoliť zvuk a video @@ -1736,7 +1814,7 @@ Výraz vyhľadávania - Nahraďte výraz s „%s“. Príklad:\nhttps://www.google.com/search?q=%s + Nahraďte výraz s „%s“. Príklad:\nhttps://www.google.com/search?q=%s Podrobnosti vlastného vyhľadávacieho modulu @@ -1937,8 +2015,6 @@ Príbehy podľa témy Objavte ďalšie - - Službu poskytuje Pocket Vďaka službe %s. diff --git a/app/src/main/res/values-skr/strings.xml b/app/src/main/res/values-skr/strings.xml index ac0918dd1..d657a6fea 100644 --- a/app/src/main/res/values-skr/strings.xml +++ b/app/src/main/res/values-skr/strings.xml @@ -67,11 +67,11 @@ - آپݨی ہوم سکرین کنوں نجی ٹیب کھولݨ کیتے ہک شارٹ کٹ شامل کرو۔ + آپݨی ہوم سکرین کنوں نجی ٹیب کھولݨ کیتے ہک شارٹ کٹ شامل کرو۔ ہک ٹیپ وچ اڳلی نویں ٹیب لان٘چ کرو۔ - شارٹ کٹ شامل کرو + شارٹ کٹ شامل کرو ہوم سکرین تے شامل کرو @@ -170,6 +170,8 @@ روکو ایڈ ــ آن + + کھاتہ معلومات اِتھاں کوئی ایڈ ــ آن کائنی @@ -256,7 +258,7 @@ ڳولݨ ترتیباں - ایں ویلے دی ڳول: + ایں ویلے دی ڳول: ایں ویلے ایندے وچ ڳول: @@ -285,6 +287,18 @@ بند کرو + + + اطلاع نامے %s نال ودھیک کرݨ وچ تہاݙی مدد کریندن۔ + + آپݨے ٹیباں کوں ڈیوائساں دے درمیان ہم وقت بݨاؤ، ڈاؤن لوڈاں منیج کرو، %s دی رازداری حفاظت بارے گُر گھنو تے ٻیا ٻہوں کجھ۔ + + جاری + + ہݨ کائناں + نویں %1$s ٹیب کھولو @@ -340,14 +354,22 @@ کوکی بینراں کوں تھوڑا کرو + + بند + + چالو - فائر فوکس آپݨے آپ کوکی بینراں دی درخواست کوں مسترد کرݨ دی کوشش کرینداے. اگر مسترد کرݨ دا آپشن موجودکائنی ، تاں فائر فوکس ساری کوکیز کوں بینر ختم کرݨ پاروں قبول کر سڳدا ہے. + فائر فوکس آپݨے آپ کوکی بینراں دی درخواست کوں مسترد کرݨ دی کوشش کرینداے. اگر مسترد کرݨ دا آپشن موجودکائنی ، تاں فائر فوکس ساری کوکیز کوں بینر ختم کرݨ پاروں قبول کر سڳدا ہے. + + %1$s کوکی بینراں تے کوکی ارداساں کوں آپݨے آپ مسترد کرݨ دی کوشش کریندے۔ ایں سائٹ کیتے بند کرو ایں سائٹ کیتے چالو کرو + + سائٹ فی الحال سہارا تھئی کائنی %1$s کیتے کوکی بینر گھٹاوݨ چالو کروں؟ @@ -356,14 +378,53 @@ %1$s ایں سائٹ دیاں کوکیاں صاف کریسی تے ورقہ تازہ کریسی۔ساریاں کوکیاں صاف کرݨ نال تساں سائن آوٹ تھی سڳدے ہو یا تہاݙی خریداری ریڑھی خالی تھی ویسی۔ - %1$s آپݨے آپ کوکی بینراں دی درخواست کوں مسترد کرݨ دی کوشش کریندا ہے. اگر مسترد کرݨ دا آپشن موجودکائنی ، تاں %2$s ساری کوکیز کوں بینر ختم کرݨ پاروں قبول کر سڳدا ہے. + %1$s آپݨے آپ کوکی بینراں دی درخواست کوں مسترد کرݨ دی کوشش کریندا ہے. اگر مسترد کرݨ دا آپشن موجودکائنی ، تاں %2$s ساری کوکیز کوں بینر ختم کرݨ پاروں قبول کر سڳدا ہے. + + + %1$s آپݨے آپ کوکی ارداساں کوں مسترد کرݨ دی کوشش کر سڳدے۔ + + %1$s آپݨے آپ سہارا تھیاں سائٹاں تے ساریاں کوکی ارداساں کوں مسترد کرݨ دی کوشش کریندا ہے۔ + + کوکی بینرز شروع تھی ڳئے! + + جہڑے ویلے ممکن ہووے، کوکی ارداساں کوں خود کار مسترد کر ݙیوو، نہ تاں ول، کوکی بینراں کوں برخاست کرݨ کیتے ساریاں کوکیاں قبول کرو۔ + + جݙݨ ممکن ہووے، آپݨے آپ کوکی ارداساں مسترد کرو۔ + + ڄݙݨ ممکن ہووے تاں %1$s کوں کوکی اردساں آپݨے آپ مسترد کرݨ دی اجازت ݙیووں؟ + + ہݨ نہ + + بینر فارغ کرو + + تساں ٻہوں تھوڑیاں کوکی ارداساں ݙیکھسو + + تھوڑیاں پوپ اپاں کوکی ݙیکھو + + بدحواسی کنوں پاک براؤزنگ کیتے کوکی پوپ اپاں دا خودکار جواب ݙیوو۔ جے ممکن ہوسی تاں %1$s ساریاں ارداساں مسترد کر ݙیسی، یا ممکن نہ ہوسی تاں ساریاں قبول کر گھنسی۔ + + بدحواسی کنوں پاک براؤزنگ کیتے کوکی پوپ اپاں دا خودکار جواب ݙیوو۔ جے ممکن ہوسی تاں %1$s ساریاں ارداساں مسترد کر ݙیسی۔ + + پوپ اپ فارغ کرو + + کوکی بینر گھٹاوݨ + + جے ممکن ہے تاں %1$s کوں سائٹ کوکی دی رضامندی ارداس دے انکار کرݨ دی اجازت ݙیووں یا ڄݙݨ ممکن نہ ہووے تاں کوکی تائیں رسائی قبول کروں؟ + + جے ممکن ہووے تاں %1$s کوں سائٹ دیاں کوکی رضامندی ارداس دا انکار کرݨ دی اجازت ݙیووں؟ + + اجازت ݙیوو خودکار طور تے ودھدی ہوئی حفاظت کیتے ایچ ٹی ٹی پی ایس خفیہ کاری پروٹوکول ورتندے ہوئے سائٹاں کوں کنکٹ کرݨ دی کوشش کریندے۔ - چالو - + چالو + بند + + ساریاں ٹیباں وچ تے + + نجی ٹیباں وچ تے ٻیا سِکھو @@ -441,6 +502,11 @@ اطلاع نامے + + اجازت ݙتے ہوئے + + اجازت کائنی + من پسند ایڈ ــ آن مجموعہ @@ -467,8 +533,6 @@ a section where users see a list of tabs that they have visited in the past few days --> حالیہ ݙٹھے - پاکٹ - فکر انگیز کہاݨیاں %s ولوں تکڑے تھئے مضمون @@ -733,6 +797,14 @@ ہک مہینے بعد بند کرو + + مکھ پنے تے کھولو + + چھیکڑی ٹیب تے کھولو + + + چار گھنٹیاں بعد مکھ پنے تے کھولو + پراݨے ٹیب غیرفعال وچ ٹورو @@ -997,9 +1069,15 @@ استثنيات - چالو + چالو بند + + معیار + + سخت + + مخصوص آڈیو تے وڈیو دی اجازت ݙیوو @@ -1745,7 +1823,7 @@ ورتݨ کیتے تند ڳولو - “%s” نال سوال وٹاؤ۔ + “%s” نال سوال وٹاؤ۔ مثال:\nhttps://www.google.com/search?q=%s من پسند ڳولݨ انجݨ تفصیلاں @@ -1945,8 +2023,6 @@ موضوع دے لحاظ نال کہاݨیاں ٻیاں لبھو - - پاکٹ ولوں تکڑا تھیا تکڑا تھیا %s ولوں. diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index e6fc39205..bab7834c1 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -67,11 +67,11 @@ - Dodajte bližnjico za odpiranje zasebnih zavihkov z začetnega zaslona. + Dodajte bližnjico za odpiranje zasebnih zavihkov z začetnega zaslona. Odprite naslednji zaseben zavihek z enim dotikom. - Dodaj bližnjico + Dodaj bližnjico Dodaj na domači zaslon @@ -86,7 +86,7 @@ Zapri - Zapri + Zapri @@ -172,6 +172,8 @@ Ustavi Dodatki + + Podatki o računu Tukaj ni dodatkov @@ -260,7 +262,7 @@ Nastavitve iskanja - Tokrat išči: + Tokrat išči: Tokrat išči: @@ -289,6 +291,14 @@ Zapri + + Sinhronizirajte zavihke med napravami, upravljajte prenose, pridobite nasvete za kar najboljši izkoristek %sovih zmožnosti in še več. + + Nadaljuj + + Ne zdaj + Odpri nov zavihek v %1$su @@ -344,12 +354,20 @@ Zmanjšanje števila pasic s piškotki Zmanjšaj število pasic s piškotki + + Izključeno + + Vključeno - Firefox samodejno poskuša zavrniti zahteve pasic s piškotki po nastavljanju piškotkov. Če zavrnitev ni možna, lahko Firefox sprejme vse piškotke in zapre pasico. + Firefox samodejno poskuša zavrniti zahteve pasic s piškotki po nastavljanju piškotkov. Če zavrnitev ni možna, lahko Firefox sprejme vse piškotke in zapre pasico. + + %1$s poskuša samodejno zavrniti zahteve pasic po shranjevanju piškotkov. Izključeno na tem spletnem mestu Vključeno na tem spletnem mestu + + Spletno mesto trenutno ni podprto Vključim zmanjšanje števila pasic s piškotki za %1$s? @@ -357,14 +375,45 @@ %1$s bo počistil piškotke tega spletnega mesta in osvežil stran. Če počistite vse piškotke, boste morda odjavljeni ali se bo izpraznila vaša nakupovalna košarica. - %1$s lahko poskusi samodejno zavrniti zahteve za nastavljanje piškotkov. Če zavrnitev ni možna, lahko %2$s sprejme vse piškotke in zapre pasico. + %1$s lahko poskusi samodejno zavrniti zahteve za nastavljanje piškotkov. Če zavrnitev ni možna, lahko %2$s sprejme vse piškotke in zapre pasico. + + + %1$s lahko poskusi samodejno zavrniti zahteve za shranjevanje piškotkov. + + %1$s poskuša samodejno zavrniti vse zahteve za shranjevanje piškotkov na spletnih mestih, ki so podprta. + + Pasice s piškotki, izginite! + + Samodejno zavrni zahteve za shranjevanje piškotkov, kadar je to mogoče. V nasprotnem primeru sprejmi vse piškotke in skrij pasico. + + Samodejno zavrni zahteve za shranjevanje piškotkov, kadar je mogoče. + + Dovolite %1$su, da samodejno zavrne zahteve za shranjevanje piškotkov, kadar je mogoče? + + Ne zdaj + + Skrij pasice + + Prikazovalo se vam bo manj zahtev za shranjevanje piškotkov + + Zmanjšanje števila pasic s piškotki + + Dovolite %1$su, da zavrača zahteve spletnih mest za shranjevanje piškotkov, če to ni mogoče, pa jih sprejme? + + Dovolite %1$su, da zavrača zahteve spletnih mest za shranjevanje piškotkov, če je to mogoče? + + Dovoli Za večjo varnost poskuša samodejno vzpostaviti povezavo s šifrirnim protokolom HTTPS. - Vključeno - + Vključeno + Izključeno + + V vseh zavihkih + + V zasebnih zavihkih Več o tem @@ -443,6 +492,11 @@ Obvestila + + Dovoljeno + + Ni dovoljeno + Zbirka dodatkov po meri @@ -466,8 +520,6 @@ Nedavno obiskano - - Pocket Zgodbe, ki spodbujajo k razmisleku @@ -728,6 +780,13 @@ Zapri po enem mesecu + + Odpri na domači strani + + Odpri na zadnjem zavihku + + Po štirih urah odpri na domači strani + Premakni stare zavihke med nedejavne @@ -997,9 +1056,15 @@ Izjeme - Vklopljeno + Vklopljeno Izklopljeno + + Običajna + + Stroga + + Po meri Dovoli zvok in video @@ -1746,7 +1811,7 @@ Iskalni niz za uporabo - Zamenjajte poizvedbo z "%s". Primer: \nhttps://www.google.com/search?q=%s + Zamenjajte poizvedbo z "%s". Primer: \nhttps://www.google.com/search?q=%s Podrobnosti iskalnika po meri @@ -1951,8 +2016,6 @@ Zgodbe po temi Odkrijte več - - Omogoča Pocket Omogoča %s. diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 3db210f10..66c8c463c 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -13,7 +13,7 @@ Çaktivizo shfletim privat - Bëni kërkim ose jepni adresë + Bëni kërkim, ose jepni adresë Kërkoni në historik @@ -58,18 +58,18 @@ - %1$s e spastron historikun tuaj të kërkimeve dhe shfletimit prej skedash private, kur i mbyllni ato ose dilni nga aplikacioni. Edhe pse kjo s’ju bën anonim përballë sajteve apo furnizuesit të shërbimit tuaj internet, e bën më të lehtë mbajtjen private të asaj çka bëni në internet, nga cilido tjetër që përdor këtë pajisje. + %1$s e spastron historikun tuaj të kërkimeve dhe shfletimit prej skedash private, kur i mbyllni ato, ose dilni nga aplikacioni. Edhe pse kjo s’ju bën anonim përballë sajteve apo furnizuesit të shërbimit tuaj internet, e bën më të lehtë mbajtjen private të asaj çka bëni në internet, nga cilido tjetër që përdor këtë pajisje. Mite të rëndomtë mbi shfletimin privat - Shtoni një shkurtore për të hapur skeda private që prej skenës Kreu juaj. + Shtoni një shkurtore për të hapur skeda private që prej skenës Kreu juaj. Skedën pasuese private hape me një prekje. - Shtoni shkurtore + Shtoni shkurtore Shtoje te skena e Kreut @@ -93,7 +93,7 @@ Mësoni mbi Mbrojtje Tërësore Nga Cookie-t - Lypset hyrje në kamera. Kaloni te rregullimet e Android-it, prekni Leje, dhe prekni Lejoje. + Lypset hyrje në kamera. Kaloni te rregullimet e Android-it, prekni mbi Leje dhe prekni Lejoje. Shko te rregullimet @@ -169,6 +169,8 @@ Ndale Shtesa + + Hollësi llogarie S’ka shtesa këtu @@ -178,7 +180,7 @@ Rregullime - Librari + Bibliotekë Sajt për desktop @@ -258,7 +260,7 @@ Rregullime mbi kërkimin - Kërkimi këtë herë: + Kërkimi këtë herë: Këtë herë kërko te: @@ -285,6 +287,18 @@ Mbylle + + + Njoftimet ju ndihmojnë të arrini më tepër gjëra me %s + + Njëkohësoni skedat tuaja nëpër pajisje, administroni shkarkime, merrni ndihmëza mbi shfrytëzimin në maksimum të mbrojtjes së privatësisë në %s, etj. + + Vazhdo + + Jo tani + Hapni një skedë të re %1$s @@ -340,14 +354,22 @@ Reduktim Banderolash Për Cookie-t Redukto banderola për cookie-t + + Off + + On - Firefox-i provon automatikisht të hedhë tej kërkesa për “cookie” nga banderola cookie-shbanners. Nëse s’ka mundësi hedhjeje tej, Firefox-i mund të pranojë krejt cookie-t, për të hequr qafe banderolën. + Firefox-i provon automatikisht të hedhë tej kërkesa për “cookie” nga banderola cookie-shbanners. Nëse s’ka mundësi hedhjeje tej, Firefox-i mund të pranojë krejt cookie-t, për të hequr qafe banderolën. + + %1$s provon vetvetiu të hedhë oshtë kërkesa depozitimi cookie -sh nga banderola cookie-sh. Çaktivizuar për këtë sajt Aktivizuar për këtë sajt + + Sajt aktualisht i pambuluar Të aktivizohet Reduktim Banderolash Cookie-sh për %1$s? @@ -355,14 +377,53 @@ %1$s do të spastrojë cookie-t për këtë sajt dhe do të rifreskojë faqen. Spastrimi i krejt cookie-ve mund të sjellë nxjerrjen tuaj nga llogaria, ose zbrazje shportash blerjesh. - %1$s-i mund të provojë të hedhë tej automatikisht kërkesa për “cookie”. Nëse s’ka mundësi hedhjeje tej, %2$s-i mund të pranojë krejt cookie-t, për të hequr qafe banderolën. + %1$s-i mund të provojë të hedhë tej automatikisht kërkesa për “cookie”. Nëse s’ka mundësi hedhjeje tej, %2$s-i mund të pranojë krejt cookie-t, për të hequr qafe banderolën. + + + %1$s mund të provojë vetvetiu të hedhë poshtë kërkesa depozitimi cookie-sh. + + %1$s provon të hedhë poshtë automatikisht krejt kërkesat për cookies, në sajtet që e mbulojnë. + + Lamtumirë banderola cookie-sh! + + Hidh vetvetiu tej kërkesa për depozitim cookie-sh, kur është e mundur. Përndryshe, prano krejt cookies, që të hiqen qafe banderolat e cookie-ve. + + Hidh vetvetiu tej kërkesa për depozitim cookie-sh, kur është e mundur. + + Të lejohet %1$s të hedhë tej vetvetiu kërkesa për depozitim cookie-sh, kur është e mundur? + + Jo Tani + + Hidh tej banderola + + Do të shihni më pak kërkesa depozitimi cookie-sh + + Shihni më pak flluska cookie-sh + + Përgjigju vetvetiu flluskave për cookie, për shfletim pa bezdisje. %1$s do të hedhë poshtë krejt kërkesat, në qoftë e mundur, ose do t’i pranojë të tëra, në mos qoftë e mundur. + + Përgjigju vetvetiu flluskave për cookie, për shfletim pa bezdisje. %1$s do të hedhë poshtë krejt kërkesat, në qoftë e mundur. + + Hidh tej Flluska + + Reduktim Banderolash Për Cookie-t + + Të lejohet %1$s të hedhë poshtë kërkesa pranimi cookie-sh nga një sajt, nëse është e mundur, apo të pranohen cookies, kur s’është e mundur? + + Të lejohet %1$s të hedhë poshtë kërkesa pranimi cookie-sh nëse është e mundur? + + Lejoje Përpiqet automatikisht të lidhet me sajtet duke përdorur protokollin HTTPS të fshehtëzimit, për më tepër siguri. - On - + On + Off + + Në krejt skedat + + Në skeda private Mësoni më tepër @@ -376,7 +437,7 @@ Por, është gjithashtu e mundshme që të jetë dora e ndonjë agresori. Nëse vazhdoni te sajti, s’duhet të jepni ndonjë të dhënë rezervat. Nëse vazhdoni, mënyra Vetëm-HTTPS do të çaktivizohet përkohësisht për sajtin. - Përdorshmëri + Përdorim nga persona me aftësi të kufizuara Shërbyes vetjak Llogarish Firefox @@ -440,6 +501,11 @@ Njoftime + + E lejuar + + E palejuar + Koleksion vetjak shtesash @@ -462,8 +528,6 @@ Vizituar së fundi - - Pocket Histori që të vënë në mendim @@ -719,6 +783,13 @@ Mbylle pas një muaji + + Hape në faqen hyrëse + + Hape në skedën e fundit + + Hape në faqen hyrëse pas katër orësh + Skedat e vjetra kaloji te joaktivet @@ -983,9 +1054,15 @@ Përjashtime - On + On Off + + Standarde + + Strikte + + Vetjake Lejo audio dhe video @@ -1018,7 +1095,7 @@ Menu koleksionesh - Koleksiononi gjërat që kanë rëndësi për ju.\nGruponi tok kërkime të ngjashme, sajte, dhe skeda, për përdorim më të shpejtë më pas. + Koleksiononi gjërat që kanë rëndësi për ju.\nGruponi tok kërkime të ngjashme, sajte dhe skeda, për përdorim më të shpejtë më pas. Përzgjidhni Skeda @@ -1172,7 +1249,7 @@ URL-ja u kopjua - Ky është një shembull teksti. Gjendet këtu për të treguar se si do të duket teksti kur zmadhoni ose zvogëloni madhësinë përmes këtij rregullimi. + Ky është një shembull teksti. Gjendet këtu për të treguar se si do të duket teksti, kur zmadhoni ose zvogëloni madhësinë përmes këtij rregullimi. Bëjeni tekstin në sajte më të madh ose më të vogël @@ -1559,7 +1636,7 @@ Siguroni kredenciale hyrjesh dhe fjalëkalime tuajt - Ujdisni një rregullsi, PIN ose fjalëkalim kyçjeje pajisjeje për të mbrojtur nga hyrja në to kredencialet e hyrjes dhe fjalëkalimet tuaj të ruajtur, nëse pajisjen tuaj e ka dikush tjetër. + Ujdisni një rregullsi, PIN, ose fjalëkalim kyçjeje pajisjeje për të mbrojtur nga hyrja në to kredencialet e hyrjes dhe fjalëkalimet tuaj të ruajtur, nëse pajisjen tuaj e ka dikush tjetër. Më vonë @@ -1649,7 +1726,7 @@ Siguroni kartat tuaja të kreditit - Ujdisni një rregullsi, PIN ose fjalëkalim kyçjeje pajisjeje për të mbrojtur nga hyrja në to kartat tuaja kreditit të ruajturar, nëse pajisjen tuaj e ka dikush tjetër. + Ujdisni një rregullsi, PIN, ose fjalëkalim kyçjeje pajisjeje për të mbrojtur nga hyrja në to kartat tuaja kreditit të ruajturar, nëse pajisjen tuaj e ka dikush tjetër. Ujdiseni tani @@ -1724,7 +1801,7 @@ Varg kërkimi për t’u përdorur - Zëvendësoni kërkesën me “%s”. Shembull:\nhttps://www.google.com/search?q=%s + Zëvendësoni kërkesën me “%s”. Shembull:\nhttps://www.google.com/search?q=%s Hollësi motori vetjak kërkimesh @@ -1820,7 +1897,7 @@ https://www.example.com - Adresa Web duhet të përmbajë "https://" ose "http://" + Adresa Web duhet të përmbajë “https://” ose “http://” Lypset strehëemër i vlefshëm @@ -1925,8 +2002,6 @@ Histori sipas subjektit Zbuloni më tepër - - Bazuar në Pocket. Mundësuar nga %s. diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 148120b07..68a5e7f98 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -59,16 +59,16 @@ - %1$s ће обрисати вашу историју прегледања и претраживања када затворите све приватне језичке или изађете из апликације. Додуше, ово неће сакрити ваш идентитет од веб страница и интернет провајдера, али ће вам помоћи да заштитите ваш онлајн живот од других корисника овог уређаја. + %1$s ће обрисати вашу историју прегледања и претраживања када затворите све приватне језичке или изађете из апликације. Додуше, ово неће сакрити ваш идентитет од веб страница и интернет добављача, али ће вам помоћи да заштитите ваш онлајн живот од других корисника овог уређаја. Чести митови о приватном прегледању - Додајте пречицу за отварање приватних језичака са вашег почетног екрана. + Додајте пречицу за отварање приватних језичака са вашег почетног екрана. Покрените приватну картицу једним додиром. - Додај пречицу + Додај пречицу Додај на почетни екран @@ -170,6 +170,8 @@ Заустави Додаци + + Информације о налогу Овде нема додатака @@ -259,7 +261,7 @@ Подешавања претраге - Овај пут претражујте са: + Овај пут претражујте са: Овај пут претражујте: @@ -289,6 +291,18 @@ Затвори + + + Обавештења вам помажу да урадите више уз %s + + Синхронизујте ваше картице између уређаја, управљајте преузимањима, добијајте савете о томе како да на најбољи начин искористите %s заштиту приватности и још много тога. + + Настави + + Не сада + Отвори нови %1$s језичак @@ -345,13 +359,21 @@ Смањење банера колачића Смањи банере колачића + + Искључено + + Укључено - Firefox аутоматски покушава да одбије захтеве за складиштење колачића када се прикаже банер колачића. Ако опција за одбијање није доступна, Firefox може прихватити све колачиће да би сакрио банер. + Firefox аутоматски покушава да одбије захтеве за складиштење колачића када се прикаже банер колачића. Ако опција за одбијање није доступна, Firefox може прихватити све колачиће да би сакрио банер. + + %1$s аутоматски покушава да одбије захтеве за колачиће на банерима колачића. Искључено за овај сајт Укључено за овај сајт + + Сајт тренутно није подржан Укључити смањење банера колачића за %1$s? @@ -359,14 +381,53 @@ %1$s ће обрисати колачиће и освежити страницу. Брисање колачића може да вас одјави са сајта или да испразни вашу корпу за куповину. - %1$s може аутоматски да покуша да одбије колачиће. Ако опција за онемогућавање није доступна, %2$s може да прихвати све колачиће да затвори банер. + %1$s може аутоматски да покуша да одбије колачиће. Ако опција за онемогућавање није доступна, %2$s може да прихвати све колачиће да затвори банер. + + + %1$s може аутоматски да одбије захтеве за колачиће. + + %1$s покушава аутоматски да одбије све захтеве за колачиће на подржаним сајтовима. + + Доле банери колачића! + + Аутоматски одбаците захтеве за колачиће када је то могуће. У супротном, прихватите све колачиће да затворите банере колачића. + + Аутоматски одбија захтеве за колачиће, ако је могуће. + + Дозволити да %1$s аутоматски одбије захтеве за колачиће, ако је могуће? + + Не сада + + Одбаци банере + + Видећете мање захтева за колачиће + + Да видите мање искачућих прозора за колачиће + + Аутоматски одговарајте на искачуће колачиће за прегледање без ометања. %1$s ће одбити све захтеве ако је то могуће или прихватити све ако није. + + Аутоматски реагује на искачуће прозоре колачића за прегледање без ометања. %1$s ће одбити све захтеве ако је могуће. + + Одбаци искачуће прозоре + + Смањење банера колачића + + Дозволити да %1$s одбије захтеве за пристанак на колачиће када је то могуће или да прихвати приступ колачићима када то није могуће? + + Дозволити %1$s да одбије захтев за колачиће, ако је то могуће? + + Дозволи Самостално се повезујемо на странице користећи HTTPS протокол за шифровање података у преносу зарад боље безбедности. - Укључено - + Укључено + Искључено + + На свим картицама + + На приватним картицама Сазнај више @@ -443,6 +504,11 @@ Обавештења + + Дозвољено + + Није дозвољено + Колекција прилагођених додатака @@ -465,8 +531,6 @@ Недавно посећено - - Pocket Побуђујуће и поучне приче @@ -726,6 +790,13 @@ Затвори након једног месеца + + Отвори на почетној страници + + Отвори на последњој картици + + Отвори на почетној страници после 4 сата + Премести старе картице у неактивне @@ -990,9 +1061,15 @@ Изузеци - Укључено + Укључено Искључено + + Обично + + Строго + + Прилагођено Дозволи звук и видео @@ -1733,7 +1810,7 @@ Текст претраге за коришћење - Замените упит са “%s”. Пример:\nhttps://www.google.com/search?q=%s + Замените упит са “%s”. Пример:\nhttps://www.google.com/search?q=%s Детаљи прилагођеног претраживача @@ -1936,8 +2013,6 @@ Приче по теми Откријте више - - Покреће Pocket. Покреће %s. diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 5acd68ac0..edb710732 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -66,11 +66,11 @@ - Lägg till en genväg för att öppna privata flikar från din startsida. + Lägg till en genväg för att öppna privata flikar från din startsida. Starta nästa privata flik med ett tryck. - Lägg till genväg + Lägg till genväg Lägg till på startsidan @@ -173,6 +173,8 @@ Stopp Tillägg + + Kontoinformation Inga tillägg här @@ -265,7 +267,7 @@ Sökinställningar - Denna sökning: + Denna sökning: Denna gång, sök med: @@ -294,6 +296,18 @@ Stäng + + + Aviseringar hjälper dig att göra mer med %s + + Synkronisera dina flikar mellan enheter, hantera nedladdningar, få tips om hur du får ut det mesta av %s:s integritetsskydd och mer. + + Fortsätt + + Inte nu + Öppna en ny %1$s-flik @@ -348,13 +362,21 @@ Reducering av kakbanner Minska kakbanners + + Av + + - Firefox försöker automatiskt avvisa kak-förfrågningar på kak-banners. Om ett avvisningsalternativ inte är tillgängligt kan Firefox acceptera alla kakor för att ta bort bannern. + Firefox försöker automatiskt avvisa kak-förfrågningar på kak-banners. Om ett avvisningsalternativ inte är tillgängligt kan Firefox acceptera alla kakor för att ta bort bannern. + + %1$s försöker automatiskt avvisa kak-förfrågningar på kakbanners. Av för denna webbplats PÅ för denna webbplats + + Webbplatsen stöds inte för närvarande Vill du aktivera reducering av kakbanners för %1$s? @@ -362,14 +384,54 @@ %1$s rensar webbplatsens kakor och uppdaterar sidan. Rensa alla kakor kan logga ut dig eller tömma kundvagnar. - %1$s kan försöka att automatiskt avvisa kak-förfrågningar. Om ett avvisningsalternativ inte är tillgängligt kan %2$s acceptera alla kakor för att ta bort bannern. + %1$s kan försöka att automatiskt avvisa kak-förfrågningar. Om ett avvisningsalternativ inte är tillgängligt kan %2$s acceptera alla kakor för att ta bort bannern. + + + %1$s kan försöka att automatiskt avvisa kak-förfrågningar. + + %1$s försöker automatiskt avvisa alla kak-förfrågningar på webbplatser som stöds. + + Ta bort kak-banners! + + Avvisa automatiskt kak-förfrågningar när det är möjligt. I annat fall, acceptera alla kakor för att ta bort kak-banners. + + Avvisa automatiskt kak-förfrågningar när det är möjligt. + + Vill du tillåta att %1$s automatiskt avvisar kak-förfrågningar när det är möjligt? + + Inte nu + + Ignorera banners + + Du kommer att se färre kak-förfrågningar + + Se färre popup-fönster för kakor + + + Svara automatiskt på popup-fönster för kakor för att surfa utan distraktion. %1$s kommer att avvisa alla förfrågningar om möjligt, eller acceptera alla om inte. + + Svara automatiskt på popup-fönster för kakor för att surfa utan distraktion. %1$s kommer att avvisa alla förfrågningar om möjligt. + + Ignorera popup-fönster + + Reducering av kakbanner + + Vill du tillåta %1$s att avslå en webbplats begäran om samtycke till kakor om möjligt eller acceptera kak-åtkomst när det inte är möjligt? + + Vill du tillåta %1$s att avslå en webbplats begäran om samtycke till kakor om möjligt? + + Tillåt Försöker automatiskt ansluta till webbplatser med HTTPS-krypteringsprotokollet för ökad säkerhet. - - + + Av + + På i alla flikar + + På i privata flikar Läs mer @@ -448,6 +510,11 @@ Aviseringar + + Tillåten + + Inte tillåtet + Anpassad tilläggssamling @@ -471,8 +538,6 @@ Nyligen besökta - - Pocket Tankeväckande berättelser @@ -732,6 +797,13 @@ Stäng efter en månad + + Öppna på hemsidan + + Öppna på den senaste fliken + + Öppnar på hemsidan efter fyra timmar + Flytta gamla flikar till inaktiva @@ -997,10 +1069,16 @@ Undantag - + Av + + Standard + + Strikt + + Anpassad Tillåt ljud och video @@ -1744,7 +1822,7 @@ Söksträng som ska användas - Byt ut frågan med “%s”. Exempel:\nhttps://www.google.com/search?q=%s + Byt ut frågan med “%s”. Exempel:\nhttps://www.google.com/search?q=%s Information om anpassad sökmotor @@ -1945,8 +2023,6 @@ Historier efter ämne Upptäck mer - - Tillhandahålls av Pocket Tillhandahålls av %s. diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index e48e1bb04..1c6087544 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -49,15 +49,12 @@ - உங்கள் முகப்புத் திரையிலிருந்து கமுக்கக் கீற்றுகளைத் திறக்கக் குறுக்குவழியைச் சேர்க்கவும். + உங்கள் முகப்புத் திரையிலிருந்து கமுக்கக் கீற்றுகளைத் திறக்கக் குறுக்குவழியைச் சேர்க்கவும். - குறுக்குவழியைச் சேர்க்கவும் - + குறுக்குவழியைச் சேர்க்கவும் + பரவாயில்லை நன்றி - - - தொடுப்புகள் செயலியில் திறக்கும்படி பயர்பாக்சை அமைக்கவும் அமைவுகளுக்கு செல் @@ -161,8 +158,6 @@ கமுக்க அமர்வுகளில் தேடல் பரிந்துரைகளை அனுமதிக்கவா? நீங்கள் முகவரி பட்டையில் உள்ளிடும் அனைத்தையும் %s உங்கள் இயல்புநிலை தேடுபொறியுடன் பகிர்ந்து கொள்ளும். - - மேலும் அறிய தேடல் @@ -208,6 +203,7 @@ கமுக்க உலாவலில் திரைப்பிடிப்பை அனுமதி கமுக்க உலாவல் குறுக்குவழியைச் சேர்க்கவும் + அணுகுத்திறன் @@ -227,8 +223,6 @@ சைகைகள் தனிப்பயனாக்கு - - உங்கள் பயர்பாக்சு கணக்குடன் புத்தகக்குறிகள், கடவுச்சொற்கள், மற்றும் பலவற்றை ஒத்திசைக்கத் தொடங்குங்கள். பயர்பாக்சு கணக்கு @@ -334,9 +328,6 @@ சந்தைப்படுத்தல் தரவு - - - ஒத்திசைவை இயக்கு மறுஇணைக்க புகுபதியுங்கள் @@ -444,8 +435,6 @@ கீற்றுப் பட்டியைத் திற கீற்றுகளைத் திரட்டில் சேமி - - கீற்றுப் பட்டி திரட்டை நீக்கு @@ -594,7 +583,7 @@ விதிவிலக்குகள் - இயக்கு + இயக்கு அணை @@ -662,13 +651,11 @@ பகிர் சாதனத்திற்கு அனுப்பு - - சமீபத்தில் பாவித்தவை ஒத்திசைக்க உள்நுழை - + அ.சாதனங்களுக்கும் அனுப்பு ஒத்திசைவுக்கு மீண்டும் இணை @@ -705,8 +692,6 @@ கீற்று மூடப்பட்டது கீற்றுகள் மூடப்பட்டன - - சிறந்த தளங்களில் சேர்க்கப்பட்டன! கமுக்கக் கீற்று மூடப்பட்டது @@ -778,8 +763,6 @@ விலகு - - இது உங்கள் உலாவல் தரவு அனைத்தையும் அழிக்கும். தேர்ந்தெடுக்கப்பட்ட உலாவல் தரவை %s செயலி நீக்கும். @@ -791,37 +774,6 @@ உலாவி வரலாற்றை அழிக்கிறது… - - - முன்னோட்ட பயர்பாக்சு இப்போது இராக்கால பயர்பாக்சு - - - ஒவ்வொரு இரவும் இராக்கால பயர்பாக்சு மேம்படுத்தப்பட்டு புதிய அம்சங்களைக் கொண்டு வெளியிடப்படுகிறது. - எப்படியாகினும், நிலைப்புத்தன்மை குறைந்திருக்கலாம். மேலும் நல்ல அனுபவத்திற்கு எங்கள் பீட்டா உலாவியைப் பதிவிறக்கவும். - - பீட்டா ஆண்ட்ராய்டு பயர்பாக்சைப் பெறுக - - - இராக்கால பயர்பாக்சு நகர்ந்தது - - - இனி இச்செயலி பாதுகாப்பு புதுப்பிப்புகளைப் பெறாது. இச்செயலியை பாவிப்பதை நிறுத்திவிட்டு புதிய இராக்கால செயலிக்கு மாறவும். - \n\nஉங்களின் புத்தகக்குறிகள், உள்நுழைவுகள் மற்றும் வரலாற்றை மற்றொரு செயலிக்கு மாற்ற, பயர்பாக்சு கணக்கை உருவாக்கவும். - - புதிய இராக்கால உலாவிக்கு மாறவும் - - - இராக்கால பயர்பாக்சு நகர்ந்தது - - இனி இச்செயலி பாதுகாப்பு புதுப்பிப்புகளைப் பெறாது. இச்செயலியை பாவிப்பதை நிறுத்திவிட்டு புதிய இராக்கால செயலிக்கு மாறவும். - \n\nஉங்களின் புத்தகக்குறிகள், உள்நுழைவுகள் மற்றும் வரலாற்றை மற்றொரு செயலிக்கு மாற்ற, பயர்பாக்சு கணக்கை உருவாக்கவும். - - புதிய இராக்கால உலாவியைப் பெறுங்கள் - - - - %s செயலிக்கு வருக! ஒத்திசைவு இயக்கத்தில் @@ -830,8 +782,6 @@ கண்டிப்பான - - உங்கள் தனியுரிமை எங்கள் தனியுரிமை அறிவிக்கையைப் படிக்க @@ -1103,7 +1053,7 @@ பயன்படுத்த வேண்டிய தேடல் தொடர் - வினவலை “%s” ஆக மாற்றுக. எ.கா:\nhttps://www.google.com/search?q=%s + வினவலை “%s” ஆக மாற்றுக. எ.கா:\nhttps://www.google.com/search?q=%s தனிப்பயன் தேடுபொறி விவரங்கள் @@ -1122,19 +1072,6 @@ %s நீக்கப்பட்டது - - புத்தம் புதிய %s க்கு வருக - - இயங்கலையில் சிறப்பாகச் செயல்பட உங்களுக்கு உதவும் மேம்பட்ட செயல்திறன், அம்சங்களுடன் முற்றிலும் மறுவடிவமைக்கப்பட்ட உலாவி உங்களுக்காகக் காத்திருக்கிறது.\n\n நாங்கள் %s புதுப்பிக்கும் வரை காத்திருங்கள் - - %s புதுப்பிக்கிறது… - - %s தொடங்குக - - பெயர்வு முடிந்தது - - கடவுச்சொற்கள் - அனுமதிக்க: @@ -1154,8 +1091,6 @@ தள விதிவிலக்குகள் இல்லை இந்தப் புத்தகக்குறியை அழிக்க விரும்புகிறீர்களா? - - முதன்மைத் தளங்களில் சேர் சரிபார்த்தது: %1$s @@ -1206,9 +1141,6 @@ திறந்த கீற்றுகள் இல்லை - - - முதன்மை தள வரம்பை அடைந்தது சரி, புரிந்தது diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 7a3eeed26..cf4b7ad9a 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -37,9 +37,6 @@ ఎంచుకున్నారు - - ఇటీవలి ఇష్టాంశాలు - ఇటీవల భద్రపరచినవి @@ -56,10 +53,10 @@ - మీ ముంగిలి తెర నుండి అంతరంగిక ట్యాబులను తెరవడానికి సత్వరమార్గాన్ని చేర్చుకోండి. + మీ ముంగిలి తెర నుండి అంతరంగిక ట్యాబులను తెరవడానికి సత్వరమార్గాన్ని చేర్చుకోండి. - సత్వరమార్గాన్ని చేర్చు - + సత్వరమార్గాన్ని చేర్చు + ఫరవాలేదు వద్దు @@ -92,12 +89,6 @@ అన్నీ చూపించు - - \"%1$s\" కోసం మీ వెతుకులాటలు - - %d సైట్లు తీసివేయి @@ -202,14 +193,6 @@ వెతుకుడు అమరికలు - - - %1$sలో కొత్తవి ఏమిటి - - ఇంతకుముందు మీరు ఆపిన చోటనుండి మొదలుపెట్టడం ఇప్పుడు తేలిక. - - ఇటీవలి వెతుకులాటలు - దాటవేయి @@ -262,6 +245,7 @@ అంతరంగిక విహరణ సత్వరమార్గాన్ని చేర్చు HTTPS-మాత్రమే రీతి + ఇంకా తెలుసుకోండి @@ -290,8 +274,6 @@ సైగలు అభిమతీకరణ - - మీ Firefox ఖాతాతో ఇష్టాంశాలను, సంకేతపదాలను, ఇంకా మరెన్నిటినో సింక్ చేసుకోండి Firefox ఖాతా @@ -301,8 +283,6 @@ డేటా ఎంపికలు - - USB ద్వారా రిమోట్ డీబగ్గింగ్ @@ -438,9 +418,6 @@ అధ్యయనాలను స్థాపించడానికి, నడపడానికి Mozillaకు అనుమతినిస్తుంది - - - సింక్‌ను చేతనించు మళ్ళీ అనుసంధానించడానికి ప్రవేశించండి @@ -626,9 +603,6 @@ %1$s (అంతరంగిక రీతి) - - ఇతర ట్యాబులు - చరిత్రను తొలగించు @@ -801,7 +775,7 @@ మినహాయింపులు - చేతనం + చేతనం అచేతనం @@ -880,9 +854,6 @@ సేకరణ %d - - - పంచుకోండి @@ -894,7 +865,7 @@ ఇటీవల వాడినవి Sync లోనికి ప్రవేశించండి - + పరికరాలన్నిటికీ పంపించు Syncకి మళ్ళీ అనుసంధానమవ్వండి @@ -1012,8 +983,6 @@ నిష్క్రమించు - - ఇది మీ విహరణ డేటా అంతటినీ తొలగించివేస్తుంది. ఈరోజు, నిన్న @@ -1039,13 +1008,8 @@ తొలగించు - - %sకి స్వాగతం! మెరుగైన అంతర్జాలానికి స్వాగతం - - నమోదవ్వండి సింక్ చేతనంగా ఉంది @@ -1054,8 +1018,6 @@ కఠినం పనిముట్లపట్టీ ఎక్కడ ఉండాలో ఎంచుకోండి - - మీ అంతరంగికత మా గోప్యతా నోటీసును చదవండి @@ -1438,7 +1400,7 @@ వాడాల్సిన శోధన పదబంధం - వెతుకుడు పదాన్ని “%s”తో పూరించండి. ఉదాహరణ:\nhttps://www.google.com/search?q=%s + వెతుకుడు పదాన్ని “%s”తో పూరించండి. ఉదాహరణ:\nhttps://www.google.com/search?q=%s అభిమత శోధన యంత్ర వివరాలు @@ -1583,4 +1545,5 @@ అమరికలకు వెళ్ళు + diff --git a/app/src/main/res/values-tg/strings.xml b/app/src/main/res/values-tg/strings.xml index b93726221..0748be384 100644 --- a/app/src/main/res/values-tg/strings.xml +++ b/app/src/main/res/values-tg/strings.xml @@ -67,11 +67,11 @@ - Барои кушодани варақаҳои хусусӣ аз экрани асосӣ миёнбуреро илова кунед. + Барои кушодани варақаҳои хусусӣ аз экрани асосӣ миёнбуреро илова кунед. Варақаи хусусии навбатиро бо як ламс оғоз кунед. - Илова кардани миёнбур + Илова кардани миёнбур Илова кардан ба экрани асосӣ @@ -173,6 +173,8 @@ Истодан Ҷузъҳои иловагӣ + + Маълумот дар бораи ҳисоби корбар Дар ин ҷо ягон ҷузъи иловагӣ нест @@ -262,7 +264,7 @@ Танзимоти ҷустуҷӯ - Ҷустуҷӯ дар ин дафъа: + Ҷустуҷӯ дар ин дафъа: Ҷустуҷӯ дар ин дафъа дар: @@ -291,6 +293,18 @@ Пӯшидан + + + Огоҳиҳо барои кори бештар бо «%s» ба шумо кумак мекунанд + + Варақаҳои худро байни дастгоҳҳо ҳамоҳанг созед, боргириҳоро идора кунед, барои беҳтар танзим кардани муҳофизати махфияти «%s» маслиҳатҳо гиред ва аз чизҳои бештар истифода баред. + + Идома додан + + Ҳоло не + Кушодани варақаи нави %1$s @@ -345,13 +359,21 @@ Маҳдудкунии баннери куки Маҳдуд кардани баннерҳои куки + + Ғайрифаъол + + Фаъол - Браузери «Firefox» кӯшиш мекунад, ки дархостҳои кукиро дар баннерҳои куки ба таври худкор рад кунад. Агар имкони радкунӣ дастнорас аст, «Firefox» метавонад барои қатъ кардани баннер ҳамаи кукиҳоро қабул кунад. + Браузери «Firefox» кӯшиш мекунад, ки дархостҳои кукиро дар баннерҳои куки ба таври худкор рад кунад. Агар имкони радкунӣ дастнорас аст, «Firefox» метавонад барои қатъ кардани баннер ҳамаи кукиҳоро қабул кунад. + + «%1$s» ба таври худкор кушиш мекунад, ки дархостҳои кукиҳоро дар баннерҳои кукиҳо рад кунад. Барои ин сомона хомӯш аст Барои ин сомона фаъол аст + + Ин сомона дар айни замон дастгирӣ намешавад «Маҳдудкунии баннери куки»-ро барои %1$s фаъол месозед? @@ -360,14 +382,53 @@ %1$s кукиҳои ин сомонаро тоза мекунад ва саҳифаро аз нав бор мекунад. Амали тозакунии ҳамаи кукиҳо метавонад шуморо аз сомона хориҷ кунад ва сабадҳои харидории шуморо холӣ намояд. - %1$s метавонад, ки кӯшиш карда, дархостҳои кукиро ба таври худкор рад намояд. Агар имкони радкунӣ дастнорас бошад, %2$s метавонад барои рад кардани баннер ҳамаи кукиҳоро қабул намояд. + %1$s метавонад, ки кӯшиш карда, дархостҳои кукиро ба таври худкор рад намояд. Агар имкони радкунӣ дастнорас бошад, %2$s метавонад барои рад кардани баннер ҳамаи кукиҳоро қабул намояд. + + + «%1$s» метавонад кӯшиш кунад, ки дархостҳои кукиҳоро батаври худкор рад кунад. + + «%1$s» кӯшиш мекунад, ки ҳамаи дархостҳои кукиҳоро дар сомонаҳои дастгиришаванда ба таври худкор рад кунад. + + Баннерҳои куки гум шаванд! + + Ба қадри имкон дархостҳои кукиҳо ба таври худкор рад карда мешаванд. Дар акси ҳол, барои қатъ кардани баннерҳои куки, ҳамаи кукиҳо қабул карда мешаванд. + + Ба қадри имкон, дархостҳои кукиҳоро ба таври худкор рад мекунад. + + Ба «%1$s» иҷозат медиҳед, то он тавонад ба қадри имкон, дархостҳои кукиҳоро ба таври худкор рад кунад? + + Ҳоло не + + Қатъ кардани баннерҳо + + Шумо бояд камтар дархостҳои кукиҳоро бинед + + Камтар дидани равзанаҳои зоҳиршавандаи кукиҳо + + Ба равзанаҳои зоҳиршавандаи куки ба таври худкор ҷавоб медиҳад, то шумо тавонед ба тамошокунии озод аз халалрасонӣ баргардед. «%1$s» ба қадри имкон ҳамаи дархостҳоро рад мекунад ё ба таври дигар ҳамаи дархостҳоро қабул мекунад. + + Ба равзанаҳои зоҳиршавандаи куки ба таври худкор ҷавоб медиҳад, то шумо тавонед ба тамошокунии озод аз халалрасонӣ баргардед. «%1$s» ба қадри имкон ҳамаи дархостҳоро рад мекунад. + + Қатъ кардани равзанаҳои зоҳиршаванда + + Маҳдудкунии баннери куки + + Ба «%1$s» иҷозат медиҳед, ки он ба қадри имкон дархости ризоияти кукии сомонаро рад кунад ё агар имкон набошад, дастрасии кукиҳоро қабул кунад? + + Ба «%1$s» иҷозат медиҳед, ки он ба қадри имкон дархости ризоияти кукии сомонаро рад кунад? + + Иҷозат додан Ба таври худкор кӯшиш мекунад, ки ба сомонаҳо бо истифода аз протоколи рамзгузории HTTPS барои баланд бардоштани амният пайваст шавад. - Фаъол - + Фаъол + Ғайрифаъол + + Фаъол дар ҳамаи варақаҳо + + Фаъол дар варақаҳои хусусӣ Маълумоти бештар @@ -443,6 +504,11 @@ Огоҳиномаҳо + + Иҷозат дода мешавад + + Иҷозат дода намешавад + Маҷмӯаи ҷузъҳои иловагии фармоишӣ @@ -465,8 +531,6 @@ Дидашудаи охирин - - Pocket Ҳикояҳои андешаангез @@ -726,6 +790,13 @@ Пас аз як моҳ пӯшидан + + Кушодан дар саҳифаи асосӣ + + Кушодан дар варақаи охирин + + Кушодан дар саҳифаи асосӣ пас аз чор соат + Варақаҳои куҳнаро ба ғайрифаъол интиқол диҳед @@ -993,10 +1064,16 @@ Истисноҳо - Фаъол + Фаъол Ғайрифаъол + + Стандартӣ + + Ҷиддӣ + + Фармоишӣ Иҷозат додани аудио ва видео @@ -1736,7 +1813,7 @@ Сатри ҷустуҷӯ барои истифода - Сатри дархостро бо “%s” иваз намоед. Масалан:\nhttps://www.google.com/search?q=%s + Сатри дархостро бо “%s” иваз намоед. Масалан:\nhttps://www.google.com/search?q=%s Тафсилот дар бораи низоми ҷустуҷӯии фармоишӣ @@ -1937,8 +2014,6 @@ Ҳикояҳо аз рӯи мавзуъ Бештар омӯзед - - Дар асоси Pocket кор мекунад. Аз ҷониби «%s» таъмин карда шудааст. diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 2596460f8..76294dc22 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -63,11 +63,11 @@ - เพิ่มทางลัดเพื่อเปิดแท็บส่วนตัวจากหน้าจอหลักของคุณ + เพิ่มทางลัดเพื่อเปิดแท็บส่วนตัวจากหน้าจอหลักของคุณ เปิดแท็บส่วนตัวถัดไปโดยแตะเพียงครั้งเดียว - เพิ่มทางลัด + เพิ่มทางลัด เพิ่มไปยังหน้าจอหลัก @@ -169,6 +169,8 @@ หยุด ส่วนเสริม + + ข้อมูลบัญชี ไม่มีส่วนเสริมที่นี่ @@ -258,7 +260,7 @@ ตั้งค่าการค้นหา - ครั้งนี้ค้นหา: + ครั้งนี้ค้นหา: ครั้งนี้ค้นหาใน: @@ -287,6 +289,18 @@ ปิด + + + การแจ้งเตือนช่วยให้คุณทำสิ่งต่างๆ ได้มากขึ้นด้วย %s + + ซิงค์แท็บของคุณระหว่างอุปกรณ์ต่างๆ จัดการการดาวน์โหลด รับคำแนะนำเกี่ยวกับการใช้ประโยชน์สูงสุดจากการปกป้องความเป็นส่วนตัวของ %s และอื่นๆ + + ดำเนินการต่อ + + ไม่ใช่ตอนนี้ + เปิดแท็บ %1$s ใหม่ @@ -342,14 +356,22 @@ การลดคุกกี้แบนเนอร์ ลดคุกกี้แบนเนอร์ + + ปิด + + เปิด - Firefox จะพยายามปฏิเสธคำขอคุกกี้บนแบนเนอร์คุกกี้โดยอัตโนมัติ หากไม่มีตัวเลือกปฏิเสธ Firefox อาจยอมรับคุกกี้ทั้งหมดเพื่อปิดแบนเนอร์ + Firefox จะพยายามปฏิเสธคำขอคุกกี้บนแบนเนอร์คุกกี้โดยอัตโนมัติ หากไม่มีตัวเลือกปฏิเสธ Firefox อาจยอมรับคุกกี้ทั้งหมดเพื่อปิดแบนเนอร์ + + %1$s จะพยายามปฏิเสธคำขอคุกกี้บนแบนเนอร์คุกกี้โดยอัตโนมัติ ปิดสำหรับไซต์นี้ เปิดสำหรับไซต์นี้ + + ไม่รองรับไซต์ในขณะนี้ ต้องการเปิดการลดแบนเนอร์คุกกี้สำหรับ %1$s หรือไม่? @@ -357,14 +379,54 @@ %1$s จะล้างคุกกี้ของไซต์นี้และรีเฟรชหน้า การล้างคุกกี้ทั้งหมดอาจนำคุณออกจากระบบหรือล้างรถเข็นช็อปปิ้ง - %1$s สามารถพยายามปฏิเสธคำขอคุกกี้โดยอัตโนมัติได้ หากไม่มีตัวเลือกปฏิเสธ %2$s อาจยอมรับคุกกี้ทั้งหมดเพื่อปิดแบนเนอร์ + %1$s สามารถพยายามปฏิเสธคำขอคุกกี้โดยอัตโนมัติได้ หากไม่มีตัวเลือกปฏิเสธ %2$s อาจยอมรับคุกกี้ทั้งหมดเพื่อปิดแบนเนอร์ + + + %1$s สามารถพยายามปฏิเสธคำขอคุกกี้โดยอัตโนมัติได้ + + %1$s จะพยายามปฏิเสธคำขอคุกกี้ทั้งหมดบนไซต์ที่รองรับโดยอัตโนมัติ + + เอาแบนเนอร์คุกกี้ออกไปให้พ้น! + + ปฏิเสธคำขอคุกกี้โดยอัตโนมัติเมื่อเป็นไปได้ หรือไม่ก็ยอมรับคุกกี้ทั้งหมดเพื่อปิดแบนเนอร์คุกกี้ + + ปฏิเสธคำขอคุกกี้โดยอัตโนมัติเมื่อเป็นไปได้ + + อนุญาตให้ %1$s ปฏิเสธคำขอคุกกี้โดยอัตโนมัติเมื่อเป็นไปได้หรือไม่? + + ไม่ใช่ตอนนี้ + + ปิดแบนเนอร์ + + + คุณจะเห็นคำขอคุกกี้น้อยลง + + เห็นป๊อปอัปคุกกี้น้อยลง + + ตอบป๊อปอัปคุกกี้โดยอัตโนมัติเพื่อให้คุณท่องเว็บโดยปราศจากสิ่งรบกวน %1$s จะปฏิเสธคำขอทั้งหมดเมื่อเป็นไปได้ หรือยอมรับทั้งหมดเมื่อเป็นไปไม่ได้ + + ตอบป๊อปอัปคุกกี้โดยอัตโนมัติเพื่อให้คุณท่องเว็บโดยปราศจากสิ่งรบกวน %1$s จะปฏิเสธคำขอทั้งหมดเมื่อเป็นไปได้ + + ปิดป๊อปอัป + + การลดแบนเนอร์คุกกี้ + + อนุญาตให้ %1$s ปฏิเสธคำขอยินยอมคุกกี้ของไซต์เมื่อเป็นไปได้ หรือยอมรับการเข้าถึงคุกกี้เมื่อเป็นไปไม่ได้หรือไม่? + + อนุญาตให้ %1$s ปฏิเสธคำขอยินยอมคุกกี้ของไซต์เมื่อเป็นไปได้หรือไม่? + + อนุญาต พยายามเชื่อมต่อกับเว็บไซต์โดยใช้โปรโตคอลการเข้ารหัส HTTPS โดยอัตโนมัติเพื่อเพิ่มความปลอดภัย - เปิด - + เปิด + ปิด + + เปิดในทุกแท็บ + + เปิดในแท็บส่วนตัว เรียนรู้เพิ่มเติม @@ -442,6 +504,11 @@ การแจ้งเตือน + + อนุญาต + + ไม่อนุญาต + ชุดสะสมส่วนเสริมที่กำหนดเอง @@ -464,8 +531,6 @@ เยี่ยมชมล่าสุด - - Pocket เรื่องราวที่จุดประกายความคิด @@ -723,6 +788,13 @@ ปิดหลังจากหนึ่งเดือน + + เปิดในหน้าแรก + + เปิดบนแท็บสุดท้าย + + เปิดหน้าแรกหลังจากสี่ชั่วโมง + ย้ายแท็บเก่าไปยังส่วนที่ไม่ได้ใช้งาน @@ -988,9 +1060,15 @@ ข้อยกเว้น - เปิด + เปิด ปิด + + มาตรฐาน + + เข้มงวด + + กำหนดเอง อนุญาตเสียงและวิดีโอ @@ -1729,7 +1807,7 @@ สตริงการค้นหาที่จะใช้ - แทนที่คำค้นด้วย “%s” ตัวอย่าง:\nhttps://www.google.com/search?q=%s + แทนที่คำค้นด้วย “%s” ตัวอย่าง:\nhttps://www.google.com/search?q=%s รายละเอียดเครื่องมือค้นหาที่กำหนดเอง @@ -1798,9 +1876,9 @@ ช่องข้อความที่แก้ไขได้สำหรับที่อยู่เว็บของการเข้าสู่ระบบ - + ช่องข้อความที่แก้ไขได้สำหรับชื่อผู้ใช้ของการเข้าสู่ระบบ - + ช่องข้อความที่แก้ไขได้สำหรับรหัสผ่านของการเข้าสู่ระบบ บันทึกการเปลี่ยนแปลงเพื่อเข้าสู่ระบบ @@ -1930,8 +2008,6 @@ เรื่องตามหัวข้อ ค้นพบสิ่งอื่น - - ขับเคลื่อนโดย Pocket ขับเคลื่อนโดย %s diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 7bca7ec46..327d09e24 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -66,11 +66,11 @@ - Ana ekranınızdan gizli sekme açmak için kısayol ekleyebilirsiniz. + Ana ekranınızdan gizli sekme açmak için kısayol ekleyebilirsiniz. Bir sonraki gizli sekmenizi tek dokunuşla açın. - Kısayol ekle + Kısayol ekle Ana ekrana ekle @@ -171,6 +171,8 @@ Durdur Eklentiler + + Hesap bilgileri Hiç eklenti yok @@ -261,7 +263,7 @@ Arama ayarları - Bununla ara: + Bununla ara: Bununla ara: @@ -290,6 +292,18 @@ Kapat + + + Bildirimler sayesinde %s ile daha fazlasını yapın + + Sekmelerinizi cihazlar arasında senkronize edin, indirmeleri yönetin, %s tarayıcınızın gizlilik korumasına dair ipuçları alın ve daha fazlasını yapın. + + Devam et + + Daha sonra + Yeni %1$s sekmesi aç @@ -341,31 +355,78 @@ Yalnızca HTTPS modu - Çerez duyurularını azalt + Çerez bildirimlerini azalt - Çerez duyurularını azalt + Çerez bildirimlerini azalt + + Kapalı + + Açık - Firefox, çerez duyurularındaki çerez isteklerini otomatik olarak reddetmeye çalışır. Reddetme seçeneği mevcut değilse Firefox, duyuruyu kapatmak için tüm çerezleri kabul edebilir. + Firefox, çerez bildirimlerindeki çerez isteklerini otomatik olarak reddetmeye çalışır. Reddetme seçeneği yoksa Firefox, bildirimi kapatmak için tüm çerezleri kabul edebilir. + + %1$s, çerez bildirimlerindeki çerez isteklerini otomatik olarak reddetmeye çalışır. Bu sitede kapalı Bu sitede açık + + Bu site şu anda desteklenmiyor - %1$s için çerez duyurularını azaltma açılsın mı? + %1$s için çerez bildirimlerini azaltma açılsın mı? - %1$s için çerez duyurularını azaltma kapatılsın mı? + %1$s için çerez bildirimlerini azaltma kapatılsın mı? %1$s bu sitenin çerezlerini temizleyip sayfayı tazeleyecek. Tüm çerezlerin temizlenmesi oturumunuzu kapatabilir veya alışveriş sepetlerinizi boşaltabilir. - %1$s, çerez duyurularındaki çerez isteklerini otomatik olarak reddetmeye çalışır. Reddetme seçeneği mevcut değilse %2$s, duyuruyu kapatmak için tüm çerezleri kabul edebilir. + %1$s, çerez bildirimlerindeki çerez isteklerini otomatik olarak reddetmeye çalışır. Reddetme seçeneği yoksa %2$s, bildirimi kapatmak için tüm çerezleri kabul edebilir. + + + %1$s çerez isteklerini otomatik olarak reddetmeyi deneyebilir. + + %1$s, desteklenen sitelerdeki tüm çerez isteklerini otomatik olarak reddetmeye çalışır. + + Çerez bildirimlerine son! + + Mümkün olduğunda çerez isteklerini otomatik olarak reddedin, mümkün değilse çerez bildirimlerini kapatmak için tüm çerezleri kabul edin. + + Mümkün olduğunda çerez isteklerini otomatik olarak reddedin. + + Mümkün olduğunda %1$s çerez isteklerini otomatik olarak reddetsin mi? + + Daha sonra + + Bildirimleri kapat + + Daha az çerez isteği göreceksiniz + + Daha az çerez bildirimi görün + + Dikkat dağıtan çerez bildirimlerini otomatik olarak kapatın. %1$s mümkünse tüm istekleri reddedecek, mümkün değilse kabul edecektir. + + Dikkat dağıtan çerez bildirimlerini otomatik olarak kapatın. %1$s mümkünse tüm istekleri reddedecektir. + + Bildirimleri kapat + + Çerez bildirimlerini azaltın + + %1$s mümkün olduğunda sitelerin çerez onayı taleplerini reddetsin, mümkün olmadığında çerezlere izin versin mi? + + %1$s sitelerin çerez isteklerini reddedebilsin mi? + + İzin ver Daha fazla güvenlik için sitelere otomatik olarak HTTPS şifreleme protokolüyle bağlanmaya çalışır. - Açık - + Açık + Kapalı + + Tüm sekmelerde açık + + Gizli sekmelerde açık Daha fazla bilgi al @@ -444,6 +505,11 @@ Bildirimler + + İzin verildi + + İzin verilmedi + Özel eklenti koleksiyonu @@ -466,8 +532,6 @@ Son bakılanlar - - Pocket Merak uyandıran makaleler @@ -725,6 +789,13 @@ Bir ay sonra kapat + + Giriş sayfasını aç + + Son sekmeyi aç + + Dört saat sonra giriş sayfasını aç + Eski sekmeleri pasife taşı @@ -990,10 +1061,16 @@ İstisnalar - Açık + Açık Kapalı + + Standart + + Sıkı + + Özel Ses ve videoya izin ver @@ -1731,7 +1808,7 @@ Kullanılacak arama dizgisi - Sorguyu “%s” ile değiştirin. Örnek:\nhttps://www.google.com/search?q=%s + Sorguyu “%s” ile değiştirin. Örnek:\nhttps://www.google.com/search?q=%s Özel arama motoru ayrıntıları @@ -1931,8 +2008,6 @@ Konuya göre makaleler Daha fazlasını keşfedin - - Pocket desteğiyle. %s desteğiyle. diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index c3ed88e1e..0d9c1bcbd 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -65,11 +65,11 @@ - Додайте ярлик для відкриття приватних вкладок з головного екрана. + Додайте ярлик для відкриття приватних вкладок з головного екрана. Запускайте наступну приватну вкладку одним торканням. - Додати ярлик + Додати ярлик Додати на головний екран @@ -170,6 +170,8 @@ Зупинити Додатки + + Інформація про обліковий запис Немає додатків @@ -262,7 +264,7 @@ Налаштування пошуку - Шукати за допомогою: + Шукати за допомогою: Шукати в: @@ -291,6 +293,18 @@ Закрити + + + Сповіщення допомагають вам ефективніше взаємодіяти з %s + + Синхронізуйте свої вкладки між пристроями, керуйте завантаженнями, отримуйте поради про захист приватності в %s, а також інші можливості. + + Продовжити + + Не зараз + Відкрити нову вкладку %1$s @@ -346,13 +360,21 @@ Зменшення кількості банерів кук Зменшити кількість банерів кук + + Вимкнено + + Увімкнено - Firefox автоматично намагається відхилити банери запитів на розміщення кук. Якщо параметр відхилення недоступний, Firefox може погодитися розмістити всі куки, щоб закрити банер. + Firefox автоматично намагається відхилити банери запитів на розміщення кук. Якщо параметр відхилення недоступний, Firefox може погодитися розмістити всі куки, щоб закрити банер. + + %1$s намагається автоматично відхиляти запити банерів кук. Вимкнено для цього сайту Увімкнено для цього сайту + + Сайт наразі не підтримується Увімкнути зменшення кількості банерів кук для %1$s? @@ -360,14 +382,53 @@ %1$s очистить куки цього сайту та оновить сторінку. Очищення всіх кук може призвести до виходу з облікових записів або спорожнення кошика для покупок. - %1$s може спробувати автоматично відхилити запити на розміщення кук. Якщо опція відхилення недоступна, %2$s може погодитися на всі куки, щоб закрити банер. + %1$s може спробувати автоматично відхилити запити на розміщення кук. Якщо опція відхилення недоступна, %2$s може погодитися на всі куки, щоб закрити банер. + + + %1$s може намагатися автоматично відхиляти запити на збереження кук. + + %1$s намагається автоматично відхиляти всі запити кук на підтримуваних сайтах. + + Геть банери про куки! + + Автоматично відхиляйте запити на збереження кук, коли це можливо. В іншому випадку, схвалюйте всі куки, щоб уникнути показу банерів про збереження кук. + + Автоматично відхиляти запити кук, коли можливо. + + Дозволити %1$s автоматично відхиляти запити на збереження кук, коли це можливо? + + Не зараз + + Відхилити банери + + Ви бачитимете менше запитів на збереження кук + + Менше спливних повідомлень про збереження кук + + Автоматично відповідайте на спливні запити про збереження кук, щоб не відриватися від роботи. %1$s відхилятиме або схвалюватиме всі можливі запити. + + Автоматично відповідайте на спливні запити про збереження кук, щоб не відриватися від роботи. %1$s відхилятиме всі можливі запити. + + Відхилити спливні запити + + Зменшення кількості банерів кук + + Дозволити %1$s відхиляти запити із погодженням на збереження кук сайтів, якщо це можливо, або схвалювати запити, якщо відхилити неможливо? + + Дозволити %1$s відхиляти запити сайтів на згоду про збереження кук, коли це можливо? + + Дозволити Намагатися автоматично доступатися до сайтів за допомогою протоколу шифрування HTTPS для поліпшення безпеки. - Увімкнено - + Увімкнено + Вимкнено + + Увімкнути в усіх вкладках + + Увімкнути у приватних вкладках Докладніше @@ -448,6 +509,11 @@ Сповіщення + + Дозволено + + Не дозволено + Власна збірка додатків @@ -470,8 +536,6 @@ Недавно відвідані - - Pocket Розповіді, що спонукають замислитися @@ -730,6 +794,13 @@ Закрити через місяць + + Відкрити домівку + + Відкрити останню вкладку + + Відкрити домівку через 4 години + Переміщувати старі вкладки в неактивні @@ -996,9 +1067,15 @@ Винятки - Увімкнено + Увімкнено Вимкнено + + Звичайний + + Надійний + + Власний Дозволити аудіо та відео @@ -1741,7 +1818,7 @@ Запит для пошуку - Змініть запит на “%s”. Зразок:\nhttps://www.google.com/search?q=%s + Змініть запит на “%s”. Зразок:\nhttps://www.google.com/search?q=%s Подробиці власного засобу пошуку @@ -1942,8 +2019,6 @@ Розповіді за темами Знайти більше - - Надано Pocket. Від %s. diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 771257c15..379dcf0e1 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -37,14 +37,6 @@ منتخب شدہ - - - حالیہ بُک مارکس - - حالیہ محفوظ شدہ بک مارک - - تمام دکھائیں - تمام محفوظ کردہ بک مارکس دکھائیں۔ @@ -55,10 +47,10 @@ - اپنے ہوم اسکرین سے نجی ٹیب کھولنے کے لئے ایک شارٹ کٹ جوڑیں۔ + اپنے ہوم اسکرین سے نجی ٹیب کھولنے کے لئے ایک شارٹ کٹ جوڑیں۔ - شارٹ کٹ شامل کریں - + شارٹ کٹ شامل کریں + نہیں شکریہ @@ -203,8 +195,6 @@ نجی سیشنوں میں تلاش کی تجاویز کی اجازت دیں؟ %s آپ کے ذریعہ پتہ بار میں ٹائپ کی گئی سبھی چیزوں کو آپ کے طے شدہ تلاش انجن کے ساتھ شیئر کرے گا - - مزید سیکھیں %s تلاش کریں @@ -212,11 +202,6 @@ ایڈریس بار سے براہ راست تلاش کریں - - صاف، منظم ٹیبز - - حالیہ تلاشیں۔ - تلاش کریں @@ -261,6 +246,7 @@ اگر اجازت دی جائے تو ، جب ایک سے زیادہ اطلاقات کھلے ہیں تو نجی ٹیبز بھی نظر آئیں گے نجی براؤزنگ شارٹکٹ شامل کریں + رسائی پزیری @@ -281,8 +267,6 @@ اشارے تخصیص کریں - - اپنے Firefox Account کے ساتھ بک مارکس ، سابقات اور بہت کچھ sync کریں Firefox اکاؤنٹ @@ -309,8 +293,6 @@ براؤزنگ کی تاریخ تلاش کریں بک مارک تلاش کریں - - اکاؤنٹ کی سیٹنگز @@ -344,8 +326,6 @@ حال ہی میں ملاحظہ کی گئی - - Pocket وال پیپرز @@ -433,9 +413,6 @@ Mozilla کو مطالعے انسٹال اور چلانے کی اجازت دیتا ہے - - - سینک آن کریں دوبارہ جڑنے کے لیئے سائن ان کریں @@ -623,8 +600,6 @@ ٹیبز کا مینو کھولیں ٹیبز کو مجموعہ میں محفوظ کریں - - ٹیب مینو مجموعہ حذف کریں @@ -644,9 +619,6 @@ %1$s (نجی موڈ) - - دیگر ٹیبز - سابقات حذف کریں @@ -801,7 +773,7 @@ استثنيات - چالو + چالو بند @@ -886,11 +858,9 @@ تمام اعمال حال ہی میں استعمال کی گئی - - سنک کرنے کے لئے سائن ان کریں Sync کے لئے سائن ان کریں - + ‏تمام آلات پر ارسال کریں Sync سے دوبارہ رابطہ کریں @@ -936,8 +906,6 @@ ٹیبز بند ہوگئیں بکمارک محفوظ کر دیا گیا! - - سر فہرست سائٹوں میں شامل! نجی ٹیب بند ہوگئیں @@ -1011,8 +979,6 @@ بند کریں - - یہ آپ کی براؤزنگ کے سبھی کوائف کو حذف کر دے گا۔ %s منتخب شدہ براؤزنگ کے کوائف کو حذف کر دے گا۔ @@ -1025,37 +991,8 @@ براؤزنگ کا ڈیٹا حذف ہو رہا ہے… - - - Firefox Preview اب Firefox Nightly ہو گیا ہے - - - Android Beta کے لئے Firefox حاصل کریں - - - Firefox Nightly منتقل ہوگیا - - - نیا Nightly میں سوئچ کریں - - - Firefox Nightly منتقل ہوگیا - - - نیا Nightly حاصل کریں - - - - %s میں خوش آمدید! - - آلات کے درمیان Firefox کو سنک کریں - - سائن اپ کریں Sync چالو ہے - - ہمیشہ پرائیویسی پر معیاری (پہلے سے طے شدہ) @@ -1063,9 +1000,6 @@ اپنے ٹول بار کی جگہ کا انتخاب کریں - - آپ کی رازداری - ہماری رازداری نوٹس پڑھیں @@ -1349,6 +1283,7 @@ کریڈٹ کارڈ شامل کریں محفوظ شدہ کریڈٹ کارڈز منظم کریں + کارڈ شامل کریں @@ -1436,17 +1371,6 @@ حذف شدہ %s - - بالکل نئی %s میں خوش آمدید - - %s تازہ کارى کر رہا ہے… - - %s شروع کریں - - منتقلی مکمل ہو گی - - پاس ورڈ - اس کی اجازت دینے کے لئے: @@ -1473,8 +1397,6 @@ کوئی سائٹ استثنات نہیں ہے کیا آپ واقعی اس بُکمارک کو حذف کرنا چاہتے ہیں؟ - - بہترین سائٹ میں شامل کریں توثیق کردہ برائے: %1$s @@ -1535,16 +1457,11 @@ کوئی کھلے ٹیب نہیں - - - اعلٰی سائٹ کی حد پوری ہو گئی ٹھیک ہے سمجھ گیا نام - - بہترین سائٹس کے نام ٹھیک ہے diff --git a/app/src/main/res/values-uz/strings.xml b/app/src/main/res/values-uz/strings.xml index 141e2ae56..e8fd1956d 100644 --- a/app/src/main/res/values-uz/strings.xml +++ b/app/src/main/res/values-uz/strings.xml @@ -63,10 +63,14 @@ - Bosh ekrandan maxfiy varaqlarni ochish uchun tezkor buyruq qoʻshing. + Bosh ekrandan maxfiy varaqlarni ochish uchun tezkor buyruq qoʻshing. + + Bir harakatda keyingi maxfiy varaqni oching. - Tezkor buyruq qoʻshish - + Tezkor buyruq qoʻshish + + Bosh ekranga qoʻshish + Kerak emas @@ -255,7 +259,7 @@ Izlash sozlamalari - Bu safar qidiramiz: + Bu safar qidiramiz: Bu safar quyidagi bilan qidiramiz: @@ -283,6 +287,11 @@ Yopish + + Davom etish + + Hozir emas + Yangi %1$s ta varaqni ochish @@ -338,13 +347,18 @@ Cookie bannerlarini kamaytirish - Firefox avtomatik ravishda cookie bannerlarida cookie soʻrovlarini rad etishga harakat qiladi. Agar rad etish tanlovi mavjud boʻlmasa, Firefox bannerni oʻchirish uchun barcha cookie fayllarni qabul qilishi mumkin. + Firefox avtomatik ravishda cookie bannerlarida cookie soʻrovlarini rad etishga harakat qiladi. Agar rad etish tanlovi mavjud boʻlmasa, Firefox bannerni oʻchirish uchun barcha cookie fayllarni qabul qilishi mumkin. + + + Bu sayt uchun oʻchirilgan + + Bu sayt uchun yoniq Xavfsizlikni oshirish uchun HTTPS shifrlash protokoli yordamida saytlarga avtomatik ulanishga harakat qiladi. - Yoniq - + Yoniq + Oʻchiq Batafsil maʼlumot @@ -445,8 +459,6 @@ Oxirgi ochilgan - - Pocket Oʻylantiruvchi hikoyalar @@ -976,7 +988,7 @@ Istisnolar - Yoniq + Yoniq Oʻchiq @@ -1074,8 +1086,6 @@ Vaqtinchalik xotiraga nusxalash Vaqtinchalik xotiraga nusxalalandi - - Sinxronlash uchun hisobingizga kiring Sinxronlash uchun hisobingizga kiring @@ -1709,7 +1719,7 @@ Foydalanish uchun qidiruv qatori - Soʻrovni “%s” bilan almashtiring. Masalan:\nhttps://www.google.com/search?q=%s + Soʻrovni “%s” bilan almashtiring. Masalan:\nhttps://www.google.com/search?q=%s Maxsus qidiruv tizimining tafsilotlari @@ -1880,6 +1890,10 @@ Avtomatik yoqish yoniq + + + Firefox Suggest + Saytlar, elektron pochta va xabarlar havolalarini Firefoxda avtomatik ravishda ochiladigan qilib sozlang. @@ -1902,8 +1916,6 @@ Mavzu boʻyicha hikoyalar Koʻproq bilib oling - - Pocket tomonidan quvvatlanadi. %s tomonidan quvvatlanadi. @@ -1917,11 +1929,7 @@ Maʼlumotlarni yuborish uchun telemetriyani yoqing. Sozlamalarni ochish - Firefox Suggest - - - yigʻish diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 24289f7ee..4293df685 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -66,11 +66,11 @@ - Thêm lối tắt để mở các thẻ riêng tư từ màn hình chính của bạn. + Thêm lối tắt để mở các thẻ riêng tư từ màn hình chính của bạn. Khởi chạy thẻ riêng tư tiếp theo chỉ bằng một lần nhấn. - Thêm lối tắt + Thêm lối tắt Thêm vào màn hình chính @@ -171,6 +171,8 @@ Dừng Tiện ích + + Thông tin tài khoản Không có tiện ích nào ở đây @@ -259,7 +261,7 @@ Cài đặt tìm kiếm - Lần này tìm kiếm: + Lần này tìm kiếm: Lần này tìm kiếm trong: @@ -288,6 +290,18 @@ Đóng + + + Thông báo giúp bạn làm được nhiều việc hơn với %s + + Đồng bộ hóa các thẻ của bạn giữa các thiết bị, quản lý tải xuống, nhận các mẹo về cách tận dụng tối đa khả năng bảo vệ quyền riêng tư của %s và nhiều hơn nữa. + + Tiếp tục + + Không phải bây giờ + Mở thẻ %1$s mới @@ -342,13 +356,21 @@ Giảm biểu ngữ cookie Giảm biểu ngữ cookie + + Tắt + + Bật - Firefox tự động cố gắng từ chối yêu cầu cookie trên biểu ngữ cookie. Nếu không có tùy chọn từ chối, Firefox có thể chấp nhận tất cả cookie để loại bỏ biểu ngữ. + Firefox tự động cố gắng từ chối yêu cầu cookie trên biểu ngữ cookie. Nếu không có tùy chọn từ chối, Firefox có thể chấp nhận tất cả cookie để loại bỏ biểu ngữ. + + %1$s tự động cố gắng từ chối yêu cầu cookie trên biểu ngữ cookie. Tắt cho trang web này Bật cho trang web này + + Trang web hiện không được hỗ trợ Bật giảm biểu ngữ cookie cho %1$s? @@ -356,14 +378,53 @@ %1$s sẽ xóa cookie của trang web này và làm mới trang. Xóa tất cả cookie có thể khiến bạn đăng xuất hoặc làm trống giỏ hàng. - %1$s có thể thử tự động từ chối yêu cầu cookie. Nếu không có tùy chọn từ chối, %2$s có thể chấp nhận tất cả cookie để loại bỏ biểu ngữ. + %1$s có thể thử tự động từ chối yêu cầu cookie. Nếu không có tùy chọn từ chối, %2$s có thể chấp nhận tất cả cookie để loại bỏ biểu ngữ. + + + %1$s có thể cố gắng tự động từ chối yêu cầu cookie. + + %1$s thử tự động từ chối tất cả các yêu cầu cookie trên các trang web được hỗ trợ. + + Biểu ngữ cookie sẽ biến mất! + + Tự động từ chối các yêu cầu cookie khi có thể. Nếu không, chấp nhận tất cả cookie để loại bỏ biểu ngữ cookie. + + Tự động từ chối các yêu cầu cookie khi có thể. + + Cho phép %1$s tự động từ chối yêu cầu cookie khi có thể? + + Không phải bây giờ + + Loại bỏ biểu ngữ + + Bạn sẽ thấy ít yêu cầu cookie hơn + + Xem ít cửa sổ bật lên về cookie hơn + + Tự động trả lời các cửa sổ bật lên cookie để duyệt web không bị phân tâm. %1$s sẽ từ chối tất cả các yêu cầu nếu có thể hoặc chấp nhận tất cả nếu không. + + Tự động trả lời các cửa sổ bật lên cookie để duyệt web không bị phân tâm. %1$s sẽ từ chối tất cả các yêu cầu nếu có thể. + + Loại bỏ cửa sổ bật lên + + Giảm biểu ngữ cookie + + Cho phép %1$s từ chối yêu cầu chấp thuận cookie của trang web nếu có thể hoặc chấp nhận quyền truy cập cookie khi không thể? + + Cho phép %1$s từ chối yêu cầu chấp thuận cookie của một trang web nếu có thể? + + Cho phép Tự động cố gắng kết nối với các trang web bằng giao thức mã hóa HTTPS để tăng cường bảo mật. - Bật - + Bật + Tắt + + Bật trong tất cả các thẻ + + Bật trong các thẻ riêng tư Tìm hiểu thêm @@ -441,6 +502,11 @@ Thông báo + + Đã cho phép + + Không cho phép + Bộ sưu tập tiện ích tùy chỉnh @@ -463,8 +529,6 @@ Đã xem gần đây - - Pocket Những câu chuyện kích động tư tưởng @@ -720,6 +784,13 @@ Đóng sau một tháng + + Mở trên trang chủ + + Mở trên thẻ cuối cùng + + Mở trên trang chủ sau bốn giờ + Chuyển các thẻ cũ sang không hoạt động @@ -984,9 +1055,15 @@ Ngoại trừ - Bật + Bật Tắt + + Tiêu chuẩn + + Nghiêm ngặt + + Tùy chỉnh Cho phép âm thanh và video @@ -1718,7 +1795,7 @@ Chuỗi tìm kiếm để sử dụng - Thay thế chuỗi truy vấn thành “%s”. Ví dụ:\nhttps://www.google.com/search?q=%s + Thay thế chuỗi truy vấn thành “%s”. Ví dụ:\nhttps://www.google.com/search?q=%s Chi tiết công cụ tìm kiếm tùy chỉnh @@ -1918,8 +1995,6 @@ Các câu chuyện theo chủ đề Khám phá thêm nữa - - Được cung cấp bởi Pocket. Được cung cấp bởi %s. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 02678c9be..e57ac88e5 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -68,11 +68,11 @@ - 添加快捷方式,即可由主屏幕直接打开隐私标签页。 + 添加快捷方式,即可由主屏幕直接打开隐私标签页。 一步进入隐私标签页。 - 添加快捷方式 + 添加快捷方式 添加到主屏幕 @@ -174,6 +174,8 @@ 停止 附加组件 + + 账户信息 这里没有附加组件 @@ -268,7 +270,7 @@ 搜索设置 - 这次搜索: + 这次搜索: 此次搜索: @@ -297,6 +299,18 @@ 关闭 + + + 允许通知可以让 %s 更贴心好用 + + 在设备间同步标签页、管理下载、了解充分利用 %s 来保护隐私的窍门,还有更多实用功能。 + + 继续 + + 暂时不要 + 新建 %1$s 标签页 @@ -352,13 +366,21 @@ 减少 Cookie 横幅 减少 Cookie 横幅 + + + + - Firefox 会自动尝试点击 Cookie 横幅上的“拒绝”按钮。若网站未提供拒绝选项,则可能会接受所有 Cookie 以关闭横幅。 + Firefox 会自动尝试点击 Cookie 横幅上的“拒绝”按钮。若网站未提供拒绝选项,则可能会接受所有 Cookie 以关闭横幅。 + + %1$s 会尝试自动拒绝 Cookie 横幅的 Cookie 请求。 在该网站关闭 在该网站开启 + + 不支持该网站 要为 %1$s 开启“减少 Cookie 横幅”吗? @@ -367,14 +389,53 @@ %1$s 将清除此网站的 Cookie 并刷新页面。清除 Cookie 可能会导致您退出登录,或清空购物车。 - %1$s 会自动尝试拒绝 Cookie 请求。若网站未提供拒绝选项,%2$s 可能会接受所有 Cookie 以关闭横幅。 + %1$s 会自动尝试拒绝 Cookie 请求。若网站未提供拒绝选项,%2$s 可能会接受所有 Cookie 以关闭横幅。 + + + %1$s 会尝试自动拒绝 Cookie 请求。 + + %1$s 会尝试在支持的网站上尽可能拒绝所有 Cookie 请求。 + + Cookie 横幅,消失不见! + + 尽可能自动拒绝 Cookie 请求,如果无法拒绝则接受所有 Cookie 以关闭 Cookie 横幅。 + + 尽可能自动拒绝 Cookie 请求。 + + 要允许 %1$s 尽可能自动拒绝 Cookie 请求吗? + + 暂时不要 + + 关闭横幅 + + 您看到的 Cookie 请求会减少 + + 减少 Cookie 弹窗 + + 自动回应 Cookie 弹窗,实现无干扰浏览。%1$s 将尽可能拒绝所有请求,如果无法拒绝则接受所有请求。 + + 自动回应 Cookie 弹窗,实现无干扰浏览。%1$s 将尽可能拒绝所有请求。 + + 关闭弹窗 + + 减少 Cookie 横幅 + + 要允许 %1$s 尽可能拒绝网站的 Cookie 请求,并在无法拒绝时接受 Cookie 请求吗? + + 要允许 %1$s 尽可能拒绝网站的 Cookie 请求吗? + + 允许 自动尝试使用 HTTPS 加密协议连接至网站,增强安全性。 - 开启 - + 开启 + 关闭 + + 在所有标签页启用 + + 仅在隐私标签页启用 详细了解 @@ -453,6 +514,11 @@ 通知 + + 允许 + + 不允许 + 自定义附加组件收藏集 @@ -475,8 +541,6 @@ 最近访问 - - Pocket 精选文章 @@ -732,7 +796,7 @@ 最后打开的标签页 - 四小时未使用即回到主页 + 四小时未使用则回到主页 手动关闭 @@ -742,6 +806,13 @@ 1 个月后关闭 + + 打开主页 + + 打开最近的标签页 + + 闲置四小时后打开主页 + 将旧标签页切换至休眠状态 @@ -1014,10 +1085,16 @@ 例外 - 开启 + 开启 关闭 + + 标准 + + 严格 + + 自定义 允许音频和视频 @@ -1777,7 +1854,7 @@ 搜索字符串 - 用“%s”替换查询关键字。示例:\nhttps://www.google.com/search?q=%s + 用“%s”替换查询关键字。示例:\nhttps://www.google.com/search?q=%s 自定义搜索引擎信息 @@ -1977,8 +2054,6 @@ 热门主题 探索更多 - - 由 Pocket 提供 由 %s 提供。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5ecdd7b2f..7520a39ca 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -67,11 +67,11 @@ - 加入捷徑,從裝置主畫面直接開啟隱私瀏覽分頁。 + 加入捷徑,從裝置主畫面直接開啟隱私瀏覽分頁。 只要輕鬆一點,即可開啟新的隱私保護分頁。 - 新增捷徑 + 新增捷徑 新增至裝置主畫面 @@ -172,6 +172,8 @@ 停止 附加元件 + + 帳號資訊 無附加元件 @@ -264,7 +266,7 @@ 搜尋設定 - 這次搜尋使用: + 這次搜尋使用: 這次搜尋: @@ -293,6 +295,18 @@ 關閉 + + + 透過通知,可幫助您使用 %s 做到更多事 + + 在不同裝置間同步分頁、管理下載資料、獲得能讓 %s 的隱私權保護功能發揮到極致的使用秘訣,與更多資訊。 + + 繼續 + + 現在不要 + 開啟新 %1$s 分頁 @@ -348,13 +362,21 @@ 減少 Cookie 橫幅 減少 Cookie 橫幅 + + 關閉 + + 開啟 - Firefox 會自動嘗試為您點擊 Cookie 橫幅上的「拒絕」按鈕。若網站未提供拒絕選向,可能還是會接受所有 Cookie 來讓橫幅消失。 + Firefox 會自動嘗試為您點擊 Cookie 橫幅上的「拒絕」按鈕。若網站未提供拒絕選向,可能還是會接受所有 Cookie 來讓橫幅消失。 + + %1$s 會自動嘗試拒絕網站 Cookie 橫幅上的設定請求。 對此網站關閉 對此網站開啟 + + 目前不支援的網站 要為 %1$s 開啟減少 Cookie 橫幅功能嗎? @@ -362,14 +384,54 @@ %1$s 將清除此網站的 Cookie 並重新載入頁面。清除 Cookie 可能會將您從網站登出,或清空購物車。 - %1$s 可自動嘗試為您拒絕 Cookie。若網站未提供拒絕選向,%2$s 可能還是會接受所有 Cookie 來讓橫幅消失。 + %1$s 可自動嘗試為您拒絕 Cookie。若網站未提供拒絕選向,%2$s 可能還是會接受所有 Cookie 來讓橫幅消失。 + + + %1$s 可以嘗試自動為您拒絕網站要設定 Cookie 的請求。 + + %1$s 可自動在支援的網站,為您拒絕網站設定 Cookie 的請求。 + + 讓 Cookie 橫幅消失! + + 在可能的情況下自動拒絕 Cookie 橫幅,否則就接受網站的所有 Cookie 來讓橫幅消失。 + + 可能的話就自動拒絕 Cookie 請求。 + + 要允許 %1$s 盡可能自動拒絕 Cookie 請求嗎? + + 現在不要 + + 關閉橫幅 + + + 您看到的 Cookie 請求會變少 + + 減少顯示 Cookie 彈出提示 + + 自動回答設定 Cookie 的彈出提示,讓您上網不用分心。%1$s 可以的話將會拒絕所有請求,如果無法拒絕就會全部接受。 + + 自動回答設定 Cookie 的彈出提示,讓您上網不用分心。%1$s 可以的話將會拒絕所有請求。 + + 關閉彈出提示 + + 減少 Cookie 橫幅 + + 要允許 %1$s 幫您拒絕網站的 Cookie 提示,或者當網站無法拒絕時就接受嗎? + + 要讓 %1$s 在可以拒絕時,盡量拒絕網站設定 Cookie 的請求嗎? + + 允許 自動嘗試使用加密過的 HTTPS 通訊協定連線到網站,以增加安全性。 - 開啟 - + 開啟 + 關閉 + + 對所有分頁開啟 + + 只對隱私分頁開啟 了解更多 @@ -449,6 +511,11 @@ 通知 + + 允許 + + 不允許 + 自訂附加元件收藏集 @@ -471,8 +538,6 @@ 最近造訪 - - Pocket 發人深省的文章 @@ -734,6 +799,13 @@ 1 個月後關閉 + + 開啟首頁 + + 開啟最近關閉分頁 + + 關閉超過四小時後開啟首頁 + 將舊分頁移動到獨立區塊 @@ -1003,10 +1075,16 @@ 例外網站 - 開啟 + 開啟 關閉 + + 標準 + + 嚴格 + + 自訂 允許自動播放影音內容 @@ -1764,7 +1842,7 @@ 要使用的搜尋字串 - 用「%s」取代查詢關鍵字。例如:\nhttps://www.google.com/search?q=%s + 用「%s」取代查詢關鍵字。例如:\nhttps://www.google.com/search?q=%s 自訂搜尋引擎詳細資訊 @@ -1964,8 +2042,6 @@ 熱門主題 探索更多 - - Powered by Pocket 由 %s 提供。 diff --git a/app/src/main/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml index 6af082f44..8f73ce620 100644 --- a/app/src/main/res/values/preference_keys.xml +++ b/app/src/main/res/values/preference_keys.xml @@ -162,6 +162,9 @@ pref_key_cookie_banner_settings + pref_key_cookie_banner_re_engage_dialog_last_interaction_with_dialog_in_ms + pref_key_cookie_banner_re_engage_dialog_dismissed + pref_key_cookie_banner_first_banner_detected pref_key_cookie_banner_v1 @@ -330,4 +333,12 @@ pref_key_growth_first_week_series_sent pref_key_growth_first_week_days_of_use pref_key_growth_ad_click_sent + pref_key_growth_usage_time + pref_key_growth_usage_time_sent + pref_key_growth_last_resumed + pref_key_growth_uri_load_last_sent + + + pref_key_notification_pre_permission_prompt_enabled + pref_key_is_notification_pre_permission_prompt_shown diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3b79c93a2..c7868cabf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -276,6 +276,18 @@ Close + + + Notifications help you do more with %s + + Sync your tabs between devices, manage downloads, get tips about making the most of %s’s privacy protection, and more. + + Continue + + Not now + Open a new %1$s tab @@ -330,7 +342,9 @@ Reduce cookie banners - Firefox automatically tries to reject cookie requests on cookie banners. If a reject option isn’t available, Firefox may accept all cookies to dismiss the banner. + Firefox automatically tries to reject cookie requests on cookie banners. If a reject option isn’t available, Firefox may accept all cookies to dismiss the banner. + + %1$s automatically tries to reject cookie requests on cookie banners. Off for this site @@ -341,8 +355,38 @@ Turn off Cookie Banner Reduction for %1$s? %1$s will clear this site’s cookies and refresh the page. Clearing all cookies may sign you out or empty shopping carts. - - Firefox can try to automatically reject cookie requests. If a reject option isn’t available, Firefox may accept all cookies to dismiss the banner. + + %1$s can try to automatically reject cookie requests. If a reject option isn’t available, %2$s may accept all cookies to dismiss the banner. + + %1$s can try to automatically reject cookie requests. + + Cookie banners begone! + + Automatically reject cookie requests, when possible. Otherwise, accept all cookies to dismiss cookie banners. + + Automatically reject cookie requests, when possible. + + Not Now + + Dismiss banners + + You’ll see fewer cookie requests + + See fewer cookie pop-ups + + Automatically answer cookie pop-ups for distraction-free browsing. %1$s will reject all requests if possible, or accept all if not. + + Automatically answer cookie pop-ups for distraction-free browsing. %1$s will reject all requests if possible. + + Dismiss Pop-ups + + Cookie Banner Reduction + + Allow %1$s to decline a site’s cookie consent request if possible or accept cookie access when not possible? + + Allow %1$s to decline a site’s cookie consent request if possible? + + Allow Automatically attempts to connect to sites using HTTPS encryption protocol for increased security. @@ -1060,8 +1104,6 @@ Copy to clipboard Copied to clipboard - - Sign in to sync Sign in to Sync @@ -1892,6 +1934,14 @@ Auto-close enabled + + + Firefox Suggest + + Google Search + + %s search + Set links from websites, emails, and messages to open automatically in Firefox. @@ -1929,7 +1979,6 @@ Enable telemetry to send data. Go to settings - Firefox Suggest diff --git a/app/src/main/res/xml/cookie_banner_preferences.xml b/app/src/main/res/xml/cookie_banner_preferences.xml index ee77bdade..08ef71ab4 100644 --- a/app/src/main/res/xml/cookie_banner_preferences.xml +++ b/app/src/main/res/xml/cookie_banner_preferences.xml @@ -2,9 +2,8 @@ - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - diff --git a/app/src/test/java/org/mozilla/fenix/components/metrics/DefaultMetricsStorageTest.kt b/app/src/test/java/org/mozilla/fenix/components/metrics/DefaultMetricsStorageTest.kt index d3f5d3481..018e68062 100644 --- a/app/src/test/java/org/mozilla/fenix/components/metrics/DefaultMetricsStorageTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/metrics/DefaultMetricsStorageTest.kt @@ -4,11 +4,16 @@ package org.mozilla.fenix.components.metrics +import android.app.Activity +import android.app.Application import io.mockk.every import io.mockk.mockk import io.mockk.slot +import io.mockk.verify import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.runTest +import mozilla.components.support.test.mock +import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before @@ -23,6 +28,7 @@ class DefaultMetricsStorageTest { private val formatter = SimpleDateFormat("yyyy-MM-dd", Locale.US) private val calendarStart = Calendar.getInstance(Locale.US) private val dayMillis: Long = 1000 * 60 * 60 * 24 + private val usageThresholdMillis: Long = 340 * 1000 private var checkDefaultBrowser = false private val doCheckDefaultBrowser = { checkDefaultBrowser } @@ -229,6 +235,153 @@ class DefaultMetricsStorageTest { assertTrue(result) } + @Test + fun `GIVEN usage time has not passed threshold and has not been sent WHEN checking to track THEN event will not be sent`() = runTest(dispatcher) { + every { settings.usageTimeGrowthData } returns usageThresholdMillis - 1 + every { settings.usageTimeGrowthSent } returns false + + val result = storage.shouldTrack(Event.GrowthData.UsageThreshold) + + assertFalse(result) + } + + @Test + fun `GIVEN usage time has passed threshold and has not been sent WHEN checking to track THEN event will be sent`() = runTest(dispatcher) { + every { settings.usageTimeGrowthData } returns usageThresholdMillis + 1 + every { settings.usageTimeGrowthSent } returns false + + val result = storage.shouldTrack(Event.GrowthData.UsageThreshold) + + assertTrue(result) + } + + @Test + fun `GIVEN usage time growth has not been sent and within first day WHEN registering as usage recorder THEN will be registered`() { + val application = mockk() + every { settings.usageTimeGrowthSent } returns false + every { application.registerActivityLifecycleCallbacks(any()) } returns Unit + + storage.tryRegisterAsUsageRecorder(application) + + verify { application.registerActivityLifecycleCallbacks(any()) } + } + + @Test + fun `GIVEN usage time growth has not been sent and not within first day WHEN registering as usage recorder THEN will not be registered`() { + val application = mockk() + installTime = System.currentTimeMillis() - dayMillis * 2 + every { settings.usageTimeGrowthSent } returns false + + storage.tryRegisterAsUsageRecorder(application) + + verify(exactly = 0) { application.registerActivityLifecycleCallbacks(any()) } + } + + @Test + fun `GIVEN usage time growth has been sent WHEN registering as usage recorder THEN will not be registered`() { + val application = mockk() + every { settings.usageTimeGrowthSent } returns true + + storage.tryRegisterAsUsageRecorder(application) + + verify(exactly = 0) { application.registerActivityLifecycleCallbacks(any()) } + } + + @Test + fun `WHEN updating usage state THEN storage will be delegated to settings`() { + val initial = 10L + val update = 15L + val slot = slot() + every { settings.usageTimeGrowthData } returns initial + every { settings.usageTimeGrowthData = capture(slot) } returns Unit + + storage.updateUsageState(update) + + assertEquals(slot.captured, initial + update) + } + + @Test + fun `WHEN usage recorder receives onResume and onPause callbacks THEN it will store usage length`() { + val storage = mockk() + val activity = mockk() + val slot = slot() + every { storage.updateUsageState(capture(slot)) } returns Unit + every { activity.componentName } returns mock() + + val usageRecorder = DefaultMetricsStorage.UsageRecorder(storage) + val startTime = System.currentTimeMillis() + + usageRecorder.onActivityResumed(activity) + usageRecorder.onActivityPaused(activity) + val stopTime = System.currentTimeMillis() + + assertTrue(slot.captured < stopTime - startTime) + } + + @Test + fun `GIVEN that it has been less than 24 hours since last resumed sent WHEN checked for sending THEN will not be sent`() = runTest(dispatcher) { + val currentTime = System.currentTimeMillis() + every { settings.resumeGrowthLastSent } returns currentTime + + val result = storage.shouldTrack(Event.GrowthData.FirstAppOpenForDay) + + assertFalse(result) + } + + @Test + fun `GIVEN that it has been more than 24 hours since last resumed sent WHEN checked for sending THEN will be sent`() = runTest(dispatcher) { + val currentTime = System.currentTimeMillis() + installTime = currentTime - (dayMillis + 1) + every { settings.resumeGrowthLastSent } returns currentTime - 1000 * 60 * 60 * 24 * 2 + + val result = storage.shouldTrack(Event.GrowthData.FirstAppOpenForDay) + + assertTrue(result) + } + + @Test + fun `WHEN last resumed state updated THEN settings updated accordingly`() = runTest(dispatcher) { + val updateSlot = slot() + every { settings.resumeGrowthLastSent } returns 0 + every { settings.resumeGrowthLastSent = capture(updateSlot) } returns Unit + + storage.updateSentState(Event.GrowthData.FirstAppOpenForDay) + + assertTrue(updateSlot.captured > 0) + } + + @Test + fun `GIVEN that it has been less than 24 hours since uri load sent WHEN checked for sending THEN will not be sent`() = runTest(dispatcher) { + val currentTime = System.currentTimeMillis() + every { settings.uriLoadGrowthLastSent } returns currentTime + + val result = storage.shouldTrack(Event.GrowthData.FirstUriLoadForDay) + + assertFalse(result) + } + + @Test + fun `GIVEN that it has been more than 24 hours since uri load sent WHEN checked for sending THEN will be sent`() = runTest(dispatcher) { + val currentTime = System.currentTimeMillis() + installTime = currentTime - (dayMillis + 1) + every { settings.uriLoadGrowthLastSent } returns currentTime - 1000 * 60 * 60 * 24 * 2 + + val result = storage.shouldTrack(Event.GrowthData.FirstUriLoadForDay) + + assertTrue(result) + } + + @Test + fun `WHEN uri load updated THEN settings updated accordingly`() = runTest(dispatcher) { + val updateSlot = slot() + every { settings.uriLoadGrowthLastSent } returns 0 + every { settings.uriLoadGrowthLastSent = capture(updateSlot) } returns Unit + + storage.updateSentState(Event.GrowthData.FirstUriLoadForDay) + + assertTrue(updateSlot.captured > 0) + } + private fun Calendar.copy() = clone() as Calendar private fun Calendar.createNextDay() = copy().apply { add(Calendar.DAY_OF_MONTH, 1) diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenterTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenterTest.kt index 75efe6a31..3c125547e 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenterTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarCFRPresenterTest.kt @@ -221,6 +221,7 @@ class BrowserToolbarCFRPresenterTest { val presenter = createPresenter( anchor = mockk(relaxed = true), ) + every { presenter.tryToShowCookieBannerDialogIfNeeded() } just Runs presenter.showTcpCfr() @@ -231,6 +232,9 @@ class BrowserToolbarCFRPresenterTest { assertNull(TrackingProtection.tcpCfrImplicitDismissal.testGetValue()) presenter.tcpCfrPopup!!.onDismiss.invoke(false) assertNotNull(TrackingProtection.tcpCfrImplicitDismissal.testGetValue()) + verify { + presenter.tryToShowCookieBannerDialogIfNeeded() + } } /** @@ -260,12 +264,14 @@ class BrowserToolbarCFRPresenterTest { every { findViewById(R.id.mozac_browser_toolbar_security_indicator) } returns anchor }, sessionId: String? = null, - ) = BrowserToolbarCFRPresenter( - context = context, - browserStore = browserStore, - settings = settings, - toolbar = toolbar, - sessionId = sessionId, + ) = spyk( + BrowserToolbarCFRPresenter( + context = context, + browserStore = browserStore, + settings = settings, + toolbar = toolbar, + sessionId = sessionId, + ), ) private fun createBrowserStore( diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt index 8ad2f6854..c23db926a 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt @@ -20,6 +20,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.utils.Settings import mozilla.components.browser.toolbar.behavior.ToolbarPosition as MozacToolbarPosition @@ -41,6 +42,7 @@ class BrowserToolbarViewTest { every { testContext.components.useCases } returns mockk(relaxed = true) every { testContext.components.core } returns mockk(relaxed = true) every { testContext.components.publicSuffixList } returns PublicSuffixList(testContext) + every { testContext.settings().showUnifiedSearchFeature } returns false toolbarView = BrowserToolbarView( context = testContext, diff --git a/app/src/test/java/org/mozilla/fenix/ext/NotificationManagerCompatTest.kt b/app/src/test/java/org/mozilla/fenix/ext/NotificationManagerCompatTest.kt new file mode 100644 index 000000000..f9edfc17f --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/ext/NotificationManagerCompatTest.kt @@ -0,0 +1,119 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ext + +import android.os.Build +import androidx.core.app.NotificationChannelCompat +import androidx.core.app.NotificationManagerCompat +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import org.robolectric.util.ReflectionHelpers + +@RunWith(FenixRobolectricTestRunner::class) +class NotificationManagerCompatTest { + + private lateinit var tested: NotificationManagerCompat + + @Before + fun setup() { + tested = mockk(relaxed = true) + + mockkStatic("org.mozilla.fenix.ext.NotificationManagerCompatKt") + } + + @Test + fun `WHEN areNotificationsEnabled throws an exception THEN areNotificationsEnabledSafe returns false`() { + every { tested.areNotificationsEnabled() } throws RuntimeException() + + assertFalse(tested.areNotificationsEnabledSafe()) + } + + @Test + fun `WHEN areNotificationsEnabled returns false THEN areNotificationsEnabledSafe returns false`() { + every { tested.areNotificationsEnabled() } returns false + + assertFalse(tested.areNotificationsEnabledSafe()) + } + + @Test + fun `WHEN areNotificationsEnabled returns true THEN areNotificationsEnabledSafe returns true`() { + every { tested.areNotificationsEnabled() } returns true + + assertTrue(tested.areNotificationsEnabledSafe()) + } + + @Test + fun `WHEN getNotificationChannelCompat returns a channel with IMPORTANCE_DEFAULT and areNotificationsEnabled returns true THEN isNotificationChannelEnabled returns true`() { + val testChannel = "test-channel" + val notificationChannelCompat = + NotificationChannelCompat.Builder( + testChannel, + NotificationManagerCompat.IMPORTANCE_DEFAULT, + ).build() + + every { tested.getNotificationChannelCompat(testChannel) } returns notificationChannelCompat + every { tested.areNotificationsEnabled() } returns true + + assertTrue(tested.isNotificationChannelEnabled(testChannel)) + } + + @Test + fun `WHEN getNotificationChannelCompat returns a channel with IMPORTANCE_NONE and areNotificationsEnabled returns true THEN isNotificationChannelEnabled returns false`() { + val testChannel = "test-channel" + val notificationChannelCompat = + NotificationChannelCompat.Builder( + testChannel, + NotificationManagerCompat.IMPORTANCE_NONE, + ).build() + + every { tested.getNotificationChannelCompat(testChannel) } returns notificationChannelCompat + every { tested.areNotificationsEnabled() } returns true + + assertFalse(tested.isNotificationChannelEnabled(testChannel)) + } + + @Test + fun `WHEN getNotificationChannelCompat returns a channel and areNotificationsEnabled returns false THEN isNotificationChannelEnabled returns false`() { + val testChannel = "test-channel" + val notificationChannelCompat = + NotificationChannelCompat.Builder( + testChannel, + NotificationManagerCompat.IMPORTANCE_DEFAULT, + ).build() + + every { tested.getNotificationChannelCompat(testChannel) } returns notificationChannelCompat + every { tested.areNotificationsEnabled() } returns false + + assertFalse(tested.isNotificationChannelEnabled(testChannel)) + } + + @Test + fun `WHEN getNotificationChannelCompat returns null THEN isNotificationChannelEnabled returns false`() { + val testChannel = "test-channel" + + every { tested.getNotificationChannelCompat(testChannel) } returns null + every { tested.areNotificationsEnabled() } returns true + + assertFalse(tested.isNotificationChannelEnabled(testChannel)) + } + + @Test + fun `WHEN sdk less than 26 and areNotificationsEnabled returns true THEN isNotificationChannelEnabled returns true`() { + val testChannel = "test-channel" + + ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SDK_INT", 25) + + every { tested.areNotificationsEnabled() } returns true + + assertTrue(tested.isNotificationChannelEnabled(testChannel)) + } +} diff --git a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt index e26da0a41..f1a67e16f 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -43,7 +43,6 @@ import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -57,7 +56,6 @@ import org.mozilla.fenix.GleanMetrics.RecentTabs import org.mozilla.fenix.GleanMetrics.TopSites import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R -import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.components.Analytics import org.mozilla.fenix.components.AppStore @@ -1046,33 +1044,6 @@ class DefaultSessionControlControllerTest { } } - @Test - @Ignore("Can't instantiate proxy for class kotlin.Function0") - fun handleMenuOpenedWhileSearchShowing() { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - - createController().handleMenuOpened() - - verify { - navController.navigateUp() - } - } - - @Test - fun handleMenuOpenedWhileSearchNotShowing() { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.homeFragment - } - - createController().handleMenuOpened() - - verify(exactly = 0) { - navController.navigateUp() - } - } - @Test fun `WHEN private mode button is selected from home THEN handle mode change`() { every { navController.currentDestination } returns mockk { @@ -1117,11 +1088,6 @@ class DefaultSessionControlControllerTest { verify { settings.incrementNumTimesPrivateModeOpened() AppAction.ModeChange(Mode.fromBrowsingMode(newMode)) - navController.navigate( - BrowserFragmentDirections.actionGlobalSearchDialog( - sessionId = null, - ), - ) } } @@ -1149,11 +1115,8 @@ class DefaultSessionControlControllerTest { settings.incrementNumTimesPrivateModeOpened() } verify { - AppAction.ModeChange(Mode.fromBrowsingMode(newMode)) - navController.navigate( - BrowserFragmentDirections.actionGlobalSearchDialog( - sessionId = null, - ), + appStore.dispatch( + AppAction.ModeChange(Mode.fromBrowsingMode(newMode)), ) } } diff --git a/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt index 41f0a036a..d5c6fe14b 100644 --- a/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt @@ -143,18 +143,6 @@ class SessionControlInteractorTest { verify { controller.handleRemoveCollectionsPlaceholder() } } - @Test - fun onCollectionMenuOpened() { - interactor.onCollectionMenuOpened() - verify { controller.handleMenuOpened() } - } - - @Test - fun onTopSiteMenuOpened() { - interactor.onTopSiteMenuOpened() - verify { controller.handleMenuOpened() } - } - @Test fun onRecentTabClicked() { val tabId = "tabId" @@ -162,12 +150,6 @@ class SessionControlInteractorTest { verify { recentTabController.handleRecentTabClicked(tabId) } } - @Test - fun onRecentTabLongClicked() { - interactor.onRecentTabLongClicked() - verify { recentTabController.handleRecentTabLongClicked() } - } - @Test fun onRecentTabShowAllClicked() { interactor.onRecentTabShowAllClicked() @@ -197,12 +179,6 @@ class SessionControlInteractorTest { verify { recentBookmarksController.handleBookmarkClicked(bookmark) } } - @Test - fun `WHEN a recent bookmark is long clicked THEN the long click is handled`() { - interactor.onRecentBookmarkLongClicked() - verify { recentBookmarksController.handleBookmarkLongClicked() } - } - @Test fun `WHEN tapping on the customize home button THEN openCustomizeHomePage`() { interactor.openCustomizeHomePage() diff --git a/app/src/test/java/org/mozilla/fenix/home/intent/AssistIntentProcessorTest.kt b/app/src/test/java/org/mozilla/fenix/home/intent/AssistIntentProcessorTest.kt new file mode 100644 index 000000000..bc122b96b --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/home/intent/AssistIntentProcessorTest.kt @@ -0,0 +1,67 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.home.intent + +import android.content.Intent +import androidx.navigation.NavController +import androidx.navigation.navOptions +import io.mockk.Called +import io.mockk.mockk +import io.mockk.verify +import org.junit.Assert.assertFalse +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.NavGraphDirections +import org.mozilla.fenix.R +import org.mozilla.fenix.components.metrics.MetricsUtils +import org.mozilla.fenix.ext.nav +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class AssistIntentProcessorTest { + private val navController: NavController = mockk(relaxed = true) + private val out: Intent = mockk(relaxed = true) + + @Test + fun `GIVEN an intent with wrong action WHEN it is processed THEN nothing should happen`() { + val intent = Intent().apply { + action = TEST_WRONG_ACTION + } + val result = StartSearchIntentProcessor().process(intent, navController, out) + + verify { navController wasNot Called } + verify { out wasNot Called } + assertFalse(result) + } + + @Test + fun `GIVEN an intent with ACTION_ASSIST action WHEN it is processed THEN navigate to the search dialog`() { + val intent = Intent().apply { + action = Intent.ACTION_ASSIST + } + + AssistIntentProcessor().process(intent, navController, out) + val options = navOptions { + popUpTo(R.id.homeFragment) + } + + verify { + navController.nav( + null, + NavGraphDirections.actionGlobalSearchDialog( + sessionId = null, + searchAccessPoint = MetricsUtils.Source.NONE, + ), + options, + ) + } + + verify { out wasNot Called } + } + + companion object { + const val TEST_WRONG_ACTION = "test-action" + } +} diff --git a/app/src/test/java/org/mozilla/fenix/home/pocket/DefaultPocketStoriesControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/pocket/DefaultPocketStoriesControllerTest.kt index 38c5f2ee2..30627470e 100644 --- a/app/src/test/java/org/mozilla/fenix/home/pocket/DefaultPocketStoriesControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/pocket/DefaultPocketStoriesControllerTest.kt @@ -4,7 +4,6 @@ package org.mozilla.fenix.home.pocket -import androidx.navigation.NavController import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic @@ -28,7 +27,6 @@ import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.GleanMetrics.Pings import org.mozilla.fenix.GleanMetrics.Pocket import org.mozilla.fenix.HomeActivity -import org.mozilla.fenix.R import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.components.appstate.AppState @@ -53,7 +51,7 @@ class DefaultPocketStoriesControllerTest { ), ), ) - val controller = DefaultPocketStoriesController(mockk(), store, mockk()) + val controller = DefaultPocketStoriesController(mockk(), store) assertNull(Pocket.homeRecsCategoryClicked.testGetValue()) controller.handleCategoryClick(category2) @@ -98,7 +96,7 @@ class DefaultPocketStoriesControllerTest { ), ), ) - val controller = DefaultPocketStoriesController(mockk(), store, mockk()) + val controller = DefaultPocketStoriesController(mockk(), store) assertNull(Pocket.homeRecsCategoryClicked.testGetValue()) controller.handleCategoryClick(PocketRecommendedStoriesCategory(newSelectedCategory.name)) @@ -142,7 +140,7 @@ class DefaultPocketStoriesControllerTest { ), ) val newSelectedCategoryName = "newSelectedCategory" - val controller = DefaultPocketStoriesController(mockk(), store, mockk()) + val controller = DefaultPocketStoriesController(mockk(), store) controller.handleCategoryClick(PocketRecommendedStoriesCategory(newSelectedCategoryName)) @@ -163,7 +161,7 @@ class DefaultPocketStoriesControllerTest { @Test fun `WHEN a new recommended story is shown THEN update the State`() { val store = spyk(AppStore()) - val controller = DefaultPocketStoriesController(mockk(), store, mockk()) + val controller = DefaultPocketStoriesController(mockk(), store) val storyShown: PocketRecommendedStory = mockk() val storyGridLocation = 1 to 2 @@ -175,7 +173,7 @@ class DefaultPocketStoriesControllerTest { @Test fun `WHEN a new sponsored story is shown THEN update the State and record telemetry`() { val store = spyk(AppStore()) - val controller = DefaultPocketStoriesController(mockk(), store, mockk()) + val controller = DefaultPocketStoriesController(mockk(), store) val storyShown: PocketSponsoredStory = mockk { every { shim.click } returns "testClickShim" every { shim.impression } returns "testImpressionShim" @@ -206,7 +204,7 @@ class DefaultPocketStoriesControllerTest { @Test fun `WHEN new stories are shown THEN update the State and record telemetry`() { val store = spyk(AppStore()) - val controller = DefaultPocketStoriesController(mockk(), store, mockk()) + val controller = DefaultPocketStoriesController(mockk(), store) val storiesShown: List = mockk() assertNull(Pocket.homeRecsShown.testGetValue()) @@ -230,7 +228,7 @@ class DefaultPocketStoriesControllerTest { timesShown = 123, ) val homeActivity: HomeActivity = mockk(relaxed = true) - val controller = DefaultPocketStoriesController(homeActivity, mockk(), mockk(relaxed = true)) + val controller = DefaultPocketStoriesController(homeActivity, mockk()) assertNull(Pocket.homeRecsStoryClicked.testGetValue()) controller.handleStoryClicked(story, 1 to 2) @@ -262,7 +260,7 @@ class DefaultPocketStoriesControllerTest { caps = mockk(relaxed = true), ) val homeActivity: HomeActivity = mockk(relaxed = true) - val controller = DefaultPocketStoriesController(homeActivity, mockk(), mockk(relaxed = true)) + val controller = DefaultPocketStoriesController(homeActivity, mockk()) var wasPingSent = false assertNull(Pocket.homeRecsSpocClicked.testGetValue()) mockkStatic("mozilla.components.service.pocket.ext.PocketStoryKt") { @@ -291,7 +289,7 @@ class DefaultPocketStoriesControllerTest { fun `WHEN discover more is clicked then open that using HomeActivity and record telemetry`() { val link = "http://getpocket.com/explore" val homeActivity: HomeActivity = mockk(relaxed = true) - val controller = DefaultPocketStoriesController(homeActivity, mockk(), mockk(relaxed = true)) + val controller = DefaultPocketStoriesController(homeActivity, mockk()) assertNull(Pocket.homeRecsDiscoverClicked.testGetValue()) controller.handleDiscoverMoreClicked(link) @@ -306,7 +304,7 @@ class DefaultPocketStoriesControllerTest { fun `WHEN learn more is clicked then open that using HomeActivity and record telemetry`() { val link = "https://www.mozilla.org/en-US/firefox/pocket/" val homeActivity: HomeActivity = mockk(relaxed = true) - val controller = DefaultPocketStoriesController(homeActivity, mockk(), mockk(relaxed = true)) + val controller = DefaultPocketStoriesController(homeActivity, mockk()) assertNull(Pocket.homeRecsLearnMoreClicked.testGetValue()) controller.handleLearnMoreClicked(link) @@ -317,79 +315,41 @@ class DefaultPocketStoriesControllerTest { } @Test - fun `WHEN a story is clicked THEN search is dismissed and then its link opened`() { + fun `WHEN a story is clicked THEN its link is opened`() { val story = PocketRecommendedStory("", "url", "", "", "", 0, 0) val homeActivity: HomeActivity = mockk(relaxed = true) - val navController: NavController = mockk(relaxed = true) - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - val controller = DefaultPocketStoriesController(homeActivity, mockk(), navController) + val controller = DefaultPocketStoriesController(homeActivity, mockk()) controller.handleStoryClicked(story, 1 to 2) verifyOrder { - navController.navigateUp() homeActivity.openToBrowserAndLoad(story.url, true, BrowserDirection.FromHome) } } @Test - fun `WHEN discover more is clicked THEN search is dismissed and then its link opened`() { + fun `WHEN discover more is clicked THEN its link is opened`() { val link = "https://discoverMore.link" val homeActivity: HomeActivity = mockk(relaxed = true) - val navController: NavController = mockk(relaxed = true) - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - val controller = DefaultPocketStoriesController(homeActivity, mockk(), navController) + val controller = DefaultPocketStoriesController(homeActivity, mockk()) controller.handleDiscoverMoreClicked(link) verifyOrder { - navController.navigateUp() homeActivity.openToBrowserAndLoad(link, true, BrowserDirection.FromHome) } } @Test - fun `WHEN learn more link is clicked THEN search is dismissed and then that link is opened`() { + fun `WHEN learn more link is clicked THEN that link is opened`() { val link = "https://learnMore.link" val homeActivity: HomeActivity = mockk(relaxed = true) - val navController: NavController = mockk(relaxed = true) - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - val controller = DefaultPocketStoriesController(homeActivity, mockk(), navController) + val controller = DefaultPocketStoriesController(homeActivity, mockk()) controller.handleLearnMoreClicked(link) verifyOrder { - navController.navigateUp() homeActivity.openToBrowserAndLoad(link, true, BrowserDirection.FromHome) } } - - @Test - fun `GIVEN search dialog is currently focused WHEN dismissSearchDialogIfDisplayed is called THEN close the search dialog`() { - val navController: NavController = mockk(relaxed = true) - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - val controller = DefaultPocketStoriesController(mockk(), mockk(), navController) - - controller.dismissSearchDialogIfDisplayed() - - verify { navController.navigateUp() } - } - - @Test - fun `GIVEN search dialog is not currently focused WHEN dismissSearchDialogIfDisplayed is called THEN do nothing`() { - val navController: NavController = mockk(relaxed = true) - val controller = DefaultPocketStoriesController(mockk(), mockk(), navController) - - controller.dismissSearchDialogIfDisplayed() - - verify(exactly = 0) { navController.navigateUp() } - } } diff --git a/app/src/test/java/org/mozilla/fenix/home/recentbookmarks/DefaultRecentBookmarksControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/recentbookmarks/DefaultRecentBookmarksControllerTest.kt index 0700fec4f..3454608bd 100644 --- a/app/src/test/java/org/mozilla/fenix/home/recentbookmarks/DefaultRecentBookmarksControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/recentbookmarks/DefaultRecentBookmarksControllerTest.kt @@ -28,7 +28,6 @@ import org.junit.runner.RunWith import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.GleanMetrics.RecentBookmarks import org.mozilla.fenix.HomeActivity -import org.mozilla.fenix.R import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.home.HomeFragmentDirections import org.mozilla.fenix.home.recentbookmarks.controller.DefaultRecentBookmarksController @@ -52,11 +51,6 @@ class DefaultRecentBookmarksControllerTest { fun setup() { every { activity.openToBrowserAndLoad(any(), any(), any()) } just Runs - every { navController.currentDestination } returns mockk { - every { id } returns R.id.homeFragment - } - every { navController.navigateUp() } returns true - controller = spyk( DefaultRecentBookmarksController( activity = activity, @@ -68,9 +62,6 @@ class DefaultRecentBookmarksControllerTest { @Test fun `WHEN a recently saved bookmark is clicked THEN the selected bookmark is opened`() { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.homeFragment - } assertNull(RecentBookmarks.bookmarkClicked.testGetValue()) val bookmark = RecentBookmark( @@ -81,7 +72,6 @@ class DefaultRecentBookmarksControllerTest { controller.handleBookmarkClicked(bookmark) verify { - controller.dismissSearchDialogIfDisplayed() activity.openToBrowserAndLoad( searchTermOrURL = bookmark.url!!, newTab = true, @@ -90,16 +80,10 @@ class DefaultRecentBookmarksControllerTest { ) } assertNotNull(RecentBookmarks.bookmarkClicked.testGetValue()) - verify(exactly = 0) { - navController.navigateUp() - } } @Test fun `WHEN show all recently saved bookmark is clicked THEN the bookmarks root is opened`() = runTestOnMain { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.homeFragment - } assertNull(RecentBookmarks.showAllBookmarks.testGetValue()) controller.handleShowAllBookmarksClicked() @@ -109,16 +93,10 @@ class DefaultRecentBookmarksControllerTest { navController.navigate(directions) } assertNotNull(RecentBookmarks.showAllBookmarks.testGetValue()) - verify(exactly = 0) { - navController.navigateUp() - } } @Test fun `WHEN show all is clicked from behind search dialog THEN open bookmarks root`() { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } assertNull(RecentBookmarks.showAllBookmarks.testGetValue()) controller.handleShowAllBookmarksClicked() @@ -126,24 +104,8 @@ class DefaultRecentBookmarksControllerTest { val directions = HomeFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id) verify { - controller.dismissSearchDialogIfDisplayed() - navController.navigateUp() navController.navigate(directions) } assertNotNull(RecentBookmarks.showAllBookmarks.testGetValue()) } - - @Test - fun `GIVEN search dialog is displayed WHEN recent bookmark is long clicked THEN dismiss search dialog`() { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - - controller.handleBookmarkLongClicked() - - verify { - controller.dismissSearchDialogIfDisplayed() - navController.navigateUp() - } - } } diff --git a/app/src/test/java/org/mozilla/fenix/home/recentsyncedtabs/controller/DefaultRecentSyncedTabControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/recentsyncedtabs/controller/DefaultRecentSyncedTabControllerTest.kt index 418d3ee3c..3fac7ee82 100644 --- a/app/src/test/java/org/mozilla/fenix/home/recentsyncedtabs/controller/DefaultRecentSyncedTabControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/recentsyncedtabs/controller/DefaultRecentSyncedTabControllerTest.kt @@ -150,20 +150,6 @@ class DefaultRecentSyncedTabControllerTest { } } - @Test - fun `GIVEN search dialog is displayed WHEN recent synced tab is long clicked THEN dismiss search dialog`() { - every { navController.navigateUp() } returns true - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - - controller.handleRecentSyncedTabLongClick() - - verify { - navController.navigateUp() - } - } - @Test fun `WHEN synced tab clicked THEN metric counter labeled by device type is incremented`() { val url = "https://mozilla.org" diff --git a/app/src/test/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabControllerTest.kt index f4347bd0b..d6ed5acc5 100644 --- a/app/src/test/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabControllerTest.kt @@ -63,7 +63,6 @@ class RecentTabControllerTest { appStore = appStore, ), ) - every { navController.navigateUp() } returns true } @Test @@ -124,21 +123,13 @@ class RecentTabControllerTest { fun handleRecentTabShowAllClickedFromHome() { assertNull(RecentTabs.showAllClicked.testGetValue()) - every { navController.currentDestination } returns mockk { - every { id } returns R.id.homeFragment - } - controller.handleRecentTabShowAllClicked() verify { - controller.dismissSearchDialogIfDisplayed() navController.navigate( match { it.actionId == R.id.action_global_tabsTrayFragment }, ) } - verify(exactly = 0) { - navController.navigateUp() - } assertNotNull(RecentTabs.showAllClicked.testGetValue()) } @@ -147,15 +138,9 @@ class RecentTabControllerTest { fun handleRecentTabShowAllClickedFromSearchDialog() { assertNull(RecentTabs.showAllClicked.testGetValue()) - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - controller.handleRecentTabShowAllClicked() verify { - controller.dismissSearchDialogIfDisplayed() - navController.navigateUp() navController.navigate( match { it.actionId == R.id.action_global_tabsTrayFragment }, ) @@ -163,19 +148,4 @@ class RecentTabControllerTest { assertNotNull(RecentTabs.showAllClicked.testGetValue()) } - - @Test - fun `GIVEN search dialog is displayed WHEN long clicking a recent tab THEN search dialog is dismissed`() { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - every { navController.navigateUp() } returns true - - controller.handleRecentTabLongClicked() - - verify { - controller.dismissSearchDialogIfDisplayed() - navController.navigateUp() - } - } } diff --git a/app/src/test/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsControllerTest.kt index 9927657bf..89e1d84a3 100644 --- a/app/src/test/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/recentvisits/controller/RecentVisitsControllerTest.kt @@ -87,7 +87,6 @@ class RecentVisitsControllerTest { controller.handleHistoryShowAllClicked() verify { - controller.dismissSearchDialogIfDisplayed() navController.navigate( HomeFragmentDirections.actionGlobalHistoryFragment(), ) @@ -181,18 +180,4 @@ class RecentVisitsControllerTest { } } } - - @Test - fun `WHEN long clicking a recent visit THEN search dialog should be dismissed `() = runTestOnMain { - every { navController.currentDestination } returns mockk { - every { id } returns R.id.searchDialogFragment - } - - controller.handleRecentVisitLongClicked() - - verify { - controller.dismissSearchDialogIfDisplayed() - navController.navigateUp() - } - } } diff --git a/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt index 8f10ffb12..6522bcdee 100644 --- a/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt @@ -120,11 +120,4 @@ class RecentVisitsInteractorTest { verify { recentVisitsController.handleRemoveRecentHistoryHighlight("url") } } - - @Test - fun onRecentVisitLongClicked() { - interactor.onRecentVisitLongClicked() - - verify { recentVisitsController.handleRecentVisitLongClicked() } - } } diff --git a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt index 806344111..9cf7492be 100644 --- a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt @@ -65,15 +65,6 @@ class TopSiteItemViewHolderTest { verify { interactor.onSelectTopSite(pocket, position = 0) } } - @Test - fun `calls interactor on long click`() { - every { testContext.components.analytics } returns mockk(relaxed = true) - TopSiteItemViewHolder(binding.root, appStore, lifecycleOwner, interactor).bind(pocket, position = 0) - - binding.root.performLongClick() - verify { interactor.onTopSiteMenuOpened() } - } - @Test fun `GIVEN a default top site WHEN bind is called THEN the title has a pin indicator`() { val defaultTopSite = TopSite.Default( diff --git a/app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt b/app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt index 49b6c0be3..288d345b0 100644 --- a/app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt @@ -13,11 +13,11 @@ import io.mockk.mockkObject import io.mockk.unmockkAll import io.mockk.verify import mozilla.components.support.base.log.logger.Logger +import mozilla.components.support.utils.ManufacturerCodes import org.junit.After import org.junit.Before import org.junit.Test import org.mozilla.fenix.helpers.StackTraces -import org.mozilla.fenix.utils.ManufacturerCodes class ThreadPenaltyDeathWithIgnoresListenerTest { diff --git a/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt b/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt index 76f99f64d..e31b2d1d6 100644 --- a/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt @@ -223,13 +223,18 @@ class SearchDialogControllerTest { @Test fun handleEditingCancelled() = runTest { var clearToolbarFocusInvoked = false + var dismissAndGoBack = false createController( clearToolbarFocus = { clearToolbarFocusInvoked = true }, + dismissDialogAndGoBack = { + dismissAndGoBack = true + }, ).handleEditingCancelled() assertTrue(clearToolbarFocusInvoked) + assertTrue(dismissAndGoBack) } @Test @@ -552,6 +557,7 @@ class SearchDialogControllerTest { focusToolbar: () -> Unit = { }, clearToolbar: () -> Unit = { }, dismissDialog: () -> Unit = { }, + dismissDialogAndGoBack: () -> Unit = { }, ): SearchDialogController { return SearchDialogController( activity = activity, @@ -564,6 +570,7 @@ class SearchDialogControllerTest { clearToolbarFocus = clearToolbarFocus, focusToolbar = focusToolbar, clearToolbar = clearToolbar, + dismissDialogAndGoBack = dismissDialogAndGoBack, ) } } diff --git a/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt index da26a2102..e2cff7b99 100644 --- a/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt +++ b/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt @@ -8,15 +8,25 @@ import androidx.fragment.app.Fragment import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController import androidx.navigation.fragment.findNavController +import io.mockk.Called +import io.mockk.Runs import io.mockk.every +import io.mockk.just import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.unmockkStatic +import io.mockk.verify +import mozilla.components.browser.state.search.SearchEngine +import mozilla.components.browser.state.state.SearchState +import mozilla.components.browser.state.state.searchEngines +import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import org.junit.After import org.junit.Assert.assertNull import org.junit.Assert.assertSame import org.junit.Before import org.junit.Test +import org.mozilla.fenix.components.Components +import org.mozilla.fenix.ext.requireComponents internal class SearchDialogFragmentTest { private val navController: NavController = mockk() @@ -78,6 +88,71 @@ internal class SearchDialogFragmentTest { assertSame(fragmentADestination, fragment.getPreviousDestination()) } + + @Test + fun `GIVEN the default search engine is currently selected WHEN checking the need to update the current search engine THEN don't to anything`() { + fragment.interactor = mockk() + val defaultSearchEngine: SearchEngine = mockk { + every { id } returns "default" + } + val otherSearchEngine: SearchEngine = mockk { + every { id } returns "other" + } + val components: Components = mockk { + every { core.store.state.search } returns mockk(relaxed = true) { + every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine) + } + } + mockkStatic( + "org.mozilla.fenix.ext.FragmentKt", + "mozilla.components.browser.state.state.SearchStateKt", + ) { + every { any().requireComponents } returns components + every { any().selectedOrDefaultSearchEngine } returns defaultSearchEngine + + fragment.maybeSelectShortcutEngine(defaultSearchEngine.id) + + verify { fragment.interactor wasNot Called } + } + } + + @Test + fun `GIVEN the default search engine is not currently selected WHEN checking the need to update the current search engine THEN update it to the current engine`() { + fragment.interactor = mockk { + every { onSearchShortcutEngineSelected(any()) } just Runs + } + val defaultSearchEngine: SearchEngine = mockk { + every { id } returns "default" + } + val otherSearchEngine: SearchEngine = mockk { + every { id } returns "other" + } + val components: Components = mockk { + every { core.store.state.search } returns mockk(relaxed = true) { + every { searchEngines } returns listOf(otherSearchEngine, defaultSearchEngine) + } + } + mockkStatic( + "org.mozilla.fenix.ext.FragmentKt", + "mozilla.components.browser.state.state.SearchStateKt", + ) { + every { any().requireComponents } returns components + every { any().selectedOrDefaultSearchEngine } returns defaultSearchEngine + + fragment.maybeSelectShortcutEngine(otherSearchEngine.id) + + verify { fragment.interactor.onSearchShortcutEngineSelected(otherSearchEngine) } + } + } + + @Test + fun `GIVEN the currently selected search engine is unknown WHEN checking the need to update the current search engine THEN don't do anything`() { + fragment.interactor = mockk() + + fragment.maybeSelectShortcutEngine(null) + + verify { fragment.interactor wasNot Called } + } } private val fragmentName = SearchDialogFragment::class.java.canonicalName?.substringAfterLast('.')!! diff --git a/app/src/test/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarActionTest.kt b/app/src/test/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarActionTest.kt index f298205ef..0cb6ade6c 100644 --- a/app/src/test/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarActionTest.kt +++ b/app/src/test/java/org/mozilla/fenix/search/toolbar/SearchSelectorToolbarActionTest.kt @@ -48,7 +48,6 @@ import java.util.UUID @RunWith(FenixRobolectricTestRunner::class) class SearchSelectorToolbarActionTest { - @MockK(relaxed = true) private lateinit var store: SearchDialogFragmentStore @MockK(relaxed = true) @@ -66,6 +65,7 @@ class SearchSelectorToolbarActionTest { @Before fun setup() { MockKAnnotations.init(this) + store = SearchDialogFragmentStore(testSearchFragmentState) every { testContext.settings() } returns settings } @@ -75,6 +75,7 @@ class SearchSelectorToolbarActionTest { val action = spyk( SearchSelectorToolbarAction( store = store, + defaultSearchEngine = null, menu = menu, ), ) @@ -86,7 +87,7 @@ class SearchSelectorToolbarActionTest { assertNotNull(UnifiedSearch.searchMenuTapped.testGetValue()) verify { - menu.menuController.show(view, Orientation.DOWN, true) + menu.menuController.show(view, Orientation.DOWN) } every { settings.shouldUseBottomToolbar } returns true @@ -94,7 +95,7 @@ class SearchSelectorToolbarActionTest { assertNotNull(UnifiedSearch.searchMenuTapped.testGetValue()) verify { - menu.menuController.show(view, Orientation.UP, true) + menu.menuController.show(view, Orientation.UP) } } @@ -103,8 +104,7 @@ class SearchSelectorToolbarActionTest { mockkStatic("org.mozilla.fenix.search.toolbar.SearchSelectorToolbarActionKt") { val searchEngineIcon: BitmapDrawable = mockk(relaxed = true) every { any().getScaledIcon(any()) } returns searchEngineIcon - val store = SearchDialogFragmentStore(testSearchFragmentState) - val selector = SearchSelectorToolbarAction(store, mockk()) + val selector = SearchSelectorToolbarAction(store, mockk(), mockk()) val view = spyk(SearchSelector(testContext)) selector.bind(view) @@ -132,8 +132,7 @@ class SearchSelectorToolbarActionTest { mockkStatic("org.mozilla.fenix.search.toolbar.SearchSelectorToolbarActionKt") { val searchEngineIcon: BitmapDrawable = mockk(relaxed = true) every { any().getScaledIcon(any()) } returns searchEngineIcon - val store = SearchDialogFragmentStore(testSearchFragmentState) - val selector = SearchSelectorToolbarAction(store, mockk()) + val selector = SearchSelectorToolbarAction(store, mockk(), mockk()) val view = spyk(SearchSelector(testContext)) selector.bind(view) @@ -162,8 +161,7 @@ class SearchSelectorToolbarActionTest { mockkStatic("org.mozilla.fenix.search.toolbar.SearchSelectorToolbarActionKt") { val searchEngineIcon: BitmapDrawable = mockk(relaxed = true) every { any().getScaledIcon(any()) } returns searchEngineIcon - val store = SearchDialogFragmentStore(testSearchFragmentState) - val selector = SearchSelectorToolbarAction(store, mockk()) + val selector = SearchSelectorToolbarAction(store, mockk(), mockk()) val view = spyk(SearchSelector(testContext)) // Test an initial change diff --git a/app/src/test/java/org/mozilla/fenix/search/toolbar/ToolbarViewTest.kt b/app/src/test/java/org/mozilla/fenix/search/toolbar/ToolbarViewTest.kt index 422bdfdde..84d2cada4 100644 --- a/app/src/test/java/org/mozilla/fenix/search/toolbar/ToolbarViewTest.kt +++ b/app/src/test/java/org/mozilla/fenix/search/toolbar/ToolbarViewTest.kt @@ -11,12 +11,14 @@ import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockk +import io.mockk.mockkObject import io.mockk.spyk import io.mockk.verify import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.browser.toolbar.edit.EditToolbar import mozilla.components.concept.engine.Engine +import mozilla.components.concept.toolbar.Toolbar import mozilla.components.support.test.robolectric.testContext import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -24,12 +26,14 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.MetricsUtils +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.search.SearchEngineSource import org.mozilla.fenix.search.SearchFragmentState -import org.mozilla.fenix.utils.Settings +import java.util.UUID @RunWith(FenixRobolectricTestRunner::class) class ToolbarViewTest { @@ -49,6 +53,7 @@ class ToolbarViewTest { every { name } returns "Search Engine" every { icon } returns testContext.getDrawable(R.drawable.ic_search)!!.toBitmap() every { type } returns SearchEngine.Type.BUNDLED + every { isGeneral } returns true }, ), defaultEngine = null, @@ -69,6 +74,7 @@ class ToolbarViewTest { fun setup() { MockKAnnotations.init(this) context = ContextThemeWrapper(testContext, R.style.NormalTheme) + every { context.settings() } returns mockk(relaxed = true) toolbar = spyk(BrowserToolbar(context)) } @@ -113,6 +119,31 @@ class ToolbarViewTest { verify(exactly = 2) { interactor.onTextChanged(any()) } } + @Test + fun `GIVEN search term is set WHEN switching to edit mode THEN the cursor is set at the end of the search term`() { + every { context.settings().showUnifiedSearchFeature } returns true + val view = buildToolbarView(false) + mockkObject(FeatureFlags) + + view.update(defaultState.copy(searchTerms = "search terms")) + + // editMode gets called when the view is initialized. + verify(exactly = 1) { toolbar.editMode(Toolbar.CursorPlacement.ALL) } + verify(exactly = 1) { toolbar.editMode(Toolbar.CursorPlacement.END) } + } + + @Test + fun `GIVEN no search term is set WHEN switching to edit mode THEN the cursor is set at the end of the search term`() { + every { context.settings().showUnifiedSearchFeature } returns true + val view = buildToolbarView(false) + mockkObject(FeatureFlags) + + view.update(defaultState) + + // editMode gets called when the view is initialized. + verify(exactly = 2) { toolbar.editMode(Toolbar.CursorPlacement.ALL) } + } + @Test fun `URL gets set to the states query`() { val toolbarView = buildToolbarView(false) @@ -158,12 +189,81 @@ class ToolbarViewTest { verify { editToolbar.setIcon(any(), "Search Engine") } } + @Test + fun `GIVEN a general search engine is default WHEN a topic specific engine is selected THEN the hint changes`() { + val topicSpecificEngine = buildSearchEngine(SearchEngine.Type.BUNDLED, false) + val toolbarView = buildToolbarView(false) + toolbarView.update(defaultState) + assertEquals(context.getString(R.string.search_hint), toolbarView.view.edit.hint) + + toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Default(topicSpecificEngine))) + + assertEquals(context.getString(R.string.application_search_hint), toolbarView.view.edit.hint) + } + + @Test + fun `GIVEN a topic specific engine is default WHEN a general engine is selected THEN the hint changes`() { + val topicSpecificEngine = buildSearchEngine(SearchEngine.Type.BUNDLED, false) + val toolbarView = buildToolbarView(false) + toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Default(topicSpecificEngine))) + assertEquals(context.getString(R.string.application_search_hint), toolbarView.view.edit.hint) + + toolbarView.update(defaultState) + + assertEquals(context.getString(R.string.search_hint), toolbarView.view.edit.hint) + } + + @Test + fun `GIVEN a topic specific engine is default WHEN a custom engine is selected THEN the hint changes`() { + val topicSpecificEngine = buildSearchEngine(SearchEngine.Type.BUNDLED, false) + val customEngine = buildSearchEngine(SearchEngine.Type.CUSTOM, true) + val toolbarView = buildToolbarView(false) + toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Default(topicSpecificEngine))) + assertEquals(context.getString(R.string.application_search_hint), toolbarView.view.edit.hint) + + toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Default(customEngine))) + + assertEquals(context.getString(R.string.search_hint), toolbarView.view.edit.hint) + } + + @Test + fun `GIVEN a general engine is default WHEN a custom engine is selected THEN the hint does not change`() { + val customEngine = buildSearchEngine(SearchEngine.Type.CUSTOM, true) + val toolbarView = buildToolbarView(false) + toolbarView.update(defaultState) + assertEquals(context.getString(R.string.search_hint), toolbarView.view.edit.hint) + + toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Default(customEngine))) + + assertEquals(context.getString(R.string.search_hint), toolbarView.view.edit.hint) + } + + @Test + fun `GIVEN a custom engine is default WHEN a general engine is selected THEN the hint does not change`() { + val customEngine = buildSearchEngine(SearchEngine.Type.CUSTOM, true) + val toolbarView = buildToolbarView(false) + toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Default(customEngine))) + assertEquals(context.getString(R.string.search_hint), toolbarView.view.edit.hint) + + toolbarView.update(defaultState) + + assertEquals(context.getString(R.string.search_hint), toolbarView.view.edit.hint) + } + private fun buildToolbarView(isPrivate: Boolean) = ToolbarView( context, - Settings(context), + context.settings(), interactor, isPrivate = isPrivate, view = toolbar, fromHomeFragment = false, ) + + private fun buildSearchEngine(type: SearchEngine.Type, isGeneral: Boolean) = SearchEngine( + id = UUID.randomUUID().toString(), + name = "General", + icon = testContext.getDrawable(R.drawable.ic_search)!!.toBitmap(), + type = type, + isGeneral = isGeneral, + ) } diff --git a/app/src/test/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStoreTest.kt b/app/src/test/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStoreTest.kt index 8a0588975..664a44f07 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStoreTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/advanced/LocaleSettingsStoreTest.kt @@ -42,4 +42,15 @@ class LocaleSettingsStoreTest { assertEquals(2, (localeSettingsStore.state.searchedLocaleList as ArrayList).size) assertEquals(selectedLocale, localeSettingsStore.state.searchedLocaleList[1]) } + + @Test + fun `GIVEN search list is amended WHEN locale selected THEN reset search list`() = runTest { + localeSettingsStore.dispatch(LocaleSettingsAction.Search("Eng")).join() + assertEquals(2, (localeSettingsStore.state.searchedLocaleList as ArrayList).size) + + localeSettingsStore.dispatch(LocaleSettingsAction.Search("fr")).join() + localeSettingsStore.dispatch(LocaleSettingsAction.Select(otherLocale)).join() + + assertEquals(localeSettingsStore.state.localeList.size, localeSettingsStore.state.searchedLocaleList.size) + } } diff --git a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultConnectionDetailsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultConnectionDetailsControllerTest.kt index 4685ea80a..e543b6ccc 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultConnectionDetailsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultConnectionDetailsControllerTest.kt @@ -27,6 +27,7 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @RunWith(FenixRobolectricTestRunner::class) @@ -87,6 +88,8 @@ class DefaultConnectionDetailsControllerTest { @Test fun `WHEN handleBackPressed is called THEN should call popBackStack and navigate`() { + every { context.settings().shouldUseCookieBanner } returns true + controller.handleBackPressed() verify { diff --git a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsViewTest.kt b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsViewTest.kt index dfa9e90f3..14b598506 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsViewTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/CookieBannerHandlingDetailsViewTest.kt @@ -6,18 +6,23 @@ package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners import android.widget.FrameLayout import io.mockk.MockKAnnotations +import io.mockk.coEvery import io.mockk.impl.annotations.MockK import io.mockk.mockk import io.mockk.spyk import io.mockk.verify +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.test.advanceUntilIdle import mozilla.components.browser.state.state.createTab import mozilla.components.lib.publicsuffixlist.PublicSuffixList -import mozilla.components.support.ktx.kotlin.toShortUrl import mozilla.components.support.test.robolectric.testContext +import mozilla.components.support.test.rule.MainCoroutineRule +import mozilla.components.support.test.rule.runTestOnMain import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.R @@ -35,6 +40,10 @@ class CookieBannerHandlingDetailsViewTest { @MockK(relaxed = true) private lateinit var publicSuffixList: PublicSuffixList + @get:Rule + val coroutinesTestRule = MainCoroutineRule() + private val scope = coroutinesTestRule.scope + @Before fun setup() { MockKAnnotations.init(this) @@ -45,6 +54,7 @@ class CookieBannerHandlingDetailsViewTest { context = testContext, publicSuffixList = publicSuffixList, interactor = interactor, + ioScope = scope, ), ) binding = view.binding @@ -74,34 +84,42 @@ class CookieBannerHandlingDetailsViewTest { } @Test - fun `GIVEN cookie banner handling is enabled WHEN biding title THEN title view must have the expected string`() { - val websiteUrl = "https://mozilla.org" + fun `GIVEN cookie banner handling is enabled WHEN biding title THEN title view must have the expected string`() = + runTestOnMain { + coEvery { publicSuffixList.getPublicSuffixPlusOne(any()) } returns CompletableDeferred("mozilla.org") - view.bindTitle(url = websiteUrl, isCookieBannerHandlingEnabled = true) + val websiteUrl = "https://mozilla.org" - val expectedText = - testContext.getString( - R.string.reduce_cookie_banner_details_panel_title_off_for_site, - websiteUrl.toShortUrl(publicSuffixList), - ) + view.bindTitle(url = websiteUrl, isCookieBannerHandlingEnabled = true) - assertEquals(expectedText, view.binding.title.text) - } + val expectedText = + testContext.getString( + R.string.reduce_cookie_banner_details_panel_title_off_for_site, + "mozilla.org", + ) + + assertEquals(expectedText, view.binding.title.text) + } @Test - fun `GIVEN cookie banner handling is disabled WHEN biding title THEN title view must have the expected string`() { - val websiteUrl = "https://mozilla.org" + fun `GIVEN cookie banner handling is disabled WHEN biding title THEN title view must have the expected string`() = + runTestOnMain { + coEvery { publicSuffixList.getPublicSuffixPlusOne(any()) } returns CompletableDeferred("mozilla.org") - view.bindTitle(url = websiteUrl, isCookieBannerHandlingEnabled = false) + val websiteUrl = "https://mozilla.org" - val expectedText = - testContext.getString( - R.string.reduce_cookie_banner_details_panel_title_on_for_site, - websiteUrl.toShortUrl(publicSuffixList), - ) + view.bindTitle(url = websiteUrl, isCookieBannerHandlingEnabled = false) - assertEquals(expectedText, view.binding.title.text) - } + advanceUntilIdle() + + val expectedText = + testContext.getString( + R.string.reduce_cookie_banner_details_panel_title_on_for_site, + "mozilla.org", + ) + + assertEquals(expectedText, view.binding.title.text) + } @Test fun `WHEN clicking the back button THEN view must delegate to the interactor#onBackPressed()`() { @@ -131,9 +149,12 @@ class CookieBannerHandlingDetailsViewTest { fun `GIVEN cookie banner handling is disabled WHEN biding description THEN description view must have the expected string`() { view.bindDescription(isCookieBannerHandlingEnabled = false) + val appName = testContext.getString(R.string.app_name) val expectedText = testContext.getString( - R.string.reduce_cookie_banner_details_panel_description_on_for_site, + R.string.reduce_cookie_banner_details_panel_description_on_for_site_1, + appName, + appName, ) assertEquals(expectedText, view.binding.details.text) diff --git a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/DefaultCookieBannerDetailsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/DefaultCookieBannerDetailsControllerTest.kt index 1745a52a3..7548266f9 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/DefaultCookieBannerDetailsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/DefaultCookieBannerDetailsControllerTest.kt @@ -9,22 +9,28 @@ import androidx.fragment.app.Fragment import androidx.navigation.NavController import androidx.navigation.NavDirections import io.mockk.MockKAnnotations +import io.mockk.Runs +import io.mockk.coEvery import io.mockk.coVerifyOrder import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.just import io.mockk.mockk import io.mockk.slot import io.mockk.spyk import io.mockk.verify +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.test.advanceUntilIdle import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.cookiehandling.CookieBannersStorage import mozilla.components.concept.engine.permission.SitePermissions import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.TrackingProtectionUseCases +import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.service.glean.testing.GleanTestRule import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.rule.MainCoroutineRule @@ -37,6 +43,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.GleanMetrics.CookieBanners import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.trackingprotection.ProtectionsAction import org.mozilla.fenix.trackingprotection.ProtectionsStore @@ -70,6 +77,12 @@ internal class DefaultCookieBannerDetailsControllerTest { @MockK(relaxed = true) private lateinit var reload: SessionUseCases.ReloadUrlUseCase + @MockK(relaxed = true) + private lateinit var engine: Engine + + @MockK(relaxed = true) + private lateinit var publicSuffixList: PublicSuffixList + private var gravity = 54 @get:Rule @@ -86,19 +99,23 @@ internal class DefaultCookieBannerDetailsControllerTest { context = spyk(testContext) tab = createTab("https://mozilla.org") browserStore = BrowserStore(BrowserState(tabs = listOf(tab))) - controller = DefaultCookieBannerDetailsController( - fragment = fragment, - context = context, - ioScope = scope, - cookieBannersStorage = cookieBannersStorage, - navController = { navController }, - sitePermissions = sitePermissions, - gravity = gravity, - getCurrentTab = { tab }, - sessionId = tab.id, - browserStore = browserStore, - protectionsStore = protectionsStore, - reload = reload, + controller = spyk( + DefaultCookieBannerDetailsController( + fragment = fragment, + context = context, + ioScope = scope, + cookieBannersStorage = cookieBannersStorage, + navController = { navController }, + sitePermissions = sitePermissions, + gravity = gravity, + getCurrentTab = { tab }, + sessionId = tab.id, + browserStore = browserStore, + protectionsStore = protectionsStore, + engine = engine, + publicSuffixList = publicSuffixList, + reload = reload, + ), ) every { fragment.context } returns context @@ -115,6 +132,8 @@ internal class DefaultCookieBannerDetailsControllerTest { @Test fun `WHEN handleBackPressed is called THEN should call popBackStack and navigate`() { + every { context.settings().shouldUseCookieBanner } returns true + controller.handleBackPressed() verify { @@ -159,12 +178,14 @@ internal class DefaultCookieBannerDetailsControllerTest { assertNull(CookieBanners.exceptionRemoved.testGetValue()) every { protectionsStore.dispatch(any()) } returns mockk() + coEvery { controller.clearSiteData(any()) } just Runs controller.handleTogglePressed(isEnabled) advanceUntilIdle() coVerifyOrder { + controller.clearSiteData(tab) cookieBannersStorage.addException( uri = tab.content.url, privateBrowsing = tab.content.private, @@ -179,4 +200,22 @@ internal class DefaultCookieBannerDetailsControllerTest { assertNotNull(CookieBanners.exceptionAdded.testGetValue()) } + + @Test + fun `WHEN clearSiteData THEN delegate the call to the engine`() = + runTestOnMain { + coEvery { publicSuffixList.getPublicSuffixPlusOne(any()) } returns CompletableDeferred("mozilla.org") + + controller.clearSiteData(tab) + + coVerifyOrder { + engine.clearData( + host = "mozilla.org", + data = Engine.BrowsingData.select( + Engine.BrowsingData.AUTH_SESSIONS, + Engine.BrowsingData.ALL_SITE_DATA, + ), + ) + } + } } diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt index 6b6fcea9c..e786bad45 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt @@ -22,6 +22,8 @@ import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.content.DownloadState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.browser.storage.sync.Tab +import mozilla.components.browser.storage.sync.TabEntry import mozilla.components.concept.base.profiler.Profiler import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.service.glean.testing.GleanTestRule @@ -35,7 +37,10 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mozilla.fenix.BrowserDirection +import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.TabsTray +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @@ -64,6 +69,9 @@ class DefaultTabsTrayControllerTest { @MockK(relaxed = true) private lateinit var tabsUseCases: TabsUseCases + @MockK(relaxed = true) + private lateinit var activity: HomeActivity + @get:Rule val gleanTestRule = GleanTestRule(testContext) @@ -475,6 +483,34 @@ class DefaultTabsTrayControllerTest { assertTrue(navigateToHomeAndDeleteSessionInvoked) } + @Test + fun `WHEN a synced tab is clicked THEN the metrics are reported and the tab is opened`() { + val tab = mockk() + val entry = mockk() + assertNull(Events.syncedTabOpened.testGetValue()) + + every { tab.active() }.answers { entry } + every { entry.url }.answers { "https://mozilla.org" } + + var dismissTabTrayInvoked = false + createController( + dismissTray = { + dismissTabTrayInvoked = true + }, + ).handleSyncedTabClicked(tab) + + assertTrue(dismissTabTrayInvoked) + assertNotNull(Events.syncedTabOpened.testGetValue()) + + verify { + activity.openToBrowserAndLoad( + searchTermOrURL = "https://mozilla.org", + newTab = true, + from = BrowserDirection.FromTabsTray, + ) + } + } + private fun createController( navigateToHomeAndDeleteSession: (String) -> Unit = { }, selectTabPosition: (Int, Boolean) -> Unit = { _, _ -> }, @@ -483,6 +519,7 @@ class DefaultTabsTrayControllerTest { showCancelledDownloadWarning: (Int, String?, String?) -> Unit = { _, _, _ -> }, ): DefaultTabsTrayController { return DefaultTabsTrayController( + activity, trayStore, browserStore, browsingModeManager, diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/FloatingActionButtonBindingTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/FloatingActionButtonBindingTest.kt index 44a8ba805..c759832bf 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/FloatingActionButtonBindingTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/FloatingActionButtonBindingTest.kt @@ -28,7 +28,7 @@ class FloatingActionButtonBindingTest { val coroutinesTestRule = MainCoroutineRule() private val actionButton: ExtendedFloatingActionButton = mockk(relaxed = true) - private val browserTrayInteractor: BrowserTrayInteractor = mockk(relaxed = true) + private val interactor: BrowserTrayInteractor = mockk(relaxed = true) @Before fun setup() { @@ -47,7 +47,7 @@ class FloatingActionButtonBindingTest { val fabBinding = FloatingActionButtonBinding( tabsTrayStore, actionButton, - browserTrayInteractor, + interactor, ) fabBinding.start() @@ -64,7 +64,7 @@ class FloatingActionButtonBindingTest { val fabBinding = FloatingActionButtonBinding( tabsTrayStore, actionButton, - browserTrayInteractor, + interactor, ) fabBinding.start() @@ -81,7 +81,7 @@ class FloatingActionButtonBindingTest { val fabBinding = FloatingActionButtonBinding( tabsTrayStore, actionButton, - browserTrayInteractor, + interactor, ) fabBinding.start() @@ -98,7 +98,7 @@ class FloatingActionButtonBindingTest { val fabBinding = FloatingActionButtonBinding( tabsTrayStore, actionButton, - browserTrayInteractor, + interactor, ) fabBinding.start() diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt index f47127d32..100ed970e 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt @@ -20,7 +20,6 @@ import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.content.DownloadState import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.browser.storage.sync.TabEntry import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.glean.testing.GleanTestRule import mozilla.components.support.test.robolectric.testContext @@ -35,17 +34,14 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.RuleChain import org.junit.runner.RunWith -import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.TabsTray -import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.collections.CollectionsDialog import org.mozilla.fenix.collections.show import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.bookmarks.BookmarksUseCase import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import mozilla.components.browser.state.state.createTab as createStateTab -import mozilla.components.browser.storage.sync.Tab as SyncTab @RunWith(FenixRobolectricTestRunner::class) // for gleanTestRule class NavigationInteractorTest { @@ -57,7 +53,6 @@ class NavigationInteractorTest { private val context: Context = mockk(relaxed = true) private val collectionStorage: TabCollectionStorage = mockk(relaxed = true) private val accountManager: FxaAccountManager = mockk(relaxed = true) - private val activity: HomeActivity = mockk(relaxed = true) val coroutinesTestRule: MainCoroutineRule = MainCoroutineRule() val gleanTestRule = GleanTestRule(testContext) @@ -220,34 +215,6 @@ class NavigationInteractorTest { Assert.assertEquals("1", snapshot.single().extra?.getValue("tab_count")) } - @Test - fun `onSyncedTabsClicked sets metrics and opens browser`() { - val tab = mockk() - val entry = mockk() - assertNull(Events.syncedTabOpened.testGetValue()) - - every { tab.active() }.answers { entry } - every { entry.url }.answers { "https://mozilla.org" } - - var dismissTabTrayInvoked = false - createInteractor( - dismissTabTray = { - dismissTabTrayInvoked = true - }, - ).onSyncedTabClicked(tab) - - assertTrue(dismissTabTrayInvoked) - assertNotNull(Events.syncedTabOpened.testGetValue()) - - verify { - activity.openToBrowserAndLoad( - searchTermOrURL = "https://mozilla.org", - newTab = true, - from = BrowserDirection.FromTabsTray, - ) - } - } - @Suppress("LongParameterList") private fun createInteractor( browserStore: BrowserStore = store, @@ -259,7 +226,6 @@ class NavigationInteractorTest { ): NavigationInteractor { return DefaultNavigationInteractor( context, - activity, browserStore, navController, dismissTabTray, diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolderTest.kt index 7b0739579..e60e75566 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolderTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/browser/AbstractBrowserTabViewHolderTest.kt @@ -165,7 +165,7 @@ class AbstractBrowserTabViewHolderTest { trayStore: TabsTrayStore, selectionHolder: SelectionHolder?, store: BrowserStore, - override val browserTrayInteractor: BrowserTrayInteractor, + override val interactor: BrowserTrayInteractor, featureName: String = "Test", ) : AbstractBrowserTabViewHolder(itemView, imageLoader, trayStore, selectionHolder, featureName, store) { override val thumbnailSize: Int diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapterTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapterTest.kt index 2ae860877..3d9dc53cd 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapterTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapterTest.kt @@ -64,7 +64,7 @@ class BrowserTabsAdapterTest { val holder = spyk( BrowserTabViewHolder.ListViewHolder( imageLoader = mockk(), - browserTrayInteractor = interactor, + interactor = interactor, store = store, selectionHolder = null, itemView = binding.root, diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsControllerTest.kt index 4241a8668..29f1fca1b 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsControllerTest.kt @@ -47,7 +47,7 @@ class DefaultInactiveTabsControllerTest { assertNull(TabsTrayMetrics.inactiveTabsExpanded.testGetValue()) assertNull(TabsTrayMetrics.inactiveTabsCollapsed.testGetValue()) - controller.updateCardExpansion(isExpanded = true) + controller.handleInactiveTabsHeaderClicked(expanded = true) assertNotNull(TabsTrayMetrics.inactiveTabsExpanded.testGetValue()) assertNull(TabsTrayMetrics.inactiveTabsCollapsed.testGetValue()) @@ -60,7 +60,7 @@ class DefaultInactiveTabsControllerTest { assertNull(TabsTrayMetrics.inactiveTabsExpanded.testGetValue()) assertNull(TabsTrayMetrics.inactiveTabsCollapsed.testGetValue()) - controller.updateCardExpansion(isExpanded = false) + controller.handleInactiveTabsHeaderClicked(expanded = false) assertNull(TabsTrayMetrics.inactiveTabsExpanded.testGetValue()) assertNotNull(TabsTrayMetrics.inactiveTabsCollapsed.testGetValue()) @@ -72,7 +72,7 @@ class DefaultInactiveTabsControllerTest { assertNull(TabsTrayMetrics.autoCloseDimissed.testGetValue()) - controller.dismissAutoCloseDialog() + controller.handleInactiveTabsAutoCloseDialogDismiss() assertNotNull(TabsTrayMetrics.autoCloseDimissed.testGetValue()) verify { settings.hasInactiveTabsAutoCloseDialogBeenDismissed = true } @@ -84,7 +84,7 @@ class DefaultInactiveTabsControllerTest { assertNull(TabsTrayMetrics.autoCloseTurnOnClicked.testGetValue()) - controller.enableInactiveTabsAutoClose() + controller.handleEnableInactiveTabsAutoCloseClicked() assertNotNull(TabsTrayMetrics.autoCloseTurnOnClicked.testGetValue()) @@ -107,7 +107,7 @@ class DefaultInactiveTabsControllerTest { assertNull(TabsTrayMetrics.openInactiveTab.testGetValue()) - controller.openInactiveTab(tab) + controller.handleInactiveTabClicked(tab) assertNotNull(TabsTrayMetrics.openInactiveTab.testGetValue()) } @@ -124,7 +124,7 @@ class DefaultInactiveTabsControllerTest { assertNull(TabsTrayMetrics.closeInactiveTab.testGetValue()) - controller.closeInactiveTab(tab) + controller.handleCloseInactiveTabClicked(tab) assertNotNull(TabsTrayMetrics.closeInactiveTab.testGetValue()) } @@ -152,7 +152,7 @@ class DefaultInactiveTabsControllerTest { every { browserStore.state.potentialInactiveTabs } returns listOf(inactiveTab) assertNull(TabsTrayMetrics.closeAllInactiveTabs.testGetValue()) - controller.deleteAllInactiveTabs() + controller.handleDeleteAllInactiveTabsClicked() verify { tabsUseCases.removeTabs(listOf("24")) } assertNotNull(TabsTrayMetrics.closeAllInactiveTabs.testGetValue()) diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt index d90cf4f18..2e0a2347a 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt @@ -18,23 +18,23 @@ class DefaultInactiveTabsInteractorTest { @Test fun `WHEN the inactive tabs header is clicked THEN update the expansion state of the inactive tabs card`() { - createInteractor().onHeaderClicked(true) + createInteractor().onInactiveTabsHeaderClicked(true) - verify { controller.updateCardExpansion(true) } + verify { controller.handleInactiveTabsHeaderClicked(true) } } @Test fun `WHEN the inactive tabs auto close dialog's close button is clicked THEN dismiss the dialog`() { - createInteractor().onCloseClicked() + createInteractor().onAutoCloseDialogCloseButtonClicked() - verify { controller.dismissAutoCloseDialog() } + verify { controller.handleInactiveTabsAutoCloseDialogDismiss() } } @Test fun `WHEN the enable inactive tabs auto close button is clicked THEN turn on the auto close feature`() { - createInteractor().onEnabledAutoCloseClicked() + createInteractor().onEnableAutoCloseClicked() - verify { controller.enableInactiveTabsAutoClose() } + verify { controller.handleEnableInactiveTabsAutoCloseClicked() } } @Test @@ -46,9 +46,9 @@ class DefaultInactiveTabsInteractorTest { ), ) - createInteractor().onTabClicked(tab) + createInteractor().onInactiveTabClicked(tab) - verify { controller.openInactiveTab(tab) } + verify { controller.handleInactiveTabClicked(tab) } verify { browserInteractor.onTabSelected(tab, TrayPagerAdapter.INACTIVE_TABS_FEATURE_NAME) } } @@ -61,9 +61,9 @@ class DefaultInactiveTabsInteractorTest { ), ) - createInteractor().onTabClosed(tab) + createInteractor().onInactiveTabClosed(tab) - verify { controller.closeInactiveTab(tab) } + verify { controller.handleCloseInactiveTabClicked(tab) } verify { browserInteractor.onTabClosed(tab, TrayPagerAdapter.INACTIVE_TABS_FEATURE_NAME) } } @@ -71,7 +71,7 @@ class DefaultInactiveTabsInteractorTest { fun `WHEN the close all inactive tabs button is clicked THEN delete all inactive tabs`() { createInteractor().onDeleteAllInactiveTabsClicked() - verify { controller.deleteAllInactiveTabs() } + verify { controller.handleDeleteAllInactiveTabsClicked() } } private fun createInteractor(): DefaultInactiveTabsInteractor { diff --git a/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractorTest.kt index 13bfc0937..20f1d2751 100644 --- a/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelInteractorTest.kt @@ -30,6 +30,7 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @RunWith(FenixRobolectricTestRunner::class) @@ -139,6 +140,8 @@ class TrackingProtectionPanelInteractorTest { @Test fun `WHEN onBackPressed is called THEN call popBackStack and navigate`() = runTestOnMain { + every { context.settings().shouldUseCookieBanner } returns true + interactor.onBackPressed() coVerify { diff --git a/app/src/test/java/org/mozilla/fenix/utils/ManufacturerCodesTest.kt b/app/src/test/java/org/mozilla/fenix/utils/ManufacturerCodesTest.kt deleted file mode 100644 index 3b67c4d9f..000000000 --- a/app/src/test/java/org/mozilla/fenix/utils/ManufacturerCodesTest.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.utils - -import android.os.Build -import org.junit.After -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Test -import java.lang.reflect.Modifier - -class ManufacturerCodesTest { - - private val manufacturerField = Build::class.java.getDeclaredField("MANUFACTURER") - private var manufacturer: String? - get() = Build.MANUFACTURER - set(value) { manufacturerField.set(null, value) } - - @Before - fun setUp() { - enableManufacturerModifications() - manufacturer = null // reset to default state before test. - assertEquals(null, Build.MANUFACTURER) // sanity check. - } - - private fun enableManufacturerModifications() { - // Mocking, which might be simpler, doesn't seem to work so we use reflection. - // Methodology via https://stackoverflow.com/a/3301720/2219998 - manufacturerField.isAccessible = true - val modifiers = manufacturerField.javaClass.getDeclaredField("modifiers") - modifiers.isAccessible = true - modifiers.setInt(manufacturerField, manufacturerField.modifiers and Modifier.FINAL.inv()) - } - - @After - fun tearDown() { - // After this method, Build.MANUFACTURER appears to return to - // static final so we don't need to undo that. - manufacturer = null - assertEquals(null, Build.MANUFACTURER) // sanity check. - } - - @Test // To reduce boilerplate, we avoid best practice and put several tests in one. - fun testIsLG() { - manufacturer = "LGE" // expected value for lg devices - assertTrue(ManufacturerCodes.isLG) - - manufacturer = "lge" // unexpected value but is still an lg device - assertTrue(ManufacturerCodes.isLG) - - manufacturer = "samsung" - assertFalse(ManufacturerCodes.isLG) - } - - @Test // To reduce boilerplate, we avoid best practice and put several tests in one. - fun testIsSamsung() { - manufacturer = "samsung" // expected value for samsung devices - assertTrue(ManufacturerCodes.isSamsung) - - manufacturer = "SaMsUnG" // unexpected value but is still a samsung device - assertTrue(ManufacturerCodes.isSamsung) - - manufacturer = "LGE" - assertFalse(ManufacturerCodes.isSamsung) - } -} diff --git a/automation/taskcluster/androidTest/flank-arm-legacy-api-tests.yml b/automation/taskcluster/androidTest/flank-arm-legacy-api-tests.yml index 7f7fb0342..670dba44a 100644 --- a/automation/taskcluster/androidTest/flank-arm-legacy-api-tests.yml +++ b/automation/taskcluster/androidTest/flank-arm-legacy-api-tests.yml @@ -20,15 +20,37 @@ gcloud: performance-metrics: true test-targets: + - notPackage org.mozilla.fenix.screenshots + - notPackage org.mozilla.fenix.syncintegration + - class org.mozilla.fenix.ui.NavigationToolbarTest#visitURLTest + - class org.mozilla.fenix.ui.NavigationToolbarTest#goBackTest + - class org.mozilla.fenix.ui.NavigationToolbarTest#goForwardTest + - class org.mozilla.fenix.ui.HistoryTest#visitedUrlHistoryTest + - class org.mozilla.fenix.ui.SmokeTest#openMainMenuSettingsItemTest + - class org.mozilla.fenix.ui.SettingsSearchTest#toggleSearchSuggestionsTest + - class org.mozilla.fenix.ui.CollectionTest#deleteCollectionTest + - class org.mozilla.fenix.ui.SmokeTest#noHistoryInPrivateBrowsingTest + - class org.mozilla.fenix.ui.SmokeTest#verifyBasicNavigationToolbarFunctionality + - class org.mozilla.fenix.ui.TabbedBrowsingTest#openNewTabTest + - class org.mozilla.fenix.ui.TabbedBrowsingTest#openNewPrivateTabTest + - class org.mozilla.fenix.ui.TopSitesTest#verifyOpenTopSiteNormalTab + - class org.mozilla.fenix.ui.BookmarksTest#addBookmarkTest + - class org.mozilla.fenix.ui.HomeScreenTest#homeScreenItemsTest device: - model: Pixel2.arm + version: 26 + locale: en_US + - model: walleye + version: 27 + locale: en_US + - model: dreamlte version: 28 locale: en_US flank: project: GOOGLE_PROJECT - max-test-shards: 2 + max-test-shards: 50 num-test-runs: 1 output-style: compact full-junit-result: true diff --git a/automation/taskcluster/androidTest/flank-arm64-v8a.yml b/automation/taskcluster/androidTest/flank-arm64-v8a.yml index 09e2b730f..d15fd84dd 100644 --- a/automation/taskcluster/androidTest/flank-arm64-v8a.yml +++ b/automation/taskcluster/androidTest/flank-arm64-v8a.yml @@ -29,7 +29,7 @@ gcloud: flank: project: GOOGLE_PROJECT - max-test-shards: 50 + max-test-shards: 100 num-test-runs: 1 output-style: compact full-junit-result: true diff --git a/automation/taskcluster/androidTest/parse-ui-test.py b/automation/taskcluster/androidTest/parse-ui-test.py index 517c76e6e..2f67ccbe7 100644 --- a/automation/taskcluster/androidTest/parse-ui-test.py +++ b/automation/taskcluster/androidTest/parse-ui-test.py @@ -2,12 +2,14 @@ from __future__ import print_function -import sys import argparse -from pathlib import Path import json +import sys +from pathlib import Path + import yaml + def parse_args(cmdln_args): parser = argparse.ArgumentParser(description="Parse UI test logs an results") parser.add_argument( @@ -41,8 +43,6 @@ def main(): log = args.log.read() matrix_ids = json.loads(args.results.joinpath("matrix_ids.json").read_text()) - #with args.results.joinpath("flank.yml") as f: - # flank_config = yaml.safe_load(f) android_args = extract_android_args(log) @@ -52,10 +52,12 @@ def main(): print(yaml.safe_dump(android_args["gcloud"]["device"])) print("# Results\n") - print("| matrix | result | logs | details \n") + print("| Matrix | Result | Firebase Test Lab | Details\n") print("| --- | --- | --- | --- |\n") for matrix, matrix_result in matrix_ids.items(): - print("| {matrixId} | {outcome} | [logs]({webLink}) | {axes[0][details]}\n".format(**matrix_result)) + for axis in matrix_result["axes"]: + print(f"| {matrix_result['matrixId']} | {matrix_result['outcome']}" + f"| [Firebase Test Lab]({matrix_result['webLink']}) | {axis['details']}\n") print("---\n") print("# References & Documentation\n") print("* [Automated UI Testing Documentation](https://github.com/mozilla-mobile/shared-docs/blob/main/android/ui-testing.md)\n") @@ -64,4 +66,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/build.gradle b/build.gradle index 3241aff78..144ee5c28 100644 --- a/build.gradle +++ b/build.gradle @@ -60,14 +60,14 @@ buildscript { } dependencies { - classpath Deps.tools_androidgradle - classpath Deps.tools_kotlingradle - classpath Deps.tools_benchmarkgradle - classpath Deps.androidx_safeargs - classpath Deps.osslicenses_plugin + classpath FenixDependencies.tools_androidgradle + classpath FenixDependencies.tools_kotlingradle + classpath FenixDependencies.tools_benchmarkgradle + classpath FenixDependencies.androidx_safeargs + classpath FenixDependencies.osslicenses_plugin - classpath "org.mozilla.components:tooling-glean-gradle:${Versions.mozilla_android_components}" - classpath "org.mozilla.components:tooling-nimbus-gradle:${Versions.mozilla_android_components}" + classpath "org.mozilla.components:tooling-glean-gradle:${FenixVersions.mozilla_android_components}" + classpath "org.mozilla.components:tooling-nimbus-gradle:${FenixVersions.mozilla_android_components}" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -197,7 +197,7 @@ dependencies { } detekt project(":mozilla-detekt-rules") - detekt "io.gitlab.arturbosch.detekt:detekt-cli:${Versions.detekt}" + detekt "io.gitlab.arturbosch.detekt:detekt-cli:${FenixVersions.detekt}" } tasks.register('ktlint', JavaExec) { diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 88dd82bae..2c2d0197c 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "109.2.0" + const val VERSION = "110.0.1" } diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 81bb5ca82..af5b29598 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -3,9 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // If you ever need to force a toolchain rebuild (taskcluster) then edit the following comment. -// FORCE REBUILD 2022-09-16 +// FORCE REBUILD 2022-12-11 -object Versions { +object FenixVersions { const val kotlin = "1.7.20" const val coroutines = "1.6.4" @@ -14,7 +14,7 @@ object Versions { const val android_gradle_plugin = "7.3.0" const val android_lint_api = "30.3.0" - const val sentry = "6.8.0" + const val sentry = "6.11.0" const val leakcanary = "2.10" const val osslicenses_plugin = "0.10.4" const val detekt = "1.19.0" @@ -63,171 +63,171 @@ object Versions { } @Suppress("unused") -object Deps { - const val tools_androidgradle = "com.android.tools.build:gradle:${Versions.android_gradle_plugin}" - const val tools_kotlingradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}" - const val tools_benchmarkgradle = "androidx.benchmark:benchmark-gradle-plugin:${Versions.androidx_benchmark}" - const val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}" - const val kotlin_stdlib_jdk8 = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Versions.kotlin}" - const val kotlin_reflect = "org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlin}" - const val kotlin_coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.coroutines}" - const val kotlin_coroutines_test = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${Versions.coroutines}" - const val kotlin_coroutines_android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutines}" - - const val osslicenses_plugin = "com.google.android.gms:oss-licenses-plugin:${Versions.osslicenses_plugin}" - - const val mozilla_compose_awesomebar = "org.mozilla.components:compose-awesomebar:${Versions.mozilla_android_components}" - - const val mozilla_concept_awesomebar = "org.mozilla.components:concept-awesomebar:${Versions.mozilla_android_components}" - const val mozilla_concept_base = "org.mozilla.components:concept-base:${Versions.mozilla_android_components}" - const val mozilla_concept_engine = "org.mozilla.components:concept-engine:${Versions.mozilla_android_components}" - const val mozilla_concept_menu = "org.mozilla.components:concept-menu:${Versions.mozilla_android_components}" - const val mozilla_concept_push = "org.mozilla.components:concept-push:${Versions.mozilla_android_components}" - const val mozilla_concept_tabstray = "org.mozilla.components:concept-tabstray:${Versions.mozilla_android_components}" - const val mozilla_concept_toolbar = "org.mozilla.components:concept-toolbar:${Versions.mozilla_android_components}" - const val mozilla_concept_storage = "org.mozilla.components:concept-storage:${Versions.mozilla_android_components}" - const val mozilla_concept_sync = "org.mozilla.components:concept-sync:${Versions.mozilla_android_components}" - - const val mozilla_browser_engine_gecko = "org.mozilla.components:browser-engine-gecko:${Versions.mozilla_android_components}" - const val mozilla_browser_domains = "org.mozilla.components:browser-domains:${Versions.mozilla_android_components}" - const val mozilla_browser_icons = "org.mozilla.components:browser-icons:${Versions.mozilla_android_components}" - const val mozilla_browser_session_storage = "org.mozilla.components:browser-session-storage:${Versions.mozilla_android_components}" - const val mozilla_browser_state = "org.mozilla.components:browser-state:${Versions.mozilla_android_components}" - const val mozilla_browser_tabstray = "org.mozilla.components:browser-tabstray:${Versions.mozilla_android_components}" - const val mozilla_browser_thumbnails = "org.mozilla.components:browser-thumbnails:${Versions.mozilla_android_components}" - const val mozilla_browser_toolbar = "org.mozilla.components:browser-toolbar:${Versions.mozilla_android_components}" - const val mozilla_browser_menu = "org.mozilla.components:browser-menu:${Versions.mozilla_android_components}" - const val mozilla_browser_menu2 = "org.mozilla.components:browser-menu2:${Versions.mozilla_android_components}" - const val mozilla_browser_errorpages = "org.mozilla.components:browser-errorpages:${Versions.mozilla_android_components}" - const val mozilla_browser_storage_sync = "org.mozilla.components:browser-storage-sync:${Versions.mozilla_android_components}" - - const val mozilla_feature_addons = "org.mozilla.components:feature-addons:${Versions.mozilla_android_components}" - const val mozilla_support_extensions = "org.mozilla.components:support-webextensions:${Versions.mozilla_android_components}" - - const val mozilla_feature_accounts = "org.mozilla.components:feature-accounts:${Versions.mozilla_android_components}" - const val mozilla_feature_app_links = "org.mozilla.components:feature-app-links:${Versions.mozilla_android_components}" - const val mozilla_feature_autofill = "org.mozilla.components:feature-autofill:${Versions.mozilla_android_components}" - const val mozilla_feature_awesomebar = "org.mozilla.components:feature-awesomebar:${Versions.mozilla_android_components}" - const val mozilla_feature_contextmenu = "org.mozilla.components:feature-contextmenu:${Versions.mozilla_android_components}" - const val mozilla_feature_customtabs = "org.mozilla.components:feature-customtabs:${Versions.mozilla_android_components}" - const val mozilla_feature_intent = "org.mozilla.components:feature-intent:${Versions.mozilla_android_components}" - const val mozilla_feature_media = "org.mozilla.components:feature-media:${Versions.mozilla_android_components}" - const val mozilla_feature_qr = "org.mozilla.components:feature-qr:${Versions.mozilla_android_components}" - const val mozilla_feature_search = "org.mozilla.components:feature-search:${Versions.mozilla_android_components}" - const val mozilla_feature_session = "org.mozilla.components:feature-session:${Versions.mozilla_android_components}" - const val mozilla_feature_syncedtabs = "org.mozilla.components:feature-syncedtabs:${Versions.mozilla_android_components}" - const val mozilla_feature_tabs = "org.mozilla.components:feature-tabs:${Versions.mozilla_android_components}" - const val mozilla_feature_downloads = "org.mozilla.components:feature-downloads:${Versions.mozilla_android_components}" - const val mozilla_feature_storage = "org.mozilla.components:feature-storage:${Versions.mozilla_android_components}" - const val mozilla_feature_prompts = "org.mozilla.components:feature-prompts:${Versions.mozilla_android_components}" - const val mozilla_feature_push = "org.mozilla.components:feature-push:${Versions.mozilla_android_components}" - const val mozilla_feature_privatemode = "org.mozilla.components:feature-privatemode:${Versions.mozilla_android_components}" - const val mozilla_feature_pwa = "org.mozilla.components:feature-pwa:${Versions.mozilla_android_components}" - const val mozilla_feature_toolbar = "org.mozilla.components:feature-toolbar:${Versions.mozilla_android_components}" - const val mozilla_feature_findinpage = "org.mozilla.components:feature-findinpage:${Versions.mozilla_android_components}" - const val mozilla_feature_logins = "org.mozilla.components:feature-logins:${Versions.mozilla_android_components}" - const val mozilla_feature_site_permissions = "org.mozilla.components:feature-sitepermissions:${Versions.mozilla_android_components}" - const val mozilla_feature_readerview = "org.mozilla.components:feature-readerview:${Versions.mozilla_android_components}" - const val mozilla_feature_tab_collections = "org.mozilla.components:feature-tab-collections:${Versions.mozilla_android_components}" - const val mozilla_feature_recentlyclosed = "org.mozilla.components:feature-recentlyclosed:${Versions.mozilla_android_components}" - const val mozilla_feature_accounts_push = "org.mozilla.components:feature-accounts-push:${Versions.mozilla_android_components}" - const val mozilla_feature_top_sites = "org.mozilla.components:feature-top-sites:${Versions.mozilla_android_components}" - const val mozilla_feature_share = "org.mozilla.components:feature-share:${Versions.mozilla_android_components}" - const val mozilla_feature_webauthn = "org.mozilla.components:feature-webauthn:${Versions.mozilla_android_components}" - const val mozilla_feature_webcompat = "org.mozilla.components:feature-webcompat:${Versions.mozilla_android_components}" - const val mozilla_feature_webnotifications = "org.mozilla.components:feature-webnotifications:${Versions.mozilla_android_components}" - const val mozilla_feature_webcompat_reporter = "org.mozilla.components:feature-webcompat-reporter:${Versions.mozilla_android_components}" - - const val mozilla_service_pocket = "org.mozilla.components:service-pocket:${Versions.mozilla_android_components}" +object FenixDependencies { + const val tools_androidgradle = "com.android.tools.build:gradle:${FenixVersions.android_gradle_plugin}" + const val tools_kotlingradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:${FenixVersions.kotlin}" + const val tools_benchmarkgradle = "androidx.benchmark:benchmark-gradle-plugin:${FenixVersions.androidx_benchmark}" + const val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${FenixVersions.kotlin}" + const val kotlin_stdlib_jdk8 = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${FenixVersions.kotlin}" + const val kotlin_reflect = "org.jetbrains.kotlin:kotlin-reflect:${FenixVersions.kotlin}" + const val kotlin_coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${FenixVersions.coroutines}" + const val kotlin_coroutines_test = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${FenixVersions.coroutines}" + const val kotlin_coroutines_android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${FenixVersions.coroutines}" + + const val osslicenses_plugin = "com.google.android.gms:oss-licenses-plugin:${FenixVersions.osslicenses_plugin}" + + const val mozilla_compose_awesomebar = "org.mozilla.components:compose-awesomebar:${FenixVersions.mozilla_android_components}" + + const val mozilla_concept_awesomebar = "org.mozilla.components:concept-awesomebar:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_base = "org.mozilla.components:concept-base:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_engine = "org.mozilla.components:concept-engine:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_menu = "org.mozilla.components:concept-menu:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_push = "org.mozilla.components:concept-push:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_tabstray = "org.mozilla.components:concept-tabstray:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_toolbar = "org.mozilla.components:concept-toolbar:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_storage = "org.mozilla.components:concept-storage:${FenixVersions.mozilla_android_components}" + const val mozilla_concept_sync = "org.mozilla.components:concept-sync:${FenixVersions.mozilla_android_components}" + + const val mozilla_browser_engine_gecko = "org.mozilla.components:browser-engine-gecko:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_domains = "org.mozilla.components:browser-domains:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_icons = "org.mozilla.components:browser-icons:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_session_storage = "org.mozilla.components:browser-session-storage:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_state = "org.mozilla.components:browser-state:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_tabstray = "org.mozilla.components:browser-tabstray:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_thumbnails = "org.mozilla.components:browser-thumbnails:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_toolbar = "org.mozilla.components:browser-toolbar:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_menu = "org.mozilla.components:browser-menu:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_menu2 = "org.mozilla.components:browser-menu2:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_errorpages = "org.mozilla.components:browser-errorpages:${FenixVersions.mozilla_android_components}" + const val mozilla_browser_storage_sync = "org.mozilla.components:browser-storage-sync:${FenixVersions.mozilla_android_components}" + + const val mozilla_feature_addons = "org.mozilla.components:feature-addons:${FenixVersions.mozilla_android_components}" + const val mozilla_support_extensions = "org.mozilla.components:support-webextensions:${FenixVersions.mozilla_android_components}" + + const val mozilla_feature_accounts = "org.mozilla.components:feature-accounts:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_app_links = "org.mozilla.components:feature-app-links:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_autofill = "org.mozilla.components:feature-autofill:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_awesomebar = "org.mozilla.components:feature-awesomebar:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_contextmenu = "org.mozilla.components:feature-contextmenu:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_customtabs = "org.mozilla.components:feature-customtabs:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_intent = "org.mozilla.components:feature-intent:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_media = "org.mozilla.components:feature-media:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_qr = "org.mozilla.components:feature-qr:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_search = "org.mozilla.components:feature-search:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_session = "org.mozilla.components:feature-session:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_syncedtabs = "org.mozilla.components:feature-syncedtabs:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_tabs = "org.mozilla.components:feature-tabs:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_downloads = "org.mozilla.components:feature-downloads:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_storage = "org.mozilla.components:feature-storage:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_prompts = "org.mozilla.components:feature-prompts:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_push = "org.mozilla.components:feature-push:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_privatemode = "org.mozilla.components:feature-privatemode:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_pwa = "org.mozilla.components:feature-pwa:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_toolbar = "org.mozilla.components:feature-toolbar:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_findinpage = "org.mozilla.components:feature-findinpage:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_logins = "org.mozilla.components:feature-logins:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_site_permissions = "org.mozilla.components:feature-sitepermissions:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_readerview = "org.mozilla.components:feature-readerview:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_tab_collections = "org.mozilla.components:feature-tab-collections:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_recentlyclosed = "org.mozilla.components:feature-recentlyclosed:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_accounts_push = "org.mozilla.components:feature-accounts-push:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_top_sites = "org.mozilla.components:feature-top-sites:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_share = "org.mozilla.components:feature-share:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_webauthn = "org.mozilla.components:feature-webauthn:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_webcompat = "org.mozilla.components:feature-webcompat:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_webnotifications = "org.mozilla.components:feature-webnotifications:${FenixVersions.mozilla_android_components}" + const val mozilla_feature_webcompat_reporter = "org.mozilla.components:feature-webcompat-reporter:${FenixVersions.mozilla_android_components}" + + const val mozilla_service_pocket = "org.mozilla.components:service-pocket:${FenixVersions.mozilla_android_components}" const val mozilla_service_contile = - "org.mozilla.components:service-contile:${Versions.mozilla_android_components}" + "org.mozilla.components:service-contile:${FenixVersions.mozilla_android_components}" const val mozilla_service_digitalassetlinks = - "org.mozilla.components:service-digitalassetlinks:${Versions.mozilla_android_components}" + "org.mozilla.components:service-digitalassetlinks:${FenixVersions.mozilla_android_components}" const val mozilla_service_sync_autofill = - "org.mozilla.components:service-sync-autofill:${Versions.mozilla_android_components}" + "org.mozilla.components:service-sync-autofill:${FenixVersions.mozilla_android_components}" const val mozilla_service_sync_logins = - "org.mozilla.components:service-sync-logins:${Versions.mozilla_android_components}" - const val mozilla_service_firefox_accounts = "org.mozilla.components:service-firefox-accounts:${Versions.mozilla_android_components}" - const val mozilla_service_glean = "org.mozilla.components:service-glean:${Versions.mozilla_android_components}" - const val mozilla_service_location = "org.mozilla.components:service-location:${Versions.mozilla_android_components}" - const val mozilla_service_nimbus = "org.mozilla.components:service-nimbus:${Versions.mozilla_android_components}" - - const val mozilla_ui_colors = "org.mozilla.components:ui-colors:${Versions.mozilla_android_components}" - const val mozilla_ui_icons = "org.mozilla.components:ui-icons:${Versions.mozilla_android_components}" - const val mozilla_ui_widgets = "org.mozilla.components:ui-widgets:${Versions.mozilla_android_components}" - const val mozilla_ui_tabcounter = "org.mozilla.components:ui-tabcounter:${Versions.mozilla_android_components}" - - const val mozilla_lib_crash = "org.mozilla.components:lib-crash:${Versions.mozilla_android_components}" + "org.mozilla.components:service-sync-logins:${FenixVersions.mozilla_android_components}" + const val mozilla_service_firefox_accounts = "org.mozilla.components:service-firefox-accounts:${FenixVersions.mozilla_android_components}" + const val mozilla_service_glean = "org.mozilla.components:service-glean:${FenixVersions.mozilla_android_components}" + const val mozilla_service_location = "org.mozilla.components:service-location:${FenixVersions.mozilla_android_components}" + const val mozilla_service_nimbus = "org.mozilla.components:service-nimbus:${FenixVersions.mozilla_android_components}" + + const val mozilla_ui_colors = "org.mozilla.components:ui-colors:${FenixVersions.mozilla_android_components}" + const val mozilla_ui_icons = "org.mozilla.components:ui-icons:${FenixVersions.mozilla_android_components}" + const val mozilla_ui_widgets = "org.mozilla.components:ui-widgets:${FenixVersions.mozilla_android_components}" + const val mozilla_ui_tabcounter = "org.mozilla.components:ui-tabcounter:${FenixVersions.mozilla_android_components}" + + const val mozilla_lib_crash = "org.mozilla.components:lib-crash:${FenixVersions.mozilla_android_components}" const val lib_crash_sentry = - "org.mozilla.components:lib-crash-sentry:${Versions.mozilla_android_components}" - const val mozilla_lib_push_firebase = "org.mozilla.components:lib-push-firebase:${Versions.mozilla_android_components}" - const val mozilla_lib_dataprotect = "org.mozilla.components:lib-dataprotect:${Versions.mozilla_android_components}" - const val mozilla_lib_state = "org.mozilla.components:lib-state:${Versions.mozilla_android_components}" - - const val mozilla_lib_publicsuffixlist = "org.mozilla.components:lib-publicsuffixlist:${Versions.mozilla_android_components}" - - const val mozilla_support_base = "org.mozilla.components:support-base:${Versions.mozilla_android_components}" - const val mozilla_support_rusterrors = "org.mozilla.components:support-rusterrors:${Versions.mozilla_android_components}" - const val mozilla_support_images = "org.mozilla.components:support-images:${Versions.mozilla_android_components}" - const val mozilla_support_ktx = "org.mozilla.components:support-ktx:${Versions.mozilla_android_components}" - const val mozilla_support_rusthttp = "org.mozilla.components:support-rusthttp:${Versions.mozilla_android_components}" - const val mozilla_support_rustlog = "org.mozilla.components:support-rustlog:${Versions.mozilla_android_components}" - const val mozilla_support_utils = "org.mozilla.components:support-utils:${Versions.mozilla_android_components}" - const val mozilla_support_test = "org.mozilla.components:support-test:${Versions.mozilla_android_components}" - const val mozilla_support_test_libstate = "org.mozilla.components:support-test-libstate:${Versions.mozilla_android_components}" - const val mozilla_support_locale = "org.mozilla.components:support-locale:${Versions.mozilla_android_components}" - - const val sentry = "io.sentry:sentry-android:${Versions.sentry}" - const val leakcanary = "com.squareup.leakcanary:leakcanary-android-core:${Versions.leakcanary}" - - const val androidx_compose_ui = "androidx.compose.ui:ui:${Versions.androidx_compose}" - const val androidx_compose_ui_test = "androidx.compose.ui:ui-test-junit4:${Versions.androidx_compose}" - const val androidx_compose_ui_test_manifest = "androidx.compose.ui:ui-test-manifest:${Versions.androidx_compose}" - const val androidx_compose_ui_tooling = "androidx.compose.ui:ui-tooling:${Versions.androidx_compose}" - const val androidx_compose_foundation = "androidx.compose.foundation:foundation:${Versions.androidx_compose}" - const val androidx_compose_material = "androidx.compose.material:material:${Versions.androidx_compose}" - const val androidx_annotation = "androidx.annotation:annotation:${Versions.androidx_annotation}" - const val androidx_benchmark_junit4 = "androidx.benchmark:benchmark-junit4:${Versions.androidx_benchmark}" - const val androidx_biometric = "androidx.biometric:biometric:${Versions.androidx_biometric}" - const val androidx_fragment = "androidx.fragment:fragment-ktx:${Versions.androidx_fragment}" - const val androidx_appcompat = "androidx.appcompat:appcompat:${Versions.androidx_appcompat}" - const val androidx_coordinatorlayout = "androidx.coordinatorlayout:coordinatorlayout:${Versions.androidx_coordinator_layout}" - const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout:${Versions.androidx_constraint_layout}" - const val androidx_legacy = "androidx.legacy:legacy-support-v4:${Versions.androidx_legacy}" - const val androidx_lifecycle_common = "androidx.lifecycle:lifecycle-common:${Versions.androidx_lifecycle}" - const val androidx_lifecycle_livedata = "androidx.lifecycle:lifecycle-livedata-ktx:${Versions.androidx_lifecycle}" - const val androidx_lifecycle_process = "androidx.lifecycle:lifecycle-process:${Versions.androidx_lifecycle}" - const val androidx_lifecycle_viewmodel = "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.androidx_lifecycle}" - const val androidx_lifecycle_runtime = "androidx.lifecycle:lifecycle-runtime-ktx:${Versions.androidx_lifecycle}" - const val androidx_paging = "androidx.paging:paging-runtime-ktx:${Versions.androidx_paging}" - const val androidx_preference = "androidx.preference:preference-ktx:${Versions.androidx_preference}" - const val androidx_safeargs = "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.androidx_navigation}" - const val androidx_navigation_fragment = "androidx.navigation:navigation-fragment-ktx:${Versions.androidx_navigation}" - const val androidx_navigation_ui = "androidx.navigation:navigation-ui:${Versions.androidx_navigation}" - const val androidx_recyclerview = "androidx.recyclerview:recyclerview:${Versions.androidx_recyclerview}" - const val androidx_core = "androidx.core:core:${Versions.androidx_core}" - const val androidx_core_ktx = "androidx.core:core-ktx:${Versions.androidx_core}" - const val androidx_transition = "androidx.transition:transition:${Versions.androidx_transition}" - const val androidx_work_ktx = "androidx.work:work-runtime-ktx:${Versions.androidx_work}" - const val androidx_work_testing = "androidx.work:work-testing:${Versions.androidx_work}" - const val androidx_datastore = "androidx.datastore:datastore:${Versions.androidx_datastore}" - const val google_material = "com.google.android.material:material:${Versions.google_material}" + "org.mozilla.components:lib-crash-sentry:${FenixVersions.mozilla_android_components}" + const val mozilla_lib_push_firebase = "org.mozilla.components:lib-push-firebase:${FenixVersions.mozilla_android_components}" + const val mozilla_lib_dataprotect = "org.mozilla.components:lib-dataprotect:${FenixVersions.mozilla_android_components}" + const val mozilla_lib_state = "org.mozilla.components:lib-state:${FenixVersions.mozilla_android_components}" + + const val mozilla_lib_publicsuffixlist = "org.mozilla.components:lib-publicsuffixlist:${FenixVersions.mozilla_android_components}" + + const val mozilla_support_base = "org.mozilla.components:support-base:${FenixVersions.mozilla_android_components}" + const val mozilla_support_rusterrors = "org.mozilla.components:support-rusterrors:${FenixVersions.mozilla_android_components}" + const val mozilla_support_images = "org.mozilla.components:support-images:${FenixVersions.mozilla_android_components}" + const val mozilla_support_ktx = "org.mozilla.components:support-ktx:${FenixVersions.mozilla_android_components}" + const val mozilla_support_rusthttp = "org.mozilla.components:support-rusthttp:${FenixVersions.mozilla_android_components}" + const val mozilla_support_rustlog = "org.mozilla.components:support-rustlog:${FenixVersions.mozilla_android_components}" + const val mozilla_support_utils = "org.mozilla.components:support-utils:${FenixVersions.mozilla_android_components}" + const val mozilla_support_test = "org.mozilla.components:support-test:${FenixVersions.mozilla_android_components}" + const val mozilla_support_test_libstate = "org.mozilla.components:support-test-libstate:${FenixVersions.mozilla_android_components}" + const val mozilla_support_locale = "org.mozilla.components:support-locale:${FenixVersions.mozilla_android_components}" + + const val sentry = "io.sentry:sentry-android:${FenixVersions.sentry}" + const val leakcanary = "com.squareup.leakcanary:leakcanary-android-core:${FenixVersions.leakcanary}" + + const val androidx_compose_ui = "androidx.compose.ui:ui:${FenixVersions.androidx_compose}" + const val androidx_compose_ui_test = "androidx.compose.ui:ui-test-junit4:${FenixVersions.androidx_compose}" + const val androidx_compose_ui_test_manifest = "androidx.compose.ui:ui-test-manifest:${FenixVersions.androidx_compose}" + const val androidx_compose_ui_tooling = "androidx.compose.ui:ui-tooling:${FenixVersions.androidx_compose}" + const val androidx_compose_foundation = "androidx.compose.foundation:foundation:${FenixVersions.androidx_compose}" + const val androidx_compose_material = "androidx.compose.material:material:${FenixVersions.androidx_compose}" + const val androidx_annotation = "androidx.annotation:annotation:${FenixVersions.androidx_annotation}" + const val androidx_benchmark_junit4 = "androidx.benchmark:benchmark-junit4:${FenixVersions.androidx_benchmark}" + const val androidx_biometric = "androidx.biometric:biometric:${FenixVersions.androidx_biometric}" + const val androidx_fragment = "androidx.fragment:fragment-ktx:${FenixVersions.androidx_fragment}" + const val androidx_appcompat = "androidx.appcompat:appcompat:${FenixVersions.androidx_appcompat}" + const val androidx_coordinatorlayout = "androidx.coordinatorlayout:coordinatorlayout:${FenixVersions.androidx_coordinator_layout}" + const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout:${FenixVersions.androidx_constraint_layout}" + const val androidx_legacy = "androidx.legacy:legacy-support-v4:${FenixVersions.androidx_legacy}" + const val androidx_lifecycle_common = "androidx.lifecycle:lifecycle-common:${FenixVersions.androidx_lifecycle}" + const val androidx_lifecycle_livedata = "androidx.lifecycle:lifecycle-livedata-ktx:${FenixVersions.androidx_lifecycle}" + const val androidx_lifecycle_process = "androidx.lifecycle:lifecycle-process:${FenixVersions.androidx_lifecycle}" + const val androidx_lifecycle_viewmodel = "androidx.lifecycle:lifecycle-viewmodel-ktx:${FenixVersions.androidx_lifecycle}" + const val androidx_lifecycle_runtime = "androidx.lifecycle:lifecycle-runtime-ktx:${FenixVersions.androidx_lifecycle}" + const val androidx_paging = "androidx.paging:paging-runtime-ktx:${FenixVersions.androidx_paging}" + const val androidx_preference = "androidx.preference:preference-ktx:${FenixVersions.androidx_preference}" + const val androidx_safeargs = "androidx.navigation:navigation-safe-args-gradle-plugin:${FenixVersions.androidx_navigation}" + const val androidx_navigation_fragment = "androidx.navigation:navigation-fragment-ktx:${FenixVersions.androidx_navigation}" + const val androidx_navigation_ui = "androidx.navigation:navigation-ui:${FenixVersions.androidx_navigation}" + const val androidx_recyclerview = "androidx.recyclerview:recyclerview:${FenixVersions.androidx_recyclerview}" + const val androidx_core = "androidx.core:core:${FenixVersions.androidx_core}" + const val androidx_core_ktx = "androidx.core:core-ktx:${FenixVersions.androidx_core}" + const val androidx_transition = "androidx.transition:transition:${FenixVersions.androidx_transition}" + const val androidx_work_ktx = "androidx.work:work-runtime-ktx:${FenixVersions.androidx_work}" + const val androidx_work_testing = "androidx.work:work-testing:${FenixVersions.androidx_work}" + const val androidx_datastore = "androidx.datastore:datastore:${FenixVersions.androidx_datastore}" + const val google_material = "com.google.android.material:material:${FenixVersions.google_material}" const val google_accompanist_drawablepainter = - "com.google.accompanist:accompanist-drawablepainter:${Versions.accompanist_drawablepainter}" + "com.google.accompanist:accompanist-drawablepainter:${FenixVersions.accompanist_drawablepainter}" const val google_accompanist_insets = - "com.google.accompanist:accompanist-insets:${Versions.accompanist_drawablepainter}" + "com.google.accompanist:accompanist-insets:${FenixVersions.accompanist_drawablepainter}" - const val protobuf_javalite = "com.google.protobuf:protobuf-javalite:${Versions.protobuf}" - const val protobuf_compiler = "com.google.protobuf:protoc:${Versions.protobuf}" + const val protobuf_javalite = "com.google.protobuf:protobuf-javalite:${FenixVersions.protobuf}" + const val protobuf_compiler = "com.google.protobuf:protoc:${FenixVersions.protobuf}" - const val adjust = "com.adjust.sdk:adjust-android:${Versions.adjust}" - const val installreferrer = "com.android.installreferrer:installreferrer:${Versions.installreferrer}" + const val adjust = "com.adjust.sdk:adjust-android:${FenixVersions.adjust}" + const val installreferrer = "com.android.installreferrer:installreferrer:${FenixVersions.installreferrer}" - const val jna = "net.java.dev.jna:jna:${Versions.jna}@jar" + const val jna = "net.java.dev.jna:jna:${FenixVersions.jna}@jar" - const val junit = "junit:junit:${Versions.junit}" - const val mockk = "io.mockk:mockk:${Versions.mockk}" - const val mockk_android = "io.mockk:mockk-android:${Versions.mockk}" + const val junit = "junit:junit:${FenixVersions.junit}" + const val mockk = "io.mockk:mockk:${FenixVersions.mockk}" + const val mockk_android = "io.mockk:mockk-android:${FenixVersions.mockk}" // --- START AndroidX test dependencies --- // // N.B.: the versions of these dependencies appear to be pinned together. To avoid bugs, they @@ -235,11 +235,12 @@ object Deps { // https://developer.android.com/jetpack/androidx/releases/test // For the full IDs of these test dependencies, see: // https://developer.android.com/training/testing/set-up-project#android-test-dependencies - private const val androidx_test_shared_version = "1.5.0" // this appears to be shared with many deps. - private const val androidx_test_junit = "1.1.4" + private const val androidx_test_shared_version = "1.5.0" + private const val androidx_test_junit = "1.1.5" private const val androidx_test_orchestrator = "1.4.2" + private const val androidx_test_runner = "1.5.2" const val androidx_test_core = "androidx.test:core:$androidx_test_shared_version" - private const val androidx_espresso_version = "3.5.0" + private const val androidx_espresso_version = "3.5.1" const val espresso_core = "androidx.test.espresso:espresso-core:$androidx_espresso_version" const val espresso_contrib = "androidx.test.espresso:espresso-contrib:$androidx_espresso_version" const val espresso_idling_resources = "androidx.test.espresso:espresso-idling-resource:$androidx_espresso_version" @@ -248,27 +249,27 @@ object Deps { const val androidx_test_extensions = "androidx.test.ext:junit-ktx:$androidx_test_junit" // Monitor is unused const val orchestrator = "androidx.test:orchestrator:$androidx_test_orchestrator" - const val tools_test_runner = "androidx.test:runner:$androidx_test_shared_version" + const val tools_test_runner = "androidx.test:runner:$androidx_test_runner" const val tools_test_rules = "androidx.test:rules:$androidx_test_shared_version" // Truth is unused // Test services is unused // --- END AndroidX test dependencies --- // - const val mockwebserver = "com.squareup.okhttp3:mockwebserver:${Versions.mockwebserver}" - const val uiautomator = "androidx.test.uiautomator:uiautomator:${Versions.uiautomator}" - const val robolectric = "org.robolectric:robolectric:${Versions.robolectric}" + const val mockwebserver = "com.squareup.okhttp3:mockwebserver:${FenixVersions.mockwebserver}" + const val uiautomator = "androidx.test.uiautomator:uiautomator:${FenixVersions.uiautomator}" + const val robolectric = "org.robolectric:robolectric:${FenixVersions.robolectric}" - const val google_ads_id = "com.google.android.gms:play-services-ads-identifier:${Versions.google_ads_id_version}" + const val google_ads_id = "com.google.android.gms:play-services-ads-identifier:${FenixVersions.google_ads_id_version}" // Required for in-app reviews - const val google_play_review = "com.google.android.play:review:${Versions.google_play_review_version}" - const val google_play_review_ktx = "com.google.android.play:review-ktx:${Versions.google_play_review_version}" - - const val detektApi = "io.gitlab.arturbosch.detekt:detekt-api:${Versions.detekt}" - const val detektTest = "io.gitlab.arturbosch.detekt:detekt-test:${Versions.detekt}" - const val junitApi = "org.junit.jupiter:junit-jupiter-api:${Versions.junit}" - const val junitParams = "org.junit.jupiter:junit-jupiter-params:${Versions.junit}" - const val junitEngine = "org.junit.jupiter:junit-jupiter-engine:${Versions.junit}" + const val google_play_review = "com.google.android.play:review:${FenixVersions.google_play_review_version}" + const val google_play_review_ktx = "com.google.android.play:review-ktx:${FenixVersions.google_play_review_version}" + + const val detektApi = "io.gitlab.arturbosch.detekt:detekt-api:${FenixVersions.detekt}" + const val detektTest = "io.gitlab.arturbosch.detekt:detekt-test:${FenixVersions.detekt}" + const val junitApi = "org.junit.jupiter:junit-jupiter-api:${FenixVersions.junit}" + const val junitParams = "org.junit.jupiter:junit-jupiter-params:${FenixVersions.junit}" + const val junitEngine = "org.junit.jupiter:junit-jupiter-engine:${FenixVersions.junit}" } /** diff --git a/config/detekt.yml b/config/detekt.yml index 389cc893f..cfbd32e5a 100644 --- a/config/detekt.yml +++ b/config/detekt.yml @@ -1,3 +1,6 @@ +# Please refer to https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/config/detekt.yml +# for the source of truth for our detekt configuration. + build: maxIssues: 0 excludeCorrectable: false @@ -151,23 +154,6 @@ coroutines: SuspendFunWithFlowReturnType: active: false -mozilla-detekt-rules: - active: true - MozillaBannedPropertyAccess: - active: true - # BuildConfig.Debug: This property tests whether the application was built - # with the debuggable flag or not. Use a check for different build variants, - # instead. - bannedProperties: 'BuildConfig.DEBUG' - MozillaStrictModeSuppression: - active: true - MozillaCorrectUnitTestRunner: - active: true - MozillaRunBlockingCheck: - active: true - MozillaUseLazyMonitored: - active: true - empty-blocks: active: true EmptyCatchBlock: @@ -646,3 +632,22 @@ style: active: true excludeImports: - 'java.util.*' + +# Custom Rules + +mozilla-detekt-rules: + active: true + MozillaBannedPropertyAccess: + active: true + # BuildConfig.Debug: This property tests whether the application was built + # with the debuggable flag or not. Use a check for different build variants, + # instead. + bannedProperties: 'BuildConfig.DEBUG' + MozillaStrictModeSuppression: + active: true + MozillaCorrectUnitTestRunner: + active: true + MozillaRunBlockingCheck: + active: true + MozillaUseLazyMonitored: + active: true diff --git a/ktlint-baseline.xml b/ktlint-baseline.xml index 2fca9dc76..8c4bd29fb 100644 --- a/ktlint-baseline.xml +++ b/ktlint-baseline.xml @@ -1,6 +1,6 @@ - + diff --git a/l10n.toml b/l10n.toml index 1e62152fc..ab8299615 100644 --- a/l10n.toml +++ b/l10n.toml @@ -39,6 +39,7 @@ locales = [ "ff", "fi", "fr", + "fur", "fy-NL", "ga-IE", "gd", @@ -79,6 +80,7 @@ locales = [ "oc", "or", "pa-IN", + "pa-PK", "pl", "pt-BR", "pt-PT", @@ -86,6 +88,7 @@ locales = [ "ro", "ru", "sat", + "sc", "si", "sk", "skr", diff --git a/mozilla-detekt-rules/build.gradle b/mozilla-detekt-rules/build.gradle index f663472f3..f49538b39 100644 --- a/mozilla-detekt-rules/build.gradle +++ b/mozilla-detekt-rules/build.gradle @@ -1,19 +1,19 @@ apply plugin: 'kotlin' dependencies { - compileOnly Deps.detektApi - implementation Deps.androidx_annotation + compileOnly FenixDependencies.detektApi + implementation FenixDependencies.androidx_annotation // I didn't look thoroughly enough to really know what's going on here but I think // the detekt API uses jdk8 so if we provide jdk7, the dependency collision system // doesn't work and there are duplicate APIs with different versions in the output. - implementation Deps.kotlin_stdlib_jdk8 + implementation FenixDependencies.kotlin_stdlib_jdk8 - testImplementation Deps.detektApi - testImplementation Deps.detektTest - testImplementation Deps.junitApi - testImplementation Deps.junitParams - testRuntimeOnly Deps.junitEngine + testImplementation FenixDependencies.detektApi + testImplementation FenixDependencies.detektTest + testImplementation FenixDependencies.junitApi + testImplementation FenixDependencies.junitParams + testRuntimeOnly FenixDependencies.junitEngine } test { diff --git a/mozilla-lint-rules/build.gradle b/mozilla-lint-rules/build.gradle index 4a9193368..64ba80603 100644 --- a/mozilla-lint-rules/build.gradle +++ b/mozilla-lint-rules/build.gradle @@ -27,17 +27,17 @@ dependencies { // // The prepareLintJar task fails with "Found more than one jar in the 'lintChecks' configuration" // if we include the stdlib (with implementation) so we have to do compileOnly + testImplementation. - compileOnly Deps.kotlin_stdlib_jdk8 - compileOnly Deps.kotlin_reflect - testImplementation Deps.kotlin_stdlib_jdk8 - testImplementation Deps.kotlin_reflect + compileOnly FenixDependencies.kotlin_stdlib_jdk8 + compileOnly FenixDependencies.kotlin_reflect + testImplementation FenixDependencies.kotlin_stdlib_jdk8 + testImplementation FenixDependencies.kotlin_reflect - compileOnly "com.android.tools.lint:lint-api:${Versions.android_lint_api}" - compileOnly "com.android.tools.lint:lint-checks:${Versions.android_lint_api}" + compileOnly "com.android.tools.lint:lint-api:${FenixVersions.android_lint_api}" + compileOnly "com.android.tools.lint:lint-checks:${FenixVersions.android_lint_api}" testImplementation "junit:junit:4.13.2" - testImplementation "com.android.tools.lint:lint:${Versions.android_lint_api}" - testImplementation "com.android.tools.lint:lint-tests:${Versions.android_lint_api}" + testImplementation "com.android.tools.lint:lint:${FenixVersions.android_lint_api}" + testImplementation "com.android.tools.lint:lint-tests:${FenixVersions.android_lint_api}" } jar { diff --git a/nimbus.fml.yaml b/nimbus.fml.yaml index 518b81658..5fadf03b6 100644 --- a/nimbus.fml.yaml +++ b/nimbus.fml.yaml @@ -114,6 +114,10 @@ features: type: ControlMessageBehavior description: What should be displayed when a control message is selected. default: show-next-message + notification-config: + description: Configuration of the notification worker for all notification messages. + type: NotificationConfig + default: {} defaults: - value: triggers: @@ -182,6 +186,9 @@ features: EXPIRES_QUICKLY: priority: 100 max-display-count: 1 + notification-config: + polling-interval: 180 # 3 minutes + mr2022: description: Features for MR 2022. variables: @@ -213,25 +220,31 @@ features: variables: sections-enabled: description: "This property provides a lookup table of whether or not the given section should be enabled." - type: Map + type: Map default: { - "feature-ui": false, - "feature-setting-value": false, + "feature-ui": 0, + "feature-setting-value": 0, + "dialog-re-engage-time": 4, + "dialog-text-variant": 0, } defaults: - channel: developer value: { "sections-enabled": { - "feature-ui": true, - "feature-setting-value": false, + "feature-ui": 1, + "feature-setting-value": 0, + "dialog-re-engage-time": 4, + "dialog-text-variant": 0, } } - channel: nightly value: { "sections-enabled": { - "feature-ui": true, - "feature-setting-value": false, + "feature-ui": 1, + "feature-setting-value": 0, + "dialog-re-engage-time": 4, + "dialog-text-variant": 0, } } unified-search: @@ -266,6 +279,14 @@ features: type: Boolean default: true + pre-permission-notification-prompt: + description: A feature that shows the pre-permission notification prompt. + variables: + enabled: + description: if true, the pre-permission notification prompt is shown to the user. + type: Boolean + default: true + types: objects: MessageData: @@ -331,6 +352,15 @@ types: How many sessions will this message be shown to the user before it is expired. default: 5 + NotificationConfig: + description: Attributes controlling the global configuration of notification messages. + fields: + polling-interval: + type: Int + description: > + How often, in seconds, the notification message worker will wake up and check for new + messages. + default: 3600 enums: ControlMessageBehavior: @@ -386,3 +416,7 @@ types: description: Indicates if the user interfaces should be visible. feature-setting-value: description: Indicates if the cookie handling setting should be enabled. + dialog-re-engage-time: + description: Indicates after how many hours of interaction, the dialog should show again. + dialog-text-variant: + description: Indicates which text variant should be used in the dialog. diff --git a/taskcluster/ci/ui-test/kind.yml b/taskcluster/ci/ui-test/kind.yml index be60e6a50..eb66d0af5 100644 --- a/taskcluster/ci/ui-test/kind.yml +++ b/taskcluster/ci/ui-test/kind.yml @@ -107,7 +107,7 @@ tasks: run-on-git-branches: ["^((?!releases[_/]).+)$"] run: commands: - - [automation/taskcluster/androidTest/ui-test.sh, arm64-v8a, app.apk, android-test.apk, '50'] + - [automation/taskcluster/androidTest/ui-test.sh, arm64-v8a, app.apk, android-test.apk, '100'] treeherder: symbol: debug(ui-test-arm) screenshots-arm: @@ -156,6 +156,6 @@ tasks: run-on-git-branches: [main] run: commands: - - [automation/taskcluster/androidTest/ui-test.sh, arm-legacy-api-tests, app.apk, android-test.apk, '2'] + - [automation/taskcluster/androidTest/ui-test.sh, arm-legacy-api-tests, app.apk, android-test.apk, '50'] treeherder: symbol: debug(legacy-arm) diff --git a/taskcluster/requirements.txt b/taskcluster/requirements.txt index ff3732d85..e4a35310d 100644 --- a/taskcluster/requirements.txt +++ b/taskcluster/requirements.txt @@ -14,16 +14,16 @@ attrs==22.1.0 \ # via # mozilla-version # taskcluster-taskgraph -certifi==2022.9.24 \ - --hash=sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14 \ - --hash=sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382 +certifi==2022.12.7 \ + --hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \ + --hash=sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18 # via requests charset-normalizer==2.1.1 \ --hash=sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845 \ --hash=sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f # via requests -future==0.18.2 \ - --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d +future==0.18.3 \ + --hash=sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307 # via mozilla-version giturlparse==0.10.0 \ --hash=sha256:04ba1a3a099c3093fa8d24a422913c6a9b2c2cd22bcffc939cf72e3e98f672d7 \ diff --git a/version.txt b/version.txt index 98eeca035..e62b99398 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -109.2.0 +110.0.1