diff --git a/.taskcluster.yml b/.taskcluster.yml index 40da0b207..89a9710ca 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -248,7 +248,7 @@ tasks: # Note: This task is built server side without the context or tooling that # exist in tree so we must hard code the hash image: - mozillareleases/taskgraph:decision-mobile-6020473b1a928d8df50e234a7ca2e81ade2220a4fb5fbe16b02477dd64a49728@sha256:98d226736b7d03907114bf37938002b90e8a37cbe3a297690e349f1ddddb1d7c + mozillareleases/taskgraph:decision-mobile-6607973bc60e32323a541861cc5856cd6a0f51ea9fd664ef7d43bca8df53db47@sha256:8c471aacc469ea8e7bb4846c16efe086f7350a5cc1df570cc6c86b22895a2456 maxRunTime: 1800 diff --git a/app/build.gradle b/app/build.gradle index 409c84b97..85d61d442 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -501,6 +501,7 @@ dependencies { 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 diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index 44cec2fa6..1d2de8f5b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -121,6 +121,7 @@ class BookmarksTest { } } + @Ignore("Intermittent failures: https://github.com/mozilla-mobile/fenix/issues/10911") @Test fun createBookmarkFolderTest() { homeScreen { 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 2adeee32b..c146a5213 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt @@ -170,6 +170,7 @@ class SettingsPrivacyTest { verifyDefaultView() verifyDefaultValueSyncLogins() verifyDefaultValueAutofillLogins() + verifyDefaultValueExceptions() }.openSavedLogins { verifySavedLoginsView() tapSetupLater() @@ -209,13 +210,13 @@ class SettingsPrivacyTest { } @Test - fun doNotSaveLoginFromPromptTest() { + fun neverSaveLoginFromPromptTest() { val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer) navigationToolbar { }.enterURLAndEnterToBrowser(saveLoginTest.url) { verifySaveLoginPromptIsShown() - // Don't save the login + // Don't save the login, add to exceptions saveLoginFromPrompt("Never save") }.openTabDrawer { }.openHomeScreen { @@ -228,7 +229,11 @@ class SettingsPrivacyTest { verifySavedLoginsView() tapSetupLater() // Verify that the login list is empty - verifyNotSavedLoginFromPromt() + verifyNotSavedLoginFromPrompt() + }.goBack { + }.openLoginExceptions { + // Verify localhost was added to exceptions list + verifyLocalhostExceptionAdded() } } 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 3a5656a67..d7c17e76b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -32,7 +32,9 @@ import org.mozilla.fenix.ui.robots.notificationShade * - Swipe to close tab (temporarily disabled) * - Undo close tab * - Close private tabs persistent notification - * + * - Empty tab tray state + * - Tab tray details + * - Shortcut context menu navigation */ class TabbedBrowsingTest { @@ -224,4 +226,86 @@ class TabbedBrowsingTest { verifyHomeScreen() } } + + @Test + fun verifyEmptyTabTray() { + homeScreen { }.dismissOnboarding() + + navigationToolbar { + }.openTabTray { + verifyNoTabsOpened() + verifyNewTabButton() + verifyTabTrayOverflowMenu(false) + }.toggleToPrivateTabs { + verifyNoTabsOpened() + verifyNewTabButton() + verifyTabTrayOverflowMenu(false) + } + } + + @Test + fun verifyOpenTabDetails() { + homeScreen { }.dismissOnboarding() + + val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + // verifyPageContent(defaultWebPage.content) + }.openTabDrawer { + verifyExistingTabList() + verifyNewTabButton() + verifyTabTrayOverflowMenu(true) + verifyExistingOpenTabs(defaultWebPage.title) + verifyCloseTabsButton(defaultWebPage.title) + }.openHomeScreen { + } + } + + @Test + fun verifyContextMenuShortcuts() { + homeScreen { }.dismissOnboarding() + + val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + // verifyPageContent(defaultWebPage.content) + }.openTabDrawer { + verifyExistingTabList() + verifyNewTabButton() + verifyTabTrayOverflowMenu(true) + verifyExistingOpenTabs(defaultWebPage.title) + verifyCloseTabsButton(defaultWebPage.title) + }.closeTabDrawer { + }.openTabButtonShortcutsMenu { + verifyTabButtonShortcutMenuItems() + }.closeTabFromShortcutsMenu { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + }.openTabButtonShortcutsMenu { + }.openNewPrivateTabFromShortcutsMenu { + verifyHomeScreen() + verifyNavigationToolbar() + verifyHomePrivateBrowsingButton() + verifyHomeMenu() + verifyHomeWordmark() + verifyTabButton() + verifyPrivateSessionMessage() + verifyHomeToolbar() + verifyHomeComponent() + } + navigationToolbar { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + + }.openTabButtonShortcutsMenu { + }.openTabFromShortcutsMenu { + verifyHomeScreen() + verifyNavigationToolbar() + verifyHomeMenu() + verifyHomeWordmark() + verifyTabButton() + verifyHomeToolbar() + verifyHomeComponent() + } + } } 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 02d1d4e67..63e102efb 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 @@ -18,8 +18,8 @@ import androidx.test.espresso.intent.matcher.BundleMatchers import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.matcher.RootMatchers.isDialog import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed import androidx.test.espresso.matcher.ViewMatchers.Visibility +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 @@ -392,6 +392,17 @@ class BrowserRobot { return TabDrawerRobot.Transition() } + fun openTabButtonShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { + mDevice.waitForIdle(waitingTime) + + tabsCounter().perform( + ViewActions.longClick() + ) + + NavigationToolbarRobot().interact() + return NavigationToolbarRobot.Transition() + } + fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition { mDevice.openNotification() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt index 057cc6cf2..556007c8f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -7,13 +7,16 @@ package org.mozilla.fenix.ui.robots import android.net.Uri +import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.IdlingResource +import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions.pressImeActionButton import androidx.test.espresso.action.ViewActions.replaceText import androidx.test.espresso.action.ViewActions.typeText import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility @@ -47,6 +50,8 @@ class NavigationToolbarRobot { fun verifyNoHistoryBookmarks() = assertNoHistoryBookmarks() + fun verifyTabButtonShortcutMenuItems() = assertTabButtonShortcutMenuItems() + class Transition { private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource @@ -113,12 +118,25 @@ class NavigationToolbarRobot { return ThreeDotMenuMainRobot.Transition() } + fun openTabTray(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + onView(withId(R.id.tab_button)) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + + tabTrayButton().click() + + TabDrawerRobot().interact() + return TabDrawerRobot.Transition() + } + fun openNewTabAndEnterToBrowser( url: Uri, interact: BrowserRobot.() -> Unit ): BrowserRobot.Transition { sessionLoadedIdlingResource = SessionLoadedIdlingResource() - mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/toolbar")), waitingTime) + mDevice.waitNotNull( + Until.findObject(By.res("org.mozilla.fenix.debug:id/toolbar")), + waitingTime + ) urlBar().click() awesomeBar().perform(replaceText(url.toString()), pressImeActionButton()) @@ -165,6 +183,54 @@ class NavigationToolbarRobot { HomeScreenRobot().interact() return HomeScreenRobot.Transition() } + + fun closeTabFromShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { + mDevice.waitForIdle(waitingTime) + + onView(withId(R.id.mozac_browser_menu_recyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + hasDescendant( + withText("Close tab") + ), ViewActions.click() + ) + ) + + NavigationToolbarRobot().interact() + return NavigationToolbarRobot.Transition() + } + + fun openTabFromShortcutsMenu(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + mDevice.waitForIdle(waitingTime) + + onView(withId(R.id.mozac_browser_menu_recyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + hasDescendant( + withText("New tab") + ), ViewActions.click() + ) + ) + + HomeScreenRobot().interact() + return HomeScreenRobot.Transition() + } + + fun openNewPrivateTabFromShortcutsMenu(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + mDevice.waitForIdle(waitingTime) + + onView(withId(R.id.mozac_browser_menu_recyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + hasDescendant( + withText("New private tab") + ), ViewActions.click() + ) + ) + + HomeScreenRobot().interact() + return HomeScreenRobot.Transition() + } } } @@ -196,10 +262,18 @@ private fun assertNoHistoryBookmarks() { .check(matches(not(hasDescendant(withText("Test_Page_3"))))) } +private fun assertTabButtonShortcutMenuItems() { + onView(withId(R.id.mozac_browser_menu_recyclerView)) + .check(matches(hasDescendant(withText("Close tab")))) + .check(matches(hasDescendant(withText("New private tab")))) + .check(matches(hasDescendant(withText("New tab")))) +} + private fun dismissOnboardingButton() = onView(withId(R.id.close_onboarding)) private fun urlBar() = onView(withId(R.id.toolbar)) private fun awesomeBar() = onView(withId(R.id.mozac_browser_toolbar_edit_url_view)) private fun threeDotButton() = onView(withId(R.id.mozac_browser_toolbar_menu)) +private fun tabTrayButton() = onView(withId(R.id.tab_button)) private fun fillLinkButton() = onView(withId(R.id.fill_link_from_clipboard)) private fun clearAddressBar() = onView(withId(R.id.mozac_browser_toolbar_clear_view)) private fun goBackButton() = mDevice.pressBack() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt index c45612625..46b8656ce 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt @@ -38,6 +38,8 @@ class SettingsSubMenuLoginsAndPasswordRobot { mDevice.waitNotNull(Until.findObjects(By.text("On")), TestAssetHelper.waitingTime) } + fun verifyDefaultValueExceptions() = assertDefaultValueExceptions() + fun verifyDefaultValueAutofillLogins() = assertDefaultValueAutofillLogins() fun verifyDefaultValueSyncLogins() = assertDefaultValueSyncLogins() @@ -60,6 +62,14 @@ class SettingsSubMenuLoginsAndPasswordRobot { return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition() } + fun openLoginExceptions(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { + fun loginExceptionsButton() = onView(ViewMatchers.withText("Exceptions")) + loginExceptionsButton().click() + + SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact() + return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition() + } + fun openSyncLogins(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition { fun syncLoginsButton() = onView(ViewMatchers.withText("Sync logins")) syncLoginsButton().click() @@ -92,5 +102,8 @@ private fun assertDefaultView() = onView(ViewMatchers.withText("Sync logins")) private fun assertDefaultValueAutofillLogins() = onView(ViewMatchers.withText("Autofill")) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) +private fun assertDefaultValueExceptions() = onView(ViewMatchers.withText("Exceptions")) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + private fun assertDefaultValueSyncLogins() = onView(ViewMatchers.withText("Sign in to Sync")) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt index 83ac1f47f..3c093ff5e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt @@ -13,6 +13,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.uiautomator.By import androidx.test.uiautomator.Until import org.hamcrest.CoreMatchers +import org.hamcrest.CoreMatchers.containsString import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.ext.waitNotNull @@ -24,16 +25,23 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { fun verifySavedLoginsView() = assertSavedLoginsView() fun verifySavedLoginsAfterSync() { - mDevice.waitNotNull(Until.findObjects(By.text("https://accounts.google.com")), TestAssetHelper.waitingTime) + mDevice.waitNotNull( + Until.findObjects(By.text("https://accounts.google.com")), + TestAssetHelper.waitingTime + ) assertSavedLoginAppears() } fun tapSetupLater() = onView(ViewMatchers.withText("Later")).perform(ViewActions.click()) - fun verifySavedLoginFromPrompt() = mDevice.waitNotNull(Until.findObjects(By.text("test@example.com"))) + fun verifySavedLoginFromPrompt() = + mDevice.waitNotNull(Until.findObjects(By.text("test@example.com"))) - fun verifyNotSavedLoginFromPromt() = onView(ViewMatchers.withText("test@example.com")) - .check(ViewAssertions.doesNotExist()) + fun verifyNotSavedLoginFromPrompt() = onView(ViewMatchers.withText("test@example.com")) + .check(ViewAssertions.doesNotExist()) + + fun verifyLocalhostExceptionAdded() = onView(ViewMatchers.withText(containsString("localhost"))) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) class Transition { fun goBack(interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition { @@ -46,9 +54,10 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { } private fun goBackButton() = - onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up"))) + onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up"))) -private fun assertSavedLoginsView() = onView(ViewMatchers.withText("Secure your logins and passwords")) +private fun assertSavedLoginsView() = + onView(ViewMatchers.withText("Secure your logins and passwords")) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) private fun assertSavedLoginAppears() = onView(ViewMatchers.withText("https://accounts.google.com")) 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 5ac8bf2d4..638674192 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 @@ -47,6 +47,8 @@ class TabDrawerRobot { fun verifyNoTabsOpened() = assertNoTabsOpenedText() fun verifyPrivateModeSelected() = assertPrivateModeSelected() fun verifyNormalModeSelected() = assertNormalModeSelected() + fun verifyNewTabButton() = assertNewTabButton() + fun verifyTabTrayOverflowMenu(visibility: Boolean) = assertTabTrayOverflowButton(visibility) fun closeTab() { closeTabButton().click() @@ -119,6 +121,18 @@ class TabDrawerRobot { return TabDrawerRobot.Transition() } + fun closeTabDrawer(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + mDevice.waitForIdle(waitingTime) + + // Dismisses the tab tray bottom sheet with 2 handle clicks + onView(withId(R.id.handle)).perform( + click(), + click() + ) + BrowserRobot().interact() + return BrowserRobot.Transition() + } + fun openHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { mDevice.waitForIdle() @@ -196,6 +210,10 @@ private fun assertNoTabsOpenedText() = onView(withId(R.id.tab_tray_empty_view)) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) +private fun assertNewTabButton() = + onView(withId(R.id.new_tab_button)) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + private fun assertNormalModeSelected() = normalBrowsingButton() .check(matches(ViewMatchers.isSelected())) @@ -204,6 +222,10 @@ private fun assertPrivateModeSelected() = privateBrowsingButton() .check(matches(ViewMatchers.isSelected())) +private fun assertTabTrayOverflowButton(visible: Boolean) = + onView(withId(R.id.tab_tray_overflow)) + .check(matches(withEffectiveVisibility(visibleOrGone(visible)))) + private fun tab(title: String) = onView( allOf( @@ -213,3 +235,6 @@ private fun tab(title: String) = ) private fun tabsCounter() = onView(withId(R.id.tab_button)) + +private fun visibleOrGone(visibility: Boolean) = + if (visibility) ViewMatchers.Visibility.VISIBLE else ViewMatchers.Visibility.GONE diff --git a/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_normal.png b/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_normal.png index f307680b1..b3c023ae4 100644 Binary files a/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_normal.png and b/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_private.png b/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_private.png index 53a3c7598..fe14fa16b 100644 Binary files a/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_private.png and b/app/src/fenixProduction/res/drawable-hdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_normal.png b/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_normal.png index 3d97d6376..0d320ef38 100644 Binary files a/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_normal.png and b/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_private.png b/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_private.png index 0b3284b1a..294661826 100644 Binary files a/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_private.png and b/app/src/fenixProduction/res/drawable-mdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_normal.png b/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_normal.png index c7ff7de9e..01ccf3b69 100644 Binary files a/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_normal.png and b/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_private.png b/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_private.png index 23f2f8552..3275aa887 100644 Binary files a/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_private.png and b/app/src/fenixProduction/res/drawable-xhdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_normal.png b/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_normal.png index 515e69f18..46946debd 100644 Binary files a/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_normal.png and b/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_private.png b/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_private.png index 7f246c172..376ec0699 100644 Binary files a/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_private.png and b/app/src/fenixProduction/res/drawable-xxhdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png b/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png index ce56c7c1f..f9816dabc 100644 Binary files a/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png and b/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_private.png b/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_private.png index 1816e8e97..b536c9655 100644 Binary files a/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_private.png and b/app/src/fenixProduction/res/drawable-xxxhdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt index 5b4ee3afe..f25f3ef9f 100644 --- a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt +++ b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt @@ -21,7 +21,7 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromSyncedTabs(R.id.syncedTabsFragment), FromBookmarks(R.id.bookmarkFragment), FromHistory(R.id.historyFragment), - FromExceptions(R.id.exceptionsFragment), + FromTrackingProtectionExceptions(R.id.trackingProtectionExceptionsFragment), FromAbout(R.id.aboutFragment), FromTrackingProtection(R.id.trackingProtectionFragment), FromSavedLoginsFragment(R.id.savedLoginsFragment), @@ -29,5 +29,6 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromAddSearchEngineFragment(R.id.addSearchEngineFragment), FromEditCustomSearchEngineFragment(R.id.editCustomSearchEngineFragment), FromAddonDetailsFragment(R.id.addonDetailsFragment), + FromAddonPermissionsDetailsFragment(R.id.addonPermissionsDetailFragment), FromLoginDetailFragment(R.id.loginDetailFragment) } diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 2112a3f3b..9f77509b1 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -56,13 +56,14 @@ import mozilla.components.support.utils.toSafeIntent import mozilla.components.support.webextensions.WebExtensionPopupFeature import org.mozilla.fenix.GleanMetrics.Metrics import org.mozilla.fenix.addons.AddonDetailsFragmentDirections +import org.mozilla.fenix.addons.AddonPermissionsDetailsFragmentDirections import org.mozilla.fenix.browser.UriOpenedObserver import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager import org.mozilla.fenix.components.metrics.BreadcrumbsRecorder import org.mozilla.fenix.components.metrics.Event -import org.mozilla.fenix.exceptions.ExceptionsFragmentDirections +import org.mozilla.fenix.trackingprotectionexceptions.TrackingProtectionExceptionsFragmentDirections import org.mozilla.fenix.ext.alreadyOnDestination import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.nav @@ -322,10 +323,12 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { private fun actionSorter(actions: Array): Array { val order = hashMapOf() - order["org.mozilla.geckoview.COPY"] = 0 - order["CUSTOM_CONTEXT_MENU_SEARCH"] = 1 - order["org.mozilla.geckoview.SELECT_ALL"] = 2 - order["CUSTOM_CONTEXT_MENU_SHARE"] = 3 + order["CUSTOM_CONTEXT_MENU_EMAIL"] = 0 + order["CUSTOM_CONTEXT_MENU_CALL"] = 1 + order["org.mozilla.geckoview.COPY"] = 2 + order["CUSTOM_CONTEXT_MENU_SEARCH"] = 3 + order["org.mozilla.geckoview.SELECT_ALL"] = 4 + order["CUSTOM_CONTEXT_MENU_SHARE"] = 5 return actions.sortedBy { actionName -> // Sort the actions in our preferred order, putting "other" actions unsorted at the end @@ -496,8 +499,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { BookmarkFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromHistory -> HistoryFragmentDirections.actionGlobalBrowser(customTabSessionId) - BrowserDirection.FromExceptions -> - ExceptionsFragmentDirections.actionGlobalBrowser(customTabSessionId) + BrowserDirection.FromTrackingProtectionExceptions -> + TrackingProtectionExceptionsFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromAbout -> AboutFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromTrackingProtection -> @@ -512,6 +515,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { EditCustomSearchEngineFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromAddonDetailsFragment -> AddonDetailsFragmentDirections.actionGlobalBrowser(customTabSessionId) + BrowserDirection.FromAddonPermissionsDetailsFragment -> + AddonPermissionsDetailsFragmentDirections.actionGlobalBrowser(customTabSessionId) BrowserDirection.FromLoginDetailFragment -> LoginDetailFragmentDirections.actionGlobalBrowser(customTabSessionId) } diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsFragment.kt index 28ef5e567..88bf2b9a3 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsFragment.kt @@ -4,61 +4,36 @@ package org.mozilla.fenix.addons -import android.content.Intent -import android.content.Intent.ACTION_VIEW +import android.net.Uri import android.os.Bundle import android.view.View -import androidx.annotation.StringRes -import androidx.core.net.toUri import androidx.fragment.app.Fragment import androidx.navigation.fragment.navArgs -import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_add_on_permissions.view.* -import mozilla.components.feature.addons.Addon -import mozilla.components.feature.addons.ui.AddonPermissionsAdapter import mozilla.components.feature.addons.ui.translatedName +import org.mozilla.fenix.BrowserDirection +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.ext.showToolbar -import org.mozilla.fenix.theme.ThemeManager - -private const val LEARN_MORE_URL = - "https://support.mozilla.org/kb/permission-request-messages-firefox-extensions" /** * A fragment to show the permissions of an add-on. */ -class AddonPermissionsDetailsFragment : Fragment(R.layout.fragment_add_on_permissions) { +class AddonPermissionsDetailsFragment : Fragment(R.layout.fragment_add_on_permissions), + AddonPermissionsDetailsInteractor { private val args by navArgs() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) showToolbar(args.addon.translatedName) - - bindPermissions(args.addon, view) - bindLearnMore(view) + AddonPermissionsDetailsView(view, interactor = this).bind(args.addon) } - private fun bindPermissions(addon: Addon, view: View) { - view.add_ons_permissions.apply { - layoutManager = LinearLayoutManager(requireContext()) - val sortedPermissions = addon.translatePermissions().map { - @StringRes val stringId = it - getString(stringId) - }.sorted() - adapter = AddonPermissionsAdapter( - sortedPermissions, - style = AddonPermissionsAdapter.Style( - ThemeManager.resolveAttribute(R.attr.primaryText, requireContext()) - ) - ) - } - } - - private fun bindLearnMore(view: View) { - view.learn_more_label.setOnClickListener { - val intent = Intent(ACTION_VIEW, LEARN_MORE_URL.toUri()) - startActivity(intent) - } + override fun openWebsite(addonSiteUrl: Uri) { + (activity as HomeActivity).openToBrowserAndLoad( + searchTermOrURL = addonSiteUrl.toString(), + newTab = true, + from = BrowserDirection.FromAddonPermissionsDetailsFragment + ) } } diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsView.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsView.kt new file mode 100644 index 000000000..e3f936df6 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsView.kt @@ -0,0 +1,66 @@ +/* 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.addons + +import android.net.Uri +import android.view.View +import androidx.annotation.StringRes +import androidx.core.net.toUri +import androidx.recyclerview.widget.LinearLayoutManager +import kotlinx.android.extensions.LayoutContainer +import kotlinx.android.synthetic.main.fragment_add_on_permissions.* +import mozilla.components.feature.addons.Addon +import mozilla.components.feature.addons.ui.AddonPermissionsAdapter +import org.mozilla.fenix.R +import org.mozilla.fenix.theme.ThemeManager + +interface AddonPermissionsDetailsInteractor { + + /** + * Open the given siteUrl in the browser. + */ + fun openWebsite(addonSiteUrl: Uri) +} + +/** + * Shows the permission details of an add-on. + */ +class AddonPermissionsDetailsView( + override val containerView: View, + private val interactor: AddonPermissionsDetailsInteractor +) : LayoutContainer { + + fun bind(addon: Addon) { + bindPermissions(addon) + bindLearnMore() + } + + private fun bindPermissions(addon: Addon) { + add_ons_permissions.apply { + layoutManager = LinearLayoutManager(context) + val sortedPermissions = addon.translatePermissions().map { + @StringRes val stringId = it + context.getString(stringId) + }.sorted() + adapter = AddonPermissionsAdapter( + sortedPermissions, + style = AddonPermissionsAdapter.Style( + ThemeManager.resolveAttribute(R.attr.primaryText, context) + ) + ) + } + } + + private fun bindLearnMore() { + learn_more_label.setOnClickListener { + interactor.openWebsite(LEARN_MORE_URL.toUri()) + } + } + + private companion object { + const val LEARN_MORE_URL = + "https://support.mozilla.org/kb/permission-request-messages-firefox-extensions" + } +} diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt index 9afcb871f..ce2a4188a 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt @@ -25,12 +25,13 @@ import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManagerException import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment import mozilla.components.feature.addons.ui.AddonsManagerAdapter -import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate import mozilla.components.feature.addons.ui.PermissionsDialogFragment import mozilla.components.feature.addons.ui.translatedName import org.mozilla.fenix.R +import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.getRootView +import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.theme.ThemeManager @@ -39,9 +40,9 @@ import java.util.concurrent.CancellationException /** * Fragment use for managing add-ons. */ -@Suppress("TooManyFunctions", "LargeClass") -class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management), - AddonsManagerAdapterDelegate { +@Suppress("TooManyFunctions") +class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) { + /** * Whether or not an add-on installation is in progress. */ @@ -65,23 +66,12 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management), } } - override fun onAddonItemClicked(addon: Addon) { - if (addon.isInstalled()) { - showInstalledAddonDetailsFragment(addon) - } else { - showDetailsFragment(addon) - } - } - - override fun onInstallAddonButtonClicked(addon: Addon) { - showPermissionDialog(addon) - } - - override fun onNotYetSupportedSectionClicked(unsupportedAddons: List) { - showNotYetSupportedAddonFragment(ArrayList(unsupportedAddons)) - } - private fun bindRecyclerView(view: View) { + val managementView = AddonsManagementView( + navController = findNavController(), + showPermissionDialog = ::showPermissionDialog + ) + val recyclerView = view.add_ons_list recyclerView.layoutManager = LinearLayoutManager(requireContext()) val shouldRefresh = adapter != null @@ -93,7 +83,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management), if (!shouldRefresh) { adapter = AddonsManagerAdapter( requireContext().components.addonCollectionProvider, - this@AddonsManagementFragment, + managementView, addons, style = createAddonStyle(requireContext()) ) @@ -135,30 +125,6 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management), ) } - private fun showInstalledAddonDetailsFragment(addon: Addon) { - val directions = - AddonsManagementFragmentDirections.actionAddonsManagementFragmentToInstalledAddonDetails( - addon - ) - findNavController().navigate(directions) - } - - private fun showDetailsFragment(addon: Addon) { - val directions = - AddonsManagementFragmentDirections.actionAddonsManagementFragmentToAddonDetailsFragment( - addon - ) - findNavController().navigate(directions) - } - - private fun showNotYetSupportedAddonFragment(unsupportedAddons: ArrayList) { - val directions = - AddonsManagementFragmentDirections.actionAddonsManagementFragmentToNotYetSupportedAddonFragment( - unsupportedAddons.toTypedArray() - ) - findNavController().navigate(directions) - } - private fun findPreviousDialogFragment(): PermissionsDialogFragment? { return parentFragmentManager.findFragmentByTag(PERMISSIONS_DIALOG_FRAGMENT_TAG) as? PermissionsDialogFragment } @@ -192,11 +158,13 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management), onPositiveButtonClicked = onPositiveButtonClicked ) dialog.show(parentFragmentManager, PERMISSIONS_DIALOG_FRAGMENT_TAG) + requireContext().components.analytics.metrics.track(Event.AddonInstalled(addon.id)) } } private fun showInstallationDialog(addon: Addon) { if (!isInstallationInProgress && !hasExistingAddonInstallationDialogFragment()) { + requireComponents.analytics.metrics.track(Event.AddonInstalled(addon.id)) val addonCollectionProvider = requireContext().components.addonCollectionProvider val dialog = AddonInstallationDialogFragment.newInstance( diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementView.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementView.kt new file mode 100644 index 000000000..2a6370ed6 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementView.kt @@ -0,0 +1,58 @@ +/* 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.addons + +import androidx.navigation.NavController +import mozilla.components.feature.addons.Addon +import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate + +/** + * View used for managing add-ons. + */ +class AddonsManagementView( + private val navController: NavController, + private val showPermissionDialog: (Addon) -> Unit +) : AddonsManagerAdapterDelegate { + + override fun onAddonItemClicked(addon: Addon) { + if (addon.isInstalled()) { + showInstalledAddonDetailsFragment(addon) + } else { + showDetailsFragment(addon) + } + } + + override fun onInstallAddonButtonClicked(addon: Addon) { + showPermissionDialog(addon) + } + + override fun onNotYetSupportedSectionClicked(unsupportedAddons: List) { + showNotYetSupportedAddonFragment(unsupportedAddons) + } + + private fun showInstalledAddonDetailsFragment(addon: Addon) { + val directions = + AddonsManagementFragmentDirections.actionAddonsManagementFragmentToInstalledAddonDetails( + addon + ) + navController.navigate(directions) + } + + private fun showDetailsFragment(addon: Addon) { + val directions = + AddonsManagementFragmentDirections.actionAddonsManagementFragmentToAddonDetailsFragment( + addon + ) + navController.navigate(directions) + } + + private fun showNotYetSupportedAddonFragment(unsupportedAddons: List) { + val directions = + AddonsManagementFragmentDirections.actionAddonsManagementFragmentToNotYetSupportedAddonFragment( + unsupportedAddons.toTypedArray() + ) + navController.navigate(directions) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 254740e31..326b01b60 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -443,6 +443,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session isSaveLoginEnabled = { context.settings().shouldPromptToSaveLogins }, + loginExceptionStorage = context.components.core.loginExceptionStorage, shareDelegate = object : ShareDelegate { override fun showShareSheet( context: Context, diff --git a/app/src/main/java/org/mozilla/fenix/components/Core.kt b/app/src/main/java/org/mozilla/fenix/components/Core.kt index 9bfe78f1c..752de367b 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Core.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Core.kt @@ -30,6 +30,7 @@ import mozilla.components.concept.engine.mediaquery.PreferredColorScheme import mozilla.components.concept.fetch.Client import mozilla.components.feature.customtabs.store.CustomTabsServiceStore import mozilla.components.feature.downloads.DownloadMiddleware +import mozilla.components.feature.logins.exceptions.LoginExceptionStorage import mozilla.components.feature.media.RecordingDevicesNotificationFeature import mozilla.components.feature.media.middleware.MediaMiddleware import mozilla.components.feature.pwa.ManifestStorage @@ -251,6 +252,8 @@ class Core(private val context: Context) { val webAppManifestStorage by lazy { ManifestStorage(context) } + val loginExceptionStorage by lazy { LoginExceptionStorage(context) } + /** * Shared Preferences that encrypt/decrypt using Android KeyStore and lib-dataprotect for 23+ * only on Nightly/Debug for now, otherwise simply stored. diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index 043cfed25..bd1c43e7c 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -650,6 +650,7 @@ private val Event.wrapper: EventWrapper<*>? is Event.ClearedPrivateData -> null is Event.DismissedOnboarding -> null is Event.FennecToFenixMigrated -> null + is Event.AddonInstalled -> null } class GleanMetricsService(private val context: Context) : MetricsService { diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt index 957d5617e..d3aa0c8c3 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt @@ -38,9 +38,10 @@ private val Event.name: String? is Event.ClearedPrivateData -> "E_Cleared_Private_Data" is Event.DismissedOnboarding -> "E_Dismissed_Onboarding" is Event.FennecToFenixMigrated -> "E_Fennec_To_Fenix_Migrated" + is Event.AddonInstalled -> "E_Addon_Installed" // Do not track other events in Leanplum - else -> "" + else -> null } class LeanplumMetricsService(private val application: Application) : MetricsService { diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt index 007dd1536..9e8fe2d88 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt @@ -465,6 +465,8 @@ sealed class Event { } object CrashReporterOpened : Event() + data class AddonInstalled(val addonId: String) : Event() + data class CrashReporterClosed(val crashSubmitted: Boolean) : Event() { override val extras: Map? get() = mapOf(CrashReporter.closedKeys.crashSubmitted to crashSubmitted.toString()) diff --git a/app/src/main/java/org/mozilla/fenix/components/searchengine/FenixSearchEngineProvider.kt b/app/src/main/java/org/mozilla/fenix/components/searchengine/FenixSearchEngineProvider.kt index 6d61f2440..8e1c28ed8 100644 --- a/app/src/main/java/org/mozilla/fenix/components/searchengine/FenixSearchEngineProvider.kt +++ b/app/src/main/java/org/mozilla/fenix/components/searchengine/FenixSearchEngineProvider.kt @@ -43,6 +43,13 @@ open class FenixSearchEngineProvider( ) } + // We have two search engine types: one based on MLS reported region, one based only on Locale. + // There are multiple steps involved in returning the default search engine for example. + // Simplest and most effective way to make sure the MLS engines do not mix with Locale based engines + // is to use the same type of engines for the entire duration of the app's run. + // See fenix/issues/11875 + private val isRegionCachedByLocationService = locationService.hasRegionCached() + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) open val localizationProvider: SearchLocalizationProvider = RegionSearchLocalizationProvider(locationService) @@ -91,7 +98,7 @@ open class FenixSearchEngineProvider( // the main one hasn't completed yet private val searchEngines: Deferred get() = - if (loadedSearchEngines.isCompleted) { + if (isRegionCachedByLocationService) { loadedSearchEngines } else { fallbackEngines @@ -200,7 +207,7 @@ open class FenixSearchEngineProvider( if (!prefs.contains(installedEnginesKey)) { val searchEngines = - if (baseSearchEngines.isCompleted) baseSearchEngines + if (isRegionCachedByLocationService) baseSearchEngines else fallbackEngines val defaultSet = searchEngines.await() @@ -219,7 +226,7 @@ open class FenixSearchEngineProvider( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) suspend fun localeAwareInstalledEnginesKey(): String { - val tag = if (loadedRegion.isCompleted) { + val tag = if (isRegionCachedByLocationService) { val localization = loadedRegion.await() val region = localization.region?.let { if (it.isEmpty()) "" else "-$it" diff --git a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt index 92433aae5..f4128e335 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt @@ -10,7 +10,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.navigation.NavDirections import androidx.navigation.NavOptions -import androidx.navigation.Navigator import androidx.navigation.fragment.NavHostFragment.findNavController import androidx.navigation.fragment.findNavController import org.mozilla.fenix.NavHostActivity @@ -23,15 +22,7 @@ import org.mozilla.fenix.components.Components val Fragment.requireComponents: Components get() = requireContext().components -fun Fragment.nav(@IdRes id: Int?, directions: NavDirections) { - findNavController(this).nav(id, directions) -} - -fun Fragment.nav(@IdRes id: Int?, directions: NavDirections, extras: Navigator.Extras) { - findNavController(this).nav(id, directions, extras) -} - -fun Fragment.nav(@IdRes id: Int?, directions: NavDirections, options: NavOptions) { +fun Fragment.nav(@IdRes id: Int?, directions: NavDirections, options: NavOptions? = null) { findNavController(this).nav(id, directions, options) } diff --git a/app/src/main/java/org/mozilla/fenix/ext/NavController.kt b/app/src/main/java/org/mozilla/fenix/ext/NavController.kt index 912fd6e16..4034c2472 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/NavController.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/NavController.kt @@ -4,12 +4,10 @@ package org.mozilla.fenix.ext -import android.os.Bundle import androidx.annotation.IdRes import androidx.navigation.NavController import androidx.navigation.NavDirections import androidx.navigation.NavOptions -import androidx.navigation.Navigator import io.sentry.Sentry import org.mozilla.fenix.components.isSentryEnabled @@ -25,35 +23,6 @@ fun NavController.nav(@IdRes id: Int?, directions: NavDirections, navOptions: Na } } -fun NavController.nav(@IdRes id: Int?, directions: NavDirections, extras: Navigator.Extras) { - if (id == null || this.currentDestination?.id == id) { - this.navigate(directions, extras) - } else { - recordIdException(this.currentDestination?.id, id) - } -} - -fun NavController.nav( - @IdRes id: Int?, - directions: NavDirections, - navOptions: NavOptions? = null, - extras: Navigator.Extras? = null -) = nav(id, directions.actionId, directions.arguments, navOptions, extras) - -fun NavController.nav( - @IdRes id: Int?, - @IdRes destId: Int, - args: Bundle?, - navOptions: NavOptions?, - extras: Navigator.Extras? -) { - if (id == null || this.currentDestination?.id == id) { - this.navigate(destId, args, navOptions, extras) - } else { - recordIdException(this.currentDestination?.id, id) - } -} - fun NavController.alreadyOnDestination(@IdRes destId: Int?): Boolean { return destId?.let { currentDestination?.id == it || popBackStack(it, false) } ?: false } diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt index 446e58aaa..4812197db 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt @@ -9,17 +9,18 @@ import android.content.Context import android.view.MotionEvent import android.view.View import android.widget.PopupWindow +import androidx.appcompat.content.res.AppCompatResources.getDrawable import kotlinx.android.synthetic.main.top_site_item.* import kotlinx.android.synthetic.main.top_site_item.view.* import mozilla.components.browser.menu.BrowserMenuBuilder import mozilla.components.browser.menu.item.SimpleBrowserMenuItem import mozilla.components.feature.top.sites.TopSite import org.mozilla.fenix.R -import org.mozilla.fenix.utils.view.ViewHolder import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.loadIntoView import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor import org.mozilla.fenix.settings.SupportUtils +import org.mozilla.fenix.utils.view.ViewHolder class TopSiteItemViewHolder( view: View, @@ -42,12 +43,12 @@ class TopSiteItemViewHolder( interactor.onSelectTopSite(topSite.url, topSite.isDefault) } - top_site_item.setOnLongClickListener() { + top_site_item.setOnLongClickListener { val menu = topSiteMenu.menuBuilder.build(view.context).show(anchor = it.top_site_title) it.setOnTouchListener @SuppressLint("ClickableViewAccessibility") { v, event -> onTouchEvent(v, event, menu) } - return@setOnLongClickListener true + true } } @@ -56,7 +57,7 @@ class TopSiteItemViewHolder( top_site_title.text = topSite.title when (topSite.url) { SupportUtils.POCKET_TRENDING_URL -> { - favicon_image.setImageDrawable(itemView.context.getDrawable(R.drawable.ic_pocket)) + favicon_image.setImageDrawable(getDrawable(itemView.context, R.drawable.ic_pocket)) } else -> { itemView.context.components.core.icons.loadIntoView(favicon_image, topSite.url) diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/ExceptionsFragmentStore.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/ExceptionsFragmentStore.kt new file mode 100644 index 000000000..88ddfbfea --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/ExceptionsFragmentStore.kt @@ -0,0 +1,41 @@ +/* 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.loginexceptions + +import mozilla.components.feature.logins.exceptions.LoginException +import mozilla.components.lib.state.Action +import mozilla.components.lib.state.State +import mozilla.components.lib.state.Store + +/** + * The [Store] for holding the [ExceptionsFragmentState] and applying [ExceptionsFragmentAction]s. + */ +class ExceptionsFragmentStore(initialState: ExceptionsFragmentState) : + Store(initialState, ::exceptionsStateReducer) + +/** + * Actions to dispatch through the `ExceptionsStore` to modify `ExceptionsState` through the reducer. + */ +sealed class ExceptionsFragmentAction : Action { + data class Change(val list: List) : ExceptionsFragmentAction() +} + +/** + * The state for the Exceptions Screen + * @property items List of exceptions to display + */ +data class ExceptionsFragmentState(val items: List) : State + +/** + * The ExceptionsState Reducer. + */ +private fun exceptionsStateReducer( + state: ExceptionsFragmentState, + action: ExceptionsFragmentAction +): ExceptionsFragmentState { + return when (action) { + is ExceptionsFragmentAction.Change -> state.copy(items = action.list) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsAdapter.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsAdapter.kt new file mode 100644 index 000000000..5a5031490 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsAdapter.kt @@ -0,0 +1,81 @@ +/* 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.loginexceptions + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import mozilla.components.feature.logins.exceptions.LoginException +import org.mozilla.fenix.loginexceptions.viewholders.LoginExceptionsDeleteButtonViewHolder +import org.mozilla.fenix.loginexceptions.viewholders.LoginExceptionsHeaderViewHolder +import org.mozilla.fenix.loginexceptions.viewholders.LoginExceptionsListItemViewHolder + +sealed class AdapterItem { + object DeleteButton : AdapterItem() + object Header : AdapterItem() + data class Item(val item: LoginException) : AdapterItem() +} + +/** + * Adapter for a list of sites that are exempted from saving logins, + * along with controls to remove the exception. + */ +class LoginExceptionsAdapter( + private val interactor: LoginExceptionsInteractor +) : ListAdapter(DiffCallback) { + + /** + * Change the list of items that are displayed. + * Header and footer items are added to the list as well. + */ + fun updateData(exceptions: List) { + val adapterItems: List = + listOf(AdapterItem.Header) + exceptions.map { AdapterItem.Item(it) } + listOf( + AdapterItem.DeleteButton + ) + submitList(adapterItems) + } + + override fun getItemViewType(position: Int) = when (getItem(position)) { + AdapterItem.DeleteButton -> LoginExceptionsDeleteButtonViewHolder.LAYOUT_ID + AdapterItem.Header -> LoginExceptionsHeaderViewHolder.LAYOUT_ID + is AdapterItem.Item -> LoginExceptionsListItemViewHolder.LAYOUT_ID + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false) + + return when (viewType) { + LoginExceptionsDeleteButtonViewHolder.LAYOUT_ID -> LoginExceptionsDeleteButtonViewHolder( + view, + interactor + ) + LoginExceptionsHeaderViewHolder.LAYOUT_ID -> LoginExceptionsHeaderViewHolder(view) + LoginExceptionsListItemViewHolder.LAYOUT_ID -> LoginExceptionsListItemViewHolder( + view, + interactor + ) + else -> throw IllegalStateException() + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is LoginExceptionsListItemViewHolder) { + val adapterItem = getItem(position) as AdapterItem.Item + holder.bind(adapterItem.item) + } + } + + private object DiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: AdapterItem, newItem: AdapterItem) = + areContentsTheSame(oldItem, newItem) + + @Suppress("DiffUtilEquals") + override fun areContentsTheSame(oldItem: AdapterItem, newItem: AdapterItem) = + oldItem == newItem + } +} diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsFragment.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsFragment.kt new file mode 100644 index 000000000..d2be2d66f --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsFragment.kt @@ -0,0 +1,88 @@ +/* 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.loginexceptions + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.asLiveData +import androidx.lifecycle.lifecycleScope +import kotlinx.android.synthetic.main.fragment_exceptions.view.* +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import mozilla.components.feature.logins.exceptions.LoginException +import mozilla.components.lib.state.ext.consumeFrom +import org.mozilla.fenix.R +import org.mozilla.fenix.components.StoreProvider +import org.mozilla.fenix.ext.requireComponents +import org.mozilla.fenix.ext.showToolbar + +/** + * Displays a list of sites that are exempted from saving logins, + * along with controls to remove the exception. + */ +class LoginExceptionsFragment : Fragment() { + private lateinit var exceptionsStore: ExceptionsFragmentStore + private lateinit var exceptionsView: LoginExceptionsView + private lateinit var exceptionsInteractor: LoginExceptionsInteractor + + override fun onResume() { + super.onResume() + showToolbar(getString(R.string.preference_exceptions)) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val view = inflater.inflate(R.layout.fragment_exceptions, container, false) + exceptionsStore = StoreProvider.get(this) { + ExceptionsFragmentStore( + ExceptionsFragmentState( + items = listOf() + ) + ) + } + exceptionsInteractor = + LoginExceptionsInteractor(::deleteOneItem, ::deleteAllItems) + exceptionsView = LoginExceptionsView(view.exceptionsLayout, exceptionsInteractor) + subscribeToLoginExceptions() + return view + } + + private fun subscribeToLoginExceptions(): Observer> { + return Observer> { exceptions -> + exceptionsStore.dispatch(ExceptionsFragmentAction.Change(exceptions)) + }.also { observer -> + requireComponents.core.loginExceptionStorage.getLoginExceptions().asLiveData() + .observe(viewLifecycleOwner, observer) + } + } + + @ExperimentalCoroutinesApi + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + consumeFrom(exceptionsStore) { + exceptionsView.update(it) + } + } + + private fun deleteAllItems() { + viewLifecycleOwner.lifecycleScope.launch(IO) { + requireComponents.core.loginExceptionStorage.deleteAllLoginExceptions() + } + } + + private fun deleteOneItem(item: LoginException) { + viewLifecycleOwner.lifecycleScope.launch(IO) { + requireComponents.core.loginExceptionStorage.removeLoginException(item) + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsInteractor.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsInteractor.kt new file mode 100644 index 000000000..8a5881c05 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsInteractor.kt @@ -0,0 +1,24 @@ +/* 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.loginexceptions + +import mozilla.components.feature.logins.exceptions.LoginException + +/** + * Interactor for the exceptions screen + * Provides implementations for the ExceptionsViewInteractor + */ +class LoginExceptionsInteractor( + private val deleteOne: (LoginException) -> Unit, + private val deleteAll: () -> Unit +) : ExceptionsViewInteractor { + override fun onDeleteAll() { + deleteAll.invoke() + } + + override fun onDeleteOne(item: LoginException) { + deleteOne.invoke(item) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsView.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsView.kt new file mode 100644 index 000000000..26854bba7 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/LoginExceptionsView.kt @@ -0,0 +1,62 @@ +/* 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.loginexceptions + +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.FrameLayout +import androidx.core.view.isVisible +import androidx.recyclerview.widget.LinearLayoutManager +import kotlinx.android.extensions.LayoutContainer +import kotlinx.android.synthetic.main.component_exceptions.view.* +import mozilla.components.feature.logins.exceptions.LoginException +import org.mozilla.fenix.R + +/** + * Interface for the ExceptionsViewInteractor. This interface is implemented by objects that want + * to respond to user interaction on the ExceptionsView + */ +interface ExceptionsViewInteractor { + /** + * Called whenever all exception items are deleted + */ + fun onDeleteAll() + + /** + * Called whenever one exception item is deleted + */ + fun onDeleteOne(item: LoginException) +} + +/** + * View that contains and configures the Exceptions List + */ +class LoginExceptionsView( + override val containerView: ViewGroup, + val interactor: LoginExceptionsInteractor +) : LayoutContainer { + + val view: FrameLayout = LayoutInflater.from(containerView.context) + .inflate(R.layout.component_exceptions, containerView, true) + .findViewById(R.id.exceptions_wrapper) + + private val exceptionsAdapter = LoginExceptionsAdapter(interactor) + + init { + view.exceptions_learn_more.isVisible = false + view.exceptions_empty_message.text = + view.context.getString(R.string.preferences_passwords_exceptions_description_empty) + view.exceptions_list.apply { + adapter = exceptionsAdapter + layoutManager = LinearLayoutManager(containerView.context) + } + } + + fun update(state: ExceptionsFragmentState) { + view.exceptions_empty_view.isVisible = state.items.isEmpty() + view.exceptions_list.isVisible = state.items.isNotEmpty() + exceptionsAdapter.updateData(state.items) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsDeleteButtonViewHolder.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsDeleteButtonViewHolder.kt new file mode 100644 index 000000000..a69ecf312 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsDeleteButtonViewHolder.kt @@ -0,0 +1,28 @@ +/* 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.loginexceptions.viewholders + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.delete_exceptions_button.view.* +import org.mozilla.fenix.R +import org.mozilla.fenix.loginexceptions.LoginExceptionsInteractor + +class LoginExceptionsDeleteButtonViewHolder( + view: View, + private val interactor: LoginExceptionsInteractor +) : RecyclerView.ViewHolder(view) { + private val deleteButton = view.removeAllExceptions + + init { + deleteButton.setOnClickListener { + interactor.onDeleteAll() + } + } + + companion object { + const val LAYOUT_ID = R.layout.delete_logins_exceptions_button + } +} diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsHeaderViewHolder.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsHeaderViewHolder.kt new file mode 100644 index 000000000..0a2033f16 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsHeaderViewHolder.kt @@ -0,0 +1,23 @@ +/* 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.loginexceptions.viewholders + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.exceptions_description.view.* +import org.mozilla.fenix.R + +class LoginExceptionsHeaderViewHolder( + view: View +) : RecyclerView.ViewHolder(view) { + companion object { + const val LAYOUT_ID = R.layout.exceptions_description + } + + init { + view.exceptions_description.text = + view.context.getString(R.string.preferences_passwords_exceptions_description) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsListItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsListItemViewHolder.kt new file mode 100644 index 000000000..688da089a --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/loginexceptions/viewholders/LoginExceptionsListItemViewHolder.kt @@ -0,0 +1,50 @@ +/* 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.loginexceptions.viewholders + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.exception_item.view.* +import mozilla.components.feature.logins.exceptions.LoginException +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.loadIntoView +import org.mozilla.fenix.loginexceptions.LoginExceptionsInteractor + +/** + * View holder for a single website that is exempted from Tracking Protection. + */ +class LoginExceptionsListItemViewHolder( + view: View, + private val interactor: LoginExceptionsInteractor +) : RecyclerView.ViewHolder(view) { + + private val favicon = view.favicon_image + private val url = view.webAddressView + private val deleteButton = view.delete_exception + + private var item: LoginException? = null + + init { + deleteButton.setOnClickListener { + item?.let { + interactor.onDeleteOne(it) + } + } + } + + fun bind(item: LoginException) { + this.item = item + url.text = item.origin + } + + private fun updateFavIcon(url: String) { + favicon.context.components.core.icons.loadIntoView(favicon, url) + } + + companion object { + const val LAYOUT_ID = R.layout.exception_item + } +} diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt b/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt index 7ef4aa16a..7268f45eb 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchFragmentStore.kt @@ -96,9 +96,7 @@ private fun searchStateReducer(state: SearchFragmentState, action: SearchFragmen is SearchFragmentAction.UpdateQuery -> state.copy(query = action.query) is SearchFragmentAction.SelectNewDefaultSearchEngine -> - state.copy( - searchEngineSource = SearchEngineSource.Default(action.engine) - ) + state.copy(searchEngineSource = SearchEngineSource.Default(action.engine)) is SearchFragmentAction.AllowSearchSuggestionsInPrivateModePrompt -> state.copy(showSearchSuggestionsHint = action.show) is SearchFragmentAction.SetShowSearchSuggestions -> diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/ShortcutsSuggestionProvider.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/ShortcutsSuggestionProvider.kt index a81f8bd82..9bba4db2b 100644 --- a/app/src/main/java/org/mozilla/fenix/search/awesomebar/ShortcutsSuggestionProvider.kt +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/ShortcutsSuggestionProvider.kt @@ -34,16 +34,15 @@ class ShortcutsSuggestionProvider( override suspend fun onInputChanged(text: String): List { val suggestions = mutableListOf() - searchEngineProvider.installedSearchEngines(context).list.forEach { - suggestions.add( - AwesomeBar.Suggestion( - provider = this, - id = it.identifier, - icon = it.icon, - title = it.name, - onSuggestionClicked = { - selectShortcutEngine(it) - }) + searchEngineProvider.installedSearchEngines(context).list.mapTo(suggestions) { + AwesomeBar.Suggestion( + provider = this, + id = it.identifier, + icon = it.icon, + title = it.name, + onSuggestionClicked = { + selectShortcutEngine(it) + } ) } @@ -55,7 +54,8 @@ class ShortcutsSuggestionProvider( title = context.getString(R.string.search_shortcuts_engine_settings), onSuggestionClicked = { selectShortcutEngineSettings() - }) + } + ) ) return suggestions } 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 4eb97f40b..34ee23dc1 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 @@ -22,24 +22,24 @@ import org.mozilla.fenix.theme.ThemeManager /** * Interface for the Toolbar Interactor. This interface is implemented by objects that want - * to respond to user interaction on the [BrowserToolbarView] + * to respond to user interaction on the [ToolbarView] */ interface ToolbarInteractor { /** - * Called when a user hits the return key while [BrowserToolbarView] has focus. - * @param url the text inside the [BrowserToolbarView] when committed + * Called when a user hits the return key while [ToolbarView] has focus. + * @param url the text inside the [ToolbarView] when committed */ fun onUrlCommitted(url: String) /** - * Called when a user removes focus from the [BrowserToolbarView] + * Called when a user removes focus from the [ToolbarView] */ fun onEditingCanceled() /** - * Called whenever the text inside the [BrowserToolbarView] changes - * @param text the current text displayed by [BrowserToolbarView] + * Called whenever the text inside the [ToolbarView] changes + * @param text the current text displayed by [ToolbarView] */ fun onTextChanged(text: String) } @@ -103,7 +103,7 @@ class ToolbarView( override fun onTextChanged(text: String) { url = text - this@ToolbarView.interactor.onTextChanged(text) + interactor.onTextChanged(text) } }) } diff --git a/app/src/main/java/org/mozilla/fenix/settings/TrackingProtectionFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/TrackingProtectionFragment.kt index 9c21ec3ab..e984b0013 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/TrackingProtectionFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/TrackingProtectionFragment.kt @@ -25,7 +25,7 @@ import org.mozilla.fenix.utils.view.addToRadioGroup /** * Displays the toggle for tracking protection, options for tracking protection policy and a button - * to open info about the tracking protection [org.mozilla.fenix.exceptions.ExceptionsFragment]. + * to open info about the tracking protection [org.mozilla.fenix.settings.TrackingProtectionFragment]. */ class TrackingProtectionFragment : PreferenceFragmentCompat() { @@ -56,7 +56,8 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() { showToolbar(getString(R.string.preference_enhanced_tracking_protection)) // Tracking Protection Switch - val preferenceTP = requirePreference(R.string.pref_key_tracking_protection) + val preferenceTP = + requirePreference(R.string.pref_key_tracking_protection) preferenceTP.isChecked = requireContext().settings().shouldUseTrackingProtection preferenceTP.setOnPreferenceChangeListener { preference, trackingProtectionOn -> @@ -86,7 +87,8 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() { getString(R.string.app_name) ) - val preferenceExceptions = requirePreference(R.string.pref_key_tracking_protection_exceptions) + val preferenceExceptions = + requirePreference(R.string.pref_key_tracking_protection_exceptions) preferenceExceptions.onPreferenceClickListener = exceptionsClickListener } diff --git a/app/src/main/java/org/mozilla/fenix/settings/account/AccountSettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/account/AccountSettingsFragment.kt index 320573e65..0eab4909c 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/account/AccountSettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/account/AccountSettingsFragment.kt @@ -34,6 +34,7 @@ import mozilla.components.service.fxa.manager.SyncEnginesStorage import mozilla.components.service.fxa.sync.SyncReason import mozilla.components.service.fxa.sync.SyncStatusObserver import mozilla.components.service.fxa.sync.getLastSynced +import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.util.dpToPx import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R @@ -138,6 +139,10 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { preferenceSyncNow.apply { onPreferenceClickListener = getClickListenerForSyncNow() + icon = icon.mutate().apply { + setTint(context.getColorFromAttr(R.attr.primaryText)) + } + // Current sync state if (requireComponents.backgroundServices.accountManager.isSyncActive()) { title = getString(R.string.sync_syncing_in_progress) diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsAuthFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsAuthFragment.kt index d0831e62b..d8051e7f3 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsAuthFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsAuthFragment.kt @@ -133,6 +133,13 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat(), AccountObserver { } } + requirePreference(R.string.pref_key_login_exceptions).apply { + setOnPreferenceClickListener { + navigateToLoginExceptionFragment() + true + } + } + requirePreference(R.string.pref_key_autofill_logins).apply { isChecked = context.settings().shouldAutofillLogins onPreferenceChangeListener = object : SharedPreferenceUpdater() { @@ -322,6 +329,12 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat(), AccountObserver { findNavController().navigate(directions) } + private fun navigateToLoginExceptionFragment() { + val directions = + SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginExceptionsFragment() + findNavController().navigate(directions) + } + companion object { const val SHORT_DELAY_MS = 100L private const val LOG_TAG = "LoginsFragment" diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsAdapter.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsAdapter.kt similarity index 89% rename from app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsAdapter.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsAdapter.kt index 1f5c62dd7..a2adfdd5d 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsAdapter.kt @@ -2,7 +2,7 @@ * 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.exceptions +package org.mozilla.fenix.trackingprotectionexceptions import android.view.LayoutInflater import android.view.ViewGroup @@ -10,9 +10,9 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import mozilla.components.concept.engine.content.blocking.TrackingProtectionException -import org.mozilla.fenix.exceptions.viewholders.ExceptionsDeleteButtonViewHolder -import org.mozilla.fenix.exceptions.viewholders.ExceptionsHeaderViewHolder -import org.mozilla.fenix.exceptions.viewholders.ExceptionsListItemViewHolder +import org.mozilla.fenix.trackingprotectionexceptions.viewholders.ExceptionsDeleteButtonViewHolder +import org.mozilla.fenix.trackingprotectionexceptions.viewholders.ExceptionsHeaderViewHolder +import org.mozilla.fenix.trackingprotectionexceptions.viewholders.ExceptionsListItemViewHolder /** * Adapter for a list of sites that are exempted from Tracking Protection, diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragmentStore.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsFragmentStore.kt similarity index 96% rename from app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragmentStore.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsFragmentStore.kt index 1ba13b0dd..6d51f98a3 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragmentStore.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsFragmentStore.kt @@ -2,7 +2,7 @@ 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.exceptions +package org.mozilla.fenix.trackingprotectionexceptions import mozilla.components.concept.engine.content.blocking.TrackingProtectionException import mozilla.components.lib.state.Action diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsInteractor.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsInteractor.kt similarity index 93% rename from app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsInteractor.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsInteractor.kt index 9ec50c71f..e609cd003 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsInteractor.kt @@ -2,7 +2,7 @@ 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.exceptions +package org.mozilla.fenix.trackingprotectionexceptions import mozilla.components.concept.engine.content.blocking.TrackingProtectionException diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsView.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsView.kt similarity index 94% rename from app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsView.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsView.kt index b40dcf5f0..090d9c303 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsView.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/ExceptionsView.kt @@ -2,7 +2,7 @@ * 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.exceptions +package org.mozilla.fenix.trackingprotectionexceptions import android.text.method.LinkMovementMethod import android.text.style.UnderlineSpan @@ -50,7 +50,10 @@ class ExceptionsView( .inflate(R.layout.component_exceptions, container, true) .findViewById(R.id.exceptions_wrapper) - private val exceptionsAdapter = ExceptionsAdapter(interactor) + private val exceptionsAdapter = + ExceptionsAdapter( + interactor + ) init { exceptions_list.apply { diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragment.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/TrackingProtectionExceptionsFragment.kt similarity index 83% rename from app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragment.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/TrackingProtectionExceptionsFragment.kt index f1ba7582e..79b37e13c 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/TrackingProtectionExceptionsFragment.kt @@ -2,7 +2,7 @@ * 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.exceptions +package org.mozilla.fenix.trackingprotectionexceptions import android.os.Bundle import android.util.Log @@ -27,7 +27,7 @@ import org.mozilla.fenix.settings.SupportUtils * Displays a list of sites that are exempted from Tracking Protection, * along with controls to remove the exception. */ -class ExceptionsFragment : Fragment() { +class TrackingProtectionExceptionsFragment : Fragment() { private lateinit var exceptionsStore: ExceptionsFragmentStore private lateinit var exceptionsView: ExceptionsView @@ -54,8 +54,16 @@ class ExceptionsFragment : Fragment() { ) } exceptionsInteractor = - ExceptionsInteractor(::openLearnMore, ::deleteOneItem, ::deleteAllItems) - exceptionsView = ExceptionsView(view.exceptionsLayout, exceptionsInteractor) + ExceptionsInteractor( + ::openLearnMore, + ::deleteOneItem, + ::deleteAllItems + ) + exceptionsView = + ExceptionsView( + view.exceptionsLayout, + exceptionsInteractor + ) reloadExceptions() return view } @@ -83,13 +91,17 @@ class ExceptionsFragment : Fragment() { searchTermOrURL = SupportUtils.getGenericSumoURLForTopic (SupportUtils.SumoTopic.TRACKING_PROTECTION), newTab = true, - from = BrowserDirection.FromExceptions + from = BrowserDirection.FromTrackingProtectionExceptions ) } private fun reloadExceptions() { trackingProtectionUseCases.fetchExceptions { resultList -> - exceptionsStore.dispatch(ExceptionsFragmentAction.Change(resultList)) + exceptionsStore.dispatch( + ExceptionsFragmentAction.Change( + resultList + ) + ) } } } diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsDeleteButtonViewHolder.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsDeleteButtonViewHolder.kt similarity index 84% rename from app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsDeleteButtonViewHolder.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsDeleteButtonViewHolder.kt index 9a0ed172c..d25754bdf 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsDeleteButtonViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsDeleteButtonViewHolder.kt @@ -2,13 +2,13 @@ * 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.exceptions.viewholders +package org.mozilla.fenix.trackingprotectionexceptions.viewholders import android.view.View import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.delete_exceptions_button.view.* import org.mozilla.fenix.R -import org.mozilla.fenix.exceptions.ExceptionsInteractor +import org.mozilla.fenix.trackingprotectionexceptions.ExceptionsInteractor class ExceptionsDeleteButtonViewHolder( view: View, diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsHeaderViewHolder.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsHeaderViewHolder.kt similarity index 87% rename from app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsHeaderViewHolder.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsHeaderViewHolder.kt index 7902c3505..2a5c7b54d 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsHeaderViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsHeaderViewHolder.kt @@ -2,7 +2,7 @@ * 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.exceptions.viewholders +package org.mozilla.fenix.trackingprotectionexceptions.viewholders import android.view.View import androidx.recyclerview.widget.RecyclerView diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsListItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsListItemViewHolder.kt similarity index 91% rename from app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsListItemViewHolder.kt rename to app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsListItemViewHolder.kt index 25e51824c..ec43919b9 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsListItemViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotectionexceptions/viewholders/ExceptionsListItemViewHolder.kt @@ -2,14 +2,14 @@ * 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.exceptions.viewholders +package org.mozilla.fenix.trackingprotectionexceptions.viewholders import android.view.View import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.exception_item.view.* import mozilla.components.concept.engine.content.blocking.TrackingProtectionException import org.mozilla.fenix.R -import org.mozilla.fenix.exceptions.ExceptionsInteractor +import org.mozilla.fenix.trackingprotectionexceptions.ExceptionsInteractor import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.loadIntoView diff --git a/app/src/main/res/layout/account_preference.xml b/app/src/main/res/layout/account_preference.xml index 1a6f0af47..e2998bee9 100644 --- a/app/src/main/res/layout/account_preference.xml +++ b/app/src/main/res/layout/account_preference.xml @@ -2,7 +2,6 @@ - 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/main/res/layout/fragment_exceptions.xml b/app/src/main/res/layout/fragment_exceptions.xml index 6fed0a94b..2b0e69fc2 100644 --- a/app/src/main/res/layout/fragment_exceptions.xml +++ b/app/src/main/res/layout/fragment_exceptions.xml @@ -3,10 +3,7 @@ - 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/. --> - + android:orientation="vertical"/> diff --git a/app/src/main/res/layout/logins_item.xml b/app/src/main/res/layout/logins_item.xml index 14f25e3af..6a311748a 100644 --- a/app/src/main/res/layout/logins_item.xml +++ b/app/src/main/res/layout/logins_item.xml @@ -1,11 +1,8 @@ - - - - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"> + + @@ -51,16 +55,14 @@ android:id="@+id/usernameView" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="12dp" - android:layout_weight="1" + android:layout_marginStart="16dp" + android:layout_marginEnd="48dp" android:ellipsize="middle" - android:paddingStart="?android:attr/listPreferredItemPaddingStart" - android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:singleLine="true" android:textColor="?secondaryText" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/favicon_image" + app:layout_constraintStart_toEndOf="@+id/favicon_wrapper" app:layout_constraintTop_toBottomOf="@id/webAddressView" app:layout_constraintVertical_chainStyle="packed" tools:text="mozilla.org" /> diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 77eba73a6..e3b1859cb 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -27,35 +27,83 @@ android:id="@+id/action_global_search" app:destination="@id/searchFragment" /> - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + tools:layout="@layout/fragment_tab_tray_dialog" /> + app:nullable="true" /> + android:defaultValue="NONE" + app:argType="org.mozilla.fenix.components.metrics.Event$PerformedSearch$SearchAccessPoint" /> + app:popExitAnim="@anim/fade_out_down" /> + android:defaultValue="false" + app:argType="boolean" /> @@ -234,8 +282,8 @@ app:destination="@id/bookmarkSelectFolderFragment" /> + android:defaultValue="false" + app:argType="boolean" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + - + tools:layout="@layout/fragment_synced_tabs"/> + + + app:nullable="false" /> + app:popUpToInclusive="true" /> + app:nullable="false" /> + app:popUpToInclusive="true" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> @@ -541,7 +601,7 @@ + android:name="org.mozilla.fenix.settings.about.AboutFragment" /> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right" /> + android:id="@+id/trackingProtectionExceptionsFragment" + android:name="org.mozilla.fenix.trackingprotectionexceptions.TrackingProtectionExceptionsFragment" + android:label="@string/preference_exceptions" /> + app:nullable="true" /> diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 6539c58d4..d67b32965 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -2,6 +2,8 @@ متصفّح %s خاص + + %s (خاص) خيارات أكثر @@ -20,6 +22,9 @@ لسان واحد مفتوح. انقر لتبديل الألسنة. + + %1$s من الألسنة مفتوح. انقر لتبديل الألسنة. + أنت في جلسة خاصة @@ -39,6 +44,9 @@ لا، شكرًا + + ليس الآن + لسان جديد @@ -81,6 +89,8 @@ أضِف إلى شاشة البداية ثبّت + + الألسنة المُزامنة ابحث في الصفحة @@ -104,6 +114,8 @@ تدعمها %1$s منظور القارئ + + أغلِق منظور القارئ افتح في التطبيق @@ -232,6 +244,8 @@ أعِد الاتصال لمواصلة المزامنة اللغة + + اختيارات البيانات جمع البيانات @@ -272,6 +286,8 @@ العلامات جلسات الولوج + + الألسنة المفتوحة اخرج @@ -281,6 +297,10 @@ يُزامن… + + فشلت المزامنة. آخر نجاح: %s + + فشلت المزامنة. تاريخ آخر مزامنة: لم تحدث تاريخ آخر مزامنة: %s @@ -291,6 +311,10 @@ الألسنة المستلمة تنبيهات الألسنة المستلمة من أجهزة Firefox الأخرى. + + وصل لسان + + وصلت ألسنة لسان من %s @@ -299,6 +323,8 @@ الحماية من التعقّب الحماية من التعقّب + + احجب المحتوى والنصوص البرمجية التي تتعقّبك على الإنترنت الاستثناءات @@ -316,6 +342,12 @@ تليمتري + + الاستخدام والبيانات التقنية + + بيانات التسويق + + التجارب يسمح بأن تثبّت Mozilla بيانات المزايا التجريبية وتجمعها @@ -330,6 +362,8 @@ امسح رمز الاقتران رقميًا في Firefox على سطح المكتب لِج + + لِج لإعادة الاتصال أزِل الحساب @@ -374,8 +408,12 @@ العلامات الأخرى التأريخ + + الألسنة المُزامنة قائمة القراءة + + ابحث الإعدادات @@ -384,8 +422,26 @@ الألسنة المفتوحة + + جلسة خاصة أضِف لسانًا + + أضِف لسانًا خاصًا + + خاص + + الألسنة المفتوحة + + احفظ في التجميعة + + شارِك كل الألسنة + + أغلِق كل الألسنة + + لسان جديد + + انتقل إلى الصفحة الرئيسية أزِل اللسان من المجموعة @@ -408,6 +464,12 @@ احفظ شارِك + + احفظ في التجميعة + + حذف المجموعة + + إعادة تسمية المجموعة افتح الألسنة @@ -444,6 +506,8 @@ آخر 30 يومًا + + أقدم ما من تأريخ هنا @@ -467,6 +531,8 @@ قائمة العلامات حرّر العلامة + + اختر مجلدًا أمتأكّد من حذف هذا المجلد؟ @@ -482,6 +548,8 @@ حرّر حرّر + + اختر انسخ @@ -502,9 +570,301 @@ حرّر المجلد + + المجلد + + الاسم + + أضِف مجلدًا + + اختر مجلدًا + + حُذف %1$s + + تراجَع + + + + الصلاحيات + + انتقل إلى الإعدادات + + صفحة الإعدادات السريعة + + موصى به + + التشغيل التلقائي + + الكمرة + + الميكروفون + + محجوبة + + مسموح بها + + الاستثناءات + + مفعّل + + معطّل اسمح بالصوت والڤِديو + + مفعّل + + معطّل + + + + التجميعات + + اختر الكل + + ألغِ تحديد الكل + + أغلِق + + احفظ + + اعرض + + + + أرسِل وشارِك + + شارِك + + شارِك + + شارك الرابط + + أرسل إلى جهاز + + كل الإجراءات + + المستخدمة حديثًا + + لِج إلى «المزامنة» + + أرسله إلى كل الأجهزة + + غير متصل + + صِلْ جهازًا آخر + + فهمت + + أرسِل إلى جهاز + + لا أجهزة متصلة + + + اطلع على المزيد عن إرسال الألسنة… + + صِلْ جهازًا آخر… + + + + جلسة تصفح خاصة + + افتح + + أُغلق اللسان + + تراجَع + + أُزيلت الصفحة + + تراجَع + + أكّد + + احذف + + ألغِ + + + حجم الخط + + + التأريخ + + أغلِق + + + ألغِ + + احذف + + حُذفت بيانات التصفح + + يحذف بيانات التصفح… + + + ألديك حساب؟ + + تعرف على %s + + اعرف ما الجديد + + استغلّ %s إلى أقصى حد. + + لِج إلى Firefox + + فشل الولوج + + القياسي (المبدئي) + + صارم (مستحسن) + + صارم + + تصفّح بخصوصية + + افتح الإعدادات + + خصوصيتك + + أغلِق + + + ابدأ التصفح + + + + اختر السمة + + + آلي + + سمة داكنة + + سمة فاتحة + + + أُرسلت الألسنة! + + أُرسل اللسان! + + تعذر الإرسال + + أعِد المحاولة + + سيتوقف Firefox عن مزامنة حسابك، لكن لن يحذف أيًا من بيانات تصفحك على هذا الجهاز. + + سيتوقف %s عن مزامنة حسابك، لكن لن يحذف أيًا من بيانات تصفحك على هذا الجهاز. + + اقطع الاتصال + + ألغِ + + + + إعدادات الحماية + + الحماية الموسّعة من التعقب + + تصفّح ولا أحد ورائك + + + لتعبّر الكاف في ”بياناتك“ عنك أنت. يحميك %s من عديد من المتعقّبات المعروفة والتي تريد معرفة ما تفعله في المواقع. + + اطّلع على المزيد + + القياسي (المبدئي) + + صارم + + مخصّص + + اختر المتعقّبات والسكربتات التي تريد حجبها. + + + الكعكات + + المتعقّبات الاجتماعية ومتعقّبات بين المواقع + + الكعكات من المواقع غير المُزارة + + كل كعكات الأطراف الثالثة (يمكن أن تعطب المواقع هكذا) + + كل الكعكات (يمكن أن تعطب المواقع هكذا) + + محتوى التعقّب + + في كل الألسنة + + في الألسنة الخاصة فقط + + في الألسنة المخصصة فقط + + المُعدّنات المعمّاة + + مسجّلات البصمات + حُجبت + + مسموح بها + + متعقبات مواقع التواصل الاجتماعي + + يحدّ من قدرة الشبكات الاجتماعية على تعقب نشاط تصفحك على الإنترنت. + + كعكات تتعقّبك بين المواقع + + المُعدّنات المعمّاة + + مسجّلات البصمات + + فُعّلت الحماية في هذا الموقع + + عُطّلت الحماية في هذا الموقع + + عُطّلت الحماية الموسّعة من التعقب لهذه المواقع + + حقوقك + + ما جديد %s + + + الدعم + + الانهيارات + + تنويه الخصوصية + + اعرف حقوقك + + معلومات الترخيص + + + + انسخ + + ألصِق وانتقل + + ألصِق + + نُسخ المسار إلى الحافظة + + + أضِف إلى شاشة البداية + + ألغِ + + أضِف + + تابِع نحو الموقع + + اسم الاختصار + جلسات الولوج وكلمات السر @@ -517,9 +877,146 @@ الملء التلقائي زامِن جلسات الولوج + + مفعّلة + + معطّلة أعِد الاتصال لِج إلى «المزامنة» - + + جلسات الولوج المحفوظة + + اعرف المزيد عن المزامنة. + + الاستثناءات + + ستظهر جلسات الولوج وكلمات السر غير المحفوظة هنا. + + لن تُحفظ جلسات الولوج وكلمات السر لهذه المواقع. + + ابحث في جلسات الولوج + + أبجديًا + + المستخدمة حديثًا + + الموقع + + اسم المستخدم + + كلمة السر + + اطّلع على المزيد + + احفظ + + لا تحفظ + + نُسخت كلمة السر إلى الحافظة + + نُسخ اسم المستخدم إلى الحافظة + + نُسخ الموقع إلى الحافظة + + انسخ كلمة السر + + اسنخ اسم المستخدم + + انسخ الموقع + + أظهِر كلمة السر + + أخفِ كلمة السر + + لاحقًا + + الاسم (ا-ي) + + آخر استخدام + + + أضِف محرك بحث + + حرّر محرك بحث + + أضِف + + احفظ + + حرّر + + احذف + + + أخرى + + الاسم + + اطّلع على المزيد + + + أدخِل اسم محرك البحث + + أدخِل نص البحث + + + ابدأ %s + + كلمات السر + + + اتصال آمن + + اتصال غير آمن + + أمتأكد من مسح كل الصلاحيات لكل المواقع؟ + + أمتأكد من مسح كل الصلاحيات لهذا الموقع؟ + + أمتأكد من مسح التصريح لهذا الموقع؟ + + أضِف للمواقع الشائعة + + احذف + + حرّر + + أمتأكد من حذف جلسة الولوج هذه؟ + + احذف + + أهمِل التعديلات + + حرّر + + كلمة السر مطلوبة + + البحث الصوتي + + تكلّم الآن + + يوجد بالفعل جلسة ولوج باسم المستخدم هذا + + + + الاتصال بحساب Firefox. + + صِلْ جهازا آخر. + + من فضلك فعّل مزامنة الألسنة. + + لا ألسنة مفتوحة في Firefox على أجهزتك الأخرى. + + اعرض قائمة بالألسنة من أجهزتك الأخرى. + + لِج إلى «المزامنة» + + + لإضافة موقع شائع جديد، أزِل واحدًا. انقر مطولًا على الموقع واختر ”أزِل“. + + حسنًا، فهمت + + diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index 314f1e69a..a68d311de 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -34,8 +34,7 @@ - %1$s llimpia los historiales cuando coles de l\'aplicación o zarres toles llingüetes privaes. Magar qu\'esto nun t\'anonimiza n\'internet, fai que la to actividá en llinia seya fácil d\'anubrir - a otros usuarios qu\'usen el preséu. + %1$s llimpia los historiales cuando coles de l\'aplicación o zarres toles llingüetes privaes. Magar qu\'esto nun t\'anonimiza n\'internet, fai que la to actividá en llinia seya fácil d\'anubrir a otros usuarios qu\'usen el preséu. Mitos comunes tocante al restolar en privao Desaniciar la sesión @@ -220,6 +219,10 @@ Amestar un atayu pa restolar en privao Accesibilidá + + Sirvidor personalizáu de Firefox Accounts + + Sirvidor personalizáu de Sync Modificóse\'l sirvidor de cuentes/sincronización de Firefox. Colando de l\'aplicación p\'aplicar los cambeos… @@ -872,6 +875,8 @@ In English this is an idiom for "choose a side as in an argument or fight" but it is ok to make this more literally about "choosing a position in a physical space --> Posición + + Prueba\'l restolar con una mano cola barra de ferramientes no baxero o móvila a lo cimero. Restolar en privao Aforra daqué de batería y curia los güeyos activando\'l mou escuru. + + Siguir l\'estilu del sistema Adáutase a los axustes del preséu @@ -1049,6 +1056,9 @@ Les biblioteques qu\'usamos + + Menú de depuración: %1$d calcu(os) p\'activar Activóse\'l menú de depuración @@ -1079,6 +1089,9 @@ Nome del atayu + + Pues amestar fácilmente esti sitiu web a la pantalla d\'aniciu del preséu p\'acceder nel intre y restolalu como si fore una aplicación. + Anicios de sesión y contraseñes @@ -1250,6 +1263,12 @@ La conexón ye segura La conexón ye insegura + + ¿De xuru que quies quitar tolos permisos de tolos sitios? + + ¿De xuru que quies quitar tolos permisos d\'esti sitiu? + + ¿De xuru que quies quitar esti permisu d\'esti sitiu? Nun hai nenguna @@ -1270,6 +1289,12 @@ Desaniciar + + El campu de testu editable pa la direición web del aniciu de sesión. + + El campu de testu editable pal nome d\'usuariu del aniciu de sesión. + + El campu de testu editable pa la contraseña del aniciu de sesión. Edición @@ -1296,7 +1321,7 @@ Algamóse la llende de sitios destacaos - P\'amestar sitios nuevos, desanicia dalgún. Ten primíu un sitiu y esbilla Desaniciar. + P\'amestar sitios nuevos desanicia dalgún. Ten primíu un sitiu y esbilla Desaniciar. Val, entendílo diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 6f0d792a3..2757c5f4f 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -25,6 +25,9 @@ Адкрытых картак: %1$s. Націсніце, каб пераключыць карткі. + + %1$s распрацаваны Mozilla. + Вы ў прыватным сеансе @@ -202,6 +205,10 @@ Дадаць ярлык прыватнага аглядання Даступнасць + + Уласны сервер уліковых запісаў Firefox + + Уласны сервер сінхранізацыі Уліковы запіс @@ -302,13 +309,19 @@ Выключэнні Ахова ад сачэння выключана на гэтых сайтах + + Уключыць для ўсіх сайтаў Даведацца больш Тэлеметрыя + + Выкарыстанне і тэхнічныя дадзеныя Дзяліцца звесткамі пра прадукцыйнасць, выкарыстанне, апаратнае забеспячэнне і налады вашага браўзера з Mozilla, каб дапамагчы ўдасканаліць %1$s + + Маркетынгавыя дадзеныя Доследы diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml new file mode 100644 index 000000000..c91f32468 --- /dev/null +++ b/app/src/main/res/values-br/strings.xml @@ -0,0 +1,310 @@ + + + + %s prevez + + %s (prevez) + + + Dibarzhioù ouzhpenn + + Gweredekaat ar Merdeiñ Prevez + + Diweredekaat ar Merdeiñ Prevez + + Klask pe chomlecʼh + + Diskouezet e vo amañ hocʼh ivinelloù digoret + + Diskouezet e vo amañ hocʼh ivinelloù prevez + + 1 ivinell digor. Stokit evit mont dʼun ivinell all. + + %1$s ivinell digor. Stokit evit mont dʼun ivinell all. + + + Gant Mozilla eo produet %1$s. + + + + En un estez prevez emaocʼh + + %1$s a skarzh ho roll istor klask ha merdeiñ eus an ivinelloù prevez pa guitait anezho pe pa guitait an arload. Daoust ma ne lak ket acʼhanocʼh da vezañ dizanv evit al lecʼhiennoù pe evit ho pourchaser kenrouedad e vo aesocʼh da zercʼhel prevez ar pezh a rit enlinenn evit an dud all a implij an trevnad-mañ. + Mojennoù a vez alies diwar-benn ar merdeiñ prevez + + Dilemel an estez + + + + Ouzhpennañ ur verradenn evit digeriñ ivinelloù prevez adalek ho skramm degemer. + + Ouzhpennañ ur verradenn + + Ket, trugarez + + + + Kit buanocʼh war Firefox. Ouzhpennit ur widjet war ho skramm degemer. + + Ouzhpennañ ur widjet + + Ket bremañ + + + + Ivinell nevez + + Ivinell prevez nevez + + Lecʼhiennoù gwellañ + + + + Ivinelloù digor + + + Distreiñ + + War-lercʼh + + Azbevaat + + Paouez + + Sined + + Embann ar sined + + Askouezhioù + + Nʼeus tamm enlugellad ebet amañ + + Skoazell + + Petra nevez + + Arventennoù + + Levraoueg + + Lecʼhienn urzhiataer + + Ouzhpennañ dʼar skramm degemer + + Staliañ + + Ivinelloù goubredet + + Kavout er bajennad + + Roadennoù prevez + + Ivinell nevez + + Enrollañ en dastumad + + Rannañ + + Rannañ gant... + + Digeriñ e %1$s + + LUSKET GANT %1$s + + Lusket gant %1$s + + Mod Lenn + + Serriñ ar mod lenn + + Digeriñ en arload + + Neuz + + Ne cʼhaller ket kennaskañ. Steuñv URL dianav. + + + + Yezh dibabet + + Klask + + Ober gant yezh ar benveg + + Klask ur yezh + + + + Cʼhwilerviñ + + Berradennoù + + Arventennoù al lusker klask + + Klask gant + + Evit ar wech-mañ, klask gant: + + Leuniañ diwar ar golver + + Aotren + + Na aotren + + Aotren alioù klask er merdeiñ prevez? + + + %s a ranno ar pezh a vizskrivit er varrenn chomlecʼhioù gant ho lusker enklask dre ziouer. + + Gouzout hirocʼh + + + + Klask + + Klask er web + + Klask dre vouezh + + + + Arventennoù + + Diazez + + Hollek + + A-zivout + + Keflusker enklask dre ziouer + + Klask + + Barrenn chomlecʼhioù + + Skoazell + + Notennit anezhañ war Google Play + + Reiñ evezhiadennoù + + A-zivout %1$s + + Ho kwirioù + + Gerioù-tremen + + Kartennoù kred ha chomlecʼhioù + + Lakaat evel merdeer dre ziouer + + Kempleshocʼh + + Buhez prevez + + Buhez prevez ha diogelroez + + Aotreoù al lecʼhiennoù + + Merdeiñ prevez + + Digeriñ an ereoù en un ivinell brevez + + Aotren an tapadennoù-skramm er merdeiñ prevez + + Ouzhpennañ ur verradenn merdeiñ prevez + + Haezadusted + + Dafariad kont Firefox personelaet + + Dafariad Sync personelaet + + Dafariad kont Firefox/Sync kemmet. Kuitaet e vo an arload evit arloañ ar cʼhemmoù… + + Kont + + Kennaskañ + + Barrenn ostilhoù + + Neuz + + Personelaat + + Goubredit sinedoù, ar roll istor, ha muiocʼh cʼhoazh gant ho kont Firefox. + + Kont Firefox + + Adkennaskit evit kendercʼhel gant ar goubredañ + + Yezh + + Dibaboù roadennoù + + Dastum roadennoù + + Evezhiadennoù a-fet buhez prevez + + Ostilhoù an diorroer + + Diveugañ a-bell dre USB + + Berradennoù klask + + Diskouez kinnigoù ar cʼhlask + + Diskouez ar cʼhlask dre vouezh + + Diskouez er estezioù prevez + + Diskouez kinnigoù ar golver + + Klask er roll istor + + Klask er sinedoù + + Arventennoù ar gont + + Digeriñ ereoù en arloadoù + + Askouezhioù + + + + Goubredañ bremañ + + Dibabit petra vo goubredet + + Roll istor + + Sinedoù + + Titouroù kennaskañ + + Ivinelloù digor + + Digennaskañ + + Anv an trevnad + + Anv an trevnad nʼhall ket bezañ goullo. + + O goubredañ... + + Goubredañ cʼhwitet. Berzh diwezhañ: %s + + + Goubredañ cʼhwitet. Goubredañ diwezhañ: morse + + Goubredañ diwezhañ : %s + + Goubredañ diwezhañ : morse + + diff --git a/app/src/main/res/values-cak/strings.xml b/app/src/main/res/values-cak/strings.xml index 477f8d853..c333c6ea9 100644 --- a/app/src/main/res/values-cak/strings.xml +++ b/app/src/main/res/values-cak/strings.xml @@ -22,6 +22,11 @@ Wawe\' xkeq\'alajin pe ri ichinan taq ruwi\'. + + 1 ruwi\' jaqon. Tachapa\' richin nak\'ëx ruwi\'. + + %1$s ruwi\' ejaqon. Tachapa\' richin nak\'ëx ruwi\'. + %1$s b\'anon ruma Mozilla. @@ -299,6 +304,8 @@ Taq yaketal Ketikirisäx molojri\'ïl + + Kejaq ruwi\' Titz\'apïx molojri\'ïl @@ -489,6 +496,8 @@ Titz\'apïx ronojel ri taq ruwi\' Kekomonïx taq ruwi\' + + Keyak ruwi\' pa mol Ruk\'utsamaj ruwi\' @@ -711,6 +720,10 @@ Ruk\'utsamaj mol + + Ke\'amolo\' ri taq wachinäq niqa chawa + + Ketzob\'ajïx taq kanoxïk, taq ruxaq chuqa\' taq ruwi\' ejunam richin ye\'okisäx na. Kecha\' taq Ruwi\' @@ -921,6 +934,9 @@ Firefox Nightly nuk\'ëx ri\' ronojel taq aq\'a\' chuqa\' k\'o k\'ak\'a\' tojtob\'enel taq rusamaj. Po rik\'in jub\'a\' man kan ta jikïl. Taqasaj ri beta qokik\'amaya\'l richin jun jikïl samaj. + + Tak\'ulu\' Firefox richin Android Beta + Firefox Nightly xsilöx @@ -1438,6 +1454,9 @@ Achi\'el: \nhttps://www.google.com/search?q=%s Kach\'o wakami + + K\'o chik jun tikirib\'äl molojri\'ïl rik\'in re b\'i\'aj re\' + Tok rik\'in jun Rub\'i\' Rutaqoya\'l Firefox @@ -1448,4 +1467,19 @@ Achi\'el: \nhttps://www.google.com/search?q=%s Tatzija\' ri kiximik taq ruwi\'. - + + Majun ruwi\' ajaqon pa Firefox pa ri ch\'aqa\' chik awokisab\'al. + + Titz\'et jun kicholb\'al ruwi\' pa juley chik awokisab\'al. + + Tatikirisaj molojri\'ïl pa yaximon + + + + Xaq\'i\' ruchi\' ri jutaqil taq ruxaq + + Richin natz\'aqatisaj jun k\'ak\'a\' jutaqil ruxaq, tayuju\' jun. Tapitz\'a\' pa ruwi\' ri ruxaq richin nacha\' tiyuj. + + ÜTZ, Wetaman Chik + + diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 14f717a77..c21238321 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -13,14 +13,17 @@ Deaktiver privat browsing Søg eller indtast adresse - - Ingen åbne faneblade Dine åbne faneblade vil blive vist her. Dine private faneblade vil blive vist her. + + 1 åbent faneblad. Tryk for at skifte faneblade. + + %1$s åbne faneblade. Tryk for at skifte faneblade. + %1$s er lavet af Mozilla. @@ -93,6 +96,8 @@ Føj til startskærm Installer + + Synkroniserede faneblade Find på siden @@ -101,8 +106,6 @@ Nyt faneblad Gem til samling - - Anmeld problem med webstedet Del @@ -116,8 +119,10 @@ Leveret af %1$s - + Læsevisning + + Luk læsevisning Åbn i app @@ -286,6 +291,8 @@ Bogmærker Logins + + Åbne faneblade Log ud @@ -417,6 +424,8 @@ Andre bogmærker Historik + + Synkroniserede faneblade Læseliste @@ -438,6 +447,24 @@ Private faneblade Tilføj faneblad + + Tilføj privat faneblad + + Privat + + Åbne faneblade + + Gem til samling + + Del alle faneblade + + Luk alle faneblade + + Nyt faneblad + + Gå til startsiden + + Skift tilstand for faneblade Fjern faneblad fra samling @@ -451,7 +478,7 @@ Del faneblade - Gem til samling + Gem faneblade til samling Faneblads-menu @@ -661,16 +688,14 @@ Fra - - Saml de ting, der er vigtige for dig. Gem åbne faneblade i en ny samling for at komme i gang. Samlinger Samlings-menu - Ingen samlinger - - Dine samlinger vil blive vist her. + Saml de ting, der betyder noget for dig + + Saml relaterede søgninger, websteder og faneblade i grupper. Så kan du hurtigt finde dem igen. Vælg faneblade @@ -700,6 +725,9 @@ Gem + + Vis + Samling %d @@ -848,8 +876,6 @@ Sletter automatisk browserdata, når du vælger "Afslut" i hovedmenuen Sletter automatisk browserdata, når du vælger \"Afslut\" i hovedmenuen - - Browserhistorik Afslut @@ -873,8 +899,9 @@ Firefox Nightly bliver opdateret hver nat og har nye, eksperimentelle funktioner. Nightly kan dog være ustabil nogle gange. Hent vores beta-version, hvis du vil have en mere stabil browser. - - Hent Mozilla Firefox Browser + + + Hent Firefox Beta til Android Firefox Nightly er flyttet @@ -929,18 +956,20 @@ Kunne ikke logge ind - Beskyt dig selv + Automatisk privatlivsbeskyttelse - %s hjælper dig med at forhindre websteder i at spore dig på nettet. + Indstillinger for privatlivsbeskyttelse og sikkerhed blokerer sporings-mekanismer, skadelig software og virksomheder, der følger dig på nettet. - Standard + Standard - Blokerer færre sporings-teknologier, men gør det muligt for sider at indlæses normalt + Blokerer færre sporings-mekanismer. Sider indlæses som normalt. Striks (anbefalet) + + Striks - Blokerer flere sporings-teknologier for at opnå bedre beskyttelse og ydelse, men kan forhindre nogle websteder fra at fungere optimalt + Blokerer flere sporings-mekanismer, reklamer og pop ups. Sider indlæses hurtigere, men noget funktionalitet virker måske ikke. @@ -1026,31 +1055,21 @@ Læs mere - Standard - - Standard (anbefalet) + Standard - Balanceret mellem beskyttelse og ydelse. - - Sider indlæses normalt, men færre sporings-teknologier blokeres. + Blokerer færre sporings-mekanismer. Sider indlæses som normalt. Hvad der bliver blokeret af standard-opsætningen af beskyttelse mod sporing Striks - - Striks (standard) - Stærkere beskyttelse mod sporing og hurtigere ydelse, men nogle websteder virker måske ikke ordentligt. - - Striks (anbefalet) - - Stærkere beskyttelse, men nogle websteder eller noget indhold indlæses måske ikke korrekt. + Blokerer flere sporings-mekanismer, reklamer og pop ups. Sider indlæses hurtigere, men noget funktionalitet virker måske ikke. Hvad der bliver blokeret af striks beskyttelse mod sporing Tilpasset - Vælg selv, hvilke sporings-teknologier og scripts der skal blokeres + Vælg selv, hvilke sporings-teknologier og scripts der skal blokeres. Hvad der bliver blokeret af tilpasset beskyttelse mod sporing @@ -1100,7 +1119,7 @@ Stopper indlæsning af eksterne reklamer, videoer og andet indhold, der indeholder sporings-kode. Kan påvirke nogle websteders funktionalitet. - %s blokerer sporings-teknologier på dette websted, når skjoldet er lilla. Tryk på ikonet for at se, hvad der er blokeret. + Når skjoldet er lilla, betyder det at %s har blokeret sporings-mekanismer på et websted. Tryk for mere info. Beskyttelse er slået TIL for dette websted @@ -1383,4 +1402,31 @@ Stemme-søgning Tal nu + + Et login med dette brugernavn findes allerede + + + + Forbind med en Firefox-konto. + + Opret forbindelse til en ny enhed. + + Godkend igen. + + Aktiver synkronisering af faneblade. + + Du har ikke nogen faneblade åbne i Firefox på dine andre enheder. + + Se en liste med faneblade fra dine andre enheder. + + Log ind på Sync + + + + Grænsen for Mest besøgte websider er nået + + Hvis du vil tilføje en ny webside, skal du først fjerne én. Tryk og hold på websiden, og vælg så Fjern. + + Ok, forstået + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c3e687433..673a112f6 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -920,8 +920,6 @@ Löscht die Browser-Daten automatisch, wenn Sie im Hauptmenü die Option „Beenden“ auswählen Löscht die Browser-Daten automatisch, wenn Sie im Hauptmenü die Option „Beenden“ auswählen - - Chronik Beenden @@ -953,7 +951,7 @@ Firefox Nightly ist umgezogen Diese App erhält keine Sicherheitsupdates mehr. Nutzen Sie diese App nicht mehr und wechseln Sie zum neuen Nightly. -        \ n \ nUm Ihre Lesezeichen, Zugangsdaten und Chronik auf eine andere App zu übertragen, erstellen Sie ein Firefox-Konto. +\n\nUm Ihre Lesezeichen, Zugangsdaten und Chronik auf eine andere App zu übertragen, erstellen Sie ein Firefox-Konto. Wechseln Sie zum neuen Nightly @@ -961,7 +959,7 @@ Firefox Nightly ist umgezogen Diese App erhält keine Sicherheitsupdates mehr. Holen Sie sich das neue Nightly und nutzen Sie diese App nicht mehr. -        \ n \ nUm Ihre Lesezeichen, Zugangsdaten und Chronik auf eine andere App zu übertragen, erstellen Sie ein Firefox-Konto. +\n\nUm Ihre Lesezeichen, Zugangsdaten und Chronik auf eine andere App zu übertragen, erstellen Sie ein Firefox-Konto. Holen Sie sich das neue Nightly diff --git a/app/src/main/res/values-hy-rAM/strings.xml b/app/src/main/res/values-hy-rAM/strings.xml index 46b617e87..3f6f99682 100644 --- a/app/src/main/res/values-hy-rAM/strings.xml +++ b/app/src/main/res/values-hy-rAM/strings.xml @@ -34,7 +34,7 @@ - %1$s-ը մաքրում է ձեր որոնման և զննարկման պատմությունը, երբ դուրս եք գալիս ծրագրից կամ փակում եք բոլոր գաղտնի ներդիրները: Չնայած դա ձեզ անանուն չի դարձնում ինտերնետային կայքերի կամ ձեր ինտերնետային ծառայություններ մատուցողի համար, այն ավելի հեշտ է դարձնում ձեր առցանց ակտիվության գաղտնիությունը այն դեպքում, եթե մեկ ուրիշը ևս օգտագործում է այս սարքը: + %1$s-ին մաքրում է որոնման և զննարկման պատմությունը, երբ փակում եք ներդիրը կամ դուրս եք գալիս հավելվածից: Չնայած դա ձեզ անանուն չի դարձնում կայքերի կամ ձեր համացանցի ծառայություններ մատուցողի համար, այն ավելի հեշտ է դարձնում ձեր առցանց ակտիվության գաղտնիությունը այն դեպքում, եթե մեկ ուրիշը ևս օգտագործում է տվյալ սարքը: Տարածված առասպելներ գաղտնի դիտարկման վերաբերյալ Ջնջել աշխատաշրջանը @@ -887,8 +887,6 @@ Ինքնաբար ջնջում է դիտարկման տվյալները, երբ հիմնական ցանկից ընտրում եք «Փակել»: Ինքնաբար ջնջում է դիտարկման տվյալները, երբ հիմնական ցանկից ընտրում եք \«Փակել»\: - - Դիտարկման պատմություն Փակել diff --git a/app/src/main/res/values-lij/strings.xml b/app/src/main/res/values-lij/strings.xml index c67f455c3..500552d81 100644 --- a/app/src/main/res/values-lij/strings.xml +++ b/app/src/main/res/values-lij/strings.xml @@ -31,7 +31,7 @@ Ti ê inte \'na sescion privâ - %1$s scancella a teu cronologia de navegaçion e de riçerche quande seri i feuggi e i barcoin de navegaçion privâ. Sciben che questo o no ti fa deventâ anònimo co-i sciti o co-o fornitô de Internet, o l\'agiutta in ògni mòddo a mantegnî privòu da-i atri utenti de sto computer cöse ti fæ in linea. + %1$s o scancella a teu stöia de navegaçion e riçerche quande særi i feuggi e-i barcoin de navegaçion privâ. Sciben che questo o no te fa deventâ anònimo co-i sciti ò co-o fornitô de Internet, o l\'agiutta in a mantegnî privòu cöse ti fæ in linea a-i atri utenti de sto computer. Miti comuin in sciâ navegaçion privâ Scancella sescion @@ -66,7 +66,7 @@ Inderê - + Avanti Agiorna @@ -94,7 +94,7 @@ Installa - + Feuggi scincronizæ Treuva in pagina @@ -143,7 +143,7 @@ Scanscionn-a - Scorsaiéu + Scorsaieu Inpostaçioin motô de riçerca @@ -337,6 +337,8 @@ A proteçion anti-traciamento a l\'é asmortâ pe sti sciti Açendi pe tutti i sciti + + Con Eceçioin ti peu dizativâ a proteçion anti-traciamento pe-i sciti seleçionæ. Atre informaçioin @@ -347,8 +349,12 @@ Telemetria Dæti tecnichi e statistiche d\'uzo + + Condividdi con Mozilla informaçioin in sce prestaçioin, uzo, hardware e personalizaçioin do navegatô pe contribuî a-o megioamento de %1$s Dæti de marketing + + Condividdi dæti in sce fonçioin adeuviæ in %1$s con Leanplum, o nòstro fornitô pe-o marketing inta piataforma mòbile. Esperimenti @@ -669,6 +675,10 @@ Asmòrtou Permetti aodio e video + + Blòcca aodio e video solo con conescion dæti + + Aodio e video saian riproduti co-a conescion Wi-Fi Blòcca solo l\'aodio @@ -685,6 +695,8 @@ Menû coleçion Ragruppa i teu interessi + + Amuggia riçerche, sciti e feuggi scimili pe poeghe acede ciù a-a spedia dòppo. Seleçionn-a feuggi @@ -745,6 +757,8 @@ Feua linia Conetti atro dispoxitivo + + Pe mandâ un feuggio, intra into conto Firefox almeno inte \'n atro dispoxitivo. Ò capio! @@ -817,6 +831,8 @@ Intra into mòddo a tutto schermo Indirisso copiou + + Sto chi o l\'é \'n testo d\'ezenpio. Serve pe fa vedde comme saiâ o testo quande ti t\'aomenti o ti diminoisci o testo con sta inpostaçion. Aomenta ò riduxi a dimenscion do testo di sciti web @@ -825,6 +841,9 @@ Dimescionamento di carateri aotomatico + + A dimenscion di carateri saiâ pægia a quella de Android. Dizativâ pe gestî a dimenscion di carateri chi. + Scancella dæti navegaçion @@ -856,6 +875,10 @@ Scancella dæti navegaçion quande sciòrto + + Scancella in aotomatico i dæti de navegaçion quande ti seleçionn-i "Sciòrti" da-o menû prinçipâ + + Scancella in aotomatico i dæti de navegaçion quande ti seleçionn-i \"Sciòrti\" da-o menû prinçipâ Sciòrti @@ -873,12 +896,29 @@ 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 @@ -893,11 +933,18 @@ Descòvri %s Descòvri cöse gh\'é de neuvo + + Ti gh\'æ de domande in sciô neuvo %s? Ti veu savei cöse l\'é cangiou? Treuva chi e risposte Piggia o mascimo da %s. + + T\'ê za conesso comme %s inte \'n atro navegatô Firefox sorvia sto telefono. Ti veu intrâ con questo conto? Sì, famme intrâ @@ -912,23 +959,41 @@ No riescio a acede Privacy aotomatica + + E inpostaçion da privacy e seguessa blocan elementi che tracian, malware e aziende che ascoran e teu ativitæ in linia. Normale (predefinio) + + Blòcca meno elementi che tracian. E pagine saian caregæ normalmente. Restritivo (consegiou) Restritivo + + Blòcca ciù elementi che tracian, publicitæ e pop-up. E pagine saian caregæ ciù a-a spedia ma quarche fonçion a no aniâ. Piggia poxiçion + + Preuva a bara di atressi da basso pe navegâ con \'na sola man, ò mesciala de d\'ato. Navega in mòddo privou + + Arvi un feuggio privou \'na sola vòtta: tocca l’iconn-a %s + + Arvi un feuggio privou ògni vòtta: agiorna e inpostaçioin do navegatô. Arvi inpostaçioin A teu privacy + + Emmo progetou %s pe date o controllo in sce cöse ti condividdi + in linia e cöse condividdi con niatri. Lezzi a nòstra informativa in sciâ privacy @@ -940,8 +1005,12 @@ Çerni o teu tema + + Risparmia bateria e protezzi i teu euggi ativando o mòddo scuo. Aotomatico + + O se adatta a-e inpostaçioin do dispoxitivo Tema scuo @@ -957,17 +1026,26 @@ PREUVA TORNA Scançionn-a o còdice + + https://firefox.com/pair]]> Pronto pe-a scançion Acedi co-a fòtocamera Acedi con l’email + + I dæti de navegaçion no saian ciù scincronizæ co-o conto Firefox, ma no saian scancelæ da sto dispoxitivo. + + I dæti de navegaçion no saian ciù scincronizæ co-o conto %s, ma no saian scancelæ da sto dispoxitivo. Disconnetti Anulla + + No pòsso cangiâ e cartelle predefinie + Preferense proteçion @@ -975,18 +1053,38 @@ Proteçion anti-traciamento avansâ Navega sensa ese ascorio + + Mantegni i teu dæti pe ti mæximmo. %s o te protezze da-a magiô parte di elementi che te tracian in linia. Atre informaçioin Normale (predefinio) + + Blòcca meno elementi che tracian. E pagine saian caregæ normalmente. + + Elementi blocæ da-a proteçion anti-traciamento standard Restritivo + + Blòcca ciù elementi che tracian, publicitæ e pop-up. E pagine saian caregæ ciù a-a spedia ma quarche fonçion a no aniâ. + + Elementi blocæ da-a proteçion anti-traciamento restritiva Personalizou + + Çerni quæ traciatoî e script blocâ. + + Elementi blocæ da-a proteçion anti-traciamento personalizâ Cookie + Traciatoî inter-scito e di social media + + Cookie da sciti no vixitæ + + Tutti i cookie de terse parte (quarche scito o porieiva no fonçionâ ben) + Tutti i cookie (quarche scito o no fonçioniâ ben) Contegnui che tracian @@ -1009,16 +1107,28 @@ Limita a capaçitæ di social network de traciâ e teu ativitæ in sciâ ræ. Cookie che tracian inter-scito + + Blòcca i cookie che e ræ de publicitæ e soçietæ de analixi dæti deuvian pe arecheugge i dæti de navegaçion quande ti passi da un scito a l\’atro. Cryptominer + + Inpedisce a di script mascarsoin de acede a-o dispoxitivo pe fâ da moneta digitale. Fingerprinter + + Blòcca l\'acugeita dæti identificativi univochi in sciô dispoxitivo e che peuan ese deuviæ pe traciate. Contegnui che tracian + + Blòcca o caregamento de anonçi esterni, video e atri contegnui che gh\'an do còdice traciante. O peu infloî in sce quarche fonçion do scito. + + Tutte e vòtte che-o scuddo o l\'é cô de viovetta, %s o l\'à blocou di elementi che tracian do scito. Tocca pe avei ciù informaçioin. E proteçioin en ative pe sto scito E proteçioin no en ative pe sto scito + + A proteçion anti-traciamento avansâ a l\'é asmortâ pe sti sciti Vanni inderæ @@ -1077,6 +1187,9 @@ Nomme scorsaieu + + Ti peu azoze con facilitæ sto scito a-a teu Pagina prinçipâ pe aveighe acesso instantaneo e navegâ veloce co-ina esperiesa scimile a \'n app. + Acessi e poule segrete @@ -1099,10 +1212,16 @@ Acedi a Sync Acessi sarvæ + + I acessi che ti sarvi ò ti scincronizzi saian mostræ chi. Ciù informaçioin in sce Sync. Eceçioin + + I acessi e poule segrete che no en sarvæ saian mostræ chi. + + I acessi e poule segrete no saian sarvæ pe sti sciti. Çerca inti acessi @@ -1117,9 +1236,15 @@ Poula segreta Scrivi torna o PIN + + Sblocca pe vedde i acessi sarvæ + + Sta conescion a no l\'é segua. Te peuan arobâ i teu acessi. Atre informaçioin + + Ti veu che %s o sarve sto acesso? Sarva @@ -1140,6 +1265,12 @@ Mostra poula segreta Ascondi poula segreta + + Sblocca pe vedde i acessi sarvæ + + Protezzi i acessi e poule segrete + + Inpòsta \'na sequensa de blòcco, PIN ò poula segreta pe protezze i teu acessi e poule segrte sarvæ da ese arobæ da quarchedun ch\'o te piggia o dispoxitivo. Dòppo @@ -1148,11 +1279,20 @@ Sblòcca o teu dispoxitivo Zoon inti tutti i sciti + + Ativa pe consentî a fonçion pitta e zoom, in sci sciti che l\'inpediscian ascì. Nomme (A-Z) Urtimo deuviou + + Òrdina menû di acessi + + + Azonzi motô de riçerca + + Cangia motô de riçerca Azonzi @@ -1168,12 +1308,26 @@ Nomme Stringa de riçerca da deuviâ + + Cangia a ciave de riçerca con “%s”. Ezenpio:\nhttps://www.google.com/search?q=%s Atre informaçioin + + Informaçioin in sciô motô de riçerca personalizou Colegamento pe atre informaçioin + + Scrivi o nomme do motô de riçerca + + L\'existe zà \'n motô de riçerca co-o nomme “%s”. + + Scrivi \'na stringa de riçerca + + Contròlla che a stringa de riçerca a segge into formou d\'ezenpio. + + Erô de conescion a “%s” %s creou @@ -1181,10 +1335,16 @@ %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 @@ -1201,6 +1361,12 @@ Conescion segua Conescion no segua + + Te seguo de scancelâ tutti i permissi de tutti i sciti? + + Te seguo de scancelâ tutti i permissi pe sto scito? + + Te seguo de scancelâ sto permisso pe sto scito? Nisciunn-a eceçion pe-i sciti @@ -1222,6 +1388,12 @@ Scancella Inpostaçioin acessi + + O canpo de testo cangiabile pe l\'indirisso de acesso. + + O canpo de testo cangiabile pe-o nomme utente de acesso. + + O canpo de testo cangiabile pe-a poula segreta de acesso. Sarva i cangiamenti a-i acessi diff --git a/app/src/main/res/values-lo/strings.xml b/app/src/main/res/values-lo/strings.xml index dec53cfc3..fa395c9e9 100644 --- a/app/src/main/res/values-lo/strings.xml +++ b/app/src/main/res/values-lo/strings.xml @@ -19,6 +19,11 @@ ແທັບສ່ວນຕົວຂອງທ່ານຈະຖືກສະແດງຢູ່ບ່ອນນີ້. + + ເປີດ 1 ແຖບ. ແຕະເພື່ອປ່ຽນແທັບ. + + ເປີດ %1$s ແຖບ. ແຕະເພື່ອປ່ຽນແທັບ. + %1$s ແມ່ນຜະລິດຂື້ນໂດຍ Mozilla. @@ -96,6 +101,8 @@ ແທັບສ່ວນຕົວ ແທັບໃຫມ່ + + ບັນທຶກໄປໄວ້ບ່ອນເກັບສະສົມ ແບ່ງປັນ @@ -111,11 +118,17 @@ ຂັບເຄື່ອນໂດຍ %1$s ມຸມມອງຂອງຜູ້ອ່ານ + + ປິດມຸມມອງຜູ້ອ່ານ ເປີດໃນ App ຮູບ​ຮ່າງ + + ບໍ່​ສາ​ມາດ​​ເຊື່ອມ​ຕໍ່ໄດ້ ເນື່ອງຈາກບໍ່ຮູ້ຈັກຮູບແບບ URL + ພາສາທີ່ເລືອກ @@ -143,6 +156,10 @@ ອະນຸຍາດ ບໍ່ອະນຸຍາດ + + ອະນຸຍາດໃຫ້ມີຄຳແນະນຳການຄົ້ນຫາໃນແຊັສຊັນສ່ວນໂຕຫລືບໍ່? + + %s ຈະແຊລທຸກຢ່າງທີ່ທ່ານພິມໃນແທັບທີ່ຢູ່ກັບເຄືອງມືການຄົ້ນຫາພື້ນຖານຂອງທ່ານ. ຮຽນຮູ້ເພີ່ມເຕີມ @@ -193,6 +210,8 @@ ຄວາມເປັນສ່ວນຕົວ ຄວາມເປັນສ່ວນຕົວ ແລະ ຄວາມປອດໄພ + + ສິດທິໃນເວັບໄຊທ ການທ່ອງເວັບແບບສ່ວນຕົວ @@ -203,6 +222,12 @@ ເພີ່ມທາງລັດການທ່ອງເວັບແບບສ່ວນຕົວ ສິ່ງອຳນວຍຄວາມສະດວກ + + ດັດແກ້ບັນຊີເຊີເວີ Firefox + + ກຳຫນົດເຊີເວີ Sync + + ບັນຊີ/Sync ຂອງ Firefox ໄດ້ຮັບການດັດແກ້ແລ້ວ. ອອກຈາກແອັບພລິເຄຊັນເພື່ອນຳໃຊ້ການດັດແກ້… ບັນຊີ @@ -345,9 +370,14 @@ ການໃຫ້ບໍລິການຕຳແຫນ່ງທີ່ຢູ່ຂອງ Mozilla + + %s ລາຍງານສະພາບການນຳໃຊ້ + ເປີດ Sync + + ສະແກນລະຫັດການຈັບຄູ່ໃນ Firefox ເດັສກທັອບ ເຂົ້າສູ່ລະບົບ @@ -375,6 +405,9 @@ ເຂັ້ມ + + ຕັ້ງໂດຍຕົວປະຢັດແບດເຕີລີ່ + ເຊດຊັນ @@ -422,6 +455,8 @@ ສ່ວນຕົວ ເປີດແທັບ + + ບັນທຶກໄປໄວ້ບ່ອນເກັບສະສົມ ແບ່ງປັນແທັບທັງໝົດ @@ -430,6 +465,10 @@ ແທັບໃຫມ່ ໄປຫນ້າທຳອິດ + + ຮູບແບບການສະຫຼັບແທັບ + + ລຶບແຖບອອກຈາກບ່ອນເກັບສະສົມ ປິດແທັບ @@ -440,6 +479,8 @@ ປິດແທັບທັງຫມົດ ແບ່ງປັນແທັບ + + ບັນທຶກແຖບໄປໄວ້ໃນບ່ອນເກັບສະສົມ ເມນູແທັບ @@ -451,6 +492,14 @@ ແບ່ງປັນ + + ແຊັສຊັນຮູບພາບຕອນນີ້ + + ບັນທຶກໄປໄວ້ບ່ອນເກັບສະສົມ + + ລຶບບ່ອນເກັບສະສົມ + + ປ່ຽນຊື່ບ່ອນເກັບສະສົມ ເປີດແທັບ @@ -511,6 +560,12 @@ ກູ້ຄືນແທັບ + + ຕົວເລືອກຂອງແຊັສຊັນ + + + ແບ່ງປັນແຊັສຊັນ + ເມນູບຸກມາກ @@ -587,4 +642,226 @@ ໄປທີ່ການຕັ້ງຄ່າ + + ອອກຈາກການຕັ້ງຄ່າ sheet + + ແນະນຳ + + ຈັດການສິດໃນເວັບໄຊທ + + ລົບລ້າງສິດ + + ລົບລ້າງສິດ + + ລົບລ້າງສິດສຳລັບທຸກເວັບໄຊທ + + ເປີດອັດຕະໂນມັດ + + ກ້ອງຖ່າຍຮູບ + + ໄມໂຄຣໂຟນ + + ຕໍາ​ແໜ່​ງທີ່​ຕັ້ງ + + ການແຈ້ງເຕືອນ + + ຖາມເພື່ອອະນຸຍາດ + + ບັອກແລ້ວ + + ອະນຸຍາດແລ້ວ + + ຖືກບລັອກໂດຍ Android + + ຂໍ້ຍົກເວັ້ນ + + ເປີດ + + ປິດ + + ອະນຸຍາດໃຫ້ເປີດສຽງ ແລະ ວີດີໂອ + + + ບັອກສຽງ ແລະ ວິດີໂອໃນການນໍາໃຊ້ຂໍ້ມູນອິນເຕີເນັດໃນໂທລະສັບມືຖືເທົ່ານັ້ນ + + ສຽງ ແລະ ວິດີໂອຈະເປີດໃນ Wi-Fi + + ບັອກສຽງເທົ່ານັ້ນ + + ບັອກສຽງ ແລະ ວີດີໂອ + + ເປີດ + + ປິດ + + + + ການສະສົມ + + ເມນູການສະສົມ + + ເກັບກຳສິ່ງທີ່ສຳຄັນສຳລັບທ່ານ + + ເອົາການຄົ້ນຫາ, ເວັບໄຊທ ແລະ ແທັບທີ່ຄ້າຍຄືກັນມາໄວ້ໃນກຸ່ມດຽວກັນ ເພື່ອເຮັດໃຫ້ສາມາດເຂົ້າໄດ້ງ່າຍໃນພາຍຫລັງ. + + ເລືອກແທັບ + + ເລືອກການສະສົມ + + ຊື່ການສະສົມ + + ເພີ່ມການສະສົມໃຫມ່ + + ເລືອກທັ້ງຫມົດ + + ບໍ່ເລືອກທັງຫມົດ + + ເລືອກແທັບເພື່ອບັນທຶກ + + + %d ແທັບທີ່ເລືອກແລ້ວ + + %d ແທັບທີ່ເລືອກແລ້ວ + + ບັນທຶກແທັບແລ້ວ! + + ບັນທຶກແທັບແລ້ວ! + + ປິດ + + ບັນທຶກ + + ມູມມອງ + + + %d ການສະສົມ + + + + ສົ່ງ ແລະ ແບ່ງປັນ + + ແບ່ງປັນ + + ແບ່ງປັນ + + ແບ່ງປັນລີ້ງ + + ສົ່ງໄປຫາອຸປະກອນ + + ການກະທຳທັງຫມົດ + + ທີ່ຫາກໍນຳໃຊ້ໄປ + + ລົງຊື່ເຂົ້າໃຊ້ເພື່ອ Sync + + ສົ່ງໄປຫາທຸກອຸປະກອນ + + ເຊື່ອມຕໍ່ຄືນໃຫມ່ເພື່ອ Sync + + ອອບລາຍ + + ເຊື່ອມຕໍ່ກັບອຸປະກອນອື່ນ + + ລົງຊື່ເຂົ້າໃຊ້ Firefox ຢ່າງນ້ອຍໃນ 1 ເຄື່ອງເພື່ອສົ່ງແທັບ + + + ບໍ່ສາມາດແບ່ງປັນກັບແອັບນີ້ໄດ້ + + ສົ່ງໄປຫາອຸປະກອນ + + ບໍ່ມີອຸປະກອນເຊື່ອມຕໍ່ + + ຮຽນຮູ້ກ່ຽວກັບການສົ່ງແທັບ… + + ເຊື່ອມຕໍ່ກັບອຸປະກອນອື່ນ… + + + + ເຊສຊັນການທ່ອງເວັບແບບສ່ວນຕົວ + + ລຶບແທັບສ່ວນຕົວ + + ປິດແທັບສ່ວນຕົວ + + ເປີດ + + ລົບ ແລະ ເປີດ + + ຂັບເຄື່ອນໂດຍ + + ລົບການສະສົມແລ້ວ + + ປ່ຽນຊື່ການສະສົມແລ້ວ + + ລົບແທັບແລ້ວ + + ລົບແທັບແລ້ວ + + ປິດແທັບແລ້ວ + + ປິດແທັບແລ້ວ + + ເພີ່ມເຂົ້າໄປໃນເວັບຍອດນິຍົມແລ້ວ! + + ປິດແທັບສ່ວນໂຕແລ້ວ + + ປິດແທັບສ່ວນໂຕແລ້ວ + + ລົບແທັບສ່ວນໂຕແລ້ວ + + ເອົາກັບຄືນ + + ລຶບເວັບໄຊທແລ້ວ + + ເອົາກັບຄືນ + + ຢືນຢັນ​ + + ອະນຸຍາດໃຫ້ %1$s ເພື່ອເປີດ %2$s + + ອະນຸຍາດ + + + ປະຕິເສດ + + ທ່ານແນ່ໃຈແລ້ວບໍ່ວ່າທ່ານຕ້ອງການລຶບ %1$s? + + ລຶບ + + ຍົກເລີກ + + ເຂົ້າສູ່ໂມດເຕັມຫນ້າຈໍ + + ສຳເນົາ URL ແລ້ວ + + ຂະໜາດຟັອນ + + + ການປັບຂະໜາດຟັອນແບບອັດຕະໂນມັດ + + + ລຶບຂໍ້ມູນການທ່ອງເວັບ + + ເປີດແທັບ + + ແທັບ %d + + ປະຫວັດການທ່ອງເວັບ ແລະ ຂໍ້ມູນເວັບໄຊທ + + ທີ່ຢູ່ %d + + ປະຫວັດ + + ຫນ້າ %d + + ຄຸກກີ້ + diff --git a/app/src/main/res/values-night-v23/styles.xml b/app/src/main/res/values-night-v23/styles.xml new file mode 100644 index 000000000..989c6e6a0 --- /dev/null +++ b/app/src/main/res/values-night-v23/styles.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index 124de4657..4897d7102 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -14,14 +14,32 @@ Recèrca o adreça + + %1$s es produch per Mozilla. + + + + Sètz en una session privada + + %1$s escafa vòstre istoric de recèrcas e de navegacion quand quitatz l’aplicacion o tampatz totes los onglets e fenèstras de navegacion privada. Malgrat qu’aquò vos faga pas venir anonim pels sites web o vòstre provesidor Internet, fa venir mai simple de gardar privat çò que fasètz en linha pels autres qu’utilizan aqueste ordenador. + Mites màgers de la navegacion privada Suprimir la session + + + Apondre un acorchi per dobrir d’onglets privats de l’ecran d’acuèlh estant. Apondre un acorchi Non, mercé + + Apondre lo widget + + Pas ara + Onglet novèl @@ -29,6 +47,9 @@ Novèl onglet de nav. privada + + Mai visitats + Onglets dobèrts @@ -38,6 +59,8 @@ Pagina seguenta Actualizar + + Arrestar Marcapagina @@ -58,12 +81,16 @@ Apondre a l’ecran d’acuèlh Installar + + Onglets sincronizats Recercar dins la pagina Onglet privat Onglet novèl + + Salvar a la colleccion Partejar @@ -78,6 +105,12 @@ The first parameter is the name of the app defined in app_name (for example: Fenix) --> Fonciona gràcia a %1$s + + Mòde lectura + + Tampar la vista de lectura + + Dobrir amb l’aplicacion Aparéncia @@ -91,8 +124,13 @@ Cercar una lenga + + + Escanerizar Acorchis + + Paramètres del motor de recèrca Recercar amb @@ -103,6 +141,8 @@ Autorizar pas Autorizar las suggestions de recèrca en navegacion privada ? + + %s enviarà tot çò que picatz dins la barra d’adreça al motor de recèrca Ne saber mai @@ -112,6 +152,9 @@ Recercar sul web + + Recèrca a la votz + Paramètres @@ -129,18 +172,36 @@ Barra d‘adreça Ajuda + + Valorar sus Google Play + + Donar vòstre vejaire A prepaus de %1$s + + Vòstres dreches Senhals + + Cartas de crèdit e adreças + + Definir coma navegador per defaut Avançat Vida privada Vida privada e seguretat + + Autorizacions de site + + Navegacion privada + + Dobrir los ligams en navigacion privada + + Permetre las capturas d’ecran en navegacion privada Accessibilitat @@ -158,8 +219,22 @@ Lenga + + Donadas collectadas + + Culhida de donadas + + Politica de confidencialitat Aisinas pels desvolopaires + + Desbugatge distant per USB + + Mostrar las suggestions de recèrca + + Mostrar la recèrca a la votz + + Mostrar en navegacion privada Cercar dins los marcapaginas @@ -170,6 +245,8 @@ Sincronizar ara + + Causir qué sincronizar Istoric @@ -177,6 +254,8 @@ Identificants + + Onglets dobèrts Desconnexion @@ -191,6 +270,11 @@ Darrièra sincr. : pas jamai + + %1$s sus %2$s %3$s + Onglets recebuts @@ -208,21 +292,57 @@ Proteccion contra lo seguiment Excepcions + + La proteccion contra lo seguiment es desactivada per aquestes sites + + Activar per totes los sites Ne saber mai + + Telemetria + + Donadas marketing + + Experimentacions + + + Raportador de plantatge + + Servici de localizacion de Mozilla + + Rapòrt de santat de %s + + + + Activar la sincronizacion + + Connexion Suprimir lo compte + + Dobrir la camèra Anullar + + + Naut + + Bas + Clar Fosc + + Definit per l’estalviador de batariá + + Segon lo tèma del periferic + Sessions @@ -242,12 +362,16 @@ Autres marcapaginas Istoric + + Onglets sincronizats Lista de lectura Recercar Paramètres + + Menú dels elements de l’istoric Tampar @@ -260,10 +384,40 @@ Onglets privats Apondre un onlget + + Dobrir onglet privat + + Privat + + Onglets dobèrts + + Salvar a la colleccion + + Partejar totes los onglets + + Tampar totes los onglets + + Onglet novèl + + Acuèlh + + Bascular de mòde d’onglets + + Suprimir l’onglet de la colleccion Tampar l’onglet Tampar l’onglet %s + + Dobrir lo menú dels onglets + + Tampar totes los onglets + + Partejar los onglets + + Enregistrar los onglets dins la colleccion + + Menú de l’onglet Partejar aqueste onglet @@ -273,9 +427,20 @@ Partejar + + Imatge de la session actuala + + Enregistrar dins una colleccion + + Suprimir la colleccion + + Onglets dobèrts Suprimir + + %1$s (mòde privat) + Escafar l’istoric @@ -287,8 +452,19 @@ %1$s suprimit Escafar + + Copiar + + Partejar + + Dobrir dins un onglet novèl + + Dobrir en navigacion privada Suprimir + + %1$d seleccionats Suprimir %1$d elements @@ -301,35 +477,114 @@ Mai ancian + + Cap d’istoric + + + + %1$s a pas pogut cargar aquesta pagina. + + Podètz ensajar de restablir o de tampar l’onglet seguent. + + Enviar un senhalament de bug a Mozilla Tampar l’onglet Restablir l’onglet + + Opcions de session + + + Partejar la session + + + + Menú dels marcapaginas + + Modificar lo marcapagina + + Seleccionar un dossièr Volètz vertadièrament suprimir aqueste dorsièr ? + + %1$s suprimit + + Apondre un dossièr + + Marcapagina creat. + + Marcapagina apondut ! + + MODIFICAR + + Modificar + + Seleccionar Copiar Partejar + + Dobrir dins un onglet novèl + + Dobrir en navigacion privada Suprimir Enregistrar + + %1$d seleccionats + + Modificar lo marcapagina + + Modificar lo dossièr URL + + DOSSIÈR NOM + + Apondre un dossièr + + Seleccionar un dossièr + + Deu aver un títol URL invalida + + I a pas cap de marcapagina aquí + + %1$s suprimit Marcapagina suprimit + + ANULLAR + + + + Permissions Anar als paramètres + + Recomandat + + Gerir las autorizacions de site + + Escafar las permissions + + Escafar la permission + + Escafar las permissions de totes los sites + + Lectura automatica Camèra @@ -339,11 +594,49 @@ Notificacion + + Demandar per autorizar + + Blocat + + Autorizat + + Blocat per Android + + Excepcions + + + Activada + + Desactivada + + Autorizar l’àudio e la vidèo + + + + Colleccions + + Menú de colleccion + + Nom de la colleccion + + Onglets enregistrats ! + + Onglet enregistrat ! Tampar Enregistrar + + Veire + + + Colleccion %d + + + + Enviar e partejar Partejar Enviar al periferic + + Totas las accions + + Utilizats fa res + + Se connectar a Sync Enviar a totes los periferics + + Tornar connectar a Sync Fòra linha + + Connectar un periferic mai + + Comprés ! Enviar al periferic Cap de periferic pas connectat + + Dobrir Onglet suprimit Onglets suprimits + + Onglet tampat + + Onglets tampats + + ANULLAR Confirmar @@ -375,6 +688,9 @@ Anullar + + URL copiada + Onglets dobèrts @@ -400,31 +716,332 @@ Suprimir + + + La benvenguda a %s ! + + Avètz ja un compte ? + + Descobrissètz %s + + Descobrissètz las novetats + + Òc, connectatz-me + + Connexion… + + Se connectar a Firefox + + Demorar desconnectat + + Estandard (per defaut) + + Estricte (recomandat) + + Estricte + + Dobrir los paramètres + + Tampar + + + Començar de navegar + + + + Causissètz vòstre tèma + + Automatic + + Tèma fosc + + Tèma clar + + + Onglets enviats ! + + Onglet enviat ! + + Se desconectar Anullar + + + Paramètres de proteccion + + Proteccion contra lo seguiment renfortida + + Navegatz sens èsser seguit + + Ne saber mai + + Personalizada + + + Cookies + + Contengut utilizat pel seguiment + + + Dins totes los onglets + + Sonque en navegacion privada + + Sonque dins os onglets personalizats + + Minaires de criptomonedas + + Generadors d’emprentas numericas + Blocat + + Autorizat + + Traçadors de malhums socials + + Cookies de seguiment entre sites + + Minaires de criptomonedas + + Generadors d’emprentas numericas + + Contengut utilizat pel seguiment + + + Quand l’escut es violet, %s a blocat de traçadors sus aqueste site. Tocatz aquí per ne saber mai. + + Las proteccions son activadas per aqueste site + + Las proteccions son desactivadas per aqueste site + + La proteccion renfortida contra lo seguiment es desactivada per aquestes sites + + Tornar + + Vòstres dreches + + Bibliotècas liuras qu’utilizam + + Qu’es nòu dins %s + + + Assisténcia + + + Plantatges + + Entresenhas sus la licéncia + + + 1 onglet + + %d onglets + + + + Copiar + + Pegar e anar + + Pegar + + URL copiada dins lo quichapapièrs. + + + Apondre a l’ecran d’acuèlh Anullar + + Apondre + + Contunhar cap al site web + + + Nom de l’acorchi + + + Identificants e senhals + + Salvar los identificants e senhals + + Demandar per salvar + + Salvar pas jamai + + Emplenament automatic + + Sincronizar los identificants + + Activat + + Desactivat + + Se reconnectar + + Se connectar a Sync + + Identificants salvats + + Per ne saber mai sus Sync. + + Excepcions + + Recercar d’identificants + + Òrdre alfabetic + + Utilizats recentament + + Site + + Nom d’utilizaire + + Senhal + + Tornatz picar lo PIN + + Aquesta connexion es pas segura. Los identificant picats aquí poirián èsser divulgats. + + Ne saber mai + + Volètz que %s enregistre aqueste identificant ? + + Enregistrar + + Enregistrar pas + + Senhal copiat al quichapapièrs + + Nom d’utilizaire copiat al quichapapièrs + + Site copiat al quichapapièrs + + Copiar lo senhal + + Copiar lo nom d’utilizaire + + Copiar lo site + + Mostrar lo senhal + + Amagar lo senhal + + + Mai tard + + O configurar ara + + Nom (A-Z) + + Darrièra utilizacion + + + Apondre un motor de recèrca + + Modificar lo motor de recèrca + + Apondre + + Enregistrar + + Modificar Suprimir + + Autre + + Nom + + Ne saber mai + + + Ligam per ne saber mai + + + Picatz una cadena de recèrca + + Error de connexion a « %s » + + %s creat + + %s enregistrat %s : supression realizada + + Mesa a jorn de %s… + + Aviar %s + + La migracion a acabat + + Senhals + + + Per l’autorizar : + + + 1. Anar als paramètres Android + + Permissions]]> + + %1$s sus ACTIVAT]]> + + + Connexion segura + + Connexion pas segura Volètz vertadièrament suprimir totas las autorizacions per totes los sites ? Volètz vertadièrament suprimir totas las autorizacions per aqueste site ? Volètz vertadièrament suprimir aquesta autorizacion per aqueste site ? + + Cap d’excepcions de site + + Articles principals Sètz segur que volètz suprimir aqueste marcapagina ? + + Apondre als sites populars + + Verificat per : %1$s Suprimir + + Modificar Sètz segur que volètz suprimir aqueste identificant ? Suprimir - + + Opcions de l’identificant + + Anullar las modificacions + + Modificar + + Senhal requesit + + Recèrca a la votz + + Parlatz ara + + + + Connectatz-vos amb un compte Firefox + + Se connectar a Sync + + + Òc, plan comprés + + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 53bfa5093..9844559eb 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -398,7 +398,7 @@ - firefox.com/pair]]> + firefox.com/pair]]> Открыть камеру @@ -955,7 +955,7 @@ Firefox Nightly переехал - Это приложение больше не будет получать обновлений безопасности. Получите новый Nightly и прекратите использование этого приложения. + Это приложение больше не будет получать обновлений безопасности. Загрузите новый Nightly и прекратите использование этого приложения. \n\nЧтобы переместить ваши закладки, логины и историю в другое приложение, создайте аккаунт Firefox. Получить новый Nightly @@ -1065,11 +1065,11 @@ ПОВТОРИТЬ - Просканируйте QR-код + Сканирование QR-кода https://firefox.com/pair]]> - Готов к сканированию + Сканировать QR-код Войти с распознаванием лица diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 9204a5f23..00d2d95a6 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -23,6 +23,9 @@ 1 otvorená karta. Ťuknutím prepnete karty. + + 1 otvorených kariet. Ťuknutím prepnete karty. + %1$s vyvíja Mozilla. diff --git a/app/src/main/res/values-su/strings.xml b/app/src/main/res/values-su/strings.xml index 32b3c0885..7c84a9373 100644 --- a/app/src/main/res/values-su/strings.xml +++ b/app/src/main/res/values-su/strings.xml @@ -8,12 +8,48 @@ Pilihan séjén + + Hurungkeun langlangan pribadi + + Pareuman langlangan pribadi Paluruh atawa asupkeun alamat + + Sakur tab anu muka bakal ditémbongkeun di dieu. + + Sakur tab pribadi anjeun bakal ditémbongkeun di dieu. + + 1 tab muka. Toél pikeun ngagilir tab. + + %1$s tab muka. Toél pikeun ngagilir tab. + + + %1$s dihasilkeun ku Mozilla. + + + + Anjeun keur dina rintakan nyamuni + Mitos umum ngeunaan langlangan nyamuni Hapus rintakan + + Teu, nuhun + + + Tambihkeun widget + + Moal waka + + + + Tab anyar + + Tab nyamuni anyar + + Loka kawentar + Buka Tab @@ -33,6 +69,8 @@ Émboh + + Teu aya add-on di dieu Pitulung @@ -47,6 +85,8 @@ Tambahkeun ka layar Tepas Pasang + + Tab singkron Panggihan dina kaca @@ -58,6 +98,8 @@ Simpen kana koléksi Bagikeun + + Bagikeun sareng… Buka di %1$s @@ -74,6 +116,9 @@ Pidangan + + + Basa anu dipilih Paluruh @@ -142,10 +187,18 @@ Jadikeun panyungsi baku Terusan + + Salindungan + + Salindungan jeung kaamanan + + Idin loka Nyungsi nyamuni Buka tutumbu di tab nyamuni + + Ngidinan layar dina langlangan nyamuni Tambahan tarabas nyungsi nyamuni @@ -156,16 +209,34 @@ Akun Asup + + Téma + + Sesuaikeun Singkronkeun markah, jujutan, jeung nu lianna maké Firefox Account anjeun Akun Firefox Sambungkeun deui pikeun neruskeun nyingkronkeun + + Basa + + Pilihan data + + Koléksi data + + Wawar privasi + + Parabot pamekar + + Debugging ti kajauhan liwat USB Témbongkeun takulan pamaluruhan Témbongkeun anjuran maluruh + + Tampilkeun panyungsi sora Témbongkeun dina rintakan nyamuni @@ -203,20 +274,90 @@ Nyingkronkeun… + + Singkronan panungtung: %s + + Singkronan panungtung: acan pernah + + %1$s dina %2$s %3$s + + + + Tab nu katampa + + Tab Katampa + + Tab Katampa + + Tab ti %s + + + + Kilung Palacakan + + Kilung Palacakan + + Iwal Kilung Palacakan pikeun ieu loka ayeuna pareum + + Lenyepan + + + Telemétri + + Data pamasaran + + Éksperimén + + Ngidinan Mozilla masang sareng ngumpulkeun data kanggo fitur ékspérimén + + Laporan karuksakan + + Laporan kaséhatan %s + + + + Hurungkeun Sync Pinday sandi papasangan dina Firefox déstop Asup + + Asup pikeun nyambungkeun deui Cabut akun + + Buka Kaméra Bolay + + + Luhur + + Handap + + + + Caang + + Poék + + Turutan téma paranti + + + + Sesi + + Téwakan layar + + Undeuran Markah @@ -227,16 +368,105 @@ Palang Parabot Markah Markah Lianna + + Jujutan + + Tab singkron + + Daptar Bacaeun Paluruh + + Setélan + + Menu barang jujutan + + Tutup + + + + Buka tab + + Sesi nyamuni + + Tab nyamuni + + Tambah tab + + Tambah tab nyamuni + + Salindungan + + Buka Tab + + Simpen kana koléksi + + Bagikeun sadaya tab + + Tutup kabéh tab + + Tab anyar + + Cabut tab tina koléksi + + Tutup tab + + Tutup tab %s + + Buka menu tab + + Tutup kabéh tab + + Bagikeun tab + + Simpen tab kana koléksi + + Menu tab + + Bagikeun tab + + Pupus + + Teundeun + + Bagikeun + + Gambaran sési kiwari + + Simpen kana koléksi + + Hapus koléksi + + Ganti ngaran koléksi + + Buka tab + + Piceun + + %1$s (Mode Nyamuni) + Hapus jujutan Yakin rék meresihan jujutan anjeun? + + Mupus jujutan + + Mupus %1$s Beresihan + + Tiron + + Bagikeun + + Buka dina tab anyar + + Buka dina tab nyamuni + + Pupus %1$d dipilih @@ -244,6 +474,34 @@ is a digit showing the number of items you have selected --> Hapus %1$d item + + 24 jam terakhir + + + 7 dinten kapungkur + + 30 dinten kapungkur + + Lawas + + Teu aya jujutan di dieu + + + + Hampura. %1$s teu tiasa nyungsi ieu kaca. + + Kirim laporan nu ruksak ka Mozilla + + Tutup tab + + Malikkeun tab + + + Pilihan sési + + + Bagikeun sési + Menu markah @@ -251,6 +509,10 @@ Édit markah Pilih map + + Yakin anjeun rék mupus ieu folder? + + Mupus %1$s Tambah map @@ -301,9 +563,27 @@ Euweuh markah di dieu + + Mupus %1$s + + Mupus markah BEDO + + + Idin + + Buka Setélan + + Sepré sétélan gancang + + Disarankeun + + Ngatur idin loka Beresihan idin @@ -311,6 +591,8 @@ Beresihan idin di sadaya loka + + Autoplay Kaméra @@ -319,14 +601,115 @@ Lokasi Iber + + Nyuhunkeun diidinan + + Dipeungpeuk + + Idinan + + Diblokir ku Android Iwal + + Hurung + + Pareum + + Ngidinan sora jeung pidéo + + Blokir sora jeung pidéo dina data sélulér wungkul + + Sora jeung pidéo bakal dimaénkeun dina Wi-Fi + + Blokir sora hungkul + + Blokir sora jueng pidéo Hurung Pareum + + + Koléksi + + Menu koléksi + + Kumpulkeun hal anu penting pikeun anjeun + + Ngagabungkeun pamaluruhan, loka sareng tab anu sami pikeun aksés gancang engké. + + Pilih Tab + + Pilih koléksi + + Ngaran koléksi + + Nambihkeun koléksi anyar + + Pilih Kabéh + + Ulah Pilih Kabéh + + Pilih tab pikeun diteundeun + + %d tab dipilih + + %d tab dipilih + + Tab diteundeun! + + Tab disimpen! + + Tutup + + Teundeun + + + Témbong + + + Koléksi %d + + + + Kirim jeung Bagikeun + + Bagikeun + + Bagikeun + + Bagikeun tutumbu + + Kirim ka parangkat + + Sadaya lampah + + Anyar dianggo + + Asup ka Sync + + Kirim ka sadaya parangkat + + Sambungkeun deui ka Sync + + Luring + + Sambungkeun parangkat séjén + + Ngarti + + Kirim ka parangkat + + Teu aya parangkat nyambung + + Sambungkeun Parangkat Séjén… + Rintakan nyungsi nyamuni @@ -338,6 +721,36 @@ Buka Hapus jeung Buka + + Ditanagaan ku + + Mupus koléksi + + Koléksi dingaranan + + Mupus tab + + Mupus tab + + Tab ditutup + + Tab ditutup + + Ditambahkeun kana loka kawentar! + + Tab nyamuni ditutup + + Tab nyamuni ditutup + + Mupus tab nyamuni + + BEDO + + Loka dipiceun + + Bedo + + Sahkeun Idinan %1$s muka %2$s @@ -345,11 +758,27 @@ IDINAN HULAG + + Anjeun yakin rék mupus %1$s? + + Pupus Bolay + + URL ditiron + + Ieu mangrupikeun conto téks. Di dieu pikeun nunjukkeun kumaha téks bakal némbongan nalika anjeun ningkatkeun atanapi ngirangan ukuran dina sétélan ieu. + + Ukuran font + + + Ukuran font otomatis + Hapus data sungsian + + Buka tab %d tab @@ -393,8 +822,44 @@ Pupus + + Data panyungsi pupus + + + Mupus data sungsian… + + + + Firefox Sawangan téh ayeuna Firefox Nightly + + Manggih Firefox Android Béta + + + Firefox Nightly parantos ngalih + + Ngalih ka Nightly anyar + + + Firefox Nightly parantos ngalih + + Manggih Nightly anyar + + + + Wilujeng sumping di %s! Geus boga akun? + + Ngenalkeun %s + + Tingali naon nu anyar + + Kéngingkeun waleran di dieu + + Maksimalkeun %s. @@ -412,10 +877,65 @@ Gagal asup + + Salindungan otomatis + + Baku (bawaan) + + Pereketkeun (pijeujeuh) + + Pereketkeun + + Nyungsi nyamuni + + Buka tab nyamuni sakali: Toél ikon %s. + + Unggal buka tab nyamuni: Anyarkeun sétélan langlangan nyamuni anjeun. + + Buka setélan + + Salindungan anjeun + + Maca wawaran salindungan kami + + Tutup + + + Mitembeyan nyungsi + + + + Pilih téma anjeun + + Otomatis + + Téma poék + + Téma caang + + + Tab dikirim! + + Tab dikirim! + + Teu tiasa ngirim + + COBA DEUI Pinday sandi + + https://firefox.com/pair]]> + + Siap mindai + + Asup maké kaméra anjeun + + Maké surél wéh Firefox bakal eureun nyingkronkeun jeung akun anjeun, ngan moal mupus sakur data langlangan anjeun dina ieu alat. + + %s bakal eureun nyingkronkeun jeung akun anjeun, ngan moal mupus sakur data langlangan anjeun dina ieu parangkat. Pegatkeun @@ -424,8 +944,16 @@ Setélan Kilung + + Protéksi Palacakan Tingkat Lanjut + + Nyungsi bari teu dituturkeun Lenyepan + + Baku (bawaan) + + Pereketkeun Réréméh @@ -437,15 +965,62 @@ Sakabéh réréméh pihak katilu (bisa ngabalukarkeun raramatloka jadi teu bener) Sakabéh réréméh (bakal ngabalukarkeun raramatloka jadi teu bener) + + Kontén palacak + + Dina sadaya tab + + Ngan dina tab Nyamuni + + Gurandil kripto + + Sidik ramo + Dipeungpeuk + + Idinan + + Palacak Media Sosial Réréméh Palacak Meuntas-Loka Meungpeuk réréméh anu dipaké ku maskapé jaringan iklan jeung analitika pikeun ngumpulkeun data langlangan anjeun di loka anu kaanjangan. + + Gurandil kripto + + Sidik ramo + + Kontén palacak Eureunan iklan, pidéo, jeung kontén lianna anu ngandung sandi palacak. Bisa mangaruhan fungsionalitas sababaraha raramatloka. + + Protéksi Palacakan Tingkat Lanjut pareum dina ieu loka + + Mundur + + Hak anjeun + + Nu anyar di %s + + + Pangrojong + + Karuksakan + + Wawar privasi + + Ieu hak anjeun + + Émbaran lisensi + + + 1 tab + + %d tab + Tiron @@ -456,12 +1031,74 @@ URL ditiron kana papan klip + + Tambahkeun ka layar Tepas Bolay + + Tambah + + Teruskeun ka loka + + + Naros keur neundeun + + Ulah diteundeun + + Hurung + + Pareum + + Sambungkeun deui + + Asup ka Sync + + Asup log kasimpen + + Leuwih jéntré ngeunaan Sync. + + Iwal Paluruh login + + Sacara abjad + + Anyar dianggo + + Loka + + Sandiasma + + Kecap sandi + + Lenyepan + + Teundeun + + Ulah diteundeun + + Kecap sandi ditiron kana papan klip + + Sandiasma ditiron kana papan klip + + Loka ditiron kana papan klip + + Niron sandi + + Niron sandiasma + + Niron loka + + Témbongkeun sandi + + Sumputkeun sandi + + Engké + + Ngaran (A-Z) + Tambah mesin pamaluruh @@ -506,6 +1143,15 @@ Wilujeng sumping ka %s anyar + + Mutahirkeun %s… + + Mimitan %s + + Migrasi réngsé + + Kecap sandi + Yakin rék ngaberesihan sadaya idin di sadaya loka? @@ -515,4 +1161,23 @@ Yakin anjeun rék mupus ieu markah? - + + Tambahkeun ka loka kawentar + + + Pupus + + Édit + + Pupus + + Pilihan asup log + + Édit + + Nyarios ayeuna + + + Okéh, Ngarti + + diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 4f6974c16..0b8875de5 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -10,7 +10,7 @@ கமுக்க உலாவல் முறை செயலில் - கமுக்க உலாவல் முறையை முடுக்கு + கமுக்க உலாவல் முறை முடக்கத்தில் தேடு/முகவரியை உள்ளிடு @@ -19,7 +19,7 @@ உங்கள் திறந்த கீற்றுகள் இங்கே காண்பிக்கப்படும். - உங்களின் ககுக்க கீற்றுகள் இங்கே காண்பிக்கப்படும். + கமுக்கக் கீற்றுகள் இங்கே காண்பிக்கப்படும். 1 கீற்றைத் திற. கீற்றுகளிடையே மாறத் தட்டவும். @@ -31,17 +31,17 @@ - நீங்கள் ஒரு தனிப்பட்ட அமர்வில் இருக்கிறீர்கள் + நீங்கள் ஒரு கமுக்க அமர்வில் இருக்கிறீர்கள் - நீங்கள் பயன்பாட்டை விட்டு வெளியேறும்போது அல்லது அனைத்து கமுக் உலாவல் தாவல்களை மூடும்போது உங்கள் தேடல் மற்றும் உலாவல் வரலாற்றை %1$s துடைக்கிறது. இது வலைத்தளங்களுக்கோ அல்லது இணைய சேவை வழங்குனர்களுக்கோ தெரியாதபோது, இந்தக் கணினியைப் பயன்படுத்தும் மற்றவர்களிடமிருந்தும் இயங்கலையில் உங்களைக் கமுக்கமா வைத்திருப்பதையும் எளிதாக்குகிறது. + நீங்கள் கமுக்கக் கீற்றுகளை மூடும்போது அல்லது செயலியை விட்டு வெளியேறும் போது உங்கள் தேடல், உலாவல் வரலாற்றை %1$s துடைக்கிறது. இது வலைத்தளங்கள் அல்லது இணைய சேவை வழங்குநர்களிடமிருந்து உங்களை அடையாளமற்றவராக மாற்றாது, ஆனால் இந்தக் கணினியைப் பயன்படுத்தும் மற்றவர்களிடமிருந்தும் இயங்கலையில் நீங்கள் செய்பவற்றை கமுக்கமாக வைப்பதை எளிதாக்குகிறது. கமுக்க உலாவல் பற்றிய பொதுவான தொன்மங்கள் அமர்வை நீக்கு - உங்கள் முகப்புத் திரையிலிருந்து கமுக்க தாவல்களைத் திறக்கக் குறுக்குவழியைச் சேர்க்கவும். + உங்கள் முகப்புத் திரையிலிருந்து கமுக்கக் கீற்றுகளைத் திறக்கக் குறுக்குவழியைச் சேர்க்கவும். குறுக்குவழியைச் சேர்க்கவும் @@ -59,7 +59,7 @@ புதிய கீற்று - புதிய தனிப்பயன் கீற்று + புதிய கமுக்கக் கீற்று சிறந்த தளங்கள் @@ -88,7 +88,7 @@ புதியவை என்ன - அமைப்புகள் + அமைவுகள் நூலகம் @@ -102,7 +102,7 @@ பக்கத்தில் தேடு - தனிப்பட்ட கீற்று + கமுக்கக் கீற்று புதிய கீற்று @@ -151,7 +151,7 @@ குறுக்குவழிகள் - தேடுபொறி அமைப்புகள் + தேடுபொறி அமைவுகள் இதனுடன் தேடு: @@ -164,7 +164,7 @@ அனுமதிக்காதே - கமுக் அமர்வுகளில் தேடல் பரிந்துரைகளை அனுமதிக்கவா? + கமுக்க அமர்வுகளில் தேடல் பரிந்துரைகளை அனுமதிக்கவா? நீங்கள் முகவரி பட்டையில் உள்ளிடும் அனைத்தையும் %s உங்கள் இயல்புநிலை தேடுபொறியுடன் பகிர்ந்து கொள்ளும். @@ -223,10 +223,10 @@ கமுக்க உலாவல் - இணைப்பைக் கமுக்க கீற்றில் திறக்க + இணைப்பைக் கமுக்கக் கீற்றில் திறக்க - கமுக்க உலாவலியில் திரைப்பிடிப்பை அனுமதி + கமுக்க உலாவலில் திரைப்பிடிப்பை அனுமதி கமுக்க உலாவல் குறுக்குவழியைச் சேர்க்கவும் @@ -282,7 +282,7 @@ புத்தகக்குறிகளைத் தேடு - கணக்கு அமைப்புகள் + கணக்கு அமைவுகள் இணைப்புகளைத் செயலியில் திறக்கவும் @@ -460,9 +460,9 @@ கீற்றைச் சேர் - கமுக்க கீற்றைச் சேர் + கமுக்கக் கீற்றைச் சேர் - கமுக்க + கமுக்கம் திறந்த கீற்றுகள் @@ -490,7 +490,7 @@ கீற்றுகளைப் பகிர் - கீற்றுகளை சேகரிப்பில் சேமிக்கவும் + கீற்றுகளைத் திரட்டில் சேமி கீற்றுப் பட்டி @@ -515,7 +515,7 @@ நீக்கு - %1$s (கமுக் பயன்முறை) + %1$s (கமுக்க முறை) @@ -535,7 +535,7 @@ புதிய கீற்றில் திற - கமுக்க கீ்ற்றில் திறக்கவும் + கமுக்கக் கீ்ற்றில் திற அழி புதிய கீற்றில் திற - கமுக்க கீ்ற்றில் திற + கமுக்கக் கீற்றில் திற அழி @@ -705,21 +705,21 @@ - தொகுப்புகள் + திரட்டுகள் - சேகரிப்பு பட்டி + திரட்டு பட்டி - உங்களுக்கு முக்கியமான விடையங்களைச் சேகரிக்கவும் + உங்களுக்கு முக்கியமான விடயங்களைச் சேகரியுங்கள் - விரைவான அணுகலுக்காக ஒத்த தேடல்கள், தளங்கள் மற்றும் கீற்றுகளை ஒன்றிணைக்கவும். + விரைவான அணுகலுக்காக ஒத்த தேடல்கள், தளங்கள், கீற்றுகளை ஒன்றிணையுங்கள். கீற்றுகளைத் தேர் - சேகரிப்பை தேர் + திரட்டைத் தேர் - சேகரிப்பை பெயரிடு + திரட்டைப் பெயரிடு - புதிய தொகுப்பைச் சேர் + புதிய திரட்டைச் சேர் அனைத்தையும் தேர் @@ -736,7 +736,7 @@ கீற்றுகள் சேமிக்கப்பட்டன! - கீற்று சேமிக்கப்பட்ட! + கீற்று சேமிக்கப்பட்டது! மூடு @@ -745,7 +745,7 @@ பார் - %d சேகரிப்பு + திரட்டு %d @@ -792,9 +792,9 @@ கமுக்க உலாவல் அமர்வு - கமுக்க கீற்றுகளை அழி + கமுக்கக் கீற்றுகளை அழி - கமுக்க கீற்றுகளை மூடு + கமுக்கக் கீற்றுகளை மூடு திற @@ -802,10 +802,10 @@ மூலம் இயக்கப்படுகிறது - சேகரிப்பு அழிக்கப்பட்டது + திரட்டு அழிக்கப்பட்டது - சேகரிப்பு மறுபெயரிடப்பட்டது + திரட்டு மறுபெயரிடப்பட்டது கீற்று அழிக்கப்பட்டது @@ -817,11 +817,11 @@ சிறந்த தளங்களில் சேர்க்கப்பட்டன! - கமுக்க கீற்று மூடப்பட்டது + கமுக்கக் கீற்று மூடப்பட்டது - கமுக்க கீற்றுகள் மூடப்பட்டன + கமுக்கக் கீற்றுகள் மூடப்பட்டன - கமுக்க கீற்றுகள் அழிக்கப்பட்டன + கமுக்கக் கீற்றுகள் அழிக்கப்பட்டன செயல்தவிர் @@ -924,6 +924,20 @@ இராக்கால பயர்பாக்சு நகர்ந்தது + + இனி இச்செயலி பாதுகாப்பு புதுப்பிப்புகளைப் பெறாது. இச்செயலியை பாவிப்பதை நிறுத்திவிட்டு புதிய இராக்கால செயலிக்கு மாறவும். + \n\nஉங்களின் புத்தகக்குறிகள், உள்நுழைவுகள் மற்றும் வரலாற்றை மற்றொரு செயலிக்கு மாற்ற, பயர்பாக்சு கணக்கை உருவாக்கவும். + + புதிய இராக்கால உலாவிக்கு மாறவும் + + + இராக்கால பயர்பாக்சு நகர்ந்தது + + இனி இச்செயலி பாதுகாப்பு புதுப்பிப்புகளைப் பெறாது. இச்செயலியை பாவிப்பதை நிறுத்திவிட்டு புதிய இராக்கால செயலிக்கு மாறவும். + \n\nஉங்களின் புத்தகக்குறிகள், உள்நுழைவுகள் மற்றும் வரலாற்றை மற்றொரு செயலிக்கு மாற்ற, பயர்பாக்சு கணக்கை உருவாக்கவும். + + புதிய இராக்கால உலாவியைப் பெறுங்கள் + @@ -943,10 +957,16 @@ %s இலிருந்து ஆக அதிகமானதைப் பெறுங்கள். + + இந்தத் தொலைபேசியில் மற்றொரு பயர்பாக்சு உலாவியில் %s பெயரில் உள்நுழைந்துள்ளீர்கள். இக்கணக்கில் உள்நுழைய விரும்புகிறீர்களா? ஆம், புகுபதி புகுபதிகிறது… + + பயர்பாக்சில் உள்நுழை விடுபதிந்தே இரு @@ -1024,12 +1044,16 @@ குறியீட்டை வருடு + + https://firefox.com/pair பக்கத்திற்கு செல்லவும்]]> வருடத் தயார் உங்கள் படக்கருவியால் புகுபதிக பதிலாக மின்னஞ்சல் பயன்படுத்துக + + பயர்பாக்சு உங்கள் கணக்குடன் ஒத்திசைவு செய்யாது, அதே சமயம் உங்கள் சாதனத்தில் உள்ள எந்த உலாவல் தரவையும் அழிக்காது. %s உங்கள் கணக்குடன் ஒத்திசைவை நிறுத்தும், ஆனால் இச்சாதனத்திலுள்ள உங்கள் உலாவல் தரவை அழிக்காது. @@ -1406,6 +1430,9 @@ அந்தப் பயனர்பெயருடன் ஒரு புகுபதிகை ஏற்கனவே உள்ளது + + + ஒரு பயர்பாக்சு கணக்குடன் இணை. மற்றொரு சாதனத்தை இணைக்க. @@ -1413,6 +1440,8 @@ மறு-அங்கீகரியுங்கள். கீற்று ஒத்திசைவைச் செயற்படுத்துங்கள். + + உங்களின் மற்ற சாதனங்களின் பயர்பாக்சில் திறந்த கீற்றுகள் ஏதுமில்லை. உங்கள் மற்ற கருவிகளிலிருந்து கீற்றுகளின் பட்டியலைப் பார்க்க. diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 4d1776fcd..206a56488 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -15,17 +15,42 @@ వెతకండి లేదా చిరునామా ఇవ్వండి - తెరిచివున్న ట్యాబులు ఇక్కడ కనిపిస్తాయి. + మీ తెరిచివున్న ట్యాబులు ఇక్కడ కనిపిస్తాయి. మీ అంతరంగిక ట్యాబులు ఇక్కడ కనిపిస్తాయి. + + 1 తెరిచివున్న ట్యాబు. ట్యాబుల మధ్య మారడానికి తాకండి. + + + %1$s తెరిచివున్న ట్యాబులు. ట్యాబుల మధ్య మారడానికి తాకండి. + + + %1$s‌ని తయారుచేసినది మొజిల్లా. + + + + మీరు అంతరంగిక సెషన్‌లో ఉన్నారు + + మీరు అంతరంగిక ట్యాబులను మూసివేసినప్పుడు లేదా అనువర్తనం నుండి నిష్క్రమించినప్పుడు మీ వెతుకుడు, విహరణ చరిత్రను %1$s తుడిచివేస్తుంది. ఇది మిమ్మల్ని వెబ్‌సైట్లకు లేదా మీ ఇంటర్నెట్ సర్వీస్ ప్రొవైడర్‌కు అనామకంగా చేయనప్పటికీ, ఈ పరికరాన్ని వాడే ఇతరుల నుండి మీ ఆన్‌లైన్ కార్యకలాపాన్ని అంతరంగికంగా ఉంచుకోవడంలో తోడ్పడుతుంది. అంతరంగిక విహారణ గురించి సామాన్య అపోహలు సెషనును తొలగించు + + + మీ ముంగిలి తెర నుండి అంతరంగిక ట్యాబులను తెరవడానికి సత్వరమార్గాన్ని చేర్చుకోండి. + + సత్వరమార్గాన్ని చేర్చు ఫరవాలేదు వద్దు + + + Firefoxకి వేగంగా చేరుకోడానికి మీ ముంగిలి తెరకు విడ్జెట్టును చేర్చుకోండి. + + విడ్జెటును చేర్చు ఇప్పుడు కాదు @@ -42,10 +67,20 @@ తెరిచివున్న ట్యాబులు వెనుకకు + + ముందుకు + + రీఫ్రెష్ చేయి + + ఆపివేయి + + ఇష్టాంశం చేయి + + ఇష్టాంశాన్ని సవరించు పొడగింతలు - పొడగింతలేమీ లేవు + ఇక్కడ పొడగింతలేమీ లేవు సహాయం @@ -70,16 +105,52 @@ కొత్త ట్యాబు సేకరణకు భద్రపరుచు + + పంచుకోండి + + దీనితో పంచుకో… + + %1$sలో తెరువు + + %1$s‌చే శక్తిమంతం + + %1$sచే శక్తిమంతం + + చదివే వీక్షణ + + చదివే వీక్షణను మూసివేయి + + అనువర్తనంలో తెరువు రూపురేఖలు + + అనుసంధానమవ్వలేక పోతున్నాం. గుర్తించేలేని URL పథకం. + ఎంచుకున్న భాష + + వెతకండి + + పరికరపు భాషను అనుసరించు భాషను వెతకండి + + + స్కాన్ చేయి + + సత్వరమార్గాలు + + శోధన యంత్ర అమరికలు + + దీనితో వెతుకు ఈసారి దీనితో వెతుకు: @@ -88,6 +159,10 @@ అనుమతించు అనుమతించవద్దు + + అంతరంగిక సెషన్లలో వెతుకుడు సలహాలను అనుమతించాలా? + + చిరునామా పట్టీలో మీరు వ్రాసిన ప్రతిదాన్ని %s మీ అప్రమేయ శోధన యంత్రంతో పంచుకుంటుంది. ఇంకా తెలుసుకోండి @@ -97,6 +172,9 @@ జాలంలో వెతకండి + + స్వర శోధన + అమరికలు @@ -106,12 +184,18 @@ సాధారణం గురించి + + అప్రమేయ శోధన యంత్రం వెతకడం చిరునామా పట్టీ సహాయం + + Google Playలో రేటు చేయండి + + అభిప్రాయాన్ని తెలియజేయండి %1$s గురించి @@ -121,6 +205,8 @@ సంకేతపదాలు క్రెడిట్ కార్డులు, చిరునామాలు + + అప్రమేయ విహారిణిగా చేయి ఉన్నతం @@ -131,12 +217,36 @@ సైటు అనుమతులు అంతరంగిక విహారణ + + లంకెలను అంతరంగిక ట్యాబులో తెరువు + + అంతరంగిక విహరణలో తెరపట్లను అనుమతించు + + అంతరంగిక విహరణ సత్వరమార్గాన్ని చేర్చు + + ప్రాప్యత + + అభిమత Firefox ఖాతా సర్వరు + + అభిమత సింక్ సర్వరు + + Firefox ఖాతా/సింక్ సర్వరు మార్చబడింది. మార్పులను వర్తింపజేయడానికి అనువర్తనం నుండి నిష్క్రమిస్తున్నాం… ఖాతా + + ప్రవేశించండి + + పనిముట్ల పట్టీ అలంకారం + + అభిమతీకరణ + + మీ Firefox ఖాతాతో ఇష్టాంశాలను, సంకేతపదాలను, ఇంకా మరెన్నిటినో సింక్ చేసుకోండి Firefox ఖాతా + + సింక్ చేయడాన్ని కొనసాగించడానికి అనుసంధానించండి భాష @@ -149,9 +259,34 @@ అంతరంగికతా విధానం డెవలపర్ పనిముట్లు + + USB ద్వారా రిమోట్ డీబగ్గింగ్ + + వెతుకుడు సలహాలను చూపించు + + స్వర శోధన చూపించు + + అంతరంగిక సెషన్లలో చూపించు + + క్లిప్‌బోర్డు సలహాలను చూపించు + + విహరణ చరిత్రలో వెతుకు + + ఇష్టాంశాలలో వెతుకు ఖాతా అమరికలు + + లంకెలను అనువర్తనాల్లో తెరువు + + + పొడగింతలు + + + + ఇప్పుడు సింక్ చేయి + + ఏమి సింక్ చేయాలో ఎంచుకోండి చరిత్ర @@ -165,10 +300,36 @@ పరికరం పేరు + + పరికరం పేరు ఖాళీగా ఉండకూడదు. + + సింక్ అవుతూంది… + + సింక్ విఫలమైంది. చివరిగా విజయవంతమైనది: %s + + సింక్ విఫలమైంది. చివరిగా విజయవంతమైనది: ఇంకా లేదు + + చివరిగా సింక్ అయినది: %s + + చివరిగా సింక్ అయ్యినది: ఇంకా లేదు + + %2$s %3$sలో %1$s + అందుకన్న ట్యాబులు + + ఇతర Firefox పరికరాల నుంచి వచ్చిన ట్యాబుల గమనింపులు. + + ట్యాబు వచ్చింది + + ట్యాబులు వచ్చాయి + + %s నుండి ట్యాబు + ట్రాకింగ్ సంరక్షణ @@ -176,21 +337,40 @@ ట్రాకింగ్ సంరక్షణ మినహాయింపులు + + ఈ వెబ్‌సైట్లకు ట్రాకింగ్ సంరక్షణ అచేతనంగా ఉంటుంది + + సైట్లన్నిటికీ చేతనం చేయి + + మినహాయింపులు మీరు ఎంచుకున్న సైట్లకు ట్రాకింగ్ సంరక్షణను అచేతనం చేసుకోనిస్తాయి. ఇంకా తెలుసుకోండి + + సర్వత్రా అచేనంగా ఉంది, దీన్ని చేతనించుకోడానికి అమరికలకు వెళ్ళండి. + టెలీమెట్రీ వాడుక, సాంకేతిక డేటా + + %1$s‌ను మెరుగుపరచడంలో తోడ్పడటానికి మీ విహారిణి గురించిన పనితనం, వాడుక, హార్డ్‌వేరు, అభిమతీకరణల డేటాను మొజిల్లాతో పంచుకుంటుంది మార్కెటింగ్ డేటా + + %1$sలో మీరు ఏయే సౌలభ్యాలు వాడుకుంటున్నారనే డేటాను మా మొబైలు మార్కెటింగ్ విక్రేత లిన్‌ప్లమ్‌తో పంచుకుంటుంది. ప్రయోగాలు + + ప్రయోగాత్మక సౌలభ్యాలను స్థాపించడానికి, వాటి డేటాను సేకరించడానికి మొజిల్లాను అనుమతిస్తుంది + + మొజిల్లా స్థాన సేవ %s ఆరోగ్య నివేదిక + + ప్రవేశించండి ఖాతాను తొలగించు @@ -209,6 +389,9 @@ చీకటి + + + సెషనులు తెరపట్లు @@ -217,19 +400,29 @@ ఇష్టాంశాలు డెస్క్‌టాప్ ఇష్టాంశాలు + + ఇష్టాంశాల మెనూ ఇతర ఇష్టాంశాలు చరిత్ర + + చదువుతూన్న జాబితా అమరికలు + + చరిత్ర అంశపు మెనూ మూసివేయి తెరిచివున్న ట్యాబులు + + అంతరంగిక సెషను + + అంతరంగిక ట్యాబులు అంతరంగికం @@ -241,6 +434,8 @@ కొత్త ట్యాబు + + ముంగిలికి వెళ్ళు ట్యాబును మూసివేయి @@ -318,12 +513,20 @@ సెషను ఎంపికలు + + మీరు నిజంగానే ఈ సంచయాన్ని తొలగించాలనుకుంటున్నారా? %1$s తొలగించబడింది సంచయం చేర్చు + + ఇష్టాంశం సృష్టించబడింది. ఇష్టాంశం భద్రమయింది! + + మార్చు + + మార్చు కొత్త ట్యాబులో తెరువు @@ -332,29 +535,53 @@ తొలగించు భద్రపరుచు + + %1$d ఎంచుకున్నారు సంచయం పేరు + + సంచయం చేర్చు + + శీర్షిక తప్పనిసరిగా ఉండాలి చెల్లని URL + + ఇక్కడ ఇష్టాంశాలేమీ లేవు + + ఇష్టాంశాలు తొలగించబడ్డాయి + అనుమతులు అమరికలకు వెళ్లు + + సిఫార్సు చేయబడింది కెమెరా మైక్రోఫోను స్థానం + + అనుమతిని అడుగు + + Android ద్వారా నిరోధించబడింది మినహాయింపులు + + చేతనం + + అచేతనం + + ఆడియో, వీడియోలను అనుమతించు ఆడియోను మాత్రమే నిరోధించు @@ -363,6 +590,10 @@ సేకరణలు + + సేకరణ మెనూ + + మీకు ముఖ్యమైన విషయాలను సేకరించండి సేకరణ ఎంపిక @@ -488,6 +719,8 @@ %d ట్యాబులు + + విహరణ చరిత్ర, సైటు డేటా %d చిరునామాలు @@ -499,9 +732,13 @@ కుకీలు + + నిల్వ జాగాని ఖాళీ చేస్తుంది సైటు అనుమతులు + + ఇది మీ విహరణ డేటా అంతటినీ తొలగించివేస్తుంది. రద్దుచేయి @@ -511,6 +748,12 @@ విహరణ డేటా తొలగించబడింది + + + Firefox Preview ఇప్పుడు Firefox Nightly అయింది + + ఆండ్రాయిడ్ కోసం Firefox బీటాను పొందండి + కొత్త నైట్లీకి మారండి @@ -537,20 +780,34 @@ కఠినం (సిఫార్సు చేయబడింది) కఠినం + + అంతరంగికంగా విహరించండి అమరికలను తెరువు మీ అంతరంగికత + + మా గోప్యతా నోటీసును చదవండి మూసివేయి + + విహరించడం మొదలుపెట్టండి + మీ అలంకారాన్ని ఎంచుకోండి + + ఆటోమెటిక్ మీ పరికర అమరికలకు తగ్గట్టు మారుతుంది + + నల్లని అలంకారం + + లేత అలంకారం + ట్యాబులు పంపబడ్డాయి! @@ -572,13 +829,43 @@ కుకీలు + + అంతరంగిక ట్యాబులలో మాత్రమే + + అభిమత సంరక్షణ ట్యాబులలో మాత్రమే + + క్రిప్టోమైనర్లు + + ఫింగర్‌ప్రింటర్లు + నిరోధించబడినవి + + అనుమతించినవి + + సామాజిక మాధ్యమాల ట్రాకర్లు + + క్రిప్టోమైనర్లు + + ఫింగర్‌ప్రింటర్లు + + + మేము వాడుతున్న ఓపెన్ సోర్స్ లైబ్రరీలు + + %s‌లో కొత్తవి ఏమిటి + తోడ్పాటు + + క్రాషులు + + గోప్యతా నోటీసు మీ హక్కులు తెలుసుకోండి లైసెన్సింగ్ సమాచారం + + మేము వాడే లైబ్రరీలు + 1 ట్యాబు @@ -587,14 +874,40 @@ రద్దుచేయి + + చేర్చు + + వెబ్‌సైట్‌కు కొనసాగు + + + వాడుకరి పేరు + + సంకేతపదం + + మీ పిన్‌ను మళ్ళీ ఇవ్వండి + తొలగించు + + పూర్తి సరికొత్త %s‌కి స్వాగతం + + సంకేతపదాలు + + + మేటి వ్యాసాలు + + ఈ ఇష్టాంశాన్ని మీరు నిజంగానే తొలగించాలనుకుంటున్నారా? తొలగించు తొలగించు + + + మేటి సైట్ల పరిమితి చేరుకున్నారు + + కొత్త మేటి సైటును చేర్చడానికి, ఒకదాన్ని తీసివేయండి. సైటు మీద ఎక్కువసేపు తట్టి, తీసివేయిను ఎంచుకోండి. సరే, అర్థమయ్యింది diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 4561e4760..10bbb091e 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -19,6 +19,11 @@ แท็บส่วนตัวของคุณจะถูกแสดงที่นี่ + + 1 แท็บที่เปิด แตะเพื่อสลับไปยังแท็บ + + %1$s แท็บที่เปิด แตะเพื่อสลับไปยังแท็บ + %1$s ผลิตขึ้นโดย Mozilla @@ -693,6 +698,8 @@ ชุดสะสม เมนูชุดสะสม + + รวบรวมสิ่งที่สำคัญสำหรับคุณ เลือกแท็บ @@ -956,6 +963,8 @@ ความเป็นส่วนตัวอัตโนมัติ มาตรฐาน (ค่าเริ่มต้น) + + ปิดกั้นตัวติดตามน้อยลง หน้าเว็บจะโหลดตามปกติ เข้มงวด (แนะนำ) @@ -1049,6 +1058,8 @@ เรียนรู้เพิ่มเติม มาตรฐาน (ค่าเริ่มต้น) + + ปิดกั้นตัวติดตามน้อยลง หน้าเว็บจะโหลดตามปกติ สิ่งที่ถูกปิดกั้นโดยการป้องกันการติดตามแบบมาตรฐาน @@ -1397,6 +1408,10 @@ เชื่อมต่ออุปกรณ์อื่น + + โปรดรับรอบความถูกต้องอีกครั้ง + + โปรดเปิดใช้งานซิงค์แท็บ คุณไม่มีแท็บใด ๆ ที่เปิดอยู่ใน Firefox บนอุปกรณ์อื่น ๆ ของคุณ @@ -1404,6 +1419,9 @@ ลงชื่อเข้าใช้เพื่อซิงค์ + + + ถึงขีดจำกัดของไซต์เด่นแล้ว ตกลง เข้าใจแล้ว diff --git a/app/src/main/res/values-v23/styles.xml b/app/src/main/res/values-v23/styles.xml index b7f59960f..bfc65cfdd 100644 --- a/app/src/main/res/values-v23/styles.xml +++ b/app/src/main/res/values-v23/styles.xml @@ -13,4 +13,11 @@ ?foundation + + \ No newline at end of file diff --git a/app/src/main/res/values-v27/styles.xml b/app/src/main/res/values-v27/styles.xml index e18af37d9..df118068e 100644 --- a/app/src/main/res/values-v27/styles.xml +++ b/app/src/main/res/values-v27/styles.xml @@ -24,4 +24,30 @@ @android:color/transparent false + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 6f7d7c1e6..fc4c5b7a3 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -464,7 +464,7 @@ 開新隱私瀏覽分頁 - 隱私 + 隱私分頁 開啟分頁 @@ -940,7 +940,7 @@ Firefox Nightly 已接手原 Firefox Preview 功能 - Firefox Nightly 每天都會更新,當中包含實驗中的新功能,然而這些新功能可能會較不穩定。\n\n若想要有較穩定的使用體驗,請下載我們的 Beta 測試版。 + Firefox Nightly 每天都會更新,當中包含實驗中的新功能,然而這些新功能可能會較不穩定。\n\n若想要有較穩定的使用體驗,請下載 Beta 測試版。 下載 Firefox for Android Beta 測試版 @@ -1148,7 +1148,7 @@ 加密貨幣採礦程式 - 防止有害的指令碼,使用您的裝置來為數位貨幣「採礦」。 + 防止有害指令碼使用您的裝置來為數位貨幣「採礦」。 數位指紋追蹤程式 diff --git a/app/src/main/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml index 7e2c43baa..e06e0524f 100644 --- a/app/src/main/res/values/preference_keys.xml +++ b/app/src/main/res/values/preference_keys.xml @@ -185,4 +185,6 @@ pref_key_search_widget_cfr_manually_dismissed pref_key_is_in_search_widget_experiment pref_key_show_search_widget_cfr + + pref_key_login_exceptions diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 96fea71e2..f8a03c6af 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1217,6 +1217,8 @@ Logins and passwords that are not saved will be shown here. Logins and passwords will not be saved for these sites. + + Delete all exceptions Search logins diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e0ffdcf79..144f053fe 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -20,8 +20,8 @@ @style/DialogStyleNormal @style/DialogStyleNormal false - @android:color/transparent false + @style/BottomSheet @color/destructive_normal_theme @@ -153,6 +153,7 @@ @style/DialogStyleDark false false + @style/BottomSheetPrivate @color/destructive_private_theme @@ -542,18 +543,30 @@ @color/search_view_hint_color - + + + + + +